From 0793a61d4df8daeac6492dbf8d2f3e5713caae5e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 4 Dec 2008 20:12:29 +0100 Subject: [PATCH 0001/6080] performance counters: core code Implement the core kernel bits of Performance Counters subsystem. The Linux Performance Counter subsystem provides an abstraction of performance counter hardware capabilities. It provides per task and per CPU counters, and it provides event capabilities on top of those. Performance counters are accessed via special file descriptors. There's one file descriptor per virtual counter used. The special file descriptor is opened via the perf_counter_open() system call: int perf_counter_open(u32 hw_event_type, u32 hw_event_period, u32 record_type, pid_t pid, int cpu); The syscall returns the new fd. The fd can be used via the normal VFS system calls: read() can be used to read the counter, fcntl() can be used to set the blocking mode, etc. Multiple counters can be kept open at a time, and the counters can be poll()ed. See more details in Documentation/perf-counters.txt. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- drivers/char/sysrq.c | 2 + include/linux/perf_counter.h | 171 +++++++ include/linux/sched.h | 9 + include/linux/syscalls.h | 6 + init/Kconfig | 29 ++ kernel/Makefile | 1 + kernel/fork.c | 1 + kernel/perf_counter.c | 943 +++++++++++++++++++++++++++++++++++ kernel/sched.c | 24 + kernel/sys_ni.c | 3 + 10 files changed, 1189 insertions(+) create mode 100644 include/linux/perf_counter.h create mode 100644 kernel/perf_counter.c diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index ce0d9da52a8a..52146c2a8d97 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -244,6 +245,7 @@ static void sysrq_handle_showregs(int key, struct tty_struct *tty) struct pt_regs *regs = get_irq_regs(); if (regs) show_regs(regs); + perf_counter_print_debug(); } static struct sysrq_key_op sysrq_showregs_op = { .handler = sysrq_handle_showregs, diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h new file mode 100644 index 000000000000..22c4469abf44 --- /dev/null +++ b/include/linux/perf_counter.h @@ -0,0 +1,171 @@ +/* + * Performance counters: + * + * Copyright(C) 2008, Thomas Gleixner + * Copyright(C) 2008, Red Hat, Inc., Ingo Molnar + * + * Data type definitions, declarations, prototypes. + * + * Started by: Thomas Gleixner and Ingo Molnar + * + * For licencing details see kernel-base/COPYING + */ +#ifndef _LINUX_PERF_COUNTER_H +#define _LINUX_PERF_COUNTER_H + +#include + +#include +#include +#include +#include +#include + +struct task_struct; + +/* + * Generalized hardware event types, used by the hw_event_type parameter + * of the sys_perf_counter_open() syscall: + */ +enum hw_event_types { + PERF_COUNT_CYCLES, + PERF_COUNT_INSTRUCTIONS, + PERF_COUNT_CACHE_REFERENCES, + PERF_COUNT_CACHE_MISSES, + PERF_COUNT_BRANCH_INSTRUCTIONS, + PERF_COUNT_BRANCH_MISSES, + /* + * If this bit is set in the type, then trigger NMI sampling: + */ + PERF_COUNT_NMI = (1 << 30), +}; + +/* + * IRQ-notification data record type: + */ +enum perf_record_type { + PERF_RECORD_SIMPLE, + PERF_RECORD_IRQ, + PERF_RECORD_GROUP, +}; + +/** + * struct hw_perf_counter - performance counter hardware details + */ +struct hw_perf_counter { + u64 config; + unsigned long config_base; + unsigned long counter_base; + int nmi; + unsigned int idx; + u64 prev_count; + s32 next_count; + u64 irq_period; +}; + +/* + * Hardcoded buffer length limit for now, for IRQ-fed events: + */ +#define PERF_DATA_BUFLEN 2048 + +/** + * struct perf_data - performance counter IRQ data sampling ... + */ +struct perf_data { + int len; + int rd_idx; + int overrun; + u8 data[PERF_DATA_BUFLEN]; +}; + +/** + * struct perf_counter - performance counter kernel representation: + */ +struct perf_counter { + struct list_head list; + int active; +#if BITS_PER_LONG == 64 + atomic64_t count; +#else + atomic_t count32[2]; +#endif + u64 __irq_period; + + struct hw_perf_counter hw; + + struct perf_counter_context *ctx; + struct task_struct *task; + + /* + * Protect attach/detach: + */ + struct mutex mutex; + + int oncpu; + int cpu; + + s32 hw_event_type; + enum perf_record_type record_type; + + /* read() / irq related data */ + wait_queue_head_t waitq; + /* optional: for NMIs */ + int wakeup_pending; + struct perf_data *irqdata; + struct perf_data *usrdata; + struct perf_data data[2]; +}; + +/** + * struct perf_counter_context - counter context structure + * + * Used as a container for task counters and CPU counters as well: + */ +struct perf_counter_context { +#ifdef CONFIG_PERF_COUNTERS + /* + * Protect the list of counters: + */ + spinlock_t lock; + struct list_head counters; + int nr_counters; + int nr_active; + struct task_struct *task; +#endif +}; + +/** + * struct perf_counter_cpu_context - per cpu counter context structure + */ +struct perf_cpu_context { + struct perf_counter_context ctx; + struct perf_counter_context *task_ctx; + int active_oncpu; + int max_pertask; +}; + +/* + * Set by architecture code: + */ +extern int perf_max_counters; + +#ifdef CONFIG_PERF_COUNTERS +extern void perf_counter_task_sched_in(struct task_struct *task, int cpu); +extern void perf_counter_task_sched_out(struct task_struct *task, int cpu); +extern void perf_counter_task_tick(struct task_struct *task, int cpu); +extern void perf_counter_init_task(struct task_struct *task); +extern void perf_counter_notify(struct pt_regs *regs); +extern void perf_counter_print_debug(void); +#else +static inline void +perf_counter_task_sched_in(struct task_struct *task, int cpu) { } +static inline void +perf_counter_task_sched_out(struct task_struct *task, int cpu) { } +static inline void +perf_counter_task_tick(struct task_struct *task, int cpu) { } +static inline void perf_counter_init_task(struct task_struct *task) { } +static inline void perf_counter_notify(struct pt_regs *regs) { } +static inline void perf_counter_print_debug(void) { } +#endif + +#endif /* _LINUX_PERF_COUNTER_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 55e30d114477..4c530278391b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -71,6 +71,7 @@ struct sched_param { #include #include #include +#include #include #include #include @@ -1326,6 +1327,7 @@ struct task_struct { struct list_head pi_state_list; struct futex_pi_state *pi_state_cache; #endif + struct perf_counter_context perf_counter_ctx; #ifdef CONFIG_NUMA struct mempolicy *mempolicy; short il_next; @@ -2285,6 +2287,13 @@ static inline void inc_syscw(struct task_struct *tsk) #define TASK_SIZE_OF(tsk) TASK_SIZE #endif +/* + * Call the function if the target task is executing on a CPU right now: + */ +extern void task_oncpu_function_call(struct task_struct *p, + void (*func) (void *info), void *info); + + #ifdef CONFIG_MM_OWNER extern void mm_update_next_owner(struct mm_struct *mm); extern void mm_init_owner(struct mm_struct *mm, struct task_struct *p); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 04fb47bfb920..6cce728a6263 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -624,4 +624,10 @@ asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); int kernel_execve(const char *filename, char *const argv[], char *const envp[]); +asmlinkage int +sys_perf_counter_open(u32 hw_event_type, + u32 hw_event_period, + u32 record_type, + pid_t pid, + int cpu); #endif diff --git a/init/Kconfig b/init/Kconfig index f763762d544a..78bede218f10 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -732,6 +732,35 @@ config AIO by some high performance threaded applications. Disabling this option saves about 7k. +config HAVE_PERF_COUNTERS + bool + +menu "Performance Counters" + +config PERF_COUNTERS + bool "Kernel Performance Counters" + depends on HAVE_PERF_COUNTERS + default y + help + Enable kernel support for performance counter hardware. + + Performance counters are special hardware registers available + on most modern CPUs. These registers count the number of certain + types of hw events: such as instructions executed, cachemisses + suffered, or branches mis-predicted - without slowing down the + kernel or applications. These registers can also trigger interrupts + when a threshold number of events have passed - and can thus be + used to profile the code that runs on that CPU. + + The Linux Performance Counter subsystem provides an abstraction of + these hardware capabilities, available via a system call. It + provides per task and per CPU counters, and it provides event + capabilities on top of those. + + Say Y if unsure. + +endmenu + config VM_EVENT_COUNTERS default y bool "Enable VM event counters for /proc/vmstat" if EMBEDDED diff --git a/kernel/Makefile b/kernel/Makefile index 19fad003b19d..1f184a1dc406 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -89,6 +89,7 @@ obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o obj-$(CONFIG_FUNCTION_TRACER) += trace/ obj-$(CONFIG_TRACING) += trace/ obj-$(CONFIG_SMP) += sched_cpupri.o +obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra , the -fno-omit-frame-pointer is diff --git a/kernel/fork.c b/kernel/fork.c index 2a372a0e206f..441fadff1fa4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -975,6 +975,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, goto fork_out; rt_mutex_init_task(p); + perf_counter_init_task(p); #ifdef CONFIG_PROVE_LOCKING DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled); diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c new file mode 100644 index 000000000000..20508f053658 --- /dev/null +++ b/kernel/perf_counter.c @@ -0,0 +1,943 @@ +/* + * Performance counter core code + * + * Copyright(C) 2008 Thomas Gleixner + * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar + * + * For licencing details see kernel-base/COPYING + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Each CPU has a list of per CPU counters: + */ +DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context); + +int perf_max_counters __read_mostly; +static int perf_reserved_percpu __read_mostly; +static int perf_overcommit __read_mostly = 1; + +/* + * Mutex for (sysadmin-configurable) counter reservations: + */ +static DEFINE_MUTEX(perf_resource_mutex); + +/* + * Architecture provided APIs - weak aliases: + */ + +int __weak hw_perf_counter_init(struct perf_counter *counter, u32 hw_event_type) +{ + return -EINVAL; +} + +void __weak hw_perf_counter_enable(struct perf_counter *counter) { } +void __weak hw_perf_counter_disable(struct perf_counter *counter) { } +void __weak hw_perf_counter_read(struct perf_counter *counter) { } +void __weak hw_perf_disable_all(void) { } +void __weak hw_perf_enable_all(void) { } +void __weak hw_perf_counter_setup(void) { } + +#if BITS_PER_LONG == 64 + +/* + * Read the cached counter in counter safe against cross CPU / NMI + * modifications. 64 bit version - no complications. + */ +static inline u64 perf_read_counter_safe(struct perf_counter *counter) +{ + return (u64) atomic64_read(&counter->count); +} + +#else + +/* + * Read the cached counter in counter safe against cross CPU / NMI + * modifications. 32 bit version. + */ +static u64 perf_read_counter_safe(struct perf_counter *counter) +{ + u32 cntl, cnth; + + local_irq_disable(); + do { + cnth = atomic_read(&counter->count32[1]); + cntl = atomic_read(&counter->count32[0]); + } while (cnth != atomic_read(&counter->count32[1])); + + local_irq_enable(); + + return cntl | ((u64) cnth) << 32; +} + +#endif + +/* + * Cross CPU call to remove a performance counter + * + * We disable the counter on the hardware level first. After that we + * remove it from the context list. + */ +static void __perf_remove_from_context(void *info) +{ + struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); + struct perf_counter *counter = info; + struct perf_counter_context *ctx = counter->ctx; + + /* + * If this is a task context, we need to check whether it is + * the current task context of this cpu. If not it has been + * scheduled out before the smp call arrived. + */ + if (ctx->task && cpuctx->task_ctx != ctx) + return; + + spin_lock(&ctx->lock); + + if (counter->active) { + hw_perf_counter_disable(counter); + counter->active = 0; + ctx->nr_active--; + cpuctx->active_oncpu--; + counter->task = NULL; + } + ctx->nr_counters--; + + /* + * Protect the list operation against NMI by disabling the + * counters on a global level. NOP for non NMI based counters. + */ + hw_perf_disable_all(); + list_del_init(&counter->list); + hw_perf_enable_all(); + + if (!ctx->task) { + /* + * Allow more per task counters with respect to the + * reservation: + */ + cpuctx->max_pertask = + min(perf_max_counters - ctx->nr_counters, + perf_max_counters - perf_reserved_percpu); + } + + spin_unlock(&ctx->lock); +} + + +/* + * Remove the counter from a task's (or a CPU's) list of counters. + * + * Must be called with counter->mutex held. + * + * CPU counters are removed with a smp call. For task counters we only + * call when the task is on a CPU. + */ +static void perf_remove_from_context(struct perf_counter *counter) +{ + struct perf_counter_context *ctx = counter->ctx; + struct task_struct *task = ctx->task; + + if (!task) { + /* + * Per cpu counters are removed via an smp call and + * the removal is always sucessful. + */ + smp_call_function_single(counter->cpu, + __perf_remove_from_context, + counter, 1); + return; + } + +retry: + task_oncpu_function_call(task, __perf_remove_from_context, + counter); + + spin_lock_irq(&ctx->lock); + /* + * If the context is active we need to retry the smp call. + */ + if (ctx->nr_active && !list_empty(&counter->list)) { + spin_unlock_irq(&ctx->lock); + goto retry; + } + + /* + * The lock prevents that this context is scheduled in so we + * can remove the counter safely, if it the call above did not + * succeed. + */ + if (!list_empty(&counter->list)) { + ctx->nr_counters--; + list_del_init(&counter->list); + counter->task = NULL; + } + spin_unlock_irq(&ctx->lock); +} + +/* + * Cross CPU call to install and enable a preformance counter + */ +static void __perf_install_in_context(void *info) +{ + struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); + struct perf_counter *counter = info; + struct perf_counter_context *ctx = counter->ctx; + int cpu = smp_processor_id(); + + /* + * If this is a task context, we need to check whether it is + * the current task context of this cpu. If not it has been + * scheduled out before the smp call arrived. + */ + if (ctx->task && cpuctx->task_ctx != ctx) + return; + + spin_lock(&ctx->lock); + + /* + * Protect the list operation against NMI by disabling the + * counters on a global level. NOP for non NMI based counters. + */ + hw_perf_disable_all(); + list_add_tail(&counter->list, &ctx->counters); + hw_perf_enable_all(); + + ctx->nr_counters++; + + if (cpuctx->active_oncpu < perf_max_counters) { + hw_perf_counter_enable(counter); + counter->active = 1; + counter->oncpu = cpu; + ctx->nr_active++; + cpuctx->active_oncpu++; + } + + if (!ctx->task && cpuctx->max_pertask) + cpuctx->max_pertask--; + + spin_unlock(&ctx->lock); +} + +/* + * Attach a performance counter to a context + * + * First we add the counter to the list with the hardware enable bit + * in counter->hw_config cleared. + * + * If the counter is attached to a task which is on a CPU we use a smp + * call to enable it in the task context. The task might have been + * scheduled away, but we check this in the smp call again. + */ +static void +perf_install_in_context(struct perf_counter_context *ctx, + struct perf_counter *counter, + int cpu) +{ + struct task_struct *task = ctx->task; + + counter->ctx = ctx; + if (!task) { + /* + * Per cpu counters are installed via an smp call and + * the install is always sucessful. + */ + smp_call_function_single(cpu, __perf_install_in_context, + counter, 1); + return; + } + + counter->task = task; +retry: + task_oncpu_function_call(task, __perf_install_in_context, + counter); + + spin_lock_irq(&ctx->lock); + /* + * If the context is active and the counter has not been added + * we need to retry the smp call. + */ + if (ctx->nr_active && list_empty(&counter->list)) { + spin_unlock_irq(&ctx->lock); + goto retry; + } + + /* + * The lock prevents that this context is scheduled in so we + * can add the counter safely, if it the call above did not + * succeed. + */ + if (list_empty(&counter->list)) { + list_add_tail(&counter->list, &ctx->counters); + ctx->nr_counters++; + } + spin_unlock_irq(&ctx->lock); +} + +/* + * Called from scheduler to remove the counters of the current task, + * with interrupts disabled. + * + * We stop each counter and update the counter value in counter->count. + * + * This does not protect us against NMI, but hw_perf_counter_disable() + * sets the disabled bit in the control field of counter _before_ + * accessing the counter control register. If a NMI hits, then it will + * not restart the counter. + */ +void perf_counter_task_sched_out(struct task_struct *task, int cpu) +{ + struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); + struct perf_counter_context *ctx = &task->perf_counter_ctx; + struct perf_counter *counter; + + if (likely(!cpuctx->task_ctx)) + return; + + spin_lock(&ctx->lock); + list_for_each_entry(counter, &ctx->counters, list) { + if (!ctx->nr_active) + break; + if (counter->active) { + hw_perf_counter_disable(counter); + counter->active = 0; + counter->oncpu = -1; + ctx->nr_active--; + cpuctx->active_oncpu--; + } + } + spin_unlock(&ctx->lock); + cpuctx->task_ctx = NULL; +} + +/* + * Called from scheduler to add the counters of the current task + * with interrupts disabled. + * + * We restore the counter value and then enable it. + * + * This does not protect us against NMI, but hw_perf_counter_enable() + * sets the enabled bit in the control field of counter _before_ + * accessing the counter control register. If a NMI hits, then it will + * keep the counter running. + */ +void perf_counter_task_sched_in(struct task_struct *task, int cpu) +{ + struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); + struct perf_counter_context *ctx = &task->perf_counter_ctx; + struct perf_counter *counter; + + if (likely(!ctx->nr_counters)) + return; + + spin_lock(&ctx->lock); + list_for_each_entry(counter, &ctx->counters, list) { + if (ctx->nr_active == cpuctx->max_pertask) + break; + if (counter->cpu != -1 && counter->cpu != cpu) + continue; + + hw_perf_counter_enable(counter); + counter->active = 1; + counter->oncpu = cpu; + ctx->nr_active++; + cpuctx->active_oncpu++; + } + spin_unlock(&ctx->lock); + cpuctx->task_ctx = ctx; +} + +void perf_counter_task_tick(struct task_struct *curr, int cpu) +{ + struct perf_counter_context *ctx = &curr->perf_counter_ctx; + struct perf_counter *counter; + + if (likely(!ctx->nr_counters)) + return; + + perf_counter_task_sched_out(curr, cpu); + + spin_lock(&ctx->lock); + + /* + * Rotate the first entry last: + */ + hw_perf_disable_all(); + list_for_each_entry(counter, &ctx->counters, list) { + list_del(&counter->list); + list_add_tail(&counter->list, &ctx->counters); + break; + } + hw_perf_enable_all(); + + spin_unlock(&ctx->lock); + + perf_counter_task_sched_in(curr, cpu); +} + +/* + * Initialize the perf_counter context in task_struct + */ +void perf_counter_init_task(struct task_struct *task) +{ + struct perf_counter_context *ctx = &task->perf_counter_ctx; + + spin_lock_init(&ctx->lock); + INIT_LIST_HEAD(&ctx->counters); + ctx->nr_counters = 0; + ctx->task = task; +} + +/* + * Cross CPU call to read the hardware counter + */ +static void __hw_perf_counter_read(void *info) +{ + hw_perf_counter_read(info); +} + +static u64 perf_read_counter(struct perf_counter *counter) +{ + /* + * If counter is enabled and currently active on a CPU, update the + * value in the counter structure: + */ + if (counter->active) { + smp_call_function_single(counter->oncpu, + __hw_perf_counter_read, counter, 1); + } + + return perf_read_counter_safe(counter); +} + +/* + * Cross CPU call to switch performance data pointers + */ +static void __perf_switch_irq_data(void *info) +{ + struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); + struct perf_counter *counter = info; + struct perf_counter_context *ctx = counter->ctx; + struct perf_data *oldirqdata = counter->irqdata; + + /* + * If this is a task context, we need to check whether it is + * the current task context of this cpu. If not it has been + * scheduled out before the smp call arrived. + */ + if (ctx->task) { + if (cpuctx->task_ctx != ctx) + return; + spin_lock(&ctx->lock); + } + + /* Change the pointer NMI safe */ + atomic_long_set((atomic_long_t *)&counter->irqdata, + (unsigned long) counter->usrdata); + counter->usrdata = oldirqdata; + + if (ctx->task) + spin_unlock(&ctx->lock); +} + +static struct perf_data *perf_switch_irq_data(struct perf_counter *counter) +{ + struct perf_counter_context *ctx = counter->ctx; + struct perf_data *oldirqdata = counter->irqdata; + struct task_struct *task = ctx->task; + + if (!task) { + smp_call_function_single(counter->cpu, + __perf_switch_irq_data, + counter, 1); + return counter->usrdata; + } + +retry: + spin_lock_irq(&ctx->lock); + if (!counter->active) { + counter->irqdata = counter->usrdata; + counter->usrdata = oldirqdata; + spin_unlock_irq(&ctx->lock); + return oldirqdata; + } + spin_unlock_irq(&ctx->lock); + task_oncpu_function_call(task, __perf_switch_irq_data, counter); + /* Might have failed, because task was scheduled out */ + if (counter->irqdata == oldirqdata) + goto retry; + + return counter->usrdata; +} + +static void put_context(struct perf_counter_context *ctx) +{ + if (ctx->task) + put_task_struct(ctx->task); +} + +static struct perf_counter_context *find_get_context(pid_t pid, int cpu) +{ + struct perf_cpu_context *cpuctx; + struct perf_counter_context *ctx; + struct task_struct *task; + + /* + * If cpu is not a wildcard then this is a percpu counter: + */ + if (cpu != -1) { + /* Must be root to operate on a CPU counter: */ + if (!capable(CAP_SYS_ADMIN)) + return ERR_PTR(-EACCES); + + if (cpu < 0 || cpu > num_possible_cpus()) + return ERR_PTR(-EINVAL); + + /* + * We could be clever and allow to attach a counter to an + * offline CPU and activate it when the CPU comes up, but + * that's for later. + */ + if (!cpu_isset(cpu, cpu_online_map)) + return ERR_PTR(-ENODEV); + + cpuctx = &per_cpu(perf_cpu_context, cpu); + ctx = &cpuctx->ctx; + + WARN_ON_ONCE(ctx->task); + return ctx; + } + + rcu_read_lock(); + if (!pid) + task = current; + else + task = find_task_by_vpid(pid); + if (task) + get_task_struct(task); + rcu_read_unlock(); + + if (!task) + return ERR_PTR(-ESRCH); + + ctx = &task->perf_counter_ctx; + ctx->task = task; + + /* Reuse ptrace permission checks for now. */ + if (!ptrace_may_access(task, PTRACE_MODE_READ)) { + put_context(ctx); + return ERR_PTR(-EACCES); + } + + return ctx; +} + +/* + * Called when the last reference to the file is gone. + */ +static int perf_release(struct inode *inode, struct file *file) +{ + struct perf_counter *counter = file->private_data; + struct perf_counter_context *ctx = counter->ctx; + + file->private_data = NULL; + + mutex_lock(&counter->mutex); + + perf_remove_from_context(counter); + put_context(ctx); + + mutex_unlock(&counter->mutex); + + kfree(counter); + + return 0; +} + +/* + * Read the performance counter - simple non blocking version for now + */ +static ssize_t +perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count) +{ + u64 cntval; + + if (count != sizeof(cntval)) + return -EINVAL; + + mutex_lock(&counter->mutex); + cntval = perf_read_counter(counter); + mutex_unlock(&counter->mutex); + + return put_user(cntval, (u64 __user *) buf) ? -EFAULT : sizeof(cntval); +} + +static ssize_t +perf_copy_usrdata(struct perf_data *usrdata, char __user *buf, size_t count) +{ + if (!usrdata->len) + return 0; + + count = min(count, (size_t)usrdata->len); + if (copy_to_user(buf, usrdata->data + usrdata->rd_idx, count)) + return -EFAULT; + + /* Adjust the counters */ + usrdata->len -= count; + if (!usrdata->len) + usrdata->rd_idx = 0; + else + usrdata->rd_idx += count; + + return count; +} + +static ssize_t +perf_read_irq_data(struct perf_counter *counter, + char __user *buf, + size_t count, + int nonblocking) +{ + struct perf_data *irqdata, *usrdata; + DECLARE_WAITQUEUE(wait, current); + ssize_t res; + + irqdata = counter->irqdata; + usrdata = counter->usrdata; + + if (usrdata->len + irqdata->len >= count) + goto read_pending; + + if (nonblocking) + return -EAGAIN; + + spin_lock_irq(&counter->waitq.lock); + __add_wait_queue(&counter->waitq, &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (usrdata->len + irqdata->len >= count) + break; + + if (signal_pending(current)) + break; + + spin_unlock_irq(&counter->waitq.lock); + schedule(); + spin_lock_irq(&counter->waitq.lock); + } + __remove_wait_queue(&counter->waitq, &wait); + __set_current_state(TASK_RUNNING); + spin_unlock_irq(&counter->waitq.lock); + + if (usrdata->len + irqdata->len < count) + return -ERESTARTSYS; +read_pending: + mutex_lock(&counter->mutex); + + /* Drain pending data first: */ + res = perf_copy_usrdata(usrdata, buf, count); + if (res < 0 || res == count) + goto out; + + /* Switch irq buffer: */ + usrdata = perf_switch_irq_data(counter); + if (perf_copy_usrdata(usrdata, buf + res, count - res) < 0) { + if (!res) + res = -EFAULT; + } else { + res = count; + } +out: + mutex_unlock(&counter->mutex); + + return res; +} + +static ssize_t +perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + struct perf_counter *counter = file->private_data; + + switch (counter->record_type) { + case PERF_RECORD_SIMPLE: + return perf_read_hw(counter, buf, count); + + case PERF_RECORD_IRQ: + case PERF_RECORD_GROUP: + return perf_read_irq_data(counter, buf, count, + file->f_flags & O_NONBLOCK); + } + return -EINVAL; +} + +static unsigned int perf_poll(struct file *file, poll_table *wait) +{ + struct perf_counter *counter = file->private_data; + unsigned int events = 0; + unsigned long flags; + + poll_wait(file, &counter->waitq, wait); + + spin_lock_irqsave(&counter->waitq.lock, flags); + if (counter->usrdata->len || counter->irqdata->len) + events |= POLLIN; + spin_unlock_irqrestore(&counter->waitq.lock, flags); + + return events; +} + +static const struct file_operations perf_fops = { + .release = perf_release, + .read = perf_read, + .poll = perf_poll, +}; + +/* + * Allocate and initialize a counter structure + */ +static struct perf_counter * +perf_counter_alloc(u32 hw_event_period, int cpu, u32 record_type) +{ + struct perf_counter *counter = kzalloc(sizeof(*counter), GFP_KERNEL); + + if (!counter) + return NULL; + + mutex_init(&counter->mutex); + INIT_LIST_HEAD(&counter->list); + init_waitqueue_head(&counter->waitq); + + counter->irqdata = &counter->data[0]; + counter->usrdata = &counter->data[1]; + counter->cpu = cpu; + counter->record_type = record_type; + counter->__irq_period = hw_event_period; + counter->wakeup_pending = 0; + + return counter; +} + +/** + * sys_perf_task_open - open a performance counter associate it to a task + * @hw_event_type: event type for monitoring/sampling... + * @pid: target pid + */ +asmlinkage int +sys_perf_counter_open(u32 hw_event_type, + u32 hw_event_period, + u32 record_type, + pid_t pid, + int cpu) +{ + struct perf_counter_context *ctx; + struct perf_counter *counter; + int ret; + + ctx = find_get_context(pid, cpu); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + ret = -ENOMEM; + counter = perf_counter_alloc(hw_event_period, cpu, record_type); + if (!counter) + goto err_put_context; + + ret = hw_perf_counter_init(counter, hw_event_type); + if (ret) + goto err_free_put_context; + + perf_install_in_context(ctx, counter, cpu); + + ret = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0); + if (ret < 0) + goto err_remove_free_put_context; + + return ret; + +err_remove_free_put_context: + mutex_lock(&counter->mutex); + perf_remove_from_context(counter); + mutex_unlock(&counter->mutex); + +err_free_put_context: + kfree(counter); + +err_put_context: + put_context(ctx); + + return ret; +} + +static void __cpuinit perf_init_cpu(int cpu) +{ + struct perf_cpu_context *ctx; + + ctx = &per_cpu(perf_cpu_context, cpu); + spin_lock_init(&ctx->ctx.lock); + INIT_LIST_HEAD(&ctx->ctx.counters); + + mutex_lock(&perf_resource_mutex); + ctx->max_pertask = perf_max_counters - perf_reserved_percpu; + mutex_unlock(&perf_resource_mutex); + hw_perf_counter_setup(); +} + +#ifdef CONFIG_HOTPLUG_CPU +static void __perf_exit_cpu(void *info) +{ + struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); + struct perf_counter_context *ctx = &cpuctx->ctx; + struct perf_counter *counter, *tmp; + + list_for_each_entry_safe(counter, tmp, &ctx->counters, list) + __perf_remove_from_context(counter); + +} +static void perf_exit_cpu(int cpu) +{ + smp_call_function_single(cpu, __perf_exit_cpu, NULL, 1); +} +#else +static inline void perf_exit_cpu(int cpu) { } +#endif + +static int __cpuinit +perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + switch (action) { + + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + perf_init_cpu(cpu); + break; + + case CPU_DOWN_PREPARE: + case CPU_DOWN_PREPARE_FROZEN: + perf_exit_cpu(cpu); + break; + + default: + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata perf_cpu_nb = { + .notifier_call = perf_cpu_notify, +}; + +static int __init perf_counter_init(void) +{ + perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE, + (void *)(long)smp_processor_id()); + register_cpu_notifier(&perf_cpu_nb); + + return 0; +} +early_initcall(perf_counter_init); + +static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, char *buf) +{ + return sprintf(buf, "%d\n", perf_reserved_percpu); +} + +static ssize_t +perf_set_reserve_percpu(struct sysdev_class *class, + const char *buf, + size_t count) +{ + struct perf_cpu_context *cpuctx; + unsigned long val; + int err, cpu, mpt; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; + if (val > perf_max_counters) + return -EINVAL; + + mutex_lock(&perf_resource_mutex); + perf_reserved_percpu = val; + for_each_online_cpu(cpu) { + cpuctx = &per_cpu(perf_cpu_context, cpu); + spin_lock_irq(&cpuctx->ctx.lock); + mpt = min(perf_max_counters - cpuctx->ctx.nr_counters, + perf_max_counters - perf_reserved_percpu); + cpuctx->max_pertask = mpt; + spin_unlock_irq(&cpuctx->ctx.lock); + } + mutex_unlock(&perf_resource_mutex); + + return count; +} + +static ssize_t perf_show_overcommit(struct sysdev_class *class, char *buf) +{ + return sprintf(buf, "%d\n", perf_overcommit); +} + +static ssize_t +perf_set_overcommit(struct sysdev_class *class, const char *buf, size_t count) +{ + unsigned long val; + int err; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; + if (val > 1) + return -EINVAL; + + mutex_lock(&perf_resource_mutex); + perf_overcommit = val; + mutex_unlock(&perf_resource_mutex); + + return count; +} + +static SYSDEV_CLASS_ATTR( + reserve_percpu, + 0644, + perf_show_reserve_percpu, + perf_set_reserve_percpu + ); + +static SYSDEV_CLASS_ATTR( + overcommit, + 0644, + perf_show_overcommit, + perf_set_overcommit + ); + +static struct attribute *perfclass_attrs[] = { + &attr_reserve_percpu.attr, + &attr_overcommit.attr, + NULL +}; + +static struct attribute_group perfclass_attr_group = { + .attrs = perfclass_attrs, + .name = "perf_counters", +}; + +static int __init perf_counter_sysfs_init(void) +{ + return sysfs_create_group(&cpu_sysdev_class.kset.kobj, + &perfclass_attr_group); +} +device_initcall(perf_counter_sysfs_init); + diff --git a/kernel/sched.c b/kernel/sched.c index b7480fb5c3dc..254d56de2548 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2212,6 +2212,27 @@ static int sched_balance_self(int cpu, int flag) #endif /* CONFIG_SMP */ +/** + * task_oncpu_function_call - call a function on the cpu on which a task runs + * @p: the task to evaluate + * @func: the function to be called + * @info: the function call argument + * + * Calls the function @func when the task is currently running. This might + * be on the current CPU, which just calls the function directly + */ +void task_oncpu_function_call(struct task_struct *p, + void (*func) (void *info), void *info) +{ + int cpu; + + preempt_disable(); + cpu = task_cpu(p); + if (task_curr(p)) + smp_call_function_single(cpu, func, info, 1); + preempt_enable(); +} + /*** * try_to_wake_up - wake up a thread * @p: the to-be-woken-up thread @@ -2534,6 +2555,7 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next) { fire_sched_out_preempt_notifiers(prev, next); + perf_counter_task_sched_out(prev, cpu_of(rq)); prepare_lock_switch(rq, next); prepare_arch_switch(next); } @@ -2574,6 +2596,7 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev) */ prev_state = prev->state; finish_arch_switch(prev); + perf_counter_task_sched_in(current, cpu_of(rq)); finish_lock_switch(rq, prev); #ifdef CONFIG_SMP if (current->sched_class->post_schedule) @@ -4296,6 +4319,7 @@ void scheduler_tick(void) rq->idle_at_tick = idle_cpu(cpu); trigger_load_balance(rq, cpu); #endif + perf_counter_task_tick(curr, cpu); } #if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \ diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index e14a23281707..4be8bbc7577c 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -174,3 +174,6 @@ cond_syscall(compat_sys_timerfd_settime); cond_syscall(compat_sys_timerfd_gettime); cond_syscall(sys_eventfd); cond_syscall(sys_eventfd2); + +/* performance counters: */ +cond_syscall(sys_perf_counter_open); -- GitLab From e7bc62b6b3aeaa8849f8383e0cfb7ca6c003adc6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 4 Dec 2008 20:13:45 +0100 Subject: [PATCH 0002/6080] performance counters: documentation Add more documentation about performance counters. Signed-off-by: Ingo Molnar --- Documentation/perf-counters.txt | 104 ++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 Documentation/perf-counters.txt diff --git a/Documentation/perf-counters.txt b/Documentation/perf-counters.txt new file mode 100644 index 000000000000..19033a0bb526 --- /dev/null +++ b/Documentation/perf-counters.txt @@ -0,0 +1,104 @@ + +Performance Counters for Linux +------------------------------ + +Performance counters are special hardware registers available on most modern +CPUs. These registers count the number of certain types of hw events: such +as instructions executed, cachemisses suffered, or branches mis-predicted - +without slowing down the kernel or applications. These registers can also +trigger interrupts when a threshold number of events have passed - and can +thus be used to profile the code that runs on that CPU. + +The Linux Performance Counter subsystem provides an abstraction of these +hardware capabilities. It provides per task and per CPU counters, and +it provides event capabilities on top of those. + +Performance counters are accessed via special file descriptors. +There's one file descriptor per virtual counter used. + +The special file descriptor is opened via the perf_counter_open() +system call: + + int + perf_counter_open(u32 hw_event_type, + u32 hw_event_period, + u32 record_type, + pid_t pid, + int cpu); + +The syscall returns the new fd. The fd can be used via the normal +VFS system calls: read() can be used to read the counter, fcntl() +can be used to set the blocking mode, etc. + +Multiple counters can be kept open at a time, and the counters +can be poll()ed. + +When creating a new counter fd, 'hw_event_type' is one of: + + enum hw_event_types { + PERF_COUNT_CYCLES, + PERF_COUNT_INSTRUCTIONS, + PERF_COUNT_CACHE_REFERENCES, + PERF_COUNT_CACHE_MISSES, + PERF_COUNT_BRANCH_INSTRUCTIONS, + PERF_COUNT_BRANCH_MISSES, + }; + +These are standardized types of events that work uniformly on all CPUs +that implements Performance Counters support under Linux. If a CPU is +not able to count branch-misses, then the system call will return +-EINVAL. + +[ Note: more hw_event_types are supported as well, but they are CPU + specific and are enumerated via /sys on a per CPU basis. Raw hw event + types can be passed in as negative numbers. For example, to count + "External bus cycles while bus lock signal asserted" events on Intel + Core CPUs, pass in a -0x4064 event type value. ] + +The parameter 'hw_event_period' is the number of events before waking up +a read() that is blocked on a counter fd. Zero value means a non-blocking +counter. + +'record_type' is the type of data that a read() will provide for the +counter, and it can be one of: + + enum perf_record_type { + PERF_RECORD_SIMPLE, + PERF_RECORD_IRQ, + }; + +a "simple" counter is one that counts hardware events and allows +them to be read out into a u64 count value. (read() returns 8 on +a successful read of a simple counter.) + +An "irq" counter is one that will also provide an IRQ context information: +the IP of the interrupted context. In this case read() will return +the 8-byte counter value, plus the Instruction Pointer address of the +interrupted context. + +The 'pid' parameter allows the counter to be specific to a task: + + pid == 0: if the pid parameter is zero, the counter is attached to the + current task. + + pid > 0: the counter is attached to a specific task (if the current task + has sufficient privilege to do so) + + pid < 0: all tasks are counted (per cpu counters) + +The 'cpu' parameter allows a counter to be made specific to a full +CPU: + + cpu >= 0: the counter is restricted to a specific CPU + cpu == -1: the counter counts on all CPUs + +Note: the combination of 'pid == -1' and 'cpu == -1' is not valid. + +A 'pid > 0' and 'cpu == -1' counter is a per task counter that counts +events of that task and 'follows' that task to whatever CPU the task +gets schedule to. Per task counters can be created by any user, for +their own tasks. + +A 'pid == -1' and 'cpu == x' counter is a per CPU counter that counts +all events on CPU-x. Per CPU counters need CAP_SYS_ADMIN privilege. + -- GitLab From 241771ef016b5c0c83cd7a4372a74321c973c1e6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 3 Dec 2008 10:39:53 +0100 Subject: [PATCH 0003/6080] performance counters: x86 support Implement performance counters for x86 Intel CPUs. It's simplified right now: the PERFMON CPU feature is assumed, which is available in Core2 and later Intel CPUs. The design is flexible to be extended to more CPU types as well. Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 1 + arch/x86/ia32/ia32entry.S | 3 +- arch/x86/include/asm/hardirq_32.h | 1 + arch/x86/include/asm/hw_irq.h | 2 + arch/x86/include/asm/intel_arch_perfmon.h | 34 +- arch/x86/include/asm/irq_vectors.h | 5 + .../x86/include/asm/mach-default/entry_arch.h | 5 + arch/x86/include/asm/pda.h | 1 + arch/x86/include/asm/thread_info.h | 4 +- arch/x86/include/asm/unistd_32.h | 1 + arch/x86/include/asm/unistd_64.h | 3 +- arch/x86/kernel/apic.c | 2 + arch/x86/kernel/cpu/Makefile | 12 +- arch/x86/kernel/cpu/common.c | 2 + arch/x86/kernel/cpu/perf_counter.c | 571 ++++++++++++++++++ arch/x86/kernel/entry_64.S | 5 + arch/x86/kernel/irq.c | 5 + arch/x86/kernel/irqinit_32.c | 3 + arch/x86/kernel/irqinit_64.c | 5 + arch/x86/kernel/signal.c | 7 +- arch/x86/kernel/syscall_table_32.S | 1 + 21 files changed, 652 insertions(+), 21 deletions(-) create mode 100644 arch/x86/kernel/cpu/perf_counter.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index d4d4cb7629ea..f2fdc1867241 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -643,6 +643,7 @@ config X86_UP_IOAPIC config X86_LOCAL_APIC def_bool y depends on X86_64 || (X86_32 && (X86_UP_APIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH)) + select HAVE_PERF_COUNTERS config X86_IO_APIC def_bool y diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S index 256b00b61892..3c14ed07dc4e 100644 --- a/arch/x86/ia32/ia32entry.S +++ b/arch/x86/ia32/ia32entry.S @@ -823,7 +823,8 @@ ia32_sys_call_table: .quad compat_sys_signalfd4 .quad sys_eventfd2 .quad sys_epoll_create1 - .quad sys_dup3 /* 330 */ + .quad sys_dup3 /* 330 */ .quad sys_pipe2 .quad sys_inotify_init1 + .quad sys_perf_counter_open ia32_syscall_end: diff --git a/arch/x86/include/asm/hardirq_32.h b/arch/x86/include/asm/hardirq_32.h index 5ca135e72f2b..b3e475dc9338 100644 --- a/arch/x86/include/asm/hardirq_32.h +++ b/arch/x86/include/asm/hardirq_32.h @@ -9,6 +9,7 @@ typedef struct { unsigned long idle_timestamp; unsigned int __nmi_count; /* arch dependent */ unsigned int apic_timer_irqs; /* arch dependent */ + unsigned int apic_perf_irqs; /* arch dependent */ unsigned int irq0_irqs; unsigned int irq_resched_count; unsigned int irq_call_count; diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 8de644b6b959..aa93e53b85ee 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -30,6 +30,8 @@ /* Interrupt handlers registered during init_IRQ */ extern void apic_timer_interrupt(void); extern void error_interrupt(void); +extern void perf_counter_interrupt(void); + extern void spurious_interrupt(void); extern void thermal_interrupt(void); extern void reschedule_interrupt(void); diff --git a/arch/x86/include/asm/intel_arch_perfmon.h b/arch/x86/include/asm/intel_arch_perfmon.h index fa0fd068bc2e..71598a9eab61 100644 --- a/arch/x86/include/asm/intel_arch_perfmon.h +++ b/arch/x86/include/asm/intel_arch_perfmon.h @@ -1,22 +1,24 @@ #ifndef _ASM_X86_INTEL_ARCH_PERFMON_H #define _ASM_X86_INTEL_ARCH_PERFMON_H -#define MSR_ARCH_PERFMON_PERFCTR0 0xc1 -#define MSR_ARCH_PERFMON_PERFCTR1 0xc2 +#define MSR_ARCH_PERFMON_PERFCTR0 0xc1 +#define MSR_ARCH_PERFMON_PERFCTR1 0xc2 -#define MSR_ARCH_PERFMON_EVENTSEL0 0x186 -#define MSR_ARCH_PERFMON_EVENTSEL1 0x187 +#define MSR_ARCH_PERFMON_EVENTSEL0 0x186 +#define MSR_ARCH_PERFMON_EVENTSEL1 0x187 -#define ARCH_PERFMON_EVENTSEL0_ENABLE (1 << 22) -#define ARCH_PERFMON_EVENTSEL_INT (1 << 20) -#define ARCH_PERFMON_EVENTSEL_OS (1 << 17) -#define ARCH_PERFMON_EVENTSEL_USR (1 << 16) +#define ARCH_PERFMON_EVENTSEL0_ENABLE (1 << 22) +#define ARCH_PERFMON_EVENTSEL_INT (1 << 20) +#define ARCH_PERFMON_EVENTSEL_OS (1 << 17) +#define ARCH_PERFMON_EVENTSEL_USR (1 << 16) -#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL (0x3c) -#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) -#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX (0) +#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c +#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) +#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX 0 #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \ - (1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX)) + (1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX)) + +#define ARCH_PERFMON_BRANCH_MISSES_RETIRED 6 union cpuid10_eax { struct { @@ -28,4 +30,12 @@ union cpuid10_eax { unsigned int full; }; +#ifdef CONFIG_PERF_COUNTERS +extern void init_hw_perf_counters(void); +extern void perf_counters_lapic_init(int nmi); +#else +static inline void init_hw_perf_counters(void) { } +static inline void perf_counters_lapic_init(int nmi) { } +#endif + #endif /* _ASM_X86_INTEL_ARCH_PERFMON_H */ diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index 0005adb0f941..b8d277f1252f 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -86,6 +86,11 @@ */ #define LOCAL_TIMER_VECTOR 0xef +/* + * Performance monitoring interrupt vector: + */ +#define LOCAL_PERF_VECTOR 0xee + /* * First APIC vector available to drivers: (vectors 0x30-0xee) we * start at 0x31(0x41) to spread out vectors evenly between priority diff --git a/arch/x86/include/asm/mach-default/entry_arch.h b/arch/x86/include/asm/mach-default/entry_arch.h index 6b1add8e31dd..ad31e5d90e90 100644 --- a/arch/x86/include/asm/mach-default/entry_arch.h +++ b/arch/x86/include/asm/mach-default/entry_arch.h @@ -25,10 +25,15 @@ BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) * a much simpler SMP time architecture: */ #ifdef CONFIG_X86_LOCAL_APIC + BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) +#ifdef CONFIG_PERF_COUNTERS +BUILD_INTERRUPT(perf_counter_interrupt, LOCAL_PERF_VECTOR) +#endif + #ifdef CONFIG_X86_MCE_P4THERMAL BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR) #endif diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 2fbfff88df37..90a8d9d4206b 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h @@ -30,6 +30,7 @@ struct x8664_pda { short isidle; struct mm_struct *active_mm; unsigned apic_timer_irqs; + unsigned apic_perf_irqs; unsigned irq0_irqs; unsigned irq_resched_count; unsigned irq_call_count; diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index e44d379faad2..810bf266d134 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -80,6 +80,7 @@ struct thread_info { #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SECCOMP 8 /* secure computing */ #define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */ +#define TIF_PERF_COUNTERS 11 /* notify perf counter work */ #define TIF_NOTSC 16 /* TSC is not accessible in userland */ #define TIF_IA32 17 /* 32bit process */ #define TIF_FORK 18 /* ret_from_fork */ @@ -103,6 +104,7 @@ struct thread_info { #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY) +#define _TIF_PERF_COUNTERS (1 << TIF_PERF_COUNTERS) #define _TIF_NOTSC (1 << TIF_NOTSC) #define _TIF_IA32 (1 << TIF_IA32) #define _TIF_FORK (1 << TIF_FORK) @@ -135,7 +137,7 @@ struct thread_info { /* Only used for 64 bit */ #define _TIF_DO_NOTIFY_MASK \ - (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_NOTIFY_RESUME) + (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_PERF_COUNTERS|_TIF_NOTIFY_RESUME) /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h index f2bba78430a4..7e47658b0a6f 100644 --- a/arch/x86/include/asm/unistd_32.h +++ b/arch/x86/include/asm/unistd_32.h @@ -338,6 +338,7 @@ #define __NR_dup3 330 #define __NR_pipe2 331 #define __NR_inotify_init1 332 +#define __NR_perf_counter_open 333 #ifdef __KERNEL__ diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h index d2e415e6666f..53025feaf88d 100644 --- a/arch/x86/include/asm/unistd_64.h +++ b/arch/x86/include/asm/unistd_64.h @@ -653,7 +653,8 @@ __SYSCALL(__NR_dup3, sys_dup3) __SYSCALL(__NR_pipe2, sys_pipe2) #define __NR_inotify_init1 294 __SYSCALL(__NR_inotify_init1, sys_inotify_init1) - +#define __NR_perf_counter_open 295 +__SYSCALL(__NR_perf_counter_open, sys_perf_counter_open) #ifndef __NO_STUBS #define __ARCH_WANT_OLD_READDIR diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 16f94879b525..8ab8c1858672 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -1147,6 +1148,7 @@ void __cpuinit setup_local_APIC(void) apic_write(APIC_ESR, 0); } #endif + perf_counters_lapic_init(0); preempt_disable(); diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 82ec6075c057..89e53361fe24 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -1,5 +1,5 @@ # -# Makefile for x86-compatible CPU details and quirks +# Makefile for x86-compatible CPU details, features and quirks # obj-y := intel_cacheinfo.o addon_cpuid_features.o @@ -16,11 +16,13 @@ obj-$(CONFIG_CPU_SUP_CENTAUR_64) += centaur_64.o obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o -obj-$(CONFIG_X86_MCE) += mcheck/ -obj-$(CONFIG_MTRR) += mtrr/ -obj-$(CONFIG_CPU_FREQ) += cpufreq/ +obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o -obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o +obj-$(CONFIG_X86_MCE) += mcheck/ +obj-$(CONFIG_MTRR) += mtrr/ +obj-$(CONFIG_CPU_FREQ) += cpufreq/ + +obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o quiet_cmd_mkcapflags = MKCAP $@ cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index b9c9ea0217a9..4461011db47c 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -750,6 +751,7 @@ void __init identify_boot_cpu(void) #else vgetcpu_set_mode(); #endif + init_hw_perf_counters(); } void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c new file mode 100644 index 000000000000..82440cbed0e6 --- /dev/null +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -0,0 +1,571 @@ +/* + * Performance counter x86 architecture code + * + * Copyright(C) 2008 Thomas Gleixner + * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar + * + * For licencing details see kernel-base/COPYING + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static bool perf_counters_initialized __read_mostly; + +/* + * Number of (generic) HW counters: + */ +static int nr_hw_counters __read_mostly; +static u32 perf_counter_mask __read_mostly; + +/* No support for fixed function counters yet */ + +#define MAX_HW_COUNTERS 8 + +struct cpu_hw_counters { + struct perf_counter *counters[MAX_HW_COUNTERS]; + unsigned long used[BITS_TO_LONGS(MAX_HW_COUNTERS)]; + int enable_all; +}; + +/* + * Intel PerfMon v3. Used on Core2 and later. + */ +static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters); + +const int intel_perfmon_event_map[] = +{ + [PERF_COUNT_CYCLES] = 0x003c, + [PERF_COUNT_INSTRUCTIONS] = 0x00c0, + [PERF_COUNT_CACHE_REFERENCES] = 0x4f2e, + [PERF_COUNT_CACHE_MISSES] = 0x412e, + [PERF_COUNT_BRANCH_INSTRUCTIONS] = 0x00c4, + [PERF_COUNT_BRANCH_MISSES] = 0x00c5, +}; + +const int max_intel_perfmon_events = ARRAY_SIZE(intel_perfmon_event_map); + +/* + * Setup the hardware configuration for a given hw_event_type + */ +int hw_perf_counter_init(struct perf_counter *counter, s32 hw_event_type) +{ + struct hw_perf_counter *hwc = &counter->hw; + + if (unlikely(!perf_counters_initialized)) + return -EINVAL; + + /* + * Count user events, and generate PMC IRQs: + * (keep 'enabled' bit clear for now) + */ + hwc->config = ARCH_PERFMON_EVENTSEL_USR | ARCH_PERFMON_EVENTSEL_INT; + + /* + * If privileged enough, count OS events too, and allow + * NMI events as well: + */ + hwc->nmi = 0; + if (capable(CAP_SYS_ADMIN)) { + hwc->config |= ARCH_PERFMON_EVENTSEL_OS; + if (hw_event_type & PERF_COUNT_NMI) + hwc->nmi = 1; + } + + hwc->config_base = MSR_ARCH_PERFMON_EVENTSEL0; + hwc->counter_base = MSR_ARCH_PERFMON_PERFCTR0; + + hwc->irq_period = counter->__irq_period; + /* + * Intel PMCs cannot be accessed sanely above 32 bit width, + * so we install an artificial 1<<31 period regardless of + * the generic counter period: + */ + if (!hwc->irq_period) + hwc->irq_period = 0x7FFFFFFF; + + hwc->next_count = -((s32) hwc->irq_period); + + /* + * Negative event types mean raw encoded event+umask values: + */ + if (hw_event_type < 0) { + counter->hw_event_type = -hw_event_type; + counter->hw_event_type &= ~PERF_COUNT_NMI; + } else { + hw_event_type &= ~PERF_COUNT_NMI; + if (hw_event_type >= max_intel_perfmon_events) + return -EINVAL; + /* + * The generic map: + */ + counter->hw_event_type = intel_perfmon_event_map[hw_event_type]; + } + hwc->config |= counter->hw_event_type; + counter->wakeup_pending = 0; + + return 0; +} + +static void __hw_perf_enable_all(void) +{ + wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask, 0); +} + +void hw_perf_enable_all(void) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + + cpuc->enable_all = 1; + __hw_perf_enable_all(); +} + +void hw_perf_disable_all(void) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + + cpuc->enable_all = 0; + wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); +} + +static DEFINE_PER_CPU(u64, prev_next_count[MAX_HW_COUNTERS]); + +static void __hw_perf_counter_enable(struct hw_perf_counter *hwc, int idx) +{ + per_cpu(prev_next_count[idx], smp_processor_id()) = hwc->next_count; + + wrmsr(hwc->counter_base + idx, hwc->next_count, 0); + wrmsr(hwc->config_base + idx, hwc->config, 0); +} + +void hw_perf_counter_enable(struct perf_counter *counter) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + struct hw_perf_counter *hwc = &counter->hw; + int idx = hwc->idx; + + /* Try to get the previous counter again */ + if (test_and_set_bit(idx, cpuc->used)) { + idx = find_first_zero_bit(cpuc->used, nr_hw_counters); + set_bit(idx, cpuc->used); + hwc->idx = idx; + } + + perf_counters_lapic_init(hwc->nmi); + + wrmsr(hwc->config_base + idx, + hwc->config & ~ARCH_PERFMON_EVENTSEL0_ENABLE, 0); + + cpuc->counters[idx] = counter; + counter->hw.config |= ARCH_PERFMON_EVENTSEL0_ENABLE; + __hw_perf_counter_enable(hwc, idx); +} + +#ifdef CONFIG_X86_64 +static inline void atomic64_counter_set(struct perf_counter *counter, u64 val) +{ + atomic64_set(&counter->count, val); +} + +static inline u64 atomic64_counter_read(struct perf_counter *counter) +{ + return atomic64_read(&counter->count); +} +#else +/* + * Todo: add proper atomic64_t support to 32-bit x86: + */ +static inline void atomic64_counter_set(struct perf_counter *counter, u64 val64) +{ + u32 *val32 = (void *)&val64; + + atomic_set(counter->count32 + 0, *(val32 + 0)); + atomic_set(counter->count32 + 1, *(val32 + 1)); +} + +static inline u64 atomic64_counter_read(struct perf_counter *counter) +{ + return atomic_read(counter->count32 + 0) | + (u64) atomic_read(counter->count32 + 1) << 32; +} +#endif + +static void __hw_perf_save_counter(struct perf_counter *counter, + struct hw_perf_counter *hwc, int idx) +{ + s64 raw = -1; + s64 delta; + int err; + + /* + * Get the raw hw counter value: + */ + err = rdmsrl_safe(hwc->counter_base + idx, &raw); + WARN_ON_ONCE(err); + + /* + * Rebase it to zero (it started counting at -irq_period), + * to see the delta since ->prev_count: + */ + delta = (s64)hwc->irq_period + (s64)(s32)raw; + + atomic64_counter_set(counter, hwc->prev_count + delta); + + /* + * Adjust the ->prev_count offset - if we went beyond + * irq_period of units, then we got an IRQ and the counter + * was set back to -irq_period: + */ + while (delta >= (s64)hwc->irq_period) { + hwc->prev_count += hwc->irq_period; + delta -= (s64)hwc->irq_period; + } + + /* + * Calculate the next raw counter value we'll write into + * the counter at the next sched-in time: + */ + delta -= (s64)hwc->irq_period; + + hwc->next_count = (s32)delta; +} + +void perf_counter_print_debug(void) +{ + u64 ctrl, status, overflow, pmc_ctrl, pmc_count, next_count; + int cpu, err, idx; + + local_irq_disable(); + + cpu = smp_processor_id(); + + err = rdmsrl_safe(MSR_CORE_PERF_GLOBAL_CTRL, &ctrl); + WARN_ON_ONCE(err); + + err = rdmsrl_safe(MSR_CORE_PERF_GLOBAL_STATUS, &status); + WARN_ON_ONCE(err); + + err = rdmsrl_safe(MSR_CORE_PERF_GLOBAL_OVF_CTRL, &overflow); + WARN_ON_ONCE(err); + + printk(KERN_INFO "\n"); + printk(KERN_INFO "CPU#%d: ctrl: %016llx\n", cpu, ctrl); + printk(KERN_INFO "CPU#%d: status: %016llx\n", cpu, status); + printk(KERN_INFO "CPU#%d: overflow: %016llx\n", cpu, overflow); + + for (idx = 0; idx < nr_hw_counters; idx++) { + err = rdmsrl_safe(MSR_ARCH_PERFMON_EVENTSEL0 + idx, &pmc_ctrl); + WARN_ON_ONCE(err); + + err = rdmsrl_safe(MSR_ARCH_PERFMON_PERFCTR0 + idx, &pmc_count); + WARN_ON_ONCE(err); + + next_count = per_cpu(prev_next_count[idx], cpu); + + printk(KERN_INFO "CPU#%d: PMC%d ctrl: %016llx\n", + cpu, idx, pmc_ctrl); + printk(KERN_INFO "CPU#%d: PMC%d count: %016llx\n", + cpu, idx, pmc_count); + printk(KERN_INFO "CPU#%d: PMC%d next: %016llx\n", + cpu, idx, next_count); + } + local_irq_enable(); +} + +void hw_perf_counter_disable(struct perf_counter *counter) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + struct hw_perf_counter *hwc = &counter->hw; + unsigned int idx = hwc->idx; + + counter->hw.config &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsr(hwc->config_base + idx, hwc->config, 0); + + clear_bit(idx, cpuc->used); + cpuc->counters[idx] = NULL; + __hw_perf_save_counter(counter, hwc, idx); +} + +void hw_perf_counter_read(struct perf_counter *counter) +{ + struct hw_perf_counter *hwc = &counter->hw; + unsigned long addr = hwc->counter_base + hwc->idx; + s64 offs, val = -1LL; + s32 val32; + int err; + + /* Careful: NMI might modify the counter offset */ + do { + offs = hwc->prev_count; + err = rdmsrl_safe(addr, &val); + WARN_ON_ONCE(err); + } while (offs != hwc->prev_count); + + val32 = (s32) val; + val = (s64)hwc->irq_period + (s64)val32; + atomic64_counter_set(counter, hwc->prev_count + val); +} + +static void perf_store_irq_data(struct perf_counter *counter, u64 data) +{ + struct perf_data *irqdata = counter->irqdata; + + if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) { + irqdata->overrun++; + } else { + u64 *p = (u64 *) &irqdata->data[irqdata->len]; + + *p = data; + irqdata->len += sizeof(u64); + } +} + +static void perf_save_and_restart(struct perf_counter *counter) +{ + struct hw_perf_counter *hwc = &counter->hw; + int idx = hwc->idx; + + wrmsr(hwc->config_base + idx, + hwc->config & ~ARCH_PERFMON_EVENTSEL0_ENABLE, 0); + + if (hwc->config & ARCH_PERFMON_EVENTSEL0_ENABLE) { + __hw_perf_save_counter(counter, hwc, idx); + __hw_perf_counter_enable(hwc, idx); + } +} + +static void +perf_handle_group(struct perf_counter *leader, u64 *status, u64 *overflown) +{ + struct perf_counter_context *ctx = leader->ctx; + struct perf_counter *counter; + int bit; + + list_for_each_entry(counter, &ctx->counters, list) { + if (counter->record_type != PERF_RECORD_SIMPLE || + counter == leader) + continue; + + if (counter->active) { + /* + * When counter was not in the overflow mask, we have to + * read it from hardware. We read it as well, when it + * has not been read yet and clear the bit in the + * status mask. + */ + bit = counter->hw.idx; + if (!test_bit(bit, (unsigned long *) overflown) || + test_bit(bit, (unsigned long *) status)) { + clear_bit(bit, (unsigned long *) status); + perf_save_and_restart(counter); + } + } + perf_store_irq_data(leader, counter->hw_event_type); + perf_store_irq_data(leader, atomic64_counter_read(counter)); + } +} + +/* + * This handler is triggered by the local APIC, so the APIC IRQ handling + * rules apply: + */ +static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) +{ + int bit, cpu = smp_processor_id(); + struct cpu_hw_counters *cpuc; + u64 ack, status; + + rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); + if (!status) { + ack_APIC_irq(); + return; + } + + /* Disable counters globally */ + wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); + ack_APIC_irq(); + + cpuc = &per_cpu(cpu_hw_counters, cpu); + +again: + ack = status; + for_each_bit(bit, (unsigned long *) &status, nr_hw_counters) { + struct perf_counter *counter = cpuc->counters[bit]; + + clear_bit(bit, (unsigned long *) &status); + if (!counter) + continue; + + perf_save_and_restart(counter); + + switch (counter->record_type) { + case PERF_RECORD_SIMPLE: + continue; + case PERF_RECORD_IRQ: + perf_store_irq_data(counter, instruction_pointer(regs)); + break; + case PERF_RECORD_GROUP: + perf_store_irq_data(counter, counter->hw_event_type); + perf_store_irq_data(counter, + atomic64_counter_read(counter)); + perf_handle_group(counter, &status, &ack); + break; + } + /* + * From NMI context we cannot call into the scheduler to + * do a task wakeup - but we mark these counters as + * wakeup_pending and initate a wakeup callback: + */ + if (nmi) { + counter->wakeup_pending = 1; + set_tsk_thread_flag(current, TIF_PERF_COUNTERS); + } else { + wake_up(&counter->waitq); + } + } + + wrmsr(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack, 0); + + /* + * Repeat if there is more work to be done: + */ + rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); + if (status) + goto again; + + /* + * Do not reenable when global enable is off: + */ + if (cpuc->enable_all) + __hw_perf_enable_all(); +} + +void smp_perf_counter_interrupt(struct pt_regs *regs) +{ + irq_enter(); +#ifdef CONFIG_X86_64 + add_pda(apic_perf_irqs, 1); +#else + per_cpu(irq_stat, smp_processor_id()).apic_perf_irqs++; +#endif + apic_write(APIC_LVTPC, LOCAL_PERF_VECTOR); + __smp_perf_counter_interrupt(regs, 0); + + irq_exit(); +} + +/* + * This handler is triggered by NMI contexts: + */ +void perf_counter_notify(struct pt_regs *regs) +{ + struct cpu_hw_counters *cpuc; + unsigned long flags; + int bit, cpu; + + local_irq_save(flags); + cpu = smp_processor_id(); + cpuc = &per_cpu(cpu_hw_counters, cpu); + + for_each_bit(bit, cpuc->used, nr_hw_counters) { + struct perf_counter *counter = cpuc->counters[bit]; + + if (!counter) + continue; + + if (counter->wakeup_pending) { + counter->wakeup_pending = 0; + wake_up(&counter->waitq); + } + } + + local_irq_restore(flags); +} + +void __cpuinit perf_counters_lapic_init(int nmi) +{ + u32 apic_val; + + if (!perf_counters_initialized) + return; + /* + * Enable the performance counter vector in the APIC LVT: + */ + apic_val = apic_read(APIC_LVTERR); + + apic_write(APIC_LVTERR, apic_val | APIC_LVT_MASKED); + if (nmi) + apic_write(APIC_LVTPC, APIC_DM_NMI); + else + apic_write(APIC_LVTPC, LOCAL_PERF_VECTOR); + apic_write(APIC_LVTERR, apic_val); +} + +static int __kprobes +perf_counter_nmi_handler(struct notifier_block *self, + unsigned long cmd, void *__args) +{ + struct die_args *args = __args; + struct pt_regs *regs; + + if (likely(cmd != DIE_NMI_IPI)) + return NOTIFY_DONE; + + regs = args->regs; + + apic_write(APIC_LVTPC, APIC_DM_NMI); + __smp_perf_counter_interrupt(regs, 1); + + return NOTIFY_STOP; +} + +static __read_mostly struct notifier_block perf_counter_nmi_notifier = { + .notifier_call = perf_counter_nmi_handler +}; + +void __init init_hw_perf_counters(void) +{ + union cpuid10_eax eax; + unsigned int unused; + unsigned int ebx; + + if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return; + + /* + * Check whether the Architectural PerfMon supports + * Branch Misses Retired Event or not. + */ + cpuid(10, &(eax.full), &ebx, &unused, &unused); + if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED) + return; + + printk(KERN_INFO "Intel Performance Monitoring support detected.\n"); + + printk(KERN_INFO "... version: %d\n", eax.split.version_id); + printk(KERN_INFO "... num_counters: %d\n", eax.split.num_counters); + nr_hw_counters = eax.split.num_counters; + if (nr_hw_counters > MAX_HW_COUNTERS) { + nr_hw_counters = MAX_HW_COUNTERS; + WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", + nr_hw_counters, MAX_HW_COUNTERS); + } + perf_counter_mask = (1 << nr_hw_counters) - 1; + perf_max_counters = nr_hw_counters; + + printk(KERN_INFO "... bit_width: %d\n", eax.split.bit_width); + printk(KERN_INFO "... mask_length: %d\n", eax.split.mask_length); + + perf_counters_lapic_init(0); + register_die_notifier(&perf_counter_nmi_notifier); + + perf_counters_initialized = true; +} diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 3194636a4293..fc013cfde307 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -984,6 +984,11 @@ apicinterrupt ERROR_APIC_VECTOR \ apicinterrupt SPURIOUS_APIC_VECTOR \ spurious_interrupt smp_spurious_interrupt +#ifdef CONFIG_PERF_COUNTERS +apicinterrupt LOCAL_PERF_VECTOR \ + perf_counter_interrupt smp_perf_counter_interrupt +#endif + /* * Exception entry points. */ diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index d1d4dc52f649..d92bc71e41a7 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -56,6 +56,10 @@ static int show_other_interrupts(struct seq_file *p) for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs); seq_printf(p, " Local timer interrupts\n"); + seq_printf(p, "CNT: "); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs); + seq_printf(p, " Performance counter interrupts\n"); #endif #ifdef CONFIG_SMP seq_printf(p, "RES: "); @@ -160,6 +164,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu) #ifdef CONFIG_X86_LOCAL_APIC sum += irq_stats(cpu)->apic_timer_irqs; + sum += irq_stats(cpu)->apic_perf_irqs; #endif #ifdef CONFIG_SMP sum += irq_stats(cpu)->irq_resched_count; diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index 607db63044a5..6a33b5e30161 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c @@ -160,6 +160,9 @@ void __init native_init_IRQ(void) /* IPI vectors for APIC spurious and error interrupts */ alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); +# ifdef CONFIG_PERF_COUNTERS + alloc_intr_gate(LOCAL_PERF_VECTOR, perf_counter_interrupt); +# endif #endif #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_MCE_P4THERMAL) diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c index 8670b3ce626e..91d785c25ad9 100644 --- a/arch/x86/kernel/irqinit_64.c +++ b/arch/x86/kernel/irqinit_64.c @@ -138,6 +138,11 @@ static void __init apic_intr_init(void) /* IPI vectors for APIC spurious and error interrupts */ alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); + + /* Performance monitoring interrupt: */ +#ifdef CONFIG_PERF_COUNTERS + alloc_intr_gate(LOCAL_PERF_VECTOR, perf_counter_interrupt); +#endif } void __init native_init_IRQ(void) diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index b1cc6da64208..dee553c503d3 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -6,7 +6,7 @@ * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-2002 x86-64 support by Andi Kleen */ - +#include #include #include #include @@ -891,6 +891,11 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) tracehook_notify_resume(regs); } + if (thread_info_flags & _TIF_PERF_COUNTERS) { + clear_thread_flag(TIF_PERF_COUNTERS); + perf_counter_notify(regs); + } + #ifdef CONFIG_X86_32 clear_thread_flag(TIF_IRET); #endif /* CONFIG_X86_32 */ diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S index d44395ff34c3..496726ddcea1 100644 --- a/arch/x86/kernel/syscall_table_32.S +++ b/arch/x86/kernel/syscall_table_32.S @@ -332,3 +332,4 @@ ENTRY(sys_call_table) .long sys_dup3 /* 330 */ .long sys_pipe2 .long sys_inotify_init1 + .long sys_perf_counter_open -- GitLab From 87b9cf4623ad4e5fc009e48c020593dffd5d3793 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 8 Dec 2008 14:20:16 +0100 Subject: [PATCH 0004/6080] x86, perfcounters: read out MSR_CORE_PERF_GLOBAL_STATUS with counters disabled Impact: make perfcounter NMI and IRQ sequence more robust Make __smp_perf_counter_interrupt() a bit more conservative: first disable all counters, then read out the status. Most invocations are because there are real events, so there's no performance impact. Code flow gets a bit simpler as well this way. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 82440cbed0e6..615e953208ef 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -383,18 +383,16 @@ static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) struct cpu_hw_counters *cpuc; u64 ack, status; - rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); - if (!status) { - ack_APIC_irq(); - return; - } - /* Disable counters globally */ wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); ack_APIC_irq(); cpuc = &per_cpu(cpu_hw_counters, cpu); + rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); + if (!status) + goto out; + again: ack = status; for_each_bit(bit, (unsigned long *) &status, nr_hw_counters) { @@ -440,7 +438,7 @@ again: rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); if (status) goto again; - +out: /* * Do not reenable when global enable is off: */ -- GitLab From 4c59e4676dc95f6f58a2cff5390b2699fa5b5549 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 8 Dec 2008 19:38:33 +0100 Subject: [PATCH 0005/6080] perfcounters: select ANON_INODES The perfcounters subsystem depends on CONFIG_ANON_INODES facilities, so make sure it's selected. Signed-off-by: Ingo Molnar --- init/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/init/Kconfig b/init/Kconfig index 78bede218f10..7d147a36e968 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -741,6 +741,7 @@ config PERF_COUNTERS bool "Kernel Performance Counters" depends on HAVE_PERF_COUNTERS default y + select ANON_INODES help Enable kernel support for performance counter hardware. -- GitLab From 7e2ae34749edf19e76e594b9c4b2cdde1066afc5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 9 Dec 2008 11:40:46 +0100 Subject: [PATCH 0006/6080] perfcounters, x86: simplify disable/enable of counters Impact: fix spurious missed counter wakeups In the case of NMI events, close a race window that can occur if an NMI hits counter code that temporarily disables+enables a counter, and the NMI leaks into the disabled section. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 40 +++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 615e953208ef..7d528ffc2d26 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -136,14 +136,25 @@ void hw_perf_disable_all(void) wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); } +static inline void +__hw_perf_counter_disable(struct hw_perf_counter *hwc, unsigned int idx) +{ + wrmsr(hwc->config_base + idx, hwc->config, 0); +} + static DEFINE_PER_CPU(u64, prev_next_count[MAX_HW_COUNTERS]); -static void __hw_perf_counter_enable(struct hw_perf_counter *hwc, int idx) +static void __hw_perf_counter_set_period(struct hw_perf_counter *hwc, int idx) { per_cpu(prev_next_count[idx], smp_processor_id()) = hwc->next_count; wrmsr(hwc->counter_base + idx, hwc->next_count, 0); - wrmsr(hwc->config_base + idx, hwc->config, 0); +} + +static void __hw_perf_counter_enable(struct hw_perf_counter *hwc, int idx) +{ + wrmsr(hwc->config_base + idx, + hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0); } void hw_perf_counter_enable(struct perf_counter *counter) @@ -161,11 +172,11 @@ void hw_perf_counter_enable(struct perf_counter *counter) perf_counters_lapic_init(hwc->nmi); - wrmsr(hwc->config_base + idx, - hwc->config & ~ARCH_PERFMON_EVENTSEL0_ENABLE, 0); + __hw_perf_counter_disable(hwc, idx); cpuc->counters[idx] = counter; - counter->hw.config |= ARCH_PERFMON_EVENTSEL0_ENABLE; + + __hw_perf_counter_set_period(hwc, idx); __hw_perf_counter_enable(hwc, idx); } @@ -286,8 +297,7 @@ void hw_perf_counter_disable(struct perf_counter *counter) struct hw_perf_counter *hwc = &counter->hw; unsigned int idx = hwc->idx; - counter->hw.config &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(hwc->config_base + idx, hwc->config, 0); + __hw_perf_counter_disable(hwc, idx); clear_bit(idx, cpuc->used); cpuc->counters[idx] = NULL; @@ -328,18 +338,24 @@ static void perf_store_irq_data(struct perf_counter *counter, u64 data) } } +/* + * NMI-safe enable method: + */ static void perf_save_and_restart(struct perf_counter *counter) { struct hw_perf_counter *hwc = &counter->hw; int idx = hwc->idx; + u64 pmc_ctrl; + int err; - wrmsr(hwc->config_base + idx, - hwc->config & ~ARCH_PERFMON_EVENTSEL0_ENABLE, 0); + err = rdmsrl_safe(MSR_ARCH_PERFMON_EVENTSEL0 + idx, &pmc_ctrl); + WARN_ON_ONCE(err); - if (hwc->config & ARCH_PERFMON_EVENTSEL0_ENABLE) { - __hw_perf_save_counter(counter, hwc, idx); + __hw_perf_save_counter(counter, hwc, idx); + __hw_perf_counter_set_period(hwc, idx); + + if (pmc_ctrl & ARCH_PERFMON_EVENTSEL0_ENABLE) __hw_perf_counter_enable(hwc, idx); - } } static void -- GitLab From 1e12567678054bc1d4c944ecfad17624b3e49345 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 9 Dec 2008 12:18:18 +0100 Subject: [PATCH 0007/6080] perfcounters, x86: clean up debug code Impact: cleanup Get rid of unused debug code. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 35 ++++++++++-------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 7d528ffc2d26..919ec46679b2 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -214,13 +214,11 @@ static void __hw_perf_save_counter(struct perf_counter *counter, { s64 raw = -1; s64 delta; - int err; /* * Get the raw hw counter value: */ - err = rdmsrl_safe(hwc->counter_base + idx, &raw); - WARN_ON_ONCE(err); + rdmsrl(hwc->counter_base + idx, raw); /* * Rebase it to zero (it started counting at -irq_period), @@ -252,20 +250,18 @@ static void __hw_perf_save_counter(struct perf_counter *counter, void perf_counter_print_debug(void) { u64 ctrl, status, overflow, pmc_ctrl, pmc_count, next_count; - int cpu, err, idx; + int cpu, idx; + + if (!nr_hw_counters) + return; local_irq_disable(); cpu = smp_processor_id(); - err = rdmsrl_safe(MSR_CORE_PERF_GLOBAL_CTRL, &ctrl); - WARN_ON_ONCE(err); - - err = rdmsrl_safe(MSR_CORE_PERF_GLOBAL_STATUS, &status); - WARN_ON_ONCE(err); - - err = rdmsrl_safe(MSR_CORE_PERF_GLOBAL_OVF_CTRL, &overflow); - WARN_ON_ONCE(err); + rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); + rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); + rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow); printk(KERN_INFO "\n"); printk(KERN_INFO "CPU#%d: ctrl: %016llx\n", cpu, ctrl); @@ -273,11 +269,8 @@ void perf_counter_print_debug(void) printk(KERN_INFO "CPU#%d: overflow: %016llx\n", cpu, overflow); for (idx = 0; idx < nr_hw_counters; idx++) { - err = rdmsrl_safe(MSR_ARCH_PERFMON_EVENTSEL0 + idx, &pmc_ctrl); - WARN_ON_ONCE(err); - - err = rdmsrl_safe(MSR_ARCH_PERFMON_PERFCTR0 + idx, &pmc_count); - WARN_ON_ONCE(err); + rdmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, pmc_ctrl); + rdmsrl(MSR_ARCH_PERFMON_PERFCTR0 + idx, pmc_count); next_count = per_cpu(prev_next_count[idx], cpu); @@ -310,13 +303,11 @@ void hw_perf_counter_read(struct perf_counter *counter) unsigned long addr = hwc->counter_base + hwc->idx; s64 offs, val = -1LL; s32 val32; - int err; /* Careful: NMI might modify the counter offset */ do { offs = hwc->prev_count; - err = rdmsrl_safe(addr, &val); - WARN_ON_ONCE(err); + rdmsrl(addr, val); } while (offs != hwc->prev_count); val32 = (s32) val; @@ -346,10 +337,8 @@ static void perf_save_and_restart(struct perf_counter *counter) struct hw_perf_counter *hwc = &counter->hw; int idx = hwc->idx; u64 pmc_ctrl; - int err; - err = rdmsrl_safe(MSR_ARCH_PERFMON_EVENTSEL0 + idx, &pmc_ctrl); - WARN_ON_ONCE(err); + rdmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, pmc_ctrl); __hw_perf_save_counter(counter, hwc, idx); __hw_perf_counter_set_period(hwc, idx); -- GitLab From 43874d238d5f208854a73c3225ca2a22833eec8b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 9 Dec 2008 12:23:59 +0100 Subject: [PATCH 0008/6080] perfcounters: consolidate global-disable codepaths Impact: cleanup Simplify global disable handling. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 919ec46679b2..6a93d1f04d97 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -33,7 +33,6 @@ static u32 perf_counter_mask __read_mostly; struct cpu_hw_counters { struct perf_counter *counters[MAX_HW_COUNTERS]; unsigned long used[BITS_TO_LONGS(MAX_HW_COUNTERS)]; - int enable_all; }; /* @@ -115,24 +114,13 @@ int hw_perf_counter_init(struct perf_counter *counter, s32 hw_event_type) return 0; } -static void __hw_perf_enable_all(void) -{ - wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask, 0); -} - void hw_perf_enable_all(void) { - struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); - - cpuc->enable_all = 1; - __hw_perf_enable_all(); + wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask, 0); } void hw_perf_disable_all(void) { - struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); - - cpuc->enable_all = 0; wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); } @@ -385,8 +373,10 @@ perf_handle_group(struct perf_counter *leader, u64 *status, u64 *overflown) static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) { int bit, cpu = smp_processor_id(); + u64 ack, status, saved_global; struct cpu_hw_counters *cpuc; - u64 ack, status; + + rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, saved_global); /* Disable counters globally */ wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); @@ -445,10 +435,9 @@ again: goto again; out: /* - * Do not reenable when global enable is off: + * Restore - do not reenable when global enable is off: */ - if (cpuc->enable_all) - __hw_perf_enable_all(); + wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, saved_global, 0); } void smp_perf_counter_interrupt(struct pt_regs *regs) -- GitLab From 4ac13294e44664bb7edf4daf52edb71e7c6bbe84 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 9 Dec 2008 21:43:39 +0100 Subject: [PATCH 0009/6080] perf counters: protect them against CSTATE transitions Impact: fix rare lost events problem There are CPUs whose performance counters misbehave on CSTATE transitions, so provide a way to just disable/enable them around deep idle methods. (hw_perf_enable_all() is cheap on x86.) Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 14 +++++++++++++- drivers/acpi/processor_idle.c | 8 ++++++++ include/linux/perf_counter.h | 4 ++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 6a93d1f04d97..0a7f3bea2dc6 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -119,10 +120,21 @@ void hw_perf_enable_all(void) wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask, 0); } -void hw_perf_disable_all(void) +void hw_perf_restore_ctrl(u64 ctrl) { + wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, ctrl, 0); +} +EXPORT_SYMBOL_GPL(hw_perf_restore_ctrl); + +u64 hw_perf_disable_all(void) +{ + u64 ctrl; + + rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); + return ctrl; } +EXPORT_SYMBOL_GPL(hw_perf_disable_all); static inline void __hw_perf_counter_disable(struct hw_perf_counter *hwc, unsigned int idx) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 5f8d746a9b81..cca804e6f1dd 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -270,8 +270,11 @@ static atomic_t c3_cpu_count; /* Common C-state entry for C2, C3, .. */ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) { + u64 pctrl; + /* Don't trace irqs off for idle */ stop_critical_timings(); + pctrl = hw_perf_disable_all(); if (cstate->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cstate); @@ -284,6 +287,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) gets asserted in time to freeze execution properly. */ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } + hw_perf_restore_ctrl(pctrl); start_critical_timings(); } #endif /* !CONFIG_CPU_IDLE */ @@ -1425,8 +1429,11 @@ static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, */ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) { + u64 pctrl; + /* Don't trace irqs off for idle */ stop_critical_timings(); + pctrl = hw_perf_disable_all(); if (cx->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cx); @@ -1441,6 +1448,7 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) gets asserted in time to freeze execution properly. */ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } + hw_perf_restore_ctrl(pctrl); start_critical_timings(); } diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 22c4469abf44..5031b5614f25 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -156,6 +156,8 @@ extern void perf_counter_task_tick(struct task_struct *task, int cpu); extern void perf_counter_init_task(struct task_struct *task); extern void perf_counter_notify(struct pt_regs *regs); extern void perf_counter_print_debug(void); +extern void hw_perf_restore_ctrl(u64 ctrl); +extern u64 hw_perf_disable_all(void); #else static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } @@ -166,6 +168,8 @@ perf_counter_task_tick(struct task_struct *task, int cpu) { } static inline void perf_counter_init_task(struct task_struct *task) { } static inline void perf_counter_notify(struct pt_regs *regs) { } static inline void perf_counter_print_debug(void) { } +static inline void hw_perf_restore_ctrl(u64 ctrl) { } +static inline u64 hw_perf_disable_all(void) { return 0; } #endif #endif /* _LINUX_PERF_COUNTER_H */ -- GitLab From eab656ae04b9d3b83265e3db01c0d2c46b748ef7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 8 Dec 2008 19:26:59 +0100 Subject: [PATCH 0010/6080] perf counters: clean up 'raw' type API Impact: cleanup Introduce a separate hw_event type. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 7 +++++++ include/linux/syscalls.h | 8 +++----- kernel/perf_counter.c | 15 ++++++++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 5031b5614f25..daedd7d87c2a 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -38,6 +38,7 @@ enum hw_event_types { * If this bit is set in the type, then trigger NMI sampling: */ PERF_COUNT_NMI = (1 << 30), + PERF_COUNT_RAW = (1 << 31), }; /* @@ -49,6 +50,12 @@ enum perf_record_type { PERF_RECORD_GROUP, }; +struct perf_counter_event { + u32 hw_event_type; + u32 hw_event_period; + u64 hw_raw_ctrl; +}; + /** * struct hw_perf_counter - performance counter hardware details */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 6cce728a6263..3ecd73d03daa 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 perf_counter_event; #include #include @@ -625,9 +626,6 @@ asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); int kernel_execve(const char *filename, char *const argv[], char *const envp[]); asmlinkage int -sys_perf_counter_open(u32 hw_event_type, - u32 hw_event_period, - u32 record_type, - pid_t pid, - int cpu); +sys_perf_counter_open(struct perf_counter_event __user *uevent, u32 record_type, + pid_t pid, int cpu, int masterfd); #endif diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 20508f053658..96c333a5b0fc 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -734,26 +734,27 @@ perf_counter_alloc(u32 hw_event_period, int cpu, u32 record_type) * @pid: target pid */ asmlinkage int -sys_perf_counter_open(u32 hw_event_type, - u32 hw_event_period, - u32 record_type, - pid_t pid, - int cpu) +sys_perf_counter_open(struct perf_counter_event __user *uevent, u32 record_type, + pid_t pid, int cpu, int masterfd) { struct perf_counter_context *ctx; + struct perf_counter_event event; struct perf_counter *counter; int ret; + if (copy_from_user(&event, uevent, sizeof(event)) != 0) + return -EFAULT; + ctx = find_get_context(pid, cpu); if (IS_ERR(ctx)) return PTR_ERR(ctx); ret = -ENOMEM; - counter = perf_counter_alloc(hw_event_period, cpu, record_type); + counter = perf_counter_alloc(event.hw_event_period, cpu, record_type); if (!counter) goto err_put_context; - ret = hw_perf_counter_init(counter, hw_event_type); + ret = hw_perf_counter_init(counter, event.hw_event_type); if (ret) goto err_free_put_context; -- GitLab From dfa7c899b401d7dc5d85aca416aee64ac82812f2 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 8 Dec 2008 19:35:37 +0100 Subject: [PATCH 0011/6080] perf counters: expand use of counter->event Impact: change syscall, cleanup Make use of the new perf_counters event type. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 22 +++++++++++----------- include/linux/perf_counter.h | 4 +--- kernel/perf_counter.c | 10 +++++----- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 0a7f3bea2dc6..30e7ebf78275 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -56,9 +56,10 @@ const int max_intel_perfmon_events = ARRAY_SIZE(intel_perfmon_event_map); /* * Setup the hardware configuration for a given hw_event_type */ -int hw_perf_counter_init(struct perf_counter *counter, s32 hw_event_type) +int hw_perf_counter_init(struct perf_counter *counter) { struct hw_perf_counter *hwc = &counter->hw; + u32 hw_event_type = counter->event.hw_event_type; if (unlikely(!perf_counters_initialized)) return -EINVAL; @@ -83,7 +84,7 @@ int hw_perf_counter_init(struct perf_counter *counter, s32 hw_event_type) hwc->config_base = MSR_ARCH_PERFMON_EVENTSEL0; hwc->counter_base = MSR_ARCH_PERFMON_PERFCTR0; - hwc->irq_period = counter->__irq_period; + hwc->irq_period = counter->event.hw_event_period; /* * Intel PMCs cannot be accessed sanely above 32 bit width, * so we install an artificial 1<<31 period regardless of @@ -95,21 +96,19 @@ int hw_perf_counter_init(struct perf_counter *counter, s32 hw_event_type) hwc->next_count = -((s32) hwc->irq_period); /* - * Negative event types mean raw encoded event+umask values: + * Raw event type provide the config in the event structure */ - if (hw_event_type < 0) { - counter->hw_event_type = -hw_event_type; - counter->hw_event_type &= ~PERF_COUNT_NMI; + hw_event_type &= ~PERF_COUNT_NMI; + if (hw_event_type == PERF_COUNT_RAW) { + hwc->config |= counter->event.hw_raw_ctrl; } else { - hw_event_type &= ~PERF_COUNT_NMI; if (hw_event_type >= max_intel_perfmon_events) return -EINVAL; /* * The generic map: */ - counter->hw_event_type = intel_perfmon_event_map[hw_event_type]; + hwc->config |= intel_perfmon_event_map[hw_event_type]; } - hwc->config |= counter->hw_event_type; counter->wakeup_pending = 0; return 0; @@ -373,7 +372,7 @@ perf_handle_group(struct perf_counter *leader, u64 *status, u64 *overflown) perf_save_and_restart(counter); } } - perf_store_irq_data(leader, counter->hw_event_type); + perf_store_irq_data(leader, counter->event.hw_event_type); perf_store_irq_data(leader, atomic64_counter_read(counter)); } } @@ -418,7 +417,8 @@ again: perf_store_irq_data(counter, instruction_pointer(regs)); break; case PERF_RECORD_GROUP: - perf_store_irq_data(counter, counter->hw_event_type); + perf_store_irq_data(counter, + counter->event.hw_event_type); perf_store_irq_data(counter, atomic64_counter_read(counter)); perf_handle_group(counter, &status, &ack); diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index daedd7d87c2a..1f0017673e77 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -96,8 +96,7 @@ struct perf_counter { #else atomic_t count32[2]; #endif - u64 __irq_period; - + struct perf_counter_event event; struct hw_perf_counter hw; struct perf_counter_context *ctx; @@ -111,7 +110,6 @@ struct perf_counter { int oncpu; int cpu; - s32 hw_event_type; enum perf_record_type record_type; /* read() / irq related data */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 96c333a5b0fc..2557c670a3bb 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -37,7 +37,7 @@ static DEFINE_MUTEX(perf_resource_mutex); * Architecture provided APIs - weak aliases: */ -int __weak hw_perf_counter_init(struct perf_counter *counter, u32 hw_event_type) +int __weak hw_perf_counter_init(struct perf_counter *counter) { return -EINVAL; } @@ -707,7 +707,7 @@ static const struct file_operations perf_fops = { * Allocate and initialize a counter structure */ static struct perf_counter * -perf_counter_alloc(u32 hw_event_period, int cpu, u32 record_type) +perf_counter_alloc(struct perf_counter_event *event, int cpu, u32 record_type) { struct perf_counter *counter = kzalloc(sizeof(*counter), GFP_KERNEL); @@ -722,7 +722,7 @@ perf_counter_alloc(u32 hw_event_period, int cpu, u32 record_type) counter->usrdata = &counter->data[1]; counter->cpu = cpu; counter->record_type = record_type; - counter->__irq_period = hw_event_period; + counter->event = *event; counter->wakeup_pending = 0; return counter; @@ -750,11 +750,11 @@ sys_perf_counter_open(struct perf_counter_event __user *uevent, u32 record_type, return PTR_ERR(ctx); ret = -ENOMEM; - counter = perf_counter_alloc(event.hw_event_period, cpu, record_type); + counter = perf_counter_alloc(&event, cpu, record_type); if (!counter) goto err_put_context; - ret = hw_perf_counter_init(counter, event.hw_event_type); + ret = hw_perf_counter_init(counter); if (ret) goto err_free_put_context; -- GitLab From 9f66a3810fe0d4100972db84290f3ae4a4d77025 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 10 Dec 2008 12:33:23 +0100 Subject: [PATCH 0012/6080] perf counters: restructure the API Impact: clean up new API Thorough cleanup of the new perf counters API, we now get clean separation of the various concepts: - introduce perf_counter_hw_event to separate out the event source details - move special type flags into separate attributes: PERF_COUNT_NMI, PERF_COUNT_RAW - extend the type to u64 and reserve it fully to the architecture in the raw type case. And make use of all these changes in the core and x86 perfcounters code. Also change the syscall signature to: asmlinkage int sys_perf_counter_open( struct perf_counter_hw_event *hw_event_uptr __user, pid_t pid, int cpu, int group_fd); ( Note that group_fd is unused for now - it's reserved for the counter groups abstraction. ) Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 29 +++++---- include/linux/perf_counter.h | 98 +++++++++++++++++++----------- include/linux/syscalls.h | 12 ++-- kernel/perf_counter.c | 38 +++++++----- 4 files changed, 106 insertions(+), 71 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 30e7ebf78275..ef1936a871aa 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -58,8 +58,8 @@ const int max_intel_perfmon_events = ARRAY_SIZE(intel_perfmon_event_map); */ int hw_perf_counter_init(struct perf_counter *counter) { + struct perf_counter_hw_event *hw_event = &counter->hw_event; struct hw_perf_counter *hwc = &counter->hw; - u32 hw_event_type = counter->event.hw_event_type; if (unlikely(!perf_counters_initialized)) return -EINVAL; @@ -77,14 +77,14 @@ int hw_perf_counter_init(struct perf_counter *counter) hwc->nmi = 0; if (capable(CAP_SYS_ADMIN)) { hwc->config |= ARCH_PERFMON_EVENTSEL_OS; - if (hw_event_type & PERF_COUNT_NMI) + if (hw_event->nmi) hwc->nmi = 1; } - hwc->config_base = MSR_ARCH_PERFMON_EVENTSEL0; - hwc->counter_base = MSR_ARCH_PERFMON_PERFCTR0; + hwc->config_base = MSR_ARCH_PERFMON_EVENTSEL0; + hwc->counter_base = MSR_ARCH_PERFMON_PERFCTR0; - hwc->irq_period = counter->event.hw_event_period; + hwc->irq_period = hw_event->irq_period; /* * Intel PMCs cannot be accessed sanely above 32 bit width, * so we install an artificial 1<<31 period regardless of @@ -93,21 +93,20 @@ int hw_perf_counter_init(struct perf_counter *counter) if (!hwc->irq_period) hwc->irq_period = 0x7FFFFFFF; - hwc->next_count = -((s32) hwc->irq_period); + hwc->next_count = -(s32)hwc->irq_period; /* * Raw event type provide the config in the event structure */ - hw_event_type &= ~PERF_COUNT_NMI; - if (hw_event_type == PERF_COUNT_RAW) { - hwc->config |= counter->event.hw_raw_ctrl; + if (hw_event->raw) { + hwc->config |= hw_event->type; } else { - if (hw_event_type >= max_intel_perfmon_events) + if (hw_event->type >= max_intel_perfmon_events) return -EINVAL; /* * The generic map: */ - hwc->config |= intel_perfmon_event_map[hw_event_type]; + hwc->config |= intel_perfmon_event_map[hw_event->type]; } counter->wakeup_pending = 0; @@ -354,7 +353,7 @@ perf_handle_group(struct perf_counter *leader, u64 *status, u64 *overflown) int bit; list_for_each_entry(counter, &ctx->counters, list) { - if (counter->record_type != PERF_RECORD_SIMPLE || + if (counter->hw_event.record_type != PERF_RECORD_SIMPLE || counter == leader) continue; @@ -372,7 +371,7 @@ perf_handle_group(struct perf_counter *leader, u64 *status, u64 *overflown) perf_save_and_restart(counter); } } - perf_store_irq_data(leader, counter->event.hw_event_type); + perf_store_irq_data(leader, counter->hw_event.type); perf_store_irq_data(leader, atomic64_counter_read(counter)); } } @@ -410,7 +409,7 @@ again: perf_save_and_restart(counter); - switch (counter->record_type) { + switch (counter->hw_event.record_type) { case PERF_RECORD_SIMPLE: continue; case PERF_RECORD_IRQ: @@ -418,7 +417,7 @@ again: break; case PERF_RECORD_GROUP: perf_store_irq_data(counter, - counter->event.hw_event_type); + counter->hw_event.type); perf_store_irq_data(counter, atomic64_counter_read(counter)); perf_handle_group(counter, &status, &ack); diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 1f0017673e77..a2b4852e2d70 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -24,65 +24,93 @@ struct task_struct; /* - * Generalized hardware event types, used by the hw_event_type parameter - * of the sys_perf_counter_open() syscall: + * User-space ABI bits: + */ + +/* + * Generalized performance counter event types, used by the hw_event.type + * parameter of the sys_perf_counter_open() syscall: */ enum hw_event_types { - PERF_COUNT_CYCLES, - PERF_COUNT_INSTRUCTIONS, - PERF_COUNT_CACHE_REFERENCES, - PERF_COUNT_CACHE_MISSES, - PERF_COUNT_BRANCH_INSTRUCTIONS, - PERF_COUNT_BRANCH_MISSES, /* - * If this bit is set in the type, then trigger NMI sampling: + * Common hardware events, generalized by the kernel: */ - PERF_COUNT_NMI = (1 << 30), - PERF_COUNT_RAW = (1 << 31), + PERF_COUNT_CYCLES = 0, + PERF_COUNT_INSTRUCTIONS = 1, + PERF_COUNT_CACHE_REFERENCES = 2, + PERF_COUNT_CACHE_MISSES = 3, + PERF_COUNT_BRANCH_INSTRUCTIONS = 4, + PERF_COUNT_BRANCH_MISSES = 5, + + /* + * Special "software" counters provided by the kernel, even if + * the hardware does not support performance counters. These + * counters measure various physical and sw events of the + * kernel (and allow the profiling of them as well): + */ + PERF_COUNT_CPU_CLOCK = -1, + PERF_COUNT_TASK_CLOCK = -2, + PERF_COUNT_PAGE_FAULTS = -3, + PERF_COUNT_CONTEXT_SWITCHES = -4, }; /* * IRQ-notification data record type: */ -enum perf_record_type { - PERF_RECORD_SIMPLE, - PERF_RECORD_IRQ, - PERF_RECORD_GROUP, +enum perf_counter_record_type { + PERF_RECORD_SIMPLE = 0, + PERF_RECORD_IRQ = 1, + PERF_RECORD_GROUP = 2, }; -struct perf_counter_event { - u32 hw_event_type; - u32 hw_event_period; - u64 hw_raw_ctrl; +/* + * Hardware event to monitor via a performance monitoring counter: + */ +struct perf_counter_hw_event { + u64 type; + + u64 irq_period; + u32 record_type; + + u32 disabled : 1, /* off by default */ + nmi : 1, /* NMI sampling */ + raw : 1, /* raw event type */ + __reserved_1 : 29; + + u64 __reserved_2; }; +/* + * Kernel-internal data types: + */ + /** - * struct hw_perf_counter - performance counter hardware details + * struct hw_perf_counter - performance counter hardware details: */ struct hw_perf_counter { - u64 config; - unsigned long config_base; - unsigned long counter_base; - int nmi; - unsigned int idx; - u64 prev_count; - s32 next_count; - u64 irq_period; + u64 config; + unsigned long config_base; + unsigned long counter_base; + int nmi; + unsigned int idx; + u64 prev_count; + u64 irq_period; + s32 next_count; }; /* * Hardcoded buffer length limit for now, for IRQ-fed events: */ -#define PERF_DATA_BUFLEN 2048 +#define PERF_DATA_BUFLEN 2048 /** * struct perf_data - performance counter IRQ data sampling ... */ struct perf_data { - int len; - int rd_idx; - int overrun; - u8 data[PERF_DATA_BUFLEN]; + int len; + int rd_idx; + int overrun; + u8 data[PERF_DATA_BUFLEN]; }; /** @@ -96,7 +124,7 @@ struct perf_counter { #else atomic_t count32[2]; #endif - struct perf_counter_event event; + struct perf_counter_hw_event hw_event; struct hw_perf_counter hw; struct perf_counter_context *ctx; @@ -110,8 +138,6 @@ struct perf_counter { int oncpu; int cpu; - enum perf_record_type record_type; - /* read() / irq related data */ wait_queue_head_t waitq; /* optional: for NMIs */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 3ecd73d03daa..a549678b7c3c 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -54,7 +54,7 @@ struct compat_stat; struct compat_timeval; struct robust_list_head; struct getcpu_cache; -struct perf_counter_event; +struct perf_counter_hw_event; #include #include @@ -625,7 +625,11 @@ asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); int kernel_execve(const char *filename, char *const argv[], char *const envp[]); -asmlinkage int -sys_perf_counter_open(struct perf_counter_event __user *uevent, u32 record_type, - pid_t pid, int cpu, int masterfd); + +asmlinkage int sys_perf_counter_open( + + struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, + int cpu, + int group_fd); #endif diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 2557c670a3bb..0d323ceda3a4 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -669,7 +669,7 @@ perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct perf_counter *counter = file->private_data; - switch (counter->record_type) { + switch (counter->hw_event.record_type) { case PERF_RECORD_SIMPLE: return perf_read_hw(counter, buf, count); @@ -707,7 +707,7 @@ static const struct file_operations perf_fops = { * Allocate and initialize a counter structure */ static struct perf_counter * -perf_counter_alloc(struct perf_counter_event *event, int cpu, u32 record_type) +perf_counter_alloc(struct perf_counter_hw_event *hw_event, int cpu) { struct perf_counter *counter = kzalloc(sizeof(*counter), GFP_KERNEL); @@ -718,31 +718,37 @@ perf_counter_alloc(struct perf_counter_event *event, int cpu, u32 record_type) INIT_LIST_HEAD(&counter->list); init_waitqueue_head(&counter->waitq); - counter->irqdata = &counter->data[0]; - counter->usrdata = &counter->data[1]; - counter->cpu = cpu; - counter->record_type = record_type; - counter->event = *event; - counter->wakeup_pending = 0; + counter->irqdata = &counter->data[0]; + counter->usrdata = &counter->data[1]; + counter->cpu = cpu; + counter->hw_event = *hw_event; + counter->wakeup_pending = 0; return counter; } /** - * sys_perf_task_open - open a performance counter associate it to a task - * @hw_event_type: event type for monitoring/sampling... + * sys_perf_task_open - open a performance counter, associate it to a task/cpu + * + * @hw_event_uptr: event type attributes for monitoring/sampling * @pid: target pid + * @cpu: target cpu + * @group_fd: group leader counter fd */ -asmlinkage int -sys_perf_counter_open(struct perf_counter_event __user *uevent, u32 record_type, - pid_t pid, int cpu, int masterfd) +asmlinkage int sys_perf_counter_open( + + struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, + int cpu, + int group_fd) + { struct perf_counter_context *ctx; - struct perf_counter_event event; + struct perf_counter_hw_event hw_event; struct perf_counter *counter; int ret; - if (copy_from_user(&event, uevent, sizeof(event)) != 0) + if (copy_from_user(&hw_event, hw_event_uptr, sizeof(hw_event)) != 0) return -EFAULT; ctx = find_get_context(pid, cpu); @@ -750,7 +756,7 @@ sys_perf_counter_open(struct perf_counter_event __user *uevent, u32 record_type, return PTR_ERR(ctx); ret = -ENOMEM; - counter = perf_counter_alloc(&event, cpu, record_type); + counter = perf_counter_alloc(&hw_event, cpu); if (!counter) goto err_put_context; -- GitLab From 04289bb9891882202d7e961c4c04d2376930e9f9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Dec 2008 08:38:42 +0100 Subject: [PATCH 0013/6080] perf counters: add support for group counters Impact: add group counters This patch adds the "counter groups" abstraction. Groups of counters behave much like normal 'single' counters, with a few semantic and behavioral extensions on top of that. A counter group is created by creating a new counter with the open() syscall's group-leader group_fd file descriptor parameter pointing to another, already existing counter. Groups of counters are scheduled in and out in one atomic group, and they are also roundrobin-scheduled atomically. Counters that are member of a group can also record events with an (atomic) extended timestamp that extends to all members of the group, if the record type is set to PERF_RECORD_GROUP. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 28 +-- include/linux/perf_counter.h | 8 +- kernel/perf_counter.c | 282 ++++++++++++++++++++++------- 3 files changed, 236 insertions(+), 82 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index ef1936a871aa..54b4ad0cce68 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -346,18 +346,22 @@ static void perf_save_and_restart(struct perf_counter *counter) } static void -perf_handle_group(struct perf_counter *leader, u64 *status, u64 *overflown) +perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) { - struct perf_counter_context *ctx = leader->ctx; - struct perf_counter *counter; + struct perf_counter *counter, *group_leader = sibling->group_leader; int bit; - list_for_each_entry(counter, &ctx->counters, list) { - if (counter->hw_event.record_type != PERF_RECORD_SIMPLE || - counter == leader) - continue; + /* + * Store the counter's own timestamp first: + */ + perf_store_irq_data(sibling, sibling->hw_event.type); + perf_store_irq_data(sibling, atomic64_counter_read(sibling)); - if (counter->active) { + /* + * Then store sibling timestamps (if any): + */ + list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { + if (!counter->active) { /* * When counter was not in the overflow mask, we have to * read it from hardware. We read it as well, when it @@ -371,8 +375,8 @@ perf_handle_group(struct perf_counter *leader, u64 *status, u64 *overflown) perf_save_and_restart(counter); } } - perf_store_irq_data(leader, counter->hw_event.type); - perf_store_irq_data(leader, atomic64_counter_read(counter)); + perf_store_irq_data(sibling, counter->hw_event.type); + perf_store_irq_data(sibling, atomic64_counter_read(counter)); } } @@ -416,10 +420,6 @@ again: perf_store_irq_data(counter, instruction_pointer(regs)); break; case PERF_RECORD_GROUP: - perf_store_irq_data(counter, - counter->hw_event.type); - perf_store_irq_data(counter, - atomic64_counter_read(counter)); perf_handle_group(counter, &status, &ack); break; } diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index a2b4852e2d70..7af7d8965460 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -117,7 +117,10 @@ struct perf_data { * struct perf_counter - performance counter kernel representation: */ struct perf_counter { - struct list_head list; + struct list_head list_entry; + struct list_head sibling_list; + struct perf_counter *group_leader; + int active; #if BITS_PER_LONG == 64 atomic64_t count; @@ -158,7 +161,8 @@ struct perf_counter_context { * Protect the list of counters: */ spinlock_t lock; - struct list_head counters; + + struct list_head counter_list; int nr_counters; int nr_active; struct task_struct *task; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0d323ceda3a4..fa59fe8c02d5 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -55,7 +56,7 @@ void __weak hw_perf_counter_setup(void) { } * Read the cached counter in counter safe against cross CPU / NMI * modifications. 64 bit version - no complications. */ -static inline u64 perf_read_counter_safe(struct perf_counter *counter) +static inline u64 perf_counter_read_safe(struct perf_counter *counter) { return (u64) atomic64_read(&counter->count); } @@ -66,7 +67,7 @@ static inline u64 perf_read_counter_safe(struct perf_counter *counter) * Read the cached counter in counter safe against cross CPU / NMI * modifications. 32 bit version. */ -static u64 perf_read_counter_safe(struct perf_counter *counter) +static u64 perf_counter_read_safe(struct perf_counter *counter) { u32 cntl, cnth; @@ -83,13 +84,55 @@ static u64 perf_read_counter_safe(struct perf_counter *counter) #endif +static void +list_add_counter(struct perf_counter *counter, struct perf_counter_context *ctx) +{ + struct perf_counter *group_leader = counter->group_leader; + + /* + * Depending on whether it is a standalone or sibling counter, + * add it straight to the context's counter list, or to the group + * leader's sibling list: + */ + if (counter->group_leader == counter) + list_add_tail(&counter->list_entry, &ctx->counter_list); + else + list_add_tail(&counter->list_entry, &group_leader->sibling_list); +} + +static void +list_del_counter(struct perf_counter *counter, struct perf_counter_context *ctx) +{ + struct perf_counter *sibling, *tmp; + + list_del_init(&counter->list_entry); + + if (list_empty(&counter->sibling_list)) + return; + + /* + * If this was a group counter with sibling counters then + * upgrade the siblings to singleton counters by adding them + * to the context list directly: + */ + list_for_each_entry_safe(sibling, tmp, + &counter->sibling_list, list_entry) { + + list_del_init(&sibling->list_entry); + list_add_tail(&sibling->list_entry, &ctx->counter_list); + WARN_ON_ONCE(!sibling->group_leader); + WARN_ON_ONCE(sibling->group_leader == sibling); + sibling->group_leader = sibling; + } +} + /* * Cross CPU call to remove a performance counter * * We disable the counter on the hardware level first. After that we * remove it from the context list. */ -static void __perf_remove_from_context(void *info) +static void __perf_counter_remove_from_context(void *info) { struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); struct perf_counter *counter = info; @@ -119,7 +162,7 @@ static void __perf_remove_from_context(void *info) * counters on a global level. NOP for non NMI based counters. */ hw_perf_disable_all(); - list_del_init(&counter->list); + list_del_counter(counter, ctx); hw_perf_enable_all(); if (!ctx->task) { @@ -144,7 +187,7 @@ static void __perf_remove_from_context(void *info) * CPU counters are removed with a smp call. For task counters we only * call when the task is on a CPU. */ -static void perf_remove_from_context(struct perf_counter *counter) +static void perf_counter_remove_from_context(struct perf_counter *counter) { struct perf_counter_context *ctx = counter->ctx; struct task_struct *task = ctx->task; @@ -155,32 +198,32 @@ static void perf_remove_from_context(struct perf_counter *counter) * the removal is always sucessful. */ smp_call_function_single(counter->cpu, - __perf_remove_from_context, + __perf_counter_remove_from_context, counter, 1); return; } retry: - task_oncpu_function_call(task, __perf_remove_from_context, + task_oncpu_function_call(task, __perf_counter_remove_from_context, counter); spin_lock_irq(&ctx->lock); /* * If the context is active we need to retry the smp call. */ - if (ctx->nr_active && !list_empty(&counter->list)) { + if (ctx->nr_active && !list_empty(&counter->list_entry)) { spin_unlock_irq(&ctx->lock); goto retry; } /* * The lock prevents that this context is scheduled in so we - * can remove the counter safely, if it the call above did not + * can remove the counter safely, if the call above did not * succeed. */ - if (!list_empty(&counter->list)) { + if (!list_empty(&counter->list_entry)) { ctx->nr_counters--; - list_del_init(&counter->list); + list_del_counter(counter, ctx); counter->task = NULL; } spin_unlock_irq(&ctx->lock); @@ -211,7 +254,7 @@ static void __perf_install_in_context(void *info) * counters on a global level. NOP for non NMI based counters. */ hw_perf_disable_all(); - list_add_tail(&counter->list, &ctx->counters); + list_add_counter(counter, ctx); hw_perf_enable_all(); ctx->nr_counters++; @@ -268,7 +311,7 @@ retry: * If the context is active and the counter has not been added * we need to retry the smp call. */ - if (ctx->nr_active && list_empty(&counter->list)) { + if (ctx->nr_active && list_empty(&counter->list_entry)) { spin_unlock_irq(&ctx->lock); goto retry; } @@ -278,13 +321,45 @@ retry: * can add the counter safely, if it the call above did not * succeed. */ - if (list_empty(&counter->list)) { - list_add_tail(&counter->list, &ctx->counters); + if (list_empty(&counter->list_entry)) { + list_add_counter(counter, ctx); ctx->nr_counters++; } spin_unlock_irq(&ctx->lock); } +static void +counter_sched_out(struct perf_counter *counter, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx) +{ + if (!counter->active) + return; + + hw_perf_counter_disable(counter); + counter->active = 0; + counter->oncpu = -1; + + cpuctx->active_oncpu--; + ctx->nr_active--; +} + +static void +group_sched_out(struct perf_counter *group_counter, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx) +{ + struct perf_counter *counter; + + counter_sched_out(group_counter, cpuctx, ctx); + + /* + * Schedule out siblings (if any): + */ + list_for_each_entry(counter, &group_counter->sibling_list, list_entry) + counter_sched_out(counter, cpuctx, ctx); +} + /* * Called from scheduler to remove the counters of the current task, * with interrupts disabled. @@ -306,21 +381,48 @@ void perf_counter_task_sched_out(struct task_struct *task, int cpu) return; spin_lock(&ctx->lock); - list_for_each_entry(counter, &ctx->counters, list) { - if (!ctx->nr_active) - break; - if (counter->active) { - hw_perf_counter_disable(counter); - counter->active = 0; - counter->oncpu = -1; - ctx->nr_active--; - cpuctx->active_oncpu--; - } + if (ctx->nr_active) { + list_for_each_entry(counter, &ctx->counter_list, list_entry) + group_sched_out(counter, cpuctx, ctx); } spin_unlock(&ctx->lock); cpuctx->task_ctx = NULL; } +static void +counter_sched_in(struct perf_counter *counter, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx, + int cpu) +{ + if (!counter->active) + return; + + hw_perf_counter_enable(counter); + counter->active = 1; + counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ + + cpuctx->active_oncpu++; + ctx->nr_active++; +} + +static void +group_sched_in(struct perf_counter *group_counter, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx, + int cpu) +{ + struct perf_counter *counter; + + counter_sched_in(group_counter, cpuctx, ctx, cpu); + + /* + * Schedule in siblings as one group (if any): + */ + list_for_each_entry(counter, &group_counter->sibling_list, list_entry) + counter_sched_in(counter, cpuctx, ctx, cpu); +} + /* * Called from scheduler to add the counters of the current task * with interrupts disabled. @@ -342,19 +444,21 @@ void perf_counter_task_sched_in(struct task_struct *task, int cpu) return; spin_lock(&ctx->lock); - list_for_each_entry(counter, &ctx->counters, list) { + list_for_each_entry(counter, &ctx->counter_list, list_entry) { if (ctx->nr_active == cpuctx->max_pertask) break; + + /* + * Listen to the 'cpu' scheduling filter constraint + * of counters: + */ if (counter->cpu != -1 && counter->cpu != cpu) continue; - hw_perf_counter_enable(counter); - counter->active = 1; - counter->oncpu = cpu; - ctx->nr_active++; - cpuctx->active_oncpu++; + group_sched_in(counter, cpuctx, ctx, cpu); } spin_unlock(&ctx->lock); + cpuctx->task_ctx = ctx; } @@ -371,12 +475,12 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) spin_lock(&ctx->lock); /* - * Rotate the first entry last: + * Rotate the first entry last (works just fine for group counters too): */ hw_perf_disable_all(); - list_for_each_entry(counter, &ctx->counters, list) { - list_del(&counter->list); - list_add_tail(&counter->list, &ctx->counters); + list_for_each_entry(counter, &ctx->counter_list, list_entry) { + list_del(&counter->list_entry); + list_add_tail(&counter->list_entry, &ctx->counter_list); break; } hw_perf_enable_all(); @@ -386,17 +490,24 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) perf_counter_task_sched_in(curr, cpu); } +/* + * Initialize the perf_counter context in a task_struct: + */ +static void +__perf_counter_init_context(struct perf_counter_context *ctx, + struct task_struct *task) +{ + spin_lock_init(&ctx->lock); + INIT_LIST_HEAD(&ctx->counter_list); + ctx->nr_counters = 0; + ctx->task = task; +} /* * Initialize the perf_counter context in task_struct */ void perf_counter_init_task(struct task_struct *task) { - struct perf_counter_context *ctx = &task->perf_counter_ctx; - - spin_lock_init(&ctx->lock); - INIT_LIST_HEAD(&ctx->counters); - ctx->nr_counters = 0; - ctx->task = task; + __perf_counter_init_context(&task->perf_counter_ctx, task); } /* @@ -407,7 +518,7 @@ static void __hw_perf_counter_read(void *info) hw_perf_counter_read(info); } -static u64 perf_read_counter(struct perf_counter *counter) +static u64 perf_counter_read(struct perf_counter *counter) { /* * If counter is enabled and currently active on a CPU, update the @@ -418,7 +529,7 @@ static u64 perf_read_counter(struct perf_counter *counter) __hw_perf_counter_read, counter, 1); } - return perf_read_counter_safe(counter); + return perf_counter_read_safe(counter); } /* @@ -555,7 +666,7 @@ static int perf_release(struct inode *inode, struct file *file) mutex_lock(&counter->mutex); - perf_remove_from_context(counter); + perf_counter_remove_from_context(counter); put_context(ctx); mutex_unlock(&counter->mutex); @@ -577,7 +688,7 @@ perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count) return -EINVAL; mutex_lock(&counter->mutex); - cntval = perf_read_counter(counter); + cntval = perf_counter_read(counter); mutex_unlock(&counter->mutex); return put_user(cntval, (u64 __user *) buf) ? -EFAULT : sizeof(cntval); @@ -707,15 +818,25 @@ static const struct file_operations perf_fops = { * Allocate and initialize a counter structure */ static struct perf_counter * -perf_counter_alloc(struct perf_counter_hw_event *hw_event, int cpu) +perf_counter_alloc(struct perf_counter_hw_event *hw_event, + int cpu, + struct perf_counter *group_leader) { struct perf_counter *counter = kzalloc(sizeof(*counter), GFP_KERNEL); if (!counter) return NULL; + /* + * Single counters are their own group leaders, with an + * empty sibling list: + */ + if (!group_leader) + group_leader = counter; + mutex_init(&counter->mutex); - INIT_LIST_HEAD(&counter->list); + INIT_LIST_HEAD(&counter->list_entry); + INIT_LIST_HEAD(&counter->sibling_list); init_waitqueue_head(&counter->waitq); counter->irqdata = &counter->data[0]; @@ -723,6 +844,7 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, int cpu) counter->cpu = cpu; counter->hw_event = *hw_event; counter->wakeup_pending = 0; + counter->group_leader = group_leader; return counter; } @@ -743,20 +865,45 @@ asmlinkage int sys_perf_counter_open( int group_fd) { - struct perf_counter_context *ctx; + struct perf_counter *counter, *group_leader; struct perf_counter_hw_event hw_event; - struct perf_counter *counter; + struct perf_counter_context *ctx; + struct file *group_file = NULL; + int fput_needed = 0; int ret; if (copy_from_user(&hw_event, hw_event_uptr, sizeof(hw_event)) != 0) return -EFAULT; + /* + * Look up the group leader: + */ + group_leader = NULL; + if (group_fd != -1) { + ret = -EINVAL; + group_file = fget_light(group_fd, &fput_needed); + if (!group_file) + goto out_fput; + if (group_file->f_op != &perf_fops) + goto out_fput; + + group_leader = group_file->private_data; + /* + * Do not allow a recursive hierarchy: + */ + if (group_leader->group_leader) + goto out_fput; + } + + /* + * Get the target context (task or percpu): + */ ctx = find_get_context(pid, cpu); if (IS_ERR(ctx)) return PTR_ERR(ctx); ret = -ENOMEM; - counter = perf_counter_alloc(&hw_event, cpu); + counter = perf_counter_alloc(&hw_event, cpu, group_leader); if (!counter) goto err_put_context; @@ -770,11 +917,14 @@ asmlinkage int sys_perf_counter_open( if (ret < 0) goto err_remove_free_put_context; +out_fput: + fput_light(group_file, fput_needed); + return ret; err_remove_free_put_context: mutex_lock(&counter->mutex); - perf_remove_from_context(counter); + perf_counter_remove_from_context(counter); mutex_unlock(&counter->mutex); err_free_put_context: @@ -783,40 +933,40 @@ err_free_put_context: err_put_context: put_context(ctx); - return ret; + goto out_fput; } -static void __cpuinit perf_init_cpu(int cpu) +static void __cpuinit perf_counter_init_cpu(int cpu) { - struct perf_cpu_context *ctx; + struct perf_cpu_context *cpuctx; - ctx = &per_cpu(perf_cpu_context, cpu); - spin_lock_init(&ctx->ctx.lock); - INIT_LIST_HEAD(&ctx->ctx.counters); + cpuctx = &per_cpu(perf_cpu_context, cpu); + __perf_counter_init_context(&cpuctx->ctx, NULL); mutex_lock(&perf_resource_mutex); - ctx->max_pertask = perf_max_counters - perf_reserved_percpu; + cpuctx->max_pertask = perf_max_counters - perf_reserved_percpu; mutex_unlock(&perf_resource_mutex); + hw_perf_counter_setup(); } #ifdef CONFIG_HOTPLUG_CPU -static void __perf_exit_cpu(void *info) +static void __perf_counter_exit_cpu(void *info) { struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); struct perf_counter_context *ctx = &cpuctx->ctx; struct perf_counter *counter, *tmp; - list_for_each_entry_safe(counter, tmp, &ctx->counters, list) - __perf_remove_from_context(counter); + list_for_each_entry_safe(counter, tmp, &ctx->counter_list, list_entry) + __perf_counter_remove_from_context(counter); } -static void perf_exit_cpu(int cpu) +static void perf_counter_exit_cpu(int cpu) { - smp_call_function_single(cpu, __perf_exit_cpu, NULL, 1); + smp_call_function_single(cpu, __perf_counter_exit_cpu, NULL, 1); } #else -static inline void perf_exit_cpu(int cpu) { } +static inline void perf_counter_exit_cpu(int cpu) { } #endif static int __cpuinit @@ -828,12 +978,12 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) case CPU_UP_PREPARE: case CPU_UP_PREPARE_FROZEN: - perf_init_cpu(cpu); + perf_counter_init_cpu(cpu); break; case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: - perf_exit_cpu(cpu); + perf_counter_exit_cpu(cpu); break; default: -- GitLab From ccff286d85098ba5438e22aa2ea807fc1e18cf2f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Dec 2008 11:26:29 +0100 Subject: [PATCH 0014/6080] perf counters: group counter, fixes Impact: bugfix Check that a group does not span outside the context of a CPU or a task. Also, do not allow deep recursive hierarchies. Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index fa59fe8c02d5..278209c547a8 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -107,9 +107,6 @@ list_del_counter(struct perf_counter *counter, struct perf_counter_context *ctx) list_del_init(&counter->list_entry); - if (list_empty(&counter->sibling_list)) - return; - /* * If this was a group counter with sibling counters then * upgrade the siblings to singleton counters by adding them @@ -395,9 +392,6 @@ counter_sched_in(struct perf_counter *counter, struct perf_counter_context *ctx, int cpu) { - if (!counter->active) - return; - hw_perf_counter_enable(counter); counter->active = 1; counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ @@ -876,32 +870,39 @@ asmlinkage int sys_perf_counter_open( return -EFAULT; /* - * Look up the group leader: + * Get the target context (task or percpu): + */ + ctx = find_get_context(pid, cpu); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + + /* + * Look up the group leader (we will attach this counter to it): */ group_leader = NULL; if (group_fd != -1) { ret = -EINVAL; group_file = fget_light(group_fd, &fput_needed); if (!group_file) - goto out_fput; + goto err_put_context; if (group_file->f_op != &perf_fops) - goto out_fput; + goto err_put_context; group_leader = group_file->private_data; /* - * Do not allow a recursive hierarchy: + * Do not allow a recursive hierarchy (this new sibling + * becoming part of another group-sibling): + */ + if (group_leader->group_leader != group_leader) + goto err_put_context; + /* + * Do not allow to attach to a group in a different + * task or CPU context: */ - if (group_leader->group_leader) - goto out_fput; + if (group_leader->ctx != ctx) + goto err_put_context; } - /* - * Get the target context (task or percpu): - */ - ctx = find_get_context(pid, cpu); - if (IS_ERR(ctx)) - return PTR_ERR(ctx); - ret = -ENOMEM; counter = perf_counter_alloc(&hw_event, cpu, group_leader); if (!counter) -- GitLab From 621a01eac89b5e2f81a4cf576568b31f40a02724 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Dec 2008 12:46:46 +0100 Subject: [PATCH 0015/6080] perf counters: hw driver API Impact: restructure code, introduce hw_ops driver abstraction Introduce this abstraction to handle counter details: struct hw_perf_counter_ops { void (*hw_perf_counter_enable) (struct perf_counter *counter); void (*hw_perf_counter_disable) (struct perf_counter *counter); void (*hw_perf_counter_read) (struct perf_counter *counter); }; This will be useful to support assymetric hw details, and it will also be useful to implement "software counters". (Counters that count kernel managed sw events such as pagefaults, context-switches, wall-clock time or task-local time.) Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 37 +++++++++++++++++------- include/linux/perf_counter.h | 15 ++++++++++ kernel/perf_counter.c | 45 ++++++++++++++++-------------- 3 files changed, 66 insertions(+), 31 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 54b4ad0cce68..718b635dece6 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -56,7 +56,7 @@ const int max_intel_perfmon_events = ARRAY_SIZE(intel_perfmon_event_map); /* * Setup the hardware configuration for a given hw_event_type */ -int hw_perf_counter_init(struct perf_counter *counter) +static int __hw_perf_counter_init(struct perf_counter *counter) { struct perf_counter_hw_event *hw_event = &counter->hw_event; struct hw_perf_counter *hwc = &counter->hw; @@ -135,7 +135,7 @@ u64 hw_perf_disable_all(void) EXPORT_SYMBOL_GPL(hw_perf_disable_all); static inline void -__hw_perf_counter_disable(struct hw_perf_counter *hwc, unsigned int idx) +__x86_perf_counter_disable(struct hw_perf_counter *hwc, unsigned int idx) { wrmsr(hwc->config_base + idx, hwc->config, 0); } @@ -149,13 +149,13 @@ static void __hw_perf_counter_set_period(struct hw_perf_counter *hwc, int idx) wrmsr(hwc->counter_base + idx, hwc->next_count, 0); } -static void __hw_perf_counter_enable(struct hw_perf_counter *hwc, int idx) +static void __x86_perf_counter_enable(struct hw_perf_counter *hwc, int idx) { wrmsr(hwc->config_base + idx, hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0); } -void hw_perf_counter_enable(struct perf_counter *counter) +static void x86_perf_counter_enable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); struct hw_perf_counter *hwc = &counter->hw; @@ -170,12 +170,12 @@ void hw_perf_counter_enable(struct perf_counter *counter) perf_counters_lapic_init(hwc->nmi); - __hw_perf_counter_disable(hwc, idx); + __x86_perf_counter_disable(hwc, idx); cpuc->counters[idx] = counter; __hw_perf_counter_set_period(hwc, idx); - __hw_perf_counter_enable(hwc, idx); + __x86_perf_counter_enable(hwc, idx); } #ifdef CONFIG_X86_64 @@ -282,20 +282,20 @@ void perf_counter_print_debug(void) local_irq_enable(); } -void hw_perf_counter_disable(struct perf_counter *counter) +static void x86_perf_counter_disable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); struct hw_perf_counter *hwc = &counter->hw; unsigned int idx = hwc->idx; - __hw_perf_counter_disable(hwc, idx); + __x86_perf_counter_disable(hwc, idx); clear_bit(idx, cpuc->used); cpuc->counters[idx] = NULL; __hw_perf_save_counter(counter, hwc, idx); } -void hw_perf_counter_read(struct perf_counter *counter) +static void x86_perf_counter_read(struct perf_counter *counter) { struct hw_perf_counter *hwc = &counter->hw; unsigned long addr = hwc->counter_base + hwc->idx; @@ -342,7 +342,7 @@ static void perf_save_and_restart(struct perf_counter *counter) __hw_perf_counter_set_period(hwc, idx); if (pmc_ctrl & ARCH_PERFMON_EVENTSEL0_ENABLE) - __hw_perf_counter_enable(hwc, idx); + __x86_perf_counter_enable(hwc, idx); } static void @@ -572,3 +572,20 @@ void __init init_hw_perf_counters(void) perf_counters_initialized = true; } + +static struct hw_perf_counter_ops x86_perf_counter_ops = { + .hw_perf_counter_enable = x86_perf_counter_enable, + .hw_perf_counter_disable = x86_perf_counter_disable, + .hw_perf_counter_read = x86_perf_counter_read, +}; + +struct hw_perf_counter_ops *hw_perf_counter_init(struct perf_counter *counter) +{ + int err; + + err = __hw_perf_counter_init(counter); + if (err) + return NULL; + + return &x86_perf_counter_ops; +} diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 7af7d8965460..27385641ecb6 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -113,6 +113,17 @@ struct perf_data { u8 data[PERF_DATA_BUFLEN]; }; +struct perf_counter; + +/** + * struct hw_perf_counter_ops - performance counter hw ops + */ +struct hw_perf_counter_ops { + void (*hw_perf_counter_enable) (struct perf_counter *counter); + void (*hw_perf_counter_disable) (struct perf_counter *counter); + void (*hw_perf_counter_read) (struct perf_counter *counter); +}; + /** * struct perf_counter - performance counter kernel representation: */ @@ -120,6 +131,7 @@ struct perf_counter { struct list_head list_entry; struct list_head sibling_list; struct perf_counter *group_leader; + struct hw_perf_counter_ops *hw_ops; int active; #if BITS_PER_LONG == 64 @@ -185,6 +197,9 @@ struct perf_cpu_context { extern int perf_max_counters; #ifdef CONFIG_PERF_COUNTERS +extern struct hw_perf_counter_ops * +hw_perf_counter_init(struct perf_counter *counter); + extern void perf_counter_task_sched_in(struct task_struct *task, int cpu); extern void perf_counter_task_sched_out(struct task_struct *task, int cpu); extern void perf_counter_task_tick(struct task_struct *task, int cpu); diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 278209c547a8..e6e41ca95463 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -37,18 +37,15 @@ static DEFINE_MUTEX(perf_resource_mutex); /* * Architecture provided APIs - weak aliases: */ - -int __weak hw_perf_counter_init(struct perf_counter *counter) +extern __weak struct hw_perf_counter_ops * +hw_perf_counter_init(struct perf_counter *counter) { - return -EINVAL; + return ERR_PTR(-EINVAL); } -void __weak hw_perf_counter_enable(struct perf_counter *counter) { } -void __weak hw_perf_counter_disable(struct perf_counter *counter) { } -void __weak hw_perf_counter_read(struct perf_counter *counter) { } -void __weak hw_perf_disable_all(void) { } -void __weak hw_perf_enable_all(void) { } -void __weak hw_perf_counter_setup(void) { } +void __weak hw_perf_disable_all(void) { } +void __weak hw_perf_enable_all(void) { } +void __weak hw_perf_counter_setup(void) { } #if BITS_PER_LONG == 64 @@ -146,7 +143,7 @@ static void __perf_counter_remove_from_context(void *info) spin_lock(&ctx->lock); if (counter->active) { - hw_perf_counter_disable(counter); + counter->hw_ops->hw_perf_counter_disable(counter); counter->active = 0; ctx->nr_active--; cpuctx->active_oncpu--; @@ -257,7 +254,7 @@ static void __perf_install_in_context(void *info) ctx->nr_counters++; if (cpuctx->active_oncpu < perf_max_counters) { - hw_perf_counter_enable(counter); + counter->hw_ops->hw_perf_counter_enable(counter); counter->active = 1; counter->oncpu = cpu; ctx->nr_active++; @@ -333,7 +330,7 @@ counter_sched_out(struct perf_counter *counter, if (!counter->active) return; - hw_perf_counter_disable(counter); + counter->hw_ops->hw_perf_counter_disable(counter); counter->active = 0; counter->oncpu = -1; @@ -392,7 +389,7 @@ counter_sched_in(struct perf_counter *counter, struct perf_counter_context *ctx, int cpu) { - hw_perf_counter_enable(counter); + counter->hw_ops->hw_perf_counter_enable(counter); counter->active = 1; counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ @@ -509,7 +506,9 @@ void perf_counter_init_task(struct task_struct *task) */ static void __hw_perf_counter_read(void *info) { - hw_perf_counter_read(info); + struct perf_counter *counter = info; + + counter->hw_ops->hw_perf_counter_read(counter); } static u64 perf_counter_read(struct perf_counter *counter) @@ -816,8 +815,10 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, int cpu, struct perf_counter *group_leader) { - struct perf_counter *counter = kzalloc(sizeof(*counter), GFP_KERNEL); + struct hw_perf_counter_ops *hw_ops; + struct perf_counter *counter; + counter = kzalloc(sizeof(*counter), GFP_KERNEL); if (!counter) return NULL; @@ -839,6 +840,14 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, counter->hw_event = *hw_event; counter->wakeup_pending = 0; counter->group_leader = group_leader; + counter->hw_ops = NULL; + + hw_ops = hw_perf_counter_init(counter); + if (!hw_ops) { + kfree(counter); + return NULL; + } + counter->hw_ops = hw_ops; return counter; } @@ -908,10 +917,6 @@ asmlinkage int sys_perf_counter_open( if (!counter) goto err_put_context; - ret = hw_perf_counter_init(counter); - if (ret) - goto err_free_put_context; - perf_install_in_context(ctx, counter, cpu); ret = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0); @@ -927,8 +932,6 @@ err_remove_free_put_context: mutex_lock(&counter->mutex); perf_counter_remove_from_context(counter); mutex_unlock(&counter->mutex); - -err_free_put_context: kfree(counter); err_put_context: -- GitLab From 5c92d12411dfe5f0f3d1b1c1e2f756245e6f7249 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Dec 2008 13:21:10 +0100 Subject: [PATCH 0016/6080] perf counters: implement PERF_COUNT_CPU_CLOCK Impact: add new perf-counter type The 'CPU clock' counter counts the amount of CPU clock time that is elapsing, in nanoseconds. (regardless of how much of it the task is spending on a CPU executing) This counter type is a Linux kernel based abstraction, it is available even if the hardware does not support native hardware performance counters. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 36 ++--------- include/linux/perf_counter.h | 9 ++- kernel/perf_counter.c | 95 ++++++++++++++++++++++++++---- 3 files changed, 92 insertions(+), 48 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 718b635dece6..43c8e9a38b4e 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -178,35 +178,6 @@ static void x86_perf_counter_enable(struct perf_counter *counter) __x86_perf_counter_enable(hwc, idx); } -#ifdef CONFIG_X86_64 -static inline void atomic64_counter_set(struct perf_counter *counter, u64 val) -{ - atomic64_set(&counter->count, val); -} - -static inline u64 atomic64_counter_read(struct perf_counter *counter) -{ - return atomic64_read(&counter->count); -} -#else -/* - * Todo: add proper atomic64_t support to 32-bit x86: - */ -static inline void atomic64_counter_set(struct perf_counter *counter, u64 val64) -{ - u32 *val32 = (void *)&val64; - - atomic_set(counter->count32 + 0, *(val32 + 0)); - atomic_set(counter->count32 + 1, *(val32 + 1)); -} - -static inline u64 atomic64_counter_read(struct perf_counter *counter) -{ - return atomic_read(counter->count32 + 0) | - (u64) atomic_read(counter->count32 + 1) << 32; -} -#endif - static void __hw_perf_save_counter(struct perf_counter *counter, struct hw_perf_counter *hwc, int idx) { @@ -309,7 +280,7 @@ static void x86_perf_counter_read(struct perf_counter *counter) } while (offs != hwc->prev_count); val32 = (s32) val; - val = (s64)hwc->irq_period + (s64)val32; + val = (s64)hwc->irq_period + (s64)val32; atomic64_counter_set(counter, hwc->prev_count + val); } @@ -573,13 +544,14 @@ void __init init_hw_perf_counters(void) perf_counters_initialized = true; } -static struct hw_perf_counter_ops x86_perf_counter_ops = { +static const struct hw_perf_counter_ops x86_perf_counter_ops = { .hw_perf_counter_enable = x86_perf_counter_enable, .hw_perf_counter_disable = x86_perf_counter_disable, .hw_perf_counter_read = x86_perf_counter_read, }; -struct hw_perf_counter_ops *hw_perf_counter_init(struct perf_counter *counter) +const struct hw_perf_counter_ops * +hw_perf_counter_init(struct perf_counter *counter) { int err; diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 27385641ecb6..9a1713a1be27 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -131,7 +131,7 @@ struct perf_counter { struct list_head list_entry; struct list_head sibling_list; struct perf_counter *group_leader; - struct hw_perf_counter_ops *hw_ops; + const struct hw_perf_counter_ops *hw_ops; int active; #if BITS_PER_LONG == 64 @@ -197,7 +197,7 @@ struct perf_cpu_context { extern int perf_max_counters; #ifdef CONFIG_PERF_COUNTERS -extern struct hw_perf_counter_ops * +extern const struct hw_perf_counter_ops * hw_perf_counter_init(struct perf_counter *counter); extern void perf_counter_task_sched_in(struct task_struct *task, int cpu); @@ -208,6 +208,9 @@ extern void perf_counter_notify(struct pt_regs *regs); extern void perf_counter_print_debug(void); extern void hw_perf_restore_ctrl(u64 ctrl); extern u64 hw_perf_disable_all(void); +extern void atomic64_counter_set(struct perf_counter *counter, u64 val64); +extern u64 atomic64_counter_read(struct perf_counter *counter); + #else static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } @@ -219,7 +222,7 @@ static inline void perf_counter_init_task(struct task_struct *task) { } static inline void perf_counter_notify(struct pt_regs *regs) { } static inline void perf_counter_print_debug(void) { } static inline void hw_perf_restore_ctrl(u64 ctrl) { } -static inline u64 hw_perf_disable_all(void) { return 0; } +static inline u64 hw_perf_disable_all(void) { return 0; } #endif #endif /* _LINUX_PERF_COUNTER_H */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index e6e41ca95463..506286e5ba63 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -37,15 +37,15 @@ static DEFINE_MUTEX(perf_resource_mutex); /* * Architecture provided APIs - weak aliases: */ -extern __weak struct hw_perf_counter_ops * +extern __weak const struct hw_perf_counter_ops * hw_perf_counter_init(struct perf_counter *counter) { return ERR_PTR(-EINVAL); } -void __weak hw_perf_disable_all(void) { } -void __weak hw_perf_enable_all(void) { } -void __weak hw_perf_counter_setup(void) { } +u64 __weak hw_perf_disable_all(void) { return 0; } +void __weak hw_perf_restore_ctrl(u64 ctrl) { } +void __weak hw_perf_counter_setup(void) { } #if BITS_PER_LONG == 64 @@ -58,6 +58,16 @@ static inline u64 perf_counter_read_safe(struct perf_counter *counter) return (u64) atomic64_read(&counter->count); } +void atomic64_counter_set(struct perf_counter *counter, u64 val) +{ + atomic64_set(&counter->count, val); +} + +u64 atomic64_counter_read(struct perf_counter *counter) +{ + return atomic64_read(&counter->count); +} + #else /* @@ -79,6 +89,20 @@ static u64 perf_counter_read_safe(struct perf_counter *counter) return cntl | ((u64) cnth) << 32; } +void atomic64_counter_set(struct perf_counter *counter, u64 val64) +{ + u32 *val32 = (void *)&val64; + + atomic_set(counter->count32 + 0, *(val32 + 0)); + atomic_set(counter->count32 + 1, *(val32 + 1)); +} + +u64 atomic64_counter_read(struct perf_counter *counter) +{ + return atomic_read(counter->count32 + 0) | + (u64) atomic_read(counter->count32 + 1) << 32; +} + #endif static void @@ -131,6 +155,7 @@ static void __perf_counter_remove_from_context(void *info) struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); struct perf_counter *counter = info; struct perf_counter_context *ctx = counter->ctx; + u64 perf_flags; /* * If this is a task context, we need to check whether it is @@ -155,9 +180,9 @@ static void __perf_counter_remove_from_context(void *info) * Protect the list operation against NMI by disabling the * counters on a global level. NOP for non NMI based counters. */ - hw_perf_disable_all(); + perf_flags = hw_perf_disable_all(); list_del_counter(counter, ctx); - hw_perf_enable_all(); + hw_perf_restore_ctrl(perf_flags); if (!ctx->task) { /* @@ -232,6 +257,7 @@ static void __perf_install_in_context(void *info) struct perf_counter *counter = info; struct perf_counter_context *ctx = counter->ctx; int cpu = smp_processor_id(); + u64 perf_flags; /* * If this is a task context, we need to check whether it is @@ -247,9 +273,9 @@ static void __perf_install_in_context(void *info) * Protect the list operation against NMI by disabling the * counters on a global level. NOP for non NMI based counters. */ - hw_perf_disable_all(); + perf_flags = hw_perf_disable_all(); list_add_counter(counter, ctx); - hw_perf_enable_all(); + hw_perf_restore_ctrl(perf_flags); ctx->nr_counters++; @@ -457,6 +483,7 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) { struct perf_counter_context *ctx = &curr->perf_counter_ctx; struct perf_counter *counter; + u64 perf_flags; if (likely(!ctx->nr_counters)) return; @@ -468,13 +495,13 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) /* * Rotate the first entry last (works just fine for group counters too): */ - hw_perf_disable_all(); + perf_flags = hw_perf_disable_all(); list_for_each_entry(counter, &ctx->counter_list, list_entry) { list_del(&counter->list_entry); list_add_tail(&counter->list_entry, &ctx->counter_list); break; } - hw_perf_enable_all(); + hw_perf_restore_ctrl(perf_flags); spin_unlock(&ctx->lock); @@ -807,6 +834,42 @@ static const struct file_operations perf_fops = { .poll = perf_poll, }; +static void cpu_clock_perf_counter_enable(struct perf_counter *counter) +{ +} + +static void cpu_clock_perf_counter_disable(struct perf_counter *counter) +{ +} + +static void cpu_clock_perf_counter_read(struct perf_counter *counter) +{ + int cpu = raw_smp_processor_id(); + + atomic64_counter_set(counter, cpu_clock(cpu)); +} + +static const struct hw_perf_counter_ops perf_ops_cpu_clock = { + .hw_perf_counter_enable = cpu_clock_perf_counter_enable, + .hw_perf_counter_disable = cpu_clock_perf_counter_disable, + .hw_perf_counter_read = cpu_clock_perf_counter_read, +}; + +static const struct hw_perf_counter_ops * +sw_perf_counter_init(struct perf_counter *counter) +{ + const struct hw_perf_counter_ops *hw_ops = NULL; + + switch (counter->hw_event.type) { + case PERF_COUNT_CPU_CLOCK: + hw_ops = &perf_ops_cpu_clock; + break; + default: + break; + } + return hw_ops; +} + /* * Allocate and initialize a counter structure */ @@ -815,7 +878,7 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, int cpu, struct perf_counter *group_leader) { - struct hw_perf_counter_ops *hw_ops; + const struct hw_perf_counter_ops *hw_ops; struct perf_counter *counter; counter = kzalloc(sizeof(*counter), GFP_KERNEL); @@ -842,7 +905,13 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, counter->group_leader = group_leader; counter->hw_ops = NULL; - hw_ops = hw_perf_counter_init(counter); + hw_ops = NULL; + if (!hw_event->raw && hw_event->type < 0) + hw_ops = sw_perf_counter_init(counter); + if (!hw_ops) { + hw_ops = hw_perf_counter_init(counter); + } + if (!hw_ops) { kfree(counter); return NULL; @@ -912,7 +981,7 @@ asmlinkage int sys_perf_counter_open( goto err_put_context; } - ret = -ENOMEM; + ret = -EINVAL; counter = perf_counter_alloc(&hw_event, cpu, group_leader); if (!counter) goto err_put_context; -- GitLab From 01b2838c4298c5e0d30b4993c195ac34dd9df61e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Dec 2008 13:45:51 +0100 Subject: [PATCH 0017/6080] perf counters: consolidate hw_perf save/restore APIs Impact: cleanup Rename them to better match up the usual IRQ disable/enable APIs: hw_perf_disable_all() => hw_perf_save_disable() hw_perf_restore_ctrl() => hw_perf_restore() Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 8 ++++---- drivers/acpi/processor_idle.c | 10 +++++----- include/linux/perf_counter.h | 10 +++++----- kernel/perf_counter.c | 16 ++++++++-------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 43c8e9a38b4e..3e1dbebe22b9 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -118,13 +118,13 @@ void hw_perf_enable_all(void) wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask, 0); } -void hw_perf_restore_ctrl(u64 ctrl) +void hw_perf_restore(u64 ctrl) { wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, ctrl, 0); } -EXPORT_SYMBOL_GPL(hw_perf_restore_ctrl); +EXPORT_SYMBOL_GPL(hw_perf_restore); -u64 hw_perf_disable_all(void) +u64 hw_perf_save_disable(void) { u64 ctrl; @@ -132,7 +132,7 @@ u64 hw_perf_disable_all(void) wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); return ctrl; } -EXPORT_SYMBOL_GPL(hw_perf_disable_all); +EXPORT_SYMBOL_GPL(hw_perf_save_disable); static inline void __x86_perf_counter_disable(struct hw_perf_counter *hwc, unsigned int idx) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index cca804e6f1dd..a3e66a33b7a2 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -270,11 +270,11 @@ static atomic_t c3_cpu_count; /* Common C-state entry for C2, C3, .. */ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) { - u64 pctrl; + u64 perf_flags; /* Don't trace irqs off for idle */ stop_critical_timings(); - pctrl = hw_perf_disable_all(); + perf_flags = hw_perf_save_disable(); if (cstate->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cstate); @@ -287,7 +287,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) gets asserted in time to freeze execution properly. */ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } - hw_perf_restore_ctrl(pctrl); + hw_perf_restore(perf_flags); start_critical_timings(); } #endif /* !CONFIG_CPU_IDLE */ @@ -1433,7 +1433,7 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) /* Don't trace irqs off for idle */ stop_critical_timings(); - pctrl = hw_perf_disable_all(); + pctrl = hw_perf_save_disable(); if (cx->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cx); @@ -1448,7 +1448,7 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) gets asserted in time to freeze execution properly. */ unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } - hw_perf_restore_ctrl(pctrl); + hw_perf_restore(pctrl); start_critical_timings(); } diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 9a1713a1be27..68f6e3ad531f 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -67,7 +67,7 @@ enum perf_counter_record_type { * Hardware event to monitor via a performance monitoring counter: */ struct perf_counter_hw_event { - u64 type; + s64 type; u64 irq_period; u32 record_type; @@ -206,8 +206,8 @@ extern void perf_counter_task_tick(struct task_struct *task, int cpu); extern void perf_counter_init_task(struct task_struct *task); extern void perf_counter_notify(struct pt_regs *regs); extern void perf_counter_print_debug(void); -extern void hw_perf_restore_ctrl(u64 ctrl); -extern u64 hw_perf_disable_all(void); +extern u64 hw_perf_save_disable(void); +extern void hw_perf_restore(u64 ctrl); extern void atomic64_counter_set(struct perf_counter *counter, u64 val64); extern u64 atomic64_counter_read(struct perf_counter *counter); @@ -221,8 +221,8 @@ perf_counter_task_tick(struct task_struct *task, int cpu) { } static inline void perf_counter_init_task(struct task_struct *task) { } static inline void perf_counter_notify(struct pt_regs *regs) { } static inline void perf_counter_print_debug(void) { } -static inline void hw_perf_restore_ctrl(u64 ctrl) { } -static inline u64 hw_perf_disable_all(void) { return 0; } +static inline void hw_perf_restore(u64 ctrl) { } +static inline u64 hw_perf_save_disable(void) { return 0; } #endif #endif /* _LINUX_PERF_COUNTER_H */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 506286e5ba63..0e93fea17120 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -43,8 +43,8 @@ hw_perf_counter_init(struct perf_counter *counter) return ERR_PTR(-EINVAL); } -u64 __weak hw_perf_disable_all(void) { return 0; } -void __weak hw_perf_restore_ctrl(u64 ctrl) { } +u64 __weak hw_perf_save_disable(void) { return 0; } +void __weak hw_perf_restore(u64 ctrl) { } void __weak hw_perf_counter_setup(void) { } #if BITS_PER_LONG == 64 @@ -180,9 +180,9 @@ static void __perf_counter_remove_from_context(void *info) * Protect the list operation against NMI by disabling the * counters on a global level. NOP for non NMI based counters. */ - perf_flags = hw_perf_disable_all(); + perf_flags = hw_perf_save_disable(); list_del_counter(counter, ctx); - hw_perf_restore_ctrl(perf_flags); + hw_perf_restore(perf_flags); if (!ctx->task) { /* @@ -273,9 +273,9 @@ static void __perf_install_in_context(void *info) * Protect the list operation against NMI by disabling the * counters on a global level. NOP for non NMI based counters. */ - perf_flags = hw_perf_disable_all(); + perf_flags = hw_perf_save_disable(); list_add_counter(counter, ctx); - hw_perf_restore_ctrl(perf_flags); + hw_perf_restore(perf_flags); ctx->nr_counters++; @@ -495,13 +495,13 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) /* * Rotate the first entry last (works just fine for group counters too): */ - perf_flags = hw_perf_disable_all(); + perf_flags = hw_perf_save_disable(); list_for_each_entry(counter, &ctx->counter_list, list_entry) { list_del(&counter->list_entry); list_add_tail(&counter->list_entry, &ctx->counter_list); break; } - hw_perf_restore_ctrl(perf_flags); + hw_perf_restore(perf_flags); spin_unlock(&ctx->lock); -- GitLab From bae43c9945ebeef15e7952e317efb02393d3bfc7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Dec 2008 14:03:20 +0100 Subject: [PATCH 0018/6080] perf counters: implement PERF_COUNT_TASK_CLOCK Impact: add new perf-counter type The 'task clock' counter counts the amount of time a task is executing, in nanoseconds. It stops ticking when a task is scheduled out either due to it blocking, sleeping or it being preempted. This counter type is a Linux kernel based abstraction, it is available even if the hardware does not support native hardware performance counters. Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 7 +++++-- kernel/perf_counter.c | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 68f6e3ad531f..30c0ec8c1ee3 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -50,8 +50,11 @@ enum hw_event_types { */ PERF_COUNT_CPU_CLOCK = -1, PERF_COUNT_TASK_CLOCK = -2, - PERF_COUNT_PAGE_FAULTS = -3, - PERF_COUNT_CONTEXT_SWITCHES = -4, + /* + * Future software events: + */ + /* PERF_COUNT_PAGE_FAULTS = -3, + PERF_COUNT_CONTEXT_SWITCHES = -4, */ }; /* diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0e93fea17120..a0fe8474ee29 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -855,6 +855,25 @@ static const struct hw_perf_counter_ops perf_ops_cpu_clock = { .hw_perf_counter_read = cpu_clock_perf_counter_read, }; +static void task_clock_perf_counter_enable(struct perf_counter *counter) +{ +} + +static void task_clock_perf_counter_disable(struct perf_counter *counter) +{ +} + +static void task_clock_perf_counter_read(struct perf_counter *counter) +{ + atomic64_counter_set(counter, current->se.sum_exec_runtime); +} + +static const struct hw_perf_counter_ops perf_ops_task_clock = { + .hw_perf_counter_enable = task_clock_perf_counter_enable, + .hw_perf_counter_disable = task_clock_perf_counter_disable, + .hw_perf_counter_read = task_clock_perf_counter_read, +}; + static const struct hw_perf_counter_ops * sw_perf_counter_init(struct perf_counter *counter) { @@ -864,6 +883,9 @@ sw_perf_counter_init(struct perf_counter *counter) case PERF_COUNT_CPU_CLOCK: hw_ops = &perf_ops_cpu_clock; break; + case PERF_COUNT_TASK_CLOCK: + hw_ops = &perf_ops_task_clock; + break; default: break; } -- GitLab From 1d1c7ddbfab358445a542715551301b7fc363e28 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Dec 2008 14:59:31 +0100 Subject: [PATCH 0019/6080] perf counters: add prctl interface to disable/enable counters Add a way for self-monitoring tasks to disable/enable counters summarily, via a prctl: PR_TASK_PERF_COUNTERS_DISABLE 31 PR_TASK_PERF_COUNTERS_ENABLE 32 Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 4 ++ include/linux/prctl.h | 3 ++ kernel/perf_counter.c | 86 +++++++++++++++++++++++++++++++++--- kernel/sys.c | 7 +++ 4 files changed, 93 insertions(+), 7 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 30c0ec8c1ee3..97d86c293ee8 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -213,6 +213,8 @@ extern u64 hw_perf_save_disable(void); extern void hw_perf_restore(u64 ctrl); extern void atomic64_counter_set(struct perf_counter *counter, u64 val64); extern u64 atomic64_counter_read(struct perf_counter *counter); +extern int perf_counter_task_disable(void); +extern int perf_counter_task_enable(void); #else static inline void @@ -226,6 +228,8 @@ static inline void perf_counter_notify(struct pt_regs *regs) { } static inline void perf_counter_print_debug(void) { } static inline void hw_perf_restore(u64 ctrl) { } static inline u64 hw_perf_save_disable(void) { return 0; } +static inline int perf_counter_task_disable(void) { return -EINVAL; } +static inline int perf_counter_task_enable(void) { return -EINVAL; } #endif #endif /* _LINUX_PERF_COUNTER_H */ diff --git a/include/linux/prctl.h b/include/linux/prctl.h index 48d887e3c6e7..b00df4c79c63 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h @@ -85,4 +85,7 @@ #define PR_SET_TIMERSLACK 29 #define PR_GET_TIMERSLACK 30 +#define PR_TASK_PERF_COUNTERS_DISABLE 31 +#define PR_TASK_PERF_COUNTERS_ENABLE 32 + #endif /* _LINUX_PRCTL_H */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index a0fe8474ee29..4e679b91d8bb 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -415,6 +415,9 @@ counter_sched_in(struct perf_counter *counter, struct perf_counter_context *ctx, int cpu) { + if (counter->active == -1) + return; + counter->hw_ops->hw_perf_counter_enable(counter); counter->active = 1; counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ @@ -479,6 +482,79 @@ void perf_counter_task_sched_in(struct task_struct *task, int cpu) cpuctx->task_ctx = ctx; } +int perf_counter_task_disable(void) +{ + struct task_struct *curr = current; + struct perf_counter_context *ctx = &curr->perf_counter_ctx; + struct perf_counter *counter; + u64 perf_flags; + int cpu; + + if (likely(!ctx->nr_counters)) + return 0; + + local_irq_disable(); + cpu = smp_processor_id(); + + perf_counter_task_sched_out(curr, cpu); + + spin_lock(&ctx->lock); + + /* + * Disable all the counters: + */ + perf_flags = hw_perf_save_disable(); + + list_for_each_entry(counter, &ctx->counter_list, list_entry) { + WARN_ON_ONCE(counter->active == 1); + counter->active = -1; + } + hw_perf_restore(perf_flags); + + spin_unlock(&ctx->lock); + + local_irq_enable(); + + return 0; +} + +int perf_counter_task_enable(void) +{ + struct task_struct *curr = current; + struct perf_counter_context *ctx = &curr->perf_counter_ctx; + struct perf_counter *counter; + u64 perf_flags; + int cpu; + + if (likely(!ctx->nr_counters)) + return 0; + + local_irq_disable(); + cpu = smp_processor_id(); + + spin_lock(&ctx->lock); + + /* + * Disable all the counters: + */ + perf_flags = hw_perf_save_disable(); + + list_for_each_entry(counter, &ctx->counter_list, list_entry) { + if (counter->active != -1) + continue; + counter->active = 0; + } + hw_perf_restore(perf_flags); + + spin_unlock(&ctx->lock); + + perf_counter_task_sched_in(curr, cpu); + + local_irq_enable(); + + return 0; +} + void perf_counter_task_tick(struct task_struct *curr, int cpu) { struct perf_counter_context *ctx = &curr->perf_counter_ctx; @@ -951,13 +1027,9 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, * @cpu: target cpu * @group_fd: group leader counter fd */ -asmlinkage int sys_perf_counter_open( - - struct perf_counter_hw_event *hw_event_uptr __user, - pid_t pid, - int cpu, - int group_fd) - +asmlinkage int +sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, int cpu, int group_fd) { struct perf_counter *counter, *group_leader; struct perf_counter_hw_event hw_event; diff --git a/kernel/sys.c b/kernel/sys.c index 31deba8f7d16..0f66633be319 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1716,6 +1717,12 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, case PR_SET_TSC: error = SET_TSC_CTL(arg2); break; + case PR_TASK_PERF_COUNTERS_DISABLE: + error = perf_counter_task_disable(); + break; + case PR_TASK_PERF_COUNTERS_ENABLE: + error = perf_counter_task_enable(); + break; case PR_GET_TIMERSLACK: error = current->timer_slack_ns; break; -- GitLab From 6a930700c8b655a9e25e42fc4adc0b225ebbcefc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Dec 2008 15:17:03 +0100 Subject: [PATCH 0020/6080] perf counters: clean up state transitions Impact: cleanup Introduce a proper enum for the 3 states of a counter: PERF_COUNTER_STATE_OFF = -1 PERF_COUNTER_STATE_INACTIVE = 0 PERF_COUNTER_STATE_ACTIVE = 1 and rename counter->active to counter->state and propagate the changes everywhere. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 2 +- include/linux/perf_counter.h | 11 ++++++++++- kernel/perf_counter.c | 29 ++++++++++++++--------------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 3e1dbebe22b9..4854cca7fffd 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -332,7 +332,7 @@ perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) * Then store sibling timestamps (if any): */ list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { - if (!counter->active) { + if (counter->state != PERF_COUNTER_STATE_ACTIVE) { /* * When counter was not in the overflow mask, we have to * read it from hardware. We read it as well, when it diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 97d86c293ee8..8cb095fa442c 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -127,6 +127,15 @@ struct hw_perf_counter_ops { void (*hw_perf_counter_read) (struct perf_counter *counter); }; +/** + * enum perf_counter_active_state - the states of a counter + */ +enum perf_counter_active_state { + PERF_COUNTER_STATE_OFF = -1, + PERF_COUNTER_STATE_INACTIVE = 0, + PERF_COUNTER_STATE_ACTIVE = 1, +}; + /** * struct perf_counter - performance counter kernel representation: */ @@ -136,7 +145,7 @@ struct perf_counter { struct perf_counter *group_leader; const struct hw_perf_counter_ops *hw_ops; - int active; + enum perf_counter_active_state state; #if BITS_PER_LONG == 64 atomic64_t count; #else diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 4e679b91d8bb..559130b8774d 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -167,9 +167,9 @@ static void __perf_counter_remove_from_context(void *info) spin_lock(&ctx->lock); - if (counter->active) { + if (counter->state == PERF_COUNTER_STATE_ACTIVE) { counter->hw_ops->hw_perf_counter_disable(counter); - counter->active = 0; + counter->state = PERF_COUNTER_STATE_INACTIVE; ctx->nr_active--; cpuctx->active_oncpu--; counter->task = NULL; @@ -281,7 +281,7 @@ static void __perf_install_in_context(void *info) if (cpuctx->active_oncpu < perf_max_counters) { counter->hw_ops->hw_perf_counter_enable(counter); - counter->active = 1; + counter->state = PERF_COUNTER_STATE_ACTIVE; counter->oncpu = cpu; ctx->nr_active++; cpuctx->active_oncpu++; @@ -328,7 +328,6 @@ retry: spin_lock_irq(&ctx->lock); /* - * If the context is active and the counter has not been added * we need to retry the smp call. */ if (ctx->nr_active && list_empty(&counter->list_entry)) { @@ -353,12 +352,12 @@ counter_sched_out(struct perf_counter *counter, struct perf_cpu_context *cpuctx, struct perf_counter_context *ctx) { - if (!counter->active) + if (counter->state != PERF_COUNTER_STATE_ACTIVE) return; counter->hw_ops->hw_perf_counter_disable(counter); - counter->active = 0; - counter->oncpu = -1; + counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->oncpu = -1; cpuctx->active_oncpu--; ctx->nr_active--; @@ -415,11 +414,11 @@ counter_sched_in(struct perf_counter *counter, struct perf_counter_context *ctx, int cpu) { - if (counter->active == -1) + if (counter->state == PERF_COUNTER_STATE_OFF) return; counter->hw_ops->hw_perf_counter_enable(counter); - counter->active = 1; + counter->state = PERF_COUNTER_STATE_ACTIVE; counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ cpuctx->active_oncpu++; @@ -506,8 +505,8 @@ int perf_counter_task_disable(void) perf_flags = hw_perf_save_disable(); list_for_each_entry(counter, &ctx->counter_list, list_entry) { - WARN_ON_ONCE(counter->active == 1); - counter->active = -1; + WARN_ON_ONCE(counter->state == PERF_COUNTER_STATE_ACTIVE); + counter->state = PERF_COUNTER_STATE_OFF; } hw_perf_restore(perf_flags); @@ -540,9 +539,9 @@ int perf_counter_task_enable(void) perf_flags = hw_perf_save_disable(); list_for_each_entry(counter, &ctx->counter_list, list_entry) { - if (counter->active != -1) + if (counter->state != PERF_COUNTER_STATE_OFF) continue; - counter->active = 0; + counter->state = PERF_COUNTER_STATE_INACTIVE; } hw_perf_restore(perf_flags); @@ -620,7 +619,7 @@ static u64 perf_counter_read(struct perf_counter *counter) * If counter is enabled and currently active on a CPU, update the * value in the counter structure: */ - if (counter->active) { + if (counter->state == PERF_COUNTER_STATE_ACTIVE) { smp_call_function_single(counter->oncpu, __hw_perf_counter_read, counter, 1); } @@ -673,7 +672,7 @@ static struct perf_data *perf_switch_irq_data(struct perf_counter *counter) retry: spin_lock_irq(&ctx->lock); - if (!counter->active) { + if (counter->state != PERF_COUNTER_STATE_ACTIVE) { counter->irqdata = counter->usrdata; counter->usrdata = oldirqdata; spin_unlock_irq(&ctx->lock); -- GitLab From 447557ac7ce120306b4a31d6003faef39cb1bf14 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Dec 2008 20:40:18 +0100 Subject: [PATCH 0021/6080] perf counters: update docs Impact: update docs Signed-off-by: Ingo Molnar --- Documentation/perf-counters.txt | 107 ++++++++++++++++++++++---------- 1 file changed, 75 insertions(+), 32 deletions(-) diff --git a/Documentation/perf-counters.txt b/Documentation/perf-counters.txt index 19033a0bb526..fddd32189a50 100644 --- a/Documentation/perf-counters.txt +++ b/Documentation/perf-counters.txt @@ -10,8 +10,8 @@ trigger interrupts when a threshold number of events have passed - and can thus be used to profile the code that runs on that CPU. The Linux Performance Counter subsystem provides an abstraction of these -hardware capabilities. It provides per task and per CPU counters, and -it provides event capabilities on top of those. +hardware capabilities. It provides per task and per CPU counters, counter +groups, and it provides event capabilities on top of those. Performance counters are accessed via special file descriptors. There's one file descriptor per virtual counter used. @@ -19,12 +19,8 @@ There's one file descriptor per virtual counter used. The special file descriptor is opened via the perf_counter_open() system call: - int - perf_counter_open(u32 hw_event_type, - u32 hw_event_period, - u32 record_type, - pid_t pid, - int cpu); + int sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr, + pid_t pid, int cpu, int group_fd); The syscall returns the new fd. The fd can be used via the normal VFS system calls: read() can be used to read the counter, fcntl() @@ -33,39 +29,78 @@ can be used to set the blocking mode, etc. Multiple counters can be kept open at a time, and the counters can be poll()ed. -When creating a new counter fd, 'hw_event_type' is one of: - - enum hw_event_types { - PERF_COUNT_CYCLES, - PERF_COUNT_INSTRUCTIONS, - PERF_COUNT_CACHE_REFERENCES, - PERF_COUNT_CACHE_MISSES, - PERF_COUNT_BRANCH_INSTRUCTIONS, - PERF_COUNT_BRANCH_MISSES, - }; +When creating a new counter fd, 'perf_counter_hw_event' is: + +/* + * Hardware event to monitor via a performance monitoring counter: + */ +struct perf_counter_hw_event { + s64 type; + + u64 irq_period; + u32 record_type; + + u32 disabled : 1, /* off by default */ + nmi : 1, /* NMI sampling */ + raw : 1, /* raw event type */ + __reserved_1 : 29; + + u64 __reserved_2; +}; + +/* + * Generalized performance counter event types, used by the hw_event.type + * parameter of the sys_perf_counter_open() syscall: + */ +enum hw_event_types { + /* + * Common hardware events, generalized by the kernel: + */ + PERF_COUNT_CYCLES = 0, + PERF_COUNT_INSTRUCTIONS = 1, + PERF_COUNT_CACHE_REFERENCES = 2, + PERF_COUNT_CACHE_MISSES = 3, + PERF_COUNT_BRANCH_INSTRUCTIONS = 4, + PERF_COUNT_BRANCH_MISSES = 5, + + /* + * Special "software" counters provided by the kernel, even if + * the hardware does not support performance counters. These + * counters measure various physical and sw events of the + * kernel (and allow the profiling of them as well): + */ + PERF_COUNT_CPU_CLOCK = -1, + PERF_COUNT_TASK_CLOCK = -2, + /* + * Future software events: + */ + /* PERF_COUNT_PAGE_FAULTS = -3, + PERF_COUNT_CONTEXT_SWITCHES = -4, */ +}; These are standardized types of events that work uniformly on all CPUs that implements Performance Counters support under Linux. If a CPU is not able to count branch-misses, then the system call will return -EINVAL. -[ Note: more hw_event_types are supported as well, but they are CPU - specific and are enumerated via /sys on a per CPU basis. Raw hw event - types can be passed in as negative numbers. For example, to count - "External bus cycles while bus lock signal asserted" events on Intel - Core CPUs, pass in a -0x4064 event type value. ] - -The parameter 'hw_event_period' is the number of events before waking up -a read() that is blocked on a counter fd. Zero value means a non-blocking -counter. +More hw_event_types are supported as well, but they are CPU +specific and are enumerated via /sys on a per CPU basis. Raw hw event +types can be passed in under hw_event.type if hw_event.raw is 1. +For example, to count "External bus cycles while bus lock signal asserted" +events on Intel Core CPUs, pass in a 0x4064 event type value and set +hw_event.raw to 1. 'record_type' is the type of data that a read() will provide for the counter, and it can be one of: - enum perf_record_type { - PERF_RECORD_SIMPLE, - PERF_RECORD_IRQ, - }; +/* + * IRQ-notification data record type: + */ +enum perf_counter_record_type { + PERF_RECORD_SIMPLE = 0, + PERF_RECORD_IRQ = 1, + PERF_RECORD_GROUP = 2, +}; a "simple" counter is one that counts hardware events and allows them to be read out into a u64 count value. (read() returns 8 on @@ -76,6 +111,10 @@ the IP of the interrupted context. In this case read() will return the 8-byte counter value, plus the Instruction Pointer address of the interrupted context. +The parameter 'hw_event_period' is the number of events before waking up +a read() that is blocked on a counter fd. Zero value means a non-blocking +counter. + The 'pid' parameter allows the counter to be specific to a task: pid == 0: if the pid parameter is zero, the counter is attached to the @@ -92,7 +131,7 @@ CPU: cpu >= 0: the counter is restricted to a specific CPU cpu == -1: the counter counts on all CPUs -Note: the combination of 'pid == -1' and 'cpu == -1' is not valid. +(Note: the combination of 'pid == -1' and 'cpu == -1' is not valid.) A 'pid > 0' and 'cpu == -1' counter is a per task counter that counts events of that task and 'follows' that task to whatever CPU the task @@ -102,3 +141,7 @@ their own tasks. A 'pid == -1' and 'cpu == x' counter is a per CPU counter that counts all events on CPU-x. Per CPU counters need CAP_SYS_ADMIN privilege. +Group counters are created by passing in a group_fd of another counter. +Groups are scheduled at once and can be used with PERF_RECORD_GROUP +to record multi-dimensional timestamps. + -- GitLab From 9b194e831fb2c322ed81a373e49620f34edc2778 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Dec 2008 20:22:35 +0100 Subject: [PATCH 0022/6080] x86: implement atomic64_t on 32-bit Impact: new API Implement the atomic64_t APIs on 32-bit as well. Will be used by the performance counters code. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/atomic_32.h | 218 +++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h index ad5b9f6ecddf..9927e01b03c2 100644 --- a/arch/x86/include/asm/atomic_32.h +++ b/arch/x86/include/asm/atomic_32.h @@ -255,5 +255,223 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) #define smp_mb__before_atomic_inc() barrier() #define smp_mb__after_atomic_inc() barrier() +/* An 64bit atomic type */ + +typedef struct { + unsigned long long counter; +} atomic64_t; + +#define ATOMIC64_INIT(val) { (val) } + +/** + * atomic64_read - read atomic64 variable + * @v: pointer of type atomic64_t + * + * Atomically reads the value of @v. + * Doesn't imply a read memory barrier. + */ +#define __atomic64_read(ptr) ((ptr)->counter) + +static inline unsigned long long +cmpxchg8b(unsigned long long *ptr, unsigned long long old, unsigned long long new) +{ + asm volatile( + + LOCK_PREFIX "cmpxchg8b (%[ptr])\n" + + : "=A" (old) + + : [ptr] "D" (ptr), + "A" (old), + "b" (ll_low(new)), + "c" (ll_high(new)) + + : "memory"); + + return old; +} + +static inline unsigned long long +atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val, + unsigned long long new_val) +{ + return cmpxchg8b(&ptr->counter, old_val, new_val); +} + +/** + * atomic64_set - set atomic64 variable + * @ptr: pointer to type atomic64_t + * @new_val: value to assign + * + * Atomically sets the value of @ptr to @new_val. + */ +static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val) +{ + unsigned long long old_val; + + do { + old_val = atomic_read(ptr); + } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val); +} + +/** + * atomic64_read - read atomic64 variable + * @ptr: pointer to type atomic64_t + * + * Atomically reads the value of @ptr and returns it. + */ +static inline unsigned long long atomic64_read(atomic64_t *ptr) +{ + unsigned long long curr_val; + + do { + curr_val = __atomic64_read(ptr); + } while (atomic64_cmpxchg(ptr, curr_val, curr_val) != curr_val); + + return curr_val; +} + +/** + * atomic64_add_return - add and return + * @delta: integer value to add + * @ptr: pointer to type atomic64_t + * + * Atomically adds @delta to @ptr and returns @delta + *@ptr + */ +static inline unsigned long long +atomic64_add_return(unsigned long long delta, atomic64_t *ptr) +{ + unsigned long long old_val, new_val; + + do { + old_val = atomic_read(ptr); + new_val = old_val + delta; + + } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val); + + return new_val; +} + +static inline long atomic64_sub_return(unsigned long long delta, atomic64_t *ptr) +{ + return atomic64_add_return(-delta, ptr); +} + +static inline long atomic64_inc_return(atomic64_t *ptr) +{ + return atomic64_add_return(1, ptr); +} + +static inline long atomic64_dec_return(atomic64_t *ptr) +{ + return atomic64_sub_return(1, ptr); +} + +/** + * atomic64_add - add integer to atomic64 variable + * @delta: integer value to add + * @ptr: pointer to type atomic64_t + * + * Atomically adds @delta to @ptr. + */ +static inline void atomic64_add(unsigned long long delta, atomic64_t *ptr) +{ + atomic64_add_return(delta, ptr); +} + +/** + * atomic64_sub - subtract the atomic64 variable + * @delta: integer value to subtract + * @ptr: pointer to type atomic64_t + * + * Atomically subtracts @delta from @ptr. + */ +static inline void atomic64_sub(unsigned long long delta, atomic64_t *ptr) +{ + atomic64_add(-delta, ptr); +} + +/** + * atomic64_sub_and_test - subtract value from variable and test result + * @delta: integer value to subtract + * @ptr: pointer to type atomic64_t + * + * Atomically subtracts @delta from @ptr and returns + * true if the result is zero, or false for all + * other cases. + */ +static inline int +atomic64_sub_and_test(unsigned long long delta, atomic64_t *ptr) +{ + unsigned long long old_val = atomic64_sub_return(delta, ptr); + + return old_val == 0; +} + +/** + * atomic64_inc - increment atomic64 variable + * @ptr: pointer to type atomic64_t + * + * Atomically increments @ptr by 1. + */ +static inline void atomic64_inc(atomic64_t *ptr) +{ + atomic64_add(1, ptr); +} + +/** + * atomic64_dec - decrement atomic64 variable + * @ptr: pointer to type atomic64_t + * + * Atomically decrements @ptr by 1. + */ +static inline void atomic64_dec(atomic64_t *ptr) +{ + atomic64_sub(1, ptr); +} + +/** + * atomic64_dec_and_test - decrement and test + * @ptr: pointer to type atomic64_t + * + * Atomically decrements @ptr by 1 and + * returns true if the result is 0, or false for all other + * cases. + */ +static inline int atomic64_dec_and_test(atomic64_t *ptr) +{ + return atomic64_sub_and_test(1, ptr); +} + +/** + * atomic64_inc_and_test - increment and test + * @ptr: pointer to type atomic64_t + * + * Atomically increments @ptr by 1 + * and returns true if the result is zero, or false for all + * other cases. + */ +static inline int atomic64_inc_and_test(atomic64_t *ptr) +{ + return atomic64_sub_and_test(-1, ptr); +} + +/** + * atomic64_add_negative - add and test if negative + * @delta: integer value to add + * @ptr: pointer to type atomic64_t + * + * Atomically adds @delta to @ptr and returns true + * if the result is negative, or false when + * result is greater than or equal to zero. + */ +static inline int +atomic64_add_negative(unsigned long long delta, atomic64_t *ptr) +{ + long long old_val = atomic64_add_return(delta, ptr); + + return old_val < 0; +} + #include #endif /* _ASM_X86_ATOMIC_32_H */ -- GitLab From ee06094f8279e1312fc0a31591320cc7b6f0ab1e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 13 Dec 2008 09:00:03 +0100 Subject: [PATCH 0023/6080] perfcounters: restructure x86 counter math Impact: restructure code Change counter math from absolute values to clear delta logic. We try to extract elapsed deltas from the raw hw counter - and put that into the generic counter. Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 2 +- arch/x86/kernel/cpu/perf_counter.c | 230 ++++++++++++++++------------- include/linux/perf_counter.h | 15 +- kernel/perf_counter.c | 68 +-------- 4 files changed, 137 insertions(+), 178 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f2fdc1867241..fe94490bab61 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -643,7 +643,7 @@ config X86_UP_IOAPIC config X86_LOCAL_APIC def_bool y depends on X86_64 || (X86_32 && (X86_UP_APIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH)) - select HAVE_PERF_COUNTERS + select HAVE_PERF_COUNTERS if (!M386 && !M486) config X86_IO_APIC def_bool y diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index b903f8df72bb..5afae13d8d59 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -53,6 +53,48 @@ const int intel_perfmon_event_map[] = const int max_intel_perfmon_events = ARRAY_SIZE(intel_perfmon_event_map); +/* + * Propagate counter elapsed time into the generic counter. + * Can only be executed on the CPU where the counter is active. + * Returns the delta events processed. + */ +static void +x86_perf_counter_update(struct perf_counter *counter, + struct hw_perf_counter *hwc, int idx) +{ + u64 prev_raw_count, new_raw_count, delta; + + WARN_ON_ONCE(counter->state != PERF_COUNTER_STATE_ACTIVE); + /* + * Careful: an NMI might modify the previous counter value. + * + * Our tactic to handle this is to first atomically read and + * exchange a new raw count - then add that new-prev delta + * count to the generic counter atomically: + */ +again: + prev_raw_count = atomic64_read(&hwc->prev_count); + rdmsrl(hwc->counter_base + idx, new_raw_count); + + if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count, + new_raw_count) != prev_raw_count) + goto again; + + /* + * Now we have the new raw value and have updated the prev + * timestamp already. We can now calculate the elapsed delta + * (counter-)time and add that to the generic counter. + * + * Careful, not all hw sign-extends above the physical width + * of the count, so we do that by clipping the delta to 32 bits: + */ + delta = (u64)(u32)((s32)new_raw_count - (s32)prev_raw_count); + WARN_ON_ONCE((int)delta < 0); + + atomic64_add(delta, &counter->count); + atomic64_sub(delta, &hwc->period_left); +} + /* * Setup the hardware configuration for a given hw_event_type */ @@ -90,10 +132,10 @@ static int __hw_perf_counter_init(struct perf_counter *counter) * so we install an artificial 1<<31 period regardless of * the generic counter period: */ - if (!hwc->irq_period) + if ((s64)hwc->irq_period <= 0 || hwc->irq_period > 0x7FFFFFFF) hwc->irq_period = 0x7FFFFFFF; - hwc->next_count = -(s32)hwc->irq_period; + atomic64_set(&hwc->period_left, hwc->irq_period); /* * Raw event type provide the config in the event structure @@ -118,12 +160,6 @@ void hw_perf_enable_all(void) wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask, 0); } -void hw_perf_restore(u64 ctrl) -{ - wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, ctrl, 0); -} -EXPORT_SYMBOL_GPL(hw_perf_restore); - u64 hw_perf_save_disable(void) { u64 ctrl; @@ -134,27 +170,74 @@ u64 hw_perf_save_disable(void) } EXPORT_SYMBOL_GPL(hw_perf_save_disable); +void hw_perf_restore(u64 ctrl) +{ + wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, ctrl, 0); +} +EXPORT_SYMBOL_GPL(hw_perf_restore); + static inline void -__x86_perf_counter_disable(struct hw_perf_counter *hwc, unsigned int idx) +__x86_perf_counter_disable(struct perf_counter *counter, + struct hw_perf_counter *hwc, unsigned int idx) { - wrmsr(hwc->config_base + idx, hwc->config, 0); + int err; + + err = wrmsr_safe(hwc->config_base + idx, hwc->config, 0); + WARN_ON_ONCE(err); } -static DEFINE_PER_CPU(u64, prev_next_count[MAX_HW_COUNTERS]); +static DEFINE_PER_CPU(u64, prev_left[MAX_HW_COUNTERS]); -static void __hw_perf_counter_set_period(struct hw_perf_counter *hwc, int idx) +/* + * Set the next IRQ period, based on the hwc->period_left value. + * To be called with the counter disabled in hw: + */ +static void +__hw_perf_counter_set_period(struct perf_counter *counter, + struct hw_perf_counter *hwc, int idx) { - per_cpu(prev_next_count[idx], smp_processor_id()) = hwc->next_count; + s32 left = atomic64_read(&hwc->period_left); + s32 period = hwc->irq_period; + + WARN_ON_ONCE(period <= 0); + + /* + * If we are way outside a reasoable range then just skip forward: + */ + if (unlikely(left <= -period)) { + left = period; + atomic64_set(&hwc->period_left, left); + } + + if (unlikely(left <= 0)) { + left += period; + atomic64_set(&hwc->period_left, left); + } - wrmsr(hwc->counter_base + idx, hwc->next_count, 0); + WARN_ON_ONCE(left <= 0); + + per_cpu(prev_left[idx], smp_processor_id()) = left; + + /* + * The hw counter starts counting from this counter offset, + * mark it to be able to extra future deltas: + */ + atomic64_set(&hwc->prev_count, (u64)(s64)-left); + + wrmsr(hwc->counter_base + idx, -left, 0); } -static void __x86_perf_counter_enable(struct hw_perf_counter *hwc, int idx) +static void +__x86_perf_counter_enable(struct perf_counter *counter, + struct hw_perf_counter *hwc, int idx) { wrmsr(hwc->config_base + idx, hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0); } +/* + * Find a PMC slot for the freshly enabled / scheduled in counter: + */ static void x86_perf_counter_enable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); @@ -170,55 +253,17 @@ static void x86_perf_counter_enable(struct perf_counter *counter) perf_counters_lapic_init(hwc->nmi); - __x86_perf_counter_disable(hwc, idx); + __x86_perf_counter_disable(counter, hwc, idx); cpuc->counters[idx] = counter; - __hw_perf_counter_set_period(hwc, idx); - __x86_perf_counter_enable(hwc, idx); -} - -static void __hw_perf_save_counter(struct perf_counter *counter, - struct hw_perf_counter *hwc, int idx) -{ - s64 raw = -1; - s64 delta; - - /* - * Get the raw hw counter value: - */ - rdmsrl(hwc->counter_base + idx, raw); - - /* - * Rebase it to zero (it started counting at -irq_period), - * to see the delta since ->prev_count: - */ - delta = (s64)hwc->irq_period + (s64)(s32)raw; - - atomic64_counter_set(counter, hwc->prev_count + delta); - - /* - * Adjust the ->prev_count offset - if we went beyond - * irq_period of units, then we got an IRQ and the counter - * was set back to -irq_period: - */ - while (delta >= (s64)hwc->irq_period) { - hwc->prev_count += hwc->irq_period; - delta -= (s64)hwc->irq_period; - } - - /* - * Calculate the next raw counter value we'll write into - * the counter at the next sched-in time: - */ - delta -= (s64)hwc->irq_period; - - hwc->next_count = (s32)delta; + __hw_perf_counter_set_period(counter, hwc, idx); + __x86_perf_counter_enable(counter, hwc, idx); } void perf_counter_print_debug(void) { - u64 ctrl, status, overflow, pmc_ctrl, pmc_count, next_count; + u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left; int cpu, idx; if (!nr_hw_counters) @@ -241,14 +286,14 @@ void perf_counter_print_debug(void) rdmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, pmc_ctrl); rdmsrl(MSR_ARCH_PERFMON_PERFCTR0 + idx, pmc_count); - next_count = per_cpu(prev_next_count[idx], cpu); + prev_left = per_cpu(prev_left[idx], cpu); printk(KERN_INFO "CPU#%d: PMC%d ctrl: %016llx\n", cpu, idx, pmc_ctrl); printk(KERN_INFO "CPU#%d: PMC%d count: %016llx\n", cpu, idx, pmc_count); - printk(KERN_INFO "CPU#%d: PMC%d next: %016llx\n", - cpu, idx, next_count); + printk(KERN_INFO "CPU#%d: PMC%d left: %016llx\n", + cpu, idx, prev_left); } local_irq_enable(); } @@ -259,29 +304,16 @@ static void x86_perf_counter_disable(struct perf_counter *counter) struct hw_perf_counter *hwc = &counter->hw; unsigned int idx = hwc->idx; - __x86_perf_counter_disable(hwc, idx); + __x86_perf_counter_disable(counter, hwc, idx); clear_bit(idx, cpuc->used); cpuc->counters[idx] = NULL; - __hw_perf_save_counter(counter, hwc, idx); -} -static void x86_perf_counter_read(struct perf_counter *counter) -{ - struct hw_perf_counter *hwc = &counter->hw; - unsigned long addr = hwc->counter_base + hwc->idx; - s64 offs, val = -1LL; - s32 val32; - - /* Careful: NMI might modify the counter offset */ - do { - offs = hwc->prev_count; - rdmsrl(addr, val); - } while (offs != hwc->prev_count); - - val32 = (s32) val; - val = (s64)hwc->irq_period + (s64)val32; - atomic64_counter_set(counter, hwc->prev_count + val); + /* + * Drain the remaining delta count out of a counter + * that we are disabling: + */ + x86_perf_counter_update(counter, hwc, idx); } static void perf_store_irq_data(struct perf_counter *counter, u64 data) @@ -299,7 +331,8 @@ static void perf_store_irq_data(struct perf_counter *counter, u64 data) } /* - * NMI-safe enable method: + * Save and restart an expired counter. Called by NMI contexts, + * so it has to be careful about preempting normal counter ops: */ static void perf_save_and_restart(struct perf_counter *counter) { @@ -309,45 +342,25 @@ static void perf_save_and_restart(struct perf_counter *counter) rdmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, pmc_ctrl); - __hw_perf_save_counter(counter, hwc, idx); - __hw_perf_counter_set_period(hwc, idx); + x86_perf_counter_update(counter, hwc, idx); + __hw_perf_counter_set_period(counter, hwc, idx); if (pmc_ctrl & ARCH_PERFMON_EVENTSEL0_ENABLE) - __x86_perf_counter_enable(hwc, idx); + __x86_perf_counter_enable(counter, hwc, idx); } static void perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) { struct perf_counter *counter, *group_leader = sibling->group_leader; - int bit; - - /* - * Store the counter's own timestamp first: - */ - perf_store_irq_data(sibling, sibling->hw_event.type); - perf_store_irq_data(sibling, atomic64_counter_read(sibling)); /* - * Then store sibling timestamps (if any): + * Store sibling timestamps (if any): */ list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { - if (counter->state != PERF_COUNTER_STATE_ACTIVE) { - /* - * When counter was not in the overflow mask, we have to - * read it from hardware. We read it as well, when it - * has not been read yet and clear the bit in the - * status mask. - */ - bit = counter->hw.idx; - if (!test_bit(bit, (unsigned long *) overflown) || - test_bit(bit, (unsigned long *) status)) { - clear_bit(bit, (unsigned long *) status); - perf_save_and_restart(counter); - } - } + x86_perf_counter_update(counter, &counter->hw, counter->hw.idx); perf_store_irq_data(sibling, counter->hw_event.type); - perf_store_irq_data(sibling, atomic64_counter_read(counter)); + perf_store_irq_data(sibling, atomic64_read(&counter->count)); } } @@ -540,6 +553,11 @@ void __init init_hw_perf_counters(void) perf_counters_initialized = true; } +static void x86_perf_counter_read(struct perf_counter *counter) +{ + x86_perf_counter_update(counter, &counter->hw, counter->hw.idx); +} + static const struct hw_perf_counter_ops x86_perf_counter_ops = { .hw_perf_counter_enable = x86_perf_counter_enable, .hw_perf_counter_disable = x86_perf_counter_disable, diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 8cb095fa442c..72460289c654 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -91,14 +91,16 @@ struct perf_counter_hw_event { * struct hw_perf_counter - performance counter hardware details: */ struct hw_perf_counter { +#ifdef CONFIG_PERF_COUNTERS u64 config; unsigned long config_base; unsigned long counter_base; int nmi; unsigned int idx; - u64 prev_count; + atomic64_t prev_count; u64 irq_period; - s32 next_count; + atomic64_t period_left; +#endif }; /* @@ -140,17 +142,15 @@ enum perf_counter_active_state { * struct perf_counter - performance counter kernel representation: */ struct perf_counter { +#ifdef CONFIG_PERF_COUNTERS struct list_head list_entry; struct list_head sibling_list; struct perf_counter *group_leader; const struct hw_perf_counter_ops *hw_ops; enum perf_counter_active_state state; -#if BITS_PER_LONG == 64 atomic64_t count; -#else - atomic_t count32[2]; -#endif + struct perf_counter_hw_event hw_event; struct hw_perf_counter hw; @@ -172,6 +172,7 @@ struct perf_counter { struct perf_data *irqdata; struct perf_data *usrdata; struct perf_data data[2]; +#endif }; /** @@ -220,8 +221,6 @@ extern void perf_counter_notify(struct pt_regs *regs); extern void perf_counter_print_debug(void); extern u64 hw_perf_save_disable(void); extern void hw_perf_restore(u64 ctrl); -extern void atomic64_counter_set(struct perf_counter *counter, u64 val64); -extern u64 atomic64_counter_read(struct perf_counter *counter); extern int perf_counter_task_disable(void); extern int perf_counter_task_enable(void); diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 559130b8774d..416861ce8b27 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -44,67 +44,9 @@ hw_perf_counter_init(struct perf_counter *counter) } u64 __weak hw_perf_save_disable(void) { return 0; } -void __weak hw_perf_restore(u64 ctrl) { } +void __weak hw_perf_restore(u64 ctrl) { } void __weak hw_perf_counter_setup(void) { } -#if BITS_PER_LONG == 64 - -/* - * Read the cached counter in counter safe against cross CPU / NMI - * modifications. 64 bit version - no complications. - */ -static inline u64 perf_counter_read_safe(struct perf_counter *counter) -{ - return (u64) atomic64_read(&counter->count); -} - -void atomic64_counter_set(struct perf_counter *counter, u64 val) -{ - atomic64_set(&counter->count, val); -} - -u64 atomic64_counter_read(struct perf_counter *counter) -{ - return atomic64_read(&counter->count); -} - -#else - -/* - * Read the cached counter in counter safe against cross CPU / NMI - * modifications. 32 bit version. - */ -static u64 perf_counter_read_safe(struct perf_counter *counter) -{ - u32 cntl, cnth; - - local_irq_disable(); - do { - cnth = atomic_read(&counter->count32[1]); - cntl = atomic_read(&counter->count32[0]); - } while (cnth != atomic_read(&counter->count32[1])); - - local_irq_enable(); - - return cntl | ((u64) cnth) << 32; -} - -void atomic64_counter_set(struct perf_counter *counter, u64 val64) -{ - u32 *val32 = (void *)&val64; - - atomic_set(counter->count32 + 0, *(val32 + 0)); - atomic_set(counter->count32 + 1, *(val32 + 1)); -} - -u64 atomic64_counter_read(struct perf_counter *counter) -{ - return atomic_read(counter->count32 + 0) | - (u64) atomic_read(counter->count32 + 1) << 32; -} - -#endif - static void list_add_counter(struct perf_counter *counter, struct perf_counter_context *ctx) { @@ -280,11 +222,11 @@ static void __perf_install_in_context(void *info) ctx->nr_counters++; if (cpuctx->active_oncpu < perf_max_counters) { - counter->hw_ops->hw_perf_counter_enable(counter); counter->state = PERF_COUNTER_STATE_ACTIVE; counter->oncpu = cpu; ctx->nr_active++; cpuctx->active_oncpu++; + counter->hw_ops->hw_perf_counter_enable(counter); } if (!ctx->task && cpuctx->max_pertask) @@ -624,7 +566,7 @@ static u64 perf_counter_read(struct perf_counter *counter) __hw_perf_counter_read, counter, 1); } - return perf_counter_read_safe(counter); + return atomic64_read(&counter->count); } /* @@ -921,7 +863,7 @@ static void cpu_clock_perf_counter_read(struct perf_counter *counter) { int cpu = raw_smp_processor_id(); - atomic64_counter_set(counter, cpu_clock(cpu)); + atomic64_set(&counter->count, cpu_clock(cpu)); } static const struct hw_perf_counter_ops perf_ops_cpu_clock = { @@ -940,7 +882,7 @@ static void task_clock_perf_counter_disable(struct perf_counter *counter) static void task_clock_perf_counter_read(struct perf_counter *counter) { - atomic64_counter_set(counter, current->se.sum_exec_runtime); + atomic64_set(&counter->count, current->se.sum_exec_runtime); } static const struct hw_perf_counter_ops perf_ops_task_clock = { -- GitLab From 9b51f66dcb09ac5eb6bc68fc111d5c7a1e0131d6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 12 Dec 2008 13:49:45 +0100 Subject: [PATCH 0024/6080] perfcounters: implement "counter inheritance" Impact: implement new performance feature Counter inheritance can be used to run performance counters in a workload, transparently - and pipe back the counter results to the parent counter. Inheritance for performance counters works the following way: when creating a counter it can be marked with the .inherit=1 flag. Such counters are then 'inherited' by all child tasks (be they fork()-ed or clone()-ed). These counters get inherited through exec() boundaries as well (except through setuid boundaries). The counter values get added back to the parent counter(s) when the child task(s) exit - much like stime/utime statistics are gathered. So inherited counters are ideal to gather summary statistics about an application's behavior via shell commands, without having to modify that application. The timec.c command utilizes counter inheritance: http://redhat.com/~mingo/perfcounters/timec.c Sample output: $ ./timec -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null Performance counter stats for 'ls': 163516953 instructions 2295 cache-misses 2855182 branch-misses Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 24 +++- kernel/exit.c | 7 +- kernel/perf_counter.c | 248 +++++++++++++++++++++++++++++------ 3 files changed, 228 insertions(+), 51 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 72460289c654..e5d25bf8f74e 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -75,10 +75,11 @@ struct perf_counter_hw_event { u64 irq_period; u32 record_type; - u32 disabled : 1, /* off by default */ - nmi : 1, /* NMI sampling */ - raw : 1, /* raw event type */ - __reserved_1 : 29; + u32 disabled : 1, /* off by default */ + nmi : 1, /* NMI sampling */ + raw : 1, /* raw event type */ + inherit : 1, /* children inherit it */ + __reserved_1 : 28; u64 __reserved_2; }; @@ -138,6 +139,8 @@ enum perf_counter_active_state { PERF_COUNTER_STATE_ACTIVE = 1, }; +struct file; + /** * struct perf_counter - performance counter kernel representation: */ @@ -156,7 +159,10 @@ struct perf_counter { struct perf_counter_context *ctx; struct task_struct *task; + struct file *filp; + unsigned int nr_inherited; + struct perf_counter *parent; /* * Protect attach/detach: */ @@ -210,13 +216,16 @@ struct perf_cpu_context { extern int perf_max_counters; #ifdef CONFIG_PERF_COUNTERS +extern void +perf_counter_show(struct perf_counter *counter, char *str, int trace); extern const struct hw_perf_counter_ops * hw_perf_counter_init(struct perf_counter *counter); extern void perf_counter_task_sched_in(struct task_struct *task, int cpu); extern void perf_counter_task_sched_out(struct task_struct *task, int cpu); extern void perf_counter_task_tick(struct task_struct *task, int cpu); -extern void perf_counter_init_task(struct task_struct *task); +extern void perf_counter_init_task(struct task_struct *child); +extern void perf_counter_exit_task(struct task_struct *child); extern void perf_counter_notify(struct pt_regs *regs); extern void perf_counter_print_debug(void); extern u64 hw_perf_save_disable(void); @@ -226,12 +235,15 @@ extern int perf_counter_task_enable(void); #else static inline void +perf_counter_show(struct perf_counter *counter, char *str, int trace) { } +static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } static inline void perf_counter_task_sched_out(struct task_struct *task, int cpu) { } static inline void perf_counter_task_tick(struct task_struct *task, int cpu) { } -static inline void perf_counter_init_task(struct task_struct *task) { } +static inline void perf_counter_init_task(struct task_struct *child) { } +static inline void perf_counter_exit_task(struct task_struct *child) { } static inline void perf_counter_notify(struct pt_regs *regs) { } static inline void perf_counter_print_debug(void) { } static inline void hw_perf_restore(u64 ctrl) { } diff --git a/kernel/exit.c b/kernel/exit.c index 2d8be7ebb0f7..d336c90a5f13 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1093,11 +1093,12 @@ NORET_TYPE void do_exit(long code) mpol_put(tsk->mempolicy); tsk->mempolicy = NULL; #endif -#ifdef CONFIG_FUTEX /* - * This must happen late, after the PID is not - * hashed anymore: + * These must happen late, after the PID is not + * hashed anymore, but still at a point that may sleep: */ + perf_counter_exit_task(tsk); +#ifdef CONFIG_FUTEX if (unlikely(!list_empty(&tsk->pi_state_list))) exit_pi_state_list(tsk); if (unlikely(current->pi_state_cache)) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 416861ce8b27..f5e81dd193d1 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -80,8 +80,6 @@ list_del_counter(struct perf_counter *counter, struct perf_counter_context *ctx) list_del_init(&sibling->list_entry); list_add_tail(&sibling->list_entry, &ctx->counter_list); - WARN_ON_ONCE(!sibling->group_leader); - WARN_ON_ONCE(sibling->group_leader == sibling); sibling->group_leader = sibling; } } @@ -97,6 +95,7 @@ static void __perf_counter_remove_from_context(void *info) struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); struct perf_counter *counter = info; struct perf_counter_context *ctx = counter->ctx; + unsigned long flags; u64 perf_flags; /* @@ -107,7 +106,7 @@ static void __perf_counter_remove_from_context(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - spin_lock(&ctx->lock); + spin_lock_irqsave(&ctx->lock, flags); if (counter->state == PERF_COUNTER_STATE_ACTIVE) { counter->hw_ops->hw_perf_counter_disable(counter); @@ -136,7 +135,7 @@ static void __perf_counter_remove_from_context(void *info) perf_max_counters - perf_reserved_percpu); } - spin_unlock(&ctx->lock); + spin_unlock_irqrestore(&ctx->lock, flags); } @@ -199,6 +198,7 @@ static void __perf_install_in_context(void *info) struct perf_counter *counter = info; struct perf_counter_context *ctx = counter->ctx; int cpu = smp_processor_id(); + unsigned long flags; u64 perf_flags; /* @@ -209,7 +209,7 @@ static void __perf_install_in_context(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - spin_lock(&ctx->lock); + spin_lock_irqsave(&ctx->lock, flags); /* * Protect the list operation against NMI by disabling the @@ -232,7 +232,7 @@ static void __perf_install_in_context(void *info) if (!ctx->task && cpuctx->max_pertask) cpuctx->max_pertask--; - spin_unlock(&ctx->lock); + spin_unlock_irqrestore(&ctx->lock, flags); } /* @@ -446,10 +446,9 @@ int perf_counter_task_disable(void) */ perf_flags = hw_perf_save_disable(); - list_for_each_entry(counter, &ctx->counter_list, list_entry) { - WARN_ON_ONCE(counter->state == PERF_COUNTER_STATE_ACTIVE); + list_for_each_entry(counter, &ctx->counter_list, list_entry) counter->state = PERF_COUNTER_STATE_OFF; - } + hw_perf_restore(perf_flags); spin_unlock(&ctx->lock); @@ -525,26 +524,6 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) perf_counter_task_sched_in(curr, cpu); } -/* - * Initialize the perf_counter context in a task_struct: - */ -static void -__perf_counter_init_context(struct perf_counter_context *ctx, - struct task_struct *task) -{ - spin_lock_init(&ctx->lock); - INIT_LIST_HEAD(&ctx->counter_list); - ctx->nr_counters = 0; - ctx->task = task; -} -/* - * Initialize the perf_counter context in task_struct - */ -void perf_counter_init_task(struct task_struct *task) -{ - __perf_counter_init_context(&task->perf_counter_ctx, task); -} - /* * Cross CPU call to read the hardware counter */ @@ -663,7 +642,6 @@ static struct perf_counter_context *find_get_context(pid_t pid, int cpu) cpuctx = &per_cpu(perf_cpu_context, cpu); ctx = &cpuctx->ctx; - WARN_ON_ONCE(ctx->task); return ctx; } @@ -915,12 +893,13 @@ sw_perf_counter_init(struct perf_counter *counter) static struct perf_counter * perf_counter_alloc(struct perf_counter_hw_event *hw_event, int cpu, - struct perf_counter *group_leader) + struct perf_counter *group_leader, + gfp_t gfpflags) { const struct hw_perf_counter_ops *hw_ops; struct perf_counter *counter; - counter = kzalloc(sizeof(*counter), GFP_KERNEL); + counter = kzalloc(sizeof(*counter), gfpflags); if (!counter) return NULL; @@ -947,9 +926,8 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, hw_ops = NULL; if (!hw_event->raw && hw_event->type < 0) hw_ops = sw_perf_counter_init(counter); - if (!hw_ops) { + if (!hw_ops) hw_ops = hw_perf_counter_init(counter); - } if (!hw_ops) { kfree(counter); @@ -975,8 +953,10 @@ sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr __user, struct perf_counter *counter, *group_leader; struct perf_counter_hw_event hw_event; struct perf_counter_context *ctx; + struct file *counter_file = NULL; struct file *group_file = NULL; int fput_needed = 0; + int fput_needed2 = 0; int ret; if (copy_from_user(&hw_event, hw_event_uptr, sizeof(hw_event)) != 0) @@ -1017,25 +997,29 @@ sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr __user, } ret = -EINVAL; - counter = perf_counter_alloc(&hw_event, cpu, group_leader); + counter = perf_counter_alloc(&hw_event, cpu, group_leader, GFP_KERNEL); if (!counter) goto err_put_context; - perf_install_in_context(ctx, counter, cpu); - ret = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0); if (ret < 0) - goto err_remove_free_put_context; + goto err_free_put_context; + + counter_file = fget_light(ret, &fput_needed2); + if (!counter_file) + goto err_free_put_context; + + counter->filp = counter_file; + perf_install_in_context(ctx, counter, cpu); + + fput_light(counter_file, fput_needed2); out_fput: fput_light(group_file, fput_needed); return ret; -err_remove_free_put_context: - mutex_lock(&counter->mutex); - perf_counter_remove_from_context(counter); - mutex_unlock(&counter->mutex); +err_free_put_context: kfree(counter); err_put_context: @@ -1044,6 +1028,186 @@ err_put_context: goto out_fput; } +/* + * Initialize the perf_counter context in a task_struct: + */ +static void +__perf_counter_init_context(struct perf_counter_context *ctx, + struct task_struct *task) +{ + memset(ctx, 0, sizeof(*ctx)); + spin_lock_init(&ctx->lock); + INIT_LIST_HEAD(&ctx->counter_list); + ctx->task = task; +} + +/* + * inherit a counter from parent task to child task: + */ +static int +inherit_counter(struct perf_counter *parent_counter, + struct task_struct *parent, + struct perf_counter_context *parent_ctx, + struct task_struct *child, + struct perf_counter_context *child_ctx) +{ + struct perf_counter *child_counter; + + child_counter = perf_counter_alloc(&parent_counter->hw_event, + parent_counter->cpu, NULL, + GFP_ATOMIC); + if (!child_counter) + return -ENOMEM; + + /* + * Link it up in the child's context: + */ + child_counter->ctx = child_ctx; + child_counter->task = child; + list_add_counter(child_counter, child_ctx); + child_ctx->nr_counters++; + + child_counter->parent = parent_counter; + parent_counter->nr_inherited++; + /* + * inherit into child's child as well: + */ + child_counter->hw_event.inherit = 1; + + /* + * Get a reference to the parent filp - we will fput it + * when the child counter exits. This is safe to do because + * we are in the parent and we know that the filp still + * exists and has a nonzero count: + */ + atomic_long_inc(&parent_counter->filp->f_count); + + return 0; +} + +static void +__perf_counter_exit_task(struct task_struct *child, + struct perf_counter *child_counter, + struct perf_counter_context *child_ctx) +{ + struct perf_counter *parent_counter; + u64 parent_val, child_val; + u64 perf_flags; + + /* + * Disable and unlink this counter. + * + * Be careful about zapping the list - IRQ/NMI context + * could still be processing it: + */ + local_irq_disable(); + perf_flags = hw_perf_save_disable(); + + if (child_counter->state == PERF_COUNTER_STATE_ACTIVE) + child_counter->hw_ops->hw_perf_counter_disable(child_counter); + list_del_init(&child_counter->list_entry); + + hw_perf_restore(perf_flags); + local_irq_enable(); + + parent_counter = child_counter->parent; + /* + * It can happen that parent exits first, and has counters + * that are still around due to the child reference. These + * counters need to be zapped - but otherwise linger. + */ + if (!parent_counter) + return; + + parent_val = atomic64_read(&parent_counter->count); + child_val = atomic64_read(&child_counter->count); + + /* + * Add back the child's count to the parent's count: + */ + atomic64_add(child_val, &parent_counter->count); + + fput(parent_counter->filp); + + kfree(child_counter); +} + +/* + * When a child task exist, feed back counter values to parent counters. + * + * Note: we are running in child context, but the PID is not hashed + * anymore so new counters will not be added. + */ +void perf_counter_exit_task(struct task_struct *child) +{ + struct perf_counter *child_counter, *tmp; + struct perf_counter_context *child_ctx; + + child_ctx = &child->perf_counter_ctx; + + if (likely(!child_ctx->nr_counters)) + return; + + list_for_each_entry_safe(child_counter, tmp, &child_ctx->counter_list, + list_entry) + __perf_counter_exit_task(child, child_counter, child_ctx); +} + +/* + * Initialize the perf_counter context in task_struct + */ +void perf_counter_init_task(struct task_struct *child) +{ + struct perf_counter_context *child_ctx, *parent_ctx; + struct perf_counter *counter, *parent_counter; + struct task_struct *parent = current; + unsigned long flags; + + child_ctx = &child->perf_counter_ctx; + parent_ctx = &parent->perf_counter_ctx; + + __perf_counter_init_context(child_ctx, child); + + /* + * This is executed from the parent task context, so inherit + * counters that have been marked for cloning: + */ + + if (likely(!parent_ctx->nr_counters)) + return; + + /* + * Lock the parent list. No need to lock the child - not PID + * hashed yet and not running, so nobody can access it. + */ + spin_lock_irqsave(&parent_ctx->lock, flags); + + /* + * We dont have to disable NMIs - we are only looking at + * the list, not manipulating it: + */ + list_for_each_entry(counter, &parent_ctx->counter_list, list_entry) { + if (!counter->hw_event.inherit || counter->group_leader != counter) + continue; + + /* + * Instead of creating recursive hierarchies of counters, + * we link inheritd counters back to the original parent, + * which has a filp for sure, which we use as the reference + * count: + */ + parent_counter = counter; + if (counter->parent) + parent_counter = counter->parent; + + if (inherit_counter(parent_counter, parent, + parent_ctx, child, child_ctx)) + break; + } + + spin_unlock_irqrestore(&parent_ctx->lock, flags); +} + static void __cpuinit perf_counter_init_cpu(int cpu) { struct perf_cpu_context *cpuctx; -- GitLab From 8cb391e8786c8072367f0aeb90551903fef074ba Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Dec 2008 12:22:31 +0100 Subject: [PATCH 0025/6080] perfcounters: fix task clock counter Impact: bugfix Update the task clock counter to the new math. Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f5e81dd193d1..1f81cde0dc43 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -850,17 +850,36 @@ static const struct hw_perf_counter_ops perf_ops_cpu_clock = { .hw_perf_counter_read = cpu_clock_perf_counter_read, }; -static void task_clock_perf_counter_enable(struct perf_counter *counter) +static void task_clock_perf_counter_update(struct perf_counter *counter) { + u64 prev, now; + s64 delta; + + prev = atomic64_read(&counter->hw.prev_count); + now = current->se.sum_exec_runtime; + + atomic64_set(&counter->hw.prev_count, now); + + delta = now - prev; + if (WARN_ON_ONCE(delta < 0)) + delta = 0; + + atomic64_add(delta, &counter->count); } -static void task_clock_perf_counter_disable(struct perf_counter *counter) +static void task_clock_perf_counter_read(struct perf_counter *counter) { + task_clock_perf_counter_update(counter); } -static void task_clock_perf_counter_read(struct perf_counter *counter) +static void task_clock_perf_counter_enable(struct perf_counter *counter) +{ + atomic64_set(&counter->hw.prev_count, current->se.sum_exec_runtime); +} + +static void task_clock_perf_counter_disable(struct perf_counter *counter) { - atomic64_set(&counter->count, current->se.sum_exec_runtime); + task_clock_perf_counter_update(counter); } static const struct hw_perf_counter_ops perf_ops_task_clock = { -- GitLab From 5d6a27d8a096868ae313f71f563b06074a7e34fe Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Dec 2008 12:28:33 +0100 Subject: [PATCH 0026/6080] perfcounters: add context switch counter Impact: add new feature, new sw counter Add a counter that counts the number of context-switches a task is doing. Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 4 +-- kernel/perf_counter.c | 51 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index e5d25bf8f74e..d2a16563415f 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -53,8 +53,8 @@ enum hw_event_types { /* * Future software events: */ - /* PERF_COUNT_PAGE_FAULTS = -3, - PERF_COUNT_CONTEXT_SWITCHES = -4, */ + PERF_COUNT_PAGE_FAULTS = -3, + PERF_COUNT_CONTEXT_SWITCHES = -4, }; /* diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 1f81cde0dc43..09287091c526 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -888,6 +888,54 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = { .hw_perf_counter_read = task_clock_perf_counter_read, }; +static u64 get_context_switches(void) +{ + struct task_struct *curr = current; + + return curr->nvcsw + curr->nivcsw; +} + +static void context_switches_perf_counter_update(struct perf_counter *counter) +{ + u64 prev, now; + s64 delta; + + prev = atomic64_read(&counter->hw.prev_count); + now = get_context_switches(); + + atomic64_set(&counter->hw.prev_count, now); + + delta = now - prev; + if (WARN_ON_ONCE(delta < 0)) + delta = 0; + + atomic64_add(delta, &counter->count); +} + +static void context_switches_perf_counter_read(struct perf_counter *counter) +{ + context_switches_perf_counter_update(counter); +} + +static void context_switches_perf_counter_enable(struct perf_counter *counter) +{ + /* + * ->nvcsw + curr->nivcsw is a per-task value already, + * so we dont have to clear it on switch-in. + */ +} + +static void context_switches_perf_counter_disable(struct perf_counter *counter) +{ + context_switches_perf_counter_update(counter); +} + +static const struct hw_perf_counter_ops perf_ops_context_switches = { + .hw_perf_counter_enable = context_switches_perf_counter_enable, + .hw_perf_counter_disable = context_switches_perf_counter_disable, + .hw_perf_counter_read = context_switches_perf_counter_read, +}; + static const struct hw_perf_counter_ops * sw_perf_counter_init(struct perf_counter *counter) { @@ -900,6 +948,9 @@ sw_perf_counter_init(struct perf_counter *counter) case PERF_COUNT_TASK_CLOCK: hw_ops = &perf_ops_task_clock; break; + case PERF_COUNT_CONTEXT_SWITCHES: + hw_ops = &perf_ops_context_switches; + break; default: break; } -- GitLab From 6c594c21fcb02c662f11c97be4d7d2b73060a205 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Dec 2008 12:34:15 +0100 Subject: [PATCH 0027/6080] perfcounters: add task migrations counter Impact: add new feature, new sw counter Add a counter that counts the number of cross-CPU migrations a task is suffering. Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 8 +++--- include/linux/sched.h | 3 ++- kernel/perf_counter.c | 49 ++++++++++++++++++++++++++++++++++++ kernel/sched.c | 7 ++++-- 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index d2a16563415f..f30486fc55d7 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -42,6 +42,8 @@ enum hw_event_types { PERF_COUNT_BRANCH_INSTRUCTIONS = 4, PERF_COUNT_BRANCH_MISSES = 5, + PERF_HW_EVENTS_MAX = 6, + /* * Special "software" counters provided by the kernel, even if * the hardware does not support performance counters. These @@ -50,11 +52,11 @@ enum hw_event_types { */ PERF_COUNT_CPU_CLOCK = -1, PERF_COUNT_TASK_CLOCK = -2, - /* - * Future software events: - */ PERF_COUNT_PAGE_FAULTS = -3, PERF_COUNT_CONTEXT_SWITCHES = -4, + PERF_COUNT_CPU_MIGRATIONS = -5, + + PERF_SW_EVENTS_MIN = -6, }; /* diff --git a/include/linux/sched.h b/include/linux/sched.h index 4c530278391b..2e15be8fc792 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1014,6 +1014,8 @@ struct sched_entity { u64 last_wakeup; u64 avg_overlap; + u64 nr_migrations; + #ifdef CONFIG_SCHEDSTATS u64 wait_start; u64 wait_max; @@ -1029,7 +1031,6 @@ struct sched_entity { u64 exec_max; u64 slice_max; - u64 nr_migrations; u64 nr_migrations_cold; u64 nr_failed_migrations_affine; u64 nr_failed_migrations_running; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 09287091c526..fb11e351e44e 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -936,6 +936,52 @@ static const struct hw_perf_counter_ops perf_ops_context_switches = { .hw_perf_counter_read = context_switches_perf_counter_read, }; +static inline u64 get_cpu_migrations(void) +{ + return current->se.nr_migrations; +} + +static void cpu_migrations_perf_counter_update(struct perf_counter *counter) +{ + u64 prev, now; + s64 delta; + + prev = atomic64_read(&counter->hw.prev_count); + now = get_cpu_migrations(); + + atomic64_set(&counter->hw.prev_count, now); + + delta = now - prev; + if (WARN_ON_ONCE(delta < 0)) + delta = 0; + + atomic64_add(delta, &counter->count); +} + +static void cpu_migrations_perf_counter_read(struct perf_counter *counter) +{ + cpu_migrations_perf_counter_update(counter); +} + +static void cpu_migrations_perf_counter_enable(struct perf_counter *counter) +{ + /* + * se.nr_migrations is a per-task value already, + * so we dont have to clear it on switch-in. + */ +} + +static void cpu_migrations_perf_counter_disable(struct perf_counter *counter) +{ + cpu_migrations_perf_counter_update(counter); +} + +static const struct hw_perf_counter_ops perf_ops_cpu_migrations = { + .hw_perf_counter_enable = cpu_migrations_perf_counter_enable, + .hw_perf_counter_disable = cpu_migrations_perf_counter_disable, + .hw_perf_counter_read = cpu_migrations_perf_counter_read, +}; + static const struct hw_perf_counter_ops * sw_perf_counter_init(struct perf_counter *counter) { @@ -951,6 +997,9 @@ sw_perf_counter_init(struct perf_counter *counter) case PERF_COUNT_CONTEXT_SWITCHES: hw_ops = &perf_ops_context_switches; break; + case PERF_COUNT_CPU_MIGRATIONS: + hw_ops = &perf_ops_cpu_migrations; + break; default: break; } diff --git a/kernel/sched.c b/kernel/sched.c index 5c3f4106314e..382cfdb5e38d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1852,12 +1852,14 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) p->se.sleep_start -= clock_offset; if (p->se.block_start) p->se.block_start -= clock_offset; +#endif if (old_cpu != new_cpu) { - schedstat_inc(p, se.nr_migrations); + p->se.nr_migrations++; +#ifdef CONFIG_SCHEDSTATS if (task_hot(p, old_rq->clock, NULL)) schedstat_inc(p, se.nr_forced2_migrations); - } #endif + } p->se.vruntime -= old_cfsrq->min_vruntime - new_cfsrq->min_vruntime; @@ -2375,6 +2377,7 @@ static void __sched_fork(struct task_struct *p) p->se.exec_start = 0; p->se.sum_exec_runtime = 0; p->se.prev_sum_exec_runtime = 0; + p->se.nr_migrations = 0; p->se.last_wakeup = 0; p->se.avg_overlap = 0; -- GitLab From e06c61a879910869aa5bf3f8f634abfee1a7bebc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Dec 2008 14:44:31 +0100 Subject: [PATCH 0028/6080] perfcounters: add nr-of-faults counter Impact: add new feature, new sw counter Add a counter that counts the number of pagefaults a task is experiencing. Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index fb11e351e44e..59c52f9ee431 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -888,6 +888,54 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = { .hw_perf_counter_read = task_clock_perf_counter_read, }; +static u64 get_page_faults(void) +{ + struct task_struct *curr = current; + + return curr->maj_flt + curr->min_flt; +} + +static void page_faults_perf_counter_update(struct perf_counter *counter) +{ + u64 prev, now; + s64 delta; + + prev = atomic64_read(&counter->hw.prev_count); + now = get_page_faults(); + + atomic64_set(&counter->hw.prev_count, now); + + delta = now - prev; + if (WARN_ON_ONCE(delta < 0)) + delta = 0; + + atomic64_add(delta, &counter->count); +} + +static void page_faults_perf_counter_read(struct perf_counter *counter) +{ + page_faults_perf_counter_update(counter); +} + +static void page_faults_perf_counter_enable(struct perf_counter *counter) +{ + /* + * page-faults is a per-task value already, + * so we dont have to clear it on switch-in. + */ +} + +static void page_faults_perf_counter_disable(struct perf_counter *counter) +{ + page_faults_perf_counter_update(counter); +} + +static const struct hw_perf_counter_ops perf_ops_page_faults = { + .hw_perf_counter_enable = page_faults_perf_counter_enable, + .hw_perf_counter_disable = page_faults_perf_counter_disable, + .hw_perf_counter_read = page_faults_perf_counter_read, +}; + static u64 get_context_switches(void) { struct task_struct *curr = current; @@ -994,6 +1042,9 @@ sw_perf_counter_init(struct perf_counter *counter) case PERF_COUNT_TASK_CLOCK: hw_ops = &perf_ops_task_clock; break; + case PERF_COUNT_PAGE_FAULTS: + hw_ops = &perf_ops_page_faults; + break; case PERF_COUNT_CONTEXT_SWITCHES: hw_ops = &perf_ops_context_switches; break; -- GitLab From 2b9ff0db19b5e2c77000b7201525f9c3d6e8328d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Dec 2008 18:36:30 +0100 Subject: [PATCH 0029/6080] perfcounters: fix non-intel-perfmon CPUs Do not write MSR_CORE_PERF_GLOBAL_CTRL on CPUs where it does not exist. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 5afae13d8d59..6d30f603b62c 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -157,6 +157,9 @@ static int __hw_perf_counter_init(struct perf_counter *counter) void hw_perf_enable_all(void) { + if (unlikely(!perf_counters_initialized)) + return; + wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask, 0); } @@ -164,14 +167,21 @@ u64 hw_perf_save_disable(void) { u64 ctrl; + if (unlikely(!perf_counters_initialized)) + return 0; + rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); + return ctrl; } EXPORT_SYMBOL_GPL(hw_perf_save_disable); void hw_perf_restore(u64 ctrl) { + if (unlikely(!perf_counters_initialized)) + return; + wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, ctrl, 0); } EXPORT_SYMBOL_GPL(hw_perf_restore); -- GitLab From 088e2852c858159d47f71ee8da38e0fb1b21f806 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Dec 2008 20:21:00 +0100 Subject: [PATCH 0030/6080] perfcounters, x86: fix sw counters on non-PMC CPUs Make perf_max_counters default to at least 1 - this allows the sw counters to be used. Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 59c52f9ee431..539fa8283a06 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -25,7 +25,7 @@ */ DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context); -int perf_max_counters __read_mostly; +int perf_max_counters __read_mostly = 1; static int perf_reserved_percpu __read_mostly; static int perf_overcommit __read_mostly = 1; -- GitLab From 75f224cf7700ed6006574dc3f2efa29860727570 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Dec 2008 21:58:46 +0100 Subject: [PATCH 0031/6080] perfcounters: fix lapic initialization Fix non-working NMI sampling in certain bootup scenarios. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 6d30f603b62c..8a154bd7ba94 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -557,10 +557,10 @@ void __init init_hw_perf_counters(void) printk(KERN_INFO "... bit_width: %d\n", eax.split.bit_width); printk(KERN_INFO "... mask_length: %d\n", eax.split.mask_length); + perf_counters_initialized = true; + perf_counters_lapic_init(0); register_die_notifier(&perf_counter_nmi_notifier); - - perf_counters_initialized = true; } static void x86_perf_counter_read(struct perf_counter *counter) -- GitLab From 0cc0c027d4e028632933f1be2dc4cd730358183b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Dec 2008 23:20:36 +0100 Subject: [PATCH 0032/6080] perfcounters: release CPU context when exiting task counters If counters are exiting via do_exit() not via filp close, then the CPU context needs to be released - otherwise future percpu counter creations might fail. Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 539fa8283a06..16396e9406fa 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1273,8 +1273,19 @@ __perf_counter_exit_task(struct task_struct *child, local_irq_disable(); perf_flags = hw_perf_save_disable(); - if (child_counter->state == PERF_COUNTER_STATE_ACTIVE) + if (child_counter->state == PERF_COUNTER_STATE_ACTIVE) { + struct perf_cpu_context *cpuctx; + + cpuctx = &__get_cpu_var(perf_cpu_context); + child_counter->hw_ops->hw_perf_counter_disable(child_counter); + child_counter->state = PERF_COUNTER_STATE_INACTIVE; + child_counter->oncpu = -1; + + cpuctx->active_oncpu--; + child_ctx->nr_active--; + } + list_del_init(&child_counter->list_entry); hw_perf_restore(perf_flags); @@ -1539,4 +1550,3 @@ static int __init perf_counter_sysfs_init(void) &perfclass_attr_group); } device_initcall(perf_counter_sysfs_init); - -- GitLab From f65cb45cba63f249458b669aa67069eabc37b2f5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 16 Dec 2008 13:40:44 +0100 Subject: [PATCH 0033/6080] perfcounters: flush on setuid exec Pavel Machek pointed out that performance counters should be flushed when crossing protection domains on setuid execution. Reported-by: Pavel Machek Acked-by: Pavel Machek Signed-off-by: Ingo Molnar --- fs/exec.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/exec.c b/fs/exec.c index ec5df9a38313..d5165d899a49 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -1017,6 +1018,13 @@ int flush_old_exec(struct linux_binprm * bprm) set_dumpable(current->mm, suid_dumpable); } + /* + * Flush performance counters when crossing a + * security domain: + */ + if (!get_dumpable(current->mm)) + perf_counter_exit_task(current); + /* An exec changes our domain. We are no longer part of the thread group */ -- GitLab From a86ed50859d65a08beec9474df97b88438a996df Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 17 Dec 2008 00:43:10 +0100 Subject: [PATCH 0034/6080] perfcounters: use hw_event.disable flag Impact: implement default-off counters Make sure that counters that are created with counter.hw_event.disabled=1, get created in disabled state. They can be enabled via: prctl(PR_TASK_PERF_COUNTERS_ENABLE); Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 16396e9406fa..5431e790b5d6 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1093,6 +1093,9 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, counter->group_leader = group_leader; counter->hw_ops = NULL; + if (hw_event->disabled) + counter->state = PERF_COUNTER_STATE_OFF; + hw_ops = NULL; if (!hw_event->raw && hw_event->type < 0) hw_ops = sw_perf_counter_init(counter); -- GitLab From 94c46572a6d9bb497eda0a14099d9f1360d57d5d Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Date: Fri, 19 Dec 2008 22:37:58 +0530 Subject: [PATCH 0035/6080] x86: perf_counter.c intel_perfmon_event_map and max_intel_perfmon_events should be static Impact: cleanup, avoid sparse warnings, reduce kernel size a bit Fixes these sparse warnings: arch/x86/kernel/cpu/perf_counter.c:44:11: warning: symbol 'intel_perfmon_event_map' was not declared. Should it be static? arch/x86/kernel/cpu/perf_counter.c:54:11: warning: symbol 'max_intel_perfmon_events' was not declared. Should it be static? Signed-off-by: Jaswinder Singh Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 8a154bd7ba94..bdbdb56eaa34 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -41,7 +41,7 @@ struct cpu_hw_counters { */ static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters); -const int intel_perfmon_event_map[] = +static const int intel_perfmon_event_map[] = { [PERF_COUNT_CYCLES] = 0x003c, [PERF_COUNT_INSTRUCTIONS] = 0x00c0, @@ -51,7 +51,7 @@ const int intel_perfmon_event_map[] = [PERF_COUNT_BRANCH_MISSES] = 0x00c5, }; -const int max_intel_perfmon_events = ARRAY_SIZE(intel_perfmon_event_map); +static const int max_intel_perfmon_events = ARRAY_SIZE(intel_perfmon_event_map); /* * Propagate counter elapsed time into the generic counter. -- GitLab From 8fb9331391af95ca1f4e5c0a0da8120b13cbae01 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 23 Dec 2008 12:04:16 +0100 Subject: [PATCH 0036/6080] perfcounters: remove warnings Impact: remove debug checks Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 7 ------- include/linux/perf_counter.h | 4 ---- kernel/perf_counter.c | 8 -------- 3 files changed, 19 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index bdbdb56eaa34..89fad5d4fb37 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -64,7 +64,6 @@ x86_perf_counter_update(struct perf_counter *counter, { u64 prev_raw_count, new_raw_count, delta; - WARN_ON_ONCE(counter->state != PERF_COUNTER_STATE_ACTIVE); /* * Careful: an NMI might modify the previous counter value. * @@ -89,7 +88,6 @@ again: * of the count, so we do that by clipping the delta to 32 bits: */ delta = (u64)(u32)((s32)new_raw_count - (s32)prev_raw_count); - WARN_ON_ONCE((int)delta < 0); atomic64_add(delta, &counter->count); atomic64_sub(delta, &hwc->period_left); @@ -193,7 +191,6 @@ __x86_perf_counter_disable(struct perf_counter *counter, int err; err = wrmsr_safe(hwc->config_base + idx, hwc->config, 0); - WARN_ON_ONCE(err); } static DEFINE_PER_CPU(u64, prev_left[MAX_HW_COUNTERS]); @@ -209,8 +206,6 @@ __hw_perf_counter_set_period(struct perf_counter *counter, s32 left = atomic64_read(&hwc->period_left); s32 period = hwc->irq_period; - WARN_ON_ONCE(period <= 0); - /* * If we are way outside a reasoable range then just skip forward: */ @@ -224,8 +219,6 @@ __hw_perf_counter_set_period(struct perf_counter *counter, atomic64_set(&hwc->period_left, left); } - WARN_ON_ONCE(left <= 0); - per_cpu(prev_left[idx], smp_processor_id()) = left; /* diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index f30486fc55d7..d038450de87d 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -218,8 +218,6 @@ struct perf_cpu_context { extern int perf_max_counters; #ifdef CONFIG_PERF_COUNTERS -extern void -perf_counter_show(struct perf_counter *counter, char *str, int trace); extern const struct hw_perf_counter_ops * hw_perf_counter_init(struct perf_counter *counter); @@ -237,8 +235,6 @@ extern int perf_counter_task_enable(void); #else static inline void -perf_counter_show(struct perf_counter *counter, char *str, int trace) { } -static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } static inline void perf_counter_task_sched_out(struct task_struct *task, int cpu) { } diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 5431e790b5d6..aab6c123b02c 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -861,8 +861,6 @@ static void task_clock_perf_counter_update(struct perf_counter *counter) atomic64_set(&counter->hw.prev_count, now); delta = now - prev; - if (WARN_ON_ONCE(delta < 0)) - delta = 0; atomic64_add(delta, &counter->count); } @@ -906,8 +904,6 @@ static void page_faults_perf_counter_update(struct perf_counter *counter) atomic64_set(&counter->hw.prev_count, now); delta = now - prev; - if (WARN_ON_ONCE(delta < 0)) - delta = 0; atomic64_add(delta, &counter->count); } @@ -954,8 +950,6 @@ static void context_switches_perf_counter_update(struct perf_counter *counter) atomic64_set(&counter->hw.prev_count, now); delta = now - prev; - if (WARN_ON_ONCE(delta < 0)) - delta = 0; atomic64_add(delta, &counter->count); } @@ -1000,8 +994,6 @@ static void cpu_migrations_perf_counter_update(struct perf_counter *counter) atomic64_set(&counter->hw.prev_count, now); delta = now - prev; - if (WARN_ON_ONCE(delta < 0)) - delta = 0; atomic64_add(delta, &counter->count); } -- GitLab From 7995888fcb0246543ee8027bf2835a250ba8c925 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 17 Dec 2008 08:54:56 +0100 Subject: [PATCH 0037/6080] perfcounters: tweak group scheduling Impact: schedule in groups atomically If there are multiple groups in a task, make sure they are scheduled in and out atomically. Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index aab6c123b02c..f8a4d9a5d5d3 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -367,21 +367,26 @@ counter_sched_in(struct perf_counter *counter, ctx->nr_active++; } -static void +static int group_sched_in(struct perf_counter *group_counter, struct perf_cpu_context *cpuctx, struct perf_counter_context *ctx, int cpu) { struct perf_counter *counter; + int was_group = 0; counter_sched_in(group_counter, cpuctx, ctx, cpu); /* * Schedule in siblings as one group (if any): */ - list_for_each_entry(counter, &group_counter->sibling_list, list_entry) + list_for_each_entry(counter, &group_counter->sibling_list, list_entry) { counter_sched_in(counter, cpuctx, ctx, cpu); + was_group = 1; + } + + return was_group; } /* @@ -416,7 +421,12 @@ void perf_counter_task_sched_in(struct task_struct *task, int cpu) if (counter->cpu != -1 && counter->cpu != cpu) continue; - group_sched_in(counter, cpuctx, ctx, cpu); + /* + * If we scheduled in a group atomically and + * exclusively, break out: + */ + if (group_sched_in(counter, cpuctx, ctx, cpu)) + break; } spin_unlock(&ctx->lock); -- GitLab From 5c167b8585c8d91206b395d57011ead7711e322f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 17 Dec 2008 09:02:19 +0100 Subject: [PATCH 0038/6080] x86, perfcounters: rename intel_arch_perfmon.h => perf_counter.h Impact: rename include file We'll be providing an asm/perf_counter.h to the generic perfcounter code, so use the already existing x86 file for this purpose and rename it. Signed-off-by: Ingo Molnar --- .../include/asm/{intel_arch_perfmon.h => perf_counter.h} | 6 +++--- arch/x86/kernel/apic.c | 2 +- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/cpu/perf_counter.c | 2 +- arch/x86/kernel/cpu/perfctr-watchdog.c | 2 +- arch/x86/oprofile/op_model_ppro.c | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename arch/x86/include/asm/{intel_arch_perfmon.h => perf_counter.h} (90%) diff --git a/arch/x86/include/asm/intel_arch_perfmon.h b/arch/x86/include/asm/perf_counter.h similarity index 90% rename from arch/x86/include/asm/intel_arch_perfmon.h rename to arch/x86/include/asm/perf_counter.h index 71598a9eab61..9dadce1124ee 100644 --- a/arch/x86/include/asm/intel_arch_perfmon.h +++ b/arch/x86/include/asm/perf_counter.h @@ -1,5 +1,5 @@ -#ifndef _ASM_X86_INTEL_ARCH_PERFMON_H -#define _ASM_X86_INTEL_ARCH_PERFMON_H +#ifndef _ASM_X86_PERF_COUNTER_H +#define _ASM_X86_PERF_COUNTER_H #define MSR_ARCH_PERFMON_PERFCTR0 0xc1 #define MSR_ARCH_PERFMON_PERFCTR1 0xc2 @@ -38,4 +38,4 @@ static inline void init_hw_perf_counters(void) { } static inline void perf_counters_lapic_init(int nmi) { } #endif -#endif /* _ASM_X86_INTEL_ARCH_PERFMON_H */ +#endif /* _ASM_X86_PERF_COUNTER_H */ diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 0579ec1cd6e3..4f859acb1563 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 4461011db47c..ad331b4d6238 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 89fad5d4fb37..a4a3a09a654b 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -16,7 +16,7 @@ #include #include -#include +#include #include static bool perf_counters_initialized __read_mostly; diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index 9abd48b22674..d6f5b9fbde32 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c @@ -20,7 +20,7 @@ #include #include -#include +#include struct nmi_watchdog_ctlblk { unsigned int cccr_msr; diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index e9f80c744cf3..07c914555a5e 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include "op_x86_model.h" #include "op_counter.h" -- GitLab From eb2b861810d4ff72454c83996b891df4e0aaff9a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 17 Dec 2008 09:09:13 +0100 Subject: [PATCH 0039/6080] x86, perfcounters: prepare for fixed-mode PMCs Impact: refactor the x86 code for fixed-mode PMCs Extend the data structures and rename the existing facilities to allow for a 'generic' versus 'fixed' counter distinction. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_counter.h | 11 ++++++ arch/x86/kernel/cpu/perf_counter.c | 53 ++++++++++++++--------------- include/linux/perf_counter.h | 1 + 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h index 9dadce1124ee..dd5a4a559e2d 100644 --- a/arch/x86/include/asm/perf_counter.h +++ b/arch/x86/include/asm/perf_counter.h @@ -1,6 +1,13 @@ #ifndef _ASM_X86_PERF_COUNTER_H #define _ASM_X86_PERF_COUNTER_H +/* + * Performance counter hw details: + */ + +#define X86_PMC_MAX_GENERIC 8 +#define X86_PMC_MAX_FIXED 3 + #define MSR_ARCH_PERFMON_PERFCTR0 0xc1 #define MSR_ARCH_PERFMON_PERFCTR1 0xc2 @@ -20,6 +27,10 @@ #define ARCH_PERFMON_BRANCH_MISSES_RETIRED 6 +/* + * Intel "Architectural Performance Monitoring" CPUID + * detection/enumeration details: + */ union cpuid10_eax { struct { unsigned int version_id:8; diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index a4a3a09a654b..fc3af8688232 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -27,13 +27,12 @@ static bool perf_counters_initialized __read_mostly; static int nr_hw_counters __read_mostly; static u32 perf_counter_mask __read_mostly; -/* No support for fixed function counters yet */ - -#define MAX_HW_COUNTERS 8 - struct cpu_hw_counters { - struct perf_counter *counters[MAX_HW_COUNTERS]; - unsigned long used[BITS_TO_LONGS(MAX_HW_COUNTERS)]; + struct perf_counter *generic[X86_PMC_MAX_GENERIC]; + unsigned long used[BITS_TO_LONGS(X86_PMC_MAX_GENERIC)]; + + struct perf_counter *fixed[X86_PMC_MAX_FIXED]; + unsigned long used_fixed[BITS_TO_LONGS(X86_PMC_MAX_FIXED)]; }; /* @@ -185,7 +184,7 @@ void hw_perf_restore(u64 ctrl) EXPORT_SYMBOL_GPL(hw_perf_restore); static inline void -__x86_perf_counter_disable(struct perf_counter *counter, +__pmc_generic_disable(struct perf_counter *counter, struct hw_perf_counter *hwc, unsigned int idx) { int err; @@ -193,7 +192,7 @@ __x86_perf_counter_disable(struct perf_counter *counter, err = wrmsr_safe(hwc->config_base + idx, hwc->config, 0); } -static DEFINE_PER_CPU(u64, prev_left[MAX_HW_COUNTERS]); +static DEFINE_PER_CPU(u64, prev_left[X86_PMC_MAX_GENERIC]); /* * Set the next IRQ period, based on the hwc->period_left value. @@ -231,7 +230,7 @@ __hw_perf_counter_set_period(struct perf_counter *counter, } static void -__x86_perf_counter_enable(struct perf_counter *counter, +__pmc_generic_enable(struct perf_counter *counter, struct hw_perf_counter *hwc, int idx) { wrmsr(hwc->config_base + idx, @@ -241,7 +240,7 @@ __x86_perf_counter_enable(struct perf_counter *counter, /* * Find a PMC slot for the freshly enabled / scheduled in counter: */ -static void x86_perf_counter_enable(struct perf_counter *counter) +static void pmc_generic_enable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); struct hw_perf_counter *hwc = &counter->hw; @@ -256,12 +255,12 @@ static void x86_perf_counter_enable(struct perf_counter *counter) perf_counters_lapic_init(hwc->nmi); - __x86_perf_counter_disable(counter, hwc, idx); + __pmc_generic_disable(counter, hwc, idx); - cpuc->counters[idx] = counter; + cpuc->generic[idx] = counter; __hw_perf_counter_set_period(counter, hwc, idx); - __x86_perf_counter_enable(counter, hwc, idx); + __pmc_generic_enable(counter, hwc, idx); } void perf_counter_print_debug(void) @@ -301,16 +300,16 @@ void perf_counter_print_debug(void) local_irq_enable(); } -static void x86_perf_counter_disable(struct perf_counter *counter) +static void pmc_generic_disable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); struct hw_perf_counter *hwc = &counter->hw; unsigned int idx = hwc->idx; - __x86_perf_counter_disable(counter, hwc, idx); + __pmc_generic_disable(counter, hwc, idx); clear_bit(idx, cpuc->used); - cpuc->counters[idx] = NULL; + cpuc->generic[idx] = NULL; /* * Drain the remaining delta count out of a counter @@ -349,7 +348,7 @@ static void perf_save_and_restart(struct perf_counter *counter) __hw_perf_counter_set_period(counter, hwc, idx); if (pmc_ctrl & ARCH_PERFMON_EVENTSEL0_ENABLE) - __x86_perf_counter_enable(counter, hwc, idx); + __pmc_generic_enable(counter, hwc, idx); } static void @@ -392,7 +391,7 @@ static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) again: ack = status; for_each_bit(bit, (unsigned long *) &status, nr_hw_counters) { - struct perf_counter *counter = cpuc->counters[bit]; + struct perf_counter *counter = cpuc->generic[bit]; clear_bit(bit, (unsigned long *) &status); if (!counter) @@ -412,7 +411,7 @@ again: } /* * From NMI context we cannot call into the scheduler to - * do a task wakeup - but we mark these counters as + * do a task wakeup - but we mark these generic as * wakeup_pending and initate a wakeup callback: */ if (nmi) { @@ -462,7 +461,7 @@ void perf_counter_notify(struct pt_regs *regs) cpuc = &per_cpu(cpu_hw_counters, cpu); for_each_bit(bit, cpuc->used, nr_hw_counters) { - struct perf_counter *counter = cpuc->counters[bit]; + struct perf_counter *counter = cpuc->generic[bit]; if (!counter) continue; @@ -539,10 +538,10 @@ void __init init_hw_perf_counters(void) printk(KERN_INFO "... version: %d\n", eax.split.version_id); printk(KERN_INFO "... num_counters: %d\n", eax.split.num_counters); nr_hw_counters = eax.split.num_counters; - if (nr_hw_counters > MAX_HW_COUNTERS) { - nr_hw_counters = MAX_HW_COUNTERS; + if (nr_hw_counters > X86_PMC_MAX_GENERIC) { + nr_hw_counters = X86_PMC_MAX_GENERIC; WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", - nr_hw_counters, MAX_HW_COUNTERS); + nr_hw_counters, X86_PMC_MAX_GENERIC); } perf_counter_mask = (1 << nr_hw_counters) - 1; perf_max_counters = nr_hw_counters; @@ -556,15 +555,15 @@ void __init init_hw_perf_counters(void) register_die_notifier(&perf_counter_nmi_notifier); } -static void x86_perf_counter_read(struct perf_counter *counter) +static void pmc_generic_read(struct perf_counter *counter) { x86_perf_counter_update(counter, &counter->hw, counter->hw.idx); } static const struct hw_perf_counter_ops x86_perf_counter_ops = { - .hw_perf_counter_enable = x86_perf_counter_enable, - .hw_perf_counter_disable = x86_perf_counter_disable, - .hw_perf_counter_read = x86_perf_counter_read, + .hw_perf_counter_enable = pmc_generic_enable, + .hw_perf_counter_disable = pmc_generic_disable, + .hw_perf_counter_read = pmc_generic_read, }; const struct hw_perf_counter_ops * diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index d038450de87d..984da540224b 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -14,6 +14,7 @@ #define _LINUX_PERF_COUNTER_H #include +#include #include #include -- GitLab From 703e937c83bbad79075a7846e062e447c2fee6a4 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 17 Dec 2008 10:51:15 +0100 Subject: [PATCH 0040/6080] perfcounters: add fixed-mode PMC enumeration Enumerate fixed-mode PMCs based on CPUID, and feed that into the perfcounter code. Does not use fixed-mode PMCs yet. Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_counter.h | 23 +++++++++++++++++++++++ arch/x86/kernel/cpu/perf_counter.c | 23 +++++++++++++++++------ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h index dd5a4a559e2d..945a315e6d62 100644 --- a/arch/x86/include/asm/perf_counter.h +++ b/arch/x86/include/asm/perf_counter.h @@ -41,6 +41,29 @@ union cpuid10_eax { unsigned int full; }; +union cpuid10_edx { + struct { + unsigned int num_counters_fixed:4; + unsigned int reserved:28; + } split; + unsigned int full; +}; + + +/* + * Fixed-purpose performance counters: + */ + +/* Instr_Retired.Any: */ +#define MSR_ARCH_PERFMON_FIXED_CTR0 0x309 + +/* CPU_CLK_Unhalted.Core: */ +#define MSR_ARCH_PERFMON_FIXED_CTR1 0x30a + +/* CPU_CLK_Unhalted.Ref: */ +#define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b + + #ifdef CONFIG_PERF_COUNTERS extern void init_hw_perf_counters(void); extern void perf_counters_lapic_init(int nmi); diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index fc3af8688232..2fca50c45979 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -27,6 +27,8 @@ static bool perf_counters_initialized __read_mostly; static int nr_hw_counters __read_mostly; static u32 perf_counter_mask __read_mostly; +static int nr_hw_counters_fixed __read_mostly; + struct cpu_hw_counters { struct perf_counter *generic[X86_PMC_MAX_GENERIC]; unsigned long used[BITS_TO_LONGS(X86_PMC_MAX_GENERIC)]; @@ -519,8 +521,9 @@ static __read_mostly struct notifier_block perf_counter_nmi_notifier = { void __init init_hw_perf_counters(void) { union cpuid10_eax eax; - unsigned int unused; unsigned int ebx; + unsigned int unused; + union cpuid10_edx edx; if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) return; @@ -529,14 +532,14 @@ void __init init_hw_perf_counters(void) * Check whether the Architectural PerfMon supports * Branch Misses Retired Event or not. */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); + cpuid(10, &eax.full, &ebx, &unused, &edx.full); if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED) return; printk(KERN_INFO "Intel Performance Monitoring support detected.\n"); - printk(KERN_INFO "... version: %d\n", eax.split.version_id); - printk(KERN_INFO "... num_counters: %d\n", eax.split.num_counters); + printk(KERN_INFO "... version: %d\n", eax.split.version_id); + printk(KERN_INFO "... num counters: %d\n", eax.split.num_counters); nr_hw_counters = eax.split.num_counters; if (nr_hw_counters > X86_PMC_MAX_GENERIC) { nr_hw_counters = X86_PMC_MAX_GENERIC; @@ -546,8 +549,16 @@ void __init init_hw_perf_counters(void) perf_counter_mask = (1 << nr_hw_counters) - 1; perf_max_counters = nr_hw_counters; - printk(KERN_INFO "... bit_width: %d\n", eax.split.bit_width); - printk(KERN_INFO "... mask_length: %d\n", eax.split.mask_length); + printk(KERN_INFO "... bit width: %d\n", eax.split.bit_width); + printk(KERN_INFO "... mask length: %d\n", eax.split.mask_length); + + nr_hw_counters_fixed = edx.split.num_counters_fixed; + if (nr_hw_counters_fixed > X86_PMC_MAX_FIXED) { + nr_hw_counters_fixed = X86_PMC_MAX_FIXED; + WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!", + nr_hw_counters_fixed, X86_PMC_MAX_FIXED); + } + printk(KERN_INFO "... fixed counters: %d\n", nr_hw_counters_fixed); perf_counters_initialized = true; -- GitLab From 862a1a5f346fe7e9181ea51eaae48cf2cd70f746 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 17 Dec 2008 13:09:20 +0100 Subject: [PATCH 0041/6080] x86, perfcounters: refactor code for fixed-function PMCs Impact: clean up Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_counter.h | 14 +++++- arch/x86/kernel/cpu/perf_counter.c | 73 +++++++++++++++-------------- 2 files changed, 52 insertions(+), 35 deletions(-) diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h index 945a315e6d62..13745deb16c8 100644 --- a/arch/x86/include/asm/perf_counter.h +++ b/arch/x86/include/asm/perf_counter.h @@ -8,6 +8,10 @@ #define X86_PMC_MAX_GENERIC 8 #define X86_PMC_MAX_FIXED 3 +#define X86_PMC_IDX_GENERIC 0 +#define X86_PMC_IDX_FIXED 32 +#define X86_PMC_IDX_MAX 64 + #define MSR_ARCH_PERFMON_PERFCTR0 0xc1 #define MSR_ARCH_PERFMON_PERFCTR1 0xc2 @@ -54,6 +58,15 @@ union cpuid10_edx { * Fixed-purpose performance counters: */ +/* + * All 3 fixed-mode PMCs are configured via this single MSR: + */ +#define MSR_ARCH_PERFMON_FIXED_CTR_CTRL 0x38d + +/* + * The counts are available in three separate MSRs: + */ + /* Instr_Retired.Any: */ #define MSR_ARCH_PERFMON_FIXED_CTR0 0x309 @@ -63,7 +76,6 @@ union cpuid10_edx { /* CPU_CLK_Unhalted.Ref: */ #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b - #ifdef CONFIG_PERF_COUNTERS extern void init_hw_perf_counters(void); extern void perf_counters_lapic_init(int nmi); diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 2fca50c45979..358af5266407 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -24,17 +24,14 @@ static bool perf_counters_initialized __read_mostly; /* * Number of (generic) HW counters: */ -static int nr_hw_counters __read_mostly; -static u32 perf_counter_mask __read_mostly; +static int nr_counters_generic __read_mostly; +static u64 perf_counter_mask __read_mostly; -static int nr_hw_counters_fixed __read_mostly; +static int nr_counters_fixed __read_mostly; struct cpu_hw_counters { - struct perf_counter *generic[X86_PMC_MAX_GENERIC]; - unsigned long used[BITS_TO_LONGS(X86_PMC_MAX_GENERIC)]; - - struct perf_counter *fixed[X86_PMC_MAX_FIXED]; - unsigned long used_fixed[BITS_TO_LONGS(X86_PMC_MAX_FIXED)]; + struct perf_counter *counters[X86_PMC_IDX_MAX]; + unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; }; /* @@ -159,7 +156,7 @@ void hw_perf_enable_all(void) if (unlikely(!perf_counters_initialized)) return; - wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask, 0); + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask); } u64 hw_perf_save_disable(void) @@ -170,7 +167,7 @@ u64 hw_perf_save_disable(void) return 0; rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); - wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); return ctrl; } @@ -181,7 +178,7 @@ void hw_perf_restore(u64 ctrl) if (unlikely(!perf_counters_initialized)) return; - wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, ctrl, 0); + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); } EXPORT_SYMBOL_GPL(hw_perf_restore); @@ -239,6 +236,11 @@ __pmc_generic_enable(struct perf_counter *counter, hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0); } +static int fixed_mode_idx(struct hw_perf_counter *hwc) +{ + return -1; +} + /* * Find a PMC slot for the freshly enabled / scheduled in counter: */ @@ -250,7 +252,7 @@ static void pmc_generic_enable(struct perf_counter *counter) /* Try to get the previous counter again */ if (test_and_set_bit(idx, cpuc->used)) { - idx = find_first_zero_bit(cpuc->used, nr_hw_counters); + idx = find_first_zero_bit(cpuc->used, nr_counters_generic); set_bit(idx, cpuc->used); hwc->idx = idx; } @@ -259,7 +261,7 @@ static void pmc_generic_enable(struct perf_counter *counter) __pmc_generic_disable(counter, hwc, idx); - cpuc->generic[idx] = counter; + cpuc->counters[idx] = counter; __hw_perf_counter_set_period(counter, hwc, idx); __pmc_generic_enable(counter, hwc, idx); @@ -270,7 +272,7 @@ void perf_counter_print_debug(void) u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left; int cpu, idx; - if (!nr_hw_counters) + if (!nr_counters_generic) return; local_irq_disable(); @@ -286,7 +288,7 @@ void perf_counter_print_debug(void) printk(KERN_INFO "CPU#%d: status: %016llx\n", cpu, status); printk(KERN_INFO "CPU#%d: overflow: %016llx\n", cpu, overflow); - for (idx = 0; idx < nr_hw_counters; idx++) { + for (idx = 0; idx < nr_counters_generic; idx++) { rdmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, pmc_ctrl); rdmsrl(MSR_ARCH_PERFMON_PERFCTR0 + idx, pmc_count); @@ -311,7 +313,7 @@ static void pmc_generic_disable(struct perf_counter *counter) __pmc_generic_disable(counter, hwc, idx); clear_bit(idx, cpuc->used); - cpuc->generic[idx] = NULL; + cpuc->counters[idx] = NULL; /* * Drain the remaining delta count out of a counter @@ -381,7 +383,7 @@ static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, saved_global); /* Disable counters globally */ - wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, 0, 0); + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); ack_APIC_irq(); cpuc = &per_cpu(cpu_hw_counters, cpu); @@ -392,8 +394,8 @@ static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) again: ack = status; - for_each_bit(bit, (unsigned long *) &status, nr_hw_counters) { - struct perf_counter *counter = cpuc->generic[bit]; + for_each_bit(bit, (unsigned long *) &status, nr_counters_generic) { + struct perf_counter *counter = cpuc->counters[bit]; clear_bit(bit, (unsigned long *) &status); if (!counter) @@ -424,7 +426,7 @@ again: } } - wrmsr(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack, 0); + wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack); /* * Repeat if there is more work to be done: @@ -436,7 +438,7 @@ out: /* * Restore - do not reenable when global enable is off: */ - wrmsr(MSR_CORE_PERF_GLOBAL_CTRL, saved_global, 0); + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, saved_global); } void smp_perf_counter_interrupt(struct pt_regs *regs) @@ -462,8 +464,8 @@ void perf_counter_notify(struct pt_regs *regs) cpu = smp_processor_id(); cpuc = &per_cpu(cpu_hw_counters, cpu); - for_each_bit(bit, cpuc->used, nr_hw_counters) { - struct perf_counter *counter = cpuc->generic[bit]; + for_each_bit(bit, cpuc->used, X86_PMC_IDX_MAX) { + struct perf_counter *counter = cpuc->counters[bit]; if (!counter) continue; @@ -540,26 +542,29 @@ void __init init_hw_perf_counters(void) printk(KERN_INFO "... version: %d\n", eax.split.version_id); printk(KERN_INFO "... num counters: %d\n", eax.split.num_counters); - nr_hw_counters = eax.split.num_counters; - if (nr_hw_counters > X86_PMC_MAX_GENERIC) { - nr_hw_counters = X86_PMC_MAX_GENERIC; + nr_counters_generic = eax.split.num_counters; + if (nr_counters_generic > X86_PMC_MAX_GENERIC) { + nr_counters_generic = X86_PMC_MAX_GENERIC; WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", - nr_hw_counters, X86_PMC_MAX_GENERIC); + nr_counters_generic, X86_PMC_MAX_GENERIC); } - perf_counter_mask = (1 << nr_hw_counters) - 1; - perf_max_counters = nr_hw_counters; + perf_counter_mask = (1 << nr_counters_generic) - 1; + perf_max_counters = nr_counters_generic; printk(KERN_INFO "... bit width: %d\n", eax.split.bit_width); printk(KERN_INFO "... mask length: %d\n", eax.split.mask_length); - nr_hw_counters_fixed = edx.split.num_counters_fixed; - if (nr_hw_counters_fixed > X86_PMC_MAX_FIXED) { - nr_hw_counters_fixed = X86_PMC_MAX_FIXED; + nr_counters_fixed = edx.split.num_counters_fixed; + if (nr_counters_fixed > X86_PMC_MAX_FIXED) { + nr_counters_fixed = X86_PMC_MAX_FIXED; WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!", - nr_hw_counters_fixed, X86_PMC_MAX_FIXED); + nr_counters_fixed, X86_PMC_MAX_FIXED); } - printk(KERN_INFO "... fixed counters: %d\n", nr_hw_counters_fixed); + printk(KERN_INFO "... fixed counters: %d\n", nr_counters_fixed); + + perf_counter_mask |= ((1LL << nr_counters_fixed)-1) << X86_PMC_IDX_FIXED; + printk(KERN_INFO "... counter mask: %016Lx\n", perf_counter_mask); perf_counters_initialized = true; perf_counters_lapic_init(0); -- GitLab From 7671581f1666ef4b54a1c1e598c51ac44c060a9b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 17 Dec 2008 14:20:28 +0100 Subject: [PATCH 0042/6080] perfcounters: hw ops rename Impact: rename field names Shorten them. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 6 ++-- include/linux/perf_counter.h | 6 ++-- kernel/perf_counter.c | 50 +++++++++++++++--------------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 358af5266407..b67557121425 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -577,9 +577,9 @@ static void pmc_generic_read(struct perf_counter *counter) } static const struct hw_perf_counter_ops x86_perf_counter_ops = { - .hw_perf_counter_enable = pmc_generic_enable, - .hw_perf_counter_disable = pmc_generic_disable, - .hw_perf_counter_read = pmc_generic_read, + .enable = pmc_generic_enable, + .disable = pmc_generic_disable, + .read = pmc_generic_read, }; const struct hw_perf_counter_ops * diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 984da540224b..48f76d2e54c2 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -128,9 +128,9 @@ struct perf_counter; * struct hw_perf_counter_ops - performance counter hw ops */ struct hw_perf_counter_ops { - void (*hw_perf_counter_enable) (struct perf_counter *counter); - void (*hw_perf_counter_disable) (struct perf_counter *counter); - void (*hw_perf_counter_read) (struct perf_counter *counter); + void (*enable) (struct perf_counter *counter); + void (*disable) (struct perf_counter *counter); + void (*read) (struct perf_counter *counter); }; /** diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f8a4d9a5d5d3..961d651aa574 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -109,7 +109,7 @@ static void __perf_counter_remove_from_context(void *info) spin_lock_irqsave(&ctx->lock, flags); if (counter->state == PERF_COUNTER_STATE_ACTIVE) { - counter->hw_ops->hw_perf_counter_disable(counter); + counter->hw_ops->disable(counter); counter->state = PERF_COUNTER_STATE_INACTIVE; ctx->nr_active--; cpuctx->active_oncpu--; @@ -226,7 +226,7 @@ static void __perf_install_in_context(void *info) counter->oncpu = cpu; ctx->nr_active++; cpuctx->active_oncpu++; - counter->hw_ops->hw_perf_counter_enable(counter); + counter->hw_ops->enable(counter); } if (!ctx->task && cpuctx->max_pertask) @@ -297,7 +297,7 @@ counter_sched_out(struct perf_counter *counter, if (counter->state != PERF_COUNTER_STATE_ACTIVE) return; - counter->hw_ops->hw_perf_counter_disable(counter); + counter->hw_ops->disable(counter); counter->state = PERF_COUNTER_STATE_INACTIVE; counter->oncpu = -1; @@ -327,7 +327,7 @@ group_sched_out(struct perf_counter *group_counter, * * We stop each counter and update the counter value in counter->count. * - * This does not protect us against NMI, but hw_perf_counter_disable() + * This does not protect us against NMI, but disable() * sets the disabled bit in the control field of counter _before_ * accessing the counter control register. If a NMI hits, then it will * not restart the counter. @@ -359,7 +359,7 @@ counter_sched_in(struct perf_counter *counter, if (counter->state == PERF_COUNTER_STATE_OFF) return; - counter->hw_ops->hw_perf_counter_enable(counter); + counter->hw_ops->enable(counter); counter->state = PERF_COUNTER_STATE_ACTIVE; counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ @@ -395,7 +395,7 @@ group_sched_in(struct perf_counter *group_counter, * * We restore the counter value and then enable it. * - * This does not protect us against NMI, but hw_perf_counter_enable() + * This does not protect us against NMI, but enable() * sets the enabled bit in the control field of counter _before_ * accessing the counter control register. If a NMI hits, then it will * keep the counter running. @@ -537,11 +537,11 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) /* * Cross CPU call to read the hardware counter */ -static void __hw_perf_counter_read(void *info) +static void __read(void *info) { struct perf_counter *counter = info; - counter->hw_ops->hw_perf_counter_read(counter); + counter->hw_ops->read(counter); } static u64 perf_counter_read(struct perf_counter *counter) @@ -552,7 +552,7 @@ static u64 perf_counter_read(struct perf_counter *counter) */ if (counter->state == PERF_COUNTER_STATE_ACTIVE) { smp_call_function_single(counter->oncpu, - __hw_perf_counter_read, counter, 1); + __read, counter, 1); } return atomic64_read(&counter->count); @@ -855,9 +855,9 @@ static void cpu_clock_perf_counter_read(struct perf_counter *counter) } static const struct hw_perf_counter_ops perf_ops_cpu_clock = { - .hw_perf_counter_enable = cpu_clock_perf_counter_enable, - .hw_perf_counter_disable = cpu_clock_perf_counter_disable, - .hw_perf_counter_read = cpu_clock_perf_counter_read, + .enable = cpu_clock_perf_counter_enable, + .disable = cpu_clock_perf_counter_disable, + .read = cpu_clock_perf_counter_read, }; static void task_clock_perf_counter_update(struct perf_counter *counter) @@ -891,9 +891,9 @@ static void task_clock_perf_counter_disable(struct perf_counter *counter) } static const struct hw_perf_counter_ops perf_ops_task_clock = { - .hw_perf_counter_enable = task_clock_perf_counter_enable, - .hw_perf_counter_disable = task_clock_perf_counter_disable, - .hw_perf_counter_read = task_clock_perf_counter_read, + .enable = task_clock_perf_counter_enable, + .disable = task_clock_perf_counter_disable, + .read = task_clock_perf_counter_read, }; static u64 get_page_faults(void) @@ -937,9 +937,9 @@ static void page_faults_perf_counter_disable(struct perf_counter *counter) } static const struct hw_perf_counter_ops perf_ops_page_faults = { - .hw_perf_counter_enable = page_faults_perf_counter_enable, - .hw_perf_counter_disable = page_faults_perf_counter_disable, - .hw_perf_counter_read = page_faults_perf_counter_read, + .enable = page_faults_perf_counter_enable, + .disable = page_faults_perf_counter_disable, + .read = page_faults_perf_counter_read, }; static u64 get_context_switches(void) @@ -983,9 +983,9 @@ static void context_switches_perf_counter_disable(struct perf_counter *counter) } static const struct hw_perf_counter_ops perf_ops_context_switches = { - .hw_perf_counter_enable = context_switches_perf_counter_enable, - .hw_perf_counter_disable = context_switches_perf_counter_disable, - .hw_perf_counter_read = context_switches_perf_counter_read, + .enable = context_switches_perf_counter_enable, + .disable = context_switches_perf_counter_disable, + .read = context_switches_perf_counter_read, }; static inline u64 get_cpu_migrations(void) @@ -1027,9 +1027,9 @@ static void cpu_migrations_perf_counter_disable(struct perf_counter *counter) } static const struct hw_perf_counter_ops perf_ops_cpu_migrations = { - .hw_perf_counter_enable = cpu_migrations_perf_counter_enable, - .hw_perf_counter_disable = cpu_migrations_perf_counter_disable, - .hw_perf_counter_read = cpu_migrations_perf_counter_read, + .enable = cpu_migrations_perf_counter_enable, + .disable = cpu_migrations_perf_counter_disable, + .read = cpu_migrations_perf_counter_read, }; static const struct hw_perf_counter_ops * @@ -1283,7 +1283,7 @@ __perf_counter_exit_task(struct task_struct *child, cpuctx = &__get_cpu_var(perf_cpu_context); - child_counter->hw_ops->hw_perf_counter_disable(child_counter); + child_counter->hw_ops->disable(child_counter); child_counter->state = PERF_COUNTER_STATE_INACTIVE; child_counter->oncpu = -1; -- GitLab From aa9c4c0f967fdb482ea95e8473ec3d201e6e0781 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 17 Dec 2008 14:10:57 +0100 Subject: [PATCH 0043/6080] perfcounters: fix task clock counter Impact: fix per task clock counter precision Signed-off-by: Ingo Molnar --- include/linux/kernel_stat.h | 8 +++++ kernel/exit.c | 17 ++++++--- kernel/perf_counter.c | 70 ++++++++++++++++++++++++++++--------- kernel/sched.c | 49 ++++++++++++++++++++++++-- 4 files changed, 120 insertions(+), 24 deletions(-) diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 4a145caeee07..1b2e3242497c 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -66,7 +66,15 @@ static inline unsigned int kstat_irqs(unsigned int irq) return sum; } + +/* + * Lock/unlock the current runqueue - to extract task statistics: + */ +extern void curr_rq_lock_irq_save(unsigned long *flags); +extern void curr_rq_unlock_irq_restore(unsigned long *flags); +extern unsigned long long __task_delta_exec(struct task_struct *tsk, int update); extern unsigned long long task_delta_exec(struct task_struct *); + extern void account_user_time(struct task_struct *, cputime_t); extern void account_user_time_scaled(struct task_struct *, cputime_t); extern void account_system_time(struct task_struct *, int, cputime_t); diff --git a/kernel/exit.c b/kernel/exit.c index d336c90a5f13..244edfd96865 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -922,6 +922,12 @@ static void exit_notify(struct task_struct *tsk, int group_dead) forget_original_parent(tsk); exit_task_namespaces(tsk); + /* + * Flush inherited counters to the parent - before the parent + * gets woken up by child-exit notifications. + */ + perf_counter_exit_task(tsk); + write_lock_irq(&tasklist_lock); if (group_dead) kill_orphaned_pgrp(tsk->group_leader, NULL); @@ -1093,11 +1099,6 @@ NORET_TYPE void do_exit(long code) mpol_put(tsk->mempolicy); tsk->mempolicy = NULL; #endif - /* - * These must happen late, after the PID is not - * hashed anymore, but still at a point that may sleep: - */ - perf_counter_exit_task(tsk); #ifdef CONFIG_FUTEX if (unlikely(!list_empty(&tsk->pi_state_list))) exit_pi_state_list(tsk); @@ -1121,6 +1122,12 @@ NORET_TYPE void do_exit(long code) if (tsk->splice_pipe) __free_pipe_info(tsk->splice_pipe); + /* + * These must happen late, after the PID is not + * hashed anymore, but still at a point that may sleep: + */ + perf_counter_exit_task(tsk); + preempt_disable(); /* causes final put_task_struct in finish_task_switch(). */ tsk->state = TASK_DEAD; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 961d651aa574..f1110ac1267b 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -18,6 +18,7 @@ #include #include #include +#include #include /* @@ -106,7 +107,8 @@ static void __perf_counter_remove_from_context(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - spin_lock_irqsave(&ctx->lock, flags); + curr_rq_lock_irq_save(&flags); + spin_lock(&ctx->lock); if (counter->state == PERF_COUNTER_STATE_ACTIVE) { counter->hw_ops->disable(counter); @@ -135,7 +137,8 @@ static void __perf_counter_remove_from_context(void *info) perf_max_counters - perf_reserved_percpu); } - spin_unlock_irqrestore(&ctx->lock, flags); + spin_unlock(&ctx->lock); + curr_rq_unlock_irq_restore(&flags); } @@ -209,7 +212,8 @@ static void __perf_install_in_context(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - spin_lock_irqsave(&ctx->lock, flags); + curr_rq_lock_irq_save(&flags); + spin_lock(&ctx->lock); /* * Protect the list operation against NMI by disabling the @@ -232,7 +236,8 @@ static void __perf_install_in_context(void *info) if (!ctx->task && cpuctx->max_pertask) cpuctx->max_pertask--; - spin_unlock_irqrestore(&ctx->lock, flags); + spin_unlock(&ctx->lock); + curr_rq_unlock_irq_restore(&flags); } /* @@ -438,15 +443,19 @@ int perf_counter_task_disable(void) struct task_struct *curr = current; struct perf_counter_context *ctx = &curr->perf_counter_ctx; struct perf_counter *counter; + unsigned long flags; u64 perf_flags; int cpu; if (likely(!ctx->nr_counters)) return 0; - local_irq_disable(); + curr_rq_lock_irq_save(&flags); cpu = smp_processor_id(); + /* force the update of the task clock: */ + __task_delta_exec(curr, 1); + perf_counter_task_sched_out(curr, cpu); spin_lock(&ctx->lock); @@ -463,7 +472,7 @@ int perf_counter_task_disable(void) spin_unlock(&ctx->lock); - local_irq_enable(); + curr_rq_unlock_irq_restore(&flags); return 0; } @@ -473,15 +482,19 @@ int perf_counter_task_enable(void) struct task_struct *curr = current; struct perf_counter_context *ctx = &curr->perf_counter_ctx; struct perf_counter *counter; + unsigned long flags; u64 perf_flags; int cpu; if (likely(!ctx->nr_counters)) return 0; - local_irq_disable(); + curr_rq_lock_irq_save(&flags); cpu = smp_processor_id(); + /* force the update of the task clock: */ + __task_delta_exec(curr, 1); + spin_lock(&ctx->lock); /* @@ -493,6 +506,7 @@ int perf_counter_task_enable(void) if (counter->state != PERF_COUNTER_STATE_OFF) continue; counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->hw_event.disabled = 0; } hw_perf_restore(perf_flags); @@ -500,7 +514,7 @@ int perf_counter_task_enable(void) perf_counter_task_sched_in(curr, cpu); - local_irq_enable(); + curr_rq_unlock_irq_restore(&flags); return 0; } @@ -540,8 +554,11 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) static void __read(void *info) { struct perf_counter *counter = info; + unsigned long flags; + curr_rq_lock_irq_save(&flags); counter->hw_ops->read(counter); + curr_rq_unlock_irq_restore(&flags); } static u64 perf_counter_read(struct perf_counter *counter) @@ -860,13 +877,27 @@ static const struct hw_perf_counter_ops perf_ops_cpu_clock = { .read = cpu_clock_perf_counter_read, }; -static void task_clock_perf_counter_update(struct perf_counter *counter) +/* + * Called from within the scheduler: + */ +static u64 task_clock_perf_counter_val(struct perf_counter *counter, int update) { - u64 prev, now; + struct task_struct *curr = counter->task; + u64 delta; + + WARN_ON_ONCE(counter->task != current); + + delta = __task_delta_exec(curr, update); + + return curr->se.sum_exec_runtime + delta; +} + +static void task_clock_perf_counter_update(struct perf_counter *counter, u64 now) +{ + u64 prev; s64 delta; prev = atomic64_read(&counter->hw.prev_count); - now = current->se.sum_exec_runtime; atomic64_set(&counter->hw.prev_count, now); @@ -877,17 +908,23 @@ static void task_clock_perf_counter_update(struct perf_counter *counter) static void task_clock_perf_counter_read(struct perf_counter *counter) { - task_clock_perf_counter_update(counter); + u64 now = task_clock_perf_counter_val(counter, 1); + + task_clock_perf_counter_update(counter, now); } static void task_clock_perf_counter_enable(struct perf_counter *counter) { - atomic64_set(&counter->hw.prev_count, current->se.sum_exec_runtime); + u64 now = task_clock_perf_counter_val(counter, 0); + + atomic64_set(&counter->hw.prev_count, now); } static void task_clock_perf_counter_disable(struct perf_counter *counter) { - task_clock_perf_counter_update(counter); + u64 now = task_clock_perf_counter_val(counter, 0); + + task_clock_perf_counter_update(counter, now); } static const struct hw_perf_counter_ops perf_ops_task_clock = { @@ -1267,6 +1304,7 @@ __perf_counter_exit_task(struct task_struct *child, { struct perf_counter *parent_counter; u64 parent_val, child_val; + unsigned long flags; u64 perf_flags; /* @@ -1275,7 +1313,7 @@ __perf_counter_exit_task(struct task_struct *child, * Be careful about zapping the list - IRQ/NMI context * could still be processing it: */ - local_irq_disable(); + curr_rq_lock_irq_save(&flags); perf_flags = hw_perf_save_disable(); if (child_counter->state == PERF_COUNTER_STATE_ACTIVE) { @@ -1294,7 +1332,7 @@ __perf_counter_exit_task(struct task_struct *child, list_del_init(&child_counter->list_entry); hw_perf_restore(perf_flags); - local_irq_enable(); + curr_rq_unlock_irq_restore(&flags); parent_counter = child_counter->parent; /* diff --git a/kernel/sched.c b/kernel/sched.c index 382cfdb5e38d..4d84ff4c8774 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -638,7 +638,7 @@ static inline int cpu_of(struct rq *rq) #define task_rq(p) cpu_rq(task_cpu(p)) #define cpu_curr(cpu) (cpu_rq(cpu)->curr) -static inline void update_rq_clock(struct rq *rq) +inline void update_rq_clock(struct rq *rq) { rq->clock = sched_clock_cpu(cpu_of(rq)); } @@ -969,6 +969,26 @@ static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags) } } +void curr_rq_lock_irq_save(unsigned long *flags) + __acquires(rq->lock) +{ + struct rq *rq; + + local_irq_save(*flags); + rq = cpu_rq(smp_processor_id()); + spin_lock(&rq->lock); +} + +void curr_rq_unlock_irq_restore(unsigned long *flags) + __releases(rq->lock) +{ + struct rq *rq; + + rq = cpu_rq(smp_processor_id()); + spin_unlock(&rq->lock); + local_irq_restore(*flags); +} + void task_rq_unlock_wait(struct task_struct *p) { struct rq *rq = task_rq(p); @@ -2558,7 +2578,6 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next) { fire_sched_out_preempt_notifiers(prev, next); - perf_counter_task_sched_out(prev, cpu_of(rq)); prepare_lock_switch(rq, next); prepare_arch_switch(next); } @@ -4089,6 +4108,29 @@ DEFINE_PER_CPU(struct kernel_stat, kstat); EXPORT_PER_CPU_SYMBOL(kstat); +/* + * Return any ns on the sched_clock that have not yet been banked in + * @p in case that task is currently running. + */ +unsigned long long __task_delta_exec(struct task_struct *p, int update) +{ + s64 delta_exec; + struct rq *rq; + + rq = task_rq(p); + WARN_ON_ONCE(!runqueue_is_locked()); + WARN_ON_ONCE(!task_current(rq, p)); + + if (update) + update_rq_clock(rq); + + delta_exec = rq->clock - p->se.exec_start; + + WARN_ON_ONCE(delta_exec < 0); + + return delta_exec; +} + /* * Return any ns on the sched_clock that have not yet been banked in * @p in case that task is currently running. @@ -4316,13 +4358,13 @@ void scheduler_tick(void) update_rq_clock(rq); update_cpu_load(rq); curr->sched_class->task_tick(rq, curr, 0); + perf_counter_task_tick(curr, cpu); spin_unlock(&rq->lock); #ifdef CONFIG_SMP rq->idle_at_tick = idle_cpu(cpu); trigger_load_balance(rq, cpu); #endif - perf_counter_task_tick(curr, cpu); } #if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \ @@ -4512,6 +4554,7 @@ need_resched_nonpreemptible: if (likely(prev != next)) { sched_info_switch(prev, next); + perf_counter_task_sched_out(prev, cpu); rq->nr_switches++; rq->curr = next; -- GitLab From eef6cbf5844c620d9db9be99e4908cdf92492fb9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 19 Dec 2008 10:20:42 +0100 Subject: [PATCH 0044/6080] perfcounters: pull inherited counters Change counter inheritance from a 'push' to a 'pull' model: instead of child tasks pushing their final counts to the parent, reuse the wait4 infrastructure to pull counters as child tasks are exit-processed, much like how cutime/cstime is collected. Signed-off-by: Ingo Molnar --- include/linux/init_task.h | 9 +++++++++ kernel/exit.c | 21 +++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 23fd8909b9e5..54fa2fa2c8e4 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -113,6 +113,14 @@ extern struct group_info init_groups; # define CAP_INIT_BSET CAP_INIT_EFF_SET #endif +#ifdef CONFIG_PERF_COUNTERS +# define INIT_PERF_COUNTERS(tsk) \ + .perf_counter_ctx.counter_list = \ + LIST_HEAD_INIT(tsk.perf_counter_ctx.counter_list), +#else +# define INIT_PERF_COUNTERS(tsk) +#endif + /* * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) @@ -180,6 +188,7 @@ extern struct group_info init_groups; INIT_IDS \ INIT_TRACE_IRQFLAGS \ INIT_LOCKDEP \ + INIT_PERF_COUNTERS(tsk) \ } diff --git a/kernel/exit.c b/kernel/exit.c index 244edfd96865..101b7eeff44c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -153,6 +153,9 @@ static void delayed_put_task_struct(struct rcu_head *rhp) { struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); +#ifdef CONFIG_PERF_COUNTERS + WARN_ON_ONCE(!list_empty(&tsk->perf_counter_ctx.counter_list)); +#endif trace_sched_process_free(tsk); put_task_struct(tsk); } @@ -922,12 +925,6 @@ static void exit_notify(struct task_struct *tsk, int group_dead) forget_original_parent(tsk); exit_task_namespaces(tsk); - /* - * Flush inherited counters to the parent - before the parent - * gets woken up by child-exit notifications. - */ - perf_counter_exit_task(tsk); - write_lock_irq(&tasklist_lock); if (group_dead) kill_orphaned_pgrp(tsk->group_leader, NULL); @@ -1122,12 +1119,6 @@ NORET_TYPE void do_exit(long code) if (tsk->splice_pipe) __free_pipe_info(tsk->splice_pipe); - /* - * These must happen late, after the PID is not - * hashed anymore, but still at a point that may sleep: - */ - perf_counter_exit_task(tsk); - preempt_disable(); /* causes final put_task_struct in finish_task_switch(). */ tsk->state = TASK_DEAD; @@ -1371,6 +1362,12 @@ static int wait_task_zombie(struct task_struct *p, int options, */ read_unlock(&tasklist_lock); + /* + * Flush inherited counters to the parent - before the parent + * gets woken up by child-exit notifications. + */ + perf_counter_exit_task(p); + retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; status = (p->signal->flags & SIGNAL_GROUP_EXIT) ? p->signal->group_exit_code : p->exit_code; -- GitLab From 78b6084c907cea15bb40a564b974e072f5163781 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 21 Dec 2008 15:07:49 +0100 Subject: [PATCH 0045/6080] perfcounters: fix init context lock Signed-off-by: Ingo Molnar --- include/linux/init_task.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 54fa2fa2c8e4..467cff545c30 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -116,7 +116,9 @@ extern struct group_info init_groups; #ifdef CONFIG_PERF_COUNTERS # define INIT_PERF_COUNTERS(tsk) \ .perf_counter_ctx.counter_list = \ - LIST_HEAD_INIT(tsk.perf_counter_ctx.counter_list), + LIST_HEAD_INIT(tsk.perf_counter_ctx.counter_list), \ + .perf_counter_ctx.lock = \ + __SPIN_LOCK_UNLOCKED(tsk.perf_counter_ctx.lock), #else # define INIT_PERF_COUNTERS(tsk) #endif -- GitLab From 95cdd2e7851cce79ab839cb0b3cbe68d7911d0f1 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 21 Dec 2008 13:50:42 +0100 Subject: [PATCH 0046/6080] perfcounters: enable lowlevel pmc code to schedule counters Allow lowlevel ->enable() op to return an error if a counter can not be added. This can be used to handle counter constraints. Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 6 ++- include/linux/perf_counter.h | 2 +- kernel/perf_counter.c | 62 ++++++++++++++++++++++-------- 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index b67557121425..74090a393a7c 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -244,7 +244,7 @@ static int fixed_mode_idx(struct hw_perf_counter *hwc) /* * Find a PMC slot for the freshly enabled / scheduled in counter: */ -static void pmc_generic_enable(struct perf_counter *counter) +static int pmc_generic_enable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); struct hw_perf_counter *hwc = &counter->hw; @@ -253,6 +253,8 @@ static void pmc_generic_enable(struct perf_counter *counter) /* Try to get the previous counter again */ if (test_and_set_bit(idx, cpuc->used)) { idx = find_first_zero_bit(cpuc->used, nr_counters_generic); + if (idx == nr_counters_generic) + return -EAGAIN; set_bit(idx, cpuc->used); hwc->idx = idx; } @@ -265,6 +267,8 @@ static void pmc_generic_enable(struct perf_counter *counter) __hw_perf_counter_set_period(counter, hwc, idx); __pmc_generic_enable(counter, hwc, idx); + + return 0; } void perf_counter_print_debug(void) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 48f76d2e54c2..53af11d3767b 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -128,7 +128,7 @@ struct perf_counter; * struct hw_perf_counter_ops - performance counter hw ops */ struct hw_perf_counter_ops { - void (*enable) (struct perf_counter *counter); + int (*enable) (struct perf_counter *counter); void (*disable) (struct perf_counter *counter); void (*read) (struct perf_counter *counter); }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f1110ac1267b..2e73929a6959 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -355,21 +355,25 @@ void perf_counter_task_sched_out(struct task_struct *task, int cpu) cpuctx->task_ctx = NULL; } -static void +static int counter_sched_in(struct perf_counter *counter, struct perf_cpu_context *cpuctx, struct perf_counter_context *ctx, int cpu) { if (counter->state == PERF_COUNTER_STATE_OFF) - return; + return 0; + + if (counter->hw_ops->enable(counter)) + return -EAGAIN; - counter->hw_ops->enable(counter); counter->state = PERF_COUNTER_STATE_ACTIVE; counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ cpuctx->active_oncpu++; ctx->nr_active++; + + return 0; } static int @@ -378,20 +382,38 @@ group_sched_in(struct perf_counter *group_counter, struct perf_counter_context *ctx, int cpu) { - struct perf_counter *counter; - int was_group = 0; + struct perf_counter *counter, *partial_group; + int ret = 0; - counter_sched_in(group_counter, cpuctx, ctx, cpu); + if (counter_sched_in(group_counter, cpuctx, ctx, cpu)) + return -EAGAIN; /* * Schedule in siblings as one group (if any): */ list_for_each_entry(counter, &group_counter->sibling_list, list_entry) { - counter_sched_in(counter, cpuctx, ctx, cpu); - was_group = 1; + if (counter_sched_in(counter, cpuctx, ctx, cpu)) { + partial_group = counter; + goto group_error; + } + ret = -EAGAIN; } - return was_group; + return ret; + +group_error: + /* + * Groups can be scheduled in as one unit only, so undo any + * partial group before returning: + */ + list_for_each_entry(counter, &group_counter->sibling_list, list_entry) { + if (counter == partial_group) + break; + counter_sched_out(counter, cpuctx, ctx); + } + counter_sched_out(group_counter, cpuctx, ctx); + + return -EAGAIN; } /* @@ -416,9 +438,6 @@ void perf_counter_task_sched_in(struct task_struct *task, int cpu) spin_lock(&ctx->lock); list_for_each_entry(counter, &ctx->counter_list, list_entry) { - if (ctx->nr_active == cpuctx->max_pertask) - break; - /* * Listen to the 'cpu' scheduling filter constraint * of counters: @@ -856,8 +875,9 @@ static const struct file_operations perf_fops = { .poll = perf_poll, }; -static void cpu_clock_perf_counter_enable(struct perf_counter *counter) +static int cpu_clock_perf_counter_enable(struct perf_counter *counter) { + return 0; } static void cpu_clock_perf_counter_disable(struct perf_counter *counter) @@ -913,11 +933,13 @@ static void task_clock_perf_counter_read(struct perf_counter *counter) task_clock_perf_counter_update(counter, now); } -static void task_clock_perf_counter_enable(struct perf_counter *counter) +static int task_clock_perf_counter_enable(struct perf_counter *counter) { u64 now = task_clock_perf_counter_val(counter, 0); atomic64_set(&counter->hw.prev_count, now); + + return 0; } static void task_clock_perf_counter_disable(struct perf_counter *counter) @@ -960,12 +982,14 @@ static void page_faults_perf_counter_read(struct perf_counter *counter) page_faults_perf_counter_update(counter); } -static void page_faults_perf_counter_enable(struct perf_counter *counter) +static int page_faults_perf_counter_enable(struct perf_counter *counter) { /* * page-faults is a per-task value already, * so we dont have to clear it on switch-in. */ + + return 0; } static void page_faults_perf_counter_disable(struct perf_counter *counter) @@ -1006,12 +1030,14 @@ static void context_switches_perf_counter_read(struct perf_counter *counter) context_switches_perf_counter_update(counter); } -static void context_switches_perf_counter_enable(struct perf_counter *counter) +static int context_switches_perf_counter_enable(struct perf_counter *counter) { /* * ->nvcsw + curr->nivcsw is a per-task value already, * so we dont have to clear it on switch-in. */ + + return 0; } static void context_switches_perf_counter_disable(struct perf_counter *counter) @@ -1050,12 +1076,14 @@ static void cpu_migrations_perf_counter_read(struct perf_counter *counter) cpu_migrations_perf_counter_update(counter); } -static void cpu_migrations_perf_counter_enable(struct perf_counter *counter) +static int cpu_migrations_perf_counter_enable(struct perf_counter *counter) { /* * se.nr_migrations is a per-task value already, * so we dont have to clear it on switch-in. */ + + return 0; } static void cpu_migrations_perf_counter_disable(struct perf_counter *counter) -- GitLab From 0dff86aa7b9ec65a6d07167b7afb050b5fc98ddc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 23 Dec 2008 12:28:12 +0100 Subject: [PATCH 0047/6080] x86, perfcounters: print out the ->used bitmask Impact: extend debug printouts Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 74090a393a7c..f3359c2b3910 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -255,6 +255,7 @@ static int pmc_generic_enable(struct perf_counter *counter) idx = find_first_zero_bit(cpuc->used, nr_counters_generic); if (idx == nr_counters_generic) return -EAGAIN; + set_bit(idx, cpuc->used); hwc->idx = idx; } @@ -274,6 +275,7 @@ static int pmc_generic_enable(struct perf_counter *counter) void perf_counter_print_debug(void) { u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left; + struct cpu_hw_counters *cpuc; int cpu, idx; if (!nr_counters_generic) @@ -282,6 +284,7 @@ void perf_counter_print_debug(void) local_irq_disable(); cpu = smp_processor_id(); + cpuc = &per_cpu(cpu_hw_counters, cpu); rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); @@ -291,6 +294,7 @@ void perf_counter_print_debug(void) printk(KERN_INFO "CPU#%d: ctrl: %016llx\n", cpu, ctrl); printk(KERN_INFO "CPU#%d: status: %016llx\n", cpu, status); printk(KERN_INFO "CPU#%d: overflow: %016llx\n", cpu, overflow); + printk(KERN_INFO "CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); for (idx = 0; idx < nr_counters_generic; idx++) { rdmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, pmc_ctrl); -- GitLab From 8fe91e61cdc407c7556d3cd71cf20141a25bbcea Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 23 Dec 2008 12:29:25 +0100 Subject: [PATCH 0048/6080] perfcounters: remove ->nr_inherited Impact: remove dead code nr_inherited was not maintained correctly (not decremented) - and also not used - remove it. Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 1 - kernel/perf_counter.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 53af11d3767b..1ea08e9f31ce 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -164,7 +164,6 @@ struct perf_counter { struct task_struct *task; struct file *filp; - unsigned int nr_inherited; struct perf_counter *parent; /* * Protect attach/detach: diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 2e73929a6959..48e1dbcdc1cd 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1308,7 +1308,6 @@ inherit_counter(struct perf_counter *parent_counter, child_ctx->nr_counters++; child_counter->parent = parent_counter; - parent_counter->nr_inherited++; /* * inherit into child's child as well: */ -- GitLab From 235c7fc7c500e4fd1700c4ad01b5612bcdc1b449 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 21 Dec 2008 14:43:25 +0100 Subject: [PATCH 0049/6080] perfcounters: generalize the counter scheduler Impact: clean up and refactor code refactor the counter scheduler: separate out in/out functions and introduce a counter-rotation function as well. Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 220 +++++++++++++++++++++++++++--------------- 1 file changed, 142 insertions(+), 78 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 48e1dbcdc1cd..d7a79f321b1c 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -111,11 +111,12 @@ static void __perf_counter_remove_from_context(void *info) spin_lock(&ctx->lock); if (counter->state == PERF_COUNTER_STATE_ACTIVE) { - counter->hw_ops->disable(counter); counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->hw_ops->disable(counter); ctx->nr_active--; cpuctx->active_oncpu--; counter->task = NULL; + counter->oncpu = -1; } ctx->nr_counters--; @@ -192,8 +193,36 @@ retry: spin_unlock_irq(&ctx->lock); } +static int +counter_sched_in(struct perf_counter *counter, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx, + int cpu) +{ + if (counter->state == PERF_COUNTER_STATE_OFF) + return 0; + + counter->state = PERF_COUNTER_STATE_ACTIVE; + counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ + /* + * The new state must be visible before we turn it on in the hardware: + */ + smp_wmb(); + + if (counter->hw_ops->enable(counter)) { + counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->oncpu = -1; + return -EAGAIN; + } + + cpuctx->active_oncpu++; + ctx->nr_active++; + + return 0; +} + /* - * Cross CPU call to install and enable a preformance counter + * Cross CPU call to install and enable a performance counter */ static void __perf_install_in_context(void *info) { @@ -220,22 +249,17 @@ static void __perf_install_in_context(void *info) * counters on a global level. NOP for non NMI based counters. */ perf_flags = hw_perf_save_disable(); - list_add_counter(counter, ctx); - hw_perf_restore(perf_flags); + list_add_counter(counter, ctx); ctx->nr_counters++; - if (cpuctx->active_oncpu < perf_max_counters) { - counter->state = PERF_COUNTER_STATE_ACTIVE; - counter->oncpu = cpu; - ctx->nr_active++; - cpuctx->active_oncpu++; - counter->hw_ops->enable(counter); - } + counter_sched_in(counter, cpuctx, ctx, cpu); if (!ctx->task && cpuctx->max_pertask) cpuctx->max_pertask--; + hw_perf_restore(perf_flags); + spin_unlock(&ctx->lock); curr_rq_unlock_irq_restore(&flags); } @@ -302,8 +326,8 @@ counter_sched_out(struct perf_counter *counter, if (counter->state != PERF_COUNTER_STATE_ACTIVE) return; - counter->hw_ops->disable(counter); counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->hw_ops->disable(counter); counter->oncpu = -1; cpuctx->active_oncpu--; @@ -326,6 +350,22 @@ group_sched_out(struct perf_counter *group_counter, counter_sched_out(counter, cpuctx, ctx); } +void __perf_counter_sched_out(struct perf_counter_context *ctx, + struct perf_cpu_context *cpuctx) +{ + struct perf_counter *counter; + + if (likely(!ctx->nr_counters)) + return; + + spin_lock(&ctx->lock); + if (ctx->nr_active) { + list_for_each_entry(counter, &ctx->counter_list, list_entry) + group_sched_out(counter, cpuctx, ctx); + } + spin_unlock(&ctx->lock); +} + /* * Called from scheduler to remove the counters of the current task, * with interrupts disabled. @@ -341,39 +381,18 @@ void perf_counter_task_sched_out(struct task_struct *task, int cpu) { struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); struct perf_counter_context *ctx = &task->perf_counter_ctx; - struct perf_counter *counter; if (likely(!cpuctx->task_ctx)) return; - spin_lock(&ctx->lock); - if (ctx->nr_active) { - list_for_each_entry(counter, &ctx->counter_list, list_entry) - group_sched_out(counter, cpuctx, ctx); - } - spin_unlock(&ctx->lock); + __perf_counter_sched_out(ctx, cpuctx); + cpuctx->task_ctx = NULL; } -static int -counter_sched_in(struct perf_counter *counter, - struct perf_cpu_context *cpuctx, - struct perf_counter_context *ctx, - int cpu) +static void perf_counter_cpu_sched_out(struct perf_cpu_context *cpuctx) { - if (counter->state == PERF_COUNTER_STATE_OFF) - return 0; - - if (counter->hw_ops->enable(counter)) - return -EAGAIN; - - counter->state = PERF_COUNTER_STATE_ACTIVE; - counter->oncpu = cpu; /* TODO: put 'cpu' into cpuctx->cpu */ - - cpuctx->active_oncpu++; - ctx->nr_active++; - - return 0; + __perf_counter_sched_out(&cpuctx->ctx, cpuctx); } static int @@ -416,21 +435,10 @@ group_error: return -EAGAIN; } -/* - * Called from scheduler to add the counters of the current task - * with interrupts disabled. - * - * We restore the counter value and then enable it. - * - * This does not protect us against NMI, but enable() - * sets the enabled bit in the control field of counter _before_ - * accessing the counter control register. If a NMI hits, then it will - * keep the counter running. - */ -void perf_counter_task_sched_in(struct task_struct *task, int cpu) +static void +__perf_counter_sched_in(struct perf_counter_context *ctx, + struct perf_cpu_context *cpuctx, int cpu) { - struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); - struct perf_counter_context *ctx = &task->perf_counter_ctx; struct perf_counter *counter; if (likely(!ctx->nr_counters)) @@ -453,10 +461,35 @@ void perf_counter_task_sched_in(struct task_struct *task, int cpu) break; } spin_unlock(&ctx->lock); +} +/* + * Called from scheduler to add the counters of the current task + * with interrupts disabled. + * + * We restore the counter value and then enable it. + * + * This does not protect us against NMI, but enable() + * sets the enabled bit in the control field of counter _before_ + * accessing the counter control register. If a NMI hits, then it will + * keep the counter running. + */ +void perf_counter_task_sched_in(struct task_struct *task, int cpu) +{ + struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); + struct perf_counter_context *ctx = &task->perf_counter_ctx; + + __perf_counter_sched_in(ctx, cpuctx, cpu); cpuctx->task_ctx = ctx; } +static void perf_counter_cpu_sched_in(struct perf_cpu_context *cpuctx, int cpu) +{ + struct perf_counter_context *ctx = &cpuctx->ctx; + + __perf_counter_sched_in(ctx, cpuctx, cpu); +} + int perf_counter_task_disable(void) { struct task_struct *curr = current; @@ -514,6 +547,8 @@ int perf_counter_task_enable(void) /* force the update of the task clock: */ __task_delta_exec(curr, 1); + perf_counter_task_sched_out(curr, cpu); + spin_lock(&ctx->lock); /* @@ -538,19 +573,18 @@ int perf_counter_task_enable(void) return 0; } -void perf_counter_task_tick(struct task_struct *curr, int cpu) +/* + * Round-robin a context's counters: + */ +static void rotate_ctx(struct perf_counter_context *ctx) { - struct perf_counter_context *ctx = &curr->perf_counter_ctx; struct perf_counter *counter; u64 perf_flags; - if (likely(!ctx->nr_counters)) + if (!ctx->nr_counters) return; - perf_counter_task_sched_out(curr, cpu); - spin_lock(&ctx->lock); - /* * Rotate the first entry last (works just fine for group counters too): */ @@ -563,7 +597,24 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) hw_perf_restore(perf_flags); spin_unlock(&ctx->lock); +} + +void perf_counter_task_tick(struct task_struct *curr, int cpu) +{ + struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); + struct perf_counter_context *ctx = &curr->perf_counter_ctx; + const int rotate_percpu = 0; + + if (rotate_percpu) + perf_counter_cpu_sched_out(cpuctx); + perf_counter_task_sched_out(curr, cpu); + if (rotate_percpu) + rotate_ctx(&cpuctx->ctx); + rotate_ctx(ctx); + + if (rotate_percpu) + perf_counter_cpu_sched_in(cpuctx, cpu); perf_counter_task_sched_in(curr, cpu); } @@ -905,8 +956,6 @@ static u64 task_clock_perf_counter_val(struct perf_counter *counter, int update) struct task_struct *curr = counter->task; u64 delta; - WARN_ON_ONCE(counter->task != current); - delta = __task_delta_exec(curr, update); return curr->se.sum_exec_runtime + delta; @@ -1160,6 +1209,7 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, counter->group_leader = group_leader; counter->hw_ops = NULL; + counter->state = PERF_COUNTER_STATE_INACTIVE; if (hw_event->disabled) counter->state = PERF_COUNTER_STATE_OFF; @@ -1331,35 +1381,49 @@ __perf_counter_exit_task(struct task_struct *child, { struct perf_counter *parent_counter; u64 parent_val, child_val; - unsigned long flags; - u64 perf_flags; /* - * Disable and unlink this counter. - * - * Be careful about zapping the list - IRQ/NMI context - * could still be processing it: + * If we do not self-reap then we have to wait for the + * child task to unschedule (it will happen for sure), + * so that its counter is at its final count. (This + * condition triggers rarely - child tasks usually get + * off their CPU before the parent has a chance to + * get this far into the reaping action) */ - curr_rq_lock_irq_save(&flags); - perf_flags = hw_perf_save_disable(); - - if (child_counter->state == PERF_COUNTER_STATE_ACTIVE) { + if (child != current) { + wait_task_inactive(child, 0); + list_del_init(&child_counter->list_entry); + } else { struct perf_cpu_context *cpuctx; + unsigned long flags; + u64 perf_flags; + + /* + * Disable and unlink this counter. + * + * Be careful about zapping the list - IRQ/NMI context + * could still be processing it: + */ + curr_rq_lock_irq_save(&flags); + perf_flags = hw_perf_save_disable(); cpuctx = &__get_cpu_var(perf_cpu_context); - child_counter->hw_ops->disable(child_counter); - child_counter->state = PERF_COUNTER_STATE_INACTIVE; - child_counter->oncpu = -1; + if (child_counter->state == PERF_COUNTER_STATE_ACTIVE) { + child_counter->state = PERF_COUNTER_STATE_INACTIVE; + child_counter->hw_ops->disable(child_counter); + cpuctx->active_oncpu--; + child_ctx->nr_active--; + child_counter->oncpu = -1; + } - cpuctx->active_oncpu--; - child_ctx->nr_active--; - } + list_del_init(&child_counter->list_entry); - list_del_init(&child_counter->list_entry); + child_ctx->nr_counters--; - hw_perf_restore(perf_flags); - curr_rq_unlock_irq_restore(&flags); + hw_perf_restore(perf_flags); + curr_rq_unlock_irq_restore(&flags); + } parent_counter = child_counter->parent; /* -- GitLab From f650a672359819454c3d8d4135ecd1558cde0b24 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 23 Dec 2008 12:17:29 +0100 Subject: [PATCH 0050/6080] perfcounters: add PERF_COUNT_BUS_CYCLES Generalize "bus cycles" hw events - and map them to CPU_CLK_Unhalted.Ref on x86. (which is a good enough approximation) Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 3 ++- include/linux/perf_counter.h | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index f3359c2b3910..86b2fdd344a6 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -41,12 +41,13 @@ static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters); static const int intel_perfmon_event_map[] = { - [PERF_COUNT_CYCLES] = 0x003c, + [PERF_COUNT_CPU_CYCLES] = 0x003c, [PERF_COUNT_INSTRUCTIONS] = 0x00c0, [PERF_COUNT_CACHE_REFERENCES] = 0x4f2e, [PERF_COUNT_CACHE_MISSES] = 0x412e, [PERF_COUNT_BRANCH_INSTRUCTIONS] = 0x00c4, [PERF_COUNT_BRANCH_MISSES] = 0x00c5, + [PERF_COUNT_BUS_CYCLES] = 0x013c, }; static const int max_intel_perfmon_events = ARRAY_SIZE(intel_perfmon_event_map); diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 1ea08e9f31ce..ec77d1643d37 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -36,14 +36,15 @@ enum hw_event_types { /* * Common hardware events, generalized by the kernel: */ - PERF_COUNT_CYCLES = 0, + PERF_COUNT_CPU_CYCLES = 0, PERF_COUNT_INSTRUCTIONS = 1, PERF_COUNT_CACHE_REFERENCES = 2, PERF_COUNT_CACHE_MISSES = 3, PERF_COUNT_BRANCH_INSTRUCTIONS = 4, PERF_COUNT_BRANCH_MISSES = 5, + PERF_COUNT_BUS_CYCLES = 6, - PERF_HW_EVENTS_MAX = 6, + PERF_HW_EVENTS_MAX = 7, /* * Special "software" counters provided by the kernel, even if -- GitLab From 2f18d1e8d07ae67dd0afce875287756d4bd31a46 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 22 Dec 2008 11:10:42 +0100 Subject: [PATCH 0051/6080] x86, perfcounters: add support for fixed-function pmcs Impact: extend performance counter support on x86 Intel CPUs Modern Intel CPUs have 3 "fixed-function" performance counters, which count these hardware events: Instr_Retired.Any CPU_CLK_Unhalted.Core CPU_CLK_Unhalted.Ref Add support for them to the performance counters subsystem. Their use is transparent to user-space: the counter scheduler is extended to automatically recognize the cases where a fixed-function PMC can be utilized instead of a generic PMC. In such cases the generic PMC is kept available for more counters. The above fixed-function events map to these generic counter hw events: PERF_COUNT_INSTRUCTIONS PERF_COUNT_CPU_CYCLES PERF_COUNT_BUS_CYCLES (The 'bus' cycles are in reality often CPU-ish cycles, just with a fixed frequency.) Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_counter.h | 8 ++ arch/x86/kernel/cpu/perf_counter.c | 149 +++++++++++++++++++++++----- 2 files changed, 133 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h index 13745deb16c8..2e08ed736647 100644 --- a/arch/x86/include/asm/perf_counter.h +++ b/arch/x86/include/asm/perf_counter.h @@ -23,6 +23,11 @@ #define ARCH_PERFMON_EVENTSEL_OS (1 << 17) #define ARCH_PERFMON_EVENTSEL_USR (1 << 16) +/* + * Includes eventsel and unit mask as well: + */ +#define ARCH_PERFMON_EVENT_MASK 0xffff + #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 0x3c #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK (0x00 << 8) #define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX 0 @@ -69,12 +74,15 @@ union cpuid10_edx { /* Instr_Retired.Any: */ #define MSR_ARCH_PERFMON_FIXED_CTR0 0x309 +#define X86_PMC_IDX_FIXED_INSTRUCTIONS (X86_PMC_IDX_FIXED + 0) /* CPU_CLK_Unhalted.Core: */ #define MSR_ARCH_PERFMON_FIXED_CTR1 0x30a +#define X86_PMC_IDX_FIXED_CPU_CYCLES (X86_PMC_IDX_FIXED + 1) /* CPU_CLK_Unhalted.Ref: */ #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b +#define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2) #ifdef CONFIG_PERF_COUNTERS extern void init_hw_perf_counters(void); diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 86b2fdd344a6..da46eca12543 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -26,6 +26,7 @@ static bool perf_counters_initialized __read_mostly; */ static int nr_counters_generic __read_mostly; static u64 perf_counter_mask __read_mostly; +static u64 counter_value_mask __read_mostly; static int nr_counters_fixed __read_mostly; @@ -120,9 +121,6 @@ static int __hw_perf_counter_init(struct perf_counter *counter) hwc->nmi = 1; } - hwc->config_base = MSR_ARCH_PERFMON_EVENTSEL0; - hwc->counter_base = MSR_ARCH_PERFMON_PERFCTR0; - hwc->irq_period = hw_event->irq_period; /* * Intel PMCs cannot be accessed sanely above 32 bit width, @@ -183,16 +181,34 @@ void hw_perf_restore(u64 ctrl) } EXPORT_SYMBOL_GPL(hw_perf_restore); +static inline void +__pmc_fixed_disable(struct perf_counter *counter, + struct hw_perf_counter *hwc, unsigned int __idx) +{ + int idx = __idx - X86_PMC_IDX_FIXED; + u64 ctrl_val, mask; + int err; + + mask = 0xfULL << (idx * 4); + + rdmsrl(hwc->config_base, ctrl_val); + ctrl_val &= ~mask; + err = checking_wrmsrl(hwc->config_base, ctrl_val); +} + static inline void __pmc_generic_disable(struct perf_counter *counter, struct hw_perf_counter *hwc, unsigned int idx) { int err; + if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) + return __pmc_fixed_disable(counter, hwc, idx); + err = wrmsr_safe(hwc->config_base + idx, hwc->config, 0); } -static DEFINE_PER_CPU(u64, prev_left[X86_PMC_MAX_GENERIC]); +static DEFINE_PER_CPU(u64, prev_left[X86_PMC_IDX_MAX]); /* * Set the next IRQ period, based on the hwc->period_left value. @@ -202,8 +218,9 @@ static void __hw_perf_counter_set_period(struct perf_counter *counter, struct hw_perf_counter *hwc, int idx) { - s32 left = atomic64_read(&hwc->period_left); + s64 left = atomic64_read(&hwc->period_left); s32 period = hwc->irq_period; + int err; /* * If we are way outside a reasoable range then just skip forward: @@ -224,21 +241,64 @@ __hw_perf_counter_set_period(struct perf_counter *counter, * The hw counter starts counting from this counter offset, * mark it to be able to extra future deltas: */ - atomic64_set(&hwc->prev_count, (u64)(s64)-left); + atomic64_set(&hwc->prev_count, (u64)-left); - wrmsr(hwc->counter_base + idx, -left, 0); + err = checking_wrmsrl(hwc->counter_base + idx, + (u64)(-left) & counter_value_mask); +} + +static inline void +__pmc_fixed_enable(struct perf_counter *counter, + struct hw_perf_counter *hwc, unsigned int __idx) +{ + int idx = __idx - X86_PMC_IDX_FIXED; + u64 ctrl_val, bits, mask; + int err; + + /* + * Enable IRQ generation (0x8) and ring-3 counting (0x2), + * and enable ring-0 counting if allowed: + */ + bits = 0x8ULL | 0x2ULL; + if (hwc->config & ARCH_PERFMON_EVENTSEL_OS) + bits |= 0x1; + bits <<= (idx * 4); + mask = 0xfULL << (idx * 4); + + rdmsrl(hwc->config_base, ctrl_val); + ctrl_val &= ~mask; + ctrl_val |= bits; + err = checking_wrmsrl(hwc->config_base, ctrl_val); } static void __pmc_generic_enable(struct perf_counter *counter, struct hw_perf_counter *hwc, int idx) { + if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) + return __pmc_fixed_enable(counter, hwc, idx); + wrmsr(hwc->config_base + idx, hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0); } -static int fixed_mode_idx(struct hw_perf_counter *hwc) +static int +fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) { + unsigned int event; + + if (unlikely(hwc->nmi)) + return -1; + + event = hwc->config & ARCH_PERFMON_EVENT_MASK; + + if (unlikely(event == intel_perfmon_event_map[PERF_COUNT_INSTRUCTIONS])) + return X86_PMC_IDX_FIXED_INSTRUCTIONS; + if (unlikely(event == intel_perfmon_event_map[PERF_COUNT_CPU_CYCLES])) + return X86_PMC_IDX_FIXED_CPU_CYCLES; + if (unlikely(event == intel_perfmon_event_map[PERF_COUNT_BUS_CYCLES])) + return X86_PMC_IDX_FIXED_BUS_CYCLES; + return -1; } @@ -249,16 +309,39 @@ static int pmc_generic_enable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); struct hw_perf_counter *hwc = &counter->hw; - int idx = hwc->idx; + int idx; - /* Try to get the previous counter again */ - if (test_and_set_bit(idx, cpuc->used)) { - idx = find_first_zero_bit(cpuc->used, nr_counters_generic); - if (idx == nr_counters_generic) - return -EAGAIN; + idx = fixed_mode_idx(counter, hwc); + if (idx >= 0) { + /* + * Try to get the fixed counter, if that is already taken + * then try to get a generic counter: + */ + if (test_and_set_bit(idx, cpuc->used)) + goto try_generic; - set_bit(idx, cpuc->used); + hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; + /* + * We set it so that counter_base + idx in wrmsr/rdmsr maps to + * MSR_ARCH_PERFMON_FIXED_CTR0 ... CTR2: + */ + hwc->counter_base = + MSR_ARCH_PERFMON_FIXED_CTR0 - X86_PMC_IDX_FIXED; hwc->idx = idx; + } else { + idx = hwc->idx; + /* Try to get the previous generic counter again */ + if (test_and_set_bit(idx, cpuc->used)) { +try_generic: + idx = find_first_zero_bit(cpuc->used, nr_counters_generic); + if (idx == nr_counters_generic) + return -EAGAIN; + + set_bit(idx, cpuc->used); + hwc->idx = idx; + } + hwc->config_base = MSR_ARCH_PERFMON_EVENTSEL0; + hwc->counter_base = MSR_ARCH_PERFMON_PERFCTR0; } perf_counters_lapic_init(hwc->nmi); @@ -266,6 +349,10 @@ static int pmc_generic_enable(struct perf_counter *counter) __pmc_generic_disable(counter, hwc, idx); cpuc->counters[idx] = counter; + /* + * Make it visible before enabling the hw: + */ + smp_wmb(); __hw_perf_counter_set_period(counter, hwc, idx); __pmc_generic_enable(counter, hwc, idx); @@ -275,7 +362,7 @@ static int pmc_generic_enable(struct perf_counter *counter) void perf_counter_print_debug(void) { - u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left; + u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed; struct cpu_hw_counters *cpuc; int cpu, idx; @@ -290,11 +377,13 @@ void perf_counter_print_debug(void) rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow); + rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed); printk(KERN_INFO "\n"); printk(KERN_INFO "CPU#%d: ctrl: %016llx\n", cpu, ctrl); printk(KERN_INFO "CPU#%d: status: %016llx\n", cpu, status); printk(KERN_INFO "CPU#%d: overflow: %016llx\n", cpu, overflow); + printk(KERN_INFO "CPU#%d: fixed: %016llx\n", cpu, fixed); printk(KERN_INFO "CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); for (idx = 0; idx < nr_counters_generic; idx++) { @@ -303,13 +392,19 @@ void perf_counter_print_debug(void) prev_left = per_cpu(prev_left[idx], cpu); - printk(KERN_INFO "CPU#%d: PMC%d ctrl: %016llx\n", + printk(KERN_INFO "CPU#%d: gen-PMC%d ctrl: %016llx\n", cpu, idx, pmc_ctrl); - printk(KERN_INFO "CPU#%d: PMC%d count: %016llx\n", + printk(KERN_INFO "CPU#%d: gen-PMC%d count: %016llx\n", cpu, idx, pmc_count); - printk(KERN_INFO "CPU#%d: PMC%d left: %016llx\n", + printk(KERN_INFO "CPU#%d: gen-PMC%d left: %016llx\n", cpu, idx, prev_left); } + for (idx = 0; idx < nr_counters_fixed; idx++) { + rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count); + + printk(KERN_INFO "CPU#%d: fixed-PMC%d count: %016llx\n", + cpu, idx, pmc_count); + } local_irq_enable(); } @@ -323,6 +418,11 @@ static void pmc_generic_disable(struct perf_counter *counter) clear_bit(idx, cpuc->used); cpuc->counters[idx] = NULL; + /* + * Make sure the cleared pointer becomes visible before we + * (potentially) free the counter: + */ + smp_wmb(); /* * Drain the remaining delta count out of a counter @@ -353,14 +453,11 @@ static void perf_save_and_restart(struct perf_counter *counter) { struct hw_perf_counter *hwc = &counter->hw; int idx = hwc->idx; - u64 pmc_ctrl; - - rdmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, pmc_ctrl); x86_perf_counter_update(counter, hwc, idx); __hw_perf_counter_set_period(counter, hwc, idx); - if (pmc_ctrl & ARCH_PERFMON_EVENTSEL0_ENABLE) + if (counter->state == PERF_COUNTER_STATE_ACTIVE) __pmc_generic_enable(counter, hwc, idx); } @@ -373,6 +470,7 @@ perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) * Store sibling timestamps (if any): */ list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { + x86_perf_counter_update(counter, &counter->hw, counter->hw.idx); perf_store_irq_data(sibling, counter->hw_event.type); perf_store_irq_data(sibling, atomic64_read(&counter->count)); @@ -403,7 +501,7 @@ static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) again: ack = status; - for_each_bit(bit, (unsigned long *) &status, nr_counters_generic) { + for_each_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { struct perf_counter *counter = cpuc->counters[bit]; clear_bit(bit, (unsigned long *) &status); @@ -561,6 +659,9 @@ void __init init_hw_perf_counters(void) perf_max_counters = nr_counters_generic; printk(KERN_INFO "... bit width: %d\n", eax.split.bit_width); + counter_value_mask = (1ULL << eax.split.bit_width) - 1; + printk(KERN_INFO "... value mask: %016Lx\n", counter_value_mask); + printk(KERN_INFO "... mask length: %d\n", eax.split.mask_length); nr_counters_fixed = edx.split.num_counters_fixed; -- GitLab From e44aef58ecfbe061eb4c53b939bcc35fb1bee82d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 25 Dec 2008 09:02:11 +0100 Subject: [PATCH 0052/6080] perfcounters: include asm/perf_counter.h only if CONFIG_PERF_COUNTERS=y Impact: build fix on ia64 KOSAKI Motohiro reported that -tip doesnt build on ia64 because asm/perf_counter.h only exists on x86 for now. Fix it. Reported-by: KOSAKI Motohiro Tested-by: KOSAKI Motohiro Acked-by: KOSAKI Motohiro Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index ec77d1643d37..cc3a75a239a9 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -14,7 +14,10 @@ #define _LINUX_PERF_COUNTER_H #include -#include + +#ifdef CONFIG_PERF_COUNTERS +# include +#endif #include #include -- GitLab From 01ea1ccaa24dea3552e103be13b7897211607a8b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 26 Dec 2008 21:05:06 -0800 Subject: [PATCH 0053/6080] perf_counter: more barrier in blank weak function Impact: fix panic possible panic Some versions of GCC inline the weak global function if it's empty. Add a barrier() to work it around. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index d7a79f321b1c..37f771691f93 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -45,8 +45,8 @@ hw_perf_counter_init(struct perf_counter *counter) } u64 __weak hw_perf_save_disable(void) { return 0; } -void __weak hw_perf_restore(u64 ctrl) { } -void __weak hw_perf_counter_setup(void) { } +void __weak hw_perf_restore(u64 ctrl) { barrier(); } +void __weak hw_perf_counter_setup(void) { barrier(); } static void list_add_counter(struct perf_counter *counter, struct perf_counter_context *ctx) -- GitLab From 2b583d8bc8d7105b58d7481a4a0ceb718dac49c6 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sat, 27 Dec 2008 19:15:43 +0530 Subject: [PATCH 0054/6080] x86: perf_counter remove unwanted hw_perf_enable_all Impact: clean, reduce kernel size a bit, avoid sparse warnings Fixes sparse warnings: arch/x86/kernel/cpu/perf_counter.c:153:6: warning: symbol 'hw_perf_enable_all' was not declared. Should it be static? arch/x86/kernel/cpu/perf_counter.c:279:3: warning: returning void-valued expression arch/x86/kernel/cpu/perf_counter.c:206:3: warning: returning void-valued expression arch/x86/kernel/cpu/perf_counter.c:206:3: warning: returning void-valued expression Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index da46eca12543..9376771f757b 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -150,14 +150,6 @@ static int __hw_perf_counter_init(struct perf_counter *counter) return 0; } -void hw_perf_enable_all(void) -{ - if (unlikely(!perf_counters_initialized)) - return; - - wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, perf_counter_mask); -} - u64 hw_perf_save_disable(void) { u64 ctrl; @@ -200,12 +192,10 @@ static inline void __pmc_generic_disable(struct perf_counter *counter, struct hw_perf_counter *hwc, unsigned int idx) { - int err; - if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) - return __pmc_fixed_disable(counter, hwc, idx); - - err = wrmsr_safe(hwc->config_base + idx, hwc->config, 0); + __pmc_fixed_disable(counter, hwc, idx); + else + wrmsr_safe(hwc->config_base + idx, hwc->config, 0); } static DEFINE_PER_CPU(u64, prev_left[X86_PMC_IDX_MAX]); @@ -276,10 +266,10 @@ __pmc_generic_enable(struct perf_counter *counter, struct hw_perf_counter *hwc, int idx) { if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) - return __pmc_fixed_enable(counter, hwc, idx); - - wrmsr(hwc->config_base + idx, - hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0); + __pmc_fixed_enable(counter, hwc, idx); + else + wrmsr(hwc->config_base + idx, + hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0); } static int -- GitLab From ff6f05416ece2caec1a7a1f8180d6598e0ab9272 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Jan 2009 16:19:25 +1100 Subject: [PATCH 0055/6080] perf_counter: Fix return value from dummy hw_perf_counter_init Impact: fix oops-causing bug Currently, if you try to use perf_counters on an architecture that has no hardware support, and you select an event that doesn't map to any of the defined software counters, you get an oops rather than an error. This is because the dummy hw_perf_counter_init returns ERR_PTR(-EINVAL) but the caller (perf_counter_alloc) only tests for NULL. This makes the dummy hw_perf_counter_init return NULL instead. Signed-off-by: Paul Mackerras --- kernel/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 37f771691f93..4be1a8d872b4 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -41,7 +41,7 @@ static DEFINE_MUTEX(perf_resource_mutex); extern __weak const struct hw_perf_counter_ops * hw_perf_counter_init(struct perf_counter *counter) { - return ERR_PTR(-EINVAL); + return NULL; } u64 __weak hw_perf_save_disable(void) { return 0; } -- GitLab From 9abf8a08bc8f18a3b125f834f00e2e71b49c15d2 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Jan 2009 16:26:43 +1100 Subject: [PATCH 0056/6080] perf_counter: Fix the cpu_clock software counter Impact: bug fix Currently if you do (e.g.) timec -e -1 ls, it will report 0 for the value of the cpu_clock counter. The reason is that the core assumes that a counter's count field is up-to-date when the counter is inactive, and doesn't call the counter's read function. However, the cpu_clock counter code only updates the count in the read function. This fixes it by making both the read and disable functions update the count. It also makes the counter ignore time passing while the counter is disabled, by making the enable function update the hw.prev_count field. Signed-off-by: Paul Mackerras --- kernel/perf_counter.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 4be1a8d872b4..b7a027a2ef02 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -928,18 +928,32 @@ static const struct file_operations perf_fops = { static int cpu_clock_perf_counter_enable(struct perf_counter *counter) { + int cpu = raw_smp_processor_id(); + + atomic64_set(&counter->hw.prev_count, cpu_clock(cpu)); return 0; } +static void cpu_clock_perf_counter_update(struct perf_counter *counter) +{ + int cpu = raw_smp_processor_id(); + s64 prev; + u64 now; + + now = cpu_clock(cpu); + prev = atomic64_read(&counter->hw.prev_count); + atomic64_set(&counter->hw.prev_count, now); + atomic64_add(now - prev, &counter->count); +} + static void cpu_clock_perf_counter_disable(struct perf_counter *counter) { + cpu_clock_perf_counter_update(counter); } static void cpu_clock_perf_counter_read(struct perf_counter *counter) { - int cpu = raw_smp_processor_id(); - - atomic64_set(&counter->count, cpu_clock(cpu)); + cpu_clock_perf_counter_update(counter); } static const struct hw_perf_counter_ops perf_ops_cpu_clock = { -- GitLab From 3cbed429a9ccdb7a243f733b1056fe5c39e9004c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Jan 2009 16:43:42 +1100 Subject: [PATCH 0057/6080] perf_counter: Add optional hw_perf_group_sched_in arch function Impact: extend perf_counter infrastructure This adds an optional hw_perf_group_sched_in() arch function that enables a whole group of counters in one go. It returns 1 if it added the group successfully, 0 if it did nothing (and therefore the core needs to add the counters individually), or a negative number if an error occurred. It should add all the counters and enable any software counters in the group, or else add none of them and return an error. There are a couple of related changes/improvements in the group handling here: * As an optimization, group_sched_out() and group_sched_in() now check the state of the group leader, and do nothing if the leader is not active or disabled. * We now call hw_perf_save_disable/hw_perf_restore around the complete set of counter enable/disable calls in __perf_counter_sched_in/out, to give the arch code the opportunity to defer updating the hardware state until the hw_perf_restore call if it wants. * We no longer stop adding groups after we get to a group that has more than one counter. We will ultimately add an option for a group to be exclusive. The current code doesn't really implement exclusive groups anyway, since a group could end up going on with other counters that get added before it. Signed-off-by: Paul Mackerras --- include/linux/perf_counter.h | 3 +++ kernel/perf_counter.c | 31 ++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index cc3a75a239a9..b21d1ea4c054 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -236,6 +236,9 @@ extern u64 hw_perf_save_disable(void); extern void hw_perf_restore(u64 ctrl); extern int perf_counter_task_disable(void); extern int perf_counter_task_enable(void); +extern int hw_perf_group_sched_in(struct perf_counter *group_leader, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx, int cpu); #else static inline void diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index b7a027a2ef02..9ad11e44d9ab 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -47,6 +47,12 @@ hw_perf_counter_init(struct perf_counter *counter) u64 __weak hw_perf_save_disable(void) { return 0; } void __weak hw_perf_restore(u64 ctrl) { barrier(); } void __weak hw_perf_counter_setup(void) { barrier(); } +int __weak hw_perf_group_sched_in(struct perf_counter *group_leader, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx, int cpu) +{ + return 0; +} static void list_add_counter(struct perf_counter *counter, struct perf_counter_context *ctx) @@ -341,6 +347,9 @@ group_sched_out(struct perf_counter *group_counter, { struct perf_counter *counter; + if (group_counter->state != PERF_COUNTER_STATE_ACTIVE) + return; + counter_sched_out(group_counter, cpuctx, ctx); /* @@ -354,15 +363,18 @@ void __perf_counter_sched_out(struct perf_counter_context *ctx, struct perf_cpu_context *cpuctx) { struct perf_counter *counter; + u64 flags; if (likely(!ctx->nr_counters)) return; spin_lock(&ctx->lock); + flags = hw_perf_save_disable(); if (ctx->nr_active) { list_for_each_entry(counter, &ctx->counter_list, list_entry) group_sched_out(counter, cpuctx, ctx); } + hw_perf_restore(flags); spin_unlock(&ctx->lock); } @@ -402,7 +414,14 @@ group_sched_in(struct perf_counter *group_counter, int cpu) { struct perf_counter *counter, *partial_group; - int ret = 0; + int ret; + + if (group_counter->state == PERF_COUNTER_STATE_OFF) + return 0; + + ret = hw_perf_group_sched_in(group_counter, cpuctx, ctx, cpu); + if (ret) + return ret < 0 ? ret : 0; if (counter_sched_in(group_counter, cpuctx, ctx, cpu)) return -EAGAIN; @@ -415,10 +434,9 @@ group_sched_in(struct perf_counter *group_counter, partial_group = counter; goto group_error; } - ret = -EAGAIN; } - return ret; + return 0; group_error: /* @@ -440,11 +458,13 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, struct perf_cpu_context *cpuctx, int cpu) { struct perf_counter *counter; + u64 flags; if (likely(!ctx->nr_counters)) return; spin_lock(&ctx->lock); + flags = hw_perf_save_disable(); list_for_each_entry(counter, &ctx->counter_list, list_entry) { /* * Listen to the 'cpu' scheduling filter constraint @@ -454,12 +474,13 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, continue; /* - * If we scheduled in a group atomically and - * exclusively, break out: + * If we scheduled in a group atomically and exclusively, + * or if this group can't go on, break out: */ if (group_sched_in(counter, cpuctx, ctx, cpu)) break; } + hw_perf_restore(flags); spin_unlock(&ctx->lock); } -- GitLab From 4eb96fcfe07b7f2a05577e57533840f8e26bea53 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Jan 2009 17:24:34 +1100 Subject: [PATCH 0058/6080] perf_counter: Add dummy perf_counter_print_debug function Impact: minimize requirements on architectures Currently, an architecture just enabling CONFIG_PERF_COUNTERS but not providing any extra functions will fail to build with perf_counter_print_debug being undefined, since we don't provide an empty dummy definition like we do with the hw_perf_* functions. This provides an empty dummy perf_counter_print_debug() to make it easier for architectures to turn on CONFIG_PERF_COUNTERS. Signed-off-by: Paul Mackerras --- kernel/perf_counter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 9ad11e44d9ab..4c0dccb756ad 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -54,6 +54,8 @@ int __weak hw_perf_group_sched_in(struct perf_counter *group_leader, return 0; } +void __weak perf_counter_print_debug(void) { } + static void list_add_counter(struct perf_counter *counter, struct perf_counter_context *ctx) { -- GitLab From d662ed26734473d4cb5f3d78cebfec8f9126e97c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Jan 2009 17:01:53 +1100 Subject: [PATCH 0059/6080] powerpc/perf_counter: Add perf_counter system call on powerpc ... with an empty/dummy asm/perf_counter.h so it builds. Signed-off-by: Paul Mackerras --- arch/powerpc/include/asm/perf_counter.h | 10 ++++++++++ arch/powerpc/include/asm/systbl.h | 1 + arch/powerpc/include/asm/unistd.h | 3 ++- arch/powerpc/platforms/Kconfig.cputype | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/include/asm/perf_counter.h diff --git a/arch/powerpc/include/asm/perf_counter.h b/arch/powerpc/include/asm/perf_counter.h new file mode 100644 index 000000000000..59530ae1d53c --- /dev/null +++ b/arch/powerpc/include/asm/perf_counter.h @@ -0,0 +1,10 @@ +/* + * Performance counter support - PowerPC-specific definitions. + * + * Copyright 2008-2009 Paul Mackerras, IBM 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 the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 803def236654..da300c4d2888 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -322,3 +322,4 @@ SYSCALL_SPU(epoll_create1) SYSCALL_SPU(dup3) SYSCALL_SPU(pipe2) SYSCALL(inotify_init1) +SYSCALL(perf_counter_open) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index e07d0c76ed77..7cef5afe89d8 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -341,10 +341,11 @@ #define __NR_dup3 316 #define __NR_pipe2 317 #define __NR_inotify_init1 318 +#define __NR_perf_counter_open 319 #ifdef __KERNEL__ -#define __NR_syscalls 319 +#define __NR_syscalls 320 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 3d0c776f888d..94dd1fb9a004 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -1,6 +1,7 @@ config PPC64 bool "64-bit kernel" default n + select HAVE_PERF_COUNTERS help This option selects whether a 32-bit or a 64-bit kernel will be built. -- GitLab From 93a6d3ce6962044fe9badf528fed46b455d58292 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Jan 2009 16:52:19 +1100 Subject: [PATCH 0060/6080] powerpc: Provide a way to defer perf counter work until interrupts are enabled Because 64-bit powerpc uses lazy (soft) interrupt disabling, it is possible for a performance monitor exception to come in when the kernel thinks interrupts are disabled (i.e. when they are soft-disabled but hard-enabled). In such a situation the performance monitor exception handler might have some processing to do (such as process wakeups) which can't be done in what is effectively an NMI handler. This provides a way to defer that work until interrupts get enabled, either in raw_local_irq_restore() or by returning from an interrupt handler to code that had interrupts enabled. We have a per-processor flag that indicates that there is work pending to do when interrupts subsequently get re-enabled. This flag is checked in the interrupt return path and in raw_local_irq_restore(), and if it is set, perf_counter_do_pending() is called to do the pending work. Signed-off-by: Paul Mackerras --- arch/powerpc/include/asm/hw_irq.h | 31 +++++++++++++++++++++++++++++++ arch/powerpc/include/asm/paca.h | 1 + arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kernel/entry_64.S | 9 +++++++++ arch/powerpc/kernel/irq.c | 10 ++++++++++ 5 files changed, 52 insertions(+) diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index f75a5fc64d2e..e10f151c3db6 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -131,5 +131,36 @@ static inline int irqs_disabled_flags(unsigned long flags) */ struct hw_interrupt_type; +#ifdef CONFIG_PERF_COUNTERS +static inline unsigned long get_perf_counter_pending(void) +{ + unsigned long x; + + asm volatile("lbz %0,%1(13)" + : "=r" (x) + : "i" (offsetof(struct paca_struct, perf_counter_pending))); + return x; +} + +static inline void set_perf_counter_pending(int x) +{ + asm volatile("stb %0,%1(13)" : : + "r" (x), + "i" (offsetof(struct paca_struct, perf_counter_pending))); +} + +extern void perf_counter_do_pending(void); + +#else + +static inline unsigned long get_perf_counter_pending(void) +{ + return 0; +} + +static inline void set_perf_counter_pending(int x) {} +static inline void perf_counter_do_pending(void) {} +#endif /* CONFIG_PERF_COUNTERS */ + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HW_IRQ_H */ diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 082b3aedf145..6ef055723019 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -99,6 +99,7 @@ struct paca_struct { u8 soft_enabled; /* irq soft-enable flag */ u8 hard_enabled; /* set if irqs are enabled in MSR */ u8 io_sync; /* writel() needs spin_unlock sync */ + u8 perf_counter_pending; /* PM interrupt while soft-disabled */ /* Stuff for accurate time accounting */ u64 user_time; /* accumulated usermode TB ticks */ diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 661d07d2146b..cea462900119 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -127,6 +127,7 @@ int main(void) DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr)); DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled)); + DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_counter_pending)); DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 383ed6eb0085..f30b4e553c53 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -526,6 +526,15 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES) 2: TRACE_AND_RESTORE_IRQ(r5); +#ifdef CONFIG_PERF_COUNTERS + /* check paca->perf_counter_pending if we're enabling ints */ + lbz r3,PACAPERFPEND(r13) + and. r3,r3,r5 + beq 27f + bl .perf_counter_do_pending +27: +#endif /* CONFIG_PERF_COUNTERS */ + /* extract EE bit and use it to restore paca->hard_enabled */ ld r3,_MSR(r1) rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index ac222d0ab12e..4efb886ea439 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -104,6 +104,13 @@ static inline notrace void set_soft_enabled(unsigned long enable) : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled))); } +#ifdef CONFIG_PERF_COUNTERS +notrace void __weak perf_counter_do_pending(void) +{ + set_perf_counter_pending(0); +} +#endif + notrace void raw_local_irq_restore(unsigned long en) { /* @@ -135,6 +142,9 @@ notrace void raw_local_irq_restore(unsigned long en) iseries_handle_interrupts(); } + if (get_perf_counter_pending()) + perf_counter_do_pending(); + /* * if (get_paca()->hard_enabled) return; * But again we need to take care that gcc gets hard_enabled directly -- GitLab From 4574910e5087085a1f330ff8373cee4503f5c77c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Jan 2009 20:21:55 +1100 Subject: [PATCH 0061/6080] powerpc/perf_counter: Add generic support for POWER-family PMU hardware This provides the architecture-specific functions needed to access PMU hardware on the 64-bit PowerPC processors. It has been designed for the IBM POWER family (POWER 4/4+/5/5+/6 and PPC970) but will hopefully also suit other 64-bit PowerPC machines (although probably not Cell given how different it is in this area). This doesn't include back-ends for any specific processors. This implements a system which allows back-ends to express the constraints that their hardware has on what events can be counted simultaneously. The constraints are expressed as a 64-bit mask + 64-bit value for each event, and the encoding is capable of expressing the constraints arising from having a set of multiplexers feeding an event bus, with some events being available through multiple multiplexer settings, such as we get on POWER4 and PPC970. Furthermore, the back-end can supply alternative event codes for each event, and the constraint checking code will try all possible combinations of alternative event codes to try to find a combination that will fit. Signed-off-by: Paul Mackerras --- arch/powerpc/include/asm/perf_counter.h | 62 ++ arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/perf_counter.c | 754 ++++++++++++++++++++++++ 3 files changed, 817 insertions(+) create mode 100644 arch/powerpc/kernel/perf_counter.c diff --git a/arch/powerpc/include/asm/perf_counter.h b/arch/powerpc/include/asm/perf_counter.h index 59530ae1d53c..9d7ff6d7fb56 100644 --- a/arch/powerpc/include/asm/perf_counter.h +++ b/arch/powerpc/include/asm/perf_counter.h @@ -8,3 +8,65 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#include + +#define MAX_HWCOUNTERS 8 +#define MAX_EVENT_ALTERNATIVES 8 + +/* + * This struct provides the constants and functions needed to + * describe the PMU on a particular POWER-family CPU. + */ +struct power_pmu { + int n_counter; + int max_alternatives; + u64 add_fields; + u64 test_adder; + int (*compute_mmcr)(unsigned int events[], int n_ev, + unsigned int hwc[], u64 mmcr[]); + int (*get_constraint)(unsigned int event, u64 *mskp, u64 *valp); + int (*get_alternatives)(unsigned int event, unsigned int alt[]); + void (*disable_pmc)(unsigned int pmc, u64 mmcr[]); + int n_generic; + int *generic_events; +}; + +extern struct power_pmu *ppmu; + +/* + * The power_pmu.get_constraint function returns a 64-bit value and + * a 64-bit mask that express the constraints between this event and + * other events. + * + * The value and mask are divided up into (non-overlapping) bitfields + * of three different types: + * + * Select field: this expresses the constraint that some set of bits + * in MMCR* needs to be set to a specific value for this event. For a + * select field, the mask contains 1s in every bit of the field, and + * the value contains a unique value for each possible setting of the + * MMCR* bits. The constraint checking code will ensure that two events + * that set the same field in their masks have the same value in their + * value dwords. + * + * Add field: this expresses the constraint that there can be at most + * N events in a particular class. A field of k bits can be used for + * N <= 2^(k-1) - 1. The mask has the most significant bit of the field + * set (and the other bits 0), and the value has only the least significant + * bit of the field set. In addition, the 'add_fields' and 'test_adder' + * in the struct power_pmu for this processor come into play. The + * add_fields value contains 1 in the LSB of the field, and the + * test_adder contains 2^(k-1) - 1 - N in the field. + * + * NAND field: this expresses the constraint that you may not have events + * in all of a set of classes. (For example, on PPC970, you can't select + * events from the FPU, ISU and IDU simultaneously, although any two are + * possible.) For N classes, the field is N+1 bits wide, and each class + * is assigned one bit from the least-significant N bits. The mask has + * only the most-significant bit set, and the value has only the bit + * for the event's class set. The test_adder has the least significant + * bit set in the field. + * + * If an event is not subject to the constraint expressed by a particular + * field, then it will have 0 in both the mask and value for that field. + */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 1308a86e9070..fde190bbb2bd 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -94,6 +94,7 @@ obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o +obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c new file mode 100644 index 000000000000..c7d4c2966a5c --- /dev/null +++ b/arch/powerpc/kernel/perf_counter.c @@ -0,0 +1,754 @@ +/* + * Performance counter support - powerpc architecture code + * + * Copyright 2008-2009 Paul Mackerras, IBM 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 the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +struct cpu_hw_counters { + int n_counters; + int n_percpu; + int disabled; + int n_added; + struct perf_counter *counter[MAX_HWCOUNTERS]; + unsigned int events[MAX_HWCOUNTERS]; + u64 mmcr[3]; +}; +DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters); + +struct power_pmu *ppmu; + +void perf_counter_print_debug(void) +{ +} + +/* + * Return 1 for a software counter, 0 for a hardware counter + */ +static inline int is_software_counter(struct perf_counter *counter) +{ + return !counter->hw_event.raw && counter->hw_event.type < 0; +} + +/* + * Read one performance monitor counter (PMC). + */ +static unsigned long read_pmc(int idx) +{ + unsigned long val; + + switch (idx) { + case 1: + val = mfspr(SPRN_PMC1); + break; + case 2: + val = mfspr(SPRN_PMC2); + break; + case 3: + val = mfspr(SPRN_PMC3); + break; + case 4: + val = mfspr(SPRN_PMC4); + break; + case 5: + val = mfspr(SPRN_PMC5); + break; + case 6: + val = mfspr(SPRN_PMC6); + break; + case 7: + val = mfspr(SPRN_PMC7); + break; + case 8: + val = mfspr(SPRN_PMC8); + break; + default: + printk(KERN_ERR "oops trying to read PMC%d\n", idx); + val = 0; + } + return val; +} + +/* + * Write one PMC. + */ +static void write_pmc(int idx, unsigned long val) +{ + switch (idx) { + case 1: + mtspr(SPRN_PMC1, val); + break; + case 2: + mtspr(SPRN_PMC2, val); + break; + case 3: + mtspr(SPRN_PMC3, val); + break; + case 4: + mtspr(SPRN_PMC4, val); + break; + case 5: + mtspr(SPRN_PMC5, val); + break; + case 6: + mtspr(SPRN_PMC6, val); + break; + case 7: + mtspr(SPRN_PMC7, val); + break; + case 8: + mtspr(SPRN_PMC8, val); + break; + default: + printk(KERN_ERR "oops trying to write PMC%d\n", idx); + } +} + +/* + * Check if a set of events can all go on the PMU at once. + * If they can't, this will look at alternative codes for the events + * and see if any combination of alternative codes is feasible. + * The feasible set is returned in event[]. + */ +static int power_check_constraints(unsigned int event[], int n_ev) +{ + u64 mask, value, nv; + unsigned int alternatives[MAX_HWCOUNTERS][MAX_EVENT_ALTERNATIVES]; + u64 amasks[MAX_HWCOUNTERS][MAX_EVENT_ALTERNATIVES]; + u64 avalues[MAX_HWCOUNTERS][MAX_EVENT_ALTERNATIVES]; + u64 smasks[MAX_HWCOUNTERS], svalues[MAX_HWCOUNTERS]; + int n_alt[MAX_HWCOUNTERS], choice[MAX_HWCOUNTERS]; + int i, j; + u64 addf = ppmu->add_fields; + u64 tadd = ppmu->test_adder; + + if (n_ev > ppmu->n_counter) + return -1; + + /* First see if the events will go on as-is */ + for (i = 0; i < n_ev; ++i) { + alternatives[i][0] = event[i]; + if (ppmu->get_constraint(event[i], &amasks[i][0], + &avalues[i][0])) + return -1; + choice[i] = 0; + } + value = mask = 0; + for (i = 0; i < n_ev; ++i) { + nv = (value | avalues[i][0]) + (value & avalues[i][0] & addf); + if ((((nv + tadd) ^ value) & mask) != 0 || + (((nv + tadd) ^ avalues[i][0]) & amasks[i][0]) != 0) + break; + value = nv; + mask |= amasks[i][0]; + } + if (i == n_ev) + return 0; /* all OK */ + + /* doesn't work, gather alternatives... */ + if (!ppmu->get_alternatives) + return -1; + for (i = 0; i < n_ev; ++i) { + n_alt[i] = ppmu->get_alternatives(event[i], alternatives[i]); + for (j = 1; j < n_alt[i]; ++j) + ppmu->get_constraint(alternatives[i][j], + &amasks[i][j], &avalues[i][j]); + } + + /* enumerate all possibilities and see if any will work */ + i = 0; + j = -1; + value = mask = nv = 0; + while (i < n_ev) { + if (j >= 0) { + /* we're backtracking, restore context */ + value = svalues[i]; + mask = smasks[i]; + j = choice[i]; + } + /* + * See if any alternative k for event i, + * where k > j, will satisfy the constraints. + */ + while (++j < n_alt[i]) { + nv = (value | avalues[i][j]) + + (value & avalues[i][j] & addf); + if ((((nv + tadd) ^ value) & mask) == 0 && + (((nv + tadd) ^ avalues[i][j]) + & amasks[i][j]) == 0) + break; + } + if (j >= n_alt[i]) { + /* + * No feasible alternative, backtrack + * to event i-1 and continue enumerating its + * alternatives from where we got up to. + */ + if (--i < 0) + return -1; + } else { + /* + * Found a feasible alternative for event i, + * remember where we got up to with this event, + * go on to the next event, and start with + * the first alternative for it. + */ + choice[i] = j; + svalues[i] = value; + smasks[i] = mask; + value = nv; + mask |= amasks[i][j]; + ++i; + j = -1; + } + } + + /* OK, we have a feasible combination, tell the caller the solution */ + for (i = 0; i < n_ev; ++i) + event[i] = alternatives[i][choice[i]]; + return 0; +} + +static void power_perf_read(struct perf_counter *counter) +{ + long val, delta, prev; + + if (!counter->hw.idx) + return; + /* + * Performance monitor interrupts come even when interrupts + * are soft-disabled, as long as interrupts are hard-enabled. + * Therefore we treat them like NMIs. + */ + do { + prev = atomic64_read(&counter->hw.prev_count); + barrier(); + val = read_pmc(counter->hw.idx); + } while (atomic64_cmpxchg(&counter->hw.prev_count, prev, val) != prev); + + /* The counters are only 32 bits wide */ + delta = (val - prev) & 0xfffffffful; + atomic64_add(delta, &counter->count); + atomic64_sub(delta, &counter->hw.period_left); +} + +/* + * Disable all counters to prevent PMU interrupts and to allow + * counters to be added or removed. + */ +u64 hw_perf_save_disable(void) +{ + struct cpu_hw_counters *cpuhw; + unsigned long ret; + unsigned long flags; + + local_irq_save(flags); + cpuhw = &__get_cpu_var(cpu_hw_counters); + + ret = cpuhw->disabled; + if (!ret) { + cpuhw->disabled = 1; + cpuhw->n_added = 0; + + /* + * Set the 'freeze counters' bit. + * The barrier is to make sure the mtspr has been + * executed and the PMU has frozen the counters + * before we return. + */ + mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC); + mb(); + } + local_irq_restore(flags); + return ret; +} + +/* + * Re-enable all counters if disable == 0. + * If we were previously disabled and counters were added, then + * put the new config on the PMU. + */ +void hw_perf_restore(u64 disable) +{ + struct perf_counter *counter; + struct cpu_hw_counters *cpuhw; + unsigned long flags; + long i; + unsigned long val; + s64 left; + unsigned int hwc_index[MAX_HWCOUNTERS]; + + if (disable) + return; + local_irq_save(flags); + cpuhw = &__get_cpu_var(cpu_hw_counters); + cpuhw->disabled = 0; + + /* + * If we didn't change anything, or only removed counters, + * no need to recalculate MMCR* settings and reset the PMCs. + * Just reenable the PMU with the current MMCR* settings + * (possibly updated for removal of counters). + */ + if (!cpuhw->n_added) { + mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); + mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); + mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); + goto out; + } + + /* + * Compute MMCR* values for the new set of counters + */ + if (ppmu->compute_mmcr(cpuhw->events, cpuhw->n_counters, hwc_index, + cpuhw->mmcr)) { + /* shouldn't ever get here */ + printk(KERN_ERR "oops compute_mmcr failed\n"); + goto out; + } + + /* + * Write the new configuration to MMCR* with the freeze + * bit set and set the hardware counters to their initial values. + * Then unfreeze the counters. + */ + mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); + mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); + mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)) + | MMCR0_FC); + + /* + * Read off any pre-existing counters that need to move + * to another PMC. + */ + for (i = 0; i < cpuhw->n_counters; ++i) { + counter = cpuhw->counter[i]; + if (counter->hw.idx && counter->hw.idx != hwc_index[i] + 1) { + power_perf_read(counter); + write_pmc(counter->hw.idx, 0); + counter->hw.idx = 0; + } + } + + /* + * Initialize the PMCs for all the new and moved counters. + */ + for (i = 0; i < cpuhw->n_counters; ++i) { + counter = cpuhw->counter[i]; + if (counter->hw.idx) + continue; + val = 0; + if (counter->hw_event.irq_period) { + left = atomic64_read(&counter->hw.period_left); + if (left < 0x80000000L) + val = 0x80000000L - left; + } + atomic64_set(&counter->hw.prev_count, val); + counter->hw.idx = hwc_index[i] + 1; + write_pmc(counter->hw.idx, val); + } + mb(); + cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE; + mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); + + out: + local_irq_restore(flags); +} + +static int collect_events(struct perf_counter *group, int max_count, + struct perf_counter *ctrs[], unsigned int *events) +{ + int n = 0; + struct perf_counter *counter; + + if (!is_software_counter(group)) { + if (n >= max_count) + return -1; + ctrs[n] = group; + events[n++] = group->hw.config; + } + list_for_each_entry(counter, &group->sibling_list, list_entry) { + if (!is_software_counter(counter) && + counter->state != PERF_COUNTER_STATE_OFF) { + if (n >= max_count) + return -1; + ctrs[n] = counter; + events[n++] = counter->hw.config; + } + } + return n; +} + +static void counter_sched_in(struct perf_counter *counter, int cpu) +{ + counter->state = PERF_COUNTER_STATE_ACTIVE; + counter->oncpu = cpu; + if (is_software_counter(counter)) + counter->hw_ops->enable(counter); +} + +/* + * Called to enable a whole group of counters. + * Returns 1 if the group was enabled, or -EAGAIN if it could not be. + * Assumes the caller has disabled interrupts and has + * frozen the PMU with hw_perf_save_disable. + */ +int hw_perf_group_sched_in(struct perf_counter *group_leader, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx, int cpu) +{ + struct cpu_hw_counters *cpuhw; + long i, n, n0; + struct perf_counter *sub; + + cpuhw = &__get_cpu_var(cpu_hw_counters); + n0 = cpuhw->n_counters; + n = collect_events(group_leader, ppmu->n_counter - n0, + &cpuhw->counter[n0], &cpuhw->events[n0]); + if (n < 0) + return -EAGAIN; + if (power_check_constraints(cpuhw->events, n + n0)) + return -EAGAIN; + cpuhw->n_counters = n0 + n; + cpuhw->n_added += n; + + /* + * OK, this group can go on; update counter states etc., + * and enable any software counters + */ + for (i = n0; i < n0 + n; ++i) + cpuhw->counter[i]->hw.config = cpuhw->events[i]; + n = 1; + counter_sched_in(group_leader, cpu); + list_for_each_entry(sub, &group_leader->sibling_list, list_entry) { + if (sub->state != PERF_COUNTER_STATE_OFF) { + counter_sched_in(sub, cpu); + ++n; + } + } + cpuctx->active_oncpu += n; + ctx->nr_active += n; + + return 1; +} + +/* + * Add a counter to the PMU. + * If all counters are not already frozen, then we disable and + * re-enable the PMU in order to get hw_perf_restore to do the + * actual work of reconfiguring the PMU. + */ +static int power_perf_enable(struct perf_counter *counter) +{ + struct cpu_hw_counters *cpuhw; + unsigned long flags; + u64 pmudis; + int n0; + int ret = -EAGAIN; + + local_irq_save(flags); + pmudis = hw_perf_save_disable(); + + /* + * Add the counter to the list (if there is room) + * and check whether the total set is still feasible. + */ + cpuhw = &__get_cpu_var(cpu_hw_counters); + n0 = cpuhw->n_counters; + if (n0 >= ppmu->n_counter) + goto out; + cpuhw->counter[n0] = counter; + cpuhw->events[n0] = counter->hw.config; + if (power_check_constraints(cpuhw->events, n0 + 1)) + goto out; + + counter->hw.config = cpuhw->events[n0]; + ++cpuhw->n_counters; + ++cpuhw->n_added; + + ret = 0; + out: + hw_perf_restore(pmudis); + local_irq_restore(flags); + return ret; +} + +/* + * Remove a counter from the PMU. + */ +static void power_perf_disable(struct perf_counter *counter) +{ + struct cpu_hw_counters *cpuhw; + long i; + u64 pmudis; + unsigned long flags; + + local_irq_save(flags); + pmudis = hw_perf_save_disable(); + + power_perf_read(counter); + + cpuhw = &__get_cpu_var(cpu_hw_counters); + for (i = 0; i < cpuhw->n_counters; ++i) { + if (counter == cpuhw->counter[i]) { + while (++i < cpuhw->n_counters) + cpuhw->counter[i-1] = cpuhw->counter[i]; + --cpuhw->n_counters; + ppmu->disable_pmc(counter->hw.idx - 1, cpuhw->mmcr); + write_pmc(counter->hw.idx, 0); + counter->hw.idx = 0; + break; + } + } + if (cpuhw->n_counters == 0) { + /* disable exceptions if no counters are running */ + cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE); + } + + hw_perf_restore(pmudis); + local_irq_restore(flags); +} + +struct hw_perf_counter_ops power_perf_ops = { + .enable = power_perf_enable, + .disable = power_perf_disable, + .read = power_perf_read +}; + +const struct hw_perf_counter_ops * +hw_perf_counter_init(struct perf_counter *counter) +{ + unsigned long ev; + struct perf_counter *ctrs[MAX_HWCOUNTERS]; + unsigned int events[MAX_HWCOUNTERS]; + int n; + + if (!ppmu) + return NULL; + if ((s64)counter->hw_event.irq_period < 0) + return NULL; + ev = counter->hw_event.type; + if (!counter->hw_event.raw) { + if (ev >= ppmu->n_generic || + ppmu->generic_events[ev] == 0) + return NULL; + ev = ppmu->generic_events[ev]; + } + counter->hw.config_base = ev; + counter->hw.idx = 0; + + /* + * If this is in a group, check if it can go on with all the + * other hardware counters in the group. We assume the counter + * hasn't been linked into its leader's sibling list at this point. + */ + n = 0; + if (counter->group_leader != counter) { + n = collect_events(counter->group_leader, ppmu->n_counter - 1, + ctrs, events); + if (n < 0) + return NULL; + } + events[n++] = ev; + if (power_check_constraints(events, n)) + return NULL; + + counter->hw.config = events[n - 1]; + atomic64_set(&counter->hw.period_left, counter->hw_event.irq_period); + return &power_perf_ops; +} + +/* + * Handle wakeups. + */ +void perf_counter_do_pending(void) +{ + int i; + struct cpu_hw_counters *cpuhw = &__get_cpu_var(cpu_hw_counters); + struct perf_counter *counter; + + set_perf_counter_pending(0); + for (i = 0; i < cpuhw->n_counters; ++i) { + counter = cpuhw->counter[i]; + if (counter && counter->wakeup_pending) { + counter->wakeup_pending = 0; + wake_up(&counter->waitq); + } + } +} + +/* + * Record data for an irq counter. + * This function was lifted from the x86 code; maybe it should + * go in the core? + */ +static void perf_store_irq_data(struct perf_counter *counter, u64 data) +{ + struct perf_data *irqdata = counter->irqdata; + + if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) { + irqdata->overrun++; + } else { + u64 *p = (u64 *) &irqdata->data[irqdata->len]; + + *p = data; + irqdata->len += sizeof(u64); + } +} + +/* + * Record all the values of the counters in a group + */ +static void perf_handle_group(struct perf_counter *counter) +{ + struct perf_counter *leader, *sub; + + leader = counter->group_leader; + list_for_each_entry(sub, &leader->sibling_list, list_entry) { + if (sub != counter) + sub->hw_ops->read(sub); + perf_store_irq_data(counter, sub->hw_event.type); + perf_store_irq_data(counter, atomic64_read(&sub->count)); + } +} + +/* + * A counter has overflowed; update its count and record + * things if requested. Note that interrupts are hard-disabled + * here so there is no possibility of being interrupted. + */ +static void record_and_restart(struct perf_counter *counter, long val, + struct pt_regs *regs) +{ + s64 prev, delta, left; + int record = 0; + + /* we don't have to worry about interrupts here */ + prev = atomic64_read(&counter->hw.prev_count); + delta = (val - prev) & 0xfffffffful; + atomic64_add(delta, &counter->count); + + /* + * See if the total period for this counter has expired, + * and update for the next period. + */ + val = 0; + left = atomic64_read(&counter->hw.period_left) - delta; + if (counter->hw_event.irq_period) { + if (left <= 0) { + left += counter->hw_event.irq_period; + if (left <= 0) + left = counter->hw_event.irq_period; + record = 1; + } + if (left < 0x80000000L) + val = 0x80000000L - left; + } + write_pmc(counter->hw.idx, val); + atomic64_set(&counter->hw.prev_count, val); + atomic64_set(&counter->hw.period_left, left); + + /* + * Finally record data if requested. + */ + if (record) { + switch (counter->hw_event.record_type) { + case PERF_RECORD_SIMPLE: + break; + case PERF_RECORD_IRQ: + perf_store_irq_data(counter, instruction_pointer(regs)); + counter->wakeup_pending = 1; + break; + case PERF_RECORD_GROUP: + perf_handle_group(counter); + counter->wakeup_pending = 1; + break; + } + } +} + +/* + * Performance monitor interrupt stuff + */ +static void perf_counter_interrupt(struct pt_regs *regs) +{ + int i; + struct cpu_hw_counters *cpuhw = &__get_cpu_var(cpu_hw_counters); + struct perf_counter *counter; + long val; + int need_wakeup = 0, found = 0; + + for (i = 0; i < cpuhw->n_counters; ++i) { + counter = cpuhw->counter[i]; + val = read_pmc(counter->hw.idx); + if ((int)val < 0) { + /* counter has overflowed */ + found = 1; + record_and_restart(counter, val, regs); + if (counter->wakeup_pending) + need_wakeup = 1; + } + } + + /* + * In case we didn't find and reset the counter that caused + * the interrupt, scan all counters and reset any that are + * negative, to avoid getting continual interrupts. + * Any that we processed in the previous loop will not be negative. + */ + if (!found) { + for (i = 0; i < ppmu->n_counter; ++i) { + val = read_pmc(i + 1); + if ((int)val < 0) + write_pmc(i + 1, 0); + } + } + + /* + * Reset MMCR0 to its normal value. This will set PMXE and + * clear FC (freeze counters) and PMAO (perf mon alert occurred) + * and thus allow interrupts to occur again. + * XXX might want to use MSR.PM to keep the counters frozen until + * we get back out of this interrupt. + */ + mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); + + /* + * If we need a wakeup, check whether interrupts were soft-enabled + * when we took the interrupt. If they were, we can wake stuff up + * immediately; otherwise we'll have to set a flag and do the + * wakeup when interrupts get soft-enabled. + */ + if (need_wakeup) { + if (regs->softe) { + irq_enter(); + perf_counter_do_pending(); + irq_exit(); + } else { + set_perf_counter_pending(1); + } + } +} + +static int init_perf_counters(void) +{ + if (reserve_pmc_hardware(perf_counter_interrupt)) { + printk(KERN_ERR "Couldn't init performance monitor subsystem\n"); + return -EBUSY; + } + + return 0; +} + +arch_initcall(init_perf_counters); -- GitLab From 16b067993dee3dfde61b20027e0b168dc06201ee Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 10 Jan 2009 16:34:07 +1100 Subject: [PATCH 0062/6080] powerpc/perf_counter: Add support for PPC970 family This adds the back-end for the PMU on the PPC970 family. The PPC970 allows events from the ISU to be selected in two different ways. Rather than use alternative event codes to express this, we instead use a single encoding for ISU events and express the resulting constraint (that you can't select events from all three of FPU/IFU/VPU, ISU and IDU/STS at the same time, since they all come in through only 2 multiplexers) using a NAND constraint field, and work out which multiplexer is used for ISU events at compute_mmcr time. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/perf_counter.c | 13 + arch/powerpc/kernel/ppc970-pmu.c | 375 +++++++++++++++++++++++++++++ 3 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/kernel/ppc970-pmu.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index fde190bbb2bd..45798f6fb137 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -94,7 +94,7 @@ obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o -obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o +obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o ppc970-pmu.o obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index c7d4c2966a5c..5561ecb02a4b 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -741,13 +741,26 @@ static void perf_counter_interrupt(struct pt_regs *regs) } } +extern struct power_pmu ppc970_pmu; + static int init_perf_counters(void) { + unsigned long pvr; + if (reserve_pmc_hardware(perf_counter_interrupt)) { printk(KERN_ERR "Couldn't init performance monitor subsystem\n"); return -EBUSY; } + /* XXX should get this from cputable */ + pvr = mfspr(SPRN_PVR); + switch (PVR_VER(pvr)) { + case PV_970: + case PV_970FX: + case PV_970MP: + ppmu = &ppc970_pmu; + break; + } return 0; } diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c new file mode 100644 index 000000000000..c3256580be1a --- /dev/null +++ b/arch/powerpc/kernel/ppc970-pmu.c @@ -0,0 +1,375 @@ +/* + * Performance counter support for PPC970-family processors. + * + * Copyright 2008-2009 Paul Mackerras, IBM 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 the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include + +/* + * Bits in event code for PPC970 + */ +#define PM_PMC_SH 12 /* PMC number (1-based) for direct events */ +#define PM_PMC_MSK 0xf +#define PM_UNIT_SH 8 /* TTMMUX number and setting - unit select */ +#define PM_UNIT_MSK 0xf +#define PM_BYTE_SH 4 /* Byte number of event bus to use */ +#define PM_BYTE_MSK 3 +#define PM_PMCSEL_MSK 0xf + +/* Values in PM_UNIT field */ +#define PM_NONE 0 +#define PM_FPU 1 +#define PM_VPU 2 +#define PM_ISU 3 +#define PM_IFU 4 +#define PM_IDU 5 +#define PM_STS 6 +#define PM_LSU0 7 +#define PM_LSU1U 8 +#define PM_LSU1L 9 +#define PM_LASTUNIT 9 + +/* + * Bits in MMCR0 for PPC970 + */ +#define MMCR0_PMC1SEL_SH 8 +#define MMCR0_PMC2SEL_SH 1 +#define MMCR_PMCSEL_MSK 0x1f + +/* + * Bits in MMCR1 for PPC970 + */ +#define MMCR1_TTM0SEL_SH 62 +#define MMCR1_TTM1SEL_SH 59 +#define MMCR1_TTM3SEL_SH 53 +#define MMCR1_TTMSEL_MSK 3 +#define MMCR1_TD_CP_DBG0SEL_SH 50 +#define MMCR1_TD_CP_DBG1SEL_SH 48 +#define MMCR1_TD_CP_DBG2SEL_SH 46 +#define MMCR1_TD_CP_DBG3SEL_SH 44 +#define MMCR1_PMC1_ADDER_SEL_SH 39 +#define MMCR1_PMC2_ADDER_SEL_SH 38 +#define MMCR1_PMC6_ADDER_SEL_SH 37 +#define MMCR1_PMC5_ADDER_SEL_SH 36 +#define MMCR1_PMC8_ADDER_SEL_SH 35 +#define MMCR1_PMC7_ADDER_SEL_SH 34 +#define MMCR1_PMC3_ADDER_SEL_SH 33 +#define MMCR1_PMC4_ADDER_SEL_SH 32 +#define MMCR1_PMC3SEL_SH 27 +#define MMCR1_PMC4SEL_SH 22 +#define MMCR1_PMC5SEL_SH 17 +#define MMCR1_PMC6SEL_SH 12 +#define MMCR1_PMC7SEL_SH 7 +#define MMCR1_PMC8SEL_SH 2 + +static short mmcr1_adder_bits[8] = { + MMCR1_PMC1_ADDER_SEL_SH, + MMCR1_PMC2_ADDER_SEL_SH, + MMCR1_PMC3_ADDER_SEL_SH, + MMCR1_PMC4_ADDER_SEL_SH, + MMCR1_PMC5_ADDER_SEL_SH, + MMCR1_PMC6_ADDER_SEL_SH, + MMCR1_PMC7_ADDER_SEL_SH, + MMCR1_PMC8_ADDER_SEL_SH +}; + +/* + * Bits in MMCRA + */ + +/* + * Layout of constraint bits: + * 6666555555555544444444443333333333222222222211111111110000000000 + * 3210987654321098765432109876543210987654321098765432109876543210 + * <><>[ >[ >[ >< >< >< >< ><><><><><><><><> + * T0T1 UC PS1 PS2 B0 B1 B2 B3 P1P2P3P4P5P6P7P8 + * + * T0 - TTM0 constraint + * 46-47: TTM0SEL value (0=FPU, 2=IFU, 3=VPU) 0xC000_0000_0000 + * + * T1 - TTM1 constraint + * 44-45: TTM1SEL value (0=IDU, 3=STS) 0x3000_0000_0000 + * + * UC - unit constraint: can't have all three of FPU|IFU|VPU, ISU, IDU|STS + * 43: UC3 error 0x0800_0000_0000 + * 42: FPU|IFU|VPU events needed 0x0400_0000_0000 + * 41: ISU events needed 0x0200_0000_0000 + * 40: IDU|STS events needed 0x0100_0000_0000 + * + * PS1 + * 39: PS1 error 0x0080_0000_0000 + * 36-38: count of events needing PMC1/2/5/6 0x0070_0000_0000 + * + * PS2 + * 35: PS2 error 0x0008_0000_0000 + * 32-34: count of events needing PMC3/4/7/8 0x0007_0000_0000 + * + * B0 + * 28-31: Byte 0 event source 0xf000_0000 + * Encoding as for the event code + * + * B1, B2, B3 + * 24-27, 20-23, 16-19: Byte 1, 2, 3 event sources + * + * P1 + * 15: P1 error 0x8000 + * 14-15: Count of events needing PMC1 + * + * P2..P8 + * 0-13: Count of events needing PMC2..PMC8 + */ + +/* Masks and values for using events from the various units */ +static u64 unit_cons[PM_LASTUNIT+1][2] = { + [PM_FPU] = { 0xc80000000000ull, 0x040000000000ull }, + [PM_VPU] = { 0xc80000000000ull, 0xc40000000000ull }, + [PM_ISU] = { 0x080000000000ull, 0x020000000000ull }, + [PM_IFU] = { 0xc80000000000ull, 0x840000000000ull }, + [PM_IDU] = { 0x380000000000ull, 0x010000000000ull }, + [PM_STS] = { 0x380000000000ull, 0x310000000000ull }, +}; + +static int p970_get_constraint(unsigned int event, u64 *maskp, u64 *valp) +{ + int pmc, byte, unit, sh; + u64 mask = 0, value = 0; + int grp = -1; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc > 8) + return -1; + sh = (pmc - 1) * 2; + mask |= 2 << sh; + value |= 1 << sh; + grp = ((pmc - 1) >> 1) & 1; + } + unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; + if (unit) { + if (unit > PM_LASTUNIT) + return -1; + mask |= unit_cons[unit][0]; + value |= unit_cons[unit][1]; + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + /* + * Bus events on bytes 0 and 2 can be counted + * on PMC1/2/5/6; bytes 1 and 3 on PMC3/4/7/8. + */ + if (!pmc) + grp = byte & 1; + /* Set byte lane select field */ + mask |= 0xfULL << (28 - 4 * byte); + value |= (u64)unit << (28 - 4 * byte); + } + if (grp == 0) { + /* increment PMC1/2/5/6 field */ + mask |= 0x8000000000ull; + value |= 0x1000000000ull; + } else if (grp == 1) { + /* increment PMC3/4/7/8 field */ + mask |= 0x800000000ull; + value |= 0x100000000ull; + } + *maskp = mask; + *valp = value; + return 0; +} + +static int p970_get_alternatives(unsigned int event, unsigned int alt[]) +{ + alt[0] = event; + + /* 2 alternatives for LSU empty */ + if (event == 0x2002 || event == 0x3002) { + alt[1] = event ^ 0x1000; + return 2; + } + + return 1; +} + +static int p970_compute_mmcr(unsigned int event[], int n_ev, + unsigned int hwc[], u64 mmcr[]) +{ + u64 mmcr0 = 0, mmcr1 = 0, mmcra = 0; + unsigned int pmc, unit, byte, psel; + unsigned int ttm, grp; + unsigned int pmc_inuse = 0; + unsigned int pmc_grp_use[2]; + unsigned char busbyte[4]; + unsigned char unituse[16]; + unsigned char unitmap[] = { 0, 0<<3, 3<<3, 1<<3, 2<<3, 0|4, 3|4 }; + unsigned char ttmuse[2]; + unsigned char pmcsel[8]; + int i; + + if (n_ev > 8) + return -1; + + /* First pass to count resource use */ + pmc_grp_use[0] = pmc_grp_use[1] = 0; + memset(busbyte, 0, sizeof(busbyte)); + memset(unituse, 0, sizeof(unituse)); + for (i = 0; i < n_ev; ++i) { + pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc_inuse & (1 << (pmc - 1))) + return -1; + pmc_inuse |= 1 << (pmc - 1); + /* count 1/2/5/6 vs 3/4/7/8 use */ + ++pmc_grp_use[((pmc - 1) >> 1) & 1]; + } + unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK; + byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK; + if (unit) { + if (unit > PM_LASTUNIT) + return -1; + if (!pmc) + ++pmc_grp_use[byte & 1]; + if (busbyte[byte] && busbyte[byte] != unit) + return -1; + busbyte[byte] = unit; + unituse[unit] = 1; + } + } + if (pmc_grp_use[0] > 4 || pmc_grp_use[1] > 4) + return -1; + + /* + * Assign resources and set multiplexer selects. + * + * PM_ISU can go either on TTM0 or TTM1, but that's the only + * choice we have to deal with. + */ + if (unituse[PM_ISU] & + (unituse[PM_FPU] | unituse[PM_IFU] | unituse[PM_VPU])) + unitmap[PM_ISU] = 2 | 4; /* move ISU to TTM1 */ + /* Set TTM[01]SEL fields. */ + ttmuse[0] = ttmuse[1] = 0; + for (i = PM_FPU; i <= PM_STS; ++i) { + if (!unituse[i]) + continue; + ttm = unitmap[i]; + ++ttmuse[(ttm >> 2) & 1]; + mmcr1 |= (u64)(ttm & ~4) << MMCR1_TTM1SEL_SH; + } + /* Check only one unit per TTMx */ + if (ttmuse[0] > 1 || ttmuse[1] > 1) + return -1; + + /* Set byte lane select fields and TTM3SEL. */ + for (byte = 0; byte < 4; ++byte) { + unit = busbyte[byte]; + if (!unit) + continue; + if (unit <= PM_STS) + ttm = (unitmap[unit] >> 2) & 1; + else if (unit == PM_LSU0) + ttm = 2; + else { + ttm = 3; + if (unit == PM_LSU1L && byte >= 2) + mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte); + } + mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte); + } + + /* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */ + memset(pmcsel, 0x8, sizeof(pmcsel)); /* 8 means don't count */ + for (i = 0; i < n_ev; ++i) { + pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; + unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK; + byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK; + psel = event[i] & PM_PMCSEL_MSK; + if (!pmc) { + /* Bus event or any-PMC direct event */ + if (unit) + psel |= 0x10 | ((byte & 2) << 2); + else + psel |= 8; + for (pmc = 0; pmc < 8; ++pmc) { + if (pmc_inuse & (1 << pmc)) + continue; + grp = (pmc >> 1) & 1; + if (unit) { + if (grp == (byte & 1)) + break; + } else if (pmc_grp_use[grp] < 4) { + ++pmc_grp_use[grp]; + break; + } + } + pmc_inuse |= 1 << pmc; + } else { + /* Direct event */ + --pmc; + if (psel == 0 && (byte & 2)) + /* add events on higher-numbered bus */ + mmcr1 |= 1ull << mmcr1_adder_bits[pmc]; + } + pmcsel[pmc] = psel; + hwc[i] = pmc; + } + for (pmc = 0; pmc < 2; ++pmc) + mmcr0 |= pmcsel[pmc] << (MMCR0_PMC1SEL_SH - 7 * pmc); + for (; pmc < 8; ++pmc) + mmcr1 |= (u64)pmcsel[pmc] << (MMCR1_PMC3SEL_SH - 5 * (pmc - 2)); + if (pmc_inuse & 1) + mmcr0 |= MMCR0_PMC1CE; + if (pmc_inuse & 0xfe) + mmcr0 |= MMCR0_PMCjCE; + + mmcra |= 0x2000; /* mark only one IOP per PPC instruction */ + + /* Return MMCRx values */ + mmcr[0] = mmcr0; + mmcr[1] = mmcr1; + mmcr[2] = mmcra; + return 0; +} + +static void p970_disable_pmc(unsigned int pmc, u64 mmcr[]) +{ + int shift, i; + + if (pmc <= 1) { + shift = MMCR0_PMC1SEL_SH - 7 * pmc; + i = 0; + } else { + shift = MMCR1_PMC3SEL_SH - 5 * (pmc - 2); + i = 1; + } + /* + * Setting the PMCxSEL field to 0x08 disables PMC x. + */ + mmcr[i] = (mmcr[i] & ~(0x1fUL << shift)) | (0x08UL << shift); +} + +static int ppc970_generic_events[] = { + [PERF_COUNT_CPU_CYCLES] = 7, + [PERF_COUNT_INSTRUCTIONS] = 1, + [PERF_COUNT_CACHE_REFERENCES] = 0x8810, /* PM_LD_REF_L1 */ + [PERF_COUNT_CACHE_MISSES] = 0x3810, /* PM_LD_MISS_L1 */ + [PERF_COUNT_BRANCH_INSTRUCTIONS] = 0x431, /* PM_BR_ISSUED */ + [PERF_COUNT_BRANCH_MISSES] = 0x327, /* PM_GRP_BR_MPRED */ +}; + +struct power_pmu ppc970_pmu = { + .n_counter = 8, + .max_alternatives = 2, + .add_fields = 0x001100005555ull, + .test_adder = 0x013300000000ull, + .compute_mmcr = p970_compute_mmcr, + .get_constraint = p970_get_constraint, + .get_alternatives = p970_get_alternatives, + .disable_pmc = p970_disable_pmc, + .n_generic = ARRAY_SIZE(ppc970_generic_events), + .generic_events = ppc970_generic_events, +}; -- GitLab From f78628374a13bc150db77c6e02d4f2c0a7f932ef Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Jan 2009 21:05:35 +1100 Subject: [PATCH 0063/6080] powerpc/perf_counter: Add support for POWER6 This adds the back-end for the PMU on the POWER6 processor. Fortunately, the event selection hardware is somewhat simpler on POWER6 than on other POWER family processors, so the constraints fit into only 32 bits. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/perf_counter.c | 4 + arch/powerpc/kernel/power6-pmu.c | 283 +++++++++++++++++++++++++++++ 3 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/kernel/power6-pmu.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 45798f6fb137..0ebf4d04d4b9 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -94,7 +94,7 @@ obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o -obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o ppc970-pmu.o +obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o ppc970-pmu.o power6-pmu.o obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 5561ecb02a4b..df3fe057dee9 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -742,6 +742,7 @@ static void perf_counter_interrupt(struct pt_regs *regs) } extern struct power_pmu ppc970_pmu; +extern struct power_pmu power6_pmu; static int init_perf_counters(void) { @@ -760,6 +761,9 @@ static int init_perf_counters(void) case PV_970MP: ppmu = &ppc970_pmu; break; + case 0x3e: + ppmu = &power6_pmu; + break; } return 0; } diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c new file mode 100644 index 000000000000..b1f61f3c97bb --- /dev/null +++ b/arch/powerpc/kernel/power6-pmu.c @@ -0,0 +1,283 @@ +/* + * Performance counter support for POWER6 processors. + * + * Copyright 2008-2009 Paul Mackerras, IBM 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 the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include + +/* + * Bits in event code for POWER6 + */ +#define PM_PMC_SH 20 /* PMC number (1-based) for direct events */ +#define PM_PMC_MSK 0x7 +#define PM_PMC_MSKS (PM_PMC_MSK << PM_PMC_SH) +#define PM_UNIT_SH 16 /* Unit event comes (TTMxSEL encoding) */ +#define PM_UNIT_MSK 0xf +#define PM_UNIT_MSKS (PM_UNIT_MSK << PM_UNIT_SH) +#define PM_LLAV 0x8000 /* Load lookahead match value */ +#define PM_LLA 0x4000 /* Load lookahead match enable */ +#define PM_BYTE_SH 12 /* Byte of event bus to use */ +#define PM_BYTE_MSK 3 +#define PM_SUBUNIT_SH 8 /* Subunit event comes from (NEST_SEL enc.) */ +#define PM_SUBUNIT_MSK 7 +#define PM_SUBUNIT_MSKS (PM_SUBUNIT_MSK << PM_SUBUNIT_SH) +#define PM_PMCSEL_MSK 0xff /* PMCxSEL value */ +#define PM_BUSEVENT_MSK 0xf3700 + +/* + * Bits in MMCR1 for POWER6 + */ +#define MMCR1_TTM0SEL_SH 60 +#define MMCR1_TTMSEL_SH(n) (MMCR1_TTM0SEL_SH - (n) * 4) +#define MMCR1_TTMSEL_MSK 0xf +#define MMCR1_TTMSEL(m, n) (((m) >> MMCR1_TTMSEL_SH(n)) & MMCR1_TTMSEL_MSK) +#define MMCR1_NESTSEL_SH 45 +#define MMCR1_NESTSEL_MSK 0x7 +#define MMCR1_NESTSEL(m) (((m) >> MMCR1_NESTSEL_SH) & MMCR1_NESTSEL_MSK) +#define MMCR1_PMC1_LLA ((u64)1 << 44) +#define MMCR1_PMC1_LLA_VALUE ((u64)1 << 39) +#define MMCR1_PMC1_ADDR_SEL ((u64)1 << 35) +#define MMCR1_PMC1SEL_SH 24 +#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8) +#define MMCR1_PMCSEL_MSK 0xff + +/* + * Assign PMC numbers and compute MMCR1 value for a set of events + */ +static int p6_compute_mmcr(unsigned int event[], int n_ev, + unsigned int hwc[], u64 mmcr[]) +{ + u64 mmcr1 = 0; + int i; + unsigned int pmc, ev, b, u, s, psel; + unsigned int ttmset = 0; + unsigned int pmc_inuse = 0; + + if (n_ev > 4) + return -1; + for (i = 0; i < n_ev; ++i) { + pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc_inuse & (1 << (pmc - 1))) + return -1; /* collision! */ + pmc_inuse |= 1 << (pmc - 1); + } + } + for (i = 0; i < n_ev; ++i) { + ev = event[i]; + pmc = (ev >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + --pmc; + } else { + /* can go on any PMC; find a free one */ + for (pmc = 0; pmc < 4; ++pmc) + if (!(pmc_inuse & (1 << pmc))) + break; + pmc_inuse |= 1 << pmc; + } + hwc[i] = pmc; + psel = ev & PM_PMCSEL_MSK; + if (ev & PM_BUSEVENT_MSK) { + /* this event uses the event bus */ + b = (ev >> PM_BYTE_SH) & PM_BYTE_MSK; + u = (ev >> PM_UNIT_SH) & PM_UNIT_MSK; + /* check for conflict on this byte of event bus */ + if ((ttmset & (1 << b)) && MMCR1_TTMSEL(mmcr1, b) != u) + return -1; + mmcr1 |= (u64)u << MMCR1_TTMSEL_SH(b); + ttmset |= 1 << b; + if (u == 5) { + /* Nest events have a further mux */ + s = (ev >> PM_SUBUNIT_SH) & PM_SUBUNIT_MSK; + if ((ttmset & 0x10) && + MMCR1_NESTSEL(mmcr1) != s) + return -1; + ttmset |= 0x10; + mmcr1 |= (u64)s << MMCR1_NESTSEL_SH; + } + if (0x30 <= psel && psel <= 0x3d) { + /* these need the PMCx_ADDR_SEL bits */ + if (b >= 2) + mmcr1 |= MMCR1_PMC1_ADDR_SEL >> pmc; + } + /* bus select values are different for PMC3/4 */ + if (pmc >= 2 && (psel & 0x90) == 0x80) + psel ^= 0x20; + } + if (ev & PM_LLA) { + mmcr1 |= MMCR1_PMC1_LLA >> pmc; + if (ev & PM_LLAV) + mmcr1 |= MMCR1_PMC1_LLA_VALUE >> pmc; + } + mmcr1 |= (u64)psel << MMCR1_PMCSEL_SH(pmc); + } + mmcr[0] = 0; + if (pmc_inuse & 1) + mmcr[0] = MMCR0_PMC1CE; + if (pmc_inuse & 0xe) + mmcr[0] |= MMCR0_PMCjCE; + mmcr[1] = mmcr1; + mmcr[2] = 0; + return 0; +} + +/* + * Layout of constraint bits: + * + * 0-1 add field: number of uses of PMC1 (max 1) + * 2-3, 4-5, 6-7: ditto for PMC2, 3, 4 + * 8-10 select field: nest (subunit) event selector + * 16-19 select field: unit on byte 0 of event bus + * 20-23, 24-27, 28-31 ditto for bytes 1, 2, 3 + */ +static int p6_get_constraint(unsigned int event, u64 *maskp, u64 *valp) +{ + int pmc, byte, sh; + unsigned int mask = 0, value = 0; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc > 4) + return -1; + sh = (pmc - 1) * 2; + mask |= 2 << sh; + value |= 1 << sh; + } + if (event & PM_BUSEVENT_MSK) { + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + sh = byte * 4; + mask |= PM_UNIT_MSKS << sh; + value |= (event & PM_UNIT_MSKS) << sh; + if ((event & PM_UNIT_MSKS) == (5 << PM_UNIT_SH)) { + mask |= PM_SUBUNIT_MSKS; + value |= event & PM_SUBUNIT_MSKS; + } + } + *maskp = mask; + *valp = value; + return 0; +} + +#define MAX_ALT 4 /* at most 4 alternatives for any event */ + +static const unsigned int event_alternatives[][MAX_ALT] = { + { 0x0130e8, 0x2000f6, 0x3000fc }, /* PM_PTEG_RELOAD_VALID */ + { 0x080080, 0x10000d, 0x30000c, 0x4000f0 }, /* PM_LD_MISS_L1 */ + { 0x080088, 0x200054, 0x3000f0 }, /* PM_ST_MISS_L1 */ + { 0x10000a, 0x2000f4 }, /* PM_RUN_CYC */ + { 0x10000b, 0x2000f5 }, /* PM_RUN_COUNT */ + { 0x10000e, 0x400010 }, /* PM_PURR */ + { 0x100010, 0x4000f8 }, /* PM_FLUSH */ + { 0x10001a, 0x200010 }, /* PM_MRK_INST_DISP */ + { 0x100026, 0x3000f8 }, /* PM_TB_BIT_TRANS */ + { 0x100054, 0x2000f0 }, /* PM_ST_FIN */ + { 0x100056, 0x2000fc }, /* PM_L1_ICACHE_MISS */ + { 0x1000f0, 0x40000a }, /* PM_INST_IMC_MATCH_CMPL */ + { 0x1000f8, 0x200008 }, /* PM_GCT_EMPTY_CYC */ + { 0x1000fc, 0x400006 }, /* PM_LSU_DERAT_MISS_CYC */ + { 0x20000e, 0x400007 }, /* PM_LSU_DERAT_MISS */ + { 0x200012, 0x300012 }, /* PM_INST_DISP */ + { 0x2000f2, 0x3000f2 }, /* PM_INST_DISP */ + { 0x2000f8, 0x300010 }, /* PM_EXT_INT */ + { 0x2000fe, 0x300056 }, /* PM_DATA_FROM_L2MISS */ + { 0x2d0030, 0x30001a }, /* PM_MRK_FPU_FIN */ + { 0x30000a, 0x400018 }, /* PM_MRK_INST_FIN */ + { 0x3000f6, 0x40000e }, /* PM_L1_DCACHE_RELOAD_VALID */ + { 0x3000fe, 0x400056 }, /* PM_DATA_FROM_L3MISS */ +}; + +/* + * This could be made more efficient with a binary search on + * a presorted list, if necessary + */ +static int find_alternatives_list(unsigned int event) +{ + int i, j; + unsigned int alt; + + for (i = 0; i < ARRAY_SIZE(event_alternatives); ++i) { + if (event < event_alternatives[i][0]) + return -1; + for (j = 0; j < MAX_ALT; ++j) { + alt = event_alternatives[i][j]; + if (!alt || event < alt) + break; + if (event == alt) + return i; + } + } + return -1; +} + +static int p6_get_alternatives(unsigned int event, unsigned int alt[]) +{ + int i, j; + unsigned int aevent, psel, pmc; + unsigned int nalt = 1; + + alt[0] = event; + + /* check the alternatives table */ + i = find_alternatives_list(event); + if (i >= 0) { + /* copy out alternatives from list */ + for (j = 0; j < MAX_ALT; ++j) { + aevent = event_alternatives[i][j]; + if (!aevent) + break; + if (aevent != event) + alt[nalt++] = aevent; + } + + } else { + /* Check for alternative ways of computing sum events */ + /* PMCSEL 0x32 counter N == PMCSEL 0x34 counter 5-N */ + psel = event & (PM_PMCSEL_MSK & ~1); /* ignore edge bit */ + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc && (psel == 0x32 || psel == 0x34)) + alt[nalt++] = ((event ^ 0x6) & ~PM_PMC_MSKS) | + ((5 - pmc) << PM_PMC_SH); + + /* PMCSEL 0x38 counter N == PMCSEL 0x3a counter N+/-2 */ + if (pmc && (psel == 0x38 || psel == 0x3a)) + alt[nalt++] = ((event ^ 0x2) & ~PM_PMC_MSKS) | + ((pmc > 2? pmc - 2: pmc + 2) << PM_PMC_SH); + } + + return nalt; +} + +static void p6_disable_pmc(unsigned int pmc, u64 mmcr[]) +{ + /* Set PMCxSEL to 0 to disable PMCx */ + mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SH(pmc)); +} + +static int power6_generic_events[] = { + [PERF_COUNT_CPU_CYCLES] = 0x1e, + [PERF_COUNT_INSTRUCTIONS] = 2, + [PERF_COUNT_CACHE_REFERENCES] = 0x280030, /* LD_REF_L1 */ + [PERF_COUNT_CACHE_MISSES] = 0x30000c, /* LD_MISS_L1 */ + [PERF_COUNT_BRANCH_INSTRUCTIONS] = 0x410a0, /* BR_PRED */ + [PERF_COUNT_BRANCH_MISSES] = 0x400052, /* BR_MPRED */ +}; + +struct power_pmu power6_pmu = { + .n_counter = 4, + .max_alternatives = MAX_ALT, + .add_fields = 0x55, + .test_adder = 0, + .compute_mmcr = p6_compute_mmcr, + .get_constraint = p6_get_constraint, + .get_alternatives = p6_get_alternatives, + .disable_pmc = p6_disable_pmc, + .n_generic = ARRAY_SIZE(power6_generic_events), + .generic_events = power6_generic_events, +}; -- GitLab From dd0e6ba22ea21bcc2c420b385a170593c58f4c08 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 12 Jan 2009 15:11:00 +1100 Subject: [PATCH 0064/6080] perf_counter: Always schedule all software counters in Software counters aren't subject to the limitations imposed by the fixed number of hardware counter registers, so there is no reason not to enable them all in __perf_counter_sched_in. Previously we used to break out of the loop when we got to a group that wouldn't fit on the PMU; with this we continue through the list but only schedule in software counters (or groups containing only software counters) from there on. Signed-off-by: Paul Mackerras --- kernel/perf_counter.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 4c0dccb756ad..3aef3062ff78 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -455,12 +455,37 @@ group_error: return -EAGAIN; } +/* + * Return 1 for a software counter, 0 for a hardware counter + */ +static inline int is_software_counter(struct perf_counter *counter) +{ + return !counter->hw_event.raw && counter->hw_event.type < 0; +} + +/* + * Return 1 for a group consisting entirely of software counters, + * 0 if the group contains any hardware counters. + */ +static int is_software_only_group(struct perf_counter *leader) +{ + struct perf_counter *counter; + + if (!is_software_counter(leader)) + return 0; + list_for_each_entry(counter, &leader->sibling_list, list_entry) + if (!is_software_counter(counter)) + return 0; + return 1; +} + static void __perf_counter_sched_in(struct perf_counter_context *ctx, struct perf_cpu_context *cpuctx, int cpu) { struct perf_counter *counter; u64 flags; + int can_add_hw = 1; if (likely(!ctx->nr_counters)) return; @@ -477,10 +502,12 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, /* * If we scheduled in a group atomically and exclusively, - * or if this group can't go on, break out: + * or if this group can't go on, don't add any more + * hardware counters. */ - if (group_sched_in(counter, cpuctx, ctx, cpu)) - break; + if (can_add_hw || is_software_only_group(counter)) + if (group_sched_in(counter, cpuctx, ctx, cpu)) + can_add_hw = 0; } hw_perf_restore(flags); spin_unlock(&ctx->lock); -- GitLab From 01d0287f068de2934109ba9b989d8807526cccc2 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 14 Jan 2009 13:44:19 +1100 Subject: [PATCH 0065/6080] powerpc/perf_counter: Make sure PMU gets enabled properly This makes sure that we call the platform-specific ppc_md.enable_pmcs function on each CPU before we try to use the PMU on that CPU. If the CPU goes off-line and then on-line, we need to do the enable_pmcs call again, so we use the hw_perf_counter_setup hook to ensure that. It gets called as each CPU comes online, but it isn't called on the CPU that is coming up, so this adds the CPU number as an argument to it (there were no non-empty instances of hw_perf_counter_setup before). This also arranges to set the pmcregs_in_use field of the lppaca (data structure shared with the hypervisor) on each CPU when we are using the PMU and clear it when we are not. This allows the hypervisor to optimize partition switches by not saving/restoring the PMU registers when we aren't using the PMU. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/perf_counter.c | 22 ++++++++++++++++++++++ kernel/perf_counter.c | 4 ++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index df3fe057dee9..85ad25923c2c 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -15,6 +15,7 @@ #include #include #include +#include struct cpu_hw_counters { int n_counters; @@ -24,6 +25,7 @@ struct cpu_hw_counters { struct perf_counter *counter[MAX_HWCOUNTERS]; unsigned int events[MAX_HWCOUNTERS]; u64 mmcr[3]; + u8 pmcs_enabled; }; DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters); @@ -261,6 +263,15 @@ u64 hw_perf_save_disable(void) cpuhw->disabled = 1; cpuhw->n_added = 0; + /* + * Check if we ever enabled the PMU on this cpu. + */ + if (!cpuhw->pmcs_enabled) { + if (ppc_md.enable_pmcs) + ppc_md.enable_pmcs(); + cpuhw->pmcs_enabled = 1; + } + /* * Set the 'freeze counters' bit. * The barrier is to make sure the mtspr has been @@ -305,6 +316,8 @@ void hw_perf_restore(u64 disable) mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); + if (cpuhw->n_counters == 0) + get_lppaca()->pmcregs_in_use = 0; goto out; } @@ -323,6 +336,7 @@ void hw_perf_restore(u64 disable) * bit set and set the hardware counters to their initial values. * Then unfreeze the counters. */ + get_lppaca()->pmcregs_in_use = 1; mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)) @@ -741,6 +755,14 @@ static void perf_counter_interrupt(struct pt_regs *regs) } } +void hw_perf_counter_setup(int cpu) +{ + struct cpu_hw_counters *cpuhw = &per_cpu(cpu_hw_counters, cpu); + + memset(cpuhw, 0, sizeof(*cpuhw)); + cpuhw->mmcr[0] = MMCR0_FC; +} + extern struct power_pmu ppc970_pmu; extern struct power_pmu power6_pmu; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 3aef3062ff78..52f2f526248e 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -46,7 +46,7 @@ hw_perf_counter_init(struct perf_counter *counter) u64 __weak hw_perf_save_disable(void) { return 0; } void __weak hw_perf_restore(u64 ctrl) { barrier(); } -void __weak hw_perf_counter_setup(void) { barrier(); } +void __weak hw_perf_counter_setup(int cpu) { barrier(); } int __weak hw_perf_group_sched_in(struct perf_counter *group_leader, struct perf_cpu_context *cpuctx, struct perf_counter_context *ctx, int cpu) @@ -1598,7 +1598,7 @@ static void __cpuinit perf_counter_init_cpu(int cpu) cpuctx->max_pertask = perf_max_counters - perf_reserved_percpu; mutex_unlock(&perf_resource_mutex); - hw_perf_counter_setup(); + hw_perf_counter_setup(cpu); } #ifdef CONFIG_HOTPLUG_CPU -- GitLab From 3b6f9e5cb21964b7ce12bf81076f830885563ec8 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 14 Jan 2009 21:00:30 +1100 Subject: [PATCH 0066/6080] perf_counter: Add support for pinned and exclusive counter groups Impact: New perf_counter features A pinned counter group is one that the user wants to have on the CPU whenever possible, i.e. whenever the associated task is running, for a per-task group, or always for a per-cpu group. If the system cannot satisfy that, it puts the group into an error state where it is not scheduled any more and reads from it return EOF (i.e. 0 bytes read). The group can be released from error state and made readable again using prctl(PR_TASK_PERF_COUNTERS_ENABLE). When we have finer-grained enable/disable controls on counters we'll be able to reset the error state on individual groups. An exclusive group is one that the user wants to be the only group using the CPU performance monitor hardware whenever it is on. The counter group scheduler will not schedule an exclusive group if there are already other groups on the CPU and will not schedule other groups onto the CPU if there is an exclusive group scheduled (that statement does not apply to groups containing only software counters, which can always go on and which do not prevent an exclusive group from going on). With an exclusive group, we will be able to let users program PMU registers at a low level without the concern that those settings will perturb other measurements. Along the way this reorganizes things a little: - is_software_counter() is moved to perf_counter.h. - cpuctx->active_oncpu now records the number of hardware counters on the CPU, i.e. it now excludes software counters. Nothing was reading cpuctx->active_oncpu before, so this change is harmless. - A new cpuctx->exclusive field records whether we currently have an exclusive group on the CPU. - counter_sched_out moves higher up in perf_counter.c and gets called from __perf_counter_remove_from_context and __perf_counter_exit_task, where we used to have essentially the same code. - __perf_counter_sched_in now goes through the counter list twice, doing the pinned counters in the first loop and the non-pinned counters in the second loop, in order to give the pinned counters the best chance to be scheduled in. Note that only a group leader can be exclusive or pinned, and that attribute applies to the whole group. This avoids some awkwardness in some corner cases (e.g. where a group leader is closed and the other group members get added to the context list). If we want to relax that restriction later, we can, and it is easier to relax a restriction than to apply a new one. This doesn't yet handle the case where a pinned counter is inherited and goes into error state in the child - the error state is not propagated up to the parent when the child exits, and arguably it should. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/perf_counter.c | 10 +- include/linux/perf_counter.h | 15 +- kernel/perf_counter.c | 226 ++++++++++++++++++++--------- 3 files changed, 169 insertions(+), 82 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 85ad25923c2c..5b0211348c73 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -35,14 +35,6 @@ void perf_counter_print_debug(void) { } -/* - * Return 1 for a software counter, 0 for a hardware counter - */ -static inline int is_software_counter(struct perf_counter *counter) -{ - return !counter->hw_event.raw && counter->hw_event.type < 0; -} - /* * Read one performance monitor counter (PMC). */ @@ -443,6 +435,7 @@ int hw_perf_group_sched_in(struct perf_counter *group_leader, */ for (i = n0; i < n0 + n; ++i) cpuhw->counter[i]->hw.config = cpuhw->events[i]; + cpuctx->active_oncpu += n; n = 1; counter_sched_in(group_leader, cpu); list_for_each_entry(sub, &group_leader->sibling_list, list_entry) { @@ -451,7 +444,6 @@ int hw_perf_group_sched_in(struct perf_counter *group_leader, ++n; } } - cpuctx->active_oncpu += n; ctx->nr_active += n; return 1; diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index b21d1ea4c054..7ab8e5f96f5b 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -86,7 +86,10 @@ struct perf_counter_hw_event { nmi : 1, /* NMI sampling */ raw : 1, /* raw event type */ inherit : 1, /* children inherit it */ - __reserved_1 : 28; + pinned : 1, /* must always be on PMU */ + exclusive : 1, /* only counter on PMU */ + + __reserved_1 : 26; u64 __reserved_2; }; @@ -141,6 +144,7 @@ struct hw_perf_counter_ops { * enum perf_counter_active_state - the states of a counter */ enum perf_counter_active_state { + PERF_COUNTER_STATE_ERROR = -2, PERF_COUNTER_STATE_OFF = -1, PERF_COUNTER_STATE_INACTIVE = 0, PERF_COUNTER_STATE_ACTIVE = 1, @@ -214,6 +218,7 @@ struct perf_cpu_context { struct perf_counter_context *task_ctx; int active_oncpu; int max_pertask; + int exclusive; }; /* @@ -240,6 +245,14 @@ extern int hw_perf_group_sched_in(struct perf_counter *group_leader, struct perf_cpu_context *cpuctx, struct perf_counter_context *ctx, int cpu); +/* + * Return 1 for a software counter, 0 for a hardware counter + */ +static inline int is_software_counter(struct perf_counter *counter) +{ + return !counter->hw_event.raw && counter->hw_event.type < 0; +} + #else static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 52f2f526248e..faf671b29566 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -93,6 +93,25 @@ list_del_counter(struct perf_counter *counter, struct perf_counter_context *ctx) } } +static void +counter_sched_out(struct perf_counter *counter, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx) +{ + if (counter->state != PERF_COUNTER_STATE_ACTIVE) + return; + + counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->hw_ops->disable(counter); + counter->oncpu = -1; + + if (!is_software_counter(counter)) + cpuctx->active_oncpu--; + ctx->nr_active--; + if (counter->hw_event.exclusive || !cpuctx->active_oncpu) + cpuctx->exclusive = 0; +} + /* * Cross CPU call to remove a performance counter * @@ -118,14 +137,9 @@ static void __perf_counter_remove_from_context(void *info) curr_rq_lock_irq_save(&flags); spin_lock(&ctx->lock); - if (counter->state == PERF_COUNTER_STATE_ACTIVE) { - counter->state = PERF_COUNTER_STATE_INACTIVE; - counter->hw_ops->disable(counter); - ctx->nr_active--; - cpuctx->active_oncpu--; - counter->task = NULL; - counter->oncpu = -1; - } + counter_sched_out(counter, cpuctx, ctx); + + counter->task = NULL; ctx->nr_counters--; /* @@ -207,7 +221,7 @@ counter_sched_in(struct perf_counter *counter, struct perf_counter_context *ctx, int cpu) { - if (counter->state == PERF_COUNTER_STATE_OFF) + if (counter->state <= PERF_COUNTER_STATE_OFF) return 0; counter->state = PERF_COUNTER_STATE_ACTIVE; @@ -223,12 +237,63 @@ counter_sched_in(struct perf_counter *counter, return -EAGAIN; } - cpuctx->active_oncpu++; + if (!is_software_counter(counter)) + cpuctx->active_oncpu++; ctx->nr_active++; + if (counter->hw_event.exclusive) + cpuctx->exclusive = 1; + return 0; } +/* + * Return 1 for a group consisting entirely of software counters, + * 0 if the group contains any hardware counters. + */ +static int is_software_only_group(struct perf_counter *leader) +{ + struct perf_counter *counter; + + if (!is_software_counter(leader)) + return 0; + list_for_each_entry(counter, &leader->sibling_list, list_entry) + if (!is_software_counter(counter)) + return 0; + return 1; +} + +/* + * Work out whether we can put this counter group on the CPU now. + */ +static int group_can_go_on(struct perf_counter *counter, + struct perf_cpu_context *cpuctx, + int can_add_hw) +{ + /* + * Groups consisting entirely of software counters can always go on. + */ + if (is_software_only_group(counter)) + return 1; + /* + * If an exclusive group is already on, no other hardware + * counters can go on. + */ + if (cpuctx->exclusive) + return 0; + /* + * If this group is exclusive and there are already + * counters on the CPU, it can't go on. + */ + if (counter->hw_event.exclusive && cpuctx->active_oncpu) + return 0; + /* + * Otherwise, try to add it if all previous groups were able + * to go on. + */ + return can_add_hw; +} + /* * Cross CPU call to install and enable a performance counter */ @@ -240,6 +305,7 @@ static void __perf_install_in_context(void *info) int cpu = smp_processor_id(); unsigned long flags; u64 perf_flags; + int err; /* * If this is a task context, we need to check whether it is @@ -261,9 +327,21 @@ static void __perf_install_in_context(void *info) list_add_counter(counter, ctx); ctx->nr_counters++; - counter_sched_in(counter, cpuctx, ctx, cpu); + /* + * An exclusive counter can't go on if there are already active + * hardware counters, and no hardware counter can go on if there + * is already an exclusive counter on. + */ + if (counter->state == PERF_COUNTER_STATE_INACTIVE && + !group_can_go_on(counter, cpuctx, 1)) + err = -EEXIST; + else + err = counter_sched_in(counter, cpuctx, ctx, cpu); + + if (err && counter->hw_event.pinned) + counter->state = PERF_COUNTER_STATE_ERROR; - if (!ctx->task && cpuctx->max_pertask) + if (!err && !ctx->task && cpuctx->max_pertask) cpuctx->max_pertask--; hw_perf_restore(perf_flags); @@ -326,22 +404,6 @@ retry: spin_unlock_irq(&ctx->lock); } -static void -counter_sched_out(struct perf_counter *counter, - struct perf_cpu_context *cpuctx, - struct perf_counter_context *ctx) -{ - if (counter->state != PERF_COUNTER_STATE_ACTIVE) - return; - - counter->state = PERF_COUNTER_STATE_INACTIVE; - counter->hw_ops->disable(counter); - counter->oncpu = -1; - - cpuctx->active_oncpu--; - ctx->nr_active--; -} - static void group_sched_out(struct perf_counter *group_counter, struct perf_cpu_context *cpuctx, @@ -359,6 +421,9 @@ group_sched_out(struct perf_counter *group_counter, */ list_for_each_entry(counter, &group_counter->sibling_list, list_entry) counter_sched_out(counter, cpuctx, ctx); + + if (group_counter->hw_event.exclusive) + cpuctx->exclusive = 0; } void __perf_counter_sched_out(struct perf_counter_context *ctx, @@ -455,30 +520,6 @@ group_error: return -EAGAIN; } -/* - * Return 1 for a software counter, 0 for a hardware counter - */ -static inline int is_software_counter(struct perf_counter *counter) -{ - return !counter->hw_event.raw && counter->hw_event.type < 0; -} - -/* - * Return 1 for a group consisting entirely of software counters, - * 0 if the group contains any hardware counters. - */ -static int is_software_only_group(struct perf_counter *leader) -{ - struct perf_counter *counter; - - if (!is_software_counter(leader)) - return 0; - list_for_each_entry(counter, &leader->sibling_list, list_entry) - if (!is_software_counter(counter)) - return 0; - return 1; -} - static void __perf_counter_sched_in(struct perf_counter_context *ctx, struct perf_cpu_context *cpuctx, int cpu) @@ -492,7 +533,38 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, spin_lock(&ctx->lock); flags = hw_perf_save_disable(); + + /* + * First go through the list and put on any pinned groups + * in order to give them the best chance of going on. + */ + list_for_each_entry(counter, &ctx->counter_list, list_entry) { + if (counter->state <= PERF_COUNTER_STATE_OFF || + !counter->hw_event.pinned) + continue; + if (counter->cpu != -1 && counter->cpu != cpu) + continue; + + if (group_can_go_on(counter, cpuctx, 1)) + group_sched_in(counter, cpuctx, ctx, cpu); + + /* + * If this pinned group hasn't been scheduled, + * put it in error state. + */ + if (counter->state == PERF_COUNTER_STATE_INACTIVE) + counter->state = PERF_COUNTER_STATE_ERROR; + } + list_for_each_entry(counter, &ctx->counter_list, list_entry) { + /* + * Ignore counters in OFF or ERROR state, and + * ignore pinned counters since we did them already. + */ + if (counter->state <= PERF_COUNTER_STATE_OFF || + counter->hw_event.pinned) + continue; + /* * Listen to the 'cpu' scheduling filter constraint * of counters: @@ -500,14 +572,10 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, if (counter->cpu != -1 && counter->cpu != cpu) continue; - /* - * If we scheduled in a group atomically and exclusively, - * or if this group can't go on, don't add any more - * hardware counters. - */ - if (can_add_hw || is_software_only_group(counter)) + if (group_can_go_on(counter, cpuctx, can_add_hw)) { if (group_sched_in(counter, cpuctx, ctx, cpu)) can_add_hw = 0; + } } hw_perf_restore(flags); spin_unlock(&ctx->lock); @@ -567,8 +635,10 @@ int perf_counter_task_disable(void) */ perf_flags = hw_perf_save_disable(); - list_for_each_entry(counter, &ctx->counter_list, list_entry) - counter->state = PERF_COUNTER_STATE_OFF; + list_for_each_entry(counter, &ctx->counter_list, list_entry) { + if (counter->state != PERF_COUNTER_STATE_ERROR) + counter->state = PERF_COUNTER_STATE_OFF; + } hw_perf_restore(perf_flags); @@ -607,7 +677,7 @@ int perf_counter_task_enable(void) perf_flags = hw_perf_save_disable(); list_for_each_entry(counter, &ctx->counter_list, list_entry) { - if (counter->state != PERF_COUNTER_STATE_OFF) + if (counter->state > PERF_COUNTER_STATE_OFF) continue; counter->state = PERF_COUNTER_STATE_INACTIVE; counter->hw_event.disabled = 0; @@ -849,6 +919,14 @@ perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count) if (count != sizeof(cntval)) return -EINVAL; + /* + * Return end-of-file for a read on a counter that is in + * error state (i.e. because it was pinned but it couldn't be + * scheduled on to the CPU at some point). + */ + if (counter->state == PERF_COUNTER_STATE_ERROR) + return 0; + mutex_lock(&counter->mutex); cntval = perf_counter_read(counter); mutex_unlock(&counter->mutex); @@ -884,7 +962,7 @@ perf_read_irq_data(struct perf_counter *counter, { struct perf_data *irqdata, *usrdata; DECLARE_WAITQUEUE(wait, current); - ssize_t res; + ssize_t res, res2; irqdata = counter->irqdata; usrdata = counter->usrdata; @@ -905,6 +983,9 @@ perf_read_irq_data(struct perf_counter *counter, if (signal_pending(current)) break; + if (counter->state == PERF_COUNTER_STATE_ERROR) + break; + spin_unlock_irq(&counter->waitq.lock); schedule(); spin_lock_irq(&counter->waitq.lock); @@ -913,7 +994,8 @@ perf_read_irq_data(struct perf_counter *counter, __set_current_state(TASK_RUNNING); spin_unlock_irq(&counter->waitq.lock); - if (usrdata->len + irqdata->len < count) + if (usrdata->len + irqdata->len < count && + counter->state != PERF_COUNTER_STATE_ERROR) return -ERESTARTSYS; read_pending: mutex_lock(&counter->mutex); @@ -925,11 +1007,12 @@ read_pending: /* Switch irq buffer: */ usrdata = perf_switch_irq_data(counter); - if (perf_copy_usrdata(usrdata, buf + res, count - res) < 0) { + res2 = perf_copy_usrdata(usrdata, buf + res, count - res); + if (res2 < 0) { if (!res) res = -EFAULT; } else { - res = count; + res += res2; } out: mutex_unlock(&counter->mutex); @@ -1348,6 +1431,11 @@ sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr __user, */ if (group_leader->ctx != ctx) goto err_put_context; + /* + * Only a group leader can be exclusive or pinned + */ + if (hw_event.exclusive || hw_event.pinned) + goto err_put_context; } ret = -EINVAL; @@ -1473,13 +1561,7 @@ __perf_counter_exit_task(struct task_struct *child, cpuctx = &__get_cpu_var(perf_cpu_context); - if (child_counter->state == PERF_COUNTER_STATE_ACTIVE) { - child_counter->state = PERF_COUNTER_STATE_INACTIVE; - child_counter->hw_ops->disable(child_counter); - cpuctx->active_oncpu--; - child_ctx->nr_active--; - child_counter->oncpu = -1; - } + counter_sched_out(child_counter, cpuctx, child_ctx); list_del_init(&child_counter->list_entry); -- GitLab From d859e29fe34cb833071b20aef860ee94fbad9bb2 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 17 Jan 2009 18:10:22 +1100 Subject: [PATCH 0067/6080] perf_counter: Add counter enable/disable ioctls Impact: New perf_counter features This primarily adds a way for perf_counter users to enable and disable counters and groups. Enabling or disabling a counter or group also enables or disables all of the child counters that have been cloned from it to monitor children of the task monitored by the top-level counter. The userspace interface to enable/disable counters is via ioctl on the counter file descriptor. Along the way this extends the code that handles child counters to handle child counter groups properly. A group with multiple counters will be cloned to child tasks if and only if the group leader has the hw_event.inherit bit set - if it is set the whole group is cloned as a group in the child task. In order to be able to enable or disable all child counters of a given top-level counter, we need a way to find them all. Hence I have added a child_list field to struct perf_counter, which is the head of the list of children for a top-level counter, or the link in that list for a child counter. That list is protected by the perf_counter.mutex field. This also adds a mutex to the perf_counter_context struct. Previously the list of counters was protected just by the lock field in the context, which meant that perf_counter_init_task had to take that lock and then take whatever lock/mutex protects the top-level counter's child_list. But the counter enable/disable functions need to take that lock in order to traverse the list, then for each counter take the lock in that counter's context in order to change the counter's state safely, which will lead to a deadlock. To solve this, we now have both a mutex and a spinlock in the context, and taking either is sufficient to ensure the list of counters can't change - you have to take both before changing the list. Now perf_counter_init_task takes the mutex instead of the lock (which incidentally means that inherit_counter can use GFP_KERNEL instead of GFP_ATOMIC) and thus avoids the possible deadlock. Similarly the new enable/disable functions can take the mutex while traversing the list of child counters without incurring a possible deadlock when the counter manipulation code locks the context for a child counter. We also had an misfeature that the first counter added to a context would possibly not go on until the next sched-in, because we were using ctx->nr_active to detect if the context was running on a CPU. But nr_active is the number of active counters, and if that was zero (because the context didn't have any counters yet) it would look like the context wasn't running on a cpu and so the retry code in __perf_install_in_context wouldn't retry. So this adds an 'is_active' field that is set when the context is on a CPU, even if it has no counters. The is_active field is only used for task contexts, not for per-cpu contexts. If we enable a subsidiary counter in a group that is active on a CPU, and the arch code can't enable the counter, then we have to pull the whole group off the CPU. We do this with group_sched_out, which gets moved up in the file so it comes before all its callers. This also adds similar logic to __perf_install_in_context so that the "all on, or none" invariant of groups is preserved when adding a new counter to a group. Signed-off-by: Paul Mackerras --- include/linux/perf_counter.h | 21 +- kernel/perf_counter.c | 455 ++++++++++++++++++++++++++++++----- 2 files changed, 415 insertions(+), 61 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 7ab8e5f96f5b..33ba9fe0a781 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -14,6 +14,7 @@ #define _LINUX_PERF_COUNTER_H #include +#include #ifdef CONFIG_PERF_COUNTERS # include @@ -94,6 +95,12 @@ struct perf_counter_hw_event { u64 __reserved_2; }; +/* + * Ioctls that can be done on a perf counter fd: + */ +#define PERF_COUNTER_IOC_ENABLE _IO('$', 0) +#define PERF_COUNTER_IOC_DISABLE _IO('$', 1) + /* * Kernel-internal data types: */ @@ -173,8 +180,10 @@ struct perf_counter { struct file *filp; struct perf_counter *parent; + struct list_head child_list; + /* - * Protect attach/detach: + * Protect attach/detach and child_list: */ struct mutex mutex; @@ -199,13 +208,21 @@ struct perf_counter { struct perf_counter_context { #ifdef CONFIG_PERF_COUNTERS /* - * Protect the list of counters: + * Protect the states of the counters in the list, + * nr_active, and the list: */ spinlock_t lock; + /* + * Protect the list of counters. Locking either mutex or lock + * is sufficient to ensure the list doesn't change; to change + * the list you need to lock both the mutex and the spinlock. + */ + struct mutex mutex; struct list_head counter_list; int nr_counters; int nr_active; + int is_active; struct task_struct *task; #endif }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index faf671b29566..1ac18daa424f 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -112,6 +112,28 @@ counter_sched_out(struct perf_counter *counter, cpuctx->exclusive = 0; } +static void +group_sched_out(struct perf_counter *group_counter, + struct perf_cpu_context *cpuctx, + struct perf_counter_context *ctx) +{ + struct perf_counter *counter; + + if (group_counter->state != PERF_COUNTER_STATE_ACTIVE) + return; + + counter_sched_out(group_counter, cpuctx, ctx); + + /* + * Schedule out siblings (if any): + */ + list_for_each_entry(counter, &group_counter->sibling_list, list_entry) + counter_sched_out(counter, cpuctx, ctx); + + if (group_counter->hw_event.exclusive) + cpuctx->exclusive = 0; +} + /* * Cross CPU call to remove a performance counter * @@ -168,7 +190,7 @@ static void __perf_counter_remove_from_context(void *info) /* * Remove the counter from a task's (or a CPU's) list of counters. * - * Must be called with counter->mutex held. + * Must be called with counter->mutex and ctx->mutex held. * * CPU counters are removed with a smp call. For task counters we only * call when the task is on a CPU. @@ -215,6 +237,99 @@ retry: spin_unlock_irq(&ctx->lock); } +/* + * Cross CPU call to disable a performance counter + */ +static void __perf_counter_disable(void *info) +{ + struct perf_counter *counter = info; + struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); + struct perf_counter_context *ctx = counter->ctx; + unsigned long flags; + + /* + * If this is a per-task counter, need to check whether this + * counter's task is the current task on this cpu. + */ + if (ctx->task && cpuctx->task_ctx != ctx) + return; + + curr_rq_lock_irq_save(&flags); + spin_lock(&ctx->lock); + + /* + * If the counter is on, turn it off. + * If it is in error state, leave it in error state. + */ + if (counter->state >= PERF_COUNTER_STATE_INACTIVE) { + if (counter == counter->group_leader) + group_sched_out(counter, cpuctx, ctx); + else + counter_sched_out(counter, cpuctx, ctx); + counter->state = PERF_COUNTER_STATE_OFF; + } + + spin_unlock(&ctx->lock); + curr_rq_unlock_irq_restore(&flags); +} + +/* + * Disable a counter. + */ +static void perf_counter_disable(struct perf_counter *counter) +{ + struct perf_counter_context *ctx = counter->ctx; + struct task_struct *task = ctx->task; + + if (!task) { + /* + * Disable the counter on the cpu that it's on + */ + smp_call_function_single(counter->cpu, __perf_counter_disable, + counter, 1); + return; + } + + retry: + task_oncpu_function_call(task, __perf_counter_disable, counter); + + spin_lock_irq(&ctx->lock); + /* + * If the counter is still active, we need to retry the cross-call. + */ + if (counter->state == PERF_COUNTER_STATE_ACTIVE) { + spin_unlock_irq(&ctx->lock); + goto retry; + } + + /* + * Since we have the lock this context can't be scheduled + * in, so we can change the state safely. + */ + if (counter->state == PERF_COUNTER_STATE_INACTIVE) + counter->state = PERF_COUNTER_STATE_OFF; + + spin_unlock_irq(&ctx->lock); +} + +/* + * Disable a counter and all its children. + */ +static void perf_counter_disable_family(struct perf_counter *counter) +{ + struct perf_counter *child; + + perf_counter_disable(counter); + + /* + * Lock the mutex to protect the list of children + */ + mutex_lock(&counter->mutex); + list_for_each_entry(child, &counter->child_list, child_list) + perf_counter_disable(child); + mutex_unlock(&counter->mutex); +} + static int counter_sched_in(struct perf_counter *counter, struct perf_cpu_context *cpuctx, @@ -302,6 +417,7 @@ static void __perf_install_in_context(void *info) struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); struct perf_counter *counter = info; struct perf_counter_context *ctx = counter->ctx; + struct perf_counter *leader = counter->group_leader; int cpu = smp_processor_id(); unsigned long flags; u64 perf_flags; @@ -327,23 +443,40 @@ static void __perf_install_in_context(void *info) list_add_counter(counter, ctx); ctx->nr_counters++; + /* + * Don't put the counter on if it is disabled or if + * it is in a group and the group isn't on. + */ + if (counter->state != PERF_COUNTER_STATE_INACTIVE || + (leader != counter && leader->state != PERF_COUNTER_STATE_ACTIVE)) + goto unlock; + /* * An exclusive counter can't go on if there are already active * hardware counters, and no hardware counter can go on if there * is already an exclusive counter on. */ - if (counter->state == PERF_COUNTER_STATE_INACTIVE && - !group_can_go_on(counter, cpuctx, 1)) + if (!group_can_go_on(counter, cpuctx, 1)) err = -EEXIST; else err = counter_sched_in(counter, cpuctx, ctx, cpu); - if (err && counter->hw_event.pinned) - counter->state = PERF_COUNTER_STATE_ERROR; + if (err) { + /* + * This counter couldn't go on. If it is in a group + * then we have to pull the whole group off. + * If the counter group is pinned then put it in error state. + */ + if (leader != counter) + group_sched_out(leader, cpuctx, ctx); + if (leader->hw_event.pinned) + leader->state = PERF_COUNTER_STATE_ERROR; + } if (!err && !ctx->task && cpuctx->max_pertask) cpuctx->max_pertask--; + unlock: hw_perf_restore(perf_flags); spin_unlock(&ctx->lock); @@ -359,6 +492,8 @@ static void __perf_install_in_context(void *info) * If the counter is attached to a task which is on a CPU we use a smp * call to enable it in the task context. The task might have been * scheduled away, but we check this in the smp call again. + * + * Must be called with ctx->mutex held. */ static void perf_install_in_context(struct perf_counter_context *ctx, @@ -387,7 +522,7 @@ retry: /* * we need to retry the smp call. */ - if (ctx->nr_active && list_empty(&counter->list_entry)) { + if (ctx->is_active && list_empty(&counter->list_entry)) { spin_unlock_irq(&ctx->lock); goto retry; } @@ -404,26 +539,131 @@ retry: spin_unlock_irq(&ctx->lock); } -static void -group_sched_out(struct perf_counter *group_counter, - struct perf_cpu_context *cpuctx, - struct perf_counter_context *ctx) +/* + * Cross CPU call to enable a performance counter + */ +static void __perf_counter_enable(void *info) { - struct perf_counter *counter; + struct perf_counter *counter = info; + struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); + struct perf_counter_context *ctx = counter->ctx; + struct perf_counter *leader = counter->group_leader; + unsigned long flags; + int err; - if (group_counter->state != PERF_COUNTER_STATE_ACTIVE) + /* + * If this is a per-task counter, need to check whether this + * counter's task is the current task on this cpu. + */ + if (ctx->task && cpuctx->task_ctx != ctx) return; - counter_sched_out(group_counter, cpuctx, ctx); + curr_rq_lock_irq_save(&flags); + spin_lock(&ctx->lock); + + if (counter->state >= PERF_COUNTER_STATE_INACTIVE) + goto unlock; + counter->state = PERF_COUNTER_STATE_INACTIVE; /* - * Schedule out siblings (if any): + * If the counter is in a group and isn't the group leader, + * then don't put it on unless the group is on. */ - list_for_each_entry(counter, &group_counter->sibling_list, list_entry) - counter_sched_out(counter, cpuctx, ctx); + if (leader != counter && leader->state != PERF_COUNTER_STATE_ACTIVE) + goto unlock; - if (group_counter->hw_event.exclusive) - cpuctx->exclusive = 0; + if (!group_can_go_on(counter, cpuctx, 1)) + err = -EEXIST; + else + err = counter_sched_in(counter, cpuctx, ctx, + smp_processor_id()); + + if (err) { + /* + * If this counter can't go on and it's part of a + * group, then the whole group has to come off. + */ + if (leader != counter) + group_sched_out(leader, cpuctx, ctx); + if (leader->hw_event.pinned) + leader->state = PERF_COUNTER_STATE_ERROR; + } + + unlock: + spin_unlock(&ctx->lock); + curr_rq_unlock_irq_restore(&flags); +} + +/* + * Enable a counter. + */ +static void perf_counter_enable(struct perf_counter *counter) +{ + struct perf_counter_context *ctx = counter->ctx; + struct task_struct *task = ctx->task; + + if (!task) { + /* + * Enable the counter on the cpu that it's on + */ + smp_call_function_single(counter->cpu, __perf_counter_enable, + counter, 1); + return; + } + + spin_lock_irq(&ctx->lock); + if (counter->state >= PERF_COUNTER_STATE_INACTIVE) + goto out; + + /* + * If the counter is in error state, clear that first. + * That way, if we see the counter in error state below, we + * know that it has gone back into error state, as distinct + * from the task having been scheduled away before the + * cross-call arrived. + */ + if (counter->state == PERF_COUNTER_STATE_ERROR) + counter->state = PERF_COUNTER_STATE_OFF; + + retry: + spin_unlock_irq(&ctx->lock); + task_oncpu_function_call(task, __perf_counter_enable, counter); + + spin_lock_irq(&ctx->lock); + + /* + * If the context is active and the counter is still off, + * we need to retry the cross-call. + */ + if (ctx->is_active && counter->state == PERF_COUNTER_STATE_OFF) + goto retry; + + /* + * Since we have the lock this context can't be scheduled + * in, so we can change the state safely. + */ + if (counter->state == PERF_COUNTER_STATE_OFF) + counter->state = PERF_COUNTER_STATE_INACTIVE; + out: + spin_unlock_irq(&ctx->lock); +} + +/* + * Enable a counter and all its children. + */ +static void perf_counter_enable_family(struct perf_counter *counter) +{ + struct perf_counter *child; + + perf_counter_enable(counter); + + /* + * Lock the mutex to protect the list of children + */ + mutex_lock(&counter->mutex); + list_for_each_entry(child, &counter->child_list, child_list) + perf_counter_enable(child); + mutex_unlock(&counter->mutex); } void __perf_counter_sched_out(struct perf_counter_context *ctx, @@ -432,16 +672,18 @@ void __perf_counter_sched_out(struct perf_counter_context *ctx, struct perf_counter *counter; u64 flags; + spin_lock(&ctx->lock); + ctx->is_active = 0; if (likely(!ctx->nr_counters)) - return; + goto out; - spin_lock(&ctx->lock); flags = hw_perf_save_disable(); if (ctx->nr_active) { list_for_each_entry(counter, &ctx->counter_list, list_entry) group_sched_out(counter, cpuctx, ctx); } hw_perf_restore(flags); + out: spin_unlock(&ctx->lock); } @@ -528,10 +770,11 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, u64 flags; int can_add_hw = 1; + spin_lock(&ctx->lock); + ctx->is_active = 1; if (likely(!ctx->nr_counters)) - return; + goto out; - spin_lock(&ctx->lock); flags = hw_perf_save_disable(); /* @@ -578,6 +821,7 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, } } hw_perf_restore(flags); + out: spin_unlock(&ctx->lock); } @@ -896,12 +1140,14 @@ static int perf_release(struct inode *inode, struct file *file) file->private_data = NULL; + mutex_lock(&ctx->mutex); mutex_lock(&counter->mutex); perf_counter_remove_from_context(counter); put_context(ctx); mutex_unlock(&counter->mutex); + mutex_unlock(&ctx->mutex); kfree(counter); @@ -1053,10 +1299,30 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) return events; } +static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct perf_counter *counter = file->private_data; + int err = 0; + + switch (cmd) { + case PERF_COUNTER_IOC_ENABLE: + perf_counter_enable_family(counter); + break; + case PERF_COUNTER_IOC_DISABLE: + perf_counter_disable_family(counter); + break; + default: + err = -ENOTTY; + } + return err; +} + static const struct file_operations perf_fops = { .release = perf_release, .read = perf_read, .poll = perf_poll, + .unlocked_ioctl = perf_ioctl, + .compat_ioctl = perf_ioctl, }; static int cpu_clock_perf_counter_enable(struct perf_counter *counter) @@ -1348,6 +1614,8 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, INIT_LIST_HEAD(&counter->sibling_list); init_waitqueue_head(&counter->waitq); + INIT_LIST_HEAD(&counter->child_list); + counter->irqdata = &counter->data[0]; counter->usrdata = &counter->data[1]; counter->cpu = cpu; @@ -1452,7 +1720,9 @@ sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr __user, goto err_free_put_context; counter->filp = counter_file; + mutex_lock(&ctx->mutex); perf_install_in_context(ctx, counter, cpu); + mutex_unlock(&ctx->mutex); fput_light(counter_file, fput_needed2); @@ -1479,6 +1749,7 @@ __perf_counter_init_context(struct perf_counter_context *ctx, { memset(ctx, 0, sizeof(*ctx)); spin_lock_init(&ctx->lock); + mutex_init(&ctx->mutex); INIT_LIST_HEAD(&ctx->counter_list); ctx->task = task; } @@ -1486,20 +1757,30 @@ __perf_counter_init_context(struct perf_counter_context *ctx, /* * inherit a counter from parent task to child task: */ -static int +static struct perf_counter * inherit_counter(struct perf_counter *parent_counter, struct task_struct *parent, struct perf_counter_context *parent_ctx, struct task_struct *child, + struct perf_counter *group_leader, struct perf_counter_context *child_ctx) { struct perf_counter *child_counter; + /* + * Instead of creating recursive hierarchies of counters, + * we link inherited counters back to the original parent, + * which has a filp for sure, which we use as the reference + * count: + */ + if (parent_counter->parent) + parent_counter = parent_counter->parent; + child_counter = perf_counter_alloc(&parent_counter->hw_event, - parent_counter->cpu, NULL, - GFP_ATOMIC); + parent_counter->cpu, group_leader, + GFP_KERNEL); if (!child_counter) - return -ENOMEM; + return NULL; /* * Link it up in the child's context: @@ -1523,16 +1804,82 @@ inherit_counter(struct perf_counter *parent_counter, */ atomic_long_inc(&parent_counter->filp->f_count); + /* + * Link this into the parent counter's child list + */ + mutex_lock(&parent_counter->mutex); + list_add_tail(&child_counter->child_list, &parent_counter->child_list); + + /* + * Make the child state follow the state of the parent counter, + * not its hw_event.disabled bit. We hold the parent's mutex, + * so we won't race with perf_counter_{en,dis}able_family. + */ + if (parent_counter->state >= PERF_COUNTER_STATE_INACTIVE) + child_counter->state = PERF_COUNTER_STATE_INACTIVE; + else + child_counter->state = PERF_COUNTER_STATE_OFF; + + mutex_unlock(&parent_counter->mutex); + + return child_counter; +} + +static int inherit_group(struct perf_counter *parent_counter, + struct task_struct *parent, + struct perf_counter_context *parent_ctx, + struct task_struct *child, + struct perf_counter_context *child_ctx) +{ + struct perf_counter *leader; + struct perf_counter *sub; + + leader = inherit_counter(parent_counter, parent, parent_ctx, + child, NULL, child_ctx); + if (!leader) + return -ENOMEM; + list_for_each_entry(sub, &parent_counter->sibling_list, list_entry) { + if (!inherit_counter(sub, parent, parent_ctx, + child, leader, child_ctx)) + return -ENOMEM; + } return 0; } +static void sync_child_counter(struct perf_counter *child_counter, + struct perf_counter *parent_counter) +{ + u64 parent_val, child_val; + + parent_val = atomic64_read(&parent_counter->count); + child_val = atomic64_read(&child_counter->count); + + /* + * Add back the child's count to the parent's count: + */ + atomic64_add(child_val, &parent_counter->count); + + /* + * Remove this counter from the parent's list + */ + mutex_lock(&parent_counter->mutex); + list_del_init(&child_counter->child_list); + mutex_unlock(&parent_counter->mutex); + + /* + * Release the parent counter, if this was the last + * reference to it. + */ + fput(parent_counter->filp); +} + static void __perf_counter_exit_task(struct task_struct *child, struct perf_counter *child_counter, struct perf_counter_context *child_ctx) { struct perf_counter *parent_counter; - u64 parent_val, child_val; + struct perf_counter *sub, *tmp; /* * If we do not self-reap then we have to wait for the @@ -1561,7 +1908,7 @@ __perf_counter_exit_task(struct task_struct *child, cpuctx = &__get_cpu_var(perf_cpu_context); - counter_sched_out(child_counter, cpuctx, child_ctx); + group_sched_out(child_counter, cpuctx, child_ctx); list_del_init(&child_counter->list_entry); @@ -1577,26 +1924,23 @@ __perf_counter_exit_task(struct task_struct *child, * that are still around due to the child reference. These * counters need to be zapped - but otherwise linger. */ - if (!parent_counter) - return; - - parent_val = atomic64_read(&parent_counter->count); - child_val = atomic64_read(&child_counter->count); - - /* - * Add back the child's count to the parent's count: - */ - atomic64_add(child_val, &parent_counter->count); - - fput(parent_counter->filp); + if (parent_counter) { + sync_child_counter(child_counter, parent_counter); + list_for_each_entry_safe(sub, tmp, &child_counter->sibling_list, + list_entry) { + if (sub->parent) + sync_child_counter(sub, sub->parent); + kfree(sub); + } + } kfree(child_counter); } /* - * When a child task exist, feed back counter values to parent counters. + * When a child task exits, feed back counter values to parent counters. * - * Note: we are running in child context, but the PID is not hashed + * Note: we may be running in child context, but the PID is not hashed * anymore so new counters will not be added. */ void perf_counter_exit_task(struct task_struct *child) @@ -1620,9 +1964,8 @@ void perf_counter_exit_task(struct task_struct *child) void perf_counter_init_task(struct task_struct *child) { struct perf_counter_context *child_ctx, *parent_ctx; - struct perf_counter *counter, *parent_counter; + struct perf_counter *counter; struct task_struct *parent = current; - unsigned long flags; child_ctx = &child->perf_counter_ctx; parent_ctx = &parent->perf_counter_ctx; @@ -1641,32 +1984,22 @@ void perf_counter_init_task(struct task_struct *child) * Lock the parent list. No need to lock the child - not PID * hashed yet and not running, so nobody can access it. */ - spin_lock_irqsave(&parent_ctx->lock, flags); + mutex_lock(&parent_ctx->mutex); /* * We dont have to disable NMIs - we are only looking at * the list, not manipulating it: */ list_for_each_entry(counter, &parent_ctx->counter_list, list_entry) { - if (!counter->hw_event.inherit || counter->group_leader != counter) + if (!counter->hw_event.inherit) continue; - /* - * Instead of creating recursive hierarchies of counters, - * we link inheritd counters back to the original parent, - * which has a filp for sure, which we use as the reference - * count: - */ - parent_counter = counter; - if (counter->parent) - parent_counter = counter->parent; - - if (inherit_counter(parent_counter, parent, + if (inherit_group(counter, parent, parent_ctx, child, child_ctx)) break; } - spin_unlock_irqrestore(&parent_ctx->lock, flags); + mutex_unlock(&parent_ctx->mutex); } static void __cpuinit perf_counter_init_cpu(int cpu) @@ -1692,11 +2025,15 @@ static void __perf_counter_exit_cpu(void *info) list_for_each_entry_safe(counter, tmp, &ctx->counter_list, list_entry) __perf_counter_remove_from_context(counter); - } static void perf_counter_exit_cpu(int cpu) { + struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); + struct perf_counter_context *ctx = &cpuctx->ctx; + + mutex_lock(&ctx->mutex); smp_call_function_single(cpu, __perf_counter_exit_cpu, NULL, 1); + mutex_unlock(&ctx->mutex); } #else static inline void perf_counter_exit_cpu(int cpu) { } -- GitLab From 1b023a96d9b44f50f4d8ff28c15f5b80e354760f Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Fri, 23 Jan 2009 10:13:01 +0100 Subject: [PATCH 0068/6080] perfcounters: throttle on too high IRQ rates Starting kerneltop with only -c 100 seems to be a bad idea, it can easily lock the system due to perfcounter IRQ overload. So add throttling: if a new IRQ arrives in a shorter than PERFMON_MIN_PERIOD_NS time, turn off perfcounters and untrottle them from the next timer tick. Signed-off-by: Mike Galbraith Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic.c | 2 ++ arch/x86/kernel/cpu/perf_counter.c | 38 +++++++++++++++++++++++++----- include/linux/perf_counter.h | 4 ++++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 7b434e5b14c9..849c23009bf5 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c @@ -781,6 +781,8 @@ static void local_apic_timer_interrupt(void) inc_irq_stat(apic_timer_irqs); evt->event_handler(evt); + + perf_counter_unthrottle(); } /* diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 9376771f757b..1a040b179b53 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -33,6 +33,9 @@ static int nr_counters_fixed __read_mostly; struct cpu_hw_counters { struct perf_counter *counters[X86_PMC_IDX_MAX]; unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; + u64 last_interrupt; + u64 global_enable; + int throttled; }; /* @@ -474,16 +477,19 @@ perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) { int bit, cpu = smp_processor_id(); - u64 ack, status, saved_global; - struct cpu_hw_counters *cpuc; + u64 ack, status, now; + struct cpu_hw_counters *cpuc = &per_cpu(cpu_hw_counters, cpu); - rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, saved_global); + rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); /* Disable counters globally */ wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); ack_APIC_irq(); - cpuc = &per_cpu(cpu_hw_counters, cpu); + now = sched_clock(); + if (now - cpuc->last_interrupt < PERFMON_MIN_PERIOD_NS) + cpuc->throttled = 1; + cpuc->last_interrupt = now; rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); if (!status) @@ -533,9 +539,29 @@ again: goto again; out: /* - * Restore - do not reenable when global enable is off: + * Restore - do not reenable when global enable is off or throttled: */ - wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, saved_global); + if (!cpuc->throttled) + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); +} + +void perf_counter_unthrottle(void) +{ + struct cpu_hw_counters *cpuc; + + if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return; + + if (unlikely(!perf_counters_initialized)) + return; + + cpuc = &per_cpu(cpu_hw_counters, smp_processor_id()); + if (cpuc->throttled) { + if (printk_ratelimit()) + printk(KERN_WARNING "PERFMON: max event frequency exceeded!\n"); + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); + cpuc->throttled = 0; + } } void smp_perf_counter_interrupt(struct pt_regs *regs) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 33ba9fe0a781..91f1ca4c01c0 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -254,6 +254,7 @@ extern void perf_counter_init_task(struct task_struct *child); extern void perf_counter_exit_task(struct task_struct *child); extern void perf_counter_notify(struct pt_regs *regs); extern void perf_counter_print_debug(void); +extern void perf_counter_unthrottle(void); extern u64 hw_perf_save_disable(void); extern void hw_perf_restore(u64 ctrl); extern int perf_counter_task_disable(void); @@ -270,6 +271,8 @@ static inline int is_software_counter(struct perf_counter *counter) return !counter->hw_event.raw && counter->hw_event.type < 0; } +#define PERFMON_MIN_PERIOD_NS 10000 + #else static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } @@ -281,6 +284,7 @@ static inline void perf_counter_init_task(struct task_struct *child) { } static inline void perf_counter_exit_task(struct task_struct *child) { } static inline void perf_counter_notify(struct pt_regs *regs) { } static inline void perf_counter_print_debug(void) { } +static inline void perf_counter_unthrottle(void) { } static inline void hw_perf_restore(u64 ctrl) { } static inline u64 hw_perf_save_disable(void) { return 0; } static inline int perf_counter_task_disable(void) { return -EINVAL; } -- GitLab From 4b39fd96855254a244f71245b41a91cdecb87d63 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Fri, 23 Jan 2009 14:36:16 +0100 Subject: [PATCH 0069/6080] perfcounters: ratelimit performance counter interrupts Ratelimit performance counter interrupts to 100KHz per CPU. This replaces the irq-delta-time based method. Signed-off-by: Mike Galbraith Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 27 +++++++++++++++------------ include/linux/perf_counter.h | 2 -- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 1a040b179b53..a56d4cf92f30 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -33,9 +33,8 @@ static int nr_counters_fixed __read_mostly; struct cpu_hw_counters { struct perf_counter *counters[X86_PMC_IDX_MAX]; unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; - u64 last_interrupt; + unsigned long interrupts; u64 global_enable; - int throttled; }; /* @@ -470,6 +469,11 @@ perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) } } +/* + * Maximum interrupt frequency of 100KHz per CPU + */ +#define PERFMON_MAX_INTERRUPTS 100000/HZ + /* * This handler is triggered by the local APIC, so the APIC IRQ handling * rules apply: @@ -477,7 +481,7 @@ perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) { int bit, cpu = smp_processor_id(); - u64 ack, status, now; + u64 ack, status; struct cpu_hw_counters *cpuc = &per_cpu(cpu_hw_counters, cpu); rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); @@ -486,11 +490,6 @@ static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); ack_APIC_irq(); - now = sched_clock(); - if (now - cpuc->last_interrupt < PERFMON_MIN_PERIOD_NS) - cpuc->throttled = 1; - cpuc->last_interrupt = now; - rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); if (!status) goto out; @@ -541,13 +540,14 @@ out: /* * Restore - do not reenable when global enable is off or throttled: */ - if (!cpuc->throttled) + if (++cpuc->interrupts < PERFMON_MAX_INTERRUPTS) wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); } void perf_counter_unthrottle(void) { struct cpu_hw_counters *cpuc; + u64 global_enable; if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) return; @@ -556,12 +556,15 @@ void perf_counter_unthrottle(void) return; cpuc = &per_cpu(cpu_hw_counters, smp_processor_id()); - if (cpuc->throttled) { + if (cpuc->interrupts >= PERFMON_MAX_INTERRUPTS) { if (printk_ratelimit()) - printk(KERN_WARNING "PERFMON: max event frequency exceeded!\n"); + printk(KERN_WARNING "PERFMON: max interrupts exceeded!\n"); wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); - cpuc->throttled = 0; } + rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, global_enable); + if (unlikely(cpuc->global_enable && !global_enable)) + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); + cpuc->interrupts = 0; } void smp_perf_counter_interrupt(struct pt_regs *regs) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 91f1ca4c01c0..f55381fbcac9 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -271,8 +271,6 @@ static inline int is_software_counter(struct perf_counter *counter) return !counter->hw_event.raw && counter->hw_event.type < 0; } -#define PERFMON_MIN_PERIOD_NS 10000 - #else static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } -- GitLab From 3415dd9146c574bffe8f012c096bfc2bc62b9508 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Fri, 23 Jan 2009 14:16:53 +0100 Subject: [PATCH 0070/6080] perfcounters fix section mismatch warning in perf_counter.c::perf_counters_lapic_init() Fix: WARNING: arch/x86/kernel/built-in.o(.text+0xdd0f): Section mismatch in reference from the function pmc_generic_enable() to the function .cpuinit.text:perf_counters_lapic_init() The function pmc_generic_enable() references the function __cpuinit perf_counters_lapic_init(). This is often because pmc_generic_enable lacks a __cpuinit annotation or the annotation of perf_counters_lapic_init is wrong. Signed-off-by: Mike Galbraith Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index a56d4cf92f30..46c436cdd732 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -605,7 +605,7 @@ void perf_counter_notify(struct pt_regs *regs) local_irq_restore(flags); } -void __cpuinit perf_counters_lapic_init(int nmi) +void perf_counters_lapic_init(int nmi) { u32 apic_val; -- GitLab From bb3f0b59ad005d2d2ecbbe9bd048eab6d1ecbd31 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sun, 25 Jan 2009 02:38:09 -0800 Subject: [PATCH 0071/6080] x86: make irqinit_32.c more like irqinit_64.c, v2 Impact: cleanup 1. add smp_intr_init and apic_intr_init for 32bit, the same as 64bit 2. move the apic_intr_init() call before set gate with interrupt[i] 3. for 64bit, if ia32_emulation is not used, will make per_cpu to use 0x80 vector. [ v2: should use !test_bit() instead of test_bit() with 32bit ] Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- arch/x86/kernel/irqinit_32.c | 56 +++++++++++++++++++++--------------- arch/x86/kernel/irqinit_64.c | 7 +++-- arch/x86/kernel/traps.c | 15 ++++------ 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index c56496f8c6fc..ddf3eb72f864 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c @@ -120,28 +120,8 @@ int vector_used_by_percpu_irq(unsigned int vector) return 0; } -/* Overridden in paravirt.c */ -void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); - -void __init native_init_IRQ(void) +static void __init smp_intr_init(void) { - int i; - - /* all the set up before the call gates are initialised */ - pre_intr_init_hook(); - - /* - * Cover the whole vector space, no vector can escape - * us. (some of these will be overridden and become - * 'special' SMP interrupts) - */ - for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { - /* SYSCALL_VECTOR was reserved in trap_init. */ - if (i != SYSCALL_VECTOR) - set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); - } - - #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP) /* * The reschedule interrupt is a CPU-to-CPU reschedule-helper @@ -170,8 +150,13 @@ void __init native_init_IRQ(void) set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); #endif +} +static void __init apic_intr_init(void) +{ #ifdef CONFIG_X86_LOCAL_APIC + smp_intr_init(); + /* self generated IPI for local APIC timer */ alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); @@ -181,12 +166,37 @@ void __init native_init_IRQ(void) # ifdef CONFIG_PERF_COUNTERS alloc_intr_gate(LOCAL_PERF_VECTOR, perf_counter_interrupt); # endif -#endif -#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_MCE_P4THERMAL) +# ifdef CONFIG_X86_MCE_P4THERMAL /* thermal monitor LVT interrupt */ alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); +# endif #endif +} + +/* Overridden in paravirt.c */ +void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); + +void __init native_init_IRQ(void) +{ + int i; + + /* all the set up before the call gates are initialised */ + pre_intr_init_hook(); + + apic_intr_init(); + + /* + * Cover the whole vector space, no vector can escape + * us. (some of these will be overridden and become + * 'special' SMP interrupts) + */ + for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) { + int vector = FIRST_EXTERNAL_VECTOR + i; + /* SYSCALL_VECTOR was reserved in trap_init. */ + if (!test_bit(vector, used_vectors)) + set_intr_gate(vector, interrupt[i]); + } if (!acpi_ioapic) setup_irq(2, &irq2); diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c index 6a71bfc51e51..16e1fc687504 100644 --- a/arch/x86/kernel/irqinit_64.c +++ b/arch/x86/kernel/irqinit_64.c @@ -162,6 +162,9 @@ void __init native_init_IRQ(void) int i; init_ISA_irqs(); + + apic_intr_init(); + /* * Cover the whole vector space, no vector can escape * us. (some of these will be overridden and become @@ -169,12 +172,10 @@ void __init native_init_IRQ(void) */ for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) { int vector = FIRST_EXTERNAL_VECTOR + i; - if (vector != IA32_SYSCALL_VECTOR) + if (!test_bit(vector, used_vectors)) set_intr_gate(vector, interrupt[i]); } - apic_intr_init(); - if (!acpi_ioapic) setup_irq(2, &irq2); } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index ed5aee5f3fcc..d36a502d87ab 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -979,8 +979,13 @@ void __init trap_init(void) #endif set_intr_gate(19, &simd_coprocessor_error); + /* Reserve all the builtin and the syscall vector: */ + for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) + set_bit(i, used_vectors); + #ifdef CONFIG_IA32_EMULATION set_system_intr_gate(IA32_SYSCALL_VECTOR, ia32_syscall); + set_bit(IA32_SYSCALL_VECTOR, used_vectors); #endif #ifdef CONFIG_X86_32 @@ -997,17 +1002,9 @@ void __init trap_init(void) } set_system_trap_gate(SYSCALL_VECTOR, &system_call); -#endif - - /* Reserve all the builtin and the syscall vector: */ - for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) - set_bit(i, used_vectors); - -#ifdef CONFIG_X86_64 - set_bit(IA32_SYSCALL_VECTOR, used_vectors); -#else set_bit(SYSCALL_VECTOR, used_vectors); #endif + /* * Should be a barrier for any external CPU state: */ -- GitLab From 65d370862f64973611a271ced61864b5f9bb6fc0 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Thu, 29 Jan 2009 14:06:52 +0100 Subject: [PATCH 0072/6080] perfcounters: fix refcounting bug don't kfree in use counters. Running... while true; do perfstat -e 1 -c true; done ...on all cores for a while doesn't seem to be eating ram, and my oops is gone. Signed-off-by: Mike Galbraith Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 1ac18daa424f..f27a7e9f3c41 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1934,7 +1934,8 @@ __perf_counter_exit_task(struct task_struct *child, } } - kfree(child_counter); + if (!child_counter->filp || !atomic_long_read(&child_counter->filp->f_count)) + kfree(child_counter); } /* -- GitLab From 15081c61362618a0c81cc8d04e45e7427bc1ed71 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sun, 1 Feb 2009 22:07:39 +0530 Subject: [PATCH 0073/6080] x86: irqinit_32.c fix compilation warning Fix: arch/x86/kernel/irqinit_32.c:124: warning: 'smp_intr_init' defined but not used Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/irqinit_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index ddf3eb72f864..520e6c1c5d22 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c @@ -154,9 +154,9 @@ static void __init smp_intr_init(void) static void __init apic_intr_init(void) { -#ifdef CONFIG_X86_LOCAL_APIC smp_intr_init(); +#ifdef CONFIG_X86_LOCAL_APIC /* self generated IPI for local APIC timer */ alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); -- GitLab From 5b75af0a02fcf3b8899f38ff6f22164c5d8e2fdd Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Wed, 4 Feb 2009 17:11:34 +0100 Subject: [PATCH 0074/6080] perfcounters: fix "perf counters kill oprofile" bug With oprofile as a module, and unloaded by profiling script, both oprofile and kerneltop work fine.. unless you leave kerneltop running when you start profiling, then you may see badness. Signed-off-by: Mike Galbraith Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 4 +++- arch/x86/oprofile/nmi_int.c | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 46c436cdd732..8bb213323fe8 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -643,7 +643,9 @@ perf_counter_nmi_handler(struct notifier_block *self, } static __read_mostly struct notifier_block perf_counter_nmi_notifier = { - .notifier_call = perf_counter_nmi_handler + .notifier_call = perf_counter_nmi_handler, + .next = NULL, + .priority = 1 }; void __init init_hw_perf_counters(void) diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 202864ad49a7..c638685136e1 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -40,8 +40,9 @@ static int profile_exceptions_notify(struct notifier_block *self, switch (val) { case DIE_NMI: - if (model->check_ctrs(args->regs, &per_cpu(cpu_msrs, cpu))) - ret = NOTIFY_STOP; + case DIE_NMI_IPI: + model->check_ctrs(args->regs, &per_cpu(cpu_msrs, cpu)); + ret = NOTIFY_STOP; break; default: break; @@ -134,7 +135,7 @@ static void nmi_cpu_setup(void *dummy) static struct notifier_block profile_exceptions_nb = { .notifier_call = profile_exceptions_notify, .next = NULL, - .priority = 0 + .priority = 2 }; static int nmi_setup(void) -- GitLab From 82aa9a1829199233f9bdaf26e2ee271114f4701e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 5 Feb 2009 15:23:08 +0100 Subject: [PATCH 0075/6080] perfcounters: fix "perf counters kills oprofile" bug, v2 Impact: fix kernel crash Both oprofile and perfcounters register an NMI die handler, but only one can handle the NMI. Conveniently, oprofile unregisters it's notifier when not actively in use, so setting it's notifier priority higher than perfcounter's allows oprofile to borrow the NMI for the duration of it's run. Tested/works both as module and built-in. While testing, I found that if kerneltop was generating NMIs at very high frequency, the kernel may panic when oprofile registered it's handler. This turned out to be because oprofile registers it's handler before reset_value has been allocated, so if an NMI comes in while it's still setting up, kabOom. Rather than try more invasive changes, I followed the lead of other places in op_model_ppro.c, and simply returned in that highly unlikely event. (debug warnings attached) Signed-off-by: Mike Galbraith Signed-off-by: Ingo Molnar --- arch/x86/oprofile/op_model_ppro.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c index 07c914555a5e..85eb6268374f 100644 --- a/arch/x86/oprofile/op_model_ppro.c +++ b/arch/x86/oprofile/op_model_ppro.c @@ -126,6 +126,13 @@ static int ppro_check_ctrs(struct pt_regs * const regs, u64 val; int i; + /* + * This can happen if perf counters are in use when + * we steal the die notifier NMI. + */ + if (unlikely(!reset_value)) + goto out; + for (i = 0 ; i < num_counters; ++i) { if (!reset_value[i]) continue; @@ -136,6 +143,7 @@ static int ppro_check_ctrs(struct pt_regs * const regs, } } +out: /* Only P6 based Pentium M need to re-unmask the apic vector but it * doesn't hurt other P6 variant */ apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); -- GitLab From 23a185ca8abbeef64b6ffc33059b1d630e43ec10 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 9 Feb 2009 22:42:47 +1100 Subject: [PATCH 0076/6080] perf_counters: make software counters work as per-cpu counters Impact: kernel crash fix Yanmin Zhang reported that using a PERF_COUNT_TASK_CLOCK software counter as a per-cpu counter would reliably crash the system, because it calls __task_delta_exec with a null pointer. The page fault, context switch and cpu migration counters also won't function correctly as per-cpu counters since they reference the current task. This fixes the problem by redirecting the task_clock counter to the cpu_clock counter when used as a per-cpu counter, and by implementing per-cpu page fault, context switch and cpu migration counters. Along the way, this: - Initializes counter->ctx earlier, in perf_counter_alloc, so that sw_perf_counter_init can use it - Adds code to kernel/sched.c to count task migrations into each cpu, in rq->nr_migrations_in - Exports the per-cpu context switch and task migration counts via new functions added to kernel/sched.c - Makes sure that if sw_perf_counter_init fails, we don't try to initialize the counter as a hardware counter. Since the user has passed a negative, non-raw event type, they clearly don't intend for it to be interpreted as a hardware event. Reported-by: "Zhang Yanmin" Signed-off-by: Paul Mackerras Signed-off-by: Ingo Molnar --- include/linux/sched.h | 2 ++ kernel/perf_counter.c | 78 +++++++++++++++++++++++++------------------ kernel/sched.c | 17 ++++++++++ 3 files changed, 64 insertions(+), 33 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index b85b10abf770..1e5f70062a9c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -137,6 +137,8 @@ extern unsigned long nr_running(void); extern unsigned long nr_uninterruptible(void); extern unsigned long nr_active(void); extern unsigned long nr_iowait(void); +extern u64 cpu_nr_switches(int cpu); +extern u64 cpu_nr_migrations(int cpu); struct seq_file; struct cfs_rq; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f27a7e9f3c41..544193cbc478 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include /* * Each CPU has a list of per CPU counters: @@ -502,7 +504,6 @@ perf_install_in_context(struct perf_counter_context *ctx, { struct task_struct *task = ctx->task; - counter->ctx = ctx; if (!task) { /* * Per cpu counters are installed via an smp call and @@ -1417,11 +1418,19 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = { .read = task_clock_perf_counter_read, }; -static u64 get_page_faults(void) +#ifdef CONFIG_VM_EVENT_COUNTERS +#define cpu_page_faults() __get_cpu_var(vm_event_states).event[PGFAULT] +#else +#define cpu_page_faults() 0 +#endif + +static u64 get_page_faults(struct perf_counter *counter) { - struct task_struct *curr = current; + struct task_struct *curr = counter->ctx->task; - return curr->maj_flt + curr->min_flt; + if (curr) + return curr->maj_flt + curr->min_flt; + return cpu_page_faults(); } static void page_faults_perf_counter_update(struct perf_counter *counter) @@ -1430,7 +1439,7 @@ static void page_faults_perf_counter_update(struct perf_counter *counter) s64 delta; prev = atomic64_read(&counter->hw.prev_count); - now = get_page_faults(); + now = get_page_faults(counter); atomic64_set(&counter->hw.prev_count, now); @@ -1446,11 +1455,7 @@ static void page_faults_perf_counter_read(struct perf_counter *counter) static int page_faults_perf_counter_enable(struct perf_counter *counter) { - /* - * page-faults is a per-task value already, - * so we dont have to clear it on switch-in. - */ - + atomic64_set(&counter->hw.prev_count, get_page_faults(counter)); return 0; } @@ -1465,11 +1470,13 @@ static const struct hw_perf_counter_ops perf_ops_page_faults = { .read = page_faults_perf_counter_read, }; -static u64 get_context_switches(void) +static u64 get_context_switches(struct perf_counter *counter) { - struct task_struct *curr = current; + struct task_struct *curr = counter->ctx->task; - return curr->nvcsw + curr->nivcsw; + if (curr) + return curr->nvcsw + curr->nivcsw; + return cpu_nr_switches(smp_processor_id()); } static void context_switches_perf_counter_update(struct perf_counter *counter) @@ -1478,7 +1485,7 @@ static void context_switches_perf_counter_update(struct perf_counter *counter) s64 delta; prev = atomic64_read(&counter->hw.prev_count); - now = get_context_switches(); + now = get_context_switches(counter); atomic64_set(&counter->hw.prev_count, now); @@ -1494,11 +1501,7 @@ static void context_switches_perf_counter_read(struct perf_counter *counter) static int context_switches_perf_counter_enable(struct perf_counter *counter) { - /* - * ->nvcsw + curr->nivcsw is a per-task value already, - * so we dont have to clear it on switch-in. - */ - + atomic64_set(&counter->hw.prev_count, get_context_switches(counter)); return 0; } @@ -1513,9 +1516,13 @@ static const struct hw_perf_counter_ops perf_ops_context_switches = { .read = context_switches_perf_counter_read, }; -static inline u64 get_cpu_migrations(void) +static inline u64 get_cpu_migrations(struct perf_counter *counter) { - return current->se.nr_migrations; + struct task_struct *curr = counter->ctx->task; + + if (curr) + return curr->se.nr_migrations; + return cpu_nr_migrations(smp_processor_id()); } static void cpu_migrations_perf_counter_update(struct perf_counter *counter) @@ -1524,7 +1531,7 @@ static void cpu_migrations_perf_counter_update(struct perf_counter *counter) s64 delta; prev = atomic64_read(&counter->hw.prev_count); - now = get_cpu_migrations(); + now = get_cpu_migrations(counter); atomic64_set(&counter->hw.prev_count, now); @@ -1540,11 +1547,7 @@ static void cpu_migrations_perf_counter_read(struct perf_counter *counter) static int cpu_migrations_perf_counter_enable(struct perf_counter *counter) { - /* - * se.nr_migrations is a per-task value already, - * so we dont have to clear it on switch-in. - */ - + atomic64_set(&counter->hw.prev_count, get_cpu_migrations(counter)); return 0; } @@ -1569,7 +1572,14 @@ sw_perf_counter_init(struct perf_counter *counter) hw_ops = &perf_ops_cpu_clock; break; case PERF_COUNT_TASK_CLOCK: - hw_ops = &perf_ops_task_clock; + /* + * If the user instantiates this as a per-cpu counter, + * use the cpu_clock counter instead. + */ + if (counter->ctx->task) + hw_ops = &perf_ops_task_clock; + else + hw_ops = &perf_ops_cpu_clock; break; case PERF_COUNT_PAGE_FAULTS: hw_ops = &perf_ops_page_faults; @@ -1592,6 +1602,7 @@ sw_perf_counter_init(struct perf_counter *counter) static struct perf_counter * perf_counter_alloc(struct perf_counter_hw_event *hw_event, int cpu, + struct perf_counter_context *ctx, struct perf_counter *group_leader, gfp_t gfpflags) { @@ -1623,6 +1634,7 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, counter->wakeup_pending = 0; counter->group_leader = group_leader; counter->hw_ops = NULL; + counter->ctx = ctx; counter->state = PERF_COUNTER_STATE_INACTIVE; if (hw_event->disabled) @@ -1631,7 +1643,7 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, hw_ops = NULL; if (!hw_event->raw && hw_event->type < 0) hw_ops = sw_perf_counter_init(counter); - if (!hw_ops) + else hw_ops = hw_perf_counter_init(counter); if (!hw_ops) { @@ -1707,7 +1719,8 @@ sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr __user, } ret = -EINVAL; - counter = perf_counter_alloc(&hw_event, cpu, group_leader, GFP_KERNEL); + counter = perf_counter_alloc(&hw_event, cpu, ctx, group_leader, + GFP_KERNEL); if (!counter) goto err_put_context; @@ -1777,15 +1790,14 @@ inherit_counter(struct perf_counter *parent_counter, parent_counter = parent_counter->parent; child_counter = perf_counter_alloc(&parent_counter->hw_event, - parent_counter->cpu, group_leader, - GFP_KERNEL); + parent_counter->cpu, child_ctx, + group_leader, GFP_KERNEL); if (!child_counter) return NULL; /* * Link it up in the child's context: */ - child_counter->ctx = child_ctx; child_counter->task = child; list_add_counter(child_counter, child_ctx); child_ctx->nr_counters++; diff --git a/kernel/sched.c b/kernel/sched.c index 8db1a4cf2082..173768f142ad 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -558,6 +558,7 @@ struct rq { struct load_weight load; unsigned long nr_load_updates; u64 nr_switches; + u64 nr_migrations_in; struct cfs_rq cfs; struct rt_rq rt; @@ -1908,6 +1909,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) #endif if (old_cpu != new_cpu) { p->se.nr_migrations++; + new_rq->nr_migrations_in++; #ifdef CONFIG_SCHEDSTATS if (task_hot(p, old_rq->clock, NULL)) schedstat_inc(p, se.nr_forced2_migrations); @@ -2810,6 +2812,21 @@ unsigned long nr_active(void) return running + uninterruptible; } +/* + * Externally visible per-cpu scheduler statistics: + * cpu_nr_switches(cpu) - number of context switches on that cpu + * cpu_nr_migrations(cpu) - number of migrations into that cpu + */ +u64 cpu_nr_switches(int cpu) +{ + return cpu_rq(cpu)->nr_switches; +} + +u64 cpu_nr_migrations(int cpu) +{ + return cpu_rq(cpu)->nr_migrations_in; +} + /* * Update rq->cpu_load[] statistics. This function is usually called every * scheduler tick (TICK_NSEC). -- GitLab From d278c48435625cb6b7edcf6a547620768b175709 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Mon, 9 Feb 2009 07:38:50 +0100 Subject: [PATCH 0077/6080] perf_counters: account NMI interrupts I noticed that kerneltop interrupts were accounted as NMI, but not their perf counter origin. Account NMI performance counter interrupts. Signed-off-by: Mike Galbraith Signed-off-by: Ingo Molnar arch/x86/kernel/cpu/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- arch/x86/kernel/cpu/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 8bb213323fe8..9901e46998d1 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -495,6 +495,7 @@ static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) goto out; again: + inc_irq_stat(apic_perf_irqs); ack = status; for_each_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { struct perf_counter *counter = cpuc->counters[bit]; @@ -570,7 +571,6 @@ void perf_counter_unthrottle(void) void smp_perf_counter_interrupt(struct pt_regs *regs) { irq_enter(); - inc_irq_stat(apic_perf_irqs); apic_write(APIC_LVTPC, LOCAL_PERF_VECTOR); __smp_perf_counter_interrupt(regs, 0); -- GitLab From 0475f9ea8e2cc030298908949e0d5da9f2fc2cfe Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 11 Feb 2009 14:35:35 +1100 Subject: [PATCH 0078/6080] perf_counters: allow users to count user, kernel and/or hypervisor events Impact: new perf_counter feature This extends the perf_counter_hw_event struct with bits that specify that events in user, kernel and/or hypervisor mode should not be counted (i.e. should be excluded), and adds code to program the PMU mode selection bits accordingly on x86 and powerpc. For software counters, we don't currently have the infrastructure to distinguish which mode an event occurs in, so we currently fail the counter initialization if the setting of the hw_event.exclude_* bits would require us to distinguish. Context switches and CPU migrations are currently considered to occur in kernel mode. On x86, this changes the previous policy that only root can count kernel events. Now non-root users can count kernel events or exclude them. Non-root users still can't use NMI events, though. On x86 we don't appear to have any way to control whether hypervisor events are counted or not, so hw_event.exclude_hv is ignored. On powerpc, the selection of whether to count events in user, kernel and/or hypervisor mode is PMU-wide, not per-counter, so this adds a check that the hw_event.exclude_* settings are the same as other events on the PMU. Counters being added to a group have to have the same settings as the other hardware counters in the group. Counters and groups can only be enabled in hw_perf_group_sched_in or power_perf_enable if they have the same settings as any other counters already on the PMU. If we are not running on a hypervisor, the exclude_hv setting is ignored (by forcing it to 0) since we can't ever get any hypervisor events. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/perf_counter.c | 68 ++++++++++++++++++++++++++++-- arch/x86/kernel/cpu/perf_counter.c | 31 ++++++++------ include/linux/perf_counter.h | 19 +++++---- kernel/perf_counter.c | 26 ++++++++++-- 4 files changed, 117 insertions(+), 27 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 5b0211348c73..bd6ba85beb54 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -16,6 +16,7 @@ #include #include #include +#include struct cpu_hw_counters { int n_counters; @@ -214,6 +215,36 @@ static int power_check_constraints(unsigned int event[], int n_ev) return 0; } +/* + * Check if newly-added counters have consistent settings for + * exclude_{user,kernel,hv} with each other and any previously + * added counters. + */ +static int check_excludes(struct perf_counter **ctrs, int n_prev, int n_new) +{ + int eu, ek, eh; + int i, n; + struct perf_counter *counter; + + n = n_prev + n_new; + if (n <= 1) + return 0; + + eu = ctrs[0]->hw_event.exclude_user; + ek = ctrs[0]->hw_event.exclude_kernel; + eh = ctrs[0]->hw_event.exclude_hv; + if (n_prev == 0) + n_prev = 1; + for (i = n_prev; i < n; ++i) { + counter = ctrs[i]; + if (counter->hw_event.exclude_user != eu || + counter->hw_event.exclude_kernel != ek || + counter->hw_event.exclude_hv != eh) + return -EAGAIN; + } + return 0; +} + static void power_perf_read(struct perf_counter *counter) { long val, delta, prev; @@ -323,6 +354,20 @@ void hw_perf_restore(u64 disable) goto out; } + /* + * Add in MMCR0 freeze bits corresponding to the + * hw_event.exclude_* bits for the first counter. + * We have already checked that all counters have the + * same values for these bits as the first counter. + */ + counter = cpuhw->counter[0]; + if (counter->hw_event.exclude_user) + cpuhw->mmcr[0] |= MMCR0_FCP; + if (counter->hw_event.exclude_kernel) + cpuhw->mmcr[0] |= MMCR0_FCS; + if (counter->hw_event.exclude_hv) + cpuhw->mmcr[0] |= MMCR0_FCHV; + /* * Write the new configuration to MMCR* with the freeze * bit set and set the hardware counters to their initial values. @@ -424,6 +469,8 @@ int hw_perf_group_sched_in(struct perf_counter *group_leader, &cpuhw->counter[n0], &cpuhw->events[n0]); if (n < 0) return -EAGAIN; + if (check_excludes(cpuhw->counter, n0, n)) + return -EAGAIN; if (power_check_constraints(cpuhw->events, n + n0)) return -EAGAIN; cpuhw->n_counters = n0 + n; @@ -476,6 +523,8 @@ static int power_perf_enable(struct perf_counter *counter) goto out; cpuhw->counter[n0] = counter; cpuhw->events[n0] = counter->hw.config; + if (check_excludes(cpuhw->counter, n0, 1)) + goto out; if (power_check_constraints(cpuhw->events, n0 + 1)) goto out; @@ -554,6 +603,17 @@ hw_perf_counter_init(struct perf_counter *counter) counter->hw.config_base = ev; counter->hw.idx = 0; + /* + * If we are not running on a hypervisor, force the + * exclude_hv bit to 0 so that we don't care what + * the user set it to. This also means that we don't + * set the MMCR0_FCHV bit, which unconditionally freezes + * the counters on the PPC970 variants used in Apple G5 + * machines (since MSR.HV is always 1 on those machines). + */ + if (!firmware_has_feature(FW_FEATURE_LPAR)) + counter->hw_event.exclude_hv = 0; + /* * If this is in a group, check if it can go on with all the * other hardware counters in the group. We assume the counter @@ -566,11 +626,13 @@ hw_perf_counter_init(struct perf_counter *counter) if (n < 0) return NULL; } - events[n++] = ev; - if (power_check_constraints(events, n)) + events[n] = ev; + if (check_excludes(ctrs, n, 1)) + return NULL; + if (power_check_constraints(events, n + 1)) return NULL; - counter->hw.config = events[n - 1]; + counter->hw.config = events[n]; atomic64_set(&counter->hw.period_left, counter->hw_event.irq_period); return &power_perf_ops; } diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 9901e46998d1..383d4c6423a1 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -107,21 +107,25 @@ static int __hw_perf_counter_init(struct perf_counter *counter) return -EINVAL; /* - * Count user events, and generate PMC IRQs: + * Generate PMC IRQs: * (keep 'enabled' bit clear for now) */ - hwc->config = ARCH_PERFMON_EVENTSEL_USR | ARCH_PERFMON_EVENTSEL_INT; + hwc->config = ARCH_PERFMON_EVENTSEL_INT; /* - * If privileged enough, count OS events too, and allow - * NMI events as well: + * Count user and OS events unless requested not to. */ - hwc->nmi = 0; - if (capable(CAP_SYS_ADMIN)) { + if (!hw_event->exclude_user) + hwc->config |= ARCH_PERFMON_EVENTSEL_USR; + if (!hw_event->exclude_kernel) hwc->config |= ARCH_PERFMON_EVENTSEL_OS; - if (hw_event->nmi) - hwc->nmi = 1; - } + + /* + * If privileged enough, allow NMI events: + */ + hwc->nmi = 0; + if (capable(CAP_SYS_ADMIN) && hw_event->nmi) + hwc->nmi = 1; hwc->irq_period = hw_event->irq_period; /* @@ -248,10 +252,13 @@ __pmc_fixed_enable(struct perf_counter *counter, int err; /* - * Enable IRQ generation (0x8) and ring-3 counting (0x2), - * and enable ring-0 counting if allowed: + * Enable IRQ generation (0x8), + * and enable ring-3 counting (0x2) and ring-0 counting (0x1) + * if requested: */ - bits = 0x8ULL | 0x2ULL; + bits = 0x8ULL; + if (hwc->config & ARCH_PERFMON_EVENTSEL_USR) + bits |= 0x2; if (hwc->config & ARCH_PERFMON_EVENTSEL_OS) bits |= 0x1; bits <<= (idx * 4); diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index f55381fbcac9..c83f51d6e359 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -83,14 +83,17 @@ struct perf_counter_hw_event { u64 irq_period; u32 record_type; - u32 disabled : 1, /* off by default */ - nmi : 1, /* NMI sampling */ - raw : 1, /* raw event type */ - inherit : 1, /* children inherit it */ - pinned : 1, /* must always be on PMU */ - exclusive : 1, /* only counter on PMU */ - - __reserved_1 : 26; + u32 disabled : 1, /* off by default */ + nmi : 1, /* NMI sampling */ + raw : 1, /* raw event type */ + inherit : 1, /* children inherit it */ + pinned : 1, /* must always be on PMU */ + exclusive : 1, /* only group on PMU */ + exclude_user : 1, /* don't count user */ + exclude_kernel : 1, /* ditto kernel */ + exclude_hv : 1, /* ditto hypervisor */ + + __reserved_1 : 23; u64 __reserved_2; }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 544193cbc478..89d5e3fe9700 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1567,11 +1567,25 @@ sw_perf_counter_init(struct perf_counter *counter) { const struct hw_perf_counter_ops *hw_ops = NULL; + /* + * Software counters (currently) can't in general distinguish + * between user, kernel and hypervisor events. + * However, context switches and cpu migrations are considered + * to be kernel events, and page faults are never hypervisor + * events. + */ switch (counter->hw_event.type) { case PERF_COUNT_CPU_CLOCK: - hw_ops = &perf_ops_cpu_clock; + if (!(counter->hw_event.exclude_user || + counter->hw_event.exclude_kernel || + counter->hw_event.exclude_hv)) + hw_ops = &perf_ops_cpu_clock; break; case PERF_COUNT_TASK_CLOCK: + if (counter->hw_event.exclude_user || + counter->hw_event.exclude_kernel || + counter->hw_event.exclude_hv) + break; /* * If the user instantiates this as a per-cpu counter, * use the cpu_clock counter instead. @@ -1582,13 +1596,17 @@ sw_perf_counter_init(struct perf_counter *counter) hw_ops = &perf_ops_cpu_clock; break; case PERF_COUNT_PAGE_FAULTS: - hw_ops = &perf_ops_page_faults; + if (!(counter->hw_event.exclude_user || + counter->hw_event.exclude_kernel)) + hw_ops = &perf_ops_page_faults; break; case PERF_COUNT_CONTEXT_SWITCHES: - hw_ops = &perf_ops_context_switches; + if (!counter->hw_event.exclude_kernel) + hw_ops = &perf_ops_context_switches; break; case PERF_COUNT_CPU_MIGRATIONS: - hw_ops = &perf_ops_cpu_migrations; + if (!counter->hw_event.exclude_kernel) + hw_ops = &perf_ops_cpu_migrations; break; default: break; -- GitLab From 5af759176cc767e7426f89764bde4996ebaaf419 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Wed, 11 Feb 2009 10:53:37 +0100 Subject: [PATCH 0079/6080] perfcounters: fix use after free in perf_release() running... while true; do foo -d 1 -f 1 -c 100000 & sleep 1 kerneltop -d 1 -f 1 -e 1 -c 25000 -p `pidof foo` done while true; do killall foo; killall kerneltop; sleep 2 done ...in two shells with SLUB_DEBUG enabled produces flood of: BUG task_struct: Poison overwritten. Fix the use-after-free bug in perf_release(). Signed-off-by: Mike Galbraith Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 89d5e3fe9700..e0576c3fdb50 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1145,12 +1145,12 @@ static int perf_release(struct inode *inode, struct file *file) mutex_lock(&counter->mutex); perf_counter_remove_from_context(counter); - put_context(ctx); mutex_unlock(&counter->mutex); mutex_unlock(&ctx->mutex); kfree(counter); + put_context(ctx); return 0; } -- GitLab From 4bcf349a0f90d1e69eb35c6df0fa285c886c1cd6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 11 Feb 2009 13:53:19 +0100 Subject: [PATCH 0080/6080] perfcounters: fix refcounting bug, take 2 Only free child_counter if it has a parent; if it doesn't, then it has a file pointing to it and we'll free it in perf_release. Signed-off-by: Mike Galbraith Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index e0576c3fdb50..fcefb0a726f3 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1958,14 +1958,13 @@ __perf_counter_exit_task(struct task_struct *child, sync_child_counter(child_counter, parent_counter); list_for_each_entry_safe(sub, tmp, &child_counter->sibling_list, list_entry) { - if (sub->parent) + if (sub->parent) { sync_child_counter(sub, sub->parent); - kfree(sub); + kfree(sub); + } } - } - - if (!child_counter->filp || !atomic_long_read(&child_counter->filp->f_count)) kfree(child_counter); + } } /* -- GitLab From c07c99b67233ccaad38a961c17405dc1e1542aa4 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 13 Feb 2009 22:10:34 +1100 Subject: [PATCH 0081/6080] perfcounters: make context switch and migration software counters work again Jaswinder Singh Rajput reported that commit 23a185ca8abbeef caused the context switch and migration software counters to report zero always. With that commit, the software counters only count events that occur between sched-in and sched-out for a task. This is necessary for the counter enable/disable prctls and ioctls to work. However, the context switch and migration counts are incremented after sched-out for one task and before sched-in for the next. Since the increment doesn't occur while a task is scheduled in (as far as the software counters are concerned) it doesn't count towards any counter. Thus the context switch and migration counters need to count events that occur at any time, provided the counter is enabled, not just those that occur while the task is scheduled in (from the perf_counter subsystem's point of view). The problem though is that the software counter code can't tell the difference between being enabled and being scheduled in, and between being disabled and being scheduled out, since we use the one pair of enable/disable entry points for both. That is, the high-level disable operation simply arranges for the counter to not be scheduled in any more, and the high-level enable operation arranges for it to be scheduled in again. One way to solve this would be to have sched_in/out operations in the hw_perf_counter_ops struct as well as enable/disable. However, this takes a simpler approach: it adds a 'prev_state' field to the perf_counter struct that allows a counter's enable method to know whether the counter was previously disabled or just inactive (scheduled out), and therefore whether the enable method is being called as a result of a high-level enable or a schedule-in operation. This then allows the context switch, migration and page fault counters to reset their hw.prev_count value in their enable functions only if they are called as a result of a high-level enable operation. Although page faults would normally only occur while the counter is scheduled in, this changes the page fault counter code too in case there are ever circumstances where page faults get counted against a task while its counters are not scheduled in. Reported-by: Jaswinder Singh Rajput Signed-off-by: Paul Mackerras Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 1 + kernel/perf_counter.c | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index c83f51d6e359..32cd1acb7386 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -173,6 +173,7 @@ struct perf_counter { const struct hw_perf_counter_ops *hw_ops; enum perf_counter_active_state state; + enum perf_counter_active_state prev_state; atomic64_t count; struct perf_counter_hw_event hw_event; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index fcefb0a726f3..ad62965828d3 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -444,6 +444,7 @@ static void __perf_install_in_context(void *info) list_add_counter(counter, ctx); ctx->nr_counters++; + counter->prev_state = PERF_COUNTER_STATE_OFF; /* * Don't put the counter on if it is disabled or if @@ -562,6 +563,7 @@ static void __perf_counter_enable(void *info) curr_rq_lock_irq_save(&flags); spin_lock(&ctx->lock); + counter->prev_state = counter->state; if (counter->state >= PERF_COUNTER_STATE_INACTIVE) goto unlock; counter->state = PERF_COUNTER_STATE_INACTIVE; @@ -733,6 +735,7 @@ group_sched_in(struct perf_counter *group_counter, if (ret) return ret < 0 ? ret : 0; + group_counter->prev_state = group_counter->state; if (counter_sched_in(group_counter, cpuctx, ctx, cpu)) return -EAGAIN; @@ -740,6 +743,7 @@ group_sched_in(struct perf_counter *group_counter, * Schedule in siblings as one group (if any): */ list_for_each_entry(counter, &group_counter->sibling_list, list_entry) { + counter->prev_state = counter->state; if (counter_sched_in(counter, cpuctx, ctx, cpu)) { partial_group = counter; goto group_error; @@ -1398,9 +1402,9 @@ static void task_clock_perf_counter_read(struct perf_counter *counter) static int task_clock_perf_counter_enable(struct perf_counter *counter) { - u64 now = task_clock_perf_counter_val(counter, 0); - - atomic64_set(&counter->hw.prev_count, now); + if (counter->prev_state <= PERF_COUNTER_STATE_OFF) + atomic64_set(&counter->hw.prev_count, + task_clock_perf_counter_val(counter, 0)); return 0; } @@ -1455,7 +1459,8 @@ static void page_faults_perf_counter_read(struct perf_counter *counter) static int page_faults_perf_counter_enable(struct perf_counter *counter) { - atomic64_set(&counter->hw.prev_count, get_page_faults(counter)); + if (counter->prev_state <= PERF_COUNTER_STATE_OFF) + atomic64_set(&counter->hw.prev_count, get_page_faults(counter)); return 0; } @@ -1501,7 +1506,9 @@ static void context_switches_perf_counter_read(struct perf_counter *counter) static int context_switches_perf_counter_enable(struct perf_counter *counter) { - atomic64_set(&counter->hw.prev_count, get_context_switches(counter)); + if (counter->prev_state <= PERF_COUNTER_STATE_OFF) + atomic64_set(&counter->hw.prev_count, + get_context_switches(counter)); return 0; } @@ -1547,7 +1554,9 @@ static void cpu_migrations_perf_counter_read(struct perf_counter *counter) static int cpu_migrations_perf_counter_enable(struct perf_counter *counter) { - atomic64_set(&counter->hw.prev_count, get_cpu_migrations(counter)); + if (counter->prev_state <= PERF_COUNTER_STATE_OFF) + atomic64_set(&counter->hw.prev_count, + get_cpu_migrations(counter)); return 0; } -- GitLab From 73ca2f8380311115723c7afe811f3ed1f0ba945e Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 16 Feb 2009 01:08:17 +0100 Subject: [PATCH 0082/6080] perfcounters: remove duplicate definition of LOCAL_PERF_VECTOR Signed-off-by: Ingo Molnar --- arch/x86/include/asm/irq_vectors.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index b66b518ff000..b07278c55e9e 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -111,11 +111,6 @@ */ #define LOCAL_PERF_VECTOR 0xee -/* - * Performance monitoring interrupt vector: - */ -#define LOCAL_PERF_VECTOR 0xee - /* * First APIC vector available to drivers: (vectors 0x30-0xee) we * start at 0x31(0x41) to spread out vectors evenly between priority -- GitLab From 37a25424252b6cff4dd4b1937ab6a1dbfcadabcc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 16 Feb 2009 15:32:23 +0100 Subject: [PATCH 0083/6080] perfcounters: fix acpi_idle_do_entry() workaround Fix merge error in drivers/acpi/processor_idle.c. This resulted in non-working perfcounters on certain Nehalem systems. Signed-off-by: Ingo Molnar --- drivers/acpi/processor_idle.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 259f6e806314..08def2f20cd9 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -826,12 +826,9 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) { u64 perf_flags; - u64 pctrl; - /* Don't trace irqs off for idle */ stop_critical_timings(); perf_flags = hw_perf_save_disable(); - pctrl = hw_perf_save_disable(); if (cx->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cx); @@ -847,7 +844,6 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } hw_perf_restore(perf_flags); - hw_perf_restore(pctrl); start_critical_timings(); } -- GitLab From d095cd46dac104e4d2a4967c7c19b55a12f78240 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 23 Feb 2009 23:01:28 +1100 Subject: [PATCH 0084/6080] perfcounters/powerpc: Make exclude_kernel bit work on Apple G5 processors Currently, setting hw_event.exclude_kernel does nothing on the PPC970 variants used in Apple G5 machines, because they have the HV (hypervisor) bit in the MSR forced to 1, so as far as the PMU is concerned, the kernel runs in hypervisor mode. Thus we have to use the MMCR0_FCHV (freeze counters in hypervisor mode) bit rather than the MMCR0_FCS (freeze counters in supervisor mode) bit. This checks the MSR.HV bit at startup, and if it is set, we set the freeze_counters_kernel variable to MMCR0_FCHV (it was initialized to MMCR0_FCS). We then use that whenever we need to exclude kernel events. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/perf_counter.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index bd6ba85beb54..6e27913ec0d8 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -32,6 +32,15 @@ DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters); struct power_pmu *ppmu; +/* + * Normally, to ignore kernel events we set the FCS (freeze counters + * in supervisor mode) bit in MMCR0, but if the kernel runs with the + * hypervisor bit set in the MSR, or if we are running on a processor + * where the hypervisor bit is forced to 1 (as on Apple G5 processors), + * then we need to use the FCHV bit to ignore kernel events. + */ +static unsigned int freeze_counters_kernel = MMCR0_FCS; + void perf_counter_print_debug(void) { } @@ -364,7 +373,7 @@ void hw_perf_restore(u64 disable) if (counter->hw_event.exclude_user) cpuhw->mmcr[0] |= MMCR0_FCP; if (counter->hw_event.exclude_kernel) - cpuhw->mmcr[0] |= MMCR0_FCS; + cpuhw->mmcr[0] |= freeze_counters_kernel; if (counter->hw_event.exclude_hv) cpuhw->mmcr[0] |= MMCR0_FCHV; @@ -606,10 +615,7 @@ hw_perf_counter_init(struct perf_counter *counter) /* * If we are not running on a hypervisor, force the * exclude_hv bit to 0 so that we don't care what - * the user set it to. This also means that we don't - * set the MMCR0_FCHV bit, which unconditionally freezes - * the counters on the PPC970 variants used in Apple G5 - * machines (since MSR.HV is always 1 on those machines). + * the user set it to. */ if (!firmware_has_feature(FW_FEATURE_LPAR)) counter->hw_event.exclude_hv = 0; @@ -841,6 +847,13 @@ static int init_perf_counters(void) ppmu = &power6_pmu; break; } + + /* + * Use FCHV to ignore kernel events if MSR.HV is set. + */ + if (mfmsr() & MSR_HV) + freeze_counters_kernel = MMCR0_FCHV; + return 0; } -- GitLab From 742bd95ba96e19b3f7196c3a0834ebc17c8ba006 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 24 Feb 2009 11:33:56 +1100 Subject: [PATCH 0085/6080] perfcounters/powerpc: Add support for POWER5 processors This adds the back-end for the PMU on the POWER5 processor. This knows how to use the fixed-function PMC5 and PMC6 (instructions completed and run cycles). Unlike POWER6, PMC5/6 obey the freeze conditions and can generate interrupts, so their use doesn't impose any extra restrictions. POWER5+ is different and is not supported by this patch. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 3 +- arch/powerpc/kernel/perf_counter.c | 4 + arch/powerpc/kernel/power5-pmu.c | 475 +++++++++++++++++++++++++++++ 3 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/kernel/power5-pmu.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 7c941ec3b23e..b4c6f466164b 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -94,7 +94,8 @@ obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o -obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o ppc970-pmu.o power6-pmu.o +obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o ppc970-pmu.o power5-pmu.o \ + power6-pmu.o obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 6e27913ec0d8..112332d07fc2 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -824,6 +824,7 @@ void hw_perf_counter_setup(int cpu) } extern struct power_pmu ppc970_pmu; +extern struct power_pmu power5_pmu; extern struct power_pmu power6_pmu; static int init_perf_counters(void) @@ -843,6 +844,9 @@ static int init_perf_counters(void) case PV_970MP: ppmu = &ppc970_pmu; break; + case PV_POWER5: + ppmu = &power5_pmu; + break; case 0x3e: ppmu = &power6_pmu; break; diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c new file mode 100644 index 000000000000..379ed1087cca --- /dev/null +++ b/arch/powerpc/kernel/power5-pmu.c @@ -0,0 +1,475 @@ +/* + * Performance counter support for POWER5 (not POWER5++) processors. + * + * Copyright 2009 Paul Mackerras, IBM 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 the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include + +/* + * Bits in event code for POWER5 (not POWER5++) + */ +#define PM_PMC_SH 20 /* PMC number (1-based) for direct events */ +#define PM_PMC_MSK 0xf +#define PM_PMC_MSKS (PM_PMC_MSK << PM_PMC_SH) +#define PM_UNIT_SH 16 /* TTMMUX number and setting - unit select */ +#define PM_UNIT_MSK 0xf +#define PM_BYTE_SH 12 /* Byte number of event bus to use */ +#define PM_BYTE_MSK 7 +#define PM_GRS_SH 8 /* Storage subsystem mux select */ +#define PM_GRS_MSK 7 +#define PM_BUSEVENT_MSK 0x80 /* Set if event uses event bus */ +#define PM_PMCSEL_MSK 0x7f + +/* Values in PM_UNIT field */ +#define PM_FPU 0 +#define PM_ISU0 1 +#define PM_IFU 2 +#define PM_ISU1 3 +#define PM_IDU 4 +#define PM_ISU0_ALT 6 +#define PM_GRS 7 +#define PM_LSU0 8 +#define PM_LSU1 0xc +#define PM_LASTUNIT 0xc + +/* + * Bits in MMCR1 for POWER5 + */ +#define MMCR1_TTM0SEL_SH 62 +#define MMCR1_TTM1SEL_SH 60 +#define MMCR1_TTM2SEL_SH 58 +#define MMCR1_TTM3SEL_SH 56 +#define MMCR1_TTMSEL_MSK 3 +#define MMCR1_TD_CP_DBG0SEL_SH 54 +#define MMCR1_TD_CP_DBG1SEL_SH 52 +#define MMCR1_TD_CP_DBG2SEL_SH 50 +#define MMCR1_TD_CP_DBG3SEL_SH 48 +#define MMCR1_GRS_L2SEL_SH 46 +#define MMCR1_GRS_L2SEL_MSK 3 +#define MMCR1_GRS_L3SEL_SH 44 +#define MMCR1_GRS_L3SEL_MSK 3 +#define MMCR1_GRS_MCSEL_SH 41 +#define MMCR1_GRS_MCSEL_MSK 7 +#define MMCR1_GRS_FABSEL_SH 39 +#define MMCR1_GRS_FABSEL_MSK 3 +#define MMCR1_PMC1_ADDER_SEL_SH 35 +#define MMCR1_PMC2_ADDER_SEL_SH 34 +#define MMCR1_PMC3_ADDER_SEL_SH 33 +#define MMCR1_PMC4_ADDER_SEL_SH 32 +#define MMCR1_PMC1SEL_SH 25 +#define MMCR1_PMC2SEL_SH 17 +#define MMCR1_PMC3SEL_SH 9 +#define MMCR1_PMC4SEL_SH 1 +#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8) +#define MMCR1_PMCSEL_MSK 0x7f + +/* + * Bits in MMCRA + */ + +/* + * Layout of constraint bits: + * 6666555555555544444444443333333333222222222211111111110000000000 + * 3210987654321098765432109876543210987654321098765432109876543210 + * <><>[ ><><>< ><> [ >[ >[ >< >< >< >< ><><><><><><> + * T0T1 NC G0G1G2 G3 UC PS1PS2 B0 B1 B2 B3 P6P5P4P3P2P1 + * + * T0 - TTM0 constraint + * 54-55: TTM0SEL value (0=FPU, 2=IFU, 3=ISU1) 0xc0_0000_0000_0000 + * + * T1 - TTM1 constraint + * 52-53: TTM1SEL value (0=IDU, 3=GRS) 0x30_0000_0000_0000 + * + * NC - number of counters + * 51: NC error 0x0008_0000_0000_0000 + * 48-50: number of events needing PMC1-4 0x0007_0000_0000_0000 + * + * G0..G3 - GRS mux constraints + * 46-47: GRS_L2SEL value + * 44-45: GRS_L3SEL value + * 41-44: GRS_MCSEL value + * 39-40: GRS_FABSEL value + * Note that these match up with their bit positions in MMCR1 + * + * UC - unit constraint: can't have all three of FPU|IFU|ISU1, ISU0, IDU|GRS + * 37: UC3 error 0x20_0000_0000 + * 36: FPU|IFU|ISU1 events needed 0x10_0000_0000 + * 35: ISU0 events needed 0x08_0000_0000 + * 34: IDU|GRS events needed 0x04_0000_0000 + * + * PS1 + * 33: PS1 error 0x2_0000_0000 + * 31-32: count of events needing PMC1/2 0x1_8000_0000 + * + * PS2 + * 30: PS2 error 0x4000_0000 + * 28-29: count of events needing PMC3/4 0x3000_0000 + * + * B0 + * 24-27: Byte 0 event source 0x0f00_0000 + * Encoding as for the event code + * + * B1, B2, B3 + * 20-23, 16-19, 12-15: Byte 1, 2, 3 event sources + * + * P1..P6 + * 0-11: Count of events needing PMC1..PMC6 + */ + +static const int grsel_shift[8] = { + MMCR1_GRS_L2SEL_SH, MMCR1_GRS_L2SEL_SH, MMCR1_GRS_L2SEL_SH, + MMCR1_GRS_L3SEL_SH, MMCR1_GRS_L3SEL_SH, MMCR1_GRS_L3SEL_SH, + MMCR1_GRS_MCSEL_SH, MMCR1_GRS_FABSEL_SH +}; + +/* Masks and values for using events from the various units */ +static u64 unit_cons[PM_LASTUNIT+1][2] = { + [PM_FPU] = { 0xc0002000000000ull, 0x00001000000000ull }, + [PM_ISU0] = { 0x00002000000000ull, 0x00000800000000ull }, + [PM_ISU1] = { 0xc0002000000000ull, 0xc0001000000000ull }, + [PM_IFU] = { 0xc0002000000000ull, 0x80001000000000ull }, + [PM_IDU] = { 0x30002000000000ull, 0x00000400000000ull }, + [PM_GRS] = { 0x30002000000000ull, 0x30000400000000ull }, +}; + +static int power5_get_constraint(unsigned int event, u64 *maskp, u64 *valp) +{ + int pmc, byte, unit, sh; + int bit, fmask; + u64 mask = 0, value = 0; + int grp = -1; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc > 6) + return -1; + sh = (pmc - 1) * 2; + mask |= 2 << sh; + value |= 1 << sh; + if (pmc <= 4) + grp = (pmc - 1) >> 1; + else if (event != 0x500009 && event != 0x600005) + return -1; + } + if (event & PM_BUSEVENT_MSK) { + unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; + if (unit > PM_LASTUNIT) + return -1; + if (unit == PM_ISU0_ALT) + unit = PM_ISU0; + mask |= unit_cons[unit][0]; + value |= unit_cons[unit][1]; + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + if (byte >= 4) { + if (unit != PM_LSU1) + return -1; + /* Map LSU1 low word (bytes 4-7) to unit LSU1+1 */ + ++unit; + byte &= 3; + } + if (unit == PM_GRS) { + bit = event & 7; + fmask = (bit == 6)? 7: 3; + sh = grsel_shift[bit]; + mask |= (u64)fmask << sh; + value |= (u64)((event >> PM_GRS_SH) & fmask) << sh; + } + /* + * Bus events on bytes 0 and 2 can be counted + * on PMC1/2; bytes 1 and 3 on PMC3/4. + */ + if (!pmc) + grp = byte & 1; + /* Set byte lane select field */ + mask |= 0xfULL << (24 - 4 * byte); + value |= (u64)unit << (24 - 4 * byte); + } + if (grp == 0) { + /* increment PMC1/2 field */ + mask |= 0x200000000ull; + value |= 0x080000000ull; + } else if (grp == 1) { + /* increment PMC3/4 field */ + mask |= 0x40000000ull; + value |= 0x10000000ull; + } + if (pmc < 5) { + /* need a counter from PMC1-4 set */ + mask |= 0x8000000000000ull; + value |= 0x1000000000000ull; + } + *maskp = mask; + *valp = value; + return 0; +} + +#define MAX_ALT 3 /* at most 3 alternatives for any event */ + +static const unsigned int event_alternatives[][MAX_ALT] = { + { 0x120e4, 0x400002 }, /* PM_GRP_DISP_REJECT */ + { 0x410c7, 0x441084 }, /* PM_THRD_L2MISS_BOTH_CYC */ + { 0x100005, 0x600005 }, /* PM_RUN_CYC */ + { 0x100009, 0x200009, 0x500009 }, /* PM_INST_CMPL */ + { 0x300009, 0x400009 }, /* PM_INST_DISP */ +}; + +/* + * Scan the alternatives table for a match and return the + * index into the alternatives table if found, else -1. + */ +static int find_alternative(unsigned int event) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(event_alternatives); ++i) { + if (event < event_alternatives[i][0]) + break; + for (j = 0; j < MAX_ALT && event_alternatives[i][j]; ++j) + if (event == event_alternatives[i][j]) + return i; + } + return -1; +} + +static const unsigned char bytedecode_alternatives[4][4] = { + /* PMC 1 */ { 0x21, 0x23, 0x25, 0x27 }, + /* PMC 2 */ { 0x07, 0x17, 0x0e, 0x1e }, + /* PMC 3 */ { 0x20, 0x22, 0x24, 0x26 }, + /* PMC 4 */ { 0x07, 0x17, 0x0e, 0x1e } +}; + +/* + * Some direct events for decodes of event bus byte 3 have alternative + * PMCSEL values on other counters. This returns the alternative + * event code for those that do, or -1 otherwise. + */ +static int find_alternative_bdecode(unsigned int event) +{ + int pmc, altpmc, pp, j; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc == 0 || pmc > 4) + return -1; + altpmc = 5 - pmc; /* 1 <-> 4, 2 <-> 3 */ + pp = event & PM_PMCSEL_MSK; + for (j = 0; j < 4; ++j) { + if (bytedecode_alternatives[pmc - 1][j] == pp) { + return (event & ~(PM_PMC_MSKS | PM_PMCSEL_MSK)) | + (altpmc << PM_PMC_SH) | + bytedecode_alternatives[altpmc - 1][j]; + } + } + return -1; +} + +static int power5_get_alternatives(unsigned int event, unsigned int alt[]) +{ + int i, j, ae, nalt = 1; + + alt[0] = event; + nalt = 1; + i = find_alternative(event); + if (i >= 0) { + for (j = 0; j < MAX_ALT; ++j) { + ae = event_alternatives[i][j]; + if (ae && ae != event) + alt[nalt++] = ae; + } + } else { + ae = find_alternative_bdecode(event); + if (ae > 0) + alt[nalt++] = ae; + } + return nalt; +} + +static int power5_compute_mmcr(unsigned int event[], int n_ev, + unsigned int hwc[], u64 mmcr[]) +{ + u64 mmcr1 = 0; + unsigned int pmc, unit, byte, psel; + unsigned int ttm, grp; + int i, isbus, bit, grsel; + unsigned int pmc_inuse = 0; + unsigned int pmc_grp_use[2]; + unsigned char busbyte[4]; + unsigned char unituse[16]; + int ttmuse; + + if (n_ev > 6) + return -1; + + /* First pass to count resource use */ + pmc_grp_use[0] = pmc_grp_use[1] = 0; + memset(busbyte, 0, sizeof(busbyte)); + memset(unituse, 0, sizeof(unituse)); + for (i = 0; i < n_ev; ++i) { + pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc > 6) + return -1; + if (pmc_inuse & (1 << (pmc - 1))) + return -1; + pmc_inuse |= 1 << (pmc - 1); + /* count 1/2 vs 3/4 use */ + if (pmc <= 4) + ++pmc_grp_use[(pmc - 1) >> 1]; + } + if (event[i] & PM_BUSEVENT_MSK) { + unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK; + byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK; + if (unit > PM_LASTUNIT) + return -1; + if (unit == PM_ISU0_ALT) + unit = PM_ISU0; + if (byte >= 4) { + if (unit != PM_LSU1) + return -1; + ++unit; + byte &= 3; + } + if (!pmc) + ++pmc_grp_use[byte & 1]; + if (busbyte[byte] && busbyte[byte] != unit) + return -1; + busbyte[byte] = unit; + unituse[unit] = 1; + } + } + if (pmc_grp_use[0] > 2 || pmc_grp_use[1] > 2) + return -1; + + /* + * Assign resources and set multiplexer selects. + * + * PM_ISU0 can go either on TTM0 or TTM1, but that's the only + * choice we have to deal with. + */ + if (unituse[PM_ISU0] & + (unituse[PM_FPU] | unituse[PM_IFU] | unituse[PM_ISU1])) { + unituse[PM_ISU0_ALT] = 1; /* move ISU to TTM1 */ + unituse[PM_ISU0] = 0; + } + /* Set TTM[01]SEL fields. */ + ttmuse = 0; + for (i = PM_FPU; i <= PM_ISU1; ++i) { + if (!unituse[i]) + continue; + if (ttmuse++) + return -1; + mmcr1 |= (u64)i << MMCR1_TTM0SEL_SH; + } + ttmuse = 0; + for (; i <= PM_GRS; ++i) { + if (!unituse[i]) + continue; + if (ttmuse++) + return -1; + mmcr1 |= (u64)(i & 3) << MMCR1_TTM1SEL_SH; + } + if (ttmuse > 1) + return -1; + + /* Set byte lane select fields, TTM[23]SEL and GRS_*SEL. */ + for (byte = 0; byte < 4; ++byte) { + unit = busbyte[byte]; + if (!unit) + continue; + if (unit == PM_ISU0 && unituse[PM_ISU0_ALT]) { + /* get ISU0 through TTM1 rather than TTM0 */ + unit = PM_ISU0_ALT; + } else if (unit == PM_LSU1 + 1) { + /* select lower word of LSU1 for this byte */ + mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte); + } + ttm = unit >> 2; + mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte); + } + + /* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */ + for (i = 0; i < n_ev; ++i) { + pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; + unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK; + byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK; + psel = event[i] & PM_PMCSEL_MSK; + isbus = event[i] & PM_BUSEVENT_MSK; + if (!pmc) { + /* Bus event or any-PMC direct event */ + for (pmc = 0; pmc < 4; ++pmc) { + if (pmc_inuse & (1 << pmc)) + continue; + grp = (pmc >> 1) & 1; + if (isbus) { + if (grp == (byte & 1)) + break; + } else if (pmc_grp_use[grp] < 2) { + ++pmc_grp_use[grp]; + break; + } + } + pmc_inuse |= 1 << pmc; + } else if (pmc <= 4) { + /* Direct event */ + --pmc; + if ((psel == 8 || psel == 0x10) && isbus && (byte & 2)) + /* add events on higher-numbered bus */ + mmcr1 |= 1ull << (MMCR1_PMC1_ADDER_SEL_SH - pmc); + } else { + /* Instructions or run cycles on PMC5/6 */ + --pmc; + } + if (isbus && unit == PM_GRS) { + bit = psel & 7; + grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK; + mmcr1 |= (u64)grsel << grsel_shift[bit]; + } + if (pmc <= 3) + mmcr1 |= psel << MMCR1_PMCSEL_SH(pmc); + hwc[i] = pmc; + } + + /* Return MMCRx values */ + mmcr[0] = 0; + if (pmc_inuse & 1) + mmcr[0] = MMCR0_PMC1CE; + if (pmc_inuse & 0x3e) + mmcr[0] |= MMCR0_PMCjCE; + mmcr[1] = mmcr1; + mmcr[2] = 0; + return 0; +} + +static void power5_disable_pmc(unsigned int pmc, u64 mmcr[]) +{ + if (pmc <= 3) + mmcr[1] &= ~(0x7fUL << MMCR1_PMCSEL_SH(pmc)); +} + +static int power5_generic_events[] = { + [PERF_COUNT_CPU_CYCLES] = 0xf, + [PERF_COUNT_INSTRUCTIONS] = 0x100009, + [PERF_COUNT_CACHE_REFERENCES] = 0x4c1090, /* LD_REF_L1 */ + [PERF_COUNT_CACHE_MISSES] = 0x3c1088, /* LD_MISS_L1 */ + [PERF_COUNT_BRANCH_INSTRUCTIONS] = 0x230e4, /* BR_ISSUED */ + [PERF_COUNT_BRANCH_MISSES] = 0x230e5, /* BR_MPRED_CR */ +}; + +struct power_pmu power5_pmu = { + .n_counter = 6, + .max_alternatives = MAX_ALT, + .add_fields = 0x7000090000555ull, + .test_adder = 0x3000490000000ull, + .compute_mmcr = power5_compute_mmcr, + .get_constraint = power5_get_constraint, + .get_alternatives = power5_get_alternatives, + .disable_pmc = power5_disable_pmc, + .n_generic = ARRAY_SIZE(power5_generic_events), + .generic_events = power5_generic_events, +}; -- GitLab From f3dfd2656deb81a0addee4f4ceff66b50a387388 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 26 Feb 2009 22:43:46 +1100 Subject: [PATCH 0086/6080] perfcounters: fix a few minor cleanliness issues This fixes three issues noticed by Arnd Bergmann: - Add #ifdef __KERNEL__ and move some things around in perf_counter.h to make sure only the bits that userspace needs are exported to userspace. - Use __u64, __s64, __u32 types in the structs exported to userspace rather than u64, s64, u32. - Make the sys_perf_counter_open syscall available to the SPUs on Cell platforms. And one issue that I noticed in looking at the code again: - Wrap the perf_counter_open syscall with SYSCALL_DEFINE4 so we get the proper handling of int arguments on ppc64 (and some other 64-bit architectures). Reported-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/include/asm/systbl.h | 2 +- include/linux/perf_counter.h | 43 +++++++++++++++++-------------- include/linux/syscalls.h | 9 +++---- kernel/perf_counter.c | 6 ++--- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 4c8095f6bec0..d312eec8abb9 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -322,4 +322,4 @@ SYSCALL_SPU(epoll_create1) SYSCALL_SPU(dup3) SYSCALL_SPU(pipe2) SYSCALL(inotify_init1) -SYSCALL(perf_counter_open) +SYSCALL_SPU(perf_counter_open) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 32cd1acb7386..186efaf49665 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -13,20 +13,8 @@ #ifndef _LINUX_PERF_COUNTER_H #define _LINUX_PERF_COUNTER_H -#include -#include - -#ifdef CONFIG_PERF_COUNTERS -# include -#endif - -#include -#include -#include -#include -#include - -struct task_struct; +#include +#include /* * User-space ABI bits: @@ -78,12 +66,12 @@ enum perf_counter_record_type { * Hardware event to monitor via a performance monitoring counter: */ struct perf_counter_hw_event { - s64 type; + __s64 type; - u64 irq_period; - u32 record_type; + __u64 irq_period; + __u32 record_type; - u32 disabled : 1, /* off by default */ + __u32 disabled : 1, /* off by default */ nmi : 1, /* NMI sampling */ raw : 1, /* raw event type */ inherit : 1, /* children inherit it */ @@ -95,7 +83,7 @@ struct perf_counter_hw_event { __reserved_1 : 23; - u64 __reserved_2; + __u64 __reserved_2; }; /* @@ -104,10 +92,24 @@ struct perf_counter_hw_event { #define PERF_COUNTER_IOC_ENABLE _IO('$', 0) #define PERF_COUNTER_IOC_DISABLE _IO('$', 1) +#ifdef __KERNEL__ /* - * Kernel-internal data types: + * Kernel-internal data types and definitions: */ +#ifdef CONFIG_PERF_COUNTERS +# include +#endif + +#include +#include +#include +#include +#include +#include + +struct task_struct; + /** * struct hw_perf_counter - performance counter hardware details: */ @@ -293,4 +295,5 @@ static inline int perf_counter_task_disable(void) { return -EINVAL; } static inline int perf_counter_task_enable(void) { return -EINVAL; } #endif +#endif /* __KERNEL__ */ #endif /* _LINUX_PERF_COUNTER_H */ diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 88255d3261a4..28ef2be839c7 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -696,10 +696,7 @@ asmlinkage long sys_pipe(int __user *); int kernel_execve(const char *filename, char *const argv[], char *const envp[]); -asmlinkage int sys_perf_counter_open( - - struct perf_counter_hw_event *hw_event_uptr __user, - pid_t pid, - int cpu, - int group_fd); +asmlinkage long sys_perf_counter_open( + const struct perf_counter_hw_event __user *hw_event_uptr, + pid_t pid, int cpu, int group_fd); #endif diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index ad62965828d3..16b14ba99d34 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1690,9 +1690,9 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, * @cpu: target cpu * @group_fd: group leader counter fd */ -asmlinkage int -sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr __user, - pid_t pid, int cpu, int group_fd) +SYSCALL_DEFINE4(perf_counter_open, + const struct perf_counter_hw_event __user *, hw_event_uptr, + pid_t, pid, int, cpu, int, group_fd) { struct perf_counter *counter, *group_leader; struct perf_counter_hw_event hw_event; -- GitLab From b56a3802dc6df29aa27d2c12edf420258091ad66 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Fri, 27 Feb 2009 18:09:09 +0530 Subject: [PATCH 0087/6080] x86: prepare perf_counter to add more cpus Introduced struct pmc_x86_ops to add more cpus. Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 106 +++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 28 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 383d4c6423a1..a3c88529bb72 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -3,6 +3,7 @@ * * Copyright(C) 2008 Thomas Gleixner * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar + * Copyright(C) 2009 Jaswinder Singh Rajput * * For licencing details see kernel-base/COPYING */ @@ -38,10 +39,24 @@ struct cpu_hw_counters { }; /* - * Intel PerfMon v3. Used on Core2 and later. + * struct pmc_x86_ops - performance counter x86 ops */ +struct pmc_x86_ops { + u64 (*save_disable_all) (void); + void (*restore_all) (u64 ctrl); + unsigned eventsel; + unsigned perfctr; + int (*event_map) (int event); + int max_events; +}; + +static struct pmc_x86_ops *pmc_ops; + static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters); +/* + * Intel PerfMon v3. Used on Core2 and later. + */ static const int intel_perfmon_event_map[] = { [PERF_COUNT_CPU_CYCLES] = 0x003c, @@ -53,7 +68,10 @@ static const int intel_perfmon_event_map[] = [PERF_COUNT_BUS_CYCLES] = 0x013c, }; -static const int max_intel_perfmon_events = ARRAY_SIZE(intel_perfmon_event_map); +static int pmc_intel_event_map(int event) +{ + return intel_perfmon_event_map[event]; +} /* * Propagate counter elapsed time into the generic counter. @@ -144,38 +162,48 @@ static int __hw_perf_counter_init(struct perf_counter *counter) if (hw_event->raw) { hwc->config |= hw_event->type; } else { - if (hw_event->type >= max_intel_perfmon_events) + if (hw_event->type >= pmc_ops->max_events) return -EINVAL; /* * The generic map: */ - hwc->config |= intel_perfmon_event_map[hw_event->type]; + hwc->config |= pmc_ops->event_map(hw_event->type); } counter->wakeup_pending = 0; return 0; } -u64 hw_perf_save_disable(void) +static u64 pmc_intel_save_disable_all(void) { u64 ctrl; - if (unlikely(!perf_counters_initialized)) - return 0; - rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); return ctrl; } + +u64 hw_perf_save_disable(void) +{ + if (unlikely(!perf_counters_initialized)) + return 0; + + return pmc_ops->save_disable_all(); +} EXPORT_SYMBOL_GPL(hw_perf_save_disable); +static void pmc_intel_restore_all(u64 ctrl) +{ + wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); +} + void hw_perf_restore(u64 ctrl) { if (unlikely(!perf_counters_initialized)) return; - wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); + pmc_ops->restore_all(ctrl); } EXPORT_SYMBOL_GPL(hw_perf_restore); @@ -291,11 +319,11 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) event = hwc->config & ARCH_PERFMON_EVENT_MASK; - if (unlikely(event == intel_perfmon_event_map[PERF_COUNT_INSTRUCTIONS])) + if (unlikely(event == pmc_ops->event_map(PERF_COUNT_INSTRUCTIONS))) return X86_PMC_IDX_FIXED_INSTRUCTIONS; - if (unlikely(event == intel_perfmon_event_map[PERF_COUNT_CPU_CYCLES])) + if (unlikely(event == pmc_ops->event_map(PERF_COUNT_CPU_CYCLES))) return X86_PMC_IDX_FIXED_CPU_CYCLES; - if (unlikely(event == intel_perfmon_event_map[PERF_COUNT_BUS_CYCLES])) + if (unlikely(event == pmc_ops->event_map(PERF_COUNT_BUS_CYCLES))) return X86_PMC_IDX_FIXED_BUS_CYCLES; return -1; @@ -339,8 +367,8 @@ try_generic: set_bit(idx, cpuc->used); hwc->idx = idx; } - hwc->config_base = MSR_ARCH_PERFMON_EVENTSEL0; - hwc->counter_base = MSR_ARCH_PERFMON_PERFCTR0; + hwc->config_base = pmc_ops->eventsel; + hwc->counter_base = pmc_ops->perfctr; } perf_counters_lapic_init(hwc->nmi); @@ -386,8 +414,8 @@ void perf_counter_print_debug(void) printk(KERN_INFO "CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); for (idx = 0; idx < nr_counters_generic; idx++) { - rdmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, pmc_ctrl); - rdmsrl(MSR_ARCH_PERFMON_PERFCTR0 + idx, pmc_count); + rdmsrl(pmc_ops->eventsel + idx, pmc_ctrl); + rdmsrl(pmc_ops->perfctr + idx, pmc_count); prev_left = per_cpu(prev_left[idx], cpu); @@ -655,29 +683,56 @@ static __read_mostly struct notifier_block perf_counter_nmi_notifier = { .priority = 1 }; -void __init init_hw_perf_counters(void) +static struct pmc_x86_ops pmc_intel_ops = { + .save_disable_all = pmc_intel_save_disable_all, + .restore_all = pmc_intel_restore_all, + .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, + .perfctr = MSR_ARCH_PERFMON_PERFCTR0, + .event_map = pmc_intel_event_map, + .max_events = ARRAY_SIZE(intel_perfmon_event_map), +}; + +static struct pmc_x86_ops *pmc_intel_init(void) { union cpuid10_eax eax; unsigned int ebx; unsigned int unused; union cpuid10_edx edx; - if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return; - /* * Check whether the Architectural PerfMon supports * Branch Misses Retired Event or not. */ cpuid(10, &eax.full, &ebx, &unused, &edx.full); if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED) - return; + return NULL; printk(KERN_INFO "Intel Performance Monitoring support detected.\n"); - printk(KERN_INFO "... version: %d\n", eax.split.version_id); - printk(KERN_INFO "... num counters: %d\n", eax.split.num_counters); + printk(KERN_INFO "... bit width: %d\n", eax.split.bit_width); + printk(KERN_INFO "... mask length: %d\n", eax.split.mask_length); + nr_counters_generic = eax.split.num_counters; + nr_counters_fixed = edx.split.num_counters_fixed; + counter_value_mask = (1ULL << eax.split.bit_width) - 1; + + return &pmc_intel_ops; +} + +void __init init_hw_perf_counters(void) +{ + if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return; + + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_INTEL: + pmc_ops = pmc_intel_init(); + break; + } + if (!pmc_ops) + return; + + printk(KERN_INFO "... num counters: %d\n", nr_counters_generic); if (nr_counters_generic > X86_PMC_MAX_GENERIC) { nr_counters_generic = X86_PMC_MAX_GENERIC; WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", @@ -686,13 +741,8 @@ void __init init_hw_perf_counters(void) perf_counter_mask = (1 << nr_counters_generic) - 1; perf_max_counters = nr_counters_generic; - printk(KERN_INFO "... bit width: %d\n", eax.split.bit_width); - counter_value_mask = (1ULL << eax.split.bit_width) - 1; printk(KERN_INFO "... value mask: %016Lx\n", counter_value_mask); - printk(KERN_INFO "... mask length: %d\n", eax.split.mask_length); - - nr_counters_fixed = edx.split.num_counters_fixed; if (nr_counters_fixed > X86_PMC_MAX_FIXED) { nr_counters_fixed = X86_PMC_MAX_FIXED; WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!", -- GitLab From f87ad35d37fa543925210550f7db20a54c83ed70 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Fri, 27 Feb 2009 20:15:14 +0530 Subject: [PATCH 0088/6080] x86: AMD Support for perf_counter Supported basic performance counter for AMD K7 and later: $ perfstat -e 0,1,2,3,4,5,-1,-2,-3,-4,-5 ls > /dev/null Performance counter stats for 'ls': 12.298610 task clock ticks (msecs) 3298477 CPU cycles (events) 1406354 instructions (events) 749035 cache references (events) 16939 cache misses (events) 100589 branches (events) 11159 branch misses (events) 7.627540 cpu clock ticks (msecs) 12.298610 task clock ticks (msecs) 500 pagefaults (events) 6 context switches (events) 3 CPU migrations (events) Wall-clock time elapsed: 8.672290 msecs Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/amd.c | 4 ++ arch/x86/kernel/cpu/perf_counter.c | 83 +++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 25423a5b80ed..edcde52bd170 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -368,6 +368,10 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) if (c->x86 >= 6) set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK); + /* Enable Performance counter for K7 and later */ + if (c->x86 > 6 && c->x86 <= 0x11) + set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); + if (!c->x86_model_id[0]) { switch (c->x86) { case 0xf: diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index a3c88529bb72..266618aa1a03 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -73,6 +73,24 @@ static int pmc_intel_event_map(int event) return intel_perfmon_event_map[event]; } +/* + * AMD Performance Monitor K7 and later. + */ +static const int amd_perfmon_event_map[] = +{ + [PERF_COUNT_CPU_CYCLES] = 0x0076, + [PERF_COUNT_INSTRUCTIONS] = 0x00c0, + [PERF_COUNT_CACHE_REFERENCES] = 0x0080, + [PERF_COUNT_CACHE_MISSES] = 0x0081, + [PERF_COUNT_BRANCH_INSTRUCTIONS] = 0x00c4, + [PERF_COUNT_BRANCH_MISSES] = 0x00c5, +}; + +static int pmc_amd_event_map(int event) +{ + return amd_perfmon_event_map[event]; +} + /* * Propagate counter elapsed time into the generic counter. * Can only be executed on the CPU where the counter is active. @@ -151,8 +169,9 @@ static int __hw_perf_counter_init(struct perf_counter *counter) * so we install an artificial 1<<31 period regardless of * the generic counter period: */ - if ((s64)hwc->irq_period <= 0 || hwc->irq_period > 0x7FFFFFFF) - hwc->irq_period = 0x7FFFFFFF; + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) + if ((s64)hwc->irq_period <= 0 || hwc->irq_period > 0x7FFFFFFF) + hwc->irq_period = 0x7FFFFFFF; atomic64_set(&hwc->period_left, hwc->irq_period); @@ -184,6 +203,22 @@ static u64 pmc_intel_save_disable_all(void) return ctrl; } +static u64 pmc_amd_save_disable_all(void) +{ + int idx; + u64 val, ctrl = 0; + + for (idx = 0; idx < nr_counters_generic; idx++) { + rdmsrl(MSR_K7_EVNTSEL0 + idx, val); + if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) + ctrl |= (1 << idx); + val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsrl(MSR_K7_EVNTSEL0 + idx, val); + } + + return ctrl; +} + u64 hw_perf_save_disable(void) { if (unlikely(!perf_counters_initialized)) @@ -198,6 +233,20 @@ static void pmc_intel_restore_all(u64 ctrl) wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); } +static void pmc_amd_restore_all(u64 ctrl) +{ + u64 val; + int idx; + + for (idx = 0; idx < nr_counters_generic; idx++) { + if (ctrl & (1 << idx)) { + rdmsrl(MSR_K7_EVNTSEL0 + idx, val); + val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsrl(MSR_K7_EVNTSEL0 + idx, val); + } + } +} + void hw_perf_restore(u64 ctrl) { if (unlikely(!perf_counters_initialized)) @@ -314,6 +363,9 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) { unsigned int event; + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) + return -1; + if (unlikely(hwc->nmi)) return -1; @@ -401,6 +453,7 @@ void perf_counter_print_debug(void) cpu = smp_processor_id(); cpuc = &per_cpu(cpu_hw_counters, cpu); + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow); @@ -411,6 +464,7 @@ void perf_counter_print_debug(void) printk(KERN_INFO "CPU#%d: status: %016llx\n", cpu, status); printk(KERN_INFO "CPU#%d: overflow: %016llx\n", cpu, overflow); printk(KERN_INFO "CPU#%d: fixed: %016llx\n", cpu, fixed); + } printk(KERN_INFO "CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); for (idx = 0; idx < nr_counters_generic; idx++) { @@ -588,6 +642,9 @@ void perf_counter_unthrottle(void) if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) return; + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) + return; + if (unlikely(!perf_counters_initialized)) return; @@ -692,6 +749,15 @@ static struct pmc_x86_ops pmc_intel_ops = { .max_events = ARRAY_SIZE(intel_perfmon_event_map), }; +static struct pmc_x86_ops pmc_amd_ops = { + .save_disable_all = pmc_amd_save_disable_all, + .restore_all = pmc_amd_restore_all, + .eventsel = MSR_K7_EVNTSEL0, + .perfctr = MSR_K7_PERFCTR0, + .event_map = pmc_amd_event_map, + .max_events = ARRAY_SIZE(amd_perfmon_event_map), +}; + static struct pmc_x86_ops *pmc_intel_init(void) { union cpuid10_eax eax; @@ -719,6 +785,16 @@ static struct pmc_x86_ops *pmc_intel_init(void) return &pmc_intel_ops; } +static struct pmc_x86_ops *pmc_amd_init(void) +{ + nr_counters_generic = 4; + nr_counters_fixed = 0; + + printk(KERN_INFO "AMD Performance Monitoring support detected.\n"); + + return &pmc_amd_ops; +} + void __init init_hw_perf_counters(void) { if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) @@ -728,6 +804,9 @@ void __init init_hw_perf_counters(void) case X86_VENDOR_INTEL: pmc_ops = pmc_intel_init(); break; + case X86_VENDOR_AMD: + pmc_ops = pmc_amd_init(); + break; } if (!pmc_ops) return; -- GitLab From 169e41eb7f5464c077a7e0e129f025759d04cc54 Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sat, 28 Feb 2009 18:37:49 +0530 Subject: [PATCH 0089/6080] x86: decent declarations in perf_counter.c Impact: cleanup making decent declrations for struct pmc_x86_ops and fix checkpatch error: ERROR: Macros with complex values should be enclosed in parenthesis Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 266618aa1a03..a1f3646a3e8e 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -42,12 +42,12 @@ struct cpu_hw_counters { * struct pmc_x86_ops - performance counter x86 ops */ struct pmc_x86_ops { - u64 (*save_disable_all) (void); - void (*restore_all) (u64 ctrl); - unsigned eventsel; - unsigned perfctr; - int (*event_map) (int event); - int max_events; + u64 (*save_disable_all)(void); + void (*restore_all)(u64 ctrl); + unsigned eventsel; + unsigned perfctr; + int (*event_map)(int event); + int max_events; }; static struct pmc_x86_ops *pmc_ops; @@ -561,7 +561,7 @@ perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) /* * Maximum interrupt frequency of 100KHz per CPU */ -#define PERFMON_MAX_INTERRUPTS 100000/HZ +#define PERFMON_MAX_INTERRUPTS (100000/HZ) /* * This handler is triggered by the local APIC, so the APIC IRQ handling -- GitLab From a1ef58f442542d8b3e3b963339fbc522c36e827c Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sat, 28 Feb 2009 18:45:39 +0530 Subject: [PATCH 0090/6080] x86: use pr_info in perf_counter.c Impact: cleanup using pr_info in perf_counter.c fixes various 80 characters warnings and also indenting for conditional statement Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index a1f3646a3e8e..3b65f19a6681 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -454,18 +454,18 @@ void perf_counter_print_debug(void) cpuc = &per_cpu(cpu_hw_counters, cpu); if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { - rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); - rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); - rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow); - rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed); - - printk(KERN_INFO "\n"); - printk(KERN_INFO "CPU#%d: ctrl: %016llx\n", cpu, ctrl); - printk(KERN_INFO "CPU#%d: status: %016llx\n", cpu, status); - printk(KERN_INFO "CPU#%d: overflow: %016llx\n", cpu, overflow); - printk(KERN_INFO "CPU#%d: fixed: %016llx\n", cpu, fixed); + rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); + rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); + rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow); + rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed); + + pr_info("\n"); + pr_info("CPU#%d: ctrl: %016llx\n", cpu, ctrl); + pr_info("CPU#%d: status: %016llx\n", cpu, status); + pr_info("CPU#%d: overflow: %016llx\n", cpu, overflow); + pr_info("CPU#%d: fixed: %016llx\n", cpu, fixed); } - printk(KERN_INFO "CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); + pr_info("CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); for (idx = 0; idx < nr_counters_generic; idx++) { rdmsrl(pmc_ops->eventsel + idx, pmc_ctrl); @@ -473,17 +473,17 @@ void perf_counter_print_debug(void) prev_left = per_cpu(prev_left[idx], cpu); - printk(KERN_INFO "CPU#%d: gen-PMC%d ctrl: %016llx\n", + pr_info("CPU#%d: gen-PMC%d ctrl: %016llx\n", cpu, idx, pmc_ctrl); - printk(KERN_INFO "CPU#%d: gen-PMC%d count: %016llx\n", + pr_info("CPU#%d: gen-PMC%d count: %016llx\n", cpu, idx, pmc_count); - printk(KERN_INFO "CPU#%d: gen-PMC%d left: %016llx\n", + pr_info("CPU#%d: gen-PMC%d left: %016llx\n", cpu, idx, prev_left); } for (idx = 0; idx < nr_counters_fixed; idx++) { rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count); - printk(KERN_INFO "CPU#%d: fixed-PMC%d count: %016llx\n", + pr_info("CPU#%d: fixed-PMC%d count: %016llx\n", cpu, idx, pmc_count); } local_irq_enable(); @@ -773,10 +773,10 @@ static struct pmc_x86_ops *pmc_intel_init(void) if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED) return NULL; - printk(KERN_INFO "Intel Performance Monitoring support detected.\n"); - printk(KERN_INFO "... version: %d\n", eax.split.version_id); - printk(KERN_INFO "... bit width: %d\n", eax.split.bit_width); - printk(KERN_INFO "... mask length: %d\n", eax.split.mask_length); + pr_info("Intel Performance Monitoring support detected.\n"); + pr_info("... version: %d\n", eax.split.version_id); + pr_info("... bit width: %d\n", eax.split.bit_width); + pr_info("... mask length: %d\n", eax.split.mask_length); nr_counters_generic = eax.split.num_counters; nr_counters_fixed = edx.split.num_counters_fixed; @@ -790,7 +790,7 @@ static struct pmc_x86_ops *pmc_amd_init(void) nr_counters_generic = 4; nr_counters_fixed = 0; - printk(KERN_INFO "AMD Performance Monitoring support detected.\n"); + pr_info("AMD Performance Monitoring support detected.\n"); return &pmc_amd_ops; } @@ -811,7 +811,7 @@ void __init init_hw_perf_counters(void) if (!pmc_ops) return; - printk(KERN_INFO "... num counters: %d\n", nr_counters_generic); + pr_info("... num counters: %d\n", nr_counters_generic); if (nr_counters_generic > X86_PMC_MAX_GENERIC) { nr_counters_generic = X86_PMC_MAX_GENERIC; WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", @@ -820,18 +820,18 @@ void __init init_hw_perf_counters(void) perf_counter_mask = (1 << nr_counters_generic) - 1; perf_max_counters = nr_counters_generic; - printk(KERN_INFO "... value mask: %016Lx\n", counter_value_mask); + pr_info("... value mask: %016Lx\n", counter_value_mask); if (nr_counters_fixed > X86_PMC_MAX_FIXED) { nr_counters_fixed = X86_PMC_MAX_FIXED; WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!", nr_counters_fixed, X86_PMC_MAX_FIXED); } - printk(KERN_INFO "... fixed counters: %d\n", nr_counters_fixed); + pr_info("... fixed counters: %d\n", nr_counters_fixed); perf_counter_mask |= ((1LL << nr_counters_fixed)-1) << X86_PMC_IDX_FIXED; - printk(KERN_INFO "... counter mask: %016Lx\n", perf_counter_mask); + pr_info("... counter mask: %016Lx\n", perf_counter_mask); perf_counters_initialized = true; perf_counters_lapic_init(0); -- GitLab From 2743a5b0fa6f309da904f2190a9cc25deee34dbd Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 4 Mar 2009 20:36:51 +1100 Subject: [PATCH 0091/6080] perfcounters: provide expansion room in the ABI Impact: ABI change This expands several fields in the perf_counter_hw_event struct and adds a "flags" argument to the perf_counter_open system call, in order that features can be added in future without ABI changes. In particular the record_type field is expanded to 64 bits, and the space for flag bits has been expanded from 32 to 64 bits. This also adds some new fields: * read_format (64 bits) is intended to provide a way to specify what userspace wants to get back when it does a read() on a simple (non-interrupting) counter; * exclude_idle (1 bit) provides a way for userspace to ask that events that occur when the cpu is idle be excluded; * extra_config_len will provide a way for userspace to supply an arbitrary amount of extra machine-specific PMU configuration data immediately following the perf_counter_hw_event struct, to allow sophisticated users to program things such as instruction matching CAMs and address range registers; * __reserved_3 and __reserved_4 provide space for future expansion. Signed-off-by: Paul Mackerras --- include/linux/perf_counter.h | 12 +++++++++--- include/linux/syscalls.h | 2 +- kernel/perf_counter.c | 10 +++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 186efaf49665..c42455ab1558 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -69,9 +69,10 @@ struct perf_counter_hw_event { __s64 type; __u64 irq_period; - __u32 record_type; + __u64 record_type; + __u64 read_format; - __u32 disabled : 1, /* off by default */ + __u64 disabled : 1, /* off by default */ nmi : 1, /* NMI sampling */ raw : 1, /* raw event type */ inherit : 1, /* children inherit it */ @@ -80,10 +81,15 @@ struct perf_counter_hw_event { exclude_user : 1, /* don't count user */ exclude_kernel : 1, /* ditto kernel */ exclude_hv : 1, /* ditto hypervisor */ + exclude_idle : 1, /* don't count when idle */ - __reserved_1 : 23; + __reserved_1 : 55; + + __u32 extra_config_len; + __u32 __reserved_4; __u64 __reserved_2; + __u64 __reserved_3; }; /* diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 28ef2be839c7..ab1d77247395 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -698,5 +698,5 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]); asmlinkage long sys_perf_counter_open( const struct perf_counter_hw_event __user *hw_event_uptr, - pid_t pid, int cpu, int group_fd); + pid_t pid, int cpu, int group_fd, unsigned long flags); #endif diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 16b14ba99d34..b2e838959f3e 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1683,16 +1683,16 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, } /** - * sys_perf_task_open - open a performance counter, associate it to a task/cpu + * sys_perf_counter_open - open a performance counter, associate it to a task/cpu * * @hw_event_uptr: event type attributes for monitoring/sampling * @pid: target pid * @cpu: target cpu * @group_fd: group leader counter fd */ -SYSCALL_DEFINE4(perf_counter_open, +SYSCALL_DEFINE5(perf_counter_open, const struct perf_counter_hw_event __user *, hw_event_uptr, - pid_t, pid, int, cpu, int, group_fd) + pid_t, pid, int, cpu, int, group_fd, unsigned long, flags) { struct perf_counter *counter, *group_leader; struct perf_counter_hw_event hw_event; @@ -1703,6 +1703,10 @@ SYSCALL_DEFINE4(perf_counter_open, int fput_needed2 = 0; int ret; + /* for future expandability... */ + if (flags) + return -EINVAL; + if (copy_from_user(&hw_event, hw_event_uptr, sizeof(hw_event)) != 0) return -EFAULT; -- GitLab From 2485e5184452ccbda34ff83883883d9107800dff Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 5 Mar 2009 12:33:16 +0100 Subject: [PATCH 0092/6080] perfcounters: fix reserved bits sizing The sum of bits is 65 currently not 64 - so reduce the # of reserved bits from 55 to 54. Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index c42455ab1558..dde564517b66 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -83,7 +83,7 @@ struct perf_counter_hw_event { exclude_hv : 1, /* ditto hypervisor */ exclude_idle : 1, /* don't count when idle */ - __reserved_1 : 55; + __reserved_1 : 54; __u32 extra_config_len; __u32 __reserved_4; -- GitLab From b0f3f28e0f14eb335f67bfaae33ce8b8d74fd58b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 5 Mar 2009 18:08:27 +0100 Subject: [PATCH 0093/6080] perfcounters: IRQ and NMI support on AMD CPUs The below completes the K7+ performance counter support: - IRQ support - NMI support KernelTop output works now as well. Signed-off-by: Peter Zijlstra Cc: Jaswinder Singh Rajput Cc: Paul Mackerras LKML-Reference: <1236273633.5187.286.camel@laptop> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 272 ++++++++++++++++++++++++----- 1 file changed, 228 insertions(+), 44 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 3b65f19a6681..6ebe9abf6aef 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -28,6 +28,7 @@ static bool perf_counters_initialized __read_mostly; static int nr_counters_generic __read_mostly; static u64 perf_counter_mask __read_mostly; static u64 counter_value_mask __read_mostly; +static int counter_value_bits __read_mostly; static int nr_counters_fixed __read_mostly; @@ -35,7 +36,9 @@ struct cpu_hw_counters { struct perf_counter *counters[X86_PMC_IDX_MAX]; unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; unsigned long interrupts; - u64 global_enable; + u64 throttle_ctrl; + u64 active_mask; + int enabled; }; /* @@ -43,21 +46,28 @@ struct cpu_hw_counters { */ struct pmc_x86_ops { u64 (*save_disable_all)(void); - void (*restore_all)(u64 ctrl); + void (*restore_all)(u64); + u64 (*get_status)(u64); + void (*ack_status)(u64); + void (*enable)(int, u64); + void (*disable)(int, u64); unsigned eventsel; unsigned perfctr; - int (*event_map)(int event); + u64 (*event_map)(int); + u64 (*raw_event)(u64); int max_events; }; static struct pmc_x86_ops *pmc_ops; -static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters); +static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = { + .enabled = 1, +}; /* * Intel PerfMon v3. Used on Core2 and later. */ -static const int intel_perfmon_event_map[] = +static const u64 intel_perfmon_event_map[] = { [PERF_COUNT_CPU_CYCLES] = 0x003c, [PERF_COUNT_INSTRUCTIONS] = 0x00c0, @@ -68,15 +78,29 @@ static const int intel_perfmon_event_map[] = [PERF_COUNT_BUS_CYCLES] = 0x013c, }; -static int pmc_intel_event_map(int event) +static u64 pmc_intel_event_map(int event) { return intel_perfmon_event_map[event]; } +static u64 pmc_intel_raw_event(u64 event) +{ +#define CORE_EVNTSEL_EVENT_MASK 0x000000FF +#define CORE_EVNTSEL_UNIT_MASK 0x0000FF00 +#define CORE_EVNTSEL_COUNTER_MASK 0xFF000000 + +#define CORE_EVNTSEL_MASK \ + (CORE_EVNTSEL_EVENT_MASK | \ + CORE_EVNTSEL_UNIT_MASK | \ + CORE_EVNTSEL_COUNTER_MASK) + + return event & CORE_EVNTSEL_MASK; +} + /* * AMD Performance Monitor K7 and later. */ -static const int amd_perfmon_event_map[] = +static const u64 amd_perfmon_event_map[] = { [PERF_COUNT_CPU_CYCLES] = 0x0076, [PERF_COUNT_INSTRUCTIONS] = 0x00c0, @@ -86,11 +110,25 @@ static const int amd_perfmon_event_map[] = [PERF_COUNT_BRANCH_MISSES] = 0x00c5, }; -static int pmc_amd_event_map(int event) +static u64 pmc_amd_event_map(int event) { return amd_perfmon_event_map[event]; } +static u64 pmc_amd_raw_event(u64 event) +{ +#define K7_EVNTSEL_EVENT_MASK 0x7000000FF +#define K7_EVNTSEL_UNIT_MASK 0x00000FF00 +#define K7_EVNTSEL_COUNTER_MASK 0x0FF000000 + +#define K7_EVNTSEL_MASK \ + (K7_EVNTSEL_EVENT_MASK | \ + K7_EVNTSEL_UNIT_MASK | \ + K7_EVNTSEL_COUNTER_MASK) + + return event & K7_EVNTSEL_MASK; +} + /* * Propagate counter elapsed time into the generic counter. * Can only be executed on the CPU where the counter is active. @@ -179,7 +217,7 @@ static int __hw_perf_counter_init(struct perf_counter *counter) * Raw event type provide the config in the event structure */ if (hw_event->raw) { - hwc->config |= hw_event->type; + hwc->config |= pmc_ops->raw_event(hw_event->type); } else { if (hw_event->type >= pmc_ops->max_events) return -EINVAL; @@ -205,18 +243,24 @@ static u64 pmc_intel_save_disable_all(void) static u64 pmc_amd_save_disable_all(void) { - int idx; - u64 val, ctrl = 0; + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + int enabled, idx; + + enabled = cpuc->enabled; + cpuc->enabled = 0; + barrier(); for (idx = 0; idx < nr_counters_generic; idx++) { + u64 val; + rdmsrl(MSR_K7_EVNTSEL0 + idx, val); - if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) - ctrl |= (1 << idx); - val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsrl(MSR_K7_EVNTSEL0 + idx, val); + if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) { + val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsrl(MSR_K7_EVNTSEL0 + idx, val); + } } - return ctrl; + return enabled; } u64 hw_perf_save_disable(void) @@ -226,6 +270,9 @@ u64 hw_perf_save_disable(void) return pmc_ops->save_disable_all(); } +/* + * Exported because of ACPI idle + */ EXPORT_SYMBOL_GPL(hw_perf_save_disable); static void pmc_intel_restore_all(u64 ctrl) @@ -235,11 +282,18 @@ static void pmc_intel_restore_all(u64 ctrl) static void pmc_amd_restore_all(u64 ctrl) { - u64 val; + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); int idx; + cpuc->enabled = ctrl; + barrier(); + if (!ctrl) + return; + for (idx = 0; idx < nr_counters_generic; idx++) { - if (ctrl & (1 << idx)) { + if (test_bit(idx, (unsigned long *)&cpuc->active_mask)) { + u64 val; + rdmsrl(MSR_K7_EVNTSEL0 + idx, val); val |= ARCH_PERFMON_EVENTSEL0_ENABLE; wrmsrl(MSR_K7_EVNTSEL0 + idx, val); @@ -254,8 +308,112 @@ void hw_perf_restore(u64 ctrl) pmc_ops->restore_all(ctrl); } +/* + * Exported because of ACPI idle + */ EXPORT_SYMBOL_GPL(hw_perf_restore); +static u64 pmc_intel_get_status(u64 mask) +{ + u64 status; + + rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); + + return status; +} + +static u64 pmc_amd_get_status(u64 mask) +{ + u64 status = 0; + int idx; + + for (idx = 0; idx < nr_counters_generic; idx++) { + s64 val; + + if (!(mask & (1 << idx))) + continue; + + rdmsrl(MSR_K7_PERFCTR0 + idx, val); + val <<= (64 - counter_value_bits); + if (val >= 0) + status |= (1 << idx); + } + + return status; +} + +static u64 hw_perf_get_status(u64 mask) +{ + if (unlikely(!perf_counters_initialized)) + return 0; + + return pmc_ops->get_status(mask); +} + +static void pmc_intel_ack_status(u64 ack) +{ + wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack); +} + +static void pmc_amd_ack_status(u64 ack) +{ +} + +static void hw_perf_ack_status(u64 ack) +{ + if (unlikely(!perf_counters_initialized)) + return; + + pmc_ops->ack_status(ack); +} + +static void pmc_intel_enable(int idx, u64 config) +{ + wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, + config | ARCH_PERFMON_EVENTSEL0_ENABLE); +} + +static void pmc_amd_enable(int idx, u64 config) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + + set_bit(idx, (unsigned long *)&cpuc->active_mask); + if (cpuc->enabled) + config |= ARCH_PERFMON_EVENTSEL0_ENABLE; + + wrmsrl(MSR_K7_EVNTSEL0 + idx, config); +} + +static void hw_perf_enable(int idx, u64 config) +{ + if (unlikely(!perf_counters_initialized)) + return; + + pmc_ops->enable(idx, config); +} + +static void pmc_intel_disable(int idx, u64 config) +{ + wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, config); +} + +static void pmc_amd_disable(int idx, u64 config) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + + clear_bit(idx, (unsigned long *)&cpuc->active_mask); + wrmsrl(MSR_K7_EVNTSEL0 + idx, config); + +} + +static void hw_perf_disable(int idx, u64 config) +{ + if (unlikely(!perf_counters_initialized)) + return; + + pmc_ops->disable(idx, config); +} + static inline void __pmc_fixed_disable(struct perf_counter *counter, struct hw_perf_counter *hwc, unsigned int __idx) @@ -278,7 +436,7 @@ __pmc_generic_disable(struct perf_counter *counter, if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) __pmc_fixed_disable(counter, hwc, idx); else - wrmsr_safe(hwc->config_base + idx, hwc->config, 0); + hw_perf_disable(idx, hwc->config); } static DEFINE_PER_CPU(u64, prev_left[X86_PMC_IDX_MAX]); @@ -354,8 +512,7 @@ __pmc_generic_enable(struct perf_counter *counter, if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) __pmc_fixed_enable(counter, hwc, idx); else - wrmsr(hwc->config_base + idx, - hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE, 0); + hw_perf_enable(idx, hwc->config); } static int @@ -567,22 +724,20 @@ perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) * This handler is triggered by the local APIC, so the APIC IRQ handling * rules apply: */ -static void __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) +static int __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) { int bit, cpu = smp_processor_id(); u64 ack, status; struct cpu_hw_counters *cpuc = &per_cpu(cpu_hw_counters, cpu); + int ret = 0; - rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); - - /* Disable counters globally */ - wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); - ack_APIC_irq(); + cpuc->throttle_ctrl = hw_perf_save_disable(); - rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); + status = hw_perf_get_status(cpuc->throttle_ctrl); if (!status) goto out; + ret = 1; again: inc_irq_stat(apic_perf_irqs); ack = status; @@ -618,12 +773,12 @@ again: } } - wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack); + hw_perf_ack_status(ack); /* * Repeat if there is more work to be done: */ - rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); + status = hw_perf_get_status(cpuc->throttle_ctrl); if (status) goto again; out: @@ -631,32 +786,27 @@ out: * Restore - do not reenable when global enable is off or throttled: */ if (++cpuc->interrupts < PERFMON_MAX_INTERRUPTS) - wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); + hw_perf_restore(cpuc->throttle_ctrl); + + return ret; } void perf_counter_unthrottle(void) { struct cpu_hw_counters *cpuc; - u64 global_enable; if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) return; - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) - return; - if (unlikely(!perf_counters_initialized)) return; - cpuc = &per_cpu(cpu_hw_counters, smp_processor_id()); + cpuc = &__get_cpu_var(cpu_hw_counters); if (cpuc->interrupts >= PERFMON_MAX_INTERRUPTS) { if (printk_ratelimit()) printk(KERN_WARNING "PERFMON: max interrupts exceeded!\n"); - wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); + hw_perf_restore(cpuc->throttle_ctrl); } - rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, global_enable); - if (unlikely(cpuc->global_enable && !global_enable)) - wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, cpuc->global_enable); cpuc->interrupts = 0; } @@ -664,8 +814,8 @@ void smp_perf_counter_interrupt(struct pt_regs *regs) { irq_enter(); apic_write(APIC_LVTPC, LOCAL_PERF_VECTOR); + ack_APIC_irq(); __smp_perf_counter_interrupt(regs, 0); - irq_exit(); } @@ -722,16 +872,23 @@ perf_counter_nmi_handler(struct notifier_block *self, { struct die_args *args = __args; struct pt_regs *regs; + int ret; + + switch (cmd) { + case DIE_NMI: + case DIE_NMI_IPI: + break; - if (likely(cmd != DIE_NMI_IPI)) + default: return NOTIFY_DONE; + } regs = args->regs; apic_write(APIC_LVTPC, APIC_DM_NMI); - __smp_perf_counter_interrupt(regs, 1); + ret = __smp_perf_counter_interrupt(regs, 1); - return NOTIFY_STOP; + return ret ? NOTIFY_STOP : NOTIFY_OK; } static __read_mostly struct notifier_block perf_counter_nmi_notifier = { @@ -743,18 +900,28 @@ static __read_mostly struct notifier_block perf_counter_nmi_notifier = { static struct pmc_x86_ops pmc_intel_ops = { .save_disable_all = pmc_intel_save_disable_all, .restore_all = pmc_intel_restore_all, + .get_status = pmc_intel_get_status, + .ack_status = pmc_intel_ack_status, + .enable = pmc_intel_enable, + .disable = pmc_intel_disable, .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, .perfctr = MSR_ARCH_PERFMON_PERFCTR0, .event_map = pmc_intel_event_map, + .raw_event = pmc_intel_raw_event, .max_events = ARRAY_SIZE(intel_perfmon_event_map), }; static struct pmc_x86_ops pmc_amd_ops = { .save_disable_all = pmc_amd_save_disable_all, .restore_all = pmc_amd_restore_all, + .get_status = pmc_amd_get_status, + .ack_status = pmc_amd_ack_status, + .enable = pmc_amd_enable, + .disable = pmc_amd_disable, .eventsel = MSR_K7_EVNTSEL0, .perfctr = MSR_K7_PERFCTR0, .event_map = pmc_amd_event_map, + .raw_event = pmc_amd_raw_event, .max_events = ARRAY_SIZE(amd_perfmon_event_map), }; @@ -787,8 +954,25 @@ static struct pmc_x86_ops *pmc_intel_init(void) static struct pmc_x86_ops *pmc_amd_init(void) { + u64 old; + int bits; + nr_counters_generic = 4; nr_counters_fixed = 0; + counter_value_mask = ~0ULL; + + rdmsrl(MSR_K7_PERFCTR0, old); + wrmsrl(MSR_K7_PERFCTR0, counter_value_mask); + /* + * read the truncated mask + */ + rdmsrl(MSR_K7_PERFCTR0, counter_value_mask); + wrmsrl(MSR_K7_PERFCTR0, old); + + bits = 32 + fls(counter_value_mask >> 32); + if (bits == 32) + bits = fls((u32)counter_value_mask); + counter_value_bits = bits; pr_info("AMD Performance Monitoring support detected.\n"); -- GitLab From b5e8acf66ff5db707c7e08df49fdf6b415878442 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 5 Mar 2009 20:34:21 +0100 Subject: [PATCH 0094/6080] perfcounters: IRQ and NMI support on AMD CPUs, fix The BKGD suggests that counter width on AMD CPUs is 48 for all existing models (it certainly is for mine). Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 6ebe9abf6aef..f5853718d4d3 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -959,20 +959,8 @@ static struct pmc_x86_ops *pmc_amd_init(void) nr_counters_generic = 4; nr_counters_fixed = 0; - counter_value_mask = ~0ULL; - - rdmsrl(MSR_K7_PERFCTR0, old); - wrmsrl(MSR_K7_PERFCTR0, counter_value_mask); - /* - * read the truncated mask - */ - rdmsrl(MSR_K7_PERFCTR0, counter_value_mask); - wrmsrl(MSR_K7_PERFCTR0, old); - - bits = 32 + fls(counter_value_mask >> 32); - if (bits == 32) - bits = fls((u32)counter_value_mask); - counter_value_bits = bits; + counter_value_mask = 0x0000FFFFFFFFFFFFULL; + counter_value_bits = 48; pr_info("AMD Performance Monitoring support detected.\n"); -- GitLab From 86028598de16538f02519141756ccf4accfc29a6 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 5 Mar 2009 14:05:57 +1100 Subject: [PATCH 0095/6080] perfcounters/powerpc: fix oops with multiple counters in a group Impact: fix oops-causing bug This fixes a bug in the powerpc hw_perf_counter_init where the code didn't initialize ctrs[n] before passing the ctrs array to check_excludes, leading to possible oopses and other incorrect behaviour. This fixes it by initializing ctrs[n] correctly. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/perf_counter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 112332d07fc2..4fec112386fc 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -633,6 +633,7 @@ hw_perf_counter_init(struct perf_counter *counter) return NULL; } events[n] = ev; + ctrs[n] = counter; if (check_excludes(ctrs, n, 1)) return NULL; if (power_check_constraints(events, n + 1)) -- GitLab From aabbaa6036fd847c583f585c6bae82b5a033e6c7 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 6 Mar 2009 16:27:10 +1100 Subject: [PATCH 0096/6080] perfcounters/powerpc: add support for POWER5+ processors Impact: more hardware support This adds the back-end for the PMU on the POWER5+ processors (i.e. GS, including GS DD3 aka POWER5++). This doesn't use the fixed-function PMC5 and PMC6 since they don't respect the freeze conditions and don't generate interrupts, as on POWER6. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 4 +- arch/powerpc/kernel/perf_counter.c | 4 + arch/powerpc/kernel/power5+-pmu.c | 452 +++++++++++++++++++++++++++++ 3 files changed, 458 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/kernel/power5+-pmu.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index b4c6f466164b..49851e0d8fde 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -94,8 +94,8 @@ obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o -obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o ppc970-pmu.o power5-pmu.o \ - power6-pmu.o +obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o ppc970-pmu.o \ + power5-pmu.o power5+-pmu.o power6-pmu.o obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 4fec112386fc..162f3981fa27 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -826,6 +826,7 @@ void hw_perf_counter_setup(int cpu) extern struct power_pmu ppc970_pmu; extern struct power_pmu power5_pmu; +extern struct power_pmu power5p_pmu; extern struct power_pmu power6_pmu; static int init_perf_counters(void) @@ -848,6 +849,9 @@ static int init_perf_counters(void) case PV_POWER5: ppmu = &power5_pmu; break; + case PV_POWER5p: + ppmu = &power5p_pmu; + break; case 0x3e: ppmu = &power6_pmu; break; diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c new file mode 100644 index 000000000000..cec21ea65b0e --- /dev/null +++ b/arch/powerpc/kernel/power5+-pmu.c @@ -0,0 +1,452 @@ +/* + * Performance counter support for POWER5 (not POWER5++) processors. + * + * Copyright 2009 Paul Mackerras, IBM 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 the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include + +/* + * Bits in event code for POWER5+ (POWER5 GS) and POWER5++ (POWER5 GS DD3) + */ +#define PM_PMC_SH 20 /* PMC number (1-based) for direct events */ +#define PM_PMC_MSK 0xf +#define PM_PMC_MSKS (PM_PMC_MSK << PM_PMC_SH) +#define PM_UNIT_SH 16 /* TTMMUX number and setting - unit select */ +#define PM_UNIT_MSK 0xf +#define PM_BYTE_SH 12 /* Byte number of event bus to use */ +#define PM_BYTE_MSK 7 +#define PM_GRS_SH 8 /* Storage subsystem mux select */ +#define PM_GRS_MSK 7 +#define PM_BUSEVENT_MSK 0x80 /* Set if event uses event bus */ +#define PM_PMCSEL_MSK 0x7f + +/* Values in PM_UNIT field */ +#define PM_FPU 0 +#define PM_ISU0 1 +#define PM_IFU 2 +#define PM_ISU1 3 +#define PM_IDU 4 +#define PM_ISU0_ALT 6 +#define PM_GRS 7 +#define PM_LSU0 8 +#define PM_LSU1 0xc +#define PM_LASTUNIT 0xc + +/* + * Bits in MMCR1 for POWER5+ + */ +#define MMCR1_TTM0SEL_SH 62 +#define MMCR1_TTM1SEL_SH 60 +#define MMCR1_TTM2SEL_SH 58 +#define MMCR1_TTM3SEL_SH 56 +#define MMCR1_TTMSEL_MSK 3 +#define MMCR1_TD_CP_DBG0SEL_SH 54 +#define MMCR1_TD_CP_DBG1SEL_SH 52 +#define MMCR1_TD_CP_DBG2SEL_SH 50 +#define MMCR1_TD_CP_DBG3SEL_SH 48 +#define MMCR1_GRS_L2SEL_SH 46 +#define MMCR1_GRS_L2SEL_MSK 3 +#define MMCR1_GRS_L3SEL_SH 44 +#define MMCR1_GRS_L3SEL_MSK 3 +#define MMCR1_GRS_MCSEL_SH 41 +#define MMCR1_GRS_MCSEL_MSK 7 +#define MMCR1_GRS_FABSEL_SH 39 +#define MMCR1_GRS_FABSEL_MSK 3 +#define MMCR1_PMC1_ADDER_SEL_SH 35 +#define MMCR1_PMC2_ADDER_SEL_SH 34 +#define MMCR1_PMC3_ADDER_SEL_SH 33 +#define MMCR1_PMC4_ADDER_SEL_SH 32 +#define MMCR1_PMC1SEL_SH 25 +#define MMCR1_PMC2SEL_SH 17 +#define MMCR1_PMC3SEL_SH 9 +#define MMCR1_PMC4SEL_SH 1 +#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8) +#define MMCR1_PMCSEL_MSK 0x7f + +/* + * Bits in MMCRA + */ + +/* + * Layout of constraint bits: + * 6666555555555544444444443333333333222222222211111111110000000000 + * 3210987654321098765432109876543210987654321098765432109876543210 + * [ ><><>< ><> <><>[ > < >< >< >< ><><><><> + * NC G0G1G2 G3 T0T1 UC B0 B1 B2 B3 P4P3P2P1 + * + * NC - number of counters + * 51: NC error 0x0008_0000_0000_0000 + * 48-50: number of events needing PMC1-4 0x0007_0000_0000_0000 + * + * G0..G3 - GRS mux constraints + * 46-47: GRS_L2SEL value + * 44-45: GRS_L3SEL value + * 41-44: GRS_MCSEL value + * 39-40: GRS_FABSEL value + * Note that these match up with their bit positions in MMCR1 + * + * T0 - TTM0 constraint + * 36-37: TTM0SEL value (0=FPU, 2=IFU, 3=ISU1) 0x30_0000_0000 + * + * T1 - TTM1 constraint + * 34-35: TTM1SEL value (0=IDU, 3=GRS) 0x0c_0000_0000 + * + * UC - unit constraint: can't have all three of FPU|IFU|ISU1, ISU0, IDU|GRS + * 33: UC3 error 0x02_0000_0000 + * 32: FPU|IFU|ISU1 events needed 0x01_0000_0000 + * 31: ISU0 events needed 0x01_8000_0000 + * 30: IDU|GRS events needed 0x00_4000_0000 + * + * B0 + * 20-23: Byte 0 event source 0x00f0_0000 + * Encoding as for the event code + * + * B1, B2, B3 + * 16-19, 12-15, 8-11: Byte 1, 2, 3 event sources + * + * P4 + * 7: P1 error 0x80 + * 6-7: Count of events needing PMC4 + * + * P1..P3 + * 0-6: Count of events needing PMC1..PMC3 + */ + +static const int grsel_shift[8] = { + MMCR1_GRS_L2SEL_SH, MMCR1_GRS_L2SEL_SH, MMCR1_GRS_L2SEL_SH, + MMCR1_GRS_L3SEL_SH, MMCR1_GRS_L3SEL_SH, MMCR1_GRS_L3SEL_SH, + MMCR1_GRS_MCSEL_SH, MMCR1_GRS_FABSEL_SH +}; + +/* Masks and values for using events from the various units */ +static u64 unit_cons[PM_LASTUNIT+1][2] = { + [PM_FPU] = { 0x3200000000ull, 0x0100000000ull }, + [PM_ISU0] = { 0x0200000000ull, 0x0080000000ull }, + [PM_ISU1] = { 0x3200000000ull, 0x3100000000ull }, + [PM_IFU] = { 0x3200000000ull, 0x2100000000ull }, + [PM_IDU] = { 0x0e00000000ull, 0x0040000000ull }, + [PM_GRS] = { 0x0e00000000ull, 0x0c40000000ull }, +}; + +static int power5p_get_constraint(unsigned int event, u64 *maskp, u64 *valp) +{ + int pmc, byte, unit, sh; + int bit, fmask; + u64 mask = 0, value = 0; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc > 4) + return -1; + sh = (pmc - 1) * 2; + mask |= 2 << sh; + value |= 1 << sh; + } + if (event & PM_BUSEVENT_MSK) { + unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; + if (unit > PM_LASTUNIT) + return -1; + if (unit == PM_ISU0_ALT) + unit = PM_ISU0; + mask |= unit_cons[unit][0]; + value |= unit_cons[unit][1]; + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + if (byte >= 4) { + if (unit != PM_LSU1) + return -1; + /* Map LSU1 low word (bytes 4-7) to unit LSU1+1 */ + ++unit; + byte &= 3; + } + if (unit == PM_GRS) { + bit = event & 7; + fmask = (bit == 6)? 7: 3; + sh = grsel_shift[bit]; + mask |= (u64)fmask << sh; + value |= (u64)((event >> PM_GRS_SH) & fmask) << sh; + } + /* Set byte lane select field */ + mask |= 0xfULL << (20 - 4 * byte); + value |= (u64)unit << (20 - 4 * byte); + } + mask |= 0x8000000000000ull; + value |= 0x1000000000000ull; + *maskp = mask; + *valp = value; + return 0; +} + +#define MAX_ALT 3 /* at most 3 alternatives for any event */ + +static const unsigned int event_alternatives[][MAX_ALT] = { + { 0x100c0, 0x40001f }, /* PM_GCT_FULL_CYC */ + { 0x120e4, 0x400002 }, /* PM_GRP_DISP_REJECT */ + { 0x230e2, 0x323087 }, /* PM_BR_PRED_CR */ + { 0x230e3, 0x223087, 0x3230a0 }, /* PM_BR_PRED_TA */ + { 0x410c7, 0x441084 }, /* PM_THRD_L2MISS_BOTH_CYC */ + { 0x800c4, 0xc20e0 }, /* PM_DTLB_MISS */ + { 0xc50c6, 0xc60e0 }, /* PM_MRK_DTLB_MISS */ + { 0x100009, 0x200009 }, /* PM_INST_CMPL */ + { 0x200015, 0x300015 }, /* PM_LSU_LMQ_SRQ_EMPTY_CYC */ + { 0x300009, 0x400009 }, /* PM_INST_DISP */ +}; + +/* + * Scan the alternatives table for a match and return the + * index into the alternatives table if found, else -1. + */ +static int find_alternative(unsigned int event) +{ + int i, j; + + for (i = 0; i < ARRAY_SIZE(event_alternatives); ++i) { + if (event < event_alternatives[i][0]) + break; + for (j = 0; j < MAX_ALT && event_alternatives[i][j]; ++j) + if (event == event_alternatives[i][j]) + return i; + } + return -1; +} + +static const unsigned char bytedecode_alternatives[4][4] = { + /* PMC 1 */ { 0x21, 0x23, 0x25, 0x27 }, + /* PMC 2 */ { 0x07, 0x17, 0x0e, 0x1e }, + /* PMC 3 */ { 0x20, 0x22, 0x24, 0x26 }, + /* PMC 4 */ { 0x07, 0x17, 0x0e, 0x1e } +}; + +/* + * Some direct events for decodes of event bus byte 3 have alternative + * PMCSEL values on other counters. This returns the alternative + * event code for those that do, or -1 otherwise. This also handles + * alternative PCMSEL values for add events. + */ +static int find_alternative_bdecode(unsigned int event) +{ + int pmc, altpmc, pp, j; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc == 0 || pmc > 4) + return -1; + altpmc = 5 - pmc; /* 1 <-> 4, 2 <-> 3 */ + pp = event & PM_PMCSEL_MSK; + for (j = 0; j < 4; ++j) { + if (bytedecode_alternatives[pmc - 1][j] == pp) { + return (event & ~(PM_PMC_MSKS | PM_PMCSEL_MSK)) | + (altpmc << PM_PMC_SH) | + bytedecode_alternatives[altpmc - 1][j]; + } + } + + /* new decode alternatives for power5+ */ + if (pmc == 1 && (pp == 0x0d || pp == 0x0e)) + return event + (2 << PM_PMC_SH) + (0x2e - 0x0d); + if (pmc == 3 && (pp == 0x2e || pp == 0x2f)) + return event - (2 << PM_PMC_SH) - (0x2e - 0x0d); + + /* alternative add event encodings */ + if (pp == 0x10 || pp == 0x28) + return ((event ^ (0x10 ^ 0x28)) & ~PM_PMC_MSKS) | + (altpmc << PM_PMC_SH); + + return -1; +} + +static int power5p_get_alternatives(unsigned int event, unsigned int alt[]) +{ + int i, j, ae, nalt = 1; + + alt[0] = event; + nalt = 1; + i = find_alternative(event); + if (i >= 0) { + for (j = 0; j < MAX_ALT; ++j) { + ae = event_alternatives[i][j]; + if (ae && ae != event) + alt[nalt++] = ae; + } + } else { + ae = find_alternative_bdecode(event); + if (ae > 0) + alt[nalt++] = ae; + } + return nalt; +} + +static int power5p_compute_mmcr(unsigned int event[], int n_ev, + unsigned int hwc[], u64 mmcr[]) +{ + u64 mmcr1 = 0; + unsigned int pmc, unit, byte, psel; + unsigned int ttm; + int i, isbus, bit, grsel; + unsigned int pmc_inuse = 0; + unsigned char busbyte[4]; + unsigned char unituse[16]; + int ttmuse; + + if (n_ev > 4) + return -1; + + /* First pass to count resource use */ + memset(busbyte, 0, sizeof(busbyte)); + memset(unituse, 0, sizeof(unituse)); + for (i = 0; i < n_ev; ++i) { + pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc > 4) + return -1; + if (pmc_inuse & (1 << (pmc - 1))) + return -1; + pmc_inuse |= 1 << (pmc - 1); + } + if (event[i] & PM_BUSEVENT_MSK) { + unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK; + byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK; + if (unit > PM_LASTUNIT) + return -1; + if (unit == PM_ISU0_ALT) + unit = PM_ISU0; + if (byte >= 4) { + if (unit != PM_LSU1) + return -1; + ++unit; + byte &= 3; + } + if (busbyte[byte] && busbyte[byte] != unit) + return -1; + busbyte[byte] = unit; + unituse[unit] = 1; + } + } + + /* + * Assign resources and set multiplexer selects. + * + * PM_ISU0 can go either on TTM0 or TTM1, but that's the only + * choice we have to deal with. + */ + if (unituse[PM_ISU0] & + (unituse[PM_FPU] | unituse[PM_IFU] | unituse[PM_ISU1])) { + unituse[PM_ISU0_ALT] = 1; /* move ISU to TTM1 */ + unituse[PM_ISU0] = 0; + } + /* Set TTM[01]SEL fields. */ + ttmuse = 0; + for (i = PM_FPU; i <= PM_ISU1; ++i) { + if (!unituse[i]) + continue; + if (ttmuse++) + return -1; + mmcr1 |= (u64)i << MMCR1_TTM0SEL_SH; + } + ttmuse = 0; + for (; i <= PM_GRS; ++i) { + if (!unituse[i]) + continue; + if (ttmuse++) + return -1; + mmcr1 |= (u64)(i & 3) << MMCR1_TTM1SEL_SH; + } + if (ttmuse > 1) + return -1; + + /* Set byte lane select fields, TTM[23]SEL and GRS_*SEL. */ + for (byte = 0; byte < 4; ++byte) { + unit = busbyte[byte]; + if (!unit) + continue; + if (unit == PM_ISU0 && unituse[PM_ISU0_ALT]) { + /* get ISU0 through TTM1 rather than TTM0 */ + unit = PM_ISU0_ALT; + } else if (unit == PM_LSU1 + 1) { + /* select lower word of LSU1 for this byte */ + mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte); + } + ttm = unit >> 2; + mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte); + } + + /* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */ + for (i = 0; i < n_ev; ++i) { + pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; + unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK; + byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK; + psel = event[i] & PM_PMCSEL_MSK; + isbus = event[i] & PM_BUSEVENT_MSK; + if (!pmc) { + /* Bus event or any-PMC direct event */ + for (pmc = 0; pmc < 4; ++pmc) { + if (!(pmc_inuse & (1 << pmc))) + break; + } + if (pmc >= 4) + return -1; + pmc_inuse |= 1 << pmc; + } else { + /* Direct event */ + --pmc; + if (isbus && (byte & 2) && + (psel == 8 || psel == 0x10 || psel == 0x28)) + /* add events on higher-numbered bus */ + mmcr1 |= 1ull << (MMCR1_PMC1_ADDER_SEL_SH - pmc); + } + if (isbus && unit == PM_GRS) { + bit = psel & 7; + grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK; + mmcr1 |= (u64)grsel << grsel_shift[bit]; + } + if ((psel & 0x58) == 0x40 && (byte & 1) != ((pmc >> 1) & 1)) + /* select alternate byte lane */ + psel |= 0x10; + if (pmc <= 3) + mmcr1 |= psel << MMCR1_PMCSEL_SH(pmc); + hwc[i] = pmc; + } + + /* Return MMCRx values */ + mmcr[0] = 0; + if (pmc_inuse & 1) + mmcr[0] = MMCR0_PMC1CE; + if (pmc_inuse & 0x3e) + mmcr[0] |= MMCR0_PMCjCE; + mmcr[1] = mmcr1; + mmcr[2] = 0; + return 0; +} + +static void power5p_disable_pmc(unsigned int pmc, u64 mmcr[]) +{ + if (pmc <= 3) + mmcr[1] &= ~(0x7fUL << MMCR1_PMCSEL_SH(pmc)); +} + +static int power5p_generic_events[] = { + [PERF_COUNT_CPU_CYCLES] = 0xf, + [PERF_COUNT_INSTRUCTIONS] = 0x100009, + [PERF_COUNT_CACHE_REFERENCES] = 0x1c10a8, /* LD_REF_L1 */ + [PERF_COUNT_CACHE_MISSES] = 0x3c1088, /* LD_MISS_L1 */ + [PERF_COUNT_BRANCH_INSTRUCTIONS] = 0x230e4, /* BR_ISSUED */ + [PERF_COUNT_BRANCH_MISSES] = 0x230e5, /* BR_MPRED_CR */ +}; + +struct power_pmu power5p_pmu = { + .n_counter = 4, + .max_alternatives = MAX_ALT, + .add_fields = 0x7000000000055ull, + .test_adder = 0x3000040000000ull, + .compute_mmcr = power5p_compute_mmcr, + .get_constraint = power5p_get_constraint, + .get_alternatives = power5p_get_alternatives, + .disable_pmc = power5p_disable_pmc, + .n_generic = ARRAY_SIZE(power5p_generic_events), + .generic_events = power5p_generic_events, +}; -- GitLab From 880860e392d92c457e8116cdee39ec4d109174ee Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 6 Mar 2009 16:30:52 +1100 Subject: [PATCH 0097/6080] perfcounters/powerpc: add support for POWER4 processors Impact: more hardware support This adds the back-end for the PMU on the POWER4 and POWER4+ processors (GP and GQ). This is quite similar to the PPC970, with 8 PMCs, but has fewer events than the PPC970. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/perf_counter.c | 5 + arch/powerpc/kernel/power4-pmu.c | 557 +++++++++++++++++++++++++++++ 3 files changed, 563 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/kernel/power4-pmu.c diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 49851e0d8fde..8e5e2c74971e 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -94,7 +94,7 @@ obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o -obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o ppc970-pmu.o \ +obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o power4-pmu.o ppc970-pmu.o \ power5-pmu.o power5+-pmu.o power6-pmu.o obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 162f3981fa27..0e33d27cd464 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -824,6 +824,7 @@ void hw_perf_counter_setup(int cpu) cpuhw->mmcr[0] = MMCR0_FC; } +extern struct power_pmu power4_pmu; extern struct power_pmu ppc970_pmu; extern struct power_pmu power5_pmu; extern struct power_pmu power5p_pmu; @@ -841,6 +842,10 @@ static int init_perf_counters(void) /* XXX should get this from cputable */ pvr = mfspr(SPRN_PVR); switch (PVR_VER(pvr)) { + case PV_POWER4: + case PV_POWER4p: + ppmu = &power4_pmu; + break; case PV_970: case PV_970FX: case PV_970MP: diff --git a/arch/powerpc/kernel/power4-pmu.c b/arch/powerpc/kernel/power4-pmu.c new file mode 100644 index 000000000000..1407b19ab619 --- /dev/null +++ b/arch/powerpc/kernel/power4-pmu.c @@ -0,0 +1,557 @@ +/* + * Performance counter support for POWER4 (GP) and POWER4+ (GQ) processors. + * + * Copyright 2009 Paul Mackerras, IBM 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 the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include + +/* + * Bits in event code for POWER4 + */ +#define PM_PMC_SH 12 /* PMC number (1-based) for direct events */ +#define PM_PMC_MSK 0xf +#define PM_UNIT_SH 8 /* TTMMUX number and setting - unit select */ +#define PM_UNIT_MSK 0xf +#define PM_LOWER_SH 6 +#define PM_LOWER_MSK 1 +#define PM_LOWER_MSKS 0x40 +#define PM_BYTE_SH 4 /* Byte number of event bus to use */ +#define PM_BYTE_MSK 3 +#define PM_PMCSEL_MSK 7 + +/* + * Unit code values + */ +#define PM_FPU 1 +#define PM_ISU1 2 +#define PM_IFU 3 +#define PM_IDU0 4 +#define PM_ISU1_ALT 6 +#define PM_ISU2 7 +#define PM_IFU_ALT 8 +#define PM_LSU0 9 +#define PM_LSU1 0xc +#define PM_GPS 0xf + +/* + * Bits in MMCR0 for POWER4 + */ +#define MMCR0_PMC1SEL_SH 8 +#define MMCR0_PMC2SEL_SH 1 +#define MMCR_PMCSEL_MSK 0x1f + +/* + * Bits in MMCR1 for POWER4 + */ +#define MMCR1_TTM0SEL_SH 62 +#define MMCR1_TTC0SEL_SH 61 +#define MMCR1_TTM1SEL_SH 59 +#define MMCR1_TTC1SEL_SH 58 +#define MMCR1_TTM2SEL_SH 56 +#define MMCR1_TTC2SEL_SH 55 +#define MMCR1_TTM3SEL_SH 53 +#define MMCR1_TTC3SEL_SH 52 +#define MMCR1_TTMSEL_MSK 3 +#define MMCR1_TD_CP_DBG0SEL_SH 50 +#define MMCR1_TD_CP_DBG1SEL_SH 48 +#define MMCR1_TD_CP_DBG2SEL_SH 46 +#define MMCR1_TD_CP_DBG3SEL_SH 44 +#define MMCR1_DEBUG0SEL_SH 43 +#define MMCR1_DEBUG1SEL_SH 42 +#define MMCR1_DEBUG2SEL_SH 41 +#define MMCR1_DEBUG3SEL_SH 40 +#define MMCR1_PMC1_ADDER_SEL_SH 39 +#define MMCR1_PMC2_ADDER_SEL_SH 38 +#define MMCR1_PMC6_ADDER_SEL_SH 37 +#define MMCR1_PMC5_ADDER_SEL_SH 36 +#define MMCR1_PMC8_ADDER_SEL_SH 35 +#define MMCR1_PMC7_ADDER_SEL_SH 34 +#define MMCR1_PMC3_ADDER_SEL_SH 33 +#define MMCR1_PMC4_ADDER_SEL_SH 32 +#define MMCR1_PMC3SEL_SH 27 +#define MMCR1_PMC4SEL_SH 22 +#define MMCR1_PMC5SEL_SH 17 +#define MMCR1_PMC6SEL_SH 12 +#define MMCR1_PMC7SEL_SH 7 +#define MMCR1_PMC8SEL_SH 2 /* note bit 0 is in MMCRA for GP */ + +static short mmcr1_adder_bits[8] = { + MMCR1_PMC1_ADDER_SEL_SH, + MMCR1_PMC2_ADDER_SEL_SH, + MMCR1_PMC3_ADDER_SEL_SH, + MMCR1_PMC4_ADDER_SEL_SH, + MMCR1_PMC5_ADDER_SEL_SH, + MMCR1_PMC6_ADDER_SEL_SH, + MMCR1_PMC7_ADDER_SEL_SH, + MMCR1_PMC8_ADDER_SEL_SH +}; + +/* + * Bits in MMCRA + */ +#define MMCRA_PMC8SEL0_SH 17 /* PMC8SEL bit 0 for GP */ + +/* + * Layout of constraint bits: + * 6666555555555544444444443333333333222222222211111111110000000000 + * 3210987654321098765432109876543210987654321098765432109876543210 + * |[ >[ >[ >|||[ >[ >< >< >< >< ><><><><><><><><> + * | UC1 UC2 UC3 ||| PS1 PS2 B0 B1 B2 B3 P1P2P3P4P5P6P7P8 + * \SMPL ||\TTC3SEL + * |\TTC_IFU_SEL + * \TTM2SEL0 + * + * SMPL - SAMPLE_ENABLE constraint + * 56: SAMPLE_ENABLE value 0x0100_0000_0000_0000 + * + * UC1 - unit constraint 1: can't have all three of FPU/ISU1/IDU0|ISU2 + * 55: UC1 error 0x0080_0000_0000_0000 + * 54: FPU events needed 0x0040_0000_0000_0000 + * 53: ISU1 events needed 0x0020_0000_0000_0000 + * 52: IDU0|ISU2 events needed 0x0010_0000_0000_0000 + * + * UC2 - unit constraint 2: can't have all three of FPU/IFU/LSU0 + * 51: UC2 error 0x0008_0000_0000_0000 + * 50: FPU events needed 0x0004_0000_0000_0000 + * 49: IFU events needed 0x0002_0000_0000_0000 + * 48: LSU0 events needed 0x0001_0000_0000_0000 + * + * UC3 - unit constraint 3: can't have all four of LSU0/IFU/IDU0|ISU2/ISU1 + * 47: UC3 error 0x8000_0000_0000 + * 46: LSU0 events needed 0x4000_0000_0000 + * 45: IFU events needed 0x2000_0000_0000 + * 44: IDU0|ISU2 events needed 0x1000_0000_0000 + * 43: ISU1 events needed 0x0800_0000_0000 + * + * TTM2SEL0 + * 42: 0 = IDU0 events needed + * 1 = ISU2 events needed 0x0400_0000_0000 + * + * TTC_IFU_SEL + * 41: 0 = IFU.U events needed + * 1 = IFU.L events needed 0x0200_0000_0000 + * + * TTC3SEL + * 40: 0 = LSU1.U events needed + * 1 = LSU1.L events needed 0x0100_0000_0000 + * + * PS1 + * 39: PS1 error 0x0080_0000_0000 + * 36-38: count of events needing PMC1/2/5/6 0x0070_0000_0000 + * + * PS2 + * 35: PS2 error 0x0008_0000_0000 + * 32-34: count of events needing PMC3/4/7/8 0x0007_0000_0000 + * + * B0 + * 28-31: Byte 0 event source 0xf000_0000 + * 1 = FPU + * 2 = ISU1 + * 3 = IFU + * 4 = IDU0 + * 7 = ISU2 + * 9 = LSU0 + * c = LSU1 + * f = GPS + * + * B1, B2, B3 + * 24-27, 20-23, 16-19: Byte 1, 2, 3 event sources + * + * P8 + * 15: P8 error 0x8000 + * 14-15: Count of events needing PMC8 + * + * P1..P7 + * 0-13: Count of events needing PMC1..PMC7 + * + * Note: this doesn't allow events using IFU.U to be combined with events + * using IFU.L, though that is feasible (using TTM0 and TTM2). However + * there are no listed events for IFU.L (they are debug events not + * verified for performance monitoring) so this shouldn't cause a + * problem. + */ + +static struct unitinfo { + u64 value, mask; + int unit; + int lowerbit; +} p4_unitinfo[16] = { + [PM_FPU] = { 0x44000000000000ull, 0x88000000000000ull, PM_FPU, 0 }, + [PM_ISU1] = { 0x20080000000000ull, 0x88000000000000ull, PM_ISU1, 0 }, + [PM_ISU1_ALT] = + { 0x20080000000000ull, 0x88000000000000ull, PM_ISU1, 0 }, + [PM_IFU] = { 0x02200000000000ull, 0x08820000000000ull, PM_IFU, 41 }, + [PM_IFU_ALT] = + { 0x02200000000000ull, 0x08820000000000ull, PM_IFU, 41 }, + [PM_IDU0] = { 0x10100000000000ull, 0x80840000000000ull, PM_IDU0, 1 }, + [PM_ISU2] = { 0x10140000000000ull, 0x80840000000000ull, PM_ISU2, 0 }, + [PM_LSU0] = { 0x01400000000000ull, 0x08800000000000ull, PM_LSU0, 0 }, + [PM_LSU1] = { 0x00000000000000ull, 0x00010000000000ull, PM_LSU1, 40 }, + [PM_GPS] = { 0x00000000000000ull, 0x00000000000000ull, PM_GPS, 0 } +}; + +static unsigned char direct_marked_event[8] = { + (1<<2) | (1<<3), /* PMC1: PM_MRK_GRP_DISP, PM_MRK_ST_CMPL */ + (1<<3) | (1<<5), /* PMC2: PM_THRESH_TIMEO, PM_MRK_BRU_FIN */ + (1<<3), /* PMC3: PM_MRK_ST_CMPL_INT */ + (1<<4) | (1<<5), /* PMC4: PM_MRK_GRP_CMPL, PM_MRK_CRU_FIN */ + (1<<4) | (1<<5), /* PMC5: PM_MRK_GRP_TIMEO */ + (1<<3) | (1<<4) | (1<<5), + /* PMC6: PM_MRK_ST_GPS, PM_MRK_FXU_FIN, PM_MRK_GRP_ISSUED */ + (1<<4) | (1<<5), /* PMC7: PM_MRK_FPU_FIN, PM_MRK_INST_FIN */ + (1<<4), /* PMC8: PM_MRK_LSU_FIN */ +}; + +/* + * Returns 1 if event counts things relating to marked instructions + * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not. + */ +static int p4_marked_instr_event(unsigned int event) +{ + int pmc, psel, unit, byte, bit; + unsigned int mask; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + psel = event & PM_PMCSEL_MSK; + if (pmc) { + if (direct_marked_event[pmc - 1] & (1 << psel)) + return 1; + if (psel == 0) /* add events */ + bit = (pmc <= 4)? pmc - 1: 8 - pmc; + else if (psel == 6) /* decode events */ + bit = 4; + else + return 0; + } else + bit = psel; + + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; + mask = 0; + switch (unit) { + case PM_LSU1: + if (event & PM_LOWER_MSKS) + mask = 1 << 28; /* byte 7 bit 4 */ + else + mask = 6 << 24; /* byte 3 bits 1 and 2 */ + break; + case PM_LSU0: + /* byte 3, bit 3; byte 2 bits 0,2,3,4,5; byte 1 */ + mask = 0x083dff00; + } + return (mask >> (byte * 8 + bit)) & 1; +} + +static int p4_get_constraint(unsigned int event, u64 *maskp, u64 *valp) +{ + int pmc, byte, unit, lower, sh; + u64 mask = 0, value = 0; + int grp = -1; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc > 8) + return -1; + sh = (pmc - 1) * 2; + mask |= 2 << sh; + value |= 1 << sh; + grp = ((pmc - 1) >> 1) & 1; + } + unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + if (unit) { + lower = (event >> PM_LOWER_SH) & PM_LOWER_MSK; + + /* + * Bus events on bytes 0 and 2 can be counted + * on PMC1/2/5/6; bytes 1 and 3 on PMC3/4/7/8. + */ + if (!pmc) + grp = byte & 1; + + if (!p4_unitinfo[unit].unit) + return -1; + mask |= p4_unitinfo[unit].mask; + value |= p4_unitinfo[unit].value; + sh = p4_unitinfo[unit].lowerbit; + if (sh > 1) + value |= (u64)lower << sh; + else if (lower != sh) + return -1; + unit = p4_unitinfo[unit].unit; + + /* Set byte lane select field */ + mask |= 0xfULL << (28 - 4 * byte); + value |= (u64)unit << (28 - 4 * byte); + } + if (grp == 0) { + /* increment PMC1/2/5/6 field */ + mask |= 0x8000000000ull; + value |= 0x1000000000ull; + } else { + /* increment PMC3/4/7/8 field */ + mask |= 0x800000000ull; + value |= 0x100000000ull; + } + + /* Marked instruction events need sample_enable set */ + if (p4_marked_instr_event(event)) { + mask |= 1ull << 56; + value |= 1ull << 56; + } + + /* PMCSEL=6 decode events on byte 2 need sample_enable clear */ + if (pmc && (event & PM_PMCSEL_MSK) == 6 && byte == 2) + mask |= 1ull << 56; + + *maskp = mask; + *valp = value; + return 0; +} + +static unsigned int ppc_inst_cmpl[] = { + 0x1001, 0x4001, 0x6001, 0x7001, 0x8001 +}; + +static int p4_get_alternatives(unsigned int event, unsigned int alt[]) +{ + int i, j, na; + + alt[0] = event; + na = 1; + + /* 2 possibilities for PM_GRP_DISP_REJECT */ + if (event == 0x8003 || event == 0x0224) { + alt[1] = event ^ (0x8003 ^ 0x0224); + return 2; + } + + /* 2 possibilities for PM_ST_MISS_L1 */ + if (event == 0x0c13 || event == 0x0c23) { + alt[1] = event ^ (0x0c13 ^ 0x0c23); + return 2; + } + + /* several possibilities for PM_INST_CMPL */ + for (i = 0; i < ARRAY_SIZE(ppc_inst_cmpl); ++i) { + if (event == ppc_inst_cmpl[i]) { + for (j = 0; j < ARRAY_SIZE(ppc_inst_cmpl); ++j) + if (j != i) + alt[na++] = ppc_inst_cmpl[j]; + break; + } + } + + return na; +} + +static int p4_compute_mmcr(unsigned int event[], int n_ev, + unsigned int hwc[], u64 mmcr[]) +{ + u64 mmcr0 = 0, mmcr1 = 0, mmcra = 0; + unsigned int pmc, unit, byte, psel, lower; + unsigned int ttm, grp; + unsigned int pmc_inuse = 0; + unsigned int pmc_grp_use[2]; + unsigned char busbyte[4]; + unsigned char unituse[16]; + unsigned int unitlower = 0; + int i; + + if (n_ev > 8) + return -1; + + /* First pass to count resource use */ + pmc_grp_use[0] = pmc_grp_use[1] = 0; + memset(busbyte, 0, sizeof(busbyte)); + memset(unituse, 0, sizeof(unituse)); + for (i = 0; i < n_ev; ++i) { + pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; + if (pmc) { + if (pmc_inuse & (1 << (pmc - 1))) + return -1; + pmc_inuse |= 1 << (pmc - 1); + /* count 1/2/5/6 vs 3/4/7/8 use */ + ++pmc_grp_use[((pmc - 1) >> 1) & 1]; + } + unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK; + byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK; + lower = (event[i] >> PM_LOWER_SH) & PM_LOWER_MSK; + if (unit) { + if (!pmc) + ++pmc_grp_use[byte & 1]; + if (unit == 6 || unit == 8) + /* map alt ISU1/IFU codes: 6->2, 8->3 */ + unit = (unit >> 1) - 1; + if (busbyte[byte] && busbyte[byte] != unit) + return -1; + busbyte[byte] = unit; + lower <<= unit; + if (unituse[unit] && lower != (unitlower & lower)) + return -1; + unituse[unit] = 1; + unitlower |= lower; + } + } + if (pmc_grp_use[0] > 4 || pmc_grp_use[1] > 4) + return -1; + + /* + * Assign resources and set multiplexer selects. + * + * Units 1,2,3 are on TTM0, 4,6,7 on TTM1, 8,10 on TTM2. + * Each TTMx can only select one unit, but since + * units 2 and 6 are both ISU1, and 3 and 8 are both IFU, + * we have some choices. + */ + if (unituse[2] & (unituse[1] | (unituse[3] & unituse[9]))) { + unituse[6] = 1; /* Move 2 to 6 */ + unituse[2] = 0; + } + if (unituse[3] & (unituse[1] | unituse[2])) { + unituse[8] = 1; /* Move 3 to 8 */ + unituse[3] = 0; + unitlower = (unitlower & ~8) | ((unitlower & 8) << 5); + } + /* Check only one unit per TTMx */ + if (unituse[1] + unituse[2] + unituse[3] > 1 || + unituse[4] + unituse[6] + unituse[7] > 1 || + unituse[8] + unituse[9] > 1 || + (unituse[5] | unituse[10] | unituse[11] | + unituse[13] | unituse[14])) + return -1; + + /* Set TTMxSEL fields. Note, units 1-3 => TTM0SEL codes 0-2 */ + mmcr1 |= (u64)(unituse[3] * 2 + unituse[2]) << MMCR1_TTM0SEL_SH; + mmcr1 |= (u64)(unituse[7] * 3 + unituse[6] * 2) << MMCR1_TTM1SEL_SH; + mmcr1 |= (u64)unituse[9] << MMCR1_TTM2SEL_SH; + + /* Set TTCxSEL fields. */ + if (unitlower & 0xe) + mmcr1 |= 1ull << MMCR1_TTC0SEL_SH; + if (unitlower & 0xf0) + mmcr1 |= 1ull << MMCR1_TTC1SEL_SH; + if (unitlower & 0xf00) + mmcr1 |= 1ull << MMCR1_TTC2SEL_SH; + if (unitlower & 0x7000) + mmcr1 |= 1ull << MMCR1_TTC3SEL_SH; + + /* Set byte lane select fields. */ + for (byte = 0; byte < 4; ++byte) { + unit = busbyte[byte]; + if (!unit) + continue; + if (unit == 0xf) { + /* special case for GPS */ + mmcr1 |= 1ull << (MMCR1_DEBUG0SEL_SH - byte); + } else { + if (!unituse[unit]) + ttm = unit - 1; /* 2->1, 3->2 */ + else + ttm = unit >> 2; + mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2*byte); + } + } + + /* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */ + for (i = 0; i < n_ev; ++i) { + pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; + unit = (event[i] >> PM_UNIT_SH) & PM_UNIT_MSK; + byte = (event[i] >> PM_BYTE_SH) & PM_BYTE_MSK; + psel = event[i] & PM_PMCSEL_MSK; + if (!pmc) { + /* Bus event or 00xxx direct event (off or cycles) */ + if (unit) + psel |= 0x10 | ((byte & 2) << 2); + for (pmc = 0; pmc < 8; ++pmc) { + if (pmc_inuse & (1 << pmc)) + continue; + grp = (pmc >> 1) & 1; + if (unit) { + if (grp == (byte & 1)) + break; + } else if (pmc_grp_use[grp] < 4) { + ++pmc_grp_use[grp]; + break; + } + } + pmc_inuse |= 1 << pmc; + } else { + /* Direct event */ + --pmc; + if (psel == 0 && (byte & 2)) + /* add events on higher-numbered bus */ + mmcr1 |= 1ull << mmcr1_adder_bits[pmc]; + else if (psel == 6 && byte == 3) + /* seem to need to set sample_enable here */ + mmcra |= MMCRA_SAMPLE_ENABLE; + psel |= 8; + } + if (pmc <= 1) + mmcr0 |= psel << (MMCR0_PMC1SEL_SH - 7 * pmc); + else + mmcr1 |= psel << (MMCR1_PMC3SEL_SH - 5 * (pmc - 2)); + if (pmc == 7) /* PMC8 */ + mmcra |= (psel & 1) << MMCRA_PMC8SEL0_SH; + hwc[i] = pmc; + if (p4_marked_instr_event(event[i])) + mmcra |= MMCRA_SAMPLE_ENABLE; + } + + if (pmc_inuse & 1) + mmcr0 |= MMCR0_PMC1CE; + if (pmc_inuse & 0xfe) + mmcr0 |= MMCR0_PMCjCE; + + mmcra |= 0x2000; /* mark only one IOP per PPC instruction */ + + /* Return MMCRx values */ + mmcr[0] = mmcr0; + mmcr[1] = mmcr1; + mmcr[2] = mmcra; + return 0; +} + +static void p4_disable_pmc(unsigned int pmc, u64 mmcr[]) +{ + /* + * Setting the PMCxSEL field to 0 disables PMC x. + * (Note that pmc is 0-based here, not 1-based.) + */ + if (pmc <= 1) { + mmcr[0] &= ~(0x1fUL << (MMCR0_PMC1SEL_SH - 7 * pmc)); + } else { + mmcr[1] &= ~(0x1fUL << (MMCR1_PMC3SEL_SH - 5 * (pmc - 2))); + if (pmc == 7) + mmcr[2] &= ~(1UL << MMCRA_PMC8SEL0_SH); + } +} + +static int p4_generic_events[] = { + [PERF_COUNT_CPU_CYCLES] = 7, + [PERF_COUNT_INSTRUCTIONS] = 0x1001, + [PERF_COUNT_CACHE_REFERENCES] = 0x8c10, /* PM_LD_REF_L1 */ + [PERF_COUNT_CACHE_MISSES] = 0x3c10, /* PM_LD_MISS_L1 */ + [PERF_COUNT_BRANCH_INSTRUCTIONS] = 0x330, /* PM_BR_ISSUED */ + [PERF_COUNT_BRANCH_MISSES] = 0x331, /* PM_BR_MPRED_CR */ +}; + +struct power_pmu power4_pmu = { + .n_counter = 8, + .max_alternatives = 5, + .add_fields = 0x0000001100005555ull, + .test_adder = 0x0011083300000000ull, + .compute_mmcr = p4_compute_mmcr, + .get_constraint = p4_get_constraint, + .get_alternatives = p4_get_alternatives, + .disable_pmc = p4_disable_pmc, + .n_generic = ARRAY_SIZE(p4_generic_events), + .generic_events = p4_generic_events, +}; -- GitLab From 184fe4ab1f2e4dfa45584889bb3820031648386b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 8 Mar 2009 11:34:19 +0100 Subject: [PATCH 0098/6080] x86: perf_counter cleanup Use and actual unsigned long bitmap instead of casting our way around. Signed-off-by: Peter Zijlstra Cc: Jaswinder Singh Rajput LKML-Reference: <1236508459.22914.3645.camel@twins> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index f5853718d4d3..1df421042b2a 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -37,7 +37,7 @@ struct cpu_hw_counters { unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; unsigned long interrupts; u64 throttle_ctrl; - u64 active_mask; + unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; int enabled; }; @@ -291,7 +291,7 @@ static void pmc_amd_restore_all(u64 ctrl) return; for (idx = 0; idx < nr_counters_generic; idx++) { - if (test_bit(idx, (unsigned long *)&cpuc->active_mask)) { + if (test_bit(idx, cpuc->active_mask)) { u64 val; rdmsrl(MSR_K7_EVNTSEL0 + idx, val); @@ -377,7 +377,7 @@ static void pmc_amd_enable(int idx, u64 config) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); - set_bit(idx, (unsigned long *)&cpuc->active_mask); + set_bit(idx, cpuc->active_mask); if (cpuc->enabled) config |= ARCH_PERFMON_EVENTSEL0_ENABLE; @@ -401,7 +401,7 @@ static void pmc_amd_disable(int idx, u64 config) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); - clear_bit(idx, (unsigned long *)&cpuc->active_mask); + clear_bit(idx, cpuc->active_mask); wrmsrl(MSR_K7_EVNTSEL0 + idx, config); } -- GitLab From e255357764f92afcafafbd4879b222b8c752065a Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sun, 8 Mar 2009 17:09:49 +0530 Subject: [PATCH 0099/6080] x86: perf_counter cleanup Remove unused variables and duplicate header file. Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 1df421042b2a..155bc3c239b6 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -17,7 +17,6 @@ #include #include -#include #include static bool perf_counters_initialized __read_mostly; @@ -954,9 +953,6 @@ static struct pmc_x86_ops *pmc_intel_init(void) static struct pmc_x86_ops *pmc_amd_init(void) { - u64 old; - int bits; - nr_counters_generic = 4; nr_counters_fixed = 0; counter_value_mask = 0x0000FFFFFFFFFFFFULL; -- GitLab From 8a6f83afd0c5355db6d11394a798e94950306239 Mon Sep 17 00:00:00 2001 From: KaiGai Kohei Date: Wed, 1 Apr 2009 10:07:57 +0900 Subject: [PATCH 0100/6080] Permissive domain in userspace object manager This patch enables applications to handle permissive domain correctly. Since the v2.6.26 kernel, SELinux has supported an idea of permissive domain which allows certain processes to work as if permissive mode, even if the global setting is enforcing mode. However, we don't have an application program interface to inform what domains are permissive one, and what domains are not. It means applications focuses on SELinux (XACE/SELinux, SE-PostgreSQL and so on) cannot handle permissive domain correctly. This patch add the sixth field (flags) on the reply of the /selinux/access interface which is used to make an access control decision from userspace. If the first bit of the flags field is positive, it means the required access control decision is on permissive domain, so application should allow any required actions, as the kernel doing. This patch also has a side benefit. The av_decision.flags is set at context_struct_compute_av(). It enables to check required permissions without read_lock(&policy_rwlock). Signed-off-by: KaiGai Kohei Acked-by: Stephen Smalley Acked-by: Eric Paris -- security/selinux/avc.c | 2 +- security/selinux/include/security.h | 4 +++- security/selinux/selinuxfs.c | 4 ++-- security/selinux/ss/services.c | 30 +++++------------------------- 4 files changed, 11 insertions(+), 29 deletions(-) Signed-off-by: James Morris --- security/selinux/avc.c | 2 +- security/selinux/include/security.h | 4 +++- security/selinux/selinuxfs.c | 4 ++-- security/selinux/ss/services.c | 30 +++++------------------------ 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 7f9b5fac8779..b2ab60859832 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -927,7 +927,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, if (denied) { if (flags & AVC_STRICT) rc = -EACCES; - else if (!selinux_enforcing || security_permissive_sid(ssid)) + else if (!selinux_enforcing || (avd->flags & AVD_FLAGS_PERMISSIVE)) avc_update_node(AVC_CALLBACK_GRANT, requested, ssid, tsid, tclass, avd->seqno); else diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 5c3434f7626f..a7be3f01fb08 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -91,9 +91,11 @@ struct av_decision { u32 auditallow; u32 auditdeny; u32 seqno; + u32 flags; }; -int security_permissive_sid(u32 sid); +/* definitions of av_decision.flags */ +#define AVD_FLAGS_PERMISSIVE 0x0001 int security_compute_av(u32 ssid, u32 tsid, u16 tclass, u32 requested, diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 2d5136ec3d54..8d4007fbe0e9 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -527,10 +527,10 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) goto out2; length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, - "%x %x %x %x %u", + "%x %x %x %x %u %x", avd.allowed, 0xffffffff, avd.auditallow, avd.auditdeny, - avd.seqno); + avd.seqno, avd.flags); out2: kfree(tcon); out: diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index deeec6c013ae..500e6f78e115 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -410,6 +410,7 @@ static int context_struct_compute_av(struct context *scontext, avd->auditallow = 0; avd->auditdeny = 0xffffffff; avd->seqno = latest_granting; + avd->flags = 0; /* * Check for all the invalid cases. @@ -528,31 +529,6 @@ inval_class: return 0; } -/* - * Given a sid find if the type has the permissive flag set - */ -int security_permissive_sid(u32 sid) -{ - struct context *context; - u32 type; - int rc; - - read_lock(&policy_rwlock); - - context = sidtab_search(&sidtab, sid); - BUG_ON(!context); - - type = context->type; - /* - * we are intentionally using type here, not type-1, the 0th bit may - * someday indicate that we are globally setting permissive in policy. - */ - rc = ebitmap_get_bit(&policydb.permissive_map, type); - - read_unlock(&policy_rwlock); - return rc; -} - static int security_validtrans_handle_fail(struct context *ocontext, struct context *ncontext, struct context *tcontext, @@ -767,6 +743,10 @@ int security_compute_av(u32 ssid, rc = context_struct_compute_av(scontext, tcontext, tclass, requested, avd); + + /* permissive domain? */ + if (ebitmap_get_bit(&policydb.permissive_map, scontext->type)) + avd->flags |= AVD_FLAGS_PERMISSIVE; out: read_unlock(&policy_rwlock); return rc; -- GitLab From 3d43321b7015387cfebbe26436d0e9d299162ea1 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 2 Apr 2009 15:49:29 -0700 Subject: [PATCH 0101/6080] modules: sysctl to block module loading Implement a sysctl file that disables module-loading system-wide since there is no longer a viable way to remove CAP_SYS_MODULE after the system bounding capability set was removed in 2.6.25. Value can only be set to "1", and is tested only if standard capability checks allow CAP_SYS_MODULE. Given existing /dev/mem protections, this should allow administrators a one-way method to block module loading after initial boot-time module loading has finished. Signed-off-by: Kees Cook Acked-by: Serge Hallyn Signed-off-by: James Morris --- Documentation/sysctl/kernel.txt | 11 +++++++++++ kernel/module.c | 7 +++++-- kernel/sysctl.c | 12 ++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index a4ccdd1981cf..02b134956273 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -30,6 +30,7 @@ show up in /proc/sys/kernel: - kstack_depth_to_print [ X86 only ] - l2cr [ PPC only ] - modprobe ==> Documentation/debugging-modules.txt +- modules_disabled - msgmax - msgmnb - msgmni @@ -179,6 +180,16 @@ kernel stack. ============================================================== +modules_disabled: + +A toggle value indicating if modules are allowed to be loaded +in an otherwise modular kernel. This toggle defaults to off +(0), but can be set true (1). Once true, modules can be +neither loaded nor unloaded, and the toggle cannot be set back +to false. + +============================================================== + osrelease, ostype & version: # cat osrelease diff --git a/kernel/module.c b/kernel/module.c index f77ac320d0b5..eeb3f7b1383c 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -778,6 +778,9 @@ static void wait_for_zero_refcount(struct module *mod) mutex_lock(&module_mutex); } +/* Block module loading/unloading? */ +int modules_disabled = 0; + SYSCALL_DEFINE2(delete_module, const char __user *, name_user, unsigned int, flags) { @@ -785,7 +788,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, char name[MODULE_NAME_LEN]; int ret, forced = 0; - if (!capable(CAP_SYS_MODULE)) + if (!capable(CAP_SYS_MODULE) || modules_disabled) return -EPERM; if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) @@ -2349,7 +2352,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod, int ret = 0; /* Must have permission */ - if (!capable(CAP_SYS_MODULE)) + if (!capable(CAP_SYS_MODULE) || modules_disabled) return -EPERM; /* Only one module load at a time, please */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c5ef44ff850f..2fb4246d27de 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -113,6 +113,7 @@ static int ngroups_max = NGROUPS_MAX; #ifdef CONFIG_MODULES extern char modprobe_path[]; +extern int modules_disabled; #endif #ifdef CONFIG_CHR_DEV_SG extern int sg_big_buff; @@ -533,6 +534,17 @@ static struct ctl_table kern_table[] = { .proc_handler = &proc_dostring, .strategy = &sysctl_string, }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "modules_disabled", + .data = &modules_disabled, + .maxlen = sizeof(int), + .mode = 0644, + /* only handle a transition from default "0" to "1" */ + .proc_handler = &proc_dointvec_minmax, + .extra1 = &one, + .extra2 = &one, + }, #endif #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) { -- GitLab From b5f22a59c0356655a501190959db9f7f5dd07e3f Mon Sep 17 00:00:00 2001 From: "Serge E. Hallyn" Date: Thu, 2 Apr 2009 18:47:14 -0500 Subject: [PATCH 0102/6080] don't raise all privs on setuid-root file with fE set (v2) Distributions face a backward compatibility problem with starting to use file capabilities. For instance, removing setuid root from ping and doing setcap cap_net_raw=pe means that booting with an older kernel or one compiled without file capabilities means ping won't work for non-root users. In order to replace the setuid root bit on a capability-unaware program, one has to set the effective, or legacy, file capability, which makes the capability effective immediately. This patch uses the legacy bit as a queue to not automatically add full privilege to a setuid-root program. So, with this patch, an ordinary setuid-root program will run with privilege. But if /bin/ping has both setuid-root and cap_net_raw in fP and fE, then ping (when run by non-root user) will not run with only cap_net_raw. Changelog: Apr 2 2009: Print a message once when such a binary is loaded, as per James Morris' suggestion. Apr 2 2009: Fix the condition to only catch uid!=0 && euid==0. Signed-off-by: Serge E. Hallyn Acked-by: Casey Schaufler Signed-off-by: James Morris --- security/commoncap.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/security/commoncap.c b/security/commoncap.c index 7cd61a5f5205..97ac1f167717 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -28,6 +28,28 @@ #include #include +/* + * If a non-root user executes a setuid-root binary in + * !secure(SECURE_NOROOT) mode, then we raise capabilities. + * However if fE is also set, then the intent is for only + * the file capabilities to be applied, and the setuid-root + * bit is left on either to change the uid (plausible) or + * to get full privilege on a kernel without file capabilities + * support. So in that case we do not raise capabilities. + * + * Warn if that happens, once per boot. + */ +static void warn_setuid_and_fcaps_mixed(char *fname) +{ + static int warned; + if (!warned) { + printk(KERN_INFO "warning: `%s' has both setuid-root and" + " effective capabilities. Therefore not raising all" + " capabilities.\n", fname); + warned = 1; + } +} + int cap_netlink_send(struct sock *sk, struct sk_buff *skb) { NETLINK_CB(skb).eff_cap = current_cap(); @@ -463,6 +485,15 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) return ret; if (!issecure(SECURE_NOROOT)) { + /* + * If the legacy file capability is set, then don't set privs + * for a setuid root binary run by a non-root user. Do set it + * for a root user just to cause least surprise to an admin. + */ + if (effective && new->uid != 0 && new->euid == 0) { + warn_setuid_and_fcaps_mixed(bprm->filename); + goto skip; + } /* * To support inheritance of root-permissions and suid-root * executables under compatibility mode, we override the @@ -478,6 +509,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) if (new->euid == 0) effective = true; } +skip: /* Don't let someone trace a set[ug]id/setpcap binary with the revised * credentials unless they have the appropriate permit -- GitLab From 4b166da939012905f4c36fedada62067db31948e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= Date: Sat, 28 Mar 2009 19:47:01 +0100 Subject: [PATCH 0103/6080] ASoC: Add driver for s6000 I2S interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds a driver for the I2S interface found on Stretch s6000 family processors. Signed-off-by: Daniel Glöckner Signed-off-by: Mark Brown --- sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/s6000/Kconfig | 10 + sound/soc/s6000/Makefile | 6 + sound/soc/s6000/s6000-i2s.c | 629 ++++++++++++++++++++++++++++++++++++ sound/soc/s6000/s6000-i2s.h | 25 ++ sound/soc/s6000/s6000-pcm.c | 497 ++++++++++++++++++++++++++++ sound/soc/s6000/s6000-pcm.h | 35 ++ 8 files changed, 1204 insertions(+) create mode 100644 sound/soc/s6000/Kconfig create mode 100644 sound/soc/s6000/Makefile create mode 100644 sound/soc/s6000/s6000-i2s.c create mode 100644 sound/soc/s6000/s6000-i2s.h create mode 100644 sound/soc/s6000/s6000-pcm.c create mode 100644 sound/soc/s6000/s6000-pcm.h diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 3d2bb6fc6dcc..3304f9dd92fa 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -32,6 +32,7 @@ source "sound/soc/fsl/Kconfig" source "sound/soc/omap/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/s3c24xx/Kconfig" +source "sound/soc/s6000/Kconfig" source "sound/soc/sh/Kconfig" # Supported codecs diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 0237879fd412..8943a140c818 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -10,4 +10,5 @@ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += omap/ obj-$(CONFIG_SND_SOC) += pxa/ obj-$(CONFIG_SND_SOC) += s3c24xx/ +obj-$(CONFIG_SND_SOC) += s6000/ obj-$(CONFIG_SND_SOC) += sh/ diff --git a/sound/soc/s6000/Kconfig b/sound/soc/s6000/Kconfig new file mode 100644 index 000000000000..4bfc8bcac51b --- /dev/null +++ b/sound/soc/s6000/Kconfig @@ -0,0 +1,10 @@ +config SND_S6000_SOC + tristate "SoC Audio for the Stretch s6000 family" + depends on XTENSA_VARIANT_S6000 + help + Say Y or M if you want to add support for codecs attached to + s6000 family chips. You will also need to select the platform + to support below. + +config SND_S6000_SOC_I2S + tristate diff --git a/sound/soc/s6000/Makefile b/sound/soc/s6000/Makefile new file mode 100644 index 000000000000..df15f876a1a9 --- /dev/null +++ b/sound/soc/s6000/Makefile @@ -0,0 +1,6 @@ +# s6000 Platform Support +snd-soc-s6000-objs := s6000-pcm.o +snd-soc-s6000-i2s-objs := s6000-i2s.o + +obj-$(CONFIG_SND_S6000_SOC) += snd-soc-s6000.o +obj-$(CONFIG_SND_S6000_SOC_I2S) += snd-soc-s6000-i2s.o diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c new file mode 100644 index 000000000000..dcc79040bdac --- /dev/null +++ b/sound/soc/s6000/s6000-i2s.c @@ -0,0 +1,629 @@ +/* + * ALSA SoC I2S Audio Layer for the Stretch S6000 family + * + * Author: Daniel Gloeckner, + * Copyright: (C) 2009 emlix GmbH + * + * 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 "s6000-i2s.h" +#include "s6000-pcm.h" + +struct s6000_i2s_dev { + dma_addr_t sifbase; + u8 __iomem *scbbase; + unsigned int wide; + unsigned int channel_in; + unsigned int channel_out; + unsigned int lines_in; + unsigned int lines_out; + struct s6000_pcm_dma_params dma_params; +}; + +#define S6_I2S_INTERRUPT_STATUS 0x00 +#define S6_I2S_INT_OVERRUN 1 +#define S6_I2S_INT_UNDERRUN 2 +#define S6_I2S_INT_ALIGNMENT 4 +#define S6_I2S_INTERRUPT_ENABLE 0x04 +#define S6_I2S_INTERRUPT_RAW 0x08 +#define S6_I2S_INTERRUPT_CLEAR 0x0C +#define S6_I2S_INTERRUPT_SET 0x10 +#define S6_I2S_MODE 0x20 +#define S6_I2S_DUAL 0 +#define S6_I2S_WIDE 1 +#define S6_I2S_TX_DEFAULT 0x24 +#define S6_I2S_DATA_CFG(c) (0x40 + 0x10 * (c)) +#define S6_I2S_IN 0 +#define S6_I2S_OUT 1 +#define S6_I2S_UNUSED 2 +#define S6_I2S_INTERFACE_CFG(c) (0x44 + 0x10 * (c)) +#define S6_I2S_DIV_MASK 0x001fff +#define S6_I2S_16BIT 0x000000 +#define S6_I2S_20BIT 0x002000 +#define S6_I2S_24BIT 0x004000 +#define S6_I2S_32BIT 0x006000 +#define S6_I2S_BITS_MASK 0x006000 +#define S6_I2S_MEM_16BIT 0x000000 +#define S6_I2S_MEM_32BIT 0x008000 +#define S6_I2S_MEM_MASK 0x008000 +#define S6_I2S_CHANNELS_SHIFT 16 +#define S6_I2S_CHANNELS_MASK 0x030000 +#define S6_I2S_SCK_IN 0x000000 +#define S6_I2S_SCK_OUT 0x040000 +#define S6_I2S_SCK_DIR 0x040000 +#define S6_I2S_WS_IN 0x000000 +#define S6_I2S_WS_OUT 0x080000 +#define S6_I2S_WS_DIR 0x080000 +#define S6_I2S_LEFT_FIRST 0x000000 +#define S6_I2S_RIGHT_FIRST 0x100000 +#define S6_I2S_FIRST 0x100000 +#define S6_I2S_CUR_SCK 0x200000 +#define S6_I2S_CUR_WS 0x400000 +#define S6_I2S_ENABLE(c) (0x48 + 0x10 * (c)) +#define S6_I2S_DISABLE_IF 0x02 +#define S6_I2S_ENABLE_IF 0x03 +#define S6_I2S_IS_BUSY 0x04 +#define S6_I2S_DMA_ACTIVE 0x08 +#define S6_I2S_IS_ENABLED 0x10 + +#define S6_I2S_NUM_LINES 4 + +#define S6_I2S_SIF_PORT0 0x0000000 +#define S6_I2S_SIF_PORT1 0x0000080 /* docs say 0x0000010 */ + +static inline void s6_i2s_write_reg(struct s6000_i2s_dev *dev, int reg, u32 val) +{ + writel(val, dev->scbbase + reg); +} + +static inline u32 s6_i2s_read_reg(struct s6000_i2s_dev *dev, int reg) +{ + return readl(dev->scbbase + reg); +} + +static inline void s6_i2s_mod_reg(struct s6000_i2s_dev *dev, int reg, + u32 mask, u32 val) +{ + val ^= s6_i2s_read_reg(dev, reg) & ~mask; + s6_i2s_write_reg(dev, reg, val); +} + +static void s6000_i2s_start_channel(struct s6000_i2s_dev *dev, int channel) +{ + int i, j, cur, prev; + + /* + * Wait for WCLK to toggle 5 times before enabling the channel + * s6000 Family Datasheet 3.6.4: + * "At least two cycles of WS must occur between commands + * to disable or enable the interface" + */ + j = 0; + prev = ~S6_I2S_CUR_WS; + for (i = 1000000; --i && j < 6; ) { + cur = s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(channel)) + & S6_I2S_CUR_WS; + if (prev != cur) { + prev = cur; + j++; + } + } + if (j < 6) + printk(KERN_WARNING "s6000-i2s: timeout waiting for WCLK\n"); + + s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_ENABLE_IF); +} + +static void s6000_i2s_stop_channel(struct s6000_i2s_dev *dev, int channel) +{ + s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_DISABLE_IF); +} + +static void s6000_i2s_start(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data; + int channel; + + channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + dev->channel_out : dev->channel_in; + + s6000_i2s_start_channel(dev, channel); +} + +static void s6000_i2s_stop(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data; + int channel; + + channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + dev->channel_out : dev->channel_in; + + s6000_i2s_stop_channel(dev, channel); +} + +static int s6000_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + int after) +{ + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ^ !after) + s6000_i2s_start(substream); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (!after) + s6000_i2s_stop(substream); + } + return 0; +} + +static unsigned int s6000_i2s_int_sources(struct s6000_i2s_dev *dev) +{ + unsigned int pending; + pending = s6_i2s_read_reg(dev, S6_I2S_INTERRUPT_RAW); + pending &= S6_I2S_INT_ALIGNMENT | + S6_I2S_INT_UNDERRUN | + S6_I2S_INT_OVERRUN; + s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR, pending); + + return pending; +} + +static unsigned int s6000_i2s_check_xrun(struct snd_soc_dai *cpu_dai) +{ + struct s6000_i2s_dev *dev = cpu_dai->private_data; + unsigned int errors; + unsigned int ret; + + errors = s6000_i2s_int_sources(dev); + if (likely(!errors)) + return 0; + + ret = 0; + if (errors & S6_I2S_INT_ALIGNMENT) + printk(KERN_ERR "s6000-i2s: WCLK misaligned\n"); + if (errors & S6_I2S_INT_UNDERRUN) + ret |= 1 << SNDRV_PCM_STREAM_PLAYBACK; + if (errors & S6_I2S_INT_OVERRUN) + ret |= 1 << SNDRV_PCM_STREAM_CAPTURE; + return ret; +} + +static void s6000_i2s_wait_disabled(struct s6000_i2s_dev *dev) +{ + int channel; + int n = 50; + for (channel = 0; channel < 2; channel++) { + while (--n >= 0) { + int v = s6_i2s_read_reg(dev, S6_I2S_ENABLE(channel)); + if ((v & S6_I2S_IS_ENABLED) + || !(v & (S6_I2S_DMA_ACTIVE | S6_I2S_IS_BUSY))) + break; + udelay(20); + } + } + if (n < 0) + printk(KERN_WARNING "s6000-i2s: timeout disabling interfaces"); +} + +static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct s6000_i2s_dev *dev = cpu_dai->private_data; + u32 w; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + w = S6_I2S_SCK_IN | S6_I2S_WS_IN; + break; + case SND_SOC_DAIFMT_CBS_CFM: + w = S6_I2S_SCK_OUT | S6_I2S_WS_IN; + break; + case SND_SOC_DAIFMT_CBM_CFS: + w = S6_I2S_SCK_IN | S6_I2S_WS_OUT; + break; + case SND_SOC_DAIFMT_CBS_CFS: + w = S6_I2S_SCK_OUT | S6_I2S_WS_OUT; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_IB_IF: + w |= S6_I2S_LEFT_FIRST; + break; + case SND_SOC_DAIFMT_IB_NF: + w |= S6_I2S_RIGHT_FIRST; + break; + default: + return -EINVAL; + } + + s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(0), + S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w); + s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(1), + S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w); + + return 0; +} + +static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) +{ + struct s6000_i2s_dev *dev = dai->private_data; + + if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2) + return -EINVAL; + + s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(div_id), + S6_I2S_DIV_MASK, div / 2 - 1); + return 0; +} + +static int s6000_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct s6000_i2s_dev *dev = dai->private_data; + int interf; + u32 w = 0; + + if (dev->wide) + interf = 0; + else { + w |= (((params_channels(params) - 2) / 2) + << S6_I2S_CHANNELS_SHIFT) & S6_I2S_CHANNELS_MASK; + interf = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ? dev->channel_out : dev->channel_in; + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + w |= S6_I2S_16BIT | S6_I2S_MEM_16BIT; + break; + case SNDRV_PCM_FORMAT_S32_LE: + w |= S6_I2S_32BIT | S6_I2S_MEM_32BIT; + break; + default: + printk(KERN_WARNING "s6000-i2s: unsupported PCM format %x\n", + params_format(params)); + return -EINVAL; + } + + if (s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(interf)) + & S6_I2S_IS_ENABLED) { + printk(KERN_ERR "s6000-i2s: interface already enabled\n"); + return -EBUSY; + } + + s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(interf), + S6_I2S_CHANNELS_MASK|S6_I2S_MEM_MASK|S6_I2S_BITS_MASK, + w); + + return 0; +} + +static int s6000_i2s_dai_probe(struct platform_device *pdev, + struct snd_soc_dai *dai) +{ + struct s6000_i2s_dev *dev = dai->private_data; + struct s6000_snd_platform_data *pdata = pdev->dev.platform_data; + + if (!pdata) + return -EINVAL; + + dev->wide = pdata->wide; + dev->channel_in = pdata->channel_in; + dev->channel_out = pdata->channel_out; + dev->lines_in = pdata->lines_in; + dev->lines_out = pdata->lines_out; + + s6_i2s_write_reg(dev, S6_I2S_MODE, + dev->wide ? S6_I2S_WIDE : S6_I2S_DUAL); + + if (dev->wide) { + int i; + + if (dev->lines_in + dev->lines_out > S6_I2S_NUM_LINES) + return -EINVAL; + + dev->channel_in = 0; + dev->channel_out = 1; + dai->capture.channels_min = 2 * dev->lines_in; + dai->capture.channels_max = dai->capture.channels_min; + dai->playback.channels_min = 2 * dev->lines_out; + dai->playback.channels_max = dai->playback.channels_min; + + for (i = 0; i < dev->lines_out; i++) + s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_OUT); + + for (; i < S6_I2S_NUM_LINES - dev->lines_in; i++) + s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), + S6_I2S_UNUSED); + + for (; i < S6_I2S_NUM_LINES; i++) + s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_IN); + } else { + unsigned int cfg[2] = {S6_I2S_UNUSED, S6_I2S_UNUSED}; + + if (dev->lines_in > 1 || dev->lines_out > 1) + return -EINVAL; + + dai->capture.channels_min = 2 * dev->lines_in; + dai->capture.channels_max = 8 * dev->lines_in; + dai->playback.channels_min = 2 * dev->lines_out; + dai->playback.channels_max = 8 * dev->lines_out; + + if (dev->lines_in) + cfg[dev->channel_in] = S6_I2S_IN; + if (dev->lines_out) + cfg[dev->channel_out] = S6_I2S_OUT; + + s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(0), cfg[0]); + s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(1), cfg[1]); + } + + if (dev->lines_out) { + if (dev->lines_in) { + if (!dev->dma_params.dma_out) + return -ENODEV; + } else { + dev->dma_params.dma_out = dev->dma_params.dma_in; + dev->dma_params.dma_in = 0; + } + } + dev->dma_params.sif_in = dev->sifbase + (dev->channel_in ? + S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0); + dev->dma_params.sif_out = dev->sifbase + (dev->channel_out ? + S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0); + dev->dma_params.same_rate = pdata->same_rate | pdata->wide; + return 0; +} + +#define S6000_I2S_RATES (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \ + SNDRV_PCM_RATE_8000_192000) +#define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops s6000_i2s_dai_ops = { + .set_fmt = s6000_i2s_set_dai_fmt, + .set_clkdiv = s6000_i2s_set_clkdiv, + .hw_params = s6000_i2s_hw_params, +}; + +struct snd_soc_dai s6000_i2s_dai = { + .name = "s6000-i2s", + .id = 0, + .probe = s6000_i2s_dai_probe, + .playback = { + .channels_min = 2, + .channels_max = 8, + .formats = S6000_I2S_FORMATS, + .rates = S6000_I2S_RATES, + .rate_min = 0, + .rate_max = 1562500, + }, + .capture = { + .channels_min = 2, + .channels_max = 8, + .formats = S6000_I2S_FORMATS, + .rates = S6000_I2S_RATES, + .rate_min = 0, + .rate_max = 1562500, + }, + .ops = &s6000_i2s_dai_ops, +} +EXPORT_SYMBOL_GPL(s6000_i2s_dai); + +static int __devinit s6000_i2s_probe(struct platform_device *pdev) +{ + struct s6000_i2s_dev *dev; + struct resource *scbmem, *sifmem, *region, *dma1, *dma2; + u8 __iomem *mmio; + int ret; + + scbmem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!scbmem) { + dev_err(&pdev->dev, "no mem resource?\n"); + ret = -ENODEV; + goto err_release_none; + } + + region = request_mem_region(scbmem->start, + scbmem->end - scbmem->start + 1, + pdev->name); + if (!region) { + dev_err(&pdev->dev, "I2S SCB region already claimed\n"); + ret = -EBUSY; + goto err_release_none; + } + + mmio = ioremap(scbmem->start, scbmem->end - scbmem->start + 1); + if (!mmio) { + dev_err(&pdev->dev, "can't ioremap SCB region\n"); + ret = -ENOMEM; + goto err_release_scb; + } + + sifmem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!sifmem) { + dev_err(&pdev->dev, "no second mem resource?\n"); + ret = -ENODEV; + goto err_release_map; + } + + region = request_mem_region(sifmem->start, + sifmem->end - sifmem->start + 1, + pdev->name); + if (!region) { + dev_err(&pdev->dev, "I2S SIF region already claimed\n"); + ret = -EBUSY; + goto err_release_map; + } + + dma1 = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dma1) { + dev_err(&pdev->dev, "no dma resource?\n"); + ret = -ENODEV; + goto err_release_sif; + } + + region = request_mem_region(dma1->start, dma1->end - dma1->start + 1, + pdev->name); + if (!region) { + dev_err(&pdev->dev, "I2S DMA region already claimed\n"); + ret = -EBUSY; + goto err_release_sif; + } + + dma2 = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (dma2) { + region = request_mem_region(dma2->start, + dma2->end - dma2->start + 1, + pdev->name); + if (!region) { + dev_err(&pdev->dev, + "I2S DMA region already claimed\n"); + ret = -EBUSY; + goto err_release_dma1; + } + } + + dev = kzalloc(sizeof(struct s6000_i2s_dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto err_release_dma2; + } + + s6000_i2s_dai.dev = &pdev->dev; + s6000_i2s_dai.private_data = dev; + s6000_i2s_dai.dma_data = &dev->dma_params; + + dev->sifbase = sifmem->start; + dev->scbbase = mmio; + + s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0); + s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR, + S6_I2S_INT_ALIGNMENT | + S6_I2S_INT_UNDERRUN | + S6_I2S_INT_OVERRUN); + + s6000_i2s_stop_channel(dev, 0); + s6000_i2s_stop_channel(dev, 1); + s6000_i2s_wait_disabled(dev); + + dev->dma_params.check_xrun = s6000_i2s_check_xrun; + dev->dma_params.trigger = s6000_i2s_trigger; + dev->dma_params.dma_in = dma1->start; + dev->dma_params.dma_out = dma2 ? dma2->start : 0; + dev->dma_params.irq = platform_get_irq(pdev, 0); + if (dev->dma_params.irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + ret = -ENODEV; + goto err_release_dev; + } + + s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, + S6_I2S_INT_ALIGNMENT | + S6_I2S_INT_UNDERRUN | + S6_I2S_INT_OVERRUN); + + ret = snd_soc_register_dai(&s6000_i2s_dai); + if (ret) + goto err_release_dev; + + return 0; + +err_release_dev: + kfree(dev); +err_release_dma2: + if (dma2) + release_mem_region(dma2->start, dma2->end - dma2->start + 1); +err_release_dma1: + release_mem_region(dma1->start, dma1->end - dma1->start + 1); +err_release_sif: + release_mem_region(sifmem->start, (sifmem->end - sifmem->start) + 1); +err_release_map: + iounmap(mmio); +err_release_scb: + release_mem_region(scbmem->start, (scbmem->end - scbmem->start) + 1); +err_release_none: + return ret; +} + +static void __devexit s6000_i2s_remove(struct platform_device *pdev) +{ + struct s6000_i2s_dev *dev = s6000_i2s_dai.private_data; + struct resource *region; + void __iomem *mmio = dev->scbbase; + + snd_soc_unregister_dai(&s6000_i2s_dai); + + s6000_i2s_stop_channel(dev, 0); + s6000_i2s_stop_channel(dev, 1); + + s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0); + s6000_i2s_dai.private_data = 0; + kfree(dev); + + region = platform_get_resource(pdev, IORESOURCE_DMA, 0); + release_mem_region(region->start, region->end - region->start + 1); + + region = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (region) + release_mem_region(region->start, + region->end - region->start + 1); + + region = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(region->start, (region->end - region->start) + 1); + + iounmap(mmio); + region = platform_get_resource(pdev, IORESOURCE_IO, 0); + release_mem_region(region->start, (region->end - region->start) + 1); +} + +static struct platform_driver s6000_i2s_driver = { + .probe = s6000_i2s_probe, + .remove = __devexit_p(s6000_i2s_remove), + .driver = { + .name = "s6000-i2s", + .owner = THIS_MODULE, + }, +}; + +static int __init s6000_i2s_init(void) +{ + return platform_driver_register(&s6000_i2s_driver); +} +module_init(s6000_i2s_init); + +static void __exit s6000_i2s_exit(void) +{ + platform_driver_unregister(&s6000_i2s_driver); +} +module_exit(s6000_i2s_exit); + +MODULE_AUTHOR("Daniel Gloeckner"); +MODULE_DESCRIPTION("Stretch s6000 family I2S SoC Interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/s6000/s6000-i2s.h b/sound/soc/s6000/s6000-i2s.h new file mode 100644 index 000000000000..2375fdfe6dba --- /dev/null +++ b/sound/soc/s6000/s6000-i2s.h @@ -0,0 +1,25 @@ +/* + * ALSA SoC I2S Audio Layer for the Stretch s6000 family + * + * Author: Daniel Gloeckner, + * Copyright: (C) 2009 emlix GmbH + * + * 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 _S6000_I2S_H +#define _S6000_I2S_H + +extern struct snd_soc_dai s6000_i2s_dai; + +struct s6000_snd_platform_data { + int lines_in; + int lines_out; + int channel_in; + int channel_out; + int wide; + int same_rate; +}; +#endif diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c new file mode 100644 index 000000000000..83b8028e209d --- /dev/null +++ b/sound/soc/s6000/s6000-pcm.c @@ -0,0 +1,497 @@ +/* + * ALSA PCM interface for the Stetch s6000 family + * + * Author: Daniel Gloeckner, + * Copyright: (C) 2009 emlix GmbH + * + * 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 "s6000-pcm.h" + +#define S6_PCM_PREALLOCATE_SIZE (96 * 1024) +#define S6_PCM_PREALLOCATE_MAX (2048 * 1024) + +static struct snd_pcm_hardware s6000_pcm_hardware = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_JOINT_DUPLEX), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE), + .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \ + SNDRV_PCM_RATE_8000_192000), + .rate_min = 0, + .rate_max = 1562500, + .channels_min = 2, + .channels_max = 8, + .buffer_bytes_max = 0x7ffffff0, + .period_bytes_min = 16, + .period_bytes_max = 0xfffff0, + .periods_min = 2, + .periods_max = 1024, /* no limit */ + .fifo_size = 0, +}; + +struct s6000_runtime_data { + spinlock_t lock; + int period; /* current DMA period */ +}; + +static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s6000_runtime_data *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + int channel; + unsigned int period_size; + unsigned int dma_offset; + dma_addr_t dma_pos; + dma_addr_t src, dst; + + period_size = snd_pcm_lib_period_bytes(substream); + dma_offset = prtd->period * period_size; + dma_pos = runtime->dma_addr + dma_offset; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + src = dma_pos; + dst = par->sif_out; + channel = par->dma_out; + } else { + src = par->sif_in; + dst = dma_pos; + channel = par->dma_in; + } + + if (!s6dmac_channel_enabled(DMA_MASK_DMAC(channel), + DMA_INDEX_CHNL(channel))) + return; + + if (s6dmac_fifo_full(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel))) { + printk(KERN_ERR "s6000-pcm: fifo full\n"); + return; + } + + BUG_ON(period_size & 15); + s6dmac_put_fifo(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel), + src, dst, period_size); + + prtd->period++; + if (unlikely(prtd->period >= runtime->periods)) + prtd->period = 0; +} + +static irqreturn_t s6000_pcm_irq(int irq, void *data) +{ + struct snd_pcm *pcm = data; + struct snd_soc_pcm_runtime *runtime = pcm->private_data; + struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; + struct s6000_runtime_data *prtd; + unsigned int has_xrun; + int i, ret = IRQ_NONE; + u32 channel[2] = { + [SNDRV_PCM_STREAM_PLAYBACK] = params->dma_out, + [SNDRV_PCM_STREAM_CAPTURE] = params->dma_in + }; + + has_xrun = params->check_xrun(runtime->dai->cpu_dai); + + for (i = 0; i < ARRAY_SIZE(channel); ++i) { + struct snd_pcm_substream *substream = pcm->streams[i].substream; + unsigned int pending; + + if (!channel[i]) + continue; + + if (unlikely(has_xrun & (1 << i)) && + substream->runtime && + snd_pcm_running(substream)) { + dev_dbg(pcm->dev, "xrun\n"); + snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); + ret = IRQ_HANDLED; + } + + pending = s6dmac_int_sources(DMA_MASK_DMAC(channel[i]), + DMA_INDEX_CHNL(channel[i])); + + if (pending & 1) { + ret = IRQ_HANDLED; + if (likely(substream->runtime && + snd_pcm_running(substream))) { + snd_pcm_period_elapsed(substream); + dev_dbg(pcm->dev, "period elapsed %x %x\n", + s6dmac_cur_src(DMA_MASK_DMAC(channel[i]), + DMA_INDEX_CHNL(channel[i])), + s6dmac_cur_dst(DMA_MASK_DMAC(channel[i]), + DMA_INDEX_CHNL(channel[i]))); + prtd = substream->runtime->private_data; + spin_lock(&prtd->lock); + s6000_pcm_enqueue_dma(substream); + spin_unlock(&prtd->lock); + } + } + + if (unlikely(pending & ~7)) { + if (pending & (1 << 3)) + printk(KERN_WARNING + "s6000-pcm: DMA %x Underflow\n", + channel[i]); + if (pending & (1 << 4)) + printk(KERN_WARNING + "s6000-pcm: DMA %x Overflow\n", + channel[i]); + if (pending & 0x1e0) + printk(KERN_WARNING + "s6000-pcm: DMA %x Master Error " + "(mask %x)\n", + channel[i], pending >> 5); + + } + } + + return ret; +} + +static int s6000_pcm_start(struct snd_pcm_substream *substream) +{ + struct s6000_runtime_data *prtd = substream->runtime->private_data; + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + unsigned long flags; + int srcinc; + u32 dma; + + spin_lock_irqsave(&prtd->lock, flags); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + srcinc = 1; + dma = par->dma_out; + } else { + srcinc = 0; + dma = par->dma_in; + } + s6dmac_enable_chan(DMA_MASK_DMAC(dma), DMA_INDEX_CHNL(dma), + 1 /* priority 1 (0 is max) */, + 0 /* peripheral requests w/o xfer length mode */, + srcinc /* source address increment */, + srcinc^1 /* destination address increment */, + 0 /* chunksize 0 (skip impossible on this dma) */, + 0 /* source skip after chunk (impossible) */, + 0 /* destination skip after chunk (impossible) */, + 4 /* 16 byte burst size */, + -1 /* don't conserve bandwidth */, + 0 /* low watermark irq descriptor theshold */, + 0 /* disable hardware timestamps */, + 1 /* enable channel */); + + s6000_pcm_enqueue_dma(substream); + s6000_pcm_enqueue_dma(substream); + + spin_unlock_irqrestore(&prtd->lock, flags); + + return 0; +} + +static int s6000_pcm_stop(struct snd_pcm_substream *substream) +{ + struct s6000_runtime_data *prtd = substream->runtime->private_data; + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + unsigned long flags; + u32 channel; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + channel = par->dma_out; + else + channel = par->dma_in; + + s6dmac_set_terminal_count(DMA_MASK_DMAC(channel), + DMA_INDEX_CHNL(channel), 0); + + spin_lock_irqsave(&prtd->lock, flags); + + s6dmac_disable_chan(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel)); + + spin_unlock_irqrestore(&prtd->lock, flags); + + return 0; +} + +static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + int ret; + + ret = par->trigger(substream, cmd, 0); + if (ret < 0) + return ret; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ret = s6000_pcm_start(substream); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret = s6000_pcm_stop(substream); + break; + default: + ret = -EINVAL; + } + if (ret < 0) + return ret; + + return par->trigger(substream, cmd, 1); +} + +static int s6000_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct s6000_runtime_data *prtd = substream->runtime->private_data; + + prtd->period = 0; + + return 0; +} + +static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct s6000_runtime_data *prtd = runtime->private_data; + unsigned long flags; + unsigned int offset; + dma_addr_t count; + + spin_lock_irqsave(&prtd->lock, flags); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + count = s6dmac_cur_src(DMA_MASK_DMAC(par->dma_out), + DMA_INDEX_CHNL(par->dma_out)); + else + count = s6dmac_cur_dst(DMA_MASK_DMAC(par->dma_in), + DMA_INDEX_CHNL(par->dma_in)); + + count -= runtime->dma_addr; + + spin_unlock_irqrestore(&prtd->lock, flags); + + offset = bytes_to_frames(runtime, count); + if (unlikely(offset >= runtime->buffer_size)) + offset = 0; + + return offset; +} + +static int s6000_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct s6000_runtime_data *prtd; + int ret; + + snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware); + + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16); + if (ret < 0) + return ret; + ret = snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16); + if (ret < 0) + return ret; + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + return ret; + + if (par->same_rate) { + int rate; + spin_lock(&par->lock); /* needed? */ + rate = par->rate; + spin_unlock(&par->lock); + if (rate != -1) { + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_RATE, + rate, rate); + if (ret < 0) + return ret; + } + } + + prtd = kzalloc(sizeof(struct s6000_runtime_data), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + + spin_lock_init(&prtd->lock); + + runtime->private_data = prtd; + + return 0; +} + +static int s6000_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s6000_runtime_data *prtd = runtime->private_data; + + kfree(prtd); + + return 0; +} + +static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + int ret; + ret = snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); + if (ret < 0) { + printk(KERN_WARNING "s6000-pcm: allocation of memory failed\n"); + return ret; + } + + if (par->same_rate) { + spin_lock(&par->lock); + if (par->rate == -1 || + !(par->in_use & ~(1 << substream->stream))) { + par->rate = params_rate(hw_params); + par->in_use |= 1 << substream->stream; + } else if (params_rate(hw_params) != par->rate) { + snd_pcm_lib_free_pages(substream); + par->in_use &= ~(1 << substream->stream); + ret = -EBUSY; + } + spin_unlock(&par->lock); + } + return ret; +} + +static int s6000_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; + struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + + spin_lock(&par->lock); + par->in_use &= ~(1 << substream->stream); + if (!par->in_use) + par->rate = -1; + spin_unlock(&par->lock); + + return snd_pcm_lib_free_pages(substream); +} + +static struct snd_pcm_ops s6000_pcm_ops = { + .open = s6000_pcm_open, + .close = s6000_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = s6000_pcm_hw_params, + .hw_free = s6000_pcm_hw_free, + .trigger = s6000_pcm_trigger, + .prepare = s6000_pcm_prepare, + .pointer = s6000_pcm_pointer, +}; + +static void s6000_pcm_free(struct snd_pcm *pcm) +{ + struct snd_soc_pcm_runtime *runtime = pcm->private_data; + struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; + + free_irq(params->irq, pcm); + snd_pcm_lib_preallocate_free_for_all(pcm); +} + +static u64 s6000_pcm_dmamask = DMA_32BIT_MASK; + +static int s6000_pcm_new(struct snd_card *card, + struct snd_soc_dai *dai, struct snd_pcm *pcm) +{ + struct snd_soc_pcm_runtime *runtime = pcm->private_data; + struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; + int res; + + if (!card->dev->dma_mask) + card->dev->dma_mask = &s6000_pcm_dmamask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = DMA_32BIT_MASK; + + if (params->dma_in) { + s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in), + DMA_INDEX_CHNL(params->dma_in)); + s6dmac_int_sources(DMA_MASK_DMAC(params->dma_in), + DMA_INDEX_CHNL(params->dma_in)); + } + + if (params->dma_out) { + s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_out), + DMA_INDEX_CHNL(params->dma_out)); + s6dmac_int_sources(DMA_MASK_DMAC(params->dma_out), + DMA_INDEX_CHNL(params->dma_out)); + } + + res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED, + s6000_soc_platform.name, pcm); + if (res) { + printk(KERN_ERR "s6000-pcm couldn't get IRQ\n"); + return res; + } + + res = snd_pcm_lib_preallocate_pages_for_all(pcm, + SNDRV_DMA_TYPE_DEV, + card->dev, + S6_PCM_PREALLOCATE_SIZE, + S6_PCM_PREALLOCATE_MAX); + if (res) + printk(KERN_WARNING "s6000-pcm: preallocation failed\n"); + + spin_lock_init(¶ms->lock); + params->in_use = 0; + params->rate = -1; + return 0; +} + +struct snd_soc_platform s6000_soc_platform = { + .name = "s6000-audio", + .pcm_ops = &s6000_pcm_ops, + .pcm_new = s6000_pcm_new, + .pcm_free = s6000_pcm_free, +}; +EXPORT_SYMBOL_GPL(s6000_soc_platform); + +static int __init s6000_pcm_init(void) +{ + return snd_soc_register_platform(&s6000_soc_platform); +} +module_init(s6000_pcm_init); + +static void __exit s6000_pcm_exit(void) +{ + snd_soc_unregister_platform(&s6000_soc_platform); +} +module_exit(s6000_pcm_exit); + +MODULE_AUTHOR("Daniel Gloeckner"); +MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/s6000/s6000-pcm.h b/sound/soc/s6000/s6000-pcm.h new file mode 100644 index 000000000000..96f23f6f52bf --- /dev/null +++ b/sound/soc/s6000/s6000-pcm.h @@ -0,0 +1,35 @@ +/* + * ALSA PCM interface for the Stretch s6000 family + * + * Author: Daniel Gloeckner, + * Copyright: (C) 2009 emlix GmbH + * + * 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 _S6000_PCM_H +#define _S6000_PCM_H + +struct snd_soc_dai; +struct snd_pcm_substream; + +struct s6000_pcm_dma_params { + unsigned int (*check_xrun)(struct snd_soc_dai *cpu_dai); + int (*trigger)(struct snd_pcm_substream *substream, int cmd, int after); + dma_addr_t sif_in; + dma_addr_t sif_out; + u32 dma_in; + u32 dma_out; + int irq; + int same_rate; + + spinlock_t lock; + int in_use; + int rate; +}; + +extern struct snd_soc_platform s6000_soc_platform; + +#endif -- GitLab From 2b7dbbe0c9491e62b50978d1615193bec33a8291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= Date: Sat, 28 Mar 2009 19:47:02 +0100 Subject: [PATCH 0104/6080] ASoC: s6105 IP camera machine specific ASoC code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds machine specific code for the audio part of the Stretch s6105 IP camera reference design. The device uses the tlv320aic31(01) codec to generate the clock for both I2S ports of the soc. While the master clock is generated by a configurable PLL chip, the code assumes the factory default settings. An additional kcontrol has been added to handle the special routing of the board, connecting both HPLCOM and HPROUT to the same pin of the audio jack. One of these should always be switched off. Signed-off-by: Daniel Glöckner Signed-off-by: Mark Brown --- sound/soc/s6000/Kconfig | 9 ++ sound/soc/s6000/Makefile | 5 + sound/soc/s6000/s6105-ipcam.c | 244 ++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) create mode 100644 sound/soc/s6000/s6105-ipcam.c diff --git a/sound/soc/s6000/Kconfig b/sound/soc/s6000/Kconfig index 4bfc8bcac51b..c74eb3d4a47c 100644 --- a/sound/soc/s6000/Kconfig +++ b/sound/soc/s6000/Kconfig @@ -8,3 +8,12 @@ config SND_S6000_SOC config SND_S6000_SOC_I2S tristate + +config SND_S6000_SOC_S6IPCAM + tristate "SoC Audio support for Stretch 6105 IP Camera" + depends on SND_S6000_SOC && XTENSA_PLATFORM_S6105 + select SND_S6000_SOC_I2S + select SND_SOC_TLV320AIC3X + help + Say Y if you want to add support for SoC audio on the + Stretch s6105 IP Camera Reference Design. diff --git a/sound/soc/s6000/Makefile b/sound/soc/s6000/Makefile index df15f876a1a9..7a613612e010 100644 --- a/sound/soc/s6000/Makefile +++ b/sound/soc/s6000/Makefile @@ -4,3 +4,8 @@ snd-soc-s6000-i2s-objs := s6000-i2s.o obj-$(CONFIG_SND_S6000_SOC) += snd-soc-s6000.o obj-$(CONFIG_SND_S6000_SOC_I2S) += snd-soc-s6000-i2s.o + +# s6105 Machine Support +snd-soc-s6ipcam-objs := s6105-ipcam.o + +obj-$(CONFIG_SND_S6000_SOC_S6IPCAM) += snd-soc-s6ipcam.o diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c new file mode 100644 index 000000000000..21c4f55106ca --- /dev/null +++ b/sound/soc/s6000/s6105-ipcam.c @@ -0,0 +1,244 @@ +/* + * ASoC driver for Stretch s6105 IP camera platform + * + * Author: Daniel Gloeckner, + * Copyright: (C) 2009 emlix GmbH + * + * 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 "../codecs/tlv320aic3x.h" +#include "s6000-pcm.h" +#include "s6000-i2s.h" + +#define S6105_CAM_CODEC_CLOCK 12288000 + +static int s6105_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + int ret = 0; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM | + SND_SOC_DAIFMT_IB_IF); + if (ret < 0) + return ret; + + /* set the codec system clock */ + ret = snd_soc_dai_set_sysclk(codec_dai, 0, S6105_CAM_CODEC_CLOCK, + SND_SOC_CLOCK_OUT); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops s6105_ops = { + .hw_params = s6105_hw_params, +}; + +/* s6105 machine dapm widgets */ +static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { + SND_SOC_DAPM_LINE("Audio Out Differential", NULL), + SND_SOC_DAPM_LINE("Audio Out Stereo", NULL), + SND_SOC_DAPM_LINE("Audio In", NULL), +}; + +/* s6105 machine audio_mapnections to the codec pins */ +static const struct snd_soc_dapm_route audio_map[] = { + /* Audio Out connected to HPLOUT, HPLCOM, HPROUT */ + {"Audio Out Differential", NULL, "HPLOUT"}, + {"Audio Out Differential", NULL, "HPLCOM"}, + {"Audio Out Stereo", NULL, "HPLOUT"}, + {"Audio Out Stereo", NULL, "HPROUT"}, + + /* Audio In connected to LINE1L, LINE1R */ + {"LINE1L", NULL, "Audio In"}, + {"LINE1R", NULL, "Audio In"}, +}; + +static int output_type_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item) { + uinfo->value.enumerated.item = 1; + strcpy(uinfo->value.enumerated.name, "HPLOUT/HPROUT"); + } else { + strcpy(uinfo->value.enumerated.name, "HPLOUT/HPLCOM"); + } + return 0; +} + +static int output_type_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = kcontrol->private_value; + return 0; +} + +static int output_type_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = kcontrol->private_data; + unsigned int val = (ucontrol->value.enumerated.item[0] != 0); + char *differential = "Audio Out Differential"; + char *stereo = "Audio Out Stereo"; + + if (kcontrol->private_value == val) + return 0; + kcontrol->private_value = val; + snd_soc_dapm_disable_pin(codec, val ? differential : stereo); + snd_soc_dapm_sync(codec); + snd_soc_dapm_enable_pin(codec, val ? stereo : differential); + snd_soc_dapm_sync(codec); + + return 1; +} + +static const struct snd_kcontrol_new audio_out_mux = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Output Mux", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = output_type_info, + .get = output_type_get, + .put = output_type_put, + .private_value = 1 /* default to stereo */ +}; + +/* Logic for a aic3x as connected on the s6105 ip camera ref design */ +static int s6105_aic3x_init(struct snd_soc_codec *codec) +{ + /* Add s6105 specific widgets */ + snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, + ARRAY_SIZE(aic3x_dapm_widgets)); + + /* Set up s6105 specific audio path audio_map */ + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + + /* not present */ + snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); + snd_soc_dapm_nc_pin(codec, "LINE2L"); + snd_soc_dapm_nc_pin(codec, "LINE2R"); + + /* not connected */ + snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */ + snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */ + snd_soc_dapm_nc_pin(codec, "LLOUT"); + snd_soc_dapm_nc_pin(codec, "RLOUT"); + snd_soc_dapm_nc_pin(codec, "HPRCOM"); + + /* always connected */ + snd_soc_dapm_enable_pin(codec, "Audio In"); + + /* must correspond to audio_out_mux.private_value initializer */ + snd_soc_dapm_disable_pin(codec, "Audio Out Differential"); + snd_soc_dapm_sync(codec); + snd_soc_dapm_enable_pin(codec, "Audio Out Stereo"); + + snd_soc_dapm_sync(codec); + + snd_ctl_add(codec->card, snd_ctl_new1(&audio_out_mux, codec)); + + return 0; +} + +/* s6105 digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link s6105_dai = { + .name = "TLV320AIC31", + .stream_name = "AIC31", + .cpu_dai = &s6000_i2s_dai, + .codec_dai = &aic3x_dai, + .init = s6105_aic3x_init, + .ops = &s6105_ops, +}; + +/* s6105 audio machine driver */ +static struct snd_soc_card snd_soc_card_s6105 = { + .name = "Stretch IP Camera", + .platform = &s6000_soc_platform, + .dai_link = &s6105_dai, + .num_links = 1, +}; + +/* s6105 audio private data */ +static struct aic3x_setup_data s6105_aic3x_setup = { + .i2c_bus = 0, + .i2c_address = 0x18, +}; + +/* s6105 audio subsystem */ +static struct snd_soc_device s6105_snd_devdata = { + .card = &snd_soc_card_s6105, + .codec_dev = &soc_codec_dev_aic3x, + .codec_data = &s6105_aic3x_setup, +}; + +static struct s6000_snd_platform_data __initdata s6105_snd_data = { + .wide = 0, + .channel_in = 0, + .channel_out = 1, + .lines_in = 1, + .lines_out = 1, + .same_rate = 1, +}; + +static struct platform_device *s6105_snd_device; + +static int __init s6105_init(void) +{ + int ret; + + s6105_snd_device = platform_device_alloc("soc-audio", -1); + if (!s6105_snd_device) + return -ENOMEM; + + platform_set_drvdata(s6105_snd_device, &s6105_snd_devdata); + s6105_snd_devdata.dev = &s6105_snd_device->dev; + platform_device_add_data(s6105_snd_device, &s6105_snd_data, + sizeof(s6105_snd_data)); + + ret = platform_device_add(s6105_snd_device); + if (ret) + platform_device_put(s6105_snd_device); + + return ret; +} + +static void __exit s6105_exit(void) +{ + platform_device_unregister(s6105_snd_device); +} + +module_init(s6105_init); +module_exit(s6105_exit); + +MODULE_AUTHOR("Daniel Gloeckner"); +MODULE_DESCRIPTION("Stretch s6105 IP camera ASoC driver"); +MODULE_LICENSE("GPL"); -- GitLab From 595258aaeac4cc6e187b98b1bf29bb176febe763 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 12:21:28 +0100 Subject: [PATCH 0105/6080] perf_counter: x86: fix 32-bit irq_period assumption No need to assume the irq_period is 32bit. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 155bc3c239b6..1cedc3468ce5 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -449,7 +449,7 @@ __hw_perf_counter_set_period(struct perf_counter *counter, struct hw_perf_counter *hwc, int idx) { s64 left = atomic64_read(&hwc->period_left); - s32 period = hwc->irq_period; + s64 period = hwc->irq_period; int err; /* -- GitLab From 755642322aa66fbc5421a35fd3e1733f73e20083 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 12:21:29 +0100 Subject: [PATCH 0106/6080] perf_counter: use list_move_tail() Instead of del/add use a move list-op. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index b2e838959f3e..0fe22c916e29 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -89,8 +89,7 @@ list_del_counter(struct perf_counter *counter, struct perf_counter_context *ctx) list_for_each_entry_safe(sibling, tmp, &counter->sibling_list, list_entry) { - list_del_init(&sibling->list_entry); - list_add_tail(&sibling->list_entry, &ctx->counter_list); + list_move_tail(&sibling->list_entry, &ctx->counter_list); sibling->group_leader = sibling; } } @@ -959,8 +958,7 @@ static void rotate_ctx(struct perf_counter_context *ctx) */ perf_flags = hw_perf_save_disable(); list_for_each_entry(counter, &ctx->counter_list, list_entry) { - list_del(&counter->list_entry); - list_add_tail(&counter->list_entry, &ctx->counter_list); + list_move_tail(&counter->list_entry, &ctx->counter_list); break; } hw_perf_restore(perf_flags); -- GitLab From 60b3df9c1e24a18aabb412da9905208c5f04ebea Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 12:21:30 +0100 Subject: [PATCH 0107/6080] perf_counter: add comment to barrier We need to ensure the enabled=0 write happens before we start disabling the actual counters, so that a pcm_amd_enable() will not enable one underneath us. I think the race is impossible anyway, we always balance the ops within any one context and perform enable() with IRQs disabled. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 1cedc3468ce5..a2e3b76bfdc1 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -247,6 +247,10 @@ static u64 pmc_amd_save_disable_all(void) enabled = cpuc->enabled; cpuc->enabled = 0; + /* + * ensure we write the disable before we start disabling the + * counters proper, so that pcm_amd_enable() does the right thing. + */ barrier(); for (idx = 0; idx < nr_counters_generic; idx++) { -- GitLab From 82bae4f8c2fd64a2bb1e2e72c508853ed2b4a299 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 12:21:31 +0100 Subject: [PATCH 0108/6080] perf_counter: x86: use ULL postfix for 64bit constants Fix a build warning on 32bit machines by explicitly marking the constants as 64-bit. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index a2e3b76bfdc1..22dab06c08a4 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -84,9 +84,9 @@ static u64 pmc_intel_event_map(int event) static u64 pmc_intel_raw_event(u64 event) { -#define CORE_EVNTSEL_EVENT_MASK 0x000000FF -#define CORE_EVNTSEL_UNIT_MASK 0x0000FF00 -#define CORE_EVNTSEL_COUNTER_MASK 0xFF000000 +#define CORE_EVNTSEL_EVENT_MASK 0x000000FFULL +#define CORE_EVNTSEL_UNIT_MASK 0x0000FF00ULL +#define CORE_EVNTSEL_COUNTER_MASK 0xFF000000ULL #define CORE_EVNTSEL_MASK \ (CORE_EVNTSEL_EVENT_MASK | \ @@ -116,9 +116,9 @@ static u64 pmc_amd_event_map(int event) static u64 pmc_amd_raw_event(u64 event) { -#define K7_EVNTSEL_EVENT_MASK 0x7000000FF -#define K7_EVNTSEL_UNIT_MASK 0x00000FF00 -#define K7_EVNTSEL_COUNTER_MASK 0x0FF000000 +#define K7_EVNTSEL_EVENT_MASK 0x7000000FFULL +#define K7_EVNTSEL_UNIT_MASK 0x00000FF00ULL +#define K7_EVNTSEL_COUNTER_MASK 0x0FF000000ULL #define K7_EVNTSEL_MASK \ (K7_EVNTSEL_EVENT_MASK | \ -- GitLab From 15dbf27cc18559a14e99609f78678aa86b9c6ff1 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 12:21:32 +0100 Subject: [PATCH 0109/6080] perf_counter: software counter event infrastructure Provide generic software counter infrastructure that supports software events. This will be used to allow sample based profiling based on software events such as pagefaults. The current infrastructure can only provide a count of such events, no place information. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 8 +- kernel/perf_counter.c | 201 +++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 1 deletion(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index dde564517b66..3fefc3b8150d 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -126,6 +126,7 @@ struct hw_perf_counter { unsigned long counter_base; int nmi; unsigned int idx; + atomic64_t count; /* software */ atomic64_t prev_count; u64 irq_period; atomic64_t period_left; @@ -283,6 +284,8 @@ static inline int is_software_counter(struct perf_counter *counter) return !counter->hw_event.raw && counter->hw_event.type < 0; } +extern void perf_swcounter_event(enum hw_event_types, u64, int, struct pt_regs *); + #else static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } @@ -295,10 +298,13 @@ static inline void perf_counter_exit_task(struct task_struct *child) { } static inline void perf_counter_notify(struct pt_regs *regs) { } static inline void perf_counter_print_debug(void) { } static inline void perf_counter_unthrottle(void) { } -static inline void hw_perf_restore(u64 ctrl) { } +static inline void hw_perf_restore(u64 ctrl) { } static inline u64 hw_perf_save_disable(void) { return 0; } static inline int perf_counter_task_disable(void) { return -EINVAL; } static inline int perf_counter_task_enable(void) { return -EINVAL; } + +static inline void perf_swcounter_event(enum hw_event_types event, u64 nr, + int nmi, struct pt_regs *regs) { } #endif #endif /* __KERNEL__ */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0fe22c916e29..eeb1b46cf707 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1328,6 +1328,185 @@ static const struct file_operations perf_fops = { .compat_ioctl = perf_ioctl, }; +/* + * Generic software counter infrastructure + */ + +static void perf_swcounter_update(struct perf_counter *counter) +{ + struct hw_perf_counter *hwc = &counter->hw; + u64 prev, now; + s64 delta; + +again: + prev = atomic64_read(&hwc->prev_count); + now = atomic64_read(&hwc->count); + if (atomic64_cmpxchg(&hwc->prev_count, prev, now) != prev) + goto again; + + delta = now - prev; + + atomic64_add(delta, &counter->count); + atomic64_sub(delta, &hwc->period_left); +} + +static void perf_swcounter_set_period(struct perf_counter *counter) +{ + struct hw_perf_counter *hwc = &counter->hw; + s64 left = atomic64_read(&hwc->period_left); + s64 period = hwc->irq_period; + + if (unlikely(left <= -period)) { + left = period; + atomic64_set(&hwc->period_left, left); + } + + if (unlikely(left <= 0)) { + left += period; + atomic64_add(period, &hwc->period_left); + } + + atomic64_set(&hwc->prev_count, -left); + atomic64_set(&hwc->count, -left); +} + +static void perf_swcounter_save_and_restart(struct perf_counter *counter) +{ + perf_swcounter_update(counter); + perf_swcounter_set_period(counter); +} + +static void perf_swcounter_store_irq(struct perf_counter *counter, u64 data) +{ + struct perf_data *irqdata = counter->irqdata; + + if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) { + irqdata->overrun++; + } else { + u64 *p = (u64 *) &irqdata->data[irqdata->len]; + + *p = data; + irqdata->len += sizeof(u64); + } +} + +static void perf_swcounter_handle_group(struct perf_counter *sibling) +{ + struct perf_counter *counter, *group_leader = sibling->group_leader; + + list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { + perf_swcounter_update(counter); + perf_swcounter_store_irq(sibling, counter->hw_event.type); + perf_swcounter_store_irq(sibling, atomic64_read(&counter->count)); + } +} + +static void perf_swcounter_interrupt(struct perf_counter *counter, + int nmi, struct pt_regs *regs) +{ + perf_swcounter_save_and_restart(counter); + + switch (counter->hw_event.record_type) { + case PERF_RECORD_SIMPLE: + break; + + case PERF_RECORD_IRQ: + perf_swcounter_store_irq(counter, instruction_pointer(regs)); + break; + + case PERF_RECORD_GROUP: + perf_swcounter_handle_group(counter); + break; + } + + if (nmi) { + counter->wakeup_pending = 1; + set_tsk_thread_flag(current, TIF_PERF_COUNTERS); + } else + wake_up(&counter->waitq); +} + +static int perf_swcounter_match(struct perf_counter *counter, + enum hw_event_types event, + struct pt_regs *regs) +{ + if (counter->state != PERF_COUNTER_STATE_ACTIVE) + return 0; + + if (counter->hw_event.raw) + return 0; + + if (counter->hw_event.type != event) + return 0; + + if (counter->hw_event.exclude_user && user_mode(regs)) + return 0; + + if (counter->hw_event.exclude_kernel && !user_mode(regs)) + return 0; + + return 1; +} + +static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, + enum hw_event_types event, u64 nr, + int nmi, struct pt_regs *regs) +{ + struct perf_counter *counter; + unsigned long flags; + int neg; + + if (list_empty(&ctx->counter_list)) + return; + + spin_lock_irqsave(&ctx->lock, flags); + + /* + * XXX: make counter_list RCU safe + */ + list_for_each_entry(counter, &ctx->counter_list, list_entry) { + if (perf_swcounter_match(counter, event, regs)) { + neg = atomic64_add_negative(nr, &counter->hw.count); + if (counter->hw.irq_period && !neg) + perf_swcounter_interrupt(counter, nmi, regs); + } + } + + spin_unlock_irqrestore(&ctx->lock, flags); +} + +void perf_swcounter_event(enum hw_event_types event, u64 nr, + int nmi, struct pt_regs *regs) +{ + struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context); + + perf_swcounter_ctx_event(&cpuctx->ctx, event, nr, nmi, regs); + if (cpuctx->task_ctx) + perf_swcounter_ctx_event(cpuctx->task_ctx, event, nr, nmi, regs); + + put_cpu_var(perf_cpu_context); +} + +static void perf_swcounter_read(struct perf_counter *counter) +{ + perf_swcounter_update(counter); +} + +static int perf_swcounter_enable(struct perf_counter *counter) +{ + perf_swcounter_set_period(counter); + return 0; +} + +static void perf_swcounter_disable(struct perf_counter *counter) +{ + perf_swcounter_update(counter); +} + +/* + * Software counter: cpu wall time clock + */ + static int cpu_clock_perf_counter_enable(struct perf_counter *counter) { int cpu = raw_smp_processor_id(); @@ -1364,6 +1543,10 @@ static const struct hw_perf_counter_ops perf_ops_cpu_clock = { .read = cpu_clock_perf_counter_read, }; +/* + * Software counter: task time clock + */ + /* * Called from within the scheduler: */ @@ -1420,6 +1603,10 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = { .read = task_clock_perf_counter_read, }; +/* + * Software counter: page faults + */ + #ifdef CONFIG_VM_EVENT_COUNTERS #define cpu_page_faults() __get_cpu_var(vm_event_states).event[PGFAULT] #else @@ -1473,6 +1660,10 @@ static const struct hw_perf_counter_ops perf_ops_page_faults = { .read = page_faults_perf_counter_read, }; +/* + * Software counter: context switches + */ + static u64 get_context_switches(struct perf_counter *counter) { struct task_struct *curr = counter->ctx->task; @@ -1521,6 +1712,10 @@ static const struct hw_perf_counter_ops perf_ops_context_switches = { .read = context_switches_perf_counter_read, }; +/* + * Software counter: cpu migrations + */ + static inline u64 get_cpu_migrations(struct perf_counter *counter) { struct task_struct *curr = counter->ctx->task; @@ -1572,7 +1767,9 @@ static const struct hw_perf_counter_ops perf_ops_cpu_migrations = { static const struct hw_perf_counter_ops * sw_perf_counter_init(struct perf_counter *counter) { + struct perf_counter_hw_event *hw_event = &counter->hw_event; const struct hw_perf_counter_ops *hw_ops = NULL; + struct hw_perf_counter *hwc = &counter->hw; /* * Software counters (currently) can't in general distinguish @@ -1618,6 +1815,10 @@ sw_perf_counter_init(struct perf_counter *counter) default: break; } + + if (hw_ops) + hwc->irq_period = hw_event->irq_period; + return hw_ops; } -- GitLab From 7dd1fcc258b65da718f01e4684a7b9244501a9fb Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 12:21:33 +0100 Subject: [PATCH 0110/6080] perf_counter: provide pagefault software events We use the generic software counter infrastructure to provide page fault events. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- arch/powerpc/mm/fault.c | 3 +++ arch/x86/mm/fault.c | 3 +++ kernel/perf_counter.c | 53 +++-------------------------------------- 3 files changed, 9 insertions(+), 50 deletions(-) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 76993941cac9..eda5b0ca4af2 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -170,6 +171,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, die("Weird page fault", regs, SIGSEGV); } + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS, 1, 0, regs); + /* 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 diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index a03b7279efa0..c8725752b6cd 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -1044,6 +1045,8 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) if (unlikely(error_code & PF_RSVD)) pgtable_bad(regs, error_code, address); + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS, 1, 0, regs); + /* * If we're in an interrupt, have no user context or are running * in an atomic region then we must not take the fault: diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index eeb1b46cf707..1773c5d7427d 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1607,57 +1607,10 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = { * Software counter: page faults */ -#ifdef CONFIG_VM_EVENT_COUNTERS -#define cpu_page_faults() __get_cpu_var(vm_event_states).event[PGFAULT] -#else -#define cpu_page_faults() 0 -#endif - -static u64 get_page_faults(struct perf_counter *counter) -{ - struct task_struct *curr = counter->ctx->task; - - if (curr) - return curr->maj_flt + curr->min_flt; - return cpu_page_faults(); -} - -static void page_faults_perf_counter_update(struct perf_counter *counter) -{ - u64 prev, now; - s64 delta; - - prev = atomic64_read(&counter->hw.prev_count); - now = get_page_faults(counter); - - atomic64_set(&counter->hw.prev_count, now); - - delta = now - prev; - - atomic64_add(delta, &counter->count); -} - -static void page_faults_perf_counter_read(struct perf_counter *counter) -{ - page_faults_perf_counter_update(counter); -} - -static int page_faults_perf_counter_enable(struct perf_counter *counter) -{ - if (counter->prev_state <= PERF_COUNTER_STATE_OFF) - atomic64_set(&counter->hw.prev_count, get_page_faults(counter)); - return 0; -} - -static void page_faults_perf_counter_disable(struct perf_counter *counter) -{ - page_faults_perf_counter_update(counter); -} - static const struct hw_perf_counter_ops perf_ops_page_faults = { - .enable = page_faults_perf_counter_enable, - .disable = page_faults_perf_counter_disable, - .read = page_faults_perf_counter_read, + .enable = perf_swcounter_enable, + .disable = perf_swcounter_disable, + .read = perf_swcounter_read, }; /* -- GitLab From ac17dc8e58f3069ea895cfff963adf98ff3cf6b2 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 12:21:34 +0100 Subject: [PATCH 0111/6080] perf_counter: provide major/minor page fault software events Provide separate sw counters for major and minor page faults. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- arch/powerpc/mm/fault.c | 5 ++++- arch/x86/mm/fault.c | 7 +++++-- include/linux/perf_counter.h | 4 +++- kernel/perf_counter.c | 22 +++++++++------------- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index eda5b0ca4af2..17bbf6f91fbe 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -312,6 +312,7 @@ good_area: } if (ret & VM_FAULT_MAJOR) { current->maj_flt++; + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MAJ, 1, 0, regs); #ifdef CONFIG_PPC_SMLPAR if (firmware_has_feature(FW_FEATURE_CMO)) { preempt_disable(); @@ -319,8 +320,10 @@ good_area: preempt_enable(); } #endif - } else + } else { current->min_flt++; + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MIN, 1, 0, regs); + } up_read(&mm->mmap_sem); return 0; diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index c8725752b6cd..f2d3324d9215 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1140,10 +1140,13 @@ good_area: return; } - if (fault & VM_FAULT_MAJOR) + if (fault & VM_FAULT_MAJOR) { tsk->maj_flt++; - else + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MAJ, 1, 0, regs); + } else { tsk->min_flt++; + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MIN, 1, 0, regs); + } check_v8086_mode(regs, address, tsk); diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 3fefc3b8150d..4b14a8e9dbf5 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -49,8 +49,10 @@ enum hw_event_types { PERF_COUNT_PAGE_FAULTS = -3, PERF_COUNT_CONTEXT_SWITCHES = -4, PERF_COUNT_CPU_MIGRATIONS = -5, + PERF_COUNT_PAGE_FAULTS_MIN = -6, + PERF_COUNT_PAGE_FAULTS_MAJ = -7, - PERF_SW_EVENTS_MIN = -6, + PERF_SW_EVENTS_MIN = -8, }; /* diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 1773c5d7427d..68950a3a52bf 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1503,6 +1503,12 @@ static void perf_swcounter_disable(struct perf_counter *counter) perf_swcounter_update(counter); } +static const struct hw_perf_counter_ops perf_ops_generic = { + .enable = perf_swcounter_enable, + .disable = perf_swcounter_disable, + .read = perf_swcounter_read, +}; + /* * Software counter: cpu wall time clock */ @@ -1603,16 +1609,6 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = { .read = task_clock_perf_counter_read, }; -/* - * Software counter: page faults - */ - -static const struct hw_perf_counter_ops perf_ops_page_faults = { - .enable = perf_swcounter_enable, - .disable = perf_swcounter_disable, - .read = perf_swcounter_read, -}; - /* * Software counter: context switches */ @@ -1753,9 +1749,9 @@ sw_perf_counter_init(struct perf_counter *counter) hw_ops = &perf_ops_cpu_clock; break; case PERF_COUNT_PAGE_FAULTS: - if (!(counter->hw_event.exclude_user || - counter->hw_event.exclude_kernel)) - hw_ops = &perf_ops_page_faults; + case PERF_COUNT_PAGE_FAULTS_MIN: + case PERF_COUNT_PAGE_FAULTS_MAJ: + hw_ops = &perf_ops_generic; break; case PERF_COUNT_CONTEXT_SWITCHES: if (!counter->hw_event.exclude_kernel) -- GitLab From d6d020e9957745c61285ef3da9f294c5e6801f0f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 12:21:35 +0100 Subject: [PATCH 0112/6080] perf_counter: hrtimer based sampling for software time events Use hrtimers to profile timer based sampling for the software time counters. This allows platforms without hardware counter support to still perform sample based profiling. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 20 ++++-- kernel/perf_counter.c | 123 ++++++++++++++++++++++++----------- 2 files changed, 100 insertions(+), 43 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 4b14a8e9dbf5..dfb4c7ce18b3 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -114,6 +114,7 @@ struct perf_counter_hw_event { #include #include #include +#include #include struct task_struct; @@ -123,12 +124,19 @@ struct task_struct; */ struct hw_perf_counter { #ifdef CONFIG_PERF_COUNTERS - u64 config; - unsigned long config_base; - unsigned long counter_base; - int nmi; - unsigned int idx; - atomic64_t count; /* software */ + union { + struct { /* hardware */ + u64 config; + unsigned long config_base; + unsigned long counter_base; + int nmi; + unsigned int idx; + }; + union { /* software */ + atomic64_t count; + struct hrtimer hrtimer; + }; + }; atomic64_t prev_count; u64 irq_period; atomic64_t period_left; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 68950a3a52bf..f9330d5827cf 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1395,7 +1395,7 @@ static void perf_swcounter_handle_group(struct perf_counter *sibling) struct perf_counter *counter, *group_leader = sibling->group_leader; list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { - perf_swcounter_update(counter); + counter->hw_ops->read(counter); perf_swcounter_store_irq(sibling, counter->hw_event.type); perf_swcounter_store_irq(sibling, atomic64_read(&counter->count)); } @@ -1404,8 +1404,6 @@ static void perf_swcounter_handle_group(struct perf_counter *sibling) static void perf_swcounter_interrupt(struct perf_counter *counter, int nmi, struct pt_regs *regs) { - perf_swcounter_save_and_restart(counter); - switch (counter->hw_event.record_type) { case PERF_RECORD_SIMPLE: break; @@ -1426,6 +1424,38 @@ static void perf_swcounter_interrupt(struct perf_counter *counter, wake_up(&counter->waitq); } +static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) +{ + struct perf_counter *counter; + struct pt_regs *regs; + + counter = container_of(hrtimer, struct perf_counter, hw.hrtimer); + counter->hw_ops->read(counter); + + regs = get_irq_regs(); + /* + * In case we exclude kernel IPs or are somehow not in interrupt + * context, provide the next best thing, the user IP. + */ + if ((counter->hw_event.exclude_kernel || !regs) && + !counter->hw_event.exclude_user) + regs = task_pt_regs(current); + + if (regs) + perf_swcounter_interrupt(counter, 0, regs); + + hrtimer_forward_now(hrtimer, ns_to_ktime(counter->hw.irq_period)); + + return HRTIMER_RESTART; +} + +static void perf_swcounter_overflow(struct perf_counter *counter, + int nmi, struct pt_regs *regs) +{ + perf_swcounter_save_and_restart(counter); + perf_swcounter_interrupt(counter, nmi, regs); +} + static int perf_swcounter_match(struct perf_counter *counter, enum hw_event_types event, struct pt_regs *regs) @@ -1448,13 +1478,20 @@ static int perf_swcounter_match(struct perf_counter *counter, return 1; } +static void perf_swcounter_add(struct perf_counter *counter, u64 nr, + int nmi, struct pt_regs *regs) +{ + int neg = atomic64_add_negative(nr, &counter->hw.count); + if (counter->hw.irq_period && !neg) + perf_swcounter_overflow(counter, nmi, regs); +} + static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, enum hw_event_types event, u64 nr, int nmi, struct pt_regs *regs) { struct perf_counter *counter; unsigned long flags; - int neg; if (list_empty(&ctx->counter_list)) return; @@ -1465,11 +1502,8 @@ static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, * XXX: make counter_list RCU safe */ list_for_each_entry(counter, &ctx->counter_list, list_entry) { - if (perf_swcounter_match(counter, event, regs)) { - neg = atomic64_add_negative(nr, &counter->hw.count); - if (counter->hw.irq_period && !neg) - perf_swcounter_interrupt(counter, nmi, regs); - } + if (perf_swcounter_match(counter, event, regs)) + perf_swcounter_add(counter, nr, nmi, regs); } spin_unlock_irqrestore(&ctx->lock, flags); @@ -1513,14 +1547,6 @@ static const struct hw_perf_counter_ops perf_ops_generic = { * Software counter: cpu wall time clock */ -static int cpu_clock_perf_counter_enable(struct perf_counter *counter) -{ - int cpu = raw_smp_processor_id(); - - atomic64_set(&counter->hw.prev_count, cpu_clock(cpu)); - return 0; -} - static void cpu_clock_perf_counter_update(struct perf_counter *counter) { int cpu = raw_smp_processor_id(); @@ -1533,8 +1559,26 @@ static void cpu_clock_perf_counter_update(struct perf_counter *counter) atomic64_add(now - prev, &counter->count); } +static int cpu_clock_perf_counter_enable(struct perf_counter *counter) +{ + struct hw_perf_counter *hwc = &counter->hw; + int cpu = raw_smp_processor_id(); + + atomic64_set(&hwc->prev_count, cpu_clock(cpu)); + if (hwc->irq_period) { + hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hwc->hrtimer.function = perf_swcounter_hrtimer; + __hrtimer_start_range_ns(&hwc->hrtimer, + ns_to_ktime(hwc->irq_period), 0, + HRTIMER_MODE_REL, 0); + } + + return 0; +} + static void cpu_clock_perf_counter_disable(struct perf_counter *counter) { + hrtimer_cancel(&counter->hw.hrtimer); cpu_clock_perf_counter_update(counter); } @@ -1580,27 +1624,33 @@ static void task_clock_perf_counter_update(struct perf_counter *counter, u64 now atomic64_add(delta, &counter->count); } -static void task_clock_perf_counter_read(struct perf_counter *counter) -{ - u64 now = task_clock_perf_counter_val(counter, 1); - - task_clock_perf_counter_update(counter, now); -} - static int task_clock_perf_counter_enable(struct perf_counter *counter) { - if (counter->prev_state <= PERF_COUNTER_STATE_OFF) - atomic64_set(&counter->hw.prev_count, - task_clock_perf_counter_val(counter, 0)); + struct hw_perf_counter *hwc = &counter->hw; + + atomic64_set(&hwc->prev_count, task_clock_perf_counter_val(counter, 0)); + if (hwc->irq_period) { + hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hwc->hrtimer.function = perf_swcounter_hrtimer; + __hrtimer_start_range_ns(&hwc->hrtimer, + ns_to_ktime(hwc->irq_period), 0, + HRTIMER_MODE_REL, 0); + } return 0; } static void task_clock_perf_counter_disable(struct perf_counter *counter) { - u64 now = task_clock_perf_counter_val(counter, 0); + hrtimer_cancel(&counter->hw.hrtimer); + task_clock_perf_counter_update(counter, + task_clock_perf_counter_val(counter, 0)); +} - task_clock_perf_counter_update(counter, now); +static void task_clock_perf_counter_read(struct perf_counter *counter) +{ + task_clock_perf_counter_update(counter, + task_clock_perf_counter_val(counter, 1)); } static const struct hw_perf_counter_ops perf_ops_task_clock = { @@ -1729,16 +1779,12 @@ sw_perf_counter_init(struct perf_counter *counter) */ switch (counter->hw_event.type) { case PERF_COUNT_CPU_CLOCK: - if (!(counter->hw_event.exclude_user || - counter->hw_event.exclude_kernel || - counter->hw_event.exclude_hv)) - hw_ops = &perf_ops_cpu_clock; + hw_ops = &perf_ops_cpu_clock; + + if (hw_event->irq_period && hw_event->irq_period < 10000) + hw_event->irq_period = 10000; break; case PERF_COUNT_TASK_CLOCK: - if (counter->hw_event.exclude_user || - counter->hw_event.exclude_kernel || - counter->hw_event.exclude_hv) - break; /* * If the user instantiates this as a per-cpu counter, * use the cpu_clock counter instead. @@ -1747,6 +1793,9 @@ sw_perf_counter_init(struct perf_counter *counter) hw_ops = &perf_ops_task_clock; else hw_ops = &perf_ops_cpu_clock; + + if (hw_event->irq_period && hw_event->irq_period < 10000) + hw_event->irq_period = 10000; break; case PERF_COUNT_PAGE_FAULTS: case PERF_COUNT_PAGE_FAULTS_MIN: -- GitLab From 592903cdcbf606a838056bae6d03fc557806c914 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 12:21:36 +0100 Subject: [PATCH 0113/6080] perf_counter: add an event_list I noticed that the counter_list only includes top-level counters, thus perf_swcounter_event() will miss sw-counters in groups. Since perf_swcounter_event() also wants an RCU safe list, create a new event_list that includes all counters and uses RCU list ops and use call_rcu to free the counter structure. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 4 ++++ kernel/perf_counter.c | 30 +++++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index dfb4c7ce18b3..08c11a6afebc 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -187,6 +187,7 @@ struct file; struct perf_counter { #ifdef CONFIG_PERF_COUNTERS struct list_head list_entry; + struct list_head event_entry; struct list_head sibling_list; struct perf_counter *group_leader; const struct hw_perf_counter_ops *hw_ops; @@ -220,6 +221,8 @@ struct perf_counter { struct perf_data *irqdata; struct perf_data *usrdata; struct perf_data data[2]; + + struct rcu_head rcu_head; #endif }; @@ -243,6 +246,7 @@ struct perf_counter_context { struct mutex mutex; struct list_head counter_list; + struct list_head event_list; int nr_counters; int nr_active; int is_active; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f9330d5827cf..8d6ecfa64c0e 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * Each CPU has a list of per CPU counters: @@ -72,6 +73,8 @@ list_add_counter(struct perf_counter *counter, struct perf_counter_context *ctx) list_add_tail(&counter->list_entry, &ctx->counter_list); else list_add_tail(&counter->list_entry, &group_leader->sibling_list); + + list_add_rcu(&counter->event_entry, &ctx->event_list); } static void @@ -80,6 +83,7 @@ list_del_counter(struct perf_counter *counter, struct perf_counter_context *ctx) struct perf_counter *sibling, *tmp; list_del_init(&counter->list_entry); + list_del_rcu(&counter->event_entry); /* * If this was a group counter with sibling counters then @@ -1133,6 +1137,14 @@ static struct perf_counter_context *find_get_context(pid_t pid, int cpu) return ctx; } +static void free_counter_rcu(struct rcu_head *head) +{ + struct perf_counter *counter; + + counter = container_of(head, struct perf_counter, rcu_head); + kfree(counter); +} + /* * Called when the last reference to the file is gone. */ @@ -1151,7 +1163,7 @@ static int perf_release(struct inode *inode, struct file *file) mutex_unlock(&counter->mutex); mutex_unlock(&ctx->mutex); - kfree(counter); + call_rcu(&counter->rcu_head, free_counter_rcu); put_context(ctx); return 0; @@ -1491,22 +1503,16 @@ static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, int nmi, struct pt_regs *regs) { struct perf_counter *counter; - unsigned long flags; - if (list_empty(&ctx->counter_list)) + if (list_empty(&ctx->event_list)) return; - spin_lock_irqsave(&ctx->lock, flags); - - /* - * XXX: make counter_list RCU safe - */ - list_for_each_entry(counter, &ctx->counter_list, list_entry) { + rcu_read_lock(); + list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) { if (perf_swcounter_match(counter, event, regs)) perf_swcounter_add(counter, nr, nmi, regs); } - - spin_unlock_irqrestore(&ctx->lock, flags); + rcu_read_unlock(); } void perf_swcounter_event(enum hw_event_types event, u64 nr, @@ -1846,6 +1852,7 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, mutex_init(&counter->mutex); INIT_LIST_HEAD(&counter->list_entry); + INIT_LIST_HEAD(&counter->event_entry); INIT_LIST_HEAD(&counter->sibling_list); init_waitqueue_head(&counter->waitq); @@ -1992,6 +1999,7 @@ __perf_counter_init_context(struct perf_counter_context *ctx, spin_lock_init(&ctx->lock); mutex_init(&ctx->mutex); INIT_LIST_HEAD(&ctx->counter_list); + INIT_LIST_HEAD(&ctx->event_list); ctx->task = task; } -- GitLab From 039fc91e064b81c2820ff16c304be5aba35fd126 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 13 Mar 2009 16:43:47 +0100 Subject: [PATCH 0114/6080] perf_counter: fix hrtimer sampling Impact: fix deadlock with perfstat Fix for the perfstat fubar.. We cannot unconditionally call hrtimer_cancel() without ever having done hrtimer_init() on the thing. Signed-off-by: Peter Zijlstra Orig-LKML-Reference: <1236959027.22447.149.camel@twins> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 8d6ecfa64c0e..d6cc22271ef4 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1571,9 +1571,9 @@ static int cpu_clock_perf_counter_enable(struct perf_counter *counter) int cpu = raw_smp_processor_id(); atomic64_set(&hwc->prev_count, cpu_clock(cpu)); + hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hwc->hrtimer.function = perf_swcounter_hrtimer; if (hwc->irq_period) { - hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hwc->hrtimer.function = perf_swcounter_hrtimer; __hrtimer_start_range_ns(&hwc->hrtimer, ns_to_ktime(hwc->irq_period), 0, HRTIMER_MODE_REL, 0); @@ -1635,9 +1635,9 @@ static int task_clock_perf_counter_enable(struct perf_counter *counter) struct hw_perf_counter *hwc = &counter->hw; atomic64_set(&hwc->prev_count, task_clock_perf_counter_val(counter, 0)); + hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hwc->hrtimer.function = perf_swcounter_hrtimer; if (hwc->irq_period) { - hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hwc->hrtimer.function = perf_swcounter_hrtimer; __hrtimer_start_range_ns(&hwc->hrtimer, ns_to_ktime(hwc->irq_period), 0, HRTIMER_MODE_REL, 0); -- GitLab From 4e193bd4dfdc983d12969b51439b4a1fbaf2daad Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Sat, 14 Mar 2009 14:29:25 +0100 Subject: [PATCH 0115/6080] perf_counter: include missing header Impact: build fix In order to compile a kernel with performance counter patches, has to be included to provide the declaration of struct pt_regs *get_irq_regs(void); [ This bug was masked by unrelated x86 header file changes in the x86 tree, but occurs in the tip:perfcounters/core standalone tree. ] Signed-off-by: Tim Blechmann Orig-LKML-Reference: <20090314142925.49c29c17@thinkpad> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index d6cc22271ef4..0018c5e81249 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -24,6 +24,8 @@ #include #include +#include + /* * Each CPU has a list of per CPU counters: */ -- GitLab From 7bb497bd885eedd0f56dfe3cc1b5ff20710d33b9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 18 Mar 2009 08:59:21 +0100 Subject: [PATCH 0116/6080] perf_counter: fix crash on perfmon v1 systems Impact: fix boot crash on Intel Perfmon Version 1 systems Intel Perfmon v1 does not support the global MSRs, nor does it offer the generalized MSR ranges. So support v2 and later CPUs only. Also mark pmc_ops as read-mostly - to avoid false cacheline sharing. Cc: Paul Mackerras Cc: Peter Zijlstra Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 22dab06c08a4..6cba9d47b711 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -57,12 +57,14 @@ struct pmc_x86_ops { int max_events; }; -static struct pmc_x86_ops *pmc_ops; +static struct pmc_x86_ops *pmc_ops __read_mostly; static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = { .enabled = 1, }; +static __read_mostly int intel_perfmon_version; + /* * Intel PerfMon v3. Used on Core2 and later. */ @@ -613,7 +615,7 @@ void perf_counter_print_debug(void) cpu = smp_processor_id(); cpuc = &per_cpu(cpu_hw_counters, cpu); - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { + if (intel_perfmon_version >= 2) { rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow); @@ -930,10 +932,10 @@ static struct pmc_x86_ops pmc_amd_ops = { static struct pmc_x86_ops *pmc_intel_init(void) { + union cpuid10_edx edx; union cpuid10_eax eax; - unsigned int ebx; unsigned int unused; - union cpuid10_edx edx; + unsigned int ebx; /* * Check whether the Architectural PerfMon supports @@ -943,8 +945,12 @@ static struct pmc_x86_ops *pmc_intel_init(void) if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED) return NULL; + intel_perfmon_version = eax.split.version_id; + if (intel_perfmon_version < 2) + return NULL; + pr_info("Intel Performance Monitoring support detected.\n"); - pr_info("... version: %d\n", eax.split.version_id); + pr_info("... version: %d\n", intel_perfmon_version); pr_info("... bit width: %d\n", eax.split.bit_width); pr_info("... mask length: %d\n", eax.split.mask_length); -- GitLab From b6c5a71da1477d261bc36254fe1f20d32b57598d Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 16 Mar 2009 21:00:00 +1100 Subject: [PATCH 0117/6080] perf_counter: abstract wakeup flag setting in core to fix powerpc build Impact: build fix for powerpc Commit bd753921015e7905 ("perf_counter: software counter event infrastructure") introduced a use of TIF_PERF_COUNTERS into the core perfcounter code. This breaks the build on powerpc because we use a flag in a per-cpu area to signal wakeups on powerpc rather than a thread_info flag, because the thread_info flags have to be manipulated with atomic operations and are thus slower than per-cpu flags. This fixes the by changing the core to use an abstracted set_perf_counter_pending() function, which is defined on x86 to set the TIF_PERF_COUNTERS flag and on powerpc to set the per-cpu flag (paca->perf_counter_pending). It changes the previous powerpc definition of set_perf_counter_pending to not take an argument and adds a clear_perf_counter_pending, so as to simplify the definition on x86. On x86, set_perf_counter_pending() is defined as a macro. Defining it as a static inline in arch/x86/include/asm/perf_counters.h causes compile failures because gets included early in , and the definitions of set_tsk_thread_flag etc. are therefore not available in . (On powerpc this problem is avoided by defining set_perf_counter_pending etc. in .) Signed-off-by: Paul Mackerras --- arch/powerpc/include/asm/hw_irq.h | 14 +++++++++++--- arch/powerpc/kernel/irq.c | 11 +++-------- arch/powerpc/kernel/perf_counter.c | 3 +-- arch/x86/include/asm/perf_counter.h | 3 +++ kernel/perf_counter.c | 2 +- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index b43076ff92c9..cb32d571c9c7 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -142,10 +142,17 @@ static inline unsigned long get_perf_counter_pending(void) return x; } -static inline void set_perf_counter_pending(int x) +static inline void set_perf_counter_pending(void) { asm volatile("stb %0,%1(13)" : : - "r" (x), + "r" (1), + "i" (offsetof(struct paca_struct, perf_counter_pending))); +} + +static inline void clear_perf_counter_pending(void) +{ + asm volatile("stb %0,%1(13)" : : + "r" (0), "i" (offsetof(struct paca_struct, perf_counter_pending))); } @@ -158,7 +165,8 @@ static inline unsigned long get_perf_counter_pending(void) return 0; } -static inline void set_perf_counter_pending(int x) {} +static inline void set_perf_counter_pending(void) {} +static inline void clear_perf_counter_pending(void) {} static inline void perf_counter_do_pending(void) {} #endif /* CONFIG_PERF_COUNTERS */ diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 0d2e37c57738..469e9635ff04 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -104,13 +104,6 @@ static inline notrace void set_soft_enabled(unsigned long enable) : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled))); } -#ifdef CONFIG_PERF_COUNTERS -notrace void __weak perf_counter_do_pending(void) -{ - set_perf_counter_pending(0); -} -#endif - notrace void raw_local_irq_restore(unsigned long en) { /* @@ -142,8 +135,10 @@ notrace void raw_local_irq_restore(unsigned long en) iseries_handle_interrupts(); } - if (get_perf_counter_pending()) + if (get_perf_counter_pending()) { + clear_perf_counter_pending(); perf_counter_do_pending(); + } /* * if (get_paca()->hard_enabled) return; diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 0e33d27cd464..5008762e8bf4 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -653,7 +653,6 @@ void perf_counter_do_pending(void) struct cpu_hw_counters *cpuhw = &__get_cpu_var(cpu_hw_counters); struct perf_counter *counter; - set_perf_counter_pending(0); for (i = 0; i < cpuhw->n_counters; ++i) { counter = cpuhw->counter[i]; if (counter && counter->wakeup_pending) { @@ -811,7 +810,7 @@ static void perf_counter_interrupt(struct pt_regs *regs) perf_counter_do_pending(); irq_exit(); } else { - set_perf_counter_pending(1); + set_perf_counter_pending(); } } } diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h index 2e08ed736647..1662043b340f 100644 --- a/arch/x86/include/asm/perf_counter.h +++ b/arch/x86/include/asm/perf_counter.h @@ -84,6 +84,9 @@ union cpuid10_edx { #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b #define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2) +#define set_perf_counter_pending() \ + set_tsk_thread_flag(current, TIF_PERF_COUNTERS); + #ifdef CONFIG_PERF_COUNTERS extern void init_hw_perf_counters(void); extern void perf_counters_lapic_init(int nmi); diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0018c5e81249..b39456ad74a1 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1433,7 +1433,7 @@ static void perf_swcounter_interrupt(struct perf_counter *counter, if (nmi) { counter->wakeup_pending = 1; - set_tsk_thread_flag(current, TIF_PERF_COUNTERS); + set_perf_counter_pending(); } else wake_up(&counter->waitq); } -- GitLab From 01ef09d9ffb5ce9f8d62d1e5206da3d5ca612acc Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 19 Mar 2009 20:26:11 +0100 Subject: [PATCH 0118/6080] perf_counter: fix uninitialized usage of event_list Impact: fix boot crash When doing the generic context switch event I ran into some early boot hangs, which were caused by inf func recursion (event, fault, event, fault). I eventually tracked it down to event_list not being initialized at the time of the first event. Fix this. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Orig-LKML-Reference: <20090319194233.195392657@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/init_task.h | 2 ++ kernel/perf_counter.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 219748d00262..ca226a91abee 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -124,6 +124,8 @@ extern struct cred init_cred; # define INIT_PERF_COUNTERS(tsk) \ .perf_counter_ctx.counter_list = \ LIST_HEAD_INIT(tsk.perf_counter_ctx.counter_list), \ + .perf_counter_ctx.event_list = \ + LIST_HEAD_INIT(tsk.perf_counter_ctx.event_list), \ .perf_counter_ctx.lock = \ __SPIN_LOCK_UNLOCKED(tsk.perf_counter_ctx.lock), #else diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index b39456ad74a1..4c4e9eb37ab0 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1506,7 +1506,7 @@ static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, { struct perf_counter *counter; - if (list_empty(&ctx->event_list)) + if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list)) return; rcu_read_lock(); -- GitLab From 4a0deca657f3dbb8a707b5dc8f173beec01e7ed2 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 19 Mar 2009 20:26:12 +0100 Subject: [PATCH 0119/6080] perf_counter: generic context switch event Impact: cleanup Use the generic software events for context switches. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Orig-LKML-Reference: <20090319194233.283522645@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 - kernel/perf_counter.c | 60 +++---------------------------------------- kernel/sched.c | 6 ----- 3 files changed, 4 insertions(+), 63 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 75b2fc5306d8..7ed41f7c5ace 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -138,7 +138,6 @@ extern unsigned long nr_running(void); extern unsigned long nr_uninterruptible(void); extern unsigned long nr_active(void); extern unsigned long nr_iowait(void); -extern u64 cpu_nr_switches(int cpu); extern u64 cpu_nr_migrations(int cpu); extern unsigned long get_parent_ip(unsigned long addr); diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 4c4e9eb37ab0..99d5930f0a52 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -710,10 +710,13 @@ void perf_counter_task_sched_out(struct task_struct *task, int cpu) { struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu); struct perf_counter_context *ctx = &task->perf_counter_ctx; + struct pt_regs *regs; if (likely(!cpuctx->task_ctx)) return; + regs = task_pt_regs(task); + perf_swcounter_event(PERF_COUNT_CONTEXT_SWITCHES, 1, 1, regs); __perf_counter_sched_out(ctx, cpuctx); cpuctx->task_ctx = NULL; @@ -1667,58 +1670,6 @@ static const struct hw_perf_counter_ops perf_ops_task_clock = { .read = task_clock_perf_counter_read, }; -/* - * Software counter: context switches - */ - -static u64 get_context_switches(struct perf_counter *counter) -{ - struct task_struct *curr = counter->ctx->task; - - if (curr) - return curr->nvcsw + curr->nivcsw; - return cpu_nr_switches(smp_processor_id()); -} - -static void context_switches_perf_counter_update(struct perf_counter *counter) -{ - u64 prev, now; - s64 delta; - - prev = atomic64_read(&counter->hw.prev_count); - now = get_context_switches(counter); - - atomic64_set(&counter->hw.prev_count, now); - - delta = now - prev; - - atomic64_add(delta, &counter->count); -} - -static void context_switches_perf_counter_read(struct perf_counter *counter) -{ - context_switches_perf_counter_update(counter); -} - -static int context_switches_perf_counter_enable(struct perf_counter *counter) -{ - if (counter->prev_state <= PERF_COUNTER_STATE_OFF) - atomic64_set(&counter->hw.prev_count, - get_context_switches(counter)); - return 0; -} - -static void context_switches_perf_counter_disable(struct perf_counter *counter) -{ - context_switches_perf_counter_update(counter); -} - -static const struct hw_perf_counter_ops perf_ops_context_switches = { - .enable = context_switches_perf_counter_enable, - .disable = context_switches_perf_counter_disable, - .read = context_switches_perf_counter_read, -}; - /* * Software counter: cpu migrations */ @@ -1808,11 +1759,8 @@ sw_perf_counter_init(struct perf_counter *counter) case PERF_COUNT_PAGE_FAULTS: case PERF_COUNT_PAGE_FAULTS_MIN: case PERF_COUNT_PAGE_FAULTS_MAJ: - hw_ops = &perf_ops_generic; - break; case PERF_COUNT_CONTEXT_SWITCHES: - if (!counter->hw_event.exclude_kernel) - hw_ops = &perf_ops_context_switches; + hw_ops = &perf_ops_generic; break; case PERF_COUNT_CPU_MIGRATIONS: if (!counter->hw_event.exclude_kernel) diff --git a/kernel/sched.c b/kernel/sched.c index 39e708602169..f76e3c0188a2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2900,14 +2900,8 @@ unsigned long nr_active(void) /* * Externally visible per-cpu scheduler statistics: - * cpu_nr_switches(cpu) - number of context switches on that cpu * cpu_nr_migrations(cpu) - number of migrations into that cpu */ -u64 cpu_nr_switches(int cpu) -{ - return cpu_rq(cpu)->nr_switches; -} - u64 cpu_nr_migrations(int cpu) { return cpu_rq(cpu)->nr_migrations_in; -- GitLab From f16009527595ee562308653bc3d0039166d2ab15 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 19 Mar 2009 20:26:16 +0100 Subject: [PATCH 0120/6080] perf_counter: fix up counter free paths Impact: fix crash during perfcounters use I found another counter free path, create a free_counter() call to accomodate generic tear-down. Fixes an RCU bug. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Orig-LKML-Reference: <20090319194233.652078652@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 99d5930f0a52..97f891ffeb40 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1150,6 +1150,11 @@ static void free_counter_rcu(struct rcu_head *head) kfree(counter); } +static void free_counter(struct perf_counter *counter) +{ + call_rcu(&counter->rcu_head, free_counter_rcu); +} + /* * Called when the last reference to the file is gone. */ @@ -1168,7 +1173,7 @@ static int perf_release(struct inode *inode, struct file *file) mutex_unlock(&counter->mutex); mutex_unlock(&ctx->mutex); - call_rcu(&counter->rcu_head, free_counter_rcu); + free_counter(counter); put_context(ctx); return 0; @@ -2128,10 +2133,10 @@ __perf_counter_exit_task(struct task_struct *child, list_entry) { if (sub->parent) { sync_child_counter(sub, sub->parent); - kfree(sub); + free_counter(sub); } } - kfree(child_counter); + free_counter(child_counter); } } -- GitLab From e077df4f439681e43f0db8255b2d215b342ebdc6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 19 Mar 2009 20:26:17 +0100 Subject: [PATCH 0121/6080] perf_counter: hook up the tracepoint events Impact: new perfcounters feature Enable usage of tracepoints as perf counter events. tracepoint event ids can be found in /debug/tracing/event/*/*/id and (for now) are represented as -65536+id in the type field. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Orig-LKML-Reference: <20090319194233.744044174@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 3 +++ init/Kconfig | 5 +++++ kernel/perf_counter.c | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 08c11a6afebc..065984c1ff57 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -53,6 +53,8 @@ enum hw_event_types { PERF_COUNT_PAGE_FAULTS_MAJ = -7, PERF_SW_EVENTS_MIN = -8, + + PERF_TP_EVENTS_MIN = -65536 }; /* @@ -222,6 +224,7 @@ struct perf_counter { struct perf_data *usrdata; struct perf_data data[2]; + void (*destroy)(struct perf_counter *); struct rcu_head rcu_head; #endif }; diff --git a/init/Kconfig b/init/Kconfig index 38a2ecd47c37..4f647142f2e6 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -947,6 +947,11 @@ config PERF_COUNTERS Say Y if unsure. +config EVENT_PROFILE + bool "Tracepoint profile sources" + depends on PERF_COUNTERS && EVENT_TRACER + default y + endmenu config VM_EVENT_COUNTERS diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 97f891ffeb40..0bbe3e45ba0d 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1152,6 +1152,9 @@ static void free_counter_rcu(struct rcu_head *head) static void free_counter(struct perf_counter *counter) { + if (counter->destroy) + counter->destroy(counter); + call_rcu(&counter->rcu_head, free_counter_rcu); } @@ -1727,6 +1730,45 @@ static const struct hw_perf_counter_ops perf_ops_cpu_migrations = { .read = cpu_migrations_perf_counter_read, }; +#ifdef CONFIG_EVENT_PROFILE +void perf_tpcounter_event(int event_id) +{ + perf_swcounter_event(PERF_TP_EVENTS_MIN + event_id, 1, 1, + task_pt_regs(current)); +} + +extern int ftrace_profile_enable(int); +extern void ftrace_profile_disable(int); + +static void tp_perf_counter_destroy(struct perf_counter *counter) +{ + int event_id = counter->hw_event.type - PERF_TP_EVENTS_MIN; + + ftrace_profile_disable(event_id); +} + +static const struct hw_perf_counter_ops * +tp_perf_counter_init(struct perf_counter *counter) +{ + int event_id = counter->hw_event.type - PERF_TP_EVENTS_MIN; + int ret; + + ret = ftrace_profile_enable(event_id); + if (ret) + return NULL; + + counter->destroy = tp_perf_counter_destroy; + + return &perf_ops_generic; +} +#else +static const struct hw_perf_counter_ops * +tp_perf_counter_init(struct perf_counter *counter) +{ + return NULL; +} +#endif + static const struct hw_perf_counter_ops * sw_perf_counter_init(struct perf_counter *counter) { @@ -1772,6 +1814,7 @@ sw_perf_counter_init(struct perf_counter *counter) hw_ops = &perf_ops_cpu_migrations; break; default: + hw_ops = tp_perf_counter_init(counter); break; } -- GitLab From b8e83514b64577b48bfb794fe85fcde40a9343ca Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 19 Mar 2009 20:26:18 +0100 Subject: [PATCH 0122/6080] perf_counter: revamp syscall input ABI Impact: modify ABI The hardware/software classification in hw_event->type became a little strained due to the addition of tracepoint tracing. Instead split up the field and provide a type field to explicitly specify the counter type, while using the event_id field to specify which event to use. Raw counters still work as before, only the raw config now goes into raw_event. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Orig-LKML-Reference: <20090319194233.836807573@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 4 +- arch/x86/kernel/cpu/perf_counter.c | 10 ++-- include/linux/perf_counter.h | 95 +++++++++++++++++++----------- kernel/perf_counter.c | 83 +++++++++++++++----------- 4 files changed, 117 insertions(+), 75 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 5008762e8bf4..26f69dc7130e 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -602,7 +602,7 @@ hw_perf_counter_init(struct perf_counter *counter) return NULL; if ((s64)counter->hw_event.irq_period < 0) return NULL; - ev = counter->hw_event.type; + ev = counter->hw_event.event_id; if (!counter->hw_event.raw) { if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) @@ -692,7 +692,7 @@ static void perf_handle_group(struct perf_counter *counter) list_for_each_entry(sub, &leader->sibling_list, list_entry) { if (sub != counter) sub->hw_ops->read(sub); - perf_store_irq_data(counter, sub->hw_event.type); + perf_store_irq_data(counter, sub->hw_event.event_config); perf_store_irq_data(counter, atomic64_read(&sub->count)); } } diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 6cba9d47b711..d844ae41d5a3 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -217,15 +217,15 @@ static int __hw_perf_counter_init(struct perf_counter *counter) /* * Raw event type provide the config in the event structure */ - if (hw_event->raw) { - hwc->config |= pmc_ops->raw_event(hw_event->type); + if (hw_event->raw_type) { + hwc->config |= pmc_ops->raw_event(hw_event->raw_event_id); } else { - if (hw_event->type >= pmc_ops->max_events) + if (hw_event->event_id >= pmc_ops->max_events) return -EINVAL; /* * The generic map: */ - hwc->config |= pmc_ops->event_map(hw_event->type); + hwc->config |= pmc_ops->event_map(hw_event->event_id); } counter->wakeup_pending = 0; @@ -715,7 +715,7 @@ perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { x86_perf_counter_update(counter, &counter->hw, counter->hw.idx); - perf_store_irq_data(sibling, counter->hw_event.type); + perf_store_irq_data(sibling, counter->hw_event.event_config); perf_store_irq_data(sibling, atomic64_read(&counter->count)); } } diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 065984c1ff57..8f9394905502 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -21,56 +21,81 @@ */ /* - * Generalized performance counter event types, used by the hw_event.type - * parameter of the sys_perf_counter_open() syscall: + * hw_event.type */ -enum hw_event_types { +enum perf_event_types { + PERF_TYPE_HARDWARE = 0, + PERF_TYPE_SOFTWARE = 1, + PERF_TYPE_TRACEPOINT = 2, + /* - * Common hardware events, generalized by the kernel: + * available TYPE space, raw is the max value. */ - PERF_COUNT_CPU_CYCLES = 0, - PERF_COUNT_INSTRUCTIONS = 1, - PERF_COUNT_CACHE_REFERENCES = 2, - PERF_COUNT_CACHE_MISSES = 3, - PERF_COUNT_BRANCH_INSTRUCTIONS = 4, - PERF_COUNT_BRANCH_MISSES = 5, - PERF_COUNT_BUS_CYCLES = 6, - PERF_HW_EVENTS_MAX = 7, + PERF_TYPE_RAW = 128, +}; +/* + * Generalized performance counter event types, used by the hw_event.event_id + * parameter of the sys_perf_counter_open() syscall: + */ +enum hw_event_ids { /* - * Special "software" counters provided by the kernel, even if - * the hardware does not support performance counters. These - * counters measure various physical and sw events of the - * kernel (and allow the profiling of them as well): + * Common hardware events, generalized by the kernel: */ - PERF_COUNT_CPU_CLOCK = -1, - PERF_COUNT_TASK_CLOCK = -2, - PERF_COUNT_PAGE_FAULTS = -3, - PERF_COUNT_CONTEXT_SWITCHES = -4, - PERF_COUNT_CPU_MIGRATIONS = -5, - PERF_COUNT_PAGE_FAULTS_MIN = -6, - PERF_COUNT_PAGE_FAULTS_MAJ = -7, - - PERF_SW_EVENTS_MIN = -8, + PERF_COUNT_CPU_CYCLES = 0, + PERF_COUNT_INSTRUCTIONS = 1, + PERF_COUNT_CACHE_REFERENCES = 2, + PERF_COUNT_CACHE_MISSES = 3, + PERF_COUNT_BRANCH_INSTRUCTIONS = 4, + PERF_COUNT_BRANCH_MISSES = 5, + PERF_COUNT_BUS_CYCLES = 6, + + PERF_HW_EVENTS_MAX = 7, +}; - PERF_TP_EVENTS_MIN = -65536 +/* + * Special "software" counters provided by the kernel, even if the hardware + * does not support performance counters. These counters measure various + * physical and sw events of the kernel (and allow the profiling of them as + * well): + */ +enum sw_event_ids { + PERF_COUNT_CPU_CLOCK = 0, + PERF_COUNT_TASK_CLOCK = 1, + PERF_COUNT_PAGE_FAULTS = 2, + PERF_COUNT_CONTEXT_SWITCHES = 3, + PERF_COUNT_CPU_MIGRATIONS = 4, + PERF_COUNT_PAGE_FAULTS_MIN = 5, + PERF_COUNT_PAGE_FAULTS_MAJ = 6, + + PERF_SW_EVENTS_MAX = 7, }; /* * IRQ-notification data record type: */ enum perf_counter_record_type { - PERF_RECORD_SIMPLE = 0, - PERF_RECORD_IRQ = 1, - PERF_RECORD_GROUP = 2, + PERF_RECORD_SIMPLE = 0, + PERF_RECORD_IRQ = 1, + PERF_RECORD_GROUP = 2, }; /* * Hardware event to monitor via a performance monitoring counter: */ struct perf_counter_hw_event { - __s64 type; + union { + struct { + __u64 event_id : 56, + type : 8; + }; + struct { + __u64 raw_event_id : 63, + raw_type : 1; + }; + __u64 event_config; + }; __u64 irq_period; __u64 record_type; @@ -78,7 +103,6 @@ struct perf_counter_hw_event { __u64 disabled : 1, /* off by default */ nmi : 1, /* NMI sampling */ - raw : 1, /* raw event type */ inherit : 1, /* children inherit it */ pinned : 1, /* must always be on PMU */ exclusive : 1, /* only group on PMU */ @@ -87,7 +111,7 @@ struct perf_counter_hw_event { exclude_hv : 1, /* ditto hypervisor */ exclude_idle : 1, /* don't count when idle */ - __reserved_1 : 54; + __reserved_1 : 55; __u32 extra_config_len; __u32 __reserved_4; @@ -298,10 +322,11 @@ extern int hw_perf_group_sched_in(struct perf_counter *group_leader, */ static inline int is_software_counter(struct perf_counter *counter) { - return !counter->hw_event.raw && counter->hw_event.type < 0; + return !counter->hw_event.raw_type && + counter->hw_event.type != PERF_TYPE_HARDWARE; } -extern void perf_swcounter_event(enum hw_event_types, u64, int, struct pt_regs *); +extern void perf_swcounter_event(u32, u64, int, struct pt_regs *); #else static inline void @@ -320,7 +345,7 @@ static inline u64 hw_perf_save_disable(void) { return 0; } static inline int perf_counter_task_disable(void) { return -EINVAL; } static inline int perf_counter_task_enable(void) { return -EINVAL; } -static inline void perf_swcounter_event(enum hw_event_types event, u64 nr, +static inline void perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs) { } #endif diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0bbe3e45ba0d..68a56a68bc74 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1395,12 +1395,6 @@ static void perf_swcounter_set_period(struct perf_counter *counter) atomic64_set(&hwc->count, -left); } -static void perf_swcounter_save_and_restart(struct perf_counter *counter) -{ - perf_swcounter_update(counter); - perf_swcounter_set_period(counter); -} - static void perf_swcounter_store_irq(struct perf_counter *counter, u64 data) { struct perf_data *irqdata = counter->irqdata; @@ -1421,7 +1415,7 @@ static void perf_swcounter_handle_group(struct perf_counter *sibling) list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { counter->hw_ops->read(counter); - perf_swcounter_store_irq(sibling, counter->hw_event.type); + perf_swcounter_store_irq(sibling, counter->hw_event.event_config); perf_swcounter_store_irq(sibling, atomic64_read(&counter->count)); } } @@ -1477,21 +1471,25 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) static void perf_swcounter_overflow(struct perf_counter *counter, int nmi, struct pt_regs *regs) { - perf_swcounter_save_and_restart(counter); + perf_swcounter_update(counter); + perf_swcounter_set_period(counter); perf_swcounter_interrupt(counter, nmi, regs); } static int perf_swcounter_match(struct perf_counter *counter, - enum hw_event_types event, - struct pt_regs *regs) + enum perf_event_types type, + u32 event, struct pt_regs *regs) { if (counter->state != PERF_COUNTER_STATE_ACTIVE) return 0; - if (counter->hw_event.raw) + if (counter->hw_event.raw_type) + return 0; + + if (counter->hw_event.type != type) return 0; - if (counter->hw_event.type != event) + if (counter->hw_event.event_id != event) return 0; if (counter->hw_event.exclude_user && user_mode(regs)) @@ -1512,8 +1510,8 @@ static void perf_swcounter_add(struct perf_counter *counter, u64 nr, } static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, - enum hw_event_types event, u64 nr, - int nmi, struct pt_regs *regs) + enum perf_event_types type, u32 event, + u64 nr, int nmi, struct pt_regs *regs) { struct perf_counter *counter; @@ -1522,24 +1520,31 @@ static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, rcu_read_lock(); list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) { - if (perf_swcounter_match(counter, event, regs)) + if (perf_swcounter_match(counter, type, event, regs)) perf_swcounter_add(counter, nr, nmi, regs); } rcu_read_unlock(); } -void perf_swcounter_event(enum hw_event_types event, u64 nr, - int nmi, struct pt_regs *regs) +static void __perf_swcounter_event(enum perf_event_types type, u32 event, + u64 nr, int nmi, struct pt_regs *regs) { struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context); - perf_swcounter_ctx_event(&cpuctx->ctx, event, nr, nmi, regs); - if (cpuctx->task_ctx) - perf_swcounter_ctx_event(cpuctx->task_ctx, event, nr, nmi, regs); + perf_swcounter_ctx_event(&cpuctx->ctx, type, event, nr, nmi, regs); + if (cpuctx->task_ctx) { + perf_swcounter_ctx_event(cpuctx->task_ctx, type, event, + nr, nmi, regs); + } put_cpu_var(perf_cpu_context); } +void perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs) +{ + __perf_swcounter_event(PERF_TYPE_SOFTWARE, event, nr, nmi, regs); +} + static void perf_swcounter_read(struct perf_counter *counter) { perf_swcounter_update(counter); @@ -1733,8 +1738,12 @@ static const struct hw_perf_counter_ops perf_ops_cpu_migrations = { #ifdef CONFIG_EVENT_PROFILE void perf_tpcounter_event(int event_id) { - perf_swcounter_event(PERF_TP_EVENTS_MIN + event_id, 1, 1, - task_pt_regs(current)); + struct pt_regs *regs = get_irq_regs(); + + if (!regs) + regs = task_pt_regs(current); + + __perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, 1, 1, regs); } extern int ftrace_profile_enable(int); @@ -1742,15 +1751,13 @@ extern void ftrace_profile_disable(int); static void tp_perf_counter_destroy(struct perf_counter *counter) { - int event_id = counter->hw_event.type - PERF_TP_EVENTS_MIN; - - ftrace_profile_disable(event_id); + ftrace_profile_disable(counter->hw_event.event_id); } static const struct hw_perf_counter_ops * tp_perf_counter_init(struct perf_counter *counter) { - int event_id = counter->hw_event.type - PERF_TP_EVENTS_MIN; + int event_id = counter->hw_event.event_id; int ret; ret = ftrace_profile_enable(event_id); @@ -1758,6 +1765,7 @@ tp_perf_counter_init(struct perf_counter *counter) return NULL; counter->destroy = tp_perf_counter_destroy; + counter->hw.irq_period = counter->hw_event.irq_period; return &perf_ops_generic; } @@ -1783,7 +1791,7 @@ sw_perf_counter_init(struct perf_counter *counter) * to be kernel events, and page faults are never hypervisor * events. */ - switch (counter->hw_event.type) { + switch (counter->hw_event.event_id) { case PERF_COUNT_CPU_CLOCK: hw_ops = &perf_ops_cpu_clock; @@ -1813,9 +1821,6 @@ sw_perf_counter_init(struct perf_counter *counter) if (!counter->hw_event.exclude_kernel) hw_ops = &perf_ops_cpu_migrations; break; - default: - hw_ops = tp_perf_counter_init(counter); - break; } if (hw_ops) @@ -1870,10 +1875,22 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, counter->state = PERF_COUNTER_STATE_OFF; hw_ops = NULL; - if (!hw_event->raw && hw_event->type < 0) - hw_ops = sw_perf_counter_init(counter); - else + + if (hw_event->raw_type) + hw_ops = hw_perf_counter_init(counter); + else switch (hw_event->type) { + case PERF_TYPE_HARDWARE: hw_ops = hw_perf_counter_init(counter); + break; + + case PERF_TYPE_SOFTWARE: + hw_ops = sw_perf_counter_init(counter); + break; + + case PERF_TYPE_TRACEPOINT: + hw_ops = tp_perf_counter_init(counter); + break; + } if (!hw_ops) { kfree(counter); -- GitLab From 0322cd6ec504b0bf08ca7b2c3d7f43bda37d79c9 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 19 Mar 2009 20:26:19 +0100 Subject: [PATCH 0123/6080] perf_counter: unify irq output code Impact: cleanup Having 3 slightly different copies of the same code around does nobody any good. First step in revamping the output format. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Steven Rostedt Orig-LKML-Reference: <20090319194233.929962222@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 51 +------------- arch/x86/kernel/cpu/perf_counter.c | 53 +-------------- include/linux/perf_counter.h | 2 + kernel/perf_counter.c | 106 +++++++++++++++-------------- 4 files changed, 61 insertions(+), 151 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 26f69dc7130e..88b72eb4af12 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -662,41 +662,6 @@ void perf_counter_do_pending(void) } } -/* - * Record data for an irq counter. - * This function was lifted from the x86 code; maybe it should - * go in the core? - */ -static void perf_store_irq_data(struct perf_counter *counter, u64 data) -{ - struct perf_data *irqdata = counter->irqdata; - - if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) { - irqdata->overrun++; - } else { - u64 *p = (u64 *) &irqdata->data[irqdata->len]; - - *p = data; - irqdata->len += sizeof(u64); - } -} - -/* - * Record all the values of the counters in a group - */ -static void perf_handle_group(struct perf_counter *counter) -{ - struct perf_counter *leader, *sub; - - leader = counter->group_leader; - list_for_each_entry(sub, &leader->sibling_list, list_entry) { - if (sub != counter) - sub->hw_ops->read(sub); - perf_store_irq_data(counter, sub->hw_event.event_config); - perf_store_irq_data(counter, atomic64_read(&sub->count)); - } -} - /* * A counter has overflowed; update its count and record * things if requested. Note that interrupts are hard-disabled @@ -736,20 +701,8 @@ static void record_and_restart(struct perf_counter *counter, long val, /* * Finally record data if requested. */ - if (record) { - switch (counter->hw_event.record_type) { - case PERF_RECORD_SIMPLE: - break; - case PERF_RECORD_IRQ: - perf_store_irq_data(counter, instruction_pointer(regs)); - counter->wakeup_pending = 1; - break; - case PERF_RECORD_GROUP: - perf_handle_group(counter); - counter->wakeup_pending = 1; - break; - } - } + if (record) + perf_counter_output(counter, 1, regs); } /* diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index d844ae41d5a3..902282d68b0c 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -674,20 +674,6 @@ static void pmc_generic_disable(struct perf_counter *counter) x86_perf_counter_update(counter, hwc, idx); } -static void perf_store_irq_data(struct perf_counter *counter, u64 data) -{ - struct perf_data *irqdata = counter->irqdata; - - if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) { - irqdata->overrun++; - } else { - u64 *p = (u64 *) &irqdata->data[irqdata->len]; - - *p = data; - irqdata->len += sizeof(u64); - } -} - /* * Save and restart an expired counter. Called by NMI contexts, * so it has to be careful about preempting normal counter ops: @@ -704,22 +690,6 @@ static void perf_save_and_restart(struct perf_counter *counter) __pmc_generic_enable(counter, hwc, idx); } -static void -perf_handle_group(struct perf_counter *sibling, u64 *status, u64 *overflown) -{ - struct perf_counter *counter, *group_leader = sibling->group_leader; - - /* - * Store sibling timestamps (if any): - */ - list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { - - x86_perf_counter_update(counter, &counter->hw, counter->hw.idx); - perf_store_irq_data(sibling, counter->hw_event.event_config); - perf_store_irq_data(sibling, atomic64_read(&counter->count)); - } -} - /* * Maximum interrupt frequency of 100KHz per CPU */ @@ -754,28 +724,7 @@ again: continue; perf_save_and_restart(counter); - - switch (counter->hw_event.record_type) { - case PERF_RECORD_SIMPLE: - continue; - case PERF_RECORD_IRQ: - perf_store_irq_data(counter, instruction_pointer(regs)); - break; - case PERF_RECORD_GROUP: - perf_handle_group(counter, &status, &ack); - break; - } - /* - * From NMI context we cannot call into the scheduler to - * do a task wakeup - but we mark these generic as - * wakeup_pending and initate a wakeup callback: - */ - if (nmi) { - counter->wakeup_pending = 1; - set_tsk_thread_flag(current, TIF_PERF_COUNTERS); - } else { - wake_up(&counter->waitq); - } + perf_counter_output(counter, nmi, regs); } hw_perf_ack_status(ack); diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 8f9394905502..a4b76c0175f3 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -317,6 +317,8 @@ extern int hw_perf_group_sched_in(struct perf_counter *group_leader, struct perf_cpu_context *cpuctx, struct perf_counter_context *ctx, int cpu); +extern void perf_counter_output(struct perf_counter *counter, + int nmi, struct pt_regs *regs); /* * Return 1 for a software counter, 0 for a hardware counter */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 68a56a68bc74..f054b8c9bf96 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1353,6 +1353,60 @@ static const struct file_operations perf_fops = { .compat_ioctl = perf_ioctl, }; +/* + * Output + */ + +static void perf_counter_store_irq(struct perf_counter *counter, u64 data) +{ + struct perf_data *irqdata = counter->irqdata; + + if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) { + irqdata->overrun++; + } else { + u64 *p = (u64 *) &irqdata->data[irqdata->len]; + + *p = data; + irqdata->len += sizeof(u64); + } +} + +static void perf_counter_handle_group(struct perf_counter *counter) +{ + struct perf_counter *leader, *sub; + + leader = counter->group_leader; + list_for_each_entry(sub, &leader->sibling_list, list_entry) { + if (sub != counter) + sub->hw_ops->read(sub); + perf_counter_store_irq(counter, sub->hw_event.event_config); + perf_counter_store_irq(counter, atomic64_read(&sub->count)); + } +} + +void perf_counter_output(struct perf_counter *counter, + int nmi, struct pt_regs *regs) +{ + switch (counter->hw_event.record_type) { + case PERF_RECORD_SIMPLE: + return; + + case PERF_RECORD_IRQ: + perf_counter_store_irq(counter, instruction_pointer(regs)); + break; + + case PERF_RECORD_GROUP: + perf_counter_handle_group(counter); + break; + } + + if (nmi) { + counter->wakeup_pending = 1; + set_perf_counter_pending(); + } else + wake_up(&counter->waitq); +} + /* * Generic software counter infrastructure */ @@ -1395,54 +1449,6 @@ static void perf_swcounter_set_period(struct perf_counter *counter) atomic64_set(&hwc->count, -left); } -static void perf_swcounter_store_irq(struct perf_counter *counter, u64 data) -{ - struct perf_data *irqdata = counter->irqdata; - - if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) { - irqdata->overrun++; - } else { - u64 *p = (u64 *) &irqdata->data[irqdata->len]; - - *p = data; - irqdata->len += sizeof(u64); - } -} - -static void perf_swcounter_handle_group(struct perf_counter *sibling) -{ - struct perf_counter *counter, *group_leader = sibling->group_leader; - - list_for_each_entry(counter, &group_leader->sibling_list, list_entry) { - counter->hw_ops->read(counter); - perf_swcounter_store_irq(sibling, counter->hw_event.event_config); - perf_swcounter_store_irq(sibling, atomic64_read(&counter->count)); - } -} - -static void perf_swcounter_interrupt(struct perf_counter *counter, - int nmi, struct pt_regs *regs) -{ - switch (counter->hw_event.record_type) { - case PERF_RECORD_SIMPLE: - break; - - case PERF_RECORD_IRQ: - perf_swcounter_store_irq(counter, instruction_pointer(regs)); - break; - - case PERF_RECORD_GROUP: - perf_swcounter_handle_group(counter); - break; - } - - if (nmi) { - counter->wakeup_pending = 1; - set_perf_counter_pending(); - } else - wake_up(&counter->waitq); -} - static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) { struct perf_counter *counter; @@ -1461,7 +1467,7 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) regs = task_pt_regs(current); if (regs) - perf_swcounter_interrupt(counter, 0, regs); + perf_counter_output(counter, 0, regs); hrtimer_forward_now(hrtimer, ns_to_ktime(counter->hw.irq_period)); @@ -1473,7 +1479,7 @@ static void perf_swcounter_overflow(struct perf_counter *counter, { perf_swcounter_update(counter); perf_swcounter_set_period(counter); - perf_swcounter_interrupt(counter, nmi, regs); + perf_counter_output(counter, nmi, regs); } static int perf_swcounter_match(struct perf_counter *counter, -- GitLab From db4fb5acf20295063d1d5105e67724eb51440207 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 19 Mar 2009 20:26:20 +0100 Subject: [PATCH 0124/6080] perf_counter: powerpc: clean up perc_counter_interrupt Impact: cleanup This updates the powerpc perf_counter_interrupt following on from the "perf_counter: unify irq output code" patch. Since we now use the generic perf_counter_output code, which sets the perf_counter_pending flag directly, we no longer need the need_wakeup variable. This removes need_wakeup and makes perf_counter_interrupt use get_perf_counter_pending() instead. Signed-off-by: Paul Mackerras Signed-off-by: Peter Zijlstra Cc: Steven Rostedt Orig-LKML-Reference: <20090319194234.024464535@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 88b72eb4af12..830ca9c4494c 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -723,8 +723,6 @@ static void perf_counter_interrupt(struct pt_regs *regs) /* counter has overflowed */ found = 1; record_and_restart(counter, val, regs); - if (counter->wakeup_pending) - need_wakeup = 1; } } @@ -754,17 +752,14 @@ static void perf_counter_interrupt(struct pt_regs *regs) /* * If we need a wakeup, check whether interrupts were soft-enabled * when we took the interrupt. If they were, we can wake stuff up - * immediately; otherwise we'll have to set a flag and do the - * wakeup when interrupts get soft-enabled. + * immediately; otherwise we'll have do the wakeup when interrupts + * get soft-enabled. */ - if (need_wakeup) { - if (regs->softe) { - irq_enter(); - perf_counter_do_pending(); - irq_exit(); - } else { - set_perf_counter_pending(); - } + if (get_perf_counter_pending() && regs->softe) { + irq_enter(); + clear_perf_counter_pending(); + perf_counter_do_pending(); + irq_exit(); } } -- GitLab From 9aaa131a279834dff75c290c91f0058f62d72d46 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 21 Mar 2009 15:31:47 +1100 Subject: [PATCH 0125/6080] perf_counter: fix type/event_id layout on big-endian systems Impact: build fix for powerpc Commit db3a944aca35ae61 ("perf_counter: revamp syscall input ABI") expanded the hw_event.type field into a union of structs containing bitfields. In particular it introduced a type field and a raw_type field, with the intention that the 1-bit raw_type field should overlay the most-significant bit of the 8-bit type field, and in fact perf_counter_alloc() now assumes that (or at least, assumes that raw_type doesn't overlay any of the bits that are 1 in the values of PERF_TYPE_{HARDWARE,SOFTWARE,TRACEPOINT}). Unfortunately this is not true on big-endian systems such as PowerPC, where bitfields are laid out from left to right, i.e. from most significant bit to least significant. This means that setting hw_event.type = PERF_TYPE_SOFTWARE will set hw_event.raw_type to 1. This fixes it by making the layout depend on whether or not __BIG_ENDIAN_BITFIELD is defined. It's a bit ugly, but that's what we get for using bitfields in a user/kernel ABI. Also, that commit didn't fix up some places in arch/powerpc/kernel/ perf_counter.c where hw_event.raw and hw_event.event_id were used. This fixes them too. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/perf_counter.c | 9 +++++---- include/linux/perf_counter.h | 12 ++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 830ca9c4494c..6413d9c0313b 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -602,12 +602,13 @@ hw_perf_counter_init(struct perf_counter *counter) return NULL; if ((s64)counter->hw_event.irq_period < 0) return NULL; - ev = counter->hw_event.event_id; - if (!counter->hw_event.raw) { - if (ev >= ppmu->n_generic || - ppmu->generic_events[ev] == 0) + if (!counter->hw_event.raw_type) { + ev = counter->hw_event.event_id; + if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) return NULL; ev = ppmu->generic_events[ev]; + } else { + ev = counter->hw_event.raw_event_id; } counter->hw.config_base = ev; counter->hw.idx = 0; diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index a4b76c0175f3..98f5990be1e1 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -15,6 +15,7 @@ #include #include +#include /* * User-space ABI bits: @@ -86,6 +87,7 @@ enum perf_counter_record_type { */ struct perf_counter_hw_event { union { +#ifndef __BIG_ENDIAN_BITFIELD struct { __u64 event_id : 56, type : 8; @@ -94,6 +96,16 @@ struct perf_counter_hw_event { __u64 raw_event_id : 63, raw_type : 1; }; +#else + struct { + __u64 type : 8, + event_id : 56; + }; + struct { + __u64 raw_type : 1, + raw_event_id : 63; + }; +#endif /* __BIT_ENDIAN_BITFIELD */ __u64 event_config; }; -- GitLab From 6f9f791eb53b56097cd311a1a5517a8e89bdaf35 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 23 Mar 2009 21:26:52 +0100 Subject: [PATCH 0126/6080] perf_counter: create Documentation/perf_counter/ and move perfcounters.txt there We'll have more files in that directory, prepare for that. Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/{perf-counters.txt => perf_counter/design.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Documentation/{perf-counters.txt => perf_counter/design.txt} (100%) diff --git a/Documentation/perf-counters.txt b/Documentation/perf_counter/design.txt similarity index 100% rename from Documentation/perf-counters.txt rename to Documentation/perf_counter/design.txt -- GitLab From e0143bad9dbf2a8fad4c5430562bceba196b66ea Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 23 Mar 2009 21:29:59 +0100 Subject: [PATCH 0127/6080] perf_counter: add sample user-space to Documentation/perf_counter/ Initial version of kerneltop.c and perfstat.c. Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 12 + Documentation/perf_counter/kerneltop.c | 956 +++++++++++++++++++++++++ Documentation/perf_counter/perfstat.c | 521 ++++++++++++++ 3 files changed, 1489 insertions(+) create mode 100644 Documentation/perf_counter/Makefile create mode 100644 Documentation/perf_counter/kerneltop.c create mode 100644 Documentation/perf_counter/perfstat.c diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile new file mode 100644 index 000000000000..b45749753fcb --- /dev/null +++ b/Documentation/perf_counter/Makefile @@ -0,0 +1,12 @@ +BINS = kerneltop perfstat + +all: $(BINS) + +kerneltop: kerneltop.c perfcounters.h + cc -O6 -Wall -lrt `pkg-config --cflags --libs glib-2.0` -o $@ $< + +perfstat: kerneltop + ln -sf kerneltop perfstat + +clean: + rm $(BINS) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c new file mode 100644 index 000000000000..cf0e30bab5d5 --- /dev/null +++ b/Documentation/perf_counter/kerneltop.c @@ -0,0 +1,956 @@ +/* + * kerneltop.c: show top kernel functions - performance counters showcase + + Build with: + + cc -O6 -Wall `pkg-config --cflags --libs glib-2.0` -o kerneltop kerneltop.c + + Sample output: + +------------------------------------------------------------------------------ + KernelTop: 2669 irqs/sec [NMI, cache-misses/cache-refs], (all, cpu: 2) +------------------------------------------------------------------------------ + + weight RIP kernel function + ______ ________________ _______________ + + 35.20 - ffffffff804ce74b : skb_copy_and_csum_dev + 33.00 - ffffffff804cb740 : sock_alloc_send_skb + 31.26 - ffffffff804ce808 : skb_push + 22.43 - ffffffff80510004 : tcp_established_options + 19.00 - ffffffff8027d250 : find_get_page + 15.76 - ffffffff804e4fc9 : eth_type_trans + 15.20 - ffffffff804d8baa : dst_release + 14.86 - ffffffff804cf5d8 : skb_release_head_state + 14.00 - ffffffff802217d5 : read_hpet + 12.00 - ffffffff804ffb7f : __ip_local_out + 11.97 - ffffffff804fc0c8 : ip_local_deliver_finish + 8.54 - ffffffff805001a3 : ip_queue_xmit + + Started by Ingo Molnar + + Improvements and fixes by: + + Arjan van de Ven + Yanmin Zhang + Mike Galbraith + + Released under the GPL v2. (and only v2, not any later version) + + */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef __x86_64__ +# define __NR_perf_counter_open 295 +#endif + +#ifdef __i386__ +# define __NR_perf_counter_open 333 +#endif + +/* + * Pick up some kernel type conventions: + */ +#define __user +#define asmlinkage + +typedef unsigned int __u32; +typedef unsigned long long __u64; +typedef long long __s64; + +/* + * User-space ABI bits: + */ + +/* + * Generalized performance counter event types, used by the hw_event.type + * parameter of the sys_perf_counter_open() syscall: + */ +enum hw_event_types { + /* + * Common hardware events, generalized by the kernel: + */ + PERF_COUNT_CPU_CYCLES = 0, + PERF_COUNT_INSTRUCTIONS = 1, + PERF_COUNT_CACHE_REFERENCES = 2, + PERF_COUNT_CACHE_MISSES = 3, + PERF_COUNT_BRANCH_INSTRUCTIONS = 4, + PERF_COUNT_BRANCH_MISSES = 5, + PERF_COUNT_BUS_CYCLES = 6, + + PERF_HW_EVENTS_MAX = 7, + + /* + * Special "software" counters provided by the kernel, even if + * the hardware does not support performance counters. These + * counters measure various physical and sw events of the + * kernel (and allow the profiling of them as well): + */ + PERF_COUNT_CPU_CLOCK = -1, + PERF_COUNT_TASK_CLOCK = -2, + PERF_COUNT_PAGE_FAULTS = -3, + PERF_COUNT_CONTEXT_SWITCHES = -4, + PERF_COUNT_CPU_MIGRATIONS = -5, + + PERF_SW_EVENTS_MIN = -6, +}; + +/* + * IRQ-notification data record type: + */ +enum perf_counter_record_type { + PERF_RECORD_SIMPLE = 0, + PERF_RECORD_IRQ = 1, + PERF_RECORD_GROUP = 2, +}; + +/* + * Hardware event to monitor via a performance monitoring counter: + */ +struct perf_counter_hw_event { + __s64 type; + + __u64 irq_period; + __u64 record_type; + __u64 read_format; + + __u64 disabled : 1, /* off by default */ + nmi : 1, /* NMI sampling */ + raw : 1, /* raw event type */ + inherit : 1, /* children inherit it */ + pinned : 1, /* must always be on PMU */ + exclusive : 1, /* only group on PMU */ + exclude_user : 1, /* don't count user */ + exclude_kernel : 1, /* ditto kernel */ + exclude_hv : 1, /* ditto hypervisor */ + exclude_idle : 1, /* don't count when idle */ + + __reserved_1 : 54; + + __u32 extra_config_len; + __u32 __reserved_4; + + __u64 __reserved_2; + __u64 __reserved_3; +}; + +/* + * Ioctls that can be done on a perf counter fd: + */ +#define PERF_COUNTER_IOC_ENABLE _IO('$', 0) +#define PERF_COUNTER_IOC_DISABLE _IO('$', 1) + +asmlinkage int sys_perf_counter_open( + + struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, + int cpu, + int group_fd, + unsigned long flags) +{ + int ret; + + ret = syscall( + __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); +#if defined(__x86_64__) || defined(__i386__) + if (ret < 0 && ret > -4096) { + errno = -ret; + ret = -1; + } +#endif + return ret; +} + +const char *event_types [] = { + "CPU cycles", + "instructions", + "cache-refs", + "cache-misses", + "branches", + "branch-misses", + "bus cycles" +}; + +const unsigned int default_count[] = { + 1000000, + 1000000, + 10000, + 10000, + 1000000, + 10000, +}; + +/* + * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all + * counters in the current task. + */ +#define PR_TASK_PERF_COUNTERS_DISABLE 31 +#define PR_TASK_PERF_COUNTERS_ENABLE 32 + +#define MAX_COUNTERS 8 + +static int nr_counters = -1; + +static __u64 count_filter = 100; + +#define MAX_NR_CPUS 256 + +static int event_count[MAX_COUNTERS]; +static unsigned long event_id[MAX_COUNTERS]; +static int event_raw[MAX_COUNTERS]; + +static int tid = -1; +static int profile_cpu = -1; +static int nr_cpus = 0; +static int nmi = 1; +static int group = 0; + +static char *vmlinux; + +static char *sym_filter; +static unsigned long filter_start; +static unsigned long filter_end; + +static int delay_secs = 2; +static int zero; +static int dump_symtab; + +struct source_line { + uint64_t EIP; + unsigned long count; + char *line; +}; + +static GList *lines; + +static void display_help(void) +{ + printf( + "Usage: kerneltop []\n\n" + "KernelTop Options (up to %d event types can be specified at once):\n\n", + MAX_COUNTERS); + printf( + " -e EID --event_id=EID # event type ID [default: 0]\n" + " 0: CPU cycles\n" + " 1: instructions\n" + " 2: cache accesses\n" + " 3: cache misses\n" + " 4: branch instructions\n" + " 5: branch prediction misses\n" + " 6: bus cycles\n\n" + " rNNN: raw PMU events (eventsel+umask)\n\n" + " -c CNT --count=CNT # event period to sample\n\n" + " -C CPU --cpu=CPU # CPU (-1 for all) [default: -1]\n" + " -p PID --pid=PID # PID of sampled task (-1 for all) [default: -1]\n\n" + " -d delay --delay= # sampling/display delay [default: 2]\n" + " -f CNT --filter=CNT # min-event-count filter [default: 100]\n\n" + " -s symbol --symbol= # function to be showed annotated one-shot\n" + " -x path --vmlinux= # the vmlinux binary, required for -s use:\n" + " -z --zero # zero counts after display\n" + " -D --dump_symtab # dump symbol table to stderr on startup\n" + "\n"); + + exit(0); +} + +static void process_options(int argc, char *argv[]) +{ + int error = 0, counter; + + for (;;) { + int option_index = 0; + /** Options for getopt */ + static struct option long_options[] = { + {"count", required_argument, NULL, 'c'}, + {"cpu", required_argument, NULL, 'C'}, + {"delay", required_argument, NULL, 'd'}, + {"dump_symtab", no_argument, NULL, 'D'}, + {"event_id", required_argument, NULL, 'e'}, + {"filter", required_argument, NULL, 'f'}, + {"group", required_argument, NULL, 'g'}, + {"help", no_argument, NULL, 'h'}, + {"nmi", required_argument, NULL, 'n'}, + {"pid", required_argument, NULL, 'p'}, + {"vmlinux", required_argument, NULL, 'x'}, + {"symbol", required_argument, NULL, 's'}, + {"zero", no_argument, NULL, 'z'}, + {NULL, 0, NULL, 0 } + }; + int c = getopt_long(argc, argv, "c:C:d:De:f:g:hn:p:s:x:z", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'c': + if (nr_counters == -1) + nr_counters = 0; + event_count[nr_counters] = atoi(optarg); break; + case 'C': + /* CPU and PID are mutually exclusive */ + if (tid != -1) { + printf("WARNING: CPU switch overriding PID\n"); + sleep(1); + tid = -1; + } + profile_cpu = atoi(optarg); break; + case 'd': delay_secs = atoi(optarg); break; + case 'D': dump_symtab = 1; break; + + case 'e': + nr_counters++; + if (nr_counters == MAX_COUNTERS) { + error = 1; + break; + } + if (*optarg == 'r') { + event_raw[nr_counters] = 1; + ++optarg; + } + event_id[nr_counters] = strtol(optarg, NULL, 16); + break; + + case 'f': count_filter = atoi(optarg); break; + case 'g': group = atoi(optarg); break; + case 'h': display_help(); break; + case 'n': nmi = atoi(optarg); break; + case 'p': + /* CPU and PID are mutually exclusive */ + if (profile_cpu != -1) { + printf("WARNING: PID switch overriding CPU\n"); + sleep(1); + profile_cpu = -1; + } + tid = atoi(optarg); break; + case 's': sym_filter = strdup(optarg); break; + case 'x': vmlinux = strdup(optarg); break; + case 'z': zero = 1; break; + default: error = 1; break; + } + } + if (error) + display_help(); + + nr_counters++; + if (nr_counters < 1) + nr_counters = 1; + + for (counter = 0; counter < nr_counters; counter++) { + if (event_count[counter]) + continue; + + if (event_id[counter] < PERF_HW_EVENTS_MAX) + event_count[counter] = default_count[event_id[counter]]; + else + event_count[counter] = 100000; + } +} + +static uint64_t min_ip; +static uint64_t max_ip = -1ll; + +struct sym_entry { + unsigned long long addr; + char *sym; + unsigned long count[MAX_COUNTERS]; + int skip; + GList *source; +}; + +#define MAX_SYMS 100000 + +static int sym_table_count; + +struct sym_entry *sym_filter_entry; + +static struct sym_entry sym_table[MAX_SYMS]; + +static void show_details(struct sym_entry *sym); + +/* + * Ordering weight: count-1 * count-1 * ... / count-n + */ +static double sym_weight(const struct sym_entry *sym) +{ + double weight; + int counter; + + weight = sym->count[0]; + + for (counter = 1; counter < nr_counters-1; counter++) + weight *= sym->count[counter]; + + weight /= (sym->count[counter] + 1); + + return weight; +} + +static int compare(const void *__sym1, const void *__sym2) +{ + const struct sym_entry *sym1 = __sym1, *sym2 = __sym2; + + return sym_weight(sym1) < sym_weight(sym2); +} + +static time_t last_refresh; +static long events; +static long userspace_events; +static const char CONSOLE_CLEAR[] = ""; + +static struct sym_entry tmp[MAX_SYMS]; + +static void print_sym_table(void) +{ + int i, printed; + int counter; + float events_per_sec = events/delay_secs; + float kevents_per_sec = (events-userspace_events)/delay_secs; + + memcpy(tmp, sym_table, sizeof(sym_table[0])*sym_table_count); + qsort(tmp, sym_table_count, sizeof(tmp[0]), compare); + + write(1, CONSOLE_CLEAR, strlen(CONSOLE_CLEAR)); + + printf( +"------------------------------------------------------------------------------\n"); + printf( " KernelTop:%8.0f irqs/sec kernel:%3.1f%% [%s, ", + events_per_sec, + 100.0 - (100.0*((events_per_sec-kevents_per_sec)/events_per_sec)), + nmi ? "NMI" : "IRQ"); + + if (nr_counters == 1) + printf("%d ", event_count[0]); + + for (counter = 0; counter < nr_counters; counter++) { + if (counter) + printf("/"); + + if (event_id[counter] < PERF_HW_EVENTS_MAX) + printf( "%s", event_types[event_id[counter]]); + else + printf( "raw:%04lx", event_id[counter]); + } + + printf( "], "); + + if (tid != -1) + printf(" (tid: %d", tid); + else + printf(" (all"); + + if (profile_cpu != -1) + printf(", cpu: %d)\n", profile_cpu); + else { + if (tid != -1) + printf(")\n"); + else + printf(", %d CPUs)\n", nr_cpus); + } + + printf("------------------------------------------------------------------------------\n\n"); + + if (nr_counters == 1) + printf(" events"); + else + printf(" weight events"); + + printf(" RIP kernel function\n" + " ______ ______ ________________ _______________\n\n" + ); + + printed = 0; + for (i = 0; i < sym_table_count; i++) { + int count; + + if (nr_counters == 1) { + if (printed <= 18 && + tmp[i].count[0] >= count_filter) { + printf("%19.2f - %016llx : %s\n", + sym_weight(tmp + i), tmp[i].addr, tmp[i].sym); + printed++; + } + } else { + if (printed <= 18 && + tmp[i].count[0] >= count_filter) { + printf("%8.1f %10ld - %016llx : %s\n", + sym_weight(tmp + i), + tmp[i].count[0], + tmp[i].addr, tmp[i].sym); + printed++; + } + } + /* + * Add decay to the counts: + */ + for (count = 0; count < nr_counters; count++) + sym_table[i].count[count] = zero ? 0 : sym_table[i].count[count] * 7 / 8; + } + + if (sym_filter_entry) + show_details(sym_filter_entry); + + last_refresh = time(NULL); + + { + struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; + + if (poll(&stdin_poll, 1, 0) == 1) { + printf("key pressed - exiting.\n"); + exit(0); + } + } +} + +static int read_symbol(FILE *in, struct sym_entry *s) +{ + static int filter_match = 0; + char *sym, stype; + char str[500]; + int rc, pos; + + rc = fscanf(in, "%llx %c %499s", &s->addr, &stype, str); + if (rc == EOF) + return -1; + + assert(rc == 3); + + /* skip until end of line: */ + pos = strlen(str); + do { + rc = fgetc(in); + if (rc == '\n' || rc == EOF || pos >= 499) + break; + str[pos] = rc; + pos++; + } while (1); + str[pos] = 0; + + sym = str; + + /* Filter out known duplicates and non-text symbols. */ + if (!strcmp(sym, "_text")) + return 1; + if (!min_ip && !strcmp(sym, "_stext")) + return 1; + if (!strcmp(sym, "_etext") || !strcmp(sym, "_sinittext")) + return 1; + if (stype != 'T' && stype != 't') + return 1; + if (!strncmp("init_module", sym, 11) || !strncmp("cleanup_module", sym, 14)) + return 1; + if (strstr(sym, "_text_start") || strstr(sym, "_text_end")) + return 1; + + s->sym = malloc(strlen(str)); + assert(s->sym); + + strcpy((char *)s->sym, str); + s->skip = 0; + + /* Tag events to be skipped. */ + if (!strcmp("default_idle", s->sym) || !strcmp("cpu_idle", s->sym)) + s->skip = 1; + if (!strcmp("enter_idle", s->sym) || !strcmp("exit_idle", s->sym)) + s->skip = 1; + + if (filter_match == 1) { + filter_end = s->addr; + filter_match = -1; + if (filter_end - filter_start > 10000) { + printf("hm, too large filter symbol <%s> - skipping.\n", + sym_filter); + printf("symbol filter start: %016lx\n", filter_start); + printf(" end: %016lx\n", filter_end); + filter_end = filter_start = 0; + sym_filter = NULL; + sleep(1); + } + } + if (filter_match == 0 && sym_filter && !strcmp(s->sym, sym_filter)) { + filter_match = 1; + filter_start = s->addr; + } + + return 0; +} + +int compare_addr(const void *__sym1, const void *__sym2) +{ + const struct sym_entry *sym1 = __sym1, *sym2 = __sym2; + + return sym1->addr > sym2->addr; +} + +static void sort_symbol_table(void) +{ + int i, dups; + + do { + qsort(sym_table, sym_table_count, sizeof(sym_table[0]), compare_addr); + for (i = 0, dups = 0; i < sym_table_count; i++) { + if (sym_table[i].addr == sym_table[i+1].addr) { + sym_table[i+1].addr = -1ll; + dups++; + } + } + sym_table_count -= dups; + } while(dups); +} + +static void parse_symbols(void) +{ + struct sym_entry *last; + + FILE *kallsyms = fopen("/proc/kallsyms", "r"); + + if (!kallsyms) { + printf("Could not open /proc/kallsyms - no CONFIG_KALLSYMS_ALL=y?\n"); + exit(-1); + } + + while (!feof(kallsyms)) { + if (read_symbol(kallsyms, &sym_table[sym_table_count]) == 0) { + sym_table_count++; + assert(sym_table_count <= MAX_SYMS); + } + } + + sort_symbol_table(); + min_ip = sym_table[0].addr; + max_ip = sym_table[sym_table_count-1].addr; + last = sym_table + sym_table_count++; + + last->addr = -1ll; + last->sym = ""; + + if (filter_end) { + int count; + for (count=0; count < sym_table_count; count ++) { + if (!strcmp(sym_table[count].sym, sym_filter)) { + sym_filter_entry = &sym_table[count]; + break; + } + } + } + if (dump_symtab) { + int i; + + for (i = 0; i < sym_table_count; i++) + fprintf(stderr, "%llx %s\n", + sym_table[i].addr, sym_table[i].sym); + } +} + + +static void parse_vmlinux(char *filename) +{ + FILE *file; + char command[PATH_MAX*2]; + if (!filename) + return; + + sprintf(command, "objdump --start-address=0x%016lx --stop-address=0x%016lx -dS %s", filter_start, filter_end, filename); + + file = popen(command, "r"); + if (!file) + return; + + while (!feof(file)) { + struct source_line *src; + size_t dummy = 0; + char *c; + + src = malloc(sizeof(struct source_line)); + assert(src != NULL); + memset(src, 0, sizeof(struct source_line)); + + if (getline(&src->line, &dummy, file) < 0) + break; + if (!src->line) + break; + + c = strchr(src->line, '\n'); + if (c) + *c = 0; + + lines = g_list_prepend(lines, src); + + if (strlen(src->line)>8 && src->line[8] == ':') + src->EIP = strtoull(src->line, NULL, 16); + if (strlen(src->line)>8 && src->line[16] == ':') + src->EIP = strtoull(src->line, NULL, 16); + } + pclose(file); + lines = g_list_reverse(lines); +} + +static void record_precise_ip(uint64_t ip) +{ + struct source_line *line; + GList *item; + + item = g_list_first(lines); + while (item) { + line = item->data; + if (line->EIP == ip) + line->count++; + if (line->EIP > ip) + break; + item = g_list_next(item); + } +} + +static void lookup_sym_in_vmlinux(struct sym_entry *sym) +{ + struct source_line *line; + GList *item; + char pattern[PATH_MAX]; + sprintf(pattern, "<%s>:", sym->sym); + + item = g_list_first(lines); + while (item) { + line = item->data; + if (strstr(line->line, pattern)) { + sym->source = item; + break; + } + item = g_list_next(item); + } +} + +void show_lines(GList *item_queue, int item_queue_count) +{ + int i; + struct source_line *line; + + for (i = 0; i < item_queue_count; i++) { + line = item_queue->data; + printf("%8li\t%s\n", line->count, line->line); + item_queue = g_list_next(item_queue); + } +} + +#define TRACE_COUNT 3 + +static void show_details(struct sym_entry *sym) +{ + struct source_line *line; + GList *item; + int displayed = 0; + GList *item_queue = NULL; + int item_queue_count = 0; + + if (!sym->source) + lookup_sym_in_vmlinux(sym); + if (!sym->source) + return; + + printf("Showing details for %s\n", sym->sym); + + item = sym->source; + while (item) { + line = item->data; + if (displayed && strstr(line->line, ">:")) + break; + + if (!item_queue_count) + item_queue = item; + item_queue_count ++; + + if (line->count >= count_filter) { + show_lines(item_queue, item_queue_count); + item_queue_count = 0; + item_queue = NULL; + } else if (item_queue_count > TRACE_COUNT) { + item_queue = g_list_next(item_queue); + item_queue_count --; + } + + line->count = 0; + displayed++; + if (displayed > 300) + break; + item = g_list_next(item); + } +} + +/* + * Binary search in the histogram table and record the hit: + */ +static void record_ip(uint64_t ip, int counter) +{ + int left_idx, middle_idx, right_idx, idx; + unsigned long left, middle, right; + + record_precise_ip(ip); + + left_idx = 0; + right_idx = sym_table_count-1; + assert(ip <= max_ip && ip >= min_ip); + + while (left_idx + 1 < right_idx) { + middle_idx = (left_idx + right_idx) / 2; + + left = sym_table[ left_idx].addr; + middle = sym_table[middle_idx].addr; + right = sym_table[ right_idx].addr; + + if (!(left <= middle && middle <= right)) { + printf("%016lx...\n%016lx...\n%016lx\n", left, middle, right); + printf("%d %d %d\n", left_idx, middle_idx, right_idx); + } + assert(left <= middle && middle <= right); + if (!(left <= ip && ip <= right)) { + printf(" left: %016lx\n", left); + printf(" ip: %016lx\n", ip); + printf("right: %016lx\n", right); + } + assert(left <= ip && ip <= right); + /* + * [ left .... target .... middle .... right ] + * => right := middle + */ + if (ip < middle) { + right_idx = middle_idx; + continue; + } + /* + * [ left .... middle ... target ... right ] + * => left := middle + */ + left_idx = middle_idx; + } + + idx = left_idx; + + if (!sym_table[idx].skip) + sym_table[idx].count[counter]++; + else events--; +} + +static void process_event(uint64_t ip, int counter) +{ + events++; + + if (ip < min_ip || ip > max_ip) { + userspace_events++; + return; + } + + record_ip(ip, counter); +} + +int main(int argc, char *argv[]) +{ + struct pollfd event_array[MAX_NR_CPUS][MAX_COUNTERS]; + struct perf_counter_hw_event hw_event; + int fd[MAX_NR_CPUS][MAX_COUNTERS]; + int i, counter, group_fd; + unsigned int cpu; + uint64_t ip; + ssize_t res; + int ret; + + process_options(argc, argv); + + nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + if (tid != -1 || profile_cpu != -1) + nr_cpus = 1; + + assert(nr_cpus <= MAX_NR_CPUS); + + for (i = 0; i < nr_cpus; i++) { + group_fd = -1; + for (counter = 0; counter < nr_counters; counter++) { + + cpu = profile_cpu; + if (tid == -1 && profile_cpu == -1) + cpu = i; + + memset(&hw_event, 0, sizeof(hw_event)); + hw_event.type = event_id[counter]; + hw_event.raw = event_raw[counter]; + hw_event.irq_period = event_count[counter]; + hw_event.record_type = PERF_RECORD_IRQ; + hw_event.nmi = nmi; + + fd[i][counter] = sys_perf_counter_open(&hw_event, tid, cpu, group_fd, 0); + fcntl(fd[i][counter], F_SETFL, O_NONBLOCK); + if (fd[i][counter] < 0) { + printf("kerneltop error: syscall returned with %d (%s)\n", + fd[i][counter], strerror(-fd[i][counter])); + if (fd[i][counter] == -1) + printf("Are you root?\n"); + exit(-1); + } + assert(fd[i][counter] >= 0); + + /* + * First counter acts as the group leader: + */ + if (group && group_fd == -1) + group_fd = fd[i][counter]; + + event_array[i][counter].fd = fd[i][counter]; + event_array[i][counter].events = POLLIN; + } + } + + parse_symbols(); + if (vmlinux && sym_filter_entry) + parse_vmlinux(vmlinux); + + printf("KernelTop refresh period: %d seconds\n", delay_secs); + last_refresh = time(NULL); + + while (1) { + int hits = events; + + for (i = 0; i < nr_cpus; i++) { + for (counter = 0; counter < nr_counters; counter++) { + res = read(fd[i][counter], (char *) &ip, sizeof(ip)); + if (res > 0) { + assert(res == sizeof(ip)); + + process_event(ip, counter); + } + } + } + + if (time(NULL) >= last_refresh + delay_secs) { + print_sym_table(); + events = userspace_events = 0; + } + + if (hits == events) + ret = poll(event_array[0], nr_cpus, 1000); + hits = events; + } + + return 0; +} diff --git a/Documentation/perf_counter/perfstat.c b/Documentation/perf_counter/perfstat.c new file mode 100644 index 000000000000..9a5808fbcf90 --- /dev/null +++ b/Documentation/perf_counter/perfstat.c @@ -0,0 +1,521 @@ +/* + * perfstat: /usr/bin/time -alike performance counter statistics utility + * + * It summarizes the counter events of all tasks (and child tasks), + * covering all CPUs that the command (or workload) executes on. + * It only counts the per-task events of the workload started, + * independent of how many other tasks run on those CPUs. + * + * Build with: cc -O2 -g -lrt -Wall -W -o perfstat perfstat.c + * + * Sample output: + * + + $ ./perfstat -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null + + Performance counter stats for 'ls': + + 163516953 instructions + 2295 cache-misses + 2855182 branch-misses + + * + * Copyright (C) 2008, Red Hat Inc, Ingo Molnar + * + * Released under the GPLv2 (not later). + * + * Percpu counter support by: Yanmin Zhang + * Symbolic event options by: Wu Fengguang + */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef __x86_64__ +# define __NR_perf_counter_open 295 +#endif + +#ifdef __i386__ +# define __NR_perf_counter_open 333 +#endif + +#ifdef __powerpc__ +#define __NR_perf_counter_open 319 +#endif + +/* + * Pick up some kernel type conventions: + */ +#define __user +#define asmlinkage + +typedef unsigned int __u32; +typedef unsigned long long __u64; +typedef long long __s64; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/* + * User-space ABI bits: + */ + +/* + * Generalized performance counter event types, used by the hw_event.type + * parameter of the sys_perf_counter_open() syscall: + */ +enum hw_event_types { + /* + * Common hardware events, generalized by the kernel: + */ + PERF_COUNT_CPU_CYCLES = 0, + PERF_COUNT_INSTRUCTIONS = 1, + PERF_COUNT_CACHE_REFERENCES = 2, + PERF_COUNT_CACHE_MISSES = 3, + PERF_COUNT_BRANCH_INSTRUCTIONS = 4, + PERF_COUNT_BRANCH_MISSES = 5, + PERF_COUNT_BUS_CYCLES = 6, + + PERF_HW_EVENTS_MAX = 7, + + /* + * Special "software" counters provided by the kernel, even if + * the hardware does not support performance counters. These + * counters measure various physical and sw events of the + * kernel (and allow the profiling of them as well): + */ + PERF_COUNT_CPU_CLOCK = -1, + PERF_COUNT_TASK_CLOCK = -2, + PERF_COUNT_PAGE_FAULTS = -3, + PERF_COUNT_CONTEXT_SWITCHES = -4, + PERF_COUNT_CPU_MIGRATIONS = -5, + + PERF_SW_EVENTS_MIN = -6, +}; + +/* + * IRQ-notification data record type: + */ +enum perf_counter_record_type { + PERF_RECORD_SIMPLE = 0, + PERF_RECORD_IRQ = 1, + PERF_RECORD_GROUP = 2, +}; + +/* + * Hardware event to monitor via a performance monitoring counter: + */ +struct perf_counter_hw_event { + __s64 type; + + __u64 irq_period; + __u64 record_type; + __u64 read_format; + + __u64 disabled : 1, /* off by default */ + nmi : 1, /* NMI sampling */ + raw : 1, /* raw event type */ + inherit : 1, /* children inherit it */ + pinned : 1, /* must always be on PMU */ + exclusive : 1, /* only group on PMU */ + exclude_user : 1, /* don't count user */ + exclude_kernel : 1, /* ditto kernel */ + exclude_hv : 1, /* ditto hypervisor */ + exclude_idle : 1, /* don't count when idle */ + + __reserved_1 : 54; + + __u32 extra_config_len; + __u32 __reserved_4; + + __u64 __reserved_2; + __u64 __reserved_3; +}; + +/* + * Ioctls that can be done on a perf counter fd: + */ +#define PERF_COUNTER_IOC_ENABLE _IO('$', 0) +#define PERF_COUNTER_IOC_DISABLE _IO('$', 1) + +asmlinkage int sys_perf_counter_open( + + struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, + int cpu, + int group_fd, + unsigned long flags) +{ + int ret; + + ret = syscall( + __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); +#if defined(__x86_64__) || defined(__i386__) + if (ret < 0 && ret > -4096) { + errno = -ret; + ret = -1; + } +#endif + return ret; +} + + +static char *hw_event_names [] = { + "CPU cycles", + "instructions", + "cache references", + "cache misses", + "branches", + "branch misses", + "bus cycles", +}; + +static char *sw_event_names [] = { + "cpu clock ticks", + "task clock ticks", + "pagefaults", + "context switches", + "CPU migrations", +}; + +struct event_symbol { + int event; + char *symbol; +}; + +static struct event_symbol event_symbols [] = { + {PERF_COUNT_CPU_CYCLES, "cpu-cycles", }, + {PERF_COUNT_CPU_CYCLES, "cycles", }, + {PERF_COUNT_INSTRUCTIONS, "instructions", }, + {PERF_COUNT_CACHE_REFERENCES, "cache-references", }, + {PERF_COUNT_CACHE_MISSES, "cache-misses", }, + {PERF_COUNT_BRANCH_INSTRUCTIONS, "branch-instructions", }, + {PERF_COUNT_BRANCH_INSTRUCTIONS, "branches", }, + {PERF_COUNT_BRANCH_MISSES, "branch-misses", }, + {PERF_COUNT_BUS_CYCLES, "bus-cycles", }, + {PERF_COUNT_CPU_CLOCK, "cpu-ticks", }, + {PERF_COUNT_CPU_CLOCK, "ticks", }, + {PERF_COUNT_TASK_CLOCK, "task-ticks", }, + {PERF_COUNT_PAGE_FAULTS, "page-faults", }, + {PERF_COUNT_PAGE_FAULTS, "faults", }, + {PERF_COUNT_CONTEXT_SWITCHES, "context-switches", }, + {PERF_COUNT_CONTEXT_SWITCHES, "cs", }, + {PERF_COUNT_CPU_MIGRATIONS, "cpu-migrations", }, + {PERF_COUNT_CPU_MIGRATIONS, "migrations", }, +}; + +#define MAX_COUNTERS 64 +#define MAX_NR_CPUS 256 + +static int nr_counters = 0; +static int nr_cpus = 0; + +static int event_id[MAX_COUNTERS] = + { -2, -5, -4, -3, 0, 1, 2, 3}; + +static int event_raw[MAX_COUNTERS]; + +static int system_wide = 0; + +static void display_help(void) +{ + unsigned int i; + int e; + + printf( + "Usage: perfstat [] \n\n" + "PerfStat Options (up to %d event types can be specified):\n\n", + MAX_COUNTERS); + printf( + " -e EVENT --event=EVENT # symbolic-name abbreviations"); + + for (i = 0, e = PERF_HW_EVENTS_MAX; i < ARRAY_SIZE(event_symbols); i++) { + if (e != event_symbols[i].event) { + e = event_symbols[i].event; + printf( + "\n %2d: %-20s", e, event_symbols[i].symbol); + } else + printf(" %s", event_symbols[i].symbol); + } + + printf("\n" + " rNNN: raw event type\n\n" + " -s # system-wide collection\n\n" + " -c --command= # command+arguments to be timed.\n" + "\n"); + exit(0); +} + +static int type_valid(int type) +{ + if (type >= PERF_HW_EVENTS_MAX) + return 0; + if (type <= PERF_SW_EVENTS_MIN) + return 0; + + return 1; +} + +static char *event_name(int ctr) +{ + int type = event_id[ctr]; + static char buf[32]; + + if (event_raw[ctr]) { + sprintf(buf, "raw 0x%x", type); + return buf; + } + if (!type_valid(type)) + return "unknown"; + + if (type >= 0) + return hw_event_names[type]; + + return sw_event_names[-type-1]; +} + +/* + * Each event can have multiple symbolic names. + * Symbolic names are (almost) exactly matched. + */ +static int match_event_symbols(char *str) +{ + unsigned int i; + + if (isdigit(str[0]) || str[0] == '-') + return atoi(str); + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + if (!strncmp(str, event_symbols[i].symbol, + strlen(event_symbols[i].symbol))) + return event_symbols[i].event; + } + + return PERF_HW_EVENTS_MAX; +} + +static void parse_events(char *str) +{ + int type, raw; + +again: + nr_counters++; + if (nr_counters == MAX_COUNTERS) + display_help(); + + raw = 0; + if (*str == 'r') { + raw = 1; + ++str; + type = strtol(str, NULL, 16); + } else { + type = match_event_symbols(str); + if (!type_valid(type)) + display_help(); + } + + event_id[nr_counters] = type; + event_raw[nr_counters] = raw; + + str = strstr(str, ","); + if (str) { + str++; + goto again; + } +} + +static void process_options(int argc, char *argv[]) +{ + for (;;) { + int option_index = 0; + /** Options for getopt */ + static struct option long_options[] = { + {"event", required_argument, NULL, 'e'}, + {"help", no_argument, NULL, 'h'}, + {"command", no_argument, NULL, 'c'}, + {NULL, 0, NULL, 0 } + }; + int c = getopt_long(argc, argv, "+:e:c:s", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'c': + break; + case 's': + system_wide = 1; + break; + case 'e': + parse_events(optarg); + break; + default: + break; + } + } + if (optind == argc) + goto err; + + if (!nr_counters) + nr_counters = 8; + else + nr_counters++; + return; + +err: + display_help(); +} + +char fault_here[1000000]; + +#define PR_TASK_PERF_COUNTERS_DISABLE 31 +#define PR_TASK_PERF_COUNTERS_ENABLE 32 + +static int fd[MAX_NR_CPUS][MAX_COUNTERS]; + +static void create_counter(int counter) +{ + struct perf_counter_hw_event hw_event; + + memset(&hw_event, 0, sizeof(hw_event)); + hw_event.type = event_id[counter]; + hw_event.raw = event_raw[counter]; + hw_event.record_type = PERF_RECORD_SIMPLE; + hw_event.nmi = 0; + + if (system_wide) { + int cpu; + for (cpu = 0; cpu < nr_cpus; cpu ++) { + fd[cpu][counter] = sys_perf_counter_open(&hw_event, -1, cpu, -1, 0); + if (fd[cpu][counter] < 0) { + printf("perfstat error: syscall returned with %d (%s)\n", + fd[cpu][counter], strerror(errno)); + exit(-1); + } + + } + } else { + hw_event.inherit = 1; + hw_event.disabled = 1; + + fd[0][counter] = sys_perf_counter_open(&hw_event, 0, -1, -1, 0); + if (fd[0][counter] < 0) { + printf("perfstat error: syscall returned with %d (%s)\n", + fd[0][counter], strerror(errno)); + exit(-1); + } + } +} + + +#define rdclock() \ +({ \ + struct timespec ts; \ + \ + clock_gettime(CLOCK_MONOTONIC, &ts); \ + ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ +}) + +int main(int argc, char *argv[]) +{ + unsigned long long t0, t1; + int counter; + ssize_t res; + int status; + int pid; + + process_options(argc, argv); + + if (system_wide) { + nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + assert(nr_cpus <= MAX_NR_CPUS); + assert(nr_cpus >= 0); + } else + nr_cpus = 1; + + for (counter = 0; counter < nr_counters; counter++) + create_counter(counter); + + argc -= optind; + argv += optind; + + /* + * Enable counters and exec the command: + */ + t0 = rdclock(); + prctl(PR_TASK_PERF_COUNTERS_ENABLE); + + if ((pid = fork()) < 0) + perror("failed to fork"); + if (!pid) { + if (execvp(argv[0], argv)) { + perror(argv[0]); + exit(-1); + } + } + while (wait(&status) >= 0) + ; + prctl(PR_TASK_PERF_COUNTERS_DISABLE); + t1 = rdclock(); + + fflush(stdout); + + fprintf(stderr, "\n"); + fprintf(stderr, " Performance counter stats for \'%s\':\n", + argv[0]); + fprintf(stderr, "\n"); + + for (counter = 0; counter < nr_counters; counter++) { + int cpu; + __u64 count, single_count; + + count = 0; + for (cpu = 0; cpu < nr_cpus; cpu ++) { + res = read(fd[cpu][counter], + (char *) &single_count, sizeof(single_count)); + assert(res == sizeof(single_count)); + count += single_count; + } + + if (!event_raw[counter] && + (event_id[counter] == PERF_COUNT_CPU_CLOCK || + event_id[counter] == PERF_COUNT_TASK_CLOCK)) { + + double msecs = (double)count / 1000000; + + fprintf(stderr, " %14.6f %-20s (msecs)\n", + msecs, event_name(counter)); + } else { + fprintf(stderr, " %14Ld %-20s (events)\n", + count, event_name(counter)); + } + if (!counter) + fprintf(stderr, "\n"); + } + fprintf(stderr, "\n"); + fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", + (double)(t1-t0)/1e6); + fprintf(stderr, "\n"); + + return 0; +} -- GitLab From cea92ce5b07078cd62c4712d51390b09a43dba2e Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 20 Mar 2009 10:08:02 +0800 Subject: [PATCH 0128/6080] perf_counter tools: Merge common code into perfcounters.h kerneltop's MAX_COUNTERS is increased from 8 to 64(the value used by perfstat). Signed-off-by: Wu Fengguang Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 132 +-------------------- Documentation/perf_counter/perfcounters.h | 137 ++++++++++++++++++++++ Documentation/perf_counter/perfstat.c | 134 +-------------------- 3 files changed, 139 insertions(+), 264 deletions(-) create mode 100644 Documentation/perf_counter/perfcounters.h diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index cf0e30bab5d5..fe70a2c92a8e 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -65,126 +65,7 @@ #include -#ifdef __x86_64__ -# define __NR_perf_counter_open 295 -#endif - -#ifdef __i386__ -# define __NR_perf_counter_open 333 -#endif - -/* - * Pick up some kernel type conventions: - */ -#define __user -#define asmlinkage - -typedef unsigned int __u32; -typedef unsigned long long __u64; -typedef long long __s64; - -/* - * User-space ABI bits: - */ - -/* - * Generalized performance counter event types, used by the hw_event.type - * parameter of the sys_perf_counter_open() syscall: - */ -enum hw_event_types { - /* - * Common hardware events, generalized by the kernel: - */ - PERF_COUNT_CPU_CYCLES = 0, - PERF_COUNT_INSTRUCTIONS = 1, - PERF_COUNT_CACHE_REFERENCES = 2, - PERF_COUNT_CACHE_MISSES = 3, - PERF_COUNT_BRANCH_INSTRUCTIONS = 4, - PERF_COUNT_BRANCH_MISSES = 5, - PERF_COUNT_BUS_CYCLES = 6, - - PERF_HW_EVENTS_MAX = 7, - - /* - * Special "software" counters provided by the kernel, even if - * the hardware does not support performance counters. These - * counters measure various physical and sw events of the - * kernel (and allow the profiling of them as well): - */ - PERF_COUNT_CPU_CLOCK = -1, - PERF_COUNT_TASK_CLOCK = -2, - PERF_COUNT_PAGE_FAULTS = -3, - PERF_COUNT_CONTEXT_SWITCHES = -4, - PERF_COUNT_CPU_MIGRATIONS = -5, - - PERF_SW_EVENTS_MIN = -6, -}; - -/* - * IRQ-notification data record type: - */ -enum perf_counter_record_type { - PERF_RECORD_SIMPLE = 0, - PERF_RECORD_IRQ = 1, - PERF_RECORD_GROUP = 2, -}; - -/* - * Hardware event to monitor via a performance monitoring counter: - */ -struct perf_counter_hw_event { - __s64 type; - - __u64 irq_period; - __u64 record_type; - __u64 read_format; - - __u64 disabled : 1, /* off by default */ - nmi : 1, /* NMI sampling */ - raw : 1, /* raw event type */ - inherit : 1, /* children inherit it */ - pinned : 1, /* must always be on PMU */ - exclusive : 1, /* only group on PMU */ - exclude_user : 1, /* don't count user */ - exclude_kernel : 1, /* ditto kernel */ - exclude_hv : 1, /* ditto hypervisor */ - exclude_idle : 1, /* don't count when idle */ - - __reserved_1 : 54; - - __u32 extra_config_len; - __u32 __reserved_4; - - __u64 __reserved_2; - __u64 __reserved_3; -}; - -/* - * Ioctls that can be done on a perf counter fd: - */ -#define PERF_COUNTER_IOC_ENABLE _IO('$', 0) -#define PERF_COUNTER_IOC_DISABLE _IO('$', 1) - -asmlinkage int sys_perf_counter_open( - - struct perf_counter_hw_event *hw_event_uptr __user, - pid_t pid, - int cpu, - int group_fd, - unsigned long flags) -{ - int ret; - - ret = syscall( - __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); -#if defined(__x86_64__) || defined(__i386__) - if (ret < 0 && ret > -4096) { - errno = -ret; - ret = -1; - } -#endif - return ret; -} +#include "perfcounters.h" const char *event_types [] = { "CPU cycles", @@ -205,21 +86,10 @@ const unsigned int default_count[] = { 10000, }; -/* - * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all - * counters in the current task. - */ -#define PR_TASK_PERF_COUNTERS_DISABLE 31 -#define PR_TASK_PERF_COUNTERS_ENABLE 32 - -#define MAX_COUNTERS 8 - static int nr_counters = -1; static __u64 count_filter = 100; -#define MAX_NR_CPUS 256 - static int event_count[MAX_COUNTERS]; static unsigned long event_id[MAX_COUNTERS]; static int event_raw[MAX_COUNTERS]; diff --git a/Documentation/perf_counter/perfcounters.h b/Documentation/perf_counter/perfcounters.h new file mode 100644 index 000000000000..8c1559b25f10 --- /dev/null +++ b/Documentation/perf_counter/perfcounters.h @@ -0,0 +1,137 @@ +/* + * Ioctls that can be done on a perf counter fd: + */ +#define PERF_COUNTER_IOC_ENABLE _IO('$', 0) +#define PERF_COUNTER_IOC_DISABLE _IO('$', 1) + +/* + * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all + * counters in the current task. + */ +#define PR_TASK_PERF_COUNTERS_DISABLE 31 +#define PR_TASK_PERF_COUNTERS_ENABLE 32 + +#define MAX_COUNTERS 64 +#define MAX_NR_CPUS 256 + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/* + * Pick up some kernel type conventions: + */ +#define __user +#define asmlinkage + +typedef unsigned int __u32; +typedef unsigned long long __u64; +typedef long long __s64; + +/* + * User-space ABI bits: + */ + +/* + * Generalized performance counter event types, used by the hw_event.type + * parameter of the sys_perf_counter_open() syscall: + */ +enum hw_event_types { + /* + * Common hardware events, generalized by the kernel: + */ + PERF_COUNT_CPU_CYCLES = 0, + PERF_COUNT_INSTRUCTIONS = 1, + PERF_COUNT_CACHE_REFERENCES = 2, + PERF_COUNT_CACHE_MISSES = 3, + PERF_COUNT_BRANCH_INSTRUCTIONS = 4, + PERF_COUNT_BRANCH_MISSES = 5, + PERF_COUNT_BUS_CYCLES = 6, + + PERF_HW_EVENTS_MAX = 7, + + /* + * Special "software" counters provided by the kernel, even if + * the hardware does not support performance counters. These + * counters measure various physical and sw events of the + * kernel (and allow the profiling of them as well): + */ + PERF_COUNT_CPU_CLOCK = -1, + PERF_COUNT_TASK_CLOCK = -2, + PERF_COUNT_PAGE_FAULTS = -3, + PERF_COUNT_CONTEXT_SWITCHES = -4, + PERF_COUNT_CPU_MIGRATIONS = -5, + + PERF_SW_EVENTS_MIN = -6, +}; + +/* + * IRQ-notification data record type: + */ +enum perf_counter_record_type { + PERF_RECORD_SIMPLE = 0, + PERF_RECORD_IRQ = 1, + PERF_RECORD_GROUP = 2, +}; + +/* + * Hardware event to monitor via a performance monitoring counter: + */ +struct perf_counter_hw_event { + __s64 type; + + __u64 irq_period; + __u64 record_type; + __u64 read_format; + + __u64 disabled : 1, /* off by default */ + nmi : 1, /* NMI sampling */ + raw : 1, /* raw event type */ + inherit : 1, /* children inherit it */ + pinned : 1, /* must always be on PMU */ + exclusive : 1, /* only group on PMU */ + exclude_user : 1, /* don't count user */ + exclude_kernel : 1, /* ditto kernel */ + exclude_hv : 1, /* ditto hypervisor */ + exclude_idle : 1, /* don't count when idle */ + + __reserved_1 : 54; + + __u32 extra_config_len; + __u32 __reserved_4; + + __u64 __reserved_2; + __u64 __reserved_3; +}; + +#ifdef __x86_64__ +# define __NR_perf_counter_open 295 +#endif + +#ifdef __i386__ +# define __NR_perf_counter_open 333 +#endif + +#ifdef __powerpc__ +#define __NR_perf_counter_open 319 +#endif + +asmlinkage int sys_perf_counter_open( + + struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, + int cpu, + int group_fd, + unsigned long flags) +{ + int ret; + + ret = syscall( + __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); +#if defined(__x86_64__) || defined(__i386__) + if (ret < 0 && ret > -4096) { + errno = -ret; + ret = -1; + } +#endif + return ret; +} + diff --git a/Documentation/perf_counter/perfstat.c b/Documentation/perf_counter/perfstat.c index 9a5808fbcf90..a3d4a7a602f6 100644 --- a/Documentation/perf_counter/perfstat.c +++ b/Documentation/perf_counter/perfstat.c @@ -52,133 +52,7 @@ #include -#ifdef __x86_64__ -# define __NR_perf_counter_open 295 -#endif - -#ifdef __i386__ -# define __NR_perf_counter_open 333 -#endif - -#ifdef __powerpc__ -#define __NR_perf_counter_open 319 -#endif - -/* - * Pick up some kernel type conventions: - */ -#define __user -#define asmlinkage - -typedef unsigned int __u32; -typedef unsigned long long __u64; -typedef long long __s64; - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -/* - * User-space ABI bits: - */ - -/* - * Generalized performance counter event types, used by the hw_event.type - * parameter of the sys_perf_counter_open() syscall: - */ -enum hw_event_types { - /* - * Common hardware events, generalized by the kernel: - */ - PERF_COUNT_CPU_CYCLES = 0, - PERF_COUNT_INSTRUCTIONS = 1, - PERF_COUNT_CACHE_REFERENCES = 2, - PERF_COUNT_CACHE_MISSES = 3, - PERF_COUNT_BRANCH_INSTRUCTIONS = 4, - PERF_COUNT_BRANCH_MISSES = 5, - PERF_COUNT_BUS_CYCLES = 6, - - PERF_HW_EVENTS_MAX = 7, - - /* - * Special "software" counters provided by the kernel, even if - * the hardware does not support performance counters. These - * counters measure various physical and sw events of the - * kernel (and allow the profiling of them as well): - */ - PERF_COUNT_CPU_CLOCK = -1, - PERF_COUNT_TASK_CLOCK = -2, - PERF_COUNT_PAGE_FAULTS = -3, - PERF_COUNT_CONTEXT_SWITCHES = -4, - PERF_COUNT_CPU_MIGRATIONS = -5, - - PERF_SW_EVENTS_MIN = -6, -}; - -/* - * IRQ-notification data record type: - */ -enum perf_counter_record_type { - PERF_RECORD_SIMPLE = 0, - PERF_RECORD_IRQ = 1, - PERF_RECORD_GROUP = 2, -}; - -/* - * Hardware event to monitor via a performance monitoring counter: - */ -struct perf_counter_hw_event { - __s64 type; - - __u64 irq_period; - __u64 record_type; - __u64 read_format; - - __u64 disabled : 1, /* off by default */ - nmi : 1, /* NMI sampling */ - raw : 1, /* raw event type */ - inherit : 1, /* children inherit it */ - pinned : 1, /* must always be on PMU */ - exclusive : 1, /* only group on PMU */ - exclude_user : 1, /* don't count user */ - exclude_kernel : 1, /* ditto kernel */ - exclude_hv : 1, /* ditto hypervisor */ - exclude_idle : 1, /* don't count when idle */ - - __reserved_1 : 54; - - __u32 extra_config_len; - __u32 __reserved_4; - - __u64 __reserved_2; - __u64 __reserved_3; -}; - -/* - * Ioctls that can be done on a perf counter fd: - */ -#define PERF_COUNTER_IOC_ENABLE _IO('$', 0) -#define PERF_COUNTER_IOC_DISABLE _IO('$', 1) - -asmlinkage int sys_perf_counter_open( - - struct perf_counter_hw_event *hw_event_uptr __user, - pid_t pid, - int cpu, - int group_fd, - unsigned long flags) -{ - int ret; - - ret = syscall( - __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); -#if defined(__x86_64__) || defined(__i386__) - if (ret < 0 && ret > -4096) { - errno = -ret; - ret = -1; - } -#endif - return ret; -} - +#include "perfcounters.h" static char *hw_event_names [] = { "CPU cycles", @@ -224,9 +98,6 @@ static struct event_symbol event_symbols [] = { {PERF_COUNT_CPU_MIGRATIONS, "migrations", }, }; -#define MAX_COUNTERS 64 -#define MAX_NR_CPUS 256 - static int nr_counters = 0; static int nr_cpus = 0; @@ -388,9 +259,6 @@ err: char fault_here[1000000]; -#define PR_TASK_PERF_COUNTERS_DISABLE 31 -#define PR_TASK_PERF_COUNTERS_ENABLE 32 - static int fd[MAX_NR_CPUS][MAX_COUNTERS]; static void create_counter(int counter) -- GitLab From f49012fad4ed2231c7380c0b1901122242b3eab0 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 20 Mar 2009 10:08:03 +0800 Subject: [PATCH 0129/6080] perf_counter tools: Move perfstat supporting code into perfcounters.h Signed-off-by: Wu Fengguang Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/perfcounters.h | 130 ++++++++++++++++++++++ Documentation/perf_counter/perfstat.c | 130 ---------------------- 2 files changed, 130 insertions(+), 130 deletions(-) diff --git a/Documentation/perf_counter/perfcounters.h b/Documentation/perf_counter/perfcounters.h index 8c1559b25f10..0f3764aa52ab 100644 --- a/Documentation/perf_counter/perfcounters.h +++ b/Documentation/perf_counter/perfcounters.h @@ -16,6 +16,14 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define rdclock() \ +({ \ + struct timespec ts; \ + \ + clock_gettime(CLOCK_MONOTONIC, &ts); \ + ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ +}) + /* * Pick up some kernel type conventions: */ @@ -135,3 +143,125 @@ asmlinkage int sys_perf_counter_open( return ret; } +static char *hw_event_names [] = { + "CPU cycles", + "instructions", + "cache references", + "cache misses", + "branches", + "branch misses", + "bus cycles", +}; + +static char *sw_event_names [] = { + "cpu clock ticks", + "task clock ticks", + "pagefaults", + "context switches", + "CPU migrations", +}; + +struct event_symbol { + int event; + char *symbol; +}; + +static struct event_symbol event_symbols [] = { + {PERF_COUNT_CPU_CYCLES, "cpu-cycles", }, + {PERF_COUNT_CPU_CYCLES, "cycles", }, + {PERF_COUNT_INSTRUCTIONS, "instructions", }, + {PERF_COUNT_CACHE_REFERENCES, "cache-references", }, + {PERF_COUNT_CACHE_MISSES, "cache-misses", }, + {PERF_COUNT_BRANCH_INSTRUCTIONS, "branch-instructions", }, + {PERF_COUNT_BRANCH_INSTRUCTIONS, "branches", }, + {PERF_COUNT_BRANCH_MISSES, "branch-misses", }, + {PERF_COUNT_BUS_CYCLES, "bus-cycles", }, + {PERF_COUNT_CPU_CLOCK, "cpu-ticks", }, + {PERF_COUNT_CPU_CLOCK, "ticks", }, + {PERF_COUNT_TASK_CLOCK, "task-ticks", }, + {PERF_COUNT_PAGE_FAULTS, "page-faults", }, + {PERF_COUNT_PAGE_FAULTS, "faults", }, + {PERF_COUNT_CONTEXT_SWITCHES, "context-switches", }, + {PERF_COUNT_CONTEXT_SWITCHES, "cs", }, + {PERF_COUNT_CPU_MIGRATIONS, "cpu-migrations", }, + {PERF_COUNT_CPU_MIGRATIONS, "migrations", }, +}; + +static int type_valid(int type) +{ + if (type >= PERF_HW_EVENTS_MAX) + return 0; + if (type <= PERF_SW_EVENTS_MIN) + return 0; + + return 1; +} + +static char *event_name(int ctr) +{ + int type = event_id[ctr]; + static char buf[32]; + + if (event_raw[ctr]) { + sprintf(buf, "raw 0x%x", type); + return buf; + } + if (!type_valid(type)) + return "unknown"; + + if (type >= 0) + return hw_event_names[type]; + + return sw_event_names[-type-1]; +} + +/* + * Each event can have multiple symbolic names. + * Symbolic names are (almost) exactly matched. + */ +static int match_event_symbols(char *str) +{ + unsigned int i; + + if (isdigit(str[0]) || str[0] == '-') + return atoi(str); + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + if (!strncmp(str, event_symbols[i].symbol, + strlen(event_symbols[i].symbol))) + return event_symbols[i].event; + } + + return PERF_HW_EVENTS_MAX; +} + +static void parse_events(char *str) +{ + int type, raw; + +again: + nr_counters++; + if (nr_counters == MAX_COUNTERS) + display_help(); + + raw = 0; + if (*str == 'r') { + raw = 1; + ++str; + type = strtol(str, NULL, 16); + } else { + type = match_event_symbols(str); + if (!type_valid(type)) + display_help(); + } + + event_id[nr_counters] = type; + event_raw[nr_counters] = raw; + + str = strstr(str, ","); + if (str) { + str++; + goto again; + } +} + diff --git a/Documentation/perf_counter/perfstat.c b/Documentation/perf_counter/perfstat.c index a3d4a7a602f6..3364dcb9dd9d 100644 --- a/Documentation/perf_counter/perfstat.c +++ b/Documentation/perf_counter/perfstat.c @@ -54,50 +54,6 @@ #include "perfcounters.h" -static char *hw_event_names [] = { - "CPU cycles", - "instructions", - "cache references", - "cache misses", - "branches", - "branch misses", - "bus cycles", -}; - -static char *sw_event_names [] = { - "cpu clock ticks", - "task clock ticks", - "pagefaults", - "context switches", - "CPU migrations", -}; - -struct event_symbol { - int event; - char *symbol; -}; - -static struct event_symbol event_symbols [] = { - {PERF_COUNT_CPU_CYCLES, "cpu-cycles", }, - {PERF_COUNT_CPU_CYCLES, "cycles", }, - {PERF_COUNT_INSTRUCTIONS, "instructions", }, - {PERF_COUNT_CACHE_REFERENCES, "cache-references", }, - {PERF_COUNT_CACHE_MISSES, "cache-misses", }, - {PERF_COUNT_BRANCH_INSTRUCTIONS, "branch-instructions", }, - {PERF_COUNT_BRANCH_INSTRUCTIONS, "branches", }, - {PERF_COUNT_BRANCH_MISSES, "branch-misses", }, - {PERF_COUNT_BUS_CYCLES, "bus-cycles", }, - {PERF_COUNT_CPU_CLOCK, "cpu-ticks", }, - {PERF_COUNT_CPU_CLOCK, "ticks", }, - {PERF_COUNT_TASK_CLOCK, "task-ticks", }, - {PERF_COUNT_PAGE_FAULTS, "page-faults", }, - {PERF_COUNT_PAGE_FAULTS, "faults", }, - {PERF_COUNT_CONTEXT_SWITCHES, "context-switches", }, - {PERF_COUNT_CONTEXT_SWITCHES, "cs", }, - {PERF_COUNT_CPU_MIGRATIONS, "cpu-migrations", }, - {PERF_COUNT_CPU_MIGRATIONS, "migrations", }, -}; - static int nr_counters = 0; static int nr_cpus = 0; @@ -137,84 +93,6 @@ static void display_help(void) exit(0); } -static int type_valid(int type) -{ - if (type >= PERF_HW_EVENTS_MAX) - return 0; - if (type <= PERF_SW_EVENTS_MIN) - return 0; - - return 1; -} - -static char *event_name(int ctr) -{ - int type = event_id[ctr]; - static char buf[32]; - - if (event_raw[ctr]) { - sprintf(buf, "raw 0x%x", type); - return buf; - } - if (!type_valid(type)) - return "unknown"; - - if (type >= 0) - return hw_event_names[type]; - - return sw_event_names[-type-1]; -} - -/* - * Each event can have multiple symbolic names. - * Symbolic names are (almost) exactly matched. - */ -static int match_event_symbols(char *str) -{ - unsigned int i; - - if (isdigit(str[0]) || str[0] == '-') - return atoi(str); - - for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { - if (!strncmp(str, event_symbols[i].symbol, - strlen(event_symbols[i].symbol))) - return event_symbols[i].event; - } - - return PERF_HW_EVENTS_MAX; -} - -static void parse_events(char *str) -{ - int type, raw; - -again: - nr_counters++; - if (nr_counters == MAX_COUNTERS) - display_help(); - - raw = 0; - if (*str == 'r') { - raw = 1; - ++str; - type = strtol(str, NULL, 16); - } else { - type = match_event_symbols(str); - if (!type_valid(type)) - display_help(); - } - - event_id[nr_counters] = type; - event_raw[nr_counters] = raw; - - str = strstr(str, ","); - if (str) { - str++; - goto again; - } -} - static void process_options(int argc, char *argv[]) { for (;;) { @@ -296,14 +174,6 @@ static void create_counter(int counter) } -#define rdclock() \ -({ \ - struct timespec ts; \ - \ - clock_gettime(CLOCK_MONOTONIC, &ts); \ - ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ -}) - int main(int argc, char *argv[]) { unsigned long long t0, t1; -- GitLab From 95bb3be1b3ca4a71cc168787b675d5b7852fc6be Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 20 Mar 2009 10:08:04 +0800 Subject: [PATCH 0130/6080] perf_counter tools: support symbolic event names in kerneltop - kerneltop: --event_id => --event - kerneltop: can accept SW event types now - perfstat: it used to implicitly add event -2(task-clock), the new code no longer does this. Shall we? Signed-off-by: Wu Fengguang Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 28 +++++------------------ Documentation/perf_counter/perfcounters.h | 15 ++++++++---- Documentation/perf_counter/perfstat.c | 8 ------- 3 files changed, 16 insertions(+), 35 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index fe70a2c92a8e..edc5b09fb586 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -86,13 +86,9 @@ const unsigned int default_count[] = { 10000, }; -static int nr_counters = -1; - static __u64 count_filter = 100; static int event_count[MAX_COUNTERS]; -static unsigned long event_id[MAX_COUNTERS]; -static int event_raw[MAX_COUNTERS]; static int tid = -1; static int profile_cpu = -1; @@ -125,7 +121,7 @@ static void display_help(void) "KernelTop Options (up to %d event types can be specified at once):\n\n", MAX_COUNTERS); printf( - " -e EID --event_id=EID # event type ID [default: 0]\n" + " -e EID --event=EID # event type ID [default: 0]\n" " 0: CPU cycles\n" " 1: instructions\n" " 2: cache accesses\n" @@ -160,7 +156,7 @@ static void process_options(int argc, char *argv[]) {"cpu", required_argument, NULL, 'C'}, {"delay", required_argument, NULL, 'd'}, {"dump_symtab", no_argument, NULL, 'D'}, - {"event_id", required_argument, NULL, 'e'}, + {"event", required_argument, NULL, 'e'}, {"filter", required_argument, NULL, 'f'}, {"group", required_argument, NULL, 'g'}, {"help", no_argument, NULL, 'h'}, @@ -178,8 +174,6 @@ static void process_options(int argc, char *argv[]) switch (c) { case 'c': - if (nr_counters == -1) - nr_counters = 0; event_count[nr_counters] = atoi(optarg); break; case 'C': /* CPU and PID are mutually exclusive */ @@ -192,18 +186,7 @@ static void process_options(int argc, char *argv[]) case 'd': delay_secs = atoi(optarg); break; case 'D': dump_symtab = 1; break; - case 'e': - nr_counters++; - if (nr_counters == MAX_COUNTERS) { - error = 1; - break; - } - if (*optarg == 'r') { - event_raw[nr_counters] = 1; - ++optarg; - } - event_id[nr_counters] = strtol(optarg, NULL, 16); - break; + case 'e': error = parse_events(optarg); break; case 'f': count_filter = atoi(optarg); break; case 'g': group = atoi(optarg); break; @@ -226,9 +209,10 @@ static void process_options(int argc, char *argv[]) if (error) display_help(); - nr_counters++; - if (nr_counters < 1) + if (!nr_counters) { nr_counters = 1; + event_id[0] = 0; + } for (counter = 0; counter < nr_counters; counter++) { if (event_count[counter]) diff --git a/Documentation/perf_counter/perfcounters.h b/Documentation/perf_counter/perfcounters.h index 0f3764aa52ab..99a90d833e12 100644 --- a/Documentation/perf_counter/perfcounters.h +++ b/Documentation/perf_counter/perfcounters.h @@ -143,6 +143,10 @@ asmlinkage int sys_perf_counter_open( return ret; } +static int nr_counters = 0; +static long event_id[MAX_COUNTERS] = { -2, -5, -4, -3, 0, 1, 2, 3}; +static int event_raw[MAX_COUNTERS]; + static char *hw_event_names [] = { "CPU cycles", "instructions", @@ -235,14 +239,13 @@ static int match_event_symbols(char *str) return PERF_HW_EVENTS_MAX; } -static void parse_events(char *str) +static int parse_events(char *str) { int type, raw; again: - nr_counters++; if (nr_counters == MAX_COUNTERS) - display_help(); + return -1; raw = 0; if (*str == 'r') { @@ -252,16 +255,18 @@ again: } else { type = match_event_symbols(str); if (!type_valid(type)) - display_help(); + return -1; } event_id[nr_counters] = type; event_raw[nr_counters] = raw; + nr_counters++; str = strstr(str, ","); if (str) { str++; goto again; } -} + return 0; +} diff --git a/Documentation/perf_counter/perfstat.c b/Documentation/perf_counter/perfstat.c index 3364dcb9dd9d..fd594468e655 100644 --- a/Documentation/perf_counter/perfstat.c +++ b/Documentation/perf_counter/perfstat.c @@ -54,14 +54,8 @@ #include "perfcounters.h" -static int nr_counters = 0; static int nr_cpus = 0; -static int event_id[MAX_COUNTERS] = - { -2, -5, -4, -3, 0, 1, 2, 3}; - -static int event_raw[MAX_COUNTERS]; - static int system_wide = 0; static void display_help(void) @@ -127,8 +121,6 @@ static void process_options(int argc, char *argv[]) if (!nr_counters) nr_counters = 8; - else - nr_counters++; return; err: -- GitLab From e3908612d93dff9d7746d85d37c42593254bf282 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 20 Mar 2009 10:08:05 +0800 Subject: [PATCH 0131/6080] perf_counter tools: Reuse event_name() in kerneltop - can handle sw counters now - the outputs will look slightly different Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index edc5b09fb586..cba5cb0a97f9 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -67,16 +67,6 @@ #include "perfcounters.h" -const char *event_types [] = { - "CPU cycles", - "instructions", - "cache-refs", - "cache-misses", - "branches", - "branch-misses", - "bus cycles" -}; - const unsigned int default_count[] = { 1000000, 1000000, @@ -304,10 +294,7 @@ static void print_sym_table(void) if (counter) printf("/"); - if (event_id[counter] < PERF_HW_EVENTS_MAX) - printf( "%s", event_types[event_id[counter]]); - else - printf( "raw:%04lx", event_id[counter]); + printf("%s", event_name(counter)); } printf( "], "); -- GitLab From f7524bda8be8be98db356d6a83ac1da451ecdb2e Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 20 Mar 2009 10:08:06 +0800 Subject: [PATCH 0132/6080] perf_counter tools: move remaining code into kerneltop.c - perfstat.c can be safely removed now - perfstat: -s => -a for system wide accounting - kerneltop: add -S/--stat for perfstat mode - minor adjustments to kerneltop --help, perfstat --help Signed-off-by: Wu Fengguang Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 530 ++++++++++++++++++---- Documentation/perf_counter/perfcounters.h | 132 +----- 2 files changed, 432 insertions(+), 230 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index cba5cb0a97f9..9db65a4f1042 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -3,7 +3,7 @@ Build with: - cc -O6 -Wall `pkg-config --cflags --libs glib-2.0` -o kerneltop kerneltop.c + cc -O6 -Wall -lrt `pkg-config --cflags --libs glib-2.0` -o kerneltop kerneltop.c Sample output: @@ -26,18 +26,40 @@ 12.00 - ffffffff804ffb7f : __ip_local_out 11.97 - ffffffff804fc0c8 : ip_local_deliver_finish 8.54 - ffffffff805001a3 : ip_queue_xmit + */ - Started by Ingo Molnar +/* + * perfstat: /usr/bin/time -alike performance counter statistics utility - Improvements and fixes by: + It summarizes the counter events of all tasks (and child tasks), + covering all CPUs that the command (or workload) executes on. + It only counts the per-task events of the workload started, + independent of how many other tasks run on those CPUs. - Arjan van de Ven - Yanmin Zhang - Mike Galbraith + Sample output: - Released under the GPL v2. (and only v2, not any later version) + $ ./perfstat -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null + Performance counter stats for 'ls': + + 163516953 instructions + 2295 cache-misses + 2855182 branch-misses */ + + /* + * Copyright (C) 2008, Red Hat Inc, Ingo Molnar + * + * Improvements and fixes by: + * + * Arjan van de Ven + * Yanmin Zhang + * Wu Fengguang + * Mike Galbraith + * + * Released under the GPL v2. (and only v2, not any later version) + */ + #define _GNU_SOURCE #include #include @@ -67,18 +89,22 @@ #include "perfcounters.h" -const unsigned int default_count[] = { - 1000000, - 1000000, - 10000, - 10000, - 1000000, - 10000, -}; -static __u64 count_filter = 100; +#define MAX_COUNTERS 64 +#define MAX_NR_CPUS 256 + +#define DEF_PERFSTAT_EVENTS { -2, -5, -4, -3, 0, 1, 2, 3} + +static int run_perfstat = 0; +static int system_wide = 0; +static int nr_counters = 0; +static long event_id[MAX_COUNTERS] = DEF_PERFSTAT_EVENTS; +static int event_raw[MAX_COUNTERS]; static int event_count[MAX_COUNTERS]; +static int fd[MAX_NR_CPUS][MAX_COUNTERS]; + +static __u64 count_filter = 100; static int tid = -1; static int profile_cpu = -1; @@ -96,125 +122,335 @@ static int delay_secs = 2; static int zero; static int dump_symtab; +static GList *lines; + struct source_line { uint64_t EIP; unsigned long count; char *line; }; -static GList *lines; + +const unsigned int default_count[] = { + 1000000, + 1000000, + 10000, + 10000, + 1000000, + 10000, +}; + +static char *hw_event_names[] = { + "CPU cycles", + "instructions", + "cache references", + "cache misses", + "branches", + "branch misses", + "bus cycles", +}; + +static char *sw_event_names[] = { + "cpu clock ticks", + "task clock ticks", + "pagefaults", + "context switches", + "CPU migrations", +}; + +struct event_symbol { + int event; + char *symbol; +}; + +static struct event_symbol event_symbols[] = { + {PERF_COUNT_CPU_CYCLES, "cpu-cycles", }, + {PERF_COUNT_CPU_CYCLES, "cycles", }, + {PERF_COUNT_INSTRUCTIONS, "instructions", }, + {PERF_COUNT_CACHE_REFERENCES, "cache-references", }, + {PERF_COUNT_CACHE_MISSES, "cache-misses", }, + {PERF_COUNT_BRANCH_INSTRUCTIONS, "branch-instructions", }, + {PERF_COUNT_BRANCH_INSTRUCTIONS, "branches", }, + {PERF_COUNT_BRANCH_MISSES, "branch-misses", }, + {PERF_COUNT_BUS_CYCLES, "bus-cycles", }, + {PERF_COUNT_CPU_CLOCK, "cpu-ticks", }, + {PERF_COUNT_CPU_CLOCK, "ticks", }, + {PERF_COUNT_TASK_CLOCK, "task-ticks", }, + {PERF_COUNT_PAGE_FAULTS, "page-faults", }, + {PERF_COUNT_PAGE_FAULTS, "faults", }, + {PERF_COUNT_CONTEXT_SWITCHES, "context-switches", }, + {PERF_COUNT_CONTEXT_SWITCHES, "cs", }, + {PERF_COUNT_CPU_MIGRATIONS, "cpu-migrations", }, + {PERF_COUNT_CPU_MIGRATIONS, "migrations", }, +}; + +static void display_events_help(void) +{ + unsigned int i; + int e; + + printf( + " -e EVENT --event=EVENT # symbolic-name abbreviations"); + + for (i = 0, e = PERF_HW_EVENTS_MAX; i < ARRAY_SIZE(event_symbols); i++) { + if (e != event_symbols[i].event) { + e = event_symbols[i].event; + printf( + "\n %2d: %-20s", e, event_symbols[i].symbol); + } else + printf(" %s", event_symbols[i].symbol); + } + + printf("\n" + " rNNN: raw PMU events (eventsel+umask)\n\n"); +} + +static void display_perfstat_help(void) +{ + printf( + "Usage: perfstat [] \n\n" + "PerfStat Options (up to %d event types can be specified):\n\n", + MAX_COUNTERS); + + display_events_help(); + + printf( + " -a # system-wide collection\n"); + exit(0); +} static void display_help(void) { + if (run_perfstat) + return display_perfstat_help(); + printf( - "Usage: kerneltop []\n\n" + "Usage: kerneltop []\n" + " Or: kerneltop -S [] COMMAND [ARGS]\n\n" "KernelTop Options (up to %d event types can be specified at once):\n\n", MAX_COUNTERS); + + display_events_help(); + printf( - " -e EID --event=EID # event type ID [default: 0]\n" - " 0: CPU cycles\n" - " 1: instructions\n" - " 2: cache accesses\n" - " 3: cache misses\n" - " 4: branch instructions\n" - " 5: branch prediction misses\n" - " 6: bus cycles\n\n" - " rNNN: raw PMU events (eventsel+umask)\n\n" + " -S --stat # perfstat COMMAND\n" + " -a # system-wide collection (for perfstat)\n\n" " -c CNT --count=CNT # event period to sample\n\n" " -C CPU --cpu=CPU # CPU (-1 for all) [default: -1]\n" " -p PID --pid=PID # PID of sampled task (-1 for all) [default: -1]\n\n" " -d delay --delay= # sampling/display delay [default: 2]\n" - " -f CNT --filter=CNT # min-event-count filter [default: 100]\n\n" + " -f CNT --filter=CNT # min-event-count filter [default: 100]\n\n" " -s symbol --symbol= # function to be showed annotated one-shot\n" - " -x path --vmlinux= # the vmlinux binary, required for -s use:\n" + " -x path --vmlinux= # the vmlinux binary, required for -s use\n" " -z --zero # zero counts after display\n" " -D --dump_symtab # dump symbol table to stderr on startup\n" - "\n"); + ); exit(0); } -static void process_options(int argc, char *argv[]) +static int type_valid(int type) { - int error = 0, counter; + if (type >= PERF_HW_EVENTS_MAX) + return 0; + if (type <= PERF_SW_EVENTS_MIN) + return 0; - for (;;) { - int option_index = 0; - /** Options for getopt */ - static struct option long_options[] = { - {"count", required_argument, NULL, 'c'}, - {"cpu", required_argument, NULL, 'C'}, - {"delay", required_argument, NULL, 'd'}, - {"dump_symtab", no_argument, NULL, 'D'}, - {"event", required_argument, NULL, 'e'}, - {"filter", required_argument, NULL, 'f'}, - {"group", required_argument, NULL, 'g'}, - {"help", no_argument, NULL, 'h'}, - {"nmi", required_argument, NULL, 'n'}, - {"pid", required_argument, NULL, 'p'}, - {"vmlinux", required_argument, NULL, 'x'}, - {"symbol", required_argument, NULL, 's'}, - {"zero", no_argument, NULL, 'z'}, - {NULL, 0, NULL, 0 } - }; - int c = getopt_long(argc, argv, "c:C:d:De:f:g:hn:p:s:x:z", - long_options, &option_index); - if (c == -1) - break; + return 1; +} - switch (c) { - case 'c': - event_count[nr_counters] = atoi(optarg); break; - case 'C': - /* CPU and PID are mutually exclusive */ - if (tid != -1) { - printf("WARNING: CPU switch overriding PID\n"); - sleep(1); - tid = -1; - } - profile_cpu = atoi(optarg); break; - case 'd': delay_secs = atoi(optarg); break; - case 'D': dump_symtab = 1; break; +static char *event_name(int ctr) +{ + int type = event_id[ctr]; + static char buf[32]; - case 'e': error = parse_events(optarg); break; + if (event_raw[ctr]) { + sprintf(buf, "raw 0x%x", type); + return buf; + } + if (!type_valid(type)) + return "unknown"; - case 'f': count_filter = atoi(optarg); break; - case 'g': group = atoi(optarg); break; - case 'h': display_help(); break; - case 'n': nmi = atoi(optarg); break; - case 'p': - /* CPU and PID are mutually exclusive */ - if (profile_cpu != -1) { - printf("WARNING: PID switch overriding CPU\n"); - sleep(1); - profile_cpu = -1; + if (type >= 0) + return hw_event_names[type]; + + return sw_event_names[-type-1]; +} + +/* + * Each event can have multiple symbolic names. + * Symbolic names are (almost) exactly matched. + */ +static int match_event_symbols(char *str) +{ + unsigned int i; + + if (isdigit(str[0]) || str[0] == '-') + return atoi(str); + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + if (!strncmp(str, event_symbols[i].symbol, + strlen(event_symbols[i].symbol))) + return event_symbols[i].event; + } + + return PERF_HW_EVENTS_MAX; +} + +static int parse_events(char *str) +{ + int type, raw; + +again: + if (nr_counters == MAX_COUNTERS) + return -1; + + raw = 0; + if (*str == 'r') { + raw = 1; + ++str; + type = strtol(str, NULL, 16); + } else { + type = match_event_symbols(str); + if (!type_valid(type)) + return -1; + } + + event_id[nr_counters] = type; + event_raw[nr_counters] = raw; + nr_counters++; + + str = strstr(str, ","); + if (str) { + str++; + goto again; + } + + return 0; +} + + +/* + * perfstat + */ + +char fault_here[1000000]; + +static void create_perfstat_counter(int counter) +{ + struct perf_counter_hw_event hw_event; + + memset(&hw_event, 0, sizeof(hw_event)); + hw_event.type = event_id[counter]; + hw_event.raw = event_raw[counter]; + hw_event.record_type = PERF_RECORD_SIMPLE; + hw_event.nmi = 0; + + if (system_wide) { + int cpu; + for (cpu = 0; cpu < nr_cpus; cpu ++) { + fd[cpu][counter] = sys_perf_counter_open(&hw_event, -1, cpu, -1, 0); + if (fd[cpu][counter] < 0) { + printf("perfstat error: syscall returned with %d (%s)\n", + fd[cpu][counter], strerror(errno)); + exit(-1); } - tid = atoi(optarg); break; - case 's': sym_filter = strdup(optarg); break; - case 'x': vmlinux = strdup(optarg); break; - case 'z': zero = 1; break; - default: error = 1; break; + } + } else { + hw_event.inherit = 1; + hw_event.disabled = 1; + + fd[0][counter] = sys_perf_counter_open(&hw_event, 0, -1, -1, 0); + if (fd[0][counter] < 0) { + printf("perfstat error: syscall returned with %d (%s)\n", + fd[0][counter], strerror(errno)); + exit(-1); } } - if (error) - display_help(); +} - if (!nr_counters) { - nr_counters = 1; - event_id[0] = 0; +int do_perfstat(int argc, char *argv[]) +{ + unsigned long long t0, t1; + int counter; + ssize_t res; + int status; + int pid; + + if (!system_wide) + nr_cpus = 1; + + for (counter = 0; counter < nr_counters; counter++) + create_perfstat_counter(counter); + + argc -= optind; + argv += optind; + + /* + * Enable counters and exec the command: + */ + t0 = rdclock(); + prctl(PR_TASK_PERF_COUNTERS_ENABLE); + + if ((pid = fork()) < 0) + perror("failed to fork"); + if (!pid) { + if (execvp(argv[0], argv)) { + perror(argv[0]); + exit(-1); + } } + while (wait(&status) >= 0) + ; + prctl(PR_TASK_PERF_COUNTERS_DISABLE); + t1 = rdclock(); + + fflush(stdout); + + fprintf(stderr, "\n"); + fprintf(stderr, " Performance counter stats for \'%s\':\n", + argv[0]); + fprintf(stderr, "\n"); for (counter = 0; counter < nr_counters; counter++) { - if (event_count[counter]) - continue; + int cpu; + __u64 count, single_count; + + count = 0; + for (cpu = 0; cpu < nr_cpus; cpu ++) { + res = read(fd[cpu][counter], + (char *) &single_count, sizeof(single_count)); + assert(res == sizeof(single_count)); + count += single_count; + } - if (event_id[counter] < PERF_HW_EVENTS_MAX) - event_count[counter] = default_count[event_id[counter]]; - else - event_count[counter] = 100000; + if (!event_raw[counter] && + (event_id[counter] == PERF_COUNT_CPU_CLOCK || + event_id[counter] == PERF_COUNT_TASK_CLOCK)) { + + double msecs = (double)count / 1000000; + + fprintf(stderr, " %14.6f %-20s (msecs)\n", + msecs, event_name(counter)); + } else { + fprintf(stderr, " %14Ld %-20s (events)\n", + count, event_name(counter)); + } + if (!counter) + fprintf(stderr, "\n"); } + fprintf(stderr, "\n"); + fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", + (double)(t1-t0)/1e6); + fprintf(stderr, "\n"); + + return 0; } +/* + * Symbols + */ + static uint64_t min_ip; static uint64_t max_ip = -1ll; @@ -507,6 +743,9 @@ static void parse_symbols(void) } } +/* + * Source lines + */ static void parse_vmlinux(char *filename) { @@ -527,7 +766,7 @@ static void parse_vmlinux(char *filename) char *c; src = malloc(sizeof(struct source_line)); - assert(src != NULL); + assert(src != NULL); memset(src, 0, sizeof(struct source_line)); if (getline(&src->line, &dummy, file) < 0) @@ -706,11 +945,100 @@ static void process_event(uint64_t ip, int counter) record_ip(ip, counter); } +static void process_options(int argc, char *argv[]) +{ + int error = 0, counter; + + if (strstr(argv[0], "perfstat")) + run_perfstat = 1; + + for (;;) { + int option_index = 0; + /** Options for getopt */ + static struct option long_options[] = { + {"count", required_argument, NULL, 'c'}, + {"cpu", required_argument, NULL, 'C'}, + {"delay", required_argument, NULL, 'd'}, + {"dump_symtab", no_argument, NULL, 'D'}, + {"event", required_argument, NULL, 'e'}, + {"filter", required_argument, NULL, 'f'}, + {"group", required_argument, NULL, 'g'}, + {"help", no_argument, NULL, 'h'}, + {"nmi", required_argument, NULL, 'n'}, + {"pid", required_argument, NULL, 'p'}, + {"vmlinux", required_argument, NULL, 'x'}, + {"symbol", required_argument, NULL, 's'}, + {"stat", no_argument, NULL, 'S'}, + {"zero", no_argument, NULL, 'z'}, + {NULL, 0, NULL, 0 } + }; + int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hn:p:s:Sx:z", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'a': system_wide = 1; break; + case 'c': event_count[nr_counters] = atoi(optarg); break; + case 'C': + /* CPU and PID are mutually exclusive */ + if (tid != -1) { + printf("WARNING: CPU switch overriding PID\n"); + sleep(1); + tid = -1; + } + profile_cpu = atoi(optarg); break; + case 'd': delay_secs = atoi(optarg); break; + case 'D': dump_symtab = 1; break; + + case 'e': error = parse_events(optarg); break; + + case 'f': count_filter = atoi(optarg); break; + case 'g': group = atoi(optarg); break; + case 'h': display_help(); break; + case 'n': nmi = atoi(optarg); break; + case 'p': + /* CPU and PID are mutually exclusive */ + if (profile_cpu != -1) { + printf("WARNING: PID switch overriding CPU\n"); + sleep(1); + profile_cpu = -1; + } + tid = atoi(optarg); break; + case 's': sym_filter = strdup(optarg); break; + case 'S': run_perfstat = 1; break; + case 'x': vmlinux = strdup(optarg); break; + case 'z': zero = 1; break; + default: error = 1; break; + } + } + if (error) + display_help(); + + if (!nr_counters) { + if (run_perfstat) + nr_counters = 8; + else { + nr_counters = 1; + event_id[0] = 0; + } + } + + for (counter = 0; counter < nr_counters; counter++) { + if (event_count[counter]) + continue; + + if (event_id[counter] < PERF_HW_EVENTS_MAX) + event_count[counter] = default_count[event_id[counter]]; + else + event_count[counter] = 100000; + } +} + int main(int argc, char *argv[]) { struct pollfd event_array[MAX_NR_CPUS][MAX_COUNTERS]; struct perf_counter_hw_event hw_event; - int fd[MAX_NR_CPUS][MAX_COUNTERS]; int i, counter, group_fd; unsigned int cpu; uint64_t ip; @@ -720,11 +1048,15 @@ int main(int argc, char *argv[]) process_options(argc, argv); nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + assert(nr_cpus <= MAX_NR_CPUS); + assert(nr_cpus >= 0); + + if (run_perfstat) + return do_perfstat(argc, argv); + if (tid != -1 || profile_cpu != -1) nr_cpus = 1; - assert(nr_cpus <= MAX_NR_CPUS); - for (i = 0; i < nr_cpus; i++) { group_fd = -1; for (counter = 0; counter < nr_counters; counter++) { diff --git a/Documentation/perf_counter/perfcounters.h b/Documentation/perf_counter/perfcounters.h index 99a90d833e12..32e24b9154ab 100644 --- a/Documentation/perf_counter/perfcounters.h +++ b/Documentation/perf_counter/perfcounters.h @@ -11,9 +11,6 @@ #define PR_TASK_PERF_COUNTERS_DISABLE 31 #define PR_TASK_PERF_COUNTERS_ENABLE 32 -#define MAX_COUNTERS 64 -#define MAX_NR_CPUS 256 - #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define rdclock() \ @@ -110,6 +107,7 @@ struct perf_counter_hw_event { __u64 __reserved_3; }; + #ifdef __x86_64__ # define __NR_perf_counter_open 295 #endif @@ -142,131 +140,3 @@ asmlinkage int sys_perf_counter_open( #endif return ret; } - -static int nr_counters = 0; -static long event_id[MAX_COUNTERS] = { -2, -5, -4, -3, 0, 1, 2, 3}; -static int event_raw[MAX_COUNTERS]; - -static char *hw_event_names [] = { - "CPU cycles", - "instructions", - "cache references", - "cache misses", - "branches", - "branch misses", - "bus cycles", -}; - -static char *sw_event_names [] = { - "cpu clock ticks", - "task clock ticks", - "pagefaults", - "context switches", - "CPU migrations", -}; - -struct event_symbol { - int event; - char *symbol; -}; - -static struct event_symbol event_symbols [] = { - {PERF_COUNT_CPU_CYCLES, "cpu-cycles", }, - {PERF_COUNT_CPU_CYCLES, "cycles", }, - {PERF_COUNT_INSTRUCTIONS, "instructions", }, - {PERF_COUNT_CACHE_REFERENCES, "cache-references", }, - {PERF_COUNT_CACHE_MISSES, "cache-misses", }, - {PERF_COUNT_BRANCH_INSTRUCTIONS, "branch-instructions", }, - {PERF_COUNT_BRANCH_INSTRUCTIONS, "branches", }, - {PERF_COUNT_BRANCH_MISSES, "branch-misses", }, - {PERF_COUNT_BUS_CYCLES, "bus-cycles", }, - {PERF_COUNT_CPU_CLOCK, "cpu-ticks", }, - {PERF_COUNT_CPU_CLOCK, "ticks", }, - {PERF_COUNT_TASK_CLOCK, "task-ticks", }, - {PERF_COUNT_PAGE_FAULTS, "page-faults", }, - {PERF_COUNT_PAGE_FAULTS, "faults", }, - {PERF_COUNT_CONTEXT_SWITCHES, "context-switches", }, - {PERF_COUNT_CONTEXT_SWITCHES, "cs", }, - {PERF_COUNT_CPU_MIGRATIONS, "cpu-migrations", }, - {PERF_COUNT_CPU_MIGRATIONS, "migrations", }, -}; - -static int type_valid(int type) -{ - if (type >= PERF_HW_EVENTS_MAX) - return 0; - if (type <= PERF_SW_EVENTS_MIN) - return 0; - - return 1; -} - -static char *event_name(int ctr) -{ - int type = event_id[ctr]; - static char buf[32]; - - if (event_raw[ctr]) { - sprintf(buf, "raw 0x%x", type); - return buf; - } - if (!type_valid(type)) - return "unknown"; - - if (type >= 0) - return hw_event_names[type]; - - return sw_event_names[-type-1]; -} - -/* - * Each event can have multiple symbolic names. - * Symbolic names are (almost) exactly matched. - */ -static int match_event_symbols(char *str) -{ - unsigned int i; - - if (isdigit(str[0]) || str[0] == '-') - return atoi(str); - - for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { - if (!strncmp(str, event_symbols[i].symbol, - strlen(event_symbols[i].symbol))) - return event_symbols[i].event; - } - - return PERF_HW_EVENTS_MAX; -} - -static int parse_events(char *str) -{ - int type, raw; - -again: - if (nr_counters == MAX_COUNTERS) - return -1; - - raw = 0; - if (*str == 'r') { - raw = 1; - ++str; - type = strtol(str, NULL, 16); - } else { - type = match_event_symbols(str); - if (!type_valid(type)) - return -1; - } - - event_id[nr_counters] = type; - event_raw[nr_counters] = raw; - nr_counters++; - - str = strstr(str, ","); - if (str) { - str++; - goto again; - } - - return 0; -} -- GitLab From ef45fa9e6c1694d3e8063f39749097a6e496b12c Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 20 Mar 2009 10:08:07 +0800 Subject: [PATCH 0133/6080] perf_counter tools: fix comment for sym_weight() Signed-off-by: Wu Fengguang Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 9db65a4f1042..7bf2a516f18b 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -473,7 +473,7 @@ static struct sym_entry sym_table[MAX_SYMS]; static void show_details(struct sym_entry *sym); /* - * Ordering weight: count-1 * count-1 * ... / count-n + * Ordering weight: count-1 * count-2 * ... / count-n */ static double sym_weight(const struct sym_entry *sym) { -- GitLab From 3ab8d792b1348eaabfe550ba60902d781d160dd4 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 20 Mar 2009 10:08:08 +0800 Subject: [PATCH 0134/6080] perf_counter tools: fix event_id type Signed-off-by: Wu Fengguang Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 7bf2a516f18b..7bfb0f0d8005 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -99,7 +99,7 @@ static int run_perfstat = 0; static int system_wide = 0; static int nr_counters = 0; -static long event_id[MAX_COUNTERS] = DEF_PERFSTAT_EVENTS; +static __s64 event_id[MAX_COUNTERS] = DEF_PERFSTAT_EVENTS; static int event_raw[MAX_COUNTERS]; static int event_count[MAX_COUNTERS]; static int fd[MAX_NR_CPUS][MAX_COUNTERS]; @@ -261,11 +261,11 @@ static int type_valid(int type) static char *event_name(int ctr) { - int type = event_id[ctr]; + __s64 type = event_id[ctr]; static char buf[32]; if (event_raw[ctr]) { - sprintf(buf, "raw 0x%x", type); + sprintf(buf, "raw 0x%llx", (long long)type); return buf; } if (!type_valid(type)) @@ -299,7 +299,8 @@ static int match_event_symbols(char *str) static int parse_events(char *str) { - int type, raw; + __s64 type; + int raw; again: if (nr_counters == MAX_COUNTERS) -- GitLab From dda7c02f33833bfa9412ba6f0e410b0a18b42c88 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 20 Mar 2009 10:08:09 +0800 Subject: [PATCH 0135/6080] perf_counter tools: cut down default count for cpu-cycles In my system, it takes kerneltop dozens of minutes to show up usable numbers. Make the default count 100 times smaller fixed this long startup latency. I'm not sure if it's the right solution though. Signed-off-by: Wu Fengguang Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 7bfb0f0d8005..0bd3c13150b1 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -132,7 +132,7 @@ struct source_line { const unsigned int default_count[] = { - 1000000, + 10000, 1000000, 10000, 10000, -- GitLab From af9522cf133e9be6da8525a46a9ed7e7659f0e1a Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 20 Mar 2009 10:08:10 +0800 Subject: [PATCH 0136/6080] perf_counter tools: when no command is feed to perfstat, display help and exit Signed-off-by: Wu Fengguang Acked-by: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 0bd3c13150b1..81a68aac137f 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -387,6 +387,9 @@ int do_perfstat(int argc, char *argv[]) argc -= optind; argv += optind; + if (!argc) + display_help(); + /* * Enable counters and exec the command: */ -- GitLab From f4a2deb4860497f4332cf6a1acddab3dd628ddf0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 23 Mar 2009 18:22:06 +0100 Subject: [PATCH 0137/6080] perf_counter: remove the event config bitfields Since the bitfields turned into a bit of a mess, remove them and rely on good old masks. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Orig-LKML-Reference: <20090323172417.059499915@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 6 +-- arch/x86/kernel/cpu/perf_counter.c | 8 ++-- include/linux/perf_counter.h | 74 ++++++++++++++++++++---------- kernel/perf_counter.c | 22 +++++---- 4 files changed, 70 insertions(+), 40 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 6413d9c0313b..d05651584d43 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -602,13 +602,13 @@ hw_perf_counter_init(struct perf_counter *counter) return NULL; if ((s64)counter->hw_event.irq_period < 0) return NULL; - if (!counter->hw_event.raw_type) { - ev = counter->hw_event.event_id; + if (!perf_event_raw(&counter->hw_event)) { + ev = perf_event_id(&counter->hw_event); if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) return NULL; ev = ppmu->generic_events[ev]; } else { - ev = counter->hw_event.raw_event_id; + ev = perf_event_config(&counter->hw_event); } counter->hw.config_base = ev; counter->hw.idx = 0; diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 902282d68b0c..3f95b0cdc550 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -217,15 +217,15 @@ static int __hw_perf_counter_init(struct perf_counter *counter) /* * Raw event type provide the config in the event structure */ - if (hw_event->raw_type) { - hwc->config |= pmc_ops->raw_event(hw_event->raw_event_id); + if (perf_event_raw(hw_event)) { + hwc->config |= pmc_ops->raw_event(perf_event_config(hw_event)); } else { - if (hw_event->event_id >= pmc_ops->max_events) + if (perf_event_id(hw_event) >= pmc_ops->max_events) return -EINVAL; /* * The generic map: */ - hwc->config |= pmc_ops->event_map(hw_event->event_id); + hwc->config |= pmc_ops->event_map(perf_event_id(hw_event)); } counter->wakeup_pending = 0; diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 98f5990be1e1..56099e52970d 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -82,32 +82,37 @@ enum perf_counter_record_type { PERF_RECORD_GROUP = 2, }; +#define __PERF_COUNTER_MASK(name) \ + (((1ULL << PERF_COUNTER_##name##_BITS) - 1) << \ + PERF_COUNTER_##name##_SHIFT) + +#define PERF_COUNTER_RAW_BITS 1 +#define PERF_COUNTER_RAW_SHIFT 63 +#define PERF_COUNTER_RAW_MASK __PERF_COUNTER_MASK(RAW) + +#define PERF_COUNTER_CONFIG_BITS 63 +#define PERF_COUNTER_CONFIG_SHIFT 0 +#define PERF_COUNTER_CONFIG_MASK __PERF_COUNTER_MASK(CONFIG) + +#define PERF_COUNTER_TYPE_BITS 7 +#define PERF_COUNTER_TYPE_SHIFT 56 +#define PERF_COUNTER_TYPE_MASK __PERF_COUNTER_MASK(TYPE) + +#define PERF_COUNTER_EVENT_BITS 56 +#define PERF_COUNTER_EVENT_SHIFT 0 +#define PERF_COUNTER_EVENT_MASK __PERF_COUNTER_MASK(EVENT) + /* * Hardware event to monitor via a performance monitoring counter: */ struct perf_counter_hw_event { - union { -#ifndef __BIG_ENDIAN_BITFIELD - struct { - __u64 event_id : 56, - type : 8; - }; - struct { - __u64 raw_event_id : 63, - raw_type : 1; - }; -#else - struct { - __u64 type : 8, - event_id : 56; - }; - struct { - __u64 raw_type : 1, - raw_event_id : 63; - }; -#endif /* __BIT_ENDIAN_BITFIELD */ - __u64 event_config; - }; + /* + * The MSB of the config word signifies if the rest contains cpu + * specific (raw) counter configuration data, if unset, the next + * 7 bits are an event type and the rest of the bits are the event + * identifier. + */ + __u64 config; __u64 irq_period; __u64 record_type; @@ -157,6 +162,27 @@ struct perf_counter_hw_event { struct task_struct; +static inline u64 perf_event_raw(struct perf_counter_hw_event *hw_event) +{ + return hw_event->config & PERF_COUNTER_RAW_MASK; +} + +static inline u64 perf_event_config(struct perf_counter_hw_event *hw_event) +{ + return hw_event->config & PERF_COUNTER_CONFIG_MASK; +} + +static inline u64 perf_event_type(struct perf_counter_hw_event *hw_event) +{ + return (hw_event->config & PERF_COUNTER_TYPE_MASK) >> + PERF_COUNTER_TYPE_SHIFT; +} + +static inline u64 perf_event_id(struct perf_counter_hw_event *hw_event) +{ + return hw_event->config & PERF_COUNTER_EVENT_MASK; +} + /** * struct hw_perf_counter - performance counter hardware details: */ @@ -336,8 +362,8 @@ extern void perf_counter_output(struct perf_counter *counter, */ static inline int is_software_counter(struct perf_counter *counter) { - return !counter->hw_event.raw_type && - counter->hw_event.type != PERF_TYPE_HARDWARE; + return !perf_event_raw(&counter->hw_event) && + perf_event_type(&counter->hw_event) != PERF_TYPE_HARDWARE; } extern void perf_swcounter_event(u32, u64, int, struct pt_regs *); diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f054b8c9bf96..ca14fc41ccdf 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1379,7 +1379,7 @@ static void perf_counter_handle_group(struct perf_counter *counter) list_for_each_entry(sub, &leader->sibling_list, list_entry) { if (sub != counter) sub->hw_ops->read(sub); - perf_counter_store_irq(counter, sub->hw_event.event_config); + perf_counter_store_irq(counter, sub->hw_event.config); perf_counter_store_irq(counter, atomic64_read(&sub->count)); } } @@ -1489,13 +1489,13 @@ static int perf_swcounter_match(struct perf_counter *counter, if (counter->state != PERF_COUNTER_STATE_ACTIVE) return 0; - if (counter->hw_event.raw_type) + if (perf_event_raw(&counter->hw_event)) return 0; - if (counter->hw_event.type != type) + if (perf_event_type(&counter->hw_event) != type) return 0; - if (counter->hw_event.event_id != event) + if (perf_event_id(&counter->hw_event) != event) return 0; if (counter->hw_event.exclude_user && user_mode(regs)) @@ -1757,13 +1757,13 @@ extern void ftrace_profile_disable(int); static void tp_perf_counter_destroy(struct perf_counter *counter) { - ftrace_profile_disable(counter->hw_event.event_id); + ftrace_profile_disable(perf_event_id(&counter->hw_event)); } static const struct hw_perf_counter_ops * tp_perf_counter_init(struct perf_counter *counter) { - int event_id = counter->hw_event.event_id; + int event_id = perf_event_id(&counter->hw_event); int ret; ret = ftrace_profile_enable(event_id); @@ -1797,7 +1797,7 @@ sw_perf_counter_init(struct perf_counter *counter) * to be kernel events, and page faults are never hypervisor * events. */ - switch (counter->hw_event.event_id) { + switch (perf_event_id(&counter->hw_event)) { case PERF_COUNT_CPU_CLOCK: hw_ops = &perf_ops_cpu_clock; @@ -1882,9 +1882,12 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, hw_ops = NULL; - if (hw_event->raw_type) + if (perf_event_raw(hw_event)) { hw_ops = hw_perf_counter_init(counter); - else switch (hw_event->type) { + goto done; + } + + switch (perf_event_type(hw_event)) { case PERF_TYPE_HARDWARE: hw_ops = hw_perf_counter_init(counter); break; @@ -1902,6 +1905,7 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, kfree(counter); return NULL; } +done: counter->hw_ops = hw_ops; return counter; -- GitLab From 96f6d4444302bb2ea2cf409529eef816462f6ce0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 23 Mar 2009 18:22:07 +0100 Subject: [PATCH 0138/6080] perf_counter: avoid recursion Tracepoint events like lock_acquire and software counters like pagefaults can recurse into the perf counter code again, avoid that. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Orig-LKML-Reference: <20090323172417.152096433@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 7 +++++++ kernel/perf_counter.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 56099e52970d..18dc17d0a61c 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -328,6 +328,13 @@ struct perf_cpu_context { int active_oncpu; int max_pertask; int exclusive; + + /* + * Recursion avoidance: + * + * task, softirq, irq, nmi context + */ + int recursion[4]; }; /* diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index ca14fc41ccdf..ce34bff07bda 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -1532,10 +1533,31 @@ static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, rcu_read_unlock(); } +static int *perf_swcounter_recursion_context(struct perf_cpu_context *cpuctx) +{ + if (in_nmi()) + return &cpuctx->recursion[3]; + + if (in_irq()) + return &cpuctx->recursion[2]; + + if (in_softirq()) + return &cpuctx->recursion[1]; + + return &cpuctx->recursion[0]; +} + static void __perf_swcounter_event(enum perf_event_types type, u32 event, u64 nr, int nmi, struct pt_regs *regs) { struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context); + int *recursion = perf_swcounter_recursion_context(cpuctx); + + if (*recursion) + goto out; + + (*recursion)++; + barrier(); perf_swcounter_ctx_event(&cpuctx->ctx, type, event, nr, nmi, regs); if (cpuctx->task_ctx) { @@ -1543,6 +1565,10 @@ static void __perf_swcounter_event(enum perf_event_types type, u32 event, nr, nmi, regs); } + barrier(); + (*recursion)--; + +out: put_cpu_var(perf_cpu_context); } -- GitLab From 37d81828385f8ff823caaaf1a83e72d065b6cfa1 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 23 Mar 2009 18:22:08 +0100 Subject: [PATCH 0139/6080] perf_counter: add an mmap method to allow userspace to read hardware counters Impact: new feature giving performance improvement This adds the ability for userspace to do an mmap on a hardware counter fd and get access to a read-only page that contains the information needed to translate a hardware counter value to the full 64-bit counter value that would be returned by a read on the fd. This is useful on architectures that allow user programs to read the hardware counters, such as PowerPC. The mmap will only succeed if the counter is a hardware counter monitoring the current process. On my quad 2.5GHz PowerPC 970MP machine, userspace can read a counter and translate it to the full 64-bit value in about 30ns using the mmapped page, compared to about 830ns for the read syscall on the counter, so this does give a significant performance improvement. Signed-off-by: Paul Mackerras Signed-off-by: Peter Zijlstra Orig-LKML-Reference: <20090323172417.297057964@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 6 +++ include/linux/perf_counter.h | 15 ++++++ kernel/perf_counter.c | 76 ++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index d05651584d43..e4349281b07d 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -417,6 +417,8 @@ void hw_perf_restore(u64 disable) atomic64_set(&counter->hw.prev_count, val); counter->hw.idx = hwc_index[i] + 1; write_pmc(counter->hw.idx, val); + if (counter->user_page) + perf_counter_update_userpage(counter); } mb(); cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE; @@ -572,6 +574,8 @@ static void power_perf_disable(struct perf_counter *counter) ppmu->disable_pmc(counter->hw.idx - 1, cpuhw->mmcr); write_pmc(counter->hw.idx, 0); counter->hw.idx = 0; + if (counter->user_page) + perf_counter_update_userpage(counter); break; } } @@ -698,6 +702,8 @@ static void record_and_restart(struct perf_counter *counter, long val, write_pmc(counter->hw.idx, val); atomic64_set(&counter->hw.prev_count, val); atomic64_set(&counter->hw.period_left, left); + if (counter->user_page) + perf_counter_update_userpage(counter); /* * Finally record data if requested. diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 18dc17d0a61c..40b324e91bf6 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -143,6 +143,17 @@ struct perf_counter_hw_event { #define PERF_COUNTER_IOC_ENABLE _IO('$', 0) #define PERF_COUNTER_IOC_DISABLE _IO('$', 1) +/* + * Structure of the page that can be mapped via mmap + */ +struct perf_counter_mmap_page { + __u32 version; /* version number of this structure */ + __u32 compat_version; /* lowest version this is compat with */ + __u32 lock; /* seqlock for synchronization */ + __u32 index; /* hardware counter identifier */ + __s64 offset; /* add to hardware counter value */ +}; + #ifdef __KERNEL__ /* * Kernel-internal data types and definitions: @@ -278,6 +289,9 @@ struct perf_counter { int oncpu; int cpu; + /* pointer to page shared with userspace via mmap */ + unsigned long user_page; + /* read() / irq related data */ wait_queue_head_t waitq; /* optional: for NMIs */ @@ -361,6 +375,7 @@ extern int perf_counter_task_enable(void); extern int hw_perf_group_sched_in(struct perf_counter *group_leader, struct perf_cpu_context *cpuctx, struct perf_counter_context *ctx, int cpu); +extern void perf_counter_update_userpage(struct perf_counter *counter); extern void perf_counter_output(struct perf_counter *counter, int nmi, struct pt_regs *regs); diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index ce34bff07bda..d9cfd902140e 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1177,6 +1177,7 @@ static int perf_release(struct inode *inode, struct file *file) mutex_unlock(&counter->mutex); mutex_unlock(&ctx->mutex); + free_page(counter->user_page); free_counter(counter); put_context(ctx); @@ -1346,12 +1347,87 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return err; } +void perf_counter_update_userpage(struct perf_counter *counter) +{ + struct perf_counter_mmap_page *userpg; + + if (!counter->user_page) + return; + userpg = (struct perf_counter_mmap_page *) counter->user_page; + + ++userpg->lock; + smp_wmb(); + userpg->index = counter->hw.idx; + userpg->offset = atomic64_read(&counter->count); + if (counter->state == PERF_COUNTER_STATE_ACTIVE) + userpg->offset -= atomic64_read(&counter->hw.prev_count); + smp_wmb(); + ++userpg->lock; +} + +static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct perf_counter *counter = vma->vm_file->private_data; + + if (!counter->user_page) + return VM_FAULT_SIGBUS; + + vmf->page = virt_to_page(counter->user_page); + get_page(vmf->page); + return 0; +} + +static struct vm_operations_struct perf_mmap_vmops = { + .fault = perf_mmap_fault, +}; + +static int perf_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct perf_counter *counter = file->private_data; + unsigned long userpg; + + if (!(vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_WRITE)) + return -EINVAL; + if (vma->vm_end - vma->vm_start != PAGE_SIZE) + return -EINVAL; + + /* + * For now, restrict to the case of a hardware counter + * on the current task. + */ + if (is_software_counter(counter) || counter->task != current) + return -EINVAL; + + userpg = counter->user_page; + if (!userpg) { + userpg = get_zeroed_page(GFP_KERNEL); + mutex_lock(&counter->mutex); + if (counter->user_page) { + free_page(userpg); + userpg = counter->user_page; + } else { + counter->user_page = userpg; + } + mutex_unlock(&counter->mutex); + if (!userpg) + return -ENOMEM; + } + + perf_counter_update_userpage(counter); + + vma->vm_flags &= ~VM_MAYWRITE; + vma->vm_flags |= VM_RESERVED; + vma->vm_ops = &perf_mmap_vmops; + return 0; +} + static const struct file_operations perf_fops = { .release = perf_release, .read = perf_read, .poll = perf_poll, .unlocked_ioctl = perf_ioctl, .compat_ioctl = perf_ioctl, + .mmap = perf_mmap, }; /* -- GitLab From 9ab772cd535c4b256a577eae516f9c7462346b2d Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 23 Mar 2009 18:22:09 +0100 Subject: [PATCH 0140/6080] mutex: add atomic_dec_and_mutex_lock() Much like the atomic_dec_and_lock() function in which we take an hold a spin_lock if we drop the atomic to 0 this function takes and holds the mutex if we dec the atomic to 0. Signed-off-by: Eric Paris Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Orig-LKML-Reference: <20090323172417.410913479@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/mutex.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/include/linux/mutex.h b/include/linux/mutex.h index 3069ec7e0ab8..93054fc3635c 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -151,4 +151,27 @@ extern int __must_check mutex_lock_killable(struct mutex *lock); extern int mutex_trylock(struct mutex *lock); extern void mutex_unlock(struct mutex *lock); +/** + * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0 + * @cnt: the atomic which we are to dec + * @lock: the mutex to return holding if we dec to 0 + * + * return true and hold lock if we dec to 0, return false otherwise + */ +static inline int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock) +{ + /* dec if we can't possibly hit 0 */ + if (atomic_add_unless(cnt, -1, 1)) + return 0; + /* we might hit 0, so take the lock */ + mutex_lock(lock); + if (!atomic_dec_and_test(cnt)) { + /* when we actually did the dec, we didn't hit 0 */ + mutex_unlock(lock); + return 0; + } + /* we hit 0, and we hold the lock */ + return 1; +} + #endif -- GitLab From b09d2501ed3d294619cbfbcf828ad39324d0e548 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 1 Apr 2009 17:21:56 -0700 Subject: [PATCH 0141/6080] mutex: drop "inline" from mutex_lock() inside kernel/mutex.c Impact: build fix mutex_lock() is was defined inline in kernel/mutex.c, but wasn't declared so not in . This didn't cause a problem until checkin 3a2d367d9aabac486ac4444c6c7ec7a1dab16267 added the atomic_dec_and_mutex_lock() inline in between declaration and definion. This broke building with CONFIG_ALLOW_WARNINGS=n, e.g. make allnoconfig. Either from the source code nor the allnoconfig binary output I cannot find any internal references to mutex_lock() in kernel/mutex.c, so presumably this "inline" is now-useless legacy. Cc: Eric Paris Cc: Peter Zijlstra Cc: Paul Mackerras Orig-LKML-Reference: Signed-off-by: H. Peter Anvin --- kernel/mutex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/mutex.c b/kernel/mutex.c index 5d79781394a3..fd95eaa672e6 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -89,7 +89,7 @@ __mutex_lock_slowpath(atomic_t *lock_count); * * This function is similar to (but not equivalent to) down(). */ -void inline __sched mutex_lock(struct mutex *lock) +void __sched mutex_lock(struct mutex *lock) { might_sleep(); /* -- GitLab From 7b732a75047738e4f85438ed2f9cd34bf5f2a19a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 23 Mar 2009 18:22:10 +0100 Subject: [PATCH 0142/6080] perf_counter: new output ABI - part 1 Impact: Rework the perfcounter output ABI use sys_read() only for instant data and provide mmap() output for all async overflow data. The first mmap() determines the size of the output buffer. The mmap() size must be a PAGE_SIZE multiple of 1+pages, where pages must be a power of 2 or 0. Further mmap()s of the same fd must have the same size. Once all maps are gone, you can again mmap() with a new size. In case of 0 extra pages there is no data output and the first page only contains meta data. When there are data pages, a poll() event will be generated for each full page of data. Furthermore, the output is circular. This means that although 1 page is a valid configuration, its useless, since we'll start overwriting it the instant we report a full page. Future work will focus on the output format (currently maintained) where we'll likey want each entry denoted by a header which includes a type and length. Further future work will allow to splice() the fd, also containing the async overflow data -- splice() would be mutually exclusive with mmap() of the data. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Orig-LKML-Reference: <20090323172417.470536358@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 9 +- include/linux/perf_counter.h | 36 +-- kernel/perf_counter.c | 464 +++++++++++++++-------------- 3 files changed, 263 insertions(+), 246 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index e4349281b07d..d48596ab6557 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -417,8 +417,7 @@ void hw_perf_restore(u64 disable) atomic64_set(&counter->hw.prev_count, val); counter->hw.idx = hwc_index[i] + 1; write_pmc(counter->hw.idx, val); - if (counter->user_page) - perf_counter_update_userpage(counter); + perf_counter_update_userpage(counter); } mb(); cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE; @@ -574,8 +573,7 @@ static void power_perf_disable(struct perf_counter *counter) ppmu->disable_pmc(counter->hw.idx - 1, cpuhw->mmcr); write_pmc(counter->hw.idx, 0); counter->hw.idx = 0; - if (counter->user_page) - perf_counter_update_userpage(counter); + perf_counter_update_userpage(counter); break; } } @@ -702,8 +700,7 @@ static void record_and_restart(struct perf_counter *counter, long val, write_pmc(counter->hw.idx, val); atomic64_set(&counter->hw.prev_count, val); atomic64_set(&counter->hw.period_left, left); - if (counter->user_page) - perf_counter_update_userpage(counter); + perf_counter_update_userpage(counter); /* * Finally record data if requested. diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 40b324e91bf6..2b5e66d5ebdf 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -152,6 +152,8 @@ struct perf_counter_mmap_page { __u32 lock; /* seqlock for synchronization */ __u32 index; /* hardware counter identifier */ __s64 offset; /* add to hardware counter value */ + + __u32 data_head; /* head in the data section */ }; #ifdef __KERNEL__ @@ -218,21 +220,6 @@ struct hw_perf_counter { #endif }; -/* - * Hardcoded buffer length limit for now, for IRQ-fed events: - */ -#define PERF_DATA_BUFLEN 2048 - -/** - * struct perf_data - performance counter IRQ data sampling ... - */ -struct perf_data { - int len; - int rd_idx; - int overrun; - u8 data[PERF_DATA_BUFLEN]; -}; - struct perf_counter; /** @@ -256,6 +243,14 @@ enum perf_counter_active_state { struct file; +struct perf_mmap_data { + struct rcu_head rcu_head; + int nr_pages; + atomic_t head; + struct perf_counter_mmap_page *user_page; + void *data_pages[0]; +}; + /** * struct perf_counter - performance counter kernel representation: */ @@ -289,16 +284,15 @@ struct perf_counter { int oncpu; int cpu; - /* pointer to page shared with userspace via mmap */ - unsigned long user_page; + /* mmap bits */ + struct mutex mmap_mutex; + atomic_t mmap_count; + struct perf_mmap_data *data; - /* read() / irq related data */ + /* poll related */ wait_queue_head_t waitq; /* optional: for NMIs */ int wakeup_pending; - struct perf_data *irqdata; - struct perf_data *usrdata; - struct perf_data data[2]; void (*destroy)(struct perf_counter *); struct rcu_head rcu_head; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index d9cfd902140e..0dfe91094fd1 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -4,7 +4,8 @@ * Copyright(C) 2008 Thomas Gleixner * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar * - * For licencing details see kernel-base/COPYING + * + * For licensing details see kernel-base/COPYING */ #include @@ -1022,66 +1023,6 @@ static u64 perf_counter_read(struct perf_counter *counter) return atomic64_read(&counter->count); } -/* - * Cross CPU call to switch performance data pointers - */ -static void __perf_switch_irq_data(void *info) -{ - struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); - struct perf_counter *counter = info; - struct perf_counter_context *ctx = counter->ctx; - struct perf_data *oldirqdata = counter->irqdata; - - /* - * If this is a task context, we need to check whether it is - * the current task context of this cpu. If not it has been - * scheduled out before the smp call arrived. - */ - if (ctx->task) { - if (cpuctx->task_ctx != ctx) - return; - spin_lock(&ctx->lock); - } - - /* Change the pointer NMI safe */ - atomic_long_set((atomic_long_t *)&counter->irqdata, - (unsigned long) counter->usrdata); - counter->usrdata = oldirqdata; - - if (ctx->task) - spin_unlock(&ctx->lock); -} - -static struct perf_data *perf_switch_irq_data(struct perf_counter *counter) -{ - struct perf_counter_context *ctx = counter->ctx; - struct perf_data *oldirqdata = counter->irqdata; - struct task_struct *task = ctx->task; - - if (!task) { - smp_call_function_single(counter->cpu, - __perf_switch_irq_data, - counter, 1); - return counter->usrdata; - } - -retry: - spin_lock_irq(&ctx->lock); - if (counter->state != PERF_COUNTER_STATE_ACTIVE) { - counter->irqdata = counter->usrdata; - counter->usrdata = oldirqdata; - spin_unlock_irq(&ctx->lock); - return oldirqdata; - } - spin_unlock_irq(&ctx->lock); - task_oncpu_function_call(task, __perf_switch_irq_data, counter); - /* Might have failed, because task was scheduled out */ - if (counter->irqdata == oldirqdata) - goto retry; - - return counter->usrdata; -} - static void put_context(struct perf_counter_context *ctx) { if (ctx->task) @@ -1177,7 +1118,6 @@ static int perf_release(struct inode *inode, struct file *file) mutex_unlock(&counter->mutex); mutex_unlock(&ctx->mutex); - free_page(counter->user_page); free_counter(counter); put_context(ctx); @@ -1192,7 +1132,7 @@ perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count) { u64 cntval; - if (count != sizeof(cntval)) + if (count < sizeof(cntval)) return -EINVAL; /* @@ -1210,122 +1150,21 @@ perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count) return put_user(cntval, (u64 __user *) buf) ? -EFAULT : sizeof(cntval); } -static ssize_t -perf_copy_usrdata(struct perf_data *usrdata, char __user *buf, size_t count) -{ - if (!usrdata->len) - return 0; - - count = min(count, (size_t)usrdata->len); - if (copy_to_user(buf, usrdata->data + usrdata->rd_idx, count)) - return -EFAULT; - - /* Adjust the counters */ - usrdata->len -= count; - if (!usrdata->len) - usrdata->rd_idx = 0; - else - usrdata->rd_idx += count; - - return count; -} - -static ssize_t -perf_read_irq_data(struct perf_counter *counter, - char __user *buf, - size_t count, - int nonblocking) -{ - struct perf_data *irqdata, *usrdata; - DECLARE_WAITQUEUE(wait, current); - ssize_t res, res2; - - irqdata = counter->irqdata; - usrdata = counter->usrdata; - - if (usrdata->len + irqdata->len >= count) - goto read_pending; - - if (nonblocking) - return -EAGAIN; - - spin_lock_irq(&counter->waitq.lock); - __add_wait_queue(&counter->waitq, &wait); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - if (usrdata->len + irqdata->len >= count) - break; - - if (signal_pending(current)) - break; - - if (counter->state == PERF_COUNTER_STATE_ERROR) - break; - - spin_unlock_irq(&counter->waitq.lock); - schedule(); - spin_lock_irq(&counter->waitq.lock); - } - __remove_wait_queue(&counter->waitq, &wait); - __set_current_state(TASK_RUNNING); - spin_unlock_irq(&counter->waitq.lock); - - if (usrdata->len + irqdata->len < count && - counter->state != PERF_COUNTER_STATE_ERROR) - return -ERESTARTSYS; -read_pending: - mutex_lock(&counter->mutex); - - /* Drain pending data first: */ - res = perf_copy_usrdata(usrdata, buf, count); - if (res < 0 || res == count) - goto out; - - /* Switch irq buffer: */ - usrdata = perf_switch_irq_data(counter); - res2 = perf_copy_usrdata(usrdata, buf + res, count - res); - if (res2 < 0) { - if (!res) - res = -EFAULT; - } else { - res += res2; - } -out: - mutex_unlock(&counter->mutex); - - return res; -} - static ssize_t perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct perf_counter *counter = file->private_data; - switch (counter->hw_event.record_type) { - case PERF_RECORD_SIMPLE: - return perf_read_hw(counter, buf, count); - - case PERF_RECORD_IRQ: - case PERF_RECORD_GROUP: - return perf_read_irq_data(counter, buf, count, - file->f_flags & O_NONBLOCK); - } - return -EINVAL; + return perf_read_hw(counter, buf, count); } static unsigned int perf_poll(struct file *file, poll_table *wait) { struct perf_counter *counter = file->private_data; - unsigned int events = 0; - unsigned long flags; + unsigned int events = POLLIN; poll_wait(file, &counter->waitq, wait); - spin_lock_irqsave(&counter->waitq.lock, flags); - if (counter->usrdata->len || counter->irqdata->len) - events |= POLLIN; - spin_unlock_irqrestore(&counter->waitq.lock, flags); - return events; } @@ -1347,78 +1186,207 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return err; } -void perf_counter_update_userpage(struct perf_counter *counter) +static void __perf_counter_update_userpage(struct perf_counter *counter, + struct perf_mmap_data *data) { - struct perf_counter_mmap_page *userpg; - - if (!counter->user_page) - return; - userpg = (struct perf_counter_mmap_page *) counter->user_page; + struct perf_counter_mmap_page *userpg = data->user_page; + /* + * Disable preemption so as to not let the corresponding user-space + * spin too long if we get preempted. + */ + preempt_disable(); ++userpg->lock; smp_wmb(); userpg->index = counter->hw.idx; userpg->offset = atomic64_read(&counter->count); if (counter->state == PERF_COUNTER_STATE_ACTIVE) userpg->offset -= atomic64_read(&counter->hw.prev_count); + + userpg->data_head = atomic_read(&data->head); smp_wmb(); ++userpg->lock; + preempt_enable(); +} + +void perf_counter_update_userpage(struct perf_counter *counter) +{ + struct perf_mmap_data *data; + + rcu_read_lock(); + data = rcu_dereference(counter->data); + if (data) + __perf_counter_update_userpage(counter, data); + rcu_read_unlock(); } static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct perf_counter *counter = vma->vm_file->private_data; + struct perf_mmap_data *data; + int ret = VM_FAULT_SIGBUS; - if (!counter->user_page) - return VM_FAULT_SIGBUS; + rcu_read_lock(); + data = rcu_dereference(counter->data); + if (!data) + goto unlock; + + if (vmf->pgoff == 0) { + vmf->page = virt_to_page(data->user_page); + } else { + int nr = vmf->pgoff - 1; - vmf->page = virt_to_page(counter->user_page); + if ((unsigned)nr > data->nr_pages) + goto unlock; + + vmf->page = virt_to_page(data->data_pages[nr]); + } get_page(vmf->page); + ret = 0; +unlock: + rcu_read_unlock(); + + return ret; +} + +static int perf_mmap_data_alloc(struct perf_counter *counter, int nr_pages) +{ + struct perf_mmap_data *data; + unsigned long size; + int i; + + WARN_ON(atomic_read(&counter->mmap_count)); + + size = sizeof(struct perf_mmap_data); + size += nr_pages * sizeof(void *); + + data = kzalloc(size, GFP_KERNEL); + if (!data) + goto fail; + + data->user_page = (void *)get_zeroed_page(GFP_KERNEL); + if (!data->user_page) + goto fail_user_page; + + for (i = 0; i < nr_pages; i++) { + data->data_pages[i] = (void *)get_zeroed_page(GFP_KERNEL); + if (!data->data_pages[i]) + goto fail_data_pages; + } + + data->nr_pages = nr_pages; + + rcu_assign_pointer(counter->data, data); + return 0; + +fail_data_pages: + for (i--; i >= 0; i--) + free_page((unsigned long)data->data_pages[i]); + + free_page((unsigned long)data->user_page); + +fail_user_page: + kfree(data); + +fail: + return -ENOMEM; +} + +static void __perf_mmap_data_free(struct rcu_head *rcu_head) +{ + struct perf_mmap_data *data = container_of(rcu_head, + struct perf_mmap_data, rcu_head); + int i; + + free_page((unsigned long)data->user_page); + for (i = 0; i < data->nr_pages; i++) + free_page((unsigned long)data->data_pages[i]); + kfree(data); +} + +static void perf_mmap_data_free(struct perf_counter *counter) +{ + struct perf_mmap_data *data = counter->data; + + WARN_ON(atomic_read(&counter->mmap_count)); + + rcu_assign_pointer(counter->data, NULL); + call_rcu(&data->rcu_head, __perf_mmap_data_free); +} + +static void perf_mmap_open(struct vm_area_struct *vma) +{ + struct perf_counter *counter = vma->vm_file->private_data; + + atomic_inc(&counter->mmap_count); +} + +static void perf_mmap_close(struct vm_area_struct *vma) +{ + struct perf_counter *counter = vma->vm_file->private_data; + + if (atomic_dec_and_mutex_lock(&counter->mmap_count, + &counter->mmap_mutex)) { + perf_mmap_data_free(counter); + mutex_unlock(&counter->mmap_mutex); + } } static struct vm_operations_struct perf_mmap_vmops = { + .open = perf_mmap_open, + .close = perf_mmap_close, .fault = perf_mmap_fault, }; static int perf_mmap(struct file *file, struct vm_area_struct *vma) { struct perf_counter *counter = file->private_data; - unsigned long userpg; + unsigned long vma_size; + unsigned long nr_pages; + unsigned long locked, lock_limit; + int ret = 0; if (!(vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_WRITE)) return -EINVAL; - if (vma->vm_end - vma->vm_start != PAGE_SIZE) + + vma_size = vma->vm_end - vma->vm_start; + nr_pages = (vma_size / PAGE_SIZE) - 1; + + if (nr_pages == 0 || !is_power_of_2(nr_pages)) return -EINVAL; - /* - * For now, restrict to the case of a hardware counter - * on the current task. - */ - if (is_software_counter(counter) || counter->task != current) + if (vma_size != PAGE_SIZE * (1 + nr_pages)) return -EINVAL; - userpg = counter->user_page; - if (!userpg) { - userpg = get_zeroed_page(GFP_KERNEL); - mutex_lock(&counter->mutex); - if (counter->user_page) { - free_page(userpg); - userpg = counter->user_page; - } else { - counter->user_page = userpg; - } - mutex_unlock(&counter->mutex); - if (!userpg) - return -ENOMEM; - } + if (vma->vm_pgoff != 0) + return -EINVAL; + + locked = vma_size >> PAGE_SHIFT; + locked += vma->vm_mm->locked_vm; - perf_counter_update_userpage(counter); + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; + lock_limit >>= PAGE_SHIFT; + + if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) + return -EPERM; + + mutex_lock(&counter->mmap_mutex); + if (atomic_inc_not_zero(&counter->mmap_count)) + goto out; + + WARN_ON(counter->data); + ret = perf_mmap_data_alloc(counter, nr_pages); + if (!ret) + atomic_set(&counter->mmap_count, 1); +out: + mutex_unlock(&counter->mmap_mutex); vma->vm_flags &= ~VM_MAYWRITE; vma->vm_flags |= VM_RESERVED; vma->vm_ops = &perf_mmap_vmops; - return 0; + + return ret; } static const struct file_operations perf_fops = { @@ -1434,30 +1402,94 @@ static const struct file_operations perf_fops = { * Output */ -static void perf_counter_store_irq(struct perf_counter *counter, u64 data) +static int perf_output_write(struct perf_counter *counter, int nmi, + void *buf, ssize_t size) { - struct perf_data *irqdata = counter->irqdata; + struct perf_mmap_data *data; + unsigned int offset, head, nr; + unsigned int len; + int ret, wakeup; - if (irqdata->len > PERF_DATA_BUFLEN - sizeof(u64)) { - irqdata->overrun++; - } else { - u64 *p = (u64 *) &irqdata->data[irqdata->len]; + rcu_read_lock(); + ret = -ENOSPC; + data = rcu_dereference(counter->data); + if (!data) + goto out; + + if (!data->nr_pages) + goto out; + + ret = -EINVAL; + if (size > PAGE_SIZE) + goto out; + + do { + offset = head = atomic_read(&data->head); + head += sizeof(u64); + } while (atomic_cmpxchg(&data->head, offset, head) != offset); + + wakeup = (offset >> PAGE_SHIFT) != (head >> PAGE_SHIFT); - *p = data; - irqdata->len += sizeof(u64); + nr = (offset >> PAGE_SHIFT) & (data->nr_pages - 1); + offset &= PAGE_SIZE - 1; + + len = min_t(unsigned int, PAGE_SIZE - offset, size); + memcpy(data->data_pages[nr] + offset, buf, len); + size -= len; + + if (size) { + nr = (nr + 1) & (data->nr_pages - 1); + memcpy(data->data_pages[nr], buf + len, size); + } + + /* + * generate a poll() wakeup for every page boundary crossed + */ + if (wakeup) { + __perf_counter_update_userpage(counter, data); + if (nmi) { + counter->wakeup_pending = 1; + set_perf_counter_pending(); + } else + wake_up(&counter->waitq); } + ret = 0; +out: + rcu_read_unlock(); + + return ret; } -static void perf_counter_handle_group(struct perf_counter *counter) +static void perf_output_simple(struct perf_counter *counter, + int nmi, struct pt_regs *regs) +{ + u64 entry; + + entry = instruction_pointer(regs); + + perf_output_write(counter, nmi, &entry, sizeof(entry)); +} + +struct group_entry { + u64 event; + u64 counter; +}; + +static void perf_output_group(struct perf_counter *counter, int nmi) { struct perf_counter *leader, *sub; leader = counter->group_leader; list_for_each_entry(sub, &leader->sibling_list, list_entry) { + struct group_entry entry; + if (sub != counter) sub->hw_ops->read(sub); - perf_counter_store_irq(counter, sub->hw_event.config); - perf_counter_store_irq(counter, atomic64_read(&sub->count)); + + entry.event = sub->hw_event.config; + entry.counter = atomic64_read(&sub->count); + + perf_output_write(counter, nmi, &entry, sizeof(entry)); } } @@ -1469,19 +1501,13 @@ void perf_counter_output(struct perf_counter *counter, return; case PERF_RECORD_IRQ: - perf_counter_store_irq(counter, instruction_pointer(regs)); + perf_output_simple(counter, nmi, regs); break; case PERF_RECORD_GROUP: - perf_counter_handle_group(counter); + perf_output_group(counter, nmi); break; } - - if (nmi) { - counter->wakeup_pending = 1; - set_perf_counter_pending(); - } else - wake_up(&counter->waitq); } /* @@ -1967,10 +1993,10 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, INIT_LIST_HEAD(&counter->sibling_list); init_waitqueue_head(&counter->waitq); + mutex_init(&counter->mmap_mutex); + INIT_LIST_HEAD(&counter->child_list); - counter->irqdata = &counter->data[0]; - counter->usrdata = &counter->data[1]; counter->cpu = cpu; counter->hw_event = *hw_event; counter->wakeup_pending = 0; -- GitLab From 803d4f3980f6e220b27311a283aab0a4d68b6709 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 23 Mar 2009 18:22:11 +0100 Subject: [PATCH 0143/6080] perf_counter tools: update to new syscall ABI update the kerneltop userspace to work with the latest syscall ABI Signed-off-by: Peter Zijlstra Cc: Wu Fengguang Cc: Paul Mackerras Orig-LKML-Reference: <20090323172417.559643732@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 235 +++++++++++++++++-------- 1 file changed, 157 insertions(+), 78 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 81a68aac137f..a72c9bd28071 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -87,20 +87,90 @@ #include -#include "perfcounters.h" +#include "include/linux/perf_counter.h" +/* + * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all + * counters in the current task. + */ +#define PR_TASK_PERF_COUNTERS_DISABLE 31 +#define PR_TASK_PERF_COUNTERS_ENABLE 32 + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define rdclock() \ +({ \ + struct timespec ts; \ + \ + clock_gettime(CLOCK_MONOTONIC, &ts); \ + ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ +}) + +/* + * Pick up some kernel type conventions: + */ +#define __user +#define asmlinkage + +typedef unsigned int __u32; +typedef unsigned long long __u64; +typedef long long __s64; + + +#ifdef __x86_64__ +# define __NR_perf_counter_open 295 +#endif + +#ifdef __i386__ +# define __NR_perf_counter_open 333 +#endif + +#ifdef __powerpc__ +#define __NR_perf_counter_open 319 +#endif + +asmlinkage int sys_perf_counter_open( + struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, + int cpu, + int group_fd, + unsigned long flags) +{ + int ret; + + ret = syscall( + __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); +#if defined(__x86_64__) || defined(__i386__) + if (ret < 0 && ret > -4096) { + errno = -ret; + ret = -1; + } +#endif + return ret; +} + #define MAX_COUNTERS 64 #define MAX_NR_CPUS 256 -#define DEF_PERFSTAT_EVENTS { -2, -5, -4, -3, 0, 1, 2, 3} +#define EID(type, id) (((__u64)(type) << PERF_COUNTER_TYPE_SHIFT) | (id)) static int run_perfstat = 0; static int system_wide = 0; static int nr_counters = 0; -static __s64 event_id[MAX_COUNTERS] = DEF_PERFSTAT_EVENTS; -static int event_raw[MAX_COUNTERS]; +static __u64 event_id[MAX_COUNTERS] = { + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), + + EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), + EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), + EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), + EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), +}; +static int default_interval = 100000; static int event_count[MAX_COUNTERS]; static int fd[MAX_NR_CPUS][MAX_COUNTERS]; @@ -156,49 +226,63 @@ static char *sw_event_names[] = { "pagefaults", "context switches", "CPU migrations", + "minor faults", + "major faults", }; struct event_symbol { - int event; + __u64 event; char *symbol; }; static struct event_symbol event_symbols[] = { - {PERF_COUNT_CPU_CYCLES, "cpu-cycles", }, - {PERF_COUNT_CPU_CYCLES, "cycles", }, - {PERF_COUNT_INSTRUCTIONS, "instructions", }, - {PERF_COUNT_CACHE_REFERENCES, "cache-references", }, - {PERF_COUNT_CACHE_MISSES, "cache-misses", }, - {PERF_COUNT_BRANCH_INSTRUCTIONS, "branch-instructions", }, - {PERF_COUNT_BRANCH_INSTRUCTIONS, "branches", }, - {PERF_COUNT_BRANCH_MISSES, "branch-misses", }, - {PERF_COUNT_BUS_CYCLES, "bus-cycles", }, - {PERF_COUNT_CPU_CLOCK, "cpu-ticks", }, - {PERF_COUNT_CPU_CLOCK, "ticks", }, - {PERF_COUNT_TASK_CLOCK, "task-ticks", }, - {PERF_COUNT_PAGE_FAULTS, "page-faults", }, - {PERF_COUNT_PAGE_FAULTS, "faults", }, - {PERF_COUNT_CONTEXT_SWITCHES, "context-switches", }, - {PERF_COUNT_CONTEXT_SWITCHES, "cs", }, - {PERF_COUNT_CPU_MIGRATIONS, "cpu-migrations", }, - {PERF_COUNT_CPU_MIGRATIONS, "migrations", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cpu-cycles", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cycles", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), "instructions", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), "cache-references", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), "cache-misses", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branch-instructions", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branches", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_MISSES), "branch-misses", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BUS_CYCLES), "bus-cycles", }, + + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK), "cpu-clock", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), "task-clock", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "page-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MIN), "minor-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MAJ), "major-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "context-switches", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "cs", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "cpu-migrations", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "migrations", }, }; +#define __PERF_COUNTER_FIELD(config, name) \ + ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT) + +#define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW) +#define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG) +#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE) +#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT) + static void display_events_help(void) { unsigned int i; - int e; + __u64 e; printf( " -e EVENT --event=EVENT # symbolic-name abbreviations"); - for (i = 0, e = PERF_HW_EVENTS_MAX; i < ARRAY_SIZE(event_symbols); i++) { - if (e != event_symbols[i].event) { - e = event_symbols[i].event; - printf( - "\n %2d: %-20s", e, event_symbols[i].symbol); - } else - printf(" %s", event_symbols[i].symbol); + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + int type, id; + + e = event_symbols[i].event; + type = PERF_COUNTER_TYPE(e); + id = PERF_COUNTER_ID(e); + + printf("\n %d:%d: %-20s", + type, id, event_symbols[i].symbol); } printf("\n" @@ -249,44 +333,51 @@ static void display_help(void) exit(0); } -static int type_valid(int type) -{ - if (type >= PERF_HW_EVENTS_MAX) - return 0; - if (type <= PERF_SW_EVENTS_MIN) - return 0; - - return 1; -} - static char *event_name(int ctr) { - __s64 type = event_id[ctr]; + __u64 config = event_id[ctr]; + int type = PERF_COUNTER_TYPE(config); + int id = PERF_COUNTER_ID(config); static char buf[32]; - if (event_raw[ctr]) { - sprintf(buf, "raw 0x%llx", (long long)type); + if (PERF_COUNTER_RAW(config)) { + sprintf(buf, "raw 0x%llx", PERF_COUNTER_CONFIG(config)); return buf; } - if (!type_valid(type)) - return "unknown"; - if (type >= 0) - return hw_event_names[type]; + switch (type) { + case PERF_TYPE_HARDWARE: + if (id < PERF_HW_EVENTS_MAX) + return hw_event_names[id]; + return "unknown-hardware"; + + case PERF_TYPE_SOFTWARE: + if (id < PERF_SW_EVENTS_MAX) + return sw_event_names[id]; + return "unknown-software"; - return sw_event_names[-type-1]; + default: + break; + } + + return "unknown"; } /* * Each event can have multiple symbolic names. * Symbolic names are (almost) exactly matched. */ -static int match_event_symbols(char *str) +static __u64 match_event_symbols(char *str) { + __u64 config, id; + int type; unsigned int i; - if (isdigit(str[0]) || str[0] == '-') - return atoi(str); + if (sscanf(str, "r%llx", &config) == 1) + return config | PERF_COUNTER_RAW_MASK; + + if (sscanf(str, "%d:%llu", &type, &id) == 2) + return EID(type, id); for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { if (!strncmp(str, event_symbols[i].symbol, @@ -294,31 +385,22 @@ static int match_event_symbols(char *str) return event_symbols[i].event; } - return PERF_HW_EVENTS_MAX; + return ~0ULL; } static int parse_events(char *str) { - __s64 type; - int raw; + __u64 config; again: if (nr_counters == MAX_COUNTERS) return -1; - raw = 0; - if (*str == 'r') { - raw = 1; - ++str; - type = strtol(str, NULL, 16); - } else { - type = match_event_symbols(str); - if (!type_valid(type)) - return -1; - } + config = match_event_symbols(str); + if (config == ~0ULL) + return -1; - event_id[nr_counters] = type; - event_raw[nr_counters] = raw; + event_id[nr_counters] = config; nr_counters++; str = strstr(str, ","); @@ -342,8 +424,7 @@ static void create_perfstat_counter(int counter) struct perf_counter_hw_event hw_event; memset(&hw_event, 0, sizeof(hw_event)); - hw_event.type = event_id[counter]; - hw_event.raw = event_raw[counter]; + hw_event.config = event_id[counter]; hw_event.record_type = PERF_RECORD_SIMPLE; hw_event.nmi = 0; @@ -428,7 +509,7 @@ int do_perfstat(int argc, char *argv[]) count += single_count; } - if (!event_raw[counter] && + if (!PERF_COUNTER_RAW(event_id[counter]) && (event_id[counter] == PERF_COUNT_CPU_CLOCK || event_id[counter] == PERF_COUNT_TASK_CLOCK)) { @@ -911,7 +992,7 @@ static void record_ip(uint64_t ip, int counter) assert(left <= middle && middle <= right); if (!(left <= ip && ip <= right)) { printf(" left: %016lx\n", left); - printf(" ip: %016lx\n", ip); + printf(" ip: %016llx\n", ip); printf("right: %016lx\n", right); } assert(left <= ip && ip <= right); @@ -983,7 +1064,7 @@ static void process_options(int argc, char *argv[]) switch (c) { case 'a': system_wide = 1; break; - case 'c': event_count[nr_counters] = atoi(optarg); break; + case 'c': default_interval = atoi(optarg); break; case 'C': /* CPU and PID are mutually exclusive */ if (tid != -1) { @@ -1032,10 +1113,7 @@ static void process_options(int argc, char *argv[]) if (event_count[counter]) continue; - if (event_id[counter] < PERF_HW_EVENTS_MAX) - event_count[counter] = default_count[event_id[counter]]; - else - event_count[counter] = 100000; + event_count[counter] = default_interval; } } @@ -1070,12 +1148,13 @@ int main(int argc, char *argv[]) cpu = i; memset(&hw_event, 0, sizeof(hw_event)); - hw_event.type = event_id[counter]; - hw_event.raw = event_raw[counter]; + hw_event.config = event_id[counter]; hw_event.irq_period = event_count[counter]; hw_event.record_type = PERF_RECORD_IRQ; hw_event.nmi = nmi; + printf("FOO: %d %llx %llx\n", counter, event_id[counter], event_count[counter]); + fd[i][counter] = sys_perf_counter_open(&hw_event, tid, cpu, group_fd, 0); fcntl(fd[i][counter], F_SETFL, O_NONBLOCK); if (fd[i][counter] < 0) { -- GitLab From bcbcb37cdb67d8100acfa66df40c4d636c28c4d1 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 23 Mar 2009 18:22:12 +0100 Subject: [PATCH 0144/6080] perf_counter tools: use mmap() output update kerneltop to use the mmap() output to gather overflow information Signed-off-by: Peter Zijlstra Cc: Wu Fengguang Cc: Paul Mackerras Orig-LKML-Reference: <20090323172417.677932499@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 93 ++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 14 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index a72c9bd28071..80b790553ec8 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -84,6 +84,7 @@ #include #include #include +#include #include @@ -119,17 +120,25 @@ typedef long long __s64; #ifdef __x86_64__ -# define __NR_perf_counter_open 295 +#define __NR_perf_counter_open 295 +#define rmb() asm volatile("lfence" ::: "memory") +#define cpu_relax() asm volatile("rep; nop" ::: "memory"); #endif #ifdef __i386__ -# define __NR_perf_counter_open 333 +#define __NR_perf_counter_open 333 +#define rmb() asm volatile("lfence" ::: "memory") +#define cpu_relax() asm volatile("rep; nop" ::: "memory"); #endif #ifdef __powerpc__ #define __NR_perf_counter_open 319 +#define rmb() asm volatile ("sync" ::: "memory") +#define cpu_relax() asm volatile ("" ::: "memory"); #endif +#define unlikely(x) __builtin_expect(!!(x), 0) + asmlinkage int sys_perf_counter_open( struct perf_counter_hw_event *hw_event_uptr __user, pid_t pid, @@ -181,6 +190,7 @@ static int profile_cpu = -1; static int nr_cpus = 0; static int nmi = 1; static int group = 0; +static unsigned int page_size; static char *vmlinux; @@ -1117,16 +1127,68 @@ static void process_options(int argc, char *argv[]) } } +struct mmap_data { + int counter; + void *base; + unsigned int mask; + unsigned int prev; +}; + +static unsigned int mmap_read_head(struct mmap_data *md) +{ + struct perf_counter_mmap_page *pc = md->base; + unsigned int seq, head; + +repeat: + rmb(); + seq = pc->lock; + + if (unlikely(seq & 1)) { + cpu_relax(); + goto repeat; + } + + head = pc->data_head; + + rmb(); + if (pc->lock != seq) + goto repeat; + + return head; +} + +static void mmap_read(struct mmap_data *md) +{ + unsigned int head = mmap_read_head(md); + unsigned int old = md->prev; + unsigned char *data = md->base + page_size; + + if (head - old > md->mask) { + printf("ERROR: failed to keep up with mmap data\n"); + exit(-1); + } + + for (; old != head;) { + __u64 *ptr = (__u64 *)&data[old & md->mask]; + old += sizeof(__u64); + + process_event(*ptr, md->counter); + } + + md->prev = old; +} + int main(int argc, char *argv[]) { struct pollfd event_array[MAX_NR_CPUS][MAX_COUNTERS]; + struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; struct perf_counter_hw_event hw_event; int i, counter, group_fd; unsigned int cpu; - uint64_t ip; - ssize_t res; int ret; + page_size = sysconf(_SC_PAGE_SIZE); + process_options(argc, argv); nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); @@ -1153,8 +1215,6 @@ int main(int argc, char *argv[]) hw_event.record_type = PERF_RECORD_IRQ; hw_event.nmi = nmi; - printf("FOO: %d %llx %llx\n", counter, event_id[counter], event_count[counter]); - fd[i][counter] = sys_perf_counter_open(&hw_event, tid, cpu, group_fd, 0); fcntl(fd[i][counter], F_SETFL, O_NONBLOCK); if (fd[i][counter] < 0) { @@ -1174,6 +1234,17 @@ int main(int argc, char *argv[]) event_array[i][counter].fd = fd[i][counter]; event_array[i][counter].events = POLLIN; + + mmap_array[i][counter].counter = counter; + mmap_array[i][counter].prev = 0; + mmap_array[i][counter].mask = 2*page_size - 1; + mmap_array[i][counter].base = mmap(NULL, 3*page_size, + PROT_READ, MAP_SHARED, fd[i][counter], 0); + if (mmap_array[i][counter].base == MAP_FAILED) { + printf("kerneltop error: failed to mmap with %d (%s)\n", + errno, strerror(errno)); + exit(-1); + } } } @@ -1188,14 +1259,8 @@ int main(int argc, char *argv[]) int hits = events; for (i = 0; i < nr_cpus; i++) { - for (counter = 0; counter < nr_counters; counter++) { - res = read(fd[i][counter], (char *) &ip, sizeof(ip)); - if (res > 0) { - assert(res == sizeof(ip)); - - process_event(ip, counter); - } - } + for (counter = 0; counter < nr_counters; counter++) + mmap_read(&mmap_array[i][counter]); } if (time(NULL) >= last_refresh + delay_secs) { -- GitLab From 383c5f8cd7d253be0017d8d5a39cbb78aaf70206 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 23 Mar 2009 21:49:25 +0100 Subject: [PATCH 0145/6080] perf_counter tools: tidy up in-kernel dependencies Remove now unified perfstat.c and perf_counter.h, and link to the in-kernel perf_counter.h. Cc: Wu Fengguang Cc: Paul Mackerras Acked-by: Peter Zijlstra Orig-LKML-Reference: <20090323172417.677932499@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 2 +- Documentation/perf_counter/kerneltop.c | 2 +- Documentation/perf_counter/perfcounters.h | 142 ------------ Documentation/perf_counter/perfstat.c | 251 ---------------------- 4 files changed, 2 insertions(+), 395 deletions(-) delete mode 100644 Documentation/perf_counter/perfcounters.h delete mode 100644 Documentation/perf_counter/perfstat.c diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index b45749753fcb..666da95a7877 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -2,7 +2,7 @@ BINS = kerneltop perfstat all: $(BINS) -kerneltop: kerneltop.c perfcounters.h +kerneltop: kerneltop.c ../../include/linux/perf_counter.h cc -O6 -Wall -lrt `pkg-config --cflags --libs glib-2.0` -o $@ $< perfstat: kerneltop diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 80b790553ec8..25e80bc44556 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -88,7 +88,7 @@ #include -#include "include/linux/perf_counter.h" +#include "../../include/linux/perf_counter.h" /* diff --git a/Documentation/perf_counter/perfcounters.h b/Documentation/perf_counter/perfcounters.h deleted file mode 100644 index 32e24b9154ab..000000000000 --- a/Documentation/perf_counter/perfcounters.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Ioctls that can be done on a perf counter fd: - */ -#define PERF_COUNTER_IOC_ENABLE _IO('$', 0) -#define PERF_COUNTER_IOC_DISABLE _IO('$', 1) - -/* - * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all - * counters in the current task. - */ -#define PR_TASK_PERF_COUNTERS_DISABLE 31 -#define PR_TASK_PERF_COUNTERS_ENABLE 32 - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -#define rdclock() \ -({ \ - struct timespec ts; \ - \ - clock_gettime(CLOCK_MONOTONIC, &ts); \ - ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ -}) - -/* - * Pick up some kernel type conventions: - */ -#define __user -#define asmlinkage - -typedef unsigned int __u32; -typedef unsigned long long __u64; -typedef long long __s64; - -/* - * User-space ABI bits: - */ - -/* - * Generalized performance counter event types, used by the hw_event.type - * parameter of the sys_perf_counter_open() syscall: - */ -enum hw_event_types { - /* - * Common hardware events, generalized by the kernel: - */ - PERF_COUNT_CPU_CYCLES = 0, - PERF_COUNT_INSTRUCTIONS = 1, - PERF_COUNT_CACHE_REFERENCES = 2, - PERF_COUNT_CACHE_MISSES = 3, - PERF_COUNT_BRANCH_INSTRUCTIONS = 4, - PERF_COUNT_BRANCH_MISSES = 5, - PERF_COUNT_BUS_CYCLES = 6, - - PERF_HW_EVENTS_MAX = 7, - - /* - * Special "software" counters provided by the kernel, even if - * the hardware does not support performance counters. These - * counters measure various physical and sw events of the - * kernel (and allow the profiling of them as well): - */ - PERF_COUNT_CPU_CLOCK = -1, - PERF_COUNT_TASK_CLOCK = -2, - PERF_COUNT_PAGE_FAULTS = -3, - PERF_COUNT_CONTEXT_SWITCHES = -4, - PERF_COUNT_CPU_MIGRATIONS = -5, - - PERF_SW_EVENTS_MIN = -6, -}; - -/* - * IRQ-notification data record type: - */ -enum perf_counter_record_type { - PERF_RECORD_SIMPLE = 0, - PERF_RECORD_IRQ = 1, - PERF_RECORD_GROUP = 2, -}; - -/* - * Hardware event to monitor via a performance monitoring counter: - */ -struct perf_counter_hw_event { - __s64 type; - - __u64 irq_period; - __u64 record_type; - __u64 read_format; - - __u64 disabled : 1, /* off by default */ - nmi : 1, /* NMI sampling */ - raw : 1, /* raw event type */ - inherit : 1, /* children inherit it */ - pinned : 1, /* must always be on PMU */ - exclusive : 1, /* only group on PMU */ - exclude_user : 1, /* don't count user */ - exclude_kernel : 1, /* ditto kernel */ - exclude_hv : 1, /* ditto hypervisor */ - exclude_idle : 1, /* don't count when idle */ - - __reserved_1 : 54; - - __u32 extra_config_len; - __u32 __reserved_4; - - __u64 __reserved_2; - __u64 __reserved_3; -}; - - -#ifdef __x86_64__ -# define __NR_perf_counter_open 295 -#endif - -#ifdef __i386__ -# define __NR_perf_counter_open 333 -#endif - -#ifdef __powerpc__ -#define __NR_perf_counter_open 319 -#endif - -asmlinkage int sys_perf_counter_open( - - struct perf_counter_hw_event *hw_event_uptr __user, - pid_t pid, - int cpu, - int group_fd, - unsigned long flags) -{ - int ret; - - ret = syscall( - __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); -#if defined(__x86_64__) || defined(__i386__) - if (ret < 0 && ret > -4096) { - errno = -ret; - ret = -1; - } -#endif - return ret; -} diff --git a/Documentation/perf_counter/perfstat.c b/Documentation/perf_counter/perfstat.c deleted file mode 100644 index fd594468e655..000000000000 --- a/Documentation/perf_counter/perfstat.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * perfstat: /usr/bin/time -alike performance counter statistics utility - * - * It summarizes the counter events of all tasks (and child tasks), - * covering all CPUs that the command (or workload) executes on. - * It only counts the per-task events of the workload started, - * independent of how many other tasks run on those CPUs. - * - * Build with: cc -O2 -g -lrt -Wall -W -o perfstat perfstat.c - * - * Sample output: - * - - $ ./perfstat -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null - - Performance counter stats for 'ls': - - 163516953 instructions - 2295 cache-misses - 2855182 branch-misses - - * - * Copyright (C) 2008, Red Hat Inc, Ingo Molnar - * - * Released under the GPLv2 (not later). - * - * Percpu counter support by: Yanmin Zhang - * Symbolic event options by: Wu Fengguang - */ -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "perfcounters.h" - -static int nr_cpus = 0; - -static int system_wide = 0; - -static void display_help(void) -{ - unsigned int i; - int e; - - printf( - "Usage: perfstat [] \n\n" - "PerfStat Options (up to %d event types can be specified):\n\n", - MAX_COUNTERS); - printf( - " -e EVENT --event=EVENT # symbolic-name abbreviations"); - - for (i = 0, e = PERF_HW_EVENTS_MAX; i < ARRAY_SIZE(event_symbols); i++) { - if (e != event_symbols[i].event) { - e = event_symbols[i].event; - printf( - "\n %2d: %-20s", e, event_symbols[i].symbol); - } else - printf(" %s", event_symbols[i].symbol); - } - - printf("\n" - " rNNN: raw event type\n\n" - " -s # system-wide collection\n\n" - " -c --command= # command+arguments to be timed.\n" - "\n"); - exit(0); -} - -static void process_options(int argc, char *argv[]) -{ - for (;;) { - int option_index = 0; - /** Options for getopt */ - static struct option long_options[] = { - {"event", required_argument, NULL, 'e'}, - {"help", no_argument, NULL, 'h'}, - {"command", no_argument, NULL, 'c'}, - {NULL, 0, NULL, 0 } - }; - int c = getopt_long(argc, argv, "+:e:c:s", - long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'c': - break; - case 's': - system_wide = 1; - break; - case 'e': - parse_events(optarg); - break; - default: - break; - } - } - if (optind == argc) - goto err; - - if (!nr_counters) - nr_counters = 8; - return; - -err: - display_help(); -} - -char fault_here[1000000]; - -static int fd[MAX_NR_CPUS][MAX_COUNTERS]; - -static void create_counter(int counter) -{ - struct perf_counter_hw_event hw_event; - - memset(&hw_event, 0, sizeof(hw_event)); - hw_event.type = event_id[counter]; - hw_event.raw = event_raw[counter]; - hw_event.record_type = PERF_RECORD_SIMPLE; - hw_event.nmi = 0; - - if (system_wide) { - int cpu; - for (cpu = 0; cpu < nr_cpus; cpu ++) { - fd[cpu][counter] = sys_perf_counter_open(&hw_event, -1, cpu, -1, 0); - if (fd[cpu][counter] < 0) { - printf("perfstat error: syscall returned with %d (%s)\n", - fd[cpu][counter], strerror(errno)); - exit(-1); - } - - } - } else { - hw_event.inherit = 1; - hw_event.disabled = 1; - - fd[0][counter] = sys_perf_counter_open(&hw_event, 0, -1, -1, 0); - if (fd[0][counter] < 0) { - printf("perfstat error: syscall returned with %d (%s)\n", - fd[0][counter], strerror(errno)); - exit(-1); - } - } -} - - -int main(int argc, char *argv[]) -{ - unsigned long long t0, t1; - int counter; - ssize_t res; - int status; - int pid; - - process_options(argc, argv); - - if (system_wide) { - nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); - assert(nr_cpus <= MAX_NR_CPUS); - assert(nr_cpus >= 0); - } else - nr_cpus = 1; - - for (counter = 0; counter < nr_counters; counter++) - create_counter(counter); - - argc -= optind; - argv += optind; - - /* - * Enable counters and exec the command: - */ - t0 = rdclock(); - prctl(PR_TASK_PERF_COUNTERS_ENABLE); - - if ((pid = fork()) < 0) - perror("failed to fork"); - if (!pid) { - if (execvp(argv[0], argv)) { - perror(argv[0]); - exit(-1); - } - } - while (wait(&status) >= 0) - ; - prctl(PR_TASK_PERF_COUNTERS_DISABLE); - t1 = rdclock(); - - fflush(stdout); - - fprintf(stderr, "\n"); - fprintf(stderr, " Performance counter stats for \'%s\':\n", - argv[0]); - fprintf(stderr, "\n"); - - for (counter = 0; counter < nr_counters; counter++) { - int cpu; - __u64 count, single_count; - - count = 0; - for (cpu = 0; cpu < nr_cpus; cpu ++) { - res = read(fd[cpu][counter], - (char *) &single_count, sizeof(single_count)); - assert(res == sizeof(single_count)); - count += single_count; - } - - if (!event_raw[counter] && - (event_id[counter] == PERF_COUNT_CPU_CLOCK || - event_id[counter] == PERF_COUNT_TASK_CLOCK)) { - - double msecs = (double)count / 1000000; - - fprintf(stderr, " %14.6f %-20s (msecs)\n", - msecs, event_name(counter)); - } else { - fprintf(stderr, " %14Ld %-20s (events)\n", - count, event_name(counter)); - } - if (!counter) - fprintf(stderr, "\n"); - } - fprintf(stderr, "\n"); - fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", - (double)(t1-t0)/1e6); - fprintf(stderr, "\n"); - - return 0; -} -- GitLab From 193e8df1b465f206f8a286202680702e1c153367 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 23 Mar 2009 22:23:16 +0100 Subject: [PATCH 0146/6080] perf_counter tools: fix build warning in kerneltop.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix: kerneltop.c: In function ‘record_ip’: kerneltop.c:1005: warning: format ‘%016llx’ expects type ‘long long unsigned int’, but argument 2 has type ‘uint64_t’ Cc: Wu Fengguang Cc: Paul Mackerras Acked-by: Peter Zijlstra Orig-LKML-Reference: <20090323172417.677932499@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 25e80bc44556..8f9a303f28d8 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -1002,7 +1002,7 @@ static void record_ip(uint64_t ip, int counter) assert(left <= middle && middle <= right); if (!(left <= ip && ip <= right)) { printf(" left: %016lx\n", left); - printf(" ip: %016llx\n", ip); + printf(" ip: %016lx\n", (unsigned long)ip); printf("right: %016lx\n", right); } assert(left <= ip && ip <= right); -- GitLab From 81cdbe0509542324ad7d3282ab67c2b6716df663 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 23 Mar 2009 22:29:50 +0100 Subject: [PATCH 0147/6080] perf_counter tools: increase cpu-cycles again Commit b7368fdd7d decreased the CPU cycles interval 100-fold, but this is causig kerneltop failures on my Nehalem box: aldebaran:/home/mingo/linux/linux/Documentation/perf_counter> ./kerneltop KernelTop refresh period: 2 seconds ERROR: failed to keep up with mmap data 10,000 cycles is way too short. What we should do instead on mostly-idle systems is some sort of read/poll timeout, so that we display something every 2 seconds for sure. Cc: Wu Fengguang Cc: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 8f9a303f28d8..2ab29b5e32e8 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -212,7 +212,7 @@ struct source_line { const unsigned int default_count[] = { - 10000, + 1000000, 1000000, 10000, 10000, -- GitLab From cbe46555dc4de6403cd757139d42289b5f21abb9 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 24 Mar 2009 16:52:34 +1100 Subject: [PATCH 0148/6080] perf_counter tools: remove glib dependency and fix bugs in kerneltop.c The glib dependency in kerneltop.c is only for a little bit of list manipulation, and I find it inconvenient. This adds a 'next' field to struct source_line, which lets us link them together into a list. The code to do the linking ourselves turns out to be no longer or more difficult than using glib. This also fixes a few other problems: - We need to #include to get PATH_MAX on powerpc. - We need to #include rather than have our own definitions of __u64 and __s64; on powerpc the installed headers define them to be unsigned long and long respectively, and if we have our own, different definition here that causes a compile error. - This takes out the x86 setting of errno from -ret in sys_perf_counter_open. My experiments on x86 indicate that the glibc syscall() does this for us already. - We had two CPU migration counters in the default set, which seems unnecessary; I changed one of them to a context switch counter. - In perfstat mode we were printing CPU cycles and instructions as milliseconds, and the cpu clock and task clock counters as events. This fixes that. - In perfstat mode we were still printing a blank line after the first counter, which was a holdover from when a task clock counter was automatically included as the first counter. This removes the blank line. - On a test machine here, parse_symbols() and parse_vmlinux() were taking long enough (almost 0.5 seconds) for the mmap buffer to overflow before we got to the first mmap_read() call, so this moves them before we open all the counters. - The error message if sys_perf_counter_open fails needs to use errno, not -fd[i][counter]. Signed-off-by: Paul Mackerras Acked-by: Peter Zijlstra Acked-by: Mike Galbraith Cc: Arjan van de Ven Orig-LKML-Reference: <18888.29986.340328.540512@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 2 +- Documentation/perf_counter/kerneltop.c | 112 ++++++++++--------------- 2 files changed, 46 insertions(+), 68 deletions(-) diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index 666da95a7877..194b66215588 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -3,7 +3,7 @@ BINS = kerneltop perfstat all: $(BINS) kerneltop: kerneltop.c ../../include/linux/perf_counter.h - cc -O6 -Wall -lrt `pkg-config --cflags --libs glib-2.0` -o $@ $< + cc -O6 -Wall -lrt -o $@ $< perfstat: kerneltop ln -sf kerneltop perfstat diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 2ab29b5e32e8..ea13e4e67229 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -3,7 +3,7 @@ Build with: - cc -O6 -Wall -lrt `pkg-config --cflags --libs glib-2.0` -o kerneltop kerneltop.c + cc -O6 -Wall -c -o kerneltop.o kerneltop.c -lrt Sample output: @@ -56,6 +56,7 @@ * Yanmin Zhang * Wu Fengguang * Mike Galbraith + * Paul Mackerras * * Released under the GPL v2. (and only v2, not any later version) */ @@ -68,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -76,8 +78,6 @@ #include #include -#include - #include #include #include @@ -87,6 +87,7 @@ #include #include +#include #include "../../include/linux/perf_counter.h" @@ -114,11 +115,6 @@ #define __user #define asmlinkage -typedef unsigned int __u32; -typedef unsigned long long __u64; -typedef long long __s64; - - #ifdef __x86_64__ #define __NR_perf_counter_open 295 #define rmb() asm volatile("lfence" ::: "memory") @@ -146,17 +142,8 @@ asmlinkage int sys_perf_counter_open( int group_fd, unsigned long flags) { - int ret; - - ret = syscall( + return syscall( __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); -#if defined(__x86_64__) || defined(__i386__) - if (ret < 0 && ret > -4096) { - errno = -ret; - ret = -1; - } -#endif - return ret; } #define MAX_COUNTERS 64 @@ -170,7 +157,7 @@ static int system_wide = 0; static int nr_counters = 0; static __u64 event_id[MAX_COUNTERS] = { EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), - EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), @@ -202,14 +189,15 @@ static int delay_secs = 2; static int zero; static int dump_symtab; -static GList *lines; - struct source_line { uint64_t EIP; unsigned long count; char *line; + struct source_line *next; }; +static struct source_line *lines; +static struct source_line **lines_tail; const unsigned int default_count[] = { 1000000, @@ -519,9 +507,8 @@ int do_perfstat(int argc, char *argv[]) count += single_count; } - if (!PERF_COUNTER_RAW(event_id[counter]) && - (event_id[counter] == PERF_COUNT_CPU_CLOCK || - event_id[counter] == PERF_COUNT_TASK_CLOCK)) { + if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK) || + event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK)) { double msecs = (double)count / 1000000; @@ -531,8 +518,6 @@ int do_perfstat(int argc, char *argv[]) fprintf(stderr, " %14Ld %-20s (events)\n", count, event_name(counter)); } - if (!counter) - fprintf(stderr, "\n"); } fprintf(stderr, "\n"); fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", @@ -554,7 +539,7 @@ struct sym_entry { char *sym; unsigned long count[MAX_COUNTERS]; int skip; - GList *source; + struct source_line *source; }; #define MAX_SYMS 100000 @@ -855,6 +840,7 @@ static void parse_vmlinux(char *filename) if (!file) return; + lines_tail = &lines; while (!feof(file)) { struct source_line *src; size_t dummy = 0; @@ -873,7 +859,9 @@ static void parse_vmlinux(char *filename) if (c) *c = 0; - lines = g_list_prepend(lines, src); + src->next = NULL; + *lines_tail = src; + lines_tail = &src->next; if (strlen(src->line)>8 && src->line[8] == ':') src->EIP = strtoull(src->line, NULL, 16); @@ -881,52 +869,43 @@ static void parse_vmlinux(char *filename) src->EIP = strtoull(src->line, NULL, 16); } pclose(file); - lines = g_list_reverse(lines); } static void record_precise_ip(uint64_t ip) { struct source_line *line; - GList *item; - item = g_list_first(lines); - while (item) { - line = item->data; + for (line = lines; line; line = line->next) { if (line->EIP == ip) line->count++; if (line->EIP > ip) break; - item = g_list_next(item); } } static void lookup_sym_in_vmlinux(struct sym_entry *sym) { struct source_line *line; - GList *item; char pattern[PATH_MAX]; sprintf(pattern, "<%s>:", sym->sym); - item = g_list_first(lines); - while (item) { - line = item->data; + for (line = lines; line; line = line->next) { if (strstr(line->line, pattern)) { - sym->source = item; + sym->source = line; break; } - item = g_list_next(item); } } -void show_lines(GList *item_queue, int item_queue_count) +static void show_lines(struct source_line *line_queue, int line_queue_count) { int i; struct source_line *line; - for (i = 0; i < item_queue_count; i++) { - line = item_queue->data; + line = line_queue; + for (i = 0; i < line_queue_count; i++) { printf("%8li\t%s\n", line->count, line->line); - item_queue = g_list_next(item_queue); + line = line->next; } } @@ -935,10 +914,9 @@ void show_lines(GList *item_queue, int item_queue_count) static void show_details(struct sym_entry *sym) { struct source_line *line; - GList *item; + struct source_line *line_queue = NULL; int displayed = 0; - GList *item_queue = NULL; - int item_queue_count = 0; + int line_queue_count = 0; if (!sym->source) lookup_sym_in_vmlinux(sym); @@ -947,30 +925,29 @@ static void show_details(struct sym_entry *sym) printf("Showing details for %s\n", sym->sym); - item = sym->source; - while (item) { - line = item->data; + line = sym->source; + while (line) { if (displayed && strstr(line->line, ">:")) break; - if (!item_queue_count) - item_queue = item; - item_queue_count ++; + if (!line_queue_count) + line_queue = line; + line_queue_count ++; if (line->count >= count_filter) { - show_lines(item_queue, item_queue_count); - item_queue_count = 0; - item_queue = NULL; - } else if (item_queue_count > TRACE_COUNT) { - item_queue = g_list_next(item_queue); - item_queue_count --; + show_lines(line_queue, line_queue_count); + line_queue_count = 0; + line_queue = NULL; + } else if (line_queue_count > TRACE_COUNT) { + line_queue = line_queue->next; + line_queue_count --; } line->count = 0; displayed++; if (displayed > 300) break; - item = g_list_next(item); + line = line->next; } } @@ -1201,6 +1178,10 @@ int main(int argc, char *argv[]) if (tid != -1 || profile_cpu != -1) nr_cpus = 1; + parse_symbols(); + if (vmlinux && sym_filter_entry) + parse_vmlinux(vmlinux); + for (i = 0; i < nr_cpus; i++) { group_fd = -1; for (counter = 0; counter < nr_counters; counter++) { @@ -1216,15 +1197,16 @@ int main(int argc, char *argv[]) hw_event.nmi = nmi; fd[i][counter] = sys_perf_counter_open(&hw_event, tid, cpu, group_fd, 0); - fcntl(fd[i][counter], F_SETFL, O_NONBLOCK); if (fd[i][counter] < 0) { + int err = errno; printf("kerneltop error: syscall returned with %d (%s)\n", - fd[i][counter], strerror(-fd[i][counter])); - if (fd[i][counter] == -1) + fd[i][counter], strerror(err)); + if (err == EPERM) printf("Are you root?\n"); exit(-1); } assert(fd[i][counter] >= 0); + fcntl(fd[i][counter], F_SETFL, O_NONBLOCK); /* * First counter acts as the group leader: @@ -1248,10 +1230,6 @@ int main(int argc, char *argv[]) } } - parse_symbols(); - if (vmlinux && sym_filter_entry) - parse_vmlinux(vmlinux); - printf("KernelTop refresh period: %d seconds\n", delay_secs); last_refresh = time(NULL); -- GitLab From 0fd112e41cd6f6d4779cbe327c3632d087e31476 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 24 Mar 2009 10:50:24 +0100 Subject: [PATCH 0149/6080] perf_counter tools: remove glib dependency and fix bugs in kerneltop.c, fix poll() Paul Mackerras wrote: > I noticed the poll stuff is bogus - we have a 2D array of struct > pollfds (MAX_NR_CPUS x MAX_COUNTERS), we fill in a sub-array (with the > rest being uninitialized, since the array is on the stack) and then > pass the first nr_cpus elements to poll. Not what we really meant, I > suspect. :) Not even if we only have one counter, since it's the > counter dimension that varies fastest. This should fix the most obvious poll fubar.. not enough to fix the full problem though.. Reported-by: Paul Mackerras Reported-by: Mike Galbraith Signed-off-by: Peter Zijlstra Cc: Arjan van de Ven Orig-LKML-Reference: <18888.29986.340328.540512@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index ea13e4e67229..7ebde7a336c6 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -1157,10 +1157,10 @@ static void mmap_read(struct mmap_data *md) int main(int argc, char *argv[]) { - struct pollfd event_array[MAX_NR_CPUS][MAX_COUNTERS]; + struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; struct perf_counter_hw_event hw_event; - int i, counter, group_fd; + int i, counter, group_fd, nr_poll = 0; unsigned int cpu; int ret; @@ -1214,8 +1214,9 @@ int main(int argc, char *argv[]) if (group && group_fd == -1) group_fd = fd[i][counter]; - event_array[i][counter].fd = fd[i][counter]; - event_array[i][counter].events = POLLIN; + event_array[nr_poll].fd = fd[i][counter]; + event_array[nr_poll].events = POLLIN; + nr_poll++; mmap_array[i][counter].counter = counter; mmap_array[i][counter].prev = 0; @@ -1247,7 +1248,7 @@ int main(int argc, char *argv[]) } if (hits == events) - ret = poll(event_array[0], nr_cpus, 1000); + ret = poll(event_array, nr_poll, 1000); hits = events; } -- GitLab From f66c6b2066b44d4ab8e8ac1ee4cae543738fe2ac Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 23 Mar 2009 10:29:36 +1100 Subject: [PATCH 0150/6080] perf_counter: update documentation Impact: documentation fix This updates the perfcounter documentation to reflect recent changes. Signed-off-by: Paul Mackerras --- Documentation/perf_counter/design.txt | 268 +++++++++++++++++++------- 1 file changed, 202 insertions(+), 66 deletions(-) diff --git a/Documentation/perf_counter/design.txt b/Documentation/perf_counter/design.txt index fddd32189a50..aaf105c02fba 100644 --- a/Documentation/perf_counter/design.txt +++ b/Documentation/perf_counter/design.txt @@ -11,7 +11,9 @@ thus be used to profile the code that runs on that CPU. The Linux Performance Counter subsystem provides an abstraction of these hardware capabilities. It provides per task and per CPU counters, counter -groups, and it provides event capabilities on top of those. +groups, and it provides event capabilities on top of those. It +provides "virtual" 64-bit counters, regardless of the width of the +underlying hardware counters. Performance counters are accessed via special file descriptors. There's one file descriptor per virtual counter used. @@ -20,7 +22,8 @@ The special file descriptor is opened via the perf_counter_open() system call: int sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr, - pid_t pid, int cpu, int group_fd); + pid_t pid, int cpu, int group_fd, + unsigned long flags); The syscall returns the new fd. The fd can be used via the normal VFS system calls: read() can be used to read the counter, fcntl() @@ -32,90 +35,180 @@ can be poll()ed. When creating a new counter fd, 'perf_counter_hw_event' is: /* - * Hardware event to monitor via a performance monitoring counter: + * Event to monitor via a performance monitoring counter: */ struct perf_counter_hw_event { - s64 type; + __u64 event_config; - u64 irq_period; - u32 record_type; + __u64 irq_period; + __u64 record_type; + __u64 read_format; - u32 disabled : 1, /* off by default */ - nmi : 1, /* NMI sampling */ - raw : 1, /* raw event type */ - __reserved_1 : 29; + __u64 disabled : 1, /* off by default */ + nmi : 1, /* NMI sampling */ + inherit : 1, /* children inherit it */ + pinned : 1, /* must always be on PMU */ + exclusive : 1, /* only group on PMU */ + exclude_user : 1, /* don't count user */ + exclude_kernel : 1, /* ditto kernel */ + exclude_hv : 1, /* ditto hypervisor */ + exclude_idle : 1, /* don't count when idle */ - u64 __reserved_2; + __reserved_1 : 55; + + __u32 extra_config_len; + + __u32 __reserved_4; + __u64 __reserved_2; + __u64 __reserved_3; }; +The 'event_config' field specifies what the counter should count. It +is divided into 3 bit-fields: + +raw_type: 1 bit (most significant bit) 0x8000_0000_0000_0000 +type: 7 bits (next most significant) 0x7f00_0000_0000_0000 +event_id: 56 bits (least significant) 0x00ff_0000_0000_0000 + +If 'raw_type' is 1, then the counter will count a hardware event +specified by the remaining 63 bits of event_config. The encoding is +machine-specific. + +If 'raw_type' is 0, then the 'type' field says what kind of counter +this is, with the following encoding: + +enum perf_event_types { + PERF_TYPE_HARDWARE = 0, + PERF_TYPE_SOFTWARE = 1, + PERF_TYPE_TRACEPOINT = 2, +}; + +A counter of PERF_TYPE_HARDWARE will count the hardware event +specified by 'event_id': + /* - * Generalized performance counter event types, used by the hw_event.type + * Generalized performance counter event types, used by the hw_event.event_id * parameter of the sys_perf_counter_open() syscall: */ -enum hw_event_types { +enum hw_event_ids { /* * Common hardware events, generalized by the kernel: */ - PERF_COUNT_CYCLES = 0, - PERF_COUNT_INSTRUCTIONS = 1, - PERF_COUNT_CACHE_REFERENCES = 2, - PERF_COUNT_CACHE_MISSES = 3, - PERF_COUNT_BRANCH_INSTRUCTIONS = 4, - PERF_COUNT_BRANCH_MISSES = 5, - - /* - * Special "software" counters provided by the kernel, even if - * the hardware does not support performance counters. These - * counters measure various physical and sw events of the - * kernel (and allow the profiling of them as well): - */ - PERF_COUNT_CPU_CLOCK = -1, - PERF_COUNT_TASK_CLOCK = -2, - /* - * Future software events: - */ - /* PERF_COUNT_PAGE_FAULTS = -3, - PERF_COUNT_CONTEXT_SWITCHES = -4, */ + PERF_COUNT_CPU_CYCLES = 0, + PERF_COUNT_INSTRUCTIONS = 1, + PERF_COUNT_CACHE_REFERENCES = 2, + PERF_COUNT_CACHE_MISSES = 3, + PERF_COUNT_BRANCH_INSTRUCTIONS = 4, + PERF_COUNT_BRANCH_MISSES = 5, + PERF_COUNT_BUS_CYCLES = 6, }; -These are standardized types of events that work uniformly on all CPUs -that implements Performance Counters support under Linux. If a CPU is -not able to count branch-misses, then the system call will return --EINVAL. +These are standardized types of events that work relatively uniformly +on all CPUs that implement Performance Counters support under Linux, +although there may be variations (e.g., different CPUs might count +cache references and misses at different levels of the cache hierarchy). +If a CPU is not able to count the selected event, then the system call +will return -EINVAL. -More hw_event_types are supported as well, but they are CPU -specific and are enumerated via /sys on a per CPU basis. Raw hw event -types can be passed in under hw_event.type if hw_event.raw is 1. -For example, to count "External bus cycles while bus lock signal asserted" -events on Intel Core CPUs, pass in a 0x4064 event type value and set -hw_event.raw to 1. +More hw_event_types are supported as well, but they are CPU-specific +and accessed as raw events. For example, to count "External bus +cycles while bus lock signal asserted" events on Intel Core CPUs, pass +in a 0x4064 event_id value and set hw_event.raw_type to 1. -'record_type' is the type of data that a read() will provide for the -counter, and it can be one of: +A counter of type PERF_TYPE_SOFTWARE will count one of the available +software events, selected by 'event_id': /* - * IRQ-notification data record type: + * Special "software" counters provided by the kernel, even if the hardware + * does not support performance counters. These counters measure various + * physical and sw events of the kernel (and allow the profiling of them as + * well): */ -enum perf_counter_record_type { - PERF_RECORD_SIMPLE = 0, - PERF_RECORD_IRQ = 1, - PERF_RECORD_GROUP = 2, +enum sw_event_ids { + PERF_COUNT_CPU_CLOCK = 0, + PERF_COUNT_TASK_CLOCK = 1, + PERF_COUNT_PAGE_FAULTS = 2, + PERF_COUNT_CONTEXT_SWITCHES = 3, + PERF_COUNT_CPU_MIGRATIONS = 4, + PERF_COUNT_PAGE_FAULTS_MIN = 5, + PERF_COUNT_PAGE_FAULTS_MAJ = 6, }; -a "simple" counter is one that counts hardware events and allows -them to be read out into a u64 count value. (read() returns 8 on -a successful read of a simple counter.) +Counters come in two flavours: counting counters and sampling +counters. A "counting" counter is one that is used for counting the +number of events that occur, and is characterised by having +irq_period = 0 and record_type = PERF_RECORD_SIMPLE. A read() on a +counting counter simply returns the current value of the counter as +an 8-byte number. -An "irq" counter is one that will also provide an IRQ context information: -the IP of the interrupted context. In this case read() will return -the 8-byte counter value, plus the Instruction Pointer address of the -interrupted context. +A "sampling" counter is one that is set up to generate an interrupt +every N events, where N is given by 'irq_period'. A sampling counter +has irq_period > 0 and record_type != PERF_RECORD_SIMPLE. The +record_type controls what data is recorded on each interrupt, and the +available values are currently: -The parameter 'hw_event_period' is the number of events before waking up -a read() that is blocked on a counter fd. Zero value means a non-blocking -counter. +/* + * IRQ-notification data record type: + */ +enum perf_counter_record_type { + PERF_RECORD_SIMPLE = 0, + PERF_RECORD_IRQ = 1, + PERF_RECORD_GROUP = 2, +}; -The 'pid' parameter allows the counter to be specific to a task: +A record_type value of PERF_RECORD_IRQ will record the instruction +pointer (IP) at which the interrupt occurred. A record_type value of +PERF_RECORD_GROUP will record the event_config and counter value of +all of the other counters in the group, and should only be used on a +group leader (see below). Currently these two values are mutually +exclusive, but record_type will become a bit-mask in future and +support other values. + +A sampling counter has an event queue, into which an event is placed +on each interrupt. A read() on a sampling counter will read the next +event from the event queue. If the queue is empty, the read() will +either block or return an EAGAIN error, depending on whether the fd +has been set to non-blocking mode or not. + +The 'disabled' bit specifies whether the counter starts out disabled +or enabled. If it is initially disabled, it can be enabled by ioctl +or prctl (see below). + +The 'nmi' bit specifies, for hardware events, whether the counter +should be set up to request non-maskable interrupts (NMIs) or normal +interrupts. This bit is ignored if the user doesn't have +CAP_SYS_ADMIN privilege (i.e. is not root) or if the CPU doesn't +generate NMIs from hardware counters. + +The 'inherit' bit, if set, specifies that this counter should count +events on descendant tasks as well as the task specified. This only +applies to new descendents, not to any existing descendents at the +time the counter is created (nor to any new descendents of existing +descendents). + +The 'pinned' bit, if set, specifies that the counter should always be +on the CPU if at all possible. It only applies to hardware counters +and only to group leaders. If a pinned counter cannot be put onto the +CPU (e.g. because there are not enough hardware counters or because of +a conflict with some other event), then the counter goes into an +'error' state, where reads return end-of-file (i.e. read() returns 0) +until the counter is subsequently enabled or disabled. + +The 'exclusive' bit, if set, specifies that when this counter's group +is on the CPU, it should be the only group using the CPU's counters. +In future, this will allow sophisticated monitoring programs to supply +extra configuration information via 'extra_config_len' to exploit +advanced features of the CPU's Performance Monitor Unit (PMU) that are +not otherwise accessible and that might disrupt other hardware +counters. + +The 'exclude_user', 'exclude_kernel' and 'exclude_hv' bits provide a +way to request that counting of events be restricted to times when the +CPU is in user, kernel and/or hypervisor mode. + + +The 'pid' parameter to the perf_counter_open() system call allows the +counter to be specific to a task: pid == 0: if the pid parameter is zero, the counter is attached to the current task. @@ -125,8 +218,7 @@ The 'pid' parameter allows the counter to be specific to a task: pid < 0: all tasks are counted (per cpu counters) -The 'cpu' parameter allows a counter to be made specific to a full -CPU: +The 'cpu' parameter allows a counter to be made specific to a CPU: cpu >= 0: the counter is restricted to a specific CPU cpu == -1: the counter counts on all CPUs @@ -141,7 +233,51 @@ their own tasks. A 'pid == -1' and 'cpu == x' counter is a per CPU counter that counts all events on CPU-x. Per CPU counters need CAP_SYS_ADMIN privilege. -Group counters are created by passing in a group_fd of another counter. -Groups are scheduled at once and can be used with PERF_RECORD_GROUP -to record multi-dimensional timestamps. +The 'flags' parameter is currently unused and must be zero. + +The 'group_fd' parameter allows counter "groups" to be set up. A +counter group has one counter which is the group "leader". The leader +is created first, with group_fd = -1 in the perf_counter_open call +that creates it. The rest of the group members are created +subsequently, with group_fd giving the fd of the group leader. +(A single counter on its own is created with group_fd = -1 and is +considered to be a group with only 1 member.) + +A counter group is scheduled onto the CPU as a unit, that is, it will +only be put onto the CPU if all of the counters in the group can be +put onto the CPU. This means that the values of the member counters +can be meaningfully compared, added, divided (to get ratios), etc., +with each other, since they have counted events for the same set of +executed instructions. + +Counters can be enabled and disabled in two ways: via ioctl and via +prctl. When a counter is disabled, it doesn't count or generate +events but does continue to exist and maintain its count value. + +An individual counter or counter group can be enabled with + + ioctl(fd, PERF_COUNTER_IOC_ENABLE); + +or disabled with + + ioctl(fd, PERF_COUNTER_IOC_DISABLE); + +Enabling or disabling the leader of a group enables or disables the +whole group; that is, while the group leader is disabled, none of the +counters in the group will count. Enabling or disabling a member of a +group other than the leader only affects that counter - disabling an +non-leader stops that counter from counting but doesn't affect any +other counter. + +A process can enable or disable all the counter groups that are +attached to it, using prctl: + + prctl(PR_TASK_PERF_COUNTERS_ENABLE); + + prctl(PR_TASK_PERF_COUNTERS_DISABLE); + +This applies to all counters on the current process, whether created +by this process or by another, and doesn't affect any counters that +this process has created on other processes. It only enables or +disables the group leaders, not any other members in the groups. -- GitLab From c7138f37f905bb7987b1f9f5a8ee73667db39f25 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 24 Mar 2009 13:18:16 +0100 Subject: [PATCH 0151/6080] perf_counter: fix perf_poll() Impact: fix kerneltop 100% CPU usage Only return a poll event when there's actually been one, poll_wait() doesn't actually wait for the waitq you pass it, it only enqueues you on it. Only once all FDs have been iterated and none of thm returned a poll-event will it schedule(). Also make it return POLL_HUP when there's not mmap() area to read from. Further, fix a silly bug in the write code. Reported-by: Mike Galbraith Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Arjan van de Ven Orig-LKML-Reference: <1237897096.24918.181.camel@twins> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 1 + kernel/perf_counter.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 2b5e66d5ebdf..48212c15b7d6 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -246,6 +246,7 @@ struct file; struct perf_mmap_data { struct rcu_head rcu_head; int nr_pages; + atomic_t wakeup; atomic_t head; struct perf_counter_mmap_page *user_page; void *data_pages[0]; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0dfe91094fd1..affe227d56a0 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1161,7 +1161,16 @@ perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) static unsigned int perf_poll(struct file *file, poll_table *wait) { struct perf_counter *counter = file->private_data; - unsigned int events = POLLIN; + struct perf_mmap_data *data; + unsigned int events; + + rcu_read_lock(); + data = rcu_dereference(counter->data); + if (data) + events = atomic_xchg(&data->wakeup, 0); + else + events = POLL_HUP; + rcu_read_unlock(); poll_wait(file, &counter->waitq, wait); @@ -1425,7 +1434,7 @@ static int perf_output_write(struct perf_counter *counter, int nmi, do { offset = head = atomic_read(&data->head); - head += sizeof(u64); + head += size; } while (atomic_cmpxchg(&data->head, offset, head) != offset); wakeup = (offset >> PAGE_SHIFT) != (head >> PAGE_SHIFT); @@ -1446,6 +1455,7 @@ static int perf_output_write(struct perf_counter *counter, int nmi, * generate a poll() wakeup for every page boundary crossed */ if (wakeup) { + atomic_xchg(&data->wakeup, POLL_IN); __perf_counter_update_userpage(counter, data); if (nmi) { counter->wakeup_pending = 1; -- GitLab From b9cacc7bf193df16532bfa7d7ca77fe50fc3c2e6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 25 Mar 2009 12:30:22 +0100 Subject: [PATCH 0152/6080] perf_counter: more elaborate write API Provide a begin, copy, end interface to the output buffer. begin() reserves the space, copy() copies the data over, considering page boundaries, end() finalizes the event and does the wakeup. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Mike Galbraith Cc: Arjan van de Ven Cc: Wu Fengguang Orig-LKML-Reference: <20090325113316.740550870@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 109 +++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 34 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index affe227d56a0..0422fd9bf627 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -16,15 +17,14 @@ #include #include #include +#include +#include +#include #include #include #include #include #include -#include -#include -#include -#include #include @@ -1411,16 +1411,20 @@ static const struct file_operations perf_fops = { * Output */ -static int perf_output_write(struct perf_counter *counter, int nmi, - void *buf, ssize_t size) +struct perf_output_handle { + struct perf_counter *counter; + struct perf_mmap_data *data; + unsigned int offset; + int wakeup; +}; + +static int perf_output_begin(struct perf_output_handle *handle, + struct perf_counter *counter, unsigned int size) { struct perf_mmap_data *data; - unsigned int offset, head, nr; - unsigned int len; - int ret, wakeup; + unsigned int offset, head; rcu_read_lock(); - ret = -ENOSPC; data = rcu_dereference(counter->data); if (!data) goto out; @@ -1428,45 +1432,82 @@ static int perf_output_write(struct perf_counter *counter, int nmi, if (!data->nr_pages) goto out; - ret = -EINVAL; - if (size > PAGE_SIZE) - goto out; - do { offset = head = atomic_read(&data->head); head += size; } while (atomic_cmpxchg(&data->head, offset, head) != offset); - wakeup = (offset >> PAGE_SHIFT) != (head >> PAGE_SHIFT); + handle->counter = counter; + handle->data = data; + handle->offset = offset; + handle->wakeup = (offset >> PAGE_SHIFT) != (head >> PAGE_SHIFT); - nr = (offset >> PAGE_SHIFT) & (data->nr_pages - 1); - offset &= PAGE_SIZE - 1; + return 0; - len = min_t(unsigned int, PAGE_SIZE - offset, size); - memcpy(data->data_pages[nr] + offset, buf, len); - size -= len; +out: + rcu_read_unlock(); - if (size) { - nr = (nr + 1) & (data->nr_pages - 1); - memcpy(data->data_pages[nr], buf + len, size); - } + return -ENOSPC; +} - /* - * generate a poll() wakeup for every page boundary crossed - */ - if (wakeup) { - atomic_xchg(&data->wakeup, POLL_IN); - __perf_counter_update_userpage(counter, data); +static void perf_output_copy(struct perf_output_handle *handle, + void *buf, unsigned int len) +{ + unsigned int pages_mask; + unsigned int offset; + unsigned int size; + void **pages; + + offset = handle->offset; + pages_mask = handle->data->nr_pages - 1; + pages = handle->data->data_pages; + + do { + unsigned int page_offset; + int nr; + + nr = (offset >> PAGE_SHIFT) & pages_mask; + page_offset = offset & (PAGE_SIZE - 1); + size = min_t(unsigned int, PAGE_SIZE - page_offset, len); + + memcpy(pages[nr] + page_offset, buf, size); + + len -= size; + buf += size; + offset += size; + } while (len); + + handle->offset = offset; +} + +static void perf_output_end(struct perf_output_handle *handle, int nmi) +{ + if (handle->wakeup) { + (void)atomic_xchg(&handle->data->wakeup, POLL_IN); + __perf_counter_update_userpage(handle->counter, handle->data); if (nmi) { - counter->wakeup_pending = 1; + handle->counter->wakeup_pending = 1; set_perf_counter_pending(); } else - wake_up(&counter->waitq); + wake_up(&handle->counter->waitq); } - ret = 0; -out: rcu_read_unlock(); +} + +static int perf_output_write(struct perf_counter *counter, int nmi, + void *buf, ssize_t size) +{ + struct perf_output_handle handle; + int ret; + ret = perf_output_begin(&handle, counter, size); + if (ret) + goto out; + + perf_output_copy(&handle, buf, size); + perf_output_end(&handle, nmi); + +out: return ret; } -- GitLab From 5c1481943250ab65fa5130e05ec479c93216e9f7 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 25 Mar 2009 12:30:23 +0100 Subject: [PATCH 0153/6080] perf_counter: output objects Provide a {type,size} header for each output entry. This should provide extensible output, and the ability to mix multiple streams. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Mike Galbraith Cc: Arjan van de Ven Cc: Wu Fengguang Orig-LKML-Reference: <20090325113316.831607932@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 11 ++++++++ kernel/perf_counter.c | 53 ++++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 48212c15b7d6..c256635377d4 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -156,6 +156,16 @@ struct perf_counter_mmap_page { __u32 data_head; /* head in the data section */ }; +struct perf_event_header { + __u32 type; + __u32 size; +}; + +enum perf_event_type { + PERF_EVENT_IP = 0, + PERF_EVENT_GROUP = 1, +}; + #ifdef __KERNEL__ /* * Kernel-internal data types and definitions: @@ -260,6 +270,7 @@ struct perf_counter { struct list_head list_entry; struct list_head event_entry; struct list_head sibling_list; + int nr_siblings; struct perf_counter *group_leader; const struct hw_perf_counter_ops *hw_ops; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0422fd9bf627..d76e3112d386 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -75,8 +75,10 @@ list_add_counter(struct perf_counter *counter, struct perf_counter_context *ctx) */ if (counter->group_leader == counter) list_add_tail(&counter->list_entry, &ctx->counter_list); - else + else { list_add_tail(&counter->list_entry, &group_leader->sibling_list); + group_leader->nr_siblings++; + } list_add_rcu(&counter->event_entry, &ctx->event_list); } @@ -89,6 +91,9 @@ list_del_counter(struct perf_counter *counter, struct perf_counter_context *ctx) list_del_init(&counter->list_entry); list_del_rcu(&counter->event_entry); + if (counter->group_leader != counter) + counter->group_leader->nr_siblings--; + /* * If this was a group counter with sibling counters then * upgrade the siblings to singleton counters by adding them @@ -381,9 +386,11 @@ static int is_software_only_group(struct perf_counter *leader) if (!is_software_counter(leader)) return 0; + list_for_each_entry(counter, &leader->sibling_list, list_entry) if (!is_software_counter(counter)) return 0; + return 1; } @@ -1480,6 +1487,9 @@ static void perf_output_copy(struct perf_output_handle *handle, handle->offset = offset; } +#define perf_output_put(handle, x) \ + perf_output_copy((handle), &(x), sizeof(x)) + static void perf_output_end(struct perf_output_handle *handle, int nmi) { if (handle->wakeup) { @@ -1514,34 +1524,53 @@ out: static void perf_output_simple(struct perf_counter *counter, int nmi, struct pt_regs *regs) { - u64 entry; + struct { + struct perf_event_header header; + u64 ip; + } event; - entry = instruction_pointer(regs); + event.header.type = PERF_EVENT_IP; + event.header.size = sizeof(event); + event.ip = instruction_pointer(regs); - perf_output_write(counter, nmi, &entry, sizeof(entry)); + perf_output_write(counter, nmi, &event, sizeof(event)); } -struct group_entry { - u64 event; - u64 counter; -}; - static void perf_output_group(struct perf_counter *counter, int nmi) { + struct perf_output_handle handle; + struct perf_event_header header; struct perf_counter *leader, *sub; + unsigned int size; + struct { + u64 event; + u64 counter; + } entry; + int ret; + + size = sizeof(header) + counter->nr_siblings * sizeof(entry); + + ret = perf_output_begin(&handle, counter, size); + if (ret) + return; + + header.type = PERF_EVENT_GROUP; + header.size = size; + + perf_output_put(&handle, header); leader = counter->group_leader; list_for_each_entry(sub, &leader->sibling_list, list_entry) { - struct group_entry entry; - if (sub != counter) sub->hw_ops->read(sub); entry.event = sub->hw_event.config; entry.counter = atomic64_read(&sub->count); - perf_output_write(counter, nmi, &entry, sizeof(entry)); + perf_output_put(&handle, entry); } + + perf_output_end(&handle, nmi); } void perf_counter_output(struct perf_counter *counter, -- GitLab From 63e35b25d6b5c3136d22ef249dbbf96716aa08bf Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 25 Mar 2009 12:30:24 +0100 Subject: [PATCH 0154/6080] perf_counter: sanity check on the output API Ensure we never write more than we said we would. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Mike Galbraith Cc: Arjan van de Ven Cc: Wu Fengguang Orig-LKML-Reference: <20090325113316.921433024@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index d76e3112d386..7669afe82cc7 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1422,6 +1422,7 @@ struct perf_output_handle { struct perf_counter *counter; struct perf_mmap_data *data; unsigned int offset; + unsigned int head; int wakeup; }; @@ -1447,6 +1448,7 @@ static int perf_output_begin(struct perf_output_handle *handle, handle->counter = counter; handle->data = data; handle->offset = offset; + handle->head = head; handle->wakeup = (offset >> PAGE_SHIFT) != (head >> PAGE_SHIFT); return 0; @@ -1485,6 +1487,8 @@ static void perf_output_copy(struct perf_output_handle *handle, } while (len); handle->offset = offset; + + WARN_ON_ONCE(handle->offset > handle->head); } #define perf_output_put(handle, x) \ -- GitLab From ea5d20cf99db5d26d43b6d322d3ace17e08a6552 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 25 Mar 2009 12:30:25 +0100 Subject: [PATCH 0155/6080] perf_counter: optionally provide the pid/tid of the sampled task Allow cpu wide counters to profile userspace by providing what process the sample belongs to. This raises the first issue with the output type, lots of these options: group, tid, callchain, etc.. are non-exclusive and could be combined, suggesting a bitfield. However, things like the mmap() data stream doesn't fit in that. How to split the type field... Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Mike Galbraith Cc: Arjan van de Ven Cc: Wu Fengguang Orig-LKML-Reference: <20090325113317.013775235@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 5 ++++- kernel/perf_counter.c | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index c256635377d4..7fdbdf8be775 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -127,8 +127,9 @@ struct perf_counter_hw_event { exclude_kernel : 1, /* ditto kernel */ exclude_hv : 1, /* ditto hypervisor */ exclude_idle : 1, /* don't count when idle */ + include_tid : 1, /* include the tid */ - __reserved_1 : 55; + __reserved_1 : 54; __u32 extra_config_len; __u32 __reserved_4; @@ -164,6 +165,8 @@ struct perf_event_header { enum perf_event_type { PERF_EVENT_IP = 0, PERF_EVENT_GROUP = 1, + + __PERF_EVENT_TID = 0x100, }; #ifdef __KERNEL__ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 7669afe82cc7..f3e1b27bc1b8 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1528,16 +1528,30 @@ out: static void perf_output_simple(struct perf_counter *counter, int nmi, struct pt_regs *regs) { + unsigned int size; struct { struct perf_event_header header; u64 ip; + u32 pid, tid; } event; event.header.type = PERF_EVENT_IP; - event.header.size = sizeof(event); event.ip = instruction_pointer(regs); - perf_output_write(counter, nmi, &event, sizeof(event)); + size = sizeof(event); + + if (counter->hw_event.include_tid) { + /* namespace issues */ + event.pid = current->group_leader->pid; + event.tid = current->pid; + + event.header.type |= __PERF_EVENT_TID; + } else + size -= sizeof(u64); + + event.header.size = size; + + perf_output_write(counter, nmi, &event, size); } static void perf_output_group(struct perf_counter *counter, int nmi) -- GitLab From 4c4ba21d2c3659e4c0421533939b58a8fd9f06c9 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 25 Mar 2009 12:30:26 +0100 Subject: [PATCH 0156/6080] perf_counter: kerneltop: mmap_pages argument provide a knob to set the number of mmap data pages. Signed-off-by: Mike Galbraith Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Mike Galbraith Cc: Arjan van de Ven Cc: Wu Fengguang Orig-LKML-Reference: <20090325113317.104545398@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 31 +++++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 7ebde7a336c6..3e45bf6591b2 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -178,6 +178,7 @@ static int nr_cpus = 0; static int nmi = 1; static int group = 0; static unsigned int page_size; +static unsigned int mmap_pages = 4; static char *vmlinux; @@ -326,6 +327,7 @@ static void display_help(void) " -x path --vmlinux= # the vmlinux binary, required for -s use\n" " -z --zero # zero counts after display\n" " -D --dump_symtab # dump symbol table to stderr on startup\n" + " -m pages --mmap_pages= # number of mmap data pages\n" ); exit(0); @@ -732,7 +734,9 @@ static int read_symbol(FILE *in, struct sym_entry *s) /* Tag events to be skipped. */ if (!strcmp("default_idle", s->sym) || !strcmp("cpu_idle", s->sym)) s->skip = 1; - if (!strcmp("enter_idle", s->sym) || !strcmp("exit_idle", s->sym)) + else if (!strcmp("enter_idle", s->sym) || !strcmp("exit_idle", s->sym)) + s->skip = 1; + else if (!strcmp("mwait_idle", s->sym)) s->skip = 1; if (filter_match == 1) { @@ -1042,9 +1046,10 @@ static void process_options(int argc, char *argv[]) {"symbol", required_argument, NULL, 's'}, {"stat", no_argument, NULL, 'S'}, {"zero", no_argument, NULL, 'z'}, + {"mmap_pages", required_argument, NULL, 'm'}, {NULL, 0, NULL, 0 } }; - int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hn:p:s:Sx:z", + int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hn:m:p:s:Sx:z", long_options, &option_index); if (c == -1) break; @@ -1081,6 +1086,7 @@ static void process_options(int argc, char *argv[]) case 'S': run_perfstat = 1; break; case 'x': vmlinux = strdup(optarg); break; case 'z': zero = 1; break; + case 'm': mmap_pages = atoi(optarg); break; default: error = 1; break; } } @@ -1134,17 +1140,30 @@ repeat: return head; } +struct timeval last_read, this_read; + static void mmap_read(struct mmap_data *md) { unsigned int head = mmap_read_head(md); unsigned int old = md->prev; unsigned char *data = md->base + page_size; + gettimeofday(&this_read, NULL); + if (head - old > md->mask) { - printf("ERROR: failed to keep up with mmap data\n"); - exit(-1); + struct timeval iv; + unsigned long msecs; + + timersub(&this_read, &last_read, &iv); + msecs = iv.tv_sec*1000 + iv.tv_usec/1000; + + fprintf(stderr, "WARNING: failed to keep up with mmap data. Last read %lu msecs ago.\n", msecs); + + old = head; } + last_read = this_read; + for (; old != head;) { __u64 *ptr = (__u64 *)&data[old & md->mask]; old += sizeof(__u64); @@ -1220,8 +1239,8 @@ int main(int argc, char *argv[]) mmap_array[i][counter].counter = counter; mmap_array[i][counter].prev = 0; - mmap_array[i][counter].mask = 2*page_size - 1; - mmap_array[i][counter].base = mmap(NULL, 3*page_size, + mmap_array[i][counter].mask = mmap_pages*page_size - 1; + mmap_array[i][counter].base = mmap(NULL, (mmap_pages+1)*page_size, PROT_READ, MAP_SHARED, fd[i][counter], 0); if (mmap_array[i][counter].base == MAP_FAILED) { printf("kerneltop error: failed to mmap with %d (%s)\n", -- GitLab From 00f0ad73ac90e3fba8b4cbe4cf21b2fb9a56cb72 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 25 Mar 2009 12:30:27 +0100 Subject: [PATCH 0157/6080] perf_counter: kerneltop: output event support Teach kerneltop about the new output ABI. XXX: anybody fancy integrating the PID/TID data into the output? Bump the mmap_data pages a little because we bloated the output and have to be more careful about overruns with structured data. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Mike Galbraith Cc: Arjan van de Ven Cc: Wu Fengguang Orig-LKML-Reference: <20090325113317.192910290@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 65 +++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 3e45bf6591b2..fda1438365dc 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -134,6 +134,11 @@ #endif #define unlikely(x) __builtin_expect(!!(x), 0) +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) asmlinkage int sys_perf_counter_open( struct perf_counter_hw_event *hw_event_uptr __user, @@ -178,7 +183,7 @@ static int nr_cpus = 0; static int nmi = 1; static int group = 0; static unsigned int page_size; -static unsigned int mmap_pages = 4; +static unsigned int mmap_pages = 16; static char *vmlinux; @@ -1147,28 +1152,75 @@ static void mmap_read(struct mmap_data *md) unsigned int head = mmap_read_head(md); unsigned int old = md->prev; unsigned char *data = md->base + page_size; + int diff; gettimeofday(&this_read, NULL); - if (head - old > md->mask) { + /* + * If we're further behind than half the buffer, there's a chance + * the writer will bite our tail and screw up the events under us. + * + * If we somehow ended up ahead of the head, we got messed up. + * + * In either case, truncate and restart at head. + */ + diff = head - old; + if (diff > md->mask / 2 || diff < 0) { struct timeval iv; unsigned long msecs; timersub(&this_read, &last_read, &iv); msecs = iv.tv_sec*1000 + iv.tv_usec/1000; - fprintf(stderr, "WARNING: failed to keep up with mmap data. Last read %lu msecs ago.\n", msecs); + fprintf(stderr, "WARNING: failed to keep up with mmap data." + " Last read %lu msecs ago.\n", msecs); + /* + * head points to a known good entry, start there. + */ old = head; } last_read = this_read; for (; old != head;) { - __u64 *ptr = (__u64 *)&data[old & md->mask]; - old += sizeof(__u64); + struct event_struct { + struct perf_event_header header; + __u64 ip; + __u32 pid, tid; + } *event = (struct event_struct *)&data[old & md->mask]; + struct event_struct event_copy; + + unsigned int size = event->header.size; + + /* + * Event straddles the mmap boundary -- header should always + * be inside due to u64 alignment of output. + */ + if ((old & md->mask) + size != ((old + size) & md->mask)) { + unsigned int offset = old; + unsigned int len = sizeof(*event), cpy; + void *dst = &event_copy; + + do { + cpy = min(md->mask + 1 - (offset & md->mask), len); + memcpy(dst, &data[offset & md->mask], cpy); + offset += cpy; + dst += cpy; + len -= cpy; + } while (len); + + event = &event_copy; + } - process_event(*ptr, md->counter); + old += size; + + switch (event->header.type) { + case PERF_EVENT_IP: + case PERF_EVENT_IP | __PERF_EVENT_TID: + process_event(event->ip, md->counter); + break; + } } md->prev = old; @@ -1214,6 +1266,7 @@ int main(int argc, char *argv[]) hw_event.irq_period = event_count[counter]; hw_event.record_type = PERF_RECORD_IRQ; hw_event.nmi = nmi; + hw_event.include_tid = 1; fd[i][counter] = sys_perf_counter_open(&hw_event, tid, cpu, group_fd, 0); if (fd[i][counter] < 0) { -- GitLab From 7730d8655880f41f2ea519aca2ca6a1413dfd2c9 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 25 Mar 2009 12:48:31 +0100 Subject: [PATCH 0158/6080] perf_counter: allow and require one-page mmap on counting counters A brainfart stopped single page mmap()s working. The rest of the code should be perfectly fine with not having any data pages. Reported-by: Paul Mackerras Signed-off-by: Peter Zijlstra Orig-LKML-Reference: <1237981712.7972.812.camel@twins> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f3e1b27bc1b8..95e02575546b 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1369,7 +1369,11 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) vma_size = vma->vm_end - vma->vm_start; nr_pages = (vma_size / PAGE_SIZE) - 1; - if (nr_pages == 0 || !is_power_of_2(nr_pages)) + /* + * If we have data pages ensure they're a power-of-two number, so we + * can do bitmasks instead of modulo. + */ + if (nr_pages != 0 && !is_power_of_2(nr_pages)) return -EINVAL; if (vma_size != PAGE_SIZE * (1 + nr_pages)) -- GitLab From 53cfbf593758916aac41db728f029986a62f1254 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 25 Mar 2009 22:46:58 +1100 Subject: [PATCH 0159/6080] perf_counter: record time running and time enabled for each counter Impact: new functionality Currently, if there are more counters enabled than can fit on the CPU, the kernel will multiplex the counters on to the hardware using round-robin scheduling. That isn't too bad for sampling counters, but for counting counters it means that the value read from a counter represents some unknown fraction of the true count of events that occurred while the counter was enabled. This remedies the situation by keeping track of how long each counter is enabled for, and how long it is actually on the cpu and counting events. These times are recorded in nanoseconds using the task clock for per-task counters and the cpu clock for per-cpu counters. These values can be supplied to userspace on a read from the counter. Userspace requests that they be supplied after the counter value by setting the PERF_FORMAT_TOTAL_TIME_ENABLED and/or PERF_FORMAT_TOTAL_TIME_RUNNING bits in the hw_event.read_format field when creating the counter. (There is no way to change the read format after the counter is created, though it would be possible to add some way to do that.) Using this information it is possible for userspace to scale the count it reads from the counter to get an estimate of the true count: true_count_estimate = count * total_time_enabled / total_time_running This also lets userspace detect the situation where the counter never got to go on the cpu: total_time_running == 0. This functionality has been requested by the PAPI developers, and will be generally needed for interpreting the count values from counting counters correctly. In the implementation, this keeps 5 time values (in nanoseconds) for each counter: total_time_enabled and total_time_running are used when the counter is in state OFF or ERROR and for reporting back to userspace. When the counter is in state INACTIVE or ACTIVE, it is the tstamp_enabled, tstamp_running and tstamp_stopped values that are relevant, and total_time_enabled and total_time_running are determined from them. (tstamp_stopped is only used in INACTIVE state.) The reason for doing it like this is that it means that only counters being enabled or disabled at sched-in and sched-out time need to be updated. There are no new loops that iterate over all counters to update total_time_enabled or total_time_running. This also keeps separate child_total_time_running and child_total_time_enabled fields that get added in when reporting the totals to userspace. They are separate fields so that they can be atomic. We don't want to use atomics for total_time_running, total_time_enabled etc., because then we would have to use atomic sequences to update them, which are slower than regular arithmetic and memory accesses. It is possible to measure total_time_running by adding a task_clock counter to each group of counters, and total_time_enabled can be measured approximately with a top-level task_clock counter (though inaccuracies will creep in if you need to disable and enable groups since it is not possible in general to disable/enable the top-level task_clock counter simultaneously with another group). However, that adds extra overhead - I measured around 15% increase in the context switch latency reported by lat_ctx (from lmbench) when a task_clock counter was added to each of 2 groups, and around 25% increase when a task_clock counter was added to each of 4 groups. (In both cases a top-level task-clock counter was also added.) In contrast, the code added in this commit gives better information with no overhead that I could measure (in fact in some cases I measured lower times with this code, but the differences were all less than one standard deviation). [ v2: address review comments by Andrew Morton. ] Signed-off-by: Paul Mackerras Acked-by: Peter Zijlstra Cc: Andrew Morton Orig-LKML-Reference: <18890.6578.728637.139402@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 2 + include/linux/perf_counter.h | 53 ++++++++++ kernel/perf_counter.c | 157 +++++++++++++++++++++++++---- 3 files changed, 191 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index d48596ab6557..df007fe0cc0b 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -455,6 +455,8 @@ static void counter_sched_in(struct perf_counter *counter, int cpu) { counter->state = PERF_COUNTER_STATE_ACTIVE; counter->oncpu = cpu; + counter->tstamp_running += counter->ctx->time_now - + counter->tstamp_stopped; if (is_software_counter(counter)) counter->hw_ops->enable(counter); } diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 7fdbdf8be775..6bf67ce17625 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -102,6 +102,16 @@ enum perf_counter_record_type { #define PERF_COUNTER_EVENT_SHIFT 0 #define PERF_COUNTER_EVENT_MASK __PERF_COUNTER_MASK(EVENT) +/* + * Bits that can be set in hw_event.read_format to request that + * reads on the counter should return the indicated quantities, + * in increasing order of bit value, after the counter value. + */ +enum perf_counter_read_format { + PERF_FORMAT_TOTAL_TIME_ENABLED = 1, + PERF_FORMAT_TOTAL_TIME_RUNNING = 2, +}; + /* * Hardware event to monitor via a performance monitoring counter: */ @@ -281,6 +291,32 @@ struct perf_counter { enum perf_counter_active_state prev_state; atomic64_t count; + /* + * These are the total time in nanoseconds that the counter + * has been enabled (i.e. eligible to run, and the task has + * been scheduled in, if this is a per-task counter) + * and running (scheduled onto the CPU), respectively. + * + * They are computed from tstamp_enabled, tstamp_running and + * tstamp_stopped when the counter is in INACTIVE or ACTIVE state. + */ + u64 total_time_enabled; + u64 total_time_running; + + /* + * These are timestamps used for computing total_time_enabled + * and total_time_running when the counter is in INACTIVE or + * ACTIVE state, measured in nanoseconds from an arbitrary point + * in time. + * tstamp_enabled: the notional time when the counter was enabled + * tstamp_running: the notional time when the counter was scheduled on + * tstamp_stopped: in INACTIVE state, the notional time when the + * counter was scheduled off. + */ + u64 tstamp_enabled; + u64 tstamp_running; + u64 tstamp_stopped; + struct perf_counter_hw_event hw_event; struct hw_perf_counter hw; @@ -291,6 +327,13 @@ struct perf_counter { struct perf_counter *parent; struct list_head child_list; + /* + * These accumulate total time (in nanoseconds) that children + * counters have been enabled and running, respectively. + */ + atomic64_t child_total_time_enabled; + atomic64_t child_total_time_running; + /* * Protect attach/detach and child_list: */ @@ -339,6 +382,16 @@ struct perf_counter_context { int nr_active; int is_active; struct task_struct *task; + + /* + * time_now is the current time in nanoseconds since an arbitrary + * point in the past. For per-task counters, this is based on the + * task clock, and for per-cpu counters it is based on the cpu clock. + * time_lost is an offset from the task/cpu clock, used to make it + * appear that time only passes while the context is scheduled in. + */ + u64 time_now; + u64 time_lost; #endif }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 95e02575546b..3b862a7988cd 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -116,6 +116,7 @@ counter_sched_out(struct perf_counter *counter, return; counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->tstamp_stopped = ctx->time_now; counter->hw_ops->disable(counter); counter->oncpu = -1; @@ -251,6 +252,60 @@ retry: spin_unlock_irq(&ctx->lock); } +/* + * Get the current time for this context. + * If this is a task context, we use the task's task clock, + * or for a per-cpu context, we use the cpu clock. + */ +static u64 get_context_time(struct perf_counter_context *ctx, int update) +{ + struct task_struct *curr = ctx->task; + + if (!curr) + return cpu_clock(smp_processor_id()); + + return __task_delta_exec(curr, update) + curr->se.sum_exec_runtime; +} + +/* + * Update the record of the current time in a context. + */ +static void update_context_time(struct perf_counter_context *ctx, int update) +{ + ctx->time_now = get_context_time(ctx, update) - ctx->time_lost; +} + +/* + * Update the total_time_enabled and total_time_running fields for a counter. + */ +static void update_counter_times(struct perf_counter *counter) +{ + struct perf_counter_context *ctx = counter->ctx; + u64 run_end; + + if (counter->state >= PERF_COUNTER_STATE_INACTIVE) { + counter->total_time_enabled = ctx->time_now - + counter->tstamp_enabled; + if (counter->state == PERF_COUNTER_STATE_INACTIVE) + run_end = counter->tstamp_stopped; + else + run_end = ctx->time_now; + counter->total_time_running = run_end - counter->tstamp_running; + } +} + +/* + * Update total_time_enabled and total_time_running for all counters in a group. + */ +static void update_group_times(struct perf_counter *leader) +{ + struct perf_counter *counter; + + update_counter_times(leader); + list_for_each_entry(counter, &leader->sibling_list, list_entry) + update_counter_times(counter); +} + /* * Cross CPU call to disable a performance counter */ @@ -276,6 +331,8 @@ static void __perf_counter_disable(void *info) * If it is in error state, leave it in error state. */ if (counter->state >= PERF_COUNTER_STATE_INACTIVE) { + update_context_time(ctx, 1); + update_counter_times(counter); if (counter == counter->group_leader) group_sched_out(counter, cpuctx, ctx); else @@ -320,8 +377,10 @@ static void perf_counter_disable(struct perf_counter *counter) * Since we have the lock this context can't be scheduled * in, so we can change the state safely. */ - if (counter->state == PERF_COUNTER_STATE_INACTIVE) + if (counter->state == PERF_COUNTER_STATE_INACTIVE) { + update_counter_times(counter); counter->state = PERF_COUNTER_STATE_OFF; + } spin_unlock_irq(&ctx->lock); } @@ -366,6 +425,8 @@ counter_sched_in(struct perf_counter *counter, return -EAGAIN; } + counter->tstamp_running += ctx->time_now - counter->tstamp_stopped; + if (!is_software_counter(counter)) cpuctx->active_oncpu++; ctx->nr_active++; @@ -425,6 +486,17 @@ static int group_can_go_on(struct perf_counter *counter, return can_add_hw; } +static void add_counter_to_ctx(struct perf_counter *counter, + struct perf_counter_context *ctx) +{ + list_add_counter(counter, ctx); + ctx->nr_counters++; + counter->prev_state = PERF_COUNTER_STATE_OFF; + counter->tstamp_enabled = ctx->time_now; + counter->tstamp_running = ctx->time_now; + counter->tstamp_stopped = ctx->time_now; +} + /* * Cross CPU call to install and enable a performance counter */ @@ -449,6 +521,7 @@ static void __perf_install_in_context(void *info) curr_rq_lock_irq_save(&flags); spin_lock(&ctx->lock); + update_context_time(ctx, 1); /* * Protect the list operation against NMI by disabling the @@ -456,9 +529,7 @@ static void __perf_install_in_context(void *info) */ perf_flags = hw_perf_save_disable(); - list_add_counter(counter, ctx); - ctx->nr_counters++; - counter->prev_state = PERF_COUNTER_STATE_OFF; + add_counter_to_ctx(counter, ctx); /* * Don't put the counter on if it is disabled or if @@ -486,8 +557,10 @@ static void __perf_install_in_context(void *info) */ if (leader != counter) group_sched_out(leader, cpuctx, ctx); - if (leader->hw_event.pinned) + if (leader->hw_event.pinned) { + update_group_times(leader); leader->state = PERF_COUNTER_STATE_ERROR; + } } if (!err && !ctx->task && cpuctx->max_pertask) @@ -548,10 +621,8 @@ retry: * can add the counter safely, if it the call above did not * succeed. */ - if (list_empty(&counter->list_entry)) { - list_add_counter(counter, ctx); - ctx->nr_counters++; - } + if (list_empty(&counter->list_entry)) + add_counter_to_ctx(counter, ctx); spin_unlock_irq(&ctx->lock); } @@ -576,11 +647,13 @@ static void __perf_counter_enable(void *info) curr_rq_lock_irq_save(&flags); spin_lock(&ctx->lock); + update_context_time(ctx, 1); counter->prev_state = counter->state; if (counter->state >= PERF_COUNTER_STATE_INACTIVE) goto unlock; counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->tstamp_enabled = ctx->time_now - counter->total_time_enabled; /* * If the counter is in a group and isn't the group leader, @@ -602,8 +675,10 @@ static void __perf_counter_enable(void *info) */ if (leader != counter) group_sched_out(leader, cpuctx, ctx); - if (leader->hw_event.pinned) + if (leader->hw_event.pinned) { + update_group_times(leader); leader->state = PERF_COUNTER_STATE_ERROR; + } } unlock: @@ -659,8 +734,11 @@ static void perf_counter_enable(struct perf_counter *counter) * Since we have the lock this context can't be scheduled * in, so we can change the state safely. */ - if (counter->state == PERF_COUNTER_STATE_OFF) + if (counter->state == PERF_COUNTER_STATE_OFF) { counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->tstamp_enabled = ctx->time_now - + counter->total_time_enabled; + } out: spin_unlock_irq(&ctx->lock); } @@ -693,6 +771,7 @@ void __perf_counter_sched_out(struct perf_counter_context *ctx, ctx->is_active = 0; if (likely(!ctx->nr_counters)) goto out; + update_context_time(ctx, 0); flags = hw_perf_save_disable(); if (ctx->nr_active) { @@ -797,6 +876,13 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, if (likely(!ctx->nr_counters)) goto out; + /* + * Add any time since the last sched_out to the lost time + * so it doesn't get included in the total_time_enabled and + * total_time_running measures for counters in the context. + */ + ctx->time_lost = get_context_time(ctx, 0) - ctx->time_now; + flags = hw_perf_save_disable(); /* @@ -817,8 +903,10 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, * If this pinned group hasn't been scheduled, * put it in error state. */ - if (counter->state == PERF_COUNTER_STATE_INACTIVE) + if (counter->state == PERF_COUNTER_STATE_INACTIVE) { + update_group_times(counter); counter->state = PERF_COUNTER_STATE_ERROR; + } } list_for_each_entry(counter, &ctx->counter_list, list_entry) { @@ -902,8 +990,10 @@ int perf_counter_task_disable(void) perf_flags = hw_perf_save_disable(); list_for_each_entry(counter, &ctx->counter_list, list_entry) { - if (counter->state != PERF_COUNTER_STATE_ERROR) + if (counter->state != PERF_COUNTER_STATE_ERROR) { + update_group_times(counter); counter->state = PERF_COUNTER_STATE_OFF; + } } hw_perf_restore(perf_flags); @@ -946,6 +1036,8 @@ int perf_counter_task_enable(void) if (counter->state > PERF_COUNTER_STATE_OFF) continue; counter->state = PERF_COUNTER_STATE_INACTIVE; + counter->tstamp_enabled = ctx->time_now - + counter->total_time_enabled; counter->hw_event.disabled = 0; } hw_perf_restore(perf_flags); @@ -1009,10 +1101,14 @@ void perf_counter_task_tick(struct task_struct *curr, int cpu) static void __read(void *info) { struct perf_counter *counter = info; + struct perf_counter_context *ctx = counter->ctx; unsigned long flags; curr_rq_lock_irq_save(&flags); + if (ctx->is_active) + update_context_time(ctx, 1); counter->hw_ops->read(counter); + update_counter_times(counter); curr_rq_unlock_irq_restore(&flags); } @@ -1025,6 +1121,8 @@ static u64 perf_counter_read(struct perf_counter *counter) if (counter->state == PERF_COUNTER_STATE_ACTIVE) { smp_call_function_single(counter->oncpu, __read, counter, 1); + } else if (counter->state == PERF_COUNTER_STATE_INACTIVE) { + update_counter_times(counter); } return atomic64_read(&counter->count); @@ -1137,10 +1235,8 @@ static int perf_release(struct inode *inode, struct file *file) static ssize_t perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count) { - u64 cntval; - - if (count < sizeof(cntval)) - return -EINVAL; + u64 values[3]; + int n; /* * Return end-of-file for a read on a counter that is in @@ -1151,10 +1247,24 @@ perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count) return 0; mutex_lock(&counter->mutex); - cntval = perf_counter_read(counter); + values[0] = perf_counter_read(counter); + n = 1; + if (counter->hw_event.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + values[n++] = counter->total_time_enabled + + atomic64_read(&counter->child_total_time_enabled); + if (counter->hw_event.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + values[n++] = counter->total_time_running + + atomic64_read(&counter->child_total_time_running); mutex_unlock(&counter->mutex); - return put_user(cntval, (u64 __user *) buf) ? -EFAULT : sizeof(cntval); + if (count < n * sizeof(u64)) + return -EINVAL; + count = n * sizeof(u64); + + if (copy_to_user(buf, values, count)) + return -EFAULT; + + return count; } static ssize_t @@ -2290,8 +2400,7 @@ inherit_counter(struct perf_counter *parent_counter, * Link it up in the child's context: */ child_counter->task = child; - list_add_counter(child_counter, child_ctx); - child_ctx->nr_counters++; + add_counter_to_ctx(child_counter, child_ctx); child_counter->parent = parent_counter; /* @@ -2361,6 +2470,10 @@ static void sync_child_counter(struct perf_counter *child_counter, * Add back the child's count to the parent's count: */ atomic64_add(child_val, &parent_counter->count); + atomic64_add(child_counter->total_time_enabled, + &parent_counter->child_total_time_enabled); + atomic64_add(child_counter->total_time_running, + &parent_counter->child_total_time_running); /* * Remove this counter from the parent's list @@ -2395,6 +2508,7 @@ __perf_counter_exit_task(struct task_struct *child, if (child != current) { wait_task_inactive(child, 0); list_del_init(&child_counter->list_entry); + update_counter_times(child_counter); } else { struct perf_cpu_context *cpuctx; unsigned long flags; @@ -2412,6 +2526,7 @@ __perf_counter_exit_task(struct task_struct *child, cpuctx = &__get_cpu_var(perf_cpu_context); group_sched_out(child_counter, cpuctx, child_ctx); + update_counter_times(child_counter); list_del_init(&child_counter->list_entry); -- GitLab From 925d519ab82b6dd7aca9420d809ee83819c08db2 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:02 +0200 Subject: [PATCH 0160/6080] perf_counter: unify and fix delayed counter wakeup While going over the wakeup code I noticed delayed wakeups only work for hardware counters but basically all software counters rely on them. This patch unifies and generalizes the delayed wakeup to fix this issue. Since we're dealing with NMI context bits here, use a cmpxchg() based single link list implementation to track counters that have pending wakeups. [ This should really be generic code for delayed wakeups, but since we cannot use cmpxchg()/xchg() in generic code, I've let it live in the perf_counter code. -- Eric Dumazet could use it to aggregate the network wakeups. ] Furthermore, the x86 method of using TIF flags was flawed in that its quite possible to end up setting the bit on the idle task, loosing the wakeup. The powerpc method uses per-cpu storage and does appear to be sufficient. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171023.153932974@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/include/asm/hw_irq.h | 4 +- arch/powerpc/kernel/irq.c | 2 +- arch/powerpc/kernel/perf_counter.c | 22 +---- arch/x86/include/asm/perf_counter.h | 5 +- arch/x86/include/asm/thread_info.h | 4 +- arch/x86/kernel/cpu/perf_counter.c | 29 ------- arch/x86/kernel/signal.c | 6 -- include/linux/perf_counter.h | 15 ++-- kernel/perf_counter.c | 128 ++++++++++++++++++++++++++-- kernel/timer.c | 3 + 10 files changed, 142 insertions(+), 76 deletions(-) diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index cb32d571c9c7..20a44d0c9fdd 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -132,7 +132,7 @@ static inline int irqs_disabled_flags(unsigned long flags) struct irq_chip; #ifdef CONFIG_PERF_COUNTERS -static inline unsigned long get_perf_counter_pending(void) +static inline unsigned long test_perf_counter_pending(void) { unsigned long x; @@ -160,7 +160,7 @@ extern void perf_counter_do_pending(void); #else -static inline unsigned long get_perf_counter_pending(void) +static inline unsigned long test_perf_counter_pending(void) { return 0; } diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 469e9635ff04..2cd471f92fe6 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -135,7 +135,7 @@ notrace void raw_local_irq_restore(unsigned long en) iseries_handle_interrupts(); } - if (get_perf_counter_pending()) { + if (test_perf_counter_pending()) { clear_perf_counter_pending(); perf_counter_do_pending(); } diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index df007fe0cc0b..cde720fc495c 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -649,24 +649,6 @@ hw_perf_counter_init(struct perf_counter *counter) return &power_perf_ops; } -/* - * Handle wakeups. - */ -void perf_counter_do_pending(void) -{ - int i; - struct cpu_hw_counters *cpuhw = &__get_cpu_var(cpu_hw_counters); - struct perf_counter *counter; - - for (i = 0; i < cpuhw->n_counters; ++i) { - counter = cpuhw->counter[i]; - if (counter && counter->wakeup_pending) { - counter->wakeup_pending = 0; - wake_up(&counter->waitq); - } - } -} - /* * A counter has overflowed; update its count and record * things if requested. Note that interrupts are hard-disabled @@ -720,7 +702,7 @@ static void perf_counter_interrupt(struct pt_regs *regs) struct cpu_hw_counters *cpuhw = &__get_cpu_var(cpu_hw_counters); struct perf_counter *counter; long val; - int need_wakeup = 0, found = 0; + int found = 0; for (i = 0; i < cpuhw->n_counters; ++i) { counter = cpuhw->counter[i]; @@ -761,7 +743,7 @@ static void perf_counter_interrupt(struct pt_regs *regs) * immediately; otherwise we'll have do the wakeup when interrupts * get soft-enabled. */ - if (get_perf_counter_pending() && regs->softe) { + if (test_perf_counter_pending() && regs->softe) { irq_enter(); clear_perf_counter_pending(); perf_counter_do_pending(); diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h index 1662043b340f..e2b0e66b2353 100644 --- a/arch/x86/include/asm/perf_counter.h +++ b/arch/x86/include/asm/perf_counter.h @@ -84,8 +84,9 @@ union cpuid10_edx { #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b #define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2) -#define set_perf_counter_pending() \ - set_tsk_thread_flag(current, TIF_PERF_COUNTERS); +#define set_perf_counter_pending() do { } while (0) +#define clear_perf_counter_pending() do { } while (0) +#define test_perf_counter_pending() (0) #ifdef CONFIG_PERF_COUNTERS extern void init_hw_perf_counters(void); diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 3ffd5d2a3676..8820a73ae090 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -83,7 +83,6 @@ struct thread_info { #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SECCOMP 8 /* secure computing */ #define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */ -#define TIF_PERF_COUNTERS 11 /* notify perf counter work */ #define TIF_NOTSC 16 /* TSC is not accessible in userland */ #define TIF_IA32 17 /* 32bit process */ #define TIF_FORK 18 /* ret_from_fork */ @@ -107,7 +106,6 @@ struct thread_info { #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY) -#define _TIF_PERF_COUNTERS (1 << TIF_PERF_COUNTERS) #define _TIF_NOTSC (1 << TIF_NOTSC) #define _TIF_IA32 (1 << TIF_IA32) #define _TIF_FORK (1 << TIF_FORK) @@ -141,7 +139,7 @@ struct thread_info { /* Only used for 64 bit */ #define _TIF_DO_NOTIFY_MASK \ - (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_PERF_COUNTERS|_TIF_NOTIFY_RESUME) + (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_NOTIFY_RESUME) /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 3f95b0cdc550..7aab177fb566 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -227,7 +227,6 @@ static int __hw_perf_counter_init(struct perf_counter *counter) */ hwc->config |= pmc_ops->event_map(perf_event_id(hw_event)); } - counter->wakeup_pending = 0; return 0; } @@ -773,34 +772,6 @@ void smp_perf_counter_interrupt(struct pt_regs *regs) irq_exit(); } -/* - * This handler is triggered by NMI contexts: - */ -void perf_counter_notify(struct pt_regs *regs) -{ - struct cpu_hw_counters *cpuc; - unsigned long flags; - int bit, cpu; - - local_irq_save(flags); - cpu = smp_processor_id(); - cpuc = &per_cpu(cpu_hw_counters, cpu); - - for_each_bit(bit, cpuc->used, X86_PMC_IDX_MAX) { - struct perf_counter *counter = cpuc->counters[bit]; - - if (!counter) - continue; - - if (counter->wakeup_pending) { - counter->wakeup_pending = 0; - wake_up(&counter->waitq); - } - } - - local_irq_restore(flags); -} - void perf_counters_lapic_init(int nmi) { u32 apic_val; diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 611615a92c90..0a813b17b172 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -6,7 +6,6 @@ * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes * 2000-2002 x86-64 support by Andi Kleen */ -#include #include #include #include @@ -872,11 +871,6 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) tracehook_notify_resume(regs); } - if (thread_info_flags & _TIF_PERF_COUNTERS) { - clear_thread_flag(TIF_PERF_COUNTERS); - perf_counter_notify(regs); - } - #ifdef CONFIG_X86_32 clear_thread_flag(TIF_IRET); #endif /* CONFIG_X86_32 */ diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 6bf67ce17625..0d833228eee5 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -275,6 +275,10 @@ struct perf_mmap_data { void *data_pages[0]; }; +struct perf_wakeup_entry { + struct perf_wakeup_entry *next; +}; + /** * struct perf_counter - performance counter kernel representation: */ @@ -350,7 +354,7 @@ struct perf_counter { /* poll related */ wait_queue_head_t waitq; /* optional: for NMIs */ - int wakeup_pending; + struct perf_wakeup_entry wakeup; void (*destroy)(struct perf_counter *); struct rcu_head rcu_head; @@ -427,7 +431,7 @@ extern void perf_counter_task_sched_out(struct task_struct *task, int cpu); extern void perf_counter_task_tick(struct task_struct *task, int cpu); extern void perf_counter_init_task(struct task_struct *child); extern void perf_counter_exit_task(struct task_struct *child); -extern void perf_counter_notify(struct pt_regs *regs); +extern void perf_counter_do_pending(void); extern void perf_counter_print_debug(void); extern void perf_counter_unthrottle(void); extern u64 hw_perf_save_disable(void); @@ -461,7 +465,7 @@ static inline void perf_counter_task_tick(struct task_struct *task, int cpu) { } static inline void perf_counter_init_task(struct task_struct *child) { } static inline void perf_counter_exit_task(struct task_struct *child) { } -static inline void perf_counter_notify(struct pt_regs *regs) { } +static inline void perf_counter_do_pending(void) { } static inline void perf_counter_print_debug(void) { } static inline void perf_counter_unthrottle(void) { } static inline void hw_perf_restore(u64 ctrl) { } @@ -469,8 +473,9 @@ static inline u64 hw_perf_save_disable(void) { return 0; } static inline int perf_counter_task_disable(void) { return -EINVAL; } static inline int perf_counter_task_enable(void) { return -EINVAL; } -static inline void perf_swcounter_event(u32 event, u64 nr, - int nmi, struct pt_regs *regs) { } +static inline void +perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs) { } + #endif #endif /* __KERNEL__ */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 3b862a7988cd..f70ff80e79d7 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1197,8 +1197,12 @@ static void free_counter_rcu(struct rcu_head *head) kfree(counter); } +static void perf_pending_sync(struct perf_counter *counter); + static void free_counter(struct perf_counter *counter) { + perf_pending_sync(counter); + if (counter->destroy) counter->destroy(counter); @@ -1528,6 +1532,118 @@ static const struct file_operations perf_fops = { .mmap = perf_mmap, }; +/* + * Perf counter wakeup + * + * If there's data, ensure we set the poll() state and publish everything + * to user-space before waking everybody up. + */ + +void perf_counter_wakeup(struct perf_counter *counter) +{ + struct perf_mmap_data *data; + + rcu_read_lock(); + data = rcu_dereference(counter->data); + if (data) { + (void)atomic_xchg(&data->wakeup, POLL_IN); + __perf_counter_update_userpage(counter, data); + } + rcu_read_unlock(); + + wake_up_all(&counter->waitq); +} + +/* + * Pending wakeups + * + * Handle the case where we need to wakeup up from NMI (or rq->lock) context. + * + * The NMI bit means we cannot possibly take locks. Therefore, maintain a + * single linked list and use cmpxchg() to add entries lockless. + */ + +#define PENDING_TAIL ((struct perf_wakeup_entry *)-1UL) + +static DEFINE_PER_CPU(struct perf_wakeup_entry *, perf_wakeup_head) = { + PENDING_TAIL, +}; + +static void perf_pending_queue(struct perf_counter *counter) +{ + struct perf_wakeup_entry **head; + struct perf_wakeup_entry *prev, *next; + + if (cmpxchg(&counter->wakeup.next, NULL, PENDING_TAIL) != NULL) + return; + + head = &get_cpu_var(perf_wakeup_head); + + do { + prev = counter->wakeup.next = *head; + next = &counter->wakeup; + } while (cmpxchg(head, prev, next) != prev); + + set_perf_counter_pending(); + + put_cpu_var(perf_wakeup_head); +} + +static int __perf_pending_run(void) +{ + struct perf_wakeup_entry *list; + int nr = 0; + + list = xchg(&__get_cpu_var(perf_wakeup_head), PENDING_TAIL); + while (list != PENDING_TAIL) { + struct perf_counter *counter = container_of(list, + struct perf_counter, wakeup); + + list = list->next; + + counter->wakeup.next = NULL; + /* + * Ensure we observe the unqueue before we issue the wakeup, + * so that we won't be waiting forever. + * -- see perf_not_pending(). + */ + smp_wmb(); + + perf_counter_wakeup(counter); + nr++; + } + + return nr; +} + +static inline int perf_not_pending(struct perf_counter *counter) +{ + /* + * If we flush on whatever cpu we run, there is a chance we don't + * need to wait. + */ + get_cpu(); + __perf_pending_run(); + put_cpu(); + + /* + * Ensure we see the proper queue state before going to sleep + * so that we do not miss the wakeup. -- see perf_pending_handle() + */ + smp_rmb(); + return counter->wakeup.next == NULL; +} + +static void perf_pending_sync(struct perf_counter *counter) +{ + wait_event(counter->waitq, perf_not_pending(counter)); +} + +void perf_counter_do_pending(void) +{ + __perf_pending_run(); +} + /* * Output */ @@ -1611,13 +1727,10 @@ static void perf_output_copy(struct perf_output_handle *handle, static void perf_output_end(struct perf_output_handle *handle, int nmi) { if (handle->wakeup) { - (void)atomic_xchg(&handle->data->wakeup, POLL_IN); - __perf_counter_update_userpage(handle->counter, handle->data); - if (nmi) { - handle->counter->wakeup_pending = 1; - set_perf_counter_pending(); - } else - wake_up(&handle->counter->waitq); + if (nmi) + perf_pending_queue(handle->counter); + else + perf_counter_wakeup(handle->counter); } rcu_read_unlock(); } @@ -2211,7 +2324,6 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, counter->cpu = cpu; counter->hw_event = *hw_event; - counter->wakeup_pending = 0; counter->group_leader = group_leader; counter->hw_ops = NULL; counter->ctx = ctx; diff --git a/kernel/timer.c b/kernel/timer.c index b4555568b4e4..672ca25fbc43 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -1167,6 +1168,8 @@ static void run_timer_softirq(struct softirq_action *h) { struct tvec_base *base = __get_cpu_var(tvec_bases); + perf_counter_do_pending(); + hrtimer_run_pending(); if (time_after_eq(jiffies, base->timer_jiffies)) -- GitLab From 38ff667b321b00f5e6830e93fb4ab11a653a2920 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:03 +0200 Subject: [PATCH 0161/6080] perf_counter: fix update_userpage() It just occured to me it is possible to have multiple contending updates of the userpage (mmap information vs overflow vs counter). This would break the seqlock logic. It appear the arch code uses this from NMI context, so we cannot possibly serialize its use, therefore separate the data_head update from it and let it return to its original use. The arch code needs to make sure there are no contending callers by disabling the counter before using it -- powerpc appears to do this nicely. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171023.241410660@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 35 +++++++++++++++++++++++++++++++++ kernel/perf_counter.c | 38 ++++++++++++++++++++++-------------- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 0d833228eee5..8ac18852dcfe 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -160,10 +160,45 @@ struct perf_counter_hw_event { struct perf_counter_mmap_page { __u32 version; /* version number of this structure */ __u32 compat_version; /* lowest version this is compat with */ + + /* + * Bits needed to read the hw counters in user-space. + * + * The index and offset should be read atomically using the seqlock: + * + * __u32 seq, index; + * __s64 offset; + * + * again: + * rmb(); + * seq = pc->lock; + * + * if (unlikely(seq & 1)) { + * cpu_relax(); + * goto again; + * } + * + * index = pc->index; + * offset = pc->offset; + * + * rmb(); + * if (pc->lock != seq) + * goto again; + * + * After this, index contains architecture specific counter index + 1, + * so that 0 means unavailable, offset contains the value to be added + * to the result of the raw timer read to obtain this counter's value. + */ __u32 lock; /* seqlock for synchronization */ __u32 index; /* hardware counter identifier */ __s64 offset; /* add to hardware counter value */ + /* + * Control data for the mmap() data buffer. + * + * User-space reading this value should issue an rmb(), on SMP capable + * platforms, after reading this value -- see perf_counter_wakeup(). + */ __u32 data_head; /* head in the data section */ }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f70ff80e79d7..c95e92329b97 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1316,10 +1316,22 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return err; } -static void __perf_counter_update_userpage(struct perf_counter *counter, - struct perf_mmap_data *data) +/* + * Callers need to ensure there can be no nesting of this function, otherwise + * the seqlock logic goes bad. We can not serialize this because the arch + * code calls this from NMI context. + */ +void perf_counter_update_userpage(struct perf_counter *counter) { - struct perf_counter_mmap_page *userpg = data->user_page; + struct perf_mmap_data *data; + struct perf_counter_mmap_page *userpg; + + rcu_read_lock(); + data = rcu_dereference(counter->data); + if (!data) + goto unlock; + + userpg = data->user_page; /* * Disable preemption so as to not let the corresponding user-space @@ -1333,20 +1345,10 @@ static void __perf_counter_update_userpage(struct perf_counter *counter, if (counter->state == PERF_COUNTER_STATE_ACTIVE) userpg->offset -= atomic64_read(&counter->hw.prev_count); - userpg->data_head = atomic_read(&data->head); smp_wmb(); ++userpg->lock; preempt_enable(); -} - -void perf_counter_update_userpage(struct perf_counter *counter) -{ - struct perf_mmap_data *data; - - rcu_read_lock(); - data = rcu_dereference(counter->data); - if (data) - __perf_counter_update_userpage(counter, data); +unlock: rcu_read_unlock(); } @@ -1547,7 +1549,13 @@ void perf_counter_wakeup(struct perf_counter *counter) data = rcu_dereference(counter->data); if (data) { (void)atomic_xchg(&data->wakeup, POLL_IN); - __perf_counter_update_userpage(counter, data); + /* + * Ensure all data writes are issued before updating the + * user-space data head information. The matching rmb() + * will be in userspace after reading this value. + */ + smp_wmb(); + data->user_page->data_head = atomic_read(&data->head); } rcu_read_unlock(); -- GitLab From 195564390210977954fe4ef45b39cdee34f41b59 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:04 +0200 Subject: [PATCH 0162/6080] perf_counter: kerneltop: simplify data_head read Now that the kernel side changed, match up again. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171023.327144324@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index fda1438365dc..2779c57ad4ba 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -1125,22 +1125,10 @@ struct mmap_data { static unsigned int mmap_read_head(struct mmap_data *md) { struct perf_counter_mmap_page *pc = md->base; - unsigned int seq, head; - -repeat: - rmb(); - seq = pc->lock; - - if (unlikely(seq & 1)) { - cpu_relax(); - goto repeat; - } + int head; head = pc->data_head; - rmb(); - if (pc->lock != seq) - goto repeat; return head; } -- GitLab From 0a4a93919bdc5cee48fe4367591e8e0449c1086c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:05 +0200 Subject: [PATCH 0163/6080] perf_counter: executable mmap() information Currently the profiling information returns userspace IPs but no way to correlate them to userspace code. Userspace could look into /proc/$pid/maps but that might not be current or even present anymore at the time of analyzing the IPs. Therefore provide means to track the mmap information and provide it in the output stream. XXX: only covers mmap()/munmap(), mremap() and mprotect() are missing. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Cc: Andrew Morton Orig-LKML-Reference: <20090330171023.417259499@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 24 +++++- kernel/perf_counter.c | 145 +++++++++++++++++++++++++++++++++++ mm/mmap.c | 10 +++ 3 files changed, 177 insertions(+), 2 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 8ac18852dcfe..037a81145aca 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -137,9 +137,11 @@ struct perf_counter_hw_event { exclude_kernel : 1, /* ditto kernel */ exclude_hv : 1, /* ditto hypervisor */ exclude_idle : 1, /* don't count when idle */ - include_tid : 1, /* include the tid */ + include_tid : 1, /* include the tid */ + mmap : 1, /* include mmap data */ + munmap : 1, /* include munmap data */ - __reserved_1 : 54; + __reserved_1 : 52; __u32 extra_config_len; __u32 __reserved_4; @@ -211,6 +213,9 @@ enum perf_event_type { PERF_EVENT_IP = 0, PERF_EVENT_GROUP = 1, + PERF_EVENT_MMAP = 2, + PERF_EVENT_MUNMAP = 3, + __PERF_EVENT_TID = 0x100, }; @@ -491,6 +496,12 @@ static inline int is_software_counter(struct perf_counter *counter) extern void perf_swcounter_event(u32, u64, int, struct pt_regs *); +extern void perf_counter_mmap(unsigned long addr, unsigned long len, + unsigned long pgoff, struct file *file); + +extern void perf_counter_munmap(unsigned long addr, unsigned long len, + unsigned long pgoff, struct file *file); + #else static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } @@ -511,6 +522,15 @@ static inline int perf_counter_task_enable(void) { return -EINVAL; } static inline void perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs) { } + +static inline void +perf_counter_mmap(unsigned long addr, unsigned long len, + unsigned long pgoff, struct file *file) { } + +static inline void +perf_counter_munmap(unsigned long addr, unsigned long len, + unsigned long pgoff, struct file *file) { } + #endif #endif /* __KERNEL__ */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index c95e92329b97..f35e89e3d6a4 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -1843,6 +1844,150 @@ void perf_counter_output(struct perf_counter *counter, } } +/* + * mmap tracking + */ + +struct perf_mmap_event { + struct file *file; + char *file_name; + int file_size; + + struct { + struct perf_event_header header; + + u32 pid; + u32 tid; + u64 start; + u64 len; + u64 pgoff; + } event; +}; + +static void perf_counter_mmap_output(struct perf_counter *counter, + struct perf_mmap_event *mmap_event) +{ + struct perf_output_handle handle; + int size = mmap_event->event.header.size; + int ret = perf_output_begin(&handle, counter, size); + + if (ret) + return; + + perf_output_put(&handle, mmap_event->event); + perf_output_copy(&handle, mmap_event->file_name, + mmap_event->file_size); + perf_output_end(&handle, 0); +} + +static int perf_counter_mmap_match(struct perf_counter *counter, + struct perf_mmap_event *mmap_event) +{ + if (counter->hw_event.mmap && + mmap_event->event.header.type == PERF_EVENT_MMAP) + return 1; + + if (counter->hw_event.munmap && + mmap_event->event.header.type == PERF_EVENT_MUNMAP) + return 1; + + return 0; +} + +static void perf_counter_mmap_ctx(struct perf_counter_context *ctx, + struct perf_mmap_event *mmap_event) +{ + struct perf_counter *counter; + + if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list)) + return; + + rcu_read_lock(); + list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) { + if (perf_counter_mmap_match(counter, mmap_event)) + perf_counter_mmap_output(counter, mmap_event); + } + rcu_read_unlock(); +} + +static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event) +{ + struct perf_cpu_context *cpuctx; + struct file *file = mmap_event->file; + unsigned int size; + char tmp[16]; + char *buf = NULL; + char *name; + + if (file) { + buf = kzalloc(PATH_MAX, GFP_KERNEL); + if (!buf) { + name = strncpy(tmp, "//enomem", sizeof(tmp)); + goto got_name; + } + name = dentry_path(file->f_dentry, buf, PATH_MAX); + if (IS_ERR(name)) { + name = strncpy(tmp, "//toolong", sizeof(tmp)); + goto got_name; + } + } else { + name = strncpy(tmp, "//anon", sizeof(tmp)); + goto got_name; + } + +got_name: + size = ALIGN(strlen(name), sizeof(u64)); + + mmap_event->file_name = name; + mmap_event->file_size = size; + + mmap_event->event.header.size = sizeof(mmap_event->event) + size; + + cpuctx = &get_cpu_var(perf_cpu_context); + perf_counter_mmap_ctx(&cpuctx->ctx, mmap_event); + put_cpu_var(perf_cpu_context); + + perf_counter_mmap_ctx(¤t->perf_counter_ctx, mmap_event); + + kfree(buf); +} + +void perf_counter_mmap(unsigned long addr, unsigned long len, + unsigned long pgoff, struct file *file) +{ + struct perf_mmap_event mmap_event = { + .file = file, + .event = { + .header = { .type = PERF_EVENT_MMAP, }, + .pid = current->group_leader->pid, + .tid = current->pid, + .start = addr, + .len = len, + .pgoff = pgoff, + }, + }; + + perf_counter_mmap_event(&mmap_event); +} + +void perf_counter_munmap(unsigned long addr, unsigned long len, + unsigned long pgoff, struct file *file) +{ + struct perf_mmap_event mmap_event = { + .file = file, + .event = { + .header = { .type = PERF_EVENT_MUNMAP, }, + .pid = current->group_leader->pid, + .tid = current->pid, + .start = addr, + .len = len, + .pgoff = pgoff, + }, + }; + + perf_counter_mmap_event(&mmap_event); +} + /* * Generic software counter infrastructure */ diff --git a/mm/mmap.c b/mm/mmap.c index 4a3841186c11..1df63f614f97 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -1223,6 +1224,9 @@ munmap_back: if (correct_wcount) atomic_inc(&inode->i_writecount); out: + if (vm_flags & VM_EXEC) + perf_counter_mmap(addr, len, pgoff, file); + mm->total_vm += len >> PAGE_SHIFT; vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); if (vm_flags & VM_LOCKED) { @@ -1756,6 +1760,12 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) do { long nrpages = vma_pages(vma); + if (vma->vm_flags & VM_EXEC) { + perf_counter_munmap(vma->vm_start, + nrpages << PAGE_SHIFT, + vma->vm_pgoff, vma->vm_file); + } + mm->total_vm -= nrpages; vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); vma = remove_vma(vma); -- GitLab From 3c1ba6fafecaed295017881f8863a18602f32c1d Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:06 +0200 Subject: [PATCH 0164/6080] perf_counter: kerneltop: parse the mmap data stream frob the kerneltop code to print the mmap data in the stream Better use would be collecting the IPs per PID and mapping them onto the provided userspace code.. TODO Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171023.501902515@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 50 ++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 2779c57ad4ba..995111dee7fb 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -184,6 +184,8 @@ static int nmi = 1; static int group = 0; static unsigned int page_size; static unsigned int mmap_pages = 16; +static int use_mmap = 0; +static int use_munmap = 0; static char *vmlinux; @@ -333,6 +335,8 @@ static void display_help(void) " -z --zero # zero counts after display\n" " -D --dump_symtab # dump symbol table to stderr on startup\n" " -m pages --mmap_pages= # number of mmap data pages\n" + " -M --mmap_info # print mmap info stream\n" + " -U --munmap_info # print munmap info stream\n" ); exit(0); @@ -1052,9 +1056,11 @@ static void process_options(int argc, char *argv[]) {"stat", no_argument, NULL, 'S'}, {"zero", no_argument, NULL, 'z'}, {"mmap_pages", required_argument, NULL, 'm'}, + {"mmap_info", no_argument, NULL, 'M'}, + {"munmap_info", no_argument, NULL, 'U'}, {NULL, 0, NULL, 0 } }; - int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hn:m:p:s:Sx:z", + int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hn:m:p:s:Sx:zMU", long_options, &option_index); if (c == -1) break; @@ -1092,6 +1098,8 @@ static void process_options(int argc, char *argv[]) case 'x': vmlinux = strdup(optarg); break; case 'z': zero = 1; break; case 'm': mmap_pages = atoi(optarg); break; + case 'M': use_mmap = 1; break; + case 'U': use_munmap = 1; break; default: error = 1; break; } } @@ -1172,12 +1180,29 @@ static void mmap_read(struct mmap_data *md) last_read = this_read; for (; old != head;) { - struct event_struct { + struct ip_event { struct perf_event_header header; __u64 ip; __u32 pid, tid; - } *event = (struct event_struct *)&data[old & md->mask]; - struct event_struct event_copy; + }; + struct mmap_event { + struct perf_event_header header; + __u32 pid, tid; + __u64 start; + __u64 len; + __u64 pgoff; + char filename[PATH_MAX]; + }; + + typedef union event_union { + struct perf_event_header header; + struct ip_event ip; + struct mmap_event mmap; + } event_t; + + event_t *event = (event_t *)&data[old & md->mask]; + + event_t event_copy; unsigned int size = event->header.size; @@ -1187,7 +1212,7 @@ static void mmap_read(struct mmap_data *md) */ if ((old & md->mask) + size != ((old + size) & md->mask)) { unsigned int offset = old; - unsigned int len = sizeof(*event), cpy; + unsigned int len = min(sizeof(*event), size), cpy; void *dst = &event_copy; do { @@ -1206,7 +1231,18 @@ static void mmap_read(struct mmap_data *md) switch (event->header.type) { case PERF_EVENT_IP: case PERF_EVENT_IP | __PERF_EVENT_TID: - process_event(event->ip, md->counter); + process_event(event->ip.ip, md->counter); + break; + + case PERF_EVENT_MMAP: + case PERF_EVENT_MUNMAP: + printf("%s: %Lu %Lu %Lu %s\n", + event->header.type == PERF_EVENT_MMAP + ? "mmap" : "munmap", + event->mmap.start, + event->mmap.len, + event->mmap.pgoff, + event->mmap.filename); break; } } @@ -1255,6 +1291,8 @@ int main(int argc, char *argv[]) hw_event.record_type = PERF_RECORD_IRQ; hw_event.nmi = nmi; hw_event.include_tid = 1; + hw_event.mmap = use_mmap; + hw_event.munmap = use_munmap; fd[i][counter] = sys_perf_counter_open(&hw_event, tid, cpu, group_fd, 0); if (fd[i][counter] < 0) { -- GitLab From 7595d63b3a9ce65d14c4fbd0e7de448a343d7215 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 30 Mar 2009 19:07:07 +0200 Subject: [PATCH 0165/6080] perf_counter: powerpc: only reserve PMU hardware when we need it Impact: cooperate with oprofile At present, on PowerPC, if you have perf_counters compiled in, oprofile doesn't work. There is code to allow the PMU to be shared between competing subsystems, such as perf_counters and oprofile, but currently the perf_counter subsystem reserves the PMU for itself at boot time, and never releases it. This makes perf_counter play nicely with oprofile. Now we keep a count of how many perf_counter instances are counting hardware events, and reserve the PMU when that count becomes non-zero, and release the PMU when that count becomes zero. This means that it is possible to have perf_counters compiled in and still use oprofile, as long as there are no hardware perf_counters active. This also means that if oprofile is active, sys_perf_counter_open will fail if the hw_event specifies a hardware event. To avoid races with other tasks creating and destroying perf_counters, we use a mutex. We use atomic_inc_not_zero and atomic_add_unless to avoid having to take the mutex unless there is a possibility of the count going between 0 and 1. Signed-off-by: Paul Mackerras Signed-off-by: Peter Zijlstra Orig-LKML-Reference: <20090330171023.627912475@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 47 ++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index cde720fc495c..560dd1e7b524 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -41,6 +41,8 @@ struct power_pmu *ppmu; */ static unsigned int freeze_counters_kernel = MMCR0_FCS; +static void perf_counter_interrupt(struct pt_regs *regs); + void perf_counter_print_debug(void) { } @@ -594,6 +596,24 @@ struct hw_perf_counter_ops power_perf_ops = { .read = power_perf_read }; +/* Number of perf_counters counting hardware events */ +static atomic_t num_counters; +/* Used to avoid races in calling reserve/release_pmc_hardware */ +static DEFINE_MUTEX(pmc_reserve_mutex); + +/* + * Release the PMU if this is the last perf_counter. + */ +static void hw_perf_counter_destroy(struct perf_counter *counter) +{ + if (!atomic_add_unless(&num_counters, -1, 1)) { + mutex_lock(&pmc_reserve_mutex); + if (atomic_dec_return(&num_counters) == 0) + release_pmc_hardware(); + mutex_unlock(&pmc_reserve_mutex); + } +} + const struct hw_perf_counter_ops * hw_perf_counter_init(struct perf_counter *counter) { @@ -601,6 +621,7 @@ hw_perf_counter_init(struct perf_counter *counter) struct perf_counter *ctrs[MAX_HWCOUNTERS]; unsigned int events[MAX_HWCOUNTERS]; int n; + int err; if (!ppmu) return NULL; @@ -646,6 +667,27 @@ hw_perf_counter_init(struct perf_counter *counter) counter->hw.config = events[n]; atomic64_set(&counter->hw.period_left, counter->hw_event.irq_period); + + /* + * See if we need to reserve the PMU. + * If no counters are currently in use, then we have to take a + * mutex to ensure that we don't race with another task doing + * reserve_pmc_hardware or release_pmc_hardware. + */ + err = 0; + if (!atomic_inc_not_zero(&num_counters)) { + mutex_lock(&pmc_reserve_mutex); + if (atomic_read(&num_counters) == 0 && + reserve_pmc_hardware(perf_counter_interrupt)) + err = -EBUSY; + else + atomic_inc(&num_counters); + mutex_unlock(&pmc_reserve_mutex); + } + counter->destroy = hw_perf_counter_destroy; + + if (err) + return NULL; return &power_perf_ops; } @@ -769,11 +811,6 @@ static int init_perf_counters(void) { unsigned long pvr; - if (reserve_pmc_hardware(perf_counter_interrupt)) { - printk(KERN_ERR "Couldn't init performance monitor subsystem\n"); - return -EBUSY; - } - /* XXX should get this from cputable */ pvr = mfspr(SPRN_PVR); switch (PVR_VER(pvr)) { -- GitLab From d5d2bc0dd0379deddb9ede66fec90a3083eaec57 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 30 Mar 2009 19:07:08 +0200 Subject: [PATCH 0166/6080] perf_counter: make it possible for hw_perf_counter_init to return error codes Impact: better error reporting At present, if hw_perf_counter_init encounters an error, all it can do is return NULL, which causes sys_perf_counter_open to return an EINVAL error to userspace. This isn't very informative for userspace; it means that userspace can't tell the difference between "sorry, oprofile is already using the PMU" and "we don't support this CPU" and "this CPU doesn't support the requested generic hardware event". This commit uses the PTR_ERR/ERR_PTR/IS_ERR set of macros to let hw_perf_counter_init return an error code on error rather than just NULL if it wishes. If it does so, that error code will be returned from sys_perf_counter_open to userspace. If it returns NULL, an EINVAL error will be returned to userspace, as before. This also adapts the powerpc hw_perf_counter_init to make use of this to return ENXIO, EINVAL, EBUSY, or EOPNOTSUPP as appropriate. It would be good to add extra error numbers in future to allow userspace to distinguish the various errors that are currently reported as EINVAL, i.e. irq_period < 0, too many events in a group, conflict between exclude_* settings in a group, and PMU resource conflict in a group. [ v2: fix a bug pointed out by Corey Ashford where error returns from hw_perf_counter_init were not handled correctly in the case of raw hardware events.] Signed-off-by: Paul Mackerras Signed-off-by: Peter Zijlstra Orig-LKML-Reference: <20090330171023.682428180@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 14 ++++++------ kernel/perf_counter.c | 35 +++++++++++++++++++----------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 560dd1e7b524..0a4d14f279ae 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -624,13 +624,13 @@ hw_perf_counter_init(struct perf_counter *counter) int err; if (!ppmu) - return NULL; + return ERR_PTR(-ENXIO); if ((s64)counter->hw_event.irq_period < 0) - return NULL; + return ERR_PTR(-EINVAL); if (!perf_event_raw(&counter->hw_event)) { ev = perf_event_id(&counter->hw_event); if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0) - return NULL; + return ERR_PTR(-EOPNOTSUPP); ev = ppmu->generic_events[ev]; } else { ev = perf_event_config(&counter->hw_event); @@ -656,14 +656,14 @@ hw_perf_counter_init(struct perf_counter *counter) n = collect_events(counter->group_leader, ppmu->n_counter - 1, ctrs, events); if (n < 0) - return NULL; + return ERR_PTR(-EINVAL); } events[n] = ev; ctrs[n] = counter; if (check_excludes(ctrs, n, 1)) - return NULL; + return ERR_PTR(-EINVAL); if (power_check_constraints(events, n + 1)) - return NULL; + return ERR_PTR(-EINVAL); counter->hw.config = events[n]; atomic64_set(&counter->hw.period_left, counter->hw_event.irq_period); @@ -687,7 +687,7 @@ hw_perf_counter_init(struct perf_counter *counter) counter->destroy = hw_perf_counter_destroy; if (err) - return NULL; + return ERR_PTR(err); return &power_perf_ops; } diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f35e89e3d6a4..d07b45278b4f 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -2453,10 +2453,11 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, { const struct hw_perf_counter_ops *hw_ops; struct perf_counter *counter; + long err; counter = kzalloc(sizeof(*counter), gfpflags); if (!counter) - return NULL; + return ERR_PTR(-ENOMEM); /* * Single counters are their own group leaders, with an @@ -2505,12 +2506,18 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, hw_ops = tp_perf_counter_init(counter); break; } +done: + err = 0; + if (!hw_ops) + err = -EINVAL; + else if (IS_ERR(hw_ops)) + err = PTR_ERR(hw_ops); - if (!hw_ops) { + if (err) { kfree(counter); - return NULL; + return ERR_PTR(err); } -done: + counter->hw_ops = hw_ops; return counter; @@ -2583,10 +2590,10 @@ SYSCALL_DEFINE5(perf_counter_open, goto err_put_context; } - ret = -EINVAL; counter = perf_counter_alloc(&hw_event, cpu, ctx, group_leader, GFP_KERNEL); - if (!counter) + ret = PTR_ERR(counter); + if (IS_ERR(counter)) goto err_put_context; ret = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0); @@ -2658,8 +2665,8 @@ inherit_counter(struct perf_counter *parent_counter, child_counter = perf_counter_alloc(&parent_counter->hw_event, parent_counter->cpu, child_ctx, group_leader, GFP_KERNEL); - if (!child_counter) - return NULL; + if (IS_ERR(child_counter)) + return child_counter; /* * Link it up in the child's context: @@ -2710,15 +2717,17 @@ static int inherit_group(struct perf_counter *parent_counter, { struct perf_counter *leader; struct perf_counter *sub; + struct perf_counter *child_ctr; leader = inherit_counter(parent_counter, parent, parent_ctx, child, NULL, child_ctx); - if (!leader) - return -ENOMEM; + if (IS_ERR(leader)) + return PTR_ERR(leader); list_for_each_entry(sub, &parent_counter->sibling_list, list_entry) { - if (!inherit_counter(sub, parent, parent_ctx, - child, leader, child_ctx)) - return -ENOMEM; + child_ctr = inherit_counter(sub, parent, parent_ctx, + child, leader, child_ctx); + if (IS_ERR(child_ctr)) + return PTR_ERR(child_ctr); } return 0; } -- GitLab From 9ea98e191255ee642e64a5745014424fc63f83b0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:09 +0200 Subject: [PATCH 0167/6080] perf_counter: x86: proper error propagation for the x86 hw_perf_counter_init() Now that Paul cleaned up the error propagation paths, pass down the x86 error as well. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171023.792822360@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 7aab177fb566..b8885ccd8049 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -954,7 +954,7 @@ hw_perf_counter_init(struct perf_counter *counter) err = __hw_perf_counter_init(counter); if (err) - return NULL; + return ERR_PTR(err); return &x86_perf_counter_ops; } -- GitLab From 31f004df8d14212f0a8a2fb12a8ed44a3d80e2fb Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 30 Mar 2009 19:07:10 +0200 Subject: [PATCH 0168/6080] perf_counter tools: optionally scale counter values in perfstat mode Impact: new functionality This adds add an option to the perfstat mode of kerneltop to scale the reported counter values according to the fraction of time that each counter gets to count. This is invoked with the -l option (I used 'l' because s, c, a and e were all taken already.) This uses the new PERF_RECORD_TOTAL_TIME_{ENABLED,RUNNING} read format options. With this, we get output like this: $ ./perfstat -l -e 0:0,0:1,0:2,0:3,0:4,0:5 ./spin Performance counter stats for './spin': 4016072055 CPU cycles (events) (scaled from 66.53%) 2005887318 instructions (events) (scaled from 66.53%) 1762849 cache references (events) (scaled from 66.69%) 165229 cache misses (events) (scaled from 66.85%) 1001298009 branches (events) (scaled from 66.78%) 41566 branch misses (events) (scaled from 66.61%) Wall-clock time elapsed: 2438.227446 msecs This also lets us detect when a counter is zero because the counter never got to go on the CPU at all. In that case we print rather than 0. Signed-off-by: Paul Mackerras Signed-off-by: Peter Zijlstra Orig-LKML-Reference: <20090330171023.871484899@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 56 +++++++++++++++++++++----- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 995111dee7fb..c0ca01504ff3 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -197,6 +197,8 @@ static int delay_secs = 2; static int zero; static int dump_symtab; +static int scale; + struct source_line { uint64_t EIP; unsigned long count; @@ -305,6 +307,7 @@ static void display_perfstat_help(void) display_events_help(); printf( + " -l # scale counter values\n" " -a # system-wide collection\n"); exit(0); } @@ -328,6 +331,7 @@ static void display_help(void) " -c CNT --count=CNT # event period to sample\n\n" " -C CPU --cpu=CPU # CPU (-1 for all) [default: -1]\n" " -p PID --pid=PID # PID of sampled task (-1 for all) [default: -1]\n\n" + " -l # show scale factor for RR events\n" " -d delay --delay= # sampling/display delay [default: 2]\n" " -f CNT --filter=CNT # min-event-count filter [default: 100]\n\n" " -s symbol --symbol= # function to be showed annotated one-shot\n" @@ -436,6 +440,9 @@ static void create_perfstat_counter(int counter) hw_event.config = event_id[counter]; hw_event.record_type = PERF_RECORD_SIMPLE; hw_event.nmi = 0; + if (scale) + hw_event.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | + PERF_FORMAT_TOTAL_TIME_RUNNING; if (system_wide) { int cpu; @@ -507,28 +514,53 @@ int do_perfstat(int argc, char *argv[]) fprintf(stderr, "\n"); for (counter = 0; counter < nr_counters; counter++) { - int cpu; - __u64 count, single_count; + int cpu, nv; + __u64 count[3], single_count[3]; + int scaled; - count = 0; + count[0] = count[1] = count[2] = 0; + nv = scale ? 3 : 1; for (cpu = 0; cpu < nr_cpus; cpu ++) { res = read(fd[cpu][counter], - (char *) &single_count, sizeof(single_count)); - assert(res == sizeof(single_count)); - count += single_count; + single_count, nv * sizeof(__u64)); + assert(res == nv * sizeof(__u64)); + + count[0] += single_count[0]; + if (scale) { + count[1] += single_count[1]; + count[2] += single_count[2]; + } + } + + scaled = 0; + if (scale) { + if (count[2] == 0) { + fprintf(stderr, " %14s %-20s\n", + "", event_name(counter)); + continue; + } + if (count[2] < count[1]) { + scaled = 1; + count[0] = (unsigned long long) + ((double)count[0] * count[1] / count[2] + 0.5); + } } if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK) || event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK)) { - double msecs = (double)count / 1000000; + double msecs = (double)count[0] / 1000000; - fprintf(stderr, " %14.6f %-20s (msecs)\n", + fprintf(stderr, " %14.6f %-20s (msecs)", msecs, event_name(counter)); } else { - fprintf(stderr, " %14Ld %-20s (events)\n", - count, event_name(counter)); + fprintf(stderr, " %14Ld %-20s (events)", + count[0], event_name(counter)); } + if (scaled) + fprintf(stderr, " (scaled from %.2f%%)", + (double) count[2] / count[1] * 100); + fprintf(stderr, "\n"); } fprintf(stderr, "\n"); fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", @@ -1049,6 +1081,7 @@ static void process_options(int argc, char *argv[]) {"filter", required_argument, NULL, 'f'}, {"group", required_argument, NULL, 'g'}, {"help", no_argument, NULL, 'h'}, + {"scale", no_argument, NULL, 'l'}, {"nmi", required_argument, NULL, 'n'}, {"pid", required_argument, NULL, 'p'}, {"vmlinux", required_argument, NULL, 'x'}, @@ -1060,7 +1093,7 @@ static void process_options(int argc, char *argv[]) {"munmap_info", no_argument, NULL, 'U'}, {NULL, 0, NULL, 0 } }; - int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hn:m:p:s:Sx:zMU", + int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hln:m:p:s:Sx:zMU", long_options, &option_index); if (c == -1) break; @@ -1084,6 +1117,7 @@ static void process_options(int argc, char *argv[]) case 'f': count_filter = atoi(optarg); break; case 'g': group = atoi(optarg); break; case 'h': display_help(); break; + case 'l': scale = 1; break; case 'n': nmi = atoi(optarg); break; case 'p': /* CPU and PID are mutually exclusive */ -- GitLab From 78d613eb129fc4edf0e2cabfcc6a4c5285482d21 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:11 +0200 Subject: [PATCH 0169/6080] perf_counter: small cleanup of the output routines Move the nmi argument to the _begin() function, so that _end() only needs the handle. This allows the _begin() function to generate a wakeup on event loss. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171023.959404268@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index d07b45278b4f..4471e7e2c109 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1663,10 +1663,20 @@ struct perf_output_handle { unsigned int offset; unsigned int head; int wakeup; + int nmi; }; +static inline void __perf_output_wakeup(struct perf_output_handle *handle) +{ + if (handle->nmi) + perf_pending_queue(handle->counter); + else + perf_counter_wakeup(handle->counter); +} + static int perf_output_begin(struct perf_output_handle *handle, - struct perf_counter *counter, unsigned int size) + struct perf_counter *counter, unsigned int size, + int nmi) { struct perf_mmap_data *data; unsigned int offset, head; @@ -1676,15 +1686,17 @@ static int perf_output_begin(struct perf_output_handle *handle, if (!data) goto out; + handle->counter = counter; + handle->nmi = nmi; + if (!data->nr_pages) - goto out; + goto fail; do { offset = head = atomic_read(&data->head); head += size; } while (atomic_cmpxchg(&data->head, offset, head) != offset); - handle->counter = counter; handle->data = data; handle->offset = offset; handle->head = head; @@ -1692,6 +1704,8 @@ static int perf_output_begin(struct perf_output_handle *handle, return 0; +fail: + __perf_output_wakeup(handle); out: rcu_read_unlock(); @@ -1733,14 +1747,10 @@ static void perf_output_copy(struct perf_output_handle *handle, #define perf_output_put(handle, x) \ perf_output_copy((handle), &(x), sizeof(x)) -static void perf_output_end(struct perf_output_handle *handle, int nmi) +static void perf_output_end(struct perf_output_handle *handle) { - if (handle->wakeup) { - if (nmi) - perf_pending_queue(handle->counter); - else - perf_counter_wakeup(handle->counter); - } + if (handle->wakeup) + __perf_output_wakeup(handle); rcu_read_unlock(); } @@ -1750,12 +1760,12 @@ static int perf_output_write(struct perf_counter *counter, int nmi, struct perf_output_handle handle; int ret; - ret = perf_output_begin(&handle, counter, size); + ret = perf_output_begin(&handle, counter, size, nmi); if (ret) goto out; perf_output_copy(&handle, buf, size); - perf_output_end(&handle, nmi); + perf_output_end(&handle); out: return ret; @@ -1804,7 +1814,7 @@ static void perf_output_group(struct perf_counter *counter, int nmi) size = sizeof(header) + counter->nr_siblings * sizeof(entry); - ret = perf_output_begin(&handle, counter, size); + ret = perf_output_begin(&handle, counter, size, nmi); if (ret) return; @@ -1824,7 +1834,7 @@ static void perf_output_group(struct perf_counter *counter, int nmi) perf_output_put(&handle, entry); } - perf_output_end(&handle, nmi); + perf_output_end(&handle); } void perf_counter_output(struct perf_counter *counter, @@ -1869,7 +1879,7 @@ static void perf_counter_mmap_output(struct perf_counter *counter, { struct perf_output_handle handle; int size = mmap_event->event.header.size; - int ret = perf_output_begin(&handle, counter, size); + int ret = perf_output_begin(&handle, counter, size, 0); if (ret) return; @@ -1877,7 +1887,7 @@ static void perf_counter_mmap_output(struct perf_counter *counter, perf_output_put(&handle, mmap_event->event); perf_output_copy(&handle, mmap_event->file_name, mmap_event->file_size); - perf_output_end(&handle, 0); + perf_output_end(&handle); } static int perf_counter_mmap_match(struct perf_counter *counter, -- GitLab From 5ed00415e304203a0a9dcaef226d6d3f1106070e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:12 +0200 Subject: [PATCH 0170/6080] perf_counter: re-arrange the perf_event_type Breaks ABI yet again :-) Change the event type so that [0, 2^31-1] are regular event types, but [2^31, 2^32-1] forms a bitmask for overflow events. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171024.047961770@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 6 ++-- kernel/perf_counter.c | 56 ++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 037a81145aca..edf5bfb7ff51 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -210,13 +210,15 @@ struct perf_event_header { }; enum perf_event_type { - PERF_EVENT_IP = 0, + PERF_EVENT_GROUP = 1, PERF_EVENT_MMAP = 2, PERF_EVENT_MUNMAP = 3, - __PERF_EVENT_TID = 0x100, + PERF_EVENT_OVERFLOW = 1UL << 31, + __PERF_EVENT_IP = 1UL << 30, + __PERF_EVENT_TID = 1UL << 29, }; #ifdef __KERNEL__ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 4471e7e2c109..d93e9ddf7848 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1754,50 +1754,44 @@ static void perf_output_end(struct perf_output_handle *handle) rcu_read_unlock(); } -static int perf_output_write(struct perf_counter *counter, int nmi, - void *buf, ssize_t size) -{ - struct perf_output_handle handle; - int ret; - - ret = perf_output_begin(&handle, counter, size, nmi); - if (ret) - goto out; - - perf_output_copy(&handle, buf, size); - perf_output_end(&handle); - -out: - return ret; -} - static void perf_output_simple(struct perf_counter *counter, int nmi, struct pt_regs *regs) { - unsigned int size; + int ret; + struct perf_output_handle handle; + struct perf_event_header header; + u64 ip; struct { - struct perf_event_header header; - u64 ip; u32 pid, tid; - } event; + } tid_entry; - event.header.type = PERF_EVENT_IP; - event.ip = instruction_pointer(regs); + header.type = PERF_EVENT_OVERFLOW; + header.size = sizeof(header); - size = sizeof(event); + ip = instruction_pointer(regs); + header.type |= __PERF_EVENT_IP; + header.size += sizeof(ip); if (counter->hw_event.include_tid) { /* namespace issues */ - event.pid = current->group_leader->pid; - event.tid = current->pid; + tid_entry.pid = current->group_leader->pid; + tid_entry.tid = current->pid; - event.header.type |= __PERF_EVENT_TID; - } else - size -= sizeof(u64); + header.type |= __PERF_EVENT_TID; + header.size += sizeof(tid_entry); + } - event.header.size = size; + ret = perf_output_begin(&handle, counter, header.size, nmi); + if (ret) + return; + + perf_output_put(&handle, header); + perf_output_put(&handle, ip); + + if (counter->hw_event.include_tid) + perf_output_put(&handle, tid_entry); - perf_output_write(counter, nmi, &event, size); + perf_output_end(&handle); } static void perf_output_group(struct perf_counter *counter, int nmi) -- GitLab From 023c54c42288416b4f43c67bfd5049a76926fad6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:13 +0200 Subject: [PATCH 0171/6080] perf_counter tools: kerneltop: update event_types Go along with the new perf_event_type ABI. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171024.133985461@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index c0ca01504ff3..430810dae1fe 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -1263,8 +1263,8 @@ static void mmap_read(struct mmap_data *md) old += size; switch (event->header.type) { - case PERF_EVENT_IP: - case PERF_EVENT_IP | __PERF_EVENT_TID: + case PERF_EVENT_OVERFLOW | __PERF_EVENT_IP: + case PERF_EVENT_OVERFLOW | __PERF_EVENT_IP | __PERF_EVENT_TID: process_event(event->ip.ip, md->counter); break; -- GitLab From 394ee07623cf556c8daae2b3c00cf5fea47f0811 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:14 +0200 Subject: [PATCH 0172/6080] perf_counter: provide generic callchain bits Provide the generic callchain support bits. If hw_event->callchain is set the arch specific perf_callchain() function is called upon to provide a perf_callchain_entry structure filled with the current callchain. If it does so, it is added to the overflow output event. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171024.254266860@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 13 ++++++++++++- kernel/perf_counter.c | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index edf5bfb7ff51..43083afffe0f 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -140,8 +140,9 @@ struct perf_counter_hw_event { include_tid : 1, /* include the tid */ mmap : 1, /* include mmap data */ munmap : 1, /* include munmap data */ + callchain : 1, /* add callchain data */ - __reserved_1 : 52; + __reserved_1 : 51; __u32 extra_config_len; __u32 __reserved_4; @@ -219,6 +220,7 @@ enum perf_event_type { PERF_EVENT_OVERFLOW = 1UL << 31, __PERF_EVENT_IP = 1UL << 30, __PERF_EVENT_TID = 1UL << 29, + __PERF_EVENT_CALLCHAIN = 1UL << 28, }; #ifdef __KERNEL__ @@ -504,6 +506,15 @@ extern void perf_counter_mmap(unsigned long addr, unsigned long len, extern void perf_counter_munmap(unsigned long addr, unsigned long len, unsigned long pgoff, struct file *file); +#define MAX_STACK_DEPTH 255 + +struct perf_callchain_entry { + u64 nr; + u64 ip[MAX_STACK_DEPTH]; +}; + +extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs); + #else static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index d93e9ddf7848..860cdc26bd7a 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1653,6 +1653,17 @@ void perf_counter_do_pending(void) __perf_pending_run(); } +/* + * Callchain support -- arch specific + */ + +struct perf_callchain_entry * +__attribute__((weak)) +perf_callchain(struct pt_regs *regs) +{ + return NULL; +} + /* * Output */ @@ -1764,6 +1775,8 @@ static void perf_output_simple(struct perf_counter *counter, struct { u32 pid, tid; } tid_entry; + struct perf_callchain_entry *callchain = NULL; + int callchain_size = 0; header.type = PERF_EVENT_OVERFLOW; header.size = sizeof(header); @@ -1781,6 +1794,17 @@ static void perf_output_simple(struct perf_counter *counter, header.size += sizeof(tid_entry); } + if (counter->hw_event.callchain) { + callchain = perf_callchain(regs); + + if (callchain) { + callchain_size = (1 + callchain->nr) * sizeof(u64); + + header.type |= __PERF_EVENT_CALLCHAIN; + header.size += callchain_size; + } + } + ret = perf_output_begin(&handle, counter, header.size, nmi); if (ret) return; @@ -1791,6 +1815,9 @@ static void perf_output_simple(struct perf_counter *counter, if (counter->hw_event.include_tid) perf_output_put(&handle, tid_entry); + if (callchain) + perf_output_copy(&handle, callchain, callchain_size); + perf_output_end(&handle); } -- GitLab From d7d59fb323833682b117b528d77eeb8ef587036a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:15 +0200 Subject: [PATCH 0173/6080] perf_counter: x86: callchain support Provide the x86 perf_callchain() implementation. Code based on the ftrace/sysprof code from Soeren Sandmann Pedersen. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Cc: Soeren Sandmann Pedersen Cc: Frederic Weisbecker Cc: Steven Rostedt Orig-LKML-Reference: <20090330171024.341993293@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 154 +++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index b8885ccd8049..e16dfafc6d72 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -16,8 +16,10 @@ #include #include #include +#include #include +#include static bool perf_counters_initialized __read_mostly; @@ -958,3 +960,155 @@ hw_perf_counter_init(struct perf_counter *counter) return &x86_perf_counter_ops; } + +/* + * callchain support + */ + +static inline +void callchain_store(struct perf_callchain_entry *entry, unsigned long ip) +{ + if (entry->nr < MAX_STACK_DEPTH) + entry->ip[entry->nr++] = ip; +} + +static DEFINE_PER_CPU(struct perf_callchain_entry, irq_entry); +static DEFINE_PER_CPU(struct perf_callchain_entry, nmi_entry); + + +static void +backtrace_warning_symbol(void *data, char *msg, unsigned long symbol) +{ + /* Ignore warnings */ +} + +static void backtrace_warning(void *data, char *msg) +{ + /* Ignore warnings */ +} + +static int backtrace_stack(void *data, char *name) +{ + /* Don't bother with IRQ stacks for now */ + return -1; +} + +static void backtrace_address(void *data, unsigned long addr, int reliable) +{ + struct perf_callchain_entry *entry = data; + + if (reliable) + callchain_store(entry, addr); +} + +static const struct stacktrace_ops backtrace_ops = { + .warning = backtrace_warning, + .warning_symbol = backtrace_warning_symbol, + .stack = backtrace_stack, + .address = backtrace_address, +}; + +static void +perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) +{ + unsigned long bp; + char *stack; + + callchain_store(entry, instruction_pointer(regs)); + + stack = ((char *)regs + sizeof(struct pt_regs)); +#ifdef CONFIG_FRAME_POINTER + bp = frame_pointer(regs); +#else + bp = 0; +#endif + + dump_trace(NULL, regs, (void *)stack, bp, &backtrace_ops, entry); +} + + +struct stack_frame { + const void __user *next_fp; + unsigned long return_address; +}; + +static int copy_stack_frame(const void __user *fp, struct stack_frame *frame) +{ + int ret; + + if (!access_ok(VERIFY_READ, fp, sizeof(*frame))) + return 0; + + ret = 1; + pagefault_disable(); + if (__copy_from_user_inatomic(frame, fp, sizeof(*frame))) + ret = 0; + pagefault_enable(); + + return ret; +} + +static void +perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) +{ + struct stack_frame frame; + const void __user *fp; + + regs = (struct pt_regs *)current->thread.sp0 - 1; + fp = (void __user *)regs->bp; + + callchain_store(entry, regs->ip); + + while (entry->nr < MAX_STACK_DEPTH) { + frame.next_fp = NULL; + frame.return_address = 0; + + if (!copy_stack_frame(fp, &frame)) + break; + + if ((unsigned long)fp < user_stack_pointer(regs)) + break; + + callchain_store(entry, frame.return_address); + fp = frame.next_fp; + } +} + +static void +perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry) +{ + int is_user; + + if (!regs) + return; + + is_user = user_mode(regs); + + if (!current || current->pid == 0) + return; + + if (is_user && current->state != TASK_RUNNING) + return; + + if (!is_user) + perf_callchain_kernel(regs, entry); + + if (current->mm) + perf_callchain_user(regs, entry); +} + +struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) +{ + struct perf_callchain_entry *entry; + + if (in_nmi()) + entry = &__get_cpu_var(nmi_entry); + else + entry = &__get_cpu_var(irq_entry); + + entry->nr = 0; + + perf_do_callchain(regs, entry); + + return entry; +} -- GitLab From 4e935e47177c3b26cf383e79849bae2a464d0160 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 30 Mar 2009 19:07:16 +0200 Subject: [PATCH 0174/6080] perf_counter: pmc arbitration Follow the example set by powerpc and try to play nice with oprofile and the nmi watchdog. Signed-off-by: Peter Zijlstra Acked-by: Paul Mackerras Orig-LKML-Reference: <20090330171024.459968444@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index e16dfafc6d72..2a946a160cac 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -20,6 +20,7 @@ #include #include +#include static bool perf_counters_initialized __read_mostly; @@ -172,6 +173,65 @@ again: atomic64_sub(delta, &hwc->period_left); } +static atomic_t num_counters; +static DEFINE_MUTEX(pmc_reserve_mutex); + +static bool reserve_pmc_hardware(void) +{ + int i; + + if (nmi_watchdog == NMI_LOCAL_APIC) + disable_lapic_nmi_watchdog(); + + for (i = 0; i < nr_counters_generic; i++) { + if (!reserve_perfctr_nmi(pmc_ops->perfctr + i)) + goto perfctr_fail; + } + + for (i = 0; i < nr_counters_generic; i++) { + if (!reserve_evntsel_nmi(pmc_ops->eventsel + i)) + goto eventsel_fail; + } + + return true; + +eventsel_fail: + for (i--; i >= 0; i--) + release_evntsel_nmi(pmc_ops->eventsel + i); + + i = nr_counters_generic; + +perfctr_fail: + for (i--; i >= 0; i--) + release_perfctr_nmi(pmc_ops->perfctr + i); + + if (nmi_watchdog == NMI_LOCAL_APIC) + enable_lapic_nmi_watchdog(); + + return false; +} + +static void release_pmc_hardware(void) +{ + int i; + + for (i = 0; i < nr_counters_generic; i++) { + release_perfctr_nmi(pmc_ops->perfctr + i); + release_evntsel_nmi(pmc_ops->eventsel + i); + } + + if (nmi_watchdog == NMI_LOCAL_APIC) + enable_lapic_nmi_watchdog(); +} + +static void hw_perf_counter_destroy(struct perf_counter *counter) +{ + if (atomic_dec_and_mutex_lock(&num_counters, &pmc_reserve_mutex)) { + release_pmc_hardware(); + mutex_unlock(&pmc_reserve_mutex); + } +} + /* * Setup the hardware configuration for a given hw_event_type */ @@ -179,10 +239,23 @@ static int __hw_perf_counter_init(struct perf_counter *counter) { struct perf_counter_hw_event *hw_event = &counter->hw_event; struct hw_perf_counter *hwc = &counter->hw; + int err; if (unlikely(!perf_counters_initialized)) return -EINVAL; + err = 0; + if (atomic_inc_not_zero(&num_counters)) { + mutex_lock(&pmc_reserve_mutex); + if (atomic_read(&num_counters) == 0 && !reserve_pmc_hardware()) + err = -EBUSY; + else + atomic_inc(&num_counters); + mutex_unlock(&pmc_reserve_mutex); + } + if (err) + return err; + /* * Generate PMC IRQs: * (keep 'enabled' bit clear for now) @@ -230,6 +303,8 @@ static int __hw_perf_counter_init(struct perf_counter *counter) hwc->config |= pmc_ops->event_map(perf_event_id(hw_event)); } + counter->destroy = hw_perf_counter_destroy; + return 0; } -- GitLab From 9dd499889bdb12ac0e412ccdd718fe0d348258f2 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Fri, 27 Mar 2009 12:13:43 +0100 Subject: [PATCH 0175/6080] perf_counter tools: kerneltop: add real-time data acquisition thread Decouple kerneltop display from event acquisition by introducing a separate data acquisition thread. This fixes annnoying kerneltop display refresh jitter and missed events. Also add a -r option, to switch the data acquisition thread to real-time priority. Signed-off-by: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Orig-LKML-Reference: Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 57 ++++++++++++++++++-------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 430810dae1fe..33b4fcf6e489 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -77,6 +77,8 @@ #include #include #include +#include +#include #include #include @@ -181,6 +183,7 @@ static int tid = -1; static int profile_cpu = -1; static int nr_cpus = 0; static int nmi = 1; +static unsigned int realtime_prio = 0; static int group = 0; static unsigned int page_size; static unsigned int mmap_pages = 16; @@ -334,6 +337,7 @@ static void display_help(void) " -l # show scale factor for RR events\n" " -d delay --delay= # sampling/display delay [default: 2]\n" " -f CNT --filter=CNT # min-event-count filter [default: 100]\n\n" + " -r prio --realtime= # event acquisition runs with SCHED_FIFO policy\n" " -s symbol --symbol= # function to be showed annotated one-shot\n" " -x path --vmlinux= # the vmlinux binary, required for -s use\n" " -z --zero # zero counts after display\n" @@ -620,7 +624,6 @@ static int compare(const void *__sym1, const void *__sym2) return sym_weight(sym1) < sym_weight(sym2); } -static time_t last_refresh; static long events; static long userspace_events; static const char CONSOLE_CLEAR[] = ""; @@ -634,6 +637,7 @@ static void print_sym_table(void) float events_per_sec = events/delay_secs; float kevents_per_sec = (events-userspace_events)/delay_secs; + events = userspace_events = 0; memcpy(tmp, sym_table, sizeof(sym_table[0])*sym_table_count); qsort(tmp, sym_table_count, sizeof(tmp[0]), compare); @@ -714,8 +718,6 @@ static void print_sym_table(void) if (sym_filter_entry) show_details(sym_filter_entry); - last_refresh = time(NULL); - { struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; @@ -726,6 +728,16 @@ static void print_sym_table(void) } } +static void *display_thread(void *arg) +{ + printf("KernelTop refresh period: %d seconds\n", delay_secs); + + while (!sleep(delay_secs)) + print_sym_table(); + + return NULL; +} + static int read_symbol(FILE *in, struct sym_entry *s) { static int filter_match = 0; @@ -1081,19 +1093,20 @@ static void process_options(int argc, char *argv[]) {"filter", required_argument, NULL, 'f'}, {"group", required_argument, NULL, 'g'}, {"help", no_argument, NULL, 'h'}, - {"scale", no_argument, NULL, 'l'}, {"nmi", required_argument, NULL, 'n'}, + {"mmap_info", no_argument, NULL, 'M'}, + {"mmap_pages", required_argument, NULL, 'm'}, + {"munmap_info", no_argument, NULL, 'U'}, {"pid", required_argument, NULL, 'p'}, - {"vmlinux", required_argument, NULL, 'x'}, + {"realtime", required_argument, NULL, 'r'}, + {"scale", no_argument, NULL, 'l'}, {"symbol", required_argument, NULL, 's'}, {"stat", no_argument, NULL, 'S'}, + {"vmlinux", required_argument, NULL, 'x'}, {"zero", no_argument, NULL, 'z'}, - {"mmap_pages", required_argument, NULL, 'm'}, - {"mmap_info", no_argument, NULL, 'M'}, - {"munmap_info", no_argument, NULL, 'U'}, {NULL, 0, NULL, 0 } }; - int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hln:m:p:s:Sx:zMU", + int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hln:m:p:r:s:Sx:zMU", long_options, &option_index); if (c == -1) break; @@ -1127,6 +1140,7 @@ static void process_options(int argc, char *argv[]) profile_cpu = -1; } tid = atoi(optarg); break; + case 'r': realtime_prio = atoi(optarg); break; case 's': sym_filter = strdup(optarg); break; case 'S': run_perfstat = 1; break; case 'x': vmlinux = strdup(optarg); break; @@ -1289,6 +1303,7 @@ int main(int argc, char *argv[]) struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; struct perf_counter_hw_event hw_event; + pthread_t thread; int i, counter, group_fd, nr_poll = 0; unsigned int cpu; int ret; @@ -1363,8 +1378,20 @@ int main(int argc, char *argv[]) } } - printf("KernelTop refresh period: %d seconds\n", delay_secs); - last_refresh = time(NULL); + if (pthread_create(&thread, NULL, display_thread, NULL)) { + printf("Could not create display thread.\n"); + exit(-1); + } + + if (realtime_prio) { + struct sched_param param; + + param.sched_priority = realtime_prio; + if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { + printf("Could not set realtime priority.\n"); + exit(-1); + } + } while (1) { int hits = events; @@ -1374,14 +1401,8 @@ int main(int argc, char *argv[]) mmap_read(&mmap_array[i][counter]); } - if (time(NULL) >= last_refresh + delay_secs) { - print_sym_table(); - events = userspace_events = 0; - } - if (hits == events) - ret = poll(event_array, nr_poll, 1000); - hits = events; + ret = poll(event_array, nr_poll, 100); } return 0; -- GitLab From 8a057d84912f36e53f970c4d177cb4bb6b2f9e08 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 2 Apr 2009 11:11:59 +0200 Subject: [PATCH 0176/6080] perf_counter: move the event overflow output bits to record_type Per suggestion from Paul, move the event overflow bits to record_type and sanitize the enums a bit. Breaks the ABI -- again ;-) Suggested-by: Paul Mackerras Signed-off-by: Peter Zijlstra Cc: Corey Ashford Orig-LKML-Reference: <20090402091319.151921176@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 50 +++++++++-------- kernel/perf_counter.c | 101 ++++++++++++++--------------------- 2 files changed, 68 insertions(+), 83 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 43083afffe0f..06a6fba9f531 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -73,15 +73,6 @@ enum sw_event_ids { PERF_SW_EVENTS_MAX = 7, }; -/* - * IRQ-notification data record type: - */ -enum perf_counter_record_type { - PERF_RECORD_SIMPLE = 0, - PERF_RECORD_IRQ = 1, - PERF_RECORD_GROUP = 2, -}; - #define __PERF_COUNTER_MASK(name) \ (((1ULL << PERF_COUNTER_##name##_BITS) - 1) << \ PERF_COUNTER_##name##_SHIFT) @@ -102,6 +93,17 @@ enum perf_counter_record_type { #define PERF_COUNTER_EVENT_SHIFT 0 #define PERF_COUNTER_EVENT_MASK __PERF_COUNTER_MASK(EVENT) +/* + * Bits that can be set in hw_event.record_type to request information + * in the overflow packets. + */ +enum perf_counter_record_format { + PERF_RECORD_IP = 1U << 0, + PERF_RECORD_TID = 1U << 1, + PERF_RECORD_GROUP = 1U << 2, + PERF_RECORD_CALLCHAIN = 1U << 3, +}; + /* * Bits that can be set in hw_event.read_format to request that * reads on the counter should return the indicated quantities, @@ -125,8 +127,8 @@ struct perf_counter_hw_event { __u64 config; __u64 irq_period; - __u64 record_type; - __u64 read_format; + __u32 record_type; + __u32 read_format; __u64 disabled : 1, /* off by default */ nmi : 1, /* NMI sampling */ @@ -137,12 +139,10 @@ struct perf_counter_hw_event { exclude_kernel : 1, /* ditto kernel */ exclude_hv : 1, /* ditto hypervisor */ exclude_idle : 1, /* don't count when idle */ - include_tid : 1, /* include the tid */ mmap : 1, /* include mmap data */ munmap : 1, /* include munmap data */ - callchain : 1, /* add callchain data */ - __reserved_1 : 51; + __reserved_1 : 53; __u32 extra_config_len; __u32 __reserved_4; @@ -212,15 +212,21 @@ struct perf_event_header { enum perf_event_type { - PERF_EVENT_GROUP = 1, - - PERF_EVENT_MMAP = 2, - PERF_EVENT_MUNMAP = 3, + PERF_EVENT_MMAP = 1, + PERF_EVENT_MUNMAP = 2, - PERF_EVENT_OVERFLOW = 1UL << 31, - __PERF_EVENT_IP = 1UL << 30, - __PERF_EVENT_TID = 1UL << 29, - __PERF_EVENT_CALLCHAIN = 1UL << 28, + /* + * Half the event type space is reserved for the counter overflow + * bitfields, as found in hw_event.record_type. + * + * These events will have types of the form: + * PERF_EVENT_COUNTER_OVERFLOW { | __PERF_EVENT_* } * + */ + PERF_EVENT_COUNTER_OVERFLOW = 1UL << 31, + __PERF_EVENT_IP = PERF_RECORD_IP, + __PERF_EVENT_TID = PERF_RECORD_TID, + __PERF_EVENT_GROUP = PERF_RECORD_GROUP, + __PERF_EVENT_CALLCHAIN = PERF_RECORD_CALLCHAIN, }; #ifdef __KERNEL__ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 860cdc26bd7a..995063df910f 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1765,27 +1765,34 @@ static void perf_output_end(struct perf_output_handle *handle) rcu_read_unlock(); } -static void perf_output_simple(struct perf_counter *counter, - int nmi, struct pt_regs *regs) +void perf_counter_output(struct perf_counter *counter, + int nmi, struct pt_regs *regs) { int ret; + u64 record_type = counter->hw_event.record_type; struct perf_output_handle handle; struct perf_event_header header; u64 ip; struct { u32 pid, tid; } tid_entry; + struct { + u64 event; + u64 counter; + } group_entry; struct perf_callchain_entry *callchain = NULL; int callchain_size = 0; - header.type = PERF_EVENT_OVERFLOW; + header.type = PERF_EVENT_COUNTER_OVERFLOW; header.size = sizeof(header); - ip = instruction_pointer(regs); - header.type |= __PERF_EVENT_IP; - header.size += sizeof(ip); + if (record_type & PERF_RECORD_IP) { + ip = instruction_pointer(regs); + header.type |= __PERF_EVENT_IP; + header.size += sizeof(ip); + } - if (counter->hw_event.include_tid) { + if (record_type & PERF_RECORD_TID) { /* namespace issues */ tid_entry.pid = current->group_leader->pid; tid_entry.tid = current->pid; @@ -1794,7 +1801,13 @@ static void perf_output_simple(struct perf_counter *counter, header.size += sizeof(tid_entry); } - if (counter->hw_event.callchain) { + if (record_type & PERF_RECORD_GROUP) { + header.type |= __PERF_EVENT_GROUP; + header.size += sizeof(u64) + + counter->nr_siblings * sizeof(group_entry); + } + + if (record_type & PERF_RECORD_CALLCHAIN) { callchain = perf_callchain(regs); if (callchain) { @@ -1810,69 +1823,35 @@ static void perf_output_simple(struct perf_counter *counter, return; perf_output_put(&handle, header); - perf_output_put(&handle, ip); - if (counter->hw_event.include_tid) - perf_output_put(&handle, tid_entry); + if (record_type & PERF_RECORD_IP) + perf_output_put(&handle, ip); - if (callchain) - perf_output_copy(&handle, callchain, callchain_size); - - perf_output_end(&handle); -} - -static void perf_output_group(struct perf_counter *counter, int nmi) -{ - struct perf_output_handle handle; - struct perf_event_header header; - struct perf_counter *leader, *sub; - unsigned int size; - struct { - u64 event; - u64 counter; - } entry; - int ret; - - size = sizeof(header) + counter->nr_siblings * sizeof(entry); + if (record_type & PERF_RECORD_TID) + perf_output_put(&handle, tid_entry); - ret = perf_output_begin(&handle, counter, size, nmi); - if (ret) - return; + if (record_type & PERF_RECORD_GROUP) { + struct perf_counter *leader, *sub; + u64 nr = counter->nr_siblings; - header.type = PERF_EVENT_GROUP; - header.size = size; + perf_output_put(&handle, nr); - perf_output_put(&handle, header); + leader = counter->group_leader; + list_for_each_entry(sub, &leader->sibling_list, list_entry) { + if (sub != counter) + sub->hw_ops->read(sub); - leader = counter->group_leader; - list_for_each_entry(sub, &leader->sibling_list, list_entry) { - if (sub != counter) - sub->hw_ops->read(sub); + group_entry.event = sub->hw_event.config; + group_entry.counter = atomic64_read(&sub->count); - entry.event = sub->hw_event.config; - entry.counter = atomic64_read(&sub->count); - - perf_output_put(&handle, entry); + perf_output_put(&handle, group_entry); + } } - perf_output_end(&handle); -} - -void perf_counter_output(struct perf_counter *counter, - int nmi, struct pt_regs *regs) -{ - switch (counter->hw_event.record_type) { - case PERF_RECORD_SIMPLE: - return; - - case PERF_RECORD_IRQ: - perf_output_simple(counter, nmi, regs); - break; + if (callchain) + perf_output_copy(&handle, callchain, callchain_size); - case PERF_RECORD_GROUP: - perf_output_group(counter, nmi); - break; - } + perf_output_end(&handle); } /* -- GitLab From c457810ab4a825161aec6ef71b581e1bc8febd1a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 2 Apr 2009 11:12:01 +0200 Subject: [PATCH 0177/6080] perf_counter: per event wakeups By request, provide a way to request a wakeup every 'n' events instead of every page of output. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford Orig-LKML-Reference: <20090402091319.323309784@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 3 ++- kernel/perf_counter.c | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 06a6fba9f531..5428ba120d78 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -145,7 +145,7 @@ struct perf_counter_hw_event { __reserved_1 : 53; __u32 extra_config_len; - __u32 __reserved_4; + __u32 wakeup_events; /* wakeup every n events */ __u64 __reserved_2; __u64 __reserved_3; @@ -321,6 +321,7 @@ struct perf_mmap_data { int nr_pages; atomic_t wakeup; atomic_t head; + atomic_t events; struct perf_counter_mmap_page *user_page; void *data_pages[0]; }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 995063df910f..9bcab10e735d 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1760,7 +1760,15 @@ static void perf_output_copy(struct perf_output_handle *handle, static void perf_output_end(struct perf_output_handle *handle) { - if (handle->wakeup) + int wakeup_events = handle->counter->hw_event.wakeup_events; + + if (wakeup_events) { + int events = atomic_inc_return(&handle->data->events); + if (events >= wakeup_events) { + atomic_sub(wakeup_events, &handle->data->events); + __perf_output_wakeup(handle); + } + } else if (handle->wakeup) __perf_output_wakeup(handle); rcu_read_unlock(); } -- GitLab From 3df70fd623bb109e0079e697c0276d220a4b7908 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 2 Apr 2009 11:12:02 +0200 Subject: [PATCH 0178/6080] perf_counter: kerneltop: update to new ABI Update to reflect the new record_type ABI changes. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford Orig-LKML-Reference: <20090402091319.407283141@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 33b4fcf6e489..4f8d7917aba1 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -442,7 +442,7 @@ static void create_perfstat_counter(int counter) memset(&hw_event, 0, sizeof(hw_event)); hw_event.config = event_id[counter]; - hw_event.record_type = PERF_RECORD_SIMPLE; + hw_event.record_type = 0; hw_event.nmi = 0; if (scale) hw_event.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | @@ -1277,8 +1277,8 @@ static void mmap_read(struct mmap_data *md) old += size; switch (event->header.type) { - case PERF_EVENT_OVERFLOW | __PERF_EVENT_IP: - case PERF_EVENT_OVERFLOW | __PERF_EVENT_IP | __PERF_EVENT_TID: + case PERF_EVENT_COUNTER_OVERFLOW | __PERF_EVENT_IP: + case PERF_EVENT_COUNTER_OVERFLOW | __PERF_EVENT_IP | __PERF_EVENT_TID: process_event(event->ip.ip, md->counter); break; @@ -1337,9 +1337,8 @@ int main(int argc, char *argv[]) memset(&hw_event, 0, sizeof(hw_event)); hw_event.config = event_id[counter]; hw_event.irq_period = event_count[counter]; - hw_event.record_type = PERF_RECORD_IRQ; + hw_event.record_type = PERF_RECORD_IP | PERF_RECORD_TID; hw_event.nmi = nmi; - hw_event.include_tid = 1; hw_event.mmap = use_mmap; hw_event.munmap = use_munmap; -- GitLab From 5872bdb88a35fae7d224bd6b21e5f377e854ccfc Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 2 Apr 2009 11:12:03 +0200 Subject: [PATCH 0179/6080] perf_counter: add more context information Put in counts to tell which ips belong to what context. ----- | | hv | -- nr | | kernel | -- | | user ----- Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford Orig-LKML-Reference: <20090402091319.493101305@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 9 +++++++++ include/linux/perf_counter.h | 4 ++-- kernel/perf_counter.c | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 2a946a160cac..c74e20d593a7 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -1088,6 +1088,7 @@ perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) { unsigned long bp; char *stack; + int nr = entry->nr; callchain_store(entry, instruction_pointer(regs)); @@ -1099,6 +1100,8 @@ perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) #endif dump_trace(NULL, regs, (void *)stack, bp, &backtrace_ops, entry); + + entry->kernel = entry->nr - nr; } @@ -1128,6 +1131,7 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) { struct stack_frame frame; const void __user *fp; + int nr = entry->nr; regs = (struct pt_regs *)current->thread.sp0 - 1; fp = (void __user *)regs->bp; @@ -1147,6 +1151,8 @@ perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry) callchain_store(entry, frame.return_address); fp = frame.next_fp; } + + entry->user = entry->nr - nr; } static void @@ -1182,6 +1188,9 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) entry = &__get_cpu_var(irq_entry); entry->nr = 0; + entry->hv = 0; + entry->kernel = 0; + entry->user = 0; perf_do_callchain(regs, entry); diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 5428ba120d78..90cce0c74a03 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -513,10 +513,10 @@ extern void perf_counter_mmap(unsigned long addr, unsigned long len, extern void perf_counter_munmap(unsigned long addr, unsigned long len, unsigned long pgoff, struct file *file); -#define MAX_STACK_DEPTH 255 +#define MAX_STACK_DEPTH 254 struct perf_callchain_entry { - u64 nr; + u32 nr, hv, kernel, user; u64 ip[MAX_STACK_DEPTH]; }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 9bcab10e735d..f105a6e696c2 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1819,7 +1819,7 @@ void perf_counter_output(struct perf_counter *counter, callchain = perf_callchain(regs); if (callchain) { - callchain_size = (1 + callchain->nr) * sizeof(u64); + callchain_size = (2 + callchain->nr) * sizeof(u64); header.type |= __PERF_EVENT_CALLCHAIN; header.size += callchain_size; -- GitLab From 92f22a3865abe87eea2609a6f8e5be5123f7ce4f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 2 Apr 2009 11:12:04 +0200 Subject: [PATCH 0180/6080] perf_counter: update mmap() counter read Paul noted that we don't need SMP barriers for the mmap() counter read because its always on the same cpu (otherwise you can't access the hw counter anyway). So remove the SMP barriers and replace them with regular compiler barriers. Further, update the comment to include a race free method of reading said hardware counter. The primary change is putting the pmc_read inside the seq-loop, otherwise we can still race and read rubbish. Noticed-by: Paul Mackerras Signed-off-by: Peter Zijlstra Cc: Corey Ashford Orig-LKML-Reference: <20090402091319.577951445@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 22 ++++++++++------------ kernel/perf_counter.c | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 90cce0c74a03..f2b914de3f0c 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -167,30 +167,28 @@ struct perf_counter_mmap_page { /* * Bits needed to read the hw counters in user-space. * - * The index and offset should be read atomically using the seqlock: - * - * __u32 seq, index; - * __s64 offset; + * u32 seq; + * s64 count; * * again: - * rmb(); * seq = pc->lock; - * * if (unlikely(seq & 1)) { * cpu_relax(); * goto again; * } * - * index = pc->index; - * offset = pc->offset; + * if (pc->index) { + * count = pmc_read(pc->index - 1); + * count += pc->offset; + * } else + * goto regular_read; * - * rmb(); + * barrier(); * if (pc->lock != seq) * goto again; * - * After this, index contains architecture specific counter index + 1, - * so that 0 means unavailable, offset contains the value to be added - * to the result of the raw timer read to obtain this counter's value. + * NOTE: for obvious reason this only works on self-monitoring + * processes. */ __u32 lock; /* seqlock for synchronization */ __u32 index; /* hardware counter identifier */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f105a6e696c2..2a5d4f525567 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1340,13 +1340,13 @@ void perf_counter_update_userpage(struct perf_counter *counter) */ preempt_disable(); ++userpg->lock; - smp_wmb(); + barrier(); userpg->index = counter->hw.idx; userpg->offset = atomic64_read(&counter->count); if (counter->state == PERF_COUNTER_STATE_ACTIVE) userpg->offset -= atomic64_read(&counter->hw.prev_count); - smp_wmb(); + barrier(); ++userpg->lock; preempt_enable(); unlock: -- GitLab From 80fbe6ac9b47cbc11e174a9bf853834dc281da35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gl=C3=B6ckner?= Date: Mon, 6 Apr 2009 11:50:22 +0200 Subject: [PATCH 0181/6080] ASoC: correct s6000 I2S clock polarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the data sheet data is clocked out on the falling edge and latched on the rising edge of the bit clock. While the left sample is transmitted the word clock line is low. Signed-off-by: Daniel Glöckner Signed-off-by: Mark Brown --- sound/soc/s6000/s6000-i2s.c | 4 ++-- sound/soc/s6000/s6105-ipcam.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index dcc79040bdac..c5cda187ecab 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c @@ -252,10 +252,10 @@ static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, } switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_IB_IF: + case SND_SOC_DAIFMT_NB_NF: w |= S6_I2S_LEFT_FIRST; break; - case SND_SOC_DAIFMT_IB_NF: + case SND_SOC_DAIFMT_NB_IF: w |= S6_I2S_RIGHT_FIRST; break; default: diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c index 21c4f55106ca..b5f95f9781c1 100644 --- a/sound/soc/s6000/s6105-ipcam.c +++ b/sound/soc/s6000/s6105-ipcam.c @@ -43,7 +43,7 @@ static int s6105_hw_params(struct snd_pcm_substream *substream, /* set cpu DAI configuration */ ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM | - SND_SOC_DAIFMT_IB_IF); + SND_SOC_DAIFMT_NB_NF); if (ret < 0) return ret; -- GitLab From 7ba5779533819fc061b4afafcb4a609d55f37057 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Mon, 6 Apr 2009 20:49:14 +0900 Subject: [PATCH 0182/6080] tomoyo: remove "undelete domain" command. Since TOMOYO's policy management tools does not use the "undelete domain" command, we decided to remove that command. Signed-off-by: Kentaro Takeda Signed-off-by: Tetsuo Handa Signed-off-by: Toshiharu Harada Signed-off-by: James Morris --- security/tomoyo/common.c | 7 +--- security/tomoyo/common.h | 8 +--- security/tomoyo/domain.c | 90 ++-------------------------------------- 3 files changed, 5 insertions(+), 100 deletions(-) diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 92cea656ad21..a0affd9cfca8 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -1252,15 +1252,12 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) struct tomoyo_domain_info *domain = head->write_var1; bool is_delete = false; bool is_select = false; - bool is_undelete = false; unsigned int profile; if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE)) is_delete = true; else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT)) is_select = true; - else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_UNDELETE)) - is_undelete = true; if (is_select && tomoyo_is_select_one(head, data)) return 0; /* Don't allow updating policies by non manager programs. */ @@ -1274,9 +1271,7 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) down_read(&tomoyo_domain_list_lock); domain = tomoyo_find_domain(data); up_read(&tomoyo_domain_list_lock); - } else if (is_undelete) - domain = tomoyo_undelete_domain(data); - else + } else domain = tomoyo_find_or_assign_new_domain(data, 0); head->write_var1 = domain; return 0; diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 26a76d67aa1c..e77e6a6de0f2 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h @@ -88,10 +88,7 @@ struct tomoyo_domain_info { /* Name of this domain. Never NULL. */ const struct tomoyo_path_info *domainname; u8 profile; /* Profile number to use. */ - u8 is_deleted; /* Delete flag. - 0 = active. - 1 = deleted but undeletable. - 255 = deleted and no longer undeletable. */ + bool is_deleted; /* Delete flag. */ bool quota_warned; /* Quota warnning flag. */ /* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */ u8 flags; @@ -144,7 +141,6 @@ struct tomoyo_double_path_acl_record { #define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain " #define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain " #define TOMOYO_KEYWORD_SELECT "select " -#define TOMOYO_KEYWORD_UNDELETE "undelete " #define TOMOYO_KEYWORD_USE_PROFILE "use_profile " #define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read" /* A domain definition starts with . */ @@ -267,8 +263,6 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname); struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * domainname, const u8 profile); -/* Undelete a domain. */ -struct tomoyo_domain_info *tomoyo_undelete_domain(const char *domainname); /* Check mode for specified functionality. */ unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, const u8 index); diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 093a756030bd..2f2b449ffd2d 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c @@ -551,9 +551,7 @@ int tomoyo_write_alias_policy(char *data, const bool is_delete) return tomoyo_update_alias_entry(data, cp, is_delete); } -/* Domain create/delete/undelete handler. */ - -/* #define TOMOYO_DEBUG_DOMAIN_UNDELETE */ +/* Domain create/delete handler. */ /** * tomoyo_delete_domain - Delete a domain. @@ -571,41 +569,15 @@ int tomoyo_delete_domain(char *domainname) tomoyo_fill_path_info(&name); /***** EXCLUSIVE SECTION START *****/ down_write(&tomoyo_domain_list_lock); -#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE - printk(KERN_DEBUG "tomoyo_delete_domain %s\n", domainname); - list_for_each_entry(domain, &tomoyo_domain_list, list) { - if (tomoyo_pathcmp(domain->domainname, &name)) - continue; - printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted); - } -#endif /* Is there an active domain? */ list_for_each_entry(domain, &tomoyo_domain_list, list) { - struct tomoyo_domain_info *domain2; /* Never delete tomoyo_kernel_domain */ if (domain == &tomoyo_kernel_domain) continue; if (domain->is_deleted || tomoyo_pathcmp(domain->domainname, &name)) continue; - /* Mark already deleted domains as non undeletable. */ - list_for_each_entry(domain2, &tomoyo_domain_list, list) { - if (!domain2->is_deleted || - tomoyo_pathcmp(domain2->domainname, &name)) - continue; -#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE - if (domain2->is_deleted != 255) - printk(KERN_DEBUG - "Marked %p as non undeletable\n", - domain2); -#endif - domain2->is_deleted = 255; - } - /* Delete and mark active domain as undeletable. */ - domain->is_deleted = 1; -#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE - printk(KERN_DEBUG "Marked %p as undeletable\n", domain); -#endif + domain->is_deleted = true; break; } up_write(&tomoyo_domain_list_lock); @@ -613,58 +585,6 @@ int tomoyo_delete_domain(char *domainname) return 0; } -/** - * tomoyo_undelete_domain - Undelete a domain. - * - * @domainname: The name of domain. - * - * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. - */ -struct tomoyo_domain_info *tomoyo_undelete_domain(const char *domainname) -{ - struct tomoyo_domain_info *domain; - struct tomoyo_domain_info *candidate_domain = NULL; - struct tomoyo_path_info name; - - name.name = domainname; - tomoyo_fill_path_info(&name); - /***** EXCLUSIVE SECTION START *****/ - down_write(&tomoyo_domain_list_lock); -#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE - printk(KERN_DEBUG "tomoyo_undelete_domain %s\n", domainname); - list_for_each_entry(domain, &tomoyo_domain_list, list) { - if (tomoyo_pathcmp(domain->domainname, &name)) - continue; - printk(KERN_DEBUG "List: %p %u\n", domain, domain->is_deleted); - } -#endif - list_for_each_entry(domain, &tomoyo_domain_list, list) { - if (tomoyo_pathcmp(&name, domain->domainname)) - continue; - if (!domain->is_deleted) { - /* This domain is active. I can't undelete. */ - candidate_domain = NULL; -#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE - printk(KERN_DEBUG "%p is active. I can't undelete.\n", - domain); -#endif - break; - } - /* Is this domain undeletable? */ - if (domain->is_deleted == 1) - candidate_domain = domain; - } - if (candidate_domain) { - candidate_domain->is_deleted = 0; -#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE - printk(KERN_DEBUG "%p was undeleted.\n", candidate_domain); -#endif - } - up_write(&tomoyo_domain_list_lock); - /***** EXCLUSIVE SECTION END *****/ - return candidate_domain; -} - /** * tomoyo_find_or_assign_new_domain - Create a domain. * @@ -711,10 +631,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * /***** CRITICAL SECTION END *****/ if (flag) continue; -#ifdef TOMOYO_DEBUG_DOMAIN_UNDELETE - printk(KERN_DEBUG "Reusing %p %s\n", domain, - domain->domainname->name); -#endif list_for_each_entry(ptr, &domain->acl_info_list, list) { ptr->type |= TOMOYO_ACL_DELETED; } @@ -722,7 +638,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * domain->profile = profile; domain->quota_warned = false; mb(); /* Avoid out-of-order execution. */ - domain->is_deleted = 0; + domain->is_deleted = false; goto out; } /* No memory reusable. Create using new memory. */ -- GitLab From a2e87d06ddbe6e6fdb8d6d2e5e985efe4efb07dd Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:44:59 +0200 Subject: [PATCH 0183/6080] perf_counter: update mmap() counter read, take 2 Update the userspace read method. Paul noted that: - userspace cannot observe ->lock & 1 on the same cpu. - we need a barrier() between reading ->lock and ->index to ensure we read them in that prticular order. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094517.368446033@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index f2b914de3f0c..e22ab47a2f41 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -170,22 +170,18 @@ struct perf_counter_mmap_page { * u32 seq; * s64 count; * - * again: - * seq = pc->lock; - * if (unlikely(seq & 1)) { - * cpu_relax(); - * goto again; - * } + * do { + * seq = pc->lock; * - * if (pc->index) { - * count = pmc_read(pc->index - 1); - * count += pc->offset; - * } else - * goto regular_read; + * barrier() + * if (pc->index) { + * count = pmc_read(pc->index - 1); + * count += pc->offset; + * } else + * goto regular_read; * - * barrier(); - * if (pc->lock != seq) - * goto again; + * barrier(); + * } while (pc->lock != seq); * * NOTE: for obvious reason this only works on self-monitoring * processes. -- GitLab From 9c03d88e328d5f28f13191622c2ea1349c36b799 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:00 +0200 Subject: [PATCH 0184/6080] perf_counter: add more context information Change the callchain context entries to u16, so as to gain some space. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094517.457320003@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 4 ++-- kernel/perf_counter.c | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index e22ab47a2f41..f9d5cf0bfbdd 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -507,10 +507,10 @@ extern void perf_counter_mmap(unsigned long addr, unsigned long len, extern void perf_counter_munmap(unsigned long addr, unsigned long len, unsigned long pgoff, struct file *file); -#define MAX_STACK_DEPTH 254 +#define MAX_STACK_DEPTH 255 struct perf_callchain_entry { - u32 nr, hv, kernel, user; + u16 nr, hv, kernel, user; u64 ip[MAX_STACK_DEPTH]; }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 2a5d4f525567..727624db5078 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1657,9 +1657,7 @@ void perf_counter_do_pending(void) * Callchain support -- arch specific */ -struct perf_callchain_entry * -__attribute__((weak)) -perf_callchain(struct pt_regs *regs) +__weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) { return NULL; } @@ -1819,7 +1817,7 @@ void perf_counter_output(struct perf_counter *counter, callchain = perf_callchain(regs); if (callchain) { - callchain_size = (2 + callchain->nr) * sizeof(u64); + callchain_size = (1 + callchain->nr) * sizeof(u64); header.type |= __PERF_EVENT_CALLCHAIN; header.size += callchain_size; -- GitLab From 3c446b3d3b38f991f97e9d2df0ad26a60a94dcff Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:01 +0200 Subject: [PATCH 0185/6080] perf_counter: SIGIO support Provide support for fcntl() I/O availability signals. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094517.579788800@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 2 ++ kernel/perf_counter.c | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index f9d5cf0bfbdd..8d5d11b8d011 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -238,6 +238,7 @@ enum perf_event_type { #include #include #include +#include #include struct task_struct; @@ -398,6 +399,7 @@ struct perf_counter { /* poll related */ wait_queue_head_t waitq; + struct fasync_struct *fasync; /* optional: for NMIs */ struct perf_wakeup_entry wakeup; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 727624db5078..c58cc64319e1 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1526,6 +1526,22 @@ out: return ret; } +static int perf_fasync(int fd, struct file *filp, int on) +{ + struct perf_counter *counter = filp->private_data; + struct inode *inode = filp->f_path.dentry->d_inode; + int retval; + + mutex_lock(&inode->i_mutex); + retval = fasync_helper(fd, filp, on, &counter->fasync); + mutex_unlock(&inode->i_mutex); + + if (retval < 0) + return retval; + + return 0; +} + static const struct file_operations perf_fops = { .release = perf_release, .read = perf_read, @@ -1533,6 +1549,7 @@ static const struct file_operations perf_fops = { .unlocked_ioctl = perf_ioctl, .compat_ioctl = perf_ioctl, .mmap = perf_mmap, + .fasync = perf_fasync, }; /* @@ -1549,7 +1566,7 @@ void perf_counter_wakeup(struct perf_counter *counter) rcu_read_lock(); data = rcu_dereference(counter->data); if (data) { - (void)atomic_xchg(&data->wakeup, POLL_IN); + atomic_set(&data->wakeup, POLL_IN); /* * Ensure all data writes are issued before updating the * user-space data head information. The matching rmb() @@ -1561,6 +1578,7 @@ void perf_counter_wakeup(struct perf_counter *counter) rcu_read_unlock(); wake_up_all(&counter->waitq); + kill_fasync(&counter->fasync, SIGIO, POLL_IN); } /* -- GitLab From 671dec5daf3b3c43c5777be282f00120a44cf37f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:02 +0200 Subject: [PATCH 0186/6080] perf_counter: generalize pending infrastructure Prepare the pending infrastructure to do more than wakeups. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094517.634732847@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 7 +++-- kernel/perf_counter.c | 53 ++++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 8d5d11b8d011..977fb15a53f3 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -321,8 +321,9 @@ struct perf_mmap_data { void *data_pages[0]; }; -struct perf_wakeup_entry { - struct perf_wakeup_entry *next; +struct perf_pending_entry { + struct perf_pending_entry *next; + void (*func)(struct perf_pending_entry *); }; /** @@ -401,7 +402,7 @@ struct perf_counter { wait_queue_head_t waitq; struct fasync_struct *fasync; /* optional: for NMIs */ - struct perf_wakeup_entry wakeup; + struct perf_pending_entry pending; void (*destroy)(struct perf_counter *); struct rcu_head rcu_head; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index c58cc64319e1..0a2ade2e4f11 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1581,6 +1581,14 @@ void perf_counter_wakeup(struct perf_counter *counter) kill_fasync(&counter->fasync, SIGIO, POLL_IN); } +static void perf_pending_wakeup(struct perf_pending_entry *entry) +{ + struct perf_counter *counter = container_of(entry, + struct perf_counter, pending); + + perf_counter_wakeup(counter); +} + /* * Pending wakeups * @@ -1590,45 +1598,47 @@ void perf_counter_wakeup(struct perf_counter *counter) * single linked list and use cmpxchg() to add entries lockless. */ -#define PENDING_TAIL ((struct perf_wakeup_entry *)-1UL) +#define PENDING_TAIL ((struct perf_pending_entry *)-1UL) -static DEFINE_PER_CPU(struct perf_wakeup_entry *, perf_wakeup_head) = { +static DEFINE_PER_CPU(struct perf_pending_entry *, perf_pending_head) = { PENDING_TAIL, }; -static void perf_pending_queue(struct perf_counter *counter) +static void perf_pending_queue(struct perf_pending_entry *entry, + void (*func)(struct perf_pending_entry *)) { - struct perf_wakeup_entry **head; - struct perf_wakeup_entry *prev, *next; + struct perf_pending_entry **head; - if (cmpxchg(&counter->wakeup.next, NULL, PENDING_TAIL) != NULL) + if (cmpxchg(&entry->next, NULL, PENDING_TAIL) != NULL) return; - head = &get_cpu_var(perf_wakeup_head); + entry->func = func; + + head = &get_cpu_var(perf_pending_head); do { - prev = counter->wakeup.next = *head; - next = &counter->wakeup; - } while (cmpxchg(head, prev, next) != prev); + entry->next = *head; + } while (cmpxchg(head, entry->next, entry) != entry->next); set_perf_counter_pending(); - put_cpu_var(perf_wakeup_head); + put_cpu_var(perf_pending_head); } static int __perf_pending_run(void) { - struct perf_wakeup_entry *list; + struct perf_pending_entry *list; int nr = 0; - list = xchg(&__get_cpu_var(perf_wakeup_head), PENDING_TAIL); + list = xchg(&__get_cpu_var(perf_pending_head), PENDING_TAIL); while (list != PENDING_TAIL) { - struct perf_counter *counter = container_of(list, - struct perf_counter, wakeup); + void (*func)(struct perf_pending_entry *); + struct perf_pending_entry *entry = list; list = list->next; - counter->wakeup.next = NULL; + func = entry->func; + entry->next = NULL; /* * Ensure we observe the unqueue before we issue the wakeup, * so that we won't be waiting forever. @@ -1636,7 +1646,7 @@ static int __perf_pending_run(void) */ smp_wmb(); - perf_counter_wakeup(counter); + func(entry); nr++; } @@ -1658,7 +1668,7 @@ static inline int perf_not_pending(struct perf_counter *counter) * so that we do not miss the wakeup. -- see perf_pending_handle() */ smp_rmb(); - return counter->wakeup.next == NULL; + return counter->pending.next == NULL; } static void perf_pending_sync(struct perf_counter *counter) @@ -1695,9 +1705,10 @@ struct perf_output_handle { static inline void __perf_output_wakeup(struct perf_output_handle *handle) { - if (handle->nmi) - perf_pending_queue(handle->counter); - else + if (handle->nmi) { + perf_pending_queue(&handle->counter->pending, + perf_pending_wakeup); + } else perf_counter_wakeup(handle->counter); } -- GitLab From b6276f353bf490add62dcf7db0ebd75baa3e1a37 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:03 +0200 Subject: [PATCH 0187/6080] perf_counter: x86: self-IPI for pending work Implement set_perf_counter_pending() with a self-IPI so that it will run ASAP in a usable context. For now use a second IRQ vector, because the primary vector pokes the apic in funny ways that seem to confuse things. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094517.724626696@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/entry_arch.h | 1 + arch/x86/include/asm/hardirq.h | 1 + arch/x86/include/asm/hw_irq.h | 1 + arch/x86/include/asm/irq_vectors.h | 5 +++++ arch/x86/include/asm/perf_counter.h | 3 ++- arch/x86/kernel/cpu/perf_counter.c | 14 ++++++++++++++ arch/x86/kernel/entry_64.S | 2 ++ arch/x86/kernel/irq.c | 5 +++++ arch/x86/kernel/irqinit_32.c | 1 + arch/x86/kernel/irqinit_64.c | 1 + 10 files changed, 33 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h index c2e6bedaf258..fe24d2802490 100644 --- a/arch/x86/include/asm/entry_arch.h +++ b/arch/x86/include/asm/entry_arch.h @@ -50,6 +50,7 @@ BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) #ifdef CONFIG_PERF_COUNTERS BUILD_INTERRUPT(perf_counter_interrupt, LOCAL_PERF_VECTOR) +BUILD_INTERRUPT(perf_pending_interrupt, LOCAL_PENDING_VECTOR) #endif #ifdef CONFIG_X86_MCE_P4THERMAL diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h index 25454427ceea..f5ebe2aaca4b 100644 --- a/arch/x86/include/asm/hardirq.h +++ b/arch/x86/include/asm/hardirq.h @@ -14,6 +14,7 @@ typedef struct { #endif unsigned int generic_irqs; /* arch dependent */ unsigned int apic_perf_irqs; + unsigned int apic_pending_irqs; #ifdef CONFIG_SMP unsigned int irq_resched_count; unsigned int irq_call_count; diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index ae80f64973e0..7309c0ad6902 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -30,6 +30,7 @@ extern void apic_timer_interrupt(void); extern void generic_interrupt(void); extern void error_interrupt(void); extern void perf_counter_interrupt(void); +extern void perf_pending_interrupt(void); extern void spurious_interrupt(void); extern void thermal_interrupt(void); diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index 3cbd79bbb47c..545bb811ccb5 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -116,6 +116,11 @@ */ #define GENERIC_INTERRUPT_VECTOR 0xed +/* + * Performance monitoring pending work vector: + */ +#define LOCAL_PENDING_VECTOR 0xec + /* * First APIC vector available to drivers: (vectors 0x30-0xee) we * start at 0x31(0x41) to spread out vectors evenly between priority diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h index e2b0e66b2353..d08dd52cb8ff 100644 --- a/arch/x86/include/asm/perf_counter.h +++ b/arch/x86/include/asm/perf_counter.h @@ -84,7 +84,8 @@ union cpuid10_edx { #define MSR_ARCH_PERFMON_FIXED_CTR2 0x30b #define X86_PMC_IDX_FIXED_BUS_CYCLES (X86_PMC_IDX_FIXED + 2) -#define set_perf_counter_pending() do { } while (0) +extern void set_perf_counter_pending(void); + #define clear_perf_counter_pending() do { } while (0) #define test_perf_counter_pending() (0) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index c74e20d593a7..438415866fe4 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -849,6 +849,20 @@ void smp_perf_counter_interrupt(struct pt_regs *regs) irq_exit(); } +void smp_perf_pending_interrupt(struct pt_regs *regs) +{ + irq_enter(); + ack_APIC_irq(); + inc_irq_stat(apic_pending_irqs); + perf_counter_do_pending(); + irq_exit(); +} + +void set_perf_counter_pending(void) +{ + apic->send_IPI_self(LOCAL_PENDING_VECTOR); +} + void perf_counters_lapic_init(int nmi) { u32 apic_val; diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 3f129d963a05..1d46cba56fd8 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1028,6 +1028,8 @@ apicinterrupt SPURIOUS_APIC_VECTOR \ #ifdef CONFIG_PERF_COUNTERS apicinterrupt LOCAL_PERF_VECTOR \ perf_counter_interrupt smp_perf_counter_interrupt +apicinterrupt LOCAL_PENDING_VECTOR \ + perf_pending_interrupt smp_perf_pending_interrupt #endif /* diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 9c2754302ecc..d465487da587 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -67,6 +67,10 @@ static int show_other_interrupts(struct seq_file *p, int prec) for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs); seq_printf(p, " Performance counter interrupts\n"); + seq_printf(p, "PND: "); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs); + seq_printf(p, " Performance pending work\n"); #endif if (generic_interrupt_extension) { seq_printf(p, "PLT: "); @@ -171,6 +175,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu) sum += irq_stats(cpu)->apic_timer_irqs; sum += irq_stats(cpu)->irq_spurious_count; sum += irq_stats(cpu)->apic_perf_irqs; + sum += irq_stats(cpu)->apic_pending_irqs; #endif if (generic_interrupt_extension) sum += irq_stats(cpu)->generic_irqs; diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index 925d87cfc551..3190a6b961e6 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c @@ -166,6 +166,7 @@ static void __init apic_intr_init(void) alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); # ifdef CONFIG_PERF_COUNTERS alloc_intr_gate(LOCAL_PERF_VECTOR, perf_counter_interrupt); + alloc_intr_gate(LOCAL_PENDING_VECTOR, perf_pending_interrupt); # endif # ifdef CONFIG_X86_MCE_P4THERMAL diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c index 665e2ab48abd..53ceb26f80ff 100644 --- a/arch/x86/kernel/irqinit_64.c +++ b/arch/x86/kernel/irqinit_64.c @@ -156,6 +156,7 @@ static void __init apic_intr_init(void) /* Performance monitoring interrupt: */ #ifdef CONFIG_PERF_COUNTERS alloc_intr_gate(LOCAL_PERF_VECTOR, perf_counter_interrupt); + alloc_intr_gate(LOCAL_PENDING_VECTOR, perf_pending_interrupt); #endif } -- GitLab From f6c7d5fe58b4846ee0cb4b98b6042489705eced4 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:04 +0200 Subject: [PATCH 0188/6080] perf_counter: theres more to overflow than writing events Prepare for more generic overflow handling. The new perf_counter_overflow() method will handle the generic bits of the counter overflow, and can return a !0 return value, in which case the counter should be (soft) disabled, so that it won't count until it's properly disabled. XXX: do powerpc and swcounter Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094517.812109629@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 2 +- arch/x86/kernel/cpu/perf_counter.c | 3 ++- include/linux/perf_counter.h | 4 ++-- kernel/perf_counter.c | 29 +++++++++++++++++++++++------ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 0a4d14f279ae..f88c35d0710a 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -732,7 +732,7 @@ static void record_and_restart(struct perf_counter *counter, long val, * Finally record data if requested. */ if (record) - perf_counter_output(counter, 1, regs); + perf_counter_overflow(counter, 1, regs); } /* diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 438415866fe4..1116a41bc7b5 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -800,7 +800,8 @@ again: continue; perf_save_and_restart(counter); - perf_counter_output(counter, nmi, regs); + if (perf_counter_overflow(counter, nmi, regs)) + __pmc_generic_disable(counter, &counter->hw, bit); } hw_perf_ack_status(ack); diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 977fb15a53f3..ca2d4df29e0c 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -491,8 +491,8 @@ extern int hw_perf_group_sched_in(struct perf_counter *group_leader, struct perf_counter_context *ctx, int cpu); extern void perf_counter_update_userpage(struct perf_counter *counter); -extern void perf_counter_output(struct perf_counter *counter, - int nmi, struct pt_regs *regs); +extern int perf_counter_overflow(struct perf_counter *counter, + int nmi, struct pt_regs *regs); /* * Return 1 for a software counter, 0 for a hardware counter */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 0a2ade2e4f11..195e976eb07d 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1800,8 +1800,8 @@ static void perf_output_end(struct perf_output_handle *handle) rcu_read_unlock(); } -void perf_counter_output(struct perf_counter *counter, - int nmi, struct pt_regs *regs) +static void perf_counter_output(struct perf_counter *counter, + int nmi, struct pt_regs *regs) { int ret; u64 record_type = counter->hw_event.record_type; @@ -2033,6 +2033,17 @@ void perf_counter_munmap(unsigned long addr, unsigned long len, perf_counter_mmap_event(&mmap_event); } +/* + * Generic counter overflow handling. + */ + +int perf_counter_overflow(struct perf_counter *counter, + int nmi, struct pt_regs *regs) +{ + perf_counter_output(counter, nmi, regs); + return 0; +} + /* * Generic software counter infrastructure */ @@ -2077,6 +2088,7 @@ static void perf_swcounter_set_period(struct perf_counter *counter) static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) { + enum hrtimer_restart ret = HRTIMER_RESTART; struct perf_counter *counter; struct pt_regs *regs; @@ -2092,12 +2104,14 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) !counter->hw_event.exclude_user) regs = task_pt_regs(current); - if (regs) - perf_counter_output(counter, 0, regs); + if (regs) { + if (perf_counter_overflow(counter, 0, regs)) + ret = HRTIMER_NORESTART; + } hrtimer_forward_now(hrtimer, ns_to_ktime(counter->hw.irq_period)); - return HRTIMER_RESTART; + return ret; } static void perf_swcounter_overflow(struct perf_counter *counter, @@ -2105,7 +2119,10 @@ static void perf_swcounter_overflow(struct perf_counter *counter, { perf_swcounter_update(counter); perf_swcounter_set_period(counter); - perf_counter_output(counter, nmi, regs); + if (perf_counter_overflow(counter, nmi, regs)) + /* soft-disable the counter */ + ; + } static int perf_swcounter_match(struct perf_counter *counter, -- GitLab From ebb3c4c4cb81d64cc041356915ec015e2c57092a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:05 +0200 Subject: [PATCH 0189/6080] perf_counter: fix the mlock accounting Reading through the code I saw I forgot the finish the mlock accounting. Do so now. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094517.899767331@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 195e976eb07d..c841563de043 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1461,13 +1461,14 @@ static void perf_mmap_close(struct vm_area_struct *vma) if (atomic_dec_and_mutex_lock(&counter->mmap_count, &counter->mmap_mutex)) { + vma->vm_mm->locked_vm -= counter->data->nr_pages + 1; perf_mmap_data_free(counter); mutex_unlock(&counter->mmap_mutex); } } static struct vm_operations_struct perf_mmap_vmops = { - .open = perf_mmap_open, + .open = perf_mmap_open, .close = perf_mmap_close, .fault = perf_mmap_fault, }; @@ -1499,24 +1500,32 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) if (vma->vm_pgoff != 0) return -EINVAL; - locked = vma_size >> PAGE_SHIFT; - locked += vma->vm_mm->locked_vm; + mutex_lock(&counter->mmap_mutex); + if (atomic_inc_not_zero(&counter->mmap_count)) { + if (nr_pages != counter->data->nr_pages) + ret = -EINVAL; + goto unlock; + } + + locked = vma->vm_mm->locked_vm; + locked += nr_pages + 1; lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; lock_limit >>= PAGE_SHIFT; - if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) - return -EPERM; - - mutex_lock(&counter->mmap_mutex); - if (atomic_inc_not_zero(&counter->mmap_count)) - goto out; + if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) { + ret = -EPERM; + goto unlock; + } WARN_ON(counter->data); ret = perf_mmap_data_alloc(counter, nr_pages); - if (!ret) - atomic_set(&counter->mmap_count, 1); -out: + if (ret) + goto unlock; + + atomic_set(&counter->mmap_count, 1); + vma->vm_mm->locked_vm += nr_pages + 1; +unlock: mutex_unlock(&counter->mmap_mutex); vma->vm_flags &= ~VM_MAYWRITE; -- GitLab From 339f7c90b8a2f3aa2dd4267e79f797999e8a3c59 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:06 +0200 Subject: [PATCH 0190/6080] perf_counter: PERF_RECORD_TIME By popular request, provide means to log a timestamp along with the counter overflow event. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094518.024173282@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 2 ++ kernel/perf_counter.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index ca2d4df29e0c..928a7fae0961 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -102,6 +102,7 @@ enum perf_counter_record_format { PERF_RECORD_TID = 1U << 1, PERF_RECORD_GROUP = 1U << 2, PERF_RECORD_CALLCHAIN = 1U << 3, + PERF_RECORD_TIME = 1U << 4, }; /* @@ -221,6 +222,7 @@ enum perf_event_type { __PERF_EVENT_TID = PERF_RECORD_TID, __PERF_EVENT_GROUP = PERF_RECORD_GROUP, __PERF_EVENT_CALLCHAIN = PERF_RECORD_CALLCHAIN, + __PERF_EVENT_TIME = PERF_RECORD_TIME, }; #ifdef __KERNEL__ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index c841563de043..19990d1f0215 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1826,6 +1826,7 @@ static void perf_counter_output(struct perf_counter *counter, } group_entry; struct perf_callchain_entry *callchain = NULL; int callchain_size = 0; + u64 time; header.type = PERF_EVENT_COUNTER_OVERFLOW; header.size = sizeof(header); @@ -1862,6 +1863,16 @@ static void perf_counter_output(struct perf_counter *counter, } } + if (record_type & PERF_RECORD_TIME) { + /* + * Maybe do better on x86 and provide cpu_clock_nmi() + */ + time = sched_clock(); + + header.type |= __PERF_EVENT_TIME; + header.size += sizeof(u64); + } + ret = perf_output_begin(&handle, counter, header.size, nmi); if (ret) return; @@ -1895,6 +1906,9 @@ static void perf_counter_output(struct perf_counter *counter, if (callchain) perf_output_copy(&handle, callchain, callchain_size); + if (record_type & PERF_RECORD_TIME) + perf_output_put(&handle, time); + perf_output_end(&handle); } -- GitLab From 79f146415623fe74f39af67c0f6adc208939a410 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:07 +0200 Subject: [PATCH 0191/6080] perf_counter: counter overflow limit Provide means to auto-disable the counter after 'n' overflow events. Create the counter with hw_event.disabled = 1, and then issue an ioctl(fd, PREF_COUNTER_IOC_REFRESH, n); to set the limit and enable the counter. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094518.083139737@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 12 ++++++--- kernel/perf_counter.c | 51 +++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 928a7fae0961..ef4dcbff75ab 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -155,8 +155,9 @@ struct perf_counter_hw_event { /* * Ioctls that can be done on a perf counter fd: */ -#define PERF_COUNTER_IOC_ENABLE _IO('$', 0) -#define PERF_COUNTER_IOC_DISABLE _IO('$', 1) +#define PERF_COUNTER_IOC_ENABLE _IO ('$', 0) +#define PERF_COUNTER_IOC_DISABLE _IO ('$', 1) +#define PERF_COUNTER_IOC_REFRESH _IOW('$', 2, u32) /* * Structure of the page that can be mapped via mmap @@ -403,9 +404,14 @@ struct perf_counter { /* poll related */ wait_queue_head_t waitq; struct fasync_struct *fasync; - /* optional: for NMIs */ + + /* delayed work for NMIs and such */ + int pending_wakeup; + int pending_disable; struct perf_pending_entry pending; + atomic_t event_limit; + void (*destroy)(struct perf_counter *); struct rcu_head rcu_head; #endif diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 19990d1f0215..c05e10354bc9 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -744,6 +744,12 @@ static void perf_counter_enable(struct perf_counter *counter) spin_unlock_irq(&ctx->lock); } +static void perf_counter_refresh(struct perf_counter *counter, int refresh) +{ + atomic_add(refresh, &counter->event_limit); + perf_counter_enable(counter); +} + /* * Enable a counter and all its children. */ @@ -1311,6 +1317,9 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case PERF_COUNTER_IOC_DISABLE: perf_counter_disable_family(counter); break; + case PERF_COUNTER_IOC_REFRESH: + perf_counter_refresh(counter, arg); + break; default: err = -ENOTTY; } @@ -1590,14 +1599,6 @@ void perf_counter_wakeup(struct perf_counter *counter) kill_fasync(&counter->fasync, SIGIO, POLL_IN); } -static void perf_pending_wakeup(struct perf_pending_entry *entry) -{ - struct perf_counter *counter = container_of(entry, - struct perf_counter, pending); - - perf_counter_wakeup(counter); -} - /* * Pending wakeups * @@ -1607,6 +1608,22 @@ static void perf_pending_wakeup(struct perf_pending_entry *entry) * single linked list and use cmpxchg() to add entries lockless. */ +static void perf_pending_counter(struct perf_pending_entry *entry) +{ + struct perf_counter *counter = container_of(entry, + struct perf_counter, pending); + + if (counter->pending_disable) { + counter->pending_disable = 0; + perf_counter_disable(counter); + } + + if (counter->pending_wakeup) { + counter->pending_wakeup = 0; + perf_counter_wakeup(counter); + } +} + #define PENDING_TAIL ((struct perf_pending_entry *)-1UL) static DEFINE_PER_CPU(struct perf_pending_entry *, perf_pending_head) = { @@ -1715,8 +1732,9 @@ struct perf_output_handle { static inline void __perf_output_wakeup(struct perf_output_handle *handle) { if (handle->nmi) { + handle->counter->pending_wakeup = 1; perf_pending_queue(&handle->counter->pending, - perf_pending_wakeup); + perf_pending_counter); } else perf_counter_wakeup(handle->counter); } @@ -2063,8 +2081,21 @@ void perf_counter_munmap(unsigned long addr, unsigned long len, int perf_counter_overflow(struct perf_counter *counter, int nmi, struct pt_regs *regs) { + int events = atomic_read(&counter->event_limit); + int ret = 0; + + if (events && atomic_dec_and_test(&counter->event_limit)) { + ret = 1; + if (nmi) { + counter->pending_disable = 1; + perf_pending_queue(&counter->pending, + perf_pending_counter); + } else + perf_counter_disable(counter); + } + perf_counter_output(counter, nmi, regs); - return 0; + return ret; } /* -- GitLab From 0c593b3411341e3a05a61f5527df36ab02bd11e8 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:08 +0200 Subject: [PATCH 0192/6080] perf_counter: comment the perf_event_type stuff Describe the event format. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094518.211174347@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index ef4dcbff75ab..81220188d058 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -208,6 +208,20 @@ struct perf_event_header { enum perf_event_type { + /* + * The MMAP events record the PROT_EXEC mappings so that we can + * correlate userspace IPs to code. They have the following structure: + * + * struct { + * struct perf_event_header header; + * + * u32 pid, tid; + * u64 addr; + * u64 len; + * u64 pgoff; + * char filename[]; + * }; + */ PERF_EVENT_MMAP = 1, PERF_EVENT_MUNMAP = 2, @@ -217,6 +231,24 @@ enum perf_event_type { * * These events will have types of the form: * PERF_EVENT_COUNTER_OVERFLOW { | __PERF_EVENT_* } * + * + * struct { + * struct perf_event_header header; + * + * { u64 ip; } && __PERF_EVENT_IP + * { u32 pid, tid; } && __PERF_EVENT_TID + * + * { u64 nr; + * { u64 event, val; } cnt[nr]; } && __PERF_EVENT_GROUP + * + * { u16 nr, + * hv, + * kernel, + * user; + * u64 ips[nr]; } && __PERF_EVENT_CALLCHAIN + * + * { u64 time; } && __PERF_EVENT_TIME + * }; */ PERF_EVENT_COUNTER_OVERFLOW = 1UL << 31, __PERF_EVENT_IP = PERF_RECORD_IP, -- GitLab From 4c9e25428ff46b968a30f1dfafdba550cb6e4141 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:09 +0200 Subject: [PATCH 0193/6080] perf_counter: change event definition Currently the definition of an event is slightly ambiguous. We have wakeup events, for poll() and SIGIO, which are either generated when a record crosses a page boundary (hw_events.wakeup_events == 0), or every wakeup_events new records. Now a record can be either a counter overflow record, or a number of different things, like the mmap PROT_EXEC region notifications. Then there is the PERF_COUNTER_IOC_REFRESH event limit, which only considers counter overflows. This patch changes then wakeup_events and SIGIO notification to only consider overflow events. Furthermore it changes the SIGIO notification to report SIGHUP when the event limit is reached and the counter will be disabled. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094518.266679874@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 1 + kernel/perf_counter.c | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 81220188d058..0f5a4005048f 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -439,6 +439,7 @@ struct perf_counter { /* delayed work for NMIs and such */ int pending_wakeup; + int pending_kill; int pending_disable; struct perf_pending_entry pending; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index c05e10354bc9..8c8eaf0625f9 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1596,7 +1596,11 @@ void perf_counter_wakeup(struct perf_counter *counter) rcu_read_unlock(); wake_up_all(&counter->waitq); - kill_fasync(&counter->fasync, SIGIO, POLL_IN); + + if (counter->pending_kill) { + kill_fasync(&counter->fasync, SIGIO, counter->pending_kill); + counter->pending_kill = 0; + } } /* @@ -1727,6 +1731,7 @@ struct perf_output_handle { unsigned int head; int wakeup; int nmi; + int overflow; }; static inline void __perf_output_wakeup(struct perf_output_handle *handle) @@ -1741,7 +1746,7 @@ static inline void __perf_output_wakeup(struct perf_output_handle *handle) static int perf_output_begin(struct perf_output_handle *handle, struct perf_counter *counter, unsigned int size, - int nmi) + int nmi, int overflow) { struct perf_mmap_data *data; unsigned int offset, head; @@ -1751,8 +1756,9 @@ static int perf_output_begin(struct perf_output_handle *handle, if (!data) goto out; - handle->counter = counter; - handle->nmi = nmi; + handle->counter = counter; + handle->nmi = nmi; + handle->overflow = overflow; if (!data->nr_pages) goto fail; @@ -1816,7 +1822,7 @@ static void perf_output_end(struct perf_output_handle *handle) { int wakeup_events = handle->counter->hw_event.wakeup_events; - if (wakeup_events) { + if (handle->overflow && wakeup_events) { int events = atomic_inc_return(&handle->data->events); if (events >= wakeup_events) { atomic_sub(wakeup_events, &handle->data->events); @@ -1891,7 +1897,7 @@ static void perf_counter_output(struct perf_counter *counter, header.size += sizeof(u64); } - ret = perf_output_begin(&handle, counter, header.size, nmi); + ret = perf_output_begin(&handle, counter, header.size, nmi, 1); if (ret) return; @@ -1955,7 +1961,7 @@ static void perf_counter_mmap_output(struct perf_counter *counter, { struct perf_output_handle handle; int size = mmap_event->event.header.size; - int ret = perf_output_begin(&handle, counter, size, 0); + int ret = perf_output_begin(&handle, counter, size, 0, 0); if (ret) return; @@ -2084,8 +2090,10 @@ int perf_counter_overflow(struct perf_counter *counter, int events = atomic_read(&counter->event_limit); int ret = 0; + counter->pending_kill = POLL_IN; if (events && atomic_dec_and_test(&counter->event_limit)) { ret = 1; + counter->pending_kill = POLL_HUP; if (nmi) { counter->pending_disable = 1; perf_pending_queue(&counter->pending, -- GitLab From 4af4998b8aa35600f4c4a4f3c3a23baca6081d02 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:10 +0200 Subject: [PATCH 0194/6080] perf_counter: rework context time Since perf_counter_context is switched along with tasks, we can maintain the context time without using the task runtime clock. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094518.353552838@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 10 ++--- kernel/perf_counter.c | 78 ++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 51 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 0f5a4005048f..7f5d353d78ac 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -477,14 +477,10 @@ struct perf_counter_context { struct task_struct *task; /* - * time_now is the current time in nanoseconds since an arbitrary - * point in the past. For per-task counters, this is based on the - * task clock, and for per-cpu counters it is based on the cpu clock. - * time_lost is an offset from the task/cpu clock, used to make it - * appear that time only passes while the context is scheduled in. + * Context clock, runs when context enabled. */ - u64 time_now; - u64 time_lost; + u64 time; + u64 timestamp; #endif }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 8c8eaf0625f9..84d85ab4e161 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -117,7 +117,7 @@ counter_sched_out(struct perf_counter *counter, return; counter->state = PERF_COUNTER_STATE_INACTIVE; - counter->tstamp_stopped = ctx->time_now; + counter->tstamp_stopped = ctx->time; counter->hw_ops->disable(counter); counter->oncpu = -1; @@ -253,27 +253,20 @@ retry: spin_unlock_irq(&ctx->lock); } -/* - * Get the current time for this context. - * If this is a task context, we use the task's task clock, - * or for a per-cpu context, we use the cpu clock. - */ -static u64 get_context_time(struct perf_counter_context *ctx, int update) +static inline u64 perf_clock(void) { - struct task_struct *curr = ctx->task; - - if (!curr) - return cpu_clock(smp_processor_id()); - - return __task_delta_exec(curr, update) + curr->se.sum_exec_runtime; + return cpu_clock(smp_processor_id()); } /* * Update the record of the current time in a context. */ -static void update_context_time(struct perf_counter_context *ctx, int update) +static void update_context_time(struct perf_counter_context *ctx) { - ctx->time_now = get_context_time(ctx, update) - ctx->time_lost; + u64 now = perf_clock(); + + ctx->time += now - ctx->timestamp; + ctx->timestamp = now; } /* @@ -284,15 +277,17 @@ static void update_counter_times(struct perf_counter *counter) struct perf_counter_context *ctx = counter->ctx; u64 run_end; - if (counter->state >= PERF_COUNTER_STATE_INACTIVE) { - counter->total_time_enabled = ctx->time_now - - counter->tstamp_enabled; - if (counter->state == PERF_COUNTER_STATE_INACTIVE) - run_end = counter->tstamp_stopped; - else - run_end = ctx->time_now; - counter->total_time_running = run_end - counter->tstamp_running; - } + if (counter->state < PERF_COUNTER_STATE_INACTIVE) + return; + + counter->total_time_enabled = ctx->time - counter->tstamp_enabled; + + if (counter->state == PERF_COUNTER_STATE_INACTIVE) + run_end = counter->tstamp_stopped; + else + run_end = ctx->time; + + counter->total_time_running = run_end - counter->tstamp_running; } /* @@ -332,7 +327,7 @@ static void __perf_counter_disable(void *info) * If it is in error state, leave it in error state. */ if (counter->state >= PERF_COUNTER_STATE_INACTIVE) { - update_context_time(ctx, 1); + update_context_time(ctx); update_counter_times(counter); if (counter == counter->group_leader) group_sched_out(counter, cpuctx, ctx); @@ -426,7 +421,7 @@ counter_sched_in(struct perf_counter *counter, return -EAGAIN; } - counter->tstamp_running += ctx->time_now - counter->tstamp_stopped; + counter->tstamp_running += ctx->time - counter->tstamp_stopped; if (!is_software_counter(counter)) cpuctx->active_oncpu++; @@ -493,9 +488,9 @@ static void add_counter_to_ctx(struct perf_counter *counter, list_add_counter(counter, ctx); ctx->nr_counters++; counter->prev_state = PERF_COUNTER_STATE_OFF; - counter->tstamp_enabled = ctx->time_now; - counter->tstamp_running = ctx->time_now; - counter->tstamp_stopped = ctx->time_now; + counter->tstamp_enabled = ctx->time; + counter->tstamp_running = ctx->time; + counter->tstamp_stopped = ctx->time; } /* @@ -522,7 +517,7 @@ static void __perf_install_in_context(void *info) curr_rq_lock_irq_save(&flags); spin_lock(&ctx->lock); - update_context_time(ctx, 1); + update_context_time(ctx); /* * Protect the list operation against NMI by disabling the @@ -648,13 +643,13 @@ static void __perf_counter_enable(void *info) curr_rq_lock_irq_save(&flags); spin_lock(&ctx->lock); - update_context_time(ctx, 1); + update_context_time(ctx); counter->prev_state = counter->state; if (counter->state >= PERF_COUNTER_STATE_INACTIVE) goto unlock; counter->state = PERF_COUNTER_STATE_INACTIVE; - counter->tstamp_enabled = ctx->time_now - counter->total_time_enabled; + counter->tstamp_enabled = ctx->time - counter->total_time_enabled; /* * If the counter is in a group and isn't the group leader, @@ -737,8 +732,8 @@ static void perf_counter_enable(struct perf_counter *counter) */ if (counter->state == PERF_COUNTER_STATE_OFF) { counter->state = PERF_COUNTER_STATE_INACTIVE; - counter->tstamp_enabled = ctx->time_now - - counter->total_time_enabled; + counter->tstamp_enabled = + ctx->time - counter->total_time_enabled; } out: spin_unlock_irq(&ctx->lock); @@ -778,7 +773,7 @@ void __perf_counter_sched_out(struct perf_counter_context *ctx, ctx->is_active = 0; if (likely(!ctx->nr_counters)) goto out; - update_context_time(ctx, 0); + update_context_time(ctx); flags = hw_perf_save_disable(); if (ctx->nr_active) { @@ -883,12 +878,7 @@ __perf_counter_sched_in(struct perf_counter_context *ctx, if (likely(!ctx->nr_counters)) goto out; - /* - * Add any time since the last sched_out to the lost time - * so it doesn't get included in the total_time_enabled and - * total_time_running measures for counters in the context. - */ - ctx->time_lost = get_context_time(ctx, 0) - ctx->time_now; + ctx->timestamp = perf_clock(); flags = hw_perf_save_disable(); @@ -1043,8 +1033,8 @@ int perf_counter_task_enable(void) if (counter->state > PERF_COUNTER_STATE_OFF) continue; counter->state = PERF_COUNTER_STATE_INACTIVE; - counter->tstamp_enabled = ctx->time_now - - counter->total_time_enabled; + counter->tstamp_enabled = + ctx->time - counter->total_time_enabled; counter->hw_event.disabled = 0; } hw_perf_restore(perf_flags); @@ -1113,7 +1103,7 @@ static void __read(void *info) curr_rq_lock_irq_save(&flags); if (ctx->is_active) - update_context_time(ctx, 1); + update_context_time(ctx); counter->hw_ops->read(counter); update_counter_times(counter); curr_rq_unlock_irq_restore(&flags); -- GitLab From a39d6f2556c4a19f58f538c6aa28bf8faca4fcb8 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:11 +0200 Subject: [PATCH 0195/6080] perf_counter: rework the task clock software counter Rework the task clock software counter to use the context time instead of the task runtime clock, this removes the last such user. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094518.445450972@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 42 ++++++++++++------------------------------ 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 84d85ab4e161..56b7eb53d673 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -974,9 +974,6 @@ int perf_counter_task_disable(void) curr_rq_lock_irq_save(&flags); cpu = smp_processor_id(); - /* force the update of the task clock: */ - __task_delta_exec(curr, 1); - perf_counter_task_sched_out(curr, cpu); spin_lock(&ctx->lock); @@ -1017,9 +1014,6 @@ int perf_counter_task_enable(void) curr_rq_lock_irq_save(&flags); cpu = smp_processor_id(); - /* force the update of the task clock: */ - __task_delta_exec(curr, 1); - perf_counter_task_sched_out(curr, cpu); spin_lock(&ctx->lock); @@ -2347,38 +2341,28 @@ static const struct hw_perf_counter_ops perf_ops_cpu_clock = { * Software counter: task time clock */ -/* - * Called from within the scheduler: - */ -static u64 task_clock_perf_counter_val(struct perf_counter *counter, int update) -{ - struct task_struct *curr = counter->task; - u64 delta; - - delta = __task_delta_exec(curr, update); - - return curr->se.sum_exec_runtime + delta; -} - -static void task_clock_perf_counter_update(struct perf_counter *counter, u64 now) +static void task_clock_perf_counter_update(struct perf_counter *counter) { - u64 prev; + u64 prev, now; s64 delta; - prev = atomic64_read(&counter->hw.prev_count); - - atomic64_set(&counter->hw.prev_count, now); + update_context_time(counter->ctx); + now = counter->ctx->time; + prev = atomic64_xchg(&counter->hw.prev_count, now); delta = now - prev; - atomic64_add(delta, &counter->count); } static int task_clock_perf_counter_enable(struct perf_counter *counter) { struct hw_perf_counter *hwc = &counter->hw; + u64 now; + + update_context_time(counter->ctx); + now = counter->ctx->time; - atomic64_set(&hwc->prev_count, task_clock_perf_counter_val(counter, 0)); + atomic64_set(&hwc->prev_count, now); hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hwc->hrtimer.function = perf_swcounter_hrtimer; if (hwc->irq_period) { @@ -2393,14 +2377,12 @@ static int task_clock_perf_counter_enable(struct perf_counter *counter) static void task_clock_perf_counter_disable(struct perf_counter *counter) { hrtimer_cancel(&counter->hw.hrtimer); - task_clock_perf_counter_update(counter, - task_clock_perf_counter_val(counter, 0)); + task_clock_perf_counter_update(counter); } static void task_clock_perf_counter_read(struct perf_counter *counter) { - task_clock_perf_counter_update(counter, - task_clock_perf_counter_val(counter, 1)); + task_clock_perf_counter_update(counter); } static const struct hw_perf_counter_ops perf_ops_task_clock = { -- GitLab From 849691a6cd40270ff5f4a8846d5f6bf8df663ffc Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:12 +0200 Subject: [PATCH 0196/6080] perf_counter: remove rq->lock usage Now that all the task runtime clock users are gone, remove the ugly rq->lock usage from perf counters, which solves the nasty deadlock seen when a software task clock counter was read from an NMI overflow context. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094518.531137582@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/kernel_stat.h | 2 -- kernel/perf_counter.c | 42 ++++++++++++++----------------------- kernel/sched.c | 20 ------------------ 3 files changed, 16 insertions(+), 48 deletions(-) diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index b6d2887a5d88..080d1fd461d7 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -85,8 +85,6 @@ static inline unsigned int kstat_irqs(unsigned int irq) /* * Lock/unlock the current runqueue - to extract task statistics: */ -extern void curr_rq_lock_irq_save(unsigned long *flags); -extern void curr_rq_unlock_irq_restore(unsigned long *flags); extern unsigned long long __task_delta_exec(struct task_struct *tsk, int update); extern unsigned long long task_delta_exec(struct task_struct *); diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 56b7eb53d673..f4f7596f7841 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -172,8 +172,7 @@ static void __perf_counter_remove_from_context(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - curr_rq_lock_irq_save(&flags); - spin_lock(&ctx->lock); + spin_lock_irqsave(&ctx->lock, flags); counter_sched_out(counter, cpuctx, ctx); @@ -198,8 +197,7 @@ static void __perf_counter_remove_from_context(void *info) perf_max_counters - perf_reserved_percpu); } - spin_unlock(&ctx->lock); - curr_rq_unlock_irq_restore(&flags); + spin_unlock_irqrestore(&ctx->lock, flags); } @@ -319,8 +317,7 @@ static void __perf_counter_disable(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - curr_rq_lock_irq_save(&flags); - spin_lock(&ctx->lock); + spin_lock_irqsave(&ctx->lock, flags); /* * If the counter is on, turn it off. @@ -336,8 +333,7 @@ static void __perf_counter_disable(void *info) counter->state = PERF_COUNTER_STATE_OFF; } - spin_unlock(&ctx->lock); - curr_rq_unlock_irq_restore(&flags); + spin_unlock_irqrestore(&ctx->lock, flags); } /* @@ -515,8 +511,7 @@ static void __perf_install_in_context(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - curr_rq_lock_irq_save(&flags); - spin_lock(&ctx->lock); + spin_lock_irqsave(&ctx->lock, flags); update_context_time(ctx); /* @@ -565,8 +560,7 @@ static void __perf_install_in_context(void *info) unlock: hw_perf_restore(perf_flags); - spin_unlock(&ctx->lock); - curr_rq_unlock_irq_restore(&flags); + spin_unlock_irqrestore(&ctx->lock, flags); } /* @@ -641,8 +635,7 @@ static void __perf_counter_enable(void *info) if (ctx->task && cpuctx->task_ctx != ctx) return; - curr_rq_lock_irq_save(&flags); - spin_lock(&ctx->lock); + spin_lock_irqsave(&ctx->lock, flags); update_context_time(ctx); counter->prev_state = counter->state; @@ -678,8 +671,7 @@ static void __perf_counter_enable(void *info) } unlock: - spin_unlock(&ctx->lock); - curr_rq_unlock_irq_restore(&flags); + spin_unlock_irqrestore(&ctx->lock, flags); } /* @@ -971,7 +963,7 @@ int perf_counter_task_disable(void) if (likely(!ctx->nr_counters)) return 0; - curr_rq_lock_irq_save(&flags); + local_irq_save(flags); cpu = smp_processor_id(); perf_counter_task_sched_out(curr, cpu); @@ -992,9 +984,7 @@ int perf_counter_task_disable(void) hw_perf_restore(perf_flags); - spin_unlock(&ctx->lock); - - curr_rq_unlock_irq_restore(&flags); + spin_unlock_irqrestore(&ctx->lock, flags); return 0; } @@ -1011,7 +1001,7 @@ int perf_counter_task_enable(void) if (likely(!ctx->nr_counters)) return 0; - curr_rq_lock_irq_save(&flags); + local_irq_save(flags); cpu = smp_processor_id(); perf_counter_task_sched_out(curr, cpu); @@ -1037,7 +1027,7 @@ int perf_counter_task_enable(void) perf_counter_task_sched_in(curr, cpu); - curr_rq_unlock_irq_restore(&flags); + local_irq_restore(flags); return 0; } @@ -1095,12 +1085,12 @@ static void __read(void *info) struct perf_counter_context *ctx = counter->ctx; unsigned long flags; - curr_rq_lock_irq_save(&flags); + local_irq_save(flags); if (ctx->is_active) update_context_time(ctx); counter->hw_ops->read(counter); update_counter_times(counter); - curr_rq_unlock_irq_restore(&flags); + local_irq_restore(flags); } static u64 perf_counter_read(struct perf_counter *counter) @@ -2890,7 +2880,7 @@ __perf_counter_exit_task(struct task_struct *child, * Be careful about zapping the list - IRQ/NMI context * could still be processing it: */ - curr_rq_lock_irq_save(&flags); + local_irq_save(flags); perf_flags = hw_perf_save_disable(); cpuctx = &__get_cpu_var(perf_cpu_context); @@ -2903,7 +2893,7 @@ __perf_counter_exit_task(struct task_struct *child, child_ctx->nr_counters--; hw_perf_restore(perf_flags); - curr_rq_unlock_irq_restore(&flags); + local_irq_restore(flags); } parent_counter = child_counter->parent; diff --git a/kernel/sched.c b/kernel/sched.c index f76e3c0188a2..0de2f814fb18 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -997,26 +997,6 @@ static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags) } } -void curr_rq_lock_irq_save(unsigned long *flags) - __acquires(rq->lock) -{ - struct rq *rq; - - local_irq_save(*flags); - rq = cpu_rq(smp_processor_id()); - spin_lock(&rq->lock); -} - -void curr_rq_unlock_irq_restore(unsigned long *flags) - __releases(rq->lock) -{ - struct rq *rq; - - rq = cpu_rq(smp_processor_id()); - spin_unlock(&rq->lock); - local_irq_restore(*flags); -} - void task_rq_unlock_wait(struct task_struct *p) { struct rq *rq = task_rq(p); -- GitLab From bce379bf358738ab8efc8cda2594a299ac685085 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 6 Apr 2009 11:45:13 +0200 Subject: [PATCH 0197/6080] perf_counter: minimize context time updates Push the update_context_time() calls up the stack so that we get less invokations and thereby a less noisy output: before: # ./perfstat -e 1:0 -e 1:1 -e 1:1 -e 1:1 -l ls > /dev/null Performance counter stats for 'ls': 10.163691 cpu clock ticks (msecs) (scaled from 98.94%) 10.215360 task clock ticks (msecs) (scaled from 98.18%) 10.185549 task clock ticks (msecs) (scaled from 98.53%) 10.183581 task clock ticks (msecs) (scaled from 98.71%) Wall-clock time elapsed: 11.912858 msecs after: # ./perfstat -e 1:0 -e 1:1 -e 1:1 -e 1:1 -l ls > /dev/null Performance counter stats for 'ls': 9.316630 cpu clock ticks (msecs) 9.280789 task clock ticks (msecs) 9.280789 task clock ticks (msecs) 9.280789 task clock ticks (msecs) Wall-clock time elapsed: 9.574872 msecs Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090406094518.618876874@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index f4f7596f7841..863703b3158f 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -319,6 +319,8 @@ static void __perf_counter_disable(void *info) spin_lock_irqsave(&ctx->lock, flags); + update_context_time(ctx); + /* * If the counter is on, turn it off. * If it is in error state, leave it in error state. @@ -797,6 +799,8 @@ void perf_counter_task_sched_out(struct task_struct *task, int cpu) if (likely(!cpuctx->task_ctx)) return; + update_context_time(ctx); + regs = task_pt_regs(task); perf_swcounter_event(PERF_COUNT_CONTEXT_SWITCHES, 1, 1, regs); __perf_counter_sched_out(ctx, cpuctx); @@ -2336,7 +2340,6 @@ static void task_clock_perf_counter_update(struct perf_counter *counter) u64 prev, now; s64 delta; - update_context_time(counter->ctx); now = counter->ctx->time; prev = atomic64_xchg(&counter->hw.prev_count, now); @@ -2349,7 +2352,6 @@ static int task_clock_perf_counter_enable(struct perf_counter *counter) struct hw_perf_counter *hwc = &counter->hw; u64 now; - update_context_time(counter->ctx); now = counter->ctx->time; atomic64_set(&hwc->prev_count, now); @@ -2372,6 +2374,7 @@ static void task_clock_perf_counter_disable(struct perf_counter *counter) static void task_clock_perf_counter_read(struct perf_counter *counter) { + update_context_time(counter->ctx); task_clock_perf_counter_update(counter); } -- GitLab From 6278af660ff83fbafb18e53fc2747eb2ee6780fa Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Thu, 2 Apr 2009 10:40:28 +0200 Subject: [PATCH 0198/6080] perf_counter tools: kerneltop: display per function percentage along with event count ------------------------------------------------------------------------------ KernelTop: 90551 irqs/sec kernel:15.0% [NMI, 100000 CPU cycles], (all, 4 CPUs) ------------------------------------------------------------------------------ events pcnt RIP kernel function ______ ______ _____ ________________ _______________ 16871.00 - 19.1% - ffffffff80328e20 : clear_page_c 8810.00 - 9.9% - ffffffff8048ce80 : page_fault 4746.00 - 5.4% - ffffffff8048cae2 : _spin_lock 4428.00 - 5.0% - ffffffff80328e70 : copy_page_c 3340.00 - 3.8% - ffffffff80329090 : copy_user_generic_string! 2679.00 - 3.0% - ffffffff8028a16b : get_page_from_freelist 2254.00 - 2.5% - ffffffff80296f19 : unmap_vmas 2082.00 - 2.4% - ffffffff80297e19 : handle_mm_fault 1754.00 - 2.0% - ffffffff80288dc8 : __rmqueue_smallest 1553.00 - 1.8% - ffffffff8048ca58 : _spin_lock_irqsave 1400.00 - 1.6% - ffffffff8028cdc8 : release_pages 1337.00 - 1.5% - ffffffff80285400 : find_get_page 1335.00 - 1.5% - ffffffff80225a23 : do_page_fault 1299.00 - 1.5% - ffffffff802ba8e7 : __d_lookup 1174.00 - 1.3% - ffffffff802b38f3 : __link_path_walk 1155.00 - 1.3% - ffffffff802843e1 : perf_swcounter_ctx_event! 1137.00 - 1.3% - ffffffff8028d118 : ____pagevec_lru_add 963.00 - 1.1% - ffffffff802a670b : kmem_cache_alloc 885.00 - 1.0% - ffffffff8024bc61 : __wake_up_bit Display per function percentage along with event count. Signed-off-by: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 45 +++++++++++++------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 4f8d7917aba1..15f3a5f90198 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -636,16 +636,20 @@ static void print_sym_table(void) int counter; float events_per_sec = events/delay_secs; float kevents_per_sec = (events-userspace_events)/delay_secs; + float sum_kevents = 0.0; events = userspace_events = 0; memcpy(tmp, sym_table, sizeof(sym_table[0])*sym_table_count); qsort(tmp, sym_table_count, sizeof(tmp[0]), compare); + for (i = 0; i < sym_table_count && tmp[i].count[0]; i++) + sum_kevents += tmp[i].count[0]; + write(1, CONSOLE_CLEAR, strlen(CONSOLE_CLEAR)); printf( "------------------------------------------------------------------------------\n"); - printf( " KernelTop:%8.0f irqs/sec kernel:%3.1f%% [%s, ", + printf( " KernelTop:%8.0f irqs/sec kernel:%4.1f%% [%s, ", events_per_sec, 100.0 - (100.0*((events_per_sec-kevents_per_sec)/events_per_sec)), nmi ? "NMI" : "IRQ"); @@ -679,34 +683,31 @@ static void print_sym_table(void) printf("------------------------------------------------------------------------------\n\n"); if (nr_counters == 1) - printf(" events"); + printf(" events pcnt"); else - printf(" weight events"); + printf(" weight events pcnt"); printf(" RIP kernel function\n" - " ______ ______ ________________ _______________\n\n" + " ______ ______ _____ ________________ _______________\n\n" ); - printed = 0; - for (i = 0; i < sym_table_count; i++) { + for (i = 0, printed = 0; i < sym_table_count; i++) { + float pcnt; int count; - if (nr_counters == 1) { - if (printed <= 18 && - tmp[i].count[0] >= count_filter) { - printf("%19.2f - %016llx : %s\n", - sym_weight(tmp + i), tmp[i].addr, tmp[i].sym); - printed++; - } - } else { - if (printed <= 18 && - tmp[i].count[0] >= count_filter) { - printf("%8.1f %10ld - %016llx : %s\n", - sym_weight(tmp + i), - tmp[i].count[0], - tmp[i].addr, tmp[i].sym); - printed++; - } + if (printed <= 18 && tmp[i].count[0] >= count_filter) { + pcnt = 100.0 - (100.0*((sum_kevents-tmp[i].count[0])/sum_kevents)); + + if (nr_counters == 1) + printf("%19.2f - %4.1f%% - %016llx : %s\n", + sym_weight(tmp + i), + pcnt, tmp[i].addr, tmp[i].sym); + else + printf("%8.1f %10ld - %4.1f%% - %016llx : %s\n", + sym_weight(tmp + i), + tmp[i].count[0], + pcnt, tmp[i].addr, tmp[i].sym); + printed++; } /* * Add decay to the counts: -- GitLab From 98c2aaf8be5baf7193be37fb28bce8e7327158bc Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 7 Apr 2009 11:30:17 +0200 Subject: [PATCH 0199/6080] x86, perfcounters: add atomic64_xchg() Complete atomic64_t support on the 32-bit side by adding atomic64_xch(). Cc: Peter Zijlstra LKML-Reference: <20090406094518.445450972@chello.nl> Signed-off-by: Ingo Molnar --- arch/x86/include/asm/atomic_32.h | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h index 977250ed8b89..aff9f1fcdcd7 100644 --- a/arch/x86/include/asm/atomic_32.h +++ b/arch/x86/include/asm/atomic_32.h @@ -291,19 +291,37 @@ atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val, } /** - * atomic64_set - set atomic64 variable + * atomic64_xchg - xchg atomic64 variable * @ptr: pointer to type atomic64_t * @new_val: value to assign + * @old_val: old value that was there * - * Atomically sets the value of @ptr to @new_val. + * Atomically xchgs the value of @ptr to @new_val and returns + * the old value. */ -static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val) + +static inline unsigned long long +atomic64_xchg(atomic64_t *ptr, unsigned long long new_val) { unsigned long long old_val; do { old_val = atomic_read(ptr); } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val); + + return old_val; +} + +/** + * atomic64_set - set atomic64 variable + * @ptr: pointer to type atomic64_t + * @new_val: value to assign + * + * Atomically sets the value of @ptr to @new_val. + */ +static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val) +{ + atomic64_xchg(ptr, new_val); } /** -- GitLab From 9c83633ad38138855181af6936e8ac570ef7e2cb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 7 Apr 2009 14:48:16 +0300 Subject: [PATCH 0200/6080] missing unlock in jfs_quota_write() We should unlock &inode->i_mutex on the error path. This bug was in ext2_quota_write(). I sent a patch to them today as well. Found by smatch (http://repo.or.cz/w/smatch.git). Compile tested. regards, dan carpenter Signed-off-by: Dan Carpenter Signed-off-by: Dave Kleikamp --- fs/jfs/super.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 6f21adf9479a..d9b0e92b3602 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -720,8 +720,10 @@ static ssize_t jfs_quota_write(struct super_block *sb, int type, blk++; } out: - if (len == towrite) + if (len == towrite) { + mutex_unlock(&inode->i_mutex); return err; + } if (inode->i_size < off+len-towrite) i_size_write(inode, off+len-towrite); inode->i_version++; -- GitLab From 6553e192d48af88184029066c30c9464516ea0b7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 6 Apr 2009 16:59:32 +0100 Subject: [PATCH 0201/6080] ASoC: Display return code when failing to add a DAPM kcontrol Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 735903a74675..46485de9e6f8 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -357,8 +357,9 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, path->long_name); ret = snd_ctl_add(codec->card, path->kcontrol); if (ret < 0) { - printk(KERN_ERR "asoc: failed to add dapm kcontrol %s\n", - path->long_name); + printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", + path->long_name, + ret); kfree(path->long_name); path->long_name = NULL; return ret; -- GitLab From 06f409d76f1d382167eb1cadde2e23a73272865d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Apr 2009 18:10:13 +0100 Subject: [PATCH 0202/6080] ASoC: Provide core support for symmetric sample rates Many devices require symmetric configurations of capture and playback data formats, often due to shared clocking but sometimes also due to other shared playback and record configuration in the device. Start providing core support for this by allowing the DAIs or the machine to specify that the sample rates used should be kept symmetric. A flag symmetric_rates is provided in the snd_soc_dai and snd_soc_dai_link structures. If this is set in either of the DAIs or in the machine then a constraint will be applied when a stream is already open preventing any changes in sample rate. Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 1 + include/sound/soc.h | 6 ++++++ sound/soc/soc-core.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 13676472ddfc..22b729fbbf84 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -208,6 +208,7 @@ struct snd_soc_dai { /* DAI capabilities */ struct snd_soc_pcm_stream capture; struct snd_soc_pcm_stream playback; + unsigned int symmetric_rates:1; /* DAI runtime info */ struct snd_pcm_runtime *runtime; diff --git a/include/sound/soc.h b/include/sound/soc.h index a40bc6f316fc..b1f2f8819fea 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -417,6 +417,12 @@ struct snd_soc_dai_link { /* codec/machine specific init - e.g. add machine controls */ int (*init)(struct snd_soc_codec *codec); + /* Symmetry requirements */ + unsigned int symmetric_rates:1; + + /* Symmetry data - only valid if symmetry is being enforced */ + unsigned int rate; + /* DAI pcm */ struct snd_pcm *pcm; }; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 99712f652d0d..dd28009f8969 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -113,6 +113,35 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec) } #endif +static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_card *card = socdev->card; + struct snd_soc_dai_link *machine = rtd->dai; + struct snd_soc_dai *cpu_dai = machine->cpu_dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; + int ret; + + if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates || + machine->symmetric_rates) { + dev_dbg(card->dev, "Symmetry forces %dHz rate\n", + machine->rate); + + ret = snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, + machine->rate, + machine->rate); + if (ret < 0) { + dev_err(card->dev, + "Unable to apply rate symmetry constraint: %d\n", ret); + return ret; + } + } + + return 0; +} + /* * Called by ALSA when a PCM substream is opened, the runtime->hw record is * then initialized and any private data can be allocated. This also calls @@ -221,6 +250,13 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) goto machine_err; } + /* Symmetry only applies if we've already got an active stream. */ + if (cpu_dai->active || codec_dai->active) { + ret = soc_pcm_apply_symmetry(substream); + if (ret != 0) + goto machine_err; + } + pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates); pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, @@ -521,6 +557,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, } } + machine->rate = params_rate(params); + out: mutex_unlock(&pcm_mutex); return ret; -- GitLab From 5409fb4e327a84972483047ecf4fb41f279453e2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Apr 2009 18:45:21 +0100 Subject: [PATCH 0203/6080] ASoC: Add WM8988 CODEC driver The WM8988 is a low power, high quality stereo CODEC designed for portable digital audio applications. The device integrates complete interfaces to 2 stereo headphone or line out ports. External component requirements are drastically reduced as no separate headphone amplifiers are required. Advanced on-chip digital signal processing performs graphic equaliser, 3-D sound enhancement and automatic level control for the microphone or line input. The WM8988 can operate as a master or a slave, with various master clock frequencies including 12 or 24MHz for USB devices, or standard 256fs rates like 12.288MHz and 24.576MHz. Different audio sample rates such as 96kHz, 48kHz, 44.1kHz are generated directly from the master clock without the need for an external PLL. Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm8988.c | 1097 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8988.h | 60 ++ 4 files changed, 1163 insertions(+) create mode 100644 sound/soc/codecs/wm8988.c create mode 100644 sound/soc/codecs/wm8988.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index b6c7f7a01cb0..ab364854675b 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -36,6 +36,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8900 if I2C select SND_SOC_WM8903 if I2C select SND_SOC_WM8971 if I2C + select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8990 if I2C select SND_SOC_WM9705 if SND_SOC_AC97_BUS select SND_SOC_WM9712 if SND_SOC_AC97_BUS @@ -141,6 +142,9 @@ config SND_SOC_WM8903 config SND_SOC_WM8971 tristate +config SND_SOC_WM8988 + tristate + config SND_SOC_WM8990 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 030d2454725f..a72548dc1885 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -24,6 +24,7 @@ snd-soc-wm8753-objs := wm8753.o snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o snd-soc-wm8971-objs := wm8971.o +snd-soc-wm8988-objs := wm8988.o snd-soc-wm8990-objs := wm8990.o snd-soc-wm9705-objs := wm9705.o snd-soc-wm9712-objs := wm9712.o @@ -55,6 +56,7 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o +obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c new file mode 100644 index 000000000000..c05f71803aa8 --- /dev/null +++ b/sound/soc/codecs/wm8988.c @@ -0,0 +1,1097 @@ +/* + * wm8988.c -- WM8988 ALSA SoC audio driver + * + * Copyright 2009 Wolfson Microelectronics plc + * Copyright 2005 Openedhand Ltd. + * + * Author: Mark Brown + * + * 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 +#include +#include + +#include "wm8988.h" + +/* + * wm8988 register cache + * We can't read the WM8988 register space when we + * are using 2 wire for device control, so we cache them instead. + */ +static const u16 wm8988_reg[] = { + 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ + 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ + 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ + 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ + 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ + 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ + 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ + 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ + 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ + 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ + 0x0079, 0x0079, 0x0079, /* 40 */ +}; + +/* codec private data */ +struct wm8988_priv { + unsigned int sysclk; + struct snd_soc_codec codec; + struct snd_pcm_hw_constraint_list *sysclk_constraints; + u16 reg_cache[WM8988_NUM_REG]; +}; + + +/* + * read wm8988 register cache + */ +static inline unsigned int wm8988_read_reg_cache(struct snd_soc_codec *codec, + unsigned int reg) +{ + u16 *cache = codec->reg_cache; + if (reg > WM8988_NUM_REG) + return -1; + return cache[reg]; +} + +/* + * write wm8988 register cache + */ +static inline void wm8988_write_reg_cache(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + u16 *cache = codec->reg_cache; + if (reg > WM8988_NUM_REG) + return; + cache[reg] = value; +} + +static int wm8988_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + u8 data[2]; + + /* data is + * D15..D9 WM8753 register offset + * D8...D0 register data + */ + data[0] = (reg << 1) | ((value >> 8) & 0x0001); + data[1] = value & 0x00ff; + + wm8988_write_reg_cache(codec, reg, value); + if (codec->hw_write(codec->control_data, data, 2) == 2) + return 0; + else + return -EIO; +} + +#define wm8988_reset(c) wm8988_write(c, WM8988_RESET, 0) + +/* + * WM8988 Controls + */ + +static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"}; +static const struct soc_enum bass_boost = + SOC_ENUM_SINGLE(WM8988_BASS, 7, 2, bass_boost_txt); + +static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" }; +static const struct soc_enum bass_filter = + SOC_ENUM_SINGLE(WM8988_BASS, 6, 2, bass_filter_txt); + +static const char *treble_txt[] = {"8kHz", "4kHz"}; +static const struct soc_enum treble = + SOC_ENUM_SINGLE(WM8988_TREBLE, 6, 2, treble_txt); + +static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"}; +static const struct soc_enum stereo_3d_lc = + SOC_ENUM_SINGLE(WM8988_3D, 5, 2, stereo_3d_lc_txt); + +static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"}; +static const struct soc_enum stereo_3d_uc = + SOC_ENUM_SINGLE(WM8988_3D, 6, 2, stereo_3d_uc_txt); + +static const char *stereo_3d_func_txt[] = {"Capture", "Playback"}; +static const struct soc_enum stereo_3d_func = + SOC_ENUM_SINGLE(WM8988_3D, 7, 2, stereo_3d_func_txt); + +static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"}; +static const struct soc_enum alc_func = + SOC_ENUM_SINGLE(WM8988_ALC1, 7, 4, alc_func_txt); + +static const char *ng_type_txt[] = {"Constant PGA Gain", + "Mute ADC Output"}; +static const struct soc_enum ng_type = + SOC_ENUM_SINGLE(WM8988_NGATE, 1, 2, ng_type_txt); + +static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"}; +static const struct soc_enum deemph = + SOC_ENUM_SINGLE(WM8988_ADCDAC, 1, 4, deemph_txt); + +static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert", + "L + R Invert"}; +static const struct soc_enum adcpol = + SOC_ENUM_SINGLE(WM8988_ADCDAC, 5, 4, adcpol_txt); + +static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0); +static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1); +static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); +static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); +static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); + +static const struct snd_kcontrol_new wm8988_snd_controls[] = { + +SOC_ENUM("Bass Boost", bass_boost), +SOC_ENUM("Bass Filter", bass_filter), +SOC_SINGLE("Bass Volume", WM8988_BASS, 0, 15, 1), + +SOC_SINGLE("Treble Volume", WM8988_TREBLE, 0, 15, 0), +SOC_ENUM("Treble Cut-off", treble), + +SOC_SINGLE("3D Switch", WM8988_3D, 0, 1, 0), +SOC_SINGLE("3D Volume", WM8988_3D, 1, 15, 0), +SOC_ENUM("3D Lower Cut-off", stereo_3d_lc), +SOC_ENUM("3D Upper Cut-off", stereo_3d_uc), +SOC_ENUM("3D Mode", stereo_3d_func), + +SOC_SINGLE("ALC Capture Target Volume", WM8988_ALC1, 0, 7, 0), +SOC_SINGLE("ALC Capture Max Volume", WM8988_ALC1, 4, 7, 0), +SOC_ENUM("ALC Capture Function", alc_func), +SOC_SINGLE("ALC Capture ZC Switch", WM8988_ALC2, 7, 1, 0), +SOC_SINGLE("ALC Capture Hold Time", WM8988_ALC2, 0, 15, 0), +SOC_SINGLE("ALC Capture Decay Time", WM8988_ALC3, 4, 15, 0), +SOC_SINGLE("ALC Capture Attack Time", WM8988_ALC3, 0, 15, 0), +SOC_SINGLE("ALC Capture NG Threshold", WM8988_NGATE, 3, 31, 0), +SOC_ENUM("ALC Capture NG Type", ng_type), +SOC_SINGLE("ALC Capture NG Switch", WM8988_NGATE, 0, 1, 0), + +SOC_SINGLE("ZC Timeout Switch", WM8988_ADCTL1, 0, 1, 0), + +SOC_DOUBLE_R_TLV("Capture Digital Volume", WM8988_LADC, WM8988_RADC, + 0, 255, 0, adc_tlv), +SOC_DOUBLE_R_TLV("Capture Volume", WM8988_LINVOL, WM8988_RINVOL, + 0, 63, 0, pga_tlv), +SOC_DOUBLE_R("Capture ZC Switch", WM8988_LINVOL, WM8988_RINVOL, 6, 1, 0), +SOC_DOUBLE_R("Capture Switch", WM8988_LINVOL, WM8988_RINVOL, 7, 1, 1), + +SOC_ENUM("Playback De-emphasis", deemph), + +SOC_ENUM("Capture Polarity", adcpol), +SOC_SINGLE("Playback 6dB Attenuate", WM8988_ADCDAC, 7, 1, 0), +SOC_SINGLE("Capture 6dB Attenuate", WM8988_ADCDAC, 8, 1, 0), + +SOC_DOUBLE_R_TLV("PCM Volume", WM8988_LDAC, WM8988_RDAC, 0, 255, 0, dac_tlv), + +SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", WM8988_LOUTM1, 4, 7, 1, + bypass_tlv), +SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", WM8988_LOUTM2, 4, 7, 1, + bypass_tlv), +SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", WM8988_ROUTM1, 4, 7, 1, + bypass_tlv), +SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", WM8988_ROUTM2, 4, 7, 1, + bypass_tlv), + +SOC_DOUBLE_R("Output 1 Playback ZC Switch", WM8988_LOUT1V, + WM8988_ROUT1V, 7, 1, 0), +SOC_DOUBLE_R_TLV("Output 1 Playback Volume", WM8988_LOUT1V, WM8988_ROUT1V, + 0, 127, 0, out_tlv), + +SOC_DOUBLE_R("Output 2 Playback ZC Switch", WM8988_LOUT2V, + WM8988_ROUT2V, 7, 1, 0), +SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V, + 0, 127, 0, out_tlv), + +}; + +/* + * DAPM Controls + */ + +static int wm8988_lrc_control(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + u16 adctl2 = wm8988_read_reg_cache(codec, WM8988_ADCTL2); + + /* Use the DAC to gate LRC if active, otherwise use ADC */ + if (wm8988_read_reg_cache(codec, WM8988_PWR2) & 0x180) + adctl2 &= ~0x4; + else + adctl2 |= 0x4; + + return wm8988_write(codec, WM8988_ADCTL2, adctl2); +} + +static const char *wm8988_line_texts[] = { + "Line 1", "Line 2", "PGA", "Differential"}; + +static const unsigned int wm8988_line_values[] = { + 0, 1, 3, 4}; + +static const struct soc_enum wm8988_lline_enum = + SOC_VALUE_ENUM_SINGLE(WM8988_LOUTM1, 0, 7, + ARRAY_SIZE(wm8988_line_texts), + wm8988_line_texts, + wm8988_line_values); +static const struct snd_kcontrol_new wm8988_left_line_controls = + SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); + +static const struct soc_enum wm8988_rline_enum = + SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7, + ARRAY_SIZE(wm8988_line_texts), + wm8988_line_texts, + wm8988_line_values); +static const struct snd_kcontrol_new wm8988_right_line_controls = + SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); + +/* Left Mixer */ +static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { + SOC_DAPM_SINGLE("Playback Switch", WM8988_LOUTM1, 8, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_LOUTM1, 7, 1, 0), + SOC_DAPM_SINGLE("Right Playback Switch", WM8988_LOUTM2, 8, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_LOUTM2, 7, 1, 0), +}; + +/* Right Mixer */ +static const struct snd_kcontrol_new wm8988_right_mixer_controls[] = { + SOC_DAPM_SINGLE("Left Playback Switch", WM8988_ROUTM1, 8, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_ROUTM1, 7, 1, 0), + SOC_DAPM_SINGLE("Playback Switch", WM8988_ROUTM2, 8, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_ROUTM2, 7, 1, 0), +}; + +static const char *wm8988_pga_sel[] = {"Line 1", "Line 2", "Differential"}; +static const unsigned int wm8988_pga_val[] = { 0, 1, 3 }; + +/* Left PGA Mux */ +static const struct soc_enum wm8988_lpga_enum = + SOC_VALUE_ENUM_SINGLE(WM8988_LADCIN, 6, 3, + ARRAY_SIZE(wm8988_pga_sel), + wm8988_pga_sel, + wm8988_pga_val); +static const struct snd_kcontrol_new wm8988_left_pga_controls = + SOC_DAPM_VALUE_ENUM("Route", wm8988_lpga_enum); + +/* Right PGA Mux */ +static const struct soc_enum wm8988_rpga_enum = + SOC_VALUE_ENUM_SINGLE(WM8988_RADCIN, 6, 3, + ARRAY_SIZE(wm8988_pga_sel), + wm8988_pga_sel, + wm8988_pga_val); +static const struct snd_kcontrol_new wm8988_right_pga_controls = + SOC_DAPM_VALUE_ENUM("Route", wm8988_rpga_enum); + +/* Differential Mux */ +static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"}; +static const struct soc_enum diffmux = + SOC_ENUM_SINGLE(WM8988_ADCIN, 8, 2, wm8988_diff_sel); +static const struct snd_kcontrol_new wm8988_diffmux_controls = + SOC_DAPM_ENUM("Route", diffmux); + +/* Mono ADC Mux */ +static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)", + "Mono (Right)", "Digital Mono"}; +static const struct soc_enum monomux = + SOC_ENUM_SINGLE(WM8988_ADCIN, 6, 4, wm8988_mono_mux); +static const struct snd_kcontrol_new wm8988_monomux_controls = + SOC_DAPM_ENUM("Route", monomux); + +static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = { + SND_SOC_DAPM_MICBIAS("Mic Bias", WM8988_PWR1, 1, 0), + + SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, + &wm8988_diffmux_controls), + SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, + &wm8988_monomux_controls), + SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, + &wm8988_monomux_controls), + + SND_SOC_DAPM_MUX("Left PGA Mux", WM8988_PWR1, 5, 0, + &wm8988_left_pga_controls), + SND_SOC_DAPM_MUX("Right PGA Mux", WM8988_PWR1, 4, 0, + &wm8988_right_pga_controls), + + SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, + &wm8988_left_line_controls), + SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, + &wm8988_right_line_controls), + + SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8988_PWR1, 2, 0), + SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8988_PWR1, 3, 0), + + SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0), + SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0), + + SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, + &wm8988_left_mixer_controls[0], + ARRAY_SIZE(wm8988_left_mixer_controls)), + SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, + &wm8988_right_mixer_controls[0], + ARRAY_SIZE(wm8988_right_mixer_controls)), + + SND_SOC_DAPM_PGA("Right Out 2", WM8988_PWR2, 3, 0, NULL, 0), + SND_SOC_DAPM_PGA("Left Out 2", WM8988_PWR2, 4, 0, NULL, 0), + SND_SOC_DAPM_PGA("Right Out 1", WM8988_PWR2, 5, 0, NULL, 0), + SND_SOC_DAPM_PGA("Left Out 1", WM8988_PWR2, 6, 0, NULL, 0), + + SND_SOC_DAPM_POST("LRC control", wm8988_lrc_control), + + SND_SOC_DAPM_OUTPUT("LOUT1"), + SND_SOC_DAPM_OUTPUT("ROUT1"), + SND_SOC_DAPM_OUTPUT("LOUT2"), + SND_SOC_DAPM_OUTPUT("ROUT2"), + SND_SOC_DAPM_OUTPUT("VREF"), + + SND_SOC_DAPM_INPUT("LINPUT1"), + SND_SOC_DAPM_INPUT("LINPUT2"), + SND_SOC_DAPM_INPUT("RINPUT1"), + SND_SOC_DAPM_INPUT("RINPUT2"), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + + { "Left Line Mux", "Line 1", "LINPUT1" }, + { "Left Line Mux", "Line 2", "LINPUT2" }, + { "Left Line Mux", "PGA", "Left PGA Mux" }, + { "Left Line Mux", "Differential", "Differential Mux" }, + + { "Right Line Mux", "Line 1", "RINPUT1" }, + { "Right Line Mux", "Line 2", "RINPUT2" }, + { "Right Line Mux", "PGA", "Right PGA Mux" }, + { "Right Line Mux", "Differential", "Differential Mux" }, + + { "Left PGA Mux", "Line 1", "LINPUT1" }, + { "Left PGA Mux", "Line 2", "LINPUT2" }, + { "Left PGA Mux", "Differential", "Differential Mux" }, + + { "Right PGA Mux", "Line 1", "RINPUT1" }, + { "Right PGA Mux", "Line 2", "RINPUT2" }, + { "Right PGA Mux", "Differential", "Differential Mux" }, + + { "Differential Mux", "Line 1", "LINPUT1" }, + { "Differential Mux", "Line 1", "RINPUT1" }, + { "Differential Mux", "Line 2", "LINPUT2" }, + { "Differential Mux", "Line 2", "RINPUT2" }, + + { "Left ADC Mux", "Stereo", "Left PGA Mux" }, + { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" }, + { "Left ADC Mux", "Digital Mono", "Left PGA Mux" }, + + { "Right ADC Mux", "Stereo", "Right PGA Mux" }, + { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" }, + { "Right ADC Mux", "Digital Mono", "Right PGA Mux" }, + + { "Left ADC", NULL, "Left ADC Mux" }, + { "Right ADC", NULL, "Right ADC Mux" }, + + { "Left Line Mux", "Line 1", "LINPUT1" }, + { "Left Line Mux", "Line 2", "LINPUT2" }, + { "Left Line Mux", "PGA", "Left PGA Mux" }, + { "Left Line Mux", "Differential", "Differential Mux" }, + + { "Right Line Mux", "Line 1", "RINPUT1" }, + { "Right Line Mux", "Line 2", "RINPUT2" }, + { "Right Line Mux", "PGA", "Right PGA Mux" }, + { "Right Line Mux", "Differential", "Differential Mux" }, + + { "Left Mixer", "Playback Switch", "Left DAC" }, + { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, + { "Left Mixer", "Right Playback Switch", "Right DAC" }, + { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "Right Mixer", "Left Playback Switch", "Left DAC" }, + { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, + { "Right Mixer", "Playback Switch", "Right DAC" }, + { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "Left Out 1", NULL, "Left Mixer" }, + { "LOUT1", NULL, "Left Out 1" }, + { "Right Out 1", NULL, "Right Mixer" }, + { "ROUT1", NULL, "Right Out 1" }, + + { "Left Out 2", NULL, "Left Mixer" }, + { "LOUT2", NULL, "Left Out 2" }, + { "Right Out 2", NULL, "Right Mixer" }, + { "ROUT2", NULL, "Right Out 2" }, +}; + +struct _coeff_div { + u32 mclk; + u32 rate; + u16 fs; + u8 sr:5; + u8 usb:1; +}; + +/* codec hifi mclk clock divider coefficients */ +static const struct _coeff_div coeff_div[] = { + /* 8k */ + {12288000, 8000, 1536, 0x6, 0x0}, + {11289600, 8000, 1408, 0x16, 0x0}, + {18432000, 8000, 2304, 0x7, 0x0}, + {16934400, 8000, 2112, 0x17, 0x0}, + {12000000, 8000, 1500, 0x6, 0x1}, + + /* 11.025k */ + {11289600, 11025, 1024, 0x18, 0x0}, + {16934400, 11025, 1536, 0x19, 0x0}, + {12000000, 11025, 1088, 0x19, 0x1}, + + /* 16k */ + {12288000, 16000, 768, 0xa, 0x0}, + {18432000, 16000, 1152, 0xb, 0x0}, + {12000000, 16000, 750, 0xa, 0x1}, + + /* 22.05k */ + {11289600, 22050, 512, 0x1a, 0x0}, + {16934400, 22050, 768, 0x1b, 0x0}, + {12000000, 22050, 544, 0x1b, 0x1}, + + /* 32k */ + {12288000, 32000, 384, 0xc, 0x0}, + {18432000, 32000, 576, 0xd, 0x0}, + {12000000, 32000, 375, 0xa, 0x1}, + + /* 44.1k */ + {11289600, 44100, 256, 0x10, 0x0}, + {16934400, 44100, 384, 0x11, 0x0}, + {12000000, 44100, 272, 0x11, 0x1}, + + /* 48k */ + {12288000, 48000, 256, 0x0, 0x0}, + {18432000, 48000, 384, 0x1, 0x0}, + {12000000, 48000, 250, 0x0, 0x1}, + + /* 88.2k */ + {11289600, 88200, 128, 0x1e, 0x0}, + {16934400, 88200, 192, 0x1f, 0x0}, + {12000000, 88200, 136, 0x1f, 0x1}, + + /* 96k */ + {12288000, 96000, 128, 0xe, 0x0}, + {18432000, 96000, 192, 0xf, 0x0}, + {12000000, 96000, 125, 0xe, 0x1}, +}; + +static inline int get_coeff(int mclk, int rate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) + return i; + } + + return -EINVAL; +} + +/* The set of rates we can generate from the above for each SYSCLK */ + +static unsigned int rates_12288[] = { + 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000, +}; + +static struct snd_pcm_hw_constraint_list constraints_12288 = { + .count = ARRAY_SIZE(rates_12288), + .list = rates_12288, +}; + +static unsigned int rates_112896[] = { + 8000, 11025, 22050, 44100, +}; + +static struct snd_pcm_hw_constraint_list constraints_112896 = { + .count = ARRAY_SIZE(rates_112896), + .list = rates_112896, +}; + +static unsigned int rates_12[] = { + 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000, + 48000, 88235, 96000, +}; + +static struct snd_pcm_hw_constraint_list constraints_12 = { + .count = ARRAY_SIZE(rates_12), + .list = rates_12, +}; + +/* + * Note that this should be called from init rather than from hw_params. + */ +static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct wm8988_priv *wm8988 = codec->private_data; + + switch (freq) { + case 11289600: + case 18432000: + case 22579200: + case 36864000: + wm8988->sysclk_constraints = &constraints_112896; + wm8988->sysclk = freq; + return 0; + + case 12288000: + case 16934400: + case 24576000: + case 33868800: + wm8988->sysclk_constraints = &constraints_12288; + wm8988->sysclk = freq; + return 0; + + case 12000000: + case 24000000: + wm8988->sysclk_constraints = &constraints_12; + wm8988->sysclk = freq; + return 0; + } + return -EINVAL; +} + +static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 iface = 0; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iface = 0x0040; + break; + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface |= 0x0002; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + iface |= 0x0001; + break; + case SND_SOC_DAIFMT_DSP_A: + iface |= 0x0003; + break; + case SND_SOC_DAIFMT_DSP_B: + iface |= 0x0013; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + iface |= 0x0090; + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= 0x0080; + break; + case SND_SOC_DAIFMT_NB_IF: + iface |= 0x0010; + break; + default: + return -EINVAL; + } + + wm8988_write(codec, WM8988_IFACE, iface); + return 0; +} + +static int wm8988_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8988_priv *wm8988 = codec->private_data; + + /* The set of sample rates that can be supported depends on the + * MCLK supplied to the CODEC - enforce this. + */ + if (!wm8988->sysclk) { + dev_err(codec->dev, + "No MCLK configured, call set_sysclk() on init\n"); + return -EINVAL; + } + + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + wm8988->sysclk_constraints); + + return 0; +} + +static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + struct wm8988_priv *wm8988 = codec->private_data; + u16 iface = wm8988_read_reg_cache(codec, WM8988_IFACE) & 0x1f3; + u16 srate = wm8988_read_reg_cache(codec, WM8988_SRATE) & 0x180; + int coeff; + + coeff = get_coeff(wm8988->sysclk, params_rate(params)); + if (coeff < 0) { + coeff = get_coeff(wm8988->sysclk / 2, params_rate(params)); + srate |= 0x40; + } + if (coeff < 0) { + dev_err(codec->dev, + "Unable to configure sample rate %dHz with %dHz MCLK\n", + params_rate(params), wm8988->sysclk); + return coeff; + } + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + iface |= 0x0004; + break; + case SNDRV_PCM_FORMAT_S24_LE: + iface |= 0x0008; + break; + case SNDRV_PCM_FORMAT_S32_LE: + iface |= 0x000c; + break; + } + + /* set iface & srate */ + wm8988_write(codec, WM8988_IFACE, iface); + if (coeff >= 0) + wm8988_write(codec, WM8988_SRATE, srate | + (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); + + return 0; +} + +static int wm8988_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u16 mute_reg = wm8988_read_reg_cache(codec, WM8988_ADCDAC) & 0xfff7; + + if (mute) + wm8988_write(codec, WM8988_ADCDAC, mute_reg | 0x8); + else + wm8988_write(codec, WM8988_ADCDAC, mute_reg); + return 0; +} + +static int wm8988_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + u16 pwr_reg = wm8988_read_reg_cache(codec, WM8988_PWR1) & ~0x1c1; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* VREF, VMID=2x50k, digital enabled */ + wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x00c0); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->bias_level == SND_SOC_BIAS_OFF) { + /* VREF, VMID=2x5k */ + wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); + + /* Charge caps */ + msleep(100); + } + + /* VREF, VMID=2*500k, digital stopped */ + wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x0141); + break; + + case SND_SOC_BIAS_OFF: + wm8988_write(codec, WM8988_PWR1, 0x0000); + break; + } + codec->bias_level = level; + return 0; +} + +#define WM8988_RATES SNDRV_PCM_RATE_8000_96000 + +#define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE) + +static struct snd_soc_dai_ops wm8988_ops = { + .startup = wm8988_pcm_startup, + .hw_params = wm8988_pcm_hw_params, + .set_fmt = wm8988_set_dai_fmt, + .set_sysclk = wm8988_set_dai_sysclk, + .digital_mute = wm8988_mute, +}; + +struct snd_soc_dai wm8988_dai = { + .name = "WM8988", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8988_RATES, + .formats = WM8988_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8988_RATES, + .formats = WM8988_FORMATS, + }, + .ops = &wm8988_ops, + .symmetric_rates = 1, +}; +EXPORT_SYMBOL_GPL(wm8988_dai); + +static int wm8988_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int wm8988_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + int i; + u8 data[2]; + u16 *cache = codec->reg_cache; + + /* Sync reg_cache with the hardware */ + for (i = 0; i < WM8988_NUM_REG; i++) { + if (i == WM8988_RESET) + continue; + data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); + data[1] = cache[i] & 0x00ff; + codec->hw_write(codec->control_data, data, 2); + } + + wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + return 0; +} + +static struct snd_soc_codec *wm8988_codec; + +static int wm8988_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec; + int ret = 0; + + if (wm8988_codec == NULL) { + dev_err(&pdev->dev, "Codec device not registered\n"); + return -ENODEV; + } + + socdev->card->codec = wm8988_codec; + codec = wm8988_codec; + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + dev_err(codec->dev, "failed to create pcms: %d\n", ret); + goto pcm_err; + } + + snd_soc_add_controls(codec, wm8988_snd_controls, + ARRAY_SIZE(wm8988_snd_controls)); + snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets, + ARRAY_SIZE(wm8988_dapm_widgets)); + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_widgets(codec); + + ret = snd_soc_init_card(socdev); + if (ret < 0) { + dev_err(codec->dev, "failed to register card: %d\n", ret); + goto card_err; + } + + return ret; + +card_err: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +pcm_err: + return ret; +} + +static int wm8988_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_wm8988 = { + .probe = wm8988_probe, + .remove = wm8988_remove, + .suspend = wm8988_suspend, + .resume = wm8988_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988); + +static int wm8988_register(struct wm8988_priv *wm8988) +{ + struct snd_soc_codec *codec = &wm8988->codec; + int ret; + u16 reg; + + if (wm8988_codec) { + dev_err(codec->dev, "Another WM8988 is registered\n"); + ret = -EINVAL; + goto err; + } + + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + + codec->private_data = wm8988; + codec->name = "WM8988"; + codec->owner = THIS_MODULE; + codec->read = wm8988_read_reg_cache; + codec->write = wm8988_write; + codec->dai = &wm8988_dai; + codec->num_dai = 1; + codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache); + codec->reg_cache = &wm8988->reg_cache; + codec->bias_level = SND_SOC_BIAS_OFF; + codec->set_bias_level = wm8988_set_bias_level; + + memcpy(codec->reg_cache, wm8988_reg, + sizeof(wm8988_reg)); + + ret = wm8988_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset\n"); + return ret; + } + + /* set the update bits (we always update left then right) */ + reg = wm8988_read_reg_cache(codec, WM8988_RADC); + wm8988_write(codec, WM8988_RADC, reg | 0x100); + reg = wm8988_read_reg_cache(codec, WM8988_RDAC); + wm8988_write(codec, WM8988_RDAC, reg | 0x0100); + reg = wm8988_read_reg_cache(codec, WM8988_ROUT1V); + wm8988_write(codec, WM8988_ROUT1V, reg | 0x0100); + reg = wm8988_read_reg_cache(codec, WM8988_ROUT2V); + wm8988_write(codec, WM8988_ROUT2V, reg | 0x0100); + reg = wm8988_read_reg_cache(codec, WM8988_RINVOL); + wm8988_write(codec, WM8988_RINVOL, reg | 0x0100); + + wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY); + + wm8988_dai.dev = codec->dev; + + wm8988_codec = codec; + + ret = snd_soc_register_codec(codec); + if (ret != 0) { + dev_err(codec->dev, "Failed to register codec: %d\n", ret); + return ret; + } + + ret = snd_soc_register_dai(&wm8988_dai); + if (ret != 0) { + dev_err(codec->dev, "Failed to register DAI: %d\n", ret); + snd_soc_unregister_codec(codec); + return ret; + } + + return 0; + +err: + kfree(wm8988); + return ret; +} + +static void wm8988_unregister(struct wm8988_priv *wm8988) +{ + wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_OFF); + snd_soc_unregister_dai(&wm8988_dai); + snd_soc_unregister_codec(&wm8988->codec); + kfree(wm8988); + wm8988_codec = NULL; +} + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static int wm8988_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8988_priv *wm8988; + struct snd_soc_codec *codec; + + wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); + if (wm8988 == NULL) + return -ENOMEM; + + codec = &wm8988->codec; + codec->hw_write = (hw_write_t)i2c_master_send; + + i2c_set_clientdata(i2c, wm8988); + codec->control_data = i2c; + + codec->dev = &i2c->dev; + + return wm8988_register(wm8988); +} + +static int wm8988_i2c_remove(struct i2c_client *client) +{ + struct wm8988_priv *wm8988 = i2c_get_clientdata(client); + wm8988_unregister(wm8988); + return 0; +} + +static const struct i2c_device_id wm8988_i2c_id[] = { + { "wm8988", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id); + +static struct i2c_driver wm8988_i2c_driver = { + .driver = { + .name = "WM8988", + .owner = THIS_MODULE, + }, + .probe = wm8988_i2c_probe, + .remove = wm8988_i2c_remove, + .id_table = wm8988_i2c_id, +}; +#endif + +#if defined(CONFIG_SPI_MASTER) +static int wm8988_spi_write(struct spi_device *spi, const char *data, int len) +{ + struct spi_transfer t; + struct spi_message m; + u8 msg[2]; + + if (len <= 0) + return 0; + + msg[0] = data[0]; + msg[1] = data[1]; + + spi_message_init(&m); + memset(&t, 0, (sizeof t)); + + t.tx_buf = &msg[0]; + t.len = len; + + spi_message_add_tail(&t, &m); + spi_sync(spi, &m); + + return len; +} + +static int __devinit wm8988_spi_probe(struct spi_device *spi) +{ + struct wm8988_priv *wm8988; + struct snd_soc_codec *codec; + + wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); + if (wm8988 == NULL) + return -ENOMEM; + + codec = &wm8988->codec; + codec->hw_write = (hw_write_t)wm8988_spi_write; + codec->control_data = spi; + codec->dev = &spi->dev; + + spi->dev.driver_data = wm8988; + + return wm8988_register(wm8988); +} + +static int __devexit wm8988_spi_remove(struct spi_device *spi) +{ + struct wm8988_priv *wm8988 = spi->dev.driver_data; + + wm8988_unregister(wm8988); + + return 0; +} + +static struct spi_driver wm8988_spi_driver = { + .driver = { + .name = "wm8988", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = wm8988_spi_probe, + .remove = __devexit_p(wm8988_spi_remove), +}; +#endif + +static int __init wm8988_modinit(void) +{ + int ret; + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + ret = i2c_add_driver(&wm8988_i2c_driver); + if (ret != 0) + pr_err("WM8988: Unable to register I2C driver: %d\n", ret); +#endif +#if defined(CONFIG_SPI_MASTER) + ret = spi_register_driver(&wm8988_spi_driver); + if (ret != 0) + pr_err("WM8988: Unable to register SPI driver: %d\n", ret); +#endif + return ret; +} +module_init(wm8988_modinit); + +static void __exit wm8988_exit(void) +{ +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + i2c_del_driver(&wm8988_i2c_driver); +#endif +#if defined(CONFIG_SPI_MASTER) + spi_unregister_driver(&wm8988_spi_driver); +#endif +} +module_exit(wm8988_exit); + + +MODULE_DESCRIPTION("ASoC WM8988 driver"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8988.h b/sound/soc/codecs/wm8988.h new file mode 100644 index 000000000000..4552d37fdd41 --- /dev/null +++ b/sound/soc/codecs/wm8988.h @@ -0,0 +1,60 @@ +/* + * Copyright 2005 Openedhand Ltd. + * + * Author: Richard Purdie + * + * Based on WM8753.h + * + * 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 _WM8988_H +#define _WM8988_H + +/* WM8988 register space */ + +#define WM8988_LINVOL 0x00 +#define WM8988_RINVOL 0x01 +#define WM8988_LOUT1V 0x02 +#define WM8988_ROUT1V 0x03 +#define WM8988_ADCDAC 0x05 +#define WM8988_IFACE 0x07 +#define WM8988_SRATE 0x08 +#define WM8988_LDAC 0x0a +#define WM8988_RDAC 0x0b +#define WM8988_BASS 0x0c +#define WM8988_TREBLE 0x0d +#define WM8988_RESET 0x0f +#define WM8988_3D 0x10 +#define WM8988_ALC1 0x11 +#define WM8988_ALC2 0x12 +#define WM8988_ALC3 0x13 +#define WM8988_NGATE 0x14 +#define WM8988_LADC 0x15 +#define WM8988_RADC 0x16 +#define WM8988_ADCTL1 0x17 +#define WM8988_ADCTL2 0x18 +#define WM8988_PWR1 0x19 +#define WM8988_PWR2 0x1a +#define WM8988_ADCTL3 0x1b +#define WM8988_ADCIN 0x1f +#define WM8988_LADCIN 0x20 +#define WM8988_RADCIN 0x21 +#define WM8988_LOUTM1 0x22 +#define WM8988_LOUTM2 0x23 +#define WM8988_ROUTM1 0x24 +#define WM8988_ROUTM2 0x25 +#define WM8988_LOUT2V 0x28 +#define WM8988_ROUT2V 0x29 +#define WM8988_LPPB 0x43 +#define WM8988_NUM_REG 0x44 + +#define WM8988_SYSCLK 0 + +extern struct snd_soc_dai wm8988_dai; +extern struct snd_soc_codec_device soc_codec_dev_wm8988; + +#endif -- GitLab From dc66270b51a62b1a6888d5309229e638a305c47b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 8 Apr 2009 20:30:10 +1000 Subject: [PATCH 0204/6080] perf_counter: fix powerpc build Commit 4af4998b ("perf_counter: rework context time") changed struct perf_counter_context to have a 'time' field instead of a 'time_now' field, but neglected to fix the place in the powerpc perf_counter.c where the time_now field was accessed. This fixes it. Signed-off-by: Paul Mackerras Cc: Peter Zijlstra LKML-Reference: <18908.31922.411398.147810@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index f88c35d0710a..0e5651385ddc 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -457,8 +457,7 @@ static void counter_sched_in(struct perf_counter *counter, int cpu) { counter->state = PERF_COUNTER_STATE_ACTIVE; counter->oncpu = cpu; - counter->tstamp_running += counter->ctx->time_now - - counter->tstamp_stopped; + counter->tstamp_running += counter->ctx->time - counter->tstamp_stopped; if (is_software_counter(counter)) counter->hw_ops->enable(counter); } -- GitLab From f708223d49ac39f5af1643985056206c98033f5b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 8 Apr 2009 20:30:18 +1000 Subject: [PATCH 0205/6080] perf_counter: powerpc: set sample enable bit for marked instruction events Impact: enable access to hardware feature POWER processors have the ability to "mark" a subset of the instructions and provide more detailed information on what happens to the marked instructions as they flow through the pipeline. This marking is enabled by the "sample enable" bit in MMCRA, and there are synchronization requirements around setting and clearing the bit. This adds logic to the processor-specific back-ends so that they know which events relate to marked instructions and set the sampling enable bit if any event that we want to put on the PMU is a marked instruction event. It also adds logic to the generic powerpc code to do the necessary synchronization if that bit is set. Signed-off-by: Paul Mackerras Cc: Peter Zijlstra LKML-Reference: <18908.31930.1024.228867@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 28 +++++-- arch/powerpc/kernel/power5+-pmu.c | 103 ++++++++++++++++++++++- arch/powerpc/kernel/power5-pmu.c | 96 +++++++++++++++++++++- arch/powerpc/kernel/power6-pmu.c | 126 ++++++++++++++++++++++++++++- arch/powerpc/kernel/ppc970-pmu.c | 72 ++++++++++++++++- 5 files changed, 413 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 0e5651385ddc..0697ade84dd3 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -306,6 +306,15 @@ u64 hw_perf_save_disable(void) cpuhw->pmcs_enabled = 1; } + /* + * Disable instruction sampling if it was enabled + */ + if (cpuhw->mmcr[2] & MMCRA_SAMPLE_ENABLE) { + mtspr(SPRN_MMCRA, + cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE); + mb(); + } + /* * Set the 'freeze counters' bit. * The barrier is to make sure the mtspr has been @@ -347,12 +356,11 @@ void hw_perf_restore(u64 disable) * (possibly updated for removal of counters). */ if (!cpuhw->n_added) { - mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); + mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE); mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); - mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); if (cpuhw->n_counters == 0) get_lppaca()->pmcregs_in_use = 0; - goto out; + goto out_enable; } /* @@ -385,7 +393,7 @@ void hw_perf_restore(u64 disable) * Then unfreeze the counters. */ get_lppaca()->pmcregs_in_use = 1; - mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); + mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE); mtspr(SPRN_MMCR1, cpuhw->mmcr[1]); mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)) | MMCR0_FC); @@ -421,10 +429,20 @@ void hw_perf_restore(u64 disable) write_pmc(counter->hw.idx, val); perf_counter_update_userpage(counter); } - mb(); cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE; + + out_enable: + mb(); mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); + /* + * Enable instruction sampling if necessary + */ + if (cpuhw->mmcr[2] & MMCRA_SAMPLE_ENABLE) { + mb(); + mtspr(SPRN_MMCRA, cpuhw->mmcr[2]); + } + out: local_irq_restore(flags); } diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c index cec21ea65b0e..1222c8ea3c26 100644 --- a/arch/powerpc/kernel/power5+-pmu.c +++ b/arch/powerpc/kernel/power5+-pmu.c @@ -1,5 +1,5 @@ /* - * Performance counter support for POWER5 (not POWER5++) processors. + * Performance counter support for POWER5+/++ (not POWER5) processors. * * Copyright 2009 Paul Mackerras, IBM Corporation. * @@ -281,10 +281,107 @@ static int power5p_get_alternatives(unsigned int event, unsigned int alt[]) return nalt; } +/* + * Map of which direct events on which PMCs are marked instruction events. + * Indexed by PMCSEL value, bit i (LE) set if PMC i is a marked event. + * Bit 0 is set if it is marked for all PMCs. + * The 0x80 bit indicates a byte decode PMCSEL value. + */ +static unsigned char direct_event_is_marked[0x28] = { + 0, /* 00 */ + 0x1f, /* 01 PM_IOPS_CMPL */ + 0x2, /* 02 PM_MRK_GRP_DISP */ + 0xe, /* 03 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */ + 0, /* 04 */ + 0x1c, /* 05 PM_MRK_BRU_FIN, PM_MRK_INST_FIN, PM_MRK_CRU_FIN */ + 0x80, /* 06 */ + 0x80, /* 07 */ + 0, 0, 0,/* 08 - 0a */ + 0x18, /* 0b PM_THRESH_TIMEO, PM_MRK_GRP_TIMEO */ + 0, /* 0c */ + 0x80, /* 0d */ + 0x80, /* 0e */ + 0, /* 0f */ + 0, /* 10 */ + 0x14, /* 11 PM_MRK_GRP_BR_REDIR, PM_MRK_GRP_IC_MISS */ + 0, /* 12 */ + 0x10, /* 13 PM_MRK_GRP_CMPL */ + 0x1f, /* 14 PM_GRP_MRK, PM_MRK_{FXU,FPU,LSU}_FIN */ + 0x2, /* 15 PM_MRK_GRP_ISSUED */ + 0x80, /* 16 */ + 0x80, /* 17 */ + 0, 0, 0, 0, 0, + 0x80, /* 1d */ + 0x80, /* 1e */ + 0, /* 1f */ + 0x80, /* 20 */ + 0x80, /* 21 */ + 0x80, /* 22 */ + 0x80, /* 23 */ + 0x80, /* 24 */ + 0x80, /* 25 */ + 0x80, /* 26 */ + 0x80, /* 27 */ +}; + +/* + * Returns 1 if event counts things relating to marked instructions + * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not. + */ +static int power5p_marked_instr_event(unsigned int event) +{ + int pmc, psel; + int bit, byte, unit; + u32 mask; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + psel = event & PM_PMCSEL_MSK; + if (pmc >= 5) + return 0; + + bit = -1; + if (psel < sizeof(direct_event_is_marked)) { + if (direct_event_is_marked[psel] & (1 << pmc)) + return 1; + if (direct_event_is_marked[psel] & 0x80) + bit = 4; + else if (psel == 0x08) + bit = pmc - 1; + else if (psel == 0x10) + bit = 4 - pmc; + else if (psel == 0x1b && (pmc == 1 || pmc == 3)) + bit = 4; + } else if ((psel & 0x48) == 0x40) { + bit = psel & 7; + } else if (psel == 0x28) { + bit = pmc - 1; + } else if (pmc == 3 && (psel == 0x2e || psel == 0x2f)) { + bit = 4; + } + + if (!(event & PM_BUSEVENT_MSK) || bit == -1) + return 0; + + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; + if (unit == PM_LSU0) { + /* byte 1 bits 0-7, byte 2 bits 0,2-4,6 */ + mask = 0x5dff00; + } else if (unit == PM_LSU1 && byte >= 4) { + byte -= 4; + /* byte 5 bits 6-7, byte 6 bits 0,4, byte 7 bits 0-4,6 */ + mask = 0x5f11c000; + } else + return 0; + + return (mask >> (byte * 8 + bit)) & 1; +} + static int power5p_compute_mmcr(unsigned int event[], int n_ev, unsigned int hwc[], u64 mmcr[]) { u64 mmcr1 = 0; + u64 mmcra = 0; unsigned int pmc, unit, byte, psel; unsigned int ttm; int i, isbus, bit, grsel; @@ -404,6 +501,8 @@ static int power5p_compute_mmcr(unsigned int event[], int n_ev, grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK; mmcr1 |= (u64)grsel << grsel_shift[bit]; } + if (power5p_marked_instr_event(event[i])) + mmcra |= MMCRA_SAMPLE_ENABLE; if ((psel & 0x58) == 0x40 && (byte & 1) != ((pmc >> 1) & 1)) /* select alternate byte lane */ psel |= 0x10; @@ -419,7 +518,7 @@ static int power5p_compute_mmcr(unsigned int event[], int n_ev, if (pmc_inuse & 0x3e) mmcr[0] |= MMCR0_PMCjCE; mmcr[1] = mmcr1; - mmcr[2] = 0; + mmcr[2] = mmcra; return 0; } diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c index 379ed1087cca..116c4bb1809e 100644 --- a/arch/powerpc/kernel/power5-pmu.c +++ b/arch/powerpc/kernel/power5-pmu.c @@ -290,10 +290,102 @@ static int power5_get_alternatives(unsigned int event, unsigned int alt[]) return nalt; } +/* + * Map of which direct events on which PMCs are marked instruction events. + * Indexed by PMCSEL value, bit i (LE) set if PMC i is a marked event. + * Bit 0 is set if it is marked for all PMCs. + * The 0x80 bit indicates a byte decode PMCSEL value. + */ +static unsigned char direct_event_is_marked[0x28] = { + 0, /* 00 */ + 0x1f, /* 01 PM_IOPS_CMPL */ + 0x2, /* 02 PM_MRK_GRP_DISP */ + 0xe, /* 03 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */ + 0, /* 04 */ + 0x1c, /* 05 PM_MRK_BRU_FIN, PM_MRK_INST_FIN, PM_MRK_CRU_FIN */ + 0x80, /* 06 */ + 0x80, /* 07 */ + 0, 0, 0,/* 08 - 0a */ + 0x18, /* 0b PM_THRESH_TIMEO, PM_MRK_GRP_TIMEO */ + 0, /* 0c */ + 0x80, /* 0d */ + 0x80, /* 0e */ + 0, /* 0f */ + 0, /* 10 */ + 0x14, /* 11 PM_MRK_GRP_BR_REDIR, PM_MRK_GRP_IC_MISS */ + 0, /* 12 */ + 0x10, /* 13 PM_MRK_GRP_CMPL */ + 0x1f, /* 14 PM_GRP_MRK, PM_MRK_{FXU,FPU,LSU}_FIN */ + 0x2, /* 15 PM_MRK_GRP_ISSUED */ + 0x80, /* 16 */ + 0x80, /* 17 */ + 0, 0, 0, 0, 0, + 0x80, /* 1d */ + 0x80, /* 1e */ + 0, /* 1f */ + 0x80, /* 20 */ + 0x80, /* 21 */ + 0x80, /* 22 */ + 0x80, /* 23 */ + 0x80, /* 24 */ + 0x80, /* 25 */ + 0x80, /* 26 */ + 0x80, /* 27 */ +}; + +/* + * Returns 1 if event counts things relating to marked instructions + * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not. + */ +static int power5_marked_instr_event(unsigned int event) +{ + int pmc, psel; + int bit, byte, unit; + u32 mask; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + psel = event & PM_PMCSEL_MSK; + if (pmc >= 5) + return 0; + + bit = -1; + if (psel < sizeof(direct_event_is_marked)) { + if (direct_event_is_marked[psel] & (1 << pmc)) + return 1; + if (direct_event_is_marked[psel] & 0x80) + bit = 4; + else if (psel == 0x08) + bit = pmc - 1; + else if (psel == 0x10) + bit = 4 - pmc; + else if (psel == 0x1b && (pmc == 1 || pmc == 3)) + bit = 4; + } else if ((psel & 0x58) == 0x40) + bit = psel & 7; + + if (!(event & PM_BUSEVENT_MSK)) + return 0; + + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; + if (unit == PM_LSU0) { + /* byte 1 bits 0-7, byte 2 bits 0,2-4,6 */ + mask = 0x5dff00; + } else if (unit == PM_LSU1 && byte >= 4) { + byte -= 4; + /* byte 4 bits 1,3,5,7, byte 5 bits 6-7, byte 7 bits 0-4,6 */ + mask = 0x5f00c0aa; + } else + return 0; + + return (mask >> (byte * 8 + bit)) & 1; +} + static int power5_compute_mmcr(unsigned int event[], int n_ev, unsigned int hwc[], u64 mmcr[]) { u64 mmcr1 = 0; + u64 mmcra = 0; unsigned int pmc, unit, byte, psel; unsigned int ttm, grp; int i, isbus, bit, grsel; @@ -430,6 +522,8 @@ static int power5_compute_mmcr(unsigned int event[], int n_ev, grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK; mmcr1 |= (u64)grsel << grsel_shift[bit]; } + if (power5_marked_instr_event(event[i])) + mmcra |= MMCRA_SAMPLE_ENABLE; if (pmc <= 3) mmcr1 |= psel << MMCR1_PMCSEL_SH(pmc); hwc[i] = pmc; @@ -442,7 +536,7 @@ static int power5_compute_mmcr(unsigned int event[], int n_ev, if (pmc_inuse & 0x3e) mmcr[0] |= MMCR0_PMCjCE; mmcr[1] = mmcr1; - mmcr[2] = 0; + mmcr[2] = mmcra; return 0; } diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c index b1f61f3c97bb..fce1fc290a1d 100644 --- a/arch/powerpc/kernel/power6-pmu.c +++ b/arch/powerpc/kernel/power6-pmu.c @@ -48,6 +48,127 @@ #define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8) #define MMCR1_PMCSEL_MSK 0xff +/* + * Map of which direct events on which PMCs are marked instruction events. + * Indexed by PMCSEL value >> 1. + * Bottom 4 bits are a map of which PMCs are interesting, + * top 4 bits say what sort of event: + * 0 = direct marked event, + * 1 = byte decode event, + * 4 = add/and event (PMC1 -> bits 0 & 4), + * 5 = add/and event (PMC1 -> bits 1 & 5), + * 6 = add/and event (PMC1 -> bits 2 & 6), + * 7 = add/and event (PMC1 -> bits 3 & 7). + */ +static unsigned char direct_event_is_marked[0x60 >> 1] = { + 0, /* 00 */ + 0, /* 02 */ + 0, /* 04 */ + 0x07, /* 06 PM_MRK_ST_CMPL, PM_MRK_ST_GPS, PM_MRK_ST_CMPL_INT */ + 0x04, /* 08 PM_MRK_DFU_FIN */ + 0x06, /* 0a PM_MRK_IFU_FIN, PM_MRK_INST_FIN */ + 0, /* 0c */ + 0, /* 0e */ + 0x02, /* 10 PM_MRK_INST_DISP */ + 0x08, /* 12 PM_MRK_LSU_DERAT_MISS */ + 0, /* 14 */ + 0, /* 16 */ + 0x0c, /* 18 PM_THRESH_TIMEO, PM_MRK_INST_FIN */ + 0x0f, /* 1a PM_MRK_INST_DISP, PM_MRK_{FXU,FPU,LSU}_FIN */ + 0x01, /* 1c PM_MRK_INST_ISSUED */ + 0, /* 1e */ + 0, /* 20 */ + 0, /* 22 */ + 0, /* 24 */ + 0, /* 26 */ + 0x15, /* 28 PM_MRK_DATA_FROM_L2MISS, PM_MRK_DATA_FROM_L3MISS */ + 0, /* 2a */ + 0, /* 2c */ + 0, /* 2e */ + 0x4f, /* 30 */ + 0x7f, /* 32 */ + 0x4f, /* 34 */ + 0x5f, /* 36 */ + 0x6f, /* 38 */ + 0x4f, /* 3a */ + 0, /* 3c */ + 0x08, /* 3e PM_MRK_INST_TIMEO */ + 0x1f, /* 40 */ + 0x1f, /* 42 */ + 0x1f, /* 44 */ + 0x1f, /* 46 */ + 0x1f, /* 48 */ + 0x1f, /* 4a */ + 0x1f, /* 4c */ + 0x1f, /* 4e */ + 0, /* 50 */ + 0x05, /* 52 PM_MRK_BR_TAKEN, PM_MRK_BR_MPRED */ + 0x1c, /* 54 PM_MRK_PTEG_FROM_L3MISS, PM_MRK_PTEG_FROM_L2MISS */ + 0x02, /* 56 PM_MRK_LD_MISS_L1 */ + 0, /* 58 */ + 0, /* 5a */ + 0, /* 5c */ + 0, /* 5e */ +}; + +/* + * Masks showing for each unit which bits are marked events. + * These masks are in LE order, i.e. 0x00000001 is byte 0, bit 0. + */ +static u32 marked_bus_events[16] = { + 0x01000000, /* direct events set 1: byte 3 bit 0 */ + 0x00010000, /* direct events set 2: byte 2 bit 0 */ + 0, 0, 0, 0, /* IDU, IFU, nest: nothing */ + 0x00000088, /* VMX set 1: byte 0 bits 3, 7 */ + 0x000000c0, /* VMX set 2: byte 0 bits 4-7 */ + 0x04010000, /* LSU set 1: byte 2 bit 0, byte 3 bit 2 */ + 0xff010000u, /* LSU set 2: byte 2 bit 0, all of byte 3 */ + 0, /* LSU set 3 */ + 0x00000010, /* VMX set 3: byte 0 bit 4 */ + 0, /* BFP set 1 */ + 0x00000022, /* BFP set 2: byte 0 bits 1, 5 */ + 0, 0 +}; + +/* + * Returns 1 if event counts things relating to marked instructions + * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not. + */ +static int power6_marked_instr_event(unsigned int event) +{ + int pmc, psel, ptype; + int bit, byte, unit; + u32 mask; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + psel = (event & PM_PMCSEL_MSK) >> 1; /* drop edge/level bit */ + if (pmc >= 5) + return 0; + + bit = -1; + if (psel < sizeof(direct_event_is_marked)) { + ptype = direct_event_is_marked[psel]; + if (pmc == 0 || !(ptype & (1 << (pmc - 1)))) + return 0; + ptype >>= 4; + if (ptype == 0) + return 1; + if (ptype == 1) + bit = 0; + else + bit = ptype ^ (pmc - 1); + } else if ((psel & 0x48) == 0x40) + bit = psel & 7; + + if (!(event & PM_BUSEVENT_MSK) || bit == -1) + return 0; + + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; + mask = marked_bus_events[unit]; + return (mask >> (byte * 8 + bit)) & 1; +} + /* * Assign PMC numbers and compute MMCR1 value for a set of events */ @@ -55,6 +176,7 @@ static int p6_compute_mmcr(unsigned int event[], int n_ev, unsigned int hwc[], u64 mmcr[]) { u64 mmcr1 = 0; + u64 mmcra = 0; int i; unsigned int pmc, ev, b, u, s, psel; unsigned int ttmset = 0; @@ -116,6 +238,8 @@ static int p6_compute_mmcr(unsigned int event[], int n_ev, if (ev & PM_LLAV) mmcr1 |= MMCR1_PMC1_LLA_VALUE >> pmc; } + if (power6_marked_instr_event(event[i])) + mmcra |= MMCRA_SAMPLE_ENABLE; mmcr1 |= (u64)psel << MMCR1_PMCSEL_SH(pmc); } mmcr[0] = 0; @@ -124,7 +248,7 @@ static int p6_compute_mmcr(unsigned int event[], int n_ev, if (pmc_inuse & 0xe) mmcr[0] |= MMCR0_PMCjCE; mmcr[1] = mmcr1; - mmcr[2] = 0; + mmcr[2] = mmcra; return 0; } diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c index c3256580be1a..aed8ccd7c077 100644 --- a/arch/powerpc/kernel/ppc970-pmu.c +++ b/arch/powerpc/kernel/ppc970-pmu.c @@ -19,6 +19,8 @@ #define PM_PMC_MSK 0xf #define PM_UNIT_SH 8 /* TTMMUX number and setting - unit select */ #define PM_UNIT_MSK 0xf +#define PM_SPCSEL_SH 6 +#define PM_SPCSEL_MSK 3 #define PM_BYTE_SH 4 /* Byte number of event bus to use */ #define PM_BYTE_MSK 3 #define PM_PMCSEL_MSK 0xf @@ -88,8 +90,11 @@ static short mmcr1_adder_bits[8] = { * Layout of constraint bits: * 6666555555555544444444443333333333222222222211111111110000000000 * 3210987654321098765432109876543210987654321098765432109876543210 - * <><>[ >[ >[ >< >< >< >< ><><><><><><><><> - * T0T1 UC PS1 PS2 B0 B1 B2 B3 P1P2P3P4P5P6P7P8 + * <><><>[ >[ >[ >< >< >< >< ><><><><><><><><> + * SPT0T1 UC PS1 PS2 B0 B1 B2 B3 P1P2P3P4P5P6P7P8 + * + * SP - SPCSEL constraint + * 48-49: SPCSEL value 0x3_0000_0000_0000 * * T0 - TTM0 constraint * 46-47: TTM0SEL value (0=FPU, 2=IFU, 3=VPU) 0xC000_0000_0000 @@ -126,6 +131,57 @@ static short mmcr1_adder_bits[8] = { * 0-13: Count of events needing PMC2..PMC8 */ +static unsigned char direct_marked_event[8] = { + (1<<2) | (1<<3), /* PMC1: PM_MRK_GRP_DISP, PM_MRK_ST_CMPL */ + (1<<3) | (1<<5), /* PMC2: PM_THRESH_TIMEO, PM_MRK_BRU_FIN */ + (1<<3) | (1<<5), /* PMC3: PM_MRK_ST_CMPL_INT, PM_MRK_VMX_FIN */ + (1<<4) | (1<<5), /* PMC4: PM_MRK_GRP_CMPL, PM_MRK_CRU_FIN */ + (1<<4) | (1<<5), /* PMC5: PM_GRP_MRK, PM_MRK_GRP_TIMEO */ + (1<<3) | (1<<4) | (1<<5), + /* PMC6: PM_MRK_ST_STS, PM_MRK_FXU_FIN, PM_MRK_GRP_ISSUED */ + (1<<4) | (1<<5), /* PMC7: PM_MRK_FPU_FIN, PM_MRK_INST_FIN */ + (1<<4) /* PMC8: PM_MRK_LSU_FIN */ +}; + +/* + * Returns 1 if event counts things relating to marked instructions + * and thus needs the MMCRA_SAMPLE_ENABLE bit set, or 0 if not. + */ +static int p970_marked_instr_event(unsigned int event) +{ + int pmc, psel, unit, byte, bit; + unsigned int mask; + + pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + psel = event & PM_PMCSEL_MSK; + if (pmc) { + if (direct_marked_event[pmc - 1] & (1 << psel)) + return 1; + if (psel == 0) /* add events */ + bit = (pmc <= 4)? pmc - 1: 8 - pmc; + else if (psel == 7 || psel == 13) /* decode events */ + bit = 4; + else + return 0; + } else + bit = psel; + + byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; + unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; + mask = 0; + switch (unit) { + case PM_VPU: + mask = 0x4c; /* byte 0 bits 2,3,6 */ + case PM_LSU0: + /* byte 2 bits 0,2,3,4,6; all of byte 1 */ + mask = 0x085dff00; + case PM_LSU1L: + mask = 0x50 << 24; /* byte 3 bits 4,6 */ + break; + } + return (mask >> (byte * 8 + bit)) & 1; +} + /* Masks and values for using events from the various units */ static u64 unit_cons[PM_LASTUNIT+1][2] = { [PM_FPU] = { 0xc80000000000ull, 0x040000000000ull }, @@ -138,7 +194,7 @@ static u64 unit_cons[PM_LASTUNIT+1][2] = { static int p970_get_constraint(unsigned int event, u64 *maskp, u64 *valp) { - int pmc, byte, unit, sh; + int pmc, byte, unit, sh, spcsel; u64 mask = 0, value = 0; int grp = -1; @@ -177,6 +233,11 @@ static int p970_get_constraint(unsigned int event, u64 *maskp, u64 *valp) mask |= 0x800000000ull; value |= 0x100000000ull; } + spcsel = (event >> PM_SPCSEL_SH) & PM_SPCSEL_MSK; + if (spcsel) { + mask |= 3ull << 48; + value |= (u64)spcsel << 48; + } *maskp = mask; *valp = value; return 0; @@ -209,6 +270,7 @@ static int p970_compute_mmcr(unsigned int event[], int n_ev, unsigned char ttmuse[2]; unsigned char pmcsel[8]; int i; + int spcsel; if (n_ev > 8) return -1; @@ -316,6 +378,10 @@ static int p970_compute_mmcr(unsigned int event[], int n_ev, } pmcsel[pmc] = psel; hwc[i] = pmc; + spcsel = (event[i] >> PM_SPCSEL_SH) & PM_SPCSEL_MSK; + mmcr1 |= spcsel; + if (p970_marked_instr_event(event[i])) + mmcra |= MMCRA_SAMPLE_ENABLE; } for (pmc = 0; pmc < 2; ++pmc) mmcr0 |= pmcsel[pmc] << (MMCR0_PMC1SEL_SH - 7 * pmc); -- GitLab From 7333a8003cdc0470e8c0ae8b949cbc44f3165ff3 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Wed, 25 Mar 2009 10:50:34 +0900 Subject: [PATCH 0206/6080] x86: smarten /proc/interrupts output for new counters Now /proc/interrupts of tip tree has new counters: CNT: Performance counter interrupts Format change of output, as like that by commit: commit 7a81d9a7da03d2f27840d659f97ef140d032f609 x86: smarten /proc/interrupts output should be applied to these new counters too. Signed-off-by: Hidetoshi Seto Cc: Jan Beulich LKML-Reference: <49C98DEA.8060208@jp.fujitsu.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index d465487da587..dccaaa855789 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -63,7 +63,7 @@ static int show_other_interrupts(struct seq_file *p, int prec) for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count); seq_printf(p, " Spurious interrupts\n"); - seq_printf(p, "CNT: "); + seq_printf(p, "%*s: ", prec, "CNT"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs); seq_printf(p, " Performance counter interrupts\n"); -- GitLab From e30e08f65c7ef6c230424264f09c3d53f117f58b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Apr 2009 15:01:25 +0200 Subject: [PATCH 0207/6080] perf_counter: fix NMI race in task clock We should not be updating ctx->time from NMI context, work around that. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090408130408.681326666@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 863703b3158f..84a39081344c 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -319,8 +319,6 @@ static void __perf_counter_disable(void *info) spin_lock_irqsave(&ctx->lock, flags); - update_context_time(ctx); - /* * If the counter is on, turn it off. * If it is in error state, leave it in error state. @@ -2335,13 +2333,11 @@ static const struct hw_perf_counter_ops perf_ops_cpu_clock = { * Software counter: task time clock */ -static void task_clock_perf_counter_update(struct perf_counter *counter) +static void task_clock_perf_counter_update(struct perf_counter *counter, u64 now) { - u64 prev, now; + u64 prev; s64 delta; - now = counter->ctx->time; - prev = atomic64_xchg(&counter->hw.prev_count, now); delta = now - prev; atomic64_add(delta, &counter->count); @@ -2369,13 +2365,24 @@ static int task_clock_perf_counter_enable(struct perf_counter *counter) static void task_clock_perf_counter_disable(struct perf_counter *counter) { hrtimer_cancel(&counter->hw.hrtimer); - task_clock_perf_counter_update(counter); + task_clock_perf_counter_update(counter, counter->ctx->time); + } static void task_clock_perf_counter_read(struct perf_counter *counter) { - update_context_time(counter->ctx); - task_clock_perf_counter_update(counter); + u64 time; + + if (!in_nmi()) { + update_context_time(counter->ctx); + time = counter->ctx->time; + } else { + u64 now = perf_clock(); + u64 delta = now - counter->ctx->timestamp; + time = counter->ctx->time + delta; + } + + task_clock_perf_counter_update(counter, time); } static const struct hw_perf_counter_ops perf_ops_task_clock = { -- GitLab From 6fab01927e8bdbbc77bafba2abb4810c5591ad52 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Apr 2009 15:01:26 +0200 Subject: [PATCH 0208/6080] perf_counter: provide misc bits in the event header Limit the size of each record to 64k (or should we count in multiples of u64 and have a 512K limit?), this gives 16 bits or spare room in the header, which we can use for misc bits, so as to not have to grow the record with u64 every time we have a few bits to report. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090408130408.769271806@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 6 +++++- kernel/perf_counter.c | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 7f5d353d78ac..5bd8817b12d4 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -201,9 +201,13 @@ struct perf_counter_mmap_page { __u32 data_head; /* head in the data section */ }; +#define PERF_EVENT_MISC_KERNEL (1 << 0) +#define PERF_EVENT_MISC_USER (1 << 1) + struct perf_event_header { __u32 type; - __u32 size; + __u16 misc; + __u16 size; }; enum perf_event_type { diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 84a39081344c..4af98f943d3b 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1831,6 +1831,9 @@ static void perf_counter_output(struct perf_counter *counter, header.type = PERF_EVENT_COUNTER_OVERFLOW; header.size = sizeof(header); + header.misc = user_mode(regs) ? + PERF_EVENT_MISC_USER : PERF_EVENT_MISC_KERNEL; + if (record_type & PERF_RECORD_IP) { ip = instruction_pointer(regs); header.type |= __PERF_EVENT_IP; -- GitLab From 6b6e5486b3a168f0328c82a8d4376caf901472b1 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Apr 2009 15:01:27 +0200 Subject: [PATCH 0209/6080] perf_counter: use misc field to widen type Push the PERF_EVENT_COUNTER_OVERFLOW bit into the misc field so that we can have the full 32bit for PERF_RECORD_ bits. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090408130408.891867663@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 28 ++++++++++------------------ kernel/perf_counter.c | 15 ++++++++------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 5bd8817b12d4..4809ae18a940 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -201,8 +201,9 @@ struct perf_counter_mmap_page { __u32 data_head; /* head in the data section */ }; -#define PERF_EVENT_MISC_KERNEL (1 << 0) -#define PERF_EVENT_MISC_USER (1 << 1) +#define PERF_EVENT_MISC_KERNEL (1 << 0) +#define PERF_EVENT_MISC_USER (1 << 1) +#define PERF_EVENT_MISC_OVERFLOW (1 << 2) struct perf_event_header { __u32 type; @@ -230,36 +231,27 @@ enum perf_event_type { PERF_EVENT_MUNMAP = 2, /* - * Half the event type space is reserved for the counter overflow - * bitfields, as found in hw_event.record_type. - * - * These events will have types of the form: - * PERF_EVENT_COUNTER_OVERFLOW { | __PERF_EVENT_* } * + * When header.misc & PERF_EVENT_MISC_OVERFLOW the event_type field + * will be PERF_RECORD_* * * struct { * struct perf_event_header header; * - * { u64 ip; } && __PERF_EVENT_IP - * { u32 pid, tid; } && __PERF_EVENT_TID + * { u64 ip; } && PERF_RECORD_IP + * { u32 pid, tid; } && PERF_RECORD_TID * * { u64 nr; - * { u64 event, val; } cnt[nr]; } && __PERF_EVENT_GROUP + * { u64 event, val; } cnt[nr]; } && PERF_RECORD_GROUP * * { u16 nr, * hv, * kernel, * user; - * u64 ips[nr]; } && __PERF_EVENT_CALLCHAIN + * u64 ips[nr]; } && PERF_RECORD_CALLCHAIN * - * { u64 time; } && __PERF_EVENT_TIME + * { u64 time; } && PERF_RECORD_TIME * }; */ - PERF_EVENT_COUNTER_OVERFLOW = 1UL << 31, - __PERF_EVENT_IP = PERF_RECORD_IP, - __PERF_EVENT_TID = PERF_RECORD_TID, - __PERF_EVENT_GROUP = PERF_RECORD_GROUP, - __PERF_EVENT_CALLCHAIN = PERF_RECORD_CALLCHAIN, - __PERF_EVENT_TIME = PERF_RECORD_TIME, }; #ifdef __KERNEL__ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 4af98f943d3b..bf12df6f3538 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1828,15 +1828,16 @@ static void perf_counter_output(struct perf_counter *counter, int callchain_size = 0; u64 time; - header.type = PERF_EVENT_COUNTER_OVERFLOW; + header.type = 0; header.size = sizeof(header); - header.misc = user_mode(regs) ? + header.misc = PERF_EVENT_MISC_OVERFLOW; + header.misc |= user_mode(regs) ? PERF_EVENT_MISC_USER : PERF_EVENT_MISC_KERNEL; if (record_type & PERF_RECORD_IP) { ip = instruction_pointer(regs); - header.type |= __PERF_EVENT_IP; + header.type |= PERF_RECORD_IP; header.size += sizeof(ip); } @@ -1845,12 +1846,12 @@ static void perf_counter_output(struct perf_counter *counter, tid_entry.pid = current->group_leader->pid; tid_entry.tid = current->pid; - header.type |= __PERF_EVENT_TID; + header.type |= PERF_RECORD_TID; header.size += sizeof(tid_entry); } if (record_type & PERF_RECORD_GROUP) { - header.type |= __PERF_EVENT_GROUP; + header.type |= PERF_RECORD_GROUP; header.size += sizeof(u64) + counter->nr_siblings * sizeof(group_entry); } @@ -1861,7 +1862,7 @@ static void perf_counter_output(struct perf_counter *counter, if (callchain) { callchain_size = (1 + callchain->nr) * sizeof(u64); - header.type |= __PERF_EVENT_CALLCHAIN; + header.type |= PERF_RECORD_CALLCHAIN; header.size += callchain_size; } } @@ -1872,7 +1873,7 @@ static void perf_counter_output(struct perf_counter *counter, */ time = sched_clock(); - header.type |= __PERF_EVENT_TIME; + header.type |= PERF_RECORD_TIME; header.size += sizeof(u64); } -- GitLab From 808382b33bb4c60df6379ec2db39f332cc56b82a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Apr 2009 15:01:28 +0200 Subject: [PATCH 0210/6080] perf_counter: kerneltop: keep up with ABI changes Update kerneltop to use PERF_EVENT_MISC_OVERFLOW Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090408130408.947197470@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/kerneltop.c | 32 +++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c index 15f3a5f90198..042c1b83a872 100644 --- a/Documentation/perf_counter/kerneltop.c +++ b/Documentation/perf_counter/kerneltop.c @@ -1277,22 +1277,22 @@ static void mmap_read(struct mmap_data *md) old += size; - switch (event->header.type) { - case PERF_EVENT_COUNTER_OVERFLOW | __PERF_EVENT_IP: - case PERF_EVENT_COUNTER_OVERFLOW | __PERF_EVENT_IP | __PERF_EVENT_TID: - process_event(event->ip.ip, md->counter); - break; - - case PERF_EVENT_MMAP: - case PERF_EVENT_MUNMAP: - printf("%s: %Lu %Lu %Lu %s\n", - event->header.type == PERF_EVENT_MMAP - ? "mmap" : "munmap", - event->mmap.start, - event->mmap.len, - event->mmap.pgoff, - event->mmap.filename); - break; + if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { + if (event->header.type & PERF_RECORD_IP) + process_event(event->ip.ip, md->counter); + } else { + switch (event->header.type) { + case PERF_EVENT_MMAP: + case PERF_EVENT_MUNMAP: + printf("%s: %Lu %Lu %Lu %s\n", + event->header.type == PERF_EVENT_MMAP + ? "mmap" : "munmap", + event->mmap.start, + event->mmap.len, + event->mmap.pgoff, + event->mmap.filename); + break; + } } } -- GitLab From 8740f9418c78dcad694b46ab25d1645d5aef1f5e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Apr 2009 15:01:29 +0200 Subject: [PATCH 0211/6080] perf_counter: add some comments Add a few comments because I was forgetting what field what for what functionality. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090408130409.036984214@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 4809ae18a940..8bf764fc6220 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -344,10 +344,12 @@ struct file; struct perf_mmap_data { struct rcu_head rcu_head; - int nr_pages; - atomic_t wakeup; - atomic_t head; - atomic_t events; + int nr_pages; /* nr of data pages */ + + atomic_t wakeup; /* POLL_ for wakeups */ + atomic_t head; /* write position */ + atomic_t events; /* event limit */ + struct perf_counter_mmap_page *user_page; void *data_pages[0]; }; -- GitLab From 8d1b2d9361b494bfc761700c348c65ebbe3deb5b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Apr 2009 15:01:30 +0200 Subject: [PATCH 0212/6080] perf_counter: track task-comm data Similar to the mmap data stream, add one that tracks the task COMM field, so that the userspace reporting knows what to call a task. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090408130409.127422406@chello.nl> Signed-off-by: Ingo Molnar --- fs/exec.c | 1 + include/linux/perf_counter.h | 16 ++++++- kernel/perf_counter.c | 93 ++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/fs/exec.c b/fs/exec.c index e015c0b5a082..bf47ed0278ff 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -951,6 +951,7 @@ void set_task_comm(struct task_struct *tsk, char *buf) task_lock(tsk); strlcpy(tsk->comm, buf, sizeof(tsk->comm)); task_unlock(tsk); + perf_counter_comm(tsk); } int flush_old_exec(struct linux_binprm * bprm) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 8bf764fc6220..a70a55f27598 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -142,8 +142,9 @@ struct perf_counter_hw_event { exclude_idle : 1, /* don't count when idle */ mmap : 1, /* include mmap data */ munmap : 1, /* include munmap data */ + comm : 1, /* include comm data */ - __reserved_1 : 53; + __reserved_1 : 52; __u32 extra_config_len; __u32 wakeup_events; /* wakeup every n events */ @@ -230,6 +231,16 @@ enum perf_event_type { PERF_EVENT_MMAP = 1, PERF_EVENT_MUNMAP = 2, + /* + * struct { + * struct perf_event_header header; + * + * u32 pid, tid; + * char comm[]; + * }; + */ + PERF_EVENT_COMM = 3, + /* * When header.misc & PERF_EVENT_MISC_OVERFLOW the event_type field * will be PERF_RECORD_* @@ -545,6 +556,8 @@ extern void perf_counter_mmap(unsigned long addr, unsigned long len, extern void perf_counter_munmap(unsigned long addr, unsigned long len, unsigned long pgoff, struct file *file); +extern void perf_counter_comm(struct task_struct *tsk); + #define MAX_STACK_DEPTH 255 struct perf_callchain_entry { @@ -583,6 +596,7 @@ static inline void perf_counter_munmap(unsigned long addr, unsigned long len, unsigned long pgoff, struct file *file) { } +static inline void perf_counter_comm(struct task_struct *tsk) { } #endif #endif /* __KERNEL__ */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index bf12df6f3538..2d4aebb2982b 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1916,6 +1916,99 @@ static void perf_counter_output(struct perf_counter *counter, perf_output_end(&handle); } +/* + * comm tracking + */ + +struct perf_comm_event { + struct task_struct *task; + char *comm; + int comm_size; + + struct { + struct perf_event_header header; + + u32 pid; + u32 tid; + } event; +}; + +static void perf_counter_comm_output(struct perf_counter *counter, + struct perf_comm_event *comm_event) +{ + struct perf_output_handle handle; + int size = comm_event->event.header.size; + int ret = perf_output_begin(&handle, counter, size, 0, 0); + + if (ret) + return; + + perf_output_put(&handle, comm_event->event); + perf_output_copy(&handle, comm_event->comm, + comm_event->comm_size); + perf_output_end(&handle); +} + +static int perf_counter_comm_match(struct perf_counter *counter, + struct perf_comm_event *comm_event) +{ + if (counter->hw_event.comm && + comm_event->event.header.type == PERF_EVENT_COMM) + return 1; + + return 0; +} + +static void perf_counter_comm_ctx(struct perf_counter_context *ctx, + struct perf_comm_event *comm_event) +{ + struct perf_counter *counter; + + if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list)) + return; + + rcu_read_lock(); + list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) { + if (perf_counter_comm_match(counter, comm_event)) + perf_counter_comm_output(counter, comm_event); + } + rcu_read_unlock(); +} + +static void perf_counter_comm_event(struct perf_comm_event *comm_event) +{ + struct perf_cpu_context *cpuctx; + unsigned int size; + char *comm = comm_event->task->comm; + + size = ALIGN(strlen(comm), sizeof(u64)); + + comm_event->comm = comm; + comm_event->comm_size = size; + + comm_event->event.header.size = sizeof(comm_event->event) + size; + + cpuctx = &get_cpu_var(perf_cpu_context); + perf_counter_comm_ctx(&cpuctx->ctx, comm_event); + put_cpu_var(perf_cpu_context); + + perf_counter_comm_ctx(¤t->perf_counter_ctx, comm_event); +} + +void perf_counter_comm(struct task_struct *task) +{ + struct perf_comm_event comm_event = { + .task = task, + .event = { + .header = { .type = PERF_EVENT_COMM, }, + .pid = task->group_leader->pid, + .tid = task->pid, + }, + }; + + perf_counter_comm_event(&comm_event); +} + /* * mmap tracking */ -- GitLab From de9ac07bbf8f51e0ce40e5428c3a8f627bd237c2 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Apr 2009 15:01:31 +0200 Subject: [PATCH 0213/6080] perf_counter: some simple userspace profiling # perf-record make -j4 kernel/ # perf-report | tail -15 0.39 cc1 [kernel] lock_acquired 0.42 cc1 [kernel] lock_acquire 0.51 cc1 [ user ] /lib64/libc-2.8.90.so: _int_free 0.51 as [kernel] clear_page_c 0.53 cc1 [ user ] /lib64/libc-2.8.90.so: memcpy 0.56 cc1 [ user ] /lib64/libc-2.8.90.so: _IO_vfprintf 0.63 cc1 [kernel] lock_release 0.67 cc1 [ user ] /lib64/libc-2.8.90.so: strlen 0.68 cc1 [kernel] debug_smp_processor_id 1.38 cc1 [ user ] /lib64/libc-2.8.90.so: _int_malloc 1.55 cc1 [ user ] /lib64/libc-2.8.90.so: memset 1.77 cc1 [kernel] __lock_acquire 1.88 cc1 [kernel] clear_page_c 3.61 as [ user ] /usr/bin/as: 59.16 cc1 [ user ] /usr/libexec/gcc/x86_64-redhat-linux/4.3.2/cc1: Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford Cc: Arnaldo Carvalho de Melo LKML-Reference: <20090408130409.220518450@chello.nl> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 8 +- Documentation/perf_counter/perf-record.c | 530 ++++++++++++++++++++++ Documentation/perf_counter/perf-report.cc | 472 +++++++++++++++++++ 3 files changed, 1009 insertions(+), 1 deletion(-) create mode 100644 Documentation/perf_counter/perf-record.c create mode 100644 Documentation/perf_counter/perf-report.cc diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index 194b66215588..1dd37ee7dbdc 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -1,10 +1,16 @@ -BINS = kerneltop perfstat +BINS = kerneltop perfstat perf-record perf-report all: $(BINS) kerneltop: kerneltop.c ../../include/linux/perf_counter.h cc -O6 -Wall -lrt -o $@ $< +perf-record: perf-record.c ../../include/linux/perf_counter.h + cc -O6 -Wall -lrt -o $@ $< + +perf-report: perf-report.cc ../../include/linux/perf_counter.h + g++ -O6 -Wall -lrt -o $@ $< + perfstat: kerneltop ln -sf kerneltop perfstat diff --git a/Documentation/perf_counter/perf-record.c b/Documentation/perf_counter/perf-record.c new file mode 100644 index 000000000000..614de7c468b2 --- /dev/null +++ b/Documentation/perf_counter/perf-record.c @@ -0,0 +1,530 @@ + + +#define _GNU_SOURCE +#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/linux/perf_counter.h" + + +/* + * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all + * counters in the current task. + */ +#define PR_TASK_PERF_COUNTERS_DISABLE 31 +#define PR_TASK_PERF_COUNTERS_ENABLE 32 + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define rdclock() \ +({ \ + struct timespec ts; \ + \ + clock_gettime(CLOCK_MONOTONIC, &ts); \ + ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ +}) + +/* + * Pick up some kernel type conventions: + */ +#define __user +#define asmlinkage + +#ifdef __x86_64__ +#define __NR_perf_counter_open 295 +#define rmb() asm volatile("lfence" ::: "memory") +#define cpu_relax() asm volatile("rep; nop" ::: "memory"); +#endif + +#ifdef __i386__ +#define __NR_perf_counter_open 333 +#define rmb() asm volatile("lfence" ::: "memory") +#define cpu_relax() asm volatile("rep; nop" ::: "memory"); +#endif + +#ifdef __powerpc__ +#define __NR_perf_counter_open 319 +#define rmb() asm volatile ("sync" ::: "memory") +#define cpu_relax() asm volatile ("" ::: "memory"); +#endif + +#define unlikely(x) __builtin_expect(!!(x), 0) +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + +asmlinkage int sys_perf_counter_open( + struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, + int cpu, + int group_fd, + unsigned long flags) +{ + return syscall( + __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); +} + +#define MAX_COUNTERS 64 +#define MAX_NR_CPUS 256 + +#define EID(type, id) (((__u64)(type) << PERF_COUNTER_TYPE_SHIFT) | (id)) + +static int nr_counters = 0; +static __u64 event_id[MAX_COUNTERS] = { }; +static int default_interval = 100000; +static int event_count[MAX_COUNTERS]; +static int fd[MAX_NR_CPUS][MAX_COUNTERS]; +static int nr_cpus = 0; +static unsigned int page_size; +static unsigned int mmap_pages = 16; +static int output; +static char *output_name = "output.perf"; +static int group = 0; +static unsigned int realtime_prio = 0; + +const unsigned int default_count[] = { + 1000000, + 1000000, + 10000, + 10000, + 1000000, + 10000, +}; + +static char *hw_event_names[] = { + "CPU cycles", + "instructions", + "cache references", + "cache misses", + "branches", + "branch misses", + "bus cycles", +}; + +static char *sw_event_names[] = { + "cpu clock ticks", + "task clock ticks", + "pagefaults", + "context switches", + "CPU migrations", + "minor faults", + "major faults", +}; + +struct event_symbol { + __u64 event; + char *symbol; +}; + +static struct event_symbol event_symbols[] = { + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cpu-cycles", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cycles", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), "instructions", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), "cache-references", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), "cache-misses", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branch-instructions", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branches", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_MISSES), "branch-misses", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BUS_CYCLES), "bus-cycles", }, + + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK), "cpu-clock", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), "task-clock", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "page-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MIN), "minor-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MAJ), "major-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "context-switches", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "cs", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "cpu-migrations", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "migrations", }, +}; + +/* + * Each event can have multiple symbolic names. + * Symbolic names are (almost) exactly matched. + */ +static __u64 match_event_symbols(char *str) +{ + __u64 config, id; + int type; + unsigned int i; + + if (sscanf(str, "r%llx", &config) == 1) + return config | PERF_COUNTER_RAW_MASK; + + if (sscanf(str, "%d:%llu", &type, &id) == 2) + return EID(type, id); + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + if (!strncmp(str, event_symbols[i].symbol, + strlen(event_symbols[i].symbol))) + return event_symbols[i].event; + } + + return ~0ULL; +} + +static int parse_events(char *str) +{ + __u64 config; + +again: + if (nr_counters == MAX_COUNTERS) + return -1; + + config = match_event_symbols(str); + if (config == ~0ULL) + return -1; + + event_id[nr_counters] = config; + nr_counters++; + + str = strstr(str, ","); + if (str) { + str++; + goto again; + } + + return 0; +} + +#define __PERF_COUNTER_FIELD(config, name) \ + ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT) + +#define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW) +#define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG) +#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE) +#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT) + +static void display_events_help(void) +{ + unsigned int i; + __u64 e; + + printf( + " -e EVENT --event=EVENT # symbolic-name abbreviations"); + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + int type, id; + + e = event_symbols[i].event; + type = PERF_COUNTER_TYPE(e); + id = PERF_COUNTER_ID(e); + + printf("\n %d:%d: %-20s", + type, id, event_symbols[i].symbol); + } + + printf("\n" + " rNNN: raw PMU events (eventsel+umask)\n\n"); +} + +static void display_help(void) +{ + printf( + "Usage: perf-record []\n" + "perf-record Options (up to %d event types can be specified at once):\n\n", + MAX_COUNTERS); + + display_events_help(); + + printf( + " -c CNT --count=CNT # event period to sample\n" + " -m pages --mmap_pages= # number of mmap data pages\n" + " -o file --output= # output file\n" + " -r prio --realtime= # use RT prio\n" + ); + + exit(0); +} + +static void process_options(int argc, char *argv[]) +{ + int error = 0, counter; + + for (;;) { + int option_index = 0; + /** Options for getopt */ + static struct option long_options[] = { + {"count", required_argument, NULL, 'c'}, + {"event", required_argument, NULL, 'e'}, + {"mmap_pages", required_argument, NULL, 'm'}, + {"output", required_argument, NULL, 'o'}, + {"realtime", required_argument, NULL, 'r'}, + {NULL, 0, NULL, 0 } + }; + int c = getopt_long(argc, argv, "+:c:e:m:o:r:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'c': default_interval = atoi(optarg); break; + case 'e': error = parse_events(optarg); break; + case 'm': mmap_pages = atoi(optarg); break; + case 'o': output_name = strdup(optarg); break; + case 'r': realtime_prio = atoi(optarg); break; + default: error = 1; break; + } + } + if (error) + display_help(); + + if (!nr_counters) { + nr_counters = 1; + event_id[0] = 0; + } + + for (counter = 0; counter < nr_counters; counter++) { + if (event_count[counter]) + continue; + + event_count[counter] = default_interval; + } +} + +struct mmap_data { + int counter; + void *base; + unsigned int mask; + unsigned int prev; +}; + +static unsigned int mmap_read_head(struct mmap_data *md) +{ + struct perf_counter_mmap_page *pc = md->base; + int head; + + head = pc->data_head; + rmb(); + + return head; +} + +static long events; +static struct timeval last_read, this_read; + +static void mmap_read(struct mmap_data *md) +{ + unsigned int head = mmap_read_head(md); + unsigned int old = md->prev; + unsigned char *data = md->base + page_size; + unsigned long size; + void *buf; + int diff; + + gettimeofday(&this_read, NULL); + + /* + * If we're further behind than half the buffer, there's a chance + * the writer will bite our tail and screw up the events under us. + * + * If we somehow ended up ahead of the head, we got messed up. + * + * In either case, truncate and restart at head. + */ + diff = head - old; + if (diff > md->mask / 2 || diff < 0) { + struct timeval iv; + unsigned long msecs; + + timersub(&this_read, &last_read, &iv); + msecs = iv.tv_sec*1000 + iv.tv_usec/1000; + + fprintf(stderr, "WARNING: failed to keep up with mmap data." + " Last read %lu msecs ago.\n", msecs); + + /* + * head points to a known good entry, start there. + */ + old = head; + } + + last_read = this_read; + + if (old != head) + events++; + + size = head - old; + + if ((old & md->mask) + size != (head & md->mask)) { + buf = &data[old & md->mask]; + size = md->mask + 1 - (old & md->mask); + old += size; + while (size) { + int ret = write(output, buf, size); + if (ret < 0) { + perror("failed to write"); + exit(-1); + } + size -= ret; + buf += ret; + } + } + + buf = &data[old & md->mask]; + size = head - old; + old += size; + while (size) { + int ret = write(output, buf, size); + if (ret < 0) { + perror("failed to write"); + exit(-1); + } + size -= ret; + buf += ret; + } + + md->prev = old; +} + +static volatile int done = 0; + +static void sigchld_handler(int sig) +{ + if (sig == SIGCHLD) + done = 1; +} + +int main(int argc, char *argv[]) +{ + struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; + struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; + struct perf_counter_hw_event hw_event; + int i, counter, group_fd, nr_poll = 0; + pid_t pid; + int ret; + + page_size = sysconf(_SC_PAGE_SIZE); + + process_options(argc, argv); + + nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + assert(nr_cpus <= MAX_NR_CPUS); + assert(nr_cpus >= 0); + + output = open(output_name, O_CREAT|O_RDWR, S_IRWXU); + if (output < 0) { + perror("failed to create output file"); + exit(-1); + } + + argc -= optind; + argv += optind; + + for (i = 0; i < nr_cpus; i++) { + group_fd = -1; + for (counter = 0; counter < nr_counters; counter++) { + + memset(&hw_event, 0, sizeof(hw_event)); + hw_event.config = event_id[counter]; + hw_event.irq_period = event_count[counter]; + hw_event.record_type = PERF_RECORD_IP | PERF_RECORD_TID; + hw_event.nmi = 1; + hw_event.mmap = 1; + hw_event.comm = 1; + + fd[i][counter] = sys_perf_counter_open(&hw_event, -1, i, group_fd, 0); + if (fd[i][counter] < 0) { + int err = errno; + printf("kerneltop error: syscall returned with %d (%s)\n", + fd[i][counter], strerror(err)); + if (err == EPERM) + printf("Are you root?\n"); + exit(-1); + } + assert(fd[i][counter] >= 0); + fcntl(fd[i][counter], F_SETFL, O_NONBLOCK); + + /* + * First counter acts as the group leader: + */ + if (group && group_fd == -1) + group_fd = fd[i][counter]; + + event_array[nr_poll].fd = fd[i][counter]; + event_array[nr_poll].events = POLLIN; + nr_poll++; + + mmap_array[i][counter].counter = counter; + mmap_array[i][counter].prev = 0; + mmap_array[i][counter].mask = mmap_pages*page_size - 1; + mmap_array[i][counter].base = mmap(NULL, (mmap_pages+1)*page_size, + PROT_READ, MAP_SHARED, fd[i][counter], 0); + if (mmap_array[i][counter].base == MAP_FAILED) { + printf("kerneltop error: failed to mmap with %d (%s)\n", + errno, strerror(errno)); + exit(-1); + } + } + } + + signal(SIGCHLD, sigchld_handler); + + pid = fork(); + if (pid < 0) + perror("failed to fork"); + + if (!pid) { + if (execvp(argv[0], argv)) { + perror(argv[0]); + exit(-1); + } + } + + if (realtime_prio) { + struct sched_param param; + + param.sched_priority = realtime_prio; + if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { + printf("Could not set realtime priority.\n"); + exit(-1); + } + } + + /* + * TODO: store the current /proc/$/maps information somewhere + */ + + while (!done) { + int hits = events; + + for (i = 0; i < nr_cpus; i++) { + for (counter = 0; counter < nr_counters; counter++) + mmap_read(&mmap_array[i][counter]); + } + + if (hits == events) + ret = poll(event_array, nr_poll, 100); + } + + return 0; +} diff --git a/Documentation/perf_counter/perf-report.cc b/Documentation/perf_counter/perf-report.cc new file mode 100644 index 000000000000..09da0ba482cd --- /dev/null +++ b/Documentation/perf_counter/perf-report.cc @@ -0,0 +1,472 @@ +#define _GNU_SOURCE +#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/linux/perf_counter.h" + +#include +#include +#include + + +static char const *input_name = "output.perf"; +static int input; + +static unsigned long page_size; +static unsigned long mmap_window = 32; + +struct ip_event { + struct perf_event_header header; + __u64 ip; + __u32 pid, tid; +}; +struct mmap_event { + struct perf_event_header header; + __u32 pid, tid; + __u64 start; + __u64 len; + __u64 pgoff; + char filename[PATH_MAX]; +}; +struct comm_event { + struct perf_event_header header; + __u32 pid,tid; + char comm[16]; +}; + +typedef union event_union { + struct perf_event_header header; + struct ip_event ip; + struct mmap_event mmap; + struct comm_event comm; +} event_t; + +struct section { + uint64_t start; + uint64_t end; + + uint64_t offset; + + std::string name; + + section() { }; + + section(uint64_t stab) : end(stab) { }; + + section(uint64_t start, uint64_t size, uint64_t offset, std::string name) : + start(start), end(start + size), offset(offset), name(name) + { }; + + bool operator < (const struct section &s) const { + return end < s.end; + }; +}; + +typedef std::set sections_t; + +struct symbol { + uint64_t start; + uint64_t end; + + std::string name; + + symbol() { }; + + symbol(uint64_t ip) : start(ip) { } + + symbol(uint64_t start, uint64_t len, std::string name) : + start(start), end(start + len), name(name) + { }; + + bool operator < (const struct symbol &s) const { + return start < s.start; + }; +}; + +typedef std::set symbols_t; + +struct dso { + sections_t sections; + symbols_t syms; +}; + +static std::map dsos; + +static void load_dso_sections(std::string dso_name) +{ + struct dso &dso = dsos[dso_name]; + + std::string cmd = "readelf -DSW " + dso_name; + + FILE *file = popen(cmd.c_str(), "r"); + if (!file) { + perror("failed to open pipe"); + exit(-1); + } + + char *line = NULL; + size_t n = 0; + + while (!feof(file)) { + uint64_t addr, off, size; + char name[32]; + + if (getline(&line, &n, file) < 0) + break; + if (!line) + break; + + if (sscanf(line, " [%*2d] %16s %*14s %Lx %Lx %Lx", + name, &addr, &off, &size) == 4) { + + dso.sections.insert(section(addr, size, addr - off, name)); + } +#if 0 + /* + * for reading readelf symbols (-s), however these don't seem + * to include nearly everything, so use nm for that. + */ + if (sscanf(line, " %*4d %*3d: %Lx %5Lu %*7s %*6s %*7s %3d %s", + &start, &size, §ion, sym) == 4) { + + start -= dso.section_offsets[section]; + + dso.syms.insert(symbol(start, size, std::string(sym))); + } +#endif + } + pclose(file); +} + +static void load_dso_symbols(std::string dso_name, std::string args) +{ + struct dso &dso = dsos[dso_name]; + + std::string cmd = "nm -nSC " + args + " " + dso_name; + + FILE *file = popen(cmd.c_str(), "r"); + if (!file) { + perror("failed to open pipe"); + exit(-1); + } + + char *line = NULL; + size_t n = 0; + + while (!feof(file)) { + uint64_t start, size; + char c; + char sym[1024]; + + if (getline(&line, &n, file) < 0) + break; + if (!line) + break; + + + if (sscanf(line, "%Lx %Lx %c %s", &start, &size, &c, sym) == 4) { + sections_t::const_iterator si = + dso.sections.upper_bound(section(start)); + if (si == dso.sections.end()) { + printf("symbol in unknown section: %s\n", sym); + continue; + } + + start -= si->offset; + + dso.syms.insert(symbol(start, size, sym)); + } + } + pclose(file); +} + +static void load_dso(std::string dso_name) +{ + load_dso_sections(dso_name); + load_dso_symbols(dso_name, "-D"); /* dynamic symbols */ + load_dso_symbols(dso_name, ""); /* regular ones */ +} + +void load_kallsyms(void) +{ + struct dso &dso = dsos["[kernel]"]; + + FILE *file = fopen("/proc/kallsyms", "r"); + if (!file) { + perror("failed to open kallsyms"); + exit(-1); + } + + char *line; + size_t n; + + while (!feof(file)) { + uint64_t start; + char c; + char sym[1024]; + + if (getline(&line, &n, file) < 0) + break; + if (!line) + break; + + if (sscanf(line, "%Lx %c %s", &start, &c, sym) == 3) + dso.syms.insert(symbol(start, 0x1000000, std::string(sym))); + } + fclose(file); +} + +struct map { + uint64_t start; + uint64_t end; + uint64_t pgoff; + + std::string dso; + + map() { }; + + map(uint64_t ip) : end(ip) { } + + map(mmap_event *mmap) { + start = mmap->start; + end = mmap->start + mmap->len; + pgoff = mmap->pgoff; + + dso = std::string(mmap->filename); + + if (dsos.find(dso) == dsos.end()) + load_dso(dso); + }; + + bool operator < (const struct map &m) const { + return end < m.end; + }; +}; + +typedef std::set maps_t; + +static std::map maps; + +static std::map comms; + +static std::map hist; +static std::multimap rev_hist; + +static std::string resolve_comm(int pid) +{ + std::string comm = ""; + std::map::const_iterator ci = comms.find(pid); + if (ci != comms.end()) + comm = ci->second; + + return comm; +} + +static std::string resolve_user_symbol(int pid, uint64_t ip) +{ + std::string sym = ""; + + maps_t &m = maps[pid]; + maps_t::const_iterator mi = m.upper_bound(map(ip)); + if (mi == m.end()) + return sym; + + ip -= mi->start + mi->pgoff; + + symbols_t &s = dsos[mi->dso].syms; + symbols_t::const_iterator si = s.upper_bound(symbol(ip)); + + sym = mi->dso + ": "; + + if (si == s.begin()) + return sym; + si--; + + if (si->start <= ip && ip < si->end) + sym = mi->dso + ": " + si->name; +#if 0 + else if (si->start <= ip) + sym = mi->dso + ": ?" + si->name; +#endif + + return sym; +} + +static std::string resolve_kernel_symbol(uint64_t ip) +{ + std::string sym = ""; + + symbols_t &s = dsos["[kernel]"].syms; + symbols_t::const_iterator si = s.upper_bound(symbol(ip)); + + if (si == s.begin()) + return sym; + si--; + + if (si->start <= ip && ip < si->end) + sym = si->name; + + return sym; +} + +static void display_help(void) +{ + printf( + "Usage: perf-report []\n" + " -i file --input= # input file\n" + ); + + exit(0); +} + +static void process_options(int argc, char *argv[]) +{ + int error = 0; + + for (;;) { + int option_index = 0; + /** Options for getopt */ + static struct option long_options[] = { + {"input", required_argument, NULL, 'i'}, + {NULL, 0, NULL, 0 } + }; + int c = getopt_long(argc, argv, "+:i:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'i': input_name = strdup(optarg); break; + default: error = 1; break; + } + } + + if (error) + display_help(); +} + +int main(int argc, char *argv[]) +{ + unsigned long offset = 0; + unsigned long head = 0; + struct stat stat; + char *buf; + event_t *event; + int ret; + unsigned long total = 0; + + page_size = getpagesize(); + + process_options(argc, argv); + + input = open(input_name, O_RDONLY); + if (input < 0) { + perror("failed to open file"); + exit(-1); + } + + ret = fstat(input, &stat); + if (ret < 0) { + perror("failed to stat file"); + exit(-1); + } + + load_kallsyms(); + +remap: + buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ, + MAP_SHARED, input, offset); + if (buf == MAP_FAILED) { + perror("failed to mmap file"); + exit(-1); + } + +more: + event = (event_t *)(buf + head); + + if (head + event->header.size >= page_size * mmap_window) { + unsigned long shift = page_size * (head / page_size); + + munmap(buf, page_size * mmap_window); + offset += shift; + head -= shift; + goto remap; + } + head += event->header.size; + + if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { + std::string comm, sym, level; + char output[1024]; + + if (event->header.misc & PERF_EVENT_MISC_KERNEL) { + level = "[kernel]"; + sym = resolve_kernel_symbol(event->ip.ip); + } else if (event->header.misc & PERF_EVENT_MISC_USER) { + level = "[ user ]"; + sym = resolve_user_symbol(event->ip.pid, event->ip.ip); + } else { + level = "[ hv ]"; + } + comm = resolve_comm(event->ip.pid); + + snprintf(output, sizeof(output), "%16s %s %s", + comm.c_str(), level.c_str(), sym.c_str()); + hist[output]++; + + total++; + + } else switch (event->header.type) { + case PERF_EVENT_MMAP: + maps[event->mmap.pid].insert(map(&event->mmap)); + break; + + case PERF_EVENT_COMM: + comms[event->comm.pid] = std::string(event->comm.comm); + break; + } + + if (offset + head < stat.st_size) + goto more; + + close(input); + + std::map::iterator hi = hist.begin(); + + while (hi != hist.end()) { + rev_hist.insert(std::pair(hi->second, hi->first)); + hist.erase(hi++); + } + + std::multimap::const_iterator ri = rev_hist.begin(); + + while (ri != rev_hist.end()) { + printf(" %5.2f %s\n", (100.0 * ri->first)/total, ri->second.c_str()); + ri++; + } + + return 0; +} + -- GitLab From 4d855457d84b819fefcd1cd1b0a2a0a0ec475c07 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Apr 2009 15:01:32 +0200 Subject: [PATCH 0214/6080] perf_counter: move PERF_RECORD_TIME Move PERF_RECORD_TIME so that all the fixed length items come before the variable length ones. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090408130409.307926436@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 9 ++++----- kernel/perf_counter.c | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index a70a55f27598..8bd1be58c938 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -100,9 +100,9 @@ enum sw_event_ids { enum perf_counter_record_format { PERF_RECORD_IP = 1U << 0, PERF_RECORD_TID = 1U << 1, - PERF_RECORD_GROUP = 1U << 2, - PERF_RECORD_CALLCHAIN = 1U << 3, - PERF_RECORD_TIME = 1U << 4, + PERF_RECORD_TIME = 1U << 2, + PERF_RECORD_GROUP = 1U << 3, + PERF_RECORD_CALLCHAIN = 1U << 4, }; /* @@ -250,6 +250,7 @@ enum perf_event_type { * * { u64 ip; } && PERF_RECORD_IP * { u32 pid, tid; } && PERF_RECORD_TID + * { u64 time; } && PERF_RECORD_TIME * * { u64 nr; * { u64 event, val; } cnt[nr]; } && PERF_RECORD_GROUP @@ -259,8 +260,6 @@ enum perf_event_type { * kernel, * user; * u64 ips[nr]; } && PERF_RECORD_CALLCHAIN - * - * { u64 time; } && PERF_RECORD_TIME * }; */ }; diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 2d4aebb2982b..4dc8600d2825 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1850,6 +1850,16 @@ static void perf_counter_output(struct perf_counter *counter, header.size += sizeof(tid_entry); } + if (record_type & PERF_RECORD_TIME) { + /* + * Maybe do better on x86 and provide cpu_clock_nmi() + */ + time = sched_clock(); + + header.type |= PERF_RECORD_TIME; + header.size += sizeof(u64); + } + if (record_type & PERF_RECORD_GROUP) { header.type |= PERF_RECORD_GROUP; header.size += sizeof(u64) + @@ -1867,16 +1877,6 @@ static void perf_counter_output(struct perf_counter *counter, } } - if (record_type & PERF_RECORD_TIME) { - /* - * Maybe do better on x86 and provide cpu_clock_nmi() - */ - time = sched_clock(); - - header.type |= PERF_RECORD_TIME; - header.size += sizeof(u64); - } - ret = perf_output_begin(&handle, counter, header.size, nmi, 1); if (ret) return; @@ -1889,6 +1889,9 @@ static void perf_counter_output(struct perf_counter *counter, if (record_type & PERF_RECORD_TID) perf_output_put(&handle, tid_entry); + if (record_type & PERF_RECORD_TIME) + perf_output_put(&handle, time); + if (record_type & PERF_RECORD_GROUP) { struct perf_counter *leader, *sub; u64 nr = counter->nr_siblings; @@ -1910,9 +1913,6 @@ static void perf_counter_output(struct perf_counter *counter, if (callchain) perf_output_copy(&handle, callchain, callchain_size); - if (record_type & PERF_RECORD_TIME) - perf_output_put(&handle, time); - perf_output_end(&handle); } -- GitLab From 78f13e9525ba777da25c4ddab89f28e9366a8b7c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 8 Apr 2009 15:01:33 +0200 Subject: [PATCH 0215/6080] perf_counter: allow for data addresses to be recorded Paul suggested we allow for data addresses to be recorded along with the traditional IPs as power can provide these. For now, only the software pagefault events provide data addresses, but in the future power might as well for some events. x86 doesn't seem capable of providing this atm. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090408130409.394816925@chello.nl> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 2 +- arch/powerpc/mm/fault.c | 8 ++++-- arch/x86/kernel/cpu/perf_counter.c | 2 +- arch/x86/mm/fault.c | 8 ++++-- include/linux/perf_counter.h | 14 +++++---- kernel/perf_counter.c | 46 +++++++++++++++++++----------- 6 files changed, 49 insertions(+), 31 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index 0697ade84dd3..c9d019f19074 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -749,7 +749,7 @@ static void record_and_restart(struct perf_counter *counter, long val, * Finally record data if requested. */ if (record) - perf_counter_overflow(counter, 1, regs); + perf_counter_overflow(counter, 1, regs, 0); } /* diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 17bbf6f91fbe..ac0e112031b2 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -171,7 +171,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, die("Weird page fault", regs, SIGSEGV); } - perf_swcounter_event(PERF_COUNT_PAGE_FAULTS, 1, 0, regs); + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS, 1, 0, regs, address); /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the @@ -312,7 +312,8 @@ good_area: } if (ret & VM_FAULT_MAJOR) { current->maj_flt++; - perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MAJ, 1, 0, regs); + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MAJ, 1, 0, + regs, address); #ifdef CONFIG_PPC_SMLPAR if (firmware_has_feature(FW_FEATURE_CMO)) { preempt_disable(); @@ -322,7 +323,8 @@ good_area: #endif } else { current->min_flt++; - perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MIN, 1, 0, regs); + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MIN, 1, 0, + regs, address); } up_read(&mm->mmap_sem); return 0; diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 1116a41bc7b5..0fcbaab83f9b 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -800,7 +800,7 @@ again: continue; perf_save_and_restart(counter); - if (perf_counter_overflow(counter, nmi, regs)) + if (perf_counter_overflow(counter, nmi, regs, 0)) __pmc_generic_disable(counter, &counter->hw, bit); } diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index f2d3324d9215..6f9df2babe48 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1045,7 +1045,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) if (unlikely(error_code & PF_RSVD)) pgtable_bad(regs, error_code, address); - perf_swcounter_event(PERF_COUNT_PAGE_FAULTS, 1, 0, regs); + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS, 1, 0, regs, address); /* * If we're in an interrupt, have no user context or are running @@ -1142,10 +1142,12 @@ good_area: if (fault & VM_FAULT_MAJOR) { tsk->maj_flt++; - perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MAJ, 1, 0, regs); + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MAJ, 1, 0, + regs, address); } else { tsk->min_flt++; - perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MIN, 1, 0, regs); + perf_swcounter_event(PERF_COUNT_PAGE_FAULTS_MIN, 1, 0, + regs, address); } check_v8086_mode(regs, address, tsk); diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 8bd1be58c938..c22363a4f746 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -101,8 +101,9 @@ enum perf_counter_record_format { PERF_RECORD_IP = 1U << 0, PERF_RECORD_TID = 1U << 1, PERF_RECORD_TIME = 1U << 2, - PERF_RECORD_GROUP = 1U << 3, - PERF_RECORD_CALLCHAIN = 1U << 4, + PERF_RECORD_ADDR = 1U << 3, + PERF_RECORD_GROUP = 1U << 4, + PERF_RECORD_CALLCHAIN = 1U << 5, }; /* @@ -251,6 +252,7 @@ enum perf_event_type { * { u64 ip; } && PERF_RECORD_IP * { u32 pid, tid; } && PERF_RECORD_TID * { u64 time; } && PERF_RECORD_TIME + * { u64 addr; } && PERF_RECORD_ADDR * * { u64 nr; * { u64 event, val; } cnt[nr]; } && PERF_RECORD_GROUP @@ -537,7 +539,7 @@ extern int hw_perf_group_sched_in(struct perf_counter *group_leader, extern void perf_counter_update_userpage(struct perf_counter *counter); extern int perf_counter_overflow(struct perf_counter *counter, - int nmi, struct pt_regs *regs); + int nmi, struct pt_regs *regs, u64 addr); /* * Return 1 for a software counter, 0 for a hardware counter */ @@ -547,7 +549,7 @@ static inline int is_software_counter(struct perf_counter *counter) perf_event_type(&counter->hw_event) != PERF_TYPE_HARDWARE; } -extern void perf_swcounter_event(u32, u64, int, struct pt_regs *); +extern void perf_swcounter_event(u32, u64, int, struct pt_regs *, u64); extern void perf_counter_mmap(unsigned long addr, unsigned long len, unsigned long pgoff, struct file *file); @@ -584,8 +586,8 @@ static inline int perf_counter_task_disable(void) { return -EINVAL; } static inline int perf_counter_task_enable(void) { return -EINVAL; } static inline void -perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs) { } - +perf_swcounter_event(u32 event, u64 nr, int nmi, + struct pt_regs *regs, u64 addr) { } static inline void perf_counter_mmap(unsigned long addr, unsigned long len, diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 4dc8600d2825..321c57e3556f 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -800,7 +800,7 @@ void perf_counter_task_sched_out(struct task_struct *task, int cpu) update_context_time(ctx); regs = task_pt_regs(task); - perf_swcounter_event(PERF_COUNT_CONTEXT_SWITCHES, 1, 1, regs); + perf_swcounter_event(PERF_COUNT_CONTEXT_SWITCHES, 1, 1, regs, 0); __perf_counter_sched_out(ctx, cpuctx); cpuctx->task_ctx = NULL; @@ -1810,7 +1810,7 @@ static void perf_output_end(struct perf_output_handle *handle) } static void perf_counter_output(struct perf_counter *counter, - int nmi, struct pt_regs *regs) + int nmi, struct pt_regs *regs, u64 addr) { int ret; u64 record_type = counter->hw_event.record_type; @@ -1860,6 +1860,11 @@ static void perf_counter_output(struct perf_counter *counter, header.size += sizeof(u64); } + if (record_type & PERF_RECORD_ADDR) { + header.type |= PERF_RECORD_ADDR; + header.size += sizeof(u64); + } + if (record_type & PERF_RECORD_GROUP) { header.type |= PERF_RECORD_GROUP; header.size += sizeof(u64) + @@ -1892,6 +1897,9 @@ static void perf_counter_output(struct perf_counter *counter, if (record_type & PERF_RECORD_TIME) perf_output_put(&handle, time); + if (record_type & PERF_RECORD_ADDR) + perf_output_put(&handle, addr); + if (record_type & PERF_RECORD_GROUP) { struct perf_counter *leader, *sub; u64 nr = counter->nr_siblings; @@ -2158,7 +2166,7 @@ void perf_counter_munmap(unsigned long addr, unsigned long len, */ int perf_counter_overflow(struct perf_counter *counter, - int nmi, struct pt_regs *regs) + int nmi, struct pt_regs *regs, u64 addr) { int events = atomic_read(&counter->event_limit); int ret = 0; @@ -2175,7 +2183,7 @@ int perf_counter_overflow(struct perf_counter *counter, perf_counter_disable(counter); } - perf_counter_output(counter, nmi, regs); + perf_counter_output(counter, nmi, regs, addr); return ret; } @@ -2240,7 +2248,7 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) regs = task_pt_regs(current); if (regs) { - if (perf_counter_overflow(counter, 0, regs)) + if (perf_counter_overflow(counter, 0, regs, 0)) ret = HRTIMER_NORESTART; } @@ -2250,11 +2258,11 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) } static void perf_swcounter_overflow(struct perf_counter *counter, - int nmi, struct pt_regs *regs) + int nmi, struct pt_regs *regs, u64 addr) { perf_swcounter_update(counter); perf_swcounter_set_period(counter); - if (perf_counter_overflow(counter, nmi, regs)) + if (perf_counter_overflow(counter, nmi, regs, addr)) /* soft-disable the counter */ ; @@ -2286,16 +2294,17 @@ static int perf_swcounter_match(struct perf_counter *counter, } static void perf_swcounter_add(struct perf_counter *counter, u64 nr, - int nmi, struct pt_regs *regs) + int nmi, struct pt_regs *regs, u64 addr) { int neg = atomic64_add_negative(nr, &counter->hw.count); if (counter->hw.irq_period && !neg) - perf_swcounter_overflow(counter, nmi, regs); + perf_swcounter_overflow(counter, nmi, regs, addr); } static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, enum perf_event_types type, u32 event, - u64 nr, int nmi, struct pt_regs *regs) + u64 nr, int nmi, struct pt_regs *regs, + u64 addr) { struct perf_counter *counter; @@ -2305,7 +2314,7 @@ static void perf_swcounter_ctx_event(struct perf_counter_context *ctx, rcu_read_lock(); list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) { if (perf_swcounter_match(counter, type, event, regs)) - perf_swcounter_add(counter, nr, nmi, regs); + perf_swcounter_add(counter, nr, nmi, regs, addr); } rcu_read_unlock(); } @@ -2325,7 +2334,8 @@ static int *perf_swcounter_recursion_context(struct perf_cpu_context *cpuctx) } static void __perf_swcounter_event(enum perf_event_types type, u32 event, - u64 nr, int nmi, struct pt_regs *regs) + u64 nr, int nmi, struct pt_regs *regs, + u64 addr) { struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context); int *recursion = perf_swcounter_recursion_context(cpuctx); @@ -2336,10 +2346,11 @@ static void __perf_swcounter_event(enum perf_event_types type, u32 event, (*recursion)++; barrier(); - perf_swcounter_ctx_event(&cpuctx->ctx, type, event, nr, nmi, regs); + perf_swcounter_ctx_event(&cpuctx->ctx, type, event, + nr, nmi, regs, addr); if (cpuctx->task_ctx) { perf_swcounter_ctx_event(cpuctx->task_ctx, type, event, - nr, nmi, regs); + nr, nmi, regs, addr); } barrier(); @@ -2349,9 +2360,10 @@ out: put_cpu_var(perf_cpu_context); } -void perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs) +void +perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs, u64 addr) { - __perf_swcounter_event(PERF_TYPE_SOFTWARE, event, nr, nmi, regs); + __perf_swcounter_event(PERF_TYPE_SOFTWARE, event, nr, nmi, regs, addr); } static void perf_swcounter_read(struct perf_counter *counter) @@ -2548,7 +2560,7 @@ void perf_tpcounter_event(int event_id) if (!regs) regs = task_pt_regs(current); - __perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, 1, 1, regs); + __perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, 1, 1, regs, 0); } extern int ftrace_profile_enable(int); -- GitLab From 1c1452be2e9ae282a7316c3b23987811bd7acda6 Mon Sep 17 00:00:00 2001 From: Jonas Larsson Date: Tue, 31 Mar 2009 11:16:48 +0200 Subject: [PATCH 0216/6080] atmel-mci: Add support for inverted detect pin Same patch as before, modified to use bool. Also adds description of the new field in struct atmel_mci that I missed in the first patch. This patch adds Atmel MCI support for inverted detect pins. Signed-off-by: Jonas Larsson Acked-by: Pierre Ossman Signed-off-by: Haavard Skinnemoen --- drivers/mmc/host/atmel-mci.c | 12 +++++++++--- include/linux/atmel-mci.h | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index cf6a100bb38f..7b603e4b41db 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -177,6 +177,7 @@ struct atmel_mci { * available. * @wp_pin: GPIO pin used for card write protect sending, or negative * if not available. + * @detect_is_active_high: The state of the detect pin when it is active. * @detect_timer: Timer used for debouncing @detect_pin interrupts. */ struct atmel_mci_slot { @@ -196,6 +197,7 @@ struct atmel_mci_slot { int detect_pin; int wp_pin; + bool detect_is_active_high; struct timer_list detect_timer; }; @@ -924,7 +926,8 @@ static int atmci_get_cd(struct mmc_host *mmc) struct atmel_mci_slot *slot = mmc_priv(mmc); if (gpio_is_valid(slot->detect_pin)) { - present = !gpio_get_value(slot->detect_pin); + present = !(gpio_get_value(slot->detect_pin) ^ + slot->detect_is_active_high); dev_dbg(&mmc->class_dev, "card is %spresent\n", present ? "" : "not "); } @@ -1028,7 +1031,8 @@ static void atmci_detect_change(unsigned long data) return; enable_irq(gpio_to_irq(slot->detect_pin)); - present = !gpio_get_value(slot->detect_pin); + present = !(gpio_get_value(slot->detect_pin) ^ + slot->detect_is_active_high); present_old = test_bit(ATMCI_CARD_PRESENT, &slot->flags); dev_vdbg(&slot->mmc->class_dev, "detect change: %d (was %d)\n", @@ -1456,6 +1460,7 @@ static int __init atmci_init_slot(struct atmel_mci *host, slot->host = host; slot->detect_pin = slot_data->detect_pin; slot->wp_pin = slot_data->wp_pin; + slot->detect_is_active_high = slot_data->detect_is_active_high; slot->sdc_reg = sdc_reg; mmc->ops = &atmci_ops; @@ -1477,7 +1482,8 @@ static int __init atmci_init_slot(struct atmel_mci *host, if (gpio_request(slot->detect_pin, "mmc_detect")) { dev_dbg(&mmc->class_dev, "no detect pin available\n"); slot->detect_pin = -EBUSY; - } else if (gpio_get_value(slot->detect_pin)) { + } else if (gpio_get_value(slot->detect_pin) ^ + slot->detect_is_active_high) { clear_bit(ATMCI_CARD_PRESENT, &slot->flags); } } diff --git a/include/linux/atmel-mci.h b/include/linux/atmel-mci.h index 2f1f95737acb..57b1846a3c87 100644 --- a/include/linux/atmel-mci.h +++ b/include/linux/atmel-mci.h @@ -10,6 +10,7 @@ * @bus_width: Number of data lines wired up the slot * @detect_pin: GPIO pin wired to the card detect switch * @wp_pin: GPIO pin wired to the write protect sensor + * @detect_is_active_high: The state of the detect pin when it is active * * If a given slot is not present on the board, @bus_width should be * set to 0. The other fields are ignored in this case. @@ -24,6 +25,7 @@ struct mci_slot_pdata { unsigned int bus_width; int detect_pin; int wp_pin; + bool detect_is_active_high; }; /** -- GitLab From 7ebcfcf19723254ebe90cdf8718436b9955a9a01 Mon Sep 17 00:00:00 2001 From: Jonas Larsson Date: Tue, 31 Mar 2009 11:16:52 +0200 Subject: [PATCH 0217/6080] avr32: Solves problem with inverted MCI detect pin on Merisc board Same patch as before, modified to use bool. This patch solves the problem with the inverted mci detect pin on Merisc boards. Signed-off-by: Jonas Larsson Signed-off-by: Haavard Skinnemoen --- arch/avr32/boards/merisc/setup.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c index 20b300cf105a..623b077594fc 100644 --- a/arch/avr32/boards/merisc/setup.c +++ b/arch/avr32/boards/merisc/setup.c @@ -94,9 +94,10 @@ static struct spi_board_info __initdata spi0_board_info[] = { static struct mci_platform_data __initdata mci0_data = { .slot[0] = { - .bus_width = 4, - .detect_pin = GPIO_PIN_PE(19), - .wp_pin = GPIO_PIN_PE(20), + .bus_width = 4, + .detect_pin = GPIO_PIN_PE(19), + .wp_pin = GPIO_PIN_PE(20), + .detect_is_active_high = true, }, }; -- GitLab From e98e3350c03af4187e1d5fe007c7b460e378990c Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:38 +0000 Subject: [PATCH 0218/6080] netxen: code cleanup o remove unused structure defs. o remove unnecessary includes. o replace enums with specific #defines. o reduce footprint of stats structure. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 246 ++++++++--------------- drivers/net/netxen/netxen_nic_ethtool.c | 11 +- drivers/net/netxen/netxen_nic_hdr.h | 8 - drivers/net/netxen/netxen_nic_hw.c | 17 +- drivers/net/netxen/netxen_nic_hw.h | 66 ++---- drivers/net/netxen/netxen_nic_main.c | 19 +- drivers/net/netxen/netxen_nic_niu.c | 14 +- drivers/net/netxen/netxen_nic_phan_reg.h | 21 +- 8 files changed, 146 insertions(+), 256 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index c40815169f35..184eb6f76d55 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -34,10 +34,6 @@ #include #include #include -#include -#include -#include -#include #include #include #include @@ -49,18 +45,12 @@ #include #include -#include #include -#include -#include #include -#include #include #include -#include -#include #include "netxen_nic_hw.h" @@ -118,6 +108,7 @@ #define NX_P3_A2 0x30 #define NX_P3_B0 0x40 #define NX_P3_B1 0x41 +#define NX_P3_B2 0x42 #define NX_IS_REVISION_P2(REVISION) (REVISION <= NX_P2_C1) #define NX_IS_REVISION_P3(REVISION) (REVISION >= NX_P3_A0) @@ -203,18 +194,8 @@ #define MAX_RCV_DESCRIPTORS_10G 4096 #define MAX_JUMBO_RCV_DESCRIPTORS 1024 #define MAX_LRO_RCV_DESCRIPTORS 8 -#define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS -#define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS -#define MAX_RCV_DESC MAX_RCV_DESCRIPTORS -#define MAX_RCVSTATUS_DESC MAX_RCV_DESCRIPTORS -#define MAX_EPG_DESCRIPTORS (MAX_CMD_DESCRIPTORS * 8) -#define NUM_RCV_DESC (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS + \ - MAX_LRO_RCV_DESCRIPTORS) -#define MIN_TX_COUNT 4096 -#define MIN_RX_COUNT 4096 #define NETXEN_CTX_SIGNATURE 0xdee0 #define NETXEN_RCV_PRODUCER(ringid) (ringid) -#define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */ #define PHAN_PEG_RCV_INITIALIZED 0xff01 #define PHAN_PEG_RCV_START_INITIALIZE 0xff00 @@ -384,11 +365,6 @@ struct rcv_desc { /* Note: sizeof(status_desc) should always be a mutliple of 2 */ -#define netxen_get_sts_desc_lro_cnt(status_desc) \ - ((status_desc)->lro & 0x7F) -#define netxen_get_sts_desc_lro_last_frag(status_desc) \ - (((status_desc)->lro & 0x80) >> 7) - #define netxen_get_sts_port(sts_data) \ ((sts_data) & 0x0F) #define netxen_get_sts_status(sts_data) \ @@ -434,10 +410,6 @@ struct status_desc { }; } __attribute__ ((aligned(16))); -enum { - NETXEN_RCV_PEG_0 = 0, - NETXEN_RCV_PEG_1 -}; /* The version of the main data structure */ #define NETXEN_BDINFO_VERSION 1 @@ -447,85 +419,35 @@ enum { /* Max number of Gig ports on a Phantom board */ #define NETXEN_MAX_PORTS 4 -typedef enum { - NETXEN_BRDTYPE_P1_BD = 0x0000, - NETXEN_BRDTYPE_P1_SB = 0x0001, - NETXEN_BRDTYPE_P1_SMAX = 0x0002, - NETXEN_BRDTYPE_P1_SOCK = 0x0003, - - NETXEN_BRDTYPE_P2_SOCK_31 = 0x0008, - NETXEN_BRDTYPE_P2_SOCK_35 = 0x0009, - NETXEN_BRDTYPE_P2_SB35_4G = 0x000a, - NETXEN_BRDTYPE_P2_SB31_10G = 0x000b, - NETXEN_BRDTYPE_P2_SB31_2G = 0x000c, - - NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d, - NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e, - NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f, - - NETXEN_BRDTYPE_P3_REF_QG = 0x0021, - NETXEN_BRDTYPE_P3_HMEZ = 0x0022, - NETXEN_BRDTYPE_P3_10G_CX4_LP = 0x0023, - NETXEN_BRDTYPE_P3_4_GB = 0x0024, - NETXEN_BRDTYPE_P3_IMEZ = 0x0025, - NETXEN_BRDTYPE_P3_10G_SFP_PLUS = 0x0026, - NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027, - NETXEN_BRDTYPE_P3_XG_LOM = 0x0028, - NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029, - 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_TP = 0x0080 - -} netxen_brdtype_t; - -typedef enum { - NETXEN_BRDMFG_INVENTEC = 1 -} netxen_brdmfg; - -typedef enum { - MEM_ORG_128Mbx4 = 0x0, /* DDR1 only */ - MEM_ORG_128Mbx8 = 0x1, /* DDR1 only */ - MEM_ORG_128Mbx16 = 0x2, /* DDR1 only */ - MEM_ORG_256Mbx4 = 0x3, - MEM_ORG_256Mbx8 = 0x4, - MEM_ORG_256Mbx16 = 0x5, - MEM_ORG_512Mbx4 = 0x6, - MEM_ORG_512Mbx8 = 0x7, - MEM_ORG_512Mbx16 = 0x8, - MEM_ORG_1Gbx4 = 0x9, - MEM_ORG_1Gbx8 = 0xa, - MEM_ORG_1Gbx16 = 0xb, - MEM_ORG_2Gbx4 = 0xc, - MEM_ORG_2Gbx8 = 0xd, - MEM_ORG_2Gbx16 = 0xe, - MEM_ORG_128Mbx32 = 0x10002, /* GDDR only */ - MEM_ORG_256Mbx32 = 0x10005 /* GDDR only */ -} netxen_mn_mem_org_t; - -typedef enum { - MEM_ORG_512Kx36 = 0x0, - MEM_ORG_1Mx36 = 0x1, - MEM_ORG_2Mx36 = 0x2 -} netxen_sn_mem_org_t; - -typedef enum { - MEM_DEPTH_4MB = 0x1, - MEM_DEPTH_8MB = 0x2, - MEM_DEPTH_16MB = 0x3, - MEM_DEPTH_32MB = 0x4, - MEM_DEPTH_64MB = 0x5, - MEM_DEPTH_128MB = 0x6, - MEM_DEPTH_256MB = 0x7, - MEM_DEPTH_512MB = 0x8, - MEM_DEPTH_1GB = 0x9, - MEM_DEPTH_2GB = 0xa, - MEM_DEPTH_4GB = 0xb, - MEM_DEPTH_8GB = 0xc, - MEM_DEPTH_16GB = 0xd, - MEM_DEPTH_32GB = 0xe -} netxen_mem_depth_t; +#define NETXEN_BRDTYPE_P1_BD 0x0000 +#define NETXEN_BRDTYPE_P1_SB 0x0001 +#define NETXEN_BRDTYPE_P1_SMAX 0x0002 +#define NETXEN_BRDTYPE_P1_SOCK 0x0003 + +#define NETXEN_BRDTYPE_P2_SOCK_31 0x0008 +#define NETXEN_BRDTYPE_P2_SOCK_35 0x0009 +#define NETXEN_BRDTYPE_P2_SB35_4G 0x000a +#define NETXEN_BRDTYPE_P2_SB31_10G 0x000b +#define NETXEN_BRDTYPE_P2_SB31_2G 0x000c + +#define NETXEN_BRDTYPE_P2_SB31_10G_IMEZ 0x000d +#define NETXEN_BRDTYPE_P2_SB31_10G_HMEZ 0x000e +#define NETXEN_BRDTYPE_P2_SB31_10G_CX4 0x000f + +#define NETXEN_BRDTYPE_P3_REF_QG 0x0021 +#define NETXEN_BRDTYPE_P3_HMEZ 0x0022 +#define NETXEN_BRDTYPE_P3_10G_CX4_LP 0x0023 +#define NETXEN_BRDTYPE_P3_4_GB 0x0024 +#define NETXEN_BRDTYPE_P3_IMEZ 0x0025 +#define NETXEN_BRDTYPE_P3_10G_SFP_PLUS 0x0026 +#define NETXEN_BRDTYPE_P3_10000_BASE_T 0x0027 +#define NETXEN_BRDTYPE_P3_XG_LOM 0x0028 +#define NETXEN_BRDTYPE_P3_4_GB_MM 0x0029 +#define NETXEN_BRDTYPE_P3_10G_SFP_CT 0x002a +#define NETXEN_BRDTYPE_P3_10G_SFP_QT 0x002b +#define NETXEN_BRDTYPE_P3_10G_CX4 0x0031 +#define NETXEN_BRDTYPE_P3_10G_XFP 0x0032 +#define NETXEN_BRDTYPE_P3_10G_TP 0x0080 struct netxen_board_info { u32 header_version; @@ -676,17 +598,15 @@ struct netxen_new_user_info { #define PRIMARY_IMAGE_BAD 0xffffffff /* Flash memory map */ -typedef enum { - NETXEN_CRBINIT_START = 0, /* Crbinit section */ - NETXEN_BRDCFG_START = 0x4000, /* board config */ - NETXEN_INITCODE_START = 0x6000, /* pegtune code */ - NETXEN_BOOTLD_START = 0x10000, /* bootld */ - NETXEN_IMAGE_START = 0x43000, /* compressed image */ - NETXEN_SECONDARY_START = 0x200000, /* backup images */ - NETXEN_PXE_START = 0x3E0000, /* user defined region */ - NETXEN_USER_START = 0x3E8000, /* User defined region for new boards */ - NETXEN_FIXED_START = 0x3F0000 /* backup of crbinit */ -} netxen_flash_map_t; +#define NETXEN_CRBINIT_START 0 /* crbinit section */ +#define NETXEN_BRDCFG_START 0x4000 /* board config */ +#define NETXEN_INITCODE_START 0x6000 /* pegtune code */ +#define NETXEN_BOOTLD_START 0x10000 /* bootld */ +#define NETXEN_IMAGE_START 0x43000 /* compressed image */ +#define NETXEN_SECONDARY_START 0x200000 /* backup images */ +#define NETXEN_PXE_START 0x3E0000 /* PXE boot rom */ +#define NETXEN_USER_START 0x3E8000 /* Firmare info */ +#define NETXEN_FIXED_START 0x3F0000 /* backup of crbinit */ #define NX_FW_VERSION_OFFSET (NETXEN_USER_START+0x408) #define NX_FW_SIZE_OFFSET (NETXEN_USER_START+0x40c) @@ -708,21 +628,8 @@ typedef enum { #define NETXEN_FLASH_SECONDARY_SIZE (NETXEN_USER_START-NETXEN_SECONDARY_START) #define NETXEN_NUM_PRIMARY_SECTORS (0x20) #define NETXEN_NUM_CONFIG_SECTORS (1) -#define PFX "NetXen: " extern char netxen_nic_driver_name[]; -/* Note: Make sure to not call this before adapter->port is valid */ -#if !defined(NETXEN_DEBUG) -#define DPRINTK(klevel, fmt, args...) do { \ - } while (0) -#else -#define DPRINTK(klevel, fmt, args...) do { \ - printk(KERN_##klevel PFX "%s: %s: " fmt, __func__,\ - (adapter != NULL && adapter->netdev != NULL) ? \ - adapter->netdev->name : NULL, \ - ## args); } while(0) -#endif - /* Number of status descriptors to handle per interrupt */ #define MAX_STATUS_HANDLE (64) @@ -807,20 +714,14 @@ struct netxen_hardware_context { #define ETHERNET_FCS_SIZE 4 struct netxen_adapter_stats { - u64 rcvdbadskb; u64 xmitcalled; - u64 xmitedframes; u64 xmitfinished; - u64 badskblen; - u64 nocmddescriptor; - u64 polled; u64 rxdropped; u64 txdropped; u64 csummed; u64 no_rcv; u64 rxbytes; u64 txbytes; - u64 ints; }; /* @@ -1154,26 +1055,53 @@ typedef struct { #define NX_MAC_EVENT 0x1 -enum { - NX_NIC_H2C_OPCODE_START = 0, - NX_NIC_H2C_OPCODE_CONFIG_RSS, - NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL, - NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE, - NX_NIC_H2C_OPCODE_CONFIG_LED, - NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS, - NX_NIC_H2C_OPCODE_CONFIG_L2_MAC, - NX_NIC_H2C_OPCODE_LRO_REQUEST, - NX_NIC_H2C_OPCODE_GET_SNMP_STATS, - NX_NIC_H2C_OPCODE_PROXY_START_REQUEST, - NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST, - NX_NIC_H2C_OPCODE_PROXY_SET_MTU, - NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE, - NX_H2P_OPCODE_GET_FINGER_PRINT_REQUEST, - NX_H2P_OPCODE_INSTALL_LICENSE_REQUEST, - NX_H2P_OPCODE_GET_LICENSE_CAPABILITY_REQUEST, - NX_NIC_H2C_OPCODE_GET_NET_STATS, - NX_NIC_H2C_OPCODE_LAST -}; +/* + * Driver --> Firmware + */ +#define NX_NIC_H2C_OPCODE_START 0 +#define NX_NIC_H2C_OPCODE_CONFIG_RSS 1 +#define NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL 2 +#define NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE 3 +#define NX_NIC_H2C_OPCODE_CONFIG_LED 4 +#define NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS 5 +#define NX_NIC_H2C_OPCODE_CONFIG_L2_MAC 6 +#define NX_NIC_H2C_OPCODE_LRO_REQUEST 7 +#define NX_NIC_H2C_OPCODE_GET_SNMP_STATS 8 +#define NX_NIC_H2C_OPCODE_PROXY_START_REQUEST 9 +#define NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST 10 +#define NX_NIC_H2C_OPCODE_PROXY_SET_MTU 11 +#define NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE 12 +#define NX_NIC_H2C_OPCODE_GET_FINGER_PRINT_REQUEST 13 +#define NX_NIC_H2C_OPCODE_INSTALL_LICENSE_REQUEST 14 +#define NX_NIC_H2C_OPCODE_GET_LICENSE_CAPABILITY_REQUEST 15 +#define NX_NIC_H2C_OPCODE_GET_NET_STATS 16 +#define NX_NIC_H2C_OPCODE_PROXY_UPDATE_P2V 17 +#define NX_NIC_H2C_OPCODE_CONFIG_IPADDR 18 +#define NX_NIC_H2C_OPCODE_CONFIG_LOOPBACK 19 +#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE 20 +#define NX_NIC_H2C_OPCODE_GET_LINKEVENT 21 +#define NX_NIC_C2C_OPCODE 22 +#define NX_NIC_H2C_OPCODE_LAST 23 + +/* + * Firmware --> Driver + */ + +#define NX_NIC_C2H_OPCODE_START 128 +#define NX_NIC_C2H_OPCODE_CONFIG_RSS_RESPONSE 129 +#define NX_NIC_C2H_OPCODE_CONFIG_RSS_TBL_RESPONSE 130 +#define NX_NIC_C2H_OPCODE_CONFIG_MAC_RESPONSE 131 +#define NX_NIC_C2H_OPCODE_CONFIG_PROMISCUOUS_RESPONSE 132 +#define NX_NIC_C2H_OPCODE_CONFIG_L2_MAC_RESPONSE 133 +#define NX_NIC_C2H_OPCODE_LRO_DELETE_RESPONSE 134 +#define NX_NIC_C2H_OPCODE_LRO_ADD_FAILURE_RESPONSE 135 +#define NX_NIC_C2H_OPCODE_GET_SNMP_STATS 136 +#define NX_NIC_C2H_OPCODE_GET_FINGER_PRINT_REPLY 137 +#define NX_NIC_C2H_OPCODE_INSTALL_LICENSE_REPLY 138 +#define NX_NIC_C2H_OPCODE_GET_LICENSE_CAPABILITIES_REPLY 139 +#define NX_NIC_C2H_OPCODE_GET_NET_STATS_RESPONSE 140 +#define NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE 141 +#define NX_NIC_C2H_OPCODE_LAST 142 #define VPORT_MISS_MODE_DROP 0 /* drop all unmatched */ #define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */ @@ -1491,7 +1419,7 @@ void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, #define NETXEN_MAX_SHORT_NAME 32 struct netxen_brdinfo { - netxen_brdtype_t brdtype; /* type of board */ + int brdtype; /* type of board */ long ports; /* max no of physical ports */ char short_name[NETXEN_MAX_SHORT_NAME]; }; diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index a677ff895184..fe910c1715d6 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -30,7 +30,6 @@ #include #include -#include #include #include #include @@ -53,13 +52,9 @@ struct netxen_nic_stats { #define NETXEN_NIC_INVALID_DATA 0xDEADBEEF static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = { - {"rcvd_bad_skb", NETXEN_NIC_STAT(stats.rcvdbadskb)}, {"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)}, - {"xmited_frames", NETXEN_NIC_STAT(stats.xmitedframes)}, {"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)}, - {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)}, - {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)}, - {"polled", NETXEN_NIC_STAT(stats.polled)}, + {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)}, {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)}, {"csummed", NETXEN_NIC_STAT(stats.csummed)}, {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)}, @@ -168,7 +163,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->phy_address = adapter->physical_port; ecmd->transceiver = XCVR_EXTERNAL; - switch ((netxen_brdtype_t)adapter->ahw.board_type) { + switch (adapter->ahw.board_type) { case NETXEN_BRDTYPE_P2_SB35_4G: case NETXEN_BRDTYPE_P2_SB31_2G: case NETXEN_BRDTYPE_P3_REF_QG: @@ -227,7 +222,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) break; default: printk(KERN_ERR "netxen-nic: Unsupported board model %d\n", - (netxen_brdtype_t)adapter->ahw.board_type); + adapter->ahw.board_type); return -EIO; } diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 016c62129c76..7f0ddbfa7b28 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -31,16 +31,8 @@ #ifndef __NETXEN_NIC_HDR_H_ #define __NETXEN_NIC_HDR_H_ -#include #include -#include -#include -#include -#include -#include #include -#include -#include /* for memset */ /* * The basic unit of access when reading/writing control registers. diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 5026811c04ce..67d63eecc9cb 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -48,6 +48,21 @@ #define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) #define CRB_INDIRECT_2M (0x1e0000UL) +#ifndef readq +static inline u64 readq(void __iomem *addr) +{ + return readl(addr) | (((u64) readl(addr + 4)) << 32LL); +} +#endif + +#ifndef writeq +static inline void writeq(u64 val, void __iomem *addr) +{ + writel(((u32) (val)), (addr)); + writel(((u32) (val >> 32)), (addr + 4)); +} +#endif + #define CRB_WIN_LOCK_TIMEOUT 100000000 static crb_128M_2M_block_map_t crb_128M_2M_map[64] = { {{{0, 0, 0, 0} } }, /* 0: PCI */ @@ -2148,7 +2163,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) board_type = NETXEN_BRDTYPE_P3_10G_TP; } - switch ((netxen_brdtype_t)board_type) { + switch (board_type) { case NETXEN_BRDTYPE_P2_SB35_4G: adapter->ahw.port_type = NETXEN_NIC_GBE; break; diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index 04b47a7993cd..f20c96591a87 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h @@ -36,35 +36,15 @@ /* Hardware memory size of 128 meg */ #define NETXEN_MEMADDR_MAX (128 * 1024 * 1024) -#ifndef readq -static inline u64 readq(void __iomem * addr) -{ - return readl(addr) | (((u64) readl(addr + 4)) << 32LL); -} -#endif - -#ifndef writeq -static inline void writeq(u64 val, void __iomem * addr) -{ - writel(((u32) (val)), (addr)); - writel(((u32) (val >> 32)), (addr + 4)); -} -#endif - struct netxen_adapter; #define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20) -struct netxen_port; void netxen_nic_set_link_parameters(struct netxen_adapter *adapter); typedef u8 netxen_ethernet_macaddr_t[6]; /* Nibble or Byte mode for phy interface (GbE mode only) */ -typedef enum { - NETXEN_NIU_10_100_MB = 0, - NETXEN_NIU_1000_MB -} netxen_niu_gbe_ifmode_t; #define _netxen_crb_get_bit(var, bit) ((var >> bit) & 0x1) @@ -222,30 +202,28 @@ typedef enum { /* * PHY-Specific MII control/status registers. */ -typedef enum { - NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL = 0, - NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS = 1, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 = 2, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 = 3, - NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG = 4, - NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART = 5, - NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE = 6, - NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT = 7, - NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE = 8, - NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL = 9, - NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS = 10, - NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS = 15, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL = 16, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS = 17, - NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE = 18, - NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS = 19, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE = 20, - NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT = 21, - NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL = 24, - NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE = 25, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET = 26, - NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE = 27 -} netxen_niu_phy_register_t; +#define NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL 0 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS 1 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 2 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 3 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG 4 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART 5 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE 6 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT 7 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE 8 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL 9 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS 10 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS 15 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL 16 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS 17 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE 18 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS 19 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE 20 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT 21 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL 24 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE 25 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET 26 +#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE 27 /* * PHY-Specific Status Register (reg 17). diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index aef77289bd34..85693c0f5637 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -29,7 +29,7 @@ */ #include -#include +#include #include "netxen_nic_hw.h" #include "netxen_nic.h" @@ -1598,10 +1598,6 @@ static void netxen_tx_timeout_task(struct work_struct *work) netif_wake_queue(adapter->netdev); } -/* - * netxen_nic_get_stats - Get System Network Statistics - * @netdev: network interface device structure - */ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); @@ -1609,22 +1605,11 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) memset(stats, 0, sizeof(*stats)); - /* total packets received */ stats->rx_packets = adapter->stats.no_rcv; - /* total packets transmitted */ - stats->tx_packets = adapter->stats.xmitedframes + - adapter->stats.xmitfinished; - /* total bytes received */ + stats->tx_packets = adapter->stats.xmitfinished; stats->rx_bytes = adapter->stats.rxbytes; - /* total bytes transmitted */ stats->tx_bytes = adapter->stats.txbytes; - /* bad packets received */ - stats->rx_errors = adapter->stats.rcvdbadskb; - /* packet transmit problems */ - stats->tx_errors = adapter->stats.nocmddescriptor; - /* no space in linux buffers */ stats->rx_dropped = adapter->stats.rxdropped; - /* no space available in linux */ stats->tx_dropped = adapter->stats.txdropped; return stats; diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index d85203203d4d..3310471ba1a0 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -342,9 +342,9 @@ static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, } if (netxen_niu_gbe_enable_phy_interrupts(adapter)) - printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n"); + printk(KERN_ERR "ERROR enabling PHY interrupts\n"); if (netxen_niu_gbe_clear_phy_interrupts(adapter)) - printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); + printk(KERN_ERR "ERROR clearing PHY interrupts\n"); } /* @@ -380,9 +380,9 @@ static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, } if (netxen_niu_gbe_enable_phy_interrupts(adapter)) - printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n"); + printk(KERN_ERR "ERROR enabling PHY interrupts\n"); if (netxen_niu_gbe_clear_phy_interrupts(adapter)) - printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); + printk(KERN_ERR "ERROR clearing PHY interrupts\n"); } int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) @@ -428,13 +428,13 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) | NETXEN_GB_MAC_PAUSED_FRMS); if (netxen_niu_gbe_clear_phy_interrupts(adapter)) - printk(KERN_ERR PFX + printk(KERN_ERR "ERROR clearing PHY interrupts\n"); if (netxen_niu_gbe_enable_phy_interrupts(adapter)) - printk(KERN_ERR PFX + printk(KERN_ERR "ERROR enabling PHY interrupts\n"); if (netxen_niu_gbe_clear_phy_interrupts(adapter)) - printk(KERN_ERR PFX + printk(KERN_ERR "ERROR clearing PHY interrupts\n"); result = -1; } diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 50183335e43a..18ea35d51160 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -41,18 +41,18 @@ #define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04) #define CRB_CMD_PRODUCER_OFFSET NETXEN_NIC_REG(0x08) #define CRB_CMD_CONSUMER_OFFSET NETXEN_NIC_REG(0x0c) -#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) /* C0 EPG BUG */ +#define CRB_PAUSE_ADDR_LO NETXEN_NIC_REG(0x10) #define CRB_PAUSE_ADDR_HI NETXEN_NIC_REG(0x14) #define NX_CDRP_CRB_OFFSET NETXEN_NIC_REG(0x18) #define NX_ARG1_CRB_OFFSET NETXEN_NIC_REG(0x1c) #define NX_ARG2_CRB_OFFSET NETXEN_NIC_REG(0x20) #define NX_ARG3_CRB_OFFSET NETXEN_NIC_REG(0x24) #define NX_SIGN_CRB_OFFSET NETXEN_NIC_REG(0x28) -#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20) /* 4 regs for perf */ +#define CRB_CMD_INTR_LOOP NETXEN_NIC_REG(0x20) #define CRB_CMD_DMA_LOOP NETXEN_NIC_REG(0x24) #define CRB_RCV_INTR_LOOP NETXEN_NIC_REG(0x28) #define CRB_RCV_DMA_LOOP NETXEN_NIC_REG(0x2c) -#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x30) /* phantom init status */ +#define CRB_ENABLE_TX_INTR NETXEN_NIC_REG(0x30) #define CRB_MMAP_ADDR_3 NETXEN_NIC_REG(0x34) #define CRB_CMDPEG_CMDRING NETXEN_NIC_REG(0x38) #define CRB_HOST_DUMMY_BUF_ADDR_HI NETXEN_NIC_REG(0x3c) @@ -65,7 +65,7 @@ #define CRB_MMAP_SIZE_1 NETXEN_NIC_REG(0x58) #define CRB_MMAP_SIZE_2 NETXEN_NIC_REG(0x5c) #define CRB_MMAP_SIZE_3 NETXEN_NIC_REG(0x60) -#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x64) /* interrupt coalescing */ +#define CRB_GLOBAL_INT_COAL NETXEN_NIC_REG(0x64) #define CRB_INT_COAL_MODE NETXEN_NIC_REG(0x68) #define CRB_MAX_RCV_BUFS NETXEN_NIC_REG(0x6c) #define CRB_TX_INT_THRESHOLD NETXEN_NIC_REG(0x70) @@ -83,13 +83,13 @@ #define CRB_AGENT_TX_TYPE NETXEN_NIC_REG(0xa0) #define CRB_AGENT_TX_ADDR NETXEN_NIC_REG(0xa4) #define CRB_AGENT_TX_MSS NETXEN_NIC_REG(0xa8) -#define CRB_TX_STATE NETXEN_NIC_REG(0xac) /* Debug -performance */ +#define CRB_TX_STATE NETXEN_NIC_REG(0xac) #define CRB_TX_COUNT NETXEN_NIC_REG(0xb0) #define CRB_RX_STATE NETXEN_NIC_REG(0xb4) #define CRB_RX_PERF_DEBUG_1 NETXEN_NIC_REG(0xb8) -#define CRB_RX_LRO_CONTROL NETXEN_NIC_REG(0xbc) /* LRO On/OFF */ +#define CRB_RX_LRO_CONTROL NETXEN_NIC_REG(0xbc) #define CRB_RX_LRO_START_NUM NETXEN_NIC_REG(0xc0) -#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4) /* Multiport Mode */ +#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4) #define CRB_CMD_RING_SIZE NETXEN_NIC_REG(0xc8) #define CRB_DMA_SHIFT NETXEN_NIC_REG(0xcc) #define CRB_INT_VECTOR NETXEN_NIC_REG(0xd4) @@ -109,8 +109,6 @@ #define CRB_CMD_CONSUMER_OFFSET_1 NETXEN_NIC_REG(0x1b0) #define CRB_CMD_PRODUCER_OFFSET_2 NETXEN_NIC_REG(0x1b8) #define CRB_CMD_CONSUMER_OFFSET_2 NETXEN_NIC_REG(0x1bc) - -// 1c0 to 1cc used for signature reg #define CRB_CMD_PRODUCER_OFFSET_3 NETXEN_NIC_REG(0x1d0) #define CRB_CMD_CONSUMER_OFFSET_3 NETXEN_NIC_REG(0x1d4) #define CRB_TEMP_STATE NETXEN_NIC_REG(0x1b4) @@ -120,8 +118,7 @@ #define CRB_V2P_2 NETXEN_NIC_REG(0x298) #define CRB_V2P_3 NETXEN_NIC_REG(0x29c) #define CRB_V2P(port) (CRB_V2P_0+((port)*4)) -#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0) -/* sw int status/mask registers */ +#define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0) #define CRB_SW_INT_MASK_0 NETXEN_NIC_REG(0x1d8) #define CRB_SW_INT_MASK_1 NETXEN_NIC_REG(0x1e0) #define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4) @@ -136,7 +133,7 @@ #define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) #define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) #define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270) -#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274) +#define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274) #define INTR_SCHEME_PERPORT 0x1 #define MSI_MODE_MULTIFUNC 0x1 -- GitLab From 1b1f789818c6be9437cfe199932ee13faafca60f Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:39 +0000 Subject: [PATCH 0219/6080] netxen: refactor netxen_adapter Rearrange members to align them at right offset. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 80 ++++++++++++++-------------- drivers/net/netxen/netxen_nic_ctx.c | 7 --- drivers/net/netxen/netxen_nic_main.c | 11 ---- 3 files changed, 39 insertions(+), 59 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 184eb6f76d55..1165f53ea2ca 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -700,14 +700,13 @@ struct netxen_hardware_context { u8 cut_through; u8 revision_id; + u8 pci_func; + u8 linkup; u16 port_type; - int board_type; - u32 linkup; + u16 board_type; /* Address of cmd ring in Phantom */ struct cmd_desc_type0 *cmd_desc_head; dma_addr_t cmd_desc_phys_addr; - struct netxen_adapter *adapter; - int pci_func; }; #define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */ @@ -1146,61 +1145,52 @@ struct netxen_adapter { struct net_device *netdev; struct pci_dev *pdev; - int pci_using_dac; - struct net_device_stats net_stats; - int mtu; - int portnum; - u8 physical_port; - u16 tx_context_id; - - uint8_t mc_enabled; - uint8_t max_mc_count; nx_mac_list_t *mac_list; - struct netxen_legacy_intr_set legacy_intr; - - struct work_struct watchdog_task; - struct timer_list watchdog_timer; - struct work_struct tx_timeout_task; - u32 curr_window; u32 crb_win; rwlock_t adapter_lock; + spinlock_t tx_clean_lock; u32 cmd_producer; - __le32 *cmd_consumer; u32 last_cmd_consumer; u32 crb_addr_cmd_producer; u32 crb_addr_cmd_consumer; - spinlock_t tx_clean_lock; + __le32 *cmd_consumer; u32 num_txd; u32 num_rxd; u32 num_jumbo_rxd; u32 num_lro_rxd; - int max_rds_rings; - int max_sds_rings; + u8 max_rds_rings; + u8 max_sds_rings; + u8 driver_mismatch; + u8 msix_supported; + u8 rx_csum; + u8 pci_using_dac; + u8 portnum; + u8 physical_port; + + u8 mc_enabled; + u8 max_mc_count; + u16 tx_context_id; + u16 mtu; + u16 is_up; + u16 link_speed; + u16 link_duplex; + u16 link_autoneg; + u16 resv1; + u32 resv2; u32 flags; u32 irq; - int driver_mismatch; u32 temp; - u32 fw_major; u32 fw_version; - int msix_supported; - struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER]; - struct netxen_adapter_stats stats; - u16 link_speed; - u16 link_duplex; - u16 state; - u16 link_autoneg; - int rx_csum; - struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */ /* @@ -1209,15 +1199,9 @@ struct netxen_adapter { */ struct netxen_recv_context recv_ctx; - int is_up; - struct netxen_dummy_dma dummy_dma; - nx_nic_intr_coalesce_t coal; - /* Context interface shared between card and host */ struct netxen_ring_ctx *ctx_desc; dma_addr_t ctx_desc_phys_addr; - int intr_scheme; - int msi_mode; int (*enable_phy_interrupts) (struct netxen_adapter *); int (*disable_phy_interrupts) (struct netxen_adapter *); int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t); @@ -1238,7 +1222,21 @@ struct netxen_adapter { u32 (*pci_read_normalize)(struct netxen_adapter *, u64); unsigned long (*pci_set_window)(struct netxen_adapter *, unsigned long long); -}; /* netxen_adapter structure */ + + struct netxen_legacy_intr_set legacy_intr; + + struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER]; + + struct netxen_dummy_dma dummy_dma; + + struct work_struct watchdog_task; + struct timer_list watchdog_timer; + struct work_struct tx_timeout_task; + + struct net_device_stats net_stats; + + nx_nic_intr_coalesce_t coal; +}; /* * NetXen dma watchdog control structure diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 9234473bc08a..73f6debacf9c 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -624,9 +624,6 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) if (adapter->fw_major >= 4) { - adapter->intr_scheme = INTR_SCHEME_PERPORT; - adapter->msi_mode = MSI_MODE_MULTIFUNC; - err = nx_fw_cmd_create_rx_ctx(adapter); if (err) goto err_out_free; @@ -638,10 +635,6 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) sds_ring->crb_sts_consumer = recv_crb_registers[adapter->portnum].crb_sts_consumer; - adapter->intr_scheme = adapter->pci_read_normalize(adapter, - CRB_NIC_CAPABILITIES_FW); - adapter->msi_mode = adapter->pci_read_normalize(adapter, - CRB_NIC_MSI_MODE_FW); recv_ctx->sds_rings[0].crb_intr_mask = sw_int_mask[adapter->portnum]; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 85693c0f5637..853dee8057d9 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -462,8 +462,6 @@ netxen_setup_intr(struct netxen_adapter *adapter) struct pci_dev *pdev = adapter->pdev; adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED); - adapter->intr_scheme = -1; - adapter->msi_mode = -1; if (adapter->ahw.revision_id >= NX_P3_B0) legacy_intrp = &legacy_intr[adapter->ahw.pci_func]; @@ -726,15 +724,6 @@ netxen_nic_request_irq(struct netxen_adapter *adapter) struct net_device *netdev = adapter->netdev; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; - if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) || - (adapter->intr_scheme != INTR_SCHEME_PERPORT)) { - printk(KERN_ERR "%s: Firmware interrupt scheme is " - "incompatible with driver\n", - netdev->name); - adapter->driver_mismatch = 1; - return -EINVAL; - } - if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) handler = netxen_msix_intr; else if (adapter->flags & NETXEN_NIC_MSI_ENABLED) -- GitLab From d877f1e344f5515988d9dcd6db5d4285911778a3 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:40 +0000 Subject: [PATCH 0220/6080] netxen: refactor transmit code o move tx stuff into nx_host_tx_ring structure, this will help managing multiple tx rings in future. o sanitize some variable names Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 42 +++++++++++----------- drivers/net/netxen/netxen_nic_ctx.c | 49 ++++++++++---------------- drivers/net/netxen/netxen_nic_hw.c | 37 ++++++++++---------- drivers/net/netxen/netxen_nic_init.c | 48 +++++++++++++------------ drivers/net/netxen/netxen_nic_main.c | 52 +++++++++++++--------------- 5 files changed, 108 insertions(+), 120 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 1165f53ea2ca..2aa658db103f 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -74,10 +74,10 @@ (sizeof(struct netxen_rx_buffer) * rds_ring->num_desc) #define STATUS_DESC_RINGSIZE(sds_ring) \ (sizeof(struct status_desc) * (sds_ring)->num_desc) -#define TX_BUFF_RINGSIZE(adapter) \ - (sizeof(struct netxen_cmd_buffer) * adapter->num_txd) -#define TX_DESC_RINGSIZE(adapter) \ - (sizeof(struct cmd_desc_type0) * adapter->num_txd) +#define TX_BUFF_RINGSIZE(tx_ring) \ + (sizeof(struct netxen_cmd_buffer) * tx_ring->num_desc) +#define TX_DESC_RINGSIZE(tx_ring) \ + (sizeof(struct cmd_desc_type0) * tx_ring->num_desc) #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) @@ -639,7 +639,7 @@ extern char netxen_nic_driver_name[]; */ struct netxen_skb_frag { u64 dma; - ulong length; + u64 length; }; #define _netxen_set_bits(config_word, start, bits, val) {\ @@ -704,9 +704,6 @@ struct netxen_hardware_context { u8 linkup; u16 port_type; u16 board_type; - /* Address of cmd ring in Phantom */ - struct cmd_desc_type0 *cmd_desc_head; - dma_addr_t cmd_desc_phys_addr; }; #define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */ @@ -752,14 +749,25 @@ struct nx_host_sds_ring { struct napi_struct napi; struct list_head free_list[NUM_RCV_DESC_RINGS]; - u16 clean_tx; - u16 post_rxd; int irq; dma_addr_t phys_addr; char name[IFNAMSIZ+4]; }; +struct nx_host_tx_ring { + u32 producer; + __le32 *hw_consumer; + u32 sw_consumer; + u32 crb_cmd_producer; + u32 crb_cmd_consumer; + u32 num_desc; + + struct netxen_cmd_buffer *cmd_buf_arr; + struct cmd_desc_type0 *desc_head; + dma_addr_t phys_addr; +}; + /* * Receive context. There is one such structure per instance of the * receive processing. Any state information that is relevant to @@ -1152,11 +1160,6 @@ struct netxen_adapter { rwlock_t adapter_lock; spinlock_t tx_clean_lock; - u32 cmd_producer; - u32 last_cmd_consumer; - u32 crb_addr_cmd_producer; - u32 crb_addr_cmd_consumer; - __le32 *cmd_consumer; u32 num_txd; u32 num_rxd; @@ -1191,13 +1194,8 @@ struct netxen_adapter { struct netxen_adapter_stats stats; - struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */ - - /* - * Receive instances. These can be either one per port, - * or one per peg, etc. - */ struct netxen_recv_context recv_ctx; + struct nx_host_tx_ring tx_ring; /* Context interface shared between card and host */ struct netxen_ring_ctx *ctx_desc; @@ -1409,7 +1407,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p); struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, - uint32_t crb_producer); + struct nx_host_tx_ring *tx_ring, uint32_t crb_producer); /* * NetXen Board information diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 73f6debacf9c..794335188a26 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -328,6 +328,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) int err = 0; u64 offset, phys_addr; dma_addr_t rq_phys_addr, rsp_phys_addr; + struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); rq_addr = pci_alloc_consistent(adapter->pdev, @@ -367,10 +368,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) prq_cds = &prq->cds_ring; - prq_cds->host_phys_addr = - cpu_to_le64(adapter->ahw.cmd_desc_phys_addr); - - prq_cds->ring_size = cpu_to_le32(adapter->num_txd); + prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr); + prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc); phys_addr = rq_phys_addr; err = netxen_issue_cmd(adapter, @@ -383,8 +382,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) if (err == NX_RCODE_SUCCESS) { temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); - adapter->crb_addr_cmd_producer = - NETXEN_NIC_REG(temp - 0x200); + tx_ring->crb_cmd_producer = NETXEN_NIC_REG(temp - 0x200); #if 0 adapter->tx_state = le32_to_cpu(prsp->host_ctx_state); @@ -497,13 +495,13 @@ netxen_init_old_ctx(struct netxen_adapter *adapter) struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; struct nx_host_sds_ring *sds_ring; + struct nx_host_tx_ring *tx_ring; int ring; int func_id = adapter->portnum; - adapter->ctx_desc->cmd_ring_addr = - cpu_to_le64(adapter->ahw.cmd_desc_phys_addr); - adapter->ctx_desc->cmd_ring_size = - cpu_to_le32(adapter->num_txd); + tx_ring = &adapter->tx_ring; + adapter->ctx_desc->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr); + adapter->ctx_desc->cmd_ring_size = cpu_to_le32(tx_ring->num_desc); recv_ctx = &adapter->recv_ctx; @@ -535,25 +533,17 @@ static uint32_t sw_int_mask[4] = { int netxen_alloc_hw_resources(struct netxen_adapter *adapter) { - struct netxen_hardware_context *hw = &adapter->ahw; - u32 state = 0; void *addr; int err = 0; int ring; struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; struct nx_host_sds_ring *sds_ring; + struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; - err = netxen_receive_peg_ready(adapter); - if (err) { - printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n", - state); - return err; - } - addr = pci_alloc_consistent(pdev, sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), &adapter->ctx_desc_phys_addr); @@ -568,13 +558,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) adapter->ctx_desc->cmd_consumer_offset = cpu_to_le64(adapter->ctx_desc_phys_addr + sizeof(struct netxen_ring_ctx)); - adapter->cmd_consumer = + tx_ring->hw_consumer = (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx)); /* cmd desc ring */ - addr = pci_alloc_consistent(pdev, - TX_DESC_RINGSIZE(adapter), - &hw->cmd_desc_phys_addr); + addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring), + &tx_ring->phys_addr); if (addr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n", @@ -582,7 +571,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) return -ENOMEM; } - hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; + tx_ring->desc_head = (struct cmd_desc_type0 *)addr; recv_ctx = &adapter->recv_ctx; @@ -658,6 +647,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; struct nx_host_sds_ring *sds_ring; + struct nx_host_tx_ring *tx_ring; int ring; if (adapter->fw_major >= 4) { @@ -674,13 +664,12 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) adapter->ctx_desc = NULL; } - if (adapter->ahw.cmd_desc_head != NULL) { + tx_ring = &adapter->tx_ring; + if (tx_ring->desc_head != NULL) { pci_free_consistent(adapter->pdev, - sizeof(struct cmd_desc_type0) * - adapter->num_txd, - adapter->ahw.cmd_desc_head, - adapter->ahw.cmd_desc_phys_addr); - adapter->ahw.cmd_desc_head = NULL; + TX_DESC_RINGSIZE(tx_ring), + tx_ring->desc_head, tx_ring->phys_addr); + tx_ring->desc_head = NULL; } recv_ctx = &adapter->recv_ctx; diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 67d63eecc9cb..8416962cc9ac 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -501,45 +501,44 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter, static int netxen_send_cmd_descs(struct netxen_adapter *adapter, - struct cmd_desc_type0 *cmd_desc_arr, int nr_elements) + struct cmd_desc_type0 *cmd_desc_arr, int nr_desc) { - uint32_t i, producer; + u32 i, producer, consumer; struct netxen_cmd_buffer *pbuf; struct cmd_desc_type0 *cmd_desc; - - if (nr_elements > MAX_PENDING_DESC_BLOCK_SIZE || nr_elements == 0) { - printk(KERN_WARNING "%s: Too many command descriptors in a " - "request\n", __func__); - return -EINVAL; - } + struct nx_host_tx_ring *tx_ring; i = 0; + tx_ring = &adapter->tx_ring; netif_tx_lock_bh(adapter->netdev); - producer = adapter->cmd_producer; + producer = tx_ring->producer; + consumer = tx_ring->sw_consumer; + + if (nr_desc > find_diff_among(producer, consumer, tx_ring->num_desc)) { + netif_tx_unlock_bh(adapter->netdev); + return -EBUSY; + } + do { cmd_desc = &cmd_desc_arr[i]; - pbuf = &adapter->cmd_buf_arr[producer]; + pbuf = &tx_ring->cmd_buf_arr[producer]; pbuf->skb = NULL; pbuf->frag_count = 0; - /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */ - memcpy(&adapter->ahw.cmd_desc_head[producer], + memcpy(&tx_ring->desc_head[producer], &cmd_desc_arr[i], sizeof(struct cmd_desc_type0)); - producer = get_next_index(producer, - adapter->num_txd); + producer = get_next_index(producer, tx_ring->num_desc); i++; - } while (i != nr_elements); - - adapter->cmd_producer = producer; + } while (i != nr_desc); - /* write producer index to start the xmit */ + tx_ring->producer = producer; - netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); + netxen_nic_update_cmd_producer(adapter, tx_ring, producer); netif_tx_unlock_bh(adapter->netdev); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 0759c35f16ac..8e45dcc27c7f 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -173,9 +173,10 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter) struct netxen_cmd_buffer *cmd_buf; struct netxen_skb_frag *buffrag; int i, j; + struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; - cmd_buf = adapter->cmd_buf_arr; - for (i = 0; i < adapter->num_txd; i++) { + cmd_buf = tx_ring->cmd_buf_arr; + for (i = 0; i < tx_ring->num_desc; i++) { buffrag = cmd_buf->frag_array; if (buffrag->dma) { pci_unmap_single(adapter->pdev, buffrag->dma, @@ -203,6 +204,7 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) { struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; + struct nx_host_tx_ring *tx_ring; int ring; recv_ctx = &adapter->recv_ctx; @@ -214,8 +216,9 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) } } - if (adapter->cmd_buf_arr) - vfree(adapter->cmd_buf_arr); + tx_ring = &adapter->tx_ring; + if (tx_ring->cmd_buf_arr) + vfree(tx_ring->cmd_buf_arr); return; } @@ -224,21 +227,24 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; struct nx_host_sds_ring *sds_ring; + struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; struct netxen_rx_buffer *rx_buf; int ring, i, num_rx_bufs; struct netxen_cmd_buffer *cmd_buf_arr; struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + tx_ring->num_desc = adapter->num_txd; cmd_buf_arr = - (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter)); + (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(tx_ring)); if (cmd_buf_arr == NULL) { - printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n", + dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n", netdev->name); return -ENOMEM; } - memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter)); - adapter->cmd_buf_arr = cmd_buf_arr; + memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); + tx_ring->cmd_buf_arr = cmd_buf_arr; recv_ctx = &adapter->recv_ctx; for (ring = 0; ring < adapter->max_rds_rings; ring++) { @@ -307,8 +313,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &recv_ctx->sds_rings[ring]; sds_ring->irq = adapter->msix_entries[ring].vector; - sds_ring->clean_tx = (ring == 0); - sds_ring->post_rxd = (ring == 0); sds_ring->adapter = adapter; sds_ring->num_desc = adapter->num_rxd; @@ -990,23 +994,24 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max) /* Process Command status ring */ int netxen_process_cmd_ring(struct netxen_adapter *adapter) { - u32 last_consumer, consumer; + u32 sw_consumer, hw_consumer; int count = 0, i; struct netxen_cmd_buffer *buffer; struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; struct netxen_skb_frag *frag; int done = 0; + struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; if (!spin_trylock(&adapter->tx_clean_lock)) return 1; - last_consumer = adapter->last_cmd_consumer; - barrier(); /* cmd_consumer can change underneath */ - consumer = le32_to_cpu(*(adapter->cmd_consumer)); + sw_consumer = tx_ring->sw_consumer; + barrier(); /* hw_consumer can change underneath */ + hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); - while (last_consumer != consumer) { - buffer = &adapter->cmd_buf_arr[last_consumer]; + while (sw_consumer != hw_consumer) { + buffer = &tx_ring->cmd_buf_arr[sw_consumer]; if (buffer->skb) { frag = &buffer->frag_array[0]; pci_unmap_single(pdev, frag->dma, frag->length, @@ -1024,14 +1029,13 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) buffer->skb = NULL; } - last_consumer = get_next_index(last_consumer, - adapter->num_txd); + sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc); if (++count >= MAX_STATUS_HANDLE) break; } if (count) { - adapter->last_cmd_consumer = last_consumer; + tx_ring->sw_consumer = sw_consumer; smp_mb(); if (netif_queue_stopped(netdev) && netif_running(netdev)) { netif_tx_lock(netdev); @@ -1053,9 +1057,9 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) * There is still a possible race condition and the host could miss an * interrupt. The card has to take care of this. */ - barrier(); /* cmd_consumer can change underneath */ - consumer = le32_to_cpu(*(adapter->cmd_consumer)); - done = (last_consumer == consumer); + barrier(); /* hw_consumer can change underneath */ + hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); + done = (sw_consumer == hw_consumer); spin_unlock(&adapter->tx_clean_lock); return (done); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 853dee8057d9..22b2d491c782 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -107,10 +107,10 @@ static uint32_t crb_cmd_producer[4] = { void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, - uint32_t crb_producer) + struct nx_host_tx_ring *tx_ring, u32 producer) { adapter->pci_write_normalize(adapter, - adapter->crb_addr_cmd_producer, crb_producer); + tx_ring->crb_cmd_producer, producer); } static uint32_t crb_cmd_consumer[4] = { @@ -120,10 +120,10 @@ static uint32_t crb_cmd_consumer[4] = { static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, - u32 crb_consumer) + struct nx_host_tx_ring *tx_ring, u32 consumer) { adapter->pci_write_normalize(adapter, - adapter->crb_addr_cmd_consumer, crb_consumer); + tx_ring->crb_cmd_consumer, consumer); } static uint32_t msi_tgt_status[8] = { @@ -814,6 +814,7 @@ netxen_nic_attach(struct netxen_adapter *adapter) struct pci_dev *pdev = adapter->pdev; int err, ring; struct nx_host_rds_ring *rds_ring; + struct nx_host_tx_ring *tx_ring; err = netxen_init_firmware(adapter); if (err != 0) { @@ -843,13 +844,12 @@ netxen_nic_attach(struct netxen_adapter *adapter) } if (adapter->fw_major < 4) { - adapter->crb_addr_cmd_producer = - crb_cmd_producer[adapter->portnum]; - adapter->crb_addr_cmd_consumer = - crb_cmd_consumer[adapter->portnum]; + tx_ring = &adapter->tx_ring; + tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum]; + tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum]; - netxen_nic_update_cmd_producer(adapter, 0); - netxen_nic_update_cmd_consumer(adapter, 0); + netxen_nic_update_cmd_producer(adapter, tx_ring, 0); + netxen_nic_update_cmd_consumer(adapter, tx_ring, 0); } for (ring = 0; ring < adapter->max_rds_rings; ring++) { @@ -1304,7 +1304,7 @@ 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; + struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; unsigned int first_seg_len = skb->len - skb->data_len; struct netxen_cmd_buffer *pbuf; struct netxen_skb_frag *buffrag; @@ -1315,28 +1315,26 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) u32 producer, consumer; int frag_count, no_of_desc; - u32 num_txd = adapter->num_txd; + u32 num_txd = tx_ring->num_desc; bool is_tso = false; frag_count = skb_shinfo(skb)->nr_frags + 1; - /* There 4 fragments per descriptor */ + /* 4 fragments per cmd des */ no_of_desc = (frag_count + 3) >> 2; - producer = adapter->cmd_producer; + producer = tx_ring->producer; smp_mb(); - consumer = adapter->last_cmd_consumer; + consumer = tx_ring->sw_consumer; if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) { netif_stop_queue(netdev); smp_mb(); return NETDEV_TX_BUSY; } - /* Copy the descriptors into the hardware */ - hwdesc = &hw->cmd_desc_head[producer]; + hwdesc = &tx_ring->desc_head[producer]; netxen_clear_cmddesc((u64 *)hwdesc); - /* Take skb->data itself */ - pbuf = &adapter->cmd_buf_arr[producer]; + pbuf = &tx_ring->cmd_buf_arr[producer]; is_tso = netxen_tso_check(netdev, hwdesc, skb); @@ -1365,9 +1363,9 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if ((i & 0x3) == 0) { k = 0; producer = get_next_index(producer, num_txd); - hwdesc = &hw->cmd_desc_head[producer]; + hwdesc = &tx_ring->desc_head[producer]; netxen_clear_cmddesc((u64 *)hwdesc); - pbuf = &adapter->cmd_buf_arr[producer]; + pbuf = &tx_ring->cmd_buf_arr[producer]; pbuf->skb = NULL; } frag = &skb_shinfo(skb)->frags[i - 1]; @@ -1419,8 +1417,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) more_hdr = 0; } /* copy the MAC/IP/TCP headers to the cmd descriptor list */ - hwdesc = &hw->cmd_desc_head[producer]; - pbuf = &adapter->cmd_buf_arr[producer]; + hwdesc = &tx_ring->desc_head[producer]; + pbuf = &tx_ring->cmd_buf_arr[producer]; pbuf->skb = NULL; /* copy the first 64 bytes */ @@ -1429,8 +1427,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) producer = get_next_index(producer, num_txd); if (more_hdr) { - hwdesc = &hw->cmd_desc_head[producer]; - pbuf = &adapter->cmd_buf_arr[producer]; + hwdesc = &tx_ring->desc_head[producer]; + pbuf = &tx_ring->cmd_buf_arr[producer]; pbuf->skb = NULL; /* copy the next 64 bytes - should be enough except * for pathological case @@ -1443,10 +1441,10 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } } - adapter->cmd_producer = producer; + tx_ring->producer = producer; adapter->stats.txbytes += skb->len; - netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); + netxen_nic_update_cmd_producer(adapter, tx_ring, producer); adapter->stats.xmitcalled++; netdev->trans_start = jiffies; -- GitLab From 56a007871a6689db80e19f63fe6dc3692daa2a6f Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:41 +0000 Subject: [PATCH 0221/6080] netxen: defer firmware handshake Removed duplicate firmware handshake, defer it until first port (interface) is brought up. 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 | 59 +++++++++++----------------- drivers/net/netxen/netxen_nic_main.c | 4 -- 3 files changed, 22 insertions(+), 42 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 2aa658db103f..7e208b31a27e 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1359,7 +1359,6 @@ unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, void netxen_free_adapter_offload(struct netxen_adapter *adapter); int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); -int netxen_receive_peg_ready(struct netxen_adapter *adapter); int netxen_load_firmware(struct netxen_adapter *adapter); int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 8e45dcc27c7f..9991951e6e05 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -108,42 +108,6 @@ static void crb_addr_transform_setup(void) crb_addr_transform(I2C0); } -int netxen_init_firmware(struct netxen_adapter *adapter) -{ - u32 state = 0, loops = 0, err = 0; - - /* Window 1 call */ - state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE); - - if (state == PHAN_INITIALIZE_ACK) - return 0; - - while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) { - msleep(1); - /* Window 1 call */ - state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE); - - loops++; - } - if (loops >= 2000) { - printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n", - state); - err = -EIO; - return err; - } - /* Window 1 call */ - adapter->pci_write_normalize(adapter, - CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT); - adapter->pci_write_normalize(adapter, - CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC); - adapter->pci_write_normalize(adapter, - CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE); - adapter->pci_write_normalize(adapter, - CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); - - return err; -} - void netxen_release_rx_buffers(struct netxen_adapter *adapter) { struct netxen_recv_context *recv_ctx; @@ -789,7 +753,8 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) return 0; } -int netxen_receive_peg_ready(struct netxen_adapter *adapter) +static int +netxen_receive_peg_ready(struct netxen_adapter *adapter) { u32 val = 0; int retries = 2000; @@ -813,6 +778,26 @@ int netxen_receive_peg_ready(struct netxen_adapter *adapter) return 0; } +int netxen_init_firmware(struct netxen_adapter *adapter) +{ + int err; + + err = netxen_receive_peg_ready(adapter); + if (err) + return err; + + adapter->pci_write_normalize(adapter, + CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT); + adapter->pci_write_normalize(adapter, + CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC); + adapter->pci_write_normalize(adapter, + CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE); + adapter->pci_write_normalize(adapter, + CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); + + return err; +} + static int netxen_alloc_rx_skb(struct netxen_adapter *adapter, struct nx_host_rds_ring *rds_ring, diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 22b2d491c782..665fce561d4a 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1027,10 +1027,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netxen_napi_add(adapter, netdev); - err = netxen_receive_peg_ready(adapter); - if (err) - goto err_out_disable_msi; - init_timer(&adapter->watchdog_timer); adapter->watchdog_timer.function = &netxen_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; -- GitLab From 3bf26ce3f4cc3c9e0d0478b4016c6113a16faaf1 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:42 +0000 Subject: [PATCH 0222/6080] netxen: async link event handling Add support for asynchronous events from firmware, received over one of the rx rings. Add support for event based phy interrupts, enhanced links status reporting from firmware. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 108 +++++++++++++++++------ drivers/net/netxen/netxen_nic_ethtool.c | 32 ++++++- drivers/net/netxen/netxen_nic_hw.c | 22 +++++ drivers/net/netxen/netxen_nic_init.c | 102 +++++++++++++++++++-- drivers/net/netxen/netxen_nic_main.c | 55 +++++++----- drivers/net/netxen/netxen_nic_phan_reg.h | 1 + 6 files changed, 263 insertions(+), 57 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 7e208b31a27e..f4d7e2db700b 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -354,6 +354,7 @@ struct rcv_desc { /* opcode field in status_desc */ #define NETXEN_NIC_RXPKT_DESC 0x04 #define NETXEN_OLD_RXPKT_DESC 0x3f +#define NETXEN_NIC_RESPONSE_DESC 0x05 /* for status field in status_desc */ #define STATUS_NEED_CKSUM (1) @@ -363,8 +364,11 @@ struct rcv_desc { #define STATUS_OWNER_HOST (0x1ULL << 56) #define STATUS_OWNER_PHANTOM (0x2ULL << 56) -/* Note: sizeof(status_desc) should always be a mutliple of 2 */ - +/* Status descriptor: + 0-3 port, 4-7 status, 8-11 type, 12-27 total_length + 28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset + 53-55 desc_cnt, 56-57 owner, 58-63 opcode + */ #define netxen_get_sts_port(sts_data) \ ((sts_data) & 0x0F) #define netxen_get_sts_status(sts_data) \ @@ -379,35 +383,13 @@ struct rcv_desc { (((sts_data) >> 44) & 0x0F) #define netxen_get_sts_pkt_offset(sts_data) \ (((sts_data) >> 48) & 0x1F) +#define netxen_get_sts_desc_cnt(sts_data) \ + (((sts_data) >> 53) & 0x7) #define netxen_get_sts_opcode(sts_data) \ (((sts_data) >> 58) & 0x03F) struct status_desc { - /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length - 28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset - 53-55 desc_cnt, 56-57 owner, 58-63 opcode - */ - __le64 status_desc_data; - union { - struct { - __le32 hash_value; - u8 hash_type; - u8 msg_type; - u8 unused; - union { - /* Bit pattern: 0-6 lro_count indicates frag - * sequence, 7 last_frag indicates last frag - */ - u8 lro; - - /* chained buffers */ - u8 nr_frags; - }; - }; - struct { - __le16 frag_handles[4]; - }; - }; + __le64 status_desc_data[2]; } __attribute__ ((aligned(16))); /* The version of the main data structure */ @@ -1114,6 +1096,66 @@ typedef struct { #define VPORT_MISS_MODE_ACCEPT_ALL 1 /* accept all packets */ #define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */ +#define NX_FW_CAPABILITY_LINK_NOTIFICATION (1 << 5) +#define NX_FW_CAPABILITY_SWITCHING (1 << 6) + +/* module types */ +#define LINKEVENT_MODULE_NOT_PRESENT 1 +#define LINKEVENT_MODULE_OPTICAL_UNKNOWN 2 +#define LINKEVENT_MODULE_OPTICAL_SRLR 3 +#define LINKEVENT_MODULE_OPTICAL_LRM 4 +#define LINKEVENT_MODULE_OPTICAL_SFP_1G 5 +#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE 6 +#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN 7 +#define LINKEVENT_MODULE_TWINAX 8 + +#define LINKSPEED_10GBPS 10000 +#define LINKSPEED_1GBPS 1000 +#define LINKSPEED_100MBPS 100 +#define LINKSPEED_10MBPS 10 + +#define LINKSPEED_ENCODED_10MBPS 0 +#define LINKSPEED_ENCODED_100MBPS 1 +#define LINKSPEED_ENCODED_1GBPS 2 + +#define LINKEVENT_AUTONEG_DISABLED 0 +#define LINKEVENT_AUTONEG_ENABLED 1 + +#define LINKEVENT_HALF_DUPLEX 0 +#define LINKEVENT_FULL_DUPLEX 1 + +#define LINKEVENT_LINKSPEED_MBPS 0 +#define LINKEVENT_LINKSPEED_ENCODED 1 + +/* firmware response header: + * 63:58 - message type + * 57:56 - owner + * 55:53 - desc count + * 52:48 - reserved + * 47:40 - completion id + * 39:32 - opcode + * 31:16 - error code + * 15:00 - reserved + */ +#define netxen_get_nic_msgtype(msg_hdr) \ + ((msg_hdr >> 58) & 0x3F) +#define netxen_get_nic_msg_compid(msg_hdr) \ + ((msg_hdr >> 40) & 0xFF) +#define netxen_get_nic_msg_opcode(msg_hdr) \ + ((msg_hdr >> 32) & 0xFF) +#define netxen_get_nic_msg_errcode(msg_hdr) \ + ((msg_hdr >> 16) & 0xFFFF) + +typedef struct { + union { + struct { + u64 hdr; + u64 body[7]; + }; + u64 words[8]; + }; +} nx_fw_msg_t; + typedef struct { __le64 qhdr; __le64 req_hdr; @@ -1177,15 +1219,21 @@ struct netxen_adapter { u8 mc_enabled; u8 max_mc_count; + u16 resv2; + u32 resv3; + + u8 has_link_events; + u8 resv1; u16 tx_context_id; u16 mtu; u16 is_up; + u16 link_speed; u16 link_duplex; u16 link_autoneg; - u16 resv1; + u16 module_type; - u32 resv2; + u32 capabilities; u32 flags; u32 irq; u32 temp; @@ -1398,6 +1446,8 @@ 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); int netxen_config_rss(struct netxen_adapter *adapter, int enable); +int netxen_linkevent_request(struct netxen_adapter *adapter, int enable); +void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup); int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu); int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu); diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index fe910c1715d6..5fde9e088a94 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -110,6 +110,7 @@ static int netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct netxen_adapter *adapter = netdev_priv(dev); + int check_sfp_module = 0; /* read which mode */ if (adapter->ahw.port_type == NETXEN_NIC_GBE) { @@ -143,6 +144,13 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->advertising = ADVERTISED_10000baseT_Full; } + if (netif_running(dev) && adapter->has_link_events) { + ecmd->speed = adapter->link_speed; + ecmd->autoneg = adapter->link_autoneg; + ecmd->duplex = adapter->link_duplex; + goto skip; + } + ecmd->port = PORT_TP; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { @@ -160,6 +168,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } else return -EIO; +skip: ecmd->phy_address = adapter->physical_port; ecmd->transceiver = XCVR_EXTERNAL; @@ -190,7 +199,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) case NETXEN_BRDTYPE_P3_HMEZ: ecmd->supported |= SUPPORTED_MII; ecmd->advertising |= ADVERTISED_MII; - ecmd->port = PORT_FIBRE; + ecmd->port = PORT_MII; ecmd->autoneg = AUTONEG_DISABLE; break; case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: @@ -198,6 +207,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) case NETXEN_BRDTYPE_P3_10G_SFP_QT: ecmd->advertising |= ADVERTISED_TP; ecmd->supported |= SUPPORTED_TP; + check_sfp_module = netif_running(dev) && + adapter->has_link_events; case NETXEN_BRDTYPE_P2_SB31_10G: case NETXEN_BRDTYPE_P3_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; @@ -212,6 +223,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP); ecmd->port = PORT_FIBRE; + check_sfp_module = netif_running(dev) && + adapter->has_link_events; } else { ecmd->autoneg = AUTONEG_ENABLE; ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg); @@ -226,6 +239,23 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) return -EIO; } + if (check_sfp_module) { + switch (adapter->module_type) { + case LINKEVENT_MODULE_OPTICAL_UNKNOWN: + case LINKEVENT_MODULE_OPTICAL_SRLR: + case LINKEVENT_MODULE_OPTICAL_LRM: + case LINKEVENT_MODULE_OPTICAL_SFP_1G: + ecmd->port = PORT_FIBRE; + break; + case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE: + case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN: + case LINKEVENT_MODULE_TWINAX: + ecmd->port = PORT_TP; + default: + ecmd->port = -1; + } + } + return 0; } diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 8416962cc9ac..33444a20e4f7 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -731,6 +731,28 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable) return rv; } +int netxen_linkevent_request(struct netxen_adapter *adapter, int enable) +{ + nx_nic_req_t req; + u64 word; + int rv; + + memset(&req, 0, sizeof(nx_nic_req_t)); + req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); + + word = NX_NIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); + req.words[0] = cpu_to_le64(enable); + + rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); + if (rv != 0) { + printk(KERN_ERR "%s: could not configure link notification\n", + adapter->netdev->name); + } + + return rv; +} + /* * netxen_nic_change_mtu - Change the Maximum Transfer Unit * @returns 0 on success, negative on failure diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 9991951e6e05..974783c45321 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -795,9 +795,81 @@ int netxen_init_firmware(struct netxen_adapter *adapter) adapter->pci_write_normalize(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); + if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) { + adapter->capabilities = netxen_nic_reg_read(adapter, + CRB_FW_CAPABILITIES_1); + } + return err; } +static void +netxen_handle_linkevent(struct netxen_adapter *adapter, nx_fw_msg_t *msg) +{ + u32 cable_OUI; + u16 cable_len; + u16 link_speed; + u8 link_status, module, duplex, autoneg; + struct net_device *netdev = adapter->netdev; + + adapter->has_link_events = 1; + + cable_OUI = msg->body[1] & 0xffffffff; + cable_len = (msg->body[1] >> 32) & 0xffff; + link_speed = (msg->body[1] >> 48) & 0xffff; + + link_status = msg->body[2] & 0xff; + duplex = (msg->body[2] >> 16) & 0xff; + autoneg = (msg->body[2] >> 24) & 0xff; + + module = (msg->body[2] >> 8) & 0xff; + if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE) { + printk(KERN_INFO "%s: unsupported cable: OUI 0x%x, length %d\n", + netdev->name, cable_OUI, cable_len); + } else if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN) { + printk(KERN_INFO "%s: unsupported cable length %d\n", + netdev->name, cable_len); + } + + netxen_advert_link_change(adapter, link_status); + + /* update link parameters */ + if (duplex == LINKEVENT_FULL_DUPLEX) + adapter->link_duplex = DUPLEX_FULL; + else + adapter->link_duplex = DUPLEX_HALF; + adapter->module_type = module; + adapter->link_autoneg = autoneg; + adapter->link_speed = link_speed; +} + +static void +netxen_handle_fw_message(int desc_cnt, int index, + struct nx_host_sds_ring *sds_ring) +{ + nx_fw_msg_t msg; + struct status_desc *desc; + int i = 0, opcode; + + while (desc_cnt > 0 && i < 8) { + desc = &sds_ring->desc_head[index]; + msg.words[i++] = le64_to_cpu(desc->status_desc_data[0]); + msg.words[i++] = le64_to_cpu(desc->status_desc_data[1]); + + index = get_next_index(index, sds_ring->num_desc); + desc_cnt--; + } + + opcode = netxen_get_nic_msg_opcode(msg.body[0]); + switch (opcode) { + case NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE: + netxen_handle_linkevent(sds_ring->adapter, &msg); + break; + default: + break; + } +} + static int netxen_alloc_rx_skb(struct netxen_adapter *adapter, struct nx_host_rds_ring *rds_ring, @@ -916,21 +988,35 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max) int count = 0; u64 sts_data; - int opcode, ring, index, length, cksum, pkt_offset; + int opcode, ring, index, length, cksum, pkt_offset, desc_cnt; while (count < max) { desc = &sds_ring->desc_head[consumer]; - sts_data = le64_to_cpu(desc->status_desc_data); + sts_data = le64_to_cpu(desc->status_desc_data[0]); if (!(sts_data & STATUS_OWNER_HOST)) break; + desc_cnt = netxen_get_sts_desc_cnt(sts_data); ring = netxen_get_sts_type(sts_data); + if (ring > RCV_RING_JUMBO) - continue; + goto skip; opcode = netxen_get_sts_opcode(sts_data); + switch (opcode) { + case NETXEN_NIC_RXPKT_DESC: + case NETXEN_OLD_RXPKT_DESC: + break; + case NETXEN_NIC_RESPONSE_DESC: + netxen_handle_fw_message(desc_cnt, consumer, sds_ring); + default: + goto skip; + } + + WARN_ON(desc_cnt > 1); + index = netxen_get_sts_refhandle(sts_data); length = netxen_get_sts_totallength(sts_data); cksum = netxen_get_sts_status(sts_data); @@ -942,9 +1028,13 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max) if (rxbuf) list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]); - desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM); - - consumer = get_next_index(consumer, sds_ring->num_desc); +skip: + for (; desc_cnt > 0; desc_cnt--) { + desc = &sds_ring->desc_head[consumer]; + desc->status_desc_data[0] = + cpu_to_le64(STATUS_OWNER_PHANTOM); + consumer = get_next_index(consumer, sds_ring->num_desc); + } count++; } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 665fce561d4a..bd93296be4dd 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -787,6 +787,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) if (adapter->max_sds_rings > 1) netxen_config_rss(adapter, 1); + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + netxen_linkevent_request(adapter, 1); + return 0; } @@ -1493,26 +1496,9 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) return rv; } -static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) +void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup) { struct net_device *netdev = adapter->netdev; - u32 val, port, linkup; - - port = adapter->physical_port; - - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { - val = adapter->pci_read_normalize(adapter, CRB_XG_STATE_P3); - val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); - linkup = (val == XG_LINK_UP_P3); - } else { - val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); - if (adapter->ahw.port_type == NETXEN_NIC_GBE) - linkup = (val >> port) & 1; - else { - val = (val >> port*8) & 0xff; - linkup = (val == XG_LINK_UP); - } - } if (adapter->ahw.linkup && !linkup) { printk(KERN_INFO "%s: %s NIC Link is down\n", @@ -1523,7 +1509,9 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) netif_stop_queue(netdev); } - netxen_nic_set_link_parameters(adapter); + if (!adapter->has_link_events) + 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); @@ -1533,10 +1521,34 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) netif_wake_queue(netdev); } - netxen_nic_set_link_parameters(adapter); + if (!adapter->has_link_events) + netxen_nic_set_link_parameters(adapter); } } +static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) +{ + u32 val, port, linkup; + + port = adapter->physical_port; + + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { + val = adapter->pci_read_normalize(adapter, CRB_XG_STATE_P3); + val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); + linkup = (val == XG_LINK_UP_P3); + } else { + val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); + if (adapter->ahw.port_type == NETXEN_NIC_GBE) + linkup = (val >> port) & 1; + else { + val = (val >> port*8) & 0xff; + linkup = (val == XG_LINK_UP); + } + } + + netxen_advert_link_change(adapter, linkup); +} + static void netxen_watchdog(unsigned long v) { struct netxen_adapter *adapter = (struct netxen_adapter *)v; @@ -1552,7 +1564,8 @@ void netxen_watchdog_task(struct work_struct *work) if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) return; - netxen_nic_handle_phy_intr(adapter); + if (!adapter->has_link_events) + netxen_nic_handle_phy_intr(adapter); if (netif_running(adapter->netdev)) mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 18ea35d51160..ecd622ead0e9 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -134,6 +134,7 @@ #define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) #define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270) #define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274) +#define CRB_FW_CAPABILITIES_1 NETXEN_NIC_REG(0x128) #define INTR_SCHEME_PERPORT 0x1 #define MSI_MODE_MULTIFUNC 0x1 -- GitLab From 71dcddbdd35487eb931aa8aab28a2df474008754 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:43 +0000 Subject: [PATCH 0223/6080] netxen: allocate status rings dynamically This reduces netxen_adapter footprint when rss (msi-x) is disabled. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 10 +++++----- drivers/net/netxen/netxen_nic_main.c | 26 +++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index f4d7e2db700b..e0f329ff3691 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -762,7 +762,7 @@ struct netxen_recv_context { u16 virt_port; struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS]; - struct nx_host_sds_ring sds_rings[NUM_STS_DESC_RINGS]; + struct nx_host_sds_ring *sds_rings; }; /* New HW context creation */ @@ -1203,10 +1203,10 @@ struct netxen_adapter { spinlock_t tx_clean_lock; - u32 num_txd; - u32 num_rxd; - u32 num_jumbo_rxd; - u32 num_lro_rxd; + u16 num_txd; + u16 num_rxd; + u16 num_jumbo_rxd; + u16 num_lro_rxd; u8 max_rds_rings; u8 max_sds_rings; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index bd93296be4dd..cbd47ae694ba 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -153,7 +153,24 @@ static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring) adapter->legacy_intr.tgt_mask_reg, 0xfbff); } +static int +netxen_alloc_sds_rings(struct netxen_recv_context *recv_ctx, int count) +{ + int size = sizeof(struct nx_host_sds_ring) * count; + + recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL); + + return (recv_ctx->sds_rings == NULL); +} + static void +netxen_free_sds_rings(struct netxen_recv_context *recv_ctx) +{ + if (recv_ctx->sds_rings != NULL) + kfree(recv_ctx->sds_rings); +} + +static int netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev) { int ring; @@ -165,11 +182,16 @@ netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev) else adapter->max_sds_rings = 1; + if (netxen_alloc_sds_rings(recv_ctx, adapter->max_sds_rings)) + return 1; + for (ring = 0; ring < adapter->max_sds_rings; ring++) { sds_ring = &recv_ctx->sds_rings[ring]; netif_napi_add(netdev, &sds_ring->napi, netxen_nic_poll, NETXEN_NETDEV_WEIGHT); } + + return 0; } static void @@ -1028,7 +1050,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->irq = adapter->msix_entries[0].vector; - netxen_napi_add(adapter, netdev); + if (netxen_napi_add(adapter, netdev)) + goto err_out_disable_msi; init_timer(&adapter->watchdog_timer); adapter->watchdog_timer.function = &netxen_watchdog; @@ -1110,6 +1133,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netxen_free_adapter_offload(adapter); netxen_teardown_intr(adapter); + netxen_free_sds_rings(&adapter->recv_ctx); netxen_cleanup_pci_map(adapter); -- GitLab From 1fbe63235893e5dce28fe91d8465dd231b0cb3d9 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:44 +0000 Subject: [PATCH 0224/6080] netxen: annotate register access functions o remove unnecessary length parameter since register access width is fixed 4 byte. o remove superfluous pci_read_normalize and pci_write_normalize functions. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 75 ++------ drivers/net/netxen/netxen_nic_ctx.c | 18 +- drivers/net/netxen/netxen_nic_ethtool.c | 45 +++-- drivers/net/netxen/netxen_nic_hw.c | 229 +++++++++++------------- drivers/net/netxen/netxen_nic_init.c | 40 ++--- drivers/net/netxen/netxen_nic_main.c | 66 ++++--- drivers/net/netxen/netxen_nic_niu.c | 110 +++++------- 7 files changed, 239 insertions(+), 344 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index e0f329ff3691..1e4190dd0c16 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1258,14 +1258,12 @@ struct netxen_adapter { int (*init_port) (struct netxen_adapter *, int); int (*stop_port) (struct netxen_adapter *); - int (*hw_read_wx)(struct netxen_adapter *, ulong, void *, int); - int (*hw_write_wx)(struct netxen_adapter *, ulong, void *, int); + u32 (*hw_read_wx)(struct netxen_adapter *, ulong); + int (*hw_write_wx)(struct netxen_adapter *, ulong, u32); int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int); int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int); int (*pci_write_immediate)(struct netxen_adapter *, u64, u32); u32 (*pci_read_immediate)(struct netxen_adapter *, u64); - void (*pci_write_normalize)(struct netxen_adapter *, u64, u32); - u32 (*pci_read_normalize)(struct netxen_adapter *, u64); unsigned long (*pci_set_window)(struct netxen_adapter *, unsigned long long); @@ -1302,46 +1300,6 @@ struct netxen_adapter { #define netxen_get_dma_watchdog_disabled(config_word) \ (((config_word) >> 1) & 0x1) -/* Max number of xmit producer threads that can run simultaneously */ -#define MAX_XMIT_PRODUCERS 16 - -#define PCI_OFFSET_FIRST_RANGE(adapter, off) \ - ((adapter)->ahw.pci_base0 + (off)) -#define PCI_OFFSET_SECOND_RANGE(adapter, off) \ - ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START) -#define PCI_OFFSET_THIRD_RANGE(adapter, off) \ - ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START) - -static inline void __iomem *pci_base_offset(struct netxen_adapter *adapter, - unsigned long off) -{ - if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) { - return (adapter->ahw.pci_base0 + off); - } else if ((off < SECOND_PAGE_GROUP_END) && - (off >= SECOND_PAGE_GROUP_START)) { - return (adapter->ahw.pci_base1 + off - SECOND_PAGE_GROUP_START); - } else if ((off < THIRD_PAGE_GROUP_END) && - (off >= THIRD_PAGE_GROUP_START)) { - return (adapter->ahw.pci_base2 + off - THIRD_PAGE_GROUP_START); - } - return NULL; -} - -static inline void __iomem *pci_base(struct netxen_adapter *adapter, - unsigned long off) -{ - if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) { - return adapter->ahw.pci_base0; - } else if ((off < SECOND_PAGE_GROUP_END) && - (off >= SECOND_PAGE_GROUP_START)) { - return adapter->ahw.pci_base1; - } else if ((off < THIRD_PAGE_GROUP_END) && - (off >= THIRD_PAGE_GROUP_START)) { - return adapter->ahw.pci_base2; - } - return NULL; -} - int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter); int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter); int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter); @@ -1357,18 +1315,17 @@ int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu); void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val); int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off); void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value); -void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value); +u32 netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index); void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value); -void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value); +u32 netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index); int netxen_nic_get_board_info(struct netxen_adapter *adapter); void netxen_nic_get_firmware_info(struct netxen_adapter *adapter); int netxen_nic_wol_supported(struct netxen_adapter *adapter); -int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, - ulong off, void *data, int len); +u32 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off); int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, - ulong off, void *data, int len); + ulong off, u32 data); int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, u64 off, void *data, int size); int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, @@ -1384,10 +1341,9 @@ unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter, void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw); -int netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, - ulong off, void *data, int len); +u32 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off); int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, - ulong off, void *data, int len); + ulong off, u32 data); int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, u64 off, void *data, int size); int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, @@ -1514,9 +1470,8 @@ dma_watchdog_shutdown_request(struct netxen_adapter *adapter) u32 ctrl; /* check if already inactive */ - if (adapter->hw_read_wx(adapter, - NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) - printk(KERN_ERR "failed to read dma watchdog status\n"); + ctrl = adapter->hw_read_wx(adapter, + NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL)); if (netxen_get_dma_watchdog_enabled(ctrl) == 0) return 1; @@ -1534,9 +1489,8 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter) { u32 ctrl; - if (adapter->hw_read_wx(adapter, - NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) - printk(KERN_ERR "failed to read dma watchdog status\n"); + ctrl = adapter->hw_read_wx(adapter, + NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL)); return (netxen_get_dma_watchdog_enabled(ctrl) == 0); } @@ -1546,9 +1500,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter) { u32 ctrl; - if (adapter->hw_read_wx(adapter, - NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) - printk(KERN_ERR "failed to read dma watchdog status\n"); + ctrl = adapter->hw_read_wx(adapter, + NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL)); if (netxen_get_dma_watchdog_enabled(ctrl)) return 1; diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 794335188a26..7a13ee8144ee 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -41,8 +41,8 @@ netxen_api_lock(struct netxen_adapter *adapter) for (;;) { /* Acquire PCIE HW semaphore5 */ - netxen_nic_read_w0(adapter, - NETXEN_PCIE_REG(PCIE_SEM5_LOCK), &done); + done = netxen_nic_read_w0(adapter, + NETXEN_PCIE_REG(PCIE_SEM5_LOCK)); if (done == 1) break; @@ -65,11 +65,9 @@ netxen_api_lock(struct netxen_adapter *adapter) static int netxen_api_unlock(struct netxen_adapter *adapter) { - u32 val; - /* Release PCIE HW semaphore5 */ netxen_nic_read_w0(adapter, - NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK), &val); + NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK)); return 0; } @@ -86,7 +84,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, &rsp); + rsp = netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET); } while (!NX_CDRP_IS_RSP(rsp)); return rsp; @@ -125,7 +123,7 @@ 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 = netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET); printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); @@ -517,11 +515,11 @@ netxen_init_old_ctx(struct netxen_adapter *adapter) adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr); adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc); - adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id), + adapter->hw_write_wx(adapter, CRB_CTX_ADDR_REG_LO(func_id), lower32(adapter->ctx_desc_phys_addr)); - adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_HI(func_id), + adapter->hw_write_wx(adapter, CRB_CTX_ADDR_REG_HI(func_id), upper32(adapter->ctx_desc_phys_addr)); - adapter->pci_write_normalize(adapter, CRB_CTX_SIGNATURE_REG(func_id), + adapter->hw_write_wx(adapter, CRB_CTX_SIGNATURE_REG(func_id), NETXEN_CTX_SIGNATURE | func_id); return 0; } diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 5fde9e088a94..6c5a111e80bf 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -92,11 +92,11 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) strncpy(drvinfo->driver, netxen_nic_driver_name, 32); strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); write_lock_irqsave(&adapter->adapter_lock, flags); - fw_major = adapter->pci_read_normalize(adapter, + fw_major = adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR); - fw_minor = adapter->pci_read_normalize(adapter, + fw_minor = adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR); - fw_build = adapter->pci_read_normalize(adapter, + fw_build = adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB); write_unlock_irqrestore(&adapter->adapter_lock, flags); sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); @@ -135,7 +135,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { u32 val; - adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4); + val = adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR); if (val == NETXEN_PORT_MODE_802_3_AP) { ecmd->supported = SUPPORTED_1000baseT_Full; ecmd->advertising = ADVERTISED_1000baseT_Full; @@ -156,8 +156,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { u16 pcifn = adapter->ahw.pci_func; - adapter->hw_read_wx(adapter, - P3_LINK_SPEED_REG(pcifn), &val, 4); + val = adapter->hw_read_wx(adapter, + P3_LINK_SPEED_REG(pcifn)); ecmd->speed = P3_LINK_SPEED_MHZ * P3_LINK_SPEED_VAL(pcifn, val); } else @@ -423,12 +423,12 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | (adapter->pdev)->device; /* which mode */ - adapter->hw_read_wx(adapter, NETXEN_NIU_MODE, ®s_buff[0], 4); + regs_buff[0] = adapter->hw_read_wx(adapter, NETXEN_NIU_MODE); mode = regs_buff[0]; /* Common registers to all the modes */ - adapter->hw_read_wx(adapter, - NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, ®s_buff[2], 4); + regs_buff[2] = adapter->hw_read_wx(adapter, + NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER); /* GB/XGB Mode */ mode = (mode / 2) - 1; window = 0; @@ -439,9 +439,8 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) window = adapter->physical_port * NETXEN_NIC_PORT_WINDOW; - adapter->hw_read_wx(adapter, - niu_registers[mode].reg[i - 3] + window, - ®s_buff[i], 4); + regs_buff[i] = adapter->hw_read_wx(adapter, + niu_registers[mode].reg[i - 3] + window); } } @@ -465,7 +464,7 @@ static u32 netxen_nic_test_link(struct net_device *dev) return !val; } } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { - val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); + val = adapter->hw_read_wx(adapter, CRB_XG_STATE); return (val == XG_LINK_UP) ? 0 : 1; } return -EIO; @@ -529,10 +528,10 @@ netxen_nic_get_pauseparam(struct net_device *dev, if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return; /* get flow control settings */ - netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port), - &val); + val = netxen_nic_read_w0(adapter, + NETXEN_NIU_GB_MAC_CONFIG_0(port)); pause->rx_pause = netxen_gb_get_rx_flowctl(val); - netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val); + val = netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL); switch (port) { case 0: pause->tx_pause = !(netxen_gb_get_gb0_mask(val)); @@ -552,7 +551,7 @@ netxen_nic_get_pauseparam(struct net_device *dev, if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) return; pause->rx_pause = 1; - netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val); + val = netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL); if (port == 0) pause->tx_pause = !(netxen_xg_get_xg0_mask(val)); else @@ -575,8 +574,8 @@ netxen_nic_set_pauseparam(struct net_device *dev, if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EIO; /* set flow control */ - netxen_nic_read_w0(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(port), &val); + val = netxen_nic_read_w0(adapter, + NETXEN_NIU_GB_MAC_CONFIG_0(port)); if (pause->rx_pause) netxen_gb_rx_flowctl(val); @@ -586,7 +585,7 @@ netxen_nic_set_pauseparam(struct net_device *dev, netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), val); /* set autoneg */ - netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val); + val = netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL); switch (port) { case 0: if (pause->tx_pause) @@ -618,7 +617,7 @@ netxen_nic_set_pauseparam(struct net_device *dev, } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) return -EIO; - netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val); + val = netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL); if (port == 0) { if (pause->tx_pause) netxen_xg_unset_xg0_mask(val); @@ -644,14 +643,14 @@ static int netxen_nic_reg_test(struct net_device *dev) struct netxen_adapter *adapter = netdev_priv(dev); u32 data_read, data_written; - netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0), &data_read); + data_read = netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0)); if ((data_read & 0xffff) != PHAN_VENDOR_ID) return 1; data_written = (u32)0xa5a5a5a5; netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written); - data_read = adapter->pci_read_normalize(adapter, CRB_SCRATCHPAD_TEST); + data_read = adapter->hw_read_wx(adapter, CRB_SCRATCHPAD_TEST); if (data_written != data_read) return 1; diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 33444a20e4f7..87cda65ef66b 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -63,6 +63,31 @@ static inline void writeq(u64 val, void __iomem *addr) } #endif +#define ADDR_IN_RANGE(addr, low, high) \ + (((addr) < (high)) && ((addr) >= (low))) + +#define PCI_OFFSET_FIRST_RANGE(adapter, off) \ + ((adapter)->ahw.pci_base0 + (off)) +#define PCI_OFFSET_SECOND_RANGE(adapter, off) \ + ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START) +#define PCI_OFFSET_THIRD_RANGE(adapter, off) \ + ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START) + +static void __iomem *pci_base_offset(struct netxen_adapter *adapter, + unsigned long off) +{ + if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END)) + return PCI_OFFSET_FIRST_RANGE(adapter, off); + + if (ADDR_IN_RANGE(off, SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_END)) + return PCI_OFFSET_SECOND_RANGE(adapter, off); + + if (ADDR_IN_RANGE(off, THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_END)) + return PCI_OFFSET_THIRD_RANGE(adapter, off); + + return NULL; +} + #define CRB_WIN_LOCK_TIMEOUT 100000000 static crb_128M_2M_block_map_t crb_128M_2M_map[64] = { {{{0, 0, 0, 0} } }, /* 0: PCI */ @@ -294,18 +319,8 @@ static unsigned crb_hub_agt[64] = /* PCI Windowing for DDR regions. */ -#define ADDR_IN_RANGE(addr, low, high) \ - (((addr) <= (high)) && ((addr) >= (low))) - #define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ -#define NETXEN_NIC_ZERO_PAUSE_ADDR 0ULL -#define NETXEN_NIC_UNIT_PAUSE_ADDR 0x200ULL -#define NETXEN_NIC_EPG_PAUSE_ADDR1 0x2200010000c28001ULL -#define NETXEN_NIC_EPG_PAUSE_ADDR2 0x0100088866554433ULL - -#define NETXEN_NIC_WINDOW_MARGIN 0x100000 - int netxen_nic_set_mac(struct net_device *netdev, void *p) { struct netxen_adapter *adapter = netdev_priv(netdev); @@ -346,9 +361,9 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter) if (adapter->mc_enabled) return 0; - adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); + val = adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG); val |= (1UL << (28+port)); - adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); + adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, val); /* add broadcast addr to filter */ val = 0xffffff; @@ -377,9 +392,9 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter) if (!adapter->mc_enabled) return 0; - adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); + val = adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG); val &= ~(1UL << (28+port)); - adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); + adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, val); val = MAC_HI(addr); netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val); @@ -848,8 +863,8 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) crbaddr = CRB_MAC_BLOCK_START + (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1)); - adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4); - adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4); + mac_lo = adapter->hw_read_wx(adapter, crbaddr); + mac_hi = adapter->hw_read_wx(adapter, crbaddr+4); if (pci_func & 1) *mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16)); @@ -867,8 +882,8 @@ static int crb_win_lock(struct netxen_adapter *adapter) while (!done) { /* acquire semaphore3 from PCI HW block */ - adapter->hw_read_wx(adapter, - NETXEN_PCIE_REG(PCIE_SEM7_LOCK), &done, 4); + done = adapter->hw_read_wx(adapter, + NETXEN_PCIE_REG(PCIE_SEM7_LOCK)); if (done == 1) break; if (timeout >= CRB_WIN_LOCK_TIMEOUT) @@ -885,8 +900,8 @@ static void crb_win_unlock(struct netxen_adapter *adapter) { int val; - adapter->hw_read_wx(adapter, - NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK), &val, 4); + val = adapter->hw_read_wx(adapter, + NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK)); } /* @@ -1022,7 +1037,7 @@ netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname, dev_info(&pdev->dev, "loading firmware from flash\n"); if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); if (fw) { @@ -1075,12 +1090,12 @@ netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname, msleep(1); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); else { - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0); } @@ -1168,8 +1183,8 @@ request_mn: netxen_rom_fast_read(adapter, NX_FW_VERSION_OFFSET, (int *)&flashed_ver); if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { - adapter->hw_read_wx(adapter, - NX_PEG_TUNE_CAPABILITY, &capability, 4); + capability = adapter->hw_read_wx(adapter, + NX_PEG_TUNE_CAPABILITY); if (capability & NX_PEG_TUNE_MN_PRESENT) { fw_type = NX_P3_MN_ROMIMAGE; goto request_fw; @@ -1209,13 +1224,10 @@ load_fw: } int -netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, - ulong off, void *data, int len) +netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) { void __iomem *addr; - BUG_ON(len != 4); - if (ADDR_IN_WINDOW1(off)) { addr = NETXEN_CRB_NORMALIZE(adapter, off); } else { /* Window 0 */ @@ -1228,7 +1240,7 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, return 1; } - writel(*(u32 *) data, addr); + writel(data, addr); if (!ADDR_IN_WINDOW1(off)) netxen_nic_pci_change_crbwindow_128M(adapter, 1); @@ -1236,13 +1248,11 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, return 0; } -int -netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, - ulong off, void *data, int len) +u32 +netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off) { void __iomem *addr; - - BUG_ON(len != 4); + u32 data; if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ addr = NETXEN_CRB_NORMALIZE(adapter, off); @@ -1256,24 +1266,21 @@ netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, return 1; } - *(u32 *)data = readl(addr); + data = readl(addr); if (!ADDR_IN_WINDOW1(off)) netxen_nic_pci_change_crbwindow_128M(adapter, 1); - return 0; + return data; } int -netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, - ulong off, void *data, int len) +netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data) { unsigned long flags = 0; int rv; - BUG_ON(len != 4); - - rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len); + rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, 4); if (rv == -1) { printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", @@ -1286,26 +1293,24 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, write_lock_irqsave(&adapter->adapter_lock, flags); crb_win_lock(adapter); netxen_nic_pci_set_crbwindow_2M(adapter, &off); - writel(*(uint32_t *)data, (void __iomem *)off); + writel(data, (void __iomem *)off); crb_win_unlock(adapter); write_unlock_irqrestore(&adapter->adapter_lock, flags); } else - writel(*(uint32_t *)data, (void __iomem *)off); + writel(data, (void __iomem *)off); return 0; } -int -netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, - ulong off, void *data, int len) +u32 +netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off) { unsigned long flags = 0; int rv; + u32 data; - BUG_ON(len != 4); - - rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len); + rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, 4); if (rv == -1) { printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", @@ -1318,47 +1323,45 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, write_lock_irqsave(&adapter->adapter_lock, flags); crb_win_lock(adapter); netxen_nic_pci_set_crbwindow_2M(adapter, &off); - *(uint32_t *)data = readl((void __iomem *)off); + data = readl((void __iomem *)off); crb_win_unlock(adapter); write_unlock_irqrestore(&adapter->adapter_lock, flags); } else - *(uint32_t *)data = readl((void __iomem *)off); + data = readl((void __iomem *)off); - return 0; + return data; } void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) { - adapter->hw_write_wx(adapter, off, &val, 4); + adapter->hw_write_wx(adapter, off, val); } int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) { - int val; - adapter->hw_read_wx(adapter, off, &val, 4); - return val; + return adapter->hw_read_wx(adapter, off); } /* Change the window to 0, write and change back to window 1. */ void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value) { - adapter->hw_write_wx(adapter, index, &value, 4); + adapter->hw_write_wx(adapter, index, value); } /* Change the window to 0, read and change back to window 1. */ -void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value) +u32 netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index) { - adapter->hw_read_wx(adapter, index, value, 4); + return adapter->hw_read_wx(adapter, index); } void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value) { - adapter->hw_write_wx(adapter, index, &value, 4); + adapter->hw_write_wx(adapter, index, value); } -void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value) +u32 netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index) { - adapter->hw_read_wx(adapter, index, value, 4); + return adapter->hw_read_wx(adapter, index); } /* @@ -1461,17 +1464,6 @@ u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off) return readl((void __iomem *)(pci_base_offset(adapter, off))); } -void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter, - u64 off, u32 data) -{ - writel(data, NETXEN_CRB_NORMALIZE(adapter, off)); -} - -u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off) -{ - return readl(NETXEN_CRB_NORMALIZE(adapter, off)); -} - unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, unsigned long long addr) @@ -1485,10 +1477,9 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, adapter->ahw.ddr_mn_window = window; adapter->hw_write_wx(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, - &window, 4); - adapter->hw_read_wx(adapter, - adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, - &win_read, 4); + window); + win_read = adapter->hw_read_wx(adapter, + adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE); if ((win_read << 17) != window) { printk(KERN_INFO "Written MNwin (0x%x) != " "Read MNwin (0x%x)\n", window, win_read); @@ -1505,10 +1496,9 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, adapter->ahw.ddr_mn_window = window; adapter->hw_write_wx(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, - &window, 4); - adapter->hw_read_wx(adapter, - adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, - &win_read, 4); + window); + win_read = adapter->hw_read_wx(adapter, + adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE); if ((win_read >> 7) != window) { printk(KERN_INFO "%s: Written OCMwin (0x%x) != " "Read OCMwin (0x%x)\n", @@ -1523,10 +1513,9 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, adapter->ahw.qdr_sn_window = window; adapter->hw_write_wx(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE, - &window, 4); - adapter->hw_read_wx(adapter, - adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE, - &win_read, 4); + window); + win_read = adapter->hw_read_wx(adapter, + adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE); if (win_read != window) { printk(KERN_INFO "%s: Written MSwin (0x%x) != " "Read MSwin (0x%x)\n", @@ -1973,26 +1962,26 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, for (i = 0; i < loop; i++) { temp = off8 + (i << 3); adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4); + mem_crb+MIU_TEST_AGT_ADDR_LO, temp); temp = 0; adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4); + mem_crb+MIU_TEST_AGT_ADDR_HI, temp); temp = word[i] & 0xffffffff; adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4); + mem_crb+MIU_TEST_AGT_WRDATA_LO, temp); temp = (word[i] >> 32) & 0xffffffff; adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4); + mem_crb+MIU_TEST_AGT_WRDATA_HI, temp); temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_CTRL, &temp, 4); + mem_crb+MIU_TEST_AGT_CTRL, temp); temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_CTRL, &temp, 4); + mem_crb+MIU_TEST_AGT_CTRL, temp); for (j = 0; j < MAX_CTL_CHECK; j++) { - adapter->hw_read_wx(adapter, - mem_crb + MIU_TEST_AGT_CTRL, &temp, 4); + temp = adapter->hw_read_wx(adapter, + mem_crb + MIU_TEST_AGT_CTRL); if ((temp & MIU_TA_CTL_BUSY) == 0) break; } @@ -2050,20 +2039,20 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, for (i = 0; i < loop; i++) { temp = off8 + (i << 3); adapter->hw_write_wx(adapter, - mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4); + mem_crb + MIU_TEST_AGT_ADDR_LO, temp); temp = 0; adapter->hw_write_wx(adapter, - mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4); + mem_crb + MIU_TEST_AGT_ADDR_HI, temp); temp = MIU_TA_CTL_ENABLE; adapter->hw_write_wx(adapter, - mem_crb + MIU_TEST_AGT_CTRL, &temp, 4); + mem_crb + MIU_TEST_AGT_CTRL, temp); temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE; adapter->hw_write_wx(adapter, - mem_crb + MIU_TEST_AGT_CTRL, &temp, 4); + mem_crb + MIU_TEST_AGT_CTRL, temp); for (j = 0; j < MAX_CTL_CHECK; j++) { - adapter->hw_read_wx(adapter, - mem_crb + MIU_TEST_AGT_CTRL, &temp, 4); + temp = adapter->hw_read_wx(adapter, + mem_crb + MIU_TEST_AGT_CTRL); if ((temp & MIU_TA_CTL_BUSY) == 0) break; } @@ -2078,8 +2067,8 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, start = off0[i] >> 2; end = (off0[i] + sz[i] - 1) >> 2; for (k = start; k <= end; k++) { - adapter->hw_read_wx(adapter, - mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4); + temp = adapter->hw_read_wx(adapter, + mem_crb + MIU_TEST_AGT_RDDATA(k)); word[i] |= ((uint64_t)temp << (32 * k)); } } @@ -2122,29 +2111,14 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter, u64 off, u32 data) { - adapter->hw_write_wx(adapter, off, &data, 4); + adapter->hw_write_wx(adapter, off, data); return 0; } u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off) { - u32 temp; - adapter->hw_read_wx(adapter, off, &temp, 4); - return temp; -} - -void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter, - u64 off, u32 data) -{ - adapter->hw_write_wx(adapter, off, &data, 4); -} - -u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off) -{ - u32 temp; - adapter->hw_read_wx(adapter, off, &temp, 4); - return temp; + return adapter->hw_read_wx(adapter, off); } int netxen_nic_get_board_info(struct netxen_adapter *adapter) @@ -2253,7 +2227,7 @@ void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, int data) { - adapter->hw_write_wx(adapter, off, &data, 4); + adapter->hw_write_wx(adapter, off, data); } void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) @@ -2270,8 +2244,8 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) } if (adapter->ahw.port_type == NETXEN_NIC_GBE) { - adapter->hw_read_wx(adapter, - NETXEN_PORT_MODE_ADDR, &port_mode, 4); + port_mode = adapter->hw_read_wx(adapter, + NETXEN_PORT_MODE_ADDR); if (port_mode == NETXEN_PORT_MODE_802_3_AP) { adapter->link_speed = SPEED_1000; adapter->link_duplex = DUPLEX_FULL; @@ -2348,9 +2322,9 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter) addr += sizeof(u32); } - adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR, &fw_major, 4); - adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR, &fw_minor, 4); - adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4); + fw_major = adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR); + fw_minor = adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR); + fw_build = adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB); adapter->fw_major = fw_major; adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build); @@ -2373,8 +2347,7 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter) fw_major, fw_minor, fw_build); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { - adapter->hw_read_wx(adapter, - NETXEN_MIU_MN_CONTROL, &i, 4); + i = adapter->hw_read_wx(adapter, NETXEN_MIU_MN_CONTROL); adapter->ahw.cut_through = (i & 0x4) ? 1 : 0; dev_info(&pdev->dev, "firmware running in %s mode\n", adapter->ahw.cut_through ? "cut-through" : "legacy"); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 974783c45321..83116c2817b0 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -368,8 +368,8 @@ static int rom_lock(struct netxen_adapter *adapter) while (!done) { /* acquire semaphore2 from PCI HW block */ - netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK), - &done); + done = netxen_nic_read_w0(adapter, + NETXEN_PCIE_REG(PCIE_SEM2_LOCK)); if (done == 1) break; if (timeout >= rom_lock_timeout) @@ -411,10 +411,8 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter) static void netxen_rom_unlock(struct netxen_adapter *adapter) { - u32 val; - /* release semaphore2 */ - netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val); + netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK)); } @@ -623,7 +621,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) } } - adapter->hw_write_wx(adapter, off, &buf[i].data, 4); + adapter->hw_write_wx(adapter, off, buf[i].data); msleep(init_delay); } @@ -633,8 +631,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) /* unreset_net_cache */ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { - adapter->hw_read_wx(adapter, - NETXEN_ROMUSB_GLB_SW_RESET, &val, 4); + val = adapter->hw_read_wx(adapter, + NETXEN_ROMUSB_GLB_SW_RESET); netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f)); } @@ -683,12 +681,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) hi = (addr >> 32) & 0xffffffff; lo = addr & 0xffffffff; - adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi); - adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo); + adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi); + adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { uint32_t temp = 0; - adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4); + adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, temp); } return 0; @@ -730,7 +728,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) if (!pegtune_val) { do { - val = adapter->pci_read_normalize(adapter, + val = adapter->hw_read_wx(adapter, CRB_CMDPEG_STATE); if (val == PHAN_INITIALIZE_COMPLETE || @@ -742,7 +740,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) } while (--retries); if (!retries) { - pegtune_val = adapter->pci_read_normalize(adapter, + pegtune_val = adapter->hw_read_wx(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE); printk(KERN_WARNING "netxen_phantom_init: init failed, " "pegtune_val=%x\n", pegtune_val); @@ -760,7 +758,7 @@ netxen_receive_peg_ready(struct netxen_adapter *adapter) int retries = 2000; do { - val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE); + val = adapter->hw_read_wx(adapter, CRB_RCVPEG_STATE); if (val == PHAN_PEG_RCV_INITIALIZED) return 0; @@ -786,13 +784,13 @@ int netxen_init_firmware(struct netxen_adapter *adapter) if (err) return err; - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT); - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC); - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE); - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) { @@ -1059,7 +1057,7 @@ skip: if (count) { sds_ring->consumer = consumer; - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, sds_ring->crb_sts_consumer, consumer); } @@ -1178,7 +1176,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, if (count) { rds_ring->producer = producer; - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, rds_ring->crb_rcv_producer, (producer-1) & (rds_ring->num_desc-1)); @@ -1239,7 +1237,7 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, if (count) { rds_ring->producer = producer; - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, rds_ring->crb_rcv_producer, (producer - 1) & (rds_ring->num_desc - 1)); wmb(); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index cbd47ae694ba..31966a044900 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -109,7 +109,7 @@ void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring, u32 producer) { - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, tx_ring->crb_cmd_producer, producer); } @@ -122,7 +122,7 @@ static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring, u32 consumer) { - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, tx_ring->crb_cmd_consumer, consumer); } @@ -139,14 +139,14 @@ static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring) { struct netxen_adapter *adapter = sds_ring->adapter; - adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0); + adapter->hw_write_wx(adapter, sds_ring->crb_intr_mask, 0); } static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring) { struct netxen_adapter *adapter = sds_ring->adapter; - adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0x1); + adapter->hw_write_wx(adapter, sds_ring->crb_intr_mask, 0x1); if (!NETXEN_IS_MSI_FAMILY(adapter)) adapter->pci_write_immediate(adapter, @@ -309,42 +309,41 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) if (first_boot == 0x55555555) { /* This is the first boot after power up */ - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(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, - NETXEN_PCIE_REG(0x4), &first_boot, 4); + first_boot = adapter->hw_read_wx(adapter, NETXEN_PCIE_REG(0x4)); if (!(first_boot & 0x4)) { first_boot |= 0x4; adapter->hw_write_wx(adapter, - NETXEN_PCIE_REG(0x4), &first_boot, 4); - adapter->hw_read_wx(adapter, - NETXEN_PCIE_REG(0x4), &first_boot, 4); + NETXEN_PCIE_REG(0x4), first_boot); + first_boot = adapter->hw_read_wx(adapter, + NETXEN_PCIE_REG(0x4)); } /* This is the first boot after power up */ - adapter->hw_read_wx(adapter, - NETXEN_ROMUSB_GLB_SW_RESET, &first_boot, 4); + first_boot = adapter->hw_read_wx(adapter, + NETXEN_ROMUSB_GLB_SW_RESET); if (first_boot != 0x80000f) { /* clear the register for future unloads/loads */ - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, NETXEN_CAM_RAM(0x1fc), 0); return -EIO; } /* Start P2 boot loader */ - val = adapter->pci_read_normalize(adapter, + val = adapter->hw_read_wx(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE); - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1); timeout = 0; do { msleep(1); - val = adapter->pci_read_normalize(adapter, + val = adapter->hw_read_wx(adapter, NETXEN_CAM_RAM(0x1fc)); if (++timeout > 5000) @@ -365,23 +364,23 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter) if (port_mode == NETXEN_PORT_MODE_802_3_AP) { data = NETXEN_PORT_MODE_802_3_AP; adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, &data, 4); + NETXEN_PORT_MODE_ADDR, data); } else if (port_mode == NETXEN_PORT_MODE_XG) { data = NETXEN_PORT_MODE_XG; adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, &data, 4); + NETXEN_PORT_MODE_ADDR, data); } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) { data = NETXEN_PORT_MODE_AUTO_NEG_1G; adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, &data, 4); + NETXEN_PORT_MODE_ADDR, data); } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) { data = NETXEN_PORT_MODE_AUTO_NEG_XG; adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, &data, 4); + NETXEN_PORT_MODE_ADDR, data); } else { data = NETXEN_PORT_MODE_AUTO_NEG; adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, &data, 4); + NETXEN_PORT_MODE_ADDR, data); } if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) && @@ -391,7 +390,7 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter) wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG; } adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE, - &wol_port_mode, 4); + wol_port_mode); } } @@ -572,8 +571,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) adapter->hw_read_wx = netxen_nic_hw_read_wx_128M; adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M; adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M; - adapter->pci_read_normalize = netxen_nic_pci_read_normalize_128M; - adapter->pci_write_normalize = netxen_nic_pci_write_normalize_128M; adapter->pci_set_window = netxen_nic_pci_set_window_128M; adapter->pci_mem_read = netxen_nic_pci_mem_read_128M; adapter->pci_mem_write = netxen_nic_pci_mem_write_128M; @@ -595,9 +592,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter) adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M; adapter->pci_write_immediate = netxen_nic_pci_write_immediate_2M; - adapter->pci_read_normalize = netxen_nic_pci_read_normalize_2M; - adapter->pci_write_normalize = - netxen_nic_pci_write_normalize_2M; adapter->pci_set_window = netxen_nic_pci_set_window_2M; adapter->pci_mem_read = netxen_nic_pci_mem_read_2M; adapter->pci_mem_write = netxen_nic_pci_mem_write_2M; @@ -680,7 +674,7 @@ netxen_start_firmware(struct netxen_adapter *adapter) if (!first_driver) return 0; - first_boot = adapter->pci_read_normalize(adapter, + first_boot = adapter->hw_read_wx(adapter, NETXEN_CAM_RAM(0x1fc)); err = netxen_check_hw_init(adapter, first_boot); @@ -690,7 +684,7 @@ netxen_start_firmware(struct netxen_adapter *adapter) } if (first_boot != 0x55555555) { - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, CRB_CMDPEG_STATE, 0); netxen_pinit_from_rom(adapter, 0); msleep(1); @@ -723,7 +717,7 @@ netxen_start_firmware(struct netxen_adapter *adapter) val = (_NETXEN_NIC_LINUX_MAJOR << 16) | ((_NETXEN_NIC_LINUX_MINOR << 8)) | (_NETXEN_NIC_LINUX_SUBVERSION); - adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, val); + adapter->hw_write_wx(adapter, CRB_DRIVER_VERSION, val); /* Handshake with the card before we register the devices. */ err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); @@ -1038,7 +1032,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) */ adapter->physical_port = adapter->portnum; if (adapter->fw_major < 4) { - i = adapter->pci_read_normalize(adapter, + i = adapter->hw_read_wx(adapter, CRB_V2P(adapter->portnum)); if (i != 0x55555555) adapter->physical_port = i; @@ -1486,7 +1480,7 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) uint32_t temp, temp_state, temp_val; int rv = 0; - temp = adapter->pci_read_normalize(adapter, CRB_TEMP_STATE); + temp = adapter->hw_read_wx(adapter, CRB_TEMP_STATE); temp_state = nx_get_temp_state(temp); temp_val = nx_get_temp_val(temp); @@ -1557,11 +1551,11 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) port = adapter->physical_port; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { - val = adapter->pci_read_normalize(adapter, CRB_XG_STATE_P3); + val = adapter->hw_read_wx(adapter, CRB_XG_STATE_P3); val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); linkup = (val == XG_LINK_UP_P3); } else { - val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); + val = adapter->hw_read_wx(adapter, CRB_XG_STATE); if (adapter->ahw.port_type == NETXEN_NIC_GBE) linkup = (val >> port) & 1; else { @@ -1656,14 +1650,14 @@ static irqreturn_t netxen_intr(int irq, void *data) } else { unsigned long our_int = 0; - our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR); + our_int = adapter->hw_read_wx(adapter, CRB_INT_VECTOR); /* not our interrupt */ if (!test_and_clear_bit((7 + adapter->portnum), &our_int)) return IRQ_NONE; /* claim interrupt */ - adapter->pci_write_normalize(adapter, + adapter->hw_write_wx(adapter, CRB_INT_VECTOR, (our_int & 0xffffffff)); } diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 3310471ba1a0..b54a63a64e7b 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -105,9 +105,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, * so it cannot be in reset */ - if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), - &mac_cfg0, 4)) - return -EIO; + mac_cfg0 = adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0)); if (netxen_gb_get_soft_reset(mac_cfg0)) { __u32 temp; temp = 0; @@ -116,8 +114,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, netxen_gb_tx_reset_mac(temp); netxen_gb_rx_reset_mac(temp); if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(0), - &temp, 4)) + NETXEN_NIU_GB_MAC_CONFIG_0(0), temp)) return -EIO; restore = 1; } @@ -125,43 +122,38 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, address = 0; netxen_gb_mii_mgmt_reg_addr(address, reg); netxen_gb_mii_mgmt_phy_addr(address, phy); - if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), - &address, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_GB_MII_MGMT_ADDR(0), address)) return -EIO; command = 0; /* turn off any prior activity */ - if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), - &command, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command)) return -EIO; /* send read command */ netxen_gb_mii_mgmt_set_read_cycle(command); - if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), - &command, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command)) return -EIO; status = 0; do { - if (adapter->hw_read_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_INDICATE(0), - &status, 4)) - return -EIO; + status = adapter->hw_read_wx(adapter, + NETXEN_NIU_GB_MII_MGMT_INDICATE(0)); timeout++; } while ((netxen_get_gb_mii_mgmt_busy(status) || netxen_get_gb_mii_mgmt_notvalid(status)) && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); if (timeout < NETXEN_NIU_PHY_WAITMAX) { - if (adapter->hw_read_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_STATUS(0), - readval, 4)) - return -EIO; + *readval = adapter->hw_read_wx(adapter, + NETXEN_NIU_GB_MII_MGMT_STATUS(0)); result = 0; } else result = -1; if (restore) if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(0), - &mac_cfg0, 4)) + NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0)) return -EIO; phy_unlock(adapter); return result; @@ -197,9 +189,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, * cannot be in reset */ - if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), - &mac_cfg0, 4)) - return -EIO; + mac_cfg0 = adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0)); if (netxen_gb_get_soft_reset(mac_cfg0)) { __u32 temp; temp = 0; @@ -209,34 +199,31 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, netxen_gb_rx_reset_mac(temp); if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(0), - &temp, 4)) + NETXEN_NIU_GB_MAC_CONFIG_0(0), temp)) return -EIO; restore = 1; } command = 0; /* turn off any prior activity */ - if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), - &command, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command)) return -EIO; address = 0; netxen_gb_mii_mgmt_reg_addr(address, reg); netxen_gb_mii_mgmt_phy_addr(address, phy); - if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), - &address, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_GB_MII_MGMT_ADDR(0), address)) return -EIO; - if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), - &val, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_GB_MII_MGMT_CTRL(0), val)) return -EIO; status = 0; do { - if (adapter->hw_read_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_INDICATE(0), - &status, 4)) - return -EIO; + status = adapter->hw_read_wx(adapter, + NETXEN_NIU_GB_MII_MGMT_INDICATE(0)); timeout++; } while ((netxen_get_gb_mii_mgmt_busy(status)) && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); @@ -249,8 +236,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, /* restore the state of port 0 MAC in case we tampered with it */ if (restore) if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(0), - &mac_cfg0, 4)) + NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0)) return -EIO; return result; @@ -473,12 +459,10 @@ static int netxen_niu_macaddr_get(struct netxen_adapter *adapter, if ((phy < 0) || (phy > 3)) return -EINVAL; - if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), - &stationhigh, 4)) - return -EIO; - if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), - &stationlow, 4)) - return -EIO; + stationhigh = adapter->hw_read_wx(adapter, + NETXEN_NIU_GB_STATION_ADDR_0(phy)); + stationlow = adapter->hw_read_wx(adapter, + NETXEN_NIU_GB_STATION_ADDR_1(phy)); ((__le32 *)val)[1] = cpu_to_le32(stationhigh); ((__le32 *)val)[0] = cpu_to_le32(stationlow); @@ -508,13 +492,13 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, memcpy(temp + 2, addr, 2); val = le32_to_cpu(*(__le32 *)temp); if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4)) + NETXEN_NIU_GB_STATION_ADDR_1(phy), val)) return -EIO; memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); val = le32_to_cpu(*(__le32 *)temp); if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) + NETXEN_NIU_GB_STATION_ADDR_0(phy), val)) return -2; netxen_niu_macaddr_get(adapter, @@ -545,8 +529,8 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) return -EINVAL; mac_cfg0 = 0; netxen_gb_soft_reset(mac_cfg0); - if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), - &mac_cfg0, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_GB_MAC_CONFIG_0(port), mac_cfg0)) return -EIO; return 0; } @@ -565,7 +549,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) mac_cfg = 0; if (adapter->hw_write_wx(adapter, - NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4)) + NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg)) return -EIO; return 0; } @@ -581,9 +565,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, return -EINVAL; /* save previous contents */ - if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, - ®, 4)) - return -EIO; + reg = adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR); if (mode == NETXEN_NIU_PROMISC_MODE) { switch (port) { case 0: @@ -619,8 +601,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, return -EIO; } } - if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, - ®, 4)) + if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, reg)) return -EIO; return 0; } @@ -647,28 +628,28 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, case 0: memcpy(temp + 2, addr, 2); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, - &val, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_XGE_STATION_ADDR_0_1, val)) return -EIO; memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, - &val, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_XGE_STATION_ADDR_0_HI, val)) return -EIO; break; case 1: memcpy(temp + 2, addr, 2); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, - &val, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_XG1_STATION_ADDR_0_1, val)) return -EIO; memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, - &val, 4)) + if (adapter->hw_write_wx(adapter, + NETXEN_NIU_XG1_STATION_ADDR_0_HI, val)) return -EIO; break; @@ -689,9 +670,8 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, if (port > NETXEN_NIU_MAX_XG_PORTS) return -EINVAL; - if (adapter->hw_read_wx(adapter, - NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), ®, 4)) - return -EIO; + reg = adapter->hw_read_wx(adapter, + NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); if (mode == NETXEN_NIU_PROMISC_MODE) reg = (reg | 0x2000UL); else -- GitLab From f98a9f693b5f4919d9c4085a2fd8d67c7e152f3e Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:45 +0000 Subject: [PATCH 0225/6080] netxen: sanitize function names Replace superfluous wrapper functions with two macros: NXWR32 replaces netxen_nic_reg_write, netxen_nic_write_w0, netxen_nic_read_w1, netxen_crb_writelit_adapter. NXRD32 replaces netxen_nic_reg_read, netxen_nic_read_w0, netxen_nic_read_w1. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 19 +-- drivers/net/netxen/netxen_nic_ctx.c | 29 ++-- drivers/net/netxen/netxen_nic_ethtool.c | 59 ++++---- drivers/net/netxen/netxen_nic_hw.c | 187 ++++++++---------------- drivers/net/netxen/netxen_nic_init.c | 93 +++++------- drivers/net/netxen/netxen_nic_main.c | 83 ++++------- drivers/net/netxen/netxen_nic_niu.c | 169 ++++++++------------- 7 files changed, 233 insertions(+), 406 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 1e4190dd0c16..f13fd0282f55 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -1312,12 +1312,11 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, /* Functions available from netxen_nic_hw.c */ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu); int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu); -void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val); -int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off); -void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value); -u32 netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index); -void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value); -u32 netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index); + +#define NXRD32(adapter, off) \ + (adapter->hw_read_wx(adapter, off)) +#define NXWR32(adapter, off, val) \ + (adapter->hw_write_wx(adapter, off, val)) int netxen_nic_get_board_info(struct netxen_adapter *adapter); void netxen_nic_get_firmware_info(struct netxen_adapter *adapter); @@ -1348,8 +1347,6 @@ int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, u64 off, void *data, int size); int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, u64 off, void *data, int size); -void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, - unsigned long off, int data); int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter, u64 off, u32 data); u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off); @@ -1478,8 +1475,7 @@ dma_watchdog_shutdown_request(struct netxen_adapter *adapter) /* Send the disable request */ netxen_set_dma_watchdog_disable_req(ctrl); - netxen_crb_writelit_adapter(adapter, - NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl); + NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl); return 0; } @@ -1509,8 +1505,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter) /* send the wakeup request */ netxen_set_dma_watchdog_enable_req(ctrl); - netxen_crb_writelit_adapter(adapter, - NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl); + NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl); return 0; } diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 7a13ee8144ee..32f48398398b 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -41,8 +41,7 @@ netxen_api_lock(struct netxen_adapter *adapter) for (;;) { /* Acquire PCIE HW semaphore5 */ - done = netxen_nic_read_w0(adapter, - NETXEN_PCIE_REG(PCIE_SEM5_LOCK)); + done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK)); if (done == 1) break; @@ -56,7 +55,7 @@ netxen_api_lock(struct netxen_adapter *adapter) } #if 0 - netxen_nic_write_w1(adapter, + NXWR32(adapter, NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER); #endif return 0; @@ -66,8 +65,7 @@ static int netxen_api_unlock(struct netxen_adapter *adapter) { /* Release PCIE HW semaphore5 */ - netxen_nic_read_w0(adapter, - NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK)); + NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK)); return 0; } @@ -84,7 +82,7 @@ netxen_poll_rsp(struct netxen_adapter *adapter) if (++timeout > NX_OS_CRB_RETRY_COUNT) return NX_CDRP_RSP_TIMEOUT; - rsp = netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET); + rsp = NXRD32(adapter, NX_CDRP_CRB_OFFSET); } while (!NX_CDRP_IS_RSP(rsp)); return rsp; @@ -104,16 +102,15 @@ 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, signature); + NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature); - netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1); + NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1); - netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2); + NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2); - netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3); + NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3); - netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET, - NX_CDRP_FORM_CMD(cmd)); + NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd)); rsp = netxen_poll_rsp(adapter); @@ -123,7 +120,7 @@ netxen_issue_cmd(struct netxen_adapter *adapter, rcode = NX_RCODE_TIMEOUT; } else if (rsp == NX_CDRP_RSP_FAIL) { - rcode = netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET); + rcode = NXRD32(adapter, NX_ARG1_CRB_OFFSET); printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); @@ -515,11 +512,11 @@ netxen_init_old_ctx(struct netxen_adapter *adapter) adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr); adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc); - adapter->hw_write_wx(adapter, CRB_CTX_ADDR_REG_LO(func_id), + NXWR32(adapter, CRB_CTX_ADDR_REG_LO(func_id), lower32(adapter->ctx_desc_phys_addr)); - adapter->hw_write_wx(adapter, CRB_CTX_ADDR_REG_HI(func_id), + NXWR32(adapter, CRB_CTX_ADDR_REG_HI(func_id), upper32(adapter->ctx_desc_phys_addr)); - adapter->hw_write_wx(adapter, CRB_CTX_SIGNATURE_REG(func_id), + NXWR32(adapter, CRB_CTX_SIGNATURE_REG(func_id), NETXEN_CTX_SIGNATURE | func_id); return 0; } diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 6c5a111e80bf..a452b2facb77 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -92,12 +92,9 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) strncpy(drvinfo->driver, netxen_nic_driver_name, 32); strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); write_lock_irqsave(&adapter->adapter_lock, flags); - fw_major = adapter->hw_read_wx(adapter, - NETXEN_FW_VERSION_MAJOR); - fw_minor = adapter->hw_read_wx(adapter, - NETXEN_FW_VERSION_MINOR); - fw_build = adapter->hw_read_wx(adapter, - NETXEN_FW_VERSION_SUB); + fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); + fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); + fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); write_unlock_irqrestore(&adapter->adapter_lock, flags); sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); @@ -135,7 +132,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { u32 val; - val = adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR); + val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR); if (val == NETXEN_PORT_MODE_802_3_AP) { ecmd->supported = SUPPORTED_1000baseT_Full; ecmd->advertising = ADVERTISED_1000baseT_Full; @@ -156,8 +153,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { u16 pcifn = adapter->ahw.pci_func; - val = adapter->hw_read_wx(adapter, - P3_LINK_SPEED_REG(pcifn)); + val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn)); ecmd->speed = P3_LINK_SPEED_MHZ * P3_LINK_SPEED_VAL(pcifn, val); } else @@ -423,12 +419,11 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | (adapter->pdev)->device; /* which mode */ - regs_buff[0] = adapter->hw_read_wx(adapter, NETXEN_NIU_MODE); + regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE); mode = regs_buff[0]; /* Common registers to all the modes */ - regs_buff[2] = adapter->hw_read_wx(adapter, - NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER); + regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER); /* GB/XGB Mode */ mode = (mode / 2) - 1; window = 0; @@ -439,7 +434,7 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) window = adapter->physical_port * NETXEN_NIC_PORT_WINDOW; - regs_buff[i] = adapter->hw_read_wx(adapter, + regs_buff[i] = NXRD32(adapter, niu_registers[mode].reg[i - 3] + window); } @@ -464,7 +459,7 @@ static u32 netxen_nic_test_link(struct net_device *dev) return !val; } } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { - val = adapter->hw_read_wx(adapter, CRB_XG_STATE); + val = NXRD32(adapter, CRB_XG_STATE); return (val == XG_LINK_UP) ? 0 : 1; } return -EIO; @@ -528,10 +523,9 @@ netxen_nic_get_pauseparam(struct net_device *dev, if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return; /* get flow control settings */ - val = netxen_nic_read_w0(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(port)); + val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port)); pause->rx_pause = netxen_gb_get_rx_flowctl(val); - val = netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL); + val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL); switch (port) { case 0: pause->tx_pause = !(netxen_gb_get_gb0_mask(val)); @@ -551,7 +545,7 @@ netxen_nic_get_pauseparam(struct net_device *dev, if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) return; pause->rx_pause = 1; - val = netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL); + val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL); if (port == 0) pause->tx_pause = !(netxen_xg_get_xg0_mask(val)); else @@ -574,18 +568,17 @@ netxen_nic_set_pauseparam(struct net_device *dev, if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EIO; /* set flow control */ - val = netxen_nic_read_w0(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(port)); + val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port)); if (pause->rx_pause) netxen_gb_rx_flowctl(val); else netxen_gb_unset_rx_flowctl(val); - netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), val); /* set autoneg */ - val = netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL); + val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL); switch (port) { case 0: if (pause->tx_pause) @@ -613,11 +606,11 @@ netxen_nic_set_pauseparam(struct net_device *dev, netxen_gb_set_gb3_mask(val); break; } - netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val); + NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val); } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS)) return -EIO; - val = netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL); + val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL); if (port == 0) { if (pause->tx_pause) netxen_xg_unset_xg0_mask(val); @@ -629,7 +622,7 @@ netxen_nic_set_pauseparam(struct net_device *dev, else netxen_xg_set_xg1_mask(val); } - netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val); + NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val); } else { printk(KERN_ERR "%s: Unknown board type: %x\n", netxen_nic_driver_name, @@ -643,14 +636,14 @@ static int netxen_nic_reg_test(struct net_device *dev) struct netxen_adapter *adapter = netdev_priv(dev); u32 data_read, data_written; - data_read = netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0)); + data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0)); if ((data_read & 0xffff) != PHAN_VENDOR_ID) return 1; data_written = (u32)0xa5a5a5a5; - netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written); - data_read = adapter->hw_read_wx(adapter, CRB_SCRATCHPAD_TEST); + NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written); + data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST); if (data_written != data_read) return 1; @@ -767,11 +760,11 @@ netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) return; - wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV); + wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV); if (wol_cfg & (1UL << adapter->portnum)) wol->supported |= WAKE_MAGIC; - wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG); + wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG); if (wol_cfg & (1UL << adapter->portnum)) wol->wolopts |= WAKE_MAGIC; } @@ -788,16 +781,16 @@ netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (wol->wolopts & ~WAKE_MAGIC) return -EOPNOTSUPP; - wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV); + wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV); if (!(wol_cfg & (1 << adapter->portnum))) return -EOPNOTSUPP; - wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG); + wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG); if (wol->wolopts & WAKE_MAGIC) wol_cfg |= 1UL << adapter->portnum; else wol_cfg &= ~(1UL << adapter->portnum); - netxen_nic_reg_write(adapter, NETXEN_WOL_CONFIG, wol_cfg); + NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg); return 0; } diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 87cda65ef66b..9439f89869de 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -361,22 +361,20 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter) if (adapter->mc_enabled) return 0; - val = adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG); + val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG); val |= (1UL << (28+port)); - adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, val); + NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val); /* add broadcast addr to filter */ val = 0xffffff; - netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val); - netxen_crb_writelit_adapter(adapter, - NETXEN_UNICAST_ADDR(port, 0)+4, val); + NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val); + NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val); /* add station addr to filter */ val = MAC_HI(addr); - netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), val); + NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), val); val = MAC_LO(addr); - netxen_crb_writelit_adapter(adapter, - NETXEN_UNICAST_ADDR(port, 1)+4, val); + NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, val); adapter->mc_enabled = 1; return 0; @@ -392,18 +390,17 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter) if (!adapter->mc_enabled) return 0; - val = adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG); + val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG); val &= ~(1UL << (28+port)); - adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, val); + NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val); val = MAC_HI(addr); - netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val); + NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val); val = MAC_LO(addr); - netxen_crb_writelit_adapter(adapter, - NETXEN_UNICAST_ADDR(port, 0)+4, val); + NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val); - netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), 0); - netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0); + NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), 0); + NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0); adapter->mc_enabled = 0; return 0; @@ -419,10 +416,8 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter, lo = MAC_LO(addr); hi = MAC_HI(addr); - netxen_crb_writelit_adapter(adapter, - NETXEN_MCAST_ADDR(port, index), hi); - netxen_crb_writelit_adapter(adapter, - NETXEN_MCAST_ADDR(port, index)+4, lo); + NXWR32(adapter, NETXEN_MCAST_ADDR(port, index), hi); + NXWR32(adapter, NETXEN_MCAST_ADDR(port, index)+4, lo); return 0; } @@ -863,8 +858,8 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) crbaddr = CRB_MAC_BLOCK_START + (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1)); - mac_lo = adapter->hw_read_wx(adapter, crbaddr); - mac_hi = adapter->hw_read_wx(adapter, crbaddr+4); + mac_lo = NXRD32(adapter, crbaddr); + mac_hi = NXRD32(adapter, crbaddr+4); if (pci_func & 1) *mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16)); @@ -882,8 +877,7 @@ static int crb_win_lock(struct netxen_adapter *adapter) while (!done) { /* acquire semaphore3 from PCI HW block */ - done = adapter->hw_read_wx(adapter, - NETXEN_PCIE_REG(PCIE_SEM7_LOCK)); + done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK)); if (done == 1) break; if (timeout >= CRB_WIN_LOCK_TIMEOUT) @@ -891,8 +885,7 @@ static int crb_win_lock(struct netxen_adapter *adapter) timeout++; udelay(1); } - netxen_crb_writelit_adapter(adapter, - NETXEN_CRB_WIN_LOCK_ID, adapter->portnum); + NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum); return 0; } @@ -900,8 +893,7 @@ static void crb_win_unlock(struct netxen_adapter *adapter) { int val; - val = adapter->hw_read_wx(adapter, - NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK)); + val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK)); } /* @@ -1037,8 +1029,7 @@ netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname, dev_info(&pdev->dev, "loading firmware from flash\n"); if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) - adapter->hw_write_wx(adapter, - NETXEN_ROMUSB_GLB_CAS_RST, 1); + NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); if (fw) { __le64 data; @@ -1090,13 +1081,10 @@ netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname, msleep(1); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - adapter->hw_write_wx(adapter, - NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); + NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); else { - adapter->hw_write_wx(adapter, - NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); - adapter->hw_write_wx(adapter, - NETXEN_ROMUSB_GLB_CAS_RST, 0); + NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); + NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0); } return 0; @@ -1154,8 +1142,7 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname, if (NETXEN_VERSION_CODE(major, minor, build) > ver) return -EINVAL; - netxen_nic_reg_write(adapter, NETXEN_CAM_RAM(0x1fc), - NETXEN_BDINFO_MAGIC); + NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); return 0; } @@ -1183,8 +1170,7 @@ request_mn: netxen_rom_fast_read(adapter, NX_FW_VERSION_OFFSET, (int *)&flashed_ver); if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { - capability = adapter->hw_read_wx(adapter, - NX_PEG_TUNE_CAPABILITY); + capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); if (capability & NX_PEG_TUNE_MN_PRESENT) { fw_type = NX_P3_MN_ROMIMAGE; goto request_fw; @@ -1332,38 +1318,6 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off) return data; } -void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) -{ - adapter->hw_write_wx(adapter, off, val); -} - -int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) -{ - return adapter->hw_read_wx(adapter, off); -} - -/* Change the window to 0, write and change back to window 1. */ -void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value) -{ - adapter->hw_write_wx(adapter, index, value); -} - -/* Change the window to 0, read and change back to window 1. */ -u32 netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index) -{ - return adapter->hw_read_wx(adapter, index); -} - -void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value) -{ - adapter->hw_write_wx(adapter, index, value); -} - -u32 netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index) -{ - return adapter->hw_read_wx(adapter, index); -} - /* * check memory access boundary. * used by test agent. support ddr access only for now @@ -1475,10 +1429,9 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, /* DDR network side */ window = MN_WIN(addr); adapter->ahw.ddr_mn_window = window; - adapter->hw_write_wx(adapter, - adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, + NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, window); - win_read = adapter->hw_read_wx(adapter, + win_read = NXRD32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE); if ((win_read << 17) != window) { printk(KERN_INFO "Written MNwin (0x%x) != " @@ -1494,10 +1447,9 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, window = OCM_WIN(addr); adapter->ahw.ddr_mn_window = window; - adapter->hw_write_wx(adapter, - adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, + NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE, window); - win_read = adapter->hw_read_wx(adapter, + win_read = NXRD32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE); if ((win_read >> 7) != window) { printk(KERN_INFO "%s: Written OCMwin (0x%x) != " @@ -1511,10 +1463,9 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, /* QDR network side */ window = MS_WIN(addr); adapter->ahw.qdr_sn_window = window; - adapter->hw_write_wx(adapter, - adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE, + NXWR32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE, window); - win_read = adapter->hw_read_wx(adapter, + win_read = NXRD32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE); if (win_read != window) { printk(KERN_INFO "%s: Written MSwin (0x%x) != " @@ -1961,27 +1912,20 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, for (i = 0; i < loop; i++) { temp = off8 + (i << 3); - adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_ADDR_LO, temp); + NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_LO, temp); temp = 0; - adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_ADDR_HI, temp); + NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_HI, temp); temp = word[i] & 0xffffffff; - adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_WRDATA_LO, temp); + NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp); temp = (word[i] >> 32) & 0xffffffff; - adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_WRDATA_HI, temp); + NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp); temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; - adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_CTRL, temp); + NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp); temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE; - adapter->hw_write_wx(adapter, - mem_crb+MIU_TEST_AGT_CTRL, temp); + NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp); for (j = 0; j < MAX_CTL_CHECK; j++) { - temp = adapter->hw_read_wx(adapter, - mem_crb + MIU_TEST_AGT_CTRL); + temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL); if ((temp & MIU_TA_CTL_BUSY) == 0) break; } @@ -2038,21 +1982,16 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, for (i = 0; i < loop; i++) { temp = off8 + (i << 3); - adapter->hw_write_wx(adapter, - mem_crb + MIU_TEST_AGT_ADDR_LO, temp); + NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_LO, temp); temp = 0; - adapter->hw_write_wx(adapter, - mem_crb + MIU_TEST_AGT_ADDR_HI, temp); + NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_HI, temp); temp = MIU_TA_CTL_ENABLE; - adapter->hw_write_wx(adapter, - mem_crb + MIU_TEST_AGT_CTRL, temp); + NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp); temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE; - adapter->hw_write_wx(adapter, - mem_crb + MIU_TEST_AGT_CTRL, temp); + NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp); for (j = 0; j < MAX_CTL_CHECK; j++) { - temp = adapter->hw_read_wx(adapter, - mem_crb + MIU_TEST_AGT_CTRL); + temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL); if ((temp & MIU_TA_CTL_BUSY) == 0) break; } @@ -2067,7 +2006,7 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, start = off0[i] >> 2; end = (off0[i] + sz[i] - 1) >> 2; for (k = start; k <= end; k++) { - temp = adapter->hw_read_wx(adapter, + temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_RDDATA(k)); word[i] |= ((uint64_t)temp << (32 * k)); } @@ -2111,14 +2050,14 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter, u64 off, u32 data) { - adapter->hw_write_wx(adapter, off, data); + NXWR32(adapter, off, data); return 0; } u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off) { - return adapter->hw_read_wx(adapter, off); + return NXRD32(adapter, off); } int netxen_nic_get_board_info(struct netxen_adapter *adapter) @@ -2152,8 +2091,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) adapter->ahw.board_type = board_type; if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) { - u32 gpio = netxen_nic_reg_read(adapter, - NETXEN_ROMUSB_GLB_PAD_GPIO_I); + u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I); if ((gpio & 0x8000) == 0) board_type = NETXEN_BRDTYPE_P3_10G_TP; } @@ -2205,8 +2143,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) { new_mtu += MTU_FUDGE_FACTOR; - netxen_nic_write_w0(adapter, - NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port), + NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port), new_mtu); return 0; } @@ -2215,21 +2152,12 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) { new_mtu += MTU_FUDGE_FACTOR; if (adapter->physical_port == 0) - netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, - new_mtu); + NXWR32(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu); else - netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, - new_mtu); + NXWR32(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu); return 0; } -void -netxen_crb_writelit_adapter(struct netxen_adapter *adapter, - unsigned long off, int data) -{ - adapter->hw_write_wx(adapter, off, data); -} - void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) { __u32 status; @@ -2244,8 +2172,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter) } if (adapter->ahw.port_type == NETXEN_NIC_GBE) { - port_mode = adapter->hw_read_wx(adapter, - NETXEN_PORT_MODE_ADDR); + port_mode = NXRD32(adapter, NETXEN_PORT_MODE_ADDR); if (port_mode == NETXEN_PORT_MODE_802_3_AP) { adapter->link_speed = SPEED_1000; adapter->link_duplex = DUPLEX_FULL; @@ -2322,9 +2249,9 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter) addr += sizeof(u32); } - fw_major = adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR); - fw_minor = adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR); - fw_build = adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB); + fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR); + fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR); + fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB); adapter->fw_major = fw_major; adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build); @@ -2347,7 +2274,7 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter) fw_major, fw_minor, fw_build); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { - i = adapter->hw_read_wx(adapter, NETXEN_MIU_MN_CONTROL); + i = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); adapter->ahw.cut_through = (i & 0x4) ? 1 : 0; dev_info(&pdev->dev, "firmware running in %s mode\n", adapter->ahw.cut_through ? "cut-through" : "legacy"); @@ -2362,9 +2289,9 @@ netxen_nic_wol_supported(struct netxen_adapter *adapter) if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) return 0; - wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV); + wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV); if (wol_cfg & (1UL << adapter->portnum)) { - wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG); + wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG); if (wol_cfg & (1 << adapter->portnum)) return 1; } diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 83116c2817b0..0c91238133f0 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -368,8 +368,7 @@ static int rom_lock(struct netxen_adapter *adapter) while (!done) { /* acquire semaphore2 from PCI HW block */ - done = netxen_nic_read_w0(adapter, - NETXEN_PCIE_REG(PCIE_SEM2_LOCK)); + done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK)); if (done == 1) break; if (timeout >= rom_lock_timeout) @@ -386,7 +385,7 @@ static int rom_lock(struct netxen_adapter *adapter) cpu_relax(); /*This a nop instr on i386 */ } } - netxen_nic_reg_write(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER); + NXWR32(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER); return 0; } @@ -398,7 +397,7 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter) cond_resched(); while (done == 0) { - done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS); + done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS); done &= 2; timeout++; if (timeout >= rom_max_timeout) { @@ -412,27 +411,27 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter) static void netxen_rom_unlock(struct netxen_adapter *adapter) { /* release semaphore2 */ - netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK)); + NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK)); } static int do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) { - netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); - 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); + NXWR32(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); + NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); + NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); + NXWR32(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); if (netxen_wait_rom_done(adapter)) { printk("Error waiting for rom done\n"); return -EIO; } /* reset abyte_cnt and dummy_byte_cnt */ - netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); + NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); udelay(10); - netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); + NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); - *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA); + *valp = NXRD32(adapter, NETXEN_ROMUSB_ROM_RDATA); return 0; } @@ -496,8 +495,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) /* resetall */ rom_lock(adapter); - netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, - 0xffffffff); + NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); netxen_rom_unlock(adapter); if (verbose) { @@ -621,7 +619,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) } } - adapter->hw_write_wx(adapter, off, buf[i].data); + NXWR32(adapter, off, buf[i].data); msleep(init_delay); } @@ -631,33 +629,31 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) /* unreset_net_cache */ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { - val = adapter->hw_read_wx(adapter, - NETXEN_ROMUSB_GLB_SW_RESET); - netxen_crb_writelit_adapter(adapter, - NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f)); + val = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET); + NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f)); } /* p2dn replyCount */ - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e); + NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e); /* disable_peg_cache 0 */ - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8); + NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8); /* disable_peg_cache 1 */ - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8); + NXWR32(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8); /* peg_clr_all */ /* peg_clr 0 */ - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0); - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0); + NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0); + NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0); /* peg_clr 1 */ - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0); - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0); + NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0); + NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0); /* peg_clr 2 */ - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0); - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0); + NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0); + NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0); /* peg_clr 3 */ - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0); - netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0); + NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0); + NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0); return 0; } @@ -681,12 +677,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) hi = (addr >> 32) & 0xffffffff; lo = addr & 0xffffffff; - adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi); - adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo); + NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi); + NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { uint32_t temp = 0; - adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, temp); + NXWR32(adapter, CRB_HOST_DUMMY_BUF, temp); } return 0; @@ -728,8 +724,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) if (!pegtune_val) { do { - val = adapter->hw_read_wx(adapter, - CRB_CMDPEG_STATE); + val = NXRD32(adapter, CRB_CMDPEG_STATE); if (val == PHAN_INITIALIZE_COMPLETE || val == PHAN_INITIALIZE_ACK) @@ -740,7 +735,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) } while (--retries); if (!retries) { - pegtune_val = adapter->hw_read_wx(adapter, + pegtune_val = NXRD32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE); printk(KERN_WARNING "netxen_phantom_init: init failed, " "pegtune_val=%x\n", pegtune_val); @@ -758,7 +753,7 @@ netxen_receive_peg_ready(struct netxen_adapter *adapter) int retries = 2000; do { - val = adapter->hw_read_wx(adapter, CRB_RCVPEG_STATE); + val = NXRD32(adapter, CRB_RCVPEG_STATE); if (val == PHAN_PEG_RCV_INITIALIZED) return 0; @@ -784,18 +779,13 @@ int netxen_init_firmware(struct netxen_adapter *adapter) if (err) return err; - adapter->hw_write_wx(adapter, - CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT); - adapter->hw_write_wx(adapter, - CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC); - adapter->hw_write_wx(adapter, - CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE); - adapter->hw_write_wx(adapter, - CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); + NXWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT); + NXWR32(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC); + NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE); + NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) { - adapter->capabilities = netxen_nic_reg_read(adapter, - CRB_FW_CAPABILITIES_1); + adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1); } return err; @@ -1057,8 +1047,7 @@ skip: if (count) { sds_ring->consumer = consumer; - adapter->hw_write_wx(adapter, - sds_ring->crb_sts_consumer, consumer); + NXWR32(adapter, sds_ring->crb_sts_consumer, consumer); } return count; @@ -1176,8 +1165,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, if (count) { rds_ring->producer = producer; - adapter->hw_write_wx(adapter, - rds_ring->crb_rcv_producer, + NXWR32(adapter, rds_ring->crb_rcv_producer, (producer-1) & (rds_ring->num_desc-1)); if (adapter->fw_major < 4) { @@ -1237,8 +1225,7 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, if (count) { rds_ring->producer = producer; - adapter->hw_write_wx(adapter, - rds_ring->crb_rcv_producer, + NXWR32(adapter, rds_ring->crb_rcv_producer, (producer - 1) & (rds_ring->num_desc - 1)); wmb(); } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 31966a044900..8426092deda3 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -109,8 +109,7 @@ void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring, u32 producer) { - adapter->hw_write_wx(adapter, - tx_ring->crb_cmd_producer, producer); + NXWR32(adapter, tx_ring->crb_cmd_producer, producer); } static uint32_t crb_cmd_consumer[4] = { @@ -122,8 +121,7 @@ static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring, u32 consumer) { - adapter->hw_write_wx(adapter, - tx_ring->crb_cmd_consumer, consumer); + NXWR32(adapter, tx_ring->crb_cmd_consumer, consumer); } static uint32_t msi_tgt_status[8] = { @@ -139,14 +137,14 @@ static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring) { struct netxen_adapter *adapter = sds_ring->adapter; - adapter->hw_write_wx(adapter, sds_ring->crb_intr_mask, 0); + NXWR32(adapter, sds_ring->crb_intr_mask, 0); } static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring) { struct netxen_adapter *adapter = sds_ring->adapter; - adapter->hw_write_wx(adapter, sds_ring->crb_intr_mask, 0x1); + NXWR32(adapter, sds_ring->crb_intr_mask, 0x1); if (!NETXEN_IS_MSI_FAMILY(adapter)) adapter->pci_write_immediate(adapter, @@ -262,7 +260,7 @@ nx_update_dma_mask(struct netxen_adapter *adapter) change = 0; - shift = netxen_nic_reg_read(adapter, CRB_DMA_SHIFT); + shift = NXRD32(adapter, CRB_DMA_SHIFT); if (shift >= 32) return 0; @@ -309,42 +307,34 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) if (first_boot == 0x55555555) { /* This is the first boot after power up */ - adapter->hw_write_wx(adapter, - NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); + NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) return 0; /* PCI bus master workaround */ - first_boot = adapter->hw_read_wx(adapter, NETXEN_PCIE_REG(0x4)); + first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4)); if (!(first_boot & 0x4)) { first_boot |= 0x4; - adapter->hw_write_wx(adapter, - NETXEN_PCIE_REG(0x4), first_boot); - first_boot = adapter->hw_read_wx(adapter, - NETXEN_PCIE_REG(0x4)); + NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot); + first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4)); } /* This is the first boot after power up */ - first_boot = adapter->hw_read_wx(adapter, - NETXEN_ROMUSB_GLB_SW_RESET); + first_boot = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET); if (first_boot != 0x80000f) { /* clear the register for future unloads/loads */ - adapter->hw_write_wx(adapter, - NETXEN_CAM_RAM(0x1fc), 0); + NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), 0); return -EIO; } /* Start P2 boot loader */ - val = adapter->hw_read_wx(adapter, - NETXEN_ROMUSB_GLB_PEGTUNE_DONE); - adapter->hw_write_wx(adapter, - NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1); + val = NXRD32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE); + NXWR32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1); timeout = 0; do { msleep(1); - val = adapter->hw_read_wx(adapter, - NETXEN_CAM_RAM(0x1fc)); + val = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc)); if (++timeout > 5000) return -EIO; @@ -363,24 +353,19 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter) (val == NETXEN_BRDTYPE_P3_XG_LOM)) { if (port_mode == NETXEN_PORT_MODE_802_3_AP) { data = NETXEN_PORT_MODE_802_3_AP; - adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, data); + NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data); } else if (port_mode == NETXEN_PORT_MODE_XG) { data = NETXEN_PORT_MODE_XG; - adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, data); + NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data); } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) { data = NETXEN_PORT_MODE_AUTO_NEG_1G; - adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, data); + NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data); } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) { data = NETXEN_PORT_MODE_AUTO_NEG_XG; - adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, data); + NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data); } else { data = NETXEN_PORT_MODE_AUTO_NEG; - adapter->hw_write_wx(adapter, - NETXEN_PORT_MODE_ADDR, data); + NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data); } if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) && @@ -389,8 +374,7 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter) (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) { wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG; } - adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE, - wol_port_mode); + NXWR32(adapter, NETXEN_WOL_PORT_MODE, wol_port_mode); } } @@ -674,8 +658,7 @@ netxen_start_firmware(struct netxen_adapter *adapter) if (!first_driver) return 0; - first_boot = adapter->hw_read_wx(adapter, - NETXEN_CAM_RAM(0x1fc)); + first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc)); err = netxen_check_hw_init(adapter, first_boot); if (err) { @@ -684,13 +667,12 @@ netxen_start_firmware(struct netxen_adapter *adapter) } if (first_boot != 0x55555555) { - adapter->hw_write_wx(adapter, - CRB_CMDPEG_STATE, 0); + NXWR32(adapter, CRB_CMDPEG_STATE, 0); netxen_pinit_from_rom(adapter, 0); msleep(1); } - netxen_nic_reg_write(adapter, CRB_DMA_SHIFT, 0x55555555); + NXWR32(adapter, CRB_DMA_SHIFT, 0x55555555); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) netxen_set_port_mode(adapter); @@ -702,8 +684,7 @@ netxen_start_firmware(struct netxen_adapter *adapter) val = 0x7654; if (adapter->ahw.port_type == NETXEN_NIC_XGBE) val |= 0x0f000000; - netxen_crb_writelit_adapter(adapter, - NETXEN_MAC_ADDR_CNTL_REG, val); + NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val); } @@ -717,7 +698,7 @@ netxen_start_firmware(struct netxen_adapter *adapter) val = (_NETXEN_NIC_LINUX_MAJOR << 16) | ((_NETXEN_NIC_LINUX_MINOR << 8)) | (_NETXEN_NIC_LINUX_SUBVERSION); - adapter->hw_write_wx(adapter, CRB_DRIVER_VERSION, val); + NXWR32(adapter, CRB_DRIVER_VERSION, val); /* Handshake with the card before we register the devices. */ err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); @@ -1032,8 +1013,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) */ adapter->physical_port = adapter->portnum; if (adapter->fw_major < 4) { - i = adapter->hw_read_wx(adapter, - CRB_V2P(adapter->portnum)); + i = NXRD32(adapter, CRB_V2P(adapter->portnum)); if (i != 0x55555555) adapter->physical_port = i; } @@ -1480,7 +1460,7 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) uint32_t temp, temp_state, temp_val; int rv = 0; - temp = adapter->hw_read_wx(adapter, CRB_TEMP_STATE); + temp = NXRD32(adapter, CRB_TEMP_STATE); temp_state = nx_get_temp_state(temp); temp_val = nx_get_temp_val(temp); @@ -1551,11 +1531,11 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) port = adapter->physical_port; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { - val = adapter->hw_read_wx(adapter, CRB_XG_STATE_P3); + val = NXRD32(adapter, CRB_XG_STATE_P3); val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); linkup = (val == XG_LINK_UP_P3); } else { - val = adapter->hw_read_wx(adapter, CRB_XG_STATE); + val = NXRD32(adapter, CRB_XG_STATE); if (adapter->ahw.port_type == NETXEN_NIC_GBE) linkup = (val >> port) & 1; else { @@ -1650,15 +1630,14 @@ static irqreturn_t netxen_intr(int irq, void *data) } else { unsigned long our_int = 0; - our_int = adapter->hw_read_wx(adapter, CRB_INT_VECTOR); + our_int = NXRD32(adapter, CRB_INT_VECTOR); /* not our interrupt */ if (!test_and_clear_bit((7 + adapter->portnum), &our_int)) return IRQ_NONE; /* claim interrupt */ - adapter->hw_write_wx(adapter, - CRB_INT_VECTOR, (our_int & 0xffffffff)); + NXWR32(adapter, CRB_INT_VECTOR, (our_int & 0xffffffff)); } /* clear interrupt */ diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index b54a63a64e7b..5e2698bf575a 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -43,8 +43,7 @@ static int phy_lock(struct netxen_adapter *adapter) int done = 0, timeout = 0; while (!done) { - done = netxen_nic_reg_read(adapter, - NETXEN_PCIE_REG(PCIE_SEM3_LOCK)); + done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK)); if (done == 1) break; if (timeout >= phy_lock_timeout) { @@ -59,8 +58,7 @@ static int phy_lock(struct netxen_adapter *adapter) } } - netxen_crb_writelit_adapter(adapter, - NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER); + NXWR32(adapter, NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER); return 0; } @@ -105,7 +103,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, * so it cannot be in reset */ - mac_cfg0 = adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0)); + mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0)); if (netxen_gb_get_soft_reset(mac_cfg0)) { __u32 temp; temp = 0; @@ -113,8 +111,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, netxen_gb_rx_reset_pb(temp); netxen_gb_tx_reset_mac(temp); netxen_gb_rx_reset_mac(temp); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(0), temp)) + if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp)) return -EIO; restore = 1; } @@ -122,38 +119,32 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, address = 0; netxen_gb_mii_mgmt_reg_addr(address, reg); netxen_gb_mii_mgmt_phy_addr(address, phy); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR(0), address)) + if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address)) return -EIO; command = 0; /* turn off any prior activity */ - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command)) + if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command)) return -EIO; /* send read command */ netxen_gb_mii_mgmt_set_read_cycle(command); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command)) + if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command)) return -EIO; status = 0; do { - status = adapter->hw_read_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_INDICATE(0)); + status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0)); timeout++; } while ((netxen_get_gb_mii_mgmt_busy(status) || netxen_get_gb_mii_mgmt_notvalid(status)) && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); if (timeout < NETXEN_NIU_PHY_WAITMAX) { - *readval = adapter->hw_read_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_STATUS(0)); + *readval = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0)); result = 0; } else result = -1; if (restore) - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0)) + if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0)) return -EIO; phy_unlock(adapter); return result; @@ -189,7 +180,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, * cannot be in reset */ - mac_cfg0 = adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0)); + mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0)); if (netxen_gb_get_soft_reset(mac_cfg0)) { __u32 temp; temp = 0; @@ -198,32 +189,27 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, netxen_gb_tx_reset_mac(temp); netxen_gb_rx_reset_mac(temp); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(0), temp)) + if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp)) return -EIO; restore = 1; } command = 0; /* turn off any prior activity */ - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command)) + if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command)) return -EIO; address = 0; netxen_gb_mii_mgmt_reg_addr(address, reg); netxen_gb_mii_mgmt_phy_addr(address, phy); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_ADDR(0), address)) + if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address)) return -EIO; - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_CTRL(0), val)) + if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), val)) return -EIO; status = 0; do { - status = adapter->hw_read_wx(adapter, - NETXEN_NIU_GB_MII_MGMT_INDICATE(0)); + status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0)); timeout++; } while ((netxen_get_gb_mii_mgmt_busy(status)) && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); @@ -235,8 +221,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, /* restore the state of port 0 MAC in case we tampered with it */ if (restore) - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0)) + if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0)) return -EIO; return result; @@ -244,7 +229,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter) { - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f); + NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x3f); return 0; } @@ -267,7 +252,7 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter) int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter) { - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f); + NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x7f); return 0; } @@ -301,30 +286,21 @@ static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter) static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, int port, long enable) { - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2); - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), - 0x80000000); - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), - 0x0000f0025); - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), - 0xf1ff); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB0_MII_MODE + (port << 3), 1); - netxen_crb_writelit_adapter(adapter, - (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); + NXWR32(adapter, NETXEN_NIU_MODE, 0x2); + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000); + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025); + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf1ff); + NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0); + NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 1); + NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0); + NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); if (enable) { /* * Do NOT enable flow control until a suitable solution for * shutting down pause frames is found. */ - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(port), - 0x5); + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5); } if (netxen_niu_gbe_enable_phy_interrupts(adapter)) @@ -339,30 +315,21 @@ static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int port, long enable) { - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2); - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), - 0x80000000); - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), - 0x0000f0025); - netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), - 0xf2ff); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB0_MII_MODE + (port << 3), 0); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1); - netxen_crb_writelit_adapter(adapter, - (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); + NXWR32(adapter, NETXEN_NIU_MODE, 0x2); + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000); + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025); + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf2ff); + NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 0); + NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1); + NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0); + NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); if (enable) { /* * Do NOT enable flow control until a suitable solution for * shutting down pause frames is found. */ - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(port), - 0x5); + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5); } if (netxen_niu_gbe_enable_phy_interrupts(adapter)) @@ -402,17 +369,12 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) * plugged in. */ - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0 - (port), + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), NETXEN_GB_MAC_SOFT_RESET); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0 - (port), - NETXEN_GB_MAC_RESET_PROT_BLK - | NETXEN_GB_MAC_ENABLE_TX_RX - | - NETXEN_GB_MAC_PAUSED_FRMS); + NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), + NETXEN_GB_MAC_RESET_PROT_BLK | + NETXEN_GB_MAC_ENABLE_TX_RX | + NETXEN_GB_MAC_PAUSED_FRMS); if (netxen_niu_gbe_clear_phy_interrupts(adapter)) printk(KERN_ERR "ERROR clearing PHY interrupts\n"); @@ -433,10 +395,8 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) { if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5); + NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447); + NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5); } return 0; @@ -459,10 +419,8 @@ static int netxen_niu_macaddr_get(struct netxen_adapter *adapter, if ((phy < 0) || (phy > 3)) return -EINVAL; - stationhigh = adapter->hw_read_wx(adapter, - NETXEN_NIU_GB_STATION_ADDR_0(phy)); - stationlow = adapter->hw_read_wx(adapter, - NETXEN_NIU_GB_STATION_ADDR_1(phy)); + stationhigh = NXRD32(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy)); + stationlow = NXRD32(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy)); ((__le32 *)val)[1] = cpu_to_le32(stationhigh); ((__le32 *)val)[0] = cpu_to_le32(stationlow); @@ -491,14 +449,12 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, temp[0] = temp[1] = 0; memcpy(temp + 2, addr, 2); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_STATION_ADDR_1(phy), val)) + if (NXWR32(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), val)) return -EIO; memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_STATION_ADDR_0(phy), val)) + if (NXWR32(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), val)) return -2; netxen_niu_macaddr_get(adapter, @@ -529,8 +485,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) return -EINVAL; mac_cfg0 = 0; netxen_gb_soft_reset(mac_cfg0); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_GB_MAC_CONFIG_0(port), mac_cfg0)) + if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), mac_cfg0)) return -EIO; return 0; } @@ -548,8 +503,8 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) return -EINVAL; mac_cfg = 0; - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg)) + if (NXWR32(adapter, + NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg)) return -EIO; return 0; } @@ -565,7 +520,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, return -EINVAL; /* save previous contents */ - reg = adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR); + reg = NXRD32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR); if (mode == NETXEN_NIU_PROMISC_MODE) { switch (port) { case 0: @@ -601,7 +556,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, return -EIO; } } - if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, reg)) + if (NXWR32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, reg)) return -EIO; return 0; } @@ -628,28 +583,24 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, case 0: memcpy(temp + 2, addr, 2); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_XGE_STATION_ADDR_0_1, val)) + if (NXWR32(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, val)) return -EIO; memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_XGE_STATION_ADDR_0_HI, val)) + if (NXWR32(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, val)) return -EIO; break; case 1: memcpy(temp + 2, addr, 2); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_XG1_STATION_ADDR_0_1, val)) + if (NXWR32(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, val)) return -EIO; memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); val = le32_to_cpu(*(__le32 *)temp); - if (adapter->hw_write_wx(adapter, - NETXEN_NIU_XG1_STATION_ADDR_0_HI, val)) + if (NXWR32(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, val)) return -EIO; break; @@ -670,8 +621,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, if (port > NETXEN_NIU_MAX_XG_PORTS) return -EINVAL; - reg = adapter->hw_read_wx(adapter, - NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); + reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); if (mode == NETXEN_NIU_PROMISC_MODE) reg = (reg | 0x2000UL); else @@ -682,8 +632,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, else reg = (reg & ~0x1000UL); - netxen_crb_writelit_adapter(adapter, - NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); + NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); return 0; } -- GitLab From f6d21f44122630cc9549b8ffbab23ea8c68254e0 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:46 +0000 Subject: [PATCH 0226/6080] netxen: enable rss for NX2031 Enable multiple rx rings for older NX2031 chip, firmware 3.4.336 or newer supports this feature. Signed-off-by: Amit Kumar Salecha Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 27 +++-- drivers/net/netxen/netxen_nic_ctx.c | 127 +++++++++++++++++------ drivers/net/netxen/netxen_nic_main.c | 21 +++- drivers/net/netxen/netxen_nic_phan_reg.h | 5 +- 4 files changed, 137 insertions(+), 43 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index f13fd0282f55..ebd6c2edc343 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -195,6 +195,8 @@ #define MAX_JUMBO_RCV_DESCRIPTORS 1024 #define MAX_LRO_RCV_DESCRIPTORS 8 #define NETXEN_CTX_SIGNATURE 0xdee0 +#define NETXEN_CTX_SIGNATURE_V2 0x0002dee0 +#define NETXEN_CTX_RESET 0xbad0 #define NETXEN_RCV_PRODUCER(ringid) (ringid) #define PHAN_PEG_RCV_INITIALIZED 0xff01 @@ -234,12 +236,19 @@ typedef u32 netxen_ctx_msg; #define netxen_set_msg_opcode(config_word, val) \ ((config_word) &= ~(0xf<<28), (config_word) |= (val & 0xf) << 28) -struct netxen_rcv_context { - __le64 rcv_ring_addr; - __le32 rcv_ring_size; +struct netxen_rcv_ring { + __le64 addr; + __le32 size; __le32 rsrvd; }; +struct netxen_sts_ring { + __le64 addr; + __le32 size; + __le16 msi_index; + __le16 rsvd; +} ; + struct netxen_ring_ctx { /* one command ring */ @@ -249,13 +258,18 @@ struct netxen_ring_ctx { __le32 rsrvd; /* three receive rings */ - struct netxen_rcv_context rcv_ctx[3]; + struct netxen_rcv_ring rcv_rings[NUM_RCV_DESC_RINGS]; - /* one status ring */ __le64 sts_ring_addr; __le32 sts_ring_size; __le32 ctx_id; + + __le64 rsrvd_2[3]; + __le32 sts_ring_count; + __le32 rsrvd_3; + struct netxen_sts_ring sts_rings[NUM_STS_DESC_RINGS]; + } __attribute__ ((aligned(64))); /* @@ -1219,7 +1233,8 @@ struct netxen_adapter { u8 mc_enabled; u8 max_mc_count; - u16 resv2; + u8 rss_supported; + u8 resv2; u32 resv3; u8 has_link_events; diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 32f48398398b..fd82adf4f876 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -441,7 +441,19 @@ static struct netxen_recv_crb recv_crb_registers[] = { NETXEN_NIC_REG(0x120) }, /* crb_sts_consumer: */ - NETXEN_NIC_REG(0x138), + { + NETXEN_NIC_REG(0x138), + NETXEN_NIC_REG_2(0x000), + NETXEN_NIC_REG_2(0x004), + NETXEN_NIC_REG_2(0x008), + }, + /* sw_int_mask */ + { + CRB_SW_INT_MASK_0, + NETXEN_NIC_REG_2(0x044), + NETXEN_NIC_REG_2(0x048), + NETXEN_NIC_REG_2(0x04c), + }, }, /* Instance 1 */ { @@ -454,7 +466,19 @@ static struct netxen_recv_crb recv_crb_registers[] = { NETXEN_NIC_REG(0x164) }, /* crb_sts_consumer: */ - NETXEN_NIC_REG(0x17c), + { + NETXEN_NIC_REG(0x17c), + NETXEN_NIC_REG_2(0x020), + NETXEN_NIC_REG_2(0x024), + NETXEN_NIC_REG_2(0x028), + }, + /* sw_int_mask */ + { + CRB_SW_INT_MASK_1, + NETXEN_NIC_REG_2(0x064), + NETXEN_NIC_REG_2(0x068), + NETXEN_NIC_REG_2(0x06c), + }, }, /* Instance 2 */ { @@ -467,7 +491,19 @@ static struct netxen_recv_crb recv_crb_registers[] = { NETXEN_NIC_REG(0x208) }, /* crb_sts_consumer: */ - NETXEN_NIC_REG(0x220), + { + NETXEN_NIC_REG(0x220), + NETXEN_NIC_REG_2(0x03c), + NETXEN_NIC_REG_2(0x03c), + NETXEN_NIC_REG_2(0x03c), + }, + /* sw_int_mask */ + { + CRB_SW_INT_MASK_2, + NETXEN_NIC_REG_2(0x03c), + NETXEN_NIC_REG_2(0x03c), + NETXEN_NIC_REG_2(0x03c), + }, }, /* Instance 3 */ { @@ -480,7 +516,19 @@ static struct netxen_recv_crb recv_crb_registers[] = { NETXEN_NIC_REG(0x24c) }, /* crb_sts_consumer: */ - NETXEN_NIC_REG(0x264), + { + NETXEN_NIC_REG(0x264), + NETXEN_NIC_REG_2(0x03c), + NETXEN_NIC_REG_2(0x03c), + NETXEN_NIC_REG_2(0x03c), + }, + /* sw_int_mask */ + { + CRB_SW_INT_MASK_3, + NETXEN_NIC_REG_2(0x03c), + NETXEN_NIC_REG_2(0x03c), + NETXEN_NIC_REG_2(0x03c), + }, }, }; @@ -492,40 +540,50 @@ netxen_init_old_ctx(struct netxen_adapter *adapter) struct nx_host_sds_ring *sds_ring; struct nx_host_tx_ring *tx_ring; int ring; - int func_id = adapter->portnum; + int port = adapter->portnum; + struct netxen_ring_ctx *hwctx = adapter->ctx_desc; + u32 signature; tx_ring = &adapter->tx_ring; - adapter->ctx_desc->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr); - adapter->ctx_desc->cmd_ring_size = cpu_to_le32(tx_ring->num_desc); + hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr); + hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc); recv_ctx = &adapter->recv_ctx; for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; - adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr = + hwctx->rcv_rings[ring].addr = cpu_to_le64(rds_ring->phys_addr); - adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size = + hwctx->rcv_rings[ring].size = cpu_to_le32(rds_ring->num_desc); } - sds_ring = &recv_ctx->sds_rings[0]; - adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr); - adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc); - NXWR32(adapter, CRB_CTX_ADDR_REG_LO(func_id), + for (ring = 0; ring < adapter->max_sds_rings; ring++) { + sds_ring = &recv_ctx->sds_rings[ring]; + + if (ring == 0) { + hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr); + hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc); + } + hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr); + hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc); + hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring); + } + hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings); + + signature = (adapter->max_sds_rings > 1) ? + NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE; + + NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port), lower32(adapter->ctx_desc_phys_addr)); - NXWR32(adapter, CRB_CTX_ADDR_REG_HI(func_id), + NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port), upper32(adapter->ctx_desc_phys_addr)); - NXWR32(adapter, CRB_CTX_SIGNATURE_REG(func_id), - NETXEN_CTX_SIGNATURE | func_id); + NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), + signature | port); return 0; } -static uint32_t sw_int_mask[4] = { - CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1, - CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3 -}; - int netxen_alloc_hw_resources(struct netxen_adapter *adapter) { void *addr; @@ -538,6 +596,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; + int port = adapter->portnum; addr = pci_alloc_consistent(pdev, sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), @@ -549,7 +608,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) } memset(addr, 0, sizeof(struct netxen_ring_ctx)); adapter->ctx_desc = (struct netxen_ring_ctx *)addr; - adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum); + adapter->ctx_desc->ctx_id = cpu_to_le32(port); adapter->ctx_desc->cmd_consumer_offset = cpu_to_le64(adapter->ctx_desc_phys_addr + sizeof(struct netxen_ring_ctx)); @@ -586,8 +645,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) if (adapter->fw_major < 4) rds_ring->crb_rcv_producer = - recv_crb_registers[adapter->portnum]. - crb_rcv_producer[ring]; + recv_crb_registers[port].crb_rcv_producer[ring]; } for (ring = 0; ring < adapter->max_sds_rings; ring++) { @@ -604,6 +662,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) goto err_out_free; } sds_ring->desc_head = (struct status_desc *)addr; + + sds_ring->crb_sts_consumer = + recv_crb_registers[port].crb_sts_consumer[ring]; + + sds_ring->crb_intr_mask = + recv_crb_registers[port].sw_int_mask[ring]; } @@ -615,19 +679,11 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) if (err) goto err_out_free; } else { - sds_ring = &recv_ctx->sds_rings[0]; - sds_ring->crb_sts_consumer = - recv_crb_registers[adapter->portnum].crb_sts_consumer; - - recv_ctx->sds_rings[0].crb_intr_mask = - sw_int_mask[adapter->portnum]; - err = netxen_init_old_ctx(adapter); if (err) { netxen_free_hw_resources(adapter); return err; } - } return 0; @@ -645,9 +701,16 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) struct nx_host_tx_ring *tx_ring; int ring; + int port = adapter->portnum; + if (adapter->fw_major >= 4) { nx_fw_cmd_destroy_tx_ctx(adapter); nx_fw_cmd_destroy_rx_ctx(adapter); + } else { + netxen_api_lock(adapter); + NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), + NETXEN_CTX_RESET | port); + netxen_api_unlock(adapter); } if (adapter->ctx_desc != NULL) { diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 8426092deda3..da9b90da5207 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -175,7 +175,8 @@ netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev) struct nx_host_sds_ring *sds_ring; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; - if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) + if ((adapter->flags & NETXEN_NIC_MSIX_ENABLED) && + adapter->rss_supported) adapter->max_sds_rings = (num_online_cpus() >= 4) ? 4 : 2; else adapter->max_sds_rings = 1; @@ -288,10 +289,22 @@ static void netxen_check_options(struct netxen_adapter *adapter) else if (adapter->ahw.port_type == NETXEN_NIC_GBE) adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G; - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + adapter->msix_supported = 0; + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { adapter->msix_supported = !!use_msi_x; - else - adapter->msix_supported = 0; + adapter->rss_supported = !!use_msi_x; + } else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) { + switch (adapter->ahw.board_type) { + case NETXEN_BRDTYPE_P2_SB31_10G: + case NETXEN_BRDTYPE_P2_SB31_10G_CX4: + case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: + adapter->msix_supported = !!use_msi_x; + adapter->rss_supported = !!use_msi_x; + break; + default: + break; + } + } adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST; adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS; diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index ecd622ead0e9..845dcf436cf6 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -36,6 +36,8 @@ */ #define NIC_CRB_BASE NETXEN_CAM_RAM(0x200) #define NETXEN_NIC_REG(X) (NIC_CRB_BASE+(X)) +#define NIC_CRB_BASE_2 NETXEN_CAM_RAM(0x700) +#define NETXEN_NIC_REG_2(X) (NIC_CRB_BASE_2+(X)) #define CRB_PHAN_CNTRL_LO_OFFSET NETXEN_NIC_REG(0x00) #define CRB_PHAN_CNTRL_HI_OFFSET NETXEN_NIC_REG(0x04) @@ -160,7 +162,8 @@ struct netxen_recv_crb { u32 crb_rcv_producer[NUM_RCV_DESC_RINGS]; - u32 crb_sts_consumer; + u32 crb_sts_consumer[NUM_STS_DESC_RINGS]; + u32 sw_int_mask[NUM_STS_DESC_RINGS]; }; /* -- GitLab From a92e9e65f0068a291a677c627a747fae1f230284 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Tue, 7 Apr 2009 22:50:47 +0000 Subject: [PATCH 0227/6080] netxen: enable GRO support Signed-off-by: Amit Kumar Salecha Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_init.c | 7 ++++--- drivers/net/netxen/netxen_nic_main.c | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 0c91238133f0..8893a973399a 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -923,7 +923,8 @@ no_skb: static struct netxen_rx_buffer * netxen_process_rcv(struct netxen_adapter *adapter, - int ring, int index, int length, int cksum, int pkt_offset) + int ring, int index, int length, int cksum, int pkt_offset, + struct nx_host_sds_ring *sds_ring) { struct net_device *netdev = adapter->netdev; struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; @@ -951,7 +952,7 @@ netxen_process_rcv(struct netxen_adapter *adapter, skb->protocol = eth_type_trans(skb, netdev); - netif_receive_skb(skb); + napi_gro_receive(&sds_ring->napi, skb); adapter->stats.no_rcv++; adapter->stats.rxbytes += length; @@ -1011,7 +1012,7 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max) pkt_offset = netxen_get_sts_pkt_offset(sts_data); rxbuf = netxen_process_rcv(adapter, ring, index, - length, cksum, pkt_offset); + length, cksum, pkt_offset, sds_ring); if (rxbuf) list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index da9b90da5207..e877eefdfeb0 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -981,6 +981,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops); netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); + netdev->features |= (NETIF_F_GRO); netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); if (NX_IS_REVISION_P3(revision_id)) { -- GitLab From ea7eaa39ffadffaa8f1dd1a1f85fa38bf8ae9d39 Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 7 Apr 2009 22:50:48 +0000 Subject: [PATCH 0228/6080] netxen: cache align register map table Aligning register offset translation table imporves performance on rx side. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_hw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 9439f89869de..3bb2b8c74d92 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -89,7 +89,8 @@ static void __iomem *pci_base_offset(struct netxen_adapter *adapter, } #define CRB_WIN_LOCK_TIMEOUT 100000000 -static crb_128M_2M_block_map_t crb_128M_2M_map[64] = { +static crb_128M_2M_block_map_t +crb_128M_2M_map[64] __cacheline_aligned_in_smp = { {{{0, 0, 0, 0} } }, /* 0: PCI */ {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */ {1, 0x0110000, 0x0120000, 0x130000}, -- GitLab From 8509500ac4c82c1e31515ffda6028f88693f49fd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 8 Apr 2009 15:59:53 -0700 Subject: [PATCH 0229/6080] sfc: Don't specify unexistent IRQ Neither the lm90 driver nor the lm87 driver do support interrupts, so there is no point in specifying one when declaring the devices. Signed-off-by: Jean Delvare Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/boards.c | 2 -- drivers/net/sfc/sfe4001.c | 3 --- 2 files changed, 5 deletions(-) diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c index 5182ac5a1034..4a4c74c891b7 100644 --- a/drivers/net/sfc/boards.c +++ b/drivers/net/sfc/boards.c @@ -172,7 +172,6 @@ static const u8 sfe4002_lm87_regs[] = { static struct i2c_board_info sfe4002_hwmon_info = { I2C_BOARD_INFO("lm87", 0x2e), .platform_data = &sfe4002_lm87_channel, - .irq = -1, }; /****************************************************************************/ @@ -247,7 +246,6 @@ static const u8 sfn4112f_lm87_regs[] = { static struct i2c_board_info sfn4112f_hwmon_info = { I2C_BOARD_INFO("lm87", 0x2e), .platform_data = &sfn4112f_lm87_channel, - .irq = -1, }; #define SFN4112F_ACT_LED 0 diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index 4eac5da81e5a..cee00ad49b57 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c @@ -296,7 +296,6 @@ static int sfe4001_check_hw(struct efx_nic *efx) static struct i2c_board_info sfe4001_hwmon_info = { I2C_BOARD_INFO("max6647", 0x4e), - .irq = -1, }; /* This board uses an I2C expander to provider power to the PHY, which needs to @@ -389,12 +388,10 @@ static void sfn4111t_fini(struct efx_nic *efx) static struct i2c_board_info sfn4111t_a0_hwmon_info = { I2C_BOARD_INFO("max6647", 0x4e), - .irq = -1, }; static struct i2c_board_info sfn4111t_r5_hwmon_info = { I2C_BOARD_INFO("max6646", 0x4d), - .irq = -1, }; int sfn4111t_init(struct efx_nic *efx) -- GitLab From a0c31fdfb7f158780faa43ab83cc08b414bebd7e Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Wed, 8 Apr 2009 16:01:16 -0700 Subject: [PATCH 0230/6080] ISDN: update Documentation/isdn/00-INDEX After the merging of mISDN, state which files refer only to the old isdn4linux subsystem. Also add a few missing files and sort alphabetically. Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller --- Documentation/isdn/00-INDEX | 45 +++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/Documentation/isdn/00-INDEX b/Documentation/isdn/00-INDEX index 9fee5f2e5c62..33543ac7d81f 100644 --- a/Documentation/isdn/00-INDEX +++ b/Documentation/isdn/00-INDEX @@ -2,28 +2,20 @@ - this file (info on ISDN implementation for Linux) CREDITS - list of the kind folks that brought you this stuff. +HiSax.cert + - information about the ITU approval certification of the HiSax driver. INTERFACE - - description of Linklevel and Hardwarelevel ISDN interface. + - description of isdn4linux Link Level and Hardware Level interfaces. +INTERFACE.fax + - description of the fax subinterface of isdn4linux. README - general info on what you need and what to do for Linux ISDN. README.FAQ - general info for FAQ. -README.audio - - info for running audio over ISDN. -README.fax - - info for using Fax over ISDN. -README.icn - - info on the ICN-ISDN-card and its driver. README.HiSax - info on the HiSax driver which replaces the old teles. -README.hfc-pci - - info on hfc-pci based cards. -README.pcbit - - info on the PCBIT-D ISDN adapter and driver. -README.syncppp - - info on running Sync PPP over ISDN. -syncPPP.FAQ - - frequently asked questions about running PPP over ISDN. +README.audio + - info for running audio over ISDN. README.avmb1 - info on driver for AVM-B1 ISDN card. README.act2000 @@ -34,10 +26,25 @@ README.concap - info on "CONCAP" encapsulation protocol interface used for X.25. README.diversion - info on module for isdn diversion services. +README.fax + - info for using Fax over ISDN. +README.gigaset + - info on the drivers for Siemens Gigaset ISDN adapters +README.hfc-pci + - info on hfc-pci based cards. +README.hysdn + - info on driver for Hypercope active HYSDN cards +README.icn + - info on the ICN-ISDN-card and its driver. +README.mISDN + - info on the Modular ISDN subsystem (mISDN) +README.pcbit + - info on the PCBIT-D ISDN adapter and driver. README.sc - info on driver for Spellcaster cards. +README.syncppp + - info on running Sync PPP over ISDN. README.x25 - _ info for running X.25 over ISDN. -README.hysdn - - info on driver for Hypercope active HYSDN cards - + - info on running X.25 over ISDN. +syncPPP.FAQ + - frequently asked questions about running PPP over ISDN. -- GitLab From 6c0b324435ff49fb3c68fe808a93853d81c7fb97 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 9 Apr 2009 09:27:37 +1000 Subject: [PATCH 0231/6080] perf_counter: add MAINTAINERS entry This adds an entry in MAINTAINERS for the perf_counter subsystem. Signed-off-by: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <18909.13033.345975.434902@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index c3b215970f7b..16fb45adb53e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3483,6 +3483,16 @@ M: balbir@linux.vnet.ibm.com L: linux-kernel@vger.kernel.org S: Maintained +PERFORMANCE COUNTER SUBSYSTEM +P: Peter Zijlstra +M: a.p.zijlstra@chello.nl +P: Paul Mackerras +M: paulus@samba.org +P: Ingo Molnar +M: mingo@elte.hu +L: linux-kernel@vger.kernel.org +S: Supported + PERSONALITY HANDLING P: Christoph Hellwig M: hch@infradead.org -- GitLab From ca8f2d7f019a8547f39ddb9ed0144932f12807f2 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 9 Apr 2009 14:42:56 +1000 Subject: [PATCH 0232/6080] perf_counter: powerpc: add nmi_enter/nmi_exit calls Impact: fix potential deadlocks on powerpc Now that the core is using in_nmi() (added in e30e08f6, "perf_counter: fix NMI race in task clock"), we need the powerpc perf_counter_interrupt to call nmi_enter() and nmi_exit() in those cases where the interrupt happens when interrupts are soft-disabled. If interrupts were soft-enabled, we can treat it as a regular interrupt and do irq_enter/irq_exit around the whole routine. This lets us get rid of the test_perf_counter_pending() call at the end of perf_counter_interrupt, thus simplifying things a little. Signed-off-by: Paul Mackerras Cc: Peter Zijlstra LKML-Reference: <18909.31952.873098.336615@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 31 ++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index c9d019f19074..bd76d0fa2c35 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -714,7 +714,7 @@ hw_perf_counter_init(struct perf_counter *counter) * here so there is no possibility of being interrupted. */ static void record_and_restart(struct perf_counter *counter, long val, - struct pt_regs *regs) + struct pt_regs *regs, int nmi) { s64 prev, delta, left; int record = 0; @@ -749,7 +749,7 @@ static void record_and_restart(struct perf_counter *counter, long val, * Finally record data if requested. */ if (record) - perf_counter_overflow(counter, 1, regs, 0); + perf_counter_overflow(counter, nmi, regs, 0); } /* @@ -762,6 +762,17 @@ static void perf_counter_interrupt(struct pt_regs *regs) struct perf_counter *counter; long val; int found = 0; + int nmi; + + /* + * If interrupts were soft-disabled when this PMU interrupt + * occurred, treat it as an NMI. + */ + nmi = !regs->softe; + if (nmi) + nmi_enter(); + else + irq_enter(); for (i = 0; i < cpuhw->n_counters; ++i) { counter = cpuhw->counter[i]; @@ -769,7 +780,7 @@ static void perf_counter_interrupt(struct pt_regs *regs) if ((int)val < 0) { /* counter has overflowed */ found = 1; - record_and_restart(counter, val, regs); + record_and_restart(counter, val, regs, nmi); } } @@ -796,18 +807,10 @@ static void perf_counter_interrupt(struct pt_regs *regs) */ mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); - /* - * If we need a wakeup, check whether interrupts were soft-enabled - * when we took the interrupt. If they were, we can wake stuff up - * immediately; otherwise we'll have do the wakeup when interrupts - * get soft-enabled. - */ - if (test_perf_counter_pending() && regs->softe) { - irq_enter(); - clear_perf_counter_pending(); - perf_counter_do_pending(); + if (nmi) + nmi_exit(); + else irq_exit(); - } } void hw_perf_counter_setup(int cpu) -- GitLab From 888fcee066a2f4abd0d0bc9418c0535f9b01e6e5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 9 Apr 2009 09:48:22 +0200 Subject: [PATCH 0233/6080] perf_counter: fix off task->comm by one strlen() does not include the \0. Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 321c57e3556f..b07195bbd228 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1989,7 +1989,7 @@ static void perf_counter_comm_event(struct perf_comm_event *comm_event) unsigned int size; char *comm = comm_event->task->comm; - size = ALIGN(strlen(comm), sizeof(u64)); + size = ALIGN(strlen(comm)+1, sizeof(u64)); comm_event->comm = comm; comm_event->comm_size = size; @@ -2109,7 +2109,7 @@ static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event) } got_name: - size = ALIGN(strlen(name), sizeof(u64)); + size = ALIGN(strlen(name)+1, sizeof(u64)); mmap_event->file_name = name; mmap_event->file_size = size; -- GitLab From b3828ebb3901adfe989d8d4157ed28247aeec132 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 9 Apr 2009 09:50:04 +0200 Subject: [PATCH 0234/6080] perf_counter tools: include PID in perf-report output, tweak user/kernel printut It's handier than an entry. Also replace the kernel/user column with a more compact version: 0.52 cc1 [k] page_fault 0.57 :0 [k] _spin_lock 0.59 :7506 [.] 0.69 as [.] /usr/bin/as: 0.76 cc1 [.] /lib64/libc-2.8.so: _int_free 0.92 cc1 [k] clear_page_c 1.00 :7465 [.] 1.43 cc1 [.] /lib64/libc-2.8.so: memset 1.86 cc1 [.] /lib64/libc-2.8.so: _int_malloc 70.33 cc1 [.] /usr/libexec/gcc/x86_64-redhat-linux/4.3.2/cc1: Signed-off-by: Ingo Molnar --- Documentation/perf_counter/perf-report.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Documentation/perf_counter/perf-report.cc b/Documentation/perf_counter/perf-report.cc index 09da0ba482cd..1727317352bf 100644 --- a/Documentation/perf_counter/perf-report.cc +++ b/Documentation/perf_counter/perf-report.cc @@ -277,10 +277,17 @@ static std::multimap rev_hist; static std::string resolve_comm(int pid) { - std::string comm = ""; + std::string comm; + std::map::const_iterator ci = comms.find(pid); - if (ci != comms.end()) + if (ci != comms.end()) { comm = ci->second; + } else { + char pid_str[30]; + + sprintf(pid_str, ":%d", pid); + comm = pid_str; + } return comm; } @@ -422,13 +429,13 @@ more: char output[1024]; if (event->header.misc & PERF_EVENT_MISC_KERNEL) { - level = "[kernel]"; + level = " [k] "; sym = resolve_kernel_symbol(event->ip.ip); } else if (event->header.misc & PERF_EVENT_MISC_USER) { - level = "[ user ]"; + level = " [.] "; sym = resolve_user_symbol(event->ip.pid, event->ip.ip); } else { - level = "[ hv ]"; + level = " [H] "; } comm = resolve_comm(event->ip.pid); -- GitLab From 9ee318a7825929bc3734110b83ae8e20e53d9de3 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 9 Apr 2009 10:53:44 +0200 Subject: [PATCH 0235/6080] perf_counter: optimize mmap/comm tracking Impact: performance optimization The mmap/comm tracking code does quite a lot of work before it discovers there's no interest in it, avoid that by keeping a counter. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090409085524.427173196@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index b07195bbd228..76376ecb23b5 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -38,6 +38,10 @@ int perf_max_counters __read_mostly = 1; static int perf_reserved_percpu __read_mostly; static int perf_overcommit __read_mostly = 1; +static atomic_t nr_mmap_tracking __read_mostly; +static atomic_t nr_munmap_tracking __read_mostly; +static atomic_t nr_comm_tracking __read_mostly; + /* * Mutex for (sysadmin-configurable) counter reservations: */ @@ -1186,6 +1190,13 @@ static void free_counter(struct perf_counter *counter) { perf_pending_sync(counter); + if (counter->hw_event.mmap) + atomic_dec(&nr_mmap_tracking); + if (counter->hw_event.munmap) + atomic_dec(&nr_munmap_tracking); + if (counter->hw_event.comm) + atomic_dec(&nr_comm_tracking); + if (counter->destroy) counter->destroy(counter); @@ -2005,7 +2016,12 @@ static void perf_counter_comm_event(struct perf_comm_event *comm_event) void perf_counter_comm(struct task_struct *task) { - struct perf_comm_event comm_event = { + struct perf_comm_event comm_event; + + if (!atomic_read(&nr_comm_tracking)) + return; + + comm_event = (struct perf_comm_event){ .task = task, .event = { .header = { .type = PERF_EVENT_COMM, }, @@ -2128,7 +2144,12 @@ got_name: void perf_counter_mmap(unsigned long addr, unsigned long len, unsigned long pgoff, struct file *file) { - struct perf_mmap_event mmap_event = { + struct perf_mmap_event mmap_event; + + if (!atomic_read(&nr_mmap_tracking)) + return; + + mmap_event = (struct perf_mmap_event){ .file = file, .event = { .header = { .type = PERF_EVENT_MMAP, }, @@ -2146,7 +2167,12 @@ void perf_counter_mmap(unsigned long addr, unsigned long len, void perf_counter_munmap(unsigned long addr, unsigned long len, unsigned long pgoff, struct file *file) { - struct perf_mmap_event mmap_event = { + struct perf_mmap_event mmap_event; + + if (!atomic_read(&nr_munmap_tracking)) + return; + + mmap_event = (struct perf_mmap_event){ .file = file, .event = { .header = { .type = PERF_EVENT_MUNMAP, }, @@ -2725,6 +2751,13 @@ done: counter->hw_ops = hw_ops; + if (counter->hw_event.mmap) + atomic_inc(&nr_mmap_tracking); + if (counter->hw_event.munmap) + atomic_inc(&nr_munmap_tracking); + if (counter->hw_event.comm) + atomic_inc(&nr_comm_tracking); + return counter; } -- GitLab From 1ccd15497869f3ed83b5225d410df53a96e52757 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 9 Apr 2009 10:53:45 +0200 Subject: [PATCH 0236/6080] perf_counter: sysctl for system wide perf counters Impact: add sysctl for paranoid/relaxed perfcounters policy Allow the use of system wide perf counters to everybody, but provide a sysctl to disable it for the paranoid security minded. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090409085524.514046352@chello.nl> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 2 ++ kernel/perf_counter.c | 4 +++- kernel/sysctl.c | 11 +++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index c22363a4f746..981432885301 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -568,6 +568,8 @@ struct perf_callchain_entry { extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs); +extern int sysctl_perf_counter_priv; + #else static inline void perf_counter_task_sched_in(struct task_struct *task, int cpu) { } diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 76376ecb23b5..7efb7ebaaae0 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -42,6 +42,8 @@ static atomic_t nr_mmap_tracking __read_mostly; static atomic_t nr_munmap_tracking __read_mostly; static atomic_t nr_comm_tracking __read_mostly; +int sysctl_perf_counter_priv __read_mostly; /* do we need to be privileged */ + /* * Mutex for (sysadmin-configurable) counter reservations: */ @@ -1132,7 +1134,7 @@ static struct perf_counter_context *find_get_context(pid_t pid, int cpu) */ if (cpu != -1) { /* Must be root to operate on a CPU counter: */ - if (!capable(CAP_SYS_ADMIN)) + if (sysctl_perf_counter_priv && !capable(CAP_SYS_ADMIN)) return ERR_PTR(-EACCES); if (cpu < 0 || cpu > num_possible_cpus()) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 4286b62b34a0..8ba457838d95 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -920,6 +921,16 @@ static struct ctl_table kern_table[] = { .child = slow_work_sysctls, }, #endif +#ifdef CONFIG_PERF_COUNTERS + { + .ctl_name = CTL_UNNUMBERED, + .procname = "perf_counter_privileged", + .data = &sysctl_perf_counter_priv, + .maxlen = sizeof(sysctl_perf_counter_priv), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, +#endif /* * NOTE: do not add new entries to this table unless you have read * Documentation/sysctl/ctl_unnumbered.txt -- GitLab From d3d21c412d8525eb2e208d990ab5eee5fb0fe03d Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 9 Apr 2009 10:53:46 +0200 Subject: [PATCH 0237/6080] perf_counter: log full path names Impact: fix perf-report output for /home mounted binaries, etc. dentry_path() only provide path-names up to the mount root, which is unsuited for out purpose, use d_path() instead. Signed-off-by: Peter Zijlstra Cc: Paul Mackerras Cc: Corey Ashford LKML-Reference: <20090409085524.601794134@chello.nl> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 7efb7ebaaae0..7f9521c3c01b 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -2116,7 +2116,7 @@ static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event) name = strncpy(tmp, "//enomem", sizeof(tmp)); goto got_name; } - name = dentry_path(file->f_dentry, buf, PATH_MAX); + name = d_path(&file->f_path, buf, PATH_MAX); if (IS_ERR(name)) { name = strncpy(tmp, "//toolong", sizeof(tmp)); goto got_name; -- GitLab From 894bf92fdec9909fefcfe907786c6c6944a22052 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 9 Apr 2009 12:34:40 +0300 Subject: [PATCH 0238/6080] ASoC: tlv320aic23: add DSP_A format support Add DSP_A interface format support by setting the LRP bit in DSP mode. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic23.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index c3f4afb5d017..21f69df9994c 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -523,6 +523,8 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, case SND_SOC_DAIFMT_I2S: iface_reg |= TLV320AIC23_FOR_I2S; break; + case SND_SOC_DAIFMT_DSP_A: + iface_reg |= TLV320AIC23_LRP_ON; case SND_SOC_DAIFMT_DSP_B: iface_reg |= TLV320AIC23_FOR_DSP; break; -- GitLab From 5cd2fe6d54c91aa76893b3034f5f3473063c0202 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 9 Apr 2009 14:09:36 +0000 Subject: [PATCH 0239/6080] RDS/IW+IB: Set recv ring low water mark to 1/2 full. Currently the recv ring low water mark is 1/4 the depth. Performance measurements show that this limits iWARP throughput by flow controlling the rds-stress senders. Setting it to 1/2 seems to max the T3 performance. I tried even higher levels but that didn't help and it started to increase the rds thread cpu utilization. Signed-off-by: Steve Wise Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/ib_ring.c | 2 +- net/rds/iw_ring.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rds/ib_ring.c b/net/rds/ib_ring.c index 99a6ccae964c..ff97e8eda858 100644 --- a/net/rds/ib_ring.c +++ b/net/rds/ib_ring.c @@ -137,7 +137,7 @@ int rds_ib_ring_empty(struct rds_ib_work_ring *ring) int rds_ib_ring_low(struct rds_ib_work_ring *ring) { - return __rds_ib_ring_used(ring) <= (ring->w_nr >> 2); + return __rds_ib_ring_used(ring) <= (ring->w_nr >> 1); } /* diff --git a/net/rds/iw_ring.c b/net/rds/iw_ring.c index d422d4b5deef..da8e3b63f663 100644 --- a/net/rds/iw_ring.c +++ b/net/rds/iw_ring.c @@ -137,7 +137,7 @@ int rds_iw_ring_empty(struct rds_iw_work_ring *ring) int rds_iw_ring_low(struct rds_iw_work_ring *ring) { - return __rds_iw_ring_used(ring) <= (ring->w_nr >> 2); + return __rds_iw_ring_used(ring) <= (ring->w_nr >> 1); } -- GitLab From 11bc9421da3040c71fc96da1a31e95217e8cf2af Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 9 Apr 2009 14:09:37 +0000 Subject: [PATCH 0240/6080] RDS: Correct some iw references in rdma_transport.c Had some lingering instances of _iw_ variable names from when the listen code was centralized into rdma_transport.c Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/rdma_transport.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index 7b19024f9706..7d0f901c93d5 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c @@ -34,7 +34,7 @@ #include "rdma_transport.h" -static struct rdma_cm_id *rds_iw_listen_id; +static struct rdma_cm_id *rds_rdma_listen_id; int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, struct rdma_cm_event *event) @@ -161,7 +161,7 @@ static int __init rds_rdma_listen_init(void) rdsdebug("cm %p listening on port %u\n", cm_id, RDS_PORT); - rds_iw_listen_id = cm_id; + rds_rdma_listen_id = cm_id; cm_id = NULL; out: if (cm_id) @@ -171,10 +171,10 @@ out: static void rds_rdma_listen_stop(void) { - if (rds_iw_listen_id) { - rdsdebug("cm %p\n", rds_iw_listen_id); - rdma_destroy_id(rds_iw_listen_id); - rds_iw_listen_id = NULL; + if (rds_rdma_listen_id) { + rdsdebug("cm %p\n", rds_rdma_listen_id); + rdma_destroy_id(rds_rdma_listen_id); + rds_rdma_listen_id = NULL; } } -- GitLab From d39e0602bb987133321d358d9b837d67c27b223d Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 9 Apr 2009 14:09:38 +0000 Subject: [PATCH 0241/6080] RDS/IW+IB: Set the RDS_LL_SEND_FULL bit when we're throttled. The RDS_LL_SEND_FULL bit should be set when we stop transmitted due to flow control. Otherwise the send worker will keep trying as opposed to sleeping until we unthrottle. Saves CPU. Signed-off-by: Steve Wise Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/ib_send.c | 2 +- net/rds/iw_send.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index cb6c52cb1c4c..fa684b7fc748 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -506,7 +506,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, flow_controlled++; } if (work_alloc == 0) { - rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + set_bit(RDS_LL_SEND_FULL, &conn->c_flags); rds_ib_stats_inc(s_ib_tx_throttle); ret = -ENOMEM; goto out; diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index 22dd38ffd608..626290bc7e97 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -549,7 +549,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, flow_controlled++; } if (work_alloc == 0) { - rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc); + set_bit(RDS_LL_SEND_FULL, &conn->c_flags); rds_iw_stats_inc(s_iw_tx_throttle); ret = -ENOMEM; goto out; -- GitLab From 7b70d0336da777c00395cc7a503497c2cdabd1a8 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 9 Apr 2009 14:09:39 +0000 Subject: [PATCH 0242/6080] RDS/IW+IB: Allow max credit advertise window. Fix hack that restricts the credit advertisement to 127. Signed-off-by: Steve Wise Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/ib.h | 2 +- net/rds/ib_recv.c | 2 +- net/rds/ib_send.c | 8 ++++---- net/rds/iw.h | 2 +- net/rds/iw_recv.c | 2 +- net/rds/iw_send.c | 8 ++++---- net/rds/rds.h | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/net/rds/ib.h b/net/rds/ib.h index 069206cae733..455ae73047fe 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -333,7 +333,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op); void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits); void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted); int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted, - u32 *adv_credits, int need_posted); + u32 *adv_credits, int need_posted, int max_posted); /* ib_stats.c */ DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats); diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 36d931573ff4..5709bad28329 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -524,7 +524,7 @@ void rds_ib_attempt_ack(struct rds_ib_connection *ic) } /* Can we get a send credit? */ - if (!rds_ib_send_grab_credits(ic, 1, &adv_credits, 0)) { + if (!rds_ib_send_grab_credits(ic, 1, &adv_credits, 0, RDS_MAX_ADV_CREDIT)) { rds_ib_stats_inc(s_ib_tx_throttle); clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags); return; diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index fa684b7fc748..23bf830db2d5 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -311,7 +311,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) * and using atomic_cmpxchg when updating the two counters. */ int rds_ib_send_grab_credits(struct rds_ib_connection *ic, - u32 wanted, u32 *adv_credits, int need_posted) + u32 wanted, u32 *adv_credits, int need_posted, int max_posted) { unsigned int avail, posted, got = 0, advertise; long oldval, newval; @@ -351,7 +351,7 @@ try_again: * available. */ if (posted && (got || need_posted)) { - advertise = min_t(unsigned int, posted, RDS_MAX_ADV_CREDIT); + advertise = min_t(unsigned int, posted, max_posted); newval -= IB_SET_POST_CREDITS(advertise); } @@ -498,7 +498,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, credit_alloc = work_alloc; if (ic->i_flowctl) { - credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0); + credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT); adv_credits += posted; if (credit_alloc < work_alloc) { rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc); @@ -571,7 +571,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* * Update adv_credits since we reset the ACK_REQUIRED bit. */ - rds_ib_send_grab_credits(ic, 0, &posted, 1); + rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits); adv_credits += posted; BUG_ON(adv_credits > 255); } else if (ic->i_rm != rm) diff --git a/net/rds/iw.h b/net/rds/iw.h index b4fb27252895..0715dde323e7 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h @@ -361,7 +361,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op); void rds_iw_send_add_credits(struct rds_connection *conn, unsigned int credits); void rds_iw_advertise_credits(struct rds_connection *conn, unsigned int posted); int rds_iw_send_grab_credits(struct rds_iw_connection *ic, u32 wanted, - u32 *adv_credits, int need_posted); + u32 *adv_credits, int need_posted, int max_posted); /* ib_stats.c */ DECLARE_PER_CPU(struct rds_iw_statistics, rds_iw_stats); diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c index fde470fa50d5..8683f5f66c4b 100644 --- a/net/rds/iw_recv.c +++ b/net/rds/iw_recv.c @@ -524,7 +524,7 @@ void rds_iw_attempt_ack(struct rds_iw_connection *ic) } /* Can we get a send credit? */ - if (!rds_iw_send_grab_credits(ic, 1, &adv_credits, 0)) { + if (!rds_iw_send_grab_credits(ic, 1, &adv_credits, 0, RDS_MAX_ADV_CREDIT)) { rds_iw_stats_inc(s_iw_tx_throttle); clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags); return; diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index 626290bc7e97..44a6a0551f28 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -347,7 +347,7 @@ void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context) * and using atomic_cmpxchg when updating the two counters. */ int rds_iw_send_grab_credits(struct rds_iw_connection *ic, - u32 wanted, u32 *adv_credits, int need_posted) + u32 wanted, u32 *adv_credits, int need_posted, int max_posted) { unsigned int avail, posted, got = 0, advertise; long oldval, newval; @@ -387,7 +387,7 @@ try_again: * available. */ if (posted && (got || need_posted)) { - advertise = min_t(unsigned int, posted, RDS_MAX_ADV_CREDIT); + advertise = min_t(unsigned int, posted, max_posted); newval -= IB_SET_POST_CREDITS(advertise); } @@ -541,7 +541,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, credit_alloc = work_alloc; if (ic->i_flowctl) { - credit_alloc = rds_iw_send_grab_credits(ic, work_alloc, &posted, 0); + credit_alloc = rds_iw_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT); adv_credits += posted; if (credit_alloc < work_alloc) { rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc); @@ -614,7 +614,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, /* * Update adv_credits since we reset the ACK_REQUIRED bit. */ - rds_iw_send_grab_credits(ic, 0, &posted, 1); + rds_iw_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits); adv_credits += posted; BUG_ON(adv_credits > 255); } else if (ic->i_rm != rm) diff --git a/net/rds/rds.h b/net/rds/rds.h index 619f0a30a4e5..1f82ec0d2066 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -132,7 +132,7 @@ struct rds_connection { #define RDS_FLAG_CONG_BITMAP 0x01 #define RDS_FLAG_ACK_REQUIRED 0x02 #define RDS_FLAG_RETRANSMITTED 0x04 -#define RDS_MAX_ADV_CREDIT 127 +#define RDS_MAX_ADV_CREDIT 255 /* * Maximum space available for extension headers. -- GitLab From 7acd4a794c1530af063e51f3f7171e75556458f3 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 9 Apr 2009 14:09:40 +0000 Subject: [PATCH 0243/6080] RDS: Fix ordering in a conditional Putting the constant first is a supposed "best practice" that actually makes the code harder to read. Thanks to Roland Dreier for finding a bug in this "simple, obviously correct" patch. Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/rdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index eaeeb91e1119..e390dc70b9d9 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -155,7 +155,7 @@ static int rds_pin_pages(unsigned long user_addr, unsigned int nr_pages, nr_pages, write, 0, pages, NULL); up_read(¤t->mm->mmap_sem); - if (0 <= ret && (unsigned) ret < nr_pages) { + if (ret >= 0 && ret < nr_pages) { while (ret--) put_page(pages[ret]); ret = -EFAULT; -- GitLab From 49f696914100780f6bf8e652d3468de0015d6172 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 9 Apr 2009 14:09:41 +0000 Subject: [PATCH 0244/6080] RDS: Establish connection before parsing CMSGs The first message to a remote node should prompt a new connection. Even an RDMA op via CMSG. Therefore move CMSG parsing to after connection establishment. Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/send.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/rds/send.c b/net/rds/send.c index 104fe033203d..a4a7f428cd76 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -854,11 +854,6 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, rm->m_daddr = daddr; - /* Parse any control messages the user may have included. */ - ret = rds_cmsg_send(rs, rm, msg, &allocated_mr); - if (ret) - goto out; - /* rds_conn_create has a spinlock that runs with IRQ off. * Caching the conn in the socket helps a lot. */ if (rs->rs_conn && rs->rs_conn->c_faddr == daddr) @@ -874,6 +869,11 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, rs->rs_conn = conn; } + /* Parse any control messages the user may have included. */ + ret = rds_cmsg_send(rs, rm, msg, &allocated_mr); + if (ret) + goto out; + if ((rm->m_rdma_cookie || rm->m_rdma_op) && conn->c_trans->xmit_rdma == NULL) { if (printk_ratelimit()) -- GitLab From 830eb7d56c18ff4c29acd8b0bb48db404660321f Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Thu, 9 Apr 2009 14:09:42 +0000 Subject: [PATCH 0245/6080] RDS: use get_user_pages_fast() Use the new function that is simpler and faster. Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/info.c | 5 +---- net/rds/rdma.c | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/net/rds/info.c b/net/rds/info.c index 1d885535214d..62aeef37aefe 100644 --- a/net/rds/info.c +++ b/net/rds/info.c @@ -188,10 +188,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval, ret = -ENOMEM; goto out; } - down_read(¤t->mm->mmap_sem); - ret = get_user_pages(current, current->mm, start, nr_pages, 1, 0, - pages, NULL); - up_read(¤t->mm->mmap_sem); + ret = get_user_pages_fast(start, nr_pages, 1, pages); if (ret != nr_pages) { if (ret > 0) nr_pages = ret; diff --git a/net/rds/rdma.c b/net/rds/rdma.c index e390dc70b9d9..8dc83d2caa58 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -150,10 +150,7 @@ static int rds_pin_pages(unsigned long user_addr, unsigned int nr_pages, { int ret; - down_read(¤t->mm->mmap_sem); - ret = get_user_pages(current, current->mm, user_addr, - nr_pages, write, 0, pages, NULL); - up_read(¤t->mm->mmap_sem); + ret = get_user_pages_fast(user_addr, nr_pages, write, pages); if (ret >= 0 && ret < nr_pages) { while (ret--) -- GitLab From 9c56a84478b708e5d8d34d28cc3a8e71842d5b05 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Thu, 9 Apr 2009 14:09:43 +0000 Subject: [PATCH 0246/6080] RDS: remove unused #include Remove unused #include in net/rds/af_rds.c. Signed-off-by: Huang Weiyi Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/af_rds.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index 20cf16fc572f..b11e7e527864 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "rds.h" -- GitLab From 05a178ecdc7396b78dfbb5d8bda65108b37b8672 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 9 Apr 2009 14:09:44 +0000 Subject: [PATCH 0247/6080] rds: use kmem_cache_zalloc instead of kmem_cache_alloc/memset Use kmem_cache_zalloc instead of kmem_cache_alloc/memset. Signed-off-by: Wei Yongjun Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/connection.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/rds/connection.c b/net/rds/connection.c index 273f064930a8..d14445c48304 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -148,14 +148,12 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, if (conn) goto out; - conn = kmem_cache_alloc(rds_conn_slab, gfp); + conn = kmem_cache_zalloc(rds_conn_slab, gfp); if (conn == NULL) { conn = ERR_PTR(-ENOMEM); goto out; } - memset(conn, 0, sizeof(*conn)); - INIT_HLIST_NODE(&conn->c_hash_node); conn->c_version = RDS_PROTOCOL_3_0; conn->c_laddr = laddr; -- GitLab From 5d57eeb52ae71a03c8e083a9b0a818a9b63ca440 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 9 Apr 2009 14:09:45 +0000 Subject: [PATCH 0248/6080] ERR_PTR() dereference in net/rds/iw.c rdma_create_id() returns ERR_PTR() not null. Found by smatch (http://repo.or.cz/w/smatch.git). Compile tested. regards, dan carpenter Signed-off-by: Dan Carpenter Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/iw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rds/iw.c b/net/rds/iw.c index b732efb5b634..d16e1cbc8e83 100644 --- a/net/rds/iw.c +++ b/net/rds/iw.c @@ -233,8 +233,8 @@ static int rds_iw_laddr_check(__be32 addr) * IB and iWARP capable NICs. */ cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP); - if (!cm_id) - return -EADDRNOTAVAIL; + if (IS_ERR(cm_id)) + return PTR_ERR(cm_id); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; -- GitLab From 94713bab649736177a1c33a39b7bb33cbd5af3a5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 9 Apr 2009 14:09:46 +0000 Subject: [PATCH 0249/6080] ERR_PTR() dereference in net/rds/ib.c rdma_create_id() doesn't return NULL, only ERR_PTR(). Found by smatch (http://repo.or.cz/w/smatch.git). Compile tested. regards, dan carpenter Signed-off-by: Dan Carpenter Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- net/rds/ib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rds/ib.c b/net/rds/ib.c index 4933b380985e..b9bcd32431e1 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -224,8 +224,8 @@ static int rds_ib_laddr_check(__be32 addr) * IB and iWARP capable NICs. */ cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP); - if (!cm_id) - return -EADDRNOTAVAIL; + if (IS_ERR(cm_id)) + return PTR_ERR(cm_id); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; -- GitLab From fbb5a5583034e98f87fcff94183637486d7ada18 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 9 Apr 2009 14:09:47 +0000 Subject: [PATCH 0250/6080] MAINTAINERS: rds list is moderated Signed-off-by: Kyle McMartin Signed-off-by: Andy Grover Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index c3b215970f7b..28421c22ebae 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3729,7 +3729,7 @@ S: Maintained RDS - RELIABLE DATAGRAM SOCKETS P: Andy Grover M: andy.grover@oracle.com -L: rds-devel@oss.oracle.com +L: rds-devel@oss.oracle.com (moderated for non-subscribers) S: Supported READ-COPY UPDATE (RCU) -- GitLab From 2132d38133f48ef51d28252bb9c0b792f5b57019 Mon Sep 17 00:00:00 2001 From: PJ Waskiewicz Date: Thu, 9 Apr 2009 22:26:21 +0000 Subject: [PATCH 0251/6080] ixgbe: Enable another bit for flow control operation The discard pause frames bit was not enabled, so flow control frames could be passed up to the host. Enabled DPF to keep the frames off the stack. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82598.c | 1 + drivers/net/ixgbe/ixgbe_common.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index de4db0dc7879..63aacd53aab7 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -322,6 +322,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) } /* Enable 802.3x based flow control settings. */ + fctrl_reg |= IXGBE_FCTRL_DPF; IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg); IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 63ab6671d08e..846c9deeaa7a 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1700,6 +1700,7 @@ s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num) } /* Enable 802.3x based flow control settings. */ + mflcn_reg |= IXGBE_MFLCN_DPF; IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg); IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg); -- GitLab From d988eadbe2d93b5a2d4aa4ec46264e0f6213a71c Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 9 Apr 2009 22:26:40 +0000 Subject: [PATCH 0252/6080] ixgbe: fix IXGBE_MTQC values IXGBE_MTQC_64VF was wrong and 32VF not defined at all. This patch corrects that. Signed-off-by: Don Skidmore Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_type.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 030ff0a9ea67..0d250360b97e 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1553,7 +1553,8 @@ #define IXGBE_MTQC_RT_ENA 0x1 /* DCB Enable */ #define IXGBE_MTQC_VT_ENA 0x2 /* VMDQ2 Enable */ #define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */ -#define IXGBE_MTQC_64VF 0x8 /* 2 TX Queues per pool w/64VF's */ +#define IXGBE_MTQC_32VF 0x8 /* 4 TX Queues per pool w/32VF's */ +#define IXGBE_MTQC_64VF 0x4 /* 2 TX Queues per pool w/64VF's */ #define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */ /* Receive Descriptor bit definitions */ -- GitLab From 6e4e87d68a89028204fe744a8eda8f74bff5b6a9 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 9 Apr 2009 22:27:00 +0000 Subject: [PATCH 0253/6080] ixgbe: add support for addition VT_CTL defines These defines allow for definition of target pool for packets that pass L2 filtering but didn't pass any of the pool filters. They are needed to reset the default pool. Signed-off-by: Don Skidmore Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_type.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 0d250360b97e..50285c2dd8d3 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -958,6 +958,8 @@ #define IXGBE_VT_CTL_DIS_DEFPL 0x20000000 /* disable default pool */ #define IXGBE_VT_CTL_REPLEN 0x40000000 /* replication enabled */ #define IXGBE_VT_CTL_VT_ENABLE 0x00000001 /* Enable VT Mode */ +#define IXGBE_VT_CTL_POOL_SHIFT 7 +#define IXGBE_VT_CTL_POOL_MASK (0x3F << IXGBE_VT_CTL_POOL_SHIFT) /* VMOLR bitmasks */ #define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */ -- GitLab From e80e887a959ca41066412582c5f79aae5ffd5821 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 9 Apr 2009 22:27:19 +0000 Subject: [PATCH 0254/6080] ixgbe: add define to support 82599 64 IVAR registers 82599 supports 64 IVAR registers this patch adds a define to allow us to access them. Signed-off-by: Don Skidmore Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_type.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 50285c2dd8d3..96e15d010906 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1150,6 +1150,7 @@ /* Interrupt Vector Allocation Registers */ #define IXGBE_IVAR_REG_NUM 25 +#define IXGBE_IVAR_REG_NUM_82599 64 #define IXGBE_IVAR_TXRX_ENTRY 96 #define IXGBE_IVAR_RX_ENTRY 64 #define IXGBE_IVAR_RX_QUEUE(_i) (0 + (_i)) -- GitLab From d3e9c56cafb98040c8601dcc784a773ac86da18b Mon Sep 17 00:00:00 2001 From: PJ Waskiewicz Date: Thu, 9 Apr 2009 22:27:39 +0000 Subject: [PATCH 0255/6080] ixgbe: Don't return error in flow control configuration if FC is off When flow control is disabled, an invalid low/high watermark configuration should not matter. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82598.c | 8 +++++--- drivers/net/ixgbe/ixgbe_common.c | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 63aacd53aab7..1e1d8b79f9e3 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -381,9 +381,11 @@ static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num) * because it causes the controller to just blast out fc packets. */ if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { - hw_dbg(hw, "Invalid water mark configuration\n"); - ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; - goto out; + if (hw->fc.requested_mode != ixgbe_fc_none) { + hw_dbg(hw, "Invalid water mark configuration\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } } /* diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 846c9deeaa7a..2d4af5d2d3f7 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1907,9 +1907,11 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num) * because it causes the controller to just blast out fc packets. */ if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { - hw_dbg(hw, "Invalid water mark configuration\n"); - ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; - goto out; + if (hw->fc.requested_mode != ixgbe_fc_none) { + hw_dbg(hw, "Invalid water mark configuration\n"); + ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; + goto out; + } } /* -- GitLab From 04f165ef4f18444854865d44a3359618480060af Mon Sep 17 00:00:00 2001 From: PJ Waskiewicz Date: Thu, 9 Apr 2009 22:27:57 +0000 Subject: [PATCH 0256/6080] ixgbe: Move PHY ops initialization to centralize bus accesses When PHY operations are determined, the PHY must be identified. This identification causes bus access, and should be contained within its own routines. This also helps the 82599 PHY init paths for both SFP+ and KX/KX4 devices to be easier to maintain. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82598.c | 77 ++++++++++++++++++++++----------- drivers/net/ixgbe/ixgbe_82599.c | 70 ++++++++++++++++++++---------- drivers/net/ixgbe/ixgbe_main.c | 9 +++- drivers/net/ixgbe/ixgbe_type.h | 1 + 4 files changed, 107 insertions(+), 50 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 1e1d8b79f9e3..a8151f25a4d0 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -73,20 +73,51 @@ static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw) /** */ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + + /* Call PHY identify routine to get the phy type */ + ixgbe_identify_phy_generic(hw); + + mac->mcft_size = IXGBE_82598_MC_TBL_SIZE; + mac->vft_size = IXGBE_82598_VFT_TBL_SIZE; + mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES; + mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES; + mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES; + mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw); + + return 0; +} + +/** + * ixgbe_init_phy_ops_82598 - PHY/SFP specific init + * @hw: pointer to hardware structure + * + * Initialize any function pointers that were not able to be + * set during get_invariants because the PHY/SFP type was + * not known. Perform the SFP init if necessary. + * + **/ +s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) { struct ixgbe_mac_info *mac = &hw->mac; struct ixgbe_phy_info *phy = &hw->phy; s32 ret_val = 0; u16 list_offset, data_offset; - /* Set the bus information prior to PHY identification */ - mac->ops.get_bus_info(hw); + /* Identify the PHY */ + phy->ops.identify(hw); - /* Call PHY identify routine to get the phy type */ - ixgbe_identify_phy_generic(hw); + /* Overwrite the link function pointers if copper PHY */ + if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { + mac->ops.setup_link = &ixgbe_setup_copper_link_82598; + mac->ops.setup_link_speed = + &ixgbe_setup_copper_link_speed_82598; + mac->ops.get_link_capabilities = + &ixgbe_get_copper_link_capabilities_82598; + } - /* PHY Init */ - switch (phy->type) { + switch (hw->phy.type) { case ixgbe_phy_tn: phy->ops.check_link = &ixgbe_check_phy_link_tnx; phy->ops.get_firmware_version = @@ -106,8 +137,8 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) /* Check to see if SFP+ module is supported */ ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, - &list_offset, - &data_offset); + &list_offset, + &data_offset); if (ret_val != 0) { ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED; goto out; @@ -117,21 +148,6 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) break; } - if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { - mac->ops.setup_link = &ixgbe_setup_copper_link_82598; - mac->ops.setup_link_speed = - &ixgbe_setup_copper_link_speed_82598; - mac->ops.get_link_capabilities = - &ixgbe_get_copper_link_capabilities_82598; - } - - mac->mcft_size = IXGBE_82598_MC_TBL_SIZE; - mac->vft_size = IXGBE_82598_VFT_TBL_SIZE; - mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES; - mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES; - mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES; - mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw); - out: return ret_val; } @@ -719,14 +735,23 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) } /* Reset PHY */ - if (hw->phy.reset_disable == false) + if (hw->phy.reset_disable == false) { + /* PHY ops must be identified and initialized prior to reset */ + + /* Init PHY and function pointers, perform SFP setup */ + status = hw->phy.ops.init(hw); + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto reset_hw_out; + hw->phy.ops.reset(hw); + } /* * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset */ - if (ixgbe_disable_pcie_master(hw) != 0) { + status = ixgbe_disable_pcie_master(hw); + if (status != 0) { status = IXGBE_ERR_MASTER_REQUESTS_PENDING; hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); } @@ -773,6 +798,7 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) /* Store the permanent mac address */ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); +reset_hw_out: return status; } @@ -1157,6 +1183,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82598 = { static struct ixgbe_phy_operations phy_ops_82598 = { .identify = &ixgbe_identify_phy_generic, .identify_sfp = &ixgbe_identify_sfp_module_generic, + .init = &ixgbe_init_phy_ops_82598, .reset = &ixgbe_reset_phy_generic, .read_reg = &ixgbe_read_phy_reg_generic, .write_reg = &ixgbe_write_phy_reg_generic, diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index beae7e012609..9a9998985004 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -148,51 +148,60 @@ u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw) static s32 ixgbe_get_invariants_82599(struct ixgbe_hw *hw) { struct ixgbe_mac_info *mac = &hw->mac; - struct ixgbe_phy_info *phy = &hw->phy; - s32 ret_val; - /* Set the bus information prior to PHY identification */ - mac->ops.get_bus_info(hw); + ixgbe_init_mac_link_ops_82599(hw); - /* Call PHY identify routine to get the Cu or SFI phy type */ - ret_val = phy->ops.identify(hw); + mac->mcft_size = IXGBE_82599_MC_TBL_SIZE; + mac->vft_size = IXGBE_82599_VFT_TBL_SIZE; + mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES; + mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES; + mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES; + mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw); - if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED) - goto get_invariants_out; + return 0; +} - ixgbe_init_mac_link_ops_82599(hw); +/** + * ixgbe_init_phy_ops_82599 - PHY/SFP specific init + * @hw: pointer to hardware structure + * + * Initialize any function pointers that were not able to be + * set during get_invariants because the PHY/SFP type was + * not known. Perform the SFP init if necessary. + * + **/ +s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) +{ + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + s32 ret_val = 0; - /* Setup SFP module if there is one present. */ - ret_val = mac->ops.setup_sfp(hw); + /* Identify the PHY or SFP module */ + ret_val = phy->ops.identify(hw); + + /* Setup function pointers based on detected SFP module and speeds */ + ixgbe_init_mac_link_ops_82599(hw); /* If copper media, overwrite with copper function pointers */ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { mac->ops.setup_link = &ixgbe_setup_copper_link_82599; mac->ops.setup_link_speed = - &ixgbe_setup_copper_link_speed_82599; + &ixgbe_setup_copper_link_speed_82599; mac->ops.get_link_capabilities = &ixgbe_get_copper_link_capabilities_82599; } - /* PHY Init */ + /* Set necessary function pointers based on phy type */ switch (hw->phy.type) { case ixgbe_phy_tn: phy->ops.check_link = &ixgbe_check_phy_link_tnx; phy->ops.get_firmware_version = - &ixgbe_get_phy_firmware_version_tnx; + &ixgbe_get_phy_firmware_version_tnx; break; default: break; } - mac->mcft_size = IXGBE_82599_MC_TBL_SIZE; - mac->vft_size = IXGBE_82599_VFT_TBL_SIZE; - mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES; - mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES; - mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES; - mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw); - -get_invariants_out: return ret_val; } @@ -708,13 +717,24 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) hw->mac.ops.stop_adapter(hw); /* Reset PHY */ - hw->phy.ops.reset(hw); + if (hw->phy.reset_disable == false) { + /* PHY ops must be identified and initialized prior to reset */ + + /* Init PHY and function pointers, perform SFP setup */ + status = hw->phy.ops.init(hw); + + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto reset_hw_out; + + hw->phy.ops.reset(hw); + } /* * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset */ - if (ixgbe_disable_pcie_master(hw) != 0) { + status = ixgbe_disable_pcie_master(hw); + if (status != 0) { status = IXGBE_ERR_MASTER_REQUESTS_PENDING; hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); } @@ -775,6 +795,7 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) /* Store the permanent mac address */ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); +reset_hw_out: return status; } @@ -1272,6 +1293,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = { static struct ixgbe_phy_operations phy_ops_82599 = { .identify = &ixgbe_identify_phy_82599, .identify_sfp = &ixgbe_identify_sfp_module_generic, + .init = &ixgbe_init_phy_ops_82599, .reset = &ixgbe_reset_phy_generic, .read_reg = &ixgbe_read_phy_reg_generic, .write_reg = &ixgbe_write_phy_reg_generic, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 9ef128ae6458..936a3efb3621 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4630,7 +4630,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* reset_hw fills in the perm_addr as well */ err = hw->mac.ops.reset_hw(hw); - if (err) { + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + dev_err(&adapter->pdev->dev, "failed to load because an " + "unsupported SFP+ module type was detected.\n"); + goto err_sw_init; + } else if (err) { dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err); goto err_sw_init; } @@ -4703,6 +4707,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, device_init_wakeup(&adapter->pdev->dev, true); device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); + /* pick up the PCI bus settings for reporting later */ + hw->mac.ops.get_bus_info(hw); + /* print bus type/speed/width info */ dev_info(&pdev->dev, "(PCI Express:%s:%s) %pM\n", ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s": diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 96e15d010906..06d7e8ae6225 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2150,6 +2150,7 @@ struct ixgbe_mac_operations { struct ixgbe_phy_operations { s32 (*identify)(struct ixgbe_hw *); s32 (*identify_sfp)(struct ixgbe_hw *); + s32 (*init)(struct ixgbe_hw *); s32 (*reset)(struct ixgbe_hw *); s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *); s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16); -- GitLab From 553b449784e27bb7244c41aa27397d29f213e5a3 Mon Sep 17 00:00:00 2001 From: PJ Waskiewicz Date: Thu, 9 Apr 2009 22:28:15 +0000 Subject: [PATCH 0257/6080] ixgbe: Remove unnecessary PHY reset, properly identify multispeed fiber modules This patch does two things: 1) On 82599, the PHY is emedded in the MAC. On 82598, the SFP+ NIC has an external PHY. The reset in the SFP+ setup patch for 82598 is unnecessary on 82599, and adds extra dead time to device initialization. This removes that PHY reset for 82599 only. 2) On 82599, the SFP+ modules are multispeed fiber modules (10G/1G). We need to make sure to identify them properly for the remaining init sections to properly set them up. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82599.c | 24 ++++++++++++++++-------- drivers/net/ixgbe/ixgbe_phy.c | 11 +++++++++++ drivers/net/ixgbe/ixgbe_phy.h | 1 + drivers/net/ixgbe/ixgbe_type.h | 1 + 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 9a9998985004..72a0d27a19af 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -102,6 +102,9 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) { ixgbe_init_mac_link_ops_82599(hw); + + hw->phy.ops.reset = NULL; + ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset, &data_offset); @@ -716,19 +719,24 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) /* Call adapter stop to disable tx/rx and clear interrupts */ hw->mac.ops.stop_adapter(hw); - /* Reset PHY */ - if (hw->phy.reset_disable == false) { - /* PHY ops must be identified and initialized prior to reset */ + /* PHY ops must be identified and initialized prior to reset */ - /* Init PHY and function pointers, perform SFP setup */ - status = hw->phy.ops.init(hw); + /* Init PHY and function pointers, perform SFP setup */ + status = hw->phy.ops.init(hw); - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) - goto reset_hw_out; + if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + goto reset_hw_out; - hw->phy.ops.reset(hw); + /* Setup SFP module if there is one present. */ + if (hw->phy.sfp_setup_needed) { + status = hw->mac.ops.setup_sfp(hw); + hw->phy.sfp_setup_needed = false; } + /* Reset PHY */ + if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL) + hw->phy.ops.reset(hw); + /* * Prevent the PCI-E bus from from hanging by disabling PCI-E master * access and verify no pending requests before reset diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 14e9606aa3b3..6f11df756daa 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -552,6 +552,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_PHY_ADDR_INVALID; u32 vendor_oui = 0; + enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type; u8 identifier = 0; u8 comp_codes_1g = 0; u8 comp_codes_10g = 0; @@ -620,6 +621,16 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) hw->phy.sfp_type = ixgbe_sfp_type_unknown; } + if (hw->phy.sfp_type != stored_sfp_type) + hw->phy.sfp_setup_needed = true; + + /* Determine if the SFP+ PHY is dual speed or not. */ + if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) && + (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) || + ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) && + (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE))) + hw->phy.multispeed_fiber = true; + /* Determine PHY vendor */ if (hw->phy.type == ixgbe_phy_unknown) { hw->phy.id = identifier; diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index cc5f1b3287e1..c9964b7ce1b9 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -44,6 +44,7 @@ /* Bitmasks */ #define IXGBE_SFF_TWIN_AX_CAPABLE 0x80 #define IXGBE_SFF_1GBASESX_CAPABLE 0x1 +#define IXGBE_SFF_1GBASELX_CAPABLE 0x2 #define IXGBE_SFF_10GBASESR_CAPABLE 0x10 #define IXGBE_SFF_10GBASELR_CAPABLE 0x20 #define IXGBE_I2C_EEPROM_READ_MASK 0x100 diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 06d7e8ae6225..db65c05773ad 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -2198,6 +2198,7 @@ struct ixgbe_phy_info { u32 addr; u32 id; enum ixgbe_sfp_type sfp_type; + bool sfp_setup_needed; u32 revision; enum ixgbe_media_type media_type; bool reset_disable; -- GitLab From 1eb99d5ac44e2a9ac0b2856c579ba4d7cc349ada Mon Sep 17 00:00:00 2001 From: PJ Waskiewicz Date: Thu, 9 Apr 2009 22:28:33 +0000 Subject: [PATCH 0258/6080] ixgbe: Update the usage of orig_autoc to be more consistent The orig_autoc variable tracks the original setting of the autonegotiate state prior to trying a new speed. The usage is inconsistent and not very maintainable. This patch updates the usage to make it more consistent. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82598.c | 15 +++++++++---- drivers/net/ixgbe/ixgbe_82599.c | 37 +++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index a8151f25a4d0..361c9d1d0117 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -165,12 +165,19 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, bool *autoneg) { s32 status = 0; + u32 autoc = 0; /* * Determine link capabilities based on the stored value of AUTOC, - * which represents EEPROM defaults. + * which represents EEPROM defaults. If AUTOC value has not been + * stored, use the current register value. */ - switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) { + if (hw->mac.orig_link_settings_stored) + autoc = hw->mac.orig_autoc; + else + autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + + switch (autoc & IXGBE_AUTOC_LMS_MASK) { case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: *speed = IXGBE_LINK_SPEED_1GB_FULL; *autoneg = false; @@ -189,9 +196,9 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, case IXGBE_AUTOC_LMS_KX4_AN: case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: *speed = IXGBE_LINK_SPEED_UNKNOWN; - if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP) + if (autoc & IXGBE_AUTOC_KX4_SUPP) *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP) + if (autoc & IXGBE_AUTOC_KX_SUPP) *speed |= IXGBE_LINK_SPEED_1GB_FULL; *autoneg = true; break; diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 72a0d27a19af..50b399c1e87f 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -221,8 +221,19 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, bool *negotiation) { s32 status = 0; + u32 autoc = 0; - switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) { + /* + * Determine link capabilities based on the stored value of AUTOC, + * which represents EEPROM defaults. If AUTOC value has not been + * stored, use the current register value. + */ + if (hw->mac.orig_link_settings_stored) + autoc = hw->mac.orig_autoc; + else + autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + + switch (autoc & IXGBE_AUTOC_LMS_MASK) { case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: *speed = IXGBE_LINK_SPEED_1GB_FULL; *negotiation = false; @@ -246,22 +257,22 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw, case IXGBE_AUTOC_LMS_KX4_KX_KR: case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN: *speed = IXGBE_LINK_SPEED_UNKNOWN; - if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP) + if (autoc & IXGBE_AUTOC_KR_SUPP) *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP) + if (autoc & IXGBE_AUTOC_KX4_SUPP) *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP) + if (autoc & IXGBE_AUTOC_KX_SUPP) *speed |= IXGBE_LINK_SPEED_1GB_FULL; *negotiation = true; break; case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII: *speed = IXGBE_LINK_SPEED_100_FULL; - if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP) + if (autoc & IXGBE_AUTOC_KR_SUPP) *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP) + if (autoc & IXGBE_AUTOC_KX4_SUPP) *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP) + if (autoc & IXGBE_AUTOC_KX_SUPP) *speed |= IXGBE_LINK_SPEED_1GB_FULL; *negotiation = true; break; @@ -572,6 +583,7 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, s32 status = 0; u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + u32 orig_autoc = 0; u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK; u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK; @@ -583,6 +595,13 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg); speed &= link_capabilities; + /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/ + if (hw->mac.orig_link_settings_stored) + orig_autoc = hw->mac.orig_autoc; + else + orig_autoc = autoc; + + if (speed == IXGBE_LINK_SPEED_UNKNOWN) { status = IXGBE_ERR_LINK_SETUP; } else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR || @@ -591,9 +610,9 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw, /* Set KX4/KX/KR support according to speed requested */ autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); if (speed & IXGBE_LINK_SPEED_10GB_FULL) - if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP) + if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) autoc |= IXGBE_AUTOC_KX4_SUPP; - if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP) + if (orig_autoc & IXGBE_AUTOC_KR_SUPP) autoc |= IXGBE_AUTOC_KR_SUPP; if (speed & IXGBE_LINK_SPEED_1GB_FULL) autoc |= IXGBE_AUTOC_KX_SUPP; -- GitLab From 04193058c1005551af93f04a4b975fbd7f95cad5 Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Thu, 9 Apr 2009 22:28:50 +0000 Subject: [PATCH 0259/6080] ixgbe: Update get_physical_layer() calls, plus a version bump Not all physical connection types are being correctly identified. This fixes that issue, and cleans up the logic to make it more maintainable. Also clean up the code for device capabilities from the EEPROM to support multiple SKUs of the same hardware. Bump the version to reflect all the updates since the 82599 merge. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82598.c | 85 +++++++++++++------- drivers/net/ixgbe/ixgbe_82599.c | 134 +++++++++++++++++++++++--------- drivers/net/ixgbe/ixgbe_main.c | 2 +- drivers/net/ixgbe/ixgbe_phy.c | 8 +- drivers/net/ixgbe/ixgbe_type.h | 10 ++- 5 files changed, 169 insertions(+), 70 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 361c9d1d0117..a7ae4d45b53d 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1089,35 +1089,56 @@ out: static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) { u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK; + u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; + u16 ext_ability = 0; + + hw->phy.ops.identify(hw); + + /* Copper PHY must be checked before AUTOC LMS to determine correct + * physical layer because 10GBase-T PHYs use LMS = KX4/KX */ + if (hw->phy.type == ixgbe_phy_tn || + hw->phy.type == ixgbe_phy_cu_unknown) { + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); + if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; + if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + goto out; + } - switch (hw->device_id) { - case IXGBE_DEV_ID_82598: - /* Default device ID is mezzanine card KX/KX4 */ - physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 | - IXGBE_PHYSICAL_LAYER_1000BASE_KX); - break; - case IXGBE_DEV_ID_82598_BX: - physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX; - case IXGBE_DEV_ID_82598EB_CX4: - case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: - physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; - break; - case IXGBE_DEV_ID_82598_DA_DUAL_PORT: - physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; + switch (autoc & IXGBE_AUTOC_LMS_MASK) { + case IXGBE_AUTOC_LMS_1G_AN: + case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: + if (pma_pmd_1g == IXGBE_AUTOC_1G_KX) + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX; + else + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX; break; - case IXGBE_DEV_ID_82598AF_DUAL_PORT: - case IXGBE_DEV_ID_82598AF_SINGLE_PORT: - case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: - physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; + case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: + if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; + else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4; + else /* XAUI */ + physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; break; - case IXGBE_DEV_ID_82598EB_XF_LR: - physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; + case IXGBE_AUTOC_LMS_KX4_AN: + case IXGBE_AUTOC_LMS_KX4_AN_1G_AN: + if (autoc & IXGBE_AUTOC_KX_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX; + if (autoc & IXGBE_AUTOC_KX4_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4; break; - case IXGBE_DEV_ID_82598AT: - physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T | - IXGBE_PHYSICAL_LAYER_1000BASE_T); + default: break; - case IXGBE_DEV_ID_82598EB_SFP_LOM: + } + + if (hw->phy.type == ixgbe_phy_nl) { hw->phy.ops.identify_sfp(hw); switch (hw->phy.sfp_type) { @@ -1134,13 +1155,25 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; break; } - break; + } + switch (hw->device_id) { + case IXGBE_DEV_ID_82598_DA_DUAL_PORT: + physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; + break; + case IXGBE_DEV_ID_82598AF_DUAL_PORT: + case IXGBE_DEV_ID_82598AF_SINGLE_PORT: + case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; + break; + case IXGBE_DEV_ID_82598EB_XF_LR: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; + break; default: - physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; break; } +out: return physical_layer; } diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 50b399c1e87f..b3f4e96a018c 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1177,53 +1177,98 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw) u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) { u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2); + u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK; + u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK; + u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK; + u16 ext_ability = 0; u8 comp_codes_10g = 0; - switch (hw->device_id) { - case IXGBE_DEV_ID_82599: - case IXGBE_DEV_ID_82599_KX4: - /* Default device ID is mezzanine card KX/KX4 */ - physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 | - IXGBE_PHYSICAL_LAYER_1000BASE_KX); + hw->phy.ops.identify(hw); + + if (hw->phy.type == ixgbe_phy_tn || + hw->phy.type == ixgbe_phy_cu_unknown) { + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); + if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; + if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; + if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) + physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; + goto out; + } + + switch (autoc & IXGBE_AUTOC_LMS_MASK) { + case IXGBE_AUTOC_LMS_1G_AN: + case IXGBE_AUTOC_LMS_1G_LINK_NO_AN: + if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) { + physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX | + IXGBE_PHYSICAL_LAYER_1000BASE_BX; + goto out; + } else + /* SFI mode so read SFP module */ + goto sfp_check; break; - case IXGBE_DEV_ID_82599_SFP: - hw->phy.ops.identify_sfp(hw); + case IXGBE_AUTOC_LMS_10G_LINK_NO_AN: + if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; + else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4) + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4; + goto out; + break; + case IXGBE_AUTOC_LMS_10G_SERIAL: + if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) { + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR; + goto out; + } else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI) + goto sfp_check; + break; + case IXGBE_AUTOC_LMS_KX4_KX_KR: + case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN: + if (autoc & IXGBE_AUTOC_KX_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX; + if (autoc & IXGBE_AUTOC_KX4_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4; + if (autoc & IXGBE_AUTOC_KR_SUPP) + physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR; + goto out; + break; + default: + goto out; + break; + } - switch (hw->phy.sfp_type) { - case ixgbe_sfp_type_da_cu: - case ixgbe_sfp_type_da_cu_core0: - case ixgbe_sfp_type_da_cu_core1: - physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; - break; - case ixgbe_sfp_type_sr: +sfp_check: + /* SFP check must be done last since DA modules are sometimes used to + * test KR mode - we need to id KR mode correctly before SFP module. + * Call identify_sfp because the pluggable module may have changed */ + hw->phy.ops.identify_sfp(hw); + if (hw->phy.sfp_type == ixgbe_sfp_type_not_present) + goto out; + + switch (hw->phy.type) { + case ixgbe_phy_tw_tyco: + case ixgbe_phy_tw_unknown: + physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU; + break; + case ixgbe_phy_sfp_avago: + case ixgbe_phy_sfp_ftl: + case ixgbe_phy_sfp_intel: + case ixgbe_phy_sfp_unknown: + hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g); + if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; - break; - case ixgbe_sfp_type_lr: + else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; - break; - case ixgbe_sfp_type_srlr_core0: - case ixgbe_sfp_type_srlr_core1: - hw->phy.ops.read_i2c_eeprom(hw, - IXGBE_SFF_10GBE_COMP_CODES, - &comp_codes_10g); - if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE) - physical_layer = - IXGBE_PHYSICAL_LAYER_10GBASE_SR; - else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE) - physical_layer = - IXGBE_PHYSICAL_LAYER_10GBASE_LR; - else - physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; - default: - physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; - break; - } break; default: - physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; break; } +out: return physical_layer; } @@ -1271,6 +1316,22 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval) return 0; } +/** + * ixgbe_get_device_caps_82599 - Get additional device capabilities + * @hw: pointer to hardware structure + * @device_caps: the EEPROM word with the extra device capabilities + * + * This function will read the EEPROM location for the device capabilities, + * and return the word through device_caps. + **/ +s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps) +{ + hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps); + + return 0; +} + + static struct ixgbe_mac_operations mac_ops_82599 = { .init_hw = &ixgbe_init_hw_generic, .reset_hw = &ixgbe_reset_hw_82599, @@ -1280,6 +1341,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599, .enable_rx_dma = &ixgbe_enable_rx_dma_82599, .get_mac_addr = &ixgbe_get_mac_addr_generic, + .get_device_caps = &ixgbe_get_device_caps_82599, .stop_adapter = &ixgbe_stop_adapter_generic, .get_bus_info = &ixgbe_get_bus_info_generic, .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 936a3efb3621..2856486e1655 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -47,7 +47,7 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = "Intel(R) 10 Gigabit PCI Express Network Driver"; -#define DRV_VERSION "2.0.8-k2" +#define DRV_VERSION "2.0.16-k2" const char ixgbe_driver_version[] = DRV_VERSION; static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation."; diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 6f11df756daa..f3258ec901fe 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -632,7 +632,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) hw->phy.multispeed_fiber = true; /* Determine PHY vendor */ - if (hw->phy.type == ixgbe_phy_unknown) { + if (hw->phy.type != ixgbe_phy_nl) { hw->phy.id = identifier; hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_VENDOR_OUI_BYTE0, @@ -682,9 +682,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) goto out; } - hw->eeprom.ops.read(hw, IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET, - &enforce_sfp); - if (!(enforce_sfp & IXGBE_PHY_ALLOW_ANY_SFP)) { + /* This is guaranteed to be 82599, no need to check for NULL */ + hw->mac.ops.get_device_caps(hw, &enforce_sfp); + if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) { /* Make sure we're a supported PHY type */ if (hw->phy.type == ixgbe_phy_sfp_intel) { status = 0; diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index db65c05773ad..a3317d8fbf6a 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -862,6 +862,7 @@ #define IXGBE_MDIO_PHY_EXT_ABILITY 0xB /* Ext Ability Reg */ #define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */ #define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */ +#define IXGBE_MDIO_PHY_100BASETX_ABILITY 0x0080 /* 100BaseTX capable */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */ @@ -898,8 +899,6 @@ #define IXGBE_CONTROL_NL 0x000F #define IXGBE_CONTROL_EOL_NL 0x0FFF #define IXGBE_CONTROL_SOL_NL 0x0000 -#define IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET 0x002C -#define IXGBE_PHY_ALLOW_ANY_SFP 0x1 /* General purpose Interrupt Enable */ #define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */ @@ -1385,6 +1384,7 @@ #define IXGBE_FW_PTR 0x0F #define IXGBE_PBANUM0_PTR 0x15 #define IXGBE_PBANUM1_PTR 0x16 +#define IXGBE_DEVICE_CAPS 0x2C #define IXGBE_PCIE_MSIX_82599_CAPS 0x72 #define IXGBE_PCIE_MSIX_82598_CAPS 0x62 @@ -1428,6 +1428,8 @@ #define IXGBE_EERD_ATTEMPTS 100000 #endif +#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1 + /* PCI Bus Info */ #define IXGBE_PCI_LINK_STATUS 0xB2 #define IXGBE_PCI_LINK_WIDTH 0x3F0 @@ -1865,7 +1867,7 @@ typedef u32 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_UNKNOWN 0 #define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001 #define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002 -#define IXGBE_PHYSICAL_LAYER_100BASE_T 0x0004 +#define IXGBE_PHYSICAL_LAYER_100BASE_TX 0x0004 #define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008 #define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010 #define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020 @@ -1874,6 +1876,7 @@ typedef u32 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100 #define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200 #define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400 +#define IXGBE_PHYSICAL_LAYER_10GBASE_KR 0x0800 enum ixgbe_eeprom_type { ixgbe_eeprom_uninitialized = 0, @@ -2105,6 +2108,7 @@ struct ixgbe_mac_operations { enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); u32 (*get_supported_physical_layer)(struct ixgbe_hw *); s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *); + s32 (*get_device_caps)(struct ixgbe_hw *, u16 *); s32 (*stop_adapter)(struct ixgbe_hw *); s32 (*get_bus_info)(struct ixgbe_hw *); void (*set_lan_id)(struct ixgbe_hw *); -- GitLab From 8d1c3c0746098bee8ad116073120166347f21719 Mon Sep 17 00:00:00 2001 From: Tony Breeds Date: Thu, 9 Apr 2009 22:29:10 +0000 Subject: [PATCH 0260/6080] ixgbe: Be explict with what we are !'ing in ixgbe_sfp_config_module_task() GCC warns: drivers/net/ixgbe/ixgbe_main.c: In function 'ixgbe_sfp_config_module_task': drivers/net/ixgbe/ixgbe_main.c:3920: warning: suggest parantheses around operand of '!' or change '&' to '&&' or '!' to '~' Which I think is right. Bracket to remove ambiguity. Signed-off-by: Tony Breeds Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 2856486e1655..813c5bc1a8fa 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3917,7 +3917,7 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) } hw->mac.ops.setup_sfp(hw); - if (!adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK) + if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)) /* This will also work for DA Twinax connections */ schedule_work(&adapter->multispeed_fiber_task); adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK; -- GitLab From f4c1724f3437ac70d8330968379148c954ca34c7 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 12 Apr 2009 05:04:43 +0400 Subject: [PATCH 0261/6080] ASoC: n810: replace BUG() with BUG_ON() Signed-off-by: Alexander Beregalov Signed-off-by: Mark Brown --- sound/soc/omap/n810.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index a6d1178ce128..e54e1c2f5e63 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -383,10 +383,9 @@ static int __init n810_soc_init(void) clk_set_parent(sys_clkout2_src, func96m_clk); clk_set_rate(sys_clkout2, 12000000); - if (gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) - BUG(); - if (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0) - BUG(); + BUG_ON((gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) || + (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0)); + gpio_direction_output(N810_HEADSET_AMP_GPIO, 0); gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0); -- GitLab From f4976116a98f108bf385f217332aadb3ca98fe66 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 13 Apr 2009 10:53:02 +0100 Subject: [PATCH 0262/6080] ASoC: WM9713 requires symmetric rates on the voice DAI Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 523bad077fa0..aa94cc68f0c0 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1069,6 +1069,7 @@ struct snd_soc_dai wm9713_dai[] = { .rates = WM9713_PCM_RATES, .formats = WM9713_PCM_FORMATS,}, .ops = &wm9713_dai_ops_voice, + .symmetric_rates = 1, }, }; EXPORT_SYMBOL_GPL(wm9713_dai); -- GitLab From 025756eca458b4a3d5e3d76baaffb2e8e3df79db Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 13 Apr 2009 11:09:18 +0100 Subject: [PATCH 0263/6080] ASoC: Factor out application of power for generic widgets This is simple code motion, intended to support future refactoring of the DAPM algorithms and (more immediately) the additon of events for DACs and ADCs. Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 110 +++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 50 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 46485de9e6f8..713d12586705 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -522,6 +522,65 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(dapm_reg_event); +/* Standard power change method, used to apply power changes to most + * widgets. + */ +static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) +{ + int ret; + + /* call any power change event handlers */ + if (w->event) + pr_debug("power %s event for %s flags %x\n", + w->power ? "on" : "off", + w->name, w->event_flags); + + /* power up pre event */ + if (w->power && w->event && + (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { + ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); + if (ret < 0) + return ret; + } + + /* power down pre event */ + if (!w->power && w->event && + (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { + ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); + if (ret < 0) + return ret; + } + + /* Lower PGA volume to reduce pops */ + if (w->id == snd_soc_dapm_pga && !w->power) + dapm_set_pga(w, w->power); + + dapm_update_bits(w); + + /* Raise PGA volume to reduce pops */ + if (w->id == snd_soc_dapm_pga && w->power) + dapm_set_pga(w, w->power); + + /* power up post event */ + if (w->power && w->event && + (w->event_flags & SND_SOC_DAPM_POST_PMU)) { + ret = w->event(w, + NULL, SND_SOC_DAPM_POST_PMU); + if (ret < 0) + return ret; + } + + /* power down post event */ + if (!w->power && w->event && + (w->event_flags & SND_SOC_DAPM_POST_PMD)) { + ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); + if (ret < 0) + return ret; + } + + return 0; +} + /* * Scan a single DAPM widget for a complete audio path and update the * power status appropriately. @@ -601,56 +660,7 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event, if (!power_change) return 0; - /* call any power change event handlers */ - if (w->event) - pr_debug("power %s event for %s flags %x\n", - w->power ? "on" : "off", - w->name, w->event_flags); - - /* power up pre event */ - if (power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - return ret; - } - - /* power down pre event */ - if (!power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - return ret; - } - - /* Lower PGA volume to reduce pops */ - if (w->id == snd_soc_dapm_pga && !power) - dapm_set_pga(w, power); - - dapm_update_bits(w); - - /* Raise PGA volume to reduce pops */ - if (w->id == snd_soc_dapm_pga && power) - dapm_set_pga(w, power); - - /* power up post event */ - if (power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMU)) { - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - return ret; - } - - /* power down post event */ - if (!power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMD)) { - ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - return ret; - } - - return 0; + return dapm_generic_apply_power(w); } /* -- GitLab From f6d655a6e6974e474a11b25052c29d10b80814b3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 13 Apr 2009 11:27:03 +0100 Subject: [PATCH 0264/6080] ASoC: Support DAPM events for DACs and ADCs Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 10 ++++++++++ sound/soc/soc-dapm.c | 16 ++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index a7def6a9a030..fcc929da0339 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -140,9 +140,19 @@ #define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \ { .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \ .shift = wshift, .invert = winvert} +#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \ + wevent, wflags) \ +{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \ + .shift = wshift, .invert = winvert, \ + .event = wevent, .event_flags = wflags} #define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \ { .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \ .shift = wshift, .invert = winvert} +#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \ + wevent, wflags) \ +{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \ + .shift = wshift, .invert = winvert, \ + .event = wevent, .event_flags = wflags} /* generic register modifier widget */ #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 713d12586705..a6d73379ab32 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -598,18 +598,22 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event, if (w->id == snd_soc_dapm_adc && w->active) { in = is_connected_input_ep(w); dapm_clear_walk(w->codec); - w->power = (in != 0) ? 1 : 0; - dapm_update_bits(w); - return 0; + power = (in != 0) ? 1 : 0; + if (power == w->power) + return 0; + w->power = power; + return dapm_generic_apply_power(w); } /* active DAC */ if (w->id == snd_soc_dapm_dac && w->active) { out = is_connected_output_ep(w); dapm_clear_walk(w->codec); - w->power = (out != 0) ? 1 : 0; - dapm_update_bits(w); - return 0; + power = (out != 0) ? 1 : 0; + if (power == w->power) + return 0; + w->power = power; + return dapm_generic_apply_power(w); } /* pre and post event widgets */ -- GitLab From 6bbcb459cd50807511491ddf96bca1ef92006bf8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 13 Apr 2009 11:29:10 +0100 Subject: [PATCH 0265/6080] ASoC: Move the WM9713 voice DAC powerdown to a DAPM event This ensures that we sync with the DAPM powerdown sequencing properly and don't need to bounce the power on the voice DAC so often. Signed-off-by: Mark Brown --- sound/soc/codecs/wm9713.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index aa94cc68f0c0..a6feb7842314 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -189,6 +189,26 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), }; +static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + u16 status, rate; + + BUG_ON(event != SND_SOC_DAPM_PRE_PMD); + + /* Gracefully shut down the voice interface. */ + status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000; + rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF; + ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200); + schedule_timeout_interruptible(msecs_to_jiffies(1)); + ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00); + ac97_write(codec, AC97_EXTENDED_MID, status); + + return 0; +} + + /* We have to create a fake left and right HP mixers because * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path using the current @@ -400,7 +420,8 @@ SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1), +SND_SOC_DAPM_DAC_E("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1, + wm9713_voice_shutdown, SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1), SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0), SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0), @@ -936,21 +957,6 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } -static void wm9713_voiceshutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - u16 status, rate; - - /* Gracefully shut down the voice interface. */ - status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000; - rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF; - ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200); - schedule_timeout_interruptible(msecs_to_jiffies(1)); - ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00); - ac97_write(codec, AC97_EXTENDED_MID, status); -} - static int ac97_hifi_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -1019,7 +1025,6 @@ static struct snd_soc_dai_ops wm9713_dai_ops_aux = { static struct snd_soc_dai_ops wm9713_dai_ops_voice = { .hw_params = wm9713_pcm_hw_params, - .shutdown = wm9713_voiceshutdown, .set_clkdiv = wm9713_set_dai_clkdiv, .set_pll = wm9713_set_dai_pll, .set_fmt = wm9713_set_dai_fmt, -- GitLab From a820532002e70e3a06f1ea7133e9b02443d07382 Mon Sep 17 00:00:00 2001 From: Daniel Ribeiro Date: Wed, 8 Apr 2009 10:51:24 -0300 Subject: [PATCH 0266/6080] ASoC: pxa-ssp.c fix clock/frame invert SCMODE(0): Data Driven (Falling), Data Sampled (Rising), Idle State (Low) SCMODE(1): Data Driven (Rising), Data Sampled (Falling), Idle State (Low) SCMODE(2): Data Driven (Rising), Data Sampled (Falling), Idle State (High) SCMODE(3): Data Driven (Falling), Data Sampled (Rising), Idle State (High) SCMODE(3) does not invert the clock polarity compared to the default SCMODE(0). This patch also adds all possible NF/IF, NB/IB combinations to the DSP_A and DSP_B modes. Signed-off-by: Daniel Ribeiro Signed-off-by: Mark Brown --- sound/soc/pxa/pxa-ssp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index c7c1996a5447..176af7ff234b 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -568,7 +568,10 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_NB_IF: break; case SND_SOC_DAIFMT_IB_IF: - sspsp |= SSPSP_SCMODE(3); + sspsp |= SSPSP_SCMODE(2); + break; + case SND_SOC_DAIFMT_IB_NF: + sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP; break; default: return -EINVAL; @@ -585,7 +588,13 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_NB_NF: sspsp |= SSPSP_SFRMP; break; + case SND_SOC_DAIFMT_NB_IF: + break; case SND_SOC_DAIFMT_IB_IF: + sspsp |= SSPSP_SCMODE(2); + break; + case SND_SOC_DAIFMT_IB_NF: + sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP; break; default: return -EINVAL; -- GitLab From f2644a2c00a06236a9c5e85488b0680825bad39c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Apr 2009 19:20:14 +0100 Subject: [PATCH 0267/6080] ASoC: Add WM8960 CODEC driver The WM8960 is a low power, high quality stereo codec designed for portable digital audio applications. Stereo class D speaker drivers provide 1W per channel into 8W loads. Guaranteed low leakage, excellent PSRR and pop/click suppression mechanisms enable direct battery connection for the speaker supply. The device also integrates a complete microphone interface and a stereo headphone driver. External component requirements are drastically reduced as no separate microphone, speaker or headphone amplifiers are required. Advanced on-chip digital signal processing performs automatic level control for the microphone or line input. Stereo 24-bit sigma-delta ADCs and DACs are used with low power over-sampling digital interpolation and decimation filters and a flexible digital audio interface. The master clock can be input directly or generated internally by an onboard PLL, supporting most commonly-used clocking schemes. This driver was originally written by Liam Girdwood, with substantial subsequent additions and updates for feature completeness and changes in the ASoC framework from me. Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm8960.c | 969 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8960.h | 127 +++++ 4 files changed, 1102 insertions(+) create mode 100644 sound/soc/codecs/wm8960.c create mode 100644 sound/soc/codecs/wm8960.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ab364854675b..121d63f13dbb 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -35,6 +35,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8900 if I2C select SND_SOC_WM8903 if I2C + select SND_SOC_WM8960 if I2C select SND_SOC_WM8971 if I2C select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8990 if I2C @@ -139,6 +140,9 @@ config SND_SOC_WM8900 config SND_SOC_WM8903 tristate +config SND_SOC_WM8960 + tristate + config SND_SOC_WM8971 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index a72548dc1885..d8e15a47711e 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -23,6 +23,7 @@ snd-soc-wm8750-objs := wm8750.o snd-soc-wm8753-objs := wm8753.o snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o +snd-soc-wm8960-objs := wm8960.o snd-soc-wm8971-objs := wm8971.o snd-soc-wm8988-objs := wm8988.o snd-soc-wm8990-objs := wm8990.o @@ -56,6 +57,7 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o +obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o obj-$(CONFIG_SND_SOC_WM8991) += snd-soc-wm8991.o diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c new file mode 100644 index 000000000000..e224d8add170 --- /dev/null +++ b/sound/soc/codecs/wm8960.c @@ -0,0 +1,969 @@ +/* + * wm8960.c -- WM8960 ALSA SoC Audio driver + * + * Author: Liam Girdwood + * + * 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 +#include + +#include "wm8960.h" + +#define AUDIO_NAME "wm8960" + +struct snd_soc_codec_device soc_codec_dev_wm8960; + +/* R25 - Power 1 */ +#define WM8960_VREF 0x40 + +/* R28 - Anti-pop 1 */ +#define WM8960_POBCTRL 0x80 +#define WM8960_BUFDCOPEN 0x10 +#define WM8960_BUFIOEN 0x08 +#define WM8960_SOFT_ST 0x04 +#define WM8960_HPSTBY 0x01 + +/* R29 - Anti-pop 2 */ +#define WM8960_DISOP 0x40 + +/* + * wm8960 register cache + * We can't read the WM8960 register space when we are + * using 2 wire for device control, so we cache them instead. + */ +static const u16 wm8960_reg[WM8960_CACHEREGNUM] = { + 0x0097, 0x0097, 0x0000, 0x0000, + 0x0000, 0x0008, 0x0000, 0x000a, + 0x01c0, 0x0000, 0x00ff, 0x00ff, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x007b, 0x0100, 0x0032, + 0x0000, 0x00c3, 0x00c3, 0x01c0, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0100, 0x0100, 0x0050, 0x0050, + 0x0050, 0x0050, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0040, 0x0000, + 0x0000, 0x0050, 0x0050, 0x0000, + 0x0002, 0x0037, 0x004d, 0x0080, + 0x0008, 0x0031, 0x0026, 0x00e9, +}; + +struct wm8960_priv { + u16 reg_cache[WM8960_CACHEREGNUM]; + struct snd_soc_codec codec; +}; + +/* + * read wm8960 register cache + */ +static inline unsigned int wm8960_read_reg_cache(struct snd_soc_codec *codec, + unsigned int reg) +{ + u16 *cache = codec->reg_cache; + if (reg == WM8960_RESET) + return 0; + if (reg >= WM8960_CACHEREGNUM) + return -1; + return cache[reg]; +} + +/* + * write wm8960 register cache + */ +static inline void wm8960_write_reg_cache(struct snd_soc_codec *codec, + u16 reg, unsigned int value) +{ + u16 *cache = codec->reg_cache; + if (reg >= WM8960_CACHEREGNUM) + return; + cache[reg] = value; +} + +static inline unsigned int wm8960_read(struct snd_soc_codec *codec, + unsigned int reg) +{ + return wm8960_read_reg_cache(codec, reg); +} + +/* + * write to the WM8960 register space + */ +static int wm8960_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + u8 data[2]; + + /* data is + * D15..D9 WM8960 register offset + * D8...D0 register data + */ + data[0] = (reg << 1) | ((value >> 8) & 0x0001); + data[1] = value & 0x00ff; + + wm8960_write_reg_cache(codec, reg, value); + if (codec->hw_write(codec->control_data, data, 2) == 2) + return 0; + else + return -EIO; +} + +#define wm8960_reset(c) wm8960_write(c, WM8960_RESET, 0) + +/* enumerated controls */ +static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; +static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted", + "Right Inverted", "Stereo Inversion"}; +static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"}; +static const char *wm8960_3d_lower_cutoff[] = {"Low", "High"}; +static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"}; +static const char *wm8960_alcmode[] = {"ALC", "Limiter"}; + +static const struct soc_enum wm8960_enum[] = { + SOC_ENUM_SINGLE(WM8960_DACCTL1, 1, 4, wm8960_deemph), + SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity), + SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity), + SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff), + SOC_ENUM_SINGLE(WM8960_3D, 5, 2, wm8960_3d_lower_cutoff), + SOC_ENUM_SINGLE(WM8960_ALC1, 7, 4, wm8960_alcfunc), + SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode), +}; + +static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0); +static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); +static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); +static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); + +static const struct snd_kcontrol_new wm8960_snd_controls[] = { +SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, + 0, 63, 0, adc_tlv), +SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL, + 6, 1, 0), +SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL, + 7, 1, 0), + +SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC, + 0, 255, 0, dac_tlv), + +SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8960_LOUT1, WM8960_ROUT1, + 0, 127, 0, out_tlv), +SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8960_LOUT1, WM8960_ROUT1, + 7, 1, 0), + +SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8960_LOUT2, WM8960_ROUT2, + 0, 127, 0, out_tlv), +SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8960_LOUT2, WM8960_ROUT2, + 7, 1, 0), +SOC_SINGLE("Speaker DC Volume", WM8960_CLASSD3, 3, 5, 0), +SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0), + +SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0), +SOC_ENUM("ADC Polarity", wm8960_enum[1]), +SOC_ENUM("Playback De-emphasis", wm8960_enum[0]), +SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0), + +SOC_ENUM("DAC Polarity", wm8960_enum[2]), + +SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[3]), +SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[4]), +SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0), +SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0), + +SOC_ENUM("ALC Function", wm8960_enum[5]), +SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0), +SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1), +SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0), +SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0), +SOC_ENUM("ALC Mode", wm8960_enum[6]), +SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0), +SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0), + +SOC_SINGLE("Noise Gate Threshold", WM8960_NOISEG, 3, 31, 0), +SOC_SINGLE("Noise Gate Switch", WM8960_NOISEG, 0, 1, 0), + +SOC_DOUBLE_R("ADC PCM Capture Volume", WM8960_LINPATH, WM8960_RINPATH, + 0, 127, 0), + +SOC_SINGLE_TLV("Left Output Mixer Boost Bypass Volume", + WM8960_BYPASS1, 4, 7, 1, bypass_tlv), +SOC_SINGLE_TLV("Left Output Mixer LINPUT3 Volume", + WM8960_LOUTMIX, 4, 7, 1, bypass_tlv), +SOC_SINGLE_TLV("Right Output Mixer Boost Bypass Volume", + WM8960_BYPASS2, 4, 7, 1, bypass_tlv), +SOC_SINGLE_TLV("Right Output Mixer RINPUT3 Volume", + WM8960_ROUTMIX, 4, 7, 1, bypass_tlv), +}; + +static const struct snd_kcontrol_new wm8960_lin_boost[] = { +SOC_DAPM_SINGLE("LINPUT2 Switch", WM8960_LINPATH, 6, 1, 0), +SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LINPATH, 7, 1, 0), +SOC_DAPM_SINGLE("LINPUT1 Switch", WM8960_LINPATH, 8, 1, 0), +}; + +static const struct snd_kcontrol_new wm8960_lin[] = { +SOC_DAPM_SINGLE("Boost Switch", WM8960_LINPATH, 3, 1, 0), +}; + +static const struct snd_kcontrol_new wm8960_rin_boost[] = { +SOC_DAPM_SINGLE("RINPUT2 Switch", WM8960_RINPATH, 6, 1, 0), +SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_RINPATH, 7, 1, 0), +SOC_DAPM_SINGLE("RINPUT1 Switch", WM8960_RINPATH, 8, 1, 0), +}; + +static const struct snd_kcontrol_new wm8960_rin[] = { +SOC_DAPM_SINGLE("Boost Switch", WM8960_RINPATH, 3, 1, 0), +}; + +static const struct snd_kcontrol_new wm8960_loutput_mixer[] = { +SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_LOUTMIX, 8, 1, 0), +SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LOUTMIX, 7, 1, 0), +SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS1, 7, 1, 0), +}; + +static const struct snd_kcontrol_new wm8960_routput_mixer[] = { +SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_ROUTMIX, 8, 1, 0), +SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_ROUTMIX, 7, 1, 0), +SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS2, 7, 1, 0), +}; + +static const struct snd_kcontrol_new wm8960_mono_out[] = { +SOC_DAPM_SINGLE("Left Switch", WM8960_MONOMIX1, 7, 1, 0), +SOC_DAPM_SINGLE("Right Switch", WM8960_MONOMIX2, 7, 1, 0), +}; + +static const struct snd_soc_dapm_widget wm8960_dapm_widgets[] = { +SND_SOC_DAPM_INPUT("LINPUT1"), +SND_SOC_DAPM_INPUT("RINPUT1"), +SND_SOC_DAPM_INPUT("LINPUT2"), +SND_SOC_DAPM_INPUT("RINPUT2"), +SND_SOC_DAPM_INPUT("LINPUT3"), +SND_SOC_DAPM_INPUT("RINPUT3"), + +SND_SOC_DAPM_MICBIAS("MICB", WM8960_POWER1, 1, 0), + +SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0, + wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)), +SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8960_POWER1, 4, 0, + wm8960_rin_boost, ARRAY_SIZE(wm8960_rin_boost)), + +SND_SOC_DAPM_MIXER("Left Input Mixer", WM8960_POWER3, 5, 0, + wm8960_lin, ARRAY_SIZE(wm8960_lin)), +SND_SOC_DAPM_MIXER("Right Input Mixer", WM8960_POWER3, 4, 0, + wm8960_rin, ARRAY_SIZE(wm8960_rin)), + +SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER2, 3, 0), +SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER2, 2, 0), + +SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0), +SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0), + +SND_SOC_DAPM_MIXER("Left Output Mixer", WM8960_POWER3, 3, 0, + &wm8960_loutput_mixer[0], + ARRAY_SIZE(wm8960_loutput_mixer)), +SND_SOC_DAPM_MIXER("Right Output Mixer", WM8960_POWER3, 2, 0, + &wm8960_routput_mixer[0], + ARRAY_SIZE(wm8960_routput_mixer)), + +SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0, + &wm8960_mono_out[0], + ARRAY_SIZE(wm8960_mono_out)), + +SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0), + +SND_SOC_DAPM_PGA("Left Speaker PGA", WM8960_POWER2, 4, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Speaker PGA", WM8960_POWER2, 3, 0, NULL, 0), + +SND_SOC_DAPM_PGA("Right Speaker Output", WM8960_CLASSD1, 7, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left Speaker Output", WM8960_CLASSD1, 6, 0, NULL, 0), + +SND_SOC_DAPM_OUTPUT("SPK_LP"), +SND_SOC_DAPM_OUTPUT("SPK_LN"), +SND_SOC_DAPM_OUTPUT("HP_L"), +SND_SOC_DAPM_OUTPUT("HP_R"), +SND_SOC_DAPM_OUTPUT("SPK_RP"), +SND_SOC_DAPM_OUTPUT("SPK_RN"), +SND_SOC_DAPM_OUTPUT("OUT3"), +}; + +static const struct snd_soc_dapm_route audio_paths[] = { + { "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" }, + { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" }, + { "Left Boost Mixer", "LINPUT3 Switch", "LINPUT3" }, + + { "Left Input Mixer", "Boost Switch", "Left Boost Mixer", }, + { "Left Input Mixer", NULL, "LINPUT1", }, /* Really Boost Switch */ + { "Left Input Mixer", NULL, "LINPUT2" }, + { "Left Input Mixer", NULL, "LINPUT3" }, + + { "Right Boost Mixer", "RINPUT1 Switch", "RINPUT1" }, + { "Right Boost Mixer", "RINPUT2 Switch", "RINPUT2" }, + { "Right Boost Mixer", "RINPUT3 Switch", "RINPUT3" }, + + { "Right Input Mixer", "Boost Switch", "Right Boost Mixer", }, + { "Right Input Mixer", NULL, "RINPUT1", }, /* Really Boost Switch */ + { "Right Input Mixer", NULL, "RINPUT2" }, + { "Right Input Mixer", NULL, "LINPUT3" }, + + { "Left ADC", NULL, "Left Input Mixer" }, + { "Right ADC", NULL, "Right Input Mixer" }, + + { "Left Output Mixer", "LINPUT3 Switch", "LINPUT3" }, + { "Left Output Mixer", "Boost Bypass Switch", "Left Boost Mixer"} , + { "Left Output Mixer", "PCM Playback Switch", "Left DAC" }, + + { "Right Output Mixer", "RINPUT3 Switch", "RINPUT3" }, + { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } , + { "Right Output Mixer", "PCM Playback Switch", "Right DAC" }, + + { "Mono Output Mixer", "Left Switch", "Left Output Mixer" }, + { "Mono Output Mixer", "Right Switch", "Right Output Mixer" }, + + { "LOUT1 PGA", NULL, "Left Output Mixer" }, + { "ROUT1 PGA", NULL, "Right Output Mixer" }, + + { "HP_L", NULL, "LOUT1 PGA" }, + { "HP_R", NULL, "ROUT1 PGA" }, + + { "Left Speaker PGA", NULL, "Left Output Mixer" }, + { "Right Speaker PGA", NULL, "Right Output Mixer" }, + + { "Left Speaker Output", NULL, "Left Speaker PGA" }, + { "Right Speaker Output", NULL, "Right Speaker PGA" }, + + { "SPK_LN", NULL, "Left Speaker Output" }, + { "SPK_LP", NULL, "Left Speaker Output" }, + { "SPK_RN", NULL, "Right Speaker Output" }, + { "SPK_RP", NULL, "Right Speaker Output" }, + + { "OUT3", NULL, "Mono Output Mixer", } +}; + +static int wm8960_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets, + ARRAY_SIZE(wm8960_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + + snd_soc_dapm_new_widgets(codec); + return 0; +} + +static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 iface = 0; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iface |= 0x0040; + break; + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface |= 0x0002; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + iface |= 0x0001; + break; + case SND_SOC_DAIFMT_DSP_A: + iface |= 0x0003; + break; + case SND_SOC_DAIFMT_DSP_B: + iface |= 0x0013; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + iface |= 0x0090; + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= 0x0080; + break; + case SND_SOC_DAIFMT_NB_IF: + iface |= 0x0010; + break; + default: + return -EINVAL; + } + + /* set iface */ + wm8960_write(codec, WM8960_IFACE1, iface); + return 0; +} + +static int wm8960_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + u16 iface = wm8960_read(codec, WM8960_IFACE1) & 0xfff3; + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + iface |= 0x0004; + break; + case SNDRV_PCM_FORMAT_S24_LE: + iface |= 0x0008; + break; + } + + /* set iface */ + wm8960_write(codec, WM8960_IFACE1, iface); + return 0; +} + +static int wm8960_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u16 mute_reg = wm8960_read(codec, WM8960_DACCTL1) & 0xfff7; + + if (mute) + wm8960_write(codec, WM8960_DACCTL1, mute_reg | 0x8); + else + wm8960_write(codec, WM8960_DACCTL1, mute_reg); + return 0; +} + +static int wm8960_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct wm8960_data *pdata = codec->dev->platform_data; + u16 reg; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* Set VMID to 2x50k */ + reg = wm8960_read(codec, WM8960_POWER1); + reg &= ~0x180; + reg |= 0x80; + wm8960_write(codec, WM8960_POWER1, reg); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->bias_level == SND_SOC_BIAS_OFF) { + /* Enable anti-pop features */ + wm8960_write(codec, WM8960_APOP1, + WM8960_POBCTRL | WM8960_SOFT_ST | + WM8960_BUFDCOPEN | WM8960_BUFIOEN); + + /* Discharge HP output */ + reg = WM8960_DISOP; + if (pdata) + reg |= pdata->dres << 4; + wm8960_write(codec, WM8960_APOP2, reg); + + msleep(400); + + wm8960_write(codec, WM8960_APOP2, 0); + + /* Enable & ramp VMID at 2x50k */ + reg = wm8960_read(codec, WM8960_POWER1); + reg |= 0x80; + wm8960_write(codec, WM8960_POWER1, reg); + msleep(100); + + /* Enable VREF */ + wm8960_write(codec, WM8960_POWER1, reg | WM8960_VREF); + + /* Disable anti-pop features */ + wm8960_write(codec, WM8960_APOP1, WM8960_BUFIOEN); + } + + /* Set VMID to 2x250k */ + reg = wm8960_read(codec, WM8960_POWER1); + reg &= ~0x180; + reg |= 0x100; + wm8960_write(codec, WM8960_POWER1, reg); + break; + + case SND_SOC_BIAS_OFF: + /* Enable anti-pop features */ + wm8960_write(codec, WM8960_APOP1, + WM8960_POBCTRL | WM8960_SOFT_ST | + WM8960_BUFDCOPEN | WM8960_BUFIOEN); + + /* Disable VMID and VREF, let them discharge */ + wm8960_write(codec, WM8960_POWER1, 0); + msleep(600); + + wm8960_write(codec, WM8960_APOP1, 0); + break; + } + + codec->bias_level = level; + + return 0; +} + +/* PLL divisors */ +struct _pll_div { + u32 pre_div:1; + u32 n:4; + u32 k:24; +}; + +/* The size in bits of the pll divide multiplied by 10 + * to allow rounding later */ +#define FIXED_PLL_SIZE ((1 << 24) * 10) + +static int pll_factors(unsigned int source, unsigned int target, + struct _pll_div *pll_div) +{ + unsigned long long Kpart; + unsigned int K, Ndiv, Nmod; + + pr_debug("WM8960 PLL: setting %dHz->%dHz\n", source, target); + + /* Scale up target to PLL operating frequency */ + target *= 4; + + Ndiv = target / source; + if (Ndiv < 6) { + source >>= 1; + pll_div->pre_div = 1; + Ndiv = target / source; + } else + pll_div->pre_div = 0; + + if ((Ndiv < 6) || (Ndiv > 12)) { + pr_err("WM8960 PLL: Unsupported N=%d\n", Ndiv); + return -EINVAL; + } + + pll_div->n = Ndiv; + Nmod = target % source; + Kpart = FIXED_PLL_SIZE * (long long)Nmod; + + do_div(Kpart, source); + + K = Kpart & 0xFFFFFFFF; + + /* Check if we need to round */ + if ((K % 10) >= 5) + K += 5; + + /* Move down to proper range now rounding is done */ + K /= 10; + + pll_div->k = K; + + pr_debug("WM8960 PLL: N=%x K=%x pre_div=%d\n", + pll_div->n, pll_div->k, pll_div->pre_div); + + return 0; +} + +static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, + int pll_id, unsigned int freq_in, unsigned int freq_out) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 reg; + static struct _pll_div pll_div; + int ret; + + if (freq_in && freq_out) { + ret = pll_factors(freq_in, freq_out, &pll_div); + if (ret != 0) + return ret; + } + + /* Disable the PLL: even if we are changing the frequency the + * PLL needs to be disabled while we do so. */ + wm8960_write(codec, WM8960_CLOCK1, + wm8960_read(codec, WM8960_CLOCK1) & ~1); + wm8960_write(codec, WM8960_POWER2, + wm8960_read(codec, WM8960_POWER2) & ~1); + + if (!freq_in || !freq_out) + return 0; + + reg = wm8960_read(codec, WM8960_PLL1) & ~0x3f; + reg |= pll_div.pre_div << 4; + reg |= pll_div.n; + + if (pll_div.k) { + reg |= 0x20; + + wm8960_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f); + wm8960_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff); + wm8960_write(codec, WM8960_PLL4, pll_div.k & 0x1ff); + } + wm8960_write(codec, WM8960_PLL1, reg); + + /* Turn it on */ + wm8960_write(codec, WM8960_POWER2, + wm8960_read(codec, WM8960_POWER2) | 1); + msleep(250); + wm8960_write(codec, WM8960_CLOCK1, + wm8960_read(codec, WM8960_CLOCK1) | 1); + + return 0; +} + +static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai, + int div_id, int div) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 reg; + + switch (div_id) { + case WM8960_SYSCLKSEL: + reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1fe; + wm8960_write(codec, WM8960_CLOCK1, reg | div); + break; + case WM8960_SYSCLKDIV: + reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1f9; + wm8960_write(codec, WM8960_CLOCK1, reg | div); + break; + case WM8960_DACDIV: + reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1c7; + wm8960_write(codec, WM8960_CLOCK1, reg | div); + break; + case WM8960_OPCLKDIV: + reg = wm8960_read(codec, WM8960_PLL1) & 0x03f; + wm8960_write(codec, WM8960_PLL1, reg | div); + break; + case WM8960_DCLKDIV: + reg = wm8960_read(codec, WM8960_CLOCK2) & 0x03f; + wm8960_write(codec, WM8960_CLOCK2, reg | div); + break; + case WM8960_TOCLKSEL: + reg = wm8960_read(codec, WM8960_ADDCTL1) & 0x1fd; + wm8960_write(codec, WM8960_ADDCTL1, reg | div); + break; + default: + return -EINVAL; + } + + return 0; +} + +#define WM8960_RATES SNDRV_PCM_RATE_8000_48000 + +#define WM8960_FORMATS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +static struct snd_soc_dai_ops wm8960_dai_ops = { + .hw_params = wm8960_hw_params, + .digital_mute = wm8960_mute, + .set_fmt = wm8960_set_dai_fmt, + .set_clkdiv = wm8960_set_dai_clkdiv, + .set_pll = wm8960_set_dai_pll, +}; + +struct snd_soc_dai wm8960_dai = { + .name = "WM8960", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8960_RATES, + .formats = WM8960_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8960_RATES, + .formats = WM8960_FORMATS,}, + .ops = &wm8960_dai_ops, + .symmetric_rates = 1, +}; +EXPORT_SYMBOL_GPL(wm8960_dai); + +static int wm8960_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + wm8960_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int wm8960_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + int i; + u8 data[2]; + u16 *cache = codec->reg_cache; + + /* Sync reg_cache with the hardware */ + for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) { + data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); + data[1] = cache[i] & 0x00ff; + codec->hw_write(codec->control_data, data, 2); + } + + wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + wm8960_set_bias_level(codec, codec->suspend_bias_level); + return 0; +} + +static struct snd_soc_codec *wm8960_codec; + +static int wm8960_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec; + int ret = 0; + + if (wm8960_codec == NULL) { + dev_err(&pdev->dev, "Codec device not registered\n"); + return -ENODEV; + } + + socdev->card->codec = wm8960_codec; + codec = wm8960_codec; + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + dev_err(codec->dev, "failed to create pcms: %d\n", ret); + goto pcm_err; + } + + snd_soc_add_controls(codec, wm8960_snd_controls, + ARRAY_SIZE(wm8960_snd_controls)); + wm8960_add_widgets(codec); + ret = snd_soc_init_card(socdev); + if (ret < 0) { + dev_err(codec->dev, "failed to register card: %d\n", ret); + goto card_err; + } + + return ret; + +card_err: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +pcm_err: + return ret; +} + +/* power down chip */ +static int wm8960_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_wm8960 = { + .probe = wm8960_probe, + .remove = wm8960_remove, + .suspend = wm8960_suspend, + .resume = wm8960_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960); + +static int wm8960_register(struct wm8960_priv *wm8960) +{ + struct wm8960_data *pdata = wm8960->codec.dev->platform_data; + struct snd_soc_codec *codec = &wm8960->codec; + int ret; + u16 reg; + + if (wm8960_codec) { + dev_err(codec->dev, "Another WM8960 is registered\n"); + return -EINVAL; + } + + if (!pdata) { + dev_warn(codec->dev, "No platform data supplied\n"); + } else { + if (pdata->dres > WM8960_DRES_MAX) { + dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres); + pdata->dres = 0; + } + } + + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + + codec->private_data = wm8960; + codec->name = "WM8960"; + codec->owner = THIS_MODULE; + codec->read = wm8960_read_reg_cache; + codec->write = wm8960_write; + codec->bias_level = SND_SOC_BIAS_OFF; + codec->set_bias_level = wm8960_set_bias_level; + codec->dai = &wm8960_dai; + codec->num_dai = 1; + codec->reg_cache_size = WM8960_CACHEREGNUM; + codec->reg_cache = &wm8960->reg_cache; + + memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg)); + + ret = wm8960_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset\n"); + return ret; + } + + wm8960_dai.dev = codec->dev; + + wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* Latch the update bits */ + reg = wm8960_read(codec, WM8960_LINVOL); + wm8960_write(codec, WM8960_LINVOL, reg | 0x100); + reg = wm8960_read(codec, WM8960_RINVOL); + wm8960_write(codec, WM8960_RINVOL, reg | 0x100); + reg = wm8960_read(codec, WM8960_LADC); + wm8960_write(codec, WM8960_LADC, reg | 0x100); + reg = wm8960_read(codec, WM8960_RADC); + wm8960_write(codec, WM8960_RADC, reg | 0x100); + reg = wm8960_read(codec, WM8960_LDAC); + wm8960_write(codec, WM8960_LDAC, reg | 0x100); + reg = wm8960_read(codec, WM8960_RDAC); + wm8960_write(codec, WM8960_RDAC, reg | 0x100); + reg = wm8960_read(codec, WM8960_LOUT1); + wm8960_write(codec, WM8960_LOUT1, reg | 0x100); + reg = wm8960_read(codec, WM8960_ROUT1); + wm8960_write(codec, WM8960_ROUT1, reg | 0x100); + reg = wm8960_read(codec, WM8960_LOUT2); + wm8960_write(codec, WM8960_LOUT2, reg | 0x100); + reg = wm8960_read(codec, WM8960_ROUT2); + wm8960_write(codec, WM8960_ROUT2, reg | 0x100); + + wm8960_codec = codec; + + ret = snd_soc_register_codec(codec); + if (ret != 0) { + dev_err(codec->dev, "Failed to register codec: %d\n", ret); + return ret; + } + + ret = snd_soc_register_dai(&wm8960_dai); + if (ret != 0) { + dev_err(codec->dev, "Failed to register DAI: %d\n", ret); + snd_soc_unregister_codec(codec); + return ret; + } + + return 0; +} + +static void wm8960_unregister(struct wm8960_priv *wm8960) +{ + wm8960_set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF); + snd_soc_unregister_dai(&wm8960_dai); + snd_soc_unregister_codec(&wm8960->codec); + kfree(wm8960); + wm8960_codec = NULL; +} + +static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8960_priv *wm8960; + struct snd_soc_codec *codec; + + wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL); + if (wm8960 == NULL) + return -ENOMEM; + + codec = &wm8960->codec; + codec->hw_write = (hw_write_t)i2c_master_send; + + i2c_set_clientdata(i2c, wm8960); + codec->control_data = i2c; + + codec->dev = &i2c->dev; + + return wm8960_register(wm8960); +} + +static __devexit int wm8960_i2c_remove(struct i2c_client *client) +{ + struct wm8960_priv *wm8960 = i2c_get_clientdata(client); + wm8960_unregister(wm8960); + return 0; +} + +static const struct i2c_device_id wm8960_i2c_id[] = { + { "wm8960", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id); + +static struct i2c_driver wm8960_i2c_driver = { + .driver = { + .name = "WM8960 I2C Codec", + .owner = THIS_MODULE, + }, + .probe = wm8960_i2c_probe, + .remove = __devexit_p(wm8960_i2c_remove), + .id_table = wm8960_i2c_id, +}; + +static int __init wm8960_modinit(void) +{ + int ret; + + ret = i2c_add_driver(&wm8960_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n", + ret); + } + + return ret; +} +module_init(wm8960_modinit); + +static void __exit wm8960_exit(void) +{ + i2c_del_driver(&wm8960_i2c_driver); +} +module_exit(wm8960_exit); + + +MODULE_DESCRIPTION("ASoC WM8960 driver"); +MODULE_AUTHOR("Liam Girdwood"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8960.h b/sound/soc/codecs/wm8960.h new file mode 100644 index 000000000000..c9af56c9d9d4 --- /dev/null +++ b/sound/soc/codecs/wm8960.h @@ -0,0 +1,127 @@ +/* + * wm8960.h -- WM8960 Soc Audio driver + * + * 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 _WM8960_H +#define _WM8960_H + +/* WM8960 register space */ + + +#define WM8960_CACHEREGNUM 56 + +#define WM8960_LINVOL 0x0 +#define WM8960_RINVOL 0x1 +#define WM8960_LOUT1 0x2 +#define WM8960_ROUT1 0x3 +#define WM8960_CLOCK1 0x4 +#define WM8960_DACCTL1 0x5 +#define WM8960_DACCTL2 0x6 +#define WM8960_IFACE1 0x7 +#define WM8960_CLOCK2 0x8 +#define WM8960_IFACE2 0x9 +#define WM8960_LDAC 0xa +#define WM8960_RDAC 0xb + +#define WM8960_RESET 0xf +#define WM8960_3D 0x10 +#define WM8960_ALC1 0x11 +#define WM8960_ALC2 0x12 +#define WM8960_ALC3 0x13 +#define WM8960_NOISEG 0x14 +#define WM8960_LADC 0x15 +#define WM8960_RADC 0x16 +#define WM8960_ADDCTL1 0x17 +#define WM8960_ADDCTL2 0x18 +#define WM8960_POWER1 0x19 +#define WM8960_POWER2 0x1a +#define WM8960_ADDCTL3 0x1b +#define WM8960_APOP1 0x1c +#define WM8960_APOP2 0x1d + +#define WM8960_LINPATH 0x20 +#define WM8960_RINPATH 0x21 +#define WM8960_LOUTMIX 0x22 + +#define WM8960_ROUTMIX 0x25 +#define WM8960_MONOMIX1 0x26 +#define WM8960_MONOMIX2 0x27 +#define WM8960_LOUT2 0x28 +#define WM8960_ROUT2 0x29 +#define WM8960_MONO 0x2a +#define WM8960_INBMIX1 0x2b +#define WM8960_INBMIX2 0x2c +#define WM8960_BYPASS1 0x2d +#define WM8960_BYPASS2 0x2e +#define WM8960_POWER3 0x2f +#define WM8960_ADDCTL4 0x30 +#define WM8960_CLASSD1 0x31 + +#define WM8960_CLASSD3 0x33 +#define WM8960_PLL1 0x34 +#define WM8960_PLL2 0x35 +#define WM8960_PLL3 0x36 +#define WM8960_PLL4 0x37 + + +/* + * WM8960 Clock dividers + */ +#define WM8960_SYSCLKDIV 0 +#define WM8960_DACDIV 1 +#define WM8960_OPCLKDIV 2 +#define WM8960_DCLKDIV 3 +#define WM8960_TOCLKSEL 4 +#define WM8960_SYSCLKSEL 5 + +#define WM8960_SYSCLK_DIV_1 (0 << 1) +#define WM8960_SYSCLK_DIV_2 (2 << 1) + +#define WM8960_SYSCLK_MCLK (0 << 0) +#define WM8960_SYSCLK_PLL (1 << 0) + +#define WM8960_DAC_DIV_1 (0 << 3) +#define WM8960_DAC_DIV_1_5 (1 << 3) +#define WM8960_DAC_DIV_2 (2 << 3) +#define WM8960_DAC_DIV_3 (3 << 3) +#define WM8960_DAC_DIV_4 (4 << 3) +#define WM8960_DAC_DIV_5_5 (5 << 3) +#define WM8960_DAC_DIV_6 (6 << 3) + +#define WM8960_DCLK_DIV_1_5 (0 << 6) +#define WM8960_DCLK_DIV_2 (1 << 6) +#define WM8960_DCLK_DIV_3 (2 << 6) +#define WM8960_DCLK_DIV_4 (3 << 6) +#define WM8960_DCLK_DIV_6 (4 << 6) +#define WM8960_DCLK_DIV_8 (5 << 6) +#define WM8960_DCLK_DIV_12 (6 << 6) +#define WM8960_DCLK_DIV_16 (7 << 6) + +#define WM8960_TOCLK_F19 (0 << 1) +#define WM8960_TOCLK_F21 (1 << 1) + +#define WM8960_OPCLK_DIV_1 (0 << 0) +#define WM8960_OPCLK_DIV_2 (1 << 0) +#define WM8960_OPCLK_DIV_3 (2 << 0) +#define WM8960_OPCLK_DIV_4 (3 << 0) +#define WM8960_OPCLK_DIV_5_5 (4 << 0) +#define WM8960_OPCLK_DIV_6 (5 << 0) + +extern struct snd_soc_dai wm8960_dai; +extern struct snd_soc_codec_device soc_codec_dev_wm8960; + +#define WM8960_DRES_400R 0 +#define WM8960_DRES_200R 1 +#define WM8960_DRES_600R 2 +#define WM8960_DRES_150R 3 +#define WM8960_DRES_MAX 3 + +struct wm8960_data { + int dres; +}; + +#endif -- GitLab From 0f3fd87ce43727d6b8573191ce89e874533b1429 Mon Sep 17 00:00:00 2001 From: Luis Henriques Date: Mon, 13 Apr 2009 20:24:50 +0100 Subject: [PATCH 0268/6080] perf_counter: fix alignment in /proc/interrupts Trivial fix on columns alignment in /proc/interrupts file. Signed-off-by: Luis Henriques Cc: Peter Zijlstra LKML-Reference: <20090413192449.GA3920@hades.domain.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index dccaaa855789..849cfabb1fdc 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -67,7 +67,7 @@ static int show_other_interrupts(struct seq_file *p, int prec) for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs); seq_printf(p, " Performance counter interrupts\n"); - seq_printf(p, "PND: "); + seq_printf(p, "%*s: ", prec, "PND"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs); seq_printf(p, " Performance pending work\n"); -- GitLab From 728a9972d1f290608e730b9ccec2061aa81f6609 Mon Sep 17 00:00:00 2001 From: Ajit Khaparde Date: Mon, 13 Apr 2009 15:41:22 -0700 Subject: [PATCH 0269/6080] be2net: changes for checksum and segmentation offload - Enables Rx checksum feature by default. - Disables support for ipv6 tso. - Changes in Rx path to handle Rx completions with various checksum options. Signed-off-by: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/benet/be_main.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 9b75aa630062..8994b03d80ac 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -637,6 +637,22 @@ static void be_rx_stats_update(struct be_adapter *adapter, stats->be_rx_bytes += pktsize; } +static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) +{ + u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk; + + l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); + ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp); + ip_version = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp); + if (ip_version) { + tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); + udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp); + } + ipv6_chk = (ip_version && (tcpf || udpf)); + + return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true; +} + static struct be_rx_page_info * get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) { @@ -752,9 +768,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, { struct sk_buff *skb; u32 vtp, vid; - int l4_cksm; - l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN); @@ -769,10 +783,10 @@ static void be_rx_compl_process(struct be_adapter *adapter, skb_fill_rx_data(adapter, skb, rxcp); - if (l4_cksm && adapter->rx_csum) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else + if (do_pkt_csum(rxcp, adapter->rx_csum)) skb->ip_summed = CHECKSUM_NONE; + else + skb->ip_summed = CHECKSUM_UNNECESSARY; skb->truesize = skb->len + sizeof(struct sk_buff); skb->protocol = eth_type_trans(skb, adapter->netdev); @@ -1626,10 +1640,12 @@ static void be_netdev_init(struct net_device *netdev) netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_TSO6; + NETIF_F_IPV6_CSUM; netdev->flags |= IFF_MULTICAST; + adapter->rx_csum = true; + BE_SET_NETDEV_OPS(netdev, &be_netdev_ops); SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); -- GitLab From 54cb2284dce50672c40248b8e95940318ec2ca41 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 8 Apr 2009 22:16:38 +0000 Subject: [PATCH 0270/6080] at76c50x-usb: remove pointless conditional before kfree_skb() Remove pointless conditional before kfree_skb(). Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- drivers/net/wireless/at76c50x-usb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 0c02f1c2bd94..c220c9758d09 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c @@ -2309,8 +2309,7 @@ static void at76_delete_device(struct at76_priv *priv) del_timer_sync(&ledtrig_tx_timer); - if (priv->rx_skb) - kfree_skb(priv->rx_skb); + kfree_skb(priv->rx_skb); usb_put_dev(priv->udev); -- GitLab From 710b523ac59426e8bfdea3533f42118e46b9cbfb Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 9 Apr 2009 07:11:55 +0000 Subject: [PATCH 0271/6080] kaweth: Clean up code The driver kaweth yields a -EBUSY error when starting, and a -ETIME error when shutting down. These errors are avoided, and the RX status is further checked for other potential errors. Signed-off-by: Larry Finger Signed-off-by: David S. Miller --- drivers/net/usb/kaweth.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 3d0d0b0b37c5..e01314789718 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -31,7 +31,6 @@ ****************************************************************/ /* TODO: - * Fix in_interrupt() problem * Develop test procedures for USB net interfaces * Run test procedures * Fix bugs from previous two steps @@ -606,14 +605,30 @@ static void kaweth_usb_receive(struct urb *urb) struct sk_buff *skb; - if(unlikely(status == -ECONNRESET || status == -ESHUTDOWN)) - /* we are killed - set a flag and wake the disconnect handler */ - { + if (unlikely(status == -EPIPE)) { + kaweth->stats.rx_errors++; kaweth->end = 1; wake_up(&kaweth->term_wait); + dbg("Status was -EPIPE."); return; } - + if (unlikely(status == -ECONNRESET || status == -ESHUTDOWN)) { + /* we are killed - set a flag and wake the disconnect handler */ + kaweth->end = 1; + wake_up(&kaweth->term_wait); + dbg("Status was -ECONNRESET or -ESHUTDOWN."); + return; + } + if (unlikely(status == -EPROTO || status == -ETIME || + status == -EILSEQ)) { + kaweth->stats.rx_errors++; + dbg("Status was -EPROTO, -ETIME, or -EILSEQ."); + return; + } + if (unlikely(status == -EOVERFLOW)) { + kaweth->stats.rx_errors++; + dbg("Status was -EOVERFLOW."); + } spin_lock(&kaweth->device_lock); if (IS_BLOCKED(kaweth->status)) { spin_unlock(&kaweth->device_lock); @@ -883,13 +898,16 @@ static void kaweth_set_rx_mode(struct net_device *net) ****************************************************************/ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth) { + int result; __u16 packet_filter_bitmap = kaweth->packet_filter_bitmap; + kaweth->packet_filter_bitmap = 0; if (packet_filter_bitmap == 0) return; - { - int result; + if (in_interrupt()) + return; + result = kaweth_control(kaweth, usb_sndctrlpipe(kaweth->dev, 0), KAWETH_COMMAND_SET_PACKET_FILTER, @@ -906,7 +924,6 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth) else { dbg("Set Rx mode to %d", packet_filter_bitmap); } - } } /**************************************************************** -- GitLab From 0ee904c35cc3fdd26a9c76077d9692d458309186 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sat, 11 Apr 2009 14:50:23 +0000 Subject: [PATCH 0272/6080] drivers/net: replace BUG() with BUG_ON() if possible Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/atl1e/atl1e_main.c | 3 +-- drivers/net/atlx/atl1.c | 7 +++---- drivers/net/chelsio/sge.c | 4 ++-- drivers/net/fs_enet/mii-fec.c | 6 ++---- drivers/net/ixgb/ixgb_osdep.h | 2 +- drivers/net/pppol2tp.c | 3 +-- drivers/net/tulip/winbond-840.c | 3 +-- drivers/net/virtio_net.c | 12 ++++-------- drivers/net/wireless/ath5k/reset.c | 5 ++--- drivers/net/wireless/ath9k/ath9k.h | 6 +----- drivers/net/wireless/ipw2x00/ipw2200.c | 7 ++----- drivers/net/wireless/libertas/if_usb.c | 3 +-- drivers/net/wireless/libertas_tf/if_usb.c | 3 +-- 13 files changed, 22 insertions(+), 42 deletions(-) diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index fb57b750866b..adac06195c8f 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -1794,8 +1794,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc)); tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd); - if (tx_buffer->skb) - BUG(); + BUG_ON(tx_buffer->skb); tx_buffer->skb = NULL; tx_buffer->length = diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 0ab22540bf59..13f0bdc32449 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -2207,8 +2207,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, nr_frags = skb_shinfo(skb)->nr_frags; next_to_use = atomic_read(&tpd_ring->next_to_use); buffer_info = &tpd_ring->buffer_info[next_to_use]; - if (unlikely(buffer_info->skb)) - BUG(); + BUG_ON(buffer_info->skb); /* put skb in last TPD */ buffer_info->skb = NULL; @@ -2274,8 +2273,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb, ATL1_MAX_TX_BUF_LEN; for (i = 0; i < nseg; i++) { buffer_info = &tpd_ring->buffer_info[next_to_use]; - if (unlikely(buffer_info->skb)) - BUG(); + BUG_ON(buffer_info->skb); + buffer_info->skb = NULL; buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ? ATL1_MAX_TX_BUF_LEN : buf_len; diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 58f6fc055f6a..5e97a1a71d88 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1149,8 +1149,8 @@ static inline void write_tx_desc(struct cmdQ_e *e, dma_addr_t mapping, unsigned int len, unsigned int gen, unsigned int eop) { - if (unlikely(len > SGE_TX_DESC_MAX_PLEN)) - BUG(); + BUG_ON(len > SGE_TX_DESC_MAX_PLEN); + e->addr_lo = (u32)mapping; e->addr_hi = (u64)mapping >> 32; e->len_gen = V_CMD_LEN(len) | V_CMD_GEN1(gen); diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 28077cc1b949..61aaae444b40 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -54,8 +54,7 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location) fec_t __iomem *fecp = fec->fecp; int i, ret = -1; - if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) - BUG(); + BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0); /* Add PHY address to register command. */ out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_read(location)); @@ -79,8 +78,7 @@ static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, int i; /* this must never happen */ - if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0) - BUG(); + BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0); /* Add PHY address to register command. */ out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_write(location, val)); diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h index d92e72bd627a..371a6be4d965 100644 --- a/drivers/net/ixgb/ixgb_osdep.h +++ b/drivers/net/ixgb/ixgb_osdep.h @@ -40,7 +40,7 @@ #include #undef ASSERT -#define ASSERT(x) if (!(x)) BUG() +#define ASSERT(x) BUG_ON(!(x)) #define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B) #ifdef DBG diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 5b07dd8e5c04..5981debcde5e 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -1238,8 +1238,7 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel) struct pppol2tp_session *session; struct sock *sk; - if (tunnel == NULL) - BUG(); + BUG_ON(tunnel == NULL); PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, "%s: closing all sessions...\n", tunnel->name); diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 264e61404f34..842b1a2c40d4 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -1601,8 +1601,7 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state) /* no more hardware accesses behind this line. */ - BUG_ON(np->csr6); - if (ioread32(ioaddr + IntrEnable)) BUG(); + BUG_ON(np->csr6 || ioread32(ioaddr + IntrEnable)); /* pci_power_off(pdev, -1); */ diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 9c82a39497e5..071855871524 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -621,12 +621,9 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, virtio_net_ctrl_ack status = ~0; unsigned int tmp; - if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) { - BUG(); /* Caller should know better */ - return false; - } - - BUG_ON(out + in > VIRTNET_SEND_COMMAND_SG_MAX); + /* Caller should know better */ + BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) || + (out + in > VIRTNET_SEND_COMMAND_SG_MAX)); out++; /* Add header */ in++; /* Add return status */ @@ -640,8 +637,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, memcpy(&sg[1], data, sizeof(struct scatterlist) * (out + in - 2)); sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); - if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0) - BUG(); + BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi)); vi->cvq->vq_ops->kick(vi->cvq); diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c index 7a17d31b2fd9..cb5e15f97095 100644 --- a/drivers/net/wireless/ath5k/reset.c +++ b/drivers/net/wireless/ath5k/reset.c @@ -54,9 +54,8 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, u32 coef_scaled, coef_exp, coef_man, ds_coef_exp, ds_coef_man, clock; - if (!(ah->ah_version == AR5K_AR5212) || - !(channel->hw_value & CHANNEL_OFDM)) - BUG(); + BUG_ON(!(ah->ah_version == AR5K_AR5212) || + !(channel->hw_value & CHANNEL_OFDM)); /* Get coefficient * ALGO: coef = (5 * clock * carrier_freq) / 2) diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 2689a08a2844..7b1b40aaf09d 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -53,11 +53,7 @@ struct ath_node; #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) -#define ASSERT(exp) do { \ - if (unlikely(!(exp))) { \ - BUG(); \ - } \ - } while (0) +#define ASSERT(exp) BUG_ON(!(exp)) #define TSF_TO_TU(_h,_l) \ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index bd4dbcfe1bbe..9a123fbcc359 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -3176,11 +3176,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) /* Start the Dma */ rc = ipw_fw_dma_enable(priv); - if (priv->sram_desc.last_cb_index > 0) { - /* the DMA is already ready this would be a bug. */ - BUG(); - goto out; - } + /* the DMA is already ready this would be a bug. */ + BUG_ON(priv->sram_desc.last_cb_index > 0); do { chunk = (struct fw_chunk *)(data + offset); diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index ea3dc038be76..d649caebf08a 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -686,8 +686,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, return; } - if (!in_interrupt()) - BUG(); + BUG_ON(!in_interrupt()); spin_lock(&priv->driver_lock); diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index 59634c33b1f9..392337b37b1d 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -461,8 +461,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, return; } - if (!in_interrupt()) - BUG(); + BUG_ON(!in_interrupt()); spin_lock(&priv->driver_lock); memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN, -- GitLab From 6e837fb152410e571a81aaadbd9884f0bc46a55e Mon Sep 17 00:00:00 2001 From: Etienne Basset Date: Wed, 8 Apr 2009 20:39:40 +0200 Subject: [PATCH 0273/6080] smack: implement logging V3 This patch creates auditing functions usable by LSM to audit security events. It provides standard dumping of FS, NET, task etc ... events (code borrowed from SELinux) and provides 2 callbacks to define LSM specific auditing, which should be flexible enough to convert SELinux too. Signed-off-by: Etienne Basset Acked-by: Casey Schaufler cked-by: Eric Paris Signed-off-by: James Morris --- include/linux/lsm_audit.h | 111 +++++++++++ security/lsm_audit.c | 386 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 497 insertions(+) create mode 100644 include/linux/lsm_audit.h create mode 100644 security/lsm_audit.c diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h new file mode 100644 index 000000000000..e461b2c3d711 --- /dev/null +++ b/include/linux/lsm_audit.h @@ -0,0 +1,111 @@ +/* + * Common LSM logging functions + * Heavily borrowed from selinux/avc.h + * + * Author : Etienne BASSET + * + * All credits to : Stephen Smalley, + * All BUGS to : Etienne BASSET + */ +#ifndef _LSM_COMMON_LOGGING_ +#define _LSM_COMMON_LOGGING_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Auxiliary data to use in generating the audit record. */ +struct common_audit_data { + char type; +#define LSM_AUDIT_DATA_FS 1 +#define LSM_AUDIT_DATA_NET 2 +#define LSM_AUDIT_DATA_CAP 3 +#define LSM_AUDIT_DATA_IPC 4 +#define LSM_AUDIT_DATA_TASK 5 +#define LSM_AUDIT_DATA_KEY 6 + struct task_struct *tsk; + union { + struct { + struct path path; + struct inode *inode; + } fs; + struct { + int netif; + struct sock *sk; + u16 family; + __be16 dport; + __be16 sport; + union { + struct { + __be32 daddr; + __be32 saddr; + } v4; + struct { + struct in6_addr daddr; + struct in6_addr saddr; + } v6; + } fam; + } net; + int cap; + int ipc_id; + struct task_struct *tsk; +#ifdef CONFIG_KEYS + struct { + key_serial_t key; + char *key_desc; + } key_struct; +#endif + } u; + const char *function; + /* this union contains LSM specific data */ + union { + /* SMACK data */ + struct smack_audit_data { + char *subject; + char *object; + char *request; + int result; + } smack_audit_data; + /* SELinux data */ + struct { + u32 ssid; + u32 tsid; + u16 tclass; + u32 requested; + u32 audited; + struct av_decision *avd; + int result; + } selinux_audit_data; + } lsm_priv; + /* these callback will be implemented by a specific LSM */ + void (*lsm_pre_audit)(struct audit_buffer *, void *); + void (*lsm_post_audit)(struct audit_buffer *, void *); +}; + +#define v4info fam.v4 +#define v6info fam.v6 + +int ipv4_skb_to_auditdata(struct sk_buff *skb, + struct common_audit_data *ad, u8 *proto); + +int ipv6_skb_to_auditdata(struct sk_buff *skb, + struct common_audit_data *ad, u8 *proto); + +/* Initialize an LSM audit data structure. */ +#define COMMON_AUDIT_DATA_INIT(_d, _t) \ + { memset((_d), 0, sizeof(struct common_audit_data)); \ + (_d)->type = LSM_AUDIT_DATA_##_t; (_d)->function = __func__; } + +void common_lsm_audit(struct common_audit_data *a); + +#endif diff --git a/security/lsm_audit.c b/security/lsm_audit.c new file mode 100644 index 000000000000..94b868494b31 --- /dev/null +++ b/security/lsm_audit.c @@ -0,0 +1,386 @@ +/* + * common LSM auditing functions + * + * Based on code written for SELinux by : + * Stephen Smalley, + * James Morris + * Author : Etienne Basset, + * + * 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 +#include +#include +#include +#include +#include + +/** + * ipv4_skb_to_auditdata : fill auditdata from skb + * @skb : the skb + * @ad : the audit data to fill + * @proto : the layer 4 protocol + * + * return 0 on success + */ +int ipv4_skb_to_auditdata(struct sk_buff *skb, + struct common_audit_data *ad, u8 *proto) +{ + int ret = 0; + struct iphdr *ih; + + ih = ip_hdr(skb); + if (ih == NULL) + return -EINVAL; + + ad->u.net.v4info.saddr = ih->saddr; + ad->u.net.v4info.daddr = ih->daddr; + + if (proto) + *proto = ih->protocol; + /* non initial fragment */ + if (ntohs(ih->frag_off) & IP_OFFSET) + return 0; + + switch (ih->protocol) { + case IPPROTO_TCP: { + struct tcphdr *th = tcp_hdr(skb); + if (th == NULL) + break; + + ad->u.net.sport = th->source; + ad->u.net.dport = th->dest; + break; + } + case IPPROTO_UDP: { + struct udphdr *uh = udp_hdr(skb); + if (uh == NULL) + break; + + ad->u.net.sport = uh->source; + ad->u.net.dport = uh->dest; + break; + } + case IPPROTO_DCCP: { + struct dccp_hdr *dh = dccp_hdr(skb); + if (dh == NULL) + break; + + ad->u.net.sport = dh->dccph_sport; + ad->u.net.dport = dh->dccph_dport; + break; + } + case IPPROTO_SCTP: { + struct sctphdr *sh = sctp_hdr(skb); + if (sh == NULL) + break; + ad->u.net.sport = sh->source; + ad->u.net.dport = sh->dest; + break; + } + default: + ret = -EINVAL; + } + return ret; +} +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +/** + * ipv6_skb_to_auditdata : fill auditdata from skb + * @skb : the skb + * @ad : the audit data to fill + * @proto : the layer 4 protocol + * + * return 0 on success + */ +int ipv6_skb_to_auditdata(struct sk_buff *skb, + struct common_audit_data *ad, u8 *proto) +{ + int offset, ret = 0; + struct ipv6hdr *ip6; + u8 nexthdr; + + ip6 = ipv6_hdr(skb); + if (ip6 == NULL) + return -EINVAL; + ipv6_addr_copy(&ad->u.net.v6info.saddr, &ip6->saddr); + ipv6_addr_copy(&ad->u.net.v6info.daddr, &ip6->daddr); + ret = 0; + /* IPv6 can have several extension header before the Transport header + * skip them */ + offset = skb_network_offset(skb); + offset += sizeof(*ip6); + nexthdr = ip6->nexthdr; + offset = ipv6_skip_exthdr(skb, offset, &nexthdr); + if (offset < 0) + return 0; + if (proto) + *proto = nexthdr; + switch (nexthdr) { + case IPPROTO_TCP: { + struct tcphdr _tcph, *th; + + th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph); + if (th == NULL) + break; + + ad->u.net.sport = th->source; + ad->u.net.dport = th->dest; + break; + } + case IPPROTO_UDP: { + struct udphdr _udph, *uh; + + uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph); + if (uh == NULL) + break; + + ad->u.net.sport = uh->source; + ad->u.net.dport = uh->dest; + break; + } + case IPPROTO_DCCP: { + struct dccp_hdr _dccph, *dh; + + dh = skb_header_pointer(skb, offset, sizeof(_dccph), &_dccph); + if (dh == NULL) + break; + + ad->u.net.sport = dh->dccph_sport; + ad->u.net.dport = dh->dccph_dport; + break; + } + case IPPROTO_SCTP: { + struct sctphdr _sctph, *sh; + + sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); + if (sh == NULL) + break; + ad->u.net.sport = sh->source; + ad->u.net.dport = sh->dest; + break; + } + default: + ret = -EINVAL; + } + return ret; +} +#endif + + +static inline void print_ipv6_addr(struct audit_buffer *ab, + struct in6_addr *addr, __be16 port, + char *name1, char *name2) +{ + if (!ipv6_addr_any(addr)) + audit_log_format(ab, " %s=%pI6", name1, addr); + if (port) + audit_log_format(ab, " %s=%d", name2, ntohs(port)); +} + +static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr, + __be16 port, char *name1, char *name2) +{ + if (addr) + audit_log_format(ab, " %s=%pI4", name1, &addr); + if (port) + audit_log_format(ab, " %s=%d", name2, ntohs(port)); +} + +/** + * dump_common_audit_data - helper to dump common audit data + * @a : common audit data + * + */ +static void dump_common_audit_data(struct audit_buffer *ab, + struct common_audit_data *a) +{ + struct inode *inode = NULL; + struct task_struct *tsk = current; + + if (a->tsk) + tsk = a->tsk; + if (tsk && tsk->pid) { + audit_log_format(ab, " pid=%d comm=", tsk->pid); + audit_log_untrustedstring(ab, tsk->comm); + } + + switch (a->type) { + case LSM_AUDIT_DATA_IPC: + audit_log_format(ab, " key=%d ", a->u.ipc_id); + break; + case LSM_AUDIT_DATA_CAP: + audit_log_format(ab, " capability=%d ", a->u.cap); + break; + case LSM_AUDIT_DATA_FS: + if (a->u.fs.path.dentry) { + struct dentry *dentry = a->u.fs.path.dentry; + if (a->u.fs.path.mnt) { + audit_log_d_path(ab, "path=", &a->u.fs.path); + } else { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, + dentry->d_name.name); + } + inode = dentry->d_inode; + } else if (a->u.fs.inode) { + struct dentry *dentry; + inode = a->u.fs.inode; + dentry = d_find_alias(inode); + if (dentry) { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, + dentry->d_name.name); + dput(dentry); + } + } + if (inode) + audit_log_format(ab, " dev=%s ino=%lu", + inode->i_sb->s_id, + inode->i_ino); + break; + case LSM_AUDIT_DATA_TASK: + tsk = a->u.tsk; + if (tsk && tsk->pid) { + audit_log_format(ab, " pid=%d comm=", tsk->pid); + audit_log_untrustedstring(ab, tsk->comm); + } + break; + case LSM_AUDIT_DATA_NET: + if (a->u.net.sk) { + struct sock *sk = a->u.net.sk; + struct unix_sock *u; + int len = 0; + char *p = NULL; + + switch (sk->sk_family) { + case AF_INET: { + struct inet_sock *inet = inet_sk(sk); + + print_ipv4_addr(ab, inet->rcv_saddr, + inet->sport, + "laddr", "lport"); + print_ipv4_addr(ab, inet->daddr, + inet->dport, + "faddr", "fport"); + break; + } + case AF_INET6: { + struct inet_sock *inet = inet_sk(sk); + struct ipv6_pinfo *inet6 = inet6_sk(sk); + + print_ipv6_addr(ab, &inet6->rcv_saddr, + inet->sport, + "laddr", "lport"); + print_ipv6_addr(ab, &inet6->daddr, + inet->dport, + "faddr", "fport"); + break; + } + case AF_UNIX: + u = unix_sk(sk); + if (u->dentry) { + struct path path = { + .dentry = u->dentry, + .mnt = u->mnt + }; + audit_log_d_path(ab, "path=", &path); + break; + } + if (!u->addr) + break; + len = u->addr->len-sizeof(short); + p = &u->addr->name->sun_path[0]; + audit_log_format(ab, " path="); + if (*p) + audit_log_untrustedstring(ab, p); + else + audit_log_n_hex(ab, p, len); + break; + } + } + + switch (a->u.net.family) { + case AF_INET: + print_ipv4_addr(ab, a->u.net.v4info.saddr, + a->u.net.sport, + "saddr", "src"); + print_ipv4_addr(ab, a->u.net.v4info.daddr, + a->u.net.dport, + "daddr", "dest"); + break; + case AF_INET6: + print_ipv6_addr(ab, &a->u.net.v6info.saddr, + a->u.net.sport, + "saddr", "src"); + print_ipv6_addr(ab, &a->u.net.v6info.daddr, + a->u.net.dport, + "daddr", "dest"); + break; + } + if (a->u.net.netif > 0) { + struct net_device *dev; + + /* NOTE: we always use init's namespace */ + dev = dev_get_by_index(&init_net, a->u.net.netif); + if (dev) { + audit_log_format(ab, " netif=%s", dev->name); + dev_put(dev); + } + } + break; +#ifdef CONFIG_KEYS + case LSM_AUDIT_DATA_KEY: + audit_log_format(ab, " key_serial=%u", a->u.key_struct.key); + if (a->u.key_struct.key_desc) { + audit_log_format(ab, " key_desc="); + audit_log_untrustedstring(ab, a->u.key_struct.key_desc); + } + break; +#endif + } /* switch (a->type) */ +} + +/** + * common_lsm_audit - generic LSM auditing function + * @a: auxiliary audit data + * + * setup the audit buffer for common security information + * uses callback to print LSM specific information + */ +void common_lsm_audit(struct common_audit_data *a) +{ + struct audit_buffer *ab; + + if (a == NULL) + return; + /* we use GFP_ATOMIC so we won't sleep */ + ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC); + + if (ab == NULL) + return; + + if (a->lsm_pre_audit) + a->lsm_pre_audit(ab, a); + + dump_common_audit_data(ab, a); + + if (a->lsm_post_audit) + a->lsm_post_audit(ab, a); + + audit_log_end(ab); +} -- GitLab From ecfcc53fef3c357574bb6143dce6631e6d56295c Mon Sep 17 00:00:00 2001 From: Etienne Basset Date: Wed, 8 Apr 2009 20:40:06 +0200 Subject: [PATCH 0274/6080] smack: implement logging V3 the following patch, add logging of Smack security decisions. This is of course very useful to understand what your current smack policy does. As suggested by Casey, it also now forbids labels with ', " or \ It introduces a '/smack/logging' switch : 0: no logging 1: log denied (default) 2: log accepted 3: log denied&accepted Signed-off-by: Etienne Basset Acked-by: Casey Schaufler Acked-by: Eric Paris Signed-off-by: James Morris --- Documentation/Smack.txt | 20 +- security/Makefile | 3 + security/smack/smack.h | 108 +++++++++- security/smack/smack_access.c | 143 +++++++++++-- security/smack/smack_lsm.c | 390 ++++++++++++++++++++++++++-------- security/smack/smackfs.c | 66 ++++++ 6 files changed, 618 insertions(+), 112 deletions(-) diff --git a/Documentation/Smack.txt b/Documentation/Smack.txt index 629c92e99783..34614b4c708e 100644 --- a/Documentation/Smack.txt +++ b/Documentation/Smack.txt @@ -184,8 +184,9 @@ length. Single character labels using special characters, that being anything other than a letter or digit, are reserved for use by the Smack development team. Smack labels are unstructured, case sensitive, and the only operation ever performed on them is comparison for equality. Smack labels cannot -contain unprintable characters or the "/" (slash) character. Smack labels -cannot begin with a '-', which is reserved for special options. +contain unprintable characters, the "/" (slash), the "\" (backslash), the "'" +(quote) and '"' (double-quote) characters. +Smack labels cannot begin with a '-', which is reserved for special options. There are some predefined labels: @@ -523,3 +524,18 @@ Smack supports some mount options: These mount options apply to all file system types. +Smack auditing + +If you want Smack auditing of security events, you need to set CONFIG_AUDIT +in your kernel configuration. +By default, all denied events will be audited. You can change this behavior by +writing a single character to the /smack/logging file : +0 : no logging +1 : log denied (default) +2 : log accepted +3 : log denied & accepted + +Events are logged as 'key=value' pairs, for each event you at least will get +the subjet, the object, the rights requested, the action, the kernel function +that triggered the event, plus other pairs depending on the type of event +audited. diff --git a/security/Makefile b/security/Makefile index fa77021d9778..c67557cdaa85 100644 --- a/security/Makefile +++ b/security/Makefile @@ -16,6 +16,9 @@ obj-$(CONFIG_SECURITYFS) += inode.o # Must precede capability.o in order to stack properly. obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o +ifeq ($(CONFIG_AUDIT),y) +obj-$(CONFIG_SECURITY_SMACK) += lsm_audit.o +endif obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o diff --git a/security/smack/smack.h b/security/smack/smack.h index 42ef313f9856..243bec175be0 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -20,6 +20,7 @@ #include #include #include +#include /* * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is @@ -178,6 +179,20 @@ struct smack_known { #define MAY_READWRITE (MAY_READ | MAY_WRITE) #define MAY_NOT 0 +/* + * Number of access types used by Smack (rwxa) + */ +#define SMK_NUM_ACCESS_TYPE 4 + +/* + * Smack audit data; is empty if CONFIG_AUDIT not set + * to save some stack + */ +struct smk_audit_info { +#ifdef CONFIG_AUDIT + struct common_audit_data a; +#endif +}; /* * These functions are in smack_lsm.c */ @@ -186,8 +201,8 @@ struct inode_smack *new_inode_smack(char *); /* * These functions are in smack_access.c */ -int smk_access(char *, char *, int); -int smk_curacc(char *, u32); +int smk_access(char *, char *, int, struct smk_audit_info *); +int smk_curacc(char *, u32, struct smk_audit_info *); int smack_to_cipso(const char *, struct smack_cipso *); void smack_from_cipso(u32, char *, char *); char *smack_from_secid(const u32); @@ -237,4 +252,93 @@ static inline char *smk_of_inode(const struct inode *isp) return sip->smk_inode; } +/* + * logging functions + */ +#define SMACK_AUDIT_DENIED 0x1 +#define SMACK_AUDIT_ACCEPT 0x2 +extern int log_policy; + +void smack_log(char *subject_label, char *object_label, + int request, + int result, struct smk_audit_info *auditdata); + +#ifdef CONFIG_AUDIT + +/* + * some inline functions to set up audit data + * they do nothing if CONFIG_AUDIT is not set + * + */ +static inline void smk_ad_init(struct smk_audit_info *a, const char *func, + char type) +{ + memset(a, 0, sizeof(*a)); + a->a.type = type; + a->a.function = func; +} + +static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, + struct task_struct *t) +{ + a->a.u.tsk = t; +} +static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, + struct dentry *d) +{ + a->a.u.fs.path.dentry = d; +} +static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a, + struct vfsmount *m) +{ + a->a.u.fs.path.mnt = m; +} +static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, + struct inode *i) +{ + a->a.u.fs.inode = i; +} +static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, + struct path p) +{ + a->a.u.fs.path = p; +} +static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, + struct sock *sk) +{ + a->a.u.net.sk = sk; +} + +#else /* no AUDIT */ + +static inline void smk_ad_init(struct smk_audit_info *a, const char *func, + char type) +{ +} +static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, + struct task_struct *t) +{ +} +static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, + struct dentry *d) +{ +} +static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a, + struct vfsmount *m) +{ +} +static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, + struct inode *i) +{ +} +static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, + struct path p) +{ +} +static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, + struct sock *sk) +{ +} +#endif + #endif /* _SECURITY_SMACK_H */ diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index ac0a2707f6d4..513dc1aa16dd 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -59,11 +59,18 @@ LIST_HEAD(smack_known_list); */ static u32 smack_next_secid = 10; +/* + * what events do we log + * can be overwritten at run-time by /smack/logging + */ +int log_policy = SMACK_AUDIT_DENIED; + /** * smk_access - determine if a subject has a specific access to an object * @subject_label: a pointer to the subject's Smack label * @object_label: a pointer to the object's Smack label * @request: the access requested, in "MAY" format + * @a : a pointer to the audit data * * This function looks up the subject/object pair in the * access rule list and returns 0 if the access is permitted, @@ -78,10 +85,12 @@ static u32 smack_next_secid = 10; * will be on the list, so checking the pointers may be a worthwhile * optimization. */ -int smk_access(char *subject_label, char *object_label, int request) +int smk_access(char *subject_label, char *object_label, int request, + struct smk_audit_info *a) { u32 may = MAY_NOT; struct smack_rule *srp; + int rc = 0; /* * Hardcoded comparisons. @@ -89,8 +98,10 @@ int smk_access(char *subject_label, char *object_label, int request) * A star subject can't access any object. */ if (subject_label == smack_known_star.smk_known || - strcmp(subject_label, smack_known_star.smk_known) == 0) - return -EACCES; + strcmp(subject_label, smack_known_star.smk_known) == 0) { + rc = -EACCES; + goto out_audit; + } /* * An internet object can be accessed by any subject. * Tasks cannot be assigned the internet label. @@ -100,20 +111,20 @@ int smk_access(char *subject_label, char *object_label, int request) subject_label == smack_known_web.smk_known || strcmp(object_label, smack_known_web.smk_known) == 0 || strcmp(subject_label, smack_known_web.smk_known) == 0) - return 0; + goto out_audit; /* * A star object can be accessed by any subject. */ if (object_label == smack_known_star.smk_known || strcmp(object_label, smack_known_star.smk_known) == 0) - return 0; + goto out_audit; /* * An object can be accessed in any way by a subject * with the same label. */ if (subject_label == object_label || strcmp(subject_label, object_label) == 0) - return 0; + goto out_audit; /* * A hat subject can read any object. * A floor object can be read by any subject. @@ -121,10 +132,10 @@ int smk_access(char *subject_label, char *object_label, int request) if ((request & MAY_ANYREAD) == request) { if (object_label == smack_known_floor.smk_known || strcmp(object_label, smack_known_floor.smk_known) == 0) - return 0; + goto out_audit; if (subject_label == smack_known_hat.smk_known || strcmp(subject_label, smack_known_hat.smk_known) == 0) - return 0; + goto out_audit; } /* * Beyond here an explicit relationship is required. @@ -148,28 +159,36 @@ int smk_access(char *subject_label, char *object_label, int request) * This is a bit map operation. */ if ((request & may) == request) - return 0; - - return -EACCES; + goto out_audit; + + rc = -EACCES; +out_audit: +#ifdef CONFIG_AUDIT + if (a) + smack_log(subject_label, object_label, request, rc, a); +#endif + return rc; } /** * smk_curacc - determine if current has a specific access to an object * @obj_label: a pointer to the object's Smack label * @mode: the access requested, in "MAY" format + * @a : common audit data * * This function checks the current subject label/object label pair * in the access rule list and returns 0 if the access is permitted, * non zero otherwise. It allows that current may have the capability * to override the rules. */ -int smk_curacc(char *obj_label, u32 mode) +int smk_curacc(char *obj_label, u32 mode, struct smk_audit_info *a) { int rc; + char *sp = current_security(); - rc = smk_access(current_security(), obj_label, mode); + rc = smk_access(sp, obj_label, mode, NULL); if (rc == 0) - return 0; + goto out_audit; /* * Return if a specific label has been designated as the @@ -177,14 +196,105 @@ int smk_curacc(char *obj_label, u32 mode) * have that label. */ if (smack_onlycap != NULL && smack_onlycap != current->cred->security) - return rc; + goto out_audit; if (capable(CAP_MAC_OVERRIDE)) return 0; +out_audit: +#ifdef CONFIG_AUDIT + if (a) + smack_log(sp, obj_label, mode, rc, a); +#endif return rc; } +#ifdef CONFIG_AUDIT +/** + * smack_str_from_perm : helper to transalate an int to a + * readable string + * @string : the string to fill + * @access : the int + * + */ +static inline void smack_str_from_perm(char *string, int access) +{ + int i = 0; + if (access & MAY_READ) + string[i++] = 'r'; + if (access & MAY_WRITE) + string[i++] = 'w'; + if (access & MAY_EXEC) + string[i++] = 'x'; + if (access & MAY_APPEND) + string[i++] = 'a'; + string[i] = '\0'; +} +/** + * smack_log_callback - SMACK specific information + * will be called by generic audit code + * @ab : the audit_buffer + * @a : audit_data + * + */ +static void smack_log_callback(struct audit_buffer *ab, void *a) +{ + struct common_audit_data *ad = a; + struct smack_audit_data *sad = &ad->lsm_priv.smack_audit_data; + audit_log_format(ab, "lsm=SMACK fn=%s action=%s", ad->function, + sad->result ? "denied" : "granted"); + audit_log_format(ab, " subject="); + audit_log_untrustedstring(ab, sad->subject); + audit_log_format(ab, " object="); + audit_log_untrustedstring(ab, sad->object); + audit_log_format(ab, " requested=%s", sad->request); +} + +/** + * smack_log - Audit the granting or denial of permissions. + * @subject_label : smack label of the requester + * @object_label : smack label of the object being accessed + * @request: requested permissions + * @result: result from smk_access + * @a: auxiliary audit data + * + * Audit the granting or denial of permissions in accordance + * with the policy. + */ +void smack_log(char *subject_label, char *object_label, int request, + int result, struct smk_audit_info *ad) +{ + char request_buffer[SMK_NUM_ACCESS_TYPE + 1]; + struct smack_audit_data *sad; + struct common_audit_data *a = &ad->a; + + /* check if we have to log the current event */ + if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0) + return; + if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) + return; + + if (a->function == NULL) + a->function = "unknown"; + + /* end preparing the audit data */ + sad = &a->lsm_priv.smack_audit_data; + smack_str_from_perm(request_buffer, request); + sad->subject = subject_label; + sad->object = object_label; + sad->request = request_buffer; + sad->result = result; + a->lsm_pre_audit = smack_log_callback; + + common_lsm_audit(a); +} +#else /* #ifdef CONFIG_AUDIT */ +void smack_log(char *subject_label, char *object_label, int request, + int result, struct smk_audit_info *ad) +{ +} +#endif + static DEFINE_MUTEX(smack_known_lock); /** @@ -209,7 +319,8 @@ struct smack_known *smk_import_entry(const char *string, int len) if (found) smack[i] = '\0'; else if (i >= len || string[i] > '~' || string[i] <= ' ' || - string[i] == '/') { + string[i] == '/' || string[i] == '"' || + string[i] == '\\' || string[i] == '\'') { smack[i] = '\0'; found = 1; } else diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 921514902eca..f557767911c9 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -30,7 +30,6 @@ #include #include #include - #include "smack.h" #define task_security(task) (task_cred_xxx((task), security)) @@ -103,14 +102,24 @@ struct inode_smack *new_inode_smack(char *smack) static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode) { int rc; + struct smk_audit_info ad; + char *sp, *tsp; rc = cap_ptrace_may_access(ctp, mode); if (rc != 0) return rc; - rc = smk_access(current_security(), task_security(ctp), MAY_READWRITE); + sp = current_security(); + tsp = task_security(ctp); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, ctp); + + /* we won't log here, because rc can be overriden */ + rc = smk_access(sp, tsp, MAY_READWRITE, NULL); if (rc != 0 && capable(CAP_MAC_OVERRIDE)) - return 0; + rc = 0; + + smack_log(sp, tsp, MAY_READWRITE, rc, &ad); return rc; } @@ -125,14 +134,24 @@ static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode) static int smack_ptrace_traceme(struct task_struct *ptp) { int rc; + struct smk_audit_info ad; + char *sp, *tsp; rc = cap_ptrace_traceme(ptp); if (rc != 0) return rc; - rc = smk_access(task_security(ptp), current_security(), MAY_READWRITE); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, ptp); + + sp = current_security(); + tsp = task_security(ptp); + /* we won't log here, because rc can be overriden */ + rc = smk_access(tsp, sp, MAY_READWRITE, NULL); if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE)) - return 0; + rc = 0; + + smack_log(tsp, sp, MAY_READWRITE, rc, &ad); return rc; } @@ -327,8 +346,14 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) static int smack_sb_statfs(struct dentry *dentry) { struct superblock_smack *sbp = dentry->d_sb->s_security; + int rc; + struct smk_audit_info ad; - return smk_curacc(sbp->smk_floor, MAY_READ); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + + rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); + return rc; } /** @@ -346,8 +371,12 @@ static int smack_sb_mount(char *dev_name, struct path *path, char *type, unsigned long flags, void *data) { struct superblock_smack *sbp = path->mnt->mnt_sb->s_security; + struct smk_audit_info ad; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path(&ad, *path); - return smk_curacc(sbp->smk_floor, MAY_WRITE); + return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); } /** @@ -361,10 +390,14 @@ static int smack_sb_mount(char *dev_name, struct path *path, static int smack_sb_umount(struct vfsmount *mnt, int flags) { struct superblock_smack *sbp; + struct smk_audit_info ad; - sbp = mnt->mnt_sb->s_security; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_mountpoint); + smk_ad_setfield_u_fs_path_mnt(&ad, mnt); - return smk_curacc(sbp->smk_floor, MAY_WRITE); + sbp = mnt->mnt_sb->s_security; + return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); } /* @@ -441,15 +474,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) { - int rc; char *isp; + struct smk_audit_info ad; + int rc; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); isp = smk_of_inode(old_dentry->d_inode); - rc = smk_curacc(isp, MAY_WRITE); + rc = smk_curacc(isp, MAY_WRITE, &ad); if (rc == 0 && new_dentry->d_inode != NULL) { isp = smk_of_inode(new_dentry->d_inode); - rc = smk_curacc(isp, MAY_WRITE); + smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); + rc = smk_curacc(isp, MAY_WRITE, &ad); } return rc; @@ -466,18 +504,24 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) { struct inode *ip = dentry->d_inode; + struct smk_audit_info ad; int rc; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + /* * You need write access to the thing you're unlinking */ - rc = smk_curacc(smk_of_inode(ip), MAY_WRITE); - if (rc == 0) + rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad); + if (rc == 0) { /* * You also need write access to the containing directory */ - rc = smk_curacc(smk_of_inode(dir), MAY_WRITE); - + smk_ad_setfield_u_fs_path_dentry(&ad, NULL); + smk_ad_setfield_u_fs_inode(&ad, dir); + rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad); + } return rc; } @@ -491,17 +535,24 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) */ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) { + struct smk_audit_info ad; int rc; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + /* * You need write access to the thing you're removing */ - rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); - if (rc == 0) + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); + if (rc == 0) { /* * You also need write access to the containing directory */ - rc = smk_curacc(smk_of_inode(dir), MAY_WRITE); + smk_ad_setfield_u_fs_path_dentry(&ad, NULL); + smk_ad_setfield_u_fs_inode(&ad, dir); + rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad); + } return rc; } @@ -525,15 +576,19 @@ static int smack_inode_rename(struct inode *old_inode, { int rc; char *isp; + struct smk_audit_info ad; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); isp = smk_of_inode(old_dentry->d_inode); - rc = smk_curacc(isp, MAY_READWRITE); + rc = smk_curacc(isp, MAY_READWRITE, &ad); if (rc == 0 && new_dentry->d_inode != NULL) { isp = smk_of_inode(new_dentry->d_inode); - rc = smk_curacc(isp, MAY_READWRITE); + smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); + rc = smk_curacc(isp, MAY_READWRITE, &ad); } - return rc; } @@ -548,13 +603,15 @@ static int smack_inode_rename(struct inode *old_inode, */ static int smack_inode_permission(struct inode *inode, int mask) { + struct smk_audit_info ad; /* * No permission to check. Existence test. Yup, it's there. */ if (mask == 0) return 0; - - return smk_curacc(smk_of_inode(inode), mask); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_inode(&ad, inode); + return smk_curacc(smk_of_inode(inode), mask, &ad); } /** @@ -566,13 +623,16 @@ static int smack_inode_permission(struct inode *inode, int mask) */ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) { + struct smk_audit_info ad; /* * Need to allow for clearing the setuid bit. */ if (iattr->ia_valid & ATTR_FORCE) return 0; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); } /** @@ -584,7 +644,12 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) */ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) { - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); + struct smk_audit_info ad; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + smk_ad_setfield_u_fs_path_mnt(&ad, mnt); + return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); } /** @@ -602,6 +667,7 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) static int smack_inode_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { + struct smk_audit_info ad; int rc = 0; if (strcmp(name, XATTR_NAME_SMACK) == 0 || @@ -615,8 +681,11 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, } else rc = cap_inode_setxattr(dentry, name, value, size, flags); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + if (rc == 0) - rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); return rc; } @@ -671,7 +740,12 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, */ static int smack_inode_getxattr(struct dentry *dentry, const char *name) { - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); + struct smk_audit_info ad; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); + + return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); } /* @@ -685,6 +759,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name) */ static int smack_inode_removexattr(struct dentry *dentry, const char *name) { + struct smk_audit_info ad; int rc = 0; if (strcmp(name, XATTR_NAME_SMACK) == 0 || @@ -695,8 +770,10 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) } else rc = cap_inode_removexattr(dentry, name); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, dentry); if (rc == 0) - rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); return rc; } @@ -855,12 +932,16 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rc = 0; + struct smk_audit_info ad; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path(&ad, file->f_path); if (_IOC_DIR(cmd) & _IOC_WRITE) - rc = smk_curacc(file->f_security, MAY_WRITE); + rc = smk_curacc(file->f_security, MAY_WRITE, &ad); if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) - rc = smk_curacc(file->f_security, MAY_READ); + rc = smk_curacc(file->f_security, MAY_READ, &ad); return rc; } @@ -874,7 +955,11 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, */ static int smack_file_lock(struct file *file, unsigned int cmd) { - return smk_curacc(file->f_security, MAY_WRITE); + struct smk_audit_info ad; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry); + return smk_curacc(file->f_security, MAY_WRITE, &ad); } /** @@ -888,8 +973,12 @@ static int smack_file_lock(struct file *file, unsigned int cmd) static int smack_file_fcntl(struct file *file, unsigned int cmd, unsigned long arg) { + struct smk_audit_info ad; int rc; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); + smk_ad_setfield_u_fs_path(&ad, file->f_path); + switch (cmd) { case F_DUPFD: case F_GETFD: @@ -897,7 +986,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, case F_GETLK: case F_GETOWN: case F_GETSIG: - rc = smk_curacc(file->f_security, MAY_READ); + rc = smk_curacc(file->f_security, MAY_READ, &ad); break; case F_SETFD: case F_SETFL: @@ -905,10 +994,10 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, case F_SETLKW: case F_SETOWN: case F_SETSIG: - rc = smk_curacc(file->f_security, MAY_WRITE); + rc = smk_curacc(file->f_security, MAY_WRITE, &ad); break; default: - rc = smk_curacc(file->f_security, MAY_READWRITE); + rc = smk_curacc(file->f_security, MAY_READWRITE, &ad); } return rc; @@ -943,14 +1032,21 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, { struct file *file; int rc; + char *tsp = tsk->cred->security; + struct smk_audit_info ad; /* * struct fown_struct is never outside the context of a struct file */ file = container_of(fown, struct file, f_owner); - rc = smk_access(file->f_security, tsk->cred->security, MAY_WRITE); + /* we don't log here as rc can be overriden */ + rc = smk_access(file->f_security, tsp, MAY_WRITE, NULL); if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) - return 0; + rc = 0; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, tsk); + smack_log(file->f_security, tsp, MAY_WRITE, rc, &ad); return rc; } @@ -963,7 +1059,10 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, static int smack_file_receive(struct file *file) { int may = 0; + struct smk_audit_info ad; + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_fs_path(&ad, file->f_path); /* * This code relies on bitmasks. */ @@ -972,7 +1071,7 @@ static int smack_file_receive(struct file *file) if (file->f_mode & FMODE_WRITE) may |= MAY_WRITE; - return smk_curacc(file->f_security, may); + return smk_curacc(file->f_security, may, &ad); } /* @@ -1051,6 +1150,22 @@ static int smack_kernel_create_files_as(struct cred *new, return 0; } +/** + * smk_curacc_on_task - helper to log task related access + * @p: the task object + * @access : the access requested + * + * Return 0 if access is permitted + */ +static int smk_curacc_on_task(struct task_struct *p, int access) +{ + struct smk_audit_info ad; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, p); + return smk_curacc(task_security(p), access, &ad); +} + /** * smack_task_setpgid - Smack check on setting pgid * @p: the task object @@ -1060,7 +1175,7 @@ static int smack_kernel_create_files_as(struct cred *new, */ static int smack_task_setpgid(struct task_struct *p, pid_t pgid) { - return smk_curacc(task_security(p), MAY_WRITE); + return smk_curacc_on_task(p, MAY_WRITE); } /** @@ -1071,7 +1186,7 @@ static int smack_task_setpgid(struct task_struct *p, pid_t pgid) */ static int smack_task_getpgid(struct task_struct *p) { - return smk_curacc(task_security(p), MAY_READ); + return smk_curacc_on_task(p, MAY_READ); } /** @@ -1082,7 +1197,7 @@ static int smack_task_getpgid(struct task_struct *p) */ static int smack_task_getsid(struct task_struct *p) { - return smk_curacc(task_security(p), MAY_READ); + return smk_curacc_on_task(p, MAY_READ); } /** @@ -1110,7 +1225,7 @@ static int smack_task_setnice(struct task_struct *p, int nice) rc = cap_task_setnice(p, nice); if (rc == 0) - rc = smk_curacc(task_security(p), MAY_WRITE); + rc = smk_curacc_on_task(p, MAY_WRITE); return rc; } @@ -1127,7 +1242,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio) rc = cap_task_setioprio(p, ioprio); if (rc == 0) - rc = smk_curacc(task_security(p), MAY_WRITE); + rc = smk_curacc_on_task(p, MAY_WRITE); return rc; } @@ -1139,7 +1254,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio) */ static int smack_task_getioprio(struct task_struct *p) { - return smk_curacc(task_security(p), MAY_READ); + return smk_curacc_on_task(p, MAY_READ); } /** @@ -1157,7 +1272,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy, rc = cap_task_setscheduler(p, policy, lp); if (rc == 0) - rc = smk_curacc(task_security(p), MAY_WRITE); + rc = smk_curacc_on_task(p, MAY_WRITE); return rc; } @@ -1169,7 +1284,7 @@ static int smack_task_setscheduler(struct task_struct *p, int policy, */ static int smack_task_getscheduler(struct task_struct *p) { - return smk_curacc(task_security(p), MAY_READ); + return smk_curacc_on_task(p, MAY_READ); } /** @@ -1180,7 +1295,7 @@ static int smack_task_getscheduler(struct task_struct *p) */ static int smack_task_movememory(struct task_struct *p) { - return smk_curacc(task_security(p), MAY_WRITE); + return smk_curacc_on_task(p, MAY_WRITE); } /** @@ -1198,18 +1313,23 @@ static int smack_task_movememory(struct task_struct *p) static int smack_task_kill(struct task_struct *p, struct siginfo *info, int sig, u32 secid) { + struct smk_audit_info ad; + + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, p); /* * Sending a signal requires that the sender * can write the receiver. */ if (secid == 0) - return smk_curacc(task_security(p), MAY_WRITE); + return smk_curacc(task_security(p), MAY_WRITE, &ad); /* * If the secid isn't 0 we're dealing with some USB IO * specific behavior. This is not clean. For one thing * we can't take privilege into account. */ - return smk_access(smack_from_secid(secid), task_security(p), MAY_WRITE); + return smk_access(smack_from_secid(secid), task_security(p), + MAY_WRITE, &ad); } /** @@ -1220,11 +1340,15 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, */ static int smack_task_wait(struct task_struct *p) { + struct smk_audit_info ad; + char *sp = current_security(); + char *tsp = task_security(p); int rc; - rc = smk_access(current_security(), task_security(p), MAY_WRITE); + /* we don't log here, we can be overriden */ + rc = smk_access(sp, tsp, MAY_WRITE, NULL); if (rc == 0) - return 0; + goto out_log; /* * Allow the operation to succeed if either task @@ -1238,8 +1362,12 @@ static int smack_task_wait(struct task_struct *p) * the smack value. */ if (capable(CAP_MAC_OVERRIDE) || has_capability(p, CAP_MAC_OVERRIDE)) - return 0; - + rc = 0; + /* we log only if we didn't get overriden */ + out_log: + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); + smk_ad_setfield_u_tsk(&ad, p); + smack_log(sp, tsp, MAY_WRITE, rc, &ad); return rc; } @@ -1455,12 +1583,19 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) int sk_lbl; char *hostsp; struct socket_smack *ssp = sk->sk_security; + struct smk_audit_info ad; rcu_read_lock(); hostsp = smack_host_label(sap); if (hostsp != NULL) { sk_lbl = SMACK_UNLABELED_SOCKET; - rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE); +#ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); + ad.a.u.net.family = sap->sin_family; + ad.a.u.net.dport = sap->sin_port; + ad.a.u.net.v4info.daddr = sap->sin_addr.s_addr; +#endif + rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE, &ad); } else { sk_lbl = SMACK_CIPSO_SOCKET; rc = 0; @@ -1655,6 +1790,25 @@ static void smack_shm_free_security(struct shmid_kernel *shp) isp->security = NULL; } +/** + * smk_curacc_shm : check if current has access on shm + * @shp : the object + * @access : access requested + * + * Returns 0 if current has the requested access, error code otherwise + */ +static int smk_curacc_shm(struct shmid_kernel *shp, int access) +{ + char *ssp = smack_of_shm(shp); + struct smk_audit_info ad; + +#ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); + ad.a.u.ipc_id = shp->shm_perm.id; +#endif + return smk_curacc(ssp, access, &ad); +} + /** * smack_shm_associate - Smack access check for shm * @shp: the object @@ -1664,11 +1818,10 @@ static void smack_shm_free_security(struct shmid_kernel *shp) */ static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) { - char *ssp = smack_of_shm(shp); int may; may = smack_flags_to_may(shmflg); - return smk_curacc(ssp, may); + return smk_curacc_shm(shp, may); } /** @@ -1680,7 +1833,6 @@ static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) */ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) { - char *ssp; int may; switch (cmd) { @@ -1703,9 +1855,7 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) default: return -EINVAL; } - - ssp = smack_of_shm(shp); - return smk_curacc(ssp, may); + return smk_curacc_shm(shp, may); } /** @@ -1719,11 +1869,10 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg) { - char *ssp = smack_of_shm(shp); int may; may = smack_flags_to_may(shmflg); - return smk_curacc(ssp, may); + return smk_curacc_shm(shp, may); } /** @@ -1764,6 +1913,25 @@ static void smack_sem_free_security(struct sem_array *sma) isp->security = NULL; } +/** + * smk_curacc_sem : check if current has access on sem + * @sma : the object + * @access : access requested + * + * Returns 0 if current has the requested access, error code otherwise + */ +static int smk_curacc_sem(struct sem_array *sma, int access) +{ + char *ssp = smack_of_sem(sma); + struct smk_audit_info ad; + +#ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); + ad.a.u.ipc_id = sma->sem_perm.id; +#endif + return smk_curacc(ssp, access, &ad); +} + /** * smack_sem_associate - Smack access check for sem * @sma: the object @@ -1773,11 +1941,10 @@ static void smack_sem_free_security(struct sem_array *sma) */ static int smack_sem_associate(struct sem_array *sma, int semflg) { - char *ssp = smack_of_sem(sma); int may; may = smack_flags_to_may(semflg); - return smk_curacc(ssp, may); + return smk_curacc_sem(sma, may); } /** @@ -1789,7 +1956,6 @@ static int smack_sem_associate(struct sem_array *sma, int semflg) */ static int smack_sem_semctl(struct sem_array *sma, int cmd) { - char *ssp; int may; switch (cmd) { @@ -1818,8 +1984,7 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd) return -EINVAL; } - ssp = smack_of_sem(sma); - return smk_curacc(ssp, may); + return smk_curacc_sem(sma, may); } /** @@ -1836,9 +2001,7 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd) static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, unsigned nsops, int alter) { - char *ssp = smack_of_sem(sma); - - return smk_curacc(ssp, MAY_READWRITE); + return smk_curacc_sem(sma, MAY_READWRITE); } /** @@ -1879,6 +2042,25 @@ static char *smack_of_msq(struct msg_queue *msq) return (char *)msq->q_perm.security; } +/** + * smk_curacc_msq : helper to check if current has access on msq + * @msq : the msq + * @access : access requested + * + * return 0 if current has access, error otherwise + */ +static int smk_curacc_msq(struct msg_queue *msq, int access) +{ + char *msp = smack_of_msq(msq); + struct smk_audit_info ad; + +#ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); + ad.a.u.ipc_id = msq->q_perm.id; +#endif + return smk_curacc(msp, access, &ad); +} + /** * smack_msg_queue_associate - Smack access check for msg_queue * @msq: the object @@ -1888,11 +2070,10 @@ static char *smack_of_msq(struct msg_queue *msq) */ static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) { - char *msp = smack_of_msq(msq); int may; may = smack_flags_to_may(msqflg); - return smk_curacc(msp, may); + return smk_curacc_msq(msq, may); } /** @@ -1904,7 +2085,6 @@ static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) */ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) { - char *msp; int may; switch (cmd) { @@ -1926,8 +2106,7 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) return -EINVAL; } - msp = smack_of_msq(msq); - return smk_curacc(msp, may); + return smk_curacc_msq(msq, may); } /** @@ -1941,11 +2120,10 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, int msqflg) { - char *msp = smack_of_msq(msq); - int rc; + int may; - rc = smack_flags_to_may(msqflg); - return smk_curacc(msp, rc); + may = smack_flags_to_may(msqflg); + return smk_curacc_msq(msq, may); } /** @@ -1961,9 +2139,7 @@ static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, struct task_struct *target, long type, int mode) { - char *msp = smack_of_msq(msq); - - return smk_curacc(msp, MAY_READWRITE); + return smk_curacc_msq(msq, MAY_READWRITE); } /** @@ -1976,10 +2152,14 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) { char *isp = ipp->security; - int may; + int may = smack_flags_to_may(flag); + struct smk_audit_info ad; - may = smack_flags_to_may(flag); - return smk_curacc(isp, may); +#ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); + ad.a.u.ipc_id = ipp->id; +#endif + return smk_curacc(isp, may, &ad); } /** @@ -2238,8 +2418,12 @@ static int smack_unix_stream_connect(struct socket *sock, { struct inode *sp = SOCK_INODE(sock); struct inode *op = SOCK_INODE(other); + struct smk_audit_info ad; - return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_READWRITE); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); + smk_ad_setfield_u_net_sk(&ad, other->sk); + return smk_access(smk_of_inode(sp), smk_of_inode(op), + MAY_READWRITE, &ad); } /** @@ -2254,8 +2438,11 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) { struct inode *sp = SOCK_INODE(sock); struct inode *op = SOCK_INODE(other); + struct smk_audit_info ad; - return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE); + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); + smk_ad_setfield_u_net_sk(&ad, other->sk); + return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad); } /** @@ -2370,7 +2557,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) char smack[SMK_LABELLEN]; char *csp; int rc; - + struct smk_audit_info ad; if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) return 0; @@ -2388,13 +2575,19 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) netlbl_secattr_destroy(&secattr); +#ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); + ad.a.u.net.family = sk->sk_family; + ad.a.u.net.netif = skb->iif; + ipv4_skb_to_auditdata(skb, &ad.a, NULL); +#endif /* * Receiving a packet requires that the other end * be able to write here. Read access is not required. * This is the simplist possible security model * for networking. */ - rc = smk_access(csp, ssp->smk_in, MAY_WRITE); + rc = smk_access(csp, ssp->smk_in, MAY_WRITE, &ad); if (rc != 0) netlbl_skbuff_err(skb, rc, 0); return rc; @@ -2523,6 +2716,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct iphdr *hdr; char smack[SMK_LABELLEN]; int rc; + struct smk_audit_info ad; /* handle mapped IPv4 packets arriving via IPv6 sockets */ if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) @@ -2536,11 +2730,17 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN); netlbl_secattr_destroy(&secattr); +#ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); + ad.a.u.net.family = family; + ad.a.u.net.netif = skb->iif; + ipv4_skb_to_auditdata(skb, &ad.a, NULL); +#endif /* * Receiving a packet requires that the other end be able to write * here. Read access is not required. */ - rc = smk_access(smack, ssp->smk_in, MAY_WRITE); + rc = smk_access(smack, ssp->smk_in, MAY_WRITE, &ad); if (rc != 0) return rc; @@ -2642,6 +2842,7 @@ static int smack_key_permission(key_ref_t key_ref, const struct cred *cred, key_perm_t perm) { struct key *keyp; + struct smk_audit_info ad; keyp = key_ref_to_ptr(key_ref); if (keyp == NULL) @@ -2657,8 +2858,13 @@ static int smack_key_permission(key_ref_t key_ref, */ if (cred->security == NULL) return -EACCES; - - return smk_access(cred->security, keyp->security, MAY_READWRITE); +#ifdef CONFIG_AUDIT + smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY); + ad.a.u.key_struct.key = keyp->serial; + ad.a.u.key_struct.key_desc = keyp->description; +#endif + return smk_access(cred->security, keyp->security, + MAY_READWRITE, &ad); } #endif /* CONFIG_KEYS */ diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index e03a7e19c73b..904af3483286 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -41,6 +41,7 @@ enum smk_inos { SMK_AMBIENT = 7, /* internet ambient label */ SMK_NETLBLADDR = 8, /* single label hosts */ SMK_ONLYCAP = 9, /* the only "capable" label */ + SMK_LOGGING = 10, /* logging */ }; /* @@ -1191,6 +1192,69 @@ static const struct file_operations smk_onlycap_ops = { .write = smk_write_onlycap, }; +/** + * smk_read_logging - read() for /smack/logging + * @filp: file pointer, not actually used + * @buf: where to put the result + * @cn: maximum to send along + * @ppos: where to start + * + * Returns number of bytes read or error code, as appropriate + */ +static ssize_t smk_read_logging(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + char temp[32]; + ssize_t rc; + + if (*ppos != 0) + return 0; + + sprintf(temp, "%d\n", log_policy); + rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); + return rc; +} + +/** + * smk_write_logging - write() for /smack/logging + * @file: file pointer, not actually used + * @buf: where to get the data from + * @count: bytes sent + * @ppos: where to start + * + * Returns number of bytes written or error code, as appropriate + */ +static ssize_t smk_write_logging(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + char temp[32]; + int i; + + if (!capable(CAP_MAC_ADMIN)) + return -EPERM; + + if (count >= sizeof(temp) || count == 0) + return -EINVAL; + + if (copy_from_user(temp, buf, count) != 0) + return -EFAULT; + + temp[count] = '\0'; + + if (sscanf(temp, "%d", &i) != 1) + return -EINVAL; + if (i < 0 || i > 3) + return -EINVAL; + log_policy = i; + return count; +} + + + +static const struct file_operations smk_logging_ops = { + .read = smk_read_logging, + .write = smk_write_logging, +}; /** * smk_fill_super - fill the /smackfs superblock * @sb: the empty superblock @@ -1221,6 +1285,8 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) {"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR}, [SMK_ONLYCAP] = {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, + [SMK_LOGGING] = + {"logging", &smk_logging_ops, S_IRUGO|S_IWUSR}, /* last one */ {""} }; -- GitLab From 861ab44059350e5cab350238606cf8814abab93b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 5 Apr 2009 08:40:04 +0000 Subject: [PATCH 0275/6080] NET/r8169: Rework suspend and resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recent changes of the PCI PM core allow us to simplify the suspend and resume handling in a number of device drivers, since they don't need to carry out the general PCI PM operations, such as changing the power state of the device, during suspend and resume any more. Simplify the suspend and resume callbacks of r8169 using the observation that the PCI PM core can take care of some operations carried out by the driver. Additionally, make the shutdown callback of r8169 only put the device into a low power state if the system is going to be powered off (kexec is known to have problems with network adapters that are put into low power states on shutdown). This patch has been tested on MSI Wind U100. Signed-off-by: Rafael J. Wysocki Tested-by: Bruno Prémont Signed-off-by: David S. Miller --- drivers/net/r8169.c | 61 +++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 0b6e8c896835..c812e16b7ab4 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3791,16 +3791,13 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) return &dev->stats; } -#ifdef CONFIG_PM - -static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) +static void rtl8169_net_suspend(struct net_device *dev) { - struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; if (!netif_running(dev)) - goto out_pci_suspend; + return; netif_device_detach(dev); netif_stop_queue(dev); @@ -3812,24 +3809,25 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) rtl8169_rx_missed(dev, ioaddr); spin_unlock_irq(&tp->lock); +} + +#ifdef CONFIG_PM + +static int rtl8169_suspend(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + struct net_device *dev = pci_get_drvdata(pdev); -out_pci_suspend: - pci_save_state(pdev); - pci_enable_wake(pdev, pci_choose_state(pdev, state), - (tp->features & RTL_FEATURE_WOL) ? 1 : 0); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); + rtl8169_net_suspend(dev); return 0; } -static int rtl8169_resume(struct pci_dev *pdev) +static int rtl8169_resume(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); struct net_device *dev = pci_get_drvdata(pdev); - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - pci_enable_wake(pdev, PCI_D0, 0); - if (!netif_running(dev)) goto out; @@ -3840,23 +3838,42 @@ out: return 0; } +static struct dev_pm_ops rtl8169_pm_ops = { + .suspend = rtl8169_suspend, + .resume = rtl8169_resume, + .freeze = rtl8169_suspend, + .thaw = rtl8169_resume, + .poweroff = rtl8169_suspend, + .restore = rtl8169_resume, +}; + +#define RTL8169_PM_OPS (&rtl8169_pm_ops) + +#else /* !CONFIG_PM */ + +#define RTL8169_PM_OPS NULL + +#endif /* !CONFIG_PM */ + static void rtl_shutdown(struct pci_dev *pdev) { - rtl8169_suspend(pdev, PMSG_SUSPEND); -} + struct net_device *dev = pci_get_drvdata(pdev); + + rtl8169_net_suspend(dev); -#endif /* CONFIG_PM */ + if (system_state == SYSTEM_POWER_OFF) { + pci_wake_from_d3(pdev, true); + pci_set_power_state(pdev, PCI_D3hot); + } +} static struct pci_driver rtl8169_pci_driver = { .name = MODULENAME, .id_table = rtl8169_pci_tbl, .probe = rtl8169_init_one, .remove = __devexit_p(rtl8169_remove_one), -#ifdef CONFIG_PM - .suspend = rtl8169_suspend, - .resume = rtl8169_resume, .shutdown = rtl_shutdown, -#endif + .driver.pm = RTL8169_PM_OPS, }; static int __init rtl8169_init_module(void) -- GitLab From 02bec490450836ebbd628e97ec03f10b57def8ce Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Tue, 24 Mar 2009 12:24:35 +0100 Subject: [PATCH 0276/6080] ALSA: lx6464es - driver for the digigram lx6464es interface prototype of a driver for the digigram lx6464es 64 channel ethersound interface. Signed-off-by: Tim Blechmann Signed-off-by: Takashi Iwai --- include/linux/pci_ids.h | 5 + sound/pci/Kconfig | 10 + sound/pci/Makefile | 1 + sound/pci/lx6464es/Makefile | 2 + sound/pci/lx6464es/lx6464es.c | 1152 ++++++++++++++++++++++++++ sound/pci/lx6464es/lx6464es.h | 114 +++ sound/pci/lx6464es/lx_core.c | 1442 +++++++++++++++++++++++++++++++++ sound/pci/lx6464es/lx_core.h | 242 ++++++ sound/pci/lx6464es/lx_defs.h | 376 +++++++++ 9 files changed, 3344 insertions(+) create mode 100644 sound/pci/lx6464es/Makefile create mode 100644 sound/pci/lx6464es/lx6464es.c create mode 100644 sound/pci/lx6464es/lx6464es.h create mode 100644 sound/pci/lx6464es/lx_core.c create mode 100644 sound/pci/lx6464es/lx_core.h create mode 100644 sound/pci/lx6464es/lx_defs.h diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ee98cd570885..2b1a69598e74 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1005,6 +1005,7 @@ #define PCI_DEVICE_ID_PLX_PCI200SYN 0x3196 #define PCI_DEVICE_ID_PLX_9030 0x9030 #define PCI_DEVICE_ID_PLX_9050 0x9050 +#define PCI_DEVICE_ID_PLX_9056 0x9056 #define PCI_DEVICE_ID_PLX_9080 0x9080 #define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001 @@ -1847,6 +1848,10 @@ #define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107 #define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108 +#define PCI_VENDOR_ID_DIGIGRAM 0x1369 +#define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM 0xc001 +#define PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM 0xc002 + #define PCI_VENDOR_ID_KAWASAKI 0x136b #define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01 diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 93422e3a3f0c..e912b70b6f9c 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -622,6 +622,16 @@ config SND_KORG1212 To compile this driver as a module, choose M here: the module will be called snd-korg1212. +config SND_LX6464ES + tristate "Digigram LX6464ES" + select SND_PCM + help + Say Y here to include support for Digigram LX6464ES boards. + + To compile this driver as a module, choose M here: the module + will be called snd-lx6464es. + + config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" select SND_AC97_CODEC diff --git a/sound/pci/Makefile b/sound/pci/Makefile index 65b25d221cd2..7d83e084dcf4 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_SND) += \ ca0106/ \ cs46xx/ \ cs5535audio/ \ + lx6464es/ \ echoaudio/ \ emu10k1/ \ hda/ \ diff --git a/sound/pci/lx6464es/Makefile b/sound/pci/lx6464es/Makefile new file mode 100644 index 000000000000..eb04a6c73d8b --- /dev/null +++ b/sound/pci/lx6464es/Makefile @@ -0,0 +1,2 @@ +snd-lx6464es-objs := lx6464es.o lx_core.o +obj-$(CONFIG_SND_LX6464ES) += snd-lx6464es.o diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c new file mode 100644 index 000000000000..7bc8b8caa992 --- /dev/null +++ b/sound/pci/lx6464es/lx6464es.c @@ -0,0 +1,1152 @@ +/* -*- linux-c -*- * + * + * ALSA driver for the digigram lx6464es interface + * + * Copyright (c) 2008, 2009 Tim Blechmann + * + * + * 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; see the file COPYING. 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 "lx6464es.h" + +MODULE_AUTHOR("Tim Blechmann"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("digigram lx6464es"); +MODULE_SUPPORTED_DEVICE("{digigram lx6464es{}}"); + + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; + +static const char card_name[] = "LX6464ES"; + + +#define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056 + +static struct pci_device_id snd_lx6464es_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES), + .subvendor = PCI_VENDOR_ID_DIGIGRAM, + .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM + }, /* LX6464ES */ + { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES), + .subvendor = PCI_VENDOR_ID_DIGIGRAM, + .subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_CAE_SERIAL_SUBSYSTEM + }, /* LX6464ES-CAE */ + { 0, }, +}; + +MODULE_DEVICE_TABLE(pci, snd_lx6464es_ids); + + + +/* PGO pour USERo dans le registre pci_0x06/loc_0xEC */ +#define CHIPSC_RESET_XILINX (1L<<16) + + +/* alsa callbacks */ +static struct snd_pcm_hardware lx_caps = { + .info = (SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S16_BE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S24_3BE), + .rates = (SNDRV_PCM_RATE_CONTINUOUS | + SNDRV_PCM_RATE_8000_192000), + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 2, + .channels_max = 64, + .buffer_bytes_max = 64*2*3*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER, + .period_bytes_min = (2*2*MICROBLAZE_IBL_MIN*2), + .period_bytes_max = (4*64*MICROBLAZE_IBL_MAX*MAX_STREAM_BUFFER), + .periods_min = 2, + .periods_max = MAX_STREAM_BUFFER, +}; + +static int lx_set_granularity(struct lx6464es *chip, u32 gran); + + +static int lx_hardware_open(struct lx6464es *chip, + struct snd_pcm_substream *substream) +{ + int err = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + int channels = runtime->channels; + int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + + snd_pcm_uframes_t period_size = runtime->period_size; + + snd_printd(LXP "allocating pipe for %d channels\n", channels); + err = lx_pipe_allocate(chip, 0, is_capture, channels); + if (err < 0) { + snd_printk(KERN_ERR LXP "allocating pipe failed\n"); + return err; + } + + err = lx_set_granularity(chip, period_size); + if (err < 0) { + snd_printk(KERN_ERR LXP "setting granularity to %ld failed\n", + period_size); + return err; + } + + return 0; +} + +static int lx_hardware_start(struct lx6464es *chip, + struct snd_pcm_substream *substream) +{ + int err = 0; + struct snd_pcm_runtime *runtime = substream->runtime; + int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + + snd_printd(LXP "setting stream format\n"); + err = lx_stream_set_format(chip, runtime, 0, is_capture); + if (err < 0) { + snd_printk(KERN_ERR LXP "setting stream format failed\n"); + return err; + } + + snd_printd(LXP "starting pipe\n"); + err = lx_pipe_start(chip, 0, is_capture); + if (err < 0) { + snd_printk(KERN_ERR LXP "starting pipe failed\n"); + return err; + } + + snd_printd(LXP "waiting for pipe to start\n"); + err = lx_pipe_wait_for_start(chip, 0, is_capture); + if (err < 0) { + snd_printk(KERN_ERR LXP "waiting for pipe failed\n"); + return err; + } + + return err; +} + + +static int lx_hardware_stop(struct lx6464es *chip, + struct snd_pcm_substream *substream) +{ + int err = 0; + int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + + snd_printd(LXP "pausing pipe\n"); + err = lx_pipe_pause(chip, 0, is_capture); + if (err < 0) { + snd_printk(KERN_ERR LXP "pausing pipe failed\n"); + return err; + } + + snd_printd(LXP "waiting for pipe to become idle\n"); + err = lx_pipe_wait_for_idle(chip, 0, is_capture); + if (err < 0) { + snd_printk(KERN_ERR LXP "waiting for pipe failed\n"); + return err; + } + + snd_printd(LXP "stopping pipe\n"); + err = lx_pipe_stop(chip, 0, is_capture); + if (err < 0) { + snd_printk(LXP "stopping pipe failed\n"); + return err; + } + + return err; +} + + +static int lx_hardware_close(struct lx6464es *chip, + struct snd_pcm_substream *substream) +{ + int err = 0; + int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + + snd_printd(LXP "releasing pipe\n"); + err = lx_pipe_release(chip, 0, is_capture); + if (err < 0) { + snd_printk(LXP "releasing pipe failed\n"); + return err; + } + + return err; +} + + +static int lx_pcm_open(struct snd_pcm_substream *substream) +{ + struct lx6464es *chip = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int err = 0; + int board_rate; + + snd_printdd("->lx_pcm_open\n"); + mutex_lock(&chip->setup_mutex); + + /* copy the struct snd_pcm_hardware struct */ + runtime->hw = lx_caps; + +#if 0 + /* buffer-size should better be multiple of period-size */ + err = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (err < 0) { + snd_printk(KERN_WARNING LXP "could not constrain periods\n"); + goto exit; + } +#endif + + /* the clock rate cannot be changed */ + board_rate = chip->board_sample_rate; + err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, + board_rate, board_rate); + + if (err < 0) { + snd_printk(KERN_WARNING LXP "could not constrain periods\n"); + goto exit; + } + + /* constrain period size */ + err = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, + MICROBLAZE_IBL_MIN, + MICROBLAZE_IBL_MAX); + if (err < 0) { + snd_printk(KERN_WARNING LXP + "could not constrain period size\n"); + goto exit; + } + + snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32); + + snd_pcm_set_sync(substream); + err = 0; + +exit: + runtime->private_data = chip; + + mutex_unlock(&chip->setup_mutex); + snd_printdd("<-lx_pcm_open, %d\n", err); + return err; +} + +static int lx_pcm_close(struct snd_pcm_substream *substream) +{ + int err = 0; + snd_printdd("->lx_pcm_close\n"); + return err; +} + +static snd_pcm_uframes_t lx_pcm_stream_pointer(struct snd_pcm_substream + *substream) +{ + struct lx6464es *chip = snd_pcm_substream_chip(substream); + snd_pcm_uframes_t pos; + unsigned long flags; + int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + + struct lx_stream *lx_stream = is_capture ? &chip->capture_stream : + &chip->playback_stream; + + snd_printdd("->lx_pcm_stream_pointer\n"); + + spin_lock_irqsave(&chip->lock, flags); + pos = lx_stream->frame_pos * substream->runtime->period_size; + spin_unlock_irqrestore(&chip->lock, flags); + + snd_printdd(LXP "stream_pointer at %ld\n", pos); + return pos; +} + +static int lx_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct lx6464es *chip = snd_pcm_substream_chip(substream); + int err = 0; + const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + + snd_printdd("->lx_pcm_prepare\n"); + + mutex_lock(&chip->setup_mutex); + + if (chip->hardware_running[is_capture]) { + err = lx_hardware_stop(chip, substream); + if (err < 0) { + snd_printk(KERN_ERR LXP "failed to stop hardware. " + "Error code %d\n", err); + goto exit; + } + + err = lx_hardware_close(chip, substream); + if (err < 0) { + snd_printk(KERN_ERR LXP "failed to close hardware. " + "Error code %d\n", err); + goto exit; + } + } + + snd_printd(LXP "opening hardware\n"); + err = lx_hardware_open(chip, substream); + if (err < 0) { + snd_printk(KERN_ERR LXP "failed to open hardware. " + "Error code %d\n", err); + goto exit; + } + + err = lx_hardware_start(chip, substream); + if (err < 0) { + snd_printk(KERN_ERR LXP "failed to start hardware. " + "Error code %d\n", err); + goto exit; + } + + chip->hardware_running[is_capture] = 1; + + if (chip->board_sample_rate != substream->runtime->rate) { + if (!err) + chip->board_sample_rate = substream->runtime->rate; + } + +exit: + mutex_unlock(&chip->setup_mutex); + return err; +} + +static int lx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params, int is_capture) +{ + struct lx6464es *chip = snd_pcm_substream_chip(substream); + int err = 0; + + snd_printdd("->lx_pcm_hw_params\n"); + + mutex_lock(&chip->setup_mutex); + + /* set dma buffer */ + err = snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); + + if (is_capture) + chip->capture_stream.stream = substream; + else + chip->playback_stream.stream = substream; + + mutex_unlock(&chip->setup_mutex); + return err; +} + +static int lx_pcm_hw_params_playback(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + return lx_pcm_hw_params(substream, hw_params, 0); +} + +static int lx_pcm_hw_params_capture(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + return lx_pcm_hw_params(substream, hw_params, 1); +} + +static int lx_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct lx6464es *chip = snd_pcm_substream_chip(substream); + int err = 0; + int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + + snd_printdd("->lx_pcm_hw_free\n"); + mutex_lock(&chip->setup_mutex); + + if (chip->hardware_running[is_capture]) { + err = lx_hardware_stop(chip, substream); + if (err < 0) { + snd_printk(KERN_ERR LXP "failed to stop hardware. " + "Error code %d\n", err); + goto exit; + } + + err = lx_hardware_close(chip, substream); + if (err < 0) { + snd_printk(KERN_ERR LXP "failed to close hardware. " + "Error code %d\n", err); + goto exit; + } + + chip->hardware_running[is_capture] = 0; + } + + err = snd_pcm_lib_free_pages(substream); + + if (is_capture) + chip->capture_stream.stream = 0; + else + chip->playback_stream.stream = 0; + +exit: + mutex_unlock(&chip->setup_mutex); + return err; +} + +static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream) +{ + struct snd_pcm_substream *substream = lx_stream->stream; + const int is_capture = lx_stream->is_capture; + + int err; + + const u32 channels = substream->runtime->channels; + const u32 bytes_per_frame = channels * 3; + const u32 period_size = substream->runtime->period_size; + const u32 periods = substream->runtime->periods; + const u32 period_bytes = period_size * bytes_per_frame; + + dma_addr_t buf = substream->dma_buffer.addr; + int i; + + u32 needed, freed; + u32 size_array[5]; + + for (i = 0; i != periods; ++i) { + u32 buffer_index = 0; + + err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, + size_array); + snd_printdd(LXP "starting: needed %d, freed %d\n", + needed, freed); + + err = lx_buffer_give(chip, 0, is_capture, period_bytes, + lower_32_bits(buf), upper_32_bits(buf), + &buffer_index); + + snd_printdd(LXP "starting: buffer index %x on %p (%d bytes)\n", + buffer_index, (void *)buf, period_bytes); + buf += period_bytes; + } + + err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array); + snd_printdd(LXP "starting: needed %d, freed %d\n", needed, freed); + + snd_printd(LXP "starting: starting stream\n"); + err = lx_stream_start(chip, 0, is_capture); + if (err < 0) + snd_printk(KERN_ERR LXP "couldn't start stream\n"); + else + lx_stream->status = LX_STREAM_STATUS_RUNNING; + + lx_stream->frame_pos = 0; +} + +static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream) +{ + const int is_capture = lx_stream->is_capture; + int err; + + snd_printd(LXP "stopping: stopping stream\n"); + err = lx_stream_stop(chip, 0, is_capture); + if (err < 0) + snd_printk(KERN_ERR LXP "couldn't stop stream\n"); + else + lx_stream->status = LX_STREAM_STATUS_FREE; + +} + +static void lx_trigger_tasklet_dispatch_stream(struct lx6464es *chip, + struct lx_stream *lx_stream) +{ + switch (lx_stream->status) { + case LX_STREAM_STATUS_SCHEDULE_RUN: + lx_trigger_start(chip, lx_stream); + break; + + case LX_STREAM_STATUS_SCHEDULE_STOP: + lx_trigger_stop(chip, lx_stream); + break; + + default: + break; + } +} + +static void lx_trigger_tasklet(unsigned long data) +{ + struct lx6464es *chip = (struct lx6464es *)data; + unsigned long flags; + + snd_printdd("->lx_trigger_tasklet\n"); + + spin_lock_irqsave(&chip->lock, flags); + lx_trigger_tasklet_dispatch_stream(chip, &chip->capture_stream); + lx_trigger_tasklet_dispatch_stream(chip, &chip->playback_stream); + spin_unlock_irqrestore(&chip->lock, flags); +} + +static int lx_pcm_trigger_dispatch(struct lx6464es *chip, + struct lx_stream *lx_stream, int cmd) +{ + int err = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + lx_stream->status = LX_STREAM_STATUS_SCHEDULE_RUN; + break; + + case SNDRV_PCM_TRIGGER_STOP: + lx_stream->status = LX_STREAM_STATUS_SCHEDULE_STOP; + break; + + default: + err = -EINVAL; + goto exit; + } + tasklet_schedule(&chip->trigger_tasklet); + +exit: + return err; +} + + +static int lx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct lx6464es *chip = snd_pcm_substream_chip(substream); + const int is_capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + struct lx_stream *stream = is_capture ? &chip->capture_stream : + &chip->playback_stream; + + snd_printdd("->lx_pcm_trigger\n"); + + return lx_pcm_trigger_dispatch(chip, stream, cmd); +} + +static int snd_lx6464es_free(struct lx6464es *chip) +{ + snd_printdd("->snd_lx6464es_free\n"); + + lx_irq_disable(chip); + + if (chip->irq >= 0) + free_irq(chip->irq, chip); + + iounmap(chip->port_dsp_bar); + ioport_unmap(chip->port_plx_remapped); + + pci_release_regions(chip->pci); + pci_disable_device(chip->pci); + + kfree(chip); + + return 0; +} + +static int snd_lx6464es_dev_free(struct snd_device *device) +{ + return snd_lx6464es_free(device->device_data); +} + +/* reset the dsp during initialization */ +static int __devinit lx_init_xilinx_reset(struct lx6464es *chip) +{ + int i; + u32 plx_reg = lx_plx_reg_read(chip, ePLX_CHIPSC); + + snd_printdd("->lx_init_xilinx_reset\n"); + + /* activate reset of xilinx */ + plx_reg &= ~CHIPSC_RESET_XILINX; + + lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg); + msleep(1); + + lx_plx_reg_write(chip, ePLX_MBOX3, 0); + msleep(1); + + plx_reg |= CHIPSC_RESET_XILINX; + lx_plx_reg_write(chip, ePLX_CHIPSC, plx_reg); + + /* deactivate reset of xilinx */ + for (i = 0; i != 100; ++i) { + u32 reg_mbox3; + msleep(10); + reg_mbox3 = lx_plx_reg_read(chip, ePLX_MBOX3); + if (reg_mbox3) { + snd_printd(LXP "xilinx reset done\n"); + snd_printdd(LXP "xilinx took %d loops\n", i); + break; + } + } + + /* todo: add some error handling? */ + + /* clear mr */ + lx_dsp_reg_write(chip, eReg_CSM, 0); + + /* le xilinx ES peut ne pas etre encore pret, on attend. */ + msleep(600); + + return 0; +} + +static int __devinit lx_init_xilinx_test(struct lx6464es *chip) +{ + u32 reg; + + snd_printdd("->lx_init_xilinx_test\n"); + + /* TEST if we have access to Xilinx/MicroBlaze */ + lx_dsp_reg_write(chip, eReg_CSM, 0); + + reg = lx_dsp_reg_read(chip, eReg_CSM); + + if (reg) { + snd_printk(KERN_ERR LXP "Problem: Reg_CSM %x.\n", reg); + + /* PCI9056_SPACE0_REMAP */ + lx_plx_reg_write(chip, ePLX_PCICR, 1); + + reg = lx_dsp_reg_read(chip, eReg_CSM); + if (reg) { + snd_printk(KERN_ERR LXP "Error: Reg_CSM %x.\n", reg); + return -EAGAIN; /* seems to be appropriate */ + } + } + + snd_printd(LXP "Xilinx/MicroBlaze access test successful\n"); + + return 0; +} + +/* initialize ethersound */ +static int __devinit lx_init_ethersound_config(struct lx6464es *chip) +{ + int i; + u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES); + + u32 default_conf_es = (64 << IOCR_OUTPUTS_OFFSET) | + (64 << IOCR_INPUTS_OFFSET) | + (FREQ_RATIO_SINGLE_MODE << FREQ_RATIO_OFFSET); + + u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK) + | (default_conf_es & CONFES_WRITE_PART_MASK); + + snd_printdd("->lx_init_ethersound\n"); + + chip->freq_ratio = FREQ_RATIO_SINGLE_MODE; + + /* + * write it to the card ! + * this actually kicks the ES xilinx, the first time since poweron. + * the MAC address in the Reg_ADMACESMSB Reg_ADMACESLSB registers + * is not ready before this is done, and the bit 2 in Reg_CSES is set. + * */ + lx_dsp_reg_write(chip, eReg_CONFES, conf_es); + + for (i = 0; i != 1000; ++i) { + if (lx_dsp_reg_read(chip, eReg_CSES) & 4) { + snd_printd(LXP "ethersound initialized after %dms\n", + i); + goto ethersound_initialized; + } + msleep(1); + } + snd_printk(KERN_WARNING LXP + "ethersound could not be initialized after %dms\n", i); + return -ETIMEDOUT; + + ethersound_initialized: + snd_printd(LXP "ethersound initialized\n"); + return 0; +} + +static int __devinit lx_init_get_version_features(struct lx6464es *chip) +{ + u32 dsp_version; + + int err; + + snd_printdd("->lx_init_get_version_features\n"); + + err = lx_dsp_get_version(chip, &dsp_version); + + if (err == 0) { + u32 freq; + + snd_printk(LXP "DSP version: V%02d.%02d #%d\n", + (dsp_version>>16) & 0xff, (dsp_version>>8) & 0xff, + dsp_version & 0xff); + + /* later: what firmware version do we expect? */ + + /* retrieve Play/Rec features */ + /* done here because we may have to handle alternate + * DSP files. */ + /* later */ + + /* init the EtherSound sample rate */ + err = lx_dsp_get_clock_frequency(chip, &freq); + if (err == 0) + chip->board_sample_rate = freq; + snd_printd(LXP "actual clock frequency %d\n", freq); + } else { + snd_printk(KERN_ERR LXP "DSP corrupted \n"); + err = -EAGAIN; + } + + return err; +} + +static int lx_set_granularity(struct lx6464es *chip, u32 gran) +{ + int err = 0; + u32 snapped_gran = MICROBLAZE_IBL_MIN; + + snd_printdd("->lx_set_granularity\n"); + + /* blocksize is a power of 2 */ + while ((snapped_gran < gran) && + (snapped_gran < MICROBLAZE_IBL_MAX)) { + snapped_gran *= 2; + } + + if (snapped_gran == chip->pcm_granularity) + return 0; + + err = lx_dsp_set_granularity(chip, snapped_gran); + if (err < 0) { + snd_printk(KERN_WARNING LXP "could not set granularity\n"); + err = -EAGAIN; + } + + if (snapped_gran != gran) + snd_printk(LXP "snapped blocksize to %d\n", snapped_gran); + + snd_printd(LXP "set blocksize on board %d\n", snapped_gran); + chip->pcm_granularity = snapped_gran; + + return err; +} + +/* initialize and test the xilinx dsp chip */ +static int __devinit lx_init_dsp(struct lx6464es *chip) +{ + int err; + u8 mac_address[6]; + int i; + + snd_printdd("->lx_init_dsp\n"); + + snd_printd(LXP "initialize board\n"); + err = lx_init_xilinx_reset(chip); + if (err) + return err; + + snd_printd(LXP "testing board\n"); + err = lx_init_xilinx_test(chip); + if (err) + return err; + + snd_printd(LXP "initialize ethersound configuration\n"); + err = lx_init_ethersound_config(chip); + if (err) + return err; + + lx_irq_enable(chip); + + /** \todo the mac address should be ready by not, but it isn't, + * so we wait for it */ + for (i = 0; i != 1000; ++i) { + err = lx_dsp_get_mac(chip, mac_address); + if (err) + return err; + if (mac_address[0] || mac_address[1] || mac_address[2] || + mac_address[3] || mac_address[4] || mac_address[5]) + goto mac_ready; + msleep(1); + } + return -ETIMEDOUT; + +mac_ready: + snd_printd(LXP "mac address ready read after: %dms\n", i); + snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n", + mac_address[0], mac_address[1], mac_address[2], + mac_address[3], mac_address[4], mac_address[5]); + + err = lx_init_get_version_features(chip); + if (err) + return err; + + lx_set_granularity(chip, MICROBLAZE_IBL_DEFAULT); + + chip->playback_mute = 0; + + return err; +} + +static struct snd_pcm_ops lx_ops_playback = { + .open = lx_pcm_open, + .close = lx_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .prepare = lx_pcm_prepare, + .hw_params = lx_pcm_hw_params_playback, + .hw_free = lx_pcm_hw_free, + .trigger = lx_pcm_trigger, + .pointer = lx_pcm_stream_pointer, +}; + +static struct snd_pcm_ops lx_ops_capture = { + .open = lx_pcm_open, + .close = lx_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .prepare = lx_pcm_prepare, + .hw_params = lx_pcm_hw_params_capture, + .hw_free = lx_pcm_hw_free, + .trigger = lx_pcm_trigger, + .pointer = lx_pcm_stream_pointer, +}; + +static int __devinit lx_pcm_create(struct lx6464es *chip) +{ + int err; + struct snd_pcm *pcm; + + u32 size = 64 * /* channels */ + 3 * /* 24 bit samples */ + MAX_STREAM_BUFFER * /* periods */ + MICROBLAZE_IBL_MAX * /* frames per period */ + 2; /* duplex */ + + size = PAGE_ALIGN(size); + + /* hardcoded device name & channel count */ + err = snd_pcm_new(chip->card, (char *)card_name, 0, + 1, 1, &pcm); + + pcm->private_data = chip; + + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &lx_ops_playback); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &lx_ops_capture); + + pcm->info_flags = 0; + strcpy(pcm->name, card_name); + + err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + snd_dma_pci_data(chip->pci), + size, size); + if (err < 0) + return err; + + chip->pcm = pcm; + chip->capture_stream.is_capture = 1; + + return 0; +} + +static int lx_control_playback_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int lx_control_playback_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct lx6464es *chip = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = chip->playback_mute; + return 0; +} + +static int lx_control_playback_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct lx6464es *chip = snd_kcontrol_chip(kcontrol); + int changed = 0; + int current_value = chip->playback_mute; + + if (current_value != ucontrol->value.integer.value[0]) { + lx_level_unmute(chip, 0, !current_value); + chip->playback_mute = !current_value; + changed = 1; + } + return changed; +} + +static struct snd_kcontrol_new lx_control_playback_switch __devinitdata = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "PCM Playback Switch", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .private_value = 0, + .info = lx_control_playback_info, + .get = lx_control_playback_get, + .put = lx_control_playback_put +}; + + + +static void lx_proc_levels_read(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + u32 levels[64]; + int err; + int i, j; + struct lx6464es *chip = entry->private_data; + + snd_iprintf(buffer, "capture levels:\n"); + err = lx_level_peaks(chip, 1, 64, levels); + if (err < 0) + return; + + for (i = 0; i != 8; ++i) { + for (j = 0; j != 8; ++j) + snd_iprintf(buffer, "%08x ", levels[i*8+j]); + snd_iprintf(buffer, "\n"); + } + + snd_iprintf(buffer, "\nplayback levels:\n"); + + err = lx_level_peaks(chip, 0, 64, levels); + if (err < 0) + return; + + for (i = 0; i != 8; ++i) { + for (j = 0; j != 8; ++j) + snd_iprintf(buffer, "%08x ", levels[i*8+j]); + snd_iprintf(buffer, "\n"); + } + + snd_iprintf(buffer, "\n"); +} + +static int __devinit lx_proc_create(struct snd_card *card, struct lx6464es *chip) +{ + struct snd_info_entry *entry; + int err = snd_card_proc_new(card, "levels", &entry); + if (err < 0) + return err; + + snd_info_set_text_ops(entry, chip, lx_proc_levels_read); + return 0; +} + + +static int __devinit snd_lx6464es_create(struct snd_card *card, + struct pci_dev *pci, + struct lx6464es **rchip) +{ + struct lx6464es *chip; + int err; + + static struct snd_device_ops ops = { + .dev_free = snd_lx6464es_dev_free, + }; + + snd_printdd("->snd_lx6464es_create\n"); + + *rchip = NULL; + + /* enable PCI device */ + err = pci_enable_device(pci); + if (err < 0) + return err; + + pci_set_master(pci); + + /* check if we can restrict PCI DMA transfers to 32 bits */ + err = pci_set_dma_mask(pci, DMA_32BIT_MASK); + if (err < 0) { + snd_printk(KERN_ERR "architecture does not support " + "32bit PCI busmaster DMA\n"); + pci_disable_device(pci); + return -ENXIO; + } + + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (chip == NULL) { + err = -ENOMEM; + goto alloc_failed; + } + + chip->card = card; + chip->pci = pci; + chip->irq = -1; + + /* initialize synchronization structs */ + spin_lock_init(&chip->lock); + spin_lock_init(&chip->msg_lock); + mutex_init(&chip->setup_mutex); + tasklet_init(&chip->trigger_tasklet, lx_trigger_tasklet, + (unsigned long)chip); + tasklet_init(&chip->tasklet_capture, lx_tasklet_capture, + (unsigned long)chip); + tasklet_init(&chip->tasklet_playback, lx_tasklet_playback, + (unsigned long)chip); + + /* request resources */ + err = pci_request_regions(pci, card_name); + if (err < 0) + goto request_regions_failed; + + /* plx port */ + chip->port_plx = pci_resource_start(pci, 1); + chip->port_plx_remapped = ioport_map(chip->port_plx, + pci_resource_len(pci, 1)); + + /* dsp port */ + chip->port_dsp_bar = pci_ioremap_bar(pci, 2); + + err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED, + card_name, chip); + if (err) { + snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq); + goto request_irq_failed; + } + chip->irq = pci->irq; + + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) + goto device_new_failed; + + err = lx_init_dsp(chip); + if (err < 0) { + snd_printk(KERN_ERR LXP "error during DSP initialization\n"); + return err; + } + + err = lx_pcm_create(chip); + if (err < 0) + return err; + + err = lx_proc_create(card, chip); + if (err < 0) + return err; + + err = snd_ctl_add(card, snd_ctl_new1(&lx_control_playback_switch, + chip)); + if (err < 0) + return err; + + snd_card_set_dev(card, &pci->dev); + + *rchip = chip; + return 0; + +device_new_failed: + free_irq(pci->irq, chip); + +request_irq_failed: + pci_release_regions(pci); + +request_regions_failed: + kfree(chip); + +alloc_failed: + pci_disable_device(pci); + + return err; +} + +static int __devinit snd_lx6464es_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) +{ + static int dev; + struct snd_card *card; + struct lx6464es *chip; + int err; + + snd_printdd("->snd_lx6464es_probe\n"); + + if (dev >= SNDRV_CARDS) + return -ENODEV; + if (!enable[dev]) { + dev++; + return -ENOENT; + } + + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; + + err = snd_lx6464es_create(card, pci, &chip); + if (err < 0) { + snd_printk(KERN_ERR LXP "error during snd_lx6464es_create\n"); + goto out_free; + } + + strcpy(card->driver, "lx6464es"); + strcpy(card->shortname, "Digigram LX6464ES"); + sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i", + card->shortname, chip->port_plx, + chip->port_dsp_bar, chip->irq); + + err = snd_card_register(card); + if (err < 0) + goto out_free; + + snd_printdd(LXP "initialization successful\n"); + pci_set_drvdata(pci, card); + dev++; + return 0; + +out_free: + snd_card_free(card); + return err; + +} + +static void __devexit snd_lx6464es_remove(struct pci_dev *pci) +{ + snd_card_free(pci_get_drvdata(pci)); + pci_set_drvdata(pci, NULL); +} + + +static struct pci_driver driver = { + .name = "Digigram LX6464ES", + .id_table = snd_lx6464es_ids, + .probe = snd_lx6464es_probe, + .remove = __devexit_p(snd_lx6464es_remove), +}; + + +/* module initialization */ +static int __init mod_init(void) +{ + return pci_register_driver(&driver); +} + +static void __exit mod_exit(void) +{ + pci_unregister_driver(&driver); +} + +module_init(mod_init); +module_exit(mod_exit); diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h new file mode 100644 index 000000000000..012c010c8c89 --- /dev/null +++ b/sound/pci/lx6464es/lx6464es.h @@ -0,0 +1,114 @@ +/* -*- linux-c -*- * + * + * ALSA driver for the digigram lx6464es interface + * + * Copyright (c) 2009 Tim Blechmann + * + * + * 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LX6464ES_H +#define LX6464ES_H + +#include +#include + +#include +#include + +#include "lx_core.h" + +#define LXP "LX6464ES: " + +enum { + ES_cmd_free = 0, /* no command executing */ + ES_cmd_processing = 1, /* execution of a read/write command */ + ES_read_pending = 2, /* a asynchron read command is pending */ + ES_read_finishing = 3, /* a read command has finished waiting (set by + * Interrupt or CancelIrp) */ +}; + +enum lx_stream_status { + LX_STREAM_STATUS_FREE, +/* LX_STREAM_STATUS_OPEN, */ + LX_STREAM_STATUS_SCHEDULE_RUN, +/* LX_STREAM_STATUS_STARTED, */ + LX_STREAM_STATUS_RUNNING, + LX_STREAM_STATUS_SCHEDULE_STOP, +/* LX_STREAM_STATUS_STOPPED, */ +/* LX_STREAM_STATUS_PAUSED */ +}; + + +struct lx_stream { + struct snd_pcm_substream *stream; + snd_pcm_uframes_t frame_pos; + enum lx_stream_status status; /* free, open, running, draining + * pause */ + int is_capture:1; +}; + + +struct lx6464es { + struct snd_card *card; + struct pci_dev *pci; + int irq; + + spinlock_t lock; /* interrupt spinlock */ + struct mutex setup_mutex; /* mutex used in hw_params, open + * and close */ + + struct tasklet_struct trigger_tasklet; /* trigger tasklet */ + struct tasklet_struct tasklet_capture; + struct tasklet_struct tasklet_playback; + + /* ports */ + unsigned long port_plx; /* io port (size=256) */ + void __iomem *port_plx_remapped; /* remapped plx port */ + void __iomem *port_dsp_bar; /* memory port (32-bit, + * non-prefetchable, + * size=8K) */ + + /* messaging */ + spinlock_t msg_lock; /* message spinlock */ + atomic_t send_message_locked; + struct lx_rmh rmh; + + /* configuration */ + uint freq_ratio : 2; + uint playback_mute : 1; + uint hardware_running[2]; + u32 board_sample_rate; /* sample rate read from + * board */ + u32 sample_rate; /* our sample rate */ + u16 pcm_granularity; /* board blocksize */ + + /* dma */ + struct snd_dma_buffer capture_dma_buf; + struct snd_dma_buffer playback_dma_buf; + + /* pcm */ + struct snd_pcm *pcm; + + /* streams */ + struct lx_stream capture_stream; + struct lx_stream playback_stream; +}; + + +#endif /* LX6464ES_H */ diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c new file mode 100644 index 000000000000..a9f8f882b107 --- /dev/null +++ b/sound/pci/lx6464es/lx_core.c @@ -0,0 +1,1442 @@ +/* -*- linux-c -*- * + * + * ALSA driver for the digigram lx6464es interface + * low-level interface + * + * Copyright (c) 2009 Tim Blechmann + * + * 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +/* #define RMH_DEBUG 1 */ + +#include +#include +#include + +#include "lx6464es.h" +#include "lx_core.h" + +/* low-level register access */ + +static const unsigned long dsp_port_offsets[] = { + 0, + 0x400, + 0x401, + 0x402, + 0x403, + 0x404, + 0x405, + 0x406, + 0x407, + 0x408, + 0x409, + 0x40a, + 0x40b, + 0x40c, + + 0x410, + 0x411, + 0x412, + 0x413, + 0x414, + 0x415, + 0x416, + + 0x420, + 0x430, + 0x431, + 0x432, + 0x433, + 0x434, + 0x440 +}; + +static void __iomem *lx_dsp_register(struct lx6464es *chip, int port) +{ + void __iomem *base_address = chip->port_dsp_bar; + return base_address + dsp_port_offsets[port]*4; +} + +unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port) +{ + void __iomem *address = lx_dsp_register(chip, port); + return ioread32(address); +} + +void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len) +{ + void __iomem *address = lx_dsp_register(chip, port); + memcpy_fromio(data, address, len*sizeof(u32)); +} + + +void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data) +{ + void __iomem *address = lx_dsp_register(chip, port); + iowrite32(data, address); +} + +void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, + u32 len) +{ + void __iomem *address = lx_dsp_register(chip, port); + memcpy_toio(address, data, len*sizeof(u32)); +} + + +static const unsigned long plx_port_offsets[] = { + 0x04, + 0x40, + 0x44, + 0x48, + 0x4c, + 0x50, + 0x54, + 0x58, + 0x5c, + 0x64, + 0x68, + 0x6C +}; + +static void __iomem *lx_plx_register(struct lx6464es *chip, int port) +{ + void __iomem *base_address = chip->port_plx_remapped; + return base_address + plx_port_offsets[port]; +} + +unsigned long lx_plx_reg_read(struct lx6464es *chip, int port) +{ + void __iomem *address = lx_plx_register(chip, port); + return ioread32(address); +} + +void lx_plx_reg_write(struct lx6464es *chip, int port, u32 data) +{ + void __iomem *address = lx_plx_register(chip, port); + iowrite32(data, address); +} + +u32 lx_plx_mbox_read(struct lx6464es *chip, int mbox_nr) +{ + int index; + + switch (mbox_nr) { + case 1: + index = ePLX_MBOX1; break; + case 2: + index = ePLX_MBOX2; break; + case 3: + index = ePLX_MBOX3; break; + case 4: + index = ePLX_MBOX4; break; + case 5: + index = ePLX_MBOX5; break; + case 6: + index = ePLX_MBOX6; break; + case 7: + index = ePLX_MBOX7; break; + case 0: /* reserved for HF flags */ + snd_BUG(); + default: + return 0xdeadbeef; + } + + return lx_plx_reg_read(chip, index); +} + +int lx_plx_mbox_write(struct lx6464es *chip, int mbox_nr, u32 value) +{ + int index = -1; + + switch (mbox_nr) { + case 1: + index = ePLX_MBOX1; break; + case 3: + index = ePLX_MBOX3; break; + case 4: + index = ePLX_MBOX4; break; + case 5: + index = ePLX_MBOX5; break; + case 6: + index = ePLX_MBOX6; break; + case 7: + index = ePLX_MBOX7; break; + case 0: /* reserved for HF flags */ + case 2: /* reserved for Pipe States + * the DSP keeps an image of it */ + snd_BUG(); + return -EBADRQC; + } + + lx_plx_reg_write(chip, index, value); + return 0; +} + + +/* rmh */ + +#ifdef CONFIG_SND_DEBUG +#define CMD_NAME(a) a +#else +#define CMD_NAME(a) NULL +#endif + +#define Reg_CSM_MR 0x00000002 +#define Reg_CSM_MC 0x00000001 + +struct dsp_cmd_info { + u32 dcCodeOp; /* Op Code of the command (usually 1st 24-bits + * word).*/ + u16 dcCmdLength; /* Command length in words of 24 bits.*/ + u16 dcStatusType; /* Status type: 0 for fixed length, 1 for + * random. */ + u16 dcStatusLength; /* Status length (if fixed).*/ + char *dcOpName; +}; + +/* + Initialization and control data for the Microblaze interface + - OpCode: + the opcode field of the command set at the proper offset + - CmdLength + the number of command words + - StatusType + offset in the status registers: 0 means that the return value may be + different from 0, and must be read + - StatusLength + the number of status words (in addition to the return value) +*/ + +static struct dsp_cmd_info dsp_commands[] = +{ + { (CMD_00_INFO_DEBUG << OPCODE_OFFSET) , 1 /*custom*/ + , 1 , 0 /**/ , CMD_NAME("INFO_DEBUG") }, + { (CMD_01_GET_SYS_CFG << OPCODE_OFFSET) , 1 /**/ + , 1 , 2 /**/ , CMD_NAME("GET_SYS_CFG") }, + { (CMD_02_SET_GRANULARITY << OPCODE_OFFSET) , 1 /**/ + , 1 , 0 /**/ , CMD_NAME("SET_GRANULARITY") }, + { (CMD_03_SET_TIMER_IRQ << OPCODE_OFFSET) , 1 /**/ + , 1 , 0 /**/ , CMD_NAME("SET_TIMER_IRQ") }, + { (CMD_04_GET_EVENT << OPCODE_OFFSET) , 1 /**/ + , 1 , 0 /*up to 10*/ , CMD_NAME("GET_EVENT") }, + { (CMD_05_GET_PIPES << OPCODE_OFFSET) , 1 /**/ + , 1 , 2 /*up to 4*/ , CMD_NAME("GET_PIPES") }, + { (CMD_06_ALLOCATE_PIPE << OPCODE_OFFSET) , 1 /**/ + , 0 , 0 /**/ , CMD_NAME("ALLOCATE_PIPE") }, + { (CMD_07_RELEASE_PIPE << OPCODE_OFFSET) , 1 /**/ + , 0 , 0 /**/ , CMD_NAME("RELEASE_PIPE") }, + { (CMD_08_ASK_BUFFERS << OPCODE_OFFSET) , 1 /**/ + , 1 , MAX_STREAM_BUFFER , CMD_NAME("ASK_BUFFERS") }, + { (CMD_09_STOP_PIPE << OPCODE_OFFSET) , 1 /**/ + , 0 , 0 /*up to 2*/ , CMD_NAME("STOP_PIPE") }, + { (CMD_0A_GET_PIPE_SPL_COUNT << OPCODE_OFFSET) , 1 /**/ + , 1 , 1 /*up to 2*/ , CMD_NAME("GET_PIPE_SPL_COUNT") }, + { (CMD_0B_TOGGLE_PIPE_STATE << OPCODE_OFFSET) , 1 /*up to 5*/ + , 1 , 0 /**/ , CMD_NAME("TOGGLE_PIPE_STATE") }, + { (CMD_0C_DEF_STREAM << OPCODE_OFFSET) , 1 /*up to 4*/ + , 1 , 0 /**/ , CMD_NAME("DEF_STREAM") }, + { (CMD_0D_SET_MUTE << OPCODE_OFFSET) , 3 /**/ + , 1 , 0 /**/ , CMD_NAME("SET_MUTE") }, + { (CMD_0E_GET_STREAM_SPL_COUNT << OPCODE_OFFSET) , 1/**/ + , 1 , 2 /**/ , CMD_NAME("GET_STREAM_SPL_COUNT") }, + { (CMD_0F_UPDATE_BUFFER << OPCODE_OFFSET) , 3 /*up to 4*/ + , 0 , 1 /**/ , CMD_NAME("UPDATE_BUFFER") }, + { (CMD_10_GET_BUFFER << OPCODE_OFFSET) , 1 /**/ + , 1 , 4 /**/ , CMD_NAME("GET_BUFFER") }, + { (CMD_11_CANCEL_BUFFER << OPCODE_OFFSET) , 1 /**/ + , 1 , 1 /*up to 4*/ , CMD_NAME("CANCEL_BUFFER") }, + { (CMD_12_GET_PEAK << OPCODE_OFFSET) , 1 /**/ + , 1 , 1 /**/ , CMD_NAME("GET_PEAK") }, + { (CMD_13_SET_STREAM_STATE << OPCODE_OFFSET) , 1 /**/ + , 1 , 0 /**/ , CMD_NAME("SET_STREAM_STATE") }, +}; + +static void lx_message_init(struct lx_rmh *rmh, enum cmd_mb_opcodes cmd) +{ + snd_BUG_ON(cmd >= CMD_14_INVALID); + + rmh->cmd[0] = dsp_commands[cmd].dcCodeOp; + rmh->cmd_len = dsp_commands[cmd].dcCmdLength; + rmh->stat_len = dsp_commands[cmd].dcStatusLength; + rmh->dsp_stat = dsp_commands[cmd].dcStatusType; + rmh->cmd_idx = cmd; + memset(&rmh->cmd[1], 0, (REG_CRM_NUMBER - 1) * sizeof(u32)); + +#ifdef CONFIG_SND_DEBUG + memset(rmh->stat, 0, REG_CRM_NUMBER * sizeof(u32)); +#endif +#ifdef RMH_DEBUG + rmh->cmd_idx = cmd; +#endif +} + +#ifdef RMH_DEBUG +#define LXRMH "lx6464es rmh: " +static void lx_message_dump(struct lx_rmh *rmh) +{ + u8 idx = rmh->cmd_idx; + int i; + + snd_printk(LXRMH "command %s\n", dsp_commands[idx].dcOpName); + + for (i = 0; i != rmh->cmd_len; ++i) + snd_printk(LXRMH "\tcmd[%d] %08x\n", i, rmh->cmd[i]); + + for (i = 0; i != rmh->stat_len; ++i) + snd_printk(LXRMH "\tstat[%d]: %08x\n", i, rmh->stat[i]); + snd_printk("\n"); +} +#else +static inline void lx_message_dump(struct lx_rmh *rmh) +{} +#endif + + + +/* sleep 500 - 100 = 400 times 100us -> the timeout is >= 40 ms */ +#define XILINX_TIMEOUT_MS 40 +#define XILINX_POLL_NO_SLEEP 100 +#define XILINX_POLL_ITERATIONS 150 + +static int lx_message_send(struct lx6464es *chip, struct lx_rmh *rmh) +{ + u32 reg = ED_DSP_TIMED_OUT; + int dwloop; + int answer_received; + + if (lx_dsp_reg_read(chip, eReg_CSM) & (Reg_CSM_MC | Reg_CSM_MR)) { + snd_printk(KERN_ERR LXP "PIOSendMessage eReg_CSM %x\n", reg); + return -EBUSY; + } + + /* write command */ + lx_dsp_reg_writebuf(chip, eReg_CRM1, rmh->cmd, rmh->cmd_len); + + snd_BUG_ON(atomic_read(&chip->send_message_locked) != 0); + atomic_set(&chip->send_message_locked, 1); + + /* MicoBlaze gogogo */ + lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC); + + /* wait for interrupt to answer */ + for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS; ++dwloop) { + answer_received = atomic_read(&chip->send_message_locked); + if (answer_received == 0) + break; + msleep(1); + } + + if (answer_received == 0) { + /* in Debug mode verify Reg_CSM_MR */ + snd_BUG_ON(!(lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR)); + + /* command finished, read status */ + if (rmh->dsp_stat == 0) + reg = lx_dsp_reg_read(chip, eReg_CRM1); + else + reg = 0; + } else { + int i; + snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send! " + "Interrupts disabled?\n"); + + /* attente bit Reg_CSM_MR */ + for (i = 0; i != XILINX_POLL_ITERATIONS; i++) { + if ((lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR)) { + if (rmh->dsp_stat == 0) + reg = lx_dsp_reg_read(chip, eReg_CRM1); + else + reg = 0; + goto polling_successful; + } + + if (i > XILINX_POLL_NO_SLEEP) + msleep(1); + } + snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send! " + "polling failed\n"); + +polling_successful: + atomic_set(&chip->send_message_locked, 0); + } + + if ((reg & ERROR_VALUE) == 0) { + /* read response */ + if (rmh->stat_len) { + snd_BUG_ON(rmh->stat_len >= (REG_CRM_NUMBER-1)); + + lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat, + rmh->stat_len); + } + } else + snd_printk(KERN_WARNING LXP "lx_message_send: error_value %x\n", + reg); + + /* clear Reg_CSM_MR */ + lx_dsp_reg_write(chip, eReg_CSM, 0); + + switch (reg) { + case ED_DSP_TIMED_OUT: + snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n"); + return -ETIMEDOUT; + + case ED_DSP_CRASHED: + snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n"); + return -EAGAIN; + } + + lx_message_dump(rmh); + return 0; +} + +static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh) +{ + u32 reg = ED_DSP_TIMED_OUT; + int dwloop; + + if (lx_dsp_reg_read(chip, eReg_CSM) & (Reg_CSM_MC | Reg_CSM_MR)) { + snd_printk(KERN_ERR LXP "PIOSendMessage eReg_CSM %x\n", reg); + return -EBUSY; + } + + /* write command */ + lx_dsp_reg_writebuf(chip, eReg_CRM1, rmh->cmd, rmh->cmd_len); + + /* MicoBlaze gogogo */ + lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC); + + /* wait for interrupt to answer */ + for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS * 1000; ++dwloop) { + if (lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR) { + if (rmh->dsp_stat == 0) + reg = lx_dsp_reg_read(chip, eReg_CRM1); + else + reg = 0; + goto polling_successful; + } else + udelay(1); + } + snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send_atomic! " + "polling failed\n"); + +polling_successful: + if ((reg & ERROR_VALUE) == 0) { + /* read response */ + if (rmh->stat_len) { + snd_BUG_ON(rmh->stat_len >= (REG_CRM_NUMBER-1)); + lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat, + rmh->stat_len); + } + } else + snd_printk(LXP "rmh error: %08x\n", reg); + + /* clear Reg_CSM_MR */ + lx_dsp_reg_write(chip, eReg_CSM, 0); + + switch (reg) { + case ED_DSP_TIMED_OUT: + snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n"); + return -ETIMEDOUT; + + case ED_DSP_CRASHED: + snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n"); + return -EAGAIN; + } + + lx_message_dump(rmh); + + return reg; +} + + +/* low-level dsp access */ +int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version) +{ + u16 ret; + unsigned long flags; + + spin_lock_irqsave(&chip->msg_lock, flags); + + lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG); + ret = lx_message_send_atomic(chip, &chip->rmh); + + *rdsp_version = chip->rmh.stat[1]; + spin_unlock_irqrestore(&chip->msg_lock, flags); + return ret; +} + +int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq) +{ + u16 ret = 0; + unsigned long flags; + u32 freq_raw = 0; + u32 freq = 0; + u32 frequency = 0; + + spin_lock_irqsave(&chip->msg_lock, flags); + + lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG); + ret = lx_message_send_atomic(chip, &chip->rmh); + + if (ret == 0) { + freq_raw = chip->rmh.stat[0] >> FREQ_FIELD_OFFSET; + freq = freq_raw & XES_FREQ_COUNT8_MASK; + + if ((freq < XES_FREQ_COUNT8_48_MAX) || + (freq > XES_FREQ_COUNT8_44_MIN)) + frequency = 0; /* unknown */ + else if (freq >= XES_FREQ_COUNT8_44_MAX) + frequency = 44100; + else + frequency = 48000; + } + + spin_unlock_irqrestore(&chip->msg_lock, flags); + + *rfreq = frequency * chip->freq_ratio; + + return ret; +} + +int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address) +{ + u32 macmsb, maclsb; + + macmsb = lx_dsp_reg_read(chip, eReg_ADMACESMSB) & 0x00FFFFFF; + maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF; + + /* todo: endianess handling */ + mac_address[5] = ((u8 *)(&maclsb))[0]; + mac_address[4] = ((u8 *)(&maclsb))[1]; + mac_address[3] = ((u8 *)(&maclsb))[2]; + mac_address[2] = ((u8 *)(&macmsb))[0]; + mac_address[1] = ((u8 *)(&macmsb))[1]; + mac_address[0] = ((u8 *)(&macmsb))[2]; + + return 0; +} + + +int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&chip->msg_lock, flags); + + lx_message_init(&chip->rmh, CMD_02_SET_GRANULARITY); + chip->rmh.cmd[0] |= gran; + + ret = lx_message_send_atomic(chip, &chip->rmh); + spin_unlock_irqrestore(&chip->msg_lock, flags); + return ret; +} + +int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&chip->msg_lock, flags); + + lx_message_init(&chip->rmh, CMD_04_GET_EVENT); + chip->rmh.stat_len = 9; /* we don't necessarily need the full length */ + + ret = lx_message_send_atomic(chip, &chip->rmh); + + if (!ret) + memcpy(data, chip->rmh.stat, chip->rmh.stat_len * sizeof(u32)); + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return ret; +} + +#define CSES_TIMEOUT 100 /* microseconds */ +#define CSES_CE 0x0001 +#define CSES_BROADCAST 0x0002 +#define CSES_UPDATE_LDSV 0x0004 + +int lx_dsp_es_check_pipeline(struct lx6464es *chip) +{ + int i; + + for (i = 0; i != CSES_TIMEOUT; ++i) { + /* + * le bit CSES_UPDATE_LDSV est à 1 dés que le macprog + * est pret. il re-passe à 0 lorsque le premier read a + * été fait. pour l'instant on retire le test car ce bit + * passe a 1 environ 200 à 400 ms aprés que le registre + * confES à été écrit (kick du xilinx ES). + * + * On ne teste que le bit CE. + * */ + + u32 cses = lx_dsp_reg_read(chip, eReg_CSES); + + if ((cses & CSES_CE) == 0) + return 0; + + udelay(1); + } + + return -ETIMEDOUT; +} + + +#define PIPE_INFO_TO_CMD(capture, pipe) \ + ((u32)((u32)(pipe) | ((capture) ? ID_IS_CAPTURE : 0L)) << ID_OFFSET) + + + +/* low-level pipe handling */ +int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture, + int channels) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_06_ALLOCATE_PIPE); + + chip->rmh.cmd[0] |= pipe_cmd; + chip->rmh.cmd[0] |= channels; + + err = lx_message_send_atomic(chip, &chip->rmh); + spin_unlock_irqrestore(&chip->msg_lock, flags); + + if (err != 0) + snd_printk(KERN_ERR "lx6464es: could not allocate pipe\n"); + + return err; +} + +int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_07_RELEASE_PIPE); + + chip->rmh.cmd[0] |= pipe_cmd; + + err = lx_message_send_atomic(chip, &chip->rmh); + spin_unlock_irqrestore(&chip->msg_lock, flags); + + return err; +} + +int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, + u32 *r_needed, u32 *r_freed, u32 *size_array) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + +#ifdef CONFIG_SND_DEBUG + if (size_array) + memset(size_array, 0, sizeof(u32)*MAX_STREAM_BUFFER); +#endif + + *r_needed = 0; + *r_freed = 0; + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_08_ASK_BUFFERS); + + chip->rmh.cmd[0] |= pipe_cmd; + + err = lx_message_send_atomic(chip, &chip->rmh); + + if (!err) { + int i; + for (i = 0; i < MAX_STREAM_BUFFER; ++i) { + u32 stat = chip->rmh.stat[i]; + if (stat & (BF_EOB << BUFF_FLAGS_OFFSET)) { + /* finished */ + *r_freed += 1; + if (size_array) + size_array[i] = stat & MASK_DATA_SIZE; + } else if ((stat & (BF_VALID << BUFF_FLAGS_OFFSET)) + == 0) + /* free */ + *r_needed += 1; + } + +#if 0 + snd_printdd(LXP "CMD_08_ASK_BUFFERS: needed %d, freed %d\n", + *r_needed, *r_freed); + for (i = 0; i < MAX_STREAM_BUFFER; ++i) { + for (i = 0; i != chip->rmh.stat_len; ++i) + snd_printdd(" stat[%d]: %x, %x\n", i, + chip->rmh.stat[i], + chip->rmh.stat[i] & MASK_DATA_SIZE); + } +#endif + } + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + + +int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_09_STOP_PIPE); + + chip->rmh.cmd[0] |= pipe_cmd; + + err = lx_message_send_atomic(chip, &chip->rmh); + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + +static int lx_pipe_toggle_state(struct lx6464es *chip, u32 pipe, int is_capture) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_0B_TOGGLE_PIPE_STATE); + + chip->rmh.cmd[0] |= pipe_cmd; + + err = lx_message_send_atomic(chip, &chip->rmh); + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + + +int lx_pipe_start(struct lx6464es *chip, u32 pipe, int is_capture) +{ + int err; + + err = lx_pipe_wait_for_idle(chip, pipe, is_capture); + if (err < 0) + return err; + + err = lx_pipe_toggle_state(chip, pipe, is_capture); + + return err; +} + +int lx_pipe_pause(struct lx6464es *chip, u32 pipe, int is_capture) +{ + int err = 0; + + err = lx_pipe_wait_for_start(chip, pipe, is_capture); + if (err < 0) + return err; + + err = lx_pipe_toggle_state(chip, pipe, is_capture); + + return err; +} + + +int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture, + u64 *rsample_count) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT); + + chip->rmh.cmd[0] |= pipe_cmd; + chip->rmh.stat_len = 2; /* need all words here! */ + + err = lx_message_send_atomic(chip, &chip->rmh); /* don't sleep! */ + + if (err != 0) + snd_printk(KERN_ERR + "lx6464es: could not query pipe's sample count\n"); + else { + *rsample_count = ((u64)(chip->rmh.stat[0] & MASK_SPL_COUNT_HI) + << 24) /* hi part */ + + chip->rmh.stat[1]; /* lo part */ + } + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + +int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT); + + chip->rmh.cmd[0] |= pipe_cmd; + + err = lx_message_send_atomic(chip, &chip->rmh); + + if (err != 0) + snd_printk(KERN_ERR "lx6464es: could not query pipe's state\n"); + else + *rstate = (chip->rmh.stat[0] >> PSTATE_OFFSET) & 0x0F; + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + +static int lx_pipe_wait_for_state(struct lx6464es *chip, u32 pipe, + int is_capture, u16 state) +{ + int i; + + /* max 2*PCMOnlyGranularity = 2*1024 at 44100 = < 50 ms: + * timeout 50 ms */ + for (i = 0; i != 50; ++i) { + u16 current_state; + int err = lx_pipe_state(chip, pipe, is_capture, ¤t_state); + + if (err < 0) + return err; + + if (current_state == state) + return 0; + + mdelay(1); + } + + return -ETIMEDOUT; +} + +int lx_pipe_wait_for_start(struct lx6464es *chip, u32 pipe, int is_capture) +{ + return lx_pipe_wait_for_state(chip, pipe, is_capture, PSTATE_RUN); +} + +int lx_pipe_wait_for_idle(struct lx6464es *chip, u32 pipe, int is_capture) +{ + return lx_pipe_wait_for_state(chip, pipe, is_capture, PSTATE_IDLE); +} + +/* low-level stream handling */ +int lx_stream_set_state(struct lx6464es *chip, u32 pipe, + int is_capture, enum stream_state_t state) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_13_SET_STREAM_STATE); + + chip->rmh.cmd[0] |= pipe_cmd; + chip->rmh.cmd[0] |= state; + + err = lx_message_send_atomic(chip, &chip->rmh); + spin_unlock_irqrestore(&chip->msg_lock, flags); + + return err; +} + +int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime, + u32 pipe, int is_capture) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + u32 channels = runtime->channels; + + if (runtime->channels != channels) + snd_printk(KERN_ERR LXP "channel count mismatch: %d vs %d", + runtime->channels, channels); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM); + + chip->rmh.cmd[0] |= pipe_cmd; + + if (runtime->sample_bits == 16) + /* 16 bit format */ + chip->rmh.cmd[0] |= (STREAM_FMT_16b << STREAM_FMT_OFFSET); + + if (snd_pcm_format_little_endian(runtime->format)) + /* little endian/intel format */ + chip->rmh.cmd[0] |= (STREAM_FMT_intel << STREAM_FMT_OFFSET); + + chip->rmh.cmd[0] |= channels-1; + + err = lx_message_send_atomic(chip, &chip->rmh); + spin_unlock_irqrestore(&chip->msg_lock, flags); + + return err; +} + +int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture, + int *rstate) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT); + + chip->rmh.cmd[0] |= pipe_cmd; + + err = lx_message_send_atomic(chip, &chip->rmh); + + *rstate = (chip->rmh.stat[0] & SF_START) ? START_STATE : PAUSE_STATE; + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + +int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture, + u64 *r_bytepos) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT); + + chip->rmh.cmd[0] |= pipe_cmd; + + err = lx_message_send_atomic(chip, &chip->rmh); + + *r_bytepos = ((u64) (chip->rmh.stat[0] & MASK_SPL_COUNT_HI) + << 32) /* hi part */ + + chip->rmh.stat[1]; /* lo part */ + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + +/* low-level buffer handling */ +int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture, + u32 buffer_size, u32 buf_address_lo, u32 buf_address_hi, + u32 *r_buffer_index) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_0F_UPDATE_BUFFER); + + chip->rmh.cmd[0] |= pipe_cmd; + chip->rmh.cmd[0] |= BF_NOTIFY_EOB; /* request interrupt notification */ + + /* todo: pause request, circular buffer */ + + chip->rmh.cmd[1] = buffer_size & MASK_DATA_SIZE; + chip->rmh.cmd[2] = buf_address_lo; + + if (buf_address_hi) { + chip->rmh.cmd_len = 4; + chip->rmh.cmd[3] = buf_address_hi; + chip->rmh.cmd[0] |= BF_64BITS_ADR; + } + + err = lx_message_send_atomic(chip, &chip->rmh); + + if (err == 0) { + *r_buffer_index = chip->rmh.stat[0]; + goto done; + } + + if (err == EB_RBUFFERS_TABLE_OVERFLOW) + snd_printk(LXP "lx_buffer_give EB_RBUFFERS_TABLE_OVERFLOW\n"); + + if (err == EB_INVALID_STREAM) + snd_printk(LXP "lx_buffer_give EB_INVALID_STREAM\n"); + + if (err == EB_CMD_REFUSED) + snd_printk(LXP "lx_buffer_give EB_CMD_REFUSED\n"); + + done: + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + +int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture, + u32 *r_buffer_size) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER); + + chip->rmh.cmd[0] |= pipe_cmd; + chip->rmh.cmd[0] |= MASK_BUFFER_ID; /* ask for the current buffer: the + * microblaze will seek for it */ + + err = lx_message_send_atomic(chip, &chip->rmh); + + if (err == 0) + *r_buffer_size = chip->rmh.stat[0] & MASK_DATA_SIZE; + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + +int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture, + u32 buffer_index) +{ + int err; + unsigned long flags; + + u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe); + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER); + + chip->rmh.cmd[0] |= pipe_cmd; + chip->rmh.cmd[0] |= buffer_index; + + err = lx_message_send_atomic(chip, &chip->rmh); + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + + +/* low-level gain/peak handling + * + * \todo: can we unmute capture/playback channels independently? + * + * */ +int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute) +{ + int err; + unsigned long flags; + + /* bit set to 1: channel muted */ + u64 mute_mask = unmute ? 0 : 0xFFFFFFFFFFFFFFFFLLU; + + spin_lock_irqsave(&chip->msg_lock, flags); + lx_message_init(&chip->rmh, CMD_0D_SET_MUTE); + + chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, 0); + + chip->rmh.cmd[1] = (u32)(mute_mask >> (u64)32); /* hi part */ + chip->rmh.cmd[2] = (u32)(mute_mask & (u64)0xFFFFFFFF); /* lo part */ + + snd_printk("mute %x %x %x\n", chip->rmh.cmd[0], chip->rmh.cmd[1], + chip->rmh.cmd[2]); + + err = lx_message_send_atomic(chip, &chip->rmh); + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + +static u32 peak_map[] = { + 0x00000109, /* -90.308dB */ + 0x0000083B, /* -72.247dB */ + 0x000020C4, /* -60.205dB */ + 0x00008273, /* -48.030dB */ + 0x00020756, /* -36.005dB */ + 0x00040C37, /* -30.001dB */ + 0x00081385, /* -24.002dB */ + 0x00101D3F, /* -18.000dB */ + 0x0016C310, /* -15.000dB */ + 0x002026F2, /* -12.001dB */ + 0x002D6A86, /* -9.000dB */ + 0x004026E6, /* -6.004dB */ + 0x005A9DF6, /* -3.000dB */ + 0x0065AC8B, /* -2.000dB */ + 0x00721481, /* -1.000dB */ + 0x007FFFFF, /* FS */ +}; + +int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels, + u32 *r_levels) +{ + int err = 0; + unsigned long flags; + int i; + spin_lock_irqsave(&chip->msg_lock, flags); + + for (i = 0; i < channels; i += 4) { + u32 s0, s1, s2, s3; + + lx_message_init(&chip->rmh, CMD_12_GET_PEAK); + chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, i); + + err = lx_message_send_atomic(chip, &chip->rmh); + + if (err == 0) { + s0 = peak_map[chip->rmh.stat[0] & 0x0F]; + s1 = peak_map[(chip->rmh.stat[0] >> 4) & 0xf]; + s2 = peak_map[(chip->rmh.stat[0] >> 8) & 0xf]; + s3 = peak_map[(chip->rmh.stat[0] >> 12) & 0xf]; + } else + s0 = s1 = s2 = s3 = 0; + + r_levels[0] = s0; + r_levels[1] = s1; + r_levels[2] = s2; + r_levels[3] = s3; + + r_levels += 4; + } + + spin_unlock_irqrestore(&chip->msg_lock, flags); + return err; +} + +/* interrupt handling */ +#define PCX_IRQ_NONE 0 +#define IRQCS_ACTIVE_PCIDB 0x00002000L /* Bit nø 13 */ +#define IRQCS_ENABLE_PCIIRQ 0x00000100L /* Bit nø 08 */ +#define IRQCS_ENABLE_PCIDB 0x00000200L /* Bit nø 09 */ + +static u32 lx_interrupt_test_ack(struct lx6464es *chip) +{ + u32 irqcs = lx_plx_reg_read(chip, ePLX_IRQCS); + + /* Test if PCI Doorbell interrupt is active */ + if (irqcs & IRQCS_ACTIVE_PCIDB) { + u32 temp; + irqcs = PCX_IRQ_NONE; + + while ((temp = lx_plx_reg_read(chip, ePLX_L2PCIDB))) { + /* RAZ interrupt */ + irqcs |= temp; + lx_plx_reg_write(chip, ePLX_L2PCIDB, temp); + } + + return irqcs; + } + return PCX_IRQ_NONE; +} + +static int lx_interrupt_ack(struct lx6464es *chip, u32 *r_irqsrc, + int *r_async_pending, int *r_async_escmd) +{ + u32 irq_async; + u32 irqsrc = lx_interrupt_test_ack(chip); + + if (irqsrc == PCX_IRQ_NONE) + return 0; + + *r_irqsrc = irqsrc; + + irq_async = irqsrc & MASK_SYS_ASYNC_EVENTS; /* + EtherSound response + * (set by xilinx) + EOB */ + + if (irq_async & MASK_SYS_STATUS_ESA) { + irq_async &= ~MASK_SYS_STATUS_ESA; + *r_async_escmd = 1; + } + + if (irqsrc & MASK_SYS_STATUS_CMD_DONE) + /* xilinx command notification */ + atomic_set(&chip->send_message_locked, 0); + + if (irq_async) { + /* snd_printd("interrupt: async event pending\n"); */ + *r_async_pending = 1; + } + + return 1; +} + +static int lx_interrupt_handle_async_events(struct lx6464es *chip, u32 irqsrc, + int *r_freq_changed, + u64 *r_notified_in_pipe_mask, + u64 *r_notified_out_pipe_mask) +{ + int err; + u32 stat[9]; /* answer from CMD_04_GET_EVENT */ + + /* On peut optimiser pour ne pas lire les evenements vides + * les mots de réponse sont dans l'ordre suivant : + * Stat[0] mot de status général + * Stat[1] fin de buffer OUT pF + * Stat[2] fin de buffer OUT pf + * Stat[3] fin de buffer IN pF + * Stat[4] fin de buffer IN pf + * Stat[5] underrun poid fort + * Stat[6] underrun poid faible + * Stat[7] overrun poid fort + * Stat[8] overrun poid faible + * */ + + u64 orun_mask; + u64 urun_mask; +#if 0 + int has_underrun = (irqsrc & MASK_SYS_STATUS_URUN) ? 1 : 0; + int has_overrun = (irqsrc & MASK_SYS_STATUS_ORUN) ? 1 : 0; +#endif + int eb_pending_out = (irqsrc & MASK_SYS_STATUS_EOBO) ? 1 : 0; + int eb_pending_in = (irqsrc & MASK_SYS_STATUS_EOBI) ? 1 : 0; + + *r_freq_changed = (irqsrc & MASK_SYS_STATUS_FREQ) ? 1 : 0; + + err = lx_dsp_read_async_events(chip, stat); + if (err < 0) + return err; + + if (eb_pending_in) { + *r_notified_in_pipe_mask = ((u64)stat[3] << 32) + + stat[4]; + snd_printdd(LXP "interrupt: EOBI pending %llx\n", + *r_notified_in_pipe_mask); + } + if (eb_pending_out) { + *r_notified_out_pipe_mask = ((u64)stat[1] << 32) + + stat[2]; + snd_printdd(LXP "interrupt: EOBO pending %llx\n", + *r_notified_out_pipe_mask); + } + + orun_mask = ((u64)stat[7] << 32) + stat[8]; + urun_mask = ((u64)stat[5] << 32) + stat[6]; + + /* todo: handle xrun notification */ + + return err; +} + +static int lx_interrupt_request_new_buffer(struct lx6464es *chip, + struct lx_stream *lx_stream) +{ + struct snd_pcm_substream *substream = lx_stream->stream; + int is_capture = lx_stream->is_capture; + int err; + unsigned long flags; + + const u32 channels = substream->runtime->channels; + const u32 bytes_per_frame = channels * 3; + const u32 period_size = substream->runtime->period_size; + const u32 period_bytes = period_size * bytes_per_frame; + const u32 pos = lx_stream->frame_pos; + const u32 next_pos = ((pos+1) == substream->runtime->periods) ? + 0 : pos + 1; + + dma_addr_t buf = substream->dma_buffer.addr + pos * period_bytes; + u32 buf_hi = 0; + u32 buf_lo = 0; + u32 buffer_index = 0; + + u32 needed, freed; + u32 size_array[MAX_STREAM_BUFFER]; + + snd_printdd("->lx_interrupt_request_new_buffer\n"); + + spin_lock_irqsave(&chip->lock, flags); + + err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array); + snd_printdd(LXP "interrupt: needed %d, freed %d\n", needed, freed); + + unpack_pointer(buf, &buf_lo, &buf_hi); + err = lx_buffer_give(chip, 0, is_capture, period_bytes, buf_lo, buf_hi, + &buffer_index); + snd_printdd(LXP "interrupt: gave buffer index %x on %p (%d bytes)\n", + buffer_index, (void *)buf, period_bytes); + + lx_stream->frame_pos = next_pos; + spin_unlock_irqrestore(&chip->lock, flags); + + return err; +} + +void lx_tasklet_playback(unsigned long data) +{ + struct lx6464es *chip = (struct lx6464es *)data; + struct lx_stream *lx_stream = &chip->playback_stream; + int err; + + snd_printdd("->lx_tasklet_playback\n"); + + err = lx_interrupt_request_new_buffer(chip, lx_stream); + if (err < 0) + snd_printk(KERN_ERR LXP + "cannot request new buffer for playback\n"); + + snd_pcm_period_elapsed(lx_stream->stream); +} + +void lx_tasklet_capture(unsigned long data) +{ + struct lx6464es *chip = (struct lx6464es *)data; + struct lx_stream *lx_stream = &chip->capture_stream; + int err; + + snd_printdd("->lx_tasklet_capture\n"); + err = lx_interrupt_request_new_buffer(chip, lx_stream); + if (err < 0) + snd_printk(KERN_ERR LXP + "cannot request new buffer for capture\n"); + + snd_pcm_period_elapsed(lx_stream->stream); +} + + + +static int lx_interrupt_handle_audio_transfer(struct lx6464es *chip, + u64 notified_in_pipe_mask, + u64 notified_out_pipe_mask) +{ + int err = 0; + + if (notified_in_pipe_mask) { + snd_printdd(LXP "requesting audio transfer for capture\n"); + tasklet_hi_schedule(&chip->tasklet_capture); + } + + if (notified_out_pipe_mask) { + snd_printdd(LXP "requesting audio transfer for playback\n"); + tasklet_hi_schedule(&chip->tasklet_playback); + } + + return err; +} + + +irqreturn_t lx_interrupt(int irq, void *dev_id) +{ + struct lx6464es *chip = dev_id; + int async_pending, async_escmd; + u32 irqsrc; + + spin_lock(&chip->lock); + + snd_printdd("**************************************************\n"); + + if (!lx_interrupt_ack(chip, &irqsrc, &async_pending, &async_escmd)) { + spin_unlock(&chip->lock); + snd_printdd("IRQ_NONE\n"); + return IRQ_NONE; /* this device did not cause the interrupt */ + } + + if (irqsrc & MASK_SYS_STATUS_CMD_DONE) + goto exit; + +#if 0 + if (irqsrc & MASK_SYS_STATUS_EOBI) + snd_printdd(LXP "interrupt: EOBI\n"); + + if (irqsrc & MASK_SYS_STATUS_EOBO) + snd_printdd(LXP "interrupt: EOBO\n"); + + if (irqsrc & MASK_SYS_STATUS_URUN) + snd_printdd(LXP "interrupt: URUN\n"); + + if (irqsrc & MASK_SYS_STATUS_ORUN) + snd_printdd(LXP "interrupt: ORUN\n"); +#endif + + if (async_pending) { + u64 notified_in_pipe_mask = 0; + u64 notified_out_pipe_mask = 0; + int freq_changed; + int err; + + /* handle async events */ + err = lx_interrupt_handle_async_events(chip, irqsrc, + &freq_changed, + ¬ified_in_pipe_mask, + ¬ified_out_pipe_mask); + if (err) + snd_printk(KERN_ERR LXP + "error handling async events\n"); + + err = lx_interrupt_handle_audio_transfer(chip, + notified_in_pipe_mask, + notified_out_pipe_mask + ); + if (err) + snd_printk(KERN_ERR LXP + "error during audio transfer\n"); + } + + if (async_escmd) { +#if 0 + /* backdoor for ethersound commands + * + * for now, we do not need this + * + * */ + + snd_printdd("lx6464es: interrupt requests escmd handling\n"); +#endif + } + +exit: + spin_unlock(&chip->lock); + return IRQ_HANDLED; /* this device caused the interrupt */ +} + + +static void lx_irq_set(struct lx6464es *chip, int enable) +{ + u32 reg = lx_plx_reg_read(chip, ePLX_IRQCS); + + /* enable/disable interrupts + * + * Set the Doorbell and PCI interrupt enable bits + * + * */ + if (enable) + reg |= (IRQCS_ENABLE_PCIIRQ | IRQCS_ENABLE_PCIDB); + else + reg &= ~(IRQCS_ENABLE_PCIIRQ | IRQCS_ENABLE_PCIDB); + lx_plx_reg_write(chip, ePLX_IRQCS, reg); +} + +void lx_irq_enable(struct lx6464es *chip) +{ + snd_printdd("->lx_irq_enable\n"); + lx_irq_set(chip, 1); +} + +void lx_irq_disable(struct lx6464es *chip) +{ + snd_printdd("->lx_irq_disable\n"); + lx_irq_set(chip, 0); +} diff --git a/sound/pci/lx6464es/lx_core.h b/sound/pci/lx6464es/lx_core.h new file mode 100644 index 000000000000..6bd9cbbbc68d --- /dev/null +++ b/sound/pci/lx6464es/lx_core.h @@ -0,0 +1,242 @@ +/* -*- linux-c -*- * + * + * ALSA driver for the digigram lx6464es interface + * low-level interface + * + * Copyright (c) 2009 Tim Blechmann + * + * 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LX_CORE_H +#define LX_CORE_H + +#include + +#include "lx_defs.h" + +#define REG_CRM_NUMBER 12 + +struct lx6464es; + +/* low-level register access */ + +/* dsp register access */ +enum { + eReg_BASE, + eReg_CSM, + eReg_CRM1, + eReg_CRM2, + eReg_CRM3, + eReg_CRM4, + eReg_CRM5, + eReg_CRM6, + eReg_CRM7, + eReg_CRM8, + eReg_CRM9, + eReg_CRM10, + eReg_CRM11, + eReg_CRM12, + + eReg_ICR, + eReg_CVR, + eReg_ISR, + eReg_RXHTXH, + eReg_RXMTXM, + eReg_RHLTXL, + eReg_RESETDSP, + + eReg_CSUF, + eReg_CSES, + eReg_CRESMSB, + eReg_CRESLSB, + eReg_ADMACESMSB, + eReg_ADMACESLSB, + eReg_CONFES, + + eMaxPortLx +}; + +unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port); +void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len); +void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data); +void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, + u32 len); + +/* plx register access */ +enum { + ePLX_PCICR, + + ePLX_MBOX0, + ePLX_MBOX1, + ePLX_MBOX2, + ePLX_MBOX3, + ePLX_MBOX4, + ePLX_MBOX5, + ePLX_MBOX6, + ePLX_MBOX7, + + ePLX_L2PCIDB, + ePLX_IRQCS, + ePLX_CHIPSC, + + eMaxPort +}; + +unsigned long lx_plx_reg_read(struct lx6464es *chip, int port); +void lx_plx_reg_write(struct lx6464es *chip, int port, u32 data); + +/* rhm */ +struct lx_rmh { + u16 cmd_len; /* length of the command to send (WORDs) */ + u16 stat_len; /* length of the status received (WORDs) */ + u16 dsp_stat; /* status type, RMP_SSIZE_XXX */ + u16 cmd_idx; /* index of the command */ + u32 cmd[REG_CRM_NUMBER]; + u32 stat[REG_CRM_NUMBER]; +}; + + +/* low-level dsp access */ +int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version); +int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq); +int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran); +int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data); +int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address); + + +/* low-level pipe handling */ +int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture, + int channels); +int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture); +int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture, + u64 *rsample_count); +int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate); +int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture); +int lx_pipe_start(struct lx6464es *chip, u32 pipe, int is_capture); +int lx_pipe_pause(struct lx6464es *chip, u32 pipe, int is_capture); + +int lx_pipe_wait_for_start(struct lx6464es *chip, u32 pipe, int is_capture); +int lx_pipe_wait_for_idle(struct lx6464es *chip, u32 pipe, int is_capture); + +/* low-level stream handling */ +int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime, + u32 pipe, int is_capture); +int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture, + int *rstate); +int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture, + u64 *r_bytepos); + +int lx_stream_set_state(struct lx6464es *chip, u32 pipe, + int is_capture, enum stream_state_t state); + +static inline int lx_stream_start(struct lx6464es *chip, u32 pipe, + int is_capture) +{ + snd_printdd("->lx_stream_start\n"); + return lx_stream_set_state(chip, pipe, is_capture, SSTATE_RUN); +} + +static inline int lx_stream_pause(struct lx6464es *chip, u32 pipe, + int is_capture) +{ + snd_printdd("->lx_stream_pause\n"); + return lx_stream_set_state(chip, pipe, is_capture, SSTATE_PAUSE); +} + +static inline int lx_stream_stop(struct lx6464es *chip, u32 pipe, + int is_capture) +{ + snd_printdd("->lx_stream_stop\n"); + return lx_stream_set_state(chip, pipe, is_capture, SSTATE_STOP); +} + +/* low-level buffer handling */ +int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, + u32 *r_needed, u32 *r_freed, u32 *size_array); +int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture, + u32 buffer_size, u32 buf_address_lo, u32 buf_address_hi, + u32 *r_buffer_index); +int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture, + u32 *r_buffer_size); +int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture, + u32 buffer_index); + +/* low-level gain/peak handling */ +int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute); +int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels, + u32 *r_levels); + + +/* interrupt handling */ +irqreturn_t lx_interrupt(int irq, void *dev_id); +void lx_irq_enable(struct lx6464es *chip); +void lx_irq_disable(struct lx6464es *chip); + +void lx_tasklet_capture(unsigned long data); +void lx_tasklet_playback(unsigned long data); + + +/* Stream Format Header Defines (for LIN and IEEE754) */ +#define HEADER_FMT_BASE HEADER_FMT_BASE_LIN +#define HEADER_FMT_BASE_LIN 0xFED00000 +#define HEADER_FMT_BASE_FLOAT 0xFAD00000 +#define HEADER_FMT_MONO 0x00000080 /* bit 23 in header_lo. WARNING: old + * bit 22 is ignored in float + * format */ +#define HEADER_FMT_INTEL 0x00008000 +#define HEADER_FMT_16BITS 0x00002000 +#define HEADER_FMT_24BITS 0x00004000 +#define HEADER_FMT_UPTO11 0x00000200 /* frequency is less or equ. to 11k. + * */ +#define HEADER_FMT_UPTO32 0x00000100 /* frequency is over 11k and less + * then 32k.*/ + + +#define BIT_FMP_HEADER 23 +#define BIT_FMP_SD 22 +#define BIT_FMP_MULTICHANNEL 19 + +#define START_STATE 1 +#define PAUSE_STATE 0 + + + + + +/* from PcxAll_e.h */ +/* Start/Pause condition for pipes (PCXStartPipe, PCXPausePipe) */ +#define START_PAUSE_IMMEDIATE 0 +#define START_PAUSE_ON_SYNCHRO 1 +#define START_PAUSE_ON_TIME_CODE 2 + + +/* Pipe / Stream state */ +#define START_STATE 1 +#define PAUSE_STATE 0 + +static inline void unpack_pointer(dma_addr_t ptr, u32 *r_low, u32 *r_high) +{ + *r_low = (u32)(ptr & 0xffffffff); +#if BITS_PER_LONG == 32 + *r_high = 0; +#else + *r_high = (u32)((u64)ptr>>32); +#endif +} + +#endif /* LX_CORE_H */ diff --git a/sound/pci/lx6464es/lx_defs.h b/sound/pci/lx6464es/lx_defs.h new file mode 100644 index 000000000000..49d36bdd512c --- /dev/null +++ b/sound/pci/lx6464es/lx_defs.h @@ -0,0 +1,376 @@ +/* -*- linux-c -*- * + * + * ALSA driver for the digigram lx6464es interface + * adapted upstream headers + * + * Copyright (c) 2009 Tim Blechmann + * + * 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; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LX_DEFS_H +#define LX_DEFS_H + +/* code adapted from ethersound.h */ +#define XES_FREQ_COUNT8_MASK 0x00001FFF /* compteur 25MHz entre 8 ech. */ +#define XES_FREQ_COUNT8_44_MIN 0x00001288 /* 25M / + * [ 44k - ( 44.1k + 48k ) / 2 ] + * * 8 */ +#define XES_FREQ_COUNT8_44_MAX 0x000010F0 /* 25M / [ ( 44.1k + 48k ) / 2 ] + * * 8 */ +#define XES_FREQ_COUNT8_48_MAX 0x00000F08 /* 25M / + * [ 48k + ( 44.1k + 48k ) / 2 ] + * * 8 */ + +/* code adapted from LXES_registers.h */ + +#define IOCR_OUTPUTS_OFFSET 0 /* (rw) offset for the number of OUTs in the + * ConfES register. */ +#define IOCR_INPUTS_OFFSET 8 /* (rw) offset for the number of INs in the + * ConfES register. */ +#define FREQ_RATIO_OFFSET 19 /* (rw) offset for frequency ratio in the + * ConfES register. */ +#define FREQ_RATIO_SINGLE_MODE 0x01 /* value for single mode frequency ratio: + * sample rate = frequency rate. */ + +#define CONFES_READ_PART_MASK 0x00070000 +#define CONFES_WRITE_PART_MASK 0x00F80000 + +/* code adapted from if_drv_mb.h */ + +#define MASK_SYS_STATUS_ERROR (1L << 31) /* events that lead to a PCI irq if + * not yet pending */ +#define MASK_SYS_STATUS_URUN (1L << 30) +#define MASK_SYS_STATUS_ORUN (1L << 29) +#define MASK_SYS_STATUS_EOBO (1L << 28) +#define MASK_SYS_STATUS_EOBI (1L << 27) +#define MASK_SYS_STATUS_FREQ (1L << 26) +#define MASK_SYS_STATUS_ESA (1L << 25) /* reserved, this is set by the + * XES */ +#define MASK_SYS_STATUS_TIMER (1L << 24) + +#define MASK_SYS_ASYNC_EVENTS (MASK_SYS_STATUS_ERROR | \ + MASK_SYS_STATUS_URUN | \ + MASK_SYS_STATUS_ORUN | \ + MASK_SYS_STATUS_EOBO | \ + MASK_SYS_STATUS_EOBI | \ + MASK_SYS_STATUS_FREQ | \ + MASK_SYS_STATUS_ESA) + +#define MASK_SYS_PCI_EVENTS (MASK_SYS_ASYNC_EVENTS | \ + MASK_SYS_STATUS_TIMER) + +#define MASK_SYS_TIMER_COUNT 0x0000FFFF + +#define MASK_SYS_STATUS_EOT_PLX (1L << 22) /* event that remains + * internal: reserved fo end + * of plx dma */ +#define MASK_SYS_STATUS_XES (1L << 21) /* event that remains + * internal: pending XES + * IRQ */ +#define MASK_SYS_STATUS_CMD_DONE (1L << 20) /* alternate command + * management: notify driver + * instead of polling */ + + +#define MAX_STREAM_BUFFER 5 /* max amount of stream buffers. */ + +#define MICROBLAZE_IBL_MIN 32 +#define MICROBLAZE_IBL_DEFAULT 128 +#define MICROBLAZE_IBL_MAX 512 +/* #define MASK_GRANULARITY (2*MICROBLAZE_IBL_MAX-1) */ + + + +/* command opcodes, see reference for details */ + +/* + the capture bit position in the object_id field in driver commands + depends upon the number of managed channels. For now, 64 IN + 64 OUT are + supported. HOwever, the communication protocol forsees 1024 channels, hence + bit 10 indicates a capture (input) object). +*/ +#define ID_IS_CAPTURE (1L << 10) +#define ID_OFFSET 13 /* object ID is at the 13th bit in the + * 1st command word.*/ +#define ID_CH_MASK 0x3F +#define OPCODE_OFFSET 24 /* offset of the command opcode in the first + * command word.*/ + +enum cmd_mb_opcodes { + CMD_00_INFO_DEBUG = 0x00, + CMD_01_GET_SYS_CFG = 0x01, + CMD_02_SET_GRANULARITY = 0x02, + CMD_03_SET_TIMER_IRQ = 0x03, + CMD_04_GET_EVENT = 0x04, + CMD_05_GET_PIPES = 0x05, + + CMD_06_ALLOCATE_PIPE = 0x06, + CMD_07_RELEASE_PIPE = 0x07, + CMD_08_ASK_BUFFERS = 0x08, + CMD_09_STOP_PIPE = 0x09, + CMD_0A_GET_PIPE_SPL_COUNT = 0x0a, + CMD_0B_TOGGLE_PIPE_STATE = 0x0b, + + CMD_0C_DEF_STREAM = 0x0c, + CMD_0D_SET_MUTE = 0x0d, + CMD_0E_GET_STREAM_SPL_COUNT = 0x0e, + CMD_0F_UPDATE_BUFFER = 0x0f, + CMD_10_GET_BUFFER = 0x10, + CMD_11_CANCEL_BUFFER = 0x11, + CMD_12_GET_PEAK = 0x12, + CMD_13_SET_STREAM_STATE = 0x13, + CMD_14_INVALID = 0x14, +}; + +/* pipe states */ +enum pipe_state_t { + PSTATE_IDLE = 0, /* the pipe is not processed in the XES_IRQ + * (free or stopped, or paused). */ + PSTATE_RUN = 1, /* sustained play/record state. */ + PSTATE_PURGE = 2, /* the ES channels are now off, render pipes do + * not DMA, record pipe do a last DMA. */ + PSTATE_ACQUIRE = 3, /* the ES channels are now on, render pipes do + * not yet increase their sample count, record + * pipes do not DMA. */ + PSTATE_CLOSING = 4, /* the pipe is releasing, and may not yet + * receive an "alloc" command. */ +}; + +/* stream states */ +enum stream_state_t { + SSTATE_STOP = 0x00, /* setting to stop resets the stream spl + * count.*/ + SSTATE_RUN = (0x01 << 0), /* start DMA and spl count handling. */ + SSTATE_PAUSE = (0x01 << 1), /* pause DMA and spl count handling. */ +}; + +/* buffer flags */ +enum buffer_flags { + BF_VALID = 0x80, /* set if the buffer is valid, clear if free.*/ + BF_CURRENT = 0x40, /* set if this is the current buffer (there is + * always a current buffer).*/ + BF_NOTIFY_EOB = 0x20, /* set if this buffer must cause a PCI event + * when finished.*/ + BF_CIRCULAR = 0x10, /* set if buffer[1] must be copied to buffer[0] + * by the end of this buffer.*/ + BF_64BITS_ADR = 0x08, /* set if the hi part of the address is valid.*/ + BF_xx = 0x04, /* future extension.*/ + BF_EOB = 0x02, /* set if finished, but not yet free.*/ + BF_PAUSE = 0x01, /* pause stream at buffer end.*/ + BF_ZERO = 0x00, /* no flags (init).*/ +}; + +/** +* Stream Flags definitions +*/ +enum stream_flags { + SF_ZERO = 0x00000000, /* no flags (stream invalid). */ + SF_VALID = 0x10000000, /* the stream has a valid DMA_conf + * info (setstreamformat). */ + SF_XRUN = 0x20000000, /* the stream is un x-run state. */ + SF_START = 0x40000000, /* the DMA is running.*/ + SF_ASIO = 0x80000000, /* ASIO.*/ +}; + + +#define MASK_SPL_COUNT_HI 0x00FFFFFF /* 4 MSBits are status bits */ +#define PSTATE_OFFSET 28 /* 4 MSBits are status bits */ + + +#define MASK_STREAM_HAS_MAPPING (1L << 12) +#define MASK_STREAM_IS_ASIO (1L << 9) +#define STREAM_FMT_OFFSET 10 /* the stream fmt bits start at the 10th + * bit in the command word. */ + +#define STREAM_FMT_16b 0x02 +#define STREAM_FMT_intel 0x01 + +#define FREQ_FIELD_OFFSET 15 /* offset of the freq field in the response + * word */ + +#define BUFF_FLAGS_OFFSET 24 /* offset of the buffer flags in the + * response word. */ +#define MASK_DATA_SIZE 0x00FFFFFF /* this must match the field size of + * datasize in the buffer_t structure. */ + +#define MASK_BUFFER_ID 0xFF /* the cancel command awaits a buffer ID, + * may be 0xFF for "current". */ + + +/* code adapted from PcxErr_e.h */ + +/* Bits masks */ + +#define ERROR_MASK 0x8000 + +#define SOURCE_MASK 0x7800 + +#define E_SOURCE_BOARD 0x4000 /* 8 >> 1 */ +#define E_SOURCE_DRV 0x2000 /* 4 >> 1 */ +#define E_SOURCE_API 0x1000 /* 2 >> 1 */ +/* Error tools */ +#define E_SOURCE_TOOLS 0x0800 /* 1 >> 1 */ +/* Error pcxaudio */ +#define E_SOURCE_AUDIO 0x1800 /* 3 >> 1 */ +/* Error virtual pcx */ +#define E_SOURCE_VPCX 0x2800 /* 5 >> 1 */ +/* Error dispatcher */ +#define E_SOURCE_DISPATCHER 0x3000 /* 6 >> 1 */ +/* Error from CobraNet firmware */ +#define E_SOURCE_COBRANET 0x3800 /* 7 >> 1 */ + +#define E_SOURCE_USER 0x7800 + +#define CLASS_MASK 0x0700 + +#define CODE_MASK 0x00FF + +/* Bits values */ + +/* Values for the error/warning bit */ +#define ERROR_VALUE 0x8000 +#define WARNING_VALUE 0x0000 + +/* Class values */ +#define E_CLASS_GENERAL 0x0000 +#define E_CLASS_INVALID_CMD 0x0100 +#define E_CLASS_INVALID_STD_OBJECT 0x0200 +#define E_CLASS_RSRC_IMPOSSIBLE 0x0300 +#define E_CLASS_WRONG_CONTEXT 0x0400 +#define E_CLASS_BAD_SPECIFIC_PARAMETER 0x0500 +#define E_CLASS_REAL_TIME_ERROR 0x0600 +#define E_CLASS_DIRECTSHOW 0x0700 +#define E_CLASS_FREE 0x0700 + + +/* Complete DRV error code for the general class */ +#define ED_GN (ERROR_VALUE | E_SOURCE_DRV | E_CLASS_GENERAL) +#define ED_CONCURRENCY (ED_GN | 0x01) +#define ED_DSP_CRASHED (ED_GN | 0x02) +#define ED_UNKNOWN_BOARD (ED_GN | 0x03) +#define ED_NOT_INSTALLED (ED_GN | 0x04) +#define ED_CANNOT_OPEN_SVC_MANAGER (ED_GN | 0x05) +#define ED_CANNOT_READ_REGISTRY (ED_GN | 0x06) +#define ED_DSP_VERSION_MISMATCH (ED_GN | 0x07) +#define ED_UNAVAILABLE_FEATURE (ED_GN | 0x08) +#define ED_CANCELLED (ED_GN | 0x09) +#define ED_NO_RESPONSE_AT_IRQA (ED_GN | 0x10) +#define ED_INVALID_ADDRESS (ED_GN | 0x11) +#define ED_DSP_CORRUPTED (ED_GN | 0x12) +#define ED_PENDING_OPERATION (ED_GN | 0x13) +#define ED_NET_ALLOCATE_MEMORY_IMPOSSIBLE (ED_GN | 0x14) +#define ED_NET_REGISTER_ERROR (ED_GN | 0x15) +#define ED_NET_THREAD_ERROR (ED_GN | 0x16) +#define ED_NET_OPEN_ERROR (ED_GN | 0x17) +#define ED_NET_CLOSE_ERROR (ED_GN | 0x18) +#define ED_NET_NO_MORE_PACKET (ED_GN | 0x19) +#define ED_NET_NO_MORE_BUFFER (ED_GN | 0x1A) +#define ED_NET_SEND_ERROR (ED_GN | 0x1B) +#define ED_NET_RECEIVE_ERROR (ED_GN | 0x1C) +#define ED_NET_WRONG_MSG_SIZE (ED_GN | 0x1D) +#define ED_NET_WAIT_ERROR (ED_GN | 0x1E) +#define ED_NET_EEPROM_ERROR (ED_GN | 0x1F) +#define ED_INVALID_RS232_COM_NUMBER (ED_GN | 0x20) +#define ED_INVALID_RS232_INIT (ED_GN | 0x21) +#define ED_FILE_ERROR (ED_GN | 0x22) +#define ED_INVALID_GPIO_CMD (ED_GN | 0x23) +#define ED_RS232_ALREADY_OPENED (ED_GN | 0x24) +#define ED_RS232_NOT_OPENED (ED_GN | 0x25) +#define ED_GPIO_ALREADY_OPENED (ED_GN | 0x26) +#define ED_GPIO_NOT_OPENED (ED_GN | 0x27) +#define ED_REGISTRY_ERROR (ED_GN | 0x28) /* <- NCX */ +#define ED_INVALID_SERVICE (ED_GN | 0x29) /* <- NCX */ + +#define ED_READ_FILE_ALREADY_OPENED (ED_GN | 0x2a) /* <- Decalage + * pour RCX + * (old 0x28) + * */ +#define ED_READ_FILE_INVALID_COMMAND (ED_GN | 0x2b) /* ~ */ +#define ED_READ_FILE_INVALID_PARAMETER (ED_GN | 0x2c) /* ~ */ +#define ED_READ_FILE_ALREADY_CLOSED (ED_GN | 0x2d) /* ~ */ +#define ED_READ_FILE_NO_INFORMATION (ED_GN | 0x2e) /* ~ */ +#define ED_READ_FILE_INVALID_HANDLE (ED_GN | 0x2f) /* ~ */ +#define ED_READ_FILE_END_OF_FILE (ED_GN | 0x30) /* ~ */ +#define ED_READ_FILE_ERROR (ED_GN | 0x31) /* ~ */ + +#define ED_DSP_CRASHED_EXC_DSPSTACK_OVERFLOW (ED_GN | 0x32) /* <- Decalage pour + * PCX (old 0x14) */ +#define ED_DSP_CRASHED_EXC_SYSSTACK_OVERFLOW (ED_GN | 0x33) /* ~ */ +#define ED_DSP_CRASHED_EXC_ILLEGAL (ED_GN | 0x34) /* ~ */ +#define ED_DSP_CRASHED_EXC_TIMER_REENTRY (ED_GN | 0x35) /* ~ */ +#define ED_DSP_CRASHED_EXC_FATAL_ERROR (ED_GN | 0x36) /* ~ */ + +#define ED_FLASH_PCCARD_NOT_PRESENT (ED_GN | 0x37) + +#define ED_NO_CURRENT_CLOCK (ED_GN | 0x38) + +/* Complete DRV error code for real time class */ +#define ED_RT (ERROR_VALUE | E_SOURCE_DRV | E_CLASS_REAL_TIME_ERROR) +#define ED_DSP_TIMED_OUT (ED_RT | 0x01) +#define ED_DSP_CHK_TIMED_OUT (ED_RT | 0x02) +#define ED_STREAM_OVERRUN (ED_RT | 0x03) +#define ED_DSP_BUSY (ED_RT | 0x04) +#define ED_DSP_SEMAPHORE_TIME_OUT (ED_RT | 0x05) +#define ED_BOARD_TIME_OUT (ED_RT | 0x06) +#define ED_XILINX_ERROR (ED_RT | 0x07) +#define ED_COBRANET_ITF_NOT_RESPONDING (ED_RT | 0x08) + +/* Complete BOARD error code for the invaid standard object class */ +#define EB_ISO (ERROR_VALUE | E_SOURCE_BOARD | \ + E_CLASS_INVALID_STD_OBJECT) +#define EB_INVALID_EFFECT (EB_ISO | 0x00) +#define EB_INVALID_PIPE (EB_ISO | 0x40) +#define EB_INVALID_STREAM (EB_ISO | 0x80) +#define EB_INVALID_AUDIO (EB_ISO | 0xC0) + +/* Complete BOARD error code for impossible resource allocation class */ +#define EB_RI (ERROR_VALUE | E_SOURCE_BOARD | E_CLASS_RSRC_IMPOSSIBLE) +#define EB_ALLOCATE_ALL_STREAM_TRANSFERT_BUFFERS_IMPOSSIBLE (EB_RI | 0x01) +#define EB_ALLOCATE_PIPE_SAMPLE_BUFFER_IMPOSSIBLE (EB_RI | 0x02) + +#define EB_ALLOCATE_MEM_STREAM_IMPOSSIBLE \ + EB_ALLOCATE_ALL_STREAM_TRANSFERT_BUFFERS_IMPOSSIBLE +#define EB_ALLOCATE_MEM_PIPE_IMPOSSIBLE \ + EB_ALLOCATE_PIPE_SAMPLE_BUFFER_IMPOSSIBLE + +#define EB_ALLOCATE_DIFFERED_CMD_IMPOSSIBLE (EB_RI | 0x03) +#define EB_TOO_MANY_DIFFERED_CMD (EB_RI | 0x04) +#define EB_RBUFFERS_TABLE_OVERFLOW (EB_RI | 0x05) +#define EB_ALLOCATE_EFFECTS_IMPOSSIBLE (EB_RI | 0x08) +#define EB_ALLOCATE_EFFECT_POS_IMPOSSIBLE (EB_RI | 0x09) +#define EB_RBUFFER_NOT_AVAILABLE (EB_RI | 0x0A) +#define EB_ALLOCATE_CONTEXT_LIII_IMPOSSIBLE (EB_RI | 0x0B) +#define EB_STATUS_DIALOG_IMPOSSIBLE (EB_RI | 0x1D) +#define EB_CONTROL_CMD_IMPOSSIBLE (EB_RI | 0x1E) +#define EB_STATUS_SEND_IMPOSSIBLE (EB_RI | 0x1F) +#define EB_ALLOCATE_PIPE_IMPOSSIBLE (EB_RI | 0x40) +#define EB_ALLOCATE_STREAM_IMPOSSIBLE (EB_RI | 0x80) +#define EB_ALLOCATE_AUDIO_IMPOSSIBLE (EB_RI | 0xC0) + +/* Complete BOARD error code for wrong call context class */ +#define EB_WCC (ERROR_VALUE | E_SOURCE_BOARD | E_CLASS_WRONG_CONTEXT) +#define EB_CMD_REFUSED (EB_WCC | 0x00) +#define EB_START_STREAM_REFUSED (EB_WCC | 0xFC) +#define EB_SPC_REFUSED (EB_WCC | 0xFD) +#define EB_CSN_REFUSED (EB_WCC | 0xFE) +#define EB_CSE_REFUSED (EB_WCC | 0xFF) + + + + +#endif /* LX_DEFS_H */ -- GitLab From 7852fd08fdc78bf43150137bdbfdfdccdefffe0f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 14 Apr 2009 12:25:52 +0200 Subject: [PATCH 0277/6080] ALSA: lx6464es - Use snd_card_create() Use snd_card_create() instead of the obsoleted snd_card_new(). Signed-off-by: Takashi Iwai --- sound/pci/lx6464es/lx6464es.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index 7bc8b8caa992..870bfc58c697 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c @@ -1091,9 +1091,9 @@ static int __devinit snd_lx6464es_probe(struct pci_dev *pci, return -ENOENT; } - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; + err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); + if (err < 0) + return err; err = snd_lx6464es_create(card, pci, &chip); if (err < 0) { -- GitLab From d7dee4d7744d039bf28e4f6d4f5674f44820265a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 14 Apr 2009 12:27:12 +0200 Subject: [PATCH 0278/6080] ALSA: lx6464es - Disable lx_message_send() Disable lx_message_send() function temporarily as it's not used anywhere. Signed-off-by: Takashi Iwai --- sound/pci/lx6464es/lx_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index a9f8f882b107..5812780d6e89 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -314,6 +314,7 @@ static inline void lx_message_dump(struct lx_rmh *rmh) #define XILINX_POLL_NO_SLEEP 100 #define XILINX_POLL_ITERATIONS 150 +#if 0 /* not used now */ static int lx_message_send(struct lx6464es *chip, struct lx_rmh *rmh) { u32 reg = ED_DSP_TIMED_OUT; @@ -404,6 +405,7 @@ polling_successful: lx_message_dump(rmh); return 0; } +#endif /* not used now */ static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh) { -- GitLab From 8338c300642f67af5a8cc279ca5e088c7055b7eb Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 14 Apr 2009 12:30:36 +0200 Subject: [PATCH 0279/6080] ALSA: Add missing description of lx6464es to ALSA-Configuration.txt Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 012858d2b119..dfd266eec707 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1093,6 +1093,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple cards. The driver requires the firmware loader support on kernel. + Module snd-lx6464es + ------------------- + + Module for Digigram LX6464ES boards + + This module supports multiple cards. + Module snd-maestro3 ------------------- -- GitLab From c282866101bfde888a44da3babd2f9ab265ca6f9 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sat, 4 Apr 2009 14:48:32 +0200 Subject: [PATCH 0280/6080] ALSA: sc6000: add support for SC-6600 and SC-7000 Add support for later cards based on CompuMedia ASC-9408 chipsets. These cards were produced by Gallant. This patch make the OSS aedsp16 driver redundant. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- sound/isa/Kconfig | 7 ++- sound/isa/sc6000.c | 127 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 104 insertions(+), 30 deletions(-) diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index c5c9a9218ff6..64129bf22054 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -177,15 +177,18 @@ config SND_ES18XX will be called snd-es18xx. config SND_SC6000 - tristate "Gallant SC-6000, Audio Excel DSP 16" + tristate "Gallant SC-6000/6600/7000 and Audio Excel DSP 16" depends on HAS_IOPORT select SND_WSS_LIB select SND_OPL3_LIB select SND_MPU401_UART help - Say Y here to include support for Gallant SC-6000 card and clones: + Say Y here to include support for Gallant SC-6000, SC-6600, SC-7000 + cards and clones: Audio Excel DSP 16 and Zoltrix AV302. + These cards are based on CompuMedia ASC-9308 or ASC-9408 chips. + To compile this driver as a module, choose M here: the module will be called snd-sc6000. diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index 782010608ef4..983ab7e3b5b4 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c @@ -2,6 +2,8 @@ * Driver for Gallant SC-6000 soundcard. This card is also known as * Audio Excel DSP 16 or Zoltrix AV302. * These cards use CompuMedia ASC-9308 chip + AD1848 codec. + * SC-6600 and SC-7000 cards are also supported. They are based on + * CompuMedia ASC-9408 chip and CS4231 codec. * * Copyright (C) 2007 Krzysztof Helt * @@ -191,7 +193,7 @@ static __devinit unsigned char sc6000_mpu_irq_to_softcfg(int mpu_irq) return val; } -static __devinit int sc6000_wait_data(char __iomem *vport) +static int sc6000_wait_data(char __iomem *vport) { int loop = 1000; unsigned char val = 0; @@ -206,7 +208,7 @@ static __devinit int sc6000_wait_data(char __iomem *vport) return -EAGAIN; } -static __devinit int sc6000_read(char __iomem *vport) +static int sc6000_read(char __iomem *vport) { if (sc6000_wait_data(vport)) return -EBUSY; @@ -215,7 +217,7 @@ static __devinit int sc6000_read(char __iomem *vport) } -static __devinit int sc6000_write(char __iomem *vport, int cmd) +static int sc6000_write(char __iomem *vport, int cmd) { unsigned char val; int loop = 500000; @@ -276,8 +278,33 @@ static int __devinit sc6000_dsp_reset(char __iomem *vport) } /* detection and initialization */ -static int __devinit sc6000_cfg_write(char __iomem *vport, - unsigned char softcfg) +static int __devinit sc6000_hw_cfg_write(char __iomem *vport, const int *cfg) +{ + if (sc6000_write(vport, COMMAND_6C) < 0) { + snd_printk(KERN_WARNING "CMD 0x%x: failed!\n", COMMAND_6C); + return -EIO; + } + if (sc6000_write(vport, COMMAND_5C) < 0) { + snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_5C); + return -EIO; + } + if (sc6000_write(vport, cfg[0]) < 0) { + snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[0]); + return -EIO; + } + if (sc6000_write(vport, cfg[1]) < 0) { + snd_printk(KERN_ERR "DATA 0x%x: failed!\n", cfg[1]); + return -EIO; + } + if (sc6000_write(vport, COMMAND_C5) < 0) { + snd_printk(KERN_ERR "CMD 0x%x: failed!\n", COMMAND_C5); + return -EIO; + } + + return 0; +} + +static int sc6000_cfg_write(char __iomem *vport, unsigned char softcfg) { if (sc6000_write(vport, WRITE_MDIRQ_CFG)) { @@ -291,7 +318,7 @@ static int __devinit sc6000_cfg_write(char __iomem *vport, return 0; } -static int __devinit sc6000_setup_board(char __iomem *vport, int config) +static int sc6000_setup_board(char __iomem *vport, int config) { int loop = 10; @@ -334,16 +361,38 @@ static int __devinit sc6000_init_mss(char __iomem *vport, int config, return 0; } -static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, - char __iomem *vmss_port, int mpu_irq) +static void __devinit sc6000_hw_cfg_encode(char __iomem *vport, int *cfg, + long xport, long xmpu, + long xmss_port) +{ + cfg[0] = 0; + cfg[1] = 0; + if (xport == 0x240) + cfg[0] |= 1; + if (xmpu != SNDRV_AUTO_PORT) { + cfg[0] |= (xmpu & 0x30) >> 2; + cfg[1] |= 0x20; + } + if (xmss_port == 0xe80) + cfg[0] |= 0x10; + cfg[0] |= 0x40; /* always set */ + cfg[1] |= 0x80; /* enable WSS system */ + cfg[1] &= ~0x40; /* disable IDE */ + snd_printd("hw cfg %x, %x\n", cfg[0], cfg[1]); +} + +static int __devinit sc6000_init_board(char __iomem *vport, + char __iomem *vmss_port, int dev) { char answer[15]; char version[2]; - int mss_config = sc6000_irq_to_softcfg(irq) | - sc6000_dma_to_softcfg(dma); + int mss_config = sc6000_irq_to_softcfg(irq[dev]) | + sc6000_dma_to_softcfg(dma[dev]); int config = mss_config | - sc6000_mpu_irq_to_softcfg(mpu_irq); + sc6000_mpu_irq_to_softcfg(mpu_irq[dev]); int err; + int cfg[2]; + int old = 0; err = sc6000_dsp_reset(vport); if (err < 0) { @@ -360,7 +409,6 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, /* * My SC-6000 card return "SC-6000" in DSPCopyright, so * if we have something different, we have to be warned. - * Mine returns "SC-6000A " - KH */ if (strncmp("SC-6000", answer, 7)) snd_printk(KERN_WARNING "Warning: non SC-6000 audio card!\n"); @@ -372,13 +420,29 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, printk(KERN_INFO PFX "Detected model: %s, DSP version %d.%d\n", answer, version[0], version[1]); - /* - * 0x0A == (IRQ 7, DMA 1, MIRQ 0) - */ - err = sc6000_cfg_write(vport, 0x0a); + /* set configuration */ + sc6000_hw_cfg_encode(vport, &cfg[0], port[dev], mpu_port[dev], + mss_port[dev]); + if (sc6000_hw_cfg_write(vport, cfg) < 0) { + snd_printk(KERN_ERR "sc6000_hw_cfg_write: failed!\n"); + return -EIO; + } + err = sc6000_setup_board(vport, config); if (err < 0) { - snd_printk(KERN_ERR "sc6000_cfg_write: failed!\n"); - return -EFAULT; + snd_printk(KERN_ERR "sc6000_setup_board: failed!\n"); + return -ENODEV; + } + + sc6000_dsp_reset(vport); + sc6000_write(vport, COMMAND_5C); + if (sc6000_read(vport) < 0) + old = 1; + sc6000_dsp_reset(vport); + + if (!old) { + sc6000_write(vport, COMMAND_60); + sc6000_write(vport, 0x02); + sc6000_dsp_reset(vport); } err = sc6000_setup_board(vport, config); @@ -386,10 +450,9 @@ static int __devinit sc6000_init_board(char __iomem *vport, int irq, int dma, snd_printk(KERN_ERR "sc6000_setup_board: failed!\n"); return -ENODEV; } - err = sc6000_init_mss(vport, config, vmss_port, mss_config); if (err < 0) { - snd_printk(KERN_ERR "Can not initialize " + snd_printk(KERN_ERR "Cannot initialize " "Microsoft Sound System mode.\n"); return -ENODEV; } @@ -485,14 +548,16 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) struct snd_card *card; struct snd_wss *chip; struct snd_opl3 *opl3; - char __iomem *vport; + char __iomem **vport; char __iomem *vmss_port; - err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); + err = snd_card_create(index[dev], id[dev], THIS_MODULE, sizeof(vport), + &card); if (err < 0) return err; + vport = card->private_data; if (xirq == SNDRV_AUTO_IRQ) { xirq = snd_legacy_find_free_irq(possible_irqs); if (xirq < 0) { @@ -517,8 +582,8 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) err = -EBUSY; goto err_exit; } - vport = devm_ioport_map(devptr, port[dev], 0x10); - if (!vport) { + *vport = devm_ioport_map(devptr, port[dev], 0x10); + if (*vport == NULL) { snd_printk(KERN_ERR PFX "I/O port cannot be iomaped.\n"); err = -EBUSY; @@ -533,7 +598,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) goto err_unmap1; } vmss_port = devm_ioport_map(devptr, mss_port[dev], 4); - if (!vport) { + if (!vmss_port) { snd_printk(KERN_ERR PFX "MSS port I/O cannot be iomaped.\n"); err = -EBUSY; @@ -544,7 +609,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) port[dev], xirq, xdma, mpu_irq[dev] == SNDRV_AUTO_IRQ ? 0 : mpu_irq[dev]); - err = sc6000_init_board(vport, xirq, xdma, vmss_port, mpu_irq[dev]); + err = sc6000_init_board(*vport, vmss_port, dev); if (err < 0) goto err_unmap2; @@ -552,7 +617,6 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) WSS_HW_DETECT, 0, &chip); if (err < 0) goto err_unmap2; - card->private_data = chip; err = snd_wss_pcm(chip, 0, NULL); if (err < 0) { @@ -608,6 +672,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) return 0; err_unmap2: + sc6000_setup_board(*vport, 0); release_region(mss_port[dev], 4); err_unmap1: release_region(port[dev], 0x10); @@ -618,11 +683,17 @@ err_exit: static int __devexit snd_sc6000_remove(struct device *devptr, unsigned int dev) { + struct snd_card *card = dev_get_drvdata(devptr); + char __iomem **vport = card->private_data; + + if (sc6000_setup_board(*vport, 0) < 0) + snd_printk(KERN_WARNING "sc6000_setup_board failed on exit!\n"); + release_region(port[dev], 0x10); release_region(mss_port[dev], 4); - snd_card_free(dev_get_drvdata(devptr)); dev_set_drvdata(devptr, NULL); + snd_card_free(card); return 0; } -- GitLab From 19e4529ee7345079eeacc8e40cf69a304a64dc23 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 14 Apr 2009 17:27:18 +1000 Subject: [PATCH 0281/6080] modules: Fix up build when CONFIG_MODULE_UNLOAD=n. Commit 3d43321b7015387cfebbe26436d0e9d299162ea1 ("modules: sysctl to block module loading") introduces a modules_disabled variable that is only defined if CONFIG_MODULE_UNLOAD is enabled, despite being used in other places. This moves it up and fixes up the build. CC kernel/module.o kernel/module.c: In function 'sys_init_module': kernel/module.c:2401: error: 'modules_disabled' undeclared (first use in this function) kernel/module.c:2401: error: (Each undeclared identifier is reported only once kernel/module.c:2401: error: for each function it appears in.) make[1]: *** [kernel/module.o] Error 1 make: *** [kernel/module.o] Error 2 Signed-off-by: Paul Mundt Signed-off-by: James Morris --- kernel/module.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index eeb3f7b1383c..ee7ab612dafa 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -71,6 +71,9 @@ static DEFINE_MUTEX(module_mutex); static LIST_HEAD(modules); +/* Block module loading/unloading? */ +int modules_disabled = 0; + /* Waiting for a module to finish initializing? */ static DECLARE_WAIT_QUEUE_HEAD(module_wq); @@ -778,9 +781,6 @@ static void wait_for_zero_refcount(struct module *mod) mutex_lock(&module_mutex); } -/* Block module loading/unloading? */ -int modules_disabled = 0; - SYSCALL_DEFINE2(delete_module, const char __user *, name_user, unsigned int, flags) { -- GitLab From ff7b1b4f000cea84f071c1b6aa2918b2119d66f1 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Wed, 15 Apr 2009 16:55:05 +0100 Subject: [PATCH 0282/6080] perfcounters: export perf_tpcounter_event Needed for modular tracepoint support. Signed-off-by: Steven Whitehouse Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 7f9521c3c01b..09396098dd0d 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -2590,6 +2590,7 @@ void perf_tpcounter_event(int event_id) __perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, 1, 1, regs, 0); } +EXPORT_SYMBOL_GPL(perf_tpcounter_event); extern int ftrace_profile_enable(int); extern void ftrace_profile_disable(int); -- GitLab From 0207a2efb43d81e29e23662b5d035945688a103f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 16 Apr 2009 14:40:56 +0900 Subject: [PATCH 0283/6080] sh: Add support for SH7724 (SH-Mobile R2R) CPU subtype. This implements initial support for the SH-Mobile R2R CPU. Based on Rev 0.11 of the initial SH7724 hardware manual. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 10 + arch/sh/include/asm/processor.h | 2 +- arch/sh/include/cpu-sh4/cpu/freq.h | 18 + arch/sh/include/cpu-sh4/cpu/sh7724.h | 255 +++ arch/sh/kernel/cpu/sh4/probe.c | 6 + arch/sh/kernel/cpu/sh4a/Makefile | 3 + arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 112 +- arch/sh/kernel/cpu/sh4a/pinmux-sh7724.c | 2230 +++++++++++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 371 ++++ arch/sh/kernel/setup.c | 3 +- arch/sh/oprofile/common.c | 1 + 11 files changed, 2997 insertions(+), 14 deletions(-) create mode 100644 arch/sh/include/cpu-sh4/cpu/sh7724.h create mode 100644 arch/sh/kernel/cpu/sh4a/pinmux-sh7724.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7724.c diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index e7390dd0283d..505d1acbd0ad 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -347,6 +347,15 @@ config CPU_SUBTYPE_SH7723 help Select SH7723 if you have an SH-MobileR2 CPU. +config CPU_SUBTYPE_SH7724 + bool "Support SH7724 processor" + select CPU_SH4A + select CPU_SHX2 + select ARCH_SPARSEMEM_ENABLE + select SYS_SUPPORTS_CMT + help + Select SH7724 if you have an SH-MobileR2R CPU. + config CPU_SUBTYPE_SH7763 bool "Support SH7763 processor" select CPU_SH4A @@ -495,6 +504,7 @@ config SH_PCLK_FREQ CPU_SUBTYPE_SH7203 || CPU_SUBTYPE_SH7206 || \ CPU_SUBTYPE_SH7263 || CPU_SUBTYPE_MXG || \ CPU_SUBTYPE_SH7786 + default "41666666" if CPU_SUBTYPE_SH7724 default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R default "66000000" if CPU_SUBTYPE_SH4_202 default "50000000" diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 1fd58b421438..005c962c8b1c 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -32,7 +32,7 @@ enum cpu_type { /* SH-4A types */ CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SH7786, - CPU_SH7723, CPU_SHX3, + CPU_SH7723, CPU_SH7724, CPU_SHX3, /* SH4AL-DSP types */ CPU_SH7343, CPU_SH7722, CPU_SH7366, diff --git a/arch/sh/include/cpu-sh4/cpu/freq.h b/arch/sh/include/cpu-sh4/cpu/freq.h index 749d1c434337..ccf1d999db6d 100644 --- a/arch/sh/include/cpu-sh4/cpu/freq.h +++ b/arch/sh/include/cpu-sh4/cpu/freq.h @@ -25,6 +25,24 @@ #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) #define FRQCR 0xffc80000 +#elif defined(CONFIG_CPU_SUBTYPE_SH7724) +#define FRQCRA 0xa4150000 +#define FRQCRB 0xa4150004 +#define VCLKCR 0xa4150048 + +#define FCLKACR 0xa4150008 +#define FCLKBCR 0xa415000c +#define FRQCR FRQCRA +#define SCLKACR FCLKACR +#define SCLKBCR FCLKBCR +#define FCLKACR 0xa4150008 +#define FCLKBCR 0xa415000c +#define IrDACLKCR 0xa4150018 + +#define MSTPCR0 0xa4150030 +#define MSTPCR1 0xa4150034 +#define MSTPCR2 0xa4150038 + #elif defined(CONFIG_CPU_SUBTYPE_SH7785) #define FRQCR0 0xffc80000 #define FRQCR1 0xffc80004 diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h new file mode 100644 index 000000000000..34605c9e354d --- /dev/null +++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h @@ -0,0 +1,255 @@ +#ifndef __ASM_SH7724_H__ +#define __ASM_SH7724_H__ + +enum { + /* PTA */ + GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4, + GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0, + + /* PTB */ + GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4, + GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0, + + /* PTC */ + GPIO_PTC7, GPIO_PTC6, GPIO_PTC5, GPIO_PTC4, + GPIO_PTC3, GPIO_PTC2, GPIO_PTC1, GPIO_PTC0, + + /* PTD */ + GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4, + GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0, + + /* PTE */ + GPIO_PTE7, GPIO_PTE6, GPIO_PTE5, GPIO_PTE4, + GPIO_PTE3, GPIO_PTE2, GPIO_PTE1, GPIO_PTE0, + + /* PTF */ + GPIO_PTF7, GPIO_PTF6, GPIO_PTF5, GPIO_PTF4, + GPIO_PTF3, GPIO_PTF2, GPIO_PTF1, GPIO_PTF0, + + /* PTG */ + GPIO_PTG5, GPIO_PTG4, + GPIO_PTG3, GPIO_PTG2, GPIO_PTG1, GPIO_PTG0, + + /* PTH */ + GPIO_PTH7, GPIO_PTH6, GPIO_PTH5, GPIO_PTH4, + GPIO_PTH3, GPIO_PTH2, GPIO_PTH1, GPIO_PTH0, + + /* PTJ */ + GPIO_PTJ7, GPIO_PTJ6, GPIO_PTJ5, + GPIO_PTJ3, GPIO_PTJ2, GPIO_PTJ1, GPIO_PTJ0, + + /* PTK */ + GPIO_PTK7, GPIO_PTK6, GPIO_PTK5, GPIO_PTK4, + GPIO_PTK3, GPIO_PTK2, GPIO_PTK1, GPIO_PTK0, + + /* PTL */ + GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4, + GPIO_PTL3, GPIO_PTL2, GPIO_PTL1, GPIO_PTL0, + + /* PTM */ + GPIO_PTM7, GPIO_PTM6, GPIO_PTM5, GPIO_PTM4, + GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0, + + /* PTN */ + GPIO_PTN7, GPIO_PTN6, GPIO_PTN5, GPIO_PTN4, + GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0, + + /* PTQ */ + GPIO_PTQ7, GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4, + GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0, + + /* PTR */ + GPIO_PTR7, GPIO_PTR6, GPIO_PTR5, GPIO_PTR4, + GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0, + + /* PTS */ + GPIO_PTS6, GPIO_PTS5, GPIO_PTS4, + GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0, + + /* PTT */ + GPIO_PTT7, GPIO_PTT6, GPIO_PTT5, GPIO_PTT4, + GPIO_PTT3, GPIO_PTT2, GPIO_PTT1, GPIO_PTT0, + + /* PTU */ + GPIO_PTU7, GPIO_PTU6, GPIO_PTU5, GPIO_PTU4, + GPIO_PTU3, GPIO_PTU2, GPIO_PTU1, GPIO_PTU0, + + /* PTV */ + GPIO_PTV7, GPIO_PTV6, GPIO_PTV5, GPIO_PTV4, + GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0, + + /* PTW */ + GPIO_PTW7, GPIO_PTW6, GPIO_PTW5, GPIO_PTW4, + GPIO_PTW3, GPIO_PTW2, GPIO_PTW1, GPIO_PTW0, + + /* PTX */ + GPIO_PTX7, GPIO_PTX6, GPIO_PTX5, GPIO_PTX4, + GPIO_PTX3, GPIO_PTX2, GPIO_PTX1, GPIO_PTX0, + + /* PTY */ + GPIO_PTY7, GPIO_PTY6, GPIO_PTY5, GPIO_PTY4, + GPIO_PTY3, GPIO_PTY2, GPIO_PTY1, GPIO_PTY0, + + /* PTZ */ + GPIO_PTZ7, GPIO_PTZ6, GPIO_PTZ5, GPIO_PTZ4, + GPIO_PTZ3, GPIO_PTZ2, GPIO_PTZ1, GPIO_PTZ0, + + /* BSC (PTA/PTB/PTJ/PTQ/PTR/PTT) */ + GPIO_FN_D31, GPIO_FN_D30, GPIO_FN_D29, GPIO_FN_D28, + GPIO_FN_D27, GPIO_FN_D26, GPIO_FN_D25, GPIO_FN_D24, + GPIO_FN_D23, GPIO_FN_D22, GPIO_FN_D21, GPIO_FN_D20, + GPIO_FN_D19, GPIO_FN_D18, GPIO_FN_D17, GPIO_FN_D16, + GPIO_FN_D15, GPIO_FN_D14, GPIO_FN_D13, GPIO_FN_D12, + GPIO_FN_D11, GPIO_FN_D10, GPIO_FN_D9, GPIO_FN_D8, + GPIO_FN_D7, GPIO_FN_D6, GPIO_FN_D5, GPIO_FN_D4, + GPIO_FN_D3, GPIO_FN_D2, GPIO_FN_D1, GPIO_FN_D0, + GPIO_FN_A25, GPIO_FN_A24, GPIO_FN_A23, GPIO_FN_A22, + GPIO_FN_CS6B_CE1B, GPIO_FN_CS6A_CE2B, + GPIO_FN_CS5B_CE1A, GPIO_FN_CS5A_CE2A, + GPIO_FN_WE3_ICIOWR, GPIO_FN_WE2_ICIORD, + GPIO_FN_IOIS16, GPIO_FN_WAIT, + GPIO_FN_BS, + + /* KEYSC (PTA/PTB)*/ + GPIO_FN_KEYOUT5_IN5, GPIO_FN_KEYOUT4_IN6, GPIO_FN_KEYIN4, + GPIO_FN_KEYIN3, GPIO_FN_KEYIN2, GPIO_FN_KEYIN1, GPIO_FN_KEYIN0, + GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT2, GPIO_FN_KEYOUT1, GPIO_FN_KEYOUT0, + + /* ATAPI (PTA/PTB/PTK/PTR/PTS/PTW) */ + GPIO_FN_IDED15, GPIO_FN_IDED14, GPIO_FN_IDED13, GPIO_FN_IDED12, + GPIO_FN_IDED11, GPIO_FN_IDED10, GPIO_FN_IDED9, GPIO_FN_IDED8, + GPIO_FN_IDED7, GPIO_FN_IDED6, GPIO_FN_IDED5, GPIO_FN_IDED4, + GPIO_FN_IDED3, GPIO_FN_IDED2, GPIO_FN_IDED1, GPIO_FN_IDED0, + GPIO_FN_IDEA2, GPIO_FN_IDEA1, GPIO_FN_IDEA0, GPIO_FN_IDEIOWR, + GPIO_FN_IODREQ, GPIO_FN_IDECS0, GPIO_FN_IDECS1, GPIO_FN_IDEIORD, + GPIO_FN_DIRECTION, GPIO_FN_EXBUF_ENB, GPIO_FN_IDERST, GPIO_FN_IODACK, + GPIO_FN_IDEINT, GPIO_FN_IDEIORDY, + + /* TPU (PTB/PTR/PTS) */ + GPIO_FN_TPUTO3, GPIO_FN_TPUTO2, GPIO_FN_TPUTO1, GPIO_FN_TPUTO0, + GPIO_FN_TPUTI3, GPIO_FN_TPUTI2, + + /* LCDC (PTC/PTD/PTE/PTF/PTM/PTR) */ + GPIO_FN_LCDD23, GPIO_FN_LCDD22, GPIO_FN_LCDD21, GPIO_FN_LCDD20, + GPIO_FN_LCDD19, GPIO_FN_LCDD18, GPIO_FN_LCDD17, GPIO_FN_LCDD16, + GPIO_FN_LCDD15, GPIO_FN_LCDD14, GPIO_FN_LCDD13, GPIO_FN_LCDD12, + GPIO_FN_LCDD11, GPIO_FN_LCDD10, GPIO_FN_LCDD9, GPIO_FN_LCDD8, + GPIO_FN_LCDD7, GPIO_FN_LCDD6, GPIO_FN_LCDD5, GPIO_FN_LCDD4, + GPIO_FN_LCDD3, GPIO_FN_LCDD2, GPIO_FN_LCDD1, GPIO_FN_LCDD0, + GPIO_FN_LCDVSYN, GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_LCDHSYN, + GPIO_FN_LCDCS, GPIO_FN_LCDDON, GPIO_FN_LCDDCK, GPIO_FN_LCDWR, + GPIO_FN_LCDVEPWC, GPIO_FN_LCDVCPWC, GPIO_FN_LCDRD, GPIO_FN_LCDLCLK, + + /* SCIF0 (PTF/PTM) */ + GPIO_FN_SCIF0_TXD, GPIO_FN_SCIF0_RXD, GPIO_FN_SCIF0_SCK, + + /* SCIF1 (PTL) */ + GPIO_FN_SCIF1_SCK, GPIO_FN_SCIF1_RXD, GPIO_FN_SCIF1_TXD, + + /* SCIF2 (PTE/PTF/PTN) with LCDC, VOU */ + GPIO_FN_SCIF2_L_TXD, GPIO_FN_SCIF2_L_SCK, GPIO_FN_SCIF2_L_RXD, + GPIO_FN_SCIF2_V_TXD, GPIO_FN_SCIF2_V_SCK, GPIO_FN_SCIF2_V_RXD, + + /* SCIF3 (PTL/PTN/PTZ) with VOU, IRQ */ + GPIO_FN_SCIF3_V_SCK, GPIO_FN_SCIF3_V_RXD, GPIO_FN_SCIF3_V_TXD, + GPIO_FN_SCIF3_V_CTS, GPIO_FN_SCIF3_V_RTS, + GPIO_FN_SCIF3_I_SCK, GPIO_FN_SCIF3_I_RXD, GPIO_FN_SCIF3_I_TXD, + GPIO_FN_SCIF3_I_CTS, GPIO_FN_SCIF3_I_RTS, + + /* SCIF4 (PTE) */ + GPIO_FN_SCIF4_SCK, GPIO_FN_SCIF4_RXD, GPIO_FN_SCIF4_TXD, + + /* SCIF5 (PTS) */ + GPIO_FN_SCIF5_SCK, GPIO_FN_SCIF5_RXD, GPIO_FN_SCIF5_TXD, + + /* FSI (PTE/PTU/PTV) */ + GPIO_FN_FSIMCKB, GPIO_FN_FSIMCKA, GPIO_FN_FSIOASD, + GPIO_FN_FSIIABCK, GPIO_FN_FSIIALRCK, GPIO_FN_FSIOABCK, + GPIO_FN_FSIOALRCK, GPIO_FN_CLKAUDIOAO, GPIO_FN_FSIIBSD, + GPIO_FN_FSIOBSD, GPIO_FN_FSIIBBCK, GPIO_FN_FSIIBLRCK, + GPIO_FN_FSIOBBCK, GPIO_FN_FSIOBLRCK, GPIO_FN_CLKAUDIOBO, + GPIO_FN_FSIIASD, + + /* AUD (PTG) */ + GPIO_FN_AUDCK, GPIO_FN_AUDSYNC, GPIO_FN_AUDATA3, + GPIO_FN_AUDATA2, GPIO_FN_AUDATA1, GPIO_FN_AUDATA0, + + /* VIO (PTS) (common?) */ + GPIO_FN_VIO_CKO, + + /* VIO0 (PTH/PTK) */ + GPIO_FN_VIO0_D15, GPIO_FN_VIO0_D14, GPIO_FN_VIO0_D13, GPIO_FN_VIO0_D12, + GPIO_FN_VIO0_D11, GPIO_FN_VIO0_D10, GPIO_FN_VIO0_D9, GPIO_FN_VIO0_D8, + GPIO_FN_VIO0_D7, GPIO_FN_VIO0_D6, GPIO_FN_VIO0_D5, GPIO_FN_VIO0_D4, + GPIO_FN_VIO0_D3, GPIO_FN_VIO0_D2, GPIO_FN_VIO0_D1, GPIO_FN_VIO0_D0, + GPIO_FN_VIO0_VD, GPIO_FN_VIO0_CLK, + GPIO_FN_VIO0_FLD, GPIO_FN_VIO0_HD, + + /* VIO1 (PTK/PTS) */ + GPIO_FN_VIO1_D7, GPIO_FN_VIO1_D6, GPIO_FN_VIO1_D5, GPIO_FN_VIO1_D4, + GPIO_FN_VIO1_D3, GPIO_FN_VIO1_D2, GPIO_FN_VIO1_D1, GPIO_FN_VIO1_D0, + GPIO_FN_VIO1_FLD, GPIO_FN_VIO1_HD, GPIO_FN_VIO1_VD, GPIO_FN_VIO1_CLK, + + /* Eth (PTL/PTN/PTX) */ + GPIO_FN_RMII_RXD0, GPIO_FN_RMII_RXD1, + GPIO_FN_RMII_TXD0, GPIO_FN_RMII_TXD1, + GPIO_FN_RMII_REF_CLK, GPIO_FN_RMII_TX_EN, + GPIO_FN_RMII_RX_ER, GPIO_FN_RMII_CRS_DV, + GPIO_FN_LNKSTA, GPIO_FN_MDIO, + GPIO_FN_MDC, + + /* System (PTJ) */ + GPIO_FN_PDSTATUS, GPIO_FN_STATUS2, GPIO_FN_STATUS0, + + /* VOU (PTL/PTM/PTN*/ + GPIO_FN_DV_D15, GPIO_FN_DV_D14, GPIO_FN_DV_D13, GPIO_FN_DV_D12, + GPIO_FN_DV_D11, GPIO_FN_DV_D10, GPIO_FN_DV_D9, GPIO_FN_DV_D8, + GPIO_FN_DV_D7, GPIO_FN_DV_D6, GPIO_FN_DV_D5, GPIO_FN_DV_D4, + GPIO_FN_DV_D3, GPIO_FN_DV_D2, GPIO_FN_DV_D1, GPIO_FN_DV_D0, + GPIO_FN_DV_CLKI, GPIO_FN_DV_CLK, GPIO_FN_DV_VSYNC, GPIO_FN_DV_HSYNC, + + /* MSIOF0 (PTL/PTM) */ + GPIO_FN_MSIOF0_RXD, GPIO_FN_MSIOF0_TXD, + GPIO_FN_MSIOF0_MCK, GPIO_FN_MSIOF0_TSCK, + GPIO_FN_MSIOF0_SS1, GPIO_FN_MSIOF0_SS2, + GPIO_FN_MSIOF0_TSYNC, GPIO_FN_MSIOF0_RSCK, + GPIO_FN_MSIOF0_RSYNC, + + /* MSIOF1 (PTV) */ + GPIO_FN_MSIOF1_RXD, GPIO_FN_MSIOF1_TXD, + GPIO_FN_MSIOF1_MCK, GPIO_FN_MSIOF1_TSCK, + GPIO_FN_MSIOF1_SS1, GPIO_FN_MSIOF1_SS2, + GPIO_FN_MSIOF1_TSYNC, GPIO_FN_MSIOF1_RSCK, + GPIO_FN_MSIOF1_RSYNC, + + /* DMAC (PTU/PTX) */ + GPIO_FN_DMAC_DACK0, GPIO_FN_DMAC_DREQ0, + GPIO_FN_DMAC_DACK1, GPIO_FN_DMAC_DREQ1, + + /* SDHI0 (PTY) */ + GPIO_FN_SDHI0CD, GPIO_FN_SDHI0WP, GPIO_FN_SDHI0CMD, GPIO_FN_SDHI0CLK, + GPIO_FN_SDHI0D3, GPIO_FN_SDHI0D2, GPIO_FN_SDHI0D1, GPIO_FN_SDHI0D0, + + /* SDHI1 (PTW) */ + GPIO_FN_SDHI1CD, GPIO_FN_SDHI1WP, GPIO_FN_SDHI1CMD, GPIO_FN_SDHI1CLK, + GPIO_FN_SDHI1D3, GPIO_FN_SDHI1D2, GPIO_FN_SDHI1D1, GPIO_FN_SDHI1D0, + + /* MMC (PTW/PTX)*/ + GPIO_FN_MMC_D7, GPIO_FN_MMC_D6, GPIO_FN_MMC_D5, GPIO_FN_MMC_D4, + GPIO_FN_MMC_D3, GPIO_FN_MMC_D2, GPIO_FN_MMC_D1, GPIO_FN_MMC_D0, + GPIO_FN_MMC_CLK, GPIO_FN_MMC_CMD, + + /* IrDA (PTX) */ + GPIO_FN_IRDA_OUT, GPIO_FN_IRDA_IN, + + /* TSIF (PTX) */ + GPIO_FN_TSIF_TS0_SDAT, GPIO_FN_TSIF_TS0_SCK, + GPIO_FN_TSIF_TS0_SDEN, GPIO_FN_TSIF_TS0_SPSYNC, + + /* IRQ (PTZ) */ + GPIO_FN_INTC_IRQ7, GPIO_FN_INTC_IRQ6, GPIO_FN_INTC_IRQ5, + GPIO_FN_INTC_IRQ4, GPIO_FN_INTC_IRQ3, GPIO_FN_INTC_IRQ2, + GPIO_FN_INTC_IRQ1, GPIO_FN_INTC_IRQ0, +}; + +#endif /* __ASM_SH7724_H__ */ diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 91e3677ae09d..973ff831c8a8 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -156,6 +156,12 @@ int __init detect_cpu_and_cache_system(void) break; } break; + case 0x300b: + boot_cpu_data.type = CPU_SH7724; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_FPU; + break; case 0x4000: /* 1st cut */ case 0x4001: /* 2nd cut */ boot_cpu_data.type = CPU_SHX3; diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index 1a92361feeb9..afd6fba47849 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o +obj-$(CONFIG_CPU_SUBTYPE_SH7724) += setup-sh7724.o obj-$(CONFIG_CPU_SUBTYPE_SH7366) += setup-sh7366.o obj-$(CONFIG_CPU_SUBTYPE_SHX3) += setup-shx3.o @@ -26,12 +27,14 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7786) := clock-sh7786.o clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7722.o clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o +clock-$(CONFIG_CPU_SUBTYPE_SH7724) := clock-sh7722.o clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o # Pinmux setup pinmux-$(CONFIG_CPU_SUBTYPE_SH7722) := pinmux-sh7722.o pinmux-$(CONFIG_CPU_SUBTYPE_SH7723) := pinmux-sh7723.o +pinmux-$(CONFIG_CPU_SUBTYPE_SH7724) := pinmux-sh7724.o pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 0e174af21874..1ccdfc561fef 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c @@ -130,6 +130,12 @@ static void adjust_clocks(int originate, int *l, unsigned long v[], * is quite simple.. */ +#if defined(CONFIG_CPU_SUBTYPE_SH7724) +#define STCPLL(frqcr) ((((frqcr >> 24) & 0x3f) + 1) * 2) +#else +#define STCPLL(frqcr) (((frqcr >> 24) & 0x1f) + 1) +#endif + /* * Instead of having two separate multipliers/divisors set, like this: * @@ -139,13 +145,17 @@ static void adjust_clocks(int originate, int *l, unsigned long v[], * I created the divisors2 array, which is used to calculate rate like * rate = parent * 2 / divisors2[ divisor ]; */ +#if defined(CONFIG_CPU_SUBTYPE_SH7724) +static int divisors2[] = { 4, 1, 8, 12, 16, 24, 32, 1, 48, 64, 72, 96, 1, 144 }; +#else static int divisors2[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40 }; +#endif static void master_clk_recalc(struct clk *clk) { unsigned frqcr = ctrl_inl(FRQCR); - clk->rate = CONFIG_SH_PCLK_FREQ * (((frqcr >> 24) & 0x1f) + 1); + clk->rate = CONFIG_SH_PCLK_FREQ * STCPLL(frqcr); } static void master_clk_init(struct clk *clk) @@ -161,13 +171,30 @@ static void module_clk_recalc(struct clk *clk) { unsigned long frqcr = ctrl_inl(FRQCR); - clk->rate = clk->parent->rate / (((frqcr >> 24) & 0x1f) + 1); + clk->rate = clk->parent->rate / STCPLL(frqcr); } +#if defined(CONFIG_CPU_SUBTYPE_SH7724) +#define MASTERDIVS { 12, 16, 24, 30, 32, 36, 48 } +#define STCMASK 0x3f +#define DIVCALC(div) (div/2-1) +#define FRQCRKICK 0x80000000 +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +#define MASTERDIVS { 6, 8, 12, 16 } +#define STCMASK 0x1f +#define DIVCALC(div) (div-1) +#define FRQCRKICK 0x00000000 +#else +#define MASTERDIVS { 2, 3, 4, 6, 8, 16 } +#define STCMASK 0x1f +#define DIVCALC(div) (div-1) +#define FRQCRKICK 0x00000000 +#endif + static int master_clk_setrate(struct clk *clk, unsigned long rate, int id) { int div = rate / clk->rate; - int master_divs[] = { 2, 3, 4, 6, 8, 16 }; + int master_divs[] = MASTERDIVS; int index; unsigned long frqcr; @@ -180,8 +207,9 @@ static int master_clk_setrate(struct clk *clk, unsigned long rate, int id) div = master_divs[index - 1]; frqcr = ctrl_inl(FRQCR); - frqcr &= ~(0xF << 24); - frqcr |= ( (div-1) << 24); + frqcr &= ~(STCMASK << 24); + frqcr |= (DIVCALC(div) << 24); + frqcr |= FRQCRKICK; ctrl_outl(frqcr, FRQCR); return 0; @@ -377,6 +405,7 @@ static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate, /* clear FRQCR bits */ frqcr &= ~(ctx.mask << ctx.shift); frqcr |= div << ctx.shift; + frqcr |= FRQCRKICK; /* ...and perform actual change */ ctrl_outl(frqcr, FRQCR); @@ -542,8 +571,8 @@ static struct clk sh7722_r_clock = { .flags = CLK_RATE_PROPAGATES, }; -#ifndef CONFIG_CPU_SUBTYPE_SH7343 - +#if !defined(CONFIG_CPU_SUBTYPE_SH7343) &&\ + !defined(CONFIG_CPU_SUBTYPE_SH7724) /* * these three clocks - SIU A, SIU B, IrDA - share the same clk_ops * methods of clk_ops determine which register they should access by @@ -560,15 +589,16 @@ static struct clk sh7722_siu_b_clock = { .arch_flags = SCLKBCR, .ops = &sh7722_siu_clk_ops, }; +#endif /* CONFIG_CPU_SUBTYPE_SH7343, SH7724 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7722) +#if defined(CONFIG_CPU_SUBTYPE_SH7722) ||\ + defined(CONFIG_CPU_SUBTYPE_SH7724) static struct clk sh7722_irda_clock = { .name = "irda_clk", .arch_flags = IrDACLKCR, .ops = &sh7722_siu_clk_ops, }; #endif -#endif /* CONFIG_CPU_SUBTYPE_SH7343 */ static struct clk sh7722_video_clock = { .name = "video_clk", @@ -715,6 +745,61 @@ static struct clk sh7722_mstpcr_clocks[] = { MSTPCR("vpu0", "bus_clk", 2, 1), MSTPCR("lcdc0", "bus_clk", 2, 0), #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7724) + /* See Datasheet : Overview -> Block Diagram */ + MSTPCR("tlb0", "cpu_clk", 0, 31), + MSTPCR("ic0", "cpu_clk", 0, 30), + MSTPCR("oc0", "cpu_clk", 0, 29), + MSTPCR("rs0", "bus_clk", 0, 28), + MSTPCR("ilmem0", "cpu_clk", 0, 27), + MSTPCR("l2c0", "sh_clk", 0, 26), + MSTPCR("fpu0", "cpu_clk", 0, 24), + MSTPCR("intc0", "peripheral_clk", 0, 22), + MSTPCR("dmac0", "bus_clk", 0, 21), + MSTPCR("sh0", "sh_clk", 0, 20), + MSTPCR("hudi0", "peripheral_clk", 0, 19), + MSTPCR("ubc0", "cpu_clk", 0, 17), + MSTPCR("tmu0", "peripheral_clk", 0, 15), + MSTPCR("cmt0", "r_clk", 0, 14), + MSTPCR("rwdt0", "r_clk", 0, 13), + MSTPCR("dmac1", "bus_clk", 0, 12), + MSTPCR("tmu1", "peripheral_clk", 0, 10), + MSTPCR("scif0", "peripheral_clk", 0, 9), + MSTPCR("scif1", "peripheral_clk", 0, 8), + MSTPCR("scif2", "peripheral_clk", 0, 7), + MSTPCR("scif3", "bus_clk", 0, 6), + MSTPCR("scif4", "bus_clk", 0, 5), + MSTPCR("scif5", "bus_clk", 0, 4), + MSTPCR("msiof0", "bus_clk", 0, 2), + MSTPCR("msiof1", "bus_clk", 0, 1), + MSTPCR("keysc0", "r_clk", 1, 12), + MSTPCR("rtc0", "r_clk", 1, 11), + MSTPCR("i2c0", "peripheral_clk", 1, 9), + MSTPCR("i2c1", "peripheral_clk", 1, 8), + MSTPCR("mmc0", "bus_clk", 2, 29), + MSTPCR("eth0", "bus_clk", 2, 28), + MSTPCR("atapi0", "bus_clk", 2, 26), + MSTPCR("tpu0", "bus_clk", 2, 25), + MSTPCR("irda0", "peripheral_clk", 2, 24), + MSTPCR("tsif0", "bus_clk", 2, 22), + MSTPCR("usb1", "bus_clk", 2, 21), + MSTPCR("usb0", "bus_clk", 2, 20), + MSTPCR("2dg0", "bus_clk", 2, 19), + MSTPCR("sdhi0", "bus_clk", 2, 18), + MSTPCR("sdhi1", "bus_clk", 2, 17), + MSTPCR("veu1", "bus_clk", 2, 15), + MSTPCR("ceu1", "bus_clk", 2, 13), + MSTPCR("beu1", "bus_clk", 2, 12), + MSTPCR("2ddmac0", "sh_clk", 2, 10), + MSTPCR("spu0", "bus_clk", 2, 9), + MSTPCR("jpu0", "bus_clk", 2, 6), + MSTPCR("vou0", "bus_clk", 2, 5), + MSTPCR("beu0", "bus_clk", 2, 4), + MSTPCR("ceu0", "bus_clk", 2, 3), + MSTPCR("veu0", "bus_clk", 2, 2), + MSTPCR("vpu0", "bus_clk", 2, 1), + MSTPCR("lcdc0", "bus_clk", 2, 0), +#endif #if defined(CONFIG_CPU_SUBTYPE_SH7343) MSTPCR("uram0", "umem_clk", 0, 28), MSTPCR("xymem0", "bus_clk", 0, 26), @@ -786,12 +871,15 @@ static struct clk *sh7722_clocks[] = { &sh7722_sh_clock, &sh7722_peripheral_clock, &sh7722_sdram_clock, -#ifndef CONFIG_CPU_SUBTYPE_SH7343 +#if !defined(CONFIG_CPU_SUBTYPE_SH7343) &&\ + !defined(CONFIG_CPU_SUBTYPE_SH7724) &sh7722_siu_a_clock, &sh7722_siu_b_clock, -#if defined(CONFIG_CPU_SUBTYPE_SH7722) - &sh7722_irda_clock, #endif +/* 7724 should support FSI clock */ +#if defined(CONFIG_CPU_SUBTYPE_SH7722) || \ + defined(CONFIG_CPU_SUBTYPE_SH7724) + &sh7722_irda_clock, #endif &sh7722_video_clock, }; diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7724.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7724.c new file mode 100644 index 000000000000..1af0f9586379 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7724.c @@ -0,0 +1,2230 @@ +/* + * SH7724 Pinmux + * + * Copyright (C) 2009 Renesas Solutions Corp. + * + * Kuninori Morimoto + * + * Based on SH7723 Pinmux + * Copyright (C) 2008 Magnus Damm + * + * 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. + */ + +#include +#include +#include +#include + +enum { + PINMUX_RESERVED = 0, + + PINMUX_DATA_BEGIN, + PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA, + PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA, + PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA, + PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA, + PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA, + PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA, + PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA, + PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA, + PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA, + PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA, + PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA, + PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA, + PTG5_DATA, PTG4_DATA, + PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA, + PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA, + PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA, + PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, + PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA, + PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA, + PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA, + PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA, + PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA, + PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA, + PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA, + PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA, + PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA, + PTQ7_DATA, PTQ6_DATA, PTQ5_DATA, PTQ4_DATA, + PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA, + PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA, + PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA, + PTS6_DATA, PTS5_DATA, PTS4_DATA, + PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA, + PTT7_DATA, PTT6_DATA, PTT5_DATA, PTT4_DATA, + PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA, + PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA, + PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA, + PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA, + PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA, + PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA, + PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA, + PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA, + PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA, + PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA, + PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA, + PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA, + PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA, + PINMUX_DATA_END, + + PINMUX_INPUT_BEGIN, + PTA7_IN, PTA6_IN, PTA5_IN, PTA4_IN, + PTA3_IN, PTA2_IN, PTA1_IN, PTA0_IN, + PTB7_IN, PTB6_IN, PTB5_IN, PTB4_IN, + PTB3_IN, PTB2_IN, PTB1_IN, PTB0_IN, + PTC7_IN, PTC6_IN, PTC5_IN, PTC4_IN, + PTC3_IN, PTC2_IN, PTC1_IN, PTC0_IN, + PTD7_IN, PTD6_IN, PTD5_IN, PTD4_IN, + PTD3_IN, PTD2_IN, PTD1_IN, PTD0_IN, + PTE7_IN, PTE6_IN, PTE5_IN, PTE4_IN, + PTE3_IN, PTE2_IN, PTE1_IN, PTE0_IN, + PTF7_IN, PTF6_IN, PTF5_IN, PTF4_IN, + PTF3_IN, PTF2_IN, PTF1_IN, PTF0_IN, + PTH7_IN, PTH6_IN, PTH5_IN, PTH4_IN, + PTH3_IN, PTH2_IN, PTH1_IN, PTH0_IN, + PTJ3_IN, PTJ2_IN, PTJ1_IN, PTJ0_IN, + PTK7_IN, PTK6_IN, PTK5_IN, PTK4_IN, + PTK3_IN, PTK2_IN, PTK1_IN, PTK0_IN, + PTL7_IN, PTL6_IN, PTL5_IN, PTL4_IN, + PTL3_IN, PTL2_IN, PTL1_IN, PTL0_IN, + PTM7_IN, PTM6_IN, PTM5_IN, PTM4_IN, + PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN, + PTN7_IN, PTN6_IN, PTN5_IN, PTN4_IN, + PTN3_IN, PTN2_IN, PTN1_IN, PTN0_IN, + PTQ7_IN, PTQ6_IN, PTQ5_IN, PTQ4_IN, + PTQ3_IN, PTQ2_IN, PTQ1_IN, PTQ0_IN, + PTR7_IN, PTR6_IN, PTR5_IN, PTR4_IN, + PTR3_IN, PTR2_IN, PTR1_IN, PTR0_IN, + PTS6_IN, PTS5_IN, PTS4_IN, + PTS3_IN, PTS2_IN, PTS1_IN, PTS0_IN, + PTT7_IN, PTT6_IN, PTT5_IN, PTT4_IN, + PTT3_IN, PTT2_IN, PTT1_IN, PTT0_IN, + PTU7_IN, PTU6_IN, PTU5_IN, PTU4_IN, + PTU3_IN, PTU2_IN, PTU1_IN, PTU0_IN, + PTV7_IN, PTV6_IN, PTV5_IN, PTV4_IN, + PTV3_IN, PTV2_IN, PTV1_IN, PTV0_IN, + PTW7_IN, PTW6_IN, PTW5_IN, PTW4_IN, + PTW3_IN, PTW2_IN, PTW1_IN, PTW0_IN, + PTX7_IN, PTX6_IN, PTX5_IN, PTX4_IN, + PTX3_IN, PTX2_IN, PTX1_IN, PTX0_IN, + PTY7_IN, PTY6_IN, PTY5_IN, PTY4_IN, + PTY3_IN, PTY2_IN, PTY1_IN, PTY0_IN, + PTZ7_IN, PTZ6_IN, PTZ5_IN, PTZ4_IN, + PTZ3_IN, PTZ2_IN, PTZ1_IN, PTZ0_IN, + PINMUX_INPUT_END, + + PINMUX_INPUT_PULLUP_BEGIN, + PTA7_IN_PU, PTA6_IN_PU, PTA5_IN_PU, PTA4_IN_PU, + PTA3_IN_PU, PTA2_IN_PU, PTA1_IN_PU, PTA0_IN_PU, + PTB7_IN_PU, PTB6_IN_PU, PTB5_IN_PU, PTB4_IN_PU, + PTB3_IN_PU, PTB2_IN_PU, PTB1_IN_PU, PTB0_IN_PU, + PTC7_IN_PU, PTC6_IN_PU, PTC5_IN_PU, PTC4_IN_PU, + PTC3_IN_PU, PTC2_IN_PU, PTC1_IN_PU, PTC0_IN_PU, + PTD7_IN_PU, PTD6_IN_PU, PTD5_IN_PU, PTD4_IN_PU, + PTD3_IN_PU, PTD2_IN_PU, PTD1_IN_PU, PTD0_IN_PU, + PTE7_IN_PU, PTE6_IN_PU, PTE5_IN_PU, PTE4_IN_PU, + PTE3_IN_PU, PTE2_IN_PU, PTE1_IN_PU, PTE0_IN_PU, + PTF7_IN_PU, PTF6_IN_PU, PTF5_IN_PU, PTF4_IN_PU, + PTF3_IN_PU, PTF2_IN_PU, PTF1_IN_PU, PTF0_IN_PU, + PTH7_IN_PU, PTH6_IN_PU, PTH5_IN_PU, PTH4_IN_PU, + PTH3_IN_PU, PTH2_IN_PU, PTH1_IN_PU, PTH0_IN_PU, + PTJ3_IN_PU, PTJ2_IN_PU, PTJ1_IN_PU, PTJ0_IN_PU, + PTK7_IN_PU, PTK6_IN_PU, PTK5_IN_PU, PTK4_IN_PU, + PTK3_IN_PU, PTK2_IN_PU, PTK1_IN_PU, PTK0_IN_PU, + PTL7_IN_PU, PTL6_IN_PU, PTL5_IN_PU, PTL4_IN_PU, + PTL3_IN_PU, PTL2_IN_PU, PTL1_IN_PU, PTL0_IN_PU, + PTM7_IN_PU, PTM6_IN_PU, PTM5_IN_PU, PTM4_IN_PU, + PTM3_IN_PU, PTM2_IN_PU, PTM1_IN_PU, PTM0_IN_PU, + PTN7_IN_PU, PTN6_IN_PU, PTN5_IN_PU, PTN4_IN_PU, + PTN3_IN_PU, PTN2_IN_PU, PTN1_IN_PU, PTN0_IN_PU, + PTQ7_IN_PU, PTQ6_IN_PU, PTQ5_IN_PU, PTQ4_IN_PU, + PTQ3_IN_PU, PTQ2_IN_PU, PTQ1_IN_PU, PTQ0_IN_PU, + PTR7_IN_PU, PTR6_IN_PU, PTR5_IN_PU, PTR4_IN_PU, + PTR3_IN_PU, PTR2_IN_PU, PTR1_IN_PU, PTR0_IN_PU, + PTS6_IN_PU, PTS5_IN_PU, PTS4_IN_PU, + PTS3_IN_PU, PTS2_IN_PU, PTS1_IN_PU, PTS0_IN_PU, + PTT7_IN_PU, PTT6_IN_PU, PTT5_IN_PU, PTT4_IN_PU, + PTT3_IN_PU, PTT2_IN_PU, PTT1_IN_PU, PTT0_IN_PU, + PTU7_IN_PU, PTU6_IN_PU, PTU5_IN_PU, PTU4_IN_PU, + PTU3_IN_PU, PTU2_IN_PU, PTU1_IN_PU, PTU0_IN_PU, + PTV7_IN_PU, PTV6_IN_PU, PTV5_IN_PU, PTV4_IN_PU, + PTV3_IN_PU, PTV2_IN_PU, PTV1_IN_PU, PTV0_IN_PU, + PTW7_IN_PU, PTW6_IN_PU, PTW5_IN_PU, PTW4_IN_PU, + PTW3_IN_PU, PTW2_IN_PU, PTW1_IN_PU, PTW0_IN_PU, + PTX7_IN_PU, PTX6_IN_PU, PTX5_IN_PU, PTX4_IN_PU, + PTX3_IN_PU, PTX2_IN_PU, PTX1_IN_PU, PTX0_IN_PU, + PTY7_IN_PU, PTY6_IN_PU, PTY5_IN_PU, PTY4_IN_PU, + PTY3_IN_PU, PTY2_IN_PU, PTY1_IN_PU, PTY0_IN_PU, + PTZ7_IN_PU, PTZ6_IN_PU, PTZ5_IN_PU, PTZ4_IN_PU, + PTZ3_IN_PU, PTZ2_IN_PU, PTZ1_IN_PU, PTZ0_IN_PU, + PINMUX_INPUT_PULLUP_END, + + PINMUX_OUTPUT_BEGIN, + PTA7_OUT, PTA6_OUT, PTA5_OUT, PTA4_OUT, + PTA3_OUT, PTA2_OUT, PTA1_OUT, PTA0_OUT, + PTB7_OUT, PTB6_OUT, PTB5_OUT, PTB4_OUT, + PTB3_OUT, PTB2_OUT, PTB1_OUT, PTB0_OUT, + PTC7_OUT, PTC6_OUT, PTC5_OUT, PTC4_OUT, + PTC3_OUT, PTC2_OUT, PTC1_OUT, PTC0_OUT, + PTD7_OUT, PTD6_OUT, PTD5_OUT, PTD4_OUT, + PTD3_OUT, PTD2_OUT, PTD1_OUT, PTD0_OUT, + PTE7_OUT, PTE6_OUT, PTE5_OUT, PTE4_OUT, + PTE3_OUT, PTE2_OUT, PTE1_OUT, PTE0_OUT, + PTF7_OUT, PTF6_OUT, PTF5_OUT, PTF4_OUT, + PTF3_OUT, PTF2_OUT, PTF1_OUT, PTF0_OUT, + PTG5_OUT, PTG4_OUT, + PTG3_OUT, PTG2_OUT, PTG1_OUT, PTG0_OUT, + PTH7_OUT, PTH6_OUT, PTH5_OUT, PTH4_OUT, + PTH3_OUT, PTH2_OUT, PTH1_OUT, PTH0_OUT, + PTJ7_OUT, PTJ6_OUT, PTJ5_OUT, + PTJ3_OUT, PTJ2_OUT, PTJ1_OUT, PTJ0_OUT, + PTK7_OUT, PTK6_OUT, PTK5_OUT, PTK4_OUT, + PTK3_OUT, PTK2_OUT, PTK1_OUT, PTK0_OUT, + PTL7_OUT, PTL6_OUT, PTL5_OUT, PTL4_OUT, + PTL3_OUT, PTL2_OUT, PTL1_OUT, PTL0_OUT, + PTM7_OUT, PTM6_OUT, PTM5_OUT, PTM4_OUT, + PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT, + PTN7_OUT, PTN6_OUT, PTN5_OUT, PTN4_OUT, + PTN3_OUT, PTN2_OUT, PTN1_OUT, PTN0_OUT, + PTQ7_OUT, PTQ6_OUT, PTQ5_OUT, PTQ4_OUT, + PTQ3_OUT, PTQ2_OUT, PTQ1_OUT, PTQ0_OUT, + PTR7_OUT, PTR6_OUT, PTR5_OUT, PTR4_OUT, + PTR1_OUT, PTR0_OUT, + PTS6_OUT, PTS5_OUT, PTS4_OUT, + PTS3_OUT, PTS2_OUT, PTS1_OUT, PTS0_OUT, + PTT7_OUT, PTT6_OUT, PTT5_OUT, PTT4_OUT, + PTT3_OUT, PTT2_OUT, PTT1_OUT, PTT0_OUT, + PTU7_OUT, PTU6_OUT, PTU5_OUT, PTU4_OUT, + PTU3_OUT, PTU2_OUT, PTU1_OUT, PTU0_OUT, + PTV7_OUT, PTV6_OUT, PTV5_OUT, PTV4_OUT, + PTV3_OUT, PTV2_OUT, PTV1_OUT, PTV0_OUT, + PTW7_OUT, PTW6_OUT, PTW5_OUT, PTW4_OUT, + PTW3_OUT, PTW2_OUT, PTW1_OUT, PTW0_OUT, + PTX7_OUT, PTX6_OUT, PTX5_OUT, PTX4_OUT, + PTX3_OUT, PTX2_OUT, PTX1_OUT, PTX0_OUT, + PTY7_OUT, PTY6_OUT, PTY5_OUT, PTY4_OUT, + PTY3_OUT, PTY2_OUT, PTY1_OUT, PTY0_OUT, + PTZ7_OUT, PTZ6_OUT, PTZ5_OUT, PTZ4_OUT, + PTZ3_OUT, PTZ2_OUT, PTZ1_OUT, PTZ0_OUT, + PINMUX_OUTPUT_END, + + PINMUX_FUNCTION_BEGIN, + PTA7_FN, PTA6_FN, PTA5_FN, PTA4_FN, + PTA3_FN, PTA2_FN, PTA1_FN, PTA0_FN, + PTB7_FN, PTB6_FN, PTB5_FN, PTB4_FN, + PTB3_FN, PTB2_FN, PTB1_FN, PTB0_FN, + PTC7_FN, PTC6_FN, PTC5_FN, PTC4_FN, + PTC3_FN, PTC2_FN, PTC1_FN, PTC0_FN, + PTD7_FN, PTD6_FN, PTD5_FN, PTD4_FN, + PTD3_FN, PTD2_FN, PTD1_FN, PTD0_FN, + PTE7_FN, PTE6_FN, PTE5_FN, PTE4_FN, + PTE3_FN, PTE2_FN, PTE1_FN, PTE0_FN, + PTF7_FN, PTF6_FN, PTF5_FN, PTF4_FN, + PTF3_FN, PTF2_FN, PTF1_FN, PTF0_FN, + PTG5_FN, PTG4_FN, + PTG3_FN, PTG2_FN, PTG1_FN, PTG0_FN, + PTH7_FN, PTH6_FN, PTH5_FN, PTH4_FN, + PTH3_FN, PTH2_FN, PTH1_FN, PTH0_FN, + PTJ7_FN, PTJ6_FN, PTJ5_FN, + PTJ3_FN, PTJ2_FN, PTJ1_FN, PTJ0_FN, + PTK7_FN, PTK6_FN, PTK5_FN, PTK4_FN, + PTK3_FN, PTK2_FN, PTK1_FN, PTK0_FN, + PTL7_FN, PTL6_FN, PTL5_FN, PTL4_FN, + PTL3_FN, PTL2_FN, PTL1_FN, PTL0_FN, + PTM7_FN, PTM6_FN, PTM5_FN, PTM4_FN, + PTM3_FN, PTM2_FN, PTM1_FN, PTM0_FN, + PTN7_FN, PTN6_FN, PTN5_FN, PTN4_FN, + PTN3_FN, PTN2_FN, PTN1_FN, PTN0_FN, + PTQ7_FN, PTQ6_FN, PTQ5_FN, PTQ4_FN, + PTQ3_FN, PTQ2_FN, PTQ1_FN, PTQ0_FN, + PTR7_FN, PTR6_FN, PTR5_FN, PTR4_FN, + PTR3_FN, PTR2_FN, PTR1_FN, PTR0_FN, + PTS6_FN, PTS5_FN, PTS4_FN, + PTS3_FN, PTS2_FN, PTS1_FN, PTS0_FN, + PTT7_FN, PTT6_FN, PTT5_FN, PTT4_FN, + PTT3_FN, PTT2_FN, PTT1_FN, PTT0_FN, + PTU7_FN, PTU6_FN, PTU5_FN, PTU4_FN, + PTU3_FN, PTU2_FN, PTU1_FN, PTU0_FN, + PTV7_FN, PTV6_FN, PTV5_FN, PTV4_FN, + PTV3_FN, PTV2_FN, PTV1_FN, PTV0_FN, + PTW7_FN, PTW6_FN, PTW5_FN, PTW4_FN, + PTW3_FN, PTW2_FN, PTW1_FN, PTW0_FN, + PTX7_FN, PTX6_FN, PTX5_FN, PTX4_FN, + PTX3_FN, PTX2_FN, PTX1_FN, PTX0_FN, + PTY7_FN, PTY6_FN, PTY5_FN, PTY4_FN, + PTY3_FN, PTY2_FN, PTY1_FN, PTY0_FN, + PTZ7_FN, PTZ6_FN, PTZ5_FN, PTZ4_FN, + PTZ3_FN, PTZ2_FN, PTZ1_FN, PTZ0_FN, + + + PSA15_0, PSA15_1, + PSA14_0, PSA14_1, + PSA13_0, PSA13_1, + PSA12_0, PSA12_1, + PSA10_0, PSA10_1, + PSA9_0, PSA9_1, + PSA8_0, PSA8_1, + PSA7_0, PSA7_1, + PSA6_0, PSA6_1, + PSA5_0, PSA5_1, + PSA3_0, PSA3_1, + PSA2_0, PSA2_1, + PSA1_0, PSA1_1, + PSA0_0, PSA0_1, + + PSB14_0, PSB14_1, + PSB13_0, PSB13_1, + PSB12_0, PSB12_1, + PSB11_0, PSB11_1, + PSB10_0, PSB10_1, + PSB9_0, PSB9_1, + PSB8_0, PSB8_1, + PSB7_0, PSB7_1, + PSB6_0, PSB6_1, + PSB5_0, PSB5_1, + PSB4_0, PSB4_1, + PSB3_0, PSB3_1, + PSB2_0, PSB2_1, + PSB1_0, PSB1_1, + PSB0_0, PSB0_1, + + PSC15_0, PSC15_1, + PSC14_0, PSC14_1, + PSC13_0, PSC13_1, + PSC12_0, PSC12_1, + PSC11_0, PSC11_1, + PSC10_0, PSC10_1, + PSC9_0, PSC9_1, + PSC8_0, PSC8_1, + PSC7_0, PSC7_1, + PSC6_0, PSC6_1, + PSC5_0, PSC5_1, + PSC4_0, PSC4_1, + PSC2_0, PSC2_1, + PSC1_0, PSC1_1, + PSC0_0, PSC0_1, + + PSD15_0, PSD15_1, + PSD14_0, PSD14_1, + PSD13_0, PSD13_1, + PSD12_0, PSD12_1, + PSD11_0, PSD11_1, + PSD10_0, PSD10_1, + PSD9_0, PSD9_1, + PSD8_0, PSD8_1, + PSD7_0, PSD7_1, + PSD6_0, PSD6_1, + PSD5_0, PSD5_1, + PSD4_0, PSD4_1, + PSD3_0, PSD3_1, + PSD2_0, PSD2_1, + PSD1_0, PSD1_1, + PSD0_0, PSD0_1, + + PSE15_0, PSE15_1, + PSE14_0, PSE14_1, + PSE13_0, PSE13_1, + PSE12_0, PSE12_1, + PSE11_0, PSE11_1, + PSE10_0, PSE10_1, + PSE9_0, PSE9_1, + PSE8_0, PSE8_1, + PSE7_0, PSE7_1, + PSE6_0, PSE6_1, + PSE5_0, PSE5_1, + PSE4_0, PSE4_1, + PSE3_0, PSE3_1, + PSE2_0, PSE2_1, + PSE1_0, PSE1_1, + PSE0_0, PSE0_1, + PINMUX_FUNCTION_END, + + PINMUX_MARK_BEGIN, + /*PTA*/ + D23_MARK, KEYOUT2_MARK, IDED15_MARK, + D22_MARK, KEYOUT1_MARK, IDED14_MARK, + D21_MARK, KEYOUT0_MARK, IDED13_MARK, + D20_MARK, KEYIN4_MARK, IDED12_MARK, + D19_MARK, KEYIN3_MARK, IDED11_MARK, + D18_MARK, KEYIN2_MARK, IDED10_MARK, + D17_MARK, KEYIN1_MARK, IDED9_MARK, + D16_MARK, KEYIN0_MARK, IDED8_MARK, + + /*PTB*/ + D31_MARK, TPUTO1_MARK, IDEA1_MARK, + D30_MARK, TPUTO0_MARK, IDEA0_MARK, + D29_MARK, IODREQ_MARK, + D28_MARK, IDECS0_MARK, + D27_MARK, IDECS1_MARK, + D26_MARK, KEYOUT5_IN5_MARK, IDEIORD_MARK, + D25_MARK, KEYOUT4_IN6_MARK, IDEIOWR_MARK, + D24_MARK, KEYOUT3_MARK, IDEINT_MARK, + + /*PTC*/ + LCDD7_MARK, + LCDD6_MARK, + LCDD5_MARK, + LCDD4_MARK, + LCDD3_MARK, + LCDD2_MARK, + LCDD1_MARK, + LCDD0_MARK, + + /*PTD*/ + LCDD15_MARK, + LCDD14_MARK, + LCDD13_MARK, + LCDD12_MARK, + LCDD11_MARK, + LCDD10_MARK, + LCDD9_MARK, + LCDD8_MARK, + + /*PTE*/ + FSIMCKB_MARK, + FSIMCKA_MARK, + LCDD21_MARK, SCIF2_L_TXD_MARK, + LCDD20_MARK, SCIF4_SCK_MARK, + LCDD19_MARK, SCIF4_RXD_MARK, + LCDD18_MARK, SCIF4_TXD_MARK, + LCDD17_MARK, + LCDD16_MARK, + + /*PTF*/ + LCDVSYN_MARK, + LCDDISP_MARK, LCDRS_MARK, + LCDHSYN_MARK, LCDCS_MARK, + LCDDON_MARK, + LCDDCK_MARK, LCDWR_MARK, + LCDVEPWC_MARK, SCIF0_TXD_MARK, + LCDD23_MARK, SCIF2_L_SCK_MARK, + LCDD22_MARK, SCIF2_L_RXD_MARK, + + /*PTG*/ + AUDCK_MARK, + AUDSYNC_MARK, + AUDATA3_MARK, + AUDATA2_MARK, + AUDATA1_MARK, + AUDATA0_MARK, + + /*PTH*/ + VIO0_VD_MARK, + VIO0_CLK_MARK, + VIO0_D7_MARK, + VIO0_D6_MARK, + VIO0_D5_MARK, + VIO0_D4_MARK, + VIO0_D3_MARK, + VIO0_D2_MARK, + + /*PTJ*/ + PDSTATUS_MARK, + STATUS2_MARK, + STATUS0_MARK, + A25_MARK, BS_MARK, + A24_MARK, + A23_MARK, + A22_MARK, + + /*PTK*/ + VIO1_D5_MARK, VIO0_D13_MARK, IDED5_MARK, + VIO1_D4_MARK, VIO0_D12_MARK, IDED4_MARK, + VIO1_D3_MARK, VIO0_D11_MARK, IDED3_MARK, + VIO1_D2_MARK, VIO0_D10_MARK, IDED2_MARK, + VIO1_D1_MARK, VIO0_D9_MARK, IDED1_MARK, + VIO1_D0_MARK, VIO0_D8_MARK, IDED0_MARK, + VIO0_FLD_MARK, + VIO0_HD_MARK, + + /*PTL*/ + DV_D5_MARK, SCIF3_V_SCK_MARK, RMII_RXD0_MARK, + DV_D4_MARK, SCIF3_V_RXD_MARK, RMII_RXD1_MARK, + DV_D3_MARK, SCIF3_V_TXD_MARK, RMII_REF_CLK_MARK, + DV_D2_MARK, SCIF1_SCK_MARK, RMII_TX_EN_MARK, + DV_D1_MARK, SCIF1_RXD_MARK, RMII_TXD0_MARK, + DV_D0_MARK, SCIF1_TXD_MARK, RMII_TXD1_MARK, + DV_D15_MARK, + DV_D14_MARK, MSIOF0_MCK_MARK, + + /*PTM*/ + DV_D13_MARK, MSIOF0_TSCK_MARK, + DV_D12_MARK, MSIOF0_RXD_MARK, + DV_D11_MARK, MSIOF0_TXD_MARK, + DV_D10_MARK, MSIOF0_TSYNC_MARK, + DV_D9_MARK, MSIOF0_SS1_MARK, MSIOF0_RSCK_MARK, + DV_D8_MARK, MSIOF0_SS2_MARK, MSIOF0_RSYNC_MARK, + LCDVCPWC_MARK, SCIF0_RXD_MARK, + LCDRD_MARK, SCIF0_SCK_MARK, + + /*PTN*/ + VIO0_D1_MARK, + VIO0_D0_MARK, + DV_CLKI_MARK, + DV_CLK_MARK, SCIF2_V_SCK_MARK, + DV_VSYNC_MARK, SCIF2_V_RXD_MARK, + DV_HSYNC_MARK, SCIF2_V_TXD_MARK, + DV_D7_MARK, SCIF3_V_CTS_MARK, RMII_RX_ER_MARK, + DV_D6_MARK, SCIF3_V_RTS_MARK, RMII_CRS_DV_MARK, + + /*PTQ*/ + D7_MARK, + D6_MARK, + D5_MARK, + D4_MARK, + D3_MARK, + D2_MARK, + D1_MARK, + D0_MARK, + + /*PTR*/ + CS6B_CE1B_MARK, + CS6A_CE2B_MARK, + CS5B_CE1A_MARK, + CS5A_CE2A_MARK, + IOIS16_MARK, LCDLCLK_MARK, + WAIT_MARK, + WE3_ICIOWR_MARK, TPUTO3_MARK, TPUTI3_MARK, + WE2_ICIORD_MARK, TPUTO2_MARK, IDEA2_MARK, + + /*PTS*/ + VIO_CKO_MARK, + VIO1_FLD_MARK, TPUTI2_MARK, IDEIORDY_MARK, + VIO1_HD_MARK, SCIF5_SCK_MARK, + VIO1_VD_MARK, SCIF5_RXD_MARK, + VIO1_CLK_MARK, SCIF5_TXD_MARK, + VIO1_D7_MARK, VIO0_D15_MARK, IDED7_MARK, + VIO1_D6_MARK, VIO0_D14_MARK, IDED6_MARK, + + /*PTT*/ + D15_MARK, + D14_MARK, + D13_MARK, + D12_MARK, + D11_MARK, + D10_MARK, + D9_MARK, + D8_MARK, + + /*PTU*/ + DMAC_DACK0_MARK, + DMAC_DREQ0_MARK, + FSIOASD_MARK, + FSIIABCK_MARK, + FSIIALRCK_MARK, + FSIOABCK_MARK, + FSIOALRCK_MARK, + CLKAUDIOAO_MARK, + + /*PTV*/ + FSIIBSD_MARK, MSIOF1_SS2_MARK, MSIOF1_RSYNC_MARK, + FSIOBSD_MARK, MSIOF1_SS1_MARK, MSIOF1_RSCK_MARK, + FSIIBBCK_MARK, MSIOF1_RXD_MARK, + FSIIBLRCK_MARK, MSIOF1_TSYNC_MARK, + FSIOBBCK_MARK, MSIOF1_TSCK_MARK, + FSIOBLRCK_MARK, MSIOF1_TXD_MARK, + CLKAUDIOBO_MARK, MSIOF1_MCK_MARK, + FSIIASD_MARK, + + /*PTW*/ + MMC_D7_MARK, SDHI1CD_MARK, IODACK_MARK, + MMC_D6_MARK, SDHI1WP_MARK, IDERST_MARK, + MMC_D5_MARK, SDHI1D3_MARK, EXBUF_ENB_MARK, + MMC_D4_MARK, SDHI1D2_MARK, DIRECTION_MARK, + MMC_D3_MARK, SDHI1D1_MARK, + MMC_D2_MARK, SDHI1D0_MARK, + MMC_D1_MARK, SDHI1CMD_MARK, + MMC_D0_MARK, SDHI1CLK_MARK, + + /*PTX*/ + DMAC_DACK1_MARK, IRDA_OUT_MARK, + DMAC_DREQ1_MARK, IRDA_IN_MARK, + TSIF_TS0_SDAT_MARK, LNKSTA_MARK, + TSIF_TS0_SCK_MARK, MDIO_MARK, + TSIF_TS0_SDEN_MARK, MDC_MARK, + TSIF_TS0_SPSYNC_MARK, + MMC_CLK_MARK, + MMC_CMD_MARK, + + /*PTY*/ + SDHI0CD_MARK, + SDHI0WP_MARK, + SDHI0D3_MARK, + SDHI0D2_MARK, + SDHI0D1_MARK, + SDHI0D0_MARK, + SDHI0CMD_MARK, + SDHI0CLK_MARK, + + /*PTZ*/ + INTC_IRQ7_MARK, SCIF3_I_CTS_MARK, + INTC_IRQ6_MARK, SCIF3_I_RTS_MARK, + INTC_IRQ5_MARK, SCIF3_I_SCK_MARK, + INTC_IRQ4_MARK, SCIF3_I_RXD_MARK, + INTC_IRQ3_MARK, SCIF3_I_TXD_MARK, + INTC_IRQ2_MARK, + INTC_IRQ1_MARK, + INTC_IRQ0_MARK, + PINMUX_MARK_END, +}; + +static pinmux_enum_t pinmux_data[] = { + /* PTA GPIO */ + PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT, PTA7_IN_PU), + PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT, PTA6_IN_PU), + PINMUX_DATA(PTA5_DATA, PTA5_IN, PTA5_OUT, PTA5_IN_PU), + PINMUX_DATA(PTA4_DATA, PTA4_IN, PTA4_OUT, PTA4_IN_PU), + PINMUX_DATA(PTA3_DATA, PTA3_IN, PTA3_OUT, PTA3_IN_PU), + PINMUX_DATA(PTA2_DATA, PTA2_IN, PTA2_OUT, PTA2_IN_PU), + PINMUX_DATA(PTA1_DATA, PTA1_IN, PTA1_OUT, PTA1_IN_PU), + PINMUX_DATA(PTA0_DATA, PTA0_IN, PTA0_OUT, PTA0_IN_PU), + + /* PTB GPIO */ + PINMUX_DATA(PTB7_DATA, PTB7_IN, PTB7_OUT, PTB7_IN_PU), + PINMUX_DATA(PTB6_DATA, PTB6_IN, PTB6_OUT, PTB6_IN_PU), + PINMUX_DATA(PTB5_DATA, PTB5_IN, PTB5_OUT, PTB5_IN_PU), + PINMUX_DATA(PTB4_DATA, PTB4_IN, PTB4_OUT, PTB4_IN_PU), + PINMUX_DATA(PTB3_DATA, PTB3_IN, PTB3_OUT, PTB3_IN_PU), + PINMUX_DATA(PTB2_DATA, PTB2_IN, PTB2_OUT, PTB2_IN_PU), + PINMUX_DATA(PTB1_DATA, PTB1_IN, PTB1_OUT, PTB1_IN_PU), + PINMUX_DATA(PTB0_DATA, PTB0_IN, PTB0_OUT, PTB0_IN_PU), + + /* PTC GPIO */ + PINMUX_DATA(PTC7_DATA, PTC7_IN, PTC7_OUT, PTC7_IN_PU), + PINMUX_DATA(PTC6_DATA, PTC6_IN, PTC6_OUT, PTC6_IN_PU), + PINMUX_DATA(PTC5_DATA, PTC5_IN, PTC5_OUT, PTC5_IN_PU), + PINMUX_DATA(PTC4_DATA, PTC4_IN, PTC4_OUT, PTC4_IN_PU), + PINMUX_DATA(PTC3_DATA, PTC3_IN, PTC3_OUT, PTC3_IN_PU), + PINMUX_DATA(PTC2_DATA, PTC2_IN, PTC2_OUT, PTC2_IN_PU), + PINMUX_DATA(PTC1_DATA, PTC1_IN, PTC1_OUT, PTC1_IN_PU), + PINMUX_DATA(PTC0_DATA, PTC0_IN, PTC0_OUT, PTC0_IN_PU), + + /* PTD GPIO */ + PINMUX_DATA(PTD7_DATA, PTD7_IN, PTD7_OUT, PTD7_IN_PU), + PINMUX_DATA(PTD6_DATA, PTD6_IN, PTD6_OUT, PTD6_IN_PU), + PINMUX_DATA(PTD5_DATA, PTD5_IN, PTD5_OUT, PTD5_IN_PU), + PINMUX_DATA(PTD4_DATA, PTD4_IN, PTD4_OUT, PTD4_IN_PU), + PINMUX_DATA(PTD3_DATA, PTD3_IN, PTD3_OUT, PTD3_IN_PU), + PINMUX_DATA(PTD2_DATA, PTD2_IN, PTD2_OUT, PTD2_IN_PU), + PINMUX_DATA(PTD1_DATA, PTD1_IN, PTD1_OUT, PTD1_IN_PU), + PINMUX_DATA(PTD0_DATA, PTD0_IN, PTD0_OUT, PTD0_IN_PU), + + /* PTE GPIO */ + PINMUX_DATA(PTE7_DATA, PTE7_IN, PTE7_OUT, PTE7_IN_PU), + PINMUX_DATA(PTE6_DATA, PTE6_IN, PTE6_OUT, PTE6_IN_PU), + PINMUX_DATA(PTE5_DATA, PTE5_IN, PTE5_OUT, PTE5_IN_PU), + PINMUX_DATA(PTE4_DATA, PTE4_IN, PTE4_OUT, PTE4_IN_PU), + PINMUX_DATA(PTE3_DATA, PTE3_IN, PTE3_OUT, PTE3_IN_PU), + PINMUX_DATA(PTE2_DATA, PTE2_IN, PTE2_OUT, PTE2_IN_PU), + PINMUX_DATA(PTE1_DATA, PTE1_IN, PTE1_OUT, PTE1_IN_PU), + PINMUX_DATA(PTE0_DATA, PTE0_IN, PTE0_OUT, PTE0_IN_PU), + + /* PTF GPIO */ + PINMUX_DATA(PTF7_DATA, PTF7_IN, PTF7_OUT, PTF7_IN_PU), + PINMUX_DATA(PTF6_DATA, PTF6_IN, PTF6_OUT, PTF6_IN_PU), + PINMUX_DATA(PTF5_DATA, PTF5_IN, PTF5_OUT, PTF5_IN_PU), + PINMUX_DATA(PTF4_DATA, PTF4_IN, PTF4_OUT, PTF4_IN_PU), + PINMUX_DATA(PTF3_DATA, PTF3_IN, PTF3_OUT, PTF3_IN_PU), + PINMUX_DATA(PTF2_DATA, PTF2_IN, PTF2_OUT, PTF2_IN_PU), + PINMUX_DATA(PTF1_DATA, PTF1_IN, PTF1_OUT, PTF1_IN_PU), + PINMUX_DATA(PTF0_DATA, PTF0_IN, PTF0_OUT, PTF0_IN_PU), + + /* PTG GPIO */ + PINMUX_DATA(PTG5_DATA, PTG5_OUT), + PINMUX_DATA(PTG4_DATA, PTG4_OUT), + PINMUX_DATA(PTG3_DATA, PTG3_OUT), + PINMUX_DATA(PTG2_DATA, PTG2_OUT), + PINMUX_DATA(PTG1_DATA, PTG1_OUT), + PINMUX_DATA(PTG0_DATA, PTG0_OUT), + + /* PTH GPIO */ + PINMUX_DATA(PTH7_DATA, PTH7_IN, PTH7_OUT, PTH7_IN_PU), + PINMUX_DATA(PTH6_DATA, PTH6_IN, PTH6_OUT, PTH6_IN_PU), + PINMUX_DATA(PTH5_DATA, PTH5_IN, PTH5_OUT, PTH5_IN_PU), + PINMUX_DATA(PTH4_DATA, PTH4_IN, PTH4_OUT, PTH4_IN_PU), + PINMUX_DATA(PTH3_DATA, PTH3_IN, PTH3_OUT, PTH3_IN_PU), + PINMUX_DATA(PTH2_DATA, PTH2_IN, PTH2_OUT, PTH2_IN_PU), + PINMUX_DATA(PTH1_DATA, PTH1_IN, PTH1_OUT, PTH1_IN_PU), + PINMUX_DATA(PTH0_DATA, PTH0_IN, PTH0_OUT, PTH0_IN_PU), + + /* PTJ GPIO */ + PINMUX_DATA(PTJ7_DATA, PTJ7_OUT), + PINMUX_DATA(PTJ6_DATA, PTJ6_OUT), + PINMUX_DATA(PTJ5_DATA, PTJ5_OUT), + PINMUX_DATA(PTJ3_DATA, PTJ3_IN, PTJ3_OUT, PTJ3_IN_PU), + PINMUX_DATA(PTJ2_DATA, PTJ2_IN, PTJ2_OUT, PTJ2_IN_PU), + PINMUX_DATA(PTJ1_DATA, PTJ1_IN, PTJ1_OUT, PTJ1_IN_PU), + PINMUX_DATA(PTJ0_DATA, PTJ0_IN, PTJ0_OUT, PTJ0_IN_PU), + + /* PTK GPIO */ + PINMUX_DATA(PTK7_DATA, PTK7_IN, PTK7_OUT, PTK7_IN_PU), + PINMUX_DATA(PTK6_DATA, PTK6_IN, PTK6_OUT, PTK6_IN_PU), + PINMUX_DATA(PTK5_DATA, PTK5_IN, PTK5_OUT, PTK5_IN_PU), + PINMUX_DATA(PTK4_DATA, PTK4_IN, PTK4_OUT, PTK4_IN_PU), + PINMUX_DATA(PTK3_DATA, PTK3_IN, PTK3_OUT, PTK3_IN_PU), + PINMUX_DATA(PTK2_DATA, PTK2_IN, PTK2_OUT, PTK2_IN_PU), + PINMUX_DATA(PTK1_DATA, PTK1_IN, PTK1_OUT, PTK1_IN_PU), + PINMUX_DATA(PTK0_DATA, PTK0_IN, PTK0_OUT, PTK0_IN_PU), + + /* PTL GPIO */ + PINMUX_DATA(PTL7_DATA, PTL7_IN, PTL7_OUT, PTL7_IN_PU), + PINMUX_DATA(PTL6_DATA, PTL6_IN, PTL6_OUT, PTL6_IN_PU), + PINMUX_DATA(PTL5_DATA, PTL5_IN, PTL5_OUT, PTL5_IN_PU), + PINMUX_DATA(PTL4_DATA, PTL4_IN, PTL4_OUT, PTL4_IN_PU), + PINMUX_DATA(PTL3_DATA, PTL3_IN, PTL3_OUT, PTL3_IN_PU), + PINMUX_DATA(PTL2_DATA, PTL2_IN, PTL2_OUT, PTL2_IN_PU), + PINMUX_DATA(PTL1_DATA, PTL1_IN, PTL1_OUT, PTL1_IN_PU), + PINMUX_DATA(PTL0_DATA, PTL0_IN, PTL0_OUT, PTL0_IN_PU), + + /* PTM GPIO */ + PINMUX_DATA(PTM7_DATA, PTM7_IN, PTM7_OUT, PTM7_IN_PU), + PINMUX_DATA(PTM6_DATA, PTM6_IN, PTM6_OUT, PTM6_IN_PU), + PINMUX_DATA(PTM5_DATA, PTM5_IN, PTM5_OUT, PTM5_IN_PU), + PINMUX_DATA(PTM4_DATA, PTM4_IN, PTM4_OUT, PTM4_IN_PU), + PINMUX_DATA(PTM3_DATA, PTM3_IN, PTM3_OUT, PTM3_IN_PU), + PINMUX_DATA(PTM2_DATA, PTM2_IN, PTM2_OUT, PTM2_IN_PU), + PINMUX_DATA(PTM1_DATA, PTM1_IN, PTM1_OUT, PTM1_IN_PU), + PINMUX_DATA(PTM0_DATA, PTM0_IN, PTM0_OUT, PTM0_IN_PU), + + /* PTN GPIO */ + PINMUX_DATA(PTN7_DATA, PTN7_IN, PTN7_OUT, PTN7_IN_PU), + PINMUX_DATA(PTN6_DATA, PTN6_IN, PTN6_OUT, PTN6_IN_PU), + PINMUX_DATA(PTN5_DATA, PTN5_IN, PTN5_OUT, PTN5_IN_PU), + PINMUX_DATA(PTN4_DATA, PTN4_IN, PTN4_OUT, PTN4_IN_PU), + PINMUX_DATA(PTN3_DATA, PTN3_IN, PTN3_OUT, PTN3_IN_PU), + PINMUX_DATA(PTN2_DATA, PTN2_IN, PTN2_OUT, PTN2_IN_PU), + PINMUX_DATA(PTN1_DATA, PTN1_IN, PTN1_OUT, PTN1_IN_PU), + PINMUX_DATA(PTN0_DATA, PTN0_IN, PTN0_OUT, PTN0_IN_PU), + + /* PTQ GPIO */ + PINMUX_DATA(PTQ7_DATA, PTQ7_IN, PTQ7_OUT, PTQ7_IN_PU), + PINMUX_DATA(PTQ6_DATA, PTQ6_IN, PTQ6_OUT, PTQ6_IN_PU), + PINMUX_DATA(PTQ5_DATA, PTQ5_IN, PTQ5_OUT, PTQ5_IN_PU), + PINMUX_DATA(PTQ4_DATA, PTQ4_IN, PTQ4_OUT, PTQ4_IN_PU), + PINMUX_DATA(PTQ3_DATA, PTQ3_IN, PTQ3_OUT, PTQ3_IN_PU), + PINMUX_DATA(PTQ2_DATA, PTQ2_IN, PTQ2_OUT, PTQ2_IN_PU), + PINMUX_DATA(PTQ1_DATA, PTQ1_IN, PTQ1_OUT, PTQ1_IN_PU), + PINMUX_DATA(PTQ0_DATA, PTQ0_IN, PTQ0_OUT, PTQ0_IN_PU), + + /* PTR GPIO */ + PINMUX_DATA(PTR7_DATA, PTR7_IN, PTR7_OUT, PTR7_IN_PU), + PINMUX_DATA(PTR6_DATA, PTR6_IN, PTR6_OUT, PTR6_IN_PU), + PINMUX_DATA(PTR5_DATA, PTR5_IN, PTR5_OUT, PTR5_IN_PU), + PINMUX_DATA(PTR4_DATA, PTR4_IN, PTR4_OUT, PTR4_IN_PU), + PINMUX_DATA(PTR3_DATA, PTR3_IN, PTR3_IN_PU), + PINMUX_DATA(PTR2_DATA, PTR2_IN, PTR2_IN_PU), + PINMUX_DATA(PTR1_DATA, PTR1_IN, PTR1_OUT, PTR1_IN_PU), + PINMUX_DATA(PTR0_DATA, PTR0_IN, PTR0_OUT, PTR0_IN_PU), + + /* PTS GPIO */ + PINMUX_DATA(PTS6_DATA, PTS6_IN, PTS6_OUT, PTS6_IN_PU), + PINMUX_DATA(PTS5_DATA, PTS5_IN, PTS5_OUT, PTS5_IN_PU), + PINMUX_DATA(PTS4_DATA, PTS4_IN, PTS4_OUT, PTS4_IN_PU), + PINMUX_DATA(PTS3_DATA, PTS3_IN, PTS3_OUT, PTS3_IN_PU), + PINMUX_DATA(PTS2_DATA, PTS2_IN, PTS2_OUT, PTS2_IN_PU), + PINMUX_DATA(PTS1_DATA, PTS1_IN, PTS1_OUT, PTS1_IN_PU), + PINMUX_DATA(PTS0_DATA, PTS0_IN, PTS0_OUT, PTS0_IN_PU), + + /* PTT GPIO */ + PINMUX_DATA(PTT7_DATA, PTT7_IN, PTT7_OUT, PTT7_IN_PU), + PINMUX_DATA(PTT6_DATA, PTT6_IN, PTT6_OUT, PTT6_IN_PU), + PINMUX_DATA(PTT5_DATA, PTT5_IN, PTT5_OUT, PTT5_IN_PU), + PINMUX_DATA(PTT4_DATA, PTT4_IN, PTT4_OUT, PTT4_IN_PU), + PINMUX_DATA(PTT3_DATA, PTT3_IN, PTT3_OUT, PTT3_IN_PU), + PINMUX_DATA(PTT2_DATA, PTT2_IN, PTT2_OUT, PTT2_IN_PU), + PINMUX_DATA(PTT1_DATA, PTT1_IN, PTT1_OUT, PTT1_IN_PU), + PINMUX_DATA(PTT0_DATA, PTT0_IN, PTT0_OUT, PTT0_IN_PU), + + /* PTU GPIO */ + PINMUX_DATA(PTU7_DATA, PTU7_IN, PTU7_OUT, PTU7_IN_PU), + PINMUX_DATA(PTU6_DATA, PTU6_IN, PTU6_OUT, PTU6_IN_PU), + PINMUX_DATA(PTU5_DATA, PTU5_IN, PTU5_OUT, PTU5_IN_PU), + PINMUX_DATA(PTU4_DATA, PTU4_IN, PTU4_OUT, PTU4_IN_PU), + PINMUX_DATA(PTU3_DATA, PTU3_IN, PTU3_OUT, PTU3_IN_PU), + PINMUX_DATA(PTU2_DATA, PTU2_IN, PTU2_OUT, PTU2_IN_PU), + PINMUX_DATA(PTU1_DATA, PTU1_IN, PTU1_OUT, PTU1_IN_PU), + PINMUX_DATA(PTU0_DATA, PTU0_IN, PTU0_OUT, PTU0_IN_PU), + + /* PTV GPIO */ + PINMUX_DATA(PTV7_DATA, PTV7_IN, PTV7_OUT, PTV7_IN_PU), + PINMUX_DATA(PTV6_DATA, PTV6_IN, PTV6_OUT, PTV6_IN_PU), + PINMUX_DATA(PTV5_DATA, PTV5_IN, PTV5_OUT, PTV5_IN_PU), + PINMUX_DATA(PTV4_DATA, PTV4_IN, PTV4_OUT, PTV4_IN_PU), + PINMUX_DATA(PTV3_DATA, PTV3_IN, PTV3_OUT, PTV3_IN_PU), + PINMUX_DATA(PTV2_DATA, PTV2_IN, PTV2_OUT, PTV2_IN_PU), + PINMUX_DATA(PTV1_DATA, PTV1_IN, PTV1_OUT, PTV1_IN_PU), + PINMUX_DATA(PTV0_DATA, PTV0_IN, PTV0_OUT, PTV0_IN_PU), + + /* PTW GPIO */ + PINMUX_DATA(PTW7_DATA, PTW7_IN, PTW7_OUT, PTW7_IN_PU), + PINMUX_DATA(PTW6_DATA, PTW6_IN, PTW6_OUT, PTW6_IN_PU), + PINMUX_DATA(PTW5_DATA, PTW5_IN, PTW5_OUT, PTW5_IN_PU), + PINMUX_DATA(PTW4_DATA, PTW4_IN, PTW4_OUT, PTW4_IN_PU), + PINMUX_DATA(PTW3_DATA, PTW3_IN, PTW3_OUT, PTW3_IN_PU), + PINMUX_DATA(PTW2_DATA, PTW2_IN, PTW2_OUT, PTW2_IN_PU), + PINMUX_DATA(PTW1_DATA, PTW1_IN, PTW1_OUT, PTW1_IN_PU), + PINMUX_DATA(PTW0_DATA, PTW0_IN, PTW0_OUT, PTW0_IN_PU), + + /* PTX GPIO */ + PINMUX_DATA(PTX7_DATA, PTX7_IN, PTX7_OUT, PTX7_IN_PU), + PINMUX_DATA(PTX6_DATA, PTX6_IN, PTX6_OUT, PTX6_IN_PU), + PINMUX_DATA(PTX5_DATA, PTX5_IN, PTX5_OUT, PTX5_IN_PU), + PINMUX_DATA(PTX4_DATA, PTX4_IN, PTX4_OUT, PTX4_IN_PU), + PINMUX_DATA(PTX3_DATA, PTX3_IN, PTX3_OUT, PTX3_IN_PU), + PINMUX_DATA(PTX2_DATA, PTX2_IN, PTX2_OUT, PTX2_IN_PU), + PINMUX_DATA(PTX1_DATA, PTX1_IN, PTX1_OUT, PTX1_IN_PU), + PINMUX_DATA(PTX0_DATA, PTX0_IN, PTX0_OUT, PTX0_IN_PU), + + /* PTY GPIO */ + PINMUX_DATA(PTY7_DATA, PTY7_IN, PTY7_OUT, PTY7_IN_PU), + PINMUX_DATA(PTY6_DATA, PTY6_IN, PTY6_OUT, PTY6_IN_PU), + PINMUX_DATA(PTY5_DATA, PTY5_IN, PTY5_OUT, PTY5_IN_PU), + PINMUX_DATA(PTY4_DATA, PTY4_IN, PTY4_OUT, PTY4_IN_PU), + PINMUX_DATA(PTY3_DATA, PTY3_IN, PTY3_OUT, PTY3_IN_PU), + PINMUX_DATA(PTY2_DATA, PTY2_IN, PTY2_OUT, PTY2_IN_PU), + PINMUX_DATA(PTY1_DATA, PTY1_IN, PTY1_OUT, PTY1_IN_PU), + PINMUX_DATA(PTY0_DATA, PTY0_IN, PTY0_OUT, PTY0_IN_PU), + + /* PTZ GPIO */ + PINMUX_DATA(PTZ7_DATA, PTZ7_IN, PTZ7_OUT, PTZ7_IN_PU), + PINMUX_DATA(PTZ6_DATA, PTZ6_IN, PTZ6_OUT, PTZ6_IN_PU), + PINMUX_DATA(PTZ5_DATA, PTZ5_IN, PTZ5_OUT, PTZ5_IN_PU), + PINMUX_DATA(PTZ4_DATA, PTZ4_IN, PTZ4_OUT, PTZ4_IN_PU), + PINMUX_DATA(PTZ3_DATA, PTZ3_IN, PTZ3_OUT, PTZ3_IN_PU), + PINMUX_DATA(PTZ2_DATA, PTZ2_IN, PTZ2_OUT, PTZ2_IN_PU), + PINMUX_DATA(PTZ1_DATA, PTZ1_IN, PTZ1_OUT, PTZ1_IN_PU), + PINMUX_DATA(PTZ0_DATA, PTZ0_IN, PTZ0_OUT, PTZ0_IN_PU), + + /* PTA FN */ + PINMUX_DATA(D23_MARK, PSA15_0, PSA14_0, PTA7_FN), + PINMUX_DATA(D22_MARK, PSA15_0, PSA14_0, PTA6_FN), + PINMUX_DATA(D21_MARK, PSA15_0, PSA14_0, PTA5_FN), + PINMUX_DATA(D20_MARK, PSA15_0, PSA14_0, PTA4_FN), + PINMUX_DATA(D19_MARK, PSA15_0, PSA14_0, PTA3_FN), + PINMUX_DATA(D18_MARK, PSA15_0, PSA14_0, PTA2_FN), + PINMUX_DATA(D17_MARK, PSA15_0, PSA14_0, PTA1_FN), + PINMUX_DATA(D16_MARK, PSA15_0, PSA14_0, PTA0_FN), + + PINMUX_DATA(KEYOUT2_MARK, PSA15_0, PSA14_1, PTA7_FN), + PINMUX_DATA(KEYOUT1_MARK, PSA15_0, PSA14_1, PTA6_FN), + PINMUX_DATA(KEYOUT0_MARK, PSA15_0, PSA14_1, PTA5_FN), + PINMUX_DATA(KEYIN4_MARK, PSA15_0, PSA14_1, PTA4_FN), + PINMUX_DATA(KEYIN3_MARK, PSA15_0, PSA14_1, PTA3_FN), + PINMUX_DATA(KEYIN2_MARK, PSA15_0, PSA14_1, PTA2_FN), + PINMUX_DATA(KEYIN1_MARK, PSA15_0, PSA14_1, PTA1_FN), + PINMUX_DATA(KEYIN0_MARK, PSA15_0, PSA14_1, PTA0_FN), + + PINMUX_DATA(IDED15_MARK, PSA15_1, PSA14_0, PTA7_FN), + PINMUX_DATA(IDED14_MARK, PSA15_1, PSA14_0, PTA6_FN), + PINMUX_DATA(IDED13_MARK, PSA15_1, PSA14_0, PTA5_FN), + PINMUX_DATA(IDED12_MARK, PSA15_1, PSA14_0, PTA4_FN), + PINMUX_DATA(IDED11_MARK, PSA15_1, PSA14_0, PTA3_FN), + PINMUX_DATA(IDED10_MARK, PSA15_1, PSA14_0, PTA2_FN), + PINMUX_DATA(IDED9_MARK, PSA15_1, PSA14_0, PTA1_FN), + PINMUX_DATA(IDED8_MARK, PSA15_1, PSA14_0, PTA0_FN), + + /* PTB FN */ + PINMUX_DATA(D31_MARK, PSE15_0, PSE14_0, PTB7_FN), + PINMUX_DATA(D30_MARK, PSE15_0, PSE14_0, PTB6_FN), + PINMUX_DATA(D29_MARK, PSE11_0, PTB5_FN), + PINMUX_DATA(D28_MARK, PSE11_0, PTB4_FN), + PINMUX_DATA(D27_MARK, PSE11_0, PTB3_FN), + PINMUX_DATA(D26_MARK, PSA15_0, PSA14_0, PTB2_FN), + PINMUX_DATA(D25_MARK, PSA15_0, PSA14_0, PTB1_FN), + PINMUX_DATA(D24_MARK, PSA15_0, PSA14_0, PTB0_FN), + + PINMUX_DATA(IDEA1_MARK, PSE15_1, PSE14_0, PTB7_FN), + PINMUX_DATA(IDEA0_MARK, PSE15_1, PSE14_0, PTB6_FN), + PINMUX_DATA(IODREQ_MARK, PSE11_1, PTB5_FN), + PINMUX_DATA(IDECS0_MARK, PSE11_1, PTB4_FN), + PINMUX_DATA(IDECS1_MARK, PSE11_1, PTB3_FN), + PINMUX_DATA(IDEIORD_MARK, PSA15_1, PSA14_0, PTB2_FN), + PINMUX_DATA(IDEIOWR_MARK, PSA15_1, PSA14_0, PTB1_FN), + PINMUX_DATA(IDEINT_MARK, PSA15_1, PSA14_0, PTB0_FN), + + PINMUX_DATA(TPUTO1_MARK, PSE15_0, PSE14_1, PTB7_FN), + PINMUX_DATA(TPUTO0_MARK, PSE15_0, PSE14_1, PTB6_FN), + + PINMUX_DATA(KEYOUT5_IN5_MARK, PSA15_0, PSA14_1, PTB2_FN), + PINMUX_DATA(KEYOUT4_IN6_MARK, PSA15_0, PSA14_1, PTB1_FN), + PINMUX_DATA(KEYOUT3_MARK, PSA15_0, PSA14_1, PTB0_FN), + + /* PTC FN */ + PINMUX_DATA(LCDD7_MARK, PSD5_0, PTC7_FN), + PINMUX_DATA(LCDD6_MARK, PSD5_0, PTC6_FN), + PINMUX_DATA(LCDD5_MARK, PSD5_0, PTC5_FN), + PINMUX_DATA(LCDD4_MARK, PSD5_0, PTC4_FN), + PINMUX_DATA(LCDD3_MARK, PSD5_0, PTC3_FN), + PINMUX_DATA(LCDD2_MARK, PSD5_0, PTC2_FN), + PINMUX_DATA(LCDD1_MARK, PSD5_0, PTC1_FN), + PINMUX_DATA(LCDD0_MARK, PSD5_0, PTC0_FN), + + /* PTD FN */ + PINMUX_DATA(LCDD15_MARK, PSD5_0, PTD7_FN), + PINMUX_DATA(LCDD14_MARK, PSD5_0, PTD6_FN), + PINMUX_DATA(LCDD13_MARK, PSD5_0, PTD5_FN), + PINMUX_DATA(LCDD12_MARK, PSD5_0, PTD4_FN), + PINMUX_DATA(LCDD11_MARK, PSD5_0, PTD3_FN), + PINMUX_DATA(LCDD10_MARK, PSD5_0, PTD2_FN), + PINMUX_DATA(LCDD9_MARK, PSD5_0, PTD1_FN), + PINMUX_DATA(LCDD8_MARK, PSD5_0, PTD0_FN), + + /* PTE FN */ + PINMUX_DATA(FSIMCKB_MARK, PTE7_FN), + PINMUX_DATA(FSIMCKA_MARK, PTE6_FN), + + PINMUX_DATA(LCDD21_MARK, PSC5_0, PSC4_0, PTE5_FN), + PINMUX_DATA(LCDD20_MARK, PSD3_0, PSD2_0, PTE4_FN), + PINMUX_DATA(LCDD19_MARK, PSA3_0, PSA2_0, PTE3_FN), + PINMUX_DATA(LCDD18_MARK, PSA3_0, PSA2_0, PTE2_FN), + PINMUX_DATA(LCDD17_MARK, PSD5_0, PTE1_FN), + PINMUX_DATA(LCDD16_MARK, PSD5_0, PTE0_FN), + + PINMUX_DATA(SCIF2_L_TXD_MARK, PSC5_0, PSC4_1, PTE5_FN), + PINMUX_DATA(SCIF4_SCK_MARK, PSD3_0, PSD2_1, PTE4_FN), + PINMUX_DATA(SCIF4_RXD_MARK, PSA3_0, PSA2_1, PTE3_FN), + PINMUX_DATA(SCIF4_TXD_MARK, PSA3_0, PSA2_1, PTE2_FN), + + /* PTF FN */ + PINMUX_DATA(LCDVSYN_MARK, PSD8_0, PTF7_FN), + PINMUX_DATA(LCDDISP_MARK, PSD10_0, PSD9_0, PTF6_FN), + PINMUX_DATA(LCDHSYN_MARK, PSD10_0, PSD9_0, PTF5_FN), + PINMUX_DATA(LCDDON_MARK, PSD8_0, PTF4_FN), + PINMUX_DATA(LCDDCK_MARK, PSD10_0, PSD9_0, PTF3_FN), + PINMUX_DATA(LCDVEPWC_MARK, PSA6_0, PTF2_FN), + PINMUX_DATA(LCDD23_MARK, PSC7_0, PSC6_0, PTF1_FN), + PINMUX_DATA(LCDD22_MARK, PSC5_0, PSC4_0, PTF0_FN), + + PINMUX_DATA(LCDRS_MARK, PSD10_0, PSD9_1, PTF6_FN), + PINMUX_DATA(LCDCS_MARK, PSD10_0, PSD9_1, PTF5_FN), + PINMUX_DATA(LCDWR_MARK, PSD10_0, PSD9_1, PTF3_FN), + + PINMUX_DATA(SCIF0_TXD_MARK, PSA6_1, PTF2_FN), + PINMUX_DATA(SCIF2_L_SCK_MARK, PSC7_0, PSC6_1, PTF1_FN), + PINMUX_DATA(SCIF2_L_RXD_MARK, PSC5_0, PSC4_1, PTF0_FN), + + /* PTG FN */ + PINMUX_DATA(AUDCK_MARK, PTG5_FN), + PINMUX_DATA(AUDSYNC_MARK, PTG4_FN), + PINMUX_DATA(AUDATA3_MARK, PTG3_FN), + PINMUX_DATA(AUDATA2_MARK, PTG2_FN), + PINMUX_DATA(AUDATA1_MARK, PTG1_FN), + PINMUX_DATA(AUDATA0_MARK, PTG0_FN), + + /* PTH FN */ + PINMUX_DATA(VIO0_VD_MARK, PTH7_FN), + PINMUX_DATA(VIO0_CLK_MARK, PTH6_FN), + PINMUX_DATA(VIO0_D7_MARK, PTH5_FN), + PINMUX_DATA(VIO0_D6_MARK, PTH4_FN), + PINMUX_DATA(VIO0_D5_MARK, PTH3_FN), + PINMUX_DATA(VIO0_D4_MARK, PTH2_FN), + PINMUX_DATA(VIO0_D3_MARK, PTH1_FN), + PINMUX_DATA(VIO0_D2_MARK, PTH0_FN), + + /* PTJ FN */ + PINMUX_DATA(PDSTATUS_MARK, PTJ7_FN), + PINMUX_DATA(STATUS2_MARK, PTJ6_FN), + PINMUX_DATA(STATUS0_MARK, PTJ5_FN), + PINMUX_DATA(A25_MARK, PSA8_0, PTJ3_FN), + PINMUX_DATA(BS_MARK, PSA8_1, PTJ3_FN), + PINMUX_DATA(A24_MARK, PTJ2_FN), + PINMUX_DATA(A23_MARK, PTJ1_FN), + PINMUX_DATA(A22_MARK, PTJ0_FN), + + /* PTK FN */ + PINMUX_DATA(VIO1_D5_MARK, PSB7_0, PSB6_0, PTK7_FN), + PINMUX_DATA(VIO1_D4_MARK, PSB7_0, PSB6_0, PTK6_FN), + PINMUX_DATA(VIO1_D3_MARK, PSB7_0, PSB6_0, PTK5_FN), + PINMUX_DATA(VIO1_D2_MARK, PSB7_0, PSB6_0, PTK4_FN), + PINMUX_DATA(VIO1_D1_MARK, PSB7_0, PSB6_0, PTK3_FN), + PINMUX_DATA(VIO1_D0_MARK, PSB7_0, PSB6_0, PTK2_FN), + + PINMUX_DATA(VIO0_D13_MARK, PSB7_0, PSB6_1, PTK7_FN), + PINMUX_DATA(VIO0_D12_MARK, PSB7_0, PSB6_1, PTK6_FN), + PINMUX_DATA(VIO0_D11_MARK, PSB7_0, PSB6_1, PTK5_FN), + PINMUX_DATA(VIO0_D10_MARK, PSB7_0, PSB6_1, PTK4_FN), + PINMUX_DATA(VIO0_D9_MARK, PSB7_0, PSB6_1, PTK3_FN), + PINMUX_DATA(VIO0_D8_MARK, PSB7_0, PSB6_1, PTK2_FN), + + PINMUX_DATA(IDED5_MARK, PSB7_1, PSB6_0, PTK7_FN), + PINMUX_DATA(IDED4_MARK, PSB7_1, PSB6_0, PTK6_FN), + PINMUX_DATA(IDED3_MARK, PSB7_1, PSB6_0, PTK5_FN), + PINMUX_DATA(IDED2_MARK, PSB7_1, PSB6_0, PTK4_FN), + PINMUX_DATA(IDED1_MARK, PSB7_1, PSB6_0, PTK3_FN), + PINMUX_DATA(IDED0_MARK, PSB7_1, PSB6_0, PTK2_FN), + + PINMUX_DATA(VIO0_FLD_MARK, PTK1_FN), + PINMUX_DATA(VIO0_HD_MARK, PTK0_FN), + + /* PTL FN */ + PINMUX_DATA(DV_D5_MARK, PSB9_0, PSB8_0, PTL7_FN), + PINMUX_DATA(DV_D4_MARK, PSB9_0, PSB8_0, PTL6_FN), + PINMUX_DATA(DV_D3_MARK, PSE7_0, PSE6_0, PTL5_FN), + PINMUX_DATA(DV_D2_MARK, PSC9_0, PSC8_0, PTL4_FN), + PINMUX_DATA(DV_D1_MARK, PSC9_0, PSC8_0, PTL3_FN), + PINMUX_DATA(DV_D0_MARK, PSC9_0, PSC8_0, PTL2_FN), + PINMUX_DATA(DV_D15_MARK, PSD4_0, PTL1_FN), + PINMUX_DATA(DV_D14_MARK, PSE5_0, PSE4_0, PTL0_FN), + + PINMUX_DATA(SCIF3_V_SCK_MARK, PSB9_0, PSB8_1, PTL7_FN), + PINMUX_DATA(SCIF3_V_RXD_MARK, PSB9_0, PSB8_1, PTL6_FN), + PINMUX_DATA(SCIF3_V_TXD_MARK, PSE7_0, PSE6_1, PTL5_FN), + PINMUX_DATA(SCIF1_SCK_MARK, PSC9_0, PSC8_1, PTL4_FN), + PINMUX_DATA(SCIF1_RXD_MARK, PSC9_0, PSC8_1, PTL3_FN), + PINMUX_DATA(SCIF1_TXD_MARK, PSC9_0, PSC8_1, PTL2_FN), + + PINMUX_DATA(RMII_RXD0_MARK, PSB9_1, PSB8_0, PTL7_FN), + PINMUX_DATA(RMII_RXD1_MARK, PSB9_1, PSB8_0, PTL6_FN), + PINMUX_DATA(RMII_REF_CLK_MARK, PSE7_1, PSE6_0, PTL5_FN), + PINMUX_DATA(RMII_TX_EN_MARK, PSC9_1, PSC8_0, PTL4_FN), + PINMUX_DATA(RMII_TXD0_MARK, PSC9_1, PSC8_0, PTL3_FN), + PINMUX_DATA(RMII_TXD1_MARK, PSC9_1, PSC8_0, PTL2_FN), + + PINMUX_DATA(MSIOF0_MCK_MARK, PSE5_0, PSE4_1, PTL0_FN), + + /* PTM FN */ + PINMUX_DATA(DV_D13_MARK, PSC13_0, PSC12_0, PTM7_FN), + PINMUX_DATA(DV_D12_MARK, PSC13_0, PSC12_0, PTM6_FN), + PINMUX_DATA(DV_D11_MARK, PSC13_0, PSC12_0, PTM5_FN), + PINMUX_DATA(DV_D10_MARK, PSC13_0, PSC12_0, PTM4_FN), + PINMUX_DATA(DV_D9_MARK, PSC11_0, PSC10_0, PTM3_FN), + PINMUX_DATA(DV_D8_MARK, PSC11_0, PSC10_0, PTM2_FN), + + PINMUX_DATA(MSIOF0_TSCK_MARK, PSC13_0, PSC12_1, PTM7_FN), + PINMUX_DATA(MSIOF0_RXD_MARK, PSC13_0, PSC12_1, PTM6_FN), + PINMUX_DATA(MSIOF0_TXD_MARK, PSC13_0, PSC12_1, PTM5_FN), + PINMUX_DATA(MSIOF0_TSYNC_MARK, PSC13_0, PSC12_1, PTM4_FN), + PINMUX_DATA(MSIOF0_SS1_MARK, PSC11_0, PSC10_1, PTM3_FN), + PINMUX_DATA(MSIOF0_RSCK_MARK, PSC11_1, PSC10_0, PTM3_FN), + PINMUX_DATA(MSIOF0_SS2_MARK, PSC11_0, PSC10_1, PTM2_FN), + PINMUX_DATA(MSIOF0_RSYNC_MARK, PSC11_1, PSC10_0, PTM2_FN), + + PINMUX_DATA(LCDVCPWC_MARK, PSA6_0, PTM1_FN), + PINMUX_DATA(LCDRD_MARK, PSA7_0, PTM0_FN), + + PINMUX_DATA(SCIF0_RXD_MARK, PSA6_1, PTM1_FN), + PINMUX_DATA(SCIF0_SCK_MARK, PSA7_1, PTM0_FN), + + /* PTN FN */ + PINMUX_DATA(VIO0_D1_MARK, PTN7_FN), + PINMUX_DATA(VIO0_D0_MARK, PTN6_FN), + + PINMUX_DATA(DV_CLKI_MARK, PSD11_0, PTN5_FN), + PINMUX_DATA(DV_CLK_MARK, PSD13_0, PSD12_0, PTN4_FN), + PINMUX_DATA(DV_VSYNC_MARK, PSD15_0, PSD14_0, PTN3_FN), + PINMUX_DATA(DV_HSYNC_MARK, PSB5_0, PSB4_0, PTN2_FN), + PINMUX_DATA(DV_D7_MARK, PSB3_0, PSB2_0, PTN1_FN), + PINMUX_DATA(DV_D6_MARK, PSB1_0, PSB0_0, PTN0_FN), + + PINMUX_DATA(SCIF2_V_SCK_MARK, PSD13_0, PSD12_1, PTN4_FN), + PINMUX_DATA(SCIF2_V_RXD_MARK, PSD15_0, PSD14_1, PTN3_FN), + PINMUX_DATA(SCIF2_V_TXD_MARK, PSB5_0, PSB4_1, PTN2_FN), + PINMUX_DATA(SCIF3_V_CTS_MARK, PSB3_0, PSB2_1, PTN1_FN), + PINMUX_DATA(SCIF3_V_RTS_MARK, PSB1_0, PSB0_1, PTN0_FN), + + PINMUX_DATA(RMII_RX_ER_MARK, PSB3_1, PSB2_0, PTN1_FN), + PINMUX_DATA(RMII_CRS_DV_MARK, PSB1_1, PSB0_0, PTN0_FN), + + /* PTQ FN */ + PINMUX_DATA(D7_MARK, PTQ7_FN), + PINMUX_DATA(D6_MARK, PTQ6_FN), + PINMUX_DATA(D5_MARK, PTQ5_FN), + PINMUX_DATA(D4_MARK, PTQ4_FN), + PINMUX_DATA(D3_MARK, PTQ3_FN), + PINMUX_DATA(D2_MARK, PTQ2_FN), + PINMUX_DATA(D1_MARK, PTQ1_FN), + PINMUX_DATA(D0_MARK, PTQ0_FN), + + /* PTR FN */ + PINMUX_DATA(CS6B_CE1B_MARK, PTR7_FN), + PINMUX_DATA(CS6A_CE2B_MARK, PTR6_FN), + PINMUX_DATA(CS5B_CE1A_MARK, PTR5_FN), + PINMUX_DATA(CS5A_CE2A_MARK, PTR4_FN), + PINMUX_DATA(IOIS16_MARK, PSA5_0, PTR3_FN), + PINMUX_DATA(WAIT_MARK, PTR2_FN), + PINMUX_DATA(WE3_ICIOWR_MARK, PSA1_0, PSA0_0, PTR1_FN), + PINMUX_DATA(WE2_ICIORD_MARK, PSD1_0, PSD0_0, PTR0_FN), + + PINMUX_DATA(LCDLCLK_MARK, PSA5_1, PTR3_FN), + + PINMUX_DATA(IDEA2_MARK, PSD1_1, PSD0_0, PTR0_FN), + + PINMUX_DATA(TPUTO3_MARK, PSA1_0, PSA0_1, PTR1_FN), + PINMUX_DATA(TPUTI3_MARK, PSA1_1, PSA0_0, PTR1_FN), + PINMUX_DATA(TPUTO2_MARK, PSD1_0, PSD0_1, PTR0_FN), + + /* PTS FN */ + PINMUX_DATA(VIO_CKO_MARK, PTS6_FN), + + PINMUX_DATA(TPUTI2_MARK, PSE9_0, PSE8_1, PTS5_FN), + + PINMUX_DATA(IDEIORDY_MARK, PSE9_1, PSE8_0, PTS5_FN), + + PINMUX_DATA(VIO1_FLD_MARK, PSE9_0, PSE8_0, PTS5_FN), + PINMUX_DATA(VIO1_HD_MARK, PSA10_0, PTS4_FN), + PINMUX_DATA(VIO1_VD_MARK, PSA9_0, PTS3_FN), + PINMUX_DATA(VIO1_CLK_MARK, PSA9_0, PTS2_FN), + PINMUX_DATA(VIO1_D7_MARK, PSB7_0, PSB6_0, PTS1_FN), + PINMUX_DATA(VIO1_D6_MARK, PSB7_0, PSB6_0, PTS0_FN), + + PINMUX_DATA(SCIF5_SCK_MARK, PSA10_1, PTS4_FN), + PINMUX_DATA(SCIF5_RXD_MARK, PSA9_1, PTS3_FN), + PINMUX_DATA(SCIF5_TXD_MARK, PSA9_1, PTS2_FN), + + PINMUX_DATA(VIO0_D15_MARK, PSB7_0, PSB6_1, PTS1_FN), + PINMUX_DATA(VIO0_D14_MARK, PSB7_0, PSB6_1, PTS0_FN), + + PINMUX_DATA(IDED7_MARK, PSB7_1, PSB6_0, PTS1_FN), + PINMUX_DATA(IDED6_MARK, PSB7_1, PSB6_0, PTS0_FN), + + /* PTT FN */ + PINMUX_DATA(D15_MARK, PTT7_FN), + PINMUX_DATA(D14_MARK, PTT6_FN), + PINMUX_DATA(D13_MARK, PTT5_FN), + PINMUX_DATA(D12_MARK, PTT4_FN), + PINMUX_DATA(D11_MARK, PTT3_FN), + PINMUX_DATA(D10_MARK, PTT2_FN), + PINMUX_DATA(D9_MARK, PTT1_FN), + PINMUX_DATA(D8_MARK, PTT0_FN), + + /* PTU FN */ + PINMUX_DATA(DMAC_DACK0_MARK, PTU7_FN), + PINMUX_DATA(DMAC_DREQ0_MARK, PTU6_FN), + + PINMUX_DATA(FSIOASD_MARK, PSE1_0, PTU5_FN), + PINMUX_DATA(FSIIABCK_MARK, PSE1_0, PTU4_FN), + PINMUX_DATA(FSIIALRCK_MARK, PSE1_0, PTU3_FN), + PINMUX_DATA(FSIOABCK_MARK, PSE1_0, PTU2_FN), + PINMUX_DATA(FSIOALRCK_MARK, PSE1_0, PTU1_FN), + PINMUX_DATA(CLKAUDIOAO_MARK, PSE0_0, PTU0_FN), + + /* PTV FN */ + PINMUX_DATA(FSIIBSD_MARK, PSD7_0, PSD6_0, PTV7_FN), + PINMUX_DATA(FSIOBSD_MARK, PSD7_0, PSD6_0, PTV6_FN), + PINMUX_DATA(FSIIBBCK_MARK, PSC15_0, PSC14_0, PTV5_FN), + PINMUX_DATA(FSIIBLRCK_MARK, PSC15_0, PSC14_0, PTV4_FN), + PINMUX_DATA(FSIOBBCK_MARK, PSC15_0, PSC14_0, PTV3_FN), + PINMUX_DATA(FSIOBLRCK_MARK, PSC15_0, PSC14_0, PTV2_FN), + PINMUX_DATA(CLKAUDIOBO_MARK, PSE3_0, PSE2_0, PTV1_FN), + PINMUX_DATA(FSIIASD_MARK, PSE10_0, PTV0_FN), + + PINMUX_DATA(MSIOF1_SS2_MARK, PSD7_0, PSD6_1, PTV7_FN), + PINMUX_DATA(MSIOF1_RSYNC_MARK, PSD7_1, PSD6_0, PTV7_FN), + PINMUX_DATA(MSIOF1_SS1_MARK, PSD7_0, PSD6_1, PTV6_FN), + PINMUX_DATA(MSIOF1_RSCK_MARK, PSD7_1, PSD6_0, PTV6_FN), + PINMUX_DATA(MSIOF1_RXD_MARK, PSC15_0, PSC14_1, PTV5_FN), + PINMUX_DATA(MSIOF1_TSYNC_MARK, PSC15_0, PSC14_1, PTV4_FN), + PINMUX_DATA(MSIOF1_TSCK_MARK, PSC15_0, PSC14_1, PTV3_FN), + PINMUX_DATA(MSIOF1_TXD_MARK, PSC15_0, PSC14_1, PTV2_FN), + PINMUX_DATA(MSIOF1_MCK_MARK, PSE3_0, PSE2_1, PTV1_FN), + + /* PTW FN */ + PINMUX_DATA(MMC_D7_MARK, PSE13_0, PSE12_0, PTW7_FN), + PINMUX_DATA(MMC_D6_MARK, PSE13_0, PSE12_0, PTW6_FN), + PINMUX_DATA(MMC_D5_MARK, PSE13_0, PSE12_0, PTW5_FN), + PINMUX_DATA(MMC_D4_MARK, PSE13_0, PSE12_0, PTW4_FN), + PINMUX_DATA(MMC_D3_MARK, PSA13_0, PTW3_FN), + PINMUX_DATA(MMC_D2_MARK, PSA13_0, PTW2_FN), + PINMUX_DATA(MMC_D1_MARK, PSA13_0, PTW1_FN), + PINMUX_DATA(MMC_D0_MARK, PSA13_0, PTW0_FN), + + PINMUX_DATA(SDHI1CD_MARK, PSE13_0, PSE12_1, PTW7_FN), + PINMUX_DATA(SDHI1WP_MARK, PSE13_0, PSE12_1, PTW6_FN), + PINMUX_DATA(SDHI1D3_MARK, PSE13_0, PSE12_1, PTW5_FN), + PINMUX_DATA(SDHI1D2_MARK, PSE13_0, PSE12_1, PTW4_FN), + PINMUX_DATA(SDHI1D1_MARK, PSA13_1, PTW3_FN), + PINMUX_DATA(SDHI1D0_MARK, PSA13_1, PTW2_FN), + PINMUX_DATA(SDHI1CMD_MARK, PSA13_1, PTW1_FN), + PINMUX_DATA(SDHI1CLK_MARK, PSA13_1, PTW0_FN), + + PINMUX_DATA(IODACK_MARK, PSE13_1, PSE12_0, PTW7_FN), + PINMUX_DATA(IDERST_MARK, PSE13_1, PSE12_0, PTW6_FN), + PINMUX_DATA(EXBUF_ENB_MARK, PSE13_1, PSE12_0, PTW5_FN), + PINMUX_DATA(DIRECTION_MARK, PSE13_1, PSE12_0, PTW4_FN), + + /* PTX FN */ + PINMUX_DATA(DMAC_DACK1_MARK, PSA12_0, PTX7_FN), + PINMUX_DATA(DMAC_DREQ1_MARK, PSA12_0, PTX6_FN), + + PINMUX_DATA(IRDA_OUT_MARK, PSA12_1, PTX7_FN), + PINMUX_DATA(IRDA_IN_MARK, PSA12_1, PTX6_FN), + + PINMUX_DATA(TSIF_TS0_SDAT_MARK, PSC0_0, PTX5_FN), + PINMUX_DATA(TSIF_TS0_SCK_MARK, PSC1_0, PTX4_FN), + PINMUX_DATA(TSIF_TS0_SDEN_MARK, PSC2_0, PTX3_FN), + PINMUX_DATA(TSIF_TS0_SPSYNC_MARK, PTX2_FN), + + PINMUX_DATA(LNKSTA_MARK, PSC0_1, PTX5_FN), + PINMUX_DATA(MDIO_MARK, PSC1_1, PTX4_FN), + PINMUX_DATA(MDC_MARK, PSC2_1, PTX3_FN), + + PINMUX_DATA(MMC_CLK_MARK, PTX1_FN), + PINMUX_DATA(MMC_CMD_MARK, PTX0_FN), + + /* PTY FN */ + PINMUX_DATA(SDHI0CD_MARK, PTY7_FN), + PINMUX_DATA(SDHI0WP_MARK, PTY6_FN), + PINMUX_DATA(SDHI0D3_MARK, PTY5_FN), + PINMUX_DATA(SDHI0D2_MARK, PTY4_FN), + PINMUX_DATA(SDHI0D1_MARK, PTY3_FN), + PINMUX_DATA(SDHI0D0_MARK, PTY2_FN), + PINMUX_DATA(SDHI0CMD_MARK, PTY1_FN), + PINMUX_DATA(SDHI0CLK_MARK, PTY0_FN), + + /* PTZ FN */ + PINMUX_DATA(INTC_IRQ7_MARK, PSB10_0, PTZ7_FN), + PINMUX_DATA(INTC_IRQ6_MARK, PSB11_0, PTZ6_FN), + PINMUX_DATA(INTC_IRQ5_MARK, PSB12_0, PTZ5_FN), + PINMUX_DATA(INTC_IRQ4_MARK, PSB13_0, PTZ4_FN), + PINMUX_DATA(INTC_IRQ3_MARK, PSB14_0, PTZ3_FN), + PINMUX_DATA(INTC_IRQ2_MARK, PTZ2_FN), + PINMUX_DATA(INTC_IRQ1_MARK, PTZ1_FN), + PINMUX_DATA(INTC_IRQ0_MARK, PTZ0_FN), + + PINMUX_DATA(SCIF3_I_CTS_MARK, PSB10_1, PTZ7_FN), + PINMUX_DATA(SCIF3_I_RTS_MARK, PSB11_1, PTZ6_FN), + PINMUX_DATA(SCIF3_I_SCK_MARK, PSB12_1, PTZ5_FN), + PINMUX_DATA(SCIF3_I_RXD_MARK, PSB13_1, PTZ4_FN), + PINMUX_DATA(SCIF3_I_TXD_MARK, PSB14_1, PTZ3_FN), +}; + +static struct pinmux_gpio pinmux_gpios[] = { + /* PTA */ + PINMUX_GPIO(GPIO_PTA7, PTA7_DATA), + PINMUX_GPIO(GPIO_PTA6, PTA6_DATA), + PINMUX_GPIO(GPIO_PTA5, PTA5_DATA), + PINMUX_GPIO(GPIO_PTA4, PTA4_DATA), + PINMUX_GPIO(GPIO_PTA3, PTA3_DATA), + PINMUX_GPIO(GPIO_PTA2, PTA2_DATA), + PINMUX_GPIO(GPIO_PTA1, PTA1_DATA), + PINMUX_GPIO(GPIO_PTA0, PTA0_DATA), + + /* PTB */ + PINMUX_GPIO(GPIO_PTB7, PTB7_DATA), + PINMUX_GPIO(GPIO_PTB6, PTB6_DATA), + PINMUX_GPIO(GPIO_PTB5, PTB5_DATA), + PINMUX_GPIO(GPIO_PTB4, PTB4_DATA), + PINMUX_GPIO(GPIO_PTB3, PTB3_DATA), + PINMUX_GPIO(GPIO_PTB2, PTB2_DATA), + PINMUX_GPIO(GPIO_PTB1, PTB1_DATA), + PINMUX_GPIO(GPIO_PTB0, PTB0_DATA), + + /* PTC */ + PINMUX_GPIO(GPIO_PTC7, PTC7_DATA), + PINMUX_GPIO(GPIO_PTC6, PTC6_DATA), + PINMUX_GPIO(GPIO_PTC5, PTC5_DATA), + PINMUX_GPIO(GPIO_PTC4, PTC4_DATA), + PINMUX_GPIO(GPIO_PTC3, PTC3_DATA), + PINMUX_GPIO(GPIO_PTC2, PTC2_DATA), + PINMUX_GPIO(GPIO_PTC1, PTC1_DATA), + PINMUX_GPIO(GPIO_PTC0, PTC0_DATA), + + /* PTD */ + PINMUX_GPIO(GPIO_PTD7, PTD7_DATA), + PINMUX_GPIO(GPIO_PTD6, PTD6_DATA), + PINMUX_GPIO(GPIO_PTD5, PTD5_DATA), + PINMUX_GPIO(GPIO_PTD4, PTD4_DATA), + PINMUX_GPIO(GPIO_PTD3, PTD3_DATA), + PINMUX_GPIO(GPIO_PTD2, PTD2_DATA), + PINMUX_GPIO(GPIO_PTD1, PTD1_DATA), + PINMUX_GPIO(GPIO_PTD0, PTD0_DATA), + + /* PTE */ + PINMUX_GPIO(GPIO_PTE7, PTE7_DATA), + PINMUX_GPIO(GPIO_PTE6, PTE6_DATA), + PINMUX_GPIO(GPIO_PTE5, PTE5_DATA), + PINMUX_GPIO(GPIO_PTE4, PTE4_DATA), + PINMUX_GPIO(GPIO_PTE3, PTE3_DATA), + PINMUX_GPIO(GPIO_PTE2, PTE2_DATA), + PINMUX_GPIO(GPIO_PTE1, PTE1_DATA), + PINMUX_GPIO(GPIO_PTE0, PTE0_DATA), + + /* PTF */ + PINMUX_GPIO(GPIO_PTF7, PTF7_DATA), + PINMUX_GPIO(GPIO_PTF6, PTF6_DATA), + PINMUX_GPIO(GPIO_PTF5, PTF5_DATA), + PINMUX_GPIO(GPIO_PTF4, PTF4_DATA), + PINMUX_GPIO(GPIO_PTF3, PTF3_DATA), + PINMUX_GPIO(GPIO_PTF2, PTF2_DATA), + PINMUX_GPIO(GPIO_PTF1, PTF1_DATA), + PINMUX_GPIO(GPIO_PTF0, PTF0_DATA), + + /* PTG */ + PINMUX_GPIO(GPIO_PTG5, PTG5_DATA), + PINMUX_GPIO(GPIO_PTG4, PTG4_DATA), + PINMUX_GPIO(GPIO_PTG3, PTG3_DATA), + PINMUX_GPIO(GPIO_PTG2, PTG2_DATA), + PINMUX_GPIO(GPIO_PTG1, PTG1_DATA), + PINMUX_GPIO(GPIO_PTG0, PTG0_DATA), + + /* PTH */ + PINMUX_GPIO(GPIO_PTH7, PTH7_DATA), + PINMUX_GPIO(GPIO_PTH6, PTH6_DATA), + PINMUX_GPIO(GPIO_PTH5, PTH5_DATA), + PINMUX_GPIO(GPIO_PTH4, PTH4_DATA), + PINMUX_GPIO(GPIO_PTH3, PTH3_DATA), + PINMUX_GPIO(GPIO_PTH2, PTH2_DATA), + PINMUX_GPIO(GPIO_PTH1, PTH1_DATA), + PINMUX_GPIO(GPIO_PTH0, PTH0_DATA), + + /* PTJ */ + PINMUX_GPIO(GPIO_PTJ7, PTJ7_DATA), + PINMUX_GPIO(GPIO_PTJ6, PTJ6_DATA), + PINMUX_GPIO(GPIO_PTJ5, PTJ5_DATA), + PINMUX_GPIO(GPIO_PTJ3, PTJ3_DATA), + PINMUX_GPIO(GPIO_PTJ2, PTJ2_DATA), + PINMUX_GPIO(GPIO_PTJ1, PTJ1_DATA), + PINMUX_GPIO(GPIO_PTJ0, PTJ0_DATA), + + /* PTK */ + PINMUX_GPIO(GPIO_PTK7, PTK7_DATA), + PINMUX_GPIO(GPIO_PTK6, PTK6_DATA), + PINMUX_GPIO(GPIO_PTK5, PTK5_DATA), + PINMUX_GPIO(GPIO_PTK4, PTK4_DATA), + PINMUX_GPIO(GPIO_PTK3, PTK3_DATA), + PINMUX_GPIO(GPIO_PTK2, PTK2_DATA), + PINMUX_GPIO(GPIO_PTK1, PTK1_DATA), + PINMUX_GPIO(GPIO_PTK0, PTK0_DATA), + + /* PTL */ + PINMUX_GPIO(GPIO_PTL7, PTL7_DATA), + PINMUX_GPIO(GPIO_PTL6, PTL6_DATA), + PINMUX_GPIO(GPIO_PTL5, PTL5_DATA), + PINMUX_GPIO(GPIO_PTL4, PTL4_DATA), + PINMUX_GPIO(GPIO_PTL3, PTL3_DATA), + PINMUX_GPIO(GPIO_PTL2, PTL2_DATA), + PINMUX_GPIO(GPIO_PTL1, PTL1_DATA), + PINMUX_GPIO(GPIO_PTL0, PTL0_DATA), + + /* PTM */ + PINMUX_GPIO(GPIO_PTM7, PTM7_DATA), + PINMUX_GPIO(GPIO_PTM6, PTM6_DATA), + PINMUX_GPIO(GPIO_PTM5, PTM5_DATA), + PINMUX_GPIO(GPIO_PTM4, PTM4_DATA), + PINMUX_GPIO(GPIO_PTM3, PTM3_DATA), + PINMUX_GPIO(GPIO_PTM2, PTM2_DATA), + PINMUX_GPIO(GPIO_PTM1, PTM1_DATA), + PINMUX_GPIO(GPIO_PTM0, PTM0_DATA), + + /* PTN */ + PINMUX_GPIO(GPIO_PTN7, PTN7_DATA), + PINMUX_GPIO(GPIO_PTN6, PTN6_DATA), + PINMUX_GPIO(GPIO_PTN5, PTN5_DATA), + PINMUX_GPIO(GPIO_PTN4, PTN4_DATA), + PINMUX_GPIO(GPIO_PTN3, PTN3_DATA), + PINMUX_GPIO(GPIO_PTN2, PTN2_DATA), + PINMUX_GPIO(GPIO_PTN1, PTN1_DATA), + PINMUX_GPIO(GPIO_PTN0, PTN0_DATA), + + /* PTQ */ + PINMUX_GPIO(GPIO_PTQ7, PTQ7_DATA), + PINMUX_GPIO(GPIO_PTQ6, PTQ6_DATA), + PINMUX_GPIO(GPIO_PTQ5, PTQ5_DATA), + PINMUX_GPIO(GPIO_PTQ4, PTQ4_DATA), + PINMUX_GPIO(GPIO_PTQ3, PTQ3_DATA), + PINMUX_GPIO(GPIO_PTQ2, PTQ2_DATA), + PINMUX_GPIO(GPIO_PTQ1, PTQ1_DATA), + PINMUX_GPIO(GPIO_PTQ0, PTQ0_DATA), + + /* PTR */ + PINMUX_GPIO(GPIO_PTR7, PTR7_DATA), + PINMUX_GPIO(GPIO_PTR6, PTR6_DATA), + PINMUX_GPIO(GPIO_PTR5, PTR5_DATA), + PINMUX_GPIO(GPIO_PTR4, PTR4_DATA), + PINMUX_GPIO(GPIO_PTR3, PTR3_DATA), + PINMUX_GPIO(GPIO_PTR2, PTR2_DATA), + PINMUX_GPIO(GPIO_PTR1, PTR1_DATA), + PINMUX_GPIO(GPIO_PTR0, PTR0_DATA), + + /* PTS */ + PINMUX_GPIO(GPIO_PTS6, PTS6_DATA), + PINMUX_GPIO(GPIO_PTS5, PTS5_DATA), + PINMUX_GPIO(GPIO_PTS4, PTS4_DATA), + PINMUX_GPIO(GPIO_PTS3, PTS3_DATA), + PINMUX_GPIO(GPIO_PTS2, PTS2_DATA), + PINMUX_GPIO(GPIO_PTS1, PTS1_DATA), + PINMUX_GPIO(GPIO_PTS0, PTS0_DATA), + + /* PTT */ + PINMUX_GPIO(GPIO_PTT7, PTT7_DATA), + PINMUX_GPIO(GPIO_PTT6, PTT6_DATA), + PINMUX_GPIO(GPIO_PTT5, PTT5_DATA), + PINMUX_GPIO(GPIO_PTT4, PTT4_DATA), + PINMUX_GPIO(GPIO_PTT3, PTT3_DATA), + PINMUX_GPIO(GPIO_PTT2, PTT2_DATA), + PINMUX_GPIO(GPIO_PTT1, PTT1_DATA), + PINMUX_GPIO(GPIO_PTT0, PTT0_DATA), + + /* PTU */ + PINMUX_GPIO(GPIO_PTU7, PTU7_DATA), + PINMUX_GPIO(GPIO_PTU6, PTU6_DATA), + PINMUX_GPIO(GPIO_PTU5, PTU5_DATA), + PINMUX_GPIO(GPIO_PTU4, PTU4_DATA), + PINMUX_GPIO(GPIO_PTU3, PTU3_DATA), + PINMUX_GPIO(GPIO_PTU2, PTU2_DATA), + PINMUX_GPIO(GPIO_PTU1, PTU1_DATA), + PINMUX_GPIO(GPIO_PTU0, PTU0_DATA), + + /* PTV */ + PINMUX_GPIO(GPIO_PTV7, PTV7_DATA), + PINMUX_GPIO(GPIO_PTV6, PTV6_DATA), + PINMUX_GPIO(GPIO_PTV5, PTV5_DATA), + PINMUX_GPIO(GPIO_PTV4, PTV4_DATA), + PINMUX_GPIO(GPIO_PTV3, PTV3_DATA), + PINMUX_GPIO(GPIO_PTV2, PTV2_DATA), + PINMUX_GPIO(GPIO_PTV1, PTV1_DATA), + PINMUX_GPIO(GPIO_PTV0, PTV0_DATA), + + /* PTW */ + PINMUX_GPIO(GPIO_PTW7, PTW7_DATA), + PINMUX_GPIO(GPIO_PTW6, PTW6_DATA), + PINMUX_GPIO(GPIO_PTW5, PTW5_DATA), + PINMUX_GPIO(GPIO_PTW4, PTW4_DATA), + PINMUX_GPIO(GPIO_PTW3, PTW3_DATA), + PINMUX_GPIO(GPIO_PTW2, PTW2_DATA), + PINMUX_GPIO(GPIO_PTW1, PTW1_DATA), + PINMUX_GPIO(GPIO_PTW0, PTW0_DATA), + + /* PTX */ + PINMUX_GPIO(GPIO_PTX7, PTX7_DATA), + PINMUX_GPIO(GPIO_PTX6, PTX6_DATA), + PINMUX_GPIO(GPIO_PTX5, PTX5_DATA), + PINMUX_GPIO(GPIO_PTX4, PTX4_DATA), + PINMUX_GPIO(GPIO_PTX3, PTX3_DATA), + PINMUX_GPIO(GPIO_PTX2, PTX2_DATA), + PINMUX_GPIO(GPIO_PTX1, PTX1_DATA), + PINMUX_GPIO(GPIO_PTX0, PTX0_DATA), + + /* PTY */ + PINMUX_GPIO(GPIO_PTY7, PTY7_DATA), + PINMUX_GPIO(GPIO_PTY6, PTY6_DATA), + PINMUX_GPIO(GPIO_PTY5, PTY5_DATA), + PINMUX_GPIO(GPIO_PTY4, PTY4_DATA), + PINMUX_GPIO(GPIO_PTY3, PTY3_DATA), + PINMUX_GPIO(GPIO_PTY2, PTY2_DATA), + PINMUX_GPIO(GPIO_PTY1, PTY1_DATA), + PINMUX_GPIO(GPIO_PTY0, PTY0_DATA), + + /* PTZ */ + PINMUX_GPIO(GPIO_PTZ7, PTZ7_DATA), + PINMUX_GPIO(GPIO_PTZ6, PTZ6_DATA), + PINMUX_GPIO(GPIO_PTZ5, PTZ5_DATA), + PINMUX_GPIO(GPIO_PTZ4, PTZ4_DATA), + PINMUX_GPIO(GPIO_PTZ3, PTZ3_DATA), + PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA), + PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA), + PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA), + + /* BSC */ + PINMUX_GPIO(GPIO_FN_D31, D31_MARK), + PINMUX_GPIO(GPIO_FN_D30, D30_MARK), + PINMUX_GPIO(GPIO_FN_D29, D29_MARK), + PINMUX_GPIO(GPIO_FN_D28, D28_MARK), + PINMUX_GPIO(GPIO_FN_D27, D27_MARK), + PINMUX_GPIO(GPIO_FN_D26, D26_MARK), + PINMUX_GPIO(GPIO_FN_D25, D25_MARK), + PINMUX_GPIO(GPIO_FN_D24, D24_MARK), + PINMUX_GPIO(GPIO_FN_D23, D23_MARK), + PINMUX_GPIO(GPIO_FN_D22, D22_MARK), + PINMUX_GPIO(GPIO_FN_D21, D21_MARK), + PINMUX_GPIO(GPIO_FN_D20, D20_MARK), + PINMUX_GPIO(GPIO_FN_D19, D19_MARK), + PINMUX_GPIO(GPIO_FN_D18, D18_MARK), + PINMUX_GPIO(GPIO_FN_D17, D17_MARK), + PINMUX_GPIO(GPIO_FN_D16, D16_MARK), + PINMUX_GPIO(GPIO_FN_D15, D15_MARK), + PINMUX_GPIO(GPIO_FN_D14, D14_MARK), + PINMUX_GPIO(GPIO_FN_D13, D13_MARK), + PINMUX_GPIO(GPIO_FN_D12, D12_MARK), + PINMUX_GPIO(GPIO_FN_D11, D11_MARK), + PINMUX_GPIO(GPIO_FN_D10, D10_MARK), + PINMUX_GPIO(GPIO_FN_D9, D9_MARK), + PINMUX_GPIO(GPIO_FN_D8, D8_MARK), + PINMUX_GPIO(GPIO_FN_D7, D7_MARK), + PINMUX_GPIO(GPIO_FN_D6, D6_MARK), + PINMUX_GPIO(GPIO_FN_D5, D5_MARK), + PINMUX_GPIO(GPIO_FN_D4, D4_MARK), + PINMUX_GPIO(GPIO_FN_D3, D3_MARK), + PINMUX_GPIO(GPIO_FN_D2, D2_MARK), + PINMUX_GPIO(GPIO_FN_D1, D1_MARK), + PINMUX_GPIO(GPIO_FN_D0, D0_MARK), + PINMUX_GPIO(GPIO_FN_A25, A25_MARK), + PINMUX_GPIO(GPIO_FN_A24, A24_MARK), + PINMUX_GPIO(GPIO_FN_A23, A23_MARK), + PINMUX_GPIO(GPIO_FN_A22, A22_MARK), + PINMUX_GPIO(GPIO_FN_CS6B_CE1B, CS6B_CE1B_MARK), + PINMUX_GPIO(GPIO_FN_CS6A_CE2B, CS6A_CE2B_MARK), + PINMUX_GPIO(GPIO_FN_CS5B_CE1A, CS5B_CE1A_MARK), + PINMUX_GPIO(GPIO_FN_CS5A_CE2A, CS5A_CE2A_MARK), + PINMUX_GPIO(GPIO_FN_WE3_ICIOWR, WE3_ICIOWR_MARK), + PINMUX_GPIO(GPIO_FN_WE2_ICIORD, WE2_ICIORD_MARK), + PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK), + PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK), + PINMUX_GPIO(GPIO_FN_BS, BS_MARK), + + /* KEYSC */ + PINMUX_GPIO(GPIO_FN_KEYOUT5_IN5, KEYOUT5_IN5_MARK), + PINMUX_GPIO(GPIO_FN_KEYOUT4_IN6, KEYOUT4_IN6_MARK), + PINMUX_GPIO(GPIO_FN_KEYIN4, KEYIN4_MARK), + PINMUX_GPIO(GPIO_FN_KEYIN3, KEYIN3_MARK), + PINMUX_GPIO(GPIO_FN_KEYIN2, KEYIN2_MARK), + PINMUX_GPIO(GPIO_FN_KEYIN1, KEYIN1_MARK), + PINMUX_GPIO(GPIO_FN_KEYIN0, KEYIN0_MARK), + PINMUX_GPIO(GPIO_FN_KEYOUT3, KEYOUT3_MARK), + PINMUX_GPIO(GPIO_FN_KEYOUT2, KEYOUT2_MARK), + PINMUX_GPIO(GPIO_FN_KEYOUT1, KEYOUT1_MARK), + PINMUX_GPIO(GPIO_FN_KEYOUT0, KEYOUT0_MARK), + + /* ATAPI */ + PINMUX_GPIO(GPIO_FN_IDED15, IDED15_MARK), + PINMUX_GPIO(GPIO_FN_IDED14, IDED14_MARK), + PINMUX_GPIO(GPIO_FN_IDED13, IDED13_MARK), + PINMUX_GPIO(GPIO_FN_IDED12, IDED12_MARK), + PINMUX_GPIO(GPIO_FN_IDED11, IDED11_MARK), + PINMUX_GPIO(GPIO_FN_IDED10, IDED10_MARK), + PINMUX_GPIO(GPIO_FN_IDED9, IDED9_MARK), + PINMUX_GPIO(GPIO_FN_IDED8, IDED8_MARK), + PINMUX_GPIO(GPIO_FN_IDED7, IDED7_MARK), + PINMUX_GPIO(GPIO_FN_IDED6, IDED6_MARK), + PINMUX_GPIO(GPIO_FN_IDED5, IDED5_MARK), + PINMUX_GPIO(GPIO_FN_IDED4, IDED4_MARK), + PINMUX_GPIO(GPIO_FN_IDED3, IDED3_MARK), + PINMUX_GPIO(GPIO_FN_IDED2, IDED2_MARK), + PINMUX_GPIO(GPIO_FN_IDED1, IDED1_MARK), + PINMUX_GPIO(GPIO_FN_IDED0, IDED0_MARK), + PINMUX_GPIO(GPIO_FN_IDEA2, IDEA2_MARK), + PINMUX_GPIO(GPIO_FN_IDEA1, IDEA1_MARK), + PINMUX_GPIO(GPIO_FN_IDEA0, IDEA0_MARK), + PINMUX_GPIO(GPIO_FN_IDEIOWR, IDEIOWR_MARK), + PINMUX_GPIO(GPIO_FN_IODREQ, IODREQ_MARK), + PINMUX_GPIO(GPIO_FN_IDECS0, IDECS0_MARK), + PINMUX_GPIO(GPIO_FN_IDECS1, IDECS1_MARK), + PINMUX_GPIO(GPIO_FN_IDEIORD, IDEIORD_MARK), + PINMUX_GPIO(GPIO_FN_DIRECTION, DIRECTION_MARK), + PINMUX_GPIO(GPIO_FN_EXBUF_ENB, EXBUF_ENB_MARK), + PINMUX_GPIO(GPIO_FN_IDERST, IDERST_MARK), + PINMUX_GPIO(GPIO_FN_IODACK, IODACK_MARK), + PINMUX_GPIO(GPIO_FN_IDEINT, IDEINT_MARK), + PINMUX_GPIO(GPIO_FN_IDEIORDY, IDEIORDY_MARK), + + /* TPU */ + PINMUX_GPIO(GPIO_FN_TPUTO3, TPUTO3_MARK), + PINMUX_GPIO(GPIO_FN_TPUTO2, TPUTO2_MARK), + PINMUX_GPIO(GPIO_FN_TPUTO1, TPUTO1_MARK), + PINMUX_GPIO(GPIO_FN_TPUTO0, TPUTO0_MARK), + PINMUX_GPIO(GPIO_FN_TPUTI3, TPUTI3_MARK), + PINMUX_GPIO(GPIO_FN_TPUTI2, TPUTI2_MARK), + + /* LCDC */ + PINMUX_GPIO(GPIO_FN_LCDD23, LCDD23_MARK), + PINMUX_GPIO(GPIO_FN_LCDD22, LCDD22_MARK), + PINMUX_GPIO(GPIO_FN_LCDD21, LCDD21_MARK), + PINMUX_GPIO(GPIO_FN_LCDD20, LCDD20_MARK), + PINMUX_GPIO(GPIO_FN_LCDD19, LCDD19_MARK), + PINMUX_GPIO(GPIO_FN_LCDD18, LCDD18_MARK), + PINMUX_GPIO(GPIO_FN_LCDD17, LCDD17_MARK), + PINMUX_GPIO(GPIO_FN_LCDD16, LCDD16_MARK), + PINMUX_GPIO(GPIO_FN_LCDD15, LCDD15_MARK), + PINMUX_GPIO(GPIO_FN_LCDD14, LCDD14_MARK), + PINMUX_GPIO(GPIO_FN_LCDD13, LCDD13_MARK), + PINMUX_GPIO(GPIO_FN_LCDD12, LCDD12_MARK), + PINMUX_GPIO(GPIO_FN_LCDD11, LCDD11_MARK), + PINMUX_GPIO(GPIO_FN_LCDD10, LCDD10_MARK), + PINMUX_GPIO(GPIO_FN_LCDD9, LCDD9_MARK), + PINMUX_GPIO(GPIO_FN_LCDD8, LCDD8_MARK), + PINMUX_GPIO(GPIO_FN_LCDD7, LCDD7_MARK), + PINMUX_GPIO(GPIO_FN_LCDD6, LCDD6_MARK), + PINMUX_GPIO(GPIO_FN_LCDD5, LCDD5_MARK), + PINMUX_GPIO(GPIO_FN_LCDD4, LCDD4_MARK), + PINMUX_GPIO(GPIO_FN_LCDD3, LCDD3_MARK), + PINMUX_GPIO(GPIO_FN_LCDD2, LCDD2_MARK), + PINMUX_GPIO(GPIO_FN_LCDD1, LCDD1_MARK), + PINMUX_GPIO(GPIO_FN_LCDD0, LCDD0_MARK), + PINMUX_GPIO(GPIO_FN_LCDVSYN, LCDVSYN_MARK), + PINMUX_GPIO(GPIO_FN_LCDDISP, LCDDISP_MARK), + PINMUX_GPIO(GPIO_FN_LCDRS, LCDRS_MARK), + PINMUX_GPIO(GPIO_FN_LCDHSYN, LCDHSYN_MARK), + PINMUX_GPIO(GPIO_FN_LCDCS, LCDCS_MARK), + PINMUX_GPIO(GPIO_FN_LCDDON, LCDDON_MARK), + PINMUX_GPIO(GPIO_FN_LCDDCK, LCDDCK_MARK), + PINMUX_GPIO(GPIO_FN_LCDWR, LCDWR_MARK), + PINMUX_GPIO(GPIO_FN_LCDVEPWC, LCDVEPWC_MARK), + PINMUX_GPIO(GPIO_FN_LCDVCPWC, LCDVCPWC_MARK), + PINMUX_GPIO(GPIO_FN_LCDRD, LCDRD_MARK), + PINMUX_GPIO(GPIO_FN_LCDLCLK, LCDLCLK_MARK), + + /* SCIF0 */ + PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK), + + /* SCIF1 */ + PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK), + PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK), + + /* SCIF2 */ + PINMUX_GPIO(GPIO_FN_SCIF2_L_TXD, SCIF2_L_TXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF2_L_SCK, SCIF2_L_SCK_MARK), + PINMUX_GPIO(GPIO_FN_SCIF2_L_RXD, SCIF2_L_RXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF2_V_TXD, SCIF2_V_TXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF2_V_SCK, SCIF2_V_SCK_MARK), + PINMUX_GPIO(GPIO_FN_SCIF2_V_RXD, SCIF2_V_RXD_MARK), + + /* SCIF3 */ + PINMUX_GPIO(GPIO_FN_SCIF3_V_SCK, SCIF3_V_SCK_MARK), + PINMUX_GPIO(GPIO_FN_SCIF3_V_RXD, SCIF3_V_RXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF3_V_TXD, SCIF3_V_TXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF3_V_CTS, SCIF3_V_CTS_MARK), + PINMUX_GPIO(GPIO_FN_SCIF3_V_RTS, SCIF3_V_RTS_MARK), + PINMUX_GPIO(GPIO_FN_SCIF3_I_SCK, SCIF3_I_SCK_MARK), + PINMUX_GPIO(GPIO_FN_SCIF3_I_RXD, SCIF3_I_RXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF3_I_TXD, SCIF3_I_TXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF3_I_CTS, SCIF3_I_CTS_MARK), + PINMUX_GPIO(GPIO_FN_SCIF3_I_RTS, SCIF3_I_RTS_MARK), + + /* SCIF4 */ + PINMUX_GPIO(GPIO_FN_SCIF4_SCK, SCIF4_SCK_MARK), + PINMUX_GPIO(GPIO_FN_SCIF4_RXD, SCIF4_RXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF4_TXD, SCIF4_TXD_MARK), + + /* SCIF5 */ + PINMUX_GPIO(GPIO_FN_SCIF5_SCK, SCIF5_SCK_MARK), + PINMUX_GPIO(GPIO_FN_SCIF5_RXD, SCIF5_RXD_MARK), + PINMUX_GPIO(GPIO_FN_SCIF5_TXD, SCIF5_TXD_MARK), + + /* FSI */ + PINMUX_GPIO(GPIO_FN_FSIMCKB, FSIMCKB_MARK), + PINMUX_GPIO(GPIO_FN_FSIMCKA, FSIMCKA_MARK), + PINMUX_GPIO(GPIO_FN_FSIOASD, FSIOASD_MARK), + PINMUX_GPIO(GPIO_FN_FSIIABCK, FSIIABCK_MARK), + PINMUX_GPIO(GPIO_FN_FSIIALRCK, FSIIALRCK_MARK), + PINMUX_GPIO(GPIO_FN_FSIOABCK, FSIOABCK_MARK), + PINMUX_GPIO(GPIO_FN_FSIOALRCK, FSIOALRCK_MARK), + PINMUX_GPIO(GPIO_FN_CLKAUDIOAO, CLKAUDIOAO_MARK), + PINMUX_GPIO(GPIO_FN_FSIIBSD, FSIIBSD_MARK), + PINMUX_GPIO(GPIO_FN_FSIOBSD, FSIOBSD_MARK), + PINMUX_GPIO(GPIO_FN_FSIIBBCK, FSIIBBCK_MARK), + PINMUX_GPIO(GPIO_FN_FSIIBLRCK, FSIIBLRCK_MARK), + PINMUX_GPIO(GPIO_FN_FSIOBBCK, FSIOBBCK_MARK), + PINMUX_GPIO(GPIO_FN_FSIOBLRCK, FSIOBLRCK_MARK), + PINMUX_GPIO(GPIO_FN_CLKAUDIOBO, CLKAUDIOBO_MARK), + PINMUX_GPIO(GPIO_FN_FSIIASD, FSIIASD_MARK), + + /* AUD */ + PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK), + PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK), + PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK), + PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK), + PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK), + PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK), + + /* VIO */ + PINMUX_GPIO(GPIO_FN_VIO_CKO, VIO_CKO_MARK), + + /* VIO0 */ + PINMUX_GPIO(GPIO_FN_VIO0_D15, VIO0_D15_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D14, VIO0_D14_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D13, VIO0_D13_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D12, VIO0_D12_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D11, VIO0_D11_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D10, VIO0_D10_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D9, VIO0_D9_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D8, VIO0_D8_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D7, VIO0_D7_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D6, VIO0_D6_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D5, VIO0_D5_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D4, VIO0_D4_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D3, VIO0_D3_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D2, VIO0_D2_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D1, VIO0_D1_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_D0, VIO0_D0_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_VD, VIO0_VD_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_CLK, VIO0_CLK_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_FLD, VIO0_FLD_MARK), + PINMUX_GPIO(GPIO_FN_VIO0_HD, VIO0_HD_MARK), + + /* VIO1 */ + PINMUX_GPIO(GPIO_FN_VIO1_D7, VIO1_D7_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_D6, VIO1_D6_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_D5, VIO1_D5_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_D4, VIO1_D4_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_D3, VIO1_D3_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_D2, VIO1_D2_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_D1, VIO1_D1_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_D0, VIO1_D0_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_FLD, VIO1_FLD_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_HD, VIO1_HD_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_VD, VIO1_VD_MARK), + PINMUX_GPIO(GPIO_FN_VIO1_CLK, VIO1_CLK_MARK), + + /* Eth */ + PINMUX_GPIO(GPIO_FN_RMII_RXD0, RMII_RXD0_MARK), + PINMUX_GPIO(GPIO_FN_RMII_RXD1, RMII_RXD1_MARK), + PINMUX_GPIO(GPIO_FN_RMII_TXD0, RMII_TXD0_MARK), + PINMUX_GPIO(GPIO_FN_RMII_TXD1, RMII_TXD1_MARK), + PINMUX_GPIO(GPIO_FN_RMII_REF_CLK, RMII_REF_CLK_MARK), + PINMUX_GPIO(GPIO_FN_RMII_TX_EN, RMII_TX_EN_MARK), + PINMUX_GPIO(GPIO_FN_RMII_RX_ER, RMII_RX_ER_MARK), + PINMUX_GPIO(GPIO_FN_RMII_CRS_DV, RMII_CRS_DV_MARK), + PINMUX_GPIO(GPIO_FN_LNKSTA, LNKSTA_MARK), + PINMUX_GPIO(GPIO_FN_MDIO, MDIO_MARK), + PINMUX_GPIO(GPIO_FN_MDC, MDC_MARK), + + /* System */ + PINMUX_GPIO(GPIO_FN_PDSTATUS, PDSTATUS_MARK), + PINMUX_GPIO(GPIO_FN_STATUS2, STATUS2_MARK), + PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK), + + /* VOU */ + PINMUX_GPIO(GPIO_FN_DV_D15, DV_D15_MARK), + PINMUX_GPIO(GPIO_FN_DV_D14, DV_D14_MARK), + PINMUX_GPIO(GPIO_FN_DV_D13, DV_D13_MARK), + PINMUX_GPIO(GPIO_FN_DV_D12, DV_D12_MARK), + PINMUX_GPIO(GPIO_FN_DV_D11, DV_D11_MARK), + PINMUX_GPIO(GPIO_FN_DV_D10, DV_D10_MARK), + PINMUX_GPIO(GPIO_FN_DV_D9, DV_D9_MARK), + PINMUX_GPIO(GPIO_FN_DV_D8, DV_D8_MARK), + PINMUX_GPIO(GPIO_FN_DV_D7, DV_D7_MARK), + PINMUX_GPIO(GPIO_FN_DV_D6, DV_D6_MARK), + PINMUX_GPIO(GPIO_FN_DV_D5, DV_D5_MARK), + PINMUX_GPIO(GPIO_FN_DV_D4, DV_D4_MARK), + PINMUX_GPIO(GPIO_FN_DV_D3, DV_D3_MARK), + PINMUX_GPIO(GPIO_FN_DV_D2, DV_D2_MARK), + PINMUX_GPIO(GPIO_FN_DV_D1, DV_D1_MARK), + PINMUX_GPIO(GPIO_FN_DV_D0, DV_D0_MARK), + PINMUX_GPIO(GPIO_FN_DV_CLKI, DV_CLKI_MARK), + PINMUX_GPIO(GPIO_FN_DV_CLK, DV_CLK_MARK), + PINMUX_GPIO(GPIO_FN_DV_VSYNC, DV_VSYNC_MARK), + PINMUX_GPIO(GPIO_FN_DV_HSYNC, DV_HSYNC_MARK), + + /* MSIOF0 */ + PINMUX_GPIO(GPIO_FN_MSIOF0_RXD, MSIOF0_RXD_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF0_TXD, MSIOF0_TXD_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF0_MCK, MSIOF0_MCK_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF0_TSCK, MSIOF0_TSCK_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF0_SS1, MSIOF0_SS1_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF0_SS2, MSIOF0_SS2_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF0_TSYNC, MSIOF0_TSYNC_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF0_RSCK, MSIOF0_RSCK_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF0_RSYNC, MSIOF0_RSYNC_MARK), + + /* MSIOF1 */ + PINMUX_GPIO(GPIO_FN_MSIOF1_RXD, MSIOF1_RXD_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF1_TXD, MSIOF1_TXD_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF1_MCK, MSIOF1_MCK_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF1_TSCK, MSIOF1_TSCK_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF1_SS1, MSIOF1_SS1_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF1_SS2, MSIOF1_SS2_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF1_TSYNC, MSIOF1_TSYNC_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF1_RSCK, MSIOF1_RSCK_MARK), + PINMUX_GPIO(GPIO_FN_MSIOF1_RSYNC, MSIOF1_RSYNC_MARK), + + /* DMAC */ + PINMUX_GPIO(GPIO_FN_DMAC_DACK0, DMAC_DACK0_MARK), + PINMUX_GPIO(GPIO_FN_DMAC_DREQ0, DMAC_DREQ0_MARK), + PINMUX_GPIO(GPIO_FN_DMAC_DACK1, DMAC_DACK1_MARK), + PINMUX_GPIO(GPIO_FN_DMAC_DREQ1, DMAC_DREQ1_MARK), + + /* SDHI0 */ + PINMUX_GPIO(GPIO_FN_SDHI0CD, SDHI0CD_MARK), + PINMUX_GPIO(GPIO_FN_SDHI0WP, SDHI0WP_MARK), + PINMUX_GPIO(GPIO_FN_SDHI0CMD, SDHI0CMD_MARK), + PINMUX_GPIO(GPIO_FN_SDHI0CLK, SDHI0CLK_MARK), + PINMUX_GPIO(GPIO_FN_SDHI0D3, SDHI0D3_MARK), + PINMUX_GPIO(GPIO_FN_SDHI0D2, SDHI0D2_MARK), + PINMUX_GPIO(GPIO_FN_SDHI0D1, SDHI0D1_MARK), + PINMUX_GPIO(GPIO_FN_SDHI0D0, SDHI0D0_MARK), + + /* SDHI1 */ + PINMUX_GPIO(GPIO_FN_SDHI1CD, SDHI1CD_MARK), + PINMUX_GPIO(GPIO_FN_SDHI1WP, SDHI1WP_MARK), + PINMUX_GPIO(GPIO_FN_SDHI1CMD, SDHI1CMD_MARK), + PINMUX_GPIO(GPIO_FN_SDHI1CLK, SDHI1CLK_MARK), + PINMUX_GPIO(GPIO_FN_SDHI1D3, SDHI1D3_MARK), + PINMUX_GPIO(GPIO_FN_SDHI1D2, SDHI1D2_MARK), + PINMUX_GPIO(GPIO_FN_SDHI1D1, SDHI1D1_MARK), + PINMUX_GPIO(GPIO_FN_SDHI1D0, SDHI1D0_MARK), + + /* MMC */ + PINMUX_GPIO(GPIO_FN_MMC_D7, MMC_D7_MARK), + PINMUX_GPIO(GPIO_FN_MMC_D6, MMC_D6_MARK), + PINMUX_GPIO(GPIO_FN_MMC_D5, MMC_D5_MARK), + PINMUX_GPIO(GPIO_FN_MMC_D4, MMC_D4_MARK), + PINMUX_GPIO(GPIO_FN_MMC_D3, MMC_D3_MARK), + PINMUX_GPIO(GPIO_FN_MMC_D2, MMC_D2_MARK), + PINMUX_GPIO(GPIO_FN_MMC_D1, MMC_D1_MARK), + PINMUX_GPIO(GPIO_FN_MMC_D0, MMC_D0_MARK), + PINMUX_GPIO(GPIO_FN_MMC_CLK, MMC_CLK_MARK), + PINMUX_GPIO(GPIO_FN_MMC_CMD, MMC_CMD_MARK), + + /* IrDA */ + PINMUX_GPIO(GPIO_FN_IRDA_OUT, IRDA_OUT_MARK), + PINMUX_GPIO(GPIO_FN_IRDA_IN, IRDA_IN_MARK), + + /* TSIF */ + PINMUX_GPIO(GPIO_FN_TSIF_TS0_SDAT, TSIF_TS0_SDAT_MARK), + PINMUX_GPIO(GPIO_FN_TSIF_TS0_SCK, TSIF_TS0_SCK_MARK), + PINMUX_GPIO(GPIO_FN_TSIF_TS0_SDEN, TSIF_TS0_SDEN_MARK), + PINMUX_GPIO(GPIO_FN_TSIF_TS0_SPSYNC, TSIF_TS0_SPSYNC_MARK), + + /* IRQ */ + PINMUX_GPIO(GPIO_FN_INTC_IRQ7, INTC_IRQ7_MARK), + PINMUX_GPIO(GPIO_FN_INTC_IRQ6, INTC_IRQ6_MARK), + PINMUX_GPIO(GPIO_FN_INTC_IRQ5, INTC_IRQ5_MARK), + PINMUX_GPIO(GPIO_FN_INTC_IRQ4, INTC_IRQ4_MARK), + PINMUX_GPIO(GPIO_FN_INTC_IRQ3, INTC_IRQ3_MARK), + PINMUX_GPIO(GPIO_FN_INTC_IRQ2, INTC_IRQ2_MARK), + PINMUX_GPIO(GPIO_FN_INTC_IRQ1, INTC_IRQ1_MARK), + PINMUX_GPIO(GPIO_FN_INTC_IRQ0, INTC_IRQ0_MARK), + }; + +static struct pinmux_cfg_reg pinmux_config_regs[] = { + { PINMUX_CFG_REG("PACR", 0xa4050100, 16, 2) { + PTA7_FN, PTA7_OUT, PTA7_IN_PU, PTA7_IN, + PTA6_FN, PTA6_OUT, PTA6_IN_PU, PTA6_IN, + PTA5_FN, PTA5_OUT, PTA5_IN_PU, PTA5_IN, + PTA4_FN, PTA4_OUT, PTA4_IN_PU, PTA4_IN, + PTA3_FN, PTA3_OUT, PTA3_IN_PU, PTA3_IN, + PTA2_FN, PTA2_OUT, PTA2_IN_PU, PTA2_IN, + PTA1_FN, PTA1_OUT, PTA1_IN_PU, PTA1_IN, + PTA0_FN, PTA0_OUT, PTA0_IN_PU, PTA0_IN } + }, + { PINMUX_CFG_REG("PBCR", 0xa4050102, 16, 2) { + PTB7_FN, PTB7_OUT, PTB7_IN_PU, PTB7_IN, + PTB6_FN, PTB6_OUT, PTB6_IN_PU, PTB6_IN, + PTB5_FN, PTB5_OUT, PTB5_IN_PU, PTB5_IN, + PTB4_FN, PTB4_OUT, PTB4_IN_PU, PTB4_IN, + PTB3_FN, PTB3_OUT, PTB3_IN_PU, PTB3_IN, + PTB2_FN, PTB2_OUT, PTB2_IN_PU, PTB2_IN, + PTB1_FN, PTB1_OUT, PTB1_IN_PU, PTB1_IN, + PTB0_FN, PTB0_OUT, PTB0_IN_PU, PTB0_IN } + }, + { PINMUX_CFG_REG("PCCR", 0xa4050104, 16, 2) { + PTC7_FN, PTC7_OUT, PTC7_IN_PU, PTC7_IN, + PTC6_FN, PTC6_OUT, PTC6_IN_PU, PTC6_IN, + PTC5_FN, PTC5_OUT, PTC5_IN_PU, PTC5_IN, + PTC4_FN, PTC4_OUT, PTC4_IN_PU, PTC4_IN, + PTC3_FN, PTC3_OUT, PTC3_IN_PU, PTC3_IN, + PTC2_FN, PTC2_OUT, PTC2_IN_PU, PTC2_IN, + PTC1_FN, PTC1_OUT, PTC1_IN_PU, PTC1_IN, + PTC0_FN, PTC0_OUT, PTC0_IN_PU, PTC0_IN } + }, + { PINMUX_CFG_REG("PDCR", 0xa4050106, 16, 2) { + PTD7_FN, PTD7_OUT, PTD7_IN_PU, PTD7_IN, + PTD6_FN, PTD6_OUT, PTD6_IN_PU, PTD6_IN, + PTD5_FN, PTD5_OUT, PTD5_IN_PU, PTD5_IN, + PTD4_FN, PTD4_OUT, PTD4_IN_PU, PTD4_IN, + PTD3_FN, PTD3_OUT, PTD3_IN_PU, PTD3_IN, + PTD2_FN, PTD2_OUT, PTD2_IN_PU, PTD2_IN, + PTD1_FN, PTD1_OUT, PTD1_IN_PU, PTD1_IN, + PTD0_FN, PTD0_OUT, PTD0_IN_PU, PTD0_IN } + }, + { PINMUX_CFG_REG("PECR", 0xa4050108, 16, 2) { + PTE7_FN, PTE7_OUT, PTE7_IN_PU, PTE7_IN, + PTE6_FN, PTE6_OUT, PTE6_IN_PU, PTE6_IN, + PTE5_FN, PTE5_OUT, PTE5_IN_PU, PTE5_IN, + PTE4_FN, PTE4_OUT, PTE4_IN_PU, PTE4_IN, + PTE3_FN, PTE3_OUT, PTE3_IN_PU, PTE3_IN, + PTE2_FN, PTE2_OUT, PTE2_IN_PU, PTE2_IN, + PTE1_FN, PTE1_OUT, PTE1_IN_PU, PTE1_IN, + PTE0_FN, PTE0_OUT, PTE0_IN_PU, PTE0_IN } + }, + { PINMUX_CFG_REG("PFCR", 0xa405010a, 16, 2) { + PTF7_FN, PTF7_OUT, PTF7_IN_PU, PTF7_IN, + PTF6_FN, PTF6_OUT, PTF6_IN_PU, PTF6_IN, + PTF5_FN, PTF5_OUT, PTF5_IN_PU, PTF5_IN, + PTF4_FN, PTF4_OUT, PTF4_IN_PU, PTF4_IN, + PTF3_FN, PTF3_OUT, PTF3_IN_PU, PTF3_IN, + PTF2_FN, PTF2_OUT, PTF2_IN_PU, PTF2_IN, + PTF1_FN, PTF1_OUT, PTF1_IN_PU, PTF1_IN, + PTF0_FN, PTF0_OUT, PTF0_IN_PU, PTF0_IN } + }, + { PINMUX_CFG_REG("PGCR", 0xa405010c, 16, 2) { + 0, 0, 0, 0, + 0, 0, 0, 0, + PTG5_FN, PTG5_OUT, 0, 0, + PTG4_FN, PTG4_OUT, 0, 0, + PTG3_FN, PTG3_OUT, 0, 0, + PTG2_FN, PTG2_OUT, 0, 0, + PTG1_FN, PTG1_OUT, 0, 0, + PTG0_FN, PTG0_OUT, 0, 0 } + }, + { PINMUX_CFG_REG("PHCR", 0xa405010e, 16, 2) { + PTH7_FN, PTH7_OUT, PTH7_IN_PU, PTH7_IN, + PTH6_FN, PTH6_OUT, PTH6_IN_PU, PTH6_IN, + PTH5_FN, PTH5_OUT, PTH5_IN_PU, PTH5_IN, + PTH4_FN, PTH4_OUT, PTH4_IN_PU, PTH4_IN, + PTH3_FN, PTH3_OUT, PTH3_IN_PU, PTH3_IN, + PTH2_FN, PTH2_OUT, PTH2_IN_PU, PTH2_IN, + PTH1_FN, PTH1_OUT, PTH1_IN_PU, PTH1_IN, + PTH0_FN, PTH0_OUT, PTH0_IN_PU, PTH0_IN } + }, + { PINMUX_CFG_REG("PJCR", 0xa4050110, 16, 2) { + PTJ7_FN, PTJ7_OUT, 0, 0, + PTJ6_FN, PTJ6_OUT, 0, 0, + PTJ5_FN, PTJ5_OUT, 0, 0, + 0, 0, 0, 0, + PTJ3_FN, PTJ3_OUT, PTJ3_IN_PU, PTJ3_IN, + PTJ2_FN, PTJ2_OUT, PTJ2_IN_PU, PTJ2_IN, + PTJ1_FN, PTJ1_OUT, PTJ1_IN_PU, PTJ1_IN, + PTJ0_FN, PTJ0_OUT, PTJ0_IN_PU, PTJ0_IN } + }, + { PINMUX_CFG_REG("PKCR", 0xa4050112, 16, 2) { + PTK7_FN, PTK7_OUT, PTK7_IN_PU, PTK7_IN, + PTK6_FN, PTK6_OUT, PTK6_IN_PU, PTK6_IN, + PTK5_FN, PTK5_OUT, PTK5_IN_PU, PTK5_IN, + PTK4_FN, PTK4_OUT, PTK4_IN_PU, PTK4_IN, + PTK3_FN, PTK3_OUT, PTK3_IN_PU, PTK3_IN, + PTK2_FN, PTK2_OUT, PTK2_IN_PU, PTK2_IN, + PTK1_FN, PTK1_OUT, PTK1_IN_PU, PTK1_IN, + PTK0_FN, PTK0_OUT, PTK0_IN_PU, PTK0_IN } + }, + { PINMUX_CFG_REG("PLCR", 0xa4050114, 16, 2) { + PTL7_FN, PTL7_OUT, PTL7_IN_PU, PTL7_IN, + PTL6_FN, PTL6_OUT, PTL6_IN_PU, PTL6_IN, + PTL5_FN, PTL5_OUT, PTL5_IN_PU, PTL5_IN, + PTL4_FN, PTL4_OUT, PTL4_IN_PU, PTL4_IN, + PTL3_FN, PTL3_OUT, PTL3_IN_PU, PTL3_IN, + PTL2_FN, PTL2_OUT, PTL2_IN_PU, PTL2_IN, + PTL1_FN, PTL1_OUT, PTL1_IN_PU, PTL1_IN, + PTL0_FN, PTL0_OUT, PTL0_IN_PU, PTL0_IN } + }, + { PINMUX_CFG_REG("PMCR", 0xa4050116, 16, 2) { + PTM7_FN, PTM7_OUT, PTM7_IN_PU, PTM7_IN, + PTM6_FN, PTM6_OUT, PTM6_IN_PU, PTM6_IN, + PTM5_FN, PTM5_OUT, PTM5_IN_PU, PTM5_IN, + PTM4_FN, PTM4_OUT, PTM4_IN_PU, PTM4_IN, + PTM3_FN, PTM3_OUT, PTM3_IN_PU, PTM3_IN, + PTM2_FN, PTM2_OUT, PTM2_IN_PU, PTM2_IN, + PTM1_FN, PTM1_OUT, PTM1_IN_PU, PTM1_IN, + PTM0_FN, PTM0_OUT, PTM0_IN_PU, PTM0_IN } + }, + { PINMUX_CFG_REG("PNCR", 0xa4050118, 16, 2) { + PTN7_FN, PTN7_OUT, PTN7_IN_PU, PTN7_IN, + PTN6_FN, PTN6_OUT, PTN6_IN_PU, PTN6_IN, + PTN5_FN, PTN5_OUT, PTN5_IN_PU, PTN5_IN, + PTN4_FN, PTN4_OUT, PTN4_IN_PU, PTN4_IN, + PTN3_FN, PTN3_OUT, PTN3_IN_PU, PTN3_IN, + PTN2_FN, PTN2_OUT, PTN2_IN_PU, PTN2_IN, + PTN1_FN, PTN1_OUT, PTN1_IN_PU, PTN1_IN, + PTN0_FN, PTN0_OUT, PTN0_IN_PU, PTN0_IN } + }, + { PINMUX_CFG_REG("PQCR", 0xa405011a, 16, 2) { + PTQ7_FN, PTQ7_OUT, PTQ7_IN_PU, PTQ7_IN, + PTQ6_FN, PTQ6_OUT, PTQ6_IN_PU, PTQ6_IN, + PTQ5_FN, PTQ5_OUT, PTQ5_IN_PU, PTQ5_IN, + PTQ4_FN, PTQ4_OUT, PTQ4_IN_PU, PTQ4_IN, + PTQ3_FN, PTQ3_OUT, PTQ3_IN_PU, PTQ3_IN, + PTQ2_FN, PTQ2_OUT, PTQ2_IN_PU, PTQ2_IN, + PTQ1_FN, PTQ1_OUT, PTQ1_IN_PU, PTQ1_IN, + PTQ0_FN, PTQ0_OUT, PTQ0_IN_PU, PTQ0_IN } + }, + { PINMUX_CFG_REG("PRCR", 0xa405011c, 16, 2) { + PTR7_FN, PTR7_OUT, PTR7_IN_PU, PTR7_IN, + PTR6_FN, PTR6_OUT, PTR6_IN_PU, PTR6_IN, + PTR5_FN, PTR5_OUT, PTR5_IN_PU, PTR5_IN, + PTR4_FN, PTR4_OUT, PTR4_IN_PU, PTR4_IN, + PTR3_FN, 0, PTR3_IN_PU, PTR3_IN, + PTR2_FN, 0, PTR2_IN_PU, PTR2_IN, + PTR1_FN, PTR1_OUT, PTR1_IN_PU, PTR1_IN, + PTR0_FN, PTR0_OUT, PTR0_IN_PU, PTR0_IN } + }, + { PINMUX_CFG_REG("PSCR", 0xa405011e, 16, 2) { + 0, 0, 0, 0, + PTS6_FN, PTS6_OUT, PTS6_IN_PU, PTS6_IN, + PTS5_FN, PTS5_OUT, PTS5_IN_PU, PTS5_IN, + PTS4_FN, PTS4_OUT, PTS4_IN_PU, PTS4_IN, + PTS3_FN, PTS3_OUT, PTS3_IN_PU, PTS3_IN, + PTS2_FN, PTS2_OUT, PTS2_IN_PU, PTS2_IN, + PTS1_FN, PTS1_OUT, PTS1_IN_PU, PTS1_IN, + PTS0_FN, PTS0_OUT, PTS0_IN_PU, PTS0_IN } + }, + { PINMUX_CFG_REG("PTCR", 0xa4050140, 16, 2) { + PTT7_FN, PTT7_OUT, PTT7_IN_PU, PTT7_IN, + PTT6_FN, PTT6_OUT, PTT6_IN_PU, PTT6_IN, + PTT5_FN, PTT5_OUT, PTT5_IN_PU, PTT5_IN, + PTT4_FN, PTT4_OUT, PTT4_IN_PU, PTT4_IN, + PTT3_FN, PTT3_OUT, PTT3_IN_PU, PTT3_IN, + PTT2_FN, PTT2_OUT, PTT2_IN_PU, PTT2_IN, + PTT1_FN, PTT1_OUT, PTT1_IN_PU, PTT1_IN, + PTT0_FN, PTT0_OUT, PTT0_IN_PU, PTT0_IN } + }, + { PINMUX_CFG_REG("PUCR", 0xa4050142, 16, 2) { + PTU7_FN, PTU7_OUT, PTU7_IN_PU, PTU7_IN, + PTU6_FN, PTU6_OUT, PTU6_IN_PU, PTU6_IN, + PTU5_FN, PTU5_OUT, PTU5_IN_PU, PTU5_IN, + PTU4_FN, PTU4_OUT, PTU4_IN_PU, PTU4_IN, + PTU3_FN, PTU3_OUT, PTU3_IN_PU, PTU3_IN, + PTU2_FN, PTU2_OUT, PTU2_IN_PU, PTU2_IN, + PTU1_FN, PTU1_OUT, PTU1_IN_PU, PTU1_IN, + PTU0_FN, PTU0_OUT, PTU0_IN_PU, PTU0_IN } + }, + { PINMUX_CFG_REG("PVCR", 0xa4050144, 16, 2) { + PTV7_FN, PTV7_OUT, PTV7_IN_PU, PTV7_IN, + PTV6_FN, PTV6_OUT, PTV6_IN_PU, PTV6_IN, + PTV5_FN, PTV5_OUT, PTV5_IN_PU, PTV5_IN, + PTV4_FN, PTV4_OUT, PTV4_IN_PU, PTV4_IN, + PTV3_FN, PTV3_OUT, PTV3_IN_PU, PTV3_IN, + PTV2_FN, PTV2_OUT, PTV2_IN_PU, PTV2_IN, + PTV1_FN, PTV1_OUT, PTV1_IN_PU, PTV1_IN, + PTV0_FN, PTV0_OUT, PTV0_IN_PU, PTV0_IN } + }, + { PINMUX_CFG_REG("PWCR", 0xa4050146, 16, 2) { + PTW7_FN, PTW7_OUT, PTW7_IN_PU, PTW7_IN, + PTW6_FN, PTW6_OUT, PTW6_IN_PU, PTW6_IN, + PTW5_FN, PTW5_OUT, PTW5_IN_PU, PTW5_IN, + PTW4_FN, PTW4_OUT, PTW4_IN_PU, PTW4_IN, + PTW3_FN, PTW3_OUT, PTW3_IN_PU, PTW3_IN, + PTW2_FN, PTW2_OUT, PTW2_IN_PU, PTW2_IN, + PTW1_FN, PTW1_OUT, PTW1_IN_PU, PTW1_IN, + PTW0_FN, PTW0_OUT, PTW0_IN_PU, PTW0_IN } + }, + { PINMUX_CFG_REG("PXCR", 0xa4050148, 16, 2) { + PTX7_FN, PTX7_OUT, PTX7_IN_PU, PTX7_IN, + PTX6_FN, PTX6_OUT, PTX6_IN_PU, PTX6_IN, + PTX5_FN, PTX5_OUT, PTX5_IN_PU, PTX5_IN, + PTX4_FN, PTX4_OUT, PTX4_IN_PU, PTX4_IN, + PTX3_FN, PTX3_OUT, PTX3_IN_PU, PTX3_IN, + PTX2_FN, PTX2_OUT, PTX2_IN_PU, PTX2_IN, + PTX1_FN, PTX1_OUT, PTX1_IN_PU, PTX1_IN, + PTX0_FN, PTX0_OUT, PTX0_IN_PU, PTX0_IN } + }, + { PINMUX_CFG_REG("PYCR", 0xa405014a, 16, 2) { + PTY7_FN, PTY7_OUT, PTY7_IN_PU, PTY7_IN, + PTY6_FN, PTY6_OUT, PTY6_IN_PU, PTY6_IN, + PTY5_FN, PTY5_OUT, PTY5_IN_PU, PTY5_IN, + PTY4_FN, PTY4_OUT, PTY4_IN_PU, PTY4_IN, + PTY3_FN, PTY3_OUT, PTY3_IN_PU, PTY3_IN, + PTY2_FN, PTY2_OUT, PTY2_IN_PU, PTY2_IN, + PTY1_FN, PTY1_OUT, PTY1_IN_PU, PTY1_IN, + PTY0_FN, PTY0_OUT, PTY0_IN_PU, PTY0_IN } + }, + { PINMUX_CFG_REG("PZCR", 0xa405014c, 16, 2) { + PTZ7_FN, PTZ7_OUT, PTZ7_IN_PU, PTZ7_IN, + PTZ6_FN, PTZ6_OUT, PTZ6_IN_PU, PTZ6_IN, + PTZ5_FN, PTZ5_OUT, PTZ5_IN_PU, PTZ5_IN, + PTZ4_FN, PTZ4_OUT, PTZ4_IN_PU, PTZ4_IN, + PTZ3_FN, PTZ3_OUT, PTZ3_IN_PU, PTZ3_IN, + PTZ2_FN, PTZ2_OUT, PTZ2_IN_PU, PTZ2_IN, + PTZ1_FN, PTZ1_OUT, PTZ1_IN_PU, PTZ1_IN, + PTZ0_FN, PTZ0_OUT, PTZ0_IN_PU, PTZ0_IN } + }, + { PINMUX_CFG_REG("PSELA", 0xa405014e, 16, 1) { + PSA15_0, PSA15_1, + PSA14_0, PSA14_1, + PSA13_0, PSA13_1, + PSA12_0, PSA12_1, + 0, 0, + PSA10_0, PSA10_1, + PSA9_0, PSA9_1, + PSA8_0, PSA8_1, + PSA7_0, PSA7_1, + PSA6_0, PSA6_1, + PSA5_0, PSA5_1, + 0, 0, + PSA3_0, PSA3_1, + PSA2_0, PSA2_1, + PSA1_0, PSA1_1, + PSA0_0, PSA0_1} + }, + { PINMUX_CFG_REG("PSELB", 0xa4050150, 16, 1) { + 0, 0, + PSB14_0, PSB14_1, + PSB13_0, PSB13_1, + PSB12_0, PSB12_1, + PSB11_0, PSB11_1, + PSB10_0, PSB10_1, + PSB9_0, PSB9_1, + PSB8_0, PSB8_1, + PSB7_0, PSB7_1, + PSB6_0, PSB6_1, + PSB5_0, PSB5_1, + PSB4_0, PSB4_1, + PSB3_0, PSB3_1, + PSB2_0, PSB2_1, + PSB1_0, PSB1_1, + PSB0_0, PSB0_1} + }, + { PINMUX_CFG_REG("PSELC", 0xa4050152, 16, 1) { + PSC15_0, PSC15_1, + PSC14_0, PSC14_1, + PSC13_0, PSC13_1, + PSC12_0, PSC12_1, + PSC11_0, PSC11_1, + PSC10_0, PSC10_1, + PSC9_0, PSC9_1, + PSC8_0, PSC8_1, + PSC7_0, PSC7_1, + PSC6_0, PSC6_1, + PSC5_0, PSC5_1, + PSC4_0, PSC4_1, + 0, 0, + PSC2_0, PSC2_1, + PSC1_0, PSC1_1, + PSC0_0, PSC0_1} + }, + { PINMUX_CFG_REG("PSELD", 0xa4050154, 16, 1) { + PSD15_0, PSD15_1, + PSD14_0, PSD14_1, + PSD13_0, PSD13_1, + PSD12_0, PSD12_1, + PSD11_0, PSD11_1, + PSD10_0, PSD10_1, + PSD9_0, PSD9_1, + PSD8_0, PSD8_1, + PSD7_0, PSD7_1, + PSD6_0, PSD6_1, + PSD5_0, PSD5_1, + PSD4_0, PSD4_1, + PSD3_0, PSD3_1, + PSD2_0, PSD2_1, + PSD1_0, PSD1_1, + PSD0_0, PSD0_1} + }, + { PINMUX_CFG_REG("PSELE", 0xa4050156, 16, 1) { + PSE15_0, PSE15_1, + PSE14_0, PSE14_1, + PSE13_0, PSE13_1, + PSE12_0, PSE12_1, + PSE11_0, PSE11_1, + PSE10_0, PSE10_1, + PSE9_0, PSE9_1, + PSE8_0, PSE8_1, + PSE7_0, PSE7_1, + PSE6_0, PSE6_1, + PSE5_0, PSE5_1, + PSE4_0, PSE4_1, + PSE3_0, PSE3_1, + PSE2_0, PSE2_1, + PSE1_0, PSE1_1, + PSE0_0, PSE0_1} + }, + {} +}; + +static struct pinmux_data_reg pinmux_data_regs[] = { + { PINMUX_DATA_REG("PADR", 0xa4050120, 8) { + PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA, + PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA } + }, + { PINMUX_DATA_REG("PBDR", 0xa4050122, 8) { + PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA, + PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA } + }, + { PINMUX_DATA_REG("PCDR", 0xa4050124, 8) { + PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA, + PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA } + }, + { PINMUX_DATA_REG("PDDR", 0xa4050126, 8) { + PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA, + PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA } + }, + { PINMUX_DATA_REG("PEDR", 0xa4050128, 8) { + PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA, + PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA } + }, + { PINMUX_DATA_REG("PFDR", 0xa405012a, 8) { + PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA, + PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA } + }, + { PINMUX_DATA_REG("PGDR", 0xa405012c, 8) { + 0, 0, PTG5_DATA, PTG4_DATA, + PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA } + }, + { PINMUX_DATA_REG("PHDR", 0xa405012e, 8) { + PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA, + PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA } + }, + { PINMUX_DATA_REG("PJDR", 0xa4050130, 8) { + PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, 0, + PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA } + }, + { PINMUX_DATA_REG("PKDR", 0xa4050132, 8) { + PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA, + PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA } + }, + { PINMUX_DATA_REG("PLDR", 0xa4050134, 8) { + PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA, + PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA } + }, + { PINMUX_DATA_REG("PMDR", 0xa4050136, 8) { + PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA, + PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA } + }, + { PINMUX_DATA_REG("PNDR", 0xa4050138, 8) { + PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA, + PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA } + }, + { PINMUX_DATA_REG("PQDR", 0xa405013a, 8) { + PTQ7_DATA, PTQ6_DATA, PTQ5_DATA, PTQ4_DATA, + PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA } + }, + { PINMUX_DATA_REG("PRDR", 0xa405013c, 8) { + PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA, + PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA } + }, + { PINMUX_DATA_REG("PSDR", 0xa405013e, 8) { + 0, PTS6_DATA, PTS5_DATA, PTS4_DATA, + PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA } + }, + { PINMUX_DATA_REG("PTDR", 0xa4050160, 8) { + PTT7_DATA, PTT6_DATA, PTT5_DATA, PTT4_DATA, + PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA } + }, + { PINMUX_DATA_REG("PUDR", 0xa4050162, 8) { + PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA, + PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA } + }, + { PINMUX_DATA_REG("PVDR", 0xa4050164, 8) { + PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA, + PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA } + }, + { PINMUX_DATA_REG("PWDR", 0xa4050166, 8) { + PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA, + PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA } + }, + { PINMUX_DATA_REG("PXDR", 0xa4050168, 8) { + PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA, + PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA } + }, + { PINMUX_DATA_REG("PYDR", 0xa405016a, 8) { + PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA, + PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA } + }, + { PINMUX_DATA_REG("PZDR", 0xa405016c, 8) { + PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA, + PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA } + }, + { }, +}; + +static struct pinmux_info sh7724_pinmux_info = { + .name = "sh7724_pfc", + .reserved_id = PINMUX_RESERVED, + .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END }, + .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END }, + .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END }, + .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END }, + .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END }, + .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, + + .first_gpio = GPIO_PTA7, + .last_gpio = GPIO_FN_INTC_IRQ0, + + .gpios = pinmux_gpios, + .cfg_regs = pinmux_config_regs, + .data_regs = pinmux_data_regs, + + .gpio_data = pinmux_data, + .gpio_data_size = ARRAY_SIZE(pinmux_data), +}; + +static int __init plat_pinmux_setup(void) +{ + return register_pinmux(&sh7724_pinmux_info); +} +arch_initcall(plat_pinmux_setup); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c new file mode 100644 index 000000000000..4327b1e080b7 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -0,0 +1,371 @@ +/* + * SH7724 Setup + * + * Copyright (C) 2009 Renesas Solutions Corp. + * + * Kuninori Morimoto + * + * Based on SH7723 Setup + * Copyright (C) 2008 Paul Mundt + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Serial */ +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 80, 80, 80 }, + }, { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 81, 81, 81, 81 }, + }, { + .mapbase = 0xffe20000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 82, 82, 82, 82 }, + }, { + .mapbase = 0xa4e30000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIFA, + .irqs = { 56, 56, 56, 56 }, + }, { + .mapbase = 0xa4e40000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIFA, + .irqs = { 88, 88, 88, 88 }, + }, { + .mapbase = 0xa4e50000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIFA, + .irqs = { 109, 109, 109, 109 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +/* RTC */ +static struct resource rtc_resources[] = { + [0] = { + .start = 0xa465fec0, + .end = 0xa465fec0 + 0x58 - 1, + .flags = IORESOURCE_IO, + }, + [1] = { + /* Period IRQ */ + .start = 69, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* Carry IRQ */ + .start = 70, + .flags = IORESOURCE_IRQ, + }, + [3] = { + /* Alarm IRQ */ + .start = 68, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + +static struct platform_device *sh7724_devices[] __initdata = { + &sci_device, + &rtc_device, +}; + +static int __init sh7724_devices_setup(void) +{ + clk_always_enable("rtc0"); /* RTC */ + + return platform_add_devices(sh7724_devices, + ARRAY_SIZE(sh7724_devices)); +} +device_initcall(sh7724_devices_setup); + +enum { + UNUSED = 0, + + /* interrupt sources */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, + HUDI, + DMAC1A_DEI0, DMAC1A_DEI1, DMAC1A_DEI2, DMAC1A_DEI3, + _2DG_TRI, _2DG_INI, _2DG_CEI, _2DG_BRK, + DMAC0A_DEI0, DMAC0A_DEI1, DMAC0A_DEI2, DMAC0A_DEI3, + VIO_CEU20I, VIO_BEU20I, VIO_VEU3F1, VIO_VOUI, + SCIFA_SCIFA0, + VPU_VPUI, + TPU_TPUI, + CEU21I, + BEU21I, + USB_USI0, + ATAPI, + RTC_ATI, RTC_PRI, RTC_CUI, + DMAC1B_DEI4, DMAC1B_DEI5, DMAC1B_DADERR, + DMAC0B_DEI4, DMAC0B_DEI5, DMAC0B_DADERR, + KEYSC_KEYI, + SCIF_SCIF0, SCIF_SCIF1, SCIF_SCIF2, + VEU3F0I, + MSIOF_MSIOFI0, MSIOF_MSIOFI1, + SPU_SPUI0, SPU_SPUI1, + SCIFA_SCIFA1, +/* ICB_ICBI, */ + ETHI, + I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI, + I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI, + SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2, + CMT_CMTI, + TSIF_TSIFI, +/* ICB_LMBI, */ + FSI_FSI, + SCIFA_SCIFA2, + TMU0_TUNI0, TMU0_TUNI1, TMU0_TUNI2, + IRDA_IRDAI, + SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2, + JPU_JPUI, + MMC_MMCI0, MMC_MMCI1, MMC_MMCI2, + LCDC_LCDCI, + TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2, + + /* interrupt groups */ + DMAC1A, _2DG, DMAC0A, VIO, RTC, + DMAC1B, DMAC0B, I2C0, I2C1, SDHI0, SDHI1, SPU, MMC, +}; + +static struct intc_vect vectors[] __initdata = { + INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), + INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), + INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + INTC_VECT(IRQ6, 0x6c0), INTC_VECT(IRQ7, 0x6e0), + + INTC_VECT(DMAC1A_DEI0, 0x700), + INTC_VECT(DMAC1A_DEI1, 0x720), + INTC_VECT(DMAC1A_DEI2, 0x740), + INTC_VECT(DMAC1A_DEI3, 0x760), + + INTC_VECT(_2DG_TRI, 0x780), + INTC_VECT(_2DG_INI, 0x7A0), + INTC_VECT(_2DG_CEI, 0x7C0), + INTC_VECT(_2DG_BRK, 0x7E0), + + INTC_VECT(DMAC0A_DEI0, 0x800), + INTC_VECT(DMAC0A_DEI1, 0x820), + INTC_VECT(DMAC0A_DEI2, 0x840), + INTC_VECT(DMAC0A_DEI3, 0x860), + + INTC_VECT(VIO_CEU20I, 0x880), + INTC_VECT(VIO_BEU20I, 0x8A0), + INTC_VECT(VIO_VEU3F1, 0x8C0), + INTC_VECT(VIO_VOUI, 0x8E0), + + INTC_VECT(SCIFA_SCIFA0, 0x900), + INTC_VECT(VPU_VPUI, 0x980), + INTC_VECT(TPU_TPUI, 0x9A0), + INTC_VECT(CEU21I, 0x9E0), + INTC_VECT(BEU21I, 0xA00), + INTC_VECT(USB_USI0, 0xA20), + INTC_VECT(ATAPI, 0xA60), + + INTC_VECT(RTC_ATI, 0xA80), + INTC_VECT(RTC_PRI, 0xAA0), + INTC_VECT(RTC_CUI, 0xAC0), + + INTC_VECT(DMAC1B_DEI4, 0xB00), + INTC_VECT(DMAC1B_DEI5, 0xB20), + INTC_VECT(DMAC1B_DADERR, 0xB40), + + INTC_VECT(DMAC0B_DEI4, 0xB80), + INTC_VECT(DMAC0B_DEI5, 0xBA0), + INTC_VECT(DMAC0B_DADERR, 0xBC0), + + INTC_VECT(KEYSC_KEYI, 0xBE0), + INTC_VECT(SCIF_SCIF0, 0xC00), + INTC_VECT(SCIF_SCIF1, 0xC20), + INTC_VECT(SCIF_SCIF2, 0xC40), + INTC_VECT(VEU3F0I, 0xC60), + INTC_VECT(MSIOF_MSIOFI0, 0xC80), + INTC_VECT(MSIOF_MSIOFI1, 0xCA0), + INTC_VECT(SPU_SPUI0, 0xCC0), + INTC_VECT(SPU_SPUI1, 0xCE0), + INTC_VECT(SCIFA_SCIFA1, 0xD00), + +/* INTC_VECT(ICB_ICBI, 0xD20), */ + INTC_VECT(ETHI, 0xD60), + + INTC_VECT(I2C1_ALI, 0xD80), + INTC_VECT(I2C1_TACKI, 0xDA0), + INTC_VECT(I2C1_WAITI, 0xDC0), + INTC_VECT(I2C1_DTEI, 0xDE0), + + INTC_VECT(I2C0_ALI, 0xE00), + INTC_VECT(I2C0_TACKI, 0xE20), + INTC_VECT(I2C0_WAITI, 0xE40), + INTC_VECT(I2C0_DTEI, 0xE60), + + INTC_VECT(SDHI0_SDHII0, 0xE80), + INTC_VECT(SDHI0_SDHII1, 0xEA0), + INTC_VECT(SDHI0_SDHII2, 0xEC0), + + INTC_VECT(CMT_CMTI, 0xF00), + INTC_VECT(TSIF_TSIFI, 0xF20), +/* INTC_VECT(ICB_LMBI, 0xF60), */ + INTC_VECT(FSI_FSI, 0xF80), + INTC_VECT(SCIFA_SCIFA2, 0xFA0), + + INTC_VECT(TMU0_TUNI0, 0x400), + INTC_VECT(TMU0_TUNI1, 0x420), + INTC_VECT(TMU0_TUNI2, 0x440), + + INTC_VECT(IRDA_IRDAI, 0x480), + + INTC_VECT(SDHI1_SDHII0, 0x4E0), + INTC_VECT(SDHI1_SDHII1, 0x500), + INTC_VECT(SDHI1_SDHII2, 0x520), + + INTC_VECT(JPU_JPUI, 0x560), + + INTC_VECT(MMC_MMCI0, 0x580), + INTC_VECT(MMC_MMCI1, 0x5A0), + INTC_VECT(MMC_MMCI2, 0x5C0), + + INTC_VECT(LCDC_LCDCI, 0xF40), + + INTC_VECT(TMU1_TUNI0, 0x920), + INTC_VECT(TMU1_TUNI1, 0x940), + INTC_VECT(TMU1_TUNI2, 0x960), +}; + +static struct intc_group groups[] __initdata = { + INTC_GROUP(DMAC1A, DMAC1A_DEI0, DMAC1A_DEI1, DMAC1A_DEI2, DMAC1A_DEI3), + INTC_GROUP(_2DG, _2DG_TRI, _2DG_INI, _2DG_CEI, _2DG_BRK), + INTC_GROUP(DMAC0A, DMAC0A_DEI0, DMAC0A_DEI1, DMAC0A_DEI2, DMAC0A_DEI3), + INTC_GROUP(VIO, VIO_CEU20I, VIO_BEU20I, VIO_VEU3F1, VIO_VOUI), + INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), + INTC_GROUP(DMAC1B, DMAC1B_DEI4, DMAC1B_DEI5, DMAC1B_DADERR), + INTC_GROUP(DMAC0B, DMAC0B_DEI4, DMAC0B_DEI5, DMAC0B_DADERR), + INTC_GROUP(I2C0, I2C0_ALI, I2C0_TACKI, I2C0_WAITI, I2C0_DTEI), + INTC_GROUP(I2C1, I2C1_ALI, I2C1_TACKI, I2C1_WAITI, I2C1_DTEI), + INTC_GROUP(SDHI0, SDHI0_SDHII0, SDHI0_SDHII1, SDHI0_SDHII2), + INTC_GROUP(SDHI1, SDHI1_SDHII0, SDHI1_SDHII1, SDHI1_SDHII2), + INTC_GROUP(SPU, SPU_SPUI0, SPU_SPUI1), + INTC_GROUP(MMC, MMC_MMCI0, MMC_MMCI1, MMC_MMCI2), +}; + +/* FIXMEEEEEEEEEEEEEEEEEEE !!!!! */ +/* very bad manual !! */ +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ + { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0, + /*SDHII3?*/0, SDHI1_SDHII2, SDHI1_SDHII1, SDHI1_SDHII0 } }, + { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ + { VIO_VOUI, VIO_VEU3F1, VIO_BEU20I, VIO_CEU20I, + DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } }, + { 0xa4080088, 0xa40800c8, 8, /* IMR2 / IMCR2 */ + { 0, 0, 0, VPU_VPUI, ATAPI, ETHI, 0, /*SCIFA3*/SCIFA_SCIFA0 } }, + { 0xa408008c, 0xa40800cc, 8, /* IMR3 / IMCR3 */ + { DMAC1A_DEI3, DMAC1A_DEI2, DMAC1A_DEI1, DMAC1A_DEI0, + SPU_SPUI1, SPU_SPUI0, BEU21I, IRDA_IRDAI } }, + { 0xa4080090, 0xa40800d0, 8, /* IMR4 / IMCR4 */ + { 0, TMU0_TUNI2, TMU0_TUNI1, TMU0_TUNI0, + JPU_JPUI, 0, 0, LCDC_LCDCI } }, + { 0xa4080094, 0xa40800d4, 8, /* IMR5 / IMCR5 */ + { KEYSC_KEYI, DMAC0B_DADERR, DMAC0B_DEI5, DMAC0B_DEI4, + VEU3F0I, SCIF_SCIF2, SCIF_SCIF1, SCIF_SCIF0 } }, + { 0xa4080098, 0xa40800d8, 8, /* IMR6 / IMCR6 */ + { 0, 0, /*ICB_ICBI*/0, /*SCIFA4*/SCIFA_SCIFA1, + CEU21I, 0, MSIOF_MSIOFI1, MSIOF_MSIOFI0 } }, + { 0xa408009c, 0xa40800dc, 8, /* IMR7 / IMCR7 */ + { I2C0_DTEI, I2C0_WAITI, I2C0_TACKI, I2C0_ALI, + I2C1_DTEI, I2C1_WAITI, I2C1_TACKI, I2C1_ALI } }, + { 0xa40800a0, 0xa40800e0, 8, /* IMR8 / IMCR8 */ + { /*SDHII3*/0, SDHI0_SDHII2, SDHI0_SDHII1, SDHI0_SDHII0, + 0, 0, /*SCIFA5*/SCIFA_SCIFA2, FSI_FSI } }, + { 0xa40800a4, 0xa40800e4, 8, /* IMR9 / IMCR9 */ + { 0, 0, 0, CMT_CMTI, 0, /*USB1*/0, USB_USI0, 0 } }, + { 0xa40800a8, 0xa40800e8, 8, /* IMR10 / IMCR10 */ + { 0, DMAC1B_DADERR, DMAC1B_DEI5, DMAC1B_DEI4, + 0, RTC_ATI, RTC_PRI, RTC_CUI } }, + { 0xa40800ac, 0xa40800ec, 8, /* IMR11 / IMCR11 */ + { _2DG_BRK, _2DG_CEI, _2DG_INI, _2DG_TRI, + 0, TPU_TPUI, /*ICB_LMBI*/0, TSIF_TSIFI } }, + { 0xa40800b0, 0xa40800f0, 8, /* IMR12 / IMCR12 */ + { 0, 0, 0, 0, 0, 0, 0, 0/*2DDMAC*/ } }, + { 0xa4140044, 0xa4140064, 8, /* INTMSK00 / INTMSKCLR00 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0_TUNI0, TMU0_TUNI1, + TMU0_TUNI2, IRDA_IRDAI } }, + { 0xa4080004, 0, 16, 4, /* IPRB */ { JPU_JPUI, LCDC_LCDCI, + DMAC1A, BEU21I } }, + { 0xa4080008, 0, 16, 4, /* IPRC */ { TMU1_TUNI0, TMU1_TUNI1, + TMU1_TUNI2, SPU } }, + { 0xa408000c, 0, 16, 4, /* IPRD */ { 0, MMC, 0, ATAPI } }, + { 0xa4080010, 0, 16, 4, /* IPRE */ + { DMAC0A, /*BEU?VEU?*/VIO, /*SCIFA3*/SCIFA_SCIFA0, /*VPU5F*/ + VPU_VPUI } }, + { 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC_KEYI, DMAC0B, + USB_USI0, CMT_CMTI } }, + { 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF_SCIF0, SCIF_SCIF1, + SCIF_SCIF2, VEU3F0I } }, + { 0xa408001c, 0, 16, 4, /* IPRH */ { MSIOF_MSIOFI0, MSIOF_MSIOFI1, + I2C1, I2C0 } }, + { 0xa4080020, 0, 16, 4, /* IPRI */ { /*SCIFA4*/SCIFA_SCIFA1, /*ICB*/0, + TSIF_TSIFI, _2DG/*ICB?*/ } }, + { 0xa4080024, 0, 16, 4, /* IPRJ */ { CEU21I, ETHI, FSI_FSI, SDHI1 } }, + { 0xa4080028, 0, 16, 4, /* IPRK */ { RTC, DMAC1B, /*ICB?*/0, SDHI0 } }, + { 0xa408002c, 0, 16, 4, /* IPRL */ { /*SCIFA5*/SCIFA_SCIFA2, 0, + TPU_TPUI, /*2DDMAC*/0 } }, + { 0xa4140010, 0, 32, 4, /* INTPRI00 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static struct intc_sense_reg sense_registers[] __initdata = { + { 0xa414001c, 16, 2, /* ICR1 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static struct intc_mask_reg ack_registers[] __initdata = { + { 0xa4140024, 0, 8, /* INTREQ00 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static DECLARE_INTC_DESC_ACK(intc_desc, "sh7724", vectors, groups, + mask_registers, prio_registers, sense_registers, + ack_registers); + +void __init plat_irq_setup(void) +{ + register_intc_controller(&intc_desc); +} diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 04a6004fccc4..0e6ed804546e 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -435,7 +435,8 @@ static const char *cpu_name[] = { [CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3", [CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103", [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723", - [CPU_SH7366] = "SH7366", [CPU_SH_NONE] = "Unknown" + [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724", + [CPU_SH_NONE] = "Unknown" }; const char *get_cpu_subtype(struct sh_cpuinfo *c) diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c index 1b9d4304b3bf..44f4e31c6d63 100644 --- a/arch/sh/oprofile/common.c +++ b/arch/sh/oprofile/common.c @@ -109,6 +109,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_SH7785: case CPU_SH7786: case CPU_SH7723: + case CPU_SH7724: case CPU_SHX3: lmodel = &op_model_sh4a_ops; break; -- GitLab From 47948d2bd6d27648a107a27357b3bc5ad054ff64 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 15 Apr 2009 11:42:47 +0900 Subject: [PATCH 0284/6080] serial: sh-sci: SH7724 support. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.h | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index d0aa82d7fce0..84cc6512f081 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -91,6 +91,9 @@ # define SCSPTR5 0xa4050128 # define SCIF_ORER 0x0001 /* overrun error bit */ # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +#elif defined(CONFIG_CPU_SUBTYPE_SH7724) +# define SCIF_ORER 0x0001 /* overrun error bit */ +# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ @@ -361,7 +364,8 @@ h8_sci_offset, h8_sci_size) \ CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size) #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) -#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ + defined(CONFIG_CPU_SUBTYPE_SH7724) #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \ CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \ @@ -390,7 +394,8 @@ SCIF_FNS(SCFDR, 0x1c, 16) SCIF_FNS(SCxTDR, 0x20, 8) SCIF_FNS(SCxRDR, 0x24, 8) SCIF_FNS(SCLSR, 0x24, 16) -#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ + defined(CONFIG_CPU_SUBTYPE_SH7724) SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8) SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16) @@ -604,6 +609,17 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */ return 1; } +#elif defined(CONFIG_CPU_SUBTYPE_SH7724) +# define SCFSR 0x0010 +# define SCASSR 0x0014 +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->type == PORT_SCIF) + return ctrl_inw((port->mapbase + SCFSR)) & SCIF_BRK ? 1 : 0; + if (port->type == PORT_SCIFA) + return ctrl_inw((port->mapbase + SCASSR)) & SCIF_BRK ? 1 : 0; + return 1; +} #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) static inline int sci_rxd_in(struct uart_port *port) { @@ -757,7 +773,8 @@ static inline int sci_rxd_in(struct uart_port *port) defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) -#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ + defined(CONFIG_CPU_SUBTYPE_SH7724) static inline int scbrr_calc(struct uart_port *port, int bps, int clk) { if (port->type == PORT_SCIF) -- GitLab From 40c7e8be556715079d0a9d7454ceb5371a2f0b39 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 16 Apr 2009 13:16:07 +0900 Subject: [PATCH 0285/6080] sh: sh7724: Add I2C support. This adds support for the SH-Mobile I2C controller on the SH7724. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 46 ++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 4327b1e080b7..f17eda6688d0 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -99,9 +99,55 @@ static struct platform_device rtc_device = { .resource = rtc_resources, }; +/* I2C0 */ +static struct resource iic0_resources[] = { + [0] = { + .name = "IIC0", + .start = 0x04470000, + .end = 0x04470018 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 96, + .end = 99, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device iic0_device = { + .name = "i2c-sh_mobile", + .id = 0, /* "i2c0" clock */ + .num_resources = ARRAY_SIZE(iic0_resources), + .resource = iic0_resources, +}; + +/* I2C1 */ +static struct resource iic1_resources[] = { + [0] = { + .name = "IIC1", + .start = 0x04750000, + .end = 0x04750018 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 92, + .end = 95, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device iic1_device = { + .name = "i2c-sh_mobile", + .id = 1, /* "i2c1" clock */ + .num_resources = ARRAY_SIZE(iic1_resources), + .resource = iic1_resources, +}; + static struct platform_device *sh7724_devices[] __initdata = { &sci_device, &rtc_device, + &iic0_device, + &iic1_device, }; static int __init sh7724_devices_setup(void) -- GitLab From cd5b9ef776feff440e7a889d1a565ceabfecbfa1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 15 Apr 2009 11:43:03 +0900 Subject: [PATCH 0286/6080] sh: sh7724: Add VPU support. This adds uio_pdrv_genirq support for the VPU. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index f17eda6688d0..499a6fcdf231 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -143,16 +143,49 @@ static struct platform_device iic1_device = { .resource = iic1_resources, }; +/* VPU */ +static struct uio_info vpu_platform_data = { + .name = "VPU5F", + .version = "0", + .irq = 60, +}; + +static struct resource vpu_resources[] = { + [0] = { + .name = "VPU", + .start = 0xfe900000, + .end = 0xfe902807, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device vpu_device = { + .name = "uio_pdrv_genirq", + .id = 0, + .dev = { + .platform_data = &vpu_platform_data, + }, + .resource = vpu_resources, + .num_resources = ARRAY_SIZE(vpu_resources), +}; + static struct platform_device *sh7724_devices[] __initdata = { &sci_device, &rtc_device, &iic0_device, &iic1_device, + &vpu_device, }; static int __init sh7724_devices_setup(void) { clk_always_enable("rtc0"); /* RTC */ + clk_always_enable("vpu0"); /* VPU */ + + platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20); return platform_add_devices(sh7724_devices, ARRAY_SIZE(sh7724_devices)); -- GitLab From ad95b78c9f735da11ff9ec760e9b038cd82aead6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 15 Apr 2009 11:43:07 +0900 Subject: [PATCH 0287/6080] sh: sh7724: Add VEU support. This adds uio_pdrv_genirq support for the VEU. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 64 ++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 499a6fcdf231..65570ed69e6c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -172,20 +172,84 @@ static struct platform_device vpu_device = { .num_resources = ARRAY_SIZE(vpu_resources), }; +/* VEU0 */ +static struct uio_info veu0_platform_data = { + .name = "VEU3F0", + .version = "0", + .irq = 83, +}; + +static struct resource veu0_resources[] = { + [0] = { + .name = "VEU3F0", + .start = 0xfe920000, + .end = 0xfe9200cb - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device veu0_device = { + .name = "uio_pdrv_genirq", + .id = 1, + .dev = { + .platform_data = &veu0_platform_data, + }, + .resource = veu0_resources, + .num_resources = ARRAY_SIZE(veu0_resources), +}; + +/* VEU1 */ +static struct uio_info veu1_platform_data = { + .name = "VEU3F1", + .version = "0", + .irq = 54, +}; + +static struct resource veu1_resources[] = { + [0] = { + .name = "VEU3F1", + .start = 0xfe924000, + .end = 0xfe9240cb - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + /* place holder for contiguous memory */ + }, +}; + +static struct platform_device veu1_device = { + .name = "uio_pdrv_genirq", + .id = 2, + .dev = { + .platform_data = &veu1_platform_data, + }, + .resource = veu1_resources, + .num_resources = ARRAY_SIZE(veu1_resources), +}; + static struct platform_device *sh7724_devices[] __initdata = { &sci_device, &rtc_device, &iic0_device, &iic1_device, &vpu_device, + &veu0_device, + &veu1_device, }; static int __init sh7724_devices_setup(void) { clk_always_enable("rtc0"); /* RTC */ clk_always_enable("vpu0"); /* VPU */ + clk_always_enable("veu1"); /* VEU3F1 */ + clk_always_enable("veu0"); /* VEU3F0 */ platform_resource_setup_memory(&vpu_device, "vpu", 2 << 20); + platform_resource_setup_memory(&veu0_device, "veu0", 2 << 20); + platform_resource_setup_memory(&veu1_device, "veu1", 2 << 20); return platform_add_devices(sh7724_devices, ARRAY_SIZE(sh7724_devices)); -- GitLab From 6a3395beb99d7ae882ddf701c6fa6005ad7edebf Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 16 Apr 2009 15:36:13 +0900 Subject: [PATCH 0288/6080] sh: sh7724: Add CMT clockevents support. This enables support for the CMT clockevents driver on SH7724. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 65570ed69e6c..8b87ba8f26bb 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -230,7 +230,40 @@ static struct platform_device veu1_device = { .num_resources = ARRAY_SIZE(veu1_resources), }; +static struct sh_cmt_config cmt_platform_data = { + .name = "CMT", + .channel_offset = 0x60, + .timer_bit = 5, + .clk = "cmt0", + .clockevent_rating = 125, + .clocksource_rating = 200, +}; + +static struct resource cmt_resources[] = { + [0] = { + .name = "CMT", + .start = 0x044a0060, + .end = 0x044a006b, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 104, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cmt_device = { + .name = "sh_cmt", + .id = 0, + .dev = { + .platform_data = &cmt_platform_data, + }, + .resource = cmt_resources, + .num_resources = ARRAY_SIZE(cmt_resources), +}; + static struct platform_device *sh7724_devices[] __initdata = { + &cmt_device, &sci_device, &rtc_device, &iic0_device, -- GitLab From 59fe700dcbf3d6257ae86ca8c0192fc64b2eea1c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 16 Apr 2009 15:43:42 +0900 Subject: [PATCH 0289/6080] sh: Have SH7724 select ARCH_SHMOBILE. This is an SH-Mobile CPU, so select ARCH_SHMOBILE. This enables all of the PM functionality, amongst other things. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 505d1acbd0ad..4c68fdedfa10 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -351,6 +351,7 @@ config CPU_SUBTYPE_SH7724 bool "Support SH7724 processor" select CPU_SH4A select CPU_SHX2 + select ARCH_SHMOBILE select ARCH_SPARSEMEM_ENABLE select SYS_SUPPORTS_CMT help -- GitLab From bc9f3d4291f8275924a9197a81208a5df0a15095 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 16 Apr 2009 15:44:58 +0900 Subject: [PATCH 0290/6080] sh: Add a generic defconfig for SH7724 platforms. Signed-off-by: Paul Mundt --- arch/sh/configs/sh7724_generic_defconfig | 707 +++++++++++++++++++++++ 1 file changed, 707 insertions(+) create mode 100644 arch/sh/configs/sh7724_generic_defconfig diff --git a/arch/sh/configs/sh7724_generic_defconfig b/arch/sh/configs/sh7724_generic_defconfig new file mode 100644 index 000000000000..268d04ed8cdd --- /dev/null +++ b/arch/sh/configs/sh7724_generic_defconfig @@ -0,0 +1,707 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.30-rc2 +# Thu Apr 16 15:42:20 2009 +# +CONFIG_SUPERH=y +CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set +CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_IRQ_PROBE=y +# CONFIG_GENERIC_GPIO is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_SYS_SUPPORTS_CMT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set + +# +# 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=17 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_NS is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CPUSETS is not set +# CONFIG_CGROUP_CPUACCT is not set +# CONFIG_RESOURCE_COUNTERS is not set +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +# CONFIG_UID16 is not set +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=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_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +# CONFIG_MARKERS is not set +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +# CONFIG_MODULES is not set +CONFIG_BLOCK=y +# CONFIG_LBD 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_FREEZER=y + +# +# System type +# +CONFIG_CPU_SH4=y +CONFIG_CPU_SH4A=y +CONFIG_CPU_SHX2=y +CONFIG_ARCH_SHMOBILE=y +# CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7201 is not set +# CONFIG_CPU_SUBTYPE_SH7203 is not set +# CONFIG_CPU_SUBTYPE_SH7206 is not set +# CONFIG_CPU_SUBTYPE_SH7263 is not set +# CONFIG_CPU_SUBTYPE_MXG is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set +# CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7720 is not set +# CONFIG_CPU_SUBTYPE_SH7721 is not set +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set +# CONFIG_CPU_SUBTYPE_SH7723 is not set +CONFIG_CPU_SUBTYPE_SH7724=y +# CONFIG_CPU_SUBTYPE_SH7763 is not set +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set +# CONFIG_CPU_SUBTYPE_SH7786 is not set +# CONFIG_CPU_SUBTYPE_SHX3 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set +# CONFIG_CPU_SUBTYPE_SH7366 is not set + +# +# Memory management options +# +CONFIG_QUICKLIST=y +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_MEMORY_START=0x08000000 +CONFIG_MEMORY_SIZE=0x04000000 +CONFIG_29BIT=y +# CONFIG_X2TLB is not set +CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_MAX_ACTIVE_REGIONS=1 +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_ENTRY_OFFSET=0x00001000 +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_STATIC=y + +# +# Memory hotplug is currently incompatible with Software Suspend +# +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 +CONFIG_UNEVICTABLE_LRU=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y + +# +# Cache configuration +# +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_SH_FPU=y +# CONFIG_SH_STORE_QUEUES is not set +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y +CONFIG_CPU_HAS_FPU=y + +# +# Board support +# + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_CMT=y +CONFIG_SH_TIMER_IRQ=16 +CONFIG_SH_PCLK_FREQ=41666666 +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_SH_CPU_FREQ=y + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# + +# +# Additional SuperH Device Drivers +# +# CONFIG_HEARTBEAT is not set +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_SCHED_HRTICK=y +CONFIG_KEXEC=y +# CONFIG_CRASH_DUMP is not set +CONFIG_KEXEC_JUMP=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_GUSA=y + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +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 + +# +# Power management options (EXPERIMENTAL) +# +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_DEVKMEM is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=6 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_SH_MOBILE=y +# 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 + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_PCA_PLATFORM is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_DS1682 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_PCF8575 is not set +# CONFIG_SENSORS_PCA9539 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 is not set +# CONFIG_HWMON is not set +# 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 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_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 +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# 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 +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT 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_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# 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 +# + +# +# Platform RTC drivers +# +# 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 + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SH=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +CONFIG_UIO=y +# CONFIG_UIO_PDRV is not set +CONFIG_UIO_PDRV_GENIRQ=y +# CONFIG_UIO_SMX is not set +# CONFIG_UIO_SERCOS3 is not set +# CONFIG_STAGING is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y +# CONFIG_XFS_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_DNOTIFY is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +# CONFIG_PROC_FS is not set +# CONFIG_SYSFS is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_MISC_FILESYSTEMS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_RING_BUFFER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_MORE_COMPILE_OPTIONS is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +# CONFIG_CRYPTO is not set +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +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 is not set +# CONFIG_CRC32 is not set +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y -- GitLab From 4e01f54bfd3f423db8fd6c91c4f0471f18aa0c50 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Apr 2009 08:53:34 +0200 Subject: [PATCH 0291/6080] ALSA: hda - Add Creative CA0110-IBG support Added the support for Creative SB X-Fi boards with UAA (HD-audio) mode. In the HD-audio mode, no multiple streams are supported by just it behaves like a normal HD-audio device. Signed-off-by: Takashi Iwai --- sound/pci/hda/Kconfig | 13 + sound/pci/hda/Makefile | 4 + sound/pci/hda/hda_codec.c | 1 + sound/pci/hda/hda_intel.c | 5 + sound/pci/hda/patch_ca0110.c | 574 +++++++++++++++++++++++++++++++++++ 5 files changed, 597 insertions(+) create mode 100644 sound/pci/hda/patch_ca0110.c diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index eb2a19b894a0..c710150d5065 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -139,6 +139,19 @@ config SND_HDA_CODEC_CONEXANT snd-hda-codec-conexant. This module is automatically loaded at probing. +config SND_HDA_CODEC_CA0110 + bool "Build Creative CA0110-IBG codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include Creative CA0110-IBG codec support in + snd-hda-intel driver, found on some Creative X-Fi cards. + + When the HD-audio driver is built as a module, the codec + support code is also built as another module, + snd-hda-codec-ca0110. + This module is automatically loaded at probing. + config SND_HDA_CODEC_CMEDIA bool "Build C-Media HD-audio codec support" default y diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 50f9d0967251..e3081d4586cc 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -13,6 +13,7 @@ snd-hda-codec-analog-objs := patch_analog.o snd-hda-codec-idt-objs := patch_sigmatel.o snd-hda-codec-si3054-objs := patch_si3054.o snd-hda-codec-atihdmi-objs := patch_atihdmi.o +snd-hda-codec-ca0110-objs := patch_ca0110.o snd-hda-codec-conexant-objs := patch_conexant.o snd-hda-codec-via-objs := patch_via.o snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o @@ -40,6 +41,9 @@ endif ifdef CONFIG_SND_HDA_CODEC_ATIHDMI obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o endif +ifdef CONFIG_SND_HDA_CODEC_CA0110 +obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o +endif ifdef CONFIG_SND_HDA_CODEC_CONEXANT obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o endif diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index fd6e6f337d10..37f24ce7c3a2 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -48,6 +48,7 @@ static struct hda_vendor_id hda_vendor_ids[] = { { 0x1095, "Silicon Image" }, { 0x10de, "Nvidia" }, { 0x10ec, "Realtek" }, + { 0x1102, "Creative" }, { 0x1106, "VIA" }, { 0x111d, "IDT" }, { 0x11c1, "LSI" }, diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 21e99cfa8c49..21a3092fad00 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2513,6 +2513,11 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x10de, 0x0d97), .driver_data = AZX_DRIVER_NVIDIA }, /* Teradici */ { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, + /* Creative X-Fi (CA0110-IBG) */ + { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), + .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, + .class_mask = 0xffffff, + .driver_data = AZX_DRIVER_GENERIC }, /* AMD Generic, PCI class code and Vendor ID for HD Audio */ { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c new file mode 100644 index 000000000000..7ec41daa3f0c --- /dev/null +++ b/sound/pci/hda/patch_ca0110.c @@ -0,0 +1,574 @@ +/* + * HD audio interface patch for Creative X-Fi CA0110-IBG chip + * + * Copyright (c) 2008 Takashi Iwai + * + * This driver 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 driver 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 "hda_codec.h" +#include "hda_local.h" + +/* + */ + +struct ca0110_spec { + struct auto_pin_cfg autocfg; + struct hda_multi_out multiout; + hda_nid_t out_pins[AUTO_CFG_MAX_OUTS]; + hda_nid_t dacs[AUTO_CFG_MAX_OUTS]; + hda_nid_t hp_dac; + hda_nid_t input_pins[AUTO_PIN_LAST]; + hda_nid_t adcs[AUTO_PIN_LAST]; + hda_nid_t dig_out; + hda_nid_t dig_in; + unsigned int num_inputs; + const char *input_labels[AUTO_PIN_LAST]; + struct hda_pcm pcm_rec[2]; /* PCM information */ +}; + +/* + * PCM callbacks + */ +static int ca0110_playback_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct ca0110_spec *spec = codec->spec; + return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, + hinfo); +} + +static int ca0110_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct ca0110_spec *spec = codec->spec; + return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + +static int ca0110_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct ca0110_spec *spec = codec->spec; + return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); +} + +/* + * Digital out + */ +static int ca0110_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct ca0110_spec *spec = codec->spec; + return snd_hda_multi_out_dig_open(codec, &spec->multiout); +} + +static int ca0110_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct ca0110_spec *spec = codec->spec; + return snd_hda_multi_out_dig_close(codec, &spec->multiout); +} + +static int ca0110_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct ca0110_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + +/* + * Analog capture + */ +static int ca0110_capture_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct ca0110_spec *spec = codec->spec; + + snd_hda_codec_setup_stream(codec, spec->adcs[substream->number], + stream_tag, 0, format); + return 0; +} + +static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct ca0110_spec *spec = codec->spec; + + snd_hda_codec_cleanup_stream(codec, spec->adcs[substream->number]); + return 0; +} + +/* + */ + +static char *dirstr[2] = { "Playback", "Capture" }; + +static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, + int chan, int dir) +{ + char namestr[44]; + int type = dir ? HDA_INPUT : HDA_OUTPUT; + struct snd_kcontrol_new knew = + HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); + sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); + return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); +} + +static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, + int chan, int dir) +{ + char namestr[44]; + int type = dir ? HDA_INPUT : HDA_OUTPUT; + struct snd_kcontrol_new knew = + HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); + sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); + return snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec)); +} + +#define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0) +#define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0) +#define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1) +#define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1) +#define add_mono_switch(codec, nid, pfx, chan) \ + _add_switch(codec, nid, pfx, chan, 0) +#define add_mono_volume(codec, nid, pfx, chan) \ + _add_volume(codec, nid, pfx, chan, 0) + +static int ca0110_build_controls(struct hda_codec *codec) +{ + struct ca0110_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + static char *prefix[AUTO_CFG_MAX_OUTS] = { + "Front", "Surround", NULL, "Side", "Multi" + }; + hda_nid_t mutenid; + int i, err; + + for (i = 0; i < spec->multiout.num_dacs; i++) { + if (get_wcaps(codec, spec->out_pins[i]) & AC_WCAP_OUT_AMP) + mutenid = spec->out_pins[i]; + else + mutenid = spec->multiout.dac_nids[i]; + if (!prefix[i]) { + err = add_mono_switch(codec, mutenid, + "Center", 1); + if (err < 0) + return err; + err = add_mono_switch(codec, mutenid, + "LFE", 1); + if (err < 0) + return err; + err = add_mono_volume(codec, spec->multiout.dac_nids[i], + "Center", 1); + if (err < 0) + return err; + err = add_mono_volume(codec, spec->multiout.dac_nids[i], + "LFE", 1); + if (err < 0) + return err; + } else { + err = add_out_switch(codec, mutenid, + prefix[i]); + if (err < 0) + return err; + err = add_out_volume(codec, spec->multiout.dac_nids[i], + prefix[i]); + if (err < 0) + return err; + } + } + if (cfg->hp_outs) { + if (get_wcaps(codec, cfg->hp_pins[0]) & AC_WCAP_OUT_AMP) + mutenid = cfg->hp_pins[0]; + else + mutenid = spec->multiout.dac_nids[i]; + + err = add_out_switch(codec, mutenid, "Headphone"); + if (err < 0) + return err; + if (spec->hp_dac) { + err = add_out_volume(codec, spec->hp_dac, "Headphone"); + if (err < 0) + return err; + } + } + for (i = 0; i < spec->num_inputs; i++) { + const char *label = spec->input_labels[i]; + if (get_wcaps(codec, spec->input_pins[i]) & AC_WCAP_IN_AMP) + mutenid = spec->input_pins[i]; + else + mutenid = spec->adcs[i]; + err = add_in_switch(codec, mutenid, label); + if (err < 0) + return err; + err = add_in_volume(codec, spec->adcs[i], label); + if (err < 0) + return err; + } + + if (spec->dig_out) { + err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out); + if (err < 0) + return err; + err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); + if (err < 0) + return err; + spec->multiout.share_spdif = 1; + } + if (spec->dig_in) { + err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); + if (err < 0) + return err; + err = add_in_volume(codec, spec->dig_in, "IEC958"); + } + return 0; +} + +/* + */ +static struct hda_pcm_stream ca0110_pcm_analog_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 8, + .ops = { + .open = ca0110_playback_pcm_open, + .prepare = ca0110_playback_pcm_prepare, + .cleanup = ca0110_playback_pcm_cleanup + }, +}; + +static struct hda_pcm_stream ca0110_pcm_analog_capture = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .ops = { + .prepare = ca0110_capture_pcm_prepare, + .cleanup = ca0110_capture_pcm_cleanup + }, +}; + +static struct hda_pcm_stream ca0110_pcm_digital_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .ops = { + .open = ca0110_dig_playback_pcm_open, + .close = ca0110_dig_playback_pcm_close, + .prepare = ca0110_dig_playback_pcm_prepare + }, +}; + +static struct hda_pcm_stream ca0110_pcm_digital_capture = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, +}; + +static int ca0110_build_pcms(struct hda_codec *codec) +{ + struct ca0110_spec *spec = codec->spec; + struct hda_pcm *info = spec->pcm_rec; + + codec->pcm_info = info; + codec->num_pcms = 0; + + info->name = "CA0110 Analog"; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0110_pcm_analog_playback; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = + spec->multiout.num_dacs * 2; + info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0110_pcm_analog_capture; + info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs; + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; + codec->num_pcms++; + + if (!spec->dig_out && !spec->dig_in) + return 0; + + info++; + info->name = "CA0110 Digital"; + info->pcm_type = HDA_PCM_TYPE_SPDIF; + if (spec->dig_out) { + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = + ca0110_pcm_digital_playback; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out; + } + if (spec->dig_in) { + info->stream[SNDRV_PCM_STREAM_CAPTURE] = + ca0110_pcm_digital_capture; + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in; + } + codec->num_pcms++; + + return 0; +} + +static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) +{ + if (pin) { + snd_hda_codec_write(codec, pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); + if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); + } + if (dac) + snd_hda_codec_write(codec, dac, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); +} + +static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) +{ + if (pin) { + snd_hda_codec_write(codec, pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80); + if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) + snd_hda_codec_write(codec, pin, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(0)); + } + if (adc) + snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(0)); +} + +static int ca0110_init(struct hda_codec *codec) +{ + struct ca0110_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + int i; + + for (i = 0; i < spec->multiout.num_dacs; i++) + init_output(codec, spec->out_pins[i], + spec->multiout.dac_nids[i]); + init_output(codec, cfg->hp_pins[0], spec->hp_dac); + init_output(codec, cfg->dig_out_pins[0], spec->dig_out); + + for (i = 0; i < spec->num_inputs; i++) + init_input(codec, spec->input_pins[i], spec->adcs[i]); + init_input(codec, cfg->dig_in_pin, spec->dig_in); + return 0; +} + +static void ca0110_free(struct hda_codec *codec) +{ + kfree(codec->spec); +} + +static struct hda_codec_ops ca0110_patch_ops = { + .build_controls = ca0110_build_controls, + .build_pcms = ca0110_build_pcms, + .init = ca0110_init, + .free = ca0110_free, +}; + + +static void parse_line_outs(struct hda_codec *codec) +{ + struct ca0110_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + int i, n; + unsigned int def_conf; + hda_nid_t nid; + + n = 0; + for (i = 0; i < cfg->line_outs; i++) { + nid = cfg->line_out_pins[i]; + def_conf = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + if (!def_conf) + continue; /* invalid pin */ + if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1) + continue; + spec->out_pins[n++] = nid; + } + spec->multiout.dac_nids = spec->dacs; + spec->multiout.num_dacs = n; +} + +static void parse_hp_out(struct hda_codec *codec) +{ + struct ca0110_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + int i; + unsigned int def_conf; + hda_nid_t nid, dac; + + if (!cfg->hp_outs) + return; + nid = cfg->hp_pins[0]; + def_conf = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + if (!def_conf) { + cfg->hp_outs = 0; + return; + } + if (snd_hda_get_connections(codec, nid, &dac, 1) != 1) + return; + + for (i = 0; i < cfg->line_outs; i++) + if (dac == spec->dacs[i]) + break; + if (i >= cfg->line_outs) { + spec->hp_dac = dac; + spec->multiout.hp_nid = dac; + } +} + +static void parse_input(struct hda_codec *codec) +{ + struct ca0110_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + hda_nid_t nid, pin; + int n, i, j; + + n = 0; + nid = codec->start_nid; + for (i = 0; i < codec->num_nodes; i++, nid++) { + unsigned int wcaps = get_wcaps(codec, nid); + unsigned int type = (wcaps & AC_WCAP_TYPE) >> + AC_WCAP_TYPE_SHIFT; + if (type != AC_WID_AUD_IN) + continue; + if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) + continue; + if (pin == cfg->dig_in_pin) { + spec->dig_in = nid; + continue; + } + for (j = 0; j < AUTO_PIN_LAST; j++) + if (cfg->input_pins[j] == pin) + break; + if (j >= AUTO_PIN_LAST) + continue; + spec->input_pins[n] = pin; + spec->input_labels[n] = auto_pin_cfg_labels[j]; + spec->adcs[n] = nid; + n++; + } + spec->num_inputs = n; +} + +static void parse_digital(struct hda_codec *codec) +{ + struct ca0110_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + + if (cfg->dig_outs && + snd_hda_get_connections(codec, cfg->dig_out_pins[0], + &spec->dig_out, 1) == 1) + spec->multiout.dig_out_nid = cfg->dig_out_pins[0]; +} + +static int ca0110_parse_auto_config(struct hda_codec *codec) +{ + struct ca0110_spec *spec = codec->spec; + int err; + + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); + if (err < 0) + return err; + + parse_line_outs(codec); + parse_hp_out(codec); + parse_digital(codec); + parse_input(codec); + return 0; +} + + +int patch_ca0110(struct hda_codec *codec) +{ + struct ca0110_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + codec->spec = spec; + + codec->bus->needs_damn_long_delay = 1; + + err = ca0110_parse_auto_config(codec); + if (err < 0) + goto error; + + codec->patch_ops = ca0110_patch_ops; + + return 0; + + error: + kfree(codec->spec); + codec->spec = NULL; + return err; +} + + +/* + * patch entries + */ +static struct hda_codec_preset snd_hda_preset_ca0110[] = { + { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, + { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, + { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, + {} /* terminator */ +}; + +MODULE_ALIAS("snd-hda-codec-id:1102000a"); +MODULE_ALIAS("snd-hda-codec-id:1102000b"); +MODULE_ALIAS("snd-hda-codec-id:1102000d"); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Creative CA0110-IBG HD-audio codec"); + +static struct hda_codec_preset_list ca0110_list = { + .preset = snd_hda_preset_ca0110, + .owner = THIS_MODULE, +}; + +static int __init patch_ca0110_init(void) +{ + return snd_hda_add_codec_preset(&ca0110_list); +} + +static void __exit patch_ca0110_exit(void) +{ + snd_hda_delete_codec_preset(&ca0110_list); +} + +module_init(patch_ca0110_init) +module_exit(patch_ca0110_exit) -- GitLab From b8b47bfbe4eb1ae0e6891e49c86a5f4fb00413be Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 11 Mar 2009 15:41:51 +0900 Subject: [PATCH 0292/6080] sh: pass along struct pci_channel These patches rework the pci code for the sh architecture. Currently each board implements some kind of ioport to address mapping. Some boards use generic_io_base others try passing addresses as io ports. This is the first set of patches that try to unify the pci code as much as possible to avoid duplicated code. This will in the end lead to fewer lines board specific code and more generic code. This patch makes sure a struct pci_channel pointer is passed along to various pci functions such as pci_read_reg(), pci_write_reg(), pci_fixup_pcic(), sh7751_pcic_init() and sh7780_pcic_init(). Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/fixups-lboxre2.c | 23 +++++---- arch/sh/drivers/pci/fixups-r7780rp.c | 33 ++++++------ arch/sh/drivers/pci/fixups-rts7751r2d.c | 23 +++++---- arch/sh/drivers/pci/fixups-sdk7780.c | 46 +++++++++-------- arch/sh/drivers/pci/fixups-se7780.c | 32 ++++++------ arch/sh/drivers/pci/ops-landisk.c | 2 +- arch/sh/drivers/pci/ops-lboxre2.c | 2 +- arch/sh/drivers/pci/ops-r7780rp.c | 2 +- arch/sh/drivers/pci/ops-rts7751r2d.c | 2 +- arch/sh/drivers/pci/ops-sdk7780.c | 2 +- arch/sh/drivers/pci/ops-se7780.c | 2 +- arch/sh/drivers/pci/ops-sh4.c | 24 ++++----- arch/sh/drivers/pci/ops-snapgear.c | 2 +- arch/sh/drivers/pci/ops-titan.c | 2 +- arch/sh/drivers/pci/pci-sh4.h | 11 ++-- arch/sh/drivers/pci/pci-sh7751.c | 68 +++++++++++++------------ arch/sh/drivers/pci/pci-sh7751.h | 3 +- arch/sh/drivers/pci/pci-sh7780.c | 31 +++++------ arch/sh/drivers/pci/pci-sh7780.h | 3 +- 19 files changed, 164 insertions(+), 149 deletions(-) diff --git a/arch/sh/drivers/pci/fixups-lboxre2.c b/arch/sh/drivers/pci/fixups-lboxre2.c index 1c1d41255ec0..a82011d03cb0 100644 --- a/arch/sh/drivers/pci/fixups-lboxre2.c +++ b/arch/sh/drivers/pci/fixups-lboxre2.c @@ -9,33 +9,34 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ +#include #include "pci-sh4.h" #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB -int pci_fixup_pcic(void) +int pci_fixup_pcic(struct pci_channel *chan) { unsigned long bcr1, mcr; bcr1 = ctrl_inl(SH7751_BCR1); bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ - pci_write_reg(bcr1, SH4_PCIBCR1); + pci_write_reg(chan, bcr1, SH4_PCIBCR1); /* Enable all interrupts, so we known what to fix */ - pci_write_reg(0x0000c3ff, SH4_PCIINTM); - pci_write_reg(0x0000380f, SH4_PCIAINTM); - pci_write_reg(0xfb900047, SH7751_PCICONF1); - pci_write_reg(0xab000001, SH7751_PCICONF4); + pci_write_reg(chan, 0x0000c3ff, SH4_PCIINTM); + pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); + pci_write_reg(chan, 0xfb900047, SH7751_PCICONF1); + pci_write_reg(chan, 0xab000001, SH7751_PCICONF4); mcr = ctrl_inl(SH7751_MCR); mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; - pci_write_reg(mcr, SH4_PCIMCR); + pci_write_reg(chan, mcr, SH4_PCIMCR); - pci_write_reg(0x0c000000, SH7751_PCICONF5); - pci_write_reg(0xd0000000, SH7751_PCICONF6); - pci_write_reg(0x0c000000, SH4_PCILAR0); - pci_write_reg(0x00000000, SH4_PCILAR1); + pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5); + pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6); + pci_write_reg(chan, 0x0c000000, SH4_PCILAR0); + pci_write_reg(chan, 0x00000000, SH4_PCILAR1); return 0; } diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 3e321df65d22..5b25021bbd62 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -14,32 +14,33 @@ #include "pci-sh4.h" #include -int pci_fixup_pcic(void) +int pci_fixup_pcic(struct pci_channel *chan) { - pci_write_reg(0x000043ff, SH4_PCIINTM); - pci_write_reg(0x0000380f, SH4_PCIAINTM); + pci_write_reg(chan, 0x000043ff, SH4_PCIINTM); + pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); - pci_write_reg(0xfbb00047, SH7780_PCICMD); - pci_write_reg(0x00000000, SH7780_PCIIBAR); + pci_write_reg(chan, 0xfbb00047, SH7780_PCICMD); + pci_write_reg(chan, 0x00000000, SH7780_PCIIBAR); - pci_write_reg(0x00011912, SH7780_PCISVID); - pci_write_reg(0x08000000, SH7780_PCICSCR0); - pci_write_reg(0x0000001b, SH7780_PCICSAR0); - pci_write_reg(0xfd000000, SH7780_PCICSCR1); - pci_write_reg(0x0000000f, SH7780_PCICSAR1); + pci_write_reg(chan, 0x00011912, SH7780_PCISVID); + pci_write_reg(chan, 0x08000000, SH7780_PCICSCR0); + pci_write_reg(chan, 0x0000001b, SH7780_PCICSAR0); + pci_write_reg(chan, 0xfd000000, SH7780_PCICSCR1); + pci_write_reg(chan, 0x0000000f, SH7780_PCICSAR1); - pci_write_reg(0xfd000000, SH7780_PCIMBR0); - pci_write_reg(0x00fc0000, SH7780_PCIMBMR0); + pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0); + pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0); #ifdef CONFIG_32BIT - pci_write_reg(0xc0000000, SH7780_PCIMBR2); - pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); + pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2); + pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); #endif /* Set IOBR for windows containing area specified in pci.h */ - pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)), + pci_write_reg(chan, (PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)), SH7780_PCIIOBR); - pci_write_reg(((SH7780_PCI_IO_SIZE-1) & (7<<18)), SH7780_PCIIOBMR); + pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)), + SH7780_PCIIOBMR); return 0; } diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index 904bce8768d3..38852334d479 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -10,34 +10,35 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ +#include #include "pci-sh4.h" #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB -int pci_fixup_pcic(void) +int pci_fixup_pcic(struct pci_channel *chan) { unsigned long bcr1, mcr; bcr1 = ctrl_inl(SH7751_BCR1); bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ - pci_write_reg(bcr1, SH4_PCIBCR1); + pci_write_reg(chan, bcr1, SH4_PCIBCR1); /* Enable all interrupts, so we known what to fix */ - pci_write_reg(0x0000c3ff, SH4_PCIINTM); - pci_write_reg(0x0000380f, SH4_PCIAINTM); + pci_write_reg(chan, 0x0000c3ff, SH4_PCIINTM); + pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); - pci_write_reg(0xfb900047, SH7751_PCICONF1); - pci_write_reg(0xab000001, SH7751_PCICONF4); + pci_write_reg(chan, 0xfb900047, SH7751_PCICONF1); + pci_write_reg(chan, 0xab000001, SH7751_PCICONF4); mcr = ctrl_inl(SH7751_MCR); mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; - pci_write_reg(mcr, SH4_PCIMCR); + pci_write_reg(chan, mcr, SH4_PCIMCR); - pci_write_reg(0x0c000000, SH7751_PCICONF5); - pci_write_reg(0xd0000000, SH7751_PCICONF6); - pci_write_reg(0x0c000000, SH4_PCILAR0); - pci_write_reg(0x00000000, SH4_PCILAR1); + pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5); + pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6); + pci_write_reg(chan, 0x0c000000, SH4_PCILAR0); + pci_write_reg(chan, 0x00000000, SH4_PCILAR1); return 0; } diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index 2f8863099dd1..3f6754a120ed 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -14,46 +14,48 @@ #include "pci-sh4.h" #include -int pci_fixup_pcic(void) +int pci_fixup_pcic(struct pci_channel *chan) { ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable all interrupts, so we know what to fix */ - pci_write_reg(0x0000C3FF, SH7780_PCIIMR); - pci_write_reg(0x0000380F, SH7780_PCIAINTM); + pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR); + pci_write_reg(chan, 0x0000380F, SH7780_PCIAINTM); /* Set up standard PCI config registers */ - pci_write_reg(0xFB00, SH7780_PCISTATUS); - pci_write_reg(0x0047, SH7780_PCICMD); - pci_write_reg(0x00, SH7780_PCIPIF); - pci_write_reg(0x00, SH7780_PCISUB); - pci_write_reg(0x06, SH7780_PCIBCC); - pci_write_reg(0x1912, SH7780_PCISVID); - pci_write_reg(0x0001, SH7780_PCISID); + pci_write_reg(chan, 0xFB00, SH7780_PCISTATUS); + pci_write_reg(chan, 0x0047, SH7780_PCICMD); + pci_write_reg(chan, 0x00, SH7780_PCIPIF); + pci_write_reg(chan, 0x00, SH7780_PCISUB); + pci_write_reg(chan, 0x06, SH7780_PCIBCC); + pci_write_reg(chan, 0x1912, SH7780_PCISVID); + pci_write_reg(chan, 0x0001, SH7780_PCISID); - pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */ - pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */ - pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ + pci_write_reg(chan, 0x08000000, SH7780_PCIMBAR0); /* PCI */ + pci_write_reg(chan, 0x08000000, SH7780_PCILAR0); /* SHwy */ + pci_write_reg(chan, 0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ - pci_write_reg(0x00000000, SH7780_PCIMBAR1); - pci_write_reg(0x00000000, SH7780_PCILAR1); - pci_write_reg(0x00000000, SH7780_PCILSR1); + pci_write_reg(chan, 0x00000000, SH7780_PCIMBAR1); + pci_write_reg(chan, 0x00000000, SH7780_PCILAR1); + pci_write_reg(chan, 0x00000000, SH7780_PCILSR1); - pci_write_reg(0xAB000801, SH7780_PCIIBAR); + pci_write_reg(chan, 0xAB000801, SH7780_PCIIBAR); /* * Set the MBR so PCI address is one-to-one with window, * meaning all calls go straight through... use ifdef to * catch erroneous assumption. */ - pci_write_reg(0xFD000000 , SH7780_PCIMBR0); - pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ + pci_write_reg(chan, 0xFD000000 , SH7780_PCIMBR0); + pci_write_reg(chan, 0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ /* Set IOBR for window containing area specified in pci.h */ - pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); - pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR); + pci_write_reg(chan, PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), + SH7780_PCIIOBR); + pci_write_reg(chan, (SH7780_PCI_IO_SIZE-1) & (7 << 18), + SH7780_PCIIOBMR); - pci_write_reg(0xA5000C01, SH7780_PCICR); + pci_write_reg(chan, 0xA5000C01, SH7780_PCICR); return 0; } diff --git a/arch/sh/drivers/pci/fixups-se7780.c b/arch/sh/drivers/pci/fixups-se7780.c index 880cea1c0d89..b8e735e01c3c 100644 --- a/arch/sh/drivers/pci/fixups-se7780.c +++ b/arch/sh/drivers/pci/fixups-se7780.c @@ -15,13 +15,13 @@ #include "pci-sh4.h" #include -int pci_fixup_pcic(void) +int pci_fixup_pcic(struct pci_channel *chan) { ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable all interrupts, so we know what to fix */ - pci_write_reg(0x0000C3FF, SH7780_PCIIMR); - pci_write_reg(0x0000380F, SH7780_PCIAINTM); + pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR); + pci_write_reg(chan, 0x0000380F, SH7780_PCIAINTM); /* Set up standard PCI config registers */ ctrl_outw(0xFB00, PCI_REG(SH7780_PCISTATUS)); @@ -32,29 +32,31 @@ int pci_fixup_pcic(void) ctrl_outw(0x1912, PCI_REG(SH7780_PCISVID)); ctrl_outw(0x0001, PCI_REG(SH7780_PCISID)); - pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */ - pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */ - pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ + pci_write_reg(chan, 0x08000000, SH7780_PCIMBAR0); /* PCI */ + pci_write_reg(chan, 0x08000000, SH7780_PCILAR0); /* SHwy */ + pci_write_reg(chan, 0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ - pci_write_reg(0x00000000, SH7780_PCIMBAR1); - pci_write_reg(0x00000000, SH7780_PCILAR1); - pci_write_reg(0x00000000, SH7780_PCILSR1); + pci_write_reg(chan, 0x00000000, SH7780_PCIMBAR1); + pci_write_reg(chan, 0x00000000, SH7780_PCILAR1); + pci_write_reg(chan, 0x00000000, SH7780_PCILSR1); - pci_write_reg(0xAB000801, SH7780_PCIIBAR); + pci_write_reg(chan, 0xAB000801, SH7780_PCIIBAR); /* * Set the MBR so PCI address is one-to-one with window, * meaning all calls go straight through... use ifdef to * catch erroneous assumption. */ - pci_write_reg(0xFD000000 , SH7780_PCIMBR0); - pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ + pci_write_reg(chan, 0xFD000000 , SH7780_PCIMBR0); + pci_write_reg(chan, 0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ /* Set IOBR for window containing area specified in pci.h */ - pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); - pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR); + pci_write_reg(chan, PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), + SH7780_PCIIOBR); + pci_write_reg(chan, (SH7780_PCI_IO_SIZE-1) & (7 << 18), + SH7780_PCIIOBMR); - pci_write_reg(0xA5000C01, SH7780_PCICR); + pci_write_reg(chan, 0xA5000C01, SH7780_PCICR); return 0; } diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c index bff09ecf3419..343c072a5a79 100644 --- a/arch/sh/drivers/pci/ops-landisk.c +++ b/arch/sh/drivers/pci/ops-landisk.c @@ -45,7 +45,7 @@ static struct sh4_pci_address_map sh7751_pci_map = { int __init pcibios_init_platform(void) { - return sh7751_pcic_init(&sh7751_pci_map); + return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); } int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c index 86c0b6fb7375..8bff32a22101 100644 --- a/arch/sh/drivers/pci/ops-lboxre2.c +++ b/arch/sh/drivers/pci/ops-lboxre2.c @@ -59,5 +59,5 @@ static struct sh4_pci_address_map sh7751_pci_map = { int __init pcibios_init_platform(void) { - return sh7751_pcic_init(&sh7751_pci_map); + return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); } diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c index 8555238e63eb..bf32ee8b1321 100644 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ b/arch/sh/drivers/pci/ops-r7780rp.c @@ -64,5 +64,5 @@ static struct sh4_pci_address_map sh7780_pci_map = { int __init pcibios_init_platform(void) { - return sh7780_pcic_init(&sh7780_pci_map); + return sh7780_pcic_init(&board_pci_channels[0], &sh7780_pci_map); } diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index d6ca74b25d5f..e4208a697321 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -69,6 +69,6 @@ static struct sh4_pci_address_map sh7751_pci_map = { int __init pcibios_init_platform(void) { __set_io_port_base(SH7751_PCI_IO_BASE); - return sh7751_pcic_init(&sh7751_pci_map); + return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); } diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c index 4dcc64184b23..21d59d4a2150 100644 --- a/arch/sh/drivers/pci/ops-sdk7780.c +++ b/arch/sh/drivers/pci/ops-sdk7780.c @@ -69,5 +69,5 @@ static struct sh4_pci_address_map sdk7780_pci_map = { int __init pcibios_init_platform(void) { printk(KERN_INFO "SH7780 PCI: Finished initializing PCI controller\n"); - return sh7780_pcic_init(&sdk7780_pci_map); + return sh7780_pcic_init(&board_pci_channels[0], &sdk7780_pci_map); } diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c index 3145c62484d6..78a6f2bc4f12 100644 --- a/arch/sh/drivers/pci/ops-se7780.c +++ b/arch/sh/drivers/pci/ops-se7780.c @@ -92,5 +92,5 @@ int __init pcibios_init_platform(void) ctrl_outw(0x0013, FPGA_PCI_INTSEL1); ctrl_outw(0xE402, FPGA_PCI_INTSEL2); - return sh7780_pcic_init(&se7780_pci_map); + return sh7780_pcic_init(&board_pci_channels[0], &se7780_pci_map); } diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 710a3b0306e5..92d27f734f2e 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c @@ -34,8 +34,8 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, * so we must do byte alignment by hand */ spin_lock_irqsave(&sh4_pci_lock, flags); - pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); - data = pci_read_reg(SH4_PCIPDR); + pci_write_reg(NULL, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); + data = pci_read_reg(NULL, SH4_PCIPDR); spin_unlock_irqrestore(&sh4_pci_lock, flags); switch (size) { @@ -68,8 +68,8 @@ static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, u32 data; spin_lock_irqsave(&sh4_pci_lock, flags); - pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); - data = pci_read_reg(SH4_PCIPDR); + pci_write_reg(NULL, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); + data = pci_read_reg(NULL, SH4_PCIPDR); spin_unlock_irqrestore(&sh4_pci_lock, flags); switch (size) { @@ -90,7 +90,7 @@ static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_FUNC_NOT_SUPPORTED; } - pci_write_reg(data, SH4_PCIPDR); + pci_write_reg(NULL, data, SH4_PCIPDR); return PCIBIOS_SUCCESSFUL; } @@ -106,25 +106,25 @@ struct pci_ops sh4_pci_ops = { */ static unsigned int pci_probe = PCI_PROBE_CONF1; -int __init sh4_pci_check_direct(void) +int __init sh4_pci_check_direct(struct pci_channel *chan) { /* * Check if configuration works. */ if (pci_probe & PCI_PROBE_CONF1) { - unsigned int tmp = pci_read_reg(SH4_PCIPAR); + unsigned int tmp = pci_read_reg(chan, SH4_PCIPAR); - pci_write_reg(P1SEG, SH4_PCIPAR); + pci_write_reg(chan, P1SEG, SH4_PCIPAR); - if (pci_read_reg(SH4_PCIPAR) == P1SEG) { - pci_write_reg(tmp, SH4_PCIPAR); + if (pci_read_reg(chan, SH4_PCIPAR) == P1SEG) { + pci_write_reg(chan, tmp, SH4_PCIPAR); printk(KERN_INFO "PCI: Using configuration type 1\n"); request_region(PCI_REG(SH4_PCIPAR), 8, "PCI conf1"); return 0; } - pci_write_reg(tmp, SH4_PCIPAR); + pci_write_reg(chan, tmp, SH4_PCIPAR); } pr_debug("PCI: pci_check_direct failed\n"); @@ -163,7 +163,7 @@ char * __devinit pcibios_setup(char *str) return str; } -int __attribute__((weak)) pci_fixup_pcic(void) +int __attribute__((weak)) pci_fixup_pcic(struct pci_channel *chan) { /* Nothing to do. */ return 0; diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c index 53dd893d4e54..cba80153dde9 100644 --- a/arch/sh/drivers/pci/ops-snapgear.c +++ b/arch/sh/drivers/pci/ops-snapgear.c @@ -66,7 +66,7 @@ static struct sh4_pci_address_map sh7751_pci_map = { */ int __init pcibios_init_platform(void) { - return sh7751_pcic_init(&sh7751_pci_map); + return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); } int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c index a8f7801a34af..69fcc5c5d520 100644 --- a/arch/sh/drivers/pci/ops-titan.c +++ b/arch/sh/drivers/pci/ops-titan.c @@ -73,5 +73,5 @@ static struct sh4_pci_address_map sh7751_pci_map = { int __init pcibios_init_platform(void) { - return sh7751_pcic_init(&sh7751_pci_map); + return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); } diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h index a83dcf70c13b..62ba35056087 100644 --- a/arch/sh/drivers/pci/pci-sh4.h +++ b/arch/sh/drivers/pci/pci-sh4.h @@ -154,8 +154,8 @@ /* arch/sh/kernel/drivers/pci/ops-sh4.c */ extern struct pci_ops sh4_pci_ops; -int sh4_pci_check_direct(void); -int pci_fixup_pcic(void); +int sh4_pci_check_direct(struct pci_channel *chan); +int pci_fixup_pcic(struct pci_channel *chan); struct sh4_pci_address_space { unsigned long base; @@ -168,13 +168,16 @@ struct sh4_pci_address_map { unsigned long flags; }; -static inline void pci_write_reg(unsigned long val, unsigned long reg) +static inline void pci_write_reg(struct pci_channel *chan, + unsigned long val, unsigned long reg) { ctrl_outl(val, PCI_REG(reg)); } -static inline unsigned long pci_read_reg(unsigned long reg) +static inline unsigned long pci_read_reg(struct pci_channel *chan, + unsigned long reg) { return ctrl_inl(PCI_REG(reg)); } + #endif /* __PCI_SH4_H */ diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 3065eb184f01..9c2c01490d62 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -40,21 +40,22 @@ static int __init sh7751_pci_init(void) pr_debug("PCI: Starting intialization.\n"); /* check for SH7751/SH7751R hardware */ - id = pci_read_reg(SH7751_PCICONF0); + id = pci_read_reg(NULL, SH7751_PCICONF0); if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); return -ENODEV; } - if ((ret = sh4_pci_check_direct()) != 0) + if ((ret = sh4_pci_check_direct(NULL)) != 0) return ret; return pcibios_init_platform(); } subsys_initcall(sh7751_pci_init); -static int __init __area_sdram_check(unsigned int area) +static int __init __area_sdram_check(struct pci_channel *chan, + unsigned int area) { u32 word; @@ -65,7 +66,7 @@ static int __init __area_sdram_check(unsigned int area) area, word); return 0; } - pci_write_reg(word, SH4_PCIBCR1); + pci_write_reg(chan, word, SH4_PCIBCR1); word = (u16)ctrl_inw(SH7751_BCR2); /* check BCR2 for 32bit SDRAM interface*/ @@ -74,12 +75,13 @@ static int __init __area_sdram_check(unsigned int area) area, word); return 0; } - pci_write_reg(word, SH4_PCIBCR2); + pci_write_reg(chan, word, SH4_PCIBCR2); return 1; } -int __init sh7751_pcic_init(struct sh4_pci_address_map *map) +int __init sh7751_pcic_init(struct pci_channel *chan, + struct sh4_pci_address_map *map) { u32 reg; u32 word; @@ -90,10 +92,10 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) ctrl_outl(reg, SH7751_BCR1); /* Turn the clocks back on (not done in reset)*/ - pci_write_reg(0, SH4_PCICLKR); + pci_write_reg(chan, 0, SH4_PCICLKR); /* Clear Powerdown IRQ's (not done in reset) */ word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; - pci_write_reg(word, SH4_PCIPINT); + pci_write_reg(chan, word, SH4_PCIPINT); /* * This code is unused for some boards as it is done in the @@ -103,11 +105,11 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) if (!(map->flags & SH4_PCIC_NO_RESET)) { /* toggle PCI reset pin */ word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; - pci_write_reg(word, SH4_PCICR); + pci_write_reg(chan, word, SH4_PCICR); /* Wait for a long time... not 1 sec. but long enough */ mdelay(100); word = SH4_PCICR_PREFIX; - pci_write_reg(word, SH4_PCICR); + pci_write_reg(chan, word, SH4_PCICR); } /* set the command/status bits to: @@ -116,11 +118,11 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) */ word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; - pci_write_reg(word, SH7751_PCICONF1); + pci_write_reg(chan, word, SH7751_PCICONF1); /* define this host as the host bridge */ word = PCI_BASE_CLASS_BRIDGE << 24; - pci_write_reg(word, SH7751_PCICONF2); + pci_write_reg(chan, word, SH7751_PCICONF2); /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping @@ -128,24 +130,24 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * Window1 = map->window1.size @ cached area base = SDRAM */ word = map->window0.size - 1; - pci_write_reg(word, SH4_PCILSR0); + pci_write_reg(chan, word, SH4_PCILSR0); word = map->window1.size - 1; - pci_write_reg(word, SH4_PCILSR1); + pci_write_reg(chan, word, SH4_PCILSR1); /* Set the values on window 0 PCI config registers */ word = P2SEGADDR(map->window0.base); - pci_write_reg(word, SH4_PCILAR0); - pci_write_reg(word, SH7751_PCICONF5); + pci_write_reg(chan, word, SH4_PCILAR0); + pci_write_reg(chan, word, SH7751_PCICONF5); /* Set the values on window 1 PCI config registers */ word = PHYSADDR(map->window1.base); - pci_write_reg(word, SH4_PCILAR1); - pci_write_reg(word, SH7751_PCICONF6); + pci_write_reg(chan, word, SH4_PCILAR1); + pci_write_reg(chan, word, SH7751_PCICONF6); /* Set the local 16MB PCI memory space window to * the lowest PCI mapped address */ word = PCIBIOS_MIN_MEM & SH4_PCIMBR_MASK; pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); - pci_write_reg(word , SH4_PCIMBR); + pci_write_reg(chan, word , SH4_PCIMBR); /* Map IO space into PCI IO window * The IO window is 64K-PCIBIOS_MIN_IO in size @@ -160,19 +162,19 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * correctly */ word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK; pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); - pci_write_reg(word, SH4_PCIIOBR); + pci_write_reg(chan, word, SH4_PCIIOBR); /* Set PCI WCRx, BCRx's, copy from BSC locations */ /* check BCR for SDRAM in specified area */ switch (map->window0.base) { - case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(0); break; - case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(1); break; - case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(2); break; - case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(3); break; - case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(4); break; - case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break; - case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break; + case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(chan, 0); break; + case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(chan, 1); break; + case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(chan, 2); break; + case SH7751_CS3_BASE_ADDR: word = __area_sdram_check(chan, 3); break; + case SH7751_CS4_BASE_ADDR: word = __area_sdram_check(chan, 4); break; + case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(chan, 5); break; + case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(chan, 6); break; } if (!word) @@ -180,25 +182,25 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) /* configure the wait control registers */ word = ctrl_inl(SH7751_WCR1); - pci_write_reg(word, SH4_PCIWCR1); + pci_write_reg(chan, word, SH4_PCIWCR1); word = ctrl_inl(SH7751_WCR2); - pci_write_reg(word, SH4_PCIWCR2); + pci_write_reg(chan, word, SH4_PCIWCR2); word = ctrl_inl(SH7751_WCR3); - pci_write_reg(word, SH4_PCIWCR3); + pci_write_reg(chan, word, SH4_PCIWCR3); word = ctrl_inl(SH7751_MCR); - pci_write_reg(word, SH4_PCIMCR); + pci_write_reg(chan, word, SH4_PCIMCR); /* NOTE: I'm ignoring the PCI error IRQs for now.. * TODO: add support for the internal error interrupts and * DMA interrupts... */ - pci_fixup_pcic(); + pci_fixup_pcic(chan); /* SH7751 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; - pci_write_reg(word, SH4_PCICR); + pci_write_reg(chan, word, SH4_PCICR); return 1; } diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h index 68e3cb5e6bec..6f101e5a6c83 100644 --- a/arch/sh/drivers/pci/pci-sh7751.h +++ b/arch/sh/drivers/pci/pci-sh7751.h @@ -130,6 +130,7 @@ struct sh4_pci_address_map; /* arch/sh/drivers/pci/pci-sh7751.c */ -int sh7751_pcic_init(struct sh4_pci_address_map *map); +int sh7751_pcic_init(struct pci_channel *chan, + struct sh4_pci_address_map *map); #endif /* _PCI_SH7751_H_ */ diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index bae6a2cf047d..56f673f66cb5 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -55,7 +55,7 @@ static int __init sh7780_pci_init(void) ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ /* check for SH7780/SH7780R hardware */ - id = pci_read_reg(SH7780_PCIVID); + id = pci_read_reg(NULL, SH7780_PCIVID); if ((id & 0xffff) == SH7780_VENDOR_ID) { switch ((id >> 16) & 0xffff) { case SH7763_DEVICE_ID: @@ -82,14 +82,15 @@ static int __init sh7780_pci_init(void) ctrl_outl(0x33333333, INTC_INTPRI); } - if ((ret = sh4_pci_check_direct()) != 0) + if ((ret = sh4_pci_check_direct(NULL)) != 0) return ret; return pcibios_init_platform(); } core_initcall(sh7780_pci_init); -int __init sh7780_pcic_init(struct sh4_pci_address_map *map) +int __init sh7780_pcic_init(struct pci_channel *chan, + struct sh4_pci_address_map *map) { u32 word; @@ -101,34 +102,34 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map) if (!(map->flags & SH4_PCIC_NO_RESET)) { /* toggle PCI reset pin */ word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; - pci_write_reg(word, SH4_PCICR); + pci_write_reg(chan, word, SH4_PCICR); /* Wait for a long time... not 1 sec. but long enough */ mdelay(100); word = SH4_PCICR_PREFIX; - pci_write_reg(word, SH4_PCICR); + pci_write_reg(chan, word, SH4_PCICR); } /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable */ - pci_write_reg(0x00000046, SH7780_PCICMD); + pci_write_reg(chan, 0x00000046, SH7780_PCICMD); /* define this host as the host bridge */ word = PCI_BASE_CLASS_BRIDGE << 24; - pci_write_reg(word, SH7780_PCIRID); + pci_write_reg(chan, word, SH7780_PCIRID); /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping */ - pci_write_reg(map->window0.size - 0xfffff, SH4_PCILSR0); - pci_write_reg(map->window1.size - 0xfffff, SH4_PCILSR1); + pci_write_reg(chan, map->window0.size - 0xfffff, SH4_PCILSR0); + pci_write_reg(chan, map->window1.size - 0xfffff, SH4_PCILSR1); /* Set the values on window 0 PCI config registers */ - pci_write_reg(map->window0.base, SH4_PCILAR0); - pci_write_reg(map->window0.base, SH7780_PCIMBAR0); + pci_write_reg(chan, map->window0.base, SH4_PCILAR0); + pci_write_reg(chan, map->window0.base, SH7780_PCIMBAR0); /* Set the values on window 1 PCI config registers */ - pci_write_reg(map->window1.base, SH4_PCILAR1); - pci_write_reg(map->window1.base, SH7780_PCIMBAR1); + pci_write_reg(chan, map->window1.base, SH4_PCILAR1); + pci_write_reg(chan, map->window1.base, SH7780_PCIMBAR1); /* Map IO space into PCI IO window * The IO window is 64K-PCIBIOS_MIN_IO in size @@ -145,12 +146,12 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map) */ /* Apply any last-minute PCIC fixups */ - pci_fixup_pcic(); + pci_fixup_pcic(chan); /* SH7780 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; - pci_write_reg(word, SH4_PCICR); + pci_write_reg(chan, word, SH4_PCICR); return 1; } diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index 93adc7119b79..d34961153d58 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -109,6 +109,7 @@ struct sh4_pci_address_map; /* arch/sh/drivers/pci/pci-sh7780.c */ -int sh7780_pcic_init(struct sh4_pci_address_map *map); +int sh7780_pcic_init(struct pci_channel *chan, + struct sh4_pci_address_map *map); #endif /* _PCI_SH7780_H_ */ -- GitLab From d0e3db40e2a1352aa2a2f425a7d4631bddc03d51 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 11 Mar 2009 15:46:14 +0900 Subject: [PATCH 0293/6080] sh: add init member to pci_channel data This patch adds an init callback to struct pci_channel and makes sure it is initialized properly. Code is added to call this init function from pcibios_init(). Return values are adjusted and a warning is is printed if init fails. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-dreamcast/setup.c | 6 ------ arch/sh/drivers/pci/ops-cayman.c | 2 +- arch/sh/drivers/pci/ops-dreamcast.c | 18 ++++++++---------- arch/sh/drivers/pci/ops-landisk.c | 2 +- arch/sh/drivers/pci/ops-lboxre2.c | 2 +- arch/sh/drivers/pci/ops-r7780rp.c | 2 +- arch/sh/drivers/pci/ops-rts7751r2d.c | 2 +- arch/sh/drivers/pci/ops-sdk7780.c | 2 +- arch/sh/drivers/pci/ops-se7780.c | 2 +- arch/sh/drivers/pci/ops-sh03.c | 2 +- arch/sh/drivers/pci/ops-snapgear.c | 2 +- arch/sh/drivers/pci/ops-titan.c | 2 +- arch/sh/drivers/pci/pci-sh5.c | 6 ++++++ arch/sh/drivers/pci/pci-sh5.h | 1 + arch/sh/drivers/pci/pci-sh7751.c | 11 +++++------ arch/sh/drivers/pci/pci-sh7751.h | 1 + arch/sh/drivers/pci/pci-sh7780.c | 9 ++++----- arch/sh/drivers/pci/pci-sh7780.h | 1 + arch/sh/drivers/pci/pci.c | 23 ++++++++++++++++++----- arch/sh/include/asm/pci.h | 2 ++ 20 files changed, 56 insertions(+), 42 deletions(-) diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c index d1bee4884cd6..ebe99227d4e6 100644 --- a/arch/sh/boards/mach-dreamcast/setup.c +++ b/arch/sh/boards/mach-dreamcast/setup.c @@ -30,7 +30,6 @@ extern struct irq_chip systemasic_int; extern void aica_time_init(void); -extern int gapspci_init(void); extern int systemasic_irq_demux(int); static void __init dreamcast_setup(char **cmdline_p) @@ -51,11 +50,6 @@ static void __init dreamcast_setup(char **cmdline_p) handle_level_irq); board_time_init = aica_time_init; - -#ifdef CONFIG_PCI - if (gapspci_init() < 0) - printk(KERN_WARNING "GAPSPCI was not detected.\n"); -#endif } static struct sh_machine_vector mv_dreamcast __initmv = { diff --git a/arch/sh/drivers/pci/ops-cayman.c b/arch/sh/drivers/pci/ops-cayman.c index 38ef76207af6..f4a5e14f7e5a 100644 --- a/arch/sh/drivers/pci/ops-cayman.c +++ b/arch/sh/drivers/pci/ops-cayman.c @@ -77,7 +77,7 @@ int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) } struct pci_channel board_pci_channels[] = { - { &sh5_pci_ops, NULL, NULL, 0, 0xff }, + { sh5_pci_init, &sh5_pci_ops, NULL, NULL, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c index f5d2a2aa6f3f..f62063eb6490 100644 --- a/arch/sh/drivers/pci/ops-dreamcast.c +++ b/arch/sh/drivers/pci/ops-dreamcast.c @@ -42,15 +42,6 @@ static struct resource gapspci_mem_resource = { .flags = IORESOURCE_MEM, }; -static struct pci_ops gapspci_pci_ops; - -struct pci_channel board_pci_channels[] = { - { &gapspci_pci_ops, &gapspci_io_resource, - &gapspci_mem_resource, 0, 1 }, - { 0, } -}; -EXPORT_SYMBOL(board_pci_channels); - /* * The !gapspci_config_access case really shouldn't happen, ever, unless * someone implicitly messes around with the last devfn value.. otherwise we @@ -116,7 +107,7 @@ static struct pci_ops gapspci_pci_ops = { * gapspci init */ -int __init gapspci_init(void) +static int __init gapspci_init(struct pci_channel *chan) { char idbuf[16]; int i; @@ -168,3 +159,10 @@ char * __devinit pcibios_setup(char *str) { return str; } + +struct pci_channel board_pci_channels[] = { + { gapspci_init, &gapspci_pci_ops, &gapspci_io_resource, + &gapspci_mem_resource, 0, 1 }, + { 0, } +}; +EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c index 343c072a5a79..c46911d95eca 100644 --- a/arch/sh/drivers/pci/ops-landisk.c +++ b/arch/sh/drivers/pci/ops-landisk.c @@ -30,7 +30,7 @@ static struct resource sh7751_mem_resource = { }; struct pci_channel board_pci_channels[] = { - {&sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff}, + { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff}, {NULL, NULL, NULL, 0, 0}, }; diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c index 8bff32a22101..f606df2195c1 100644 --- a/arch/sh/drivers/pci/ops-lboxre2.c +++ b/arch/sh/drivers/pci/ops-lboxre2.c @@ -39,7 +39,7 @@ static struct resource sh7751_mem_resource = { extern struct pci_ops sh7751_pci_ops; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c index bf32ee8b1321..b51b7e4078d0 100644 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ b/arch/sh/drivers/pci/ops-r7780rp.c @@ -43,7 +43,7 @@ static struct resource sh7780_mem_resource = { extern struct pci_ops sh7780_pci_ops; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff }, + { sh7780_pci_init, &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index e4208a697321..fe5a231b8669 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -47,7 +47,7 @@ static struct resource sh7751_mem_resource = { extern struct pci_ops sh7751_pci_ops; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c index 21d59d4a2150..7277cd15ae6a 100644 --- a/arch/sh/drivers/pci/ops-sdk7780.c +++ b/arch/sh/drivers/pci/ops-sdk7780.c @@ -49,7 +49,7 @@ static struct resource sdk7780_mem_resource = { }; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff }, + { sh7780_pci_init, &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c index 78a6f2bc4f12..76a74fb42fb0 100644 --- a/arch/sh/drivers/pci/ops-se7780.c +++ b/arch/sh/drivers/pci/ops-se7780.c @@ -58,7 +58,7 @@ static struct resource se7780_mem_resource = { extern struct pci_ops se7780_pci_ops; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff }, + { sh7780_pci_init, &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c index e1703ff5a4d2..0218135f0bb8 100644 --- a/arch/sh/drivers/pci/ops-sh03.c +++ b/arch/sh/drivers/pci/ops-sh03.c @@ -39,7 +39,7 @@ static struct resource sh7751_mem_resource = { extern struct pci_ops sh4_pci_ops; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c index cba80153dde9..2e254c6cf6c1 100644 --- a/arch/sh/drivers/pci/ops-snapgear.c +++ b/arch/sh/drivers/pci/ops-snapgear.c @@ -40,7 +40,7 @@ static struct resource sh7751_mem_resource = { }; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { 0, } }; diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c index 69fcc5c5d520..ffa79bdf4755 100644 --- a/arch/sh/drivers/pci/ops-titan.c +++ b/arch/sh/drivers/pci/ops-titan.c @@ -52,7 +52,7 @@ static struct resource sh7751_mem_resource = { }; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c index 7a97438762c8..008a02ec0d9f 100644 --- a/arch/sh/drivers/pci/pci-sh5.c +++ b/arch/sh/drivers/pci/pci-sh5.c @@ -27,6 +27,12 @@ unsigned long pcicr_virt; unsigned long PCI_IO_AREA; +int __init sh5_pci_init(struct pci_channel *chan) +{ + pr_debug("PCI: Starting intialization.\n"); + return pcibios_init_platform(); +} + /* Rounds a number UP to the nearest power of two. Used for * sizing the PCI window. */ diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h index 7cff3fc04d30..af09f384c7d2 100644 --- a/arch/sh/drivers/pci/pci-sh5.h +++ b/arch/sh/drivers/pci/pci-sh5.h @@ -108,6 +108,7 @@ extern unsigned long pcicr_virt; extern struct pci_ops sh5_pci_ops; /* arch/sh/drivers/pci/pci-sh5.c */ +int sh5_pci_init(struct pci_channel *chan); int sh5pci_init(unsigned long memStart, unsigned long memSize); #endif /* __PCI_SH5_H */ diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 9c2c01490d62..230db8bd9744 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -32,7 +32,7 @@ * space mapping) will be called via the platform defined function * pcibios_init_platform(). */ -static int __init sh7751_pci_init(void) +int __init sh7751_pci_init(struct pci_channel *chan) { unsigned int id; int ret; @@ -40,19 +40,18 @@ static int __init sh7751_pci_init(void) pr_debug("PCI: Starting intialization.\n"); /* check for SH7751/SH7751R hardware */ - id = pci_read_reg(NULL, SH7751_PCICONF0); + id = pci_read_reg(chan, SH7751_PCICONF0); if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); return -ENODEV; } - if ((ret = sh4_pci_check_direct(NULL)) != 0) + if ((ret = sh4_pci_check_direct(chan)) != 0) return ret; return pcibios_init_platform(); } -subsys_initcall(sh7751_pci_init); static int __init __area_sdram_check(struct pci_channel *chan, unsigned int area) @@ -178,7 +177,7 @@ int __init sh7751_pcic_init(struct pci_channel *chan, } if (!word) - return 0; + return -1; /* configure the wait control registers */ word = ctrl_inl(SH7751_WCR1); @@ -202,5 +201,5 @@ int __init sh7751_pcic_init(struct pci_channel *chan, word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; pci_write_reg(chan, word, SH4_PCICR); - return 1; + return 0; } diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h index 6f101e5a6c83..0ea4387df136 100644 --- a/arch/sh/drivers/pci/pci-sh7751.h +++ b/arch/sh/drivers/pci/pci-sh7751.h @@ -130,6 +130,7 @@ struct sh4_pci_address_map; /* arch/sh/drivers/pci/pci-sh7751.c */ +int sh7751_pci_init(struct pci_channel *chan); int sh7751_pcic_init(struct pci_channel *chan, struct sh4_pci_address_map *map); diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 56f673f66cb5..4706e880b087 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -45,7 +45,7 @@ * space mapping) will be called via the platform defined function * pcibios_init_platform(). */ -static int __init sh7780_pci_init(void) +int __init sh7780_pci_init(struct pci_channel *chan) { unsigned int id; int ret, match = 0; @@ -55,7 +55,7 @@ static int __init sh7780_pci_init(void) ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ /* check for SH7780/SH7780R hardware */ - id = pci_read_reg(NULL, SH7780_PCIVID); + id = pci_read_reg(chan, SH7780_PCIVID); if ((id & 0xffff) == SH7780_VENDOR_ID) { switch ((id >> 16) & 0xffff) { case SH7763_DEVICE_ID: @@ -82,12 +82,11 @@ static int __init sh7780_pci_init(void) ctrl_outl(0x33333333, INTC_INTPRI); } - if ((ret = sh4_pci_check_direct(NULL)) != 0) + if ((ret = sh4_pci_check_direct(chan)) != 0) return ret; return pcibios_init_platform(); } -core_initcall(sh7780_pci_init); int __init sh7780_pcic_init(struct pci_channel *chan, struct sh4_pci_address_map *map) @@ -153,5 +152,5 @@ int __init sh7780_pcic_init(struct pci_channel *chan, word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; pci_write_reg(chan, word, SH4_PCICR); - return 1; + return 0; } diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index d34961153d58..2f3c92065ec3 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -109,6 +109,7 @@ struct sh4_pci_address_map; /* arch/sh/drivers/pci/pci-sh7780.c */ +int sh7780_pci_init(struct pci_channel *chan); int sh7780_pcic_init(struct pci_channel *chan, struct sh4_pci_address_map *map); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 0d6ac7a1db49..29ec16e69afa 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -28,18 +28,31 @@ static int __init pcibios_init(void) struct pci_bus *bus; int busno; + /* init channels */ + busno = 0; + for (p = board_pci_channels; p->init; p++) { + if (p->init(p) == 0) + p->enabled = 1; + else + pr_err("Unable to init pci channel %d\n", busno); + busno++; + } + #ifdef CONFIG_PCI_AUTO /* assign resources */ busno = 0; - for (p = board_pci_channels; p->pci_ops != NULL; p++) - busno = pciauto_assign_resources(busno, p) + 1; + for (p = board_pci_channels; p->init; p++) + if (p->enabled) + busno = pciauto_assign_resources(busno, p) + 1; #endif /* scan the buses */ busno = 0; - for (p = board_pci_channels; p->pci_ops != NULL; p++) { - bus = pci_scan_bus(busno, p->pci_ops, p); - busno = bus->subordinate + 1; + for (p = board_pci_channels; p->init; p++) { + if (p->enabled) { + bus = pci_scan_bus(busno, p->pci_ops, p); + busno = bus->subordinate + 1; + } } pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index df1d383e18a5..5c7a8f1d2d54 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -17,11 +17,13 @@ * external) PCI controllers. */ struct pci_channel { + int (*init)(struct pci_channel *chan); struct pci_ops *pci_ops; struct resource *io_resource; struct resource *mem_resource; int first_devfn; int last_devfn; + int enabled; }; /* -- GitLab From 710fa3c81151948ac4d836ef52b57cef91b0ab72 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 11 Mar 2009 15:47:23 +0900 Subject: [PATCH 0294/6080] sh: avoid using PCIBIOS_MIN_xxx Replaces PCIBIOS_MIN_IO and PCIBIOS_MIN_MEM with direct struct pci_channel access. This allows us to have more than one pci channel. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/fixups-r7780rp.c | 2 +- arch/sh/drivers/pci/fixups-sdk7780.c | 2 +- arch/sh/drivers/pci/fixups-se7780.c | 2 +- arch/sh/drivers/pci/pci-sh5.c | 9 ++++++--- arch/sh/drivers/pci/pci-sh7751.c | 14 ++++++-------- arch/sh/drivers/pci/pci-sh7780.c | 10 ++++------ 6 files changed, 19 insertions(+), 20 deletions(-) diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 5b25021bbd62..31f8dfbfcbf5 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -37,7 +37,7 @@ int pci_fixup_pcic(struct pci_channel *chan) #endif /* Set IOBR for windows containing area specified in pci.h */ - pci_write_reg(chan, (PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)), + pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)), SH7780_PCIIOBMR); diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index 3f6754a120ed..c2957312b30b 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -50,7 +50,7 @@ int pci_fixup_pcic(struct pci_channel *chan) pci_write_reg(chan, 0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ /* Set IOBR for window containing area specified in pci.h */ - pci_write_reg(chan, PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), + pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); pci_write_reg(chan, (SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR); diff --git a/arch/sh/drivers/pci/fixups-se7780.c b/arch/sh/drivers/pci/fixups-se7780.c index b8e735e01c3c..a968af7d6f70 100644 --- a/arch/sh/drivers/pci/fixups-se7780.c +++ b/arch/sh/drivers/pci/fixups-se7780.c @@ -51,7 +51,7 @@ int pci_fixup_pcic(struct pci_channel *chan) pci_write_reg(chan, 0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ /* Set IOBR for window containing area specified in pci.h */ - pci_write_reg(chan, PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), + pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); pci_write_reg(chan, (SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR); diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c index 008a02ec0d9f..7750da276284 100644 --- a/arch/sh/drivers/pci/pci-sh5.c +++ b/arch/sh/drivers/pci/pci-sh5.c @@ -206,6 +206,9 @@ int __init sh5pci_init(unsigned long memStart, unsigned long memSize) return 0; } +#define xPCIBIOS_MIN_IO board_pci_channels->io_resource->start +#define xPCIBIOS_MIN_MEM board_pci_channels->mem_resource->start + void __devinit pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev = bus->self; @@ -223,9 +226,9 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) /* For now, propagate host limits to the bus; * we'll adjust them later. */ bus->resource[0]->end = 64*1024 - 1 ; - bus->resource[1]->end = PCIBIOS_MIN_MEM+(256*1024*1024)-1; - bus->resource[0]->start = PCIBIOS_MIN_IO; - bus->resource[1]->start = PCIBIOS_MIN_MEM; + bus->resource[1]->end = xPCIBIOS_MIN_MEM+(256*1024*1024)-1; + bus->resource[0]->start = xPCIBIOS_MIN_IO; + bus->resource[1]->start = xPCIBIOS_MIN_MEM; /* Turn off downstream PF memory address range by default */ bus->resource[2]->start = 1024*1024; diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 230db8bd9744..447234c69ab1 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -144,22 +144,20 @@ int __init sh7751_pcic_init(struct pci_channel *chan, /* Set the local 16MB PCI memory space window to * the lowest PCI mapped address */ - word = PCIBIOS_MIN_MEM & SH4_PCIMBR_MASK; + word = chan->mem_resource->start & SH4_PCIMBR_MASK; pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); pci_write_reg(chan, word , SH4_PCIMBR); - /* Map IO space into PCI IO window - * The IO window is 64K-PCIBIOS_MIN_IO in size - * IO addresses will be translated to the - * PCI IO window base address + /* Map IO space into PCI IO window: + * IO addresses will be translated to the PCI IO window base address */ pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", - PCIBIOS_MIN_IO, (64 << 10), - SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO); + chan->io_resource->start, chan->io_resource->end, + SH7751_PCI_IO_BASE + chan->io_resource->start); /* Make sure the MSB's of IO window are set to access PCI space * correctly */ - word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK; + word = chan->io_resource->start & SH4_PCIIOBR_MASK; pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); pci_write_reg(chan, word, SH4_PCIIOBR); diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 4706e880b087..e8f3a308c075 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -130,14 +130,12 @@ int __init sh7780_pcic_init(struct pci_channel *chan, pci_write_reg(chan, map->window1.base, SH4_PCILAR1); pci_write_reg(chan, map->window1.base, SH7780_PCIMBAR1); - /* Map IO space into PCI IO window - * The IO window is 64K-PCIBIOS_MIN_IO in size - * IO addresses will be translated to the - * PCI IO window base address + /* Map IO space into PCI IO window: + * IO addresses will be translated to the PCI IO window base address */ pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", - PCIBIOS_MIN_IO, (64 << 10), - SH7780_PCI_IO_BASE + PCIBIOS_MIN_IO); + chan->io_resource->start, chan->io_resource->end, + SH7780_PCI_IO_BASE + chan->io_resource->start); /* NOTE: I'm ignoring the PCI error IRQs for now.. * TODO: add support for the internal error interrupts and -- GitLab From b6706ef10f75921733d7275fd45d268f2f6254c8 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 19 Feb 2008 21:34:55 +0900 Subject: [PATCH 0295/6080] sh: hook in struct pci_channel in sysdata Store a struct pci_channel pointer in bus->sysdata. This makes whatever struct pci_channel assigned to a bus available for sh4_pci_read() and sh4_pci_write(). We also modify PCIBIOS_MIN_IO and PCIBIOS_MIN_MEM to use bus->sysdata - this to gives us support for multiple pci channels. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-sh4.c | 12 +++++++----- arch/sh/drivers/pci/pci-auto.c | 1 + arch/sh/include/asm/pci.h | 6 ++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 92d27f734f2e..ee62e6de7133 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c @@ -26,6 +26,7 @@ static DEFINE_SPINLOCK(sh4_pci_lock); static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { + struct pci_channel *chan = bus->sysdata; unsigned long flags; u32 data; @@ -34,8 +35,8 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, * so we must do byte alignment by hand */ spin_lock_irqsave(&sh4_pci_lock, flags); - pci_write_reg(NULL, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); - data = pci_read_reg(NULL, SH4_PCIPDR); + pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); + data = pci_read_reg(chan, SH4_PCIPDR); spin_unlock_irqrestore(&sh4_pci_lock, flags); switch (size) { @@ -63,13 +64,14 @@ static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { + struct pci_channel *chan = bus->sysdata; unsigned long flags; int shift; u32 data; spin_lock_irqsave(&sh4_pci_lock, flags); - pci_write_reg(NULL, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); - data = pci_read_reg(NULL, SH4_PCIPDR); + pci_write_reg(chan, CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); + data = pci_read_reg(chan, SH4_PCIPDR); spin_unlock_irqrestore(&sh4_pci_lock, flags); switch (size) { @@ -90,7 +92,7 @@ static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_FUNC_NOT_SUPPORTED; } - pci_write_reg(NULL, data, SH4_PCIPDR); + pci_write_reg(chan, data, SH4_PCIPDR); return PCIBIOS_SUCCESSFUL; } diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c index cf48b12ee58c..1d715ec405b2 100644 --- a/arch/sh/drivers/pci/pci-auto.c +++ b/arch/sh/drivers/pci/pci-auto.c @@ -67,6 +67,7 @@ static struct pci_dev *fake_pci_dev(struct pci_channel *hose, dev.devfn = devfn; bus.number = busnr; bus.ops = hose->pci_ops; + bus.sysdata = hose; if(busnr != top_bus) /* Fake a parent bus structure. */ diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 5c7a8f1d2d54..386587e08830 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -31,8 +31,10 @@ struct pci_channel { */ extern struct pci_channel board_pci_channels[]; -#define PCIBIOS_MIN_IO board_pci_channels->io_resource->start -#define PCIBIOS_MIN_MEM board_pci_channels->mem_resource->start +/* ugly as hell, but makes drivers/pci/setup-res.c compile and work */ +#define __PCI_CHAN(bus) ((struct pci_channel *)bus->sysdata) +#define PCIBIOS_MIN_IO __PCI_CHAN(bus)->io_resource->start +#define PCIBIOS_MIN_MEM __PCI_CHAN(bus)->mem_resource->start /* * I/O routine helpers -- GitLab From e4c6a3604e07185046e2ce4be82a201f4447d788 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 19 Feb 2008 21:35:04 +0900 Subject: [PATCH 0296/6080] sh: add reg_base member to pci_channel Store the base address of the pci host controller registers in struct pci_channel and use the address in pci_read_reg() and pci_write_reg(). Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-sh4.c | 4 ++-- arch/sh/drivers/pci/pci-sh4.h | 4 ++-- arch/sh/drivers/pci/pci-sh7751.c | 2 ++ arch/sh/drivers/pci/pci-sh7751.h | 1 - arch/sh/drivers/pci/pci-sh7780.c | 2 ++ arch/sh/drivers/pci/pci-sh7780.h | 1 - arch/sh/include/asm/pci.h | 1 + 7 files changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index ee62e6de7133..540683d07c77 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c @@ -121,8 +121,8 @@ int __init sh4_pci_check_direct(struct pci_channel *chan) if (pci_read_reg(chan, SH4_PCIPAR) == P1SEG) { pci_write_reg(chan, tmp, SH4_PCIPAR); printk(KERN_INFO "PCI: Using configuration type 1\n"); - request_region(PCI_REG(SH4_PCIPAR), 8, "PCI conf1"); - + request_region(chan->reg_base + SH4_PCIPAR, 8, + "PCI conf1"); return 0; } diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h index 62ba35056087..90abfe3d39bb 100644 --- a/arch/sh/drivers/pci/pci-sh4.h +++ b/arch/sh/drivers/pci/pci-sh4.h @@ -171,13 +171,13 @@ struct sh4_pci_address_map { static inline void pci_write_reg(struct pci_channel *chan, unsigned long val, unsigned long reg) { - ctrl_outl(val, PCI_REG(reg)); + ctrl_outl(val, chan->reg_base + reg); } static inline unsigned long pci_read_reg(struct pci_channel *chan, unsigned long reg) { - return ctrl_inl(PCI_REG(reg)); + return ctrl_inl(chan->reg_base + reg); } #endif /* __PCI_SH4_H */ diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 447234c69ab1..201266b020f3 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -39,6 +39,8 @@ int __init sh7751_pci_init(struct pci_channel *chan) pr_debug("PCI: Starting intialization.\n"); + chan->reg_base = 0xfe200000; + /* check for SH7751/SH7751R hardware */ id = pci_read_reg(chan, SH7751_PCICONF0); if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h index 0ea4387df136..c390dd2f5e1a 100644 --- a/arch/sh/drivers/pci/pci-sh7751.h +++ b/arch/sh/drivers/pci/pci-sh7751.h @@ -26,7 +26,6 @@ #define SH7751_PCI_IO_SIZE 0x40000 /* Size of IO window */ #define SH7751_PCIREG_BASE 0xFE200000 /* PCI regs base address */ -#define PCI_REG(n) (SH7751_PCIREG_BASE+ n) #define SH7751_PCICONF0 0x0 /* PCI Config Reg 0 */ #define SH7751_PCICONF0_DEVID 0xFFFF0000 /* Device ID */ diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index e8f3a308c075..9d6483a26cf9 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -52,6 +52,8 @@ int __init sh7780_pci_init(struct pci_channel *chan) pr_debug("PCI: Starting intialization.\n"); + chan->reg_base = 0xfe040000; + ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ /* check for SH7780/SH7780R hardware */ diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index 2f3c92065ec3..fffcf1dcfedf 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -35,7 +35,6 @@ #define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */ #define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */ -#define PCI_REG(n) (SH7780_PCIREG_BASE+n) /* SH7780 PCI Config Registers */ #define SH7780_PCIVID 0x000 /* Vendor ID */ diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 386587e08830..8e9e0edcf36c 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -24,6 +24,7 @@ struct pci_channel { int first_devfn; int last_devfn; int enabled; + unsigned long reg_base; }; /* -- GitLab From ef53fdeb7e0cb139aff33665635b886700137abb Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 19 Feb 2008 21:35:14 +0900 Subject: [PATCH 0297/6080] sh: add io_base member to pci_channel Store the io window base address in struct pci_channel and use that one instead of SH77xx_PCI_IO_BASE. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 5 +++-- arch/sh/drivers/pci/pci-sh7780.c | 5 +++-- arch/sh/include/asm/pci.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 201266b020f3..2a6c7aab2d75 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -40,6 +40,7 @@ int __init sh7751_pci_init(struct pci_channel *chan) pr_debug("PCI: Starting intialization.\n"); chan->reg_base = 0xfe200000; + chan->io_base = 0xfe240000; /* check for SH7751/SH7751R hardware */ id = pci_read_reg(chan, SH7751_PCICONF0); @@ -153,9 +154,9 @@ int __init sh7751_pcic_init(struct pci_channel *chan, /* Map IO space into PCI IO window: * IO addresses will be translated to the PCI IO window base address */ - pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", + pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%lx\n", chan->io_resource->start, chan->io_resource->end, - SH7751_PCI_IO_BASE + chan->io_resource->start); + chan->io_base + chan->io_resource->start); /* Make sure the MSB's of IO window are set to access PCI space * correctly */ diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 9d6483a26cf9..87a7f3b7a38f 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -53,6 +53,7 @@ int __init sh7780_pci_init(struct pci_channel *chan) pr_debug("PCI: Starting intialization.\n"); chan->reg_base = 0xfe040000; + chan->io_base = 0xfe200000; ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ @@ -135,9 +136,9 @@ int __init sh7780_pcic_init(struct pci_channel *chan, /* Map IO space into PCI IO window: * IO addresses will be translated to the PCI IO window base address */ - pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", + pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%lx\n", chan->io_resource->start, chan->io_resource->end, - SH7780_PCI_IO_BASE + chan->io_resource->start); + chan->io_base + chan->io_resource->start); /* NOTE: I'm ignoring the PCI error IRQs for now.. * TODO: add support for the internal error interrupts and diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 8e9e0edcf36c..84d12ebef084 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -25,6 +25,7 @@ struct pci_channel { int last_devfn; int enabled; unsigned long reg_base; + unsigned long io_base; }; /* -- GitLab From ef339f241b08a16af58897e6288ba200e0c7a8c7 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 19 Feb 2008 21:35:22 +0900 Subject: [PATCH 0298/6080] sh: pci memory range checking code This patch changes the code to use __is_pci_memory() instead of is_pci_memaddr(). __is_pci_memory() loops through all the pci channels on the system to match memory windows. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-titan/io.c | 2 +- arch/sh/drivers/pci/pci.c | 5 ++--- arch/sh/include/asm/pci.h | 23 +++++++++++++++++++---- arch/sh/mm/ioremap_32.c | 4 ++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/arch/sh/boards/mach-titan/io.c b/arch/sh/boards/mach-titan/io.c index 4badad4c6f30..053b3ed2ed8d 100644 --- a/arch/sh/boards/mach-titan/io.c +++ b/arch/sh/boards/mach-titan/io.c @@ -117,7 +117,7 @@ void titan_outsl(unsigned long port, const void *src, unsigned long count) void __iomem *titan_ioport_map(unsigned long port, unsigned int size) { - if (PXSEG(port) || is_pci_memaddr(port)) + if (PXSEG(port)) return (void __iomem *)port; else if (is_pci_ioaddr(port)) return (void __iomem *)pci_ioaddr(port); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 29ec16e69afa..b9aca5478048 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -167,9 +167,8 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) /* * Presently the IORESOURCE_MEM case is a bit special, most * SH7751 style PCI controllers have PCI memory at a fixed - * location in the address space where no remapping is desired - * (typically at 0xfd000000, but is_pci_memaddr() will know - * best). With the IORESOURCE_MEM case more care has to be taken + * location in the address space where no remapping is desired. + * With the IORESOURCE_MEM case more care has to be taken * to inhibit page table mapping for legacy cores, but this is * punted off to __ioremap(). * -- PFM. diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 84d12ebef084..ccf5c5ff62ff 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -61,12 +61,8 @@ extern unsigned long PCI_IO_AREA; #define is_pci_ioaddr(port) \ (((port) >= PCIBIOS_MIN_IO) && \ ((port) < (PCIBIOS_MIN_IO + PCI_IO_SIZE))) -#define is_pci_memaddr(port) \ - (((port) >= PCIBIOS_MIN_MEM) && \ - ((port) < (PCIBIOS_MIN_MEM + PCI_MEM_SIZE))) #else #define is_pci_ioaddr(port) (0) -#define is_pci_memaddr(port) (0) #endif struct pci_dev; @@ -127,6 +123,25 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } + +static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) +{ + struct pci_channel *p; + struct resource *res; + + for (p = board_pci_channels; p->init; p++) { + res = p->mem_resource; + if (p->enabled && (phys_addr >= res->start) && + (phys_addr + size) <= (res->end + 1)) + return 1; + } + return 0; +} +#else +static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) +{ + return 0; +} #endif /* Board-specific fixup routines. */ diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c index 60cc486d2c2c..7e04cc8f3b9b 100644 --- a/arch/sh/mm/ioremap_32.c +++ b/arch/sh/mm/ioremap_32.c @@ -56,7 +56,7 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, * P1/P2 space, ioremap() will already do the right thing, * and we'll never get this far. */ - if (is_pci_memaddr(phys_addr) && is_pci_memaddr(last_addr)) + if (__is_pci_memory(phys_addr, size)) return (void __iomem *)phys_addr; #if !defined(CONFIG_PMB_FIXED) @@ -121,7 +121,7 @@ void __iounmap(void __iomem *addr) unsigned long seg = PXSEG(vaddr); struct vm_struct *p; - if (seg < P3SEG || vaddr >= P3_ADDR_MAX || is_pci_memaddr(vaddr)) + if (seg < P3SEG || vaddr >= P3_ADDR_MAX || __is_pci_memory(vaddr, 0)) return; #ifdef CONFIG_PMB -- GitLab From 8ce0143b11cdc519b8e1fd94a262b654ef0bc3ab Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 19 Feb 2008 21:35:31 +0900 Subject: [PATCH 0299/6080] sh: pci io port base address code Adds a __get_pci_io_base() function which is used to match a port range against struct pci_channel. This allows us to detect if a port range is assigned to pci or happens to be legacy port io. While at it, remove unused cpu-specific cruft. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-rts7751r2d.c | 1 - arch/sh/include/asm/pci.h | 47 ++++++++++++---------------- arch/sh/kernel/io.c | 5 +++ 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index fe5a231b8669..58ed1d58cffb 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -68,7 +68,6 @@ static struct sh4_pci_address_map sh7751_pci_map = { int __init pcibios_init_platform(void) { - __set_io_port_base(SH7751_PCI_IO_BASE); return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); } diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index ccf5c5ff62ff..bb2c2fcddc9e 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -38,33 +38,6 @@ extern struct pci_channel board_pci_channels[]; #define PCIBIOS_MIN_IO __PCI_CHAN(bus)->io_resource->start #define PCIBIOS_MIN_MEM __PCI_CHAN(bus)->mem_resource->start -/* - * I/O routine helpers - */ -#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) -#define PCI_IO_AREA 0xFE400000 -#define PCI_IO_SIZE 0x00400000 -#elif defined(CONFIG_CPU_SH5) -extern unsigned long PCI_IO_AREA; -#define PCI_IO_SIZE 0x00010000 -#else -#define PCI_IO_AREA 0xFE240000 -#define PCI_IO_SIZE 0x00040000 -#endif - -#define PCI_MEM_SIZE 0x01000000 - -#define SH4_PCIIOBR_MASK 0xFFFC0000 -#define pci_ioaddr(addr) (PCI_IO_AREA + (addr & ~SH4_PCIIOBR_MASK)) - -#if defined(CONFIG_PCI) -#define is_pci_ioaddr(port) \ - (((port) >= PCIBIOS_MIN_IO) && \ - ((port) < (PCIBIOS_MIN_IO + PCI_IO_SIZE))) -#else -#define is_pci_ioaddr(port) (0) -#endif - struct pci_dev; extern void pcibios_set_master(struct pci_dev *dev); @@ -137,11 +110,31 @@ static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) } return 0; } + +static inline void __iomem *__get_pci_io_base(unsigned long port, + unsigned long size) +{ + struct pci_channel *p; + struct resource *res; + + for (p = board_pci_channels; p->init; p++) { + res = p->io_resource; + if (p->enabled && (port >= res->start) && + (port + size) <= (res->end + 1)) + return (void __iomem *)(p->io_base + port); + } + return NULL; +} #else static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) { return 0; } +static inline void __iomem *__get_pci_io_base(unsigned long port, + unsigned long size) +{ + return NULL; +} #endif /* Board-specific fixup routines. */ diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c index 29cf4588fc05..59fb020718a3 100644 --- a/arch/sh/kernel/io.c +++ b/arch/sh/kernel/io.c @@ -12,6 +12,7 @@ * for more details. */ #include +#include #include #include @@ -69,6 +70,10 @@ void __iomem *ioport_map(unsigned long port, unsigned int nr) if (ret) return ret; + ret = __get_pci_io_base(port, nr); + if (ret) + return ret; + return __ioport_map(port, nr); } EXPORT_SYMBOL(ioport_map); -- GitLab From aa5d3ff99cc1f3dfe262ab9dd9179131fcfe39fd Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 19 Feb 2008 21:35:40 +0900 Subject: [PATCH 0300/6080] sh: export board_pci_channels in one place Instead of sometimes exporting board_pci_channels[] in the board specific code just export it in one place. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-cayman.c | 1 - arch/sh/drivers/pci/ops-lboxre2.c | 2 -- arch/sh/drivers/pci/ops-r7780rp.c | 1 - arch/sh/drivers/pci/ops-rts7751r2d.c | 1 - arch/sh/drivers/pci/ops-sdk7780.c | 1 - arch/sh/drivers/pci/ops-se7780.c | 1 - arch/sh/drivers/pci/ops-titan.c | 1 - arch/sh/drivers/pci/pci.c | 2 ++ 8 files changed, 2 insertions(+), 8 deletions(-) diff --git a/arch/sh/drivers/pci/ops-cayman.c b/arch/sh/drivers/pci/ops-cayman.c index f4a5e14f7e5a..cbaaf0234b72 100644 --- a/arch/sh/drivers/pci/ops-cayman.c +++ b/arch/sh/drivers/pci/ops-cayman.c @@ -80,7 +80,6 @@ struct pci_channel board_pci_channels[] = { { sh5_pci_init, &sh5_pci_ops, NULL, NULL, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; -EXPORT_SYMBOL(board_pci_channels); int __init pcibios_init_platform(void) { diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c index f606df2195c1..781496bfb1f9 100644 --- a/arch/sh/drivers/pci/ops-lboxre2.c +++ b/arch/sh/drivers/pci/ops-lboxre2.c @@ -43,8 +43,6 @@ struct pci_channel board_pci_channels[] = { { NULL, NULL, NULL, 0, 0 }, }; -EXPORT_SYMBOL(board_pci_channels); - static struct sh4_pci_address_map sh7751_pci_map = { .window0 = { .base = SH7751_CS3_BASE_ADDR, diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c index b51b7e4078d0..c58f1cff9fba 100644 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ b/arch/sh/drivers/pci/ops-r7780rp.c @@ -46,7 +46,6 @@ struct pci_channel board_pci_channels[] = { { sh7780_pci_init, &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; -EXPORT_SYMBOL(board_pci_channels); static struct sh4_pci_address_map sh7780_pci_map = { .window0 = { diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index 58ed1d58cffb..d374cd37f455 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -50,7 +50,6 @@ struct pci_channel board_pci_channels[] = { { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; -EXPORT_SYMBOL(board_pci_channels); static struct sh4_pci_address_map sh7751_pci_map = { .window0 = { diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c index 7277cd15ae6a..b34fbc54a7c6 100644 --- a/arch/sh/drivers/pci/ops-sdk7780.c +++ b/arch/sh/drivers/pci/ops-sdk7780.c @@ -52,7 +52,6 @@ struct pci_channel board_pci_channels[] = { { sh7780_pci_init, &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; -EXPORT_SYMBOL(board_pci_channels); static struct sh4_pci_address_map sdk7780_pci_map = { .window0 = { diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c index 76a74fb42fb0..47302077a0c8 100644 --- a/arch/sh/drivers/pci/ops-se7780.c +++ b/arch/sh/drivers/pci/ops-se7780.c @@ -61,7 +61,6 @@ struct pci_channel board_pci_channels[] = { { sh7780_pci_init, &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; -EXPORT_SYMBOL(board_pci_channels); static struct sh4_pci_address_map se7780_pci_map = { .window0 = { diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c index ffa79bdf4755..31ed03716a2c 100644 --- a/arch/sh/drivers/pci/ops-titan.c +++ b/arch/sh/drivers/pci/ops-titan.c @@ -55,7 +55,6 @@ struct pci_channel board_pci_channels[] = { { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; -EXPORT_SYMBOL(board_pci_channels); static struct sh4_pci_address_map sh7751_pci_map = { .window0 = { diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index b9aca5478048..8aaacc99b710 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -187,3 +187,5 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr) iounmap(addr); } EXPORT_SYMBOL(pci_iounmap); + +EXPORT_SYMBOL(board_pci_channels); -- GitLab From 10591578c84825a320734e59272f161385edcc41 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 11 Mar 2009 15:58:04 +0900 Subject: [PATCH 0301/6080] sh: drop duplicate symbol export on dreamcast and sh7785lcr. With board_pci_channels now being exported in a single place, update the boards that duplicated the export. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-dreamcast.c | 1 - arch/sh/drivers/pci/ops-sh7785lcr.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c index f62063eb6490..5bc81d5b660a 100644 --- a/arch/sh/drivers/pci/ops-dreamcast.c +++ b/arch/sh/drivers/pci/ops-dreamcast.c @@ -165,4 +165,3 @@ struct pci_channel board_pci_channels[] = { &gapspci_mem_resource, 0, 1 }, { 0, } }; -EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c index fb0869f0bef8..2a9f9a599d66 100644 --- a/arch/sh/drivers/pci/ops-sh7785lcr.c +++ b/arch/sh/drivers/pci/ops-sh7785lcr.c @@ -44,7 +44,6 @@ struct pci_channel board_pci_channels[] = { { &sh4_pci_ops, &sh7785_io_resource, &sh7785_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; -EXPORT_SYMBOL(board_pci_channels); static struct sh4_pci_address_map sh7785_pci_map = { .window0 = { -- GitLab From 3aabce8d3d2f9af2c08c2f590ac9acb272ca8c95 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 11 Mar 2009 16:12:39 +0900 Subject: [PATCH 0302/6080] sh: sh7785lcr: Update for recent PCI changes. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/fixups-sh7785lcr.c | 33 +++++++++++++------------- arch/sh/drivers/pci/ops-sh7785lcr.c | 4 ++-- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/arch/sh/drivers/pci/fixups-sh7785lcr.c b/arch/sh/drivers/pci/fixups-sh7785lcr.c index 4949e601387a..9e7dc79037e7 100644 --- a/arch/sh/drivers/pci/fixups-sh7785lcr.c +++ b/arch/sh/drivers/pci/fixups-sh7785lcr.c @@ -15,32 +15,33 @@ #include #include "pci-sh4.h" -int pci_fixup_pcic(void) +int pci_fixup_pcic(struct pci_channel *chan) { - pci_write_reg(0x000043ff, SH4_PCIINTM); - pci_write_reg(0x0000380f, SH4_PCIAINTM); + pci_write_reg(chan, 0x000043ff, SH4_PCIINTM); + pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); - pci_write_reg(0xfbb00047, SH7780_PCICMD); - pci_write_reg(0x00000000, SH7780_PCIIBAR); + pci_write_reg(chan, 0xfbb00047, SH7780_PCICMD); + pci_write_reg(chan, 0x00000000, SH7780_PCIIBAR); - pci_write_reg(0x00011912, SH7780_PCISVID); - pci_write_reg(0x08000000, SH7780_PCICSCR0); - pci_write_reg(0x0000001b, SH7780_PCICSAR0); - pci_write_reg(0xfd000000, SH7780_PCICSCR1); - pci_write_reg(0x0000000f, SH7780_PCICSAR1); + pci_write_reg(chan, 0x00011912, SH7780_PCISVID); + pci_write_reg(chan, 0x08000000, SH7780_PCICSCR0); + pci_write_reg(chan, 0x0000001b, SH7780_PCICSAR0); + pci_write_reg(chan, 0xfd000000, SH7780_PCICSCR1); + pci_write_reg(chan, 0x0000000f, SH7780_PCICSAR1); - pci_write_reg(0xfd000000, SH7780_PCIMBR0); - pci_write_reg(0x00fc0000, SH7780_PCIMBMR0); + pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0); + pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0); #ifdef CONFIG_32BIT - pci_write_reg(0xc0000000, SH7780_PCIMBR2); - pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); + pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2); + pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); #endif /* Set IOBR for windows containing area specified in pci.h */ - pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)), + pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE - 1), SH7780_PCIIOBR); - pci_write_reg(((SH7780_PCI_IO_SIZE - 1) & (7 << 18)), SH7780_PCIIOBMR); + pci_write_reg(chan, ((SH7780_PCI_IO_SIZE - 1) & (7 << 18)), + SH7780_PCIIOBMR); return 0; } diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c index 2a9f9a599d66..afbb9bd47513 100644 --- a/arch/sh/drivers/pci/ops-sh7785lcr.c +++ b/arch/sh/drivers/pci/ops-sh7785lcr.c @@ -41,7 +41,7 @@ static struct resource sh7785_mem_resource = { }; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7785_io_resource, &sh7785_mem_resource, 0, 0xff }, + { sh7780_pci_init, &sh4_pci_ops, &sh7785_io_resource, &sh7785_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; @@ -61,5 +61,5 @@ static struct sh4_pci_address_map sh7785_pci_map = { int __init pcibios_init_platform(void) { - return sh7780_pcic_init(&sh7785_pci_map); + return sh7780_pcic_init(&board_pci_channels[0], &sh7785_pci_map); } -- GitLab From f1a9ba8f15f89f3f444985251efaf809cd16da53 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 11 Mar 2009 16:17:53 +0900 Subject: [PATCH 0303/6080] sh: pci: drop duplicate PCIC fixups for SE7780 and SH7785LCR. SE7780 has the same PCIC fixup as SDK7780, and SH7785LCR the same as R7780RP. Switch to using those, and drop the duplicate code. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 4 +- arch/sh/drivers/pci/fixups-se7780.c | 62 -------------------------- arch/sh/drivers/pci/fixups-sh7785lcr.c | 47 ------------------- 3 files changed, 2 insertions(+), 111 deletions(-) delete mode 100644 arch/sh/drivers/pci/fixups-se7780.c delete mode 100644 arch/sh/drivers/pci/fixups-sh7785lcr.c diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 847e90894d1b..67d710a04de1 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -21,6 +21,6 @@ obj-$(CONFIG_SH_SDK7780) += ops-sdk7780.o fixups-sdk7780.o obj-$(CONFIG_SH_TITAN) += ops-titan.o obj-$(CONFIG_SH_LANDISK) += ops-landisk.o obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o -obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o +obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-sdk7780.o obj-$(CONFIG_SH_CAYMAN) += ops-cayman.o -obj-$(CONFIG_SH_SH7785LCR) += ops-sh7785lcr.o fixups-sh7785lcr.o +obj-$(CONFIG_SH_SH7785LCR) += ops-sh7785lcr.o fixups-r7780rp.o diff --git a/arch/sh/drivers/pci/fixups-se7780.c b/arch/sh/drivers/pci/fixups-se7780.c deleted file mode 100644 index a968af7d6f70..000000000000 --- a/arch/sh/drivers/pci/fixups-se7780.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * arch/sh/drivers/pci/fixups-se7780.c - * - * HITACHI UL Solution Engine 7780 PCI fixups - * - * Copyright (C) 2003 Lineo uSolutions, Inc. - * Copyright (C) 2004 - 2006 Paul Mundt - * Copyright (C) 2006 Nobuhiro Iwamatsu - * - * 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. - */ -#include -#include "pci-sh4.h" -#include - -int pci_fixup_pcic(struct pci_channel *chan) -{ - ctrl_outl(0x00000001, SH7780_PCI_VCR2); - - /* Enable all interrupts, so we know what to fix */ - pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR); - pci_write_reg(chan, 0x0000380F, SH7780_PCIAINTM); - - /* Set up standard PCI config registers */ - ctrl_outw(0xFB00, PCI_REG(SH7780_PCISTATUS)); - ctrl_outw(0x0047, PCI_REG(SH7780_PCICMD)); - ctrl_outb( 0x00, PCI_REG(SH7780_PCIPIF)); - ctrl_outb( 0x00, PCI_REG(SH7780_PCISUB)); - ctrl_outb( 0x06, PCI_REG(SH7780_PCIBCC)); - ctrl_outw(0x1912, PCI_REG(SH7780_PCISVID)); - ctrl_outw(0x0001, PCI_REG(SH7780_PCISID)); - - pci_write_reg(chan, 0x08000000, SH7780_PCIMBAR0); /* PCI */ - pci_write_reg(chan, 0x08000000, SH7780_PCILAR0); /* SHwy */ - pci_write_reg(chan, 0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ - - pci_write_reg(chan, 0x00000000, SH7780_PCIMBAR1); - pci_write_reg(chan, 0x00000000, SH7780_PCILAR1); - pci_write_reg(chan, 0x00000000, SH7780_PCILSR1); - - pci_write_reg(chan, 0xAB000801, SH7780_PCIIBAR); - - /* - * Set the MBR so PCI address is one-to-one with window, - * meaning all calls go straight through... use ifdef to - * catch erroneous assumption. - */ - pci_write_reg(chan, 0xFD000000 , SH7780_PCIMBR0); - pci_write_reg(chan, 0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ - - /* Set IOBR for window containing area specified in pci.h */ - pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), - SH7780_PCIIOBR); - pci_write_reg(chan, (SH7780_PCI_IO_SIZE-1) & (7 << 18), - SH7780_PCIIOBMR); - - pci_write_reg(chan, 0xA5000C01, SH7780_PCICR); - - return 0; -} diff --git a/arch/sh/drivers/pci/fixups-sh7785lcr.c b/arch/sh/drivers/pci/fixups-sh7785lcr.c deleted file mode 100644 index 9e7dc79037e7..000000000000 --- a/arch/sh/drivers/pci/fixups-sh7785lcr.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * arch/sh/drivers/pci/fixups-sh7785lcr.c - * - * R0P7785LC0011RL PCI fixups - * Copyright (C) 2008 Yoshihiro Shimoda - * - * Based on arch/sh/drivers/pci/fixups-r7780rp.c - * Copyright (C) 2003 Lineo uSolutions, Inc. - * Copyright (C) 2004 - 2006 Paul Mundt - * - * 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. - */ -#include -#include "pci-sh4.h" - -int pci_fixup_pcic(struct pci_channel *chan) -{ - pci_write_reg(chan, 0x000043ff, SH4_PCIINTM); - pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); - - pci_write_reg(chan, 0xfbb00047, SH7780_PCICMD); - pci_write_reg(chan, 0x00000000, SH7780_PCIIBAR); - - pci_write_reg(chan, 0x00011912, SH7780_PCISVID); - pci_write_reg(chan, 0x08000000, SH7780_PCICSCR0); - pci_write_reg(chan, 0x0000001b, SH7780_PCICSAR0); - pci_write_reg(chan, 0xfd000000, SH7780_PCICSCR1); - pci_write_reg(chan, 0x0000000f, SH7780_PCICSAR1); - - pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0); - pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0); - -#ifdef CONFIG_32BIT - pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2); - pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); -#endif - - /* Set IOBR for windows containing area specified in pci.h */ - pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE - 1), - SH7780_PCIIOBR); - pci_write_reg(chan, ((SH7780_PCI_IO_SIZE - 1) & (7 << 18)), - SH7780_PCIIOBMR); - - return 0; -} -- GitLab From 18cb7109d3e83195b605ff2905981020e86f72ca Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Apr 2009 10:22:24 +0200 Subject: [PATCH 0304/6080] ALSA: hda - Check strcpy length Check the length to copy via strlen() beforehand to avoid the stack corruption, or use strlcpy() to be safe in HD-audio codes. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 2 ++ sound/pci/hda/hda_intel.c | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 37f24ce7c3a2..48f0cea7df14 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1431,6 +1431,8 @@ _snd_hda_find_mixer_ctl(struct hda_codec *codec, memset(&id, 0, sizeof(id)); id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; id.index = idx; + if (snd_BUG_ON(strlen(name) >= sizeof(id.name))) + return NULL; strcpy(id.name, name); return snd_ctl_find_id(codec->bus->card, &id); } diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 21a3092fad00..41db5d4da478 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1830,7 +1830,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, &pcm); if (err < 0) return err; - strcpy(pcm->name, cpcm->name); + strlcpy(pcm->name, cpcm->name, sizeof(pcm->name)); apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); if (apcm == NULL) return -ENOMEM; @@ -2358,9 +2358,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, } strcpy(card->driver, "HDA-Intel"); - strcpy(card->shortname, driver_short_names[chip->driver_type]); - sprintf(card->longname, "%s at 0x%lx irq %i", - card->shortname, chip->addr, chip->irq); + strlcpy(card->shortname, driver_short_names[chip->driver_type], + sizeof(card->shortname)); + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx irq %i", + card->shortname, chip->addr, chip->irq); *rchip = chip; return 0; -- GitLab From 0232ba9ce031d0fd8f331fa8b3c00e16901f54e6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 16 Apr 2009 18:01:31 +0900 Subject: [PATCH 0305/6080] sh: pci: Kill off unused SH4_PCIC_NO_RESET code. Nothing ended up using this anymore, so just kill it off. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-landisk.c | 2 -- arch/sh/drivers/pci/ops-lboxre2.c | 5 ----- arch/sh/drivers/pci/ops-r7780rp.c | 2 -- arch/sh/drivers/pci/ops-rts7751r2d.c | 7 ------- arch/sh/drivers/pci/ops-sdk7780.c | 1 - arch/sh/drivers/pci/ops-se7780.c | 1 - arch/sh/drivers/pci/ops-sh7785lcr.c | 2 -- arch/sh/drivers/pci/ops-snapgear.c | 2 -- arch/sh/drivers/pci/ops-titan.c | 2 -- arch/sh/drivers/pci/pci-sh4.h | 4 ---- arch/sh/drivers/pci/pci-sh7751.c | 15 --------------- arch/sh/drivers/pci/pci-sh7780.c | 15 --------------- 12 files changed, 58 deletions(-) diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c index c46911d95eca..178b77828aa9 100644 --- a/arch/sh/drivers/pci/ops-landisk.c +++ b/arch/sh/drivers/pci/ops-landisk.c @@ -39,8 +39,6 @@ static struct sh4_pci_address_map sh7751_pci_map = { .base = SH7751_CS3_BASE_ADDR, .size = (64 << 20), /* 64MB */ }, - - .flags = SH4_PCIC_NO_RESET, }; int __init pcibios_init_platform(void) diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c index 781496bfb1f9..91cabd84f028 100644 --- a/arch/sh/drivers/pci/ops-lboxre2.c +++ b/arch/sh/drivers/pci/ops-lboxre2.c @@ -48,11 +48,6 @@ static struct sh4_pci_address_map sh7751_pci_map = { .base = SH7751_CS3_BASE_ADDR, .size = 0x04000000, }, - .window1 = { - .base = 0x00000000, /* Unused */ - .size = 0x00000000, /* Unused */ - }, - .flags = SH4_PCIC_NO_RESET, }; int __init pcibios_init_platform(void) diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c index c58f1cff9fba..8ec6d225ef9d 100644 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ b/arch/sh/drivers/pci/ops-r7780rp.c @@ -57,8 +57,6 @@ static struct sh4_pci_address_map sh7780_pci_map = { .base = SH7780_CS3_BASE_ADDR, .size = 0x04000000, }, - - .flags = SH4_PCIC_NO_RESET, }; int __init pcibios_init_platform(void) diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index d374cd37f455..96b916c0d6c5 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -56,13 +56,6 @@ static struct sh4_pci_address_map sh7751_pci_map = { .base = SH7751_CS3_BASE_ADDR, .size = 0x04000000, }, - - .window1 = { - .base = 0x00000000, /* Unused */ - .size = 0x00000000, /* Unused */ - }, - - .flags = SH4_PCIC_NO_RESET, }; int __init pcibios_init_platform(void) diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c index b34fbc54a7c6..6a0b7c067831 100644 --- a/arch/sh/drivers/pci/ops-sdk7780.c +++ b/arch/sh/drivers/pci/ops-sdk7780.c @@ -62,7 +62,6 @@ static struct sh4_pci_address_map sdk7780_pci_map = { .base = SH7780_CS3_BASE_ADDR, .size = 0x04000000, }, - .flags = SH4_PCIC_NO_RESET, }; int __init pcibios_init_platform(void) diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c index 47302077a0c8..583b8e82ff99 100644 --- a/arch/sh/drivers/pci/ops-se7780.c +++ b/arch/sh/drivers/pci/ops-se7780.c @@ -67,7 +67,6 @@ static struct sh4_pci_address_map se7780_pci_map = { .base = SH7780_CS2_BASE_ADDR, .size = 0x04000000, }, - .flags = SH4_PCIC_NO_RESET, }; int __init pcibios_init_platform(void) diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c index afbb9bd47513..ab0d1decf2df 100644 --- a/arch/sh/drivers/pci/ops-sh7785lcr.c +++ b/arch/sh/drivers/pci/ops-sh7785lcr.c @@ -55,8 +55,6 @@ static struct sh4_pci_address_map sh7785_pci_map = { .size = 0x20000000, #endif }, - - .flags = SH4_PCIC_NO_RESET, }; int __init pcibios_init_platform(void) diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c index 2e254c6cf6c1..dd2c5df28307 100644 --- a/arch/sh/drivers/pci/ops-snapgear.c +++ b/arch/sh/drivers/pci/ops-snapgear.c @@ -54,8 +54,6 @@ static struct sh4_pci_address_map sh7751_pci_map = { .base = SH7751_CS2_BASE_ADDR, .size = SNAPGEAR_LSR1_SIZE, }, - - .flags = SH4_PCIC_NO_RESET, }; /* diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c index 31ed03716a2c..e45bb62bf8ce 100644 --- a/arch/sh/drivers/pci/ops-titan.c +++ b/arch/sh/drivers/pci/ops-titan.c @@ -66,8 +66,6 @@ static struct sh4_pci_address_map sh7751_pci_map = { .base = SH7751_CS2_BASE_ADDR, .size = SH7751_MEM_REGION_SIZE*2, }, - - .flags = SH4_PCIC_NO_RESET, }; int __init pcibios_init_platform(void) diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h index 90abfe3d39bb..3d5296cde622 100644 --- a/arch/sh/drivers/pci/pci-sh4.h +++ b/arch/sh/drivers/pci/pci-sh4.h @@ -149,9 +149,6 @@ #define SH4_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */ #define SH4_PCIPDR 0x220 /* Port IO Data Register */ -/* Flags */ -#define SH4_PCIC_NO_RESET 0x0001 - /* arch/sh/kernel/drivers/pci/ops-sh4.c */ extern struct pci_ops sh4_pci_ops; int sh4_pci_check_direct(struct pci_channel *chan); @@ -165,7 +162,6 @@ struct sh4_pci_address_space { struct sh4_pci_address_map { struct sh4_pci_address_space window0; struct sh4_pci_address_space window1; - unsigned long flags; }; static inline void pci_write_reg(struct pci_channel *chan, diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 2a6c7aab2d75..af8874436d2f 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -99,21 +99,6 @@ int __init sh7751_pcic_init(struct pci_channel *chan, word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; pci_write_reg(chan, word, SH4_PCIPINT); - /* - * This code is unused for some boards as it is done in the - * bootloader and doing it here means the MAC addresses loaded - * by the bootloader get lost. - */ - if (!(map->flags & SH4_PCIC_NO_RESET)) { - /* toggle PCI reset pin */ - word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; - pci_write_reg(chan, word, SH4_PCICR); - /* Wait for a long time... not 1 sec. but long enough */ - mdelay(100); - word = SH4_PCICR_PREFIX; - pci_write_reg(chan, word, SH4_PCICR); - } - /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 87a7f3b7a38f..282cabe15e36 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -96,21 +96,6 @@ int __init sh7780_pcic_init(struct pci_channel *chan, { u32 word; - /* - * This code is unused for some boards as it is done in the - * bootloader and doing it here means the MAC addresses loaded - * by the bootloader get lost. - */ - if (!(map->flags & SH4_PCIC_NO_RESET)) { - /* toggle PCI reset pin */ - word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; - pci_write_reg(chan, word, SH4_PCICR); - /* Wait for a long time... not 1 sec. but long enough */ - mdelay(100); - word = SH4_PCICR_PREFIX; - pci_write_reg(chan, word, SH4_PCICR); - } - /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable -- GitLab From 76620aafd66f0004829764940c5466144969cffc Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 16 Apr 2009 02:02:07 -0700 Subject: [PATCH 0306/6080] gro: New frags interface to avoid copying shinfo It turns out that copying a 16-byte area at ~800k times a second can be really expensive :) This patch redesigns the frags GRO interface to avoid copying that area twice. The two disciples of the frags interface have been converted. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/cxgb3/adapter.h | 2 +- drivers/net/cxgb3/sge.c | 53 ++++++++++++++---------- drivers/net/sfc/rx.c | 26 ++++++++---- include/linux/if_vlan.h | 6 +-- include/linux/netdevice.h | 22 +++++----- net/8021q/vlan_core.c | 4 +- net/core/dev.c | 81 +++++++++++++++++-------------------- 7 files changed, 101 insertions(+), 93 deletions(-) diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 714df2b675e6..322434ac42fc 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -195,7 +195,7 @@ struct sge_qset { /* an SGE queue set */ struct sge_rspq rspq; struct sge_fl fl[SGE_RXQ_PER_SET]; struct sge_txq txq[SGE_TXQ_PER_SET]; - struct napi_gro_fraginfo lro_frag_tbl; + int nomem; int lro_enabled; void *lro_va; struct net_device *netdev; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 26d3587f3399..73d569e758ec 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -654,7 +654,8 @@ static void t3_reset_qset(struct sge_qset *q) q->txq_stopped = 0; q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */ q->rx_reclaim_timer.function = NULL; - q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0; + q->nomem = 0; + napi_free_frags(&q->napi); } @@ -2074,20 +2075,19 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, struct sge_fl *fl, int len, int complete) { struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; + struct sk_buff *skb = NULL; struct cpl_rx_pkt *cpl; - struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags; - int nr_frags = qs->lro_frag_tbl.nr_frags; - int frag_len = qs->lro_frag_tbl.len; + struct skb_frag_struct *rx_frag; + int nr_frags; int offset = 0; - if (!nr_frags) { - offset = 2 + sizeof(struct cpl_rx_pkt); - qs->lro_va = cpl = sd->pg_chunk.va + 2; + if (!qs->nomem) { + skb = napi_get_frags(&qs->napi); + qs->nomem = !skb; } fl->credits--; - len -= offset; pci_dma_sync_single_for_cpu(adap->pdev, pci_unmap_addr(sd, dma_addr), fl->buf_size - SGE_PG_RSVD, @@ -2100,21 +2100,38 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, fl->alloc_size, PCI_DMA_FROMDEVICE); + if (!skb) { + put_page(sd->pg_chunk.page); + if (complete) + qs->nomem = 0; + return; + } + + rx_frag = skb_shinfo(skb)->frags; + nr_frags = skb_shinfo(skb)->nr_frags; + + if (!nr_frags) { + offset = 2 + sizeof(struct cpl_rx_pkt); + qs->lro_va = sd->pg_chunk.va + 2; + } + len -= offset; + prefetch(qs->lro_va); rx_frag += nr_frags; rx_frag->page = sd->pg_chunk.page; rx_frag->page_offset = sd->pg_chunk.offset + offset; rx_frag->size = len; - frag_len += len; - qs->lro_frag_tbl.nr_frags++; - qs->lro_frag_tbl.len = frag_len; + skb->len += len; + skb->data_len += len; + skb->truesize += len; + skb_shinfo(skb)->nr_frags++; if (!complete) return; - qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY; + skb->ip_summed = CHECKSUM_UNNECESSARY; cpl = qs->lro_va; if (unlikely(cpl->vlan_valid)) { @@ -2123,15 +2140,11 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, struct vlan_group *grp = pi->vlan_grp; if (likely(grp != NULL)) { - vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan), - &qs->lro_frag_tbl); - goto out; + vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan)); + return; } } - napi_gro_frags(&qs->napi, &qs->lro_frag_tbl); - -out: - qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0; + napi_gro_frags(&qs->napi); } /** @@ -2300,8 +2313,6 @@ no_mem: if (fl->use_pages) { void *addr = fl->sdesc[fl->cidx].pg_chunk.va; - prefetch(&qs->lro_frag_tbl); - prefetch(addr); #if L1_CACHE_BYTES < 128 prefetch(addr + L1_CACHE_BYTES); diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 66d7fe3db3e6..01f9432c31ef 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -450,17 +450,27 @@ static void efx_rx_packet_lro(struct efx_channel *channel, /* Pass the skb/page into the LRO engine */ if (rx_buf->page) { - struct napi_gro_fraginfo info; + struct sk_buff *skb = napi_get_frags(napi); - info.frags[0].page = rx_buf->page; - info.frags[0].page_offset = efx_rx_buf_offset(rx_buf); - info.frags[0].size = rx_buf->len; - info.nr_frags = 1; - info.ip_summed = CHECKSUM_UNNECESSARY; - info.len = rx_buf->len; + if (!skb) { + put_page(rx_buf->page); + goto out; + } + + skb_shinfo(skb)->frags[0].page = rx_buf->page; + skb_shinfo(skb)->frags[0].page_offset = + efx_rx_buf_offset(rx_buf); + skb_shinfo(skb)->frags[0].size = rx_buf->len; + skb_shinfo(skb)->nr_frags = 1; + + skb->len = rx_buf->len; + skb->data_len = rx_buf->len; + skb->truesize += rx_buf->len; + skb->ip_summed = CHECKSUM_UNNECESSARY; - napi_gro_frags(napi, &info); + napi_gro_frags(napi); +out: EFX_BUG_ON_PARANOID(rx_buf->skb); rx_buf->page = NULL; } else { diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index e1ff5b14310e..7ff9af1d0f05 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -118,8 +118,7 @@ extern int vlan_hwaccel_do_receive(struct sk_buff *skb); extern int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb); extern int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci, - struct napi_gro_fraginfo *info); + unsigned int vlan_tci); #else static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev) @@ -154,8 +153,7 @@ static inline int vlan_gro_receive(struct napi_struct *napi, } static inline int vlan_gro_frags(struct napi_struct *napi, - struct vlan_group *grp, unsigned int vlan_tci, - struct napi_gro_fraginfo *info) + struct vlan_group *grp, unsigned int vlan_tci) { return NET_RX_DROP; } diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 2e7783f4a755..54db3ebf2193 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1047,14 +1047,6 @@ struct packet_type { struct list_head list; }; -struct napi_gro_fraginfo { - skb_frag_t frags[MAX_SKB_FRAGS]; - unsigned int nr_frags; - unsigned int ip_summed; - unsigned int len; - __wsum csum; -}; - #include #include @@ -1442,12 +1434,18 @@ extern int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb); extern void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb); -extern struct sk_buff * napi_fraginfo_skb(struct napi_struct *napi, - struct napi_gro_fraginfo *info); +extern struct sk_buff * napi_get_frags(struct napi_struct *napi); extern int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret); -extern int napi_gro_frags(struct napi_struct *napi, - struct napi_gro_fraginfo *info); +extern struct sk_buff * napi_frags_skb(struct napi_struct *napi); +extern int napi_gro_frags(struct napi_struct *napi); + +static inline void napi_free_frags(struct napi_struct *napi) +{ + kfree_skb(napi->skb); + napi->skb = NULL; +} + extern void netif_nit_deliver(struct sk_buff *skb); extern int dev_valid_name(const char *name); extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *); diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 654e45f5719d..c1f51e4a01b2 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -114,9 +114,9 @@ int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, EXPORT_SYMBOL(vlan_gro_receive); int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci, struct napi_gro_fraginfo *info) + unsigned int vlan_tci) { - struct sk_buff *skb = napi_fraginfo_skb(napi, info); + struct sk_buff *skb = napi_frags_skb(napi); if (!skb) return NET_RX_DROP; diff --git a/net/core/dev.c b/net/core/dev.c index 91d792d17e09..619fa141b8f5 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2519,16 +2519,10 @@ void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) } EXPORT_SYMBOL(napi_reuse_skb); -struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi, - struct napi_gro_fraginfo *info) +struct sk_buff *napi_get_frags(struct napi_struct *napi) { struct net_device *dev = napi->dev; struct sk_buff *skb = napi->skb; - struct ethhdr *eth; - skb_frag_t *frag; - int i; - - napi->skb = NULL; if (!skb) { skb = netdev_alloc_skb(dev, GRO_MAX_HEAD + NET_IP_ALIGN); @@ -2536,47 +2530,14 @@ struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi, goto out; skb_reserve(skb, NET_IP_ALIGN); - } - - BUG_ON(info->nr_frags > MAX_SKB_FRAGS); - frag = &info->frags[info->nr_frags - 1]; - for (i = skb_shinfo(skb)->nr_frags; i < info->nr_frags; i++) { - skb_fill_page_desc(skb, i, frag->page, frag->page_offset, - frag->size); - frag++; + napi->skb = skb; } - skb_shinfo(skb)->nr_frags = info->nr_frags; - - skb->data_len = info->len; - skb->len += info->len; - skb->truesize += info->len; - - skb_reset_mac_header(skb); - skb_gro_reset_offset(skb); - - eth = skb_gro_header(skb, sizeof(*eth)); - if (!eth) { - napi_reuse_skb(napi, skb); - skb = NULL; - goto out; - } - - skb_gro_pull(skb, sizeof(*eth)); - - /* - * This works because the only protocols we care about don't require - * special handling. We'll fix it up properly at the end. - */ - skb->protocol = eth->h_proto; - - skb->ip_summed = info->ip_summed; - skb->csum = info->csum; out: return skb; } -EXPORT_SYMBOL(napi_fraginfo_skb); +EXPORT_SYMBOL(napi_get_frags); int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret) { @@ -2606,9 +2567,39 @@ int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret) } EXPORT_SYMBOL(napi_frags_finish); -int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info) +struct sk_buff *napi_frags_skb(struct napi_struct *napi) +{ + struct sk_buff *skb = napi->skb; + struct ethhdr *eth; + + napi->skb = NULL; + + skb_reset_mac_header(skb); + skb_gro_reset_offset(skb); + + eth = skb_gro_header(skb, sizeof(*eth)); + if (!eth) { + napi_reuse_skb(napi, skb); + skb = NULL; + goto out; + } + + skb_gro_pull(skb, sizeof(*eth)); + + /* + * This works because the only protocols we care about don't require + * special handling. We'll fix it up properly at the end. + */ + skb->protocol = eth->h_proto; + +out: + return skb; +} +EXPORT_SYMBOL(napi_frags_skb); + +int napi_gro_frags(struct napi_struct *napi) { - struct sk_buff *skb = napi_fraginfo_skb(napi, info); + struct sk_buff *skb = napi_frags_skb(napi); if (!skb) return NET_RX_DROP; @@ -2712,7 +2703,7 @@ void netif_napi_del(struct napi_struct *napi) struct sk_buff *skb, *next; list_del_init(&napi->dev_list); - kfree_skb(napi->skb); + napi_free_frags(napi); for (skb = napi->gro_list; skb; skb = next) { next = skb->next; -- GitLab From d130fe5c95739472b61b30f3f2b401ee43d5e3ea Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 07:58:27 +0000 Subject: [PATCH 0307/6080] ipw2x00: remove old compat_net_dev_ops code Since both ipw2100 and ipw2200 are already converted to new net_device_ops this code is useless. Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/wireless/ipw2x00/libipw_module.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index 92a26922e792..8ce6e961c5da 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -154,10 +154,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv) goto failed; } ieee = netdev_priv(dev); -#ifdef CONFIG_COMPAT_NET_DEV_OPS - dev->hard_start_xmit = ieee80211_xmit; - dev->change_mtu = ieee80211_change_mtu; -#endif ieee->dev = dev; -- GitLab From 84381eed93c974024402eda250c9e7890b72ca4a Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 07:58:28 +0000 Subject: [PATCH 0308/6080] usbnet: remove old compat_net_dev_ops code Since all usb network drivers are already converted to net_device_ops this code is useless. Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/usb/usbnet.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index f3a2fce6166c..2b8b9036aff6 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1185,12 +1185,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) #endif net->netdev_ops = &usbnet_netdev_ops; -#ifdef CONFIG_COMPAT_NET_DEV_OPS - net->hard_start_xmit = usbnet_start_xmit; - net->open = usbnet_open; - net->stop = usbnet_stop; - net->tx_timeout = usbnet_tx_timeout; -#endif net->watchdog_timeo = TX_TIMEOUT_JIFFIES; net->ethtool_ops = &usbnet_ethtool_ops; -- GitLab From eb9bdaee550e4a56592ae12171b0be6de8fc9d17 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 07:58:29 +0000 Subject: [PATCH 0309/6080] 8390(p): remove old compat_net_dev_ops code Remove compat_net_dev_ops code and use struct net_device_ops instead of it. Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/8390.c | 10 ++-------- drivers/net/8390p.c | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/net/8390.c b/drivers/net/8390.c index ec3e22e6306f..21153dea8ebe 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -74,14 +74,8 @@ EXPORT_SYMBOL(ei_netdev_ops); struct net_device *__alloc_ei_netdev(int size) { struct net_device *dev = ____alloc_ei_netdev(size); -#ifdef CONFIG_COMPAT_NET_DEV_OPS - if (dev) { - dev->hard_start_xmit = ei_start_xmit; - dev->get_stats = ei_get_stats; - dev->set_multicast_list = ei_set_multicast_list; - dev->tx_timeout = ei_tx_timeout; - } -#endif + if (dev) + dev->netdev_ops = &ei_netdev_ops; return dev; } EXPORT_SYMBOL(__alloc_ei_netdev); diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c index da863c91d1d0..6ec11dafdb18 100644 --- a/drivers/net/8390p.c +++ b/drivers/net/8390p.c @@ -79,14 +79,8 @@ EXPORT_SYMBOL(eip_netdev_ops); struct net_device *__alloc_eip_netdev(int size) { struct net_device *dev = ____alloc_ei_netdev(size); -#ifdef CONFIG_COMPAT_NET_DEV_OPS - if (dev) { - dev->hard_start_xmit = eip_start_xmit; - dev->get_stats = eip_get_stats; - dev->set_multicast_list = eip_set_multicast_list; - dev->tx_timeout = eip_tx_timeout; - } -#endif + if (dev) + dev->netdev_ops = &eip_netdev_ops; return dev; } EXPORT_SYMBOL(__alloc_eip_netdev); -- GitLab From 7a4762abf20531fc8d0bdbe132bc63181b8bebe8 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:35 +0000 Subject: [PATCH 0310/6080] bmac: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/bmac.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 44d015f70d1c..9578a3dfac01 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1247,6 +1247,16 @@ static const struct ethtool_ops bmac_ethtool_ops = { .get_link = ethtool_op_get_link, }; +static const struct net_device_ops bmac_netdev_ops = { + .ndo_open = bmac_open, + .ndo_stop = bmac_close, + .ndo_start_xmit = bmac_output, + .ndo_set_multicast_list = bmac_set_multicast, + .ndo_set_mac_address = bmac_set_address, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match) { int j, rev, ret; @@ -1308,12 +1318,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i bmac_enable_and_reset_chip(dev); bmwrite(dev, INTDISABLE, DisableAll); - dev->open = bmac_open; - dev->stop = bmac_close; + dev->netdev_ops = &bmac_netdev_ops; dev->ethtool_ops = &bmac_ethtool_ops; - dev->hard_start_xmit = bmac_output; - dev->set_multicast_list = bmac_set_multicast; - dev->set_mac_address = bmac_set_address; bmac_get_station_address(dev, addr); if (bmac_verify_checksum(dev) != 0) -- GitLab From 63ef7d89cbecc249339a59c7a1ec58d2e8e88ea5 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:36 +0000 Subject: [PATCH 0311/6080] cpmac: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/cpmac.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 3f476c7c0736..af305c0b34d1 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1093,6 +1093,19 @@ static int cpmac_stop(struct net_device *dev) return 0; } +static const struct net_device_ops cpmac_netdev_ops = { + .ndo_open = cpmac_open, + .ndo_stop = cpmac_stop, + .ndo_start_xmit = cpmac_start_xmit, + .ndo_tx_timeout = cpmac_tx_timeout, + .ndo_set_multicast_list = cpmac_set_multicast_list, + .ndo_so_ioctl = cpmac_ioctl, + .ndo_set_config = cpmac_config, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + static int external_switch; static int __devinit cpmac_probe(struct platform_device *pdev) @@ -1143,14 +1156,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) dev->irq = platform_get_irq_byname(pdev, "irq"); - dev->open = cpmac_open; - dev->stop = cpmac_stop; - dev->set_config = cpmac_config; - dev->hard_start_xmit = cpmac_start_xmit; - dev->do_ioctl = cpmac_ioctl; - dev->set_multicast_list = cpmac_set_multicast_list; - dev->tx_timeout = cpmac_tx_timeout; - dev->ethtool_ops = &cpmac_ethtool_ops; + dev->netdev_ops = &cpmac_netdev_ops; + dev->ethtool_ops = &cpmac_ethtool_ops; netif_napi_add(dev, &priv->napi, cpmac_poll, 64); -- GitLab From d88106b70178a87203a23108c47eaa1f20c424b5 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:37 +0000 Subject: [PATCH 0312/6080] dm9000: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/dm9000.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index d8350860c0f8..e402e91bf188 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1170,6 +1170,21 @@ dm9000_stop(struct net_device *ndev) return 0; } +static const struct net_device_ops dm9000_netdev_ops = { + .ndo_open = dm9000_open, + .ndo_stop = dm9000_stop, + .ndo_start_xmit = dm9000_start_xmit, + .ndo_tx_timeout = dm9000_timeout, + .ndo_set_multicast_list = dm9000_hash_table, + .ndo_do_ioctl = dm9000_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = dm9000_poll_controller, +#endif +}; + #define res_size(_r) (((_r)->end - (_r)->start) + 1) /* @@ -1339,18 +1354,9 @@ dm9000_probe(struct platform_device *pdev) /* driver system function */ ether_setup(ndev); - ndev->open = &dm9000_open; - ndev->hard_start_xmit = &dm9000_start_xmit; - ndev->tx_timeout = &dm9000_timeout; - ndev->watchdog_timeo = msecs_to_jiffies(watchdog); - ndev->stop = &dm9000_stop; - ndev->set_multicast_list = &dm9000_hash_table; - ndev->ethtool_ops = &dm9000_ethtool_ops; - ndev->do_ioctl = &dm9000_ioctl; - -#ifdef CONFIG_NET_POLL_CONTROLLER - ndev->poll_controller = &dm9000_poll_controller; -#endif + ndev->netdev_ops = &dm9000_netdev_ops; + ndev->watchdog_timeo = msecs_to_jiffies(watchdog); + ndev->ethtool_ops = &dm9000_ethtool_ops; db->msg_enable = NETIF_MSG_LINK; db->mii.phy_id_mask = 0x1f; -- GitLab From 2e303a929f2178420820cbfab581ca1c7efa18e8 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:38 +0000 Subject: [PATCH 0313/6080] hplance: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/hplance.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c index 2e802634d366..3e3528ade259 100644 --- a/drivers/net/hplance.c +++ b/drivers/net/hplance.c @@ -71,6 +71,19 @@ static struct dio_driver hplance_driver = { .remove = __devexit_p(hplance_remove_one), }; +static const struct net_device_ops hplance_netdev_ops = { + .ndo_open = hplance_open, + .ndo_stop = hplance_close, + .ndo_start_xmit = lance_start_xmit, + .ndo_set_multicast_list = lance_set_multicast, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = lance_poll, +#endif +}; + /* Find all the HP Lance boards and initialise them... */ static int __devinit hplance_init_one(struct dio_dev *d, const struct dio_device_id *ent) @@ -135,13 +148,7 @@ static void __init hplance_init(struct net_device *dev, struct dio_dev *d) /* Fill the dev fields */ dev->base_addr = va; - dev->open = &hplance_open; - dev->stop = &hplance_close; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = lance_poll; -#endif - dev->hard_start_xmit = &lance_start_xmit; - dev->set_multicast_list = &lance_set_multicast; + dev->netdev_ops = &hplance_netdev_ops; dev->dma = 0; for (i=0; i<6; i++) { -- GitLab From e186d174e04a7c79606e1ee57abb7470861b3b00 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:39 +0000 Subject: [PATCH 0314/6080] ibmveth: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/ibmveth.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 5c6315df86b9..0a51b0bd1e49 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1203,6 +1203,20 @@ static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev) return ret; } +static const struct net_device_ops ibmveth_netdev_ops = { + .ndo_open = ibmveth_open, + .ndo_stop = ibmveth_close, + .ndo_start_xmit = ibmveth_start_xmit, + .ndo_set_multicast_list = ibmveth_set_multicast_list, + .ndo_do_ioctl = ibmveth_ioctl, + .ndo_change_mtu = ibmveth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ibmveth_poll_controller, +#endif +}; + static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) { int rc, i; @@ -1265,17 +1279,9 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ memcpy(&adapter->mac_addr, mac_addr_p, 6); netdev->irq = dev->irq; - netdev->open = ibmveth_open; - netdev->stop = ibmveth_close; - netdev->hard_start_xmit = ibmveth_start_xmit; - netdev->set_multicast_list = ibmveth_set_multicast_list; - netdev->do_ioctl = ibmveth_ioctl; - netdev->ethtool_ops = &netdev_ethtool_ops; - netdev->change_mtu = ibmveth_change_mtu; + netdev->netdev_ops = &ibmveth_netdev_ops; + netdev->ethtool_ops = &netdev_ethtool_ops; SET_NETDEV_DEV(netdev, &dev->dev); -#ifdef CONFIG_NET_POLL_CONTROLLER - netdev->poll_controller = ibmveth_poll_controller; -#endif netdev->features |= NETIF_F_LLTX; spin_lock_init(&adapter->stats_lock); -- GitLab From 602355a03508bf54dbf113234ef72d75080a492d Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:40 +0000 Subject: [PATCH 0315/6080] irda/au1k_ir: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/irda/au1k_ir.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index 941164076a2b..204def0f6451 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -198,6 +198,17 @@ static int au1k_irda_init_iobuf(iobuff_t *io, int size) return io->head ? 0 : -ENOMEM; } +static const struct net_device_ops au1k_irda_netdev_ops = { + .ndo_open = au1k_irda_start, + .ndo_stop = au1k_irda_stop, + .ndo_start_xmit = au1k_irda_hard_xmit, + .ndo_tx_timeout = au1k_tx_timeout, + .ndo_do_ioctl = au1k_irda_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + static int au1k_irda_net_init(struct net_device *dev) { struct au1k_private *aup = netdev_priv(dev); @@ -209,11 +220,7 @@ static int au1k_irda_net_init(struct net_device *dev) if (err) goto out1; - dev->open = au1k_irda_start; - dev->hard_start_xmit = au1k_irda_hard_xmit; - dev->stop = au1k_irda_stop; - dev->do_ioctl = au1k_irda_ioctl; - dev->tx_timeout = au1k_tx_timeout; + dev->netdev_ops = &au1k_irda_netdev_ops; irda_init_max_qos_capabilies(&aup->qos); -- GitLab From c76ccd6a256004cca1127c9afb5474638fc78b74 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:41 +0000 Subject: [PATCH 0316/6080] irda/pxaficp_ir: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/irda/pxaficp_ir.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index e775338b525f..e8ced56b050f 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -797,6 +797,16 @@ static int pxa_irda_init_iobuf(iobuff_t *io, int size) return io->head ? 0 : -ENOMEM; } +static const struct net_device_ops pxa_irda_netdev_ops = { + .ndo_open = pxa_irda_start, + .ndo_stop = pxa_irda_stop, + .ndo_start_xmit = pxa_irda_hard_xmit, + .ndo_do_ioctl = pxa_irda_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + static int pxa_irda_probe(struct platform_device *pdev) { struct net_device *dev; @@ -845,10 +855,7 @@ static int pxa_irda_probe(struct platform_device *pdev) if (err) goto err_startup; - dev->hard_start_xmit = pxa_irda_hard_xmit; - dev->open = pxa_irda_start; - dev->stop = pxa_irda_stop; - dev->do_ioctl = pxa_irda_ioctl; + dev->netdev_ops = &pxa_irda_netdev_ops; irda_init_max_qos_capabilies(&si->qos); -- GitLab From a1de966682551debbe690672e760487cc555c05f Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:42 +0000 Subject: [PATCH 0317/6080] irda/sa1100_ir: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/irda/sa1100_ir.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 7a2b003954ca..44a748e72332 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -875,6 +875,16 @@ static int sa1100_irda_init_iobuf(iobuff_t *io, int size) return io->head ? 0 : -ENOMEM; } +static const struct net_device_ops sa1100_irda_netdev_ops = { + .ndo_open = sa1100_irda_start, + .ndo_stop = sa1100_irda_stop, + .ndo_start_xmit = sa1100_irda_hard_xmit, + .ndo_do_ioctl = sa1100_irda_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + static int sa1100_irda_probe(struct platform_device *pdev) { struct net_device *dev; @@ -913,11 +923,8 @@ static int sa1100_irda_probe(struct platform_device *pdev) if (err) goto err_mem_5; - dev->hard_start_xmit = sa1100_irda_hard_xmit; - dev->open = sa1100_irda_start; - dev->stop = sa1100_irda_stop; - dev->do_ioctl = sa1100_irda_ioctl; - dev->irq = IRQ_Ser2ICP; + dev->netdev_ops = &sa1100_irda_netdev_ops; + dev->ir = IRQ_Ser2ICP; irda_init_max_qos_capabilies(&si->qos); -- GitLab From c2775360e82760be3ad7339a7a1442c45c35b395 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:43 +0000 Subject: [PATCH 0318/6080] iseries_veth: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/iseries_veth.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index cb793c2bade2..264654da85d1 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1021,6 +1021,16 @@ static const struct ethtool_ops ops = { .get_link = veth_get_link, }; +static const struct net_device_ops veth_netdev_ops = { + .ndo_open = veth_open, + .ndo_stop = veth_close, + .ndo_start_xmit = veth_start_xmit, + .ndo_change_mtu = veth_change_mtu, + .ndo_set_multicast_list = veth_set_multicast_list, + .ndo_set_mac_address = NULL, + .ndo_validate_addr = eth_validate_addr, +}; + static struct net_device *veth_probe_one(int vlan, struct vio_dev *vio_dev) { @@ -1067,12 +1077,7 @@ static struct net_device *veth_probe_one(int vlan, memcpy(&port->mac_addr, mac_addr, ETH_ALEN); - dev->open = veth_open; - dev->hard_start_xmit = veth_start_xmit; - dev->stop = veth_close; - dev->change_mtu = veth_change_mtu; - dev->set_mac_address = NULL; - dev->set_multicast_list = veth_set_multicast_list; + dev->netdev = &veth_netdev_ops; SET_ETHTOOL_OPS(dev, &ops); SET_NETDEV_DEV(dev, vdev); -- GitLab From e7090e347ad8bce0de35f9fe2b95e22e4ae8fbab Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:44 +0000 Subject: [PATCH 0319/6080] ixp2000/ixpdev: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/ixp2000/ixpdev.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index d3bf2f017cc2..2a0174b62e96 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c @@ -270,6 +270,18 @@ static int ixpdev_close(struct net_device *dev) return 0; } +static const struct net_device_ops ixpdev_netdev_ops = { + .ndo_open = ixpdev_open, + .ndo_stop = ixpdev_close, + .ndo_start_xmit = ixpdev_xmit, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = ixpdev_poll_controller, +#endif +}; + struct net_device *ixpdev_alloc(int channel, int sizeof_priv) { struct net_device *dev; @@ -279,12 +291,7 @@ struct net_device *ixpdev_alloc(int channel, int sizeof_priv) if (dev == NULL) return NULL; - dev->hard_start_xmit = ixpdev_xmit; - dev->open = ixpdev_open; - dev->stop = ixpdev_close; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = ixpdev_poll_controller; -#endif + dev->netdev_ops = &ixpdev_netdev_ops; dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM; -- GitLab From 502a326f833927a84a8de29f5fb638aa9da15f4b Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:45 +0000 Subject: [PATCH 0320/6080] jazzsonic: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/jazzsonic.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 14248cfc3dfd..d12106b47bf2 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -96,6 +96,18 @@ static int jazzsonic_close(struct net_device* dev) return err; } +static const struct net_device_ops sonic_netdev_ops = { + .ndo_open = jazzsonic_open, + .ndo_stop = jazzsonic_close, + .ndo_start_xmit = sonic_send_packet, + .ndo_get_stats = sonic_get_stats, + .ndo_set_multicast_list = sonic_multicast_list, + .ndo_tx_timeout = sonic_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __init sonic_probe1(struct net_device *dev) { static unsigned version_printed; @@ -179,12 +191,7 @@ static int __init sonic_probe1(struct net_device *dev) lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS * SONIC_BUS_SCALE(lp->dma_bitmode)); - dev->open = jazzsonic_open; - dev->stop = jazzsonic_close; - dev->hard_start_xmit = sonic_send_packet; - dev->get_stats = sonic_get_stats; - dev->set_multicast_list = &sonic_multicast_list; - dev->tx_timeout = sonic_tx_timeout; + dev->netdev_ops = &sonic_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; /* -- GitLab From 52b031ff3987a079ea759d81447312f1665dbfbd Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:46 +0000 Subject: [PATCH 0321/6080] korina: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/korina.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/net/korina.c b/drivers/net/korina.c index 38d6649a29c4..dc238567cae1 100644 --- a/drivers/net/korina.c +++ b/drivers/net/korina.c @@ -1081,6 +1081,21 @@ static int korina_close(struct net_device *dev) return 0; } +static const struct net_device_ops korina_netdev_ops = { + .ndo_open = korina_open, + .ndo_stop = korina_close, + .ndo_start_xmit = korina_send_packet, + .ndo_set_multicast_list = korina_multicast_list, + .ndo_tx_timeout = korina_tx_timeout, + .ndo_do_ioctl = korina_ioctl, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = korina_poll_controller, +#endif +}; + static int korina_probe(struct platform_device *pdev) { struct korina_device *bif = platform_get_drvdata(pdev); @@ -1149,17 +1164,9 @@ static int korina_probe(struct platform_device *pdev) dev->irq = lp->rx_irq; lp->dev = dev; - dev->open = korina_open; - dev->stop = korina_close; - dev->hard_start_xmit = korina_send_packet; - dev->set_multicast_list = &korina_multicast_list; + dev->netdev_ops = &korina_netdev_ops; dev->ethtool_ops = &netdev_ethtool_ops; - dev->tx_timeout = korina_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; - dev->do_ioctl = &korina_ioctl; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = korina_poll_controller; -#endif netif_napi_add(dev, &lp->napi, korina_poll, 64); lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05); -- GitLab From 71f4367ca24830d967fca7a9c1cfb944b08742e5 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:47 +0000 Subject: [PATCH 0322/6080] lib82596: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/lib82596.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c index 7415f517491d..070fa4500871 100644 --- a/drivers/net/lib82596.c +++ b/drivers/net/lib82596.c @@ -1036,6 +1036,19 @@ static void print_eth(unsigned char *add, char *str) printk(KERN_DEBUG "i596 0x%p, %pM --> %pM %02X%02X, %s\n", add, add + 6, add, add[12], add[13], str); } +static const struct net_device_ops i596_netdev_ops = { + .ndo_open = i596_open, + .ndo_stop = i596_close, + .ndo_start_xmit = i596_start_xmit, + .ndo_set_multicast_list = set_multicast_list, + .ndo_tx_timeout = i596_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = i596_poll_controller, +#endif +}; static int __devinit i82596_probe(struct net_device *dev) { @@ -1062,16 +1075,8 @@ static int __devinit i82596_probe(struct net_device *dev) return -ENOMEM; } - /* The 82596-specific entries in the device structure. */ - dev->open = i596_open; - dev->stop = i596_close; - dev->hard_start_xmit = i596_start_xmit; - dev->set_multicast_list = set_multicast_list; - dev->tx_timeout = i596_tx_timeout; + dev->netdev_ops = &i596_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = i596_poll_controller; -#endif memset(dma, 0, sizeof(struct i596_dma)); lp->dma = dma; -- GitLab From 488b4abcd750c0a600eefa4d9ab42aad980ace11 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:48 +0000 Subject: [PATCH 0323/6080] mace: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/mace.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/net/mace.c b/drivers/net/mace.c index feebbd92aff2..1ad740bc8878 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -94,6 +94,16 @@ static void __mace_set_address(struct net_device *dev, void *addr); */ static unsigned char *dummy_buf; +static const struct net_device_ops mace_netdev_ops = { + .ndo_open = mace_open, + .ndo_stop = mace_close, + .ndo_start_xmit = mace_xmit_start, + .ndo_set_multicast_list = mace_set_multicast, + .ndo_set_mac_address = mace_set_address, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; + static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match) { struct device_node *mace = macio_get_of_node(mdev); @@ -207,11 +217,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i } } - dev->open = mace_open; - dev->stop = mace_close; - dev->hard_start_xmit = mace_xmit_start; - dev->set_multicast_list = mace_set_multicast; - dev->set_mac_address = mace_set_address; + dev->netdev_ops = &mace_netdev_ops; /* * Most of what is below could be moved to mace_open() -- GitLab From 0d3936a8b11b72e1387923342e33fdad553271d4 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:49 +0000 Subject: [PATCH 0324/6080] macmace: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/macmace.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c index 274e99bb63ac..44f3c2896f20 100644 --- a/drivers/net/macmace.c +++ b/drivers/net/macmace.c @@ -180,6 +180,17 @@ static void mace_dma_off(struct net_device *dev) psc_write_word(PSC_ENETWR_CMD + PSC_SET1, 0x1100); } +static const struct net_device_ops mace_netdev_ops = { + .ndo_open = mace_open, + .ndo_stop = mace_close, + .ndo_start_xmit = mace_xmit_start, + .ndo_tx_timeout = mace_tx_timeout, + .ndo_set_multicast_list = mace_set_multicast, + .ndo_set_mac_address = mace_set_address, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; + /* * Not really much of a probe. The hardware table tells us if this * model of Macintrash has a MACE (AV macintoshes) @@ -240,13 +251,8 @@ static int __devinit mace_probe(struct platform_device *pdev) return -ENODEV; } - dev->open = mace_open; - dev->stop = mace_close; - dev->hard_start_xmit = mace_xmit_start; - dev->tx_timeout = mace_tx_timeout; + dev->netdev_ops = &mace_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; - dev->set_multicast_list = mace_set_multicast; - dev->set_mac_address = mace_set_address; printk(KERN_INFO "%s: 68K MACE, hardware address %pM\n", dev->name, dev->dev_addr); -- GitLab From d53bc2df189f1e11a947eed077f0360bfadf9986 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:50 +0000 Subject: [PATCH 0325/6080] meth: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/meth.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/net/meth.c b/drivers/net/meth.c index aa08987f6e81..46ffdb464ac4 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -769,9 +769,17 @@ static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } } -/* - * Return statistics to the caller - */ +static const struct net_device_ops meth_netdev_ops = { + .ndo_open = meth_open, + .ndo_stop = meth_release, + .ndo_start_xmit = meth_tx, + .ndo_do_ioctl = meth_ioctl, + .ndo_tx_timeout = meth_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + /* * The init function. */ @@ -785,16 +793,10 @@ static int __init meth_probe(struct platform_device *pdev) if (!dev) return -ENOMEM; - dev->open = meth_open; - dev->stop = meth_release; - dev->hard_start_xmit = meth_tx; - dev->do_ioctl = meth_ioctl; -#ifdef HAVE_TX_TIMEOUT - dev->tx_timeout = meth_tx_timeout; - dev->watchdog_timeo = timeout; -#endif - dev->irq = MACE_ETHERNET_IRQ; - dev->base_addr = (unsigned long)&mace->eth; + dev->netdev_ops = &meth_netdev_ops; + dev->watchdog_timeo = timeout; + dev->irq = MACE_ETHERNET_IRQ; + dev->base_addr = (unsigned long)&mace->eth; memcpy(dev->dev_addr, o2meth_eaddr, 6); priv = netdev_priv(dev); -- GitLab From d6771e0b895f04e8bbd12f12fb3a97e130a4a5f4 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:51 +0000 Subject: [PATCH 0326/6080] mipsnet: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/mipsnet.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index 664835b822fb..b3b9a147d09a 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c @@ -237,6 +237,16 @@ static void mipsnet_set_mclist(struct net_device *dev) { } +static const struct net_device_ops mipsnet_netdev_ops = { + .ndo_open = mipsnet_open, + .ndo_stop = mipsnet_close, + .ndo_start_xmit = mipsnet_xmit, + .ndo_set_multicast_list = mipsnet_set_mclist, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + static int __init mipsnet_probe(struct platform_device *dev) { struct net_device *netdev; @@ -250,10 +260,7 @@ static int __init mipsnet_probe(struct platform_device *dev) platform_set_drvdata(dev, netdev); - netdev->open = mipsnet_open; - netdev->stop = mipsnet_close; - netdev->hard_start_xmit = mipsnet_xmit; - netdev->set_multicast_list = mipsnet_set_mclist; + netdev->netdev_ops = &mipsnet_netdev_ops; /* * TODO: probe for these or load them from PARAM -- GitLab From 96cd55ea0edac7f6d51d2391d5cc1b5c2e360e67 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:52 +0000 Subject: [PATCH 0327/6080] mvme147: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/mvme147.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c index 435e5a847c43..93c709d63e2f 100644 --- a/drivers/net/mvme147.c +++ b/drivers/net/mvme147.c @@ -57,6 +57,17 @@ typedef void (*writerap_t)(void *, unsigned short); typedef void (*writerdp_t)(void *, unsigned short); typedef unsigned short (*readrdp_t)(void *); +static const struct net_device_ops lance_netdev_ops = { + .ndo_open = m147lance_open, + .ndo_stop = m147lance_close, + .ndo_start_xmit = lance_start_xmit, + .ndo_set_multicast_list = lance_set_multicast, + .ndo_tx_timeout = lance_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + /* Initialise the one and only on-board 7990 */ struct net_device * __init mvme147lance_probe(int unit) { @@ -81,11 +92,7 @@ struct net_device * __init mvme147lance_probe(int unit) /* Fill the dev fields */ dev->base_addr = (unsigned long)MVME147_LANCE_BASE; - dev->open = &m147lance_open; - dev->stop = &m147lance_close; - dev->hard_start_xmit = &lance_start_xmit; - dev->set_multicast_list = &lance_set_multicast; - dev->tx_timeout = &lance_tx_timeout; + dev->netdev_ops = &lance_netdev_ops; dev->dma = 0; addr=(u_long *)ETHERNET_ADDRESS; -- GitLab From cd732de21e3d4f0b905fdbee8abfbb8192144b3d Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:53 +0000 Subject: [PATCH 0328/6080] netx-eth: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/netx-eth.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c index 1861d5bbd96b..946366dcc992 100644 --- a/drivers/net/netx-eth.c +++ b/drivers/net/netx-eth.c @@ -301,6 +301,17 @@ netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value) while (readl(NETX_MIIMU) & MIIMU_SNRDY); } +static const struct net_device_ops netx_eth_netdev_ops = { + .ndo_open = netx_eth_open, + .ndo_stop = netx_eth_close, + .ndo_start_xmit = netx_eth_hard_start_xmit, + .ndo_tx_timeout = netx_eth_timeout, + .ndo_set_multicast_list = netx_eth_set_multicast_list, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + static int netx_eth_enable(struct net_device *ndev) { struct netx_eth_priv *priv = netdev_priv(ndev); @@ -309,12 +320,8 @@ static int netx_eth_enable(struct net_device *ndev) ether_setup(ndev); - ndev->open = netx_eth_open; - ndev->stop = netx_eth_close; - ndev->hard_start_xmit = netx_eth_hard_start_xmit; - ndev->tx_timeout = netx_eth_timeout; + ndev->netdev_ops = &netx_eth_netdev_ops; ndev->watchdog_timeo = msecs_to_jiffies(5000); - ndev->set_multicast_list = netx_eth_set_multicast_list; priv->msg_enable = NETIF_MSG_LINK; priv->mii.phy_id_mask = 0x1f; -- GitLab From 9e0ac841f42df4e7acdab7dc1620de0933ed56d7 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:54 +0000 Subject: [PATCH 0329/6080] pasemi_mac: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/pasemi_mac.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 5eeb5a87b738..067caba43656 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -1735,6 +1735,19 @@ out: return ret; } +static const struct net_device_ops pasemi_netdev_ops = { + .ndo_open = pasemi_mac_open, + .ndo_stop = pasemi_mac_close, + .ndo_start_xmit = pasemi_mac_start_tx, + .ndo_set_multicast_list = pasemi_mac_set_rx_mode, + .ndo_set_mac_address = pasemi_mac_set_mac_addr, + .ndo_change_mtu = pasemi_mac_change_mtu, + .ndo_validate_addr = eth_validate_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = pasemi_mac_netpoll, +#endif +}; + static int __devinit pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1817,19 +1830,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out; } - dev->open = pasemi_mac_open; - dev->stop = pasemi_mac_close; - dev->hard_start_xmit = pasemi_mac_start_tx; - dev->set_multicast_list = pasemi_mac_set_rx_mode; - dev->set_mac_address = pasemi_mac_set_mac_addr; + dev->netdev_ops = &pasemi_netdev_ops; dev->mtu = PE_DEF_MTU; /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */ mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = pasemi_mac_netpoll; -#endif - dev->change_mtu = pasemi_mac_change_mtu; dev->ethtool_ops = &pasemi_mac_ethtool_ops; if (err) -- GitLab From 1ec847f6d46f041bb2ae65efc7b00d122b03d212 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:55 +0000 Subject: [PATCH 0330/6080] pci-skeleton: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/pci-skeleton.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index c95fd72c3bb9..8c1f6988f398 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -728,6 +728,17 @@ err_out: return rc; } +static const struct net_device_ops netdrv_netdev_ops = { + .ndo_open = netdrv_open, + .ndo_stop = netdrv_close, + .ndo_start_xmit = netdrv_start_xmit, + .ndo_set_multicast_list = netdrv_set_rx_mode, + .ndo_do_ioctl = netdrv_ioctl, + .ndo_tx_timeout = netdrv_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; static int __devinit netdrv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) @@ -769,13 +780,7 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev, ((u16 *) (dev->dev_addr))[i] = le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len)); - /* The Rtl8139-specific entries in the device structure. */ - dev->open = netdrv_open; - dev->hard_start_xmit = netdrv_start_xmit; - dev->stop = netdrv_close; - dev->set_multicast_list = netdrv_set_rx_mode; - dev->do_ioctl = netdrv_ioctl; - dev->tx_timeout = netdrv_tx_timeout; + dev->netdev_ops = &netdrv_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; dev->irq = pdev->irq; -- GitLab From a33a2bb3c9f38c79e97f6ed720412d946e894e81 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:56 +0000 Subject: [PATCH 0331/6080] rionet: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/rionet.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index ec59e29807a6..8702e7acdee6 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -428,6 +428,15 @@ static const struct ethtool_ops rionet_ethtool_ops = { .get_link = ethtool_op_get_link, }; +static const struct net_device_ops rionet_netdev_ops = { + .ndo_open = rionet_open, + .ndo_stop = rionet_close, + .ndo_start_xmit = rionet_start_xmit, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +}; + static int rionet_setup_netdev(struct rio_mport *mport) { int rc = 0; @@ -466,10 +475,7 @@ static int rionet_setup_netdev(struct rio_mport *mport) ndev->dev_addr[4] = device_id >> 8; ndev->dev_addr[5] = device_id & 0xff; - /* Fill in the driver function table */ - ndev->open = &rionet_open; - ndev->hard_start_xmit = &rionet_start_xmit; - ndev->stop = &rionet_close; + ndev->netdev_ops = &rionet_netdev_ops; ndev->mtu = RIO_MAX_MSG_SIZE - 14; ndev->features = NETIF_F_LLTX; SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops); -- GitLab From b4cf3421afce25655233cf66f6ec545baa8cb6ae Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:57 +0000 Subject: [PATCH 0332/6080] sb1250-mac: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/sb1250-mac.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index ce7551e17ba7..aaeebf57a9a4 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -2271,6 +2271,21 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu) return 0; } +static const struct net_device_ops sbmac_netdev_ops = { + .ndo_open = sbmac_open, + .ndo_stop = sbmac_close, + .ndo_start_xmit = sbmac_start_tx, + .ndo_set_multicast_list = sbmac_set_rx_mode, + .ndo_tx_timeout = sbmac_tx_timeout, + .ndo_do_ioctl = sbmac_mii_ioctl, + .ndo_change_mtu = sb1250_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = sbmac_netpoll, +#endif +}; + /********************************************************************** * SBMAC_INIT(dev) * @@ -2327,21 +2342,11 @@ static int sbmac_init(struct platform_device *pldev, long long base) spin_lock_init(&(sc->sbm_lock)); - dev->open = sbmac_open; - dev->hard_start_xmit = sbmac_start_tx; - dev->stop = sbmac_close; - dev->set_multicast_list = sbmac_set_rx_mode; - dev->do_ioctl = sbmac_mii_ioctl; - dev->tx_timeout = sbmac_tx_timeout; - dev->watchdog_timeo = TX_TIMEOUT; + dev->netdev_ops = &sbmac_netdev_ops; + dev->watchdog_timeo = TX_TIMEOUT; netif_napi_add(dev, &sc->napi, sbmac_poll, 16); - dev->change_mtu = sb1250_change_mtu; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = sbmac_netpoll; -#endif - dev->irq = UNIT_INT(idx); /* This is needed for PASS2 for Rx H/W checksum feature */ -- GitLab From 8c2c6be186097aafd8f8a17927203b457545cc69 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:58 +0000 Subject: [PATCH 0333/6080] sgiseeq: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/sgiseeq.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 97d68560067d..5fb88ca6dd7f 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -709,6 +709,17 @@ static inline void setup_rx_ring(struct net_device *dev, dma_sync_desc_dev(dev, &buf[i]); } +static const struct net_device_ops sgiseeq_netdev_ops = { + .ndo_open = sgiseeq_open, + .ndo_stop = sgiseeq_close, + .ndo_start_xmit = sgiseeq_start_xmit, + .ndo_tx_timeout = timeout, + .ndo_set_multicast_list = sgiseeq_set_multicast, + .ndo_set_mac_address = sgiseeq_set_mac_address, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; + static int __init sgiseeq_probe(struct platform_device *pdev) { struct sgiseeq_platform_data *pd = pdev->dev.platform_data; @@ -775,13 +786,8 @@ static int __init sgiseeq_probe(struct platform_device *pdev) SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT | SEEQ_CTRL_ENCARR; - dev->open = sgiseeq_open; - dev->stop = sgiseeq_close; - dev->hard_start_xmit = sgiseeq_start_xmit; - dev->tx_timeout = timeout; + dev->netdev_ops = &sgiseeq_netdev_ops; dev->watchdog_timeo = (200 * HZ) / 1000; - dev->set_multicast_list = sgiseeq_set_multicast; - dev->set_mac_address = sgiseeq_set_mac_address; dev->irq = irq; if (register_netdev(dev)) { -- GitLab From ec4e0cff9b8c97f5d63c8f1bdf7f44fb65fa8e3b Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:52:59 +0000 Subject: [PATCH 0334/6080] smc911x: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/smc911x.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 293610334a77..bc4976ac8712 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -1774,6 +1774,20 @@ static int __devinit smc911x_findirq(struct net_device *dev) return probe_irq_off(cookie); } +static const struct net_device_ops smc911x_netdev_ops = { + .ndo_open = smc911x_open, + .ndo_stop = smc911x_close, + .ndo_start_xmit = smc911x_hard_start_xmit, + .ndo_tx_timeout = smc911x_timeout, + .ndo_set_multicast_list = smc911x_set_multicast_list, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = smc911x_poll_controller, +#endif +}; + /* * Function: smc911x_probe(unsigned long ioaddr) * @@ -1940,16 +1954,9 @@ static int __devinit smc911x_probe(struct net_device *dev) /* Fill in the fields of the device structure with ethernet values. */ ether_setup(dev); - dev->open = smc911x_open; - dev->stop = smc911x_close; - dev->hard_start_xmit = smc911x_hard_start_xmit; - dev->tx_timeout = smc911x_timeout; + dev->netdev_ops = &smc911x_netdev_ops; dev->watchdog_timeo = msecs_to_jiffies(watchdog); - dev->set_multicast_list = smc911x_set_multicast_list; dev->ethtool_ops = &smc911x_ethtool_ops; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = smc911x_poll_controller; -#endif INIT_WORK(&lp->phy_configure, smc911x_phy_configure); lp->mii.phy_id_mask = 0x1f; -- GitLab From 2160187a0a1cdeeeff1d41f53333bea91c82f259 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 15 Apr 2009 12:53:00 +0000 Subject: [PATCH 0335/6080] sun3lance: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/sun3lance.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index e5beb299cbd0..9bd9dadb8534 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -294,6 +294,16 @@ out: return ERR_PTR(err); } +static const struct net_device_ops lance_netdev_ops = { + .ndo_open = lance_open, + .ndo_stop = lance_close, + .ndo_start_xmit = lance_start_xmit, + .ndo_set_multicast_list = set_multicast_list, + .ndo_set_mac_address = NULL, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; + static int __init lance_probe( struct net_device *dev) { unsigned long ioaddr; @@ -397,12 +407,7 @@ static int __init lance_probe( struct net_device *dev) if (did_version++ == 0) printk( version ); - /* The LANCE-specific entries in the device structure. */ - dev->open = &lance_open; - dev->hard_start_xmit = &lance_start_xmit; - dev->stop = &lance_close; - dev->set_multicast_list = &set_multicast_list; - dev->set_mac_address = NULL; + dev->netdev_ops = &lance_netdev_ops; // KLUDGE -- REMOVE ME set_bit(__LINK_STATE_PRESENT, &dev->state); -- GitLab From f44d6305280378cb34319e0118e18d84cc7ac773 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 03:11:30 +0000 Subject: [PATCH 0336/6080] fec: switch to writel/readl Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 279 +++++++++++++++++++--------------------------- drivers/net/fec.h | 119 ++++++++------------ 2 files changed, 161 insertions(+), 237 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index a515acccc61f..37b333265629 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -165,7 +165,7 @@ typedef struct { */ struct fec_enet_private { /* Hardware registers of the FEC device */ - volatile fec_t *hwp; + void __iomem *hwp; struct net_device *netdev; @@ -288,15 +288,11 @@ static int mii_queue(struct net_device *dev, int request, static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct fec_enet_private *fep; - volatile fec_t *fecp; + struct fec_enet_private *fep = netdev_priv(dev); volatile cbd_t *bdp; unsigned short status; unsigned long flags; - fep = netdev_priv(dev); - fecp = (volatile fec_t*)dev->base_addr; - if (!fep->link) { /* Link is down or autonegotiation is in progress. */ return 1; @@ -363,7 +359,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->trans_start = jiffies; /* Trigger transmission start */ - fecp->fec_x_des_active = 0; + writel(0, fep->hwp + FEC_X_DES_ACTIVE); /* If this was the last BD in the ring, start at the beginning again. */ @@ -436,29 +432,25 @@ static irqreturn_t fec_enet_interrupt(int irq, void * dev_id) { struct net_device *dev = dev_id; - volatile fec_t *fecp; + struct fec_enet_private *fep = netdev_priv(dev); uint int_events; irqreturn_t ret = IRQ_NONE; - fecp = (volatile fec_t*)dev->base_addr; - - /* Get the interrupt events that caused us to be here. - */ + /* Get the interrupt events that caused us to be here. */ do { - int_events = fecp->fec_ievent; - fecp->fec_ievent = int_events; + int_events = readl(fep->hwp + FEC_IEVENT); + writel(int_events, fep->hwp + FEC_IEVENT); - /* Handle receive event in its own function. - */ + /* Handle receive event in its own function. */ if (int_events & FEC_ENET_RXF) { ret = IRQ_HANDLED; fec_enet_rx(dev); } /* Transmit OK, or non-fatal error. Update the buffer - descriptors. FEC handles all errors, we just discover - them as part of the transmit process. - */ + * descriptors. FEC handles all errors, we just discover + * them as part of the transmit process. + */ if (int_events & FEC_ENET_TXF) { ret = IRQ_HANDLED; fec_enet_tx(dev); @@ -555,8 +547,7 @@ fec_enet_tx(struct net_device *dev) static void fec_enet_rx(struct net_device *dev) { - struct fec_enet_private *fep; - volatile fec_t *fecp; + struct fec_enet_private *fep = netdev_priv(dev); volatile cbd_t *bdp; unsigned short status; struct sk_buff *skb; @@ -567,9 +558,6 @@ fec_enet_rx(struct net_device *dev) flush_cache_all(); #endif - fep = netdev_priv(dev); - fecp = (volatile fec_t*)dev->base_addr; - spin_lock_irq(&fep->hw_lock); /* First, grab all of the stats for the incoming packet. @@ -665,7 +653,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { * incoming frames. On a heavily loaded network, we should be * able to keep up at the expense of system resources. */ - fecp->fec_r_des_active = 0; + writel(0, fep->hwp + FEC_R_DES_ACTIVE); #endif } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ fep->cur_rx = (cbd_t *)bdp; @@ -690,30 +678,25 @@ static void fec_enet_mii(struct net_device *dev) { struct fec_enet_private *fep; - volatile fec_t *ep; mii_list_t *mip; - uint mii_reg; fep = netdev_priv(dev); spin_lock_irq(&fep->mii_lock); - ep = fep->hwp; - mii_reg = ep->fec_mii_data; - if ((mip = mii_head) == NULL) { printk("MII and no head!\n"); goto unlock; } if (mip->mii_func != NULL) - (*(mip->mii_func))(mii_reg, dev); + (*(mip->mii_func))(readl(fep->hwp + FEC_MII_DATA), dev); mii_head = mip->mii_next; mip->mii_next = mii_free; mii_free = mip; if ((mip = mii_head) != NULL) - ep->fec_mii_data = mip->mii_regval; + writel(mip->mii_regval, fep->hwp + FEC_MII_DATA); unlock: spin_unlock_irq(&fep->mii_lock); @@ -745,7 +728,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi mii_tail = mip; } else { mii_head = mii_tail = mip; - fep->hwp->fec_mii_data = regval; + writel(regval, fep->hwp + FEC_MII_DATA); } } else { retval = 1; @@ -1245,11 +1228,8 @@ static void __inline__ fec_phy_ack_intr(void) static void __inline__ fec_get_mac(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile fec_t *fecp; unsigned char *iap, tmpaddr[ETH_ALEN]; - fecp = fep->hwp; - if (FEC_FLASHMAC) { /* * Get MAC address from FLASH. @@ -1263,8 +1243,8 @@ static void __inline__ fec_get_mac(struct net_device *dev) (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) iap = fec_mac_default; } else { - *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; - *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); + *((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW); + *((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16); iap = &tmpaddr[0]; } @@ -1456,11 +1436,9 @@ static void mii_discover_phy(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep; - volatile fec_t *fecp; uint phytype; fep = netdev_priv(dev); - fecp = fep->hwp; if (fep->phy_addr < 32) { if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) { @@ -1478,7 +1456,8 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) } else { printk("FEC: No PHY device found.\n"); /* Disable external MII interface */ - fecp->fec_mii_speed = fep->phy_speed = 0; + writel(0, fep->hwp + FEC_MII_SPEED); + fep->phy_speed = 0; #ifdef HAVE_mii_link_interrupt fec_disable_phy_intr(); #endif @@ -1582,32 +1561,31 @@ fec_enet_close(struct net_device *dev) static void set_multicast_list(struct net_device *dev) { - struct fec_enet_private *fep; - volatile fec_t *ep; + struct fec_enet_private *fep = netdev_priv(dev); struct dev_mc_list *dmi; - unsigned int i, j, bit, data, crc; + unsigned int i, j, bit, data, crc, tmp; unsigned char hash; - fep = netdev_priv(dev); - ep = fep->hwp; - if (dev->flags&IFF_PROMISC) { - ep->fec_r_cntrl |= 0x0008; + tmp = readl(fep->hwp + FEC_R_CNTRL); + tmp |= 0x8; + writel(tmp, fep->hwp + FEC_R_CNTRL); } else { - - ep->fec_r_cntrl &= ~0x0008; + tmp = readl(fep->hwp + FEC_R_CNTRL); + tmp &= ~0x8; + writel(tmp, fep->hwp + FEC_R_CNTRL); if (dev->flags & IFF_ALLMULTI) { /* Catch all multicast addresses, so set the * filter to all 1's. */ - ep->fec_grp_hash_table_high = 0xffffffff; - ep->fec_grp_hash_table_low = 0xffffffff; + writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW); } else { /* Clear filter and add the addresses in hash register. */ - ep->fec_grp_hash_table_high = 0; - ep->fec_grp_hash_table_low = 0; + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); dmi = dev->mc_list; @@ -1637,10 +1615,15 @@ static void set_multicast_list(struct net_device *dev) */ hash = (crc >> (32 - HASH_BITS)) & 0x3f; - if (hash > 31) - ep->fec_grp_hash_table_high |= 1 << (hash - 32); - else - ep->fec_grp_hash_table_low |= 1 << hash; + if (hash > 31) { + tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + tmp |= 1 << (hash - 32); + writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + } else { + tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW); + tmp |= 1 << hash; + writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW); + } } } } @@ -1651,16 +1634,14 @@ static void set_multicast_list(struct net_device *dev) static void fec_set_mac_address(struct net_device *dev) { - volatile fec_t *fecp; - - fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp; + struct fec_enet_private *fep = netdev_priv(dev); /* Set station address. */ - fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) | - (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24); - fecp->fec_addr_high = (dev->dev_addr[5] << 16) | - (dev->dev_addr[4] << 24); - + writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) | + (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24), + fep->hwp + FEC_ADDR_LOW); + writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24), + fep + FEC_ADDR_HIGH); } /* @@ -1674,7 +1655,6 @@ int __init fec_enet_init(struct net_device *dev, int index) unsigned long mem_addr; volatile cbd_t *bdp; cbd_t *cbd_base; - volatile fec_t *fecp; int i, j; /* Allocate memory for buffer descriptors. @@ -1689,17 +1669,13 @@ int __init fec_enet_init(struct net_device *dev, int index) spin_lock_init(&fep->hw_lock); spin_lock_init(&fep->mii_lock); - /* Create an Ethernet device instance. - */ - fecp = (volatile fec_t *)dev->base_addr; - fep->index = index; - fep->hwp = fecp; + fep->hwp = (void __iomem *)dev->base_addr; fep->netdev = dev; /* Whack a reset. We should wait for this. */ - fecp->fec_ecntrl = 1; + writel(1, fep->hwp + FEC_ECNTRL); udelay(10); /* Set the Ethernet address */ @@ -1708,12 +1684,12 @@ int __init fec_enet_init(struct net_device *dev, int index) #else { unsigned long l; - l = fecp->fec_addr_low; + l = readl(fep->hwp + FEC_ADDR_LOW); dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24); dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16); dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8); dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0); - l = fecp->fec_addr_high; + l = readl(fep->hwp + FEC_ADDR_HIGH); dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24); dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16); } @@ -1783,22 +1759,22 @@ int __init fec_enet_init(struct net_device *dev, int index) /* Set receive and transmit descriptor base. */ - fecp->fec_r_des_start = fep->bd_dma; - fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) - * RX_RING_SIZE; + writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); + writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE, + fep->hwp + FEC_X_DES_START); #ifdef HAVE_mii_link_interrupt fec_request_mii_intr(dev); #endif - fecp->fec_grp_hash_table_high = 0; - fecp->fec_grp_hash_table_low = 0; - fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; - fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); + writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); + writel(2, fep->hwp + FEC_ECNTRL); + writel(0, fep->hwp + FEC_R_DES_ACTIVE); #ifndef CONFIG_M5272 - fecp->fec_hash_table_high = 0; - fecp->fec_hash_table_low = 0; + writel(0, fep->hwp + FEC_HASH_TABLE_HIGH); + writel(0, fep->hwp + FEC_HASH_TABLE_LOW); #endif /* The FEC Ethernet specific entries in the device structure. */ @@ -1814,20 +1790,21 @@ int __init fec_enet_init(struct net_device *dev, int index) mii_free = mii_cmds; /* setup MII interface */ - fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; - fecp->fec_x_cntrl = 0x00; + writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL); + writel(0, fep->hwp + FEC_X_CNTRL); /* * Set MII speed to 2.5 MHz */ fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999) / 2500000) / 2) & 0x3F) << 1; - fecp->fec_mii_speed = fep->phy_speed; + writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); fec_restart(dev, 0); /* Clear and enable interrupts */ - fecp->fec_ievent = 0xffc00000; - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); + writel(0xffc00000, fep->hwp + FEC_IEVENT); + writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII, + fep->hwp + FEC_IMASK); /* Queue up command to detect the PHY and initialize the * remainder of the interface. @@ -1846,47 +1823,36 @@ int __init fec_enet_init(struct net_device *dev, int index) static void fec_restart(struct net_device *dev, int duplex) { - struct fec_enet_private *fep; + struct fec_enet_private *fep = netdev_priv(dev); volatile cbd_t *bdp; - volatile fec_t *fecp; int i; - fep = netdev_priv(dev); - fecp = fep->hwp; - - /* Whack a reset. We should wait for this. - */ - fecp->fec_ecntrl = 1; + /* Whack a reset. We should wait for this. */ + writel(1, fep->hwp + FEC_ECNTRL); udelay(10); - /* Clear any outstanding interrupt. - */ - fecp->fec_ievent = 0xffc00000; + /* Clear any outstanding interrupt. */ + writel(0xffc00000, fep->hwp + FEC_IEVENT); - /* Set station address. - */ + /* Set station address. */ fec_set_mac_address(dev); - /* Reset all multicast. - */ - fecp->fec_grp_hash_table_high = 0; - fecp->fec_grp_hash_table_low = 0; + /* Reset all multicast. */ + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); - /* Set maximum receive buffer size. - */ - fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; + /* Set maximum receive buffer size. */ + writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); - /* Set receive and transmit descriptor base. - */ - fecp->fec_r_des_start = fep->bd_dma; - fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t) - * RX_RING_SIZE; + /* Set receive and transmit descriptor base. */ + writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); + writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE, + fep->hwp + FEC_X_DES_START); fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; fep->cur_rx = fep->rx_bd_base; - /* Reset SKB transmit buffers. - */ + /* Reset SKB transmit buffers. */ fep->skb_cur = fep->skb_dirty = 0; for (i=0; i<=TX_RING_MOD_MASK; i++) { if (fep->tx_skbuff[i] != NULL) { @@ -1895,96 +1861,81 @@ fec_restart(struct net_device *dev, int duplex) } } - /* Initialize the receive buffer descriptors. - */ + /* Initialize the receive buffer descriptors. */ bdp = fep->rx_bd_base; for (i=0; icbd_sc = BD_ENET_RX_EMPTY; bdp++; } - /* Set the last buffer to wrap. - */ + /* Set the last buffer to wrap. */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* ...and the same for transmmit. - */ + /* ...and the same for transmmit. */ bdp = fep->tx_bd_base; for (i=0; icbd_sc = 0; bdp->cbd_bufaddr = 0; bdp++; } - /* Set the last buffer to wrap. - */ + /* Set the last buffer to wrap. */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* Enable MII mode. - */ + /* Enable MII mode. */ if (duplex) { - fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */ - fecp->fec_x_cntrl = 0x04; /* FD enable */ + /* MII enable / FD enable */ + writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL); + writel(0x04, fep->hwp + FEC_X_CNTRL); } else { - /* MII enable|No Rcv on Xmit */ - fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06; - fecp->fec_x_cntrl = 0x00; + /* MII enable / No Rcv on Xmit */ + writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL); + writel(0x0, fep->hwp + FEC_X_CNTRL); } fep->full_duplex = duplex; - /* Set MII speed. - */ - fecp->fec_mii_speed = fep->phy_speed; + /* Set MII speed. */ + writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); - /* And last, enable the transmit and receive processing. - */ - fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; + /* And last, enable the transmit and receive processing. */ + writel(2, fep->hwp + FEC_ECNTRL); + writel(0, fep->hwp + FEC_R_DES_ACTIVE); - /* Enable interrupts we wish to service. - */ - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); + /* Enable interrupts we wish to service. */ + writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII, + fep->hwp + FEC_IMASK); } static void fec_stop(struct net_device *dev) { - volatile fec_t *fecp; - struct fec_enet_private *fep; - - fep = netdev_priv(dev); - fecp = fep->hwp; + struct fec_enet_private *fep = netdev_priv(dev); /* ** We cannot expect a graceful transmit stop without link !!! */ - if (fep->link) - { - fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ + if (fep->link) { + writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */ udelay(10); - if (!(fecp->fec_ievent & FEC_ENET_GRA)) + if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA)) printk("fec_stop : Graceful transmit stop did not complete !\n"); - } + } - /* Whack a reset. We should wait for this. - */ - fecp->fec_ecntrl = 1; + /* Whack a reset. We should wait for this. */ + writel(1, fep->hwp + FEC_ECNTRL); udelay(10); - /* Clear outstanding MII command interrupts. - */ - fecp->fec_ievent = FEC_ENET_MII; + /* Clear outstanding MII command interrupts. */ + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); - fecp->fec_imask = FEC_ENET_MII; - fecp->fec_mii_speed = fep->phy_speed; + writel(FEC_ENET_MII, fep->hwp + FEC_IMASK); + writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); } static int __devinit diff --git a/drivers/net/fec.h b/drivers/net/fec.h index 76c64c92e190..5474ba39d46c 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h @@ -20,82 +20,55 @@ * registers in the same peripheral device on different models * of the ColdFire! */ -typedef struct fec { - unsigned long fec_reserved0; - unsigned long fec_ievent; /* Interrupt event reg */ - unsigned long fec_imask; /* Interrupt mask reg */ - unsigned long fec_reserved1; - unsigned long fec_r_des_active; /* Receive descriptor reg */ - unsigned long fec_x_des_active; /* Transmit descriptor reg */ - unsigned long fec_reserved2[3]; - unsigned long fec_ecntrl; /* Ethernet control reg */ - unsigned long fec_reserved3[6]; - unsigned long fec_mii_data; /* MII manage frame reg */ - unsigned long fec_mii_speed; /* MII speed control reg */ - unsigned long fec_reserved4[7]; - unsigned long fec_mib_ctrlstat; /* MIB control/status reg */ - unsigned long fec_reserved5[7]; - unsigned long fec_r_cntrl; /* Receive control reg */ - unsigned long fec_reserved6[15]; - unsigned long fec_x_cntrl; /* Transmit Control reg */ - unsigned long fec_reserved7[7]; - unsigned long fec_addr_low; /* Low 32bits MAC address */ - unsigned long fec_addr_high; /* High 16bits MAC address */ - unsigned long fec_opd; /* Opcode + Pause duration */ - unsigned long fec_reserved8[10]; - unsigned long fec_hash_table_high; /* High 32bits hash table */ - unsigned long fec_hash_table_low; /* Low 32bits hash table */ - unsigned long fec_grp_hash_table_high;/* High 32bits hash table */ - unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */ - unsigned long fec_reserved9[7]; - unsigned long fec_x_wmrk; /* FIFO transmit water mark */ - unsigned long fec_reserved10; - unsigned long fec_r_bound; /* FIFO receive bound reg */ - unsigned long fec_r_fstart; /* FIFO receive start reg */ - unsigned long fec_reserved11[11]; - unsigned long fec_r_des_start; /* Receive descriptor ring */ - unsigned long fec_x_des_start; /* Transmit descriptor ring */ - unsigned long fec_r_buff_size; /* Maximum receive buff size */ -} fec_t; +#define FEC_IEVENT 0x004 /* Interrupt event reg */ +#define FEC_IMASK 0x008 /* Interrupt mask reg */ +#define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */ +#define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */ +#define FEC_ECNTRL 0x024 /* Ethernet control reg */ +#define FEC_MII_DATA 0x040 /* MII manage frame reg */ +#define FEC_MII_SPEED 0x044 /* MII speed control reg */ +#define FEC_MIB_CTRLSTAT 0x064 /* MIB control/status reg */ +#define FEC_R_CNTRL 0x084 /* Receive control reg */ +#define FEC_X_CNTRL 0x0c4 /* Transmit Control reg */ +#define FEC_ADDR_LOW 0x0e4 /* Low 32bits MAC address */ +#define FEC_ADDR_HIGH 0x0e8 /* High 16bits MAC address */ +#define FEC_OPD 0x0ec /* Opcode + Pause duration */ +#define FEC_HASH_TABLE_HIGH 0x118 /* High 32bits hash table */ +#define FEC_HASH_TABLE_LOW 0x11c /* Low 32bits hash table */ +#define FEC_GRP_HASH_TABLE_HIGH 0x120 /* High 32bits hash table */ +#define FEC_GRP_HASH_TABLE_LOW 0x124 /* Low 32bits hash table */ +#define FEC_X_WMRK 0x144 /* FIFO transmit water mark */ +#define FEC_R_BOUND 0x14c /* FIFO receive bound reg */ +#define FEC_R_FSTART 0x150 /* FIFO receive start reg */ +#define FEC_R_DES_START 0x180 /* Receive descriptor ring */ +#define FEC_X_DES_START 0x184 /* Transmit descriptor ring */ +#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */ #else -/* - * Define device register set address map. - */ -typedef struct fec { - unsigned long fec_ecntrl; /* Ethernet control reg */ - unsigned long fec_ievent; /* Interrupt even reg */ - unsigned long fec_imask; /* Interrupt mask reg */ - unsigned long fec_ivec; /* Interrupt vec status reg */ - unsigned long fec_r_des_active; /* Receive descriptor reg */ - unsigned long fec_x_des_active; /* Transmit descriptor reg */ - unsigned long fec_reserved1[10]; - unsigned long fec_mii_data; /* MII manage frame reg */ - unsigned long fec_mii_speed; /* MII speed control reg */ - unsigned long fec_reserved2[17]; - unsigned long fec_r_bound; /* FIFO receive bound reg */ - unsigned long fec_r_fstart; /* FIFO receive start reg */ - unsigned long fec_reserved3[4]; - unsigned long fec_x_wmrk; /* FIFO transmit water mark */ - unsigned long fec_reserved4; - unsigned long fec_x_fstart; /* FIFO transmit start reg */ - unsigned long fec_reserved5[21]; - unsigned long fec_r_cntrl; /* Receive control reg */ - unsigned long fec_max_frm_len; /* Maximum frame length reg */ - unsigned long fec_reserved6[14]; - unsigned long fec_x_cntrl; /* Transmit Control reg */ - unsigned long fec_reserved7[158]; - unsigned long fec_addr_low; /* Low 32bits MAC address */ - unsigned long fec_addr_high; /* High 16bits MAC address */ - unsigned long fec_grp_hash_table_high;/* High 32bits hash table */ - unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */ - unsigned long fec_r_des_start; /* Receive descriptor ring */ - unsigned long fec_x_des_start; /* Transmit descriptor ring */ - unsigned long fec_r_buff_size; /* Maximum receive buff size */ - unsigned long reserved8[9]; - unsigned long fec_fifo_ram[112]; /* FIFO RAM buffer */ -} fec_t; +#define FEC_ECNTRL; 0x000 /* Ethernet control reg */ +#define FEC_IEVENT; 0x004 /* Interrupt even reg */ +#define FEC_IMASK; 0x008 /* Interrupt mask reg */ +#define FEC_IVEC; 0x00c /* Interrupt vec status reg */ +#define FEC_R_DES_ACTIVE; 0x010 /* Receive descriptor reg */ +#define FEC_X_DES_ACTIVE; 0x01c /* Transmit descriptor reg */ +#define FEC_MII_DATA 0x040 /* MII manage frame reg */ +#define FEC_MII_SPEED 0x044 /* MII speed control reg */ +#define FEC_R_BOUND 0x08c /* FIFO receive bound reg */ +#define FEC_R_FSTART 0x090 /* FIFO receive start reg */ +#define FEC_X_WMRK 0x0a4 /* FIFO transmit water mark */ +#define FEC_X_FSTART 0x0ac /* FIFO transmit start reg */ +#define FEC_R_CNTRL 0x104 /* Receive control reg */ +#define FEC_MAX_FRM_LEN 0x108 /* Maximum frame length reg */ +#define FEC_X_CNTRL 0x144 /* Transmit Control reg */ +#define FEC_ADDR_LOW 0x3c0 /* Low 32bits MAC address */ +#define FEC_ADDR_HIGH 0x3c4 /* High 16bits MAC address */ +#define FEC_GRP_HASH_TABLE_HIGH 0x3c8 /* High 32bits hash table */ +#define FEC_GRP_HASH_TABLE_LOW 0x3cc /* Low 32bits hash table */ +#define FEC_R_DES_START 0x3d0 /* Receive descriptor ring */ +#define FEC_X_DES_START 0x3d4 /* Transmit descriptor ring */ +#define FEC_R_BUFF_SIZE 0x3d8 /* Maximum receive buff size */ +#define FEC_FIFO_RAM 0x400 /* FIFO RAM buffer */ #endif /* CONFIG_M5272 */ -- GitLab From 2e28532f7e63c3011f7b3c1516cfebd5321bdd15 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:16 +0000 Subject: [PATCH 0337/6080] fec: do not typedef struct types Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 37 ++++++++++++++++++++----------------- drivers/net/fec.h | 8 ++++---- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 37b333265629..f8396fb30326 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -180,10 +180,14 @@ struct fec_enet_private { /* CPM dual port RAM relative addresses. */ dma_addr_t bd_dma; - cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ - cbd_t *tx_bd_base; - cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ - cbd_t *dirty_tx; /* The ring entries to be free()ed. */ + /* Address of Rx and Tx buffers. */ + struct bufdesc *rx_bd_base; + struct bufdesc *tx_bd_base; + /* The next free ring entry */ + struct bufdesc *cur_rx, *cur_tx; + /* The ring entries to be free()ed. */ + struct bufdesc *dirty_tx; + uint tx_full; /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ spinlock_t hw_lock; @@ -289,7 +293,7 @@ static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile cbd_t *bdp; + struct bufdesc *bdp; unsigned short status; unsigned long flags; @@ -374,7 +378,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); } - fep->cur_tx = (cbd_t *)bdp; + fep->cur_tx = bdp; spin_unlock_irqrestore(&fep->hw_lock, flags); @@ -391,7 +395,7 @@ fec_timeout(struct net_device *dev) #ifndef final_version { int i; - cbd_t *bdp; + struct bufdesc *bdp; printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n", (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "", @@ -471,7 +475,7 @@ static void fec_enet_tx(struct net_device *dev) { struct fec_enet_private *fep; - volatile cbd_t *bdp; + struct bufdesc *bdp; unsigned short status; struct sk_buff *skb; @@ -534,7 +538,7 @@ fec_enet_tx(struct net_device *dev) netif_wake_queue(dev); } } - fep->dirty_tx = (cbd_t *)bdp; + fep->dirty_tx = bdp; spin_unlock_irq(&fep->hw_lock); } @@ -548,7 +552,7 @@ static void fec_enet_rx(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - volatile cbd_t *bdp; + struct bufdesc *bdp; unsigned short status; struct sk_buff *skb; ushort pkt_len; @@ -656,7 +660,7 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { writel(0, fep->hwp + FEC_R_DES_ACTIVE); #endif } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ - fep->cur_rx = (cbd_t *)bdp; + fep->cur_rx = bdp; #if 0 /* Doing this here will allow us to process all frames in the @@ -1653,8 +1657,7 @@ int __init fec_enet_init(struct net_device *dev, int index) { struct fec_enet_private *fep = netdev_priv(dev); unsigned long mem_addr; - volatile cbd_t *bdp; - cbd_t *cbd_base; + struct bufdesc *bdp, *cbd_base; int i, j; /* Allocate memory for buffer descriptors. @@ -1695,7 +1698,7 @@ int __init fec_enet_init(struct net_device *dev, int index) } #endif - cbd_base = (cbd_t *)mem_addr; + cbd_base = (struct bufdesc *)mem_addr; /* Set receive and transmit descriptor base. */ @@ -1760,7 +1763,7 @@ int __init fec_enet_init(struct net_device *dev, int index) /* Set receive and transmit descriptor base. */ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); - writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE, + writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); #ifdef HAVE_mii_link_interrupt @@ -1824,7 +1827,7 @@ static void fec_restart(struct net_device *dev, int duplex) { struct fec_enet_private *fep = netdev_priv(dev); - volatile cbd_t *bdp; + struct bufdesc *bdp; int i; /* Whack a reset. We should wait for this. */ @@ -1846,7 +1849,7 @@ fec_restart(struct net_device *dev, int duplex) /* Set receive and transmit descriptor base. */ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); - writel((unsigned long)fep->bd_dma + sizeof(cbd_t) * RX_RING_SIZE, + writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; diff --git a/drivers/net/fec.h b/drivers/net/fec.h index 5474ba39d46c..30b7dd671336 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h @@ -77,17 +77,17 @@ * Define the buffer descriptor structure. */ #ifdef CONFIG_ARCH_MXC -typedef struct bufdesc { +struct bufdesc { unsigned short cbd_datlen; /* Data length */ unsigned short cbd_sc; /* Control and status info */ unsigned long cbd_bufaddr; /* Buffer address */ -} cbd_t; +}; #else -typedef struct bufdesc { +struct bufdesc { unsigned short cbd_sc; /* Control and status info */ unsigned short cbd_datlen; /* Data length */ unsigned long cbd_bufaddr; /* Buffer address */ -} cbd_t; +}; #endif /* -- GitLab From 8d4dd5cff892e18a34422852c05a88b79ff978ed Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:17 +0000 Subject: [PATCH 0338/6080] fec: remove unnecessary cast Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index f8396fb30326..e03b1773966d 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1660,11 +1660,10 @@ int __init fec_enet_init(struct net_device *dev, int index) struct bufdesc *bdp, *cbd_base; int i, j; - /* Allocate memory for buffer descriptors. - */ - mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE, - &fep->bd_dma, GFP_KERNEL); - if (mem_addr == 0) { + /* Allocate memory for buffer descriptors. */ + cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, + GFP_KERNEL); + if (!cbd_base) { printk("FEC: allocate descriptor memory failed?\n"); return -ENOMEM; } @@ -1698,10 +1697,7 @@ int __init fec_enet_init(struct net_device *dev, int index) } #endif - cbd_base = (struct bufdesc *)mem_addr; - - /* Set receive and transmit descriptor base. - */ + /* Set receive and transmit descriptor base. */ fep->rx_bd_base = cbd_base; fep->tx_bd_base = cbd_base + RX_RING_SIZE; -- GitLab From 22f6b860da25abe2c3e33347ccb806e6bcc57390 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:18 +0000 Subject: [PATCH 0339/6080] fec: Codingstyle cleanups Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 354 ++++++++++++++++++---------------------------- 1 file changed, 139 insertions(+), 215 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index e03b1773966d..672566b89ecf 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -86,8 +86,7 @@ static unsigned char fec_mac_default[] = { #endif #endif /* CONFIG_M5272 */ -/* Forward declarations of some structures to support different PHYs -*/ +/* Forward declarations of some structures to support different PHYs */ typedef struct { uint mii_data; @@ -123,8 +122,7 @@ typedef struct { #error "FEC: descriptor ring size constants too large" #endif -/* Interrupt events/masks. -*/ +/* Interrupt events/masks. */ #define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */ #define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */ #define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */ @@ -177,15 +175,14 @@ struct fec_enet_private { ushort skb_cur; ushort skb_dirty; - /* CPM dual port RAM relative addresses. - */ + /* CPM dual port RAM relative addresses */ dma_addr_t bd_dma; - /* Address of Rx and Tx buffers. */ + /* Address of Rx and Tx buffers */ struct bufdesc *rx_bd_base; struct bufdesc *tx_bd_base; /* The next free ring entry */ struct bufdesc *cur_rx, *cur_tx; - /* The ring entries to be free()ed. */ + /* The ring entries to be free()ed */ struct bufdesc *dirty_tx; uint tx_full; @@ -245,19 +242,16 @@ static mii_list_t *mii_tail; static int mii_queue(struct net_device *dev, int request, void (*func)(uint, struct net_device *)); -/* Make MII read/write commands for the FEC. -*/ +/* Make MII read/write commands for the FEC */ #define mk_mii_read(REG) (0x60020000 | ((REG & 0x1f) << 18)) #define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \ (VAL & 0xffff)) #define mk_mii_end 0 -/* Transmitter timeout. -*/ -#define TX_TIMEOUT (2*HZ) +/* Transmitter timeout */ +#define TX_TIMEOUT (2 * HZ) -/* Register definitions for the PHY. -*/ +/* Register definitions for the PHY */ #define MII_REG_CR 0 /* Control Register */ #define MII_REG_SR 1 /* Status Register */ @@ -307,7 +301,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) bdp = fep->cur_tx; status = bdp->cbd_sc; -#ifndef final_version + if (status & BD_ENET_TX_READY) { /* Ooops. All transmit buffers are full. Bail out. * This should not happen, since dev->tbusy should be set. @@ -316,21 +310,18 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&fep->hw_lock, flags); return 1; } -#endif - /* Clear all of the status flags. - */ + /* Clear all of the status flags */ status &= ~BD_ENET_TX_STATS; - /* Set buffer length and buffer pointer. - */ + /* Set buffer length and buffer pointer */ bdp->cbd_bufaddr = __pa(skb->data); bdp->cbd_datlen = skb->len; /* - * On some FEC implementations data must be aligned on - * 4-byte boundaries. Use bounce buffers to copy data - * and get it aligned. Ugh. + * On some FEC implementations data must be aligned on + * 4-byte boundaries. Use bounce buffers to copy data + * and get it aligned. Ugh. */ if (bdp->cbd_bufaddr & FEC_ALIGNMENT) { unsigned int index; @@ -339,8 +330,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]); } - /* Save skb pointer. - */ + /* Save skb pointer */ fep->tx_skbuff[fep->skb_cur] = skb; dev->stats.tx_bytes += skb->len; @@ -355,7 +345,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Send it on its way. Tell FEC it's ready, interrupt when done, * it's the last BD of the frame, and to put the CRC on the end. */ - status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); bdp->cbd_sc = status; @@ -365,13 +354,11 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Trigger transmission start */ writel(0, fep->hwp + FEC_X_DES_ACTIVE); - /* If this was the last BD in the ring, start at the beginning again. - */ - if (status & BD_ENET_TX_WRAP) { + /* If this was the last BD in the ring, start at the beginning again. */ + if (status & BD_ENET_TX_WRAP) bdp = fep->tx_bd_base; - } else { + else bdp++; - } if (bdp == fep->dirty_tx) { fep->tx_full = 1; @@ -429,9 +416,6 @@ fec_timeout(struct net_device *dev) netif_wake_queue(dev); } -/* The interrupt handler. - * This is called from the MPC core interrupt. - */ static irqreturn_t fec_enet_interrupt(int irq, void * dev_id) { @@ -440,12 +424,10 @@ fec_enet_interrupt(int irq, void * dev_id) uint int_events; irqreturn_t ret = IRQ_NONE; - /* Get the interrupt events that caused us to be here. */ do { int_events = readl(fep->hwp + FEC_IEVENT); writel(int_events, fep->hwp + FEC_IEVENT); - /* Handle receive event in its own function. */ if (int_events & FEC_ENET_RXF) { ret = IRQ_HANDLED; fec_enet_rx(dev); @@ -506,31 +488,27 @@ fec_enet_tx(struct net_device *dev) dev->stats.tx_packets++; } -#ifndef final_version if (status & BD_ENET_TX_READY) printk("HEY! Enet xmit interrupt and TX_READY.\n"); -#endif + /* Deferred means some collisions occurred during transmit, * but we eventually sent the packet OK. */ if (status & BD_ENET_TX_DEF) dev->stats.collisions++; - /* Free the sk buffer associated with this last transmit. - */ + /* Free the sk buffer associated with this last transmit */ dev_kfree_skb_any(skb); fep->tx_skbuff[fep->skb_dirty] = NULL; fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK; - /* Update pointer to next buffer descriptor to be transmitted. - */ + /* Update pointer to next buffer descriptor to be transmitted */ if (status & BD_ENET_TX_WRAP) bdp = fep->tx_bd_base; else bdp++; - /* Since we have freed up a buffer, the ring is no longer - * full. + /* Since we have freed up a buffer, the ring is no longer full */ if (fep->tx_full) { fep->tx_full = 0; @@ -569,114 +547,93 @@ fec_enet_rx(struct net_device *dev) */ bdp = fep->cur_rx; -while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { + while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { -#ifndef final_version - /* Since we have allocated space to hold a complete frame, - * the last indicator should be set. - */ - if ((status & BD_ENET_RX_LAST) == 0) - printk("FEC ENET: rcv is not +last\n"); -#endif + /* Since we have allocated space to hold a complete frame, + * the last indicator should be set. + */ + if ((status & BD_ENET_RX_LAST) == 0) + printk("FEC ENET: rcv is not +last\n"); - if (!fep->opened) - goto rx_processing_done; + if (!fep->opened) + goto rx_processing_done; - /* Check for errors. */ - if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | + /* Check for errors. */ + if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { - dev->stats.rx_errors++; - if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { - /* Frame too long or too short. */ - dev->stats.rx_length_errors++; + dev->stats.rx_errors++; + if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { + /* Frame too long or too short. */ + dev->stats.rx_length_errors++; + } + if (status & BD_ENET_RX_NO) /* Frame alignment */ + dev->stats.rx_frame_errors++; + if (status & BD_ENET_RX_CR) /* CRC Error */ + dev->stats.rx_crc_errors++; + if (status & BD_ENET_RX_OV) /* FIFO overrun */ + dev->stats.rx_fifo_errors++; } - if (status & BD_ENET_RX_NO) /* Frame alignment */ - dev->stats.rx_frame_errors++; - if (status & BD_ENET_RX_CR) /* CRC Error */ - dev->stats.rx_crc_errors++; - if (status & BD_ENET_RX_OV) /* FIFO overrun */ - dev->stats.rx_fifo_errors++; - } - /* Report late collisions as a frame error. - * On this error, the BD is closed, but we don't know what we - * have in the buffer. So, just drop this frame on the floor. - */ - if (status & BD_ENET_RX_CL) { - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; - goto rx_processing_done; - } + /* Report late collisions as a frame error. + * On this error, the BD is closed, but we don't know what we + * have in the buffer. So, just drop this frame on the floor. + */ + if (status & BD_ENET_RX_CL) { + dev->stats.rx_errors++; + dev->stats.rx_frame_errors++; + goto rx_processing_done; + } - /* Process the incoming frame. - */ - dev->stats.rx_packets++; - pkt_len = bdp->cbd_datlen; - dev->stats.rx_bytes += pkt_len; - data = (__u8*)__va(bdp->cbd_bufaddr); + /* Process the incoming frame. */ + dev->stats.rx_packets++; + pkt_len = bdp->cbd_datlen; + dev->stats.rx_bytes += pkt_len; + data = (__u8*)__va(bdp->cbd_bufaddr); - dma_sync_single(NULL, (unsigned long)__pa(data), + dma_sync_single(NULL, (unsigned long)__pa(data), pkt_len - 4, DMA_FROM_DEVICE); - /* This does 16 byte alignment, exactly what we need. - * The packet length includes FCS, but we don't want to - * include that when passing upstream as it messes up - * bridging applications. - */ - skb = dev_alloc_skb(pkt_len-4); - - if (skb == NULL) { - printk("%s: Memory squeeze, dropping packet.\n", dev->name); - dev->stats.rx_dropped++; - } else { - skb_put(skb,pkt_len-4); /* Make room */ - skb_copy_to_linear_data(skb, data, pkt_len-4); - skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); - } - rx_processing_done: - - /* Clear the status flags for this buffer. - */ - status &= ~BD_ENET_RX_STATS; + /* This does 16 byte alignment, exactly what we need. + * The packet length includes FCS, but we don't want to + * include that when passing upstream as it messes up + * bridging applications. + */ + skb = dev_alloc_skb(pkt_len - 4); - /* Mark the buffer empty. - */ - status |= BD_ENET_RX_EMPTY; - bdp->cbd_sc = status; + if (skb == NULL) { + printk("%s: Memory squeeze, dropping packet.\n", + dev->name); + dev->stats.rx_dropped++; + } else { + skb_put(skb, pkt_len - 4); /* Make room */ + skb_copy_to_linear_data(skb, data, pkt_len - 4); + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + } +rx_processing_done: + /* Clear the status flags for this buffer */ + status &= ~BD_ENET_RX_STATS; - /* Update BD pointer to next entry. - */ - if (status & BD_ENET_RX_WRAP) - bdp = fep->rx_bd_base; - else - bdp++; + /* Mark the buffer empty */ + status |= BD_ENET_RX_EMPTY; + bdp->cbd_sc = status; -#if 1 - /* Doing this here will keep the FEC running while we process - * incoming frames. On a heavily loaded network, we should be - * able to keep up at the expense of system resources. - */ - writel(0, fep->hwp + FEC_R_DES_ACTIVE); -#endif - } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ + /* Update BD pointer to next entry */ + if (status & BD_ENET_RX_WRAP) + bdp = fep->rx_bd_base; + else + bdp++; + /* Doing this here will keep the FEC running while we process + * incoming frames. On a heavily loaded network, we should be + * able to keep up at the expense of system resources. + */ + writel(0, fep->hwp + FEC_R_DES_ACTIVE); + } fep->cur_rx = bdp; -#if 0 - /* Doing this here will allow us to process all frames in the - * ring before the FEC is allowed to put more there. On a heavily - * loaded network, some frames may be lost. Unfortunately, this - * increases the interrupt overhead since we can potentially work - * our way back to the interrupt return only to come right back - * here. - */ - fecp->fec_r_des_active = 0; -#endif - spin_unlock_irq(&fep->hw_lock); } - /* called from interrupt context */ static void fec_enet_mii(struct net_device *dev) @@ -714,8 +671,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi mii_list_t *mip; int retval; - /* Add PHY address to register command. - */ + /* Add PHY address to register command */ fep = netdev_priv(dev); spin_lock_irqsave(&fep->mii_lock, flags); @@ -1358,11 +1314,6 @@ static void mii_relink(struct work_struct *work) fec_restart(dev, duplex); } else fec_stop(dev); - -#if 0 - enable_irq(fep->mii_irq); -#endif - } /* mii_queue_relink is called in interrupt context from mii_link_interrupt */ @@ -1371,12 +1322,12 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev) struct fec_enet_private *fep = netdev_priv(dev); /* - ** We cannot queue phy_task twice in the workqueue. It - ** would cause an endless loop in the workqueue. - ** Fortunately, if the last mii_relink entry has not yet been - ** executed now, it will do the job for the current interrupt, - ** which is just what we want. - */ + * We cannot queue phy_task twice in the workqueue. It + * would cause an endless loop in the workqueue. + * Fortunately, if the last mii_relink entry has not yet been + * executed now, it will do the job for the current interrupt, + * which is just what we want. + */ if (fep->mii_phy_task_queued) return; @@ -1407,8 +1358,7 @@ phy_cmd_t const phy_cmd_config[] = { { mk_mii_end, } }; -/* Read remainder of PHY ID. -*/ +/* Read remainder of PHY ID. */ static void mii_discover_phy3(uint mii_reg, struct net_device *dev) { @@ -1447,8 +1397,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) if (fep->phy_addr < 32) { if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) { - /* Got first part of ID, now get remainder. - */ + /* Got first part of ID, now get remainder */ fep->phy_id = phytype << 16; mii_queue(dev, mk_mii_read(MII_REG_PHYIR2), mii_discover_phy3); @@ -1468,8 +1417,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) } } -/* This interrupt occurs when the PHY detects a link change. -*/ +/* This interrupt occurs when the PHY detects a link change */ #ifdef HAVE_mii_link_interrupt static irqreturn_t mii_link_interrupt(int irq, void * dev_id) @@ -1479,10 +1427,6 @@ mii_link_interrupt(int irq, void * dev_id) fec_phy_ack_intr(); -#if 0 - disable_irq(fep->mii_irq); /* disable now, enable later */ -#endif - mii_do_cmd(dev, fep->phy->ack_int); mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ @@ -1533,7 +1477,7 @@ fec_enet_open(struct net_device *dev) netif_start_queue(dev); fep->opened = 1; - return 0; /* Success */ + return 0; } static int @@ -1541,8 +1485,7 @@ fec_enet_close(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - /* Don't know what to do yet. - */ + /* Don't know what to do yet. */ fep->opened = 0; netif_stop_queue(dev); fec_stop(dev); @@ -1570,7 +1513,7 @@ static void set_multicast_list(struct net_device *dev) unsigned int i, j, bit, data, crc, tmp; unsigned char hash; - if (dev->flags&IFF_PROMISC) { + if (dev->flags & IFF_PROMISC) { tmp = readl(fep->hwp + FEC_R_CNTRL); tmp |= 0x8; writel(tmp, fep->hwp + FEC_R_CNTRL); @@ -1581,42 +1524,37 @@ static void set_multicast_list(struct net_device *dev) if (dev->flags & IFF_ALLMULTI) { /* Catch all multicast addresses, so set the - * filter to all 1's. + * filter to all 1's */ writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW); } else { - /* Clear filter and add the addresses in hash register. - */ + /* Clear filter and add the addresses in hash register + */ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); dmi = dev->mc_list; - for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) - { - /* Only support group multicast for now. - */ + for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) { + /* Only support group multicast for now */ if (!(dmi->dmi_addr[0] & 1)) continue; - /* calculate crc32 value of mac address - */ + /* calculate crc32 value of mac address */ crc = 0xffffffff; - for (i = 0; i < dmi->dmi_addrlen; i++) - { + for (i = 0; i < dmi->dmi_addrlen; i++) { data = dmi->dmi_addr[i]; - for (bit = 0; bit < 8; bit++, data >>= 1) - { + for (bit = 0; bit < 8; bit++, data >>= 1) { crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32_POLY : 0); } } /* only upper 6 bits (HASH_BITS) are used - which point to specific bit in he hash registers - */ + * which point to specific bit in he hash registers + */ hash = (crc >> (32 - HASH_BITS)) & 0x3f; if (hash > 31) { @@ -1633,8 +1571,7 @@ static void set_multicast_list(struct net_device *dev) } } -/* Set a MAC change in hardware. - */ +/* Set a MAC change in hardware. */ static void fec_set_mac_address(struct net_device *dev) { @@ -1675,8 +1612,7 @@ int __init fec_enet_init(struct net_device *dev, int index) fep->hwp = (void __iomem *)dev->base_addr; fep->netdev = dev; - /* Whack a reset. We should wait for this. - */ + /* Whack a reset. We should wait for this. */ writel(1, fep->hwp + FEC_ECNTRL); udelay(10); @@ -1706,18 +1642,15 @@ int __init fec_enet_init(struct net_device *dev, int index) fep->skb_cur = fep->skb_dirty = 0; - /* Initialize the receive buffer descriptors. - */ + /* Initialize the receive buffer descriptors. */ bdp = fep->rx_bd_base; for (i=0; icbd_sc = BD_ENET_RX_EMPTY; bdp->cbd_bufaddr = __pa(mem_addr); @@ -1726,13 +1659,11 @@ int __init fec_enet_init(struct net_device *dev, int index) } } - /* Set the last buffer to wrap. - */ + /* Set the last buffer to wrap */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* ...and the same for transmmit. - */ + /* ...and the same for transmit */ bdp = fep->tx_bd_base; for (i=0, j=FEC_ENET_TX_FRPPG; i= FEC_ENET_TX_FRPPG) { @@ -1744,20 +1675,17 @@ int __init fec_enet_init(struct net_device *dev, int index) } fep->tx_bounce[i] = (unsigned char *) mem_addr; - /* Initialize the BD for every fragment in the page. - */ + /* Initialize the BD for every fragment in the page */ bdp->cbd_sc = 0; bdp->cbd_bufaddr = 0; bdp++; } - /* Set the last buffer to wrap. - */ + /* Set the last buffer to wrap */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* Set receive and transmit descriptor base. - */ + /* Set receive and transmit descriptor base */ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); @@ -1776,7 +1704,7 @@ int __init fec_enet_init(struct net_device *dev, int index) writel(0, fep->hwp + FEC_HASH_TABLE_LOW); #endif - /* The FEC Ethernet specific entries in the device structure. */ + /* The FEC Ethernet specific entries in the device structure */ dev->open = fec_enet_open; dev->hard_start_xmit = fec_enet_start_xmit; dev->tx_timeout = fec_timeout; @@ -1792,9 +1720,7 @@ int __init fec_enet_init(struct net_device *dev, int index) writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL); writel(0, fep->hwp + FEC_X_CNTRL); - /* - * Set MII speed to 2.5 MHz - */ + /* Set MII speed to 2.5 MHz */ fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999) / 2500000) / 2) & 0x3F) << 1; writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); @@ -1853,8 +1779,8 @@ fec_restart(struct net_device *dev, int duplex) /* Reset SKB transmit buffers. */ fep->skb_cur = fep->skb_dirty = 0; - for (i=0; i<=TX_RING_MOD_MASK; i++) { - if (fep->tx_skbuff[i] != NULL) { + for (i = 0; i <= TX_RING_MOD_MASK; i++) { + if (fep->tx_skbuff[i]) { dev_kfree_skb_any(fep->tx_skbuff[i]); fep->tx_skbuff[i] = NULL; } @@ -1862,20 +1788,20 @@ fec_restart(struct net_device *dev, int duplex) /* Initialize the receive buffer descriptors. */ bdp = fep->rx_bd_base; - for (i=0; icbd_sc = BD_ENET_RX_EMPTY; bdp++; } - /* Set the last buffer to wrap. */ + /* Set the last buffer to wrap */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* ...and the same for transmmit. */ + /* ...and the same for transmit */ bdp = fep->tx_bd_base; - for (i=0; icbd_sc = 0; @@ -1883,11 +1809,11 @@ fec_restart(struct net_device *dev, int duplex) bdp++; } - /* Set the last buffer to wrap. */ + /* Set the last buffer to wrap */ bdp--; bdp->cbd_sc |= BD_SC_WRAP; - /* Enable MII mode. */ + /* Enable MII mode */ if (duplex) { /* MII enable / FD enable */ writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL); @@ -1899,14 +1825,14 @@ fec_restart(struct net_device *dev, int duplex) } fep->full_duplex = duplex; - /* Set MII speed. */ + /* Set MII speed */ writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); - /* And last, enable the transmit and receive processing. */ + /* And last, enable the transmit and receive processing */ writel(2, fep->hwp + FEC_ECNTRL); writel(0, fep->hwp + FEC_R_DES_ACTIVE); - /* Enable interrupts we wish to service. */ + /* Enable interrupts we wish to service */ writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII, fep->hwp + FEC_IMASK); } @@ -1916,9 +1842,7 @@ fec_stop(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - /* - ** We cannot expect a graceful transmit stop without link !!! - */ + /* We cannot expect a graceful transmit stop without link !!! */ if (fep->link) { writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */ udelay(10); -- GitLab From 4e8318368af44488f6438a31537ddb57de0d4e00 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:19 +0000 Subject: [PATCH 0340/6080] fec: refactor set_multicast_list() to make it more readable Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 99 ++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 672566b89ecf..6ac1b90c5820 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1517,57 +1517,60 @@ static void set_multicast_list(struct net_device *dev) tmp = readl(fep->hwp + FEC_R_CNTRL); tmp |= 0x8; writel(tmp, fep->hwp + FEC_R_CNTRL); - } else { - tmp = readl(fep->hwp + FEC_R_CNTRL); - tmp &= ~0x8; - writel(tmp, fep->hwp + FEC_R_CNTRL); + return; + } - if (dev->flags & IFF_ALLMULTI) { - /* Catch all multicast addresses, so set the - * filter to all 1's - */ - writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); - writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW); - } else { - /* Clear filter and add the addresses in hash register - */ - writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); - writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); - - dmi = dev->mc_list; - - for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) { - /* Only support group multicast for now */ - if (!(dmi->dmi_addr[0] & 1)) - continue; - - /* calculate crc32 value of mac address */ - crc = 0xffffffff; - - for (i = 0; i < dmi->dmi_addrlen; i++) { - data = dmi->dmi_addr[i]; - for (bit = 0; bit < 8; bit++, data >>= 1) { - crc = (crc >> 1) ^ - (((crc ^ data) & 1) ? CRC32_POLY : 0); - } - } - - /* only upper 6 bits (HASH_BITS) are used - * which point to specific bit in he hash registers - */ - hash = (crc >> (32 - HASH_BITS)) & 0x3f; - - if (hash > 31) { - tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH); - tmp |= 1 << (hash - 32); - writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); - } else { - tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW); - tmp |= 1 << hash; - writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW); - } + tmp = readl(fep->hwp + FEC_R_CNTRL); + tmp &= ~0x8; + writel(tmp, fep->hwp + FEC_R_CNTRL); + + if (dev->flags & IFF_ALLMULTI) { + /* Catch all multicast addresses, so set the + * filter to all 1's + */ + writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW); + + return; + } + + /* Clear filter and add the addresses in hash register + */ + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); + + dmi = dev->mc_list; + + for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) { + /* Only support group multicast for now */ + if (!(dmi->dmi_addr[0] & 1)) + continue; + + /* calculate crc32 value of mac address */ + crc = 0xffffffff; + + for (i = 0; i < dmi->dmi_addrlen; i++) { + data = dmi->dmi_addr[i]; + for (bit = 0; bit < 8; bit++, data >>= 1) { + crc = (crc >> 1) ^ + (((crc ^ data) & 1) ? CRC32_POLY : 0); } } + + /* only upper 6 bits (HASH_BITS) are used + * which point to specific bit in he hash registers + */ + hash = (crc >> (32 - HASH_BITS)) & 0x3f; + + if (hash > 31) { + tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + tmp |= 1 << (hash - 32); + writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); + } else { + tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW); + tmp |= 1 << hash; + writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW); + } } } -- GitLab From 4f1ceb4b46d523382f5a46622af9d3315a9b3e7f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:20 +0000 Subject: [PATCH 0341/6080] fec: refactor init function fec_enet_init() does the hardware initialisation and then calls fec_restart() which does the same initialisation again, so we can safely remove the initialisation from fec_enet_init(). Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 6ac1b90c5820..5ca2d6bcc23a 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1615,10 +1615,6 @@ int __init fec_enet_init(struct net_device *dev, int index) fep->hwp = (void __iomem *)dev->base_addr; fep->netdev = dev; - /* Whack a reset. We should wait for this. */ - writel(1, fep->hwp + FEC_ECNTRL); - udelay(10); - /* Set the Ethernet address */ #ifdef CONFIG_M5272 fec_get_mac(dev); @@ -1640,11 +1636,6 @@ int __init fec_enet_init(struct net_device *dev, int index) fep->rx_bd_base = cbd_base; fep->tx_bd_base = cbd_base + RX_RING_SIZE; - fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; - fep->cur_rx = fep->rx_bd_base; - - fep->skb_cur = fep->skb_dirty = 0; - /* Initialize the receive buffer descriptors. */ bdp = fep->rx_bd_base; for (i=0; icbd_sc |= BD_SC_WRAP; - /* Set receive and transmit descriptor base */ - writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); - writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, - fep->hwp + FEC_X_DES_START); - #ifdef HAVE_mii_link_interrupt fec_request_mii_intr(dev); #endif - - writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); - writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); - writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); - writel(2, fep->hwp + FEC_ECNTRL); - writel(0, fep->hwp + FEC_R_DES_ACTIVE); -#ifndef CONFIG_M5272 - writel(0, fep->hwp + FEC_HASH_TABLE_HIGH); - writel(0, fep->hwp + FEC_HASH_TABLE_LOW); -#endif - /* The FEC Ethernet specific entries in the device structure */ dev->open = fec_enet_open; dev->hard_start_xmit = fec_enet_start_xmit; @@ -1719,21 +1694,11 @@ int __init fec_enet_init(struct net_device *dev, int index) mii_cmds[i].mii_next = &mii_cmds[i+1]; mii_free = mii_cmds; - /* setup MII interface */ - writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL); - writel(0, fep->hwp + FEC_X_CNTRL); - /* Set MII speed to 2.5 MHz */ fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999) / 2500000) / 2) & 0x3F) << 1; - writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); fec_restart(dev, 0); - /* Clear and enable interrupts */ - writel(0xffc00000, fep->hwp + FEC_IEVENT); - writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII, - fep->hwp + FEC_IMASK); - /* Queue up command to detect the PHY and initialize the * remainder of the interface. */ @@ -1768,6 +1733,10 @@ fec_restart(struct net_device *dev, int duplex) /* Reset all multicast. */ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); +#ifndef CONFIG_M5272 + writel(0, fep->hwp + FEC_HASH_TABLE_HIGH); + writel(0, fep->hwp + FEC_HASH_TABLE_LOW); +#endif /* Set maximum receive buffer size. */ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); -- GitLab From 8549889c3369f7653bd98861c3d2cf97d810dc37 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:21 +0000 Subject: [PATCH 0342/6080] fec: align receive packets Otherwise we get a lot of alignment errors Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 5ca2d6bcc23a..ba3eb54b63f5 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -598,13 +598,14 @@ fec_enet_rx(struct net_device *dev) * include that when passing upstream as it messes up * bridging applications. */ - skb = dev_alloc_skb(pkt_len - 4); + skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN); - if (skb == NULL) { + if (unlikely(!skb)) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; } else { + skb_reserve(skb, NET_IP_ALIGN); skb_put(skb, pkt_len - 4); /* Make room */ skb_copy_to_linear_data(skb, data, pkt_len - 4); skb->protocol = eth_type_trans(skb, dev); -- GitLab From 3644ee00c43cca08c9baac7eaea22250aaf84182 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:22 +0000 Subject: [PATCH 0343/6080] fec: remove debugging printks These printks in fec_timeout do not give useful information in a production kernel. Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index ba3eb54b63f5..7b3e331dd442 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -377,41 +377,8 @@ fec_timeout(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); - printk("%s: transmit timed out.\n", dev->name); dev->stats.tx_errors++; -#ifndef final_version - { - int i; - struct bufdesc *bdp; - - printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n", - (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "", - (unsigned long)fep->dirty_tx, - (unsigned long)fep->cur_rx); - - bdp = fep->tx_bd_base; - printk(" tx: %u buffers\n", TX_RING_SIZE); - for (i = 0 ; i < TX_RING_SIZE; i++) { - printk(" %08x: %04x %04x %08x\n", - (uint) bdp, - bdp->cbd_sc, - bdp->cbd_datlen, - (int) bdp->cbd_bufaddr); - bdp++; - } - bdp = fep->rx_bd_base; - printk(" rx: %lu buffers\n", (unsigned long) RX_RING_SIZE); - for (i = 0 ; i < RX_RING_SIZE; i++) { - printk(" %08x: %04x %04x %08x\n", - (uint) bdp, - bdp->cbd_sc, - bdp->cbd_datlen, - (int) bdp->cbd_bufaddr); - bdp++; - } - } -#endif fec_restart(dev, fep->full_duplex); netif_wake_queue(dev); } -- GitLab From 009fda83ee2f38e5deb9d62fc54a904a92645fe4 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:23 +0000 Subject: [PATCH 0344/6080] fec: switch to net_device_ops Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 7b3e331dd442..54ee493768f1 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -210,17 +210,13 @@ struct fec_enet_private { int full_duplex; }; -static int fec_enet_open(struct net_device *dev); -static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev); static void fec_enet_mii(struct net_device *dev); static irqreturn_t fec_enet_interrupt(int irq, void * dev_id); static void fec_enet_tx(struct net_device *dev); static void fec_enet_rx(struct net_device *dev); static int fec_enet_close(struct net_device *dev); -static void set_multicast_list(struct net_device *dev); static void fec_restart(struct net_device *dev, int duplex); static void fec_stop(struct net_device *dev); -static void fec_set_mac_address(struct net_device *dev); /* MII processing. We keep this as simple as possible. Requests are @@ -1410,7 +1406,6 @@ fec_enet_open(struct net_device *dev) /* I should reset the ring buffers here, but I don't yet know * a simple way to do that. */ - fec_set_mac_address(dev); fep->sequence_done = 0; fep->link = 0; @@ -1543,19 +1538,35 @@ static void set_multicast_list(struct net_device *dev) } /* Set a MAC change in hardware. */ -static void -fec_set_mac_address(struct net_device *dev) +static int +fec_set_mac_address(struct net_device *dev, void *p) { struct fec_enet_private *fep = netdev_priv(dev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - /* Set station address. */ writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) | (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24), fep->hwp + FEC_ADDR_LOW); writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24), fep + FEC_ADDR_HIGH); + return 0; } +static const struct net_device_ops fec_netdev_ops = { + .ndo_open = fec_enet_open, + .ndo_stop = fec_enet_close, + .ndo_start_xmit = fec_enet_start_xmit, + .ndo_set_multicast_list = set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_tx_timeout = fec_timeout, + .ndo_set_mac_address = fec_set_mac_address, +}; + /* * XXX: We need to clean up on failure exits here. * @@ -1651,12 +1662,8 @@ int __init fec_enet_init(struct net_device *dev, int index) fec_request_mii_intr(dev); #endif /* The FEC Ethernet specific entries in the device structure */ - dev->open = fec_enet_open; - dev->hard_start_xmit = fec_enet_start_xmit; - dev->tx_timeout = fec_timeout; dev->watchdog_timeo = TX_TIMEOUT; - dev->stop = fec_enet_close; - dev->set_multicast_list = set_multicast_list; + dev->netdev_ops = &fec_netdev_ops; for (i=0; ihwp + FEC_IEVENT); - /* Set station address. */ - fec_set_mac_address(dev); - /* Reset all multicast. */ writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH); writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW); -- GitLab From f0b3fbeae11a526c3d308b691684589ee37c359b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:24 +0000 Subject: [PATCH 0345/6080] FEC Buffer rework Allocate buffers in fec_open and free them again in fec_close. This makes it possible to use this driver as a module. Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 139 +++++++++++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 51 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 54ee493768f1..54d6f86d9f6d 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -172,6 +172,7 @@ struct fec_enet_private { /* The saved address of a sent-in-place packet/buffer, for skfree(). */ unsigned char *tx_bounce[TX_RING_SIZE]; struct sk_buff* tx_skbuff[TX_RING_SIZE]; + struct sk_buff* rx_skbuff[RX_RING_SIZE]; ushort skb_cur; ushort skb_dirty; @@ -335,8 +336,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Push the data cache so the CPM does not get stale memory * data. */ - dma_sync_single(NULL, bdp->cbd_bufaddr, - bdp->cbd_datlen, DMA_TO_DEVICE); + bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data, + FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); /* Send it on its way. Tell FEC it's ready, interrupt when done, * it's the last BD of the frame, and to put the CRC on the end. @@ -429,7 +430,11 @@ fec_enet_tx(struct net_device *dev) bdp = fep->dirty_tx; while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { - if (bdp == fep->cur_tx && fep->tx_full == 0) break; + if (bdp == fep->cur_tx && fep->tx_full == 0) + break; + + dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); + bdp->cbd_bufaddr = 0; skb = fep->tx_skbuff[fep->skb_dirty]; /* Check for errors. */ @@ -553,8 +558,8 @@ fec_enet_rx(struct net_device *dev) dev->stats.rx_bytes += pkt_len; data = (__u8*)__va(bdp->cbd_bufaddr); - dma_sync_single(NULL, (unsigned long)__pa(data), - pkt_len - 4, DMA_FROM_DEVICE); + dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen, + DMA_FROM_DEVICE); /* This does 16 byte alignment, exactly what we need. * The packet length includes FCS, but we don't want to @@ -574,6 +579,9 @@ fec_enet_rx(struct net_device *dev) skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); } + + bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen, + DMA_FROM_DEVICE); rx_processing_done: /* Clear the status flags for this buffer */ status &= ~BD_ENET_RX_STATS; @@ -1398,15 +1406,86 @@ mii_link_interrupt(int irq, void * dev_id) } #endif +static void fec_enet_free_buffers(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + int i; + struct sk_buff *skb; + struct bufdesc *bdp; + + bdp = fep->rx_bd_base; + for (i = 0; i < RX_RING_SIZE; i++) { + skb = fep->rx_skbuff[i]; + + if (bdp->cbd_bufaddr) + dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, + FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); + if (skb) + dev_kfree_skb(skb); + bdp++; + } + + bdp = fep->tx_bd_base; + for (i = 0; i < TX_RING_SIZE; i++) + kfree(fep->tx_bounce[i]); +} + +static int fec_enet_alloc_buffers(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + int i; + struct sk_buff *skb; + struct bufdesc *bdp; + + bdp = fep->rx_bd_base; + for (i = 0; i < RX_RING_SIZE; i++) { + skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE); + if (!skb) { + fec_enet_free_buffers(dev); + return -ENOMEM; + } + fep->rx_skbuff[i] = skb; + + bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data, + FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); + bdp->cbd_sc = BD_ENET_RX_EMPTY; + bdp++; + } + + /* Set the last buffer to wrap. */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + bdp = fep->tx_bd_base; + for (i = 0; i < TX_RING_SIZE; i++) { + fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL); + + bdp->cbd_sc = 0; + bdp->cbd_bufaddr = 0; + bdp++; + } + + /* Set the last buffer to wrap. */ + bdp--; + bdp->cbd_sc |= BD_SC_WRAP; + + return 0; +} + static int fec_enet_open(struct net_device *dev) { struct fec_enet_private *fep = netdev_priv(dev); + int ret; /* I should reset the ring buffers here, but I don't yet know * a simple way to do that. */ + ret = fec_enet_alloc_buffers(dev); + if (ret) + return ret; + fep->sequence_done = 0; fep->link = 0; @@ -1453,6 +1532,8 @@ fec_enet_close(struct net_device *dev) netif_stop_queue(dev); fec_stop(dev); + fec_enet_free_buffers(dev); + return 0; } @@ -1575,9 +1656,8 @@ static const struct net_device_ops fec_netdev_ops = { int __init fec_enet_init(struct net_device *dev, int index) { struct fec_enet_private *fep = netdev_priv(dev); - unsigned long mem_addr; - struct bufdesc *bdp, *cbd_base; - int i, j; + struct bufdesc *cbd_base; + int i; /* Allocate memory for buffer descriptors. */ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, @@ -1615,49 +1695,6 @@ int __init fec_enet_init(struct net_device *dev, int index) fep->rx_bd_base = cbd_base; fep->tx_bd_base = cbd_base + RX_RING_SIZE; - /* Initialize the receive buffer descriptors. */ - bdp = fep->rx_bd_base; - for (i=0; icbd_sc = BD_ENET_RX_EMPTY; - bdp->cbd_bufaddr = __pa(mem_addr); - mem_addr += FEC_ENET_RX_FRSIZE; - bdp++; - } - } - - /* Set the last buffer to wrap */ - bdp--; - bdp->cbd_sc |= BD_SC_WRAP; - - /* ...and the same for transmit */ - bdp = fep->tx_bd_base; - for (i=0, j=FEC_ENET_TX_FRPPG; i= FEC_ENET_TX_FRPPG) { - mem_addr = __get_free_page(GFP_KERNEL); - j = 1; - } else { - mem_addr += FEC_ENET_TX_FRSIZE; - j++; - } - fep->tx_bounce[i] = (unsigned char *) mem_addr; - - /* Initialize the BD for every fragment in the page */ - bdp->cbd_sc = 0; - bdp->cbd_bufaddr = 0; - bdp++; - } - - /* Set the last buffer to wrap */ - bdp--; - bdp->cbd_sc |= BD_SC_WRAP; - #ifdef HAVE_mii_link_interrupt fec_request_mii_intr(dev); #endif -- GitLab From fe957c40ec5e2763b9977c565beab3bde3aaf85b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 15 Apr 2009 01:32:25 +0000 Subject: [PATCH 0346/6080] fec: call fec_restart() in fec_open() We called fec_stop() in fec_enet_close(), thus we have to call fec_restart() in fec_enet_open(). Signed-off-by: Sascha Hauer Signed-off-by: David S. Miller --- drivers/net/fec.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 54d6f86d9f6d..63eaf5de2300 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1489,6 +1489,8 @@ fec_enet_open(struct net_device *dev) fep->sequence_done = 0; fep->link = 0; + fec_restart(dev, 1); + if (fep->phy) { mii_do_cmd(dev, fep->phy->ack_int); mii_do_cmd(dev, fep->phy->config); @@ -1505,18 +1507,14 @@ fec_enet_open(struct net_device *dev) schedule(); mii_do_cmd(dev, fep->phy->startup); - - /* Set the initial link state to true. A lot of hardware - * based on this device does not implement a PHY interrupt, - * so we are never notified of link change. - */ - fep->link = 1; - } else { - fep->link = 1; /* lets just try it and see */ - /* no phy, go full duplex, it's most likely a hub chip */ - fec_restart(dev, 1); } + /* Set the initial link state to true. A lot of hardware + * based on this device does not implement a PHY interrupt, + * so we are never notified of link change. + */ + fep->link = 1; + netif_start_queue(dev); fep->opened = 1; return 0; -- GitLab From 3f1a4d826751d9759fc95da4e47d08d2745e0055 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 15 Apr 2009 21:35:26 +0100 Subject: [PATCH 0347/6080] ASoC: Check we have DAI ops when calling via accessor functions Also make sure we're checking for the right operation while we're here. Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index dd28009f8969..92503927b0c6 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2100,7 +2100,7 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, int dir) { - if (dai->ops->set_sysclk) + if (dai->ops && dai->ops->set_sysclk) return dai->ops->set_sysclk(dai, clk_id, freq, dir); else return -EINVAL; @@ -2120,7 +2120,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) { - if (dai->ops->set_clkdiv) + if (dai->ops && dai->ops->set_clkdiv) return dai->ops->set_clkdiv(dai, div_id, div); else return -EINVAL; @@ -2139,7 +2139,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv); int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, unsigned int freq_in, unsigned int freq_out) { - if (dai->ops->set_pll) + if (dai->ops && dai->ops->set_pll) return dai->ops->set_pll(dai, pll_id, freq_in, freq_out); else return -EINVAL; @@ -2155,7 +2155,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); */ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - if (dai->ops->set_fmt) + if (dai->ops && dai->ops->set_fmt) return dai->ops->set_fmt(dai, fmt); else return -EINVAL; @@ -2174,7 +2174,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int mask, int slots) { - if (dai->ops->set_sysclk) + if (dai->ops && dai->ops->set_tdm_slot) return dai->ops->set_tdm_slot(dai, mask, slots); else return -EINVAL; @@ -2190,7 +2190,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); */ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) { - if (dai->ops->set_sysclk) + if (dai->ops && dai->ops->set_tristate) return dai->ops->set_tristate(dai, tristate); else return -EINVAL; @@ -2206,7 +2206,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate); */ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) { - if (dai->ops->digital_mute) + if (dai->ops && dai->ops->digital_mute) return dai->ops->digital_mute(dai, mute); else return -EINVAL; -- GitLab From fd5dfad9cf51bc3575b5e50193403de4a3de23bc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 15 Apr 2009 21:37:46 +0100 Subject: [PATCH 0348/6080] ASoC: Volume controls are never of boolean type Some limited volume controls (mostly simple attenuations) have only two settings so the ASoC info functions misreport them as booleans. Since we currently have no better information check for " Volume" in the control name and always report any controls matching as being integer. Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 92503927b0c6..af11791a3b8c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1779,7 +1779,7 @@ int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol, { int max = kcontrol->private_value; - if (max == 1) + if (max == 1 && !strstr(kcontrol->id.name, " Volume")) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; else uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -1809,7 +1809,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; - if (max == 1) + if (max == 1 && !strstr(kcontrol->id.name, " Volume")) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; else uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -1916,7 +1916,7 @@ int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; int max = mc->max; - if (max == 1) + if (max == 1 && !strstr(kcontrol->id.name, " Volume")) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; else uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; -- GitLab From 0d960e8891459f5af85e5781bce3f1da5f7db0fb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 16 Apr 2009 10:08:39 +0100 Subject: [PATCH 0349/6080] ASoC: Request shared rates for WM8903 It has a shared LRCLK. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 8cf571f1a803..c5391841d41f 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1523,6 +1523,7 @@ struct snd_soc_dai wm8903_dai = { .formats = WM8903_FORMATS, }, .ops = &wm8903_dai_ops, + .symmetric_rates = 1, }; EXPORT_SYMBOL_GPL(wm8903_dai); -- GitLab From c29b206ffd0700acb2dc1fdb70856cc4b907216c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 15 Apr 2009 15:38:55 +0300 Subject: [PATCH 0350/6080] ASoC: OMAP: Use single-phase for DSP mode Use single-phase mode for the DSP mode and keep the dual phase mode for the I2S mode. The mono (1 channel) mode already used single phase mode, now it is more cleaner. There is no need to configure the second phase, when the single phase is used. Signed-off-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 9c09b94f0cf8..402a1eb7bd3f 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -214,8 +214,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; - int wlen, channels; + int wlen, channels, wpf; unsigned long port; + unsigned int format; if (cpu_class_is_omap1()) { dma = omap1_dma_reqs[bus_id][substream->stream]; @@ -243,18 +244,23 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, return 0; } - channels = params_channels(params); + format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; + wpf = channels = params_channels(params); switch (channels) { case 2: - /* Use dual-phase frames */ - regs->rcr2 |= RPHASE; - regs->xcr2 |= XPHASE; + if (format == SND_SOC_DAIFMT_I2S) { + /* Use dual-phase frames */ + regs->rcr2 |= RPHASE; + regs->xcr2 |= XPHASE; + /* Set 1 word per (McBSP) frame for phase1 and phase2 */ + wpf--; + regs->rcr2 |= RFRLEN2(wpf - 1); + regs->xcr2 |= XFRLEN2(wpf - 1); + } case 1: - /* Set 1 word per (McBSP) frame */ - regs->rcr2 |= RFRLEN2(1 - 1); - regs->rcr1 |= RFRLEN1(1 - 1); - regs->xcr2 |= XFRLEN2(1 - 1); - regs->xcr1 |= XFRLEN1(1 - 1); + /* Set word per (McBSP) frame for phase1 */ + regs->rcr1 |= RFRLEN1(wpf - 1); + regs->xcr1 |= XFRLEN1(wpf - 1); break; default: /* Unsupported number of channels */ @@ -276,9 +282,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, } /* Set FS period and length in terms of bit clock periods */ - switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + switch (format) { case SND_SOC_DAIFMT_I2S: - regs->srgr2 |= FPER(wlen * 2 - 1); + regs->srgr2 |= FPER(wlen * channels - 1); regs->srgr1 |= FWID(wlen - 1); break; case SND_SOC_DAIFMT_DSP_B: -- GitLab From 3ba191ce051a32b20757f063120496e860ea8f9d Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 15 Apr 2009 15:38:56 +0300 Subject: [PATCH 0351/6080] ASoC: OMAP: Add DSP_A mode support for mcbsp DSP_A mode is similar to the DSP_B, but the MSB is delayed with one bclk (appears after the FS pulse and not under it). Signed-off-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 402a1eb7bd3f..2b4a8da09918 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -287,6 +287,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, regs->srgr2 |= FPER(wlen * channels - 1); regs->srgr1 |= FWID(wlen - 1); break; + case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_B: regs->srgr2 |= FPER(wlen * channels - 1); regs->srgr1 |= FWID(wlen * channels - 2); @@ -330,6 +331,13 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, regs->rcr2 |= RDATDLY(1); regs->xcr2 |= XDATDLY(1); break; + case SND_SOC_DAIFMT_DSP_A: + /* 1-bit data delay */ + regs->rcr2 |= RDATDLY(1); + regs->xcr2 |= XDATDLY(1); + /* Invert FS polarity configuration */ + temp_fmt ^= SND_SOC_DAIFMT_NB_IF; + break; case SND_SOC_DAIFMT_DSP_B: /* 0-bit data delay */ regs->rcr2 |= RDATDLY(0); -- GitLab From 590818250684d18bb0e30c45d79971dcdff96ad0 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 16 Apr 2009 02:23:56 +0000 Subject: [PATCH 0352/6080] myri10ge: force stats update in ethtool gstats Force a statistics update when our ethtool gstats routine is called. Otherwise, ethtool will continue to read stale stats until something forces an update by reading /proc/net/dev This requires putting a lock around the stats update to guard against 2 threads (one via ethtool, and one via procfs) updating the stats at once. Signed-off-by: Brice Goglin Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index f2c4a665e93f..a833cdd85466 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -361,6 +361,8 @@ static inline void put_be32(__be32 val, __be32 __iomem * p) __raw_writel((__force __u32) val, (__force void __iomem *)p); } +static struct net_device_stats *myri10ge_get_stats(struct net_device *dev); + static int myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, struct myri10ge_cmd *data, int atomic) @@ -1803,6 +1805,8 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, int slice; int i; + /* force stats update */ + (void)myri10ge_get_stats(netdev); for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++) data[i] = ((unsigned long *)&mgp->stats)[i]; @@ -2969,6 +2973,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev) struct net_device_stats *stats = &mgp->stats; int i; + spin_lock(&mgp->stats_lock); memset(stats, 0, sizeof(*stats)); for (i = 0; i < mgp->num_slices; i++) { slice_stats = &mgp->ss[i].stats; @@ -2979,6 +2984,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev) stats->rx_dropped += slice_stats->rx_dropped; stats->tx_dropped += slice_stats->tx_dropped; } + spin_unlock(&mgp->stats_lock); return stats; } @@ -3902,6 +3908,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, (unsigned long)mgp); + spin_lock_init(&mgp->stats_lock); SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops); INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog); status = register_netdev(netdev); -- GitLab From 2d90b0aa3bc484189940444bcddcbe0ebbb53af5 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 16 Apr 2009 02:24:59 +0000 Subject: [PATCH 0353/6080] myri10ge: allow per-board firmware overriding Add myri10ge_fw_names to override the default firmware on a per-board basis. Signed-off-by: Brice Goglin Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index a833cdd85466..77de964fe676 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -255,6 +255,7 @@ struct myri10ge_priv { u32 read_write_dma; u32 link_changes; u32 msg_enable; + unsigned int board_number; }; static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat"; @@ -266,6 +267,13 @@ static char *myri10ge_fw_name = NULL; module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name"); +#define MYRI10GE_MAX_BOARDS 8 +static char *myri10ge_fw_names[MYRI10GE_MAX_BOARDS] = + {[0...(MYRI10GE_MAX_BOARDS - 1)] = NULL }; +module_param_array_named(myri10ge_fw_names, myri10ge_fw_names, charp, NULL, + 0444); +MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image names per board"); + static int myri10ge_ecrc_enable = 1; module_param(myri10ge_ecrc_enable, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E"); @@ -3259,6 +3267,8 @@ abort: static void myri10ge_select_firmware(struct myri10ge_priv *mgp) { + int overridden = 0; + if (myri10ge_force_firmware == 0) { int link_width, exp_cap; u16 lnk; @@ -3292,10 +3302,18 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) } } if (myri10ge_fw_name != NULL) { - dev_info(&mgp->pdev->dev, "overriding firmware to %s\n", - myri10ge_fw_name); + overridden = 1; mgp->fw_name = myri10ge_fw_name; } + if (mgp->board_number < MYRI10GE_MAX_BOARDS && + myri10ge_fw_names[mgp->board_number] != NULL && + strlen(myri10ge_fw_names[mgp->board_number])) { + mgp->fw_name = myri10ge_fw_names[mgp->board_number]; + overridden = 1; + } + if (overridden) + dev_info(&mgp->pdev->dev, "overriding firmware to %s\n", + mgp->fw_name); } #ifdef CONFIG_PM @@ -3760,6 +3778,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int status = -ENXIO; int dac_enabled; unsigned hdr_offset, ss_offset; + static int board_number; netdev = alloc_etherdev_mq(sizeof(*mgp), MYRI10GE_MAX_SLICES); if (netdev == NULL) { @@ -3776,6 +3795,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mgp->pause = myri10ge_flow_control; mgp->intr_coal_delay = myri10ge_intr_coal_delay; mgp->msg_enable = netif_msg_init(myri10ge_debug, MYRI10GE_MSG_DEFAULT); + mgp->board_number = board_number; init_waitqueue_head(&mgp->down_wq); if (pci_enable_device(pdev)) { @@ -3926,6 +3946,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->irq, mgp->tx_boundary, mgp->fw_name, (mgp->wc_enabled ? "Enabled" : "Disabled")); + board_number++; return 0; abort_with_state: -- GitLab From 97131079183cd671e18e661f1a387cdb5dffd313 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 16 Apr 2009 02:29:22 +0000 Subject: [PATCH 0354/6080] myri10ge: add MODULE_DEVICE_TABLE Add MODULE_DEVICE_TABLE so that modinfo reports pci device id aliases. Signed-off-by: Brice Goglin Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 77de964fe676..4a2ab4ebfb82 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -75,7 +75,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.4.4-1.401" +#define MYRI10GE_VERSION_STR "1.4.4-1.412" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -4036,6 +4036,8 @@ static struct pci_device_id myri10ge_pci_tbl[] = { {0}, }; +MODULE_DEVICE_TABLE(pci, myri10ge_pci_tbl); + static struct pci_driver myri10ge_driver = { .name = "myri10ge", .probe = myri10ge_probe, -- GitLab From 6498be3fba7b102132241be5763263e8e8bf6f9e Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 16 Apr 2009 17:56:57 -0700 Subject: [PATCH 0355/6080] myri10ge: fix tx ring size in ethtool -g Fix tx ring size reported via ethtool -g. Signed-off-by: Brice Goglin Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 4a2ab4ebfb82..291944d0aea3 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1696,7 +1696,7 @@ myri10ge_get_ringparam(struct net_device *netdev, ring->rx_mini_max_pending = mgp->ss[0].rx_small.mask + 1; ring->rx_max_pending = mgp->ss[0].rx_big.mask + 1; ring->rx_jumbo_max_pending = 0; - ring->tx_max_pending = mgp->ss[0].rx_small.mask + 1; + ring->tx_max_pending = mgp->ss[0].tx.mask + 1; ring->rx_mini_pending = ring->rx_mini_max_pending; ring->rx_pending = ring->rx_max_pending; ring->rx_jumbo_pending = ring->rx_jumbo_max_pending; -- GitLab From 84971bb401866d79c6b353cb1d8861c2b4621867 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 12:44:25 +0900 Subject: [PATCH 0356/6080] sh: pci: Kill off useless debugging printk() in pci-sh7780 init. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7780.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 282cabe15e36..b826c7bc62b9 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -118,18 +118,6 @@ int __init sh7780_pcic_init(struct pci_channel *chan, pci_write_reg(chan, map->window1.base, SH4_PCILAR1); pci_write_reg(chan, map->window1.base, SH7780_PCIMBAR1); - /* Map IO space into PCI IO window: - * IO addresses will be translated to the PCI IO window base address - */ - pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%lx\n", - chan->io_resource->start, chan->io_resource->end, - chan->io_base + chan->io_resource->start); - - /* NOTE: I'm ignoring the PCI error IRQs for now.. - * TODO: add support for the internal error interrupts and - * DMA interrupts... - */ - /* Apply any last-minute PCIC fixups */ pci_fixup_pcic(chan); -- GitLab From b627b4ed3d056c5d00e8f3cb32d033b0ee6619a9 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 13:00:18 +0900 Subject: [PATCH 0357/6080] sh: pci: Move se7780 INTC fixups out of pci-sh7780.c. These fixups belong in the board INTC setup code, not in the middle of pci-sh7780.c. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7780/irq.c | 10 ++++++++-- arch/sh/drivers/pci/pci-sh7780.c | 24 ------------------------ 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/arch/sh/boards/mach-se/7780/irq.c b/arch/sh/boards/mach-se/7780/irq.c index 66ad292c9fc3..44b61a597a15 100644 --- a/arch/sh/boards/mach-se/7780/irq.c +++ b/arch/sh/boards/mach-se/7780/irq.c @@ -12,10 +12,13 @@ #include #include #include -#include -#include +#include +#include #include +#define INTC_BASE 0xffd00000 +#define INTC_ICR1 (INTC_BASE+0x1c) + /* * Initialize IRQ setting */ @@ -43,4 +46,7 @@ void __init init_se7780_IRQ(void) ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-7 */ + + /* ICR1: detect low level(for 2ndcut) */ + ctrl_outl(0xAAAA0000, INTC_ICR1); } diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index b826c7bc62b9..45fa423f2e53 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -22,20 +22,6 @@ #include #include "pci-sh4.h" -#define INTC_BASE 0xffd00000 -#define INTC_ICR0 (INTC_BASE+0x0) -#define INTC_ICR1 (INTC_BASE+0x1c) -#define INTC_INTPRI (INTC_BASE+0x10) -#define INTC_INTREQ (INTC_BASE+0x24) -#define INTC_INTMSK0 (INTC_BASE+0x44) -#define INTC_INTMSK1 (INTC_BASE+0x48) -#define INTC_INTMSK2 (INTC_BASE+0x40080) -#define INTC_INTMSKCLR0 (INTC_BASE+0x64) -#define INTC_INTMSKCLR1 (INTC_BASE+0x68) -#define INTC_INTMSKCLR2 (INTC_BASE+0x40084) -#define INTC_INT2MSKR (INTC_BASE+0x40038) -#define INTC_INT2MSKCR (INTC_BASE+0x4003c) - /* * Initialization. Try all known PCI access methods. Note that we support * using both PCI BIOS and direct access: in such cases, we use I/O ports @@ -75,16 +61,6 @@ int __init sh7780_pci_init(struct pci_channel *chan) return -ENODEV; } - /* Setup the INTC */ - if (mach_is_7780se()) { - /* ICR0: IRL=use separately */ - ctrl_outl(0x00C00020, INTC_ICR0); - /* ICR1: detect low level(for 2ndcut) */ - ctrl_outl(0xAAAA0000, INTC_ICR1); - /* INTPRI: priority=3(all) */ - ctrl_outl(0x33333333, INTC_INTPRI); - } - if ((ret = sh4_pci_check_direct(chan)) != 0) return ret; -- GitLab From 7e4ba0d77c96d328ba968ddff4a464d4d2fa7abc Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 14:07:57 +0900 Subject: [PATCH 0358/6080] sh: pci: Prefer P1SEG over P1SEGADDR for CONFIG_CMD. P1SEGADDR is obsolete and will be killed off completely in the future, so transition off of it and reference P1SEG explicitly. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-sh4.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 540683d07c77..2a7f7b50ff0a 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c @@ -1,22 +1,22 @@ /* * Generic SH-4 / SH-4A PCIC operations (SH7751, SH7780). * - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002 - 2009 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License v2. See the file "COPYING" in the main directory of this archive * for more details. */ #include +#include #include -#include #include "pci-sh4.h" /* * Direct access to PCI hardware... */ #define CONFIG_CMD(bus, devfn, where) \ - P1SEGADDR((bus->number << 16) | (devfn << 8) | (where & ~3)) + (P1SEG | (bus->number << 16) | (devfn << 8) | (where & ~3)) static DEFINE_SPINLOCK(sh4_pci_lock); -- GitLab From 0bbc9bc3189f24de946777af43c9033c8c4871e4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 14:09:09 +0900 Subject: [PATCH 0359/6080] sh: pci: Set class/sub-class code correctly for SH7780 PCIC. The SH7780 PCI host controller implements a configuration header that requires a fair bit of hand-holding to initialize properly. By default it appears as a pre-2.0 host controller given the zeroed out class code, so fix this up properly. Some boards that happened to be using the R7780RP version of the PCIC fixups had set this correctly, but this belongs in the standard initialization, and is by no means board specific. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/fixups-sdk7780.c | 4 ---- arch/sh/drivers/pci/pci-sh7780.c | 7 +++---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index c2957312b30b..004efd486ee3 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -16,8 +16,6 @@ int pci_fixup_pcic(struct pci_channel *chan) { - ctrl_outl(0x00000001, SH7780_PCI_VCR2); - /* Enable all interrupts, so we know what to fix */ pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR); pci_write_reg(chan, 0x0000380F, SH7780_PCIAINTM); @@ -26,8 +24,6 @@ int pci_fixup_pcic(struct pci_channel *chan) pci_write_reg(chan, 0xFB00, SH7780_PCISTATUS); pci_write_reg(chan, 0x0047, SH7780_PCICMD); pci_write_reg(chan, 0x00, SH7780_PCIPIF); - pci_write_reg(chan, 0x00, SH7780_PCISUB); - pci_write_reg(chan, 0x06, SH7780_PCIBCC); pci_write_reg(chan, 0x1912, SH7780_PCISVID); pci_write_reg(chan, 0x0001, SH7780_PCISID); diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 45fa423f2e53..7f4f59037544 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -72,16 +72,15 @@ int __init sh7780_pcic_init(struct pci_channel *chan, { u32 word; + pci_write_reg(chan, PCI_CLASS_BRIDGE_HOST >> 8, SH7780_PCIBCC); + pci_write_reg(chan, PCI_CLASS_BRIDGE_HOST & 0xff, SH7780_PCISUB); + /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable */ pci_write_reg(chan, 0x00000046, SH7780_PCICMD); - /* define this host as the host bridge */ - word = PCI_BASE_CLASS_BRIDGE << 24; - pci_write_reg(chan, word, SH7780_PCIRID); - /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping */ -- GitLab From 4e7b7fdb129995640f144b7de114e109c6b46a2a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 15:05:19 +0900 Subject: [PATCH 0360/6080] sh: pci: Rework SH7780 host controller detection. This reworks how the host controller is probed, and makes it a bit more verbose in the event a new type of controller is detected. Additionally, we also log the revision information. This now uses the proper access sizes for the vendor/device registers, rather than relying on a larger access that encapsulated both of them. Not all devices support 32-bit read cycles for these registers. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7780.c | 42 ++++++++++++++++++-------------- arch/sh/drivers/pci/pci-sh7780.h | 5 ++-- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 7f4f59037544..63b5151e9aaa 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -34,33 +34,39 @@ int __init sh7780_pci_init(struct pci_channel *chan) { unsigned int id; - int ret, match = 0; + const char *type = NULL; + int ret; - pr_debug("PCI: Starting intialization.\n"); + printk(KERN_NOTICE "PCI: Starting intialization.\n"); chan->reg_base = 0xfe040000; chan->io_base = 0xfe200000; - ctrl_outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ - - /* check for SH7780/SH7780R hardware */ - id = pci_read_reg(chan, SH7780_PCIVID); - if ((id & 0xffff) == SH7780_VENDOR_ID) { - switch ((id >> 16) & 0xffff) { - case SH7763_DEVICE_ID: - case SH7780_DEVICE_ID: - case SH7781_DEVICE_ID: - case SH7785_DEVICE_ID: - match = 1; - break; - } - } + /* Enable CPU access to the PCIC registers. */ + __raw_writel(PCIECR_ENBL, PCIECR); - if (unlikely(!match)) { - printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id); + id = __raw_readw(chan->reg_base + SH7780_PCIVID); + if (id != SH7780_VENDOR_ID) { + printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id); return -ENODEV; } + id = __raw_readw(chan->reg_base + SH7780_PCIDID); + type = (id == SH7763_DEVICE_ID) ? "SH7763" : + (id == SH7780_DEVICE_ID) ? "SH7780" : + (id == SH7781_DEVICE_ID) ? "SH7781" : + (id == SH7785_DEVICE_ID) ? "SH7785" : + NULL; + if (unlikely(!type)) { + printk(KERN_ERR "PCI: Found an unsupported Renesas host " + "controller, device id 0x%04x.\n", id); + return -EINVAL; + } + + printk(KERN_NOTICE "PCI: Found a Renesas %s host " + "controller, revision %d.\n", type, + __raw_readb(chan->reg_base + SH7780_PCIRID)); + if ((ret = sh4_pci_check_direct(chan)) != 0) return ret; diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index fffcf1dcfedf..213f1d8c9ca5 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -20,9 +20,8 @@ #define SH7785_DEVICE_ID 0x0007 /* SH7780 Control Registers */ -#define SH7780_PCI_VCR0 0xFE000000 -#define SH7780_PCI_VCR1 0xFE000004 -#define SH7780_PCI_VCR2 0xFE000008 +#define PCIECR 0xFE000008 +#define PCIECR_ENBL 0x01 /* SH7780 Specific Values */ #define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */ -- GitLab From ab78cbcf6877334fc20868b7df7887349e2e01c8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 15:08:01 +0900 Subject: [PATCH 0361/6080] sh: pci: Use the proper write size for class/sub-class code. Don't use pci_write_reg() for these, as it defaults to 32-bit. Rather than using the helper, use __raw_writeb() directly. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7780.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 63b5151e9aaa..19bac2168f4f 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -78,8 +78,10 @@ int __init sh7780_pcic_init(struct pci_channel *chan, { u32 word; - pci_write_reg(chan, PCI_CLASS_BRIDGE_HOST >> 8, SH7780_PCIBCC); - pci_write_reg(chan, PCI_CLASS_BRIDGE_HOST & 0xff, SH7780_PCISUB); + __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8, + chan->reg_base + SH7780_PCIBCC); + __raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff, + chan->reg_base + SH7780_PCISUB); /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + -- GitLab From c66c1d79a94a7a302e2dc6c93da40902423eac3e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 16:38:00 +0900 Subject: [PATCH 0362/6080] sh: pci: Set pci_cache_line_size on SH7780 via the PCICLS register. The SH7780 PCIC contains a read-only cache line size register that we can derive pci_cache_line_size from. So, make sure that the software idea of the cache line size actually matches the host controller's idea. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7780.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 19bac2168f4f..fa73b0d15888 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -22,15 +22,6 @@ #include #include "pci-sh4.h" -/* - * Initialization. Try all known PCI access methods. Note that we support - * using both PCI BIOS and direct access: in such cases, we use I/O ports - * to access config space. - * - * Note that the platform specific initialization (BSC registers, and memory - * space mapping) will be called via the platform defined function - * pcibios_init_platform(). - */ int __init sh7780_pci_init(struct pci_channel *chan) { unsigned int id; @@ -70,19 +61,31 @@ int __init sh7780_pci_init(struct pci_channel *chan) if ((ret = sh4_pci_check_direct(chan)) != 0) return ret; + /* + * Platform specific initialization (BSC registers, and memory space + * mapping) will be called via the platform defined function + * pcibios_init_platform(). + */ return pcibios_init_platform(); } +extern u8 pci_cache_line_size; + int __init sh7780_pcic_init(struct pci_channel *chan, struct sh4_pci_address_map *map) { u32 word; + /* + * Set the class and sub-class codes. + */ __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8, chan->reg_base + SH7780_PCIBCC); __raw_writeb(PCI_CLASS_BRIDGE_HOST & 0xff, chan->reg_base + SH7780_PCISUB); + pci_cache_line_size = pci_read_reg(chan, SH7780_PCICLS) / 4; + /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable -- GitLab From f1dcab756687622b658154ded1657538984edcdb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 17:00:27 +0900 Subject: [PATCH 0363/6080] sh: pci: Set the I/O port base to the SH7780 I/O window default. Presently the I/O port base isn't being set anywhere, which allows things like generic_inl() to blow up. Fix this up to point at the PCI IO window. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7780.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index fa73b0d15888..207b7206fbda 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -112,5 +112,7 @@ int __init sh7780_pcic_init(struct pci_channel *chan, word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; pci_write_reg(chan, word, SH4_PCICR); + __set_io_port_base(SH7780_PCI_IO_BASE); + return 0; } -- GitLab From ab1363a8929f32cc163cd3f50ca72f20d901b00c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 17:07:47 +0900 Subject: [PATCH 0364/6080] sh: pci: Consolidate PCI I/O and mem window definitions for SH7780. This consolidates all of the PCI I/O and memory window definitions across the pci-sh7780 users in pci-sh7780 itself. No functional changes, in that every platform had exactly the same implementation. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-r7780rp.c | 23 +---------------------- arch/sh/drivers/pci/ops-sdk7780.c | 21 +-------------------- arch/sh/drivers/pci/ops-se7780.c | 23 +---------------------- arch/sh/drivers/pci/ops-sh7785lcr.c | 21 +-------------------- arch/sh/drivers/pci/pci-sh7780.c | 25 ++++++++++++++++++++++--- arch/sh/drivers/pci/pci-sh7780.h | 4 +--- 6 files changed, 27 insertions(+), 90 deletions(-) diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c index 8ec6d225ef9d..044525df18c5 100644 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ b/arch/sh/drivers/pci/ops-r7780rp.c @@ -26,27 +26,6 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) return irq_tab[slot]; } -static struct resource sh7780_io_resource = { - .name = "SH7780_IO", - .start = SH7780_PCI_IO_BASE, - .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7780_mem_resource = { - .name = "SH7780_mem", - .start = SH7780_PCI_MEMORY_BASE, - .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops sh7780_pci_ops; - -struct pci_channel board_pci_channels[] = { - { sh7780_pci_init, &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - static struct sh4_pci_address_map sh7780_pci_map = { .window0 = { .base = SH7780_CS2_BASE_ADDR, @@ -61,5 +40,5 @@ static struct sh4_pci_address_map sh7780_pci_map = { int __init pcibios_init_platform(void) { - return sh7780_pcic_init(&board_pci_channels[0], &sh7780_pci_map); + return sh7780_pcic_init(&sh7780_pci_map); } diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c index 6a0b7c067831..570fd71f6937 100644 --- a/arch/sh/drivers/pci/ops-sdk7780.c +++ b/arch/sh/drivers/pci/ops-sdk7780.c @@ -34,25 +34,6 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) return sdk7780_irq_tab[pin-1][slot]; } -static struct resource sdk7780_io_resource = { - .name = "SH7780_IO", - .start = SH7780_PCI_IO_BASE, - .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sdk7780_mem_resource = { - .name = "SH7780_mem", - .start = SH7780_PCI_MEMORY_BASE, - .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -struct pci_channel board_pci_channels[] = { - { sh7780_pci_init, &sh4_pci_ops, &sdk7780_io_resource, &sdk7780_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - static struct sh4_pci_address_map sdk7780_pci_map = { .window0 = { .base = SH7780_CS2_BASE_ADDR, @@ -67,5 +48,5 @@ static struct sh4_pci_address_map sdk7780_pci_map = { int __init pcibios_init_platform(void) { printk(KERN_INFO "SH7780 PCI: Finished initializing PCI controller\n"); - return sh7780_pcic_init(&board_pci_channels[0], &sdk7780_pci_map); + return sh7780_pcic_init(&sdk7780_pci_map); } diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c index 583b8e82ff99..8b0941515b0f 100644 --- a/arch/sh/drivers/pci/ops-se7780.c +++ b/arch/sh/drivers/pci/ops-se7780.c @@ -41,27 +41,6 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) return se7780_irq_tab[pin-1][slot]; } -static struct resource se7780_io_resource = { - .name = "SH7780_IO", - .start = SH7780_PCI_IO_BASE, - .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource se7780_mem_resource = { - .name = "SH7780_mem", - .start = SH7780_PCI_MEMORY_BASE, - .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops se7780_pci_ops; - -struct pci_channel board_pci_channels[] = { - { sh7780_pci_init, &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - static struct sh4_pci_address_map se7780_pci_map = { .window0 = { .base = SH7780_CS2_BASE_ADDR, @@ -90,5 +69,5 @@ int __init pcibios_init_platform(void) ctrl_outw(0x0013, FPGA_PCI_INTSEL1); ctrl_outw(0xE402, FPGA_PCI_INTSEL2); - return sh7780_pcic_init(&board_pci_channels[0], &se7780_pci_map); + return sh7780_pcic_init(&se7780_pci_map); } diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c index ab0d1decf2df..bac46b5d1580 100644 --- a/arch/sh/drivers/pci/ops-sh7785lcr.c +++ b/arch/sh/drivers/pci/ops-sh7785lcr.c @@ -26,25 +26,6 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) return irq_tab[slot]; } -static struct resource sh7785_io_resource = { - .name = "SH7785_IO", - .start = SH7780_PCI_IO_BASE, - .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7785_mem_resource = { - .name = "SH7785_mem", - .start = SH7780_PCI_MEMORY_BASE, - .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -struct pci_channel board_pci_channels[] = { - { sh7780_pci_init, &sh4_pci_ops, &sh7785_io_resource, &sh7785_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - static struct sh4_pci_address_map sh7785_pci_map = { .window0 = { #if defined(CONFIG_32BIT) @@ -59,5 +40,5 @@ static struct sh4_pci_address_map sh7785_pci_map = { int __init pcibios_init_platform(void) { - return sh7780_pcic_init(&board_pci_channels[0], &sh7785_pci_map); + return sh7780_pcic_init(&sh7785_pci_map); } diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 207b7206fbda..eb217ddf025f 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -22,7 +22,7 @@ #include #include "pci-sh4.h" -int __init sh7780_pci_init(struct pci_channel *chan) +static int __init sh7780_pci_init(struct pci_channel *chan) { unsigned int id; const char *type = NULL; @@ -71,9 +71,28 @@ int __init sh7780_pci_init(struct pci_channel *chan) extern u8 pci_cache_line_size; -int __init sh7780_pcic_init(struct pci_channel *chan, - struct sh4_pci_address_map *map) +static struct resource sh7785_io_resource = { + .name = "SH7785_IO", + .start = SH7780_PCI_IO_BASE, + .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7785_mem_resource = { + .name = "SH7785_mem", + .start = SH7780_PCI_MEMORY_BASE, + .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +struct pci_channel board_pci_channels[] = { + { sh7780_pci_init, &sh4_pci_ops, &sh7785_io_resource, &sh7785_mem_resource, 0, 0xff }, + { NULL, NULL, NULL, 0, 0 }, +}; + +int __init sh7780_pcic_init(struct sh4_pci_address_map *map) { + struct pci_channel *chan = &board_pci_channels[0]; u32 word; /* diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index 213f1d8c9ca5..7a4f8a8dd690 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -107,8 +107,6 @@ struct sh4_pci_address_map; /* arch/sh/drivers/pci/pci-sh7780.c */ -int sh7780_pci_init(struct pci_channel *chan); -int sh7780_pcic_init(struct pci_channel *chan, - struct sh4_pci_address_map *map); +int sh7780_pcic_init(struct sh4_pci_address_map *map); #endif /* _PCI_SH7780_H_ */ -- GitLab From f6a2629353718e588820b731af43a445b6f35648 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 16 Apr 2009 15:23:03 +0000 Subject: [PATCH 0365/6080] irda: include etherdevice.h for eth_*() functions Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/irda/au1k_ir.c | 1 + drivers/net/irda/pxaficp_ir.c | 1 + drivers/net/irda/sa1100_ir.c | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index 204def0f6451..269153eedd26 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index e8ced56b050f..3376a4f39e0a 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -14,6 +14,7 @@ */ #include #include +#include #include #include diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 44a748e72332..4ed763670a97 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include -- GitLab From d32da050a340214c5dae0d014e39f75548cac2f2 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 16 Apr 2009 15:48:17 +0000 Subject: [PATCH 0366/6080] wan/pc300_drv: convert to net_device_ops On Fri, Apr 17, 2009 at 05:23:02AM +0400, Alexander Beregalov wrote: > > Signed-off-by: Alexander Beregalov > --- > drivers/net/wan/pc300_drv.c | 22 ++++++++++++++-------- > 1 files changed, 14 insertions(+), 8 deletions(-) > > diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c > index c23fde0..df10a4c 100644 > --- a/drivers/net/wan/pc300_drv.c > +++ b/drivers/net/wan/pc300_drv.c > @@ -225,6 +225,7 @@ static char rcsid[] = > #include > #include > #include > +#include > #include > #include > #include > @@ -3246,6 +3247,18 @@ static inline void show_version(void) > rcsvers, rcsdate, __DATE__, __TIME__); > } /* show_version */ > > +static const struct net_device_ops cpc_netdev_ops = { > + .ndo_init = NULL, > + .ndo_open = cpc_open, > + .ndo_stop = cpc_close, > + .ndo_tx_timeout = cpc_tx_timeout, > + .ndo_set_multicast_list = NULL, In this case ndo_init and ndo_set_multicast_list are not needed. >From 1507a5a797a5f0005696a9bf10e390caca9c3800 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Fri, 17 Apr 2009 05:45:48 +0400 Subject: [PATCH] wan/pc300_drv: convert to net_device_ops Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/wan/pc300_drv.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index c23fde0c0344..79dabc557bd3 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -225,6 +225,7 @@ static char rcsid[] = #include #include #include +#include #include #include #include @@ -3246,6 +3247,16 @@ static inline void show_version(void) rcsvers, rcsdate, __DATE__, __TIME__); } /* show_version */ +static const struct net_device_ops cpc_netdev_ops = { + .ndo_open = cpc_open, + .ndo_stop = cpc_close, + .ndo_tx_timeout = cpc_tx_timeout, + .ndo_set_mac_address = NULL, + .ndo_change_mtu = cpc_change_mtu, + .ndo_do_ioctl = cpc_ioctl, + .ndo_validate_addr = eth_validate_addr, +}; + static void cpc_init_card(pc300_t * card) { int i, devcount = 0; @@ -3357,18 +3368,11 @@ static void cpc_init_card(pc300_t * card) dev->mem_start = card->hw.ramphys; dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1; dev->irq = card->hw.irq; - dev->init = NULL; dev->tx_queue_len = PC300_TX_QUEUE_LEN; dev->mtu = PC300_DEF_MTU; - dev->open = cpc_open; - dev->stop = cpc_close; - dev->tx_timeout = cpc_tx_timeout; + dev->netdev_ops = &cpc_netdev_ops; dev->watchdog_timeo = PC300_TX_TIMEOUT; - dev->set_multicast_list = NULL; - dev->set_mac_address = NULL; - dev->change_mtu = cpc_change_mtu; - dev->do_ioctl = cpc_ioctl; if (register_hdlc_device(dev) == 0) { printk("%s: Cyclades-PC300/", dev->name); -- GitLab From 4c7a47de897e89c25a40e228ac5319cbac7257fe Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 17:21:36 +0900 Subject: [PATCH 0367/6080] sh: pci: Kill off platform-specific multi-window mappings. Commit 68b42d1b548be1840aff7122fdebeb804daf0fa3 ("sh: sh7785lcr: Map whole PCI address space.") changed around the semantics of how various chip-selects are made accessible to PCI. Now that there is a single large mapping covering from CS0-CS6, there is no longer any need to do multi-window mapping. Subsequently, all of the differing implementations can be consolidated in to pci-sh7780. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7780/irq.c | 17 ++++++++++++++++ arch/sh/drivers/pci/ops-r7780rp.c | 17 ---------------- arch/sh/drivers/pci/ops-sdk7780.c | 17 ---------------- arch/sh/drivers/pci/ops-se7780.c | 31 ----------------------------- arch/sh/drivers/pci/ops-sh7785lcr.c | 17 ---------------- arch/sh/drivers/pci/pci-sh7780.c | 24 ++++++++++++++-------- arch/sh/drivers/pci/pci-sh7780.h | 5 ----- 7 files changed, 33 insertions(+), 95 deletions(-) diff --git a/arch/sh/boards/mach-se/7780/irq.c b/arch/sh/boards/mach-se/7780/irq.c index 44b61a597a15..b8d43b638fcf 100644 --- a/arch/sh/boards/mach-se/7780/irq.c +++ b/arch/sh/boards/mach-se/7780/irq.c @@ -49,4 +49,21 @@ void __init init_se7780_IRQ(void) /* ICR1: detect low level(for 2ndcut) */ ctrl_outl(0xAAAA0000, INTC_ICR1); + + /* + * FPGA PCISEL register initialize + * + * CPU || SLOT1 | SLOT2 | S-ATA | USB + * ------------------------------------- + * INTA || INTA | INTD | -- | INTB + * ------------------------------------- + * INTB || INTB | INTA | -- | INTC + * ------------------------------------- + * INTC || INTC | INTB | INTA | -- + * ------------------------------------- + * INTD || INTD | INTC | -- | INTA + * ------------------------------------- + */ + ctrl_outw(0x0013, FPGA_PCI_INTSEL1); + ctrl_outw(0xE402, FPGA_PCI_INTSEL2); } diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c index 044525df18c5..4ea136e4eacd 100644 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ b/arch/sh/drivers/pci/ops-r7780rp.c @@ -25,20 +25,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { return irq_tab[slot]; } - -static struct sh4_pci_address_map sh7780_pci_map = { - .window0 = { - .base = SH7780_CS2_BASE_ADDR, - .size = 0x04000000, - }, - - .window1 = { - .base = SH7780_CS3_BASE_ADDR, - .size = 0x04000000, - }, -}; - -int __init pcibios_init_platform(void) -{ - return sh7780_pcic_init(&sh7780_pci_map); -} diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c index 570fd71f6937..1d9a91bcfb7d 100644 --- a/arch/sh/drivers/pci/ops-sdk7780.c +++ b/arch/sh/drivers/pci/ops-sdk7780.c @@ -33,20 +33,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { return sdk7780_irq_tab[pin-1][slot]; } - -static struct sh4_pci_address_map sdk7780_pci_map = { - .window0 = { - .base = SH7780_CS2_BASE_ADDR, - .size = 0x04000000, - }, - .window1 = { - .base = SH7780_CS3_BASE_ADDR, - .size = 0x04000000, - }, -}; - -int __init pcibios_init_platform(void) -{ - printk(KERN_INFO "SH7780 PCI: Finished initializing PCI controller\n"); - return sh7780_pcic_init(&sdk7780_pci_map); -} diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c index 8b0941515b0f..6c088ccfe475 100644 --- a/arch/sh/drivers/pci/ops-se7780.c +++ b/arch/sh/drivers/pci/ops-se7780.c @@ -40,34 +40,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { return se7780_irq_tab[pin-1][slot]; } - -static struct sh4_pci_address_map se7780_pci_map = { - .window0 = { - .base = SH7780_CS2_BASE_ADDR, - .size = 0x04000000, - }, -}; - -int __init pcibios_init_platform(void) -{ - printk("SH7780 PCI: Finished initialization of the PCI controller\n"); - - /* - * FPGA PCISEL register initialize - * - * CPU || SLOT1 | SLOT2 | S-ATA | USB - * ------------------------------------- - * INTA || INTA | INTD | -- | INTB - * ------------------------------------- - * INTB || INTB | INTA | -- | INTC - * ------------------------------------- - * INTC || INTC | INTB | INTA | -- - * ------------------------------------- - * INTD || INTD | INTC | -- | INTA - * ------------------------------------- - */ - ctrl_outw(0x0013, FPGA_PCI_INTSEL1); - ctrl_outw(0xE402, FPGA_PCI_INTSEL2); - - return sh7780_pcic_init(&se7780_pci_map); -} diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c index bac46b5d1580..0fe423e23508 100644 --- a/arch/sh/drivers/pci/ops-sh7785lcr.c +++ b/arch/sh/drivers/pci/ops-sh7785lcr.c @@ -25,20 +25,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { return irq_tab[slot]; } - -static struct sh4_pci_address_map sh7785_pci_map = { - .window0 = { -#if defined(CONFIG_32BIT) - .base = SH7780_32BIT_DDR_BASE_ADDR, - .size = 0x40000000, -#else - .base = SH7780_CS0_BASE_ADDR, - .size = 0x20000000, -#endif - }, -}; - -int __init pcibios_init_platform(void) -{ - return sh7780_pcic_init(&sh7785_pci_map); -} diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index eb217ddf025f..07c5529a273b 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -90,7 +90,19 @@ struct pci_channel board_pci_channels[] = { { NULL, NULL, NULL, 0, 0 }, }; -int __init sh7780_pcic_init(struct sh4_pci_address_map *map) +static struct sh4_pci_address_map sh7780_pci_map = { + .window0 = { +#if defined(CONFIG_32BIT) + .base = SH7780_32BIT_DDR_BASE_ADDR, + .size = 0x40000000, +#else + .base = SH7780_CS0_BASE_ADDR, + .size = 0x20000000, +#endif + }, +}; + +int __init pcibios_init_platform(void) { struct pci_channel *chan = &board_pci_channels[0]; u32 word; @@ -114,14 +126,10 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map) /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping */ - pci_write_reg(chan, map->window0.size - 0xfffff, SH4_PCILSR0); - pci_write_reg(chan, map->window1.size - 0xfffff, SH4_PCILSR1); + pci_write_reg(chan, sh7780_pci_map.window0.size - 0xfffff, SH4_PCILSR0); /* Set the values on window 0 PCI config registers */ - pci_write_reg(chan, map->window0.base, SH4_PCILAR0); - pci_write_reg(chan, map->window0.base, SH7780_PCIMBAR0); - /* Set the values on window 1 PCI config registers */ - pci_write_reg(chan, map->window1.base, SH4_PCILAR1); - pci_write_reg(chan, map->window1.base, SH7780_PCIMBAR1); + pci_write_reg(chan, sh7780_pci_map.window0.base, SH4_PCILAR0); + pci_write_reg(chan, sh7780_pci_map.window0.base, SH7780_PCIMBAR0); /* Apply any last-minute PCIC fixups */ pci_fixup_pcic(chan); diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index 7a4f8a8dd690..4b65d4b26f75 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -104,9 +104,4 @@ #define SH7780_32BIT_DDR_BASE_ADDR 0x40000000 -struct sh4_pci_address_map; - -/* arch/sh/drivers/pci/pci-sh7780.c */ -int sh7780_pcic_init(struct sh4_pci_address_map *map); - #endif /* _PCI_SH7780_H_ */ -- GitLab From a6d377b6969235a3b5a6e87bdcef387d0976b41c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 20:11:44 +0900 Subject: [PATCH 0368/6080] sh: pci: Consolidate SH7780 PCIC IRQ routing. Now that the platform code is a bit leaner, we can start consolidating the various IRQ routing implementations. There are effectively only 2 variants, and the others can use those directly. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 8 +++--- arch/sh/drivers/pci/fixups-r7780rp.c | 10 ++++++- arch/sh/drivers/pci/fixups-sdk7780.c | 19 ++++++++++++- arch/sh/drivers/pci/ops-r7780rp.c | 27 ------------------ arch/sh/drivers/pci/ops-sdk7780.c | 35 ----------------------- arch/sh/drivers/pci/ops-se7780.c | 42 ---------------------------- arch/sh/drivers/pci/ops-sh7785lcr.c | 27 ------------------ 7 files changed, 31 insertions(+), 137 deletions(-) delete mode 100644 arch/sh/drivers/pci/ops-r7780rp.c delete mode 100644 arch/sh/drivers/pci/ops-sdk7780.c delete mode 100644 arch/sh/drivers/pci/ops-se7780.c delete mode 100644 arch/sh/drivers/pci/ops-sh7785lcr.c diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 67d710a04de1..5003971476ec 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -16,11 +16,11 @@ obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o -obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o -obj-$(CONFIG_SH_SDK7780) += ops-sdk7780.o fixups-sdk7780.o +obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o +obj-$(CONFIG_SH_SH7785LCR) += fixups-r7780rp.o +obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o +obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o obj-$(CONFIG_SH_TITAN) += ops-titan.o obj-$(CONFIG_SH_LANDISK) += ops-landisk.o obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o -obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-sdk7780.o obj-$(CONFIG_SH_CAYMAN) += ops-cayman.o -obj-$(CONFIG_SH_SH7785LCR) += ops-sh7785lcr.o fixups-r7780rp.o diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 31f8dfbfcbf5..864e92f69702 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -11,9 +11,17 @@ * for more details. */ #include +#include #include "pci-sh4.h" -#include +static char irq_tab[] __initdata = { + 65, 66, 67, 68, +}; + +int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +{ + return irq_tab[slot]; +} int pci_fixup_pcic(struct pci_channel *chan) { pci_write_reg(chan, 0x000043ff, SH4_PCIINTM); diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index 004efd486ee3..da60e99894b8 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -5,15 +5,32 @@ * * Copyright (C) 2003 Lineo uSolutions, Inc. * Copyright (C) 2004 - 2006 Paul Mundt + * Copyright (C) 2006 Nobuhiro Iwamatsu * * 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. */ #include +#include #include "pci-sh4.h" -#include +/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ +static char sdk7780_irq_tab[4][16] __initdata = { + /* INTA */ + { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + /* INTB */ + { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + /* INTC */ + { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, + /* INTD */ + { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +}; + +int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +{ + return sdk7780_irq_tab[pin-1][slot]; +} int pci_fixup_pcic(struct pci_channel *chan) { /* Enable all interrupts, so we know what to fix */ diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c deleted file mode 100644 index 4ea136e4eacd..000000000000 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Author: Ian DaSilva (idasilva@mvista.com) - * - * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board - */ -#include -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -static char irq_tab[] __initdata = { - 65, 66, 67, 68, -}; - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - return irq_tab[slot]; -} diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c deleted file mode 100644 index 1d9a91bcfb7d..000000000000 --- a/arch/sh/drivers/pci/ops-sdk7780.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/sh/drivers/pci/ops-sdk7780.c - * - * Copyright (C) 2006 Nobuhiro Iwamatsu - * - * PCI initialization for the SDK7780SE03 - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - */ -#include -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ -static char sdk7780_irq_tab[4][16] __initdata = { - /* INTA */ - { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* INTB */ - { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* INTC */ - { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* INTD */ - { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -}; - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - return sdk7780_irq_tab[pin-1][slot]; -} diff --git a/arch/sh/drivers/pci/ops-se7780.c b/arch/sh/drivers/pci/ops-se7780.c deleted file mode 100644 index 6c088ccfe475..000000000000 --- a/arch/sh/drivers/pci/ops-se7780.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * linux/arch/sh/drivers/pci/ops-se7780.c - * - * Copyright (C) 2006 Nobuhiro Iwamatsu - * - * PCI initialization for the Hitachi UL Solution Engine 7780SE03 - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - */ -#include -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -/* - * IDSEL = AD16 PCI slot - * IDSEL = AD17 PCI slot - * IDSEL = AD18 Serial ATA Controller (Silicon Image SiL3512A) - * IDSEL = AD19 USB Host Controller (NEC uPD7210100A) - */ - -/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ -static char se7780_irq_tab[4][16] __initdata = { - /* INTA */ - { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* INTB */ - { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* INTC */ - { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* INTD */ - { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -}; - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - return se7780_irq_tab[pin-1][slot]; -} diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c deleted file mode 100644 index 0fe423e23508..000000000000 --- a/arch/sh/drivers/pci/ops-sh7785lcr.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Author: Ian DaSilva (idasilva@mvista.com) - * - * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * PCI initialization for the Renesas R0P7785LC0011RL board - * Based on arch/sh/drivers/pci/ops-r7780rp.c - * - */ -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -static char irq_tab[] __initdata = { - 65, 66, 67, 68, -}; - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - return irq_tab[slot]; -} -- GitLab From 62c7ae87cb5962d3dfaa6d916a15e4faa9e07363 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 17 Apr 2009 20:37:16 +0900 Subject: [PATCH 0369/6080] sh: pci: Start unifying the SH7780 PCIC initialization. This starts moving out the common initialization bits from the various fixup paths in to the shared init path. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/fixups-r7780rp.c | 20 +---------- arch/sh/drivers/pci/fixups-sdk7780.c | 32 +++--------------- arch/sh/drivers/pci/pci-sh7780.c | 50 +++++++++++++++++----------- arch/sh/drivers/pci/pci-sh7780.h | 5 --- 4 files changed, 37 insertions(+), 70 deletions(-) diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 864e92f69702..15ca65cb667e 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -22,33 +22,15 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { return irq_tab[slot]; } + int pci_fixup_pcic(struct pci_channel *chan) { pci_write_reg(chan, 0x000043ff, SH4_PCIINTM); - pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); - - pci_write_reg(chan, 0xfbb00047, SH7780_PCICMD); pci_write_reg(chan, 0x00000000, SH7780_PCIIBAR); - - pci_write_reg(chan, 0x00011912, SH7780_PCISVID); pci_write_reg(chan, 0x08000000, SH7780_PCICSCR0); pci_write_reg(chan, 0x0000001b, SH7780_PCICSAR0); pci_write_reg(chan, 0xfd000000, SH7780_PCICSCR1); pci_write_reg(chan, 0x0000000f, SH7780_PCICSAR1); - pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0); - pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0); - -#ifdef CONFIG_32BIT - pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2); - pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); -#endif - - /* Set IOBR for windows containing area specified in pci.h */ - pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), - SH7780_PCIIOBR); - pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)), - SH7780_PCIIOBMR); - return 0; } diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index da60e99894b8..250b0edd7365 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -35,40 +35,18 @@ int pci_fixup_pcic(struct pci_channel *chan) { /* Enable all interrupts, so we know what to fix */ pci_write_reg(chan, 0x0000C3FF, SH7780_PCIIMR); - pci_write_reg(chan, 0x0000380F, SH7780_PCIAINTM); /* Set up standard PCI config registers */ - pci_write_reg(chan, 0xFB00, SH7780_PCISTATUS); - pci_write_reg(chan, 0x0047, SH7780_PCICMD); - pci_write_reg(chan, 0x00, SH7780_PCIPIF); - pci_write_reg(chan, 0x1912, SH7780_PCISVID); - pci_write_reg(chan, 0x0001, SH7780_PCISID); - pci_write_reg(chan, 0x08000000, SH7780_PCIMBAR0); /* PCI */ - pci_write_reg(chan, 0x08000000, SH7780_PCILAR0); /* SHwy */ - pci_write_reg(chan, 0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ + pci_write_reg(chan, 0x08000000, SH4_PCILAR0); /* SHwy */ + pci_write_reg(chan, 0x07F00001, SH4_PCILSR0); /* size 128M w/ MBAR */ pci_write_reg(chan, 0x00000000, SH7780_PCIMBAR1); - pci_write_reg(chan, 0x00000000, SH7780_PCILAR1); - pci_write_reg(chan, 0x00000000, SH7780_PCILSR1); + pci_write_reg(chan, 0x00000000, SH4_PCILAR1); + pci_write_reg(chan, 0x00000000, SH4_PCILSR1); pci_write_reg(chan, 0xAB000801, SH7780_PCIIBAR); - - /* - * Set the MBR so PCI address is one-to-one with window, - * meaning all calls go straight through... use ifdef to - * catch erroneous assumption. - */ - pci_write_reg(chan, 0xFD000000 , SH7780_PCIMBR0); - pci_write_reg(chan, 0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ - - /* Set IOBR for window containing area specified in pci.h */ - pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), - SH7780_PCIIOBR); - pci_write_reg(chan, (SH7780_PCI_IO_SIZE-1) & (7 << 18), - SH7780_PCIIOBMR); - - pci_write_reg(chan, 0xA5000C01, SH7780_PCICR); + pci_write_reg(chan, 0xA5000C01, SH4_PCICR); return 0; } diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 07c5529a273b..f02d9dfcf252 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -1,19 +1,12 @@ /* - * Low-Level PCI Support for the SH7780 + * Low-Level PCI Support for the SH7780 * - * Dustin McIntire (dustin@sensoria.com) - * Derived from arch/i386/kernel/pci-*.c which bore the message: - * (c) 1999--2000 Martin Mares - * - * Ported to the new API by Paul Mundt - * With cleanup by Paul van Gool - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. + * Copyright (C) 2005 - 2009 Paul Mundt * + * 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. */ -#undef DEBUG - #include #include #include @@ -117,13 +110,8 @@ int __init pcibios_init_platform(void) pci_cache_line_size = pci_read_reg(chan, SH7780_PCICLS) / 4; - /* set the command/status bits to: - * Wait Cycle Control + Parity Enable + Bus Master + - * Mem space enable - */ - pci_write_reg(chan, 0x00000046, SH7780_PCICMD); - - /* Set IO and Mem windows to local address + /* + * Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping */ pci_write_reg(chan, sh7780_pci_map.window0.size - 0xfffff, SH4_PCILSR0); @@ -131,9 +119,33 @@ int __init pcibios_init_platform(void) pci_write_reg(chan, sh7780_pci_map.window0.base, SH4_PCILAR0); pci_write_reg(chan, sh7780_pci_map.window0.base, SH7780_PCIMBAR0); + pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); + + /* Set up standard PCI config registers */ + __raw_writew(0xFB00, chan->reg_base + SH7780_PCISTATUS); + __raw_writew(0x0047, chan->reg_base + SH7780_PCICMD); + __raw_writew(0x1912, chan->reg_base + SH7780_PCISVID); + __raw_writew(0x0001, chan->reg_base + SH7780_PCISID); + + __raw_writeb(0x00, chan->reg_base + SH7780_PCIPIF); + /* Apply any last-minute PCIC fixups */ pci_fixup_pcic(chan); + pci_write_reg(chan, 0xfd000000, SH7780_PCIMBR0); + pci_write_reg(chan, 0x00fc0000, SH7780_PCIMBMR0); + +#ifdef CONFIG_32BIT + pci_write_reg(chan, 0xc0000000, SH7780_PCIMBR2); + pci_write_reg(chan, 0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); +#endif + + /* Set IOBR for windows containing area specified in pci.h */ + pci_write_reg(chan, chan->io_resource->start & ~(SH7780_PCI_IO_SIZE-1), + SH7780_PCIIOBR); + pci_write_reg(chan, ((SH7780_PCI_IO_SIZE-1) & (7<<18)), + SH7780_PCIIOBMR); + /* SH7780 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h index 4b65d4b26f75..4a52478c97cf 100644 --- a/arch/sh/drivers/pci/pci-sh7780.h +++ b/arch/sh/drivers/pci/pci-sh7780.h @@ -65,11 +65,6 @@ #define SH7780_PCIPMCSR_BSE 0x046 #define SH7780_PCICDD 0x047 -#define SH7780_PCICR 0x100 /* PCI Control Register */ -#define SH7780_PCILSR 0x104 /* PCI Local Space Register0 */ -#define SH7780_PCILSR1 0x108 /* PCI Local Space Register1 */ -#define SH7780_PCILAR0 0x10C /* PCI Local Address Register1 */ -#define SH7780_PCILAR1 0x110 /* PCI Local Address Register1 */ #define SH7780_PCIIR 0x114 /* PCI Interrupt Register */ #define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */ #define SH7780_PCIAIR 0x11C /* Error Address Register */ -- GitLab From 573636cbafeba88f7c88832ae053dafe265bf94b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 17 Apr 2009 04:52:48 -0700 Subject: [PATCH 0370/6080] [PATCH] net: remove superfluous call to synchronize_net() inet_register_protosw() function is responsible for adding a new inet protocol into a global table (inetsw[]) that is used with RCU rules. As soon as the store of the pointer is done, other cpus might see this new protocol in inetsw[], so we have to make sure new protocol is ready for use. All pending memory updates should thus be committed to memory before setting the pointer. This is correctly done using rcu_assign_pointer() synchronize_net() is typically used at unregister time, after unsetting the pointer, to make sure no other cpu is still using the object we want to dismantle. Using it at register time is only adding an artificial delay that could hide a real bug, and this bug could popup if/when synchronize_rcu() can proceed faster than now. This saves about 13 ms on boot time on a HZ=1000 8 cpus machine ;) (4 calls to inet_register_protosw(), and about 3200 us per call) Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/af_inet.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 7f03373b8c07..170689681aa2 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1003,8 +1003,6 @@ void inet_register_protosw(struct inet_protosw *p) out: spin_unlock_bh(&inetsw_lock); - synchronize_net(); - return; out_permanent: -- GitLab From 6b87a91f5417226c7fe62100b0e7217e7096b789 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 17 Apr 2009 15:55:08 +0300 Subject: [PATCH 0371/6080] ASoC: TWL4030: Fix for the constraint handling The original implementation of the constraints were good against sane applications. If the opening sequence is: stream1_open, stream1_hw_params, stream2_open, stream2_hw_params -> the constraints are set correctly for stream2. But if the sequence is: stream1_open, stream2_open, stream2_hw_params, stream1_hw_params -> than stream2 would receive constraint rate = 0, sample_bits = 0, since the stream1 has not yet called hw_params... The command to trigger this event: gst-launch-0.10 alsasrc device=hw:0 ! alsasink device=hw:0 sync=false This patch does some 'black magic' in order to always set the correct constraints and sets it only when it is needed for the other stream. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 85 +++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 921b205de28a..a1b76d7fd130 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -125,6 +125,11 @@ struct twl4030_priv { struct snd_pcm_substream *master_substream; struct snd_pcm_substream *slave_substream; + + unsigned int configured; + unsigned int rate; + unsigned int sample_bits; + unsigned int channels; }; /* @@ -1220,6 +1225,36 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec, return 0; } +static void twl4030_constraints(struct twl4030_priv *twl4030, + struct snd_pcm_substream *mst_substream) +{ + struct snd_pcm_substream *slv_substream; + + /* Pick the stream, which need to be constrained */ + if (mst_substream == twl4030->master_substream) + slv_substream = twl4030->slave_substream; + else if (mst_substream == twl4030->slave_substream) + slv_substream = twl4030->master_substream; + else /* This should not happen.. */ + return; + + /* Set the constraints according to the already configured stream */ + snd_pcm_hw_constraint_minmax(slv_substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, + twl4030->rate, + twl4030->rate); + + snd_pcm_hw_constraint_minmax(slv_substream->runtime, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + twl4030->sample_bits, + twl4030->sample_bits); + + snd_pcm_hw_constraint_minmax(slv_substream->runtime, + SNDRV_PCM_HW_PARAM_CHANNELS, + twl4030->channels, + twl4030->channels); +} + static int twl4030_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -1228,26 +1263,16 @@ static int twl4030_startup(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = socdev->card->codec; struct twl4030_priv *twl4030 = codec->private_data; - /* If we already have a playback or capture going then constrain - * this substream to match it. - */ if (twl4030->master_substream) { - struct snd_pcm_runtime *master_runtime; - master_runtime = twl4030->master_substream->runtime; - - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - master_runtime->rate, - master_runtime->rate); - - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - master_runtime->sample_bits, - master_runtime->sample_bits); - twl4030->slave_substream = substream; - } else + /* The DAI has one configuration for playback and capture, so + * if the DAI has been already configured then constrain this + * substream to match it. */ + if (twl4030->configured) + twl4030_constraints(twl4030, twl4030->master_substream); + } else { twl4030->master_substream = substream; + } return 0; } @@ -1264,6 +1289,13 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream, twl4030->master_substream = twl4030->slave_substream; twl4030->slave_substream = NULL; + + /* If all streams are closed, or the remaining stream has not yet + * been configured than set the DAI as not configured. */ + if (!twl4030->master_substream) + twl4030->configured = 0; + else if (!twl4030->master_substream->runtime->channels) + twl4030->configured = 0; } static int twl4030_hw_params(struct snd_pcm_substream *substream, @@ -1276,8 +1308,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, struct twl4030_priv *twl4030 = codec->private_data; u8 mode, old_mode, format, old_format; - if (substream == twl4030->slave_substream) - /* Ignoring hw_params for slave substream */ + if (twl4030->configured) + /* Ignoring hw_params for already configured DAI */ return 0; /* bit rate */ @@ -1357,6 +1389,21 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, /* set CODECPDZ afterwards */ twl4030_codec_enable(codec, 1); } + + /* Store the important parameters for the DAI configuration and set + * the DAI as configured */ + twl4030->configured = 1; + twl4030->rate = params_rate(params); + twl4030->sample_bits = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min; + twl4030->channels = params_channels(params); + + /* If both playback and capture streams are open, and one of them + * is setting the hw parameters right now (since we are here), set + * constraints to the other stream to match the current one. */ + if (twl4030->slave_substream) + twl4030_constraints(twl4030, substream); + return 0; } -- GitLab From 7fe624f5607ed98de0034adf130e857474dffc2b Mon Sep 17 00:00:00 2001 From: Andrew Gallatin Date: Fri, 17 Apr 2009 15:45:15 -0700 Subject: [PATCH 0372/6080] myri10ge: fix compile error A compilation error snuck into 2d90b0aa3bc484189940444bcddcbe0ebbb53af5 due to an over-zealous indent script removing spaces around array initialization ellipsis. The attached patch fixes the myri10ge compilation in net-next. Signed-off-by: Andrew Gallatin Signed-off-by: David S. Miller --- drivers/net/myri10ge/myri10ge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 291944d0aea3..140794a8d56a 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -269,7 +269,7 @@ MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name"); #define MYRI10GE_MAX_BOARDS 8 static char *myri10ge_fw_names[MYRI10GE_MAX_BOARDS] = - {[0...(MYRI10GE_MAX_BOARDS - 1)] = NULL }; + {[0 ... (MYRI10GE_MAX_BOARDS - 1)] = NULL }; module_param_array_named(myri10ge_fw_names, myri10ge_fw_names, charp, NULL, 0444); MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image names per board"); -- GitLab From 6f41469c627fe118121dfce2a8134ad24da3df28 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0373/6080] block: clear req->errors on bio completion only for fs requests Impact: subtle behavior change For fs requests, rq is only carrier of bios and rq error status as a whole doesn't mean much. This is the reason why rq->errors is being cleared on each partial completion of a request as on each partial completion the error status is transferred to the respective bios. For pc requests, rq->errors is used to carry error status to the issuer and thus __end_that_request_first() doesn't clear it on such cases. The condition was fine till now as only fs and pc requests have used bio and thus the bio completion path. However, future changes will unify data accesses to bio and all non fs users care about rq error status. Clear rq->errors on bio completion only for fs requests. In general, the implicit clearing is a bit too subtle especially as the meaning of rq->errors is completely dependent on low level drivers. Unifying / cleaning up rq->errors usage and letting llds manage it would be better. TODO comment added. Signed-off-by: Tejun Heo Acked-by: Jens Axboe --- block/blk-core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 07ab75403e1a..cce7a88dc612 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1739,10 +1739,14 @@ static int __end_that_request_first(struct request *req, int error, trace_block_rq_complete(req->q, req); /* - * for a REQ_TYPE_BLOCK_PC request, we want to carry any eventual - * sense key with us all the way through + * For fs requests, rq is just carrier of independent bio's + * and each partial completion should be handled separately. + * Reset per-request error on each partial completion. + * + * TODO: tj: This is too subtle. It would be better to let + * low level drivers do what they see fit. */ - if (!blk_pc_request(req)) + if (blk_fs_request(req)) req->errors = 0; if (error && (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))) { -- GitLab From 1e75540ec5202cae63cd238c86bd880e3d496546 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0374/6080] ide-tape: remove back-to-back REQUEST_SENSE detection Impact: fix an oops which always triggers ide_tape_issue_pc() assumed drive->pc isn't NULL on invocation when checking for back-to-back request sense issues but drive->pc can be NULL and even when it's not NULL, it's not safe to dereference it once the previous command is complete because pc could have been freed or was on stack. Kill back-to-back REQUEST_SENSE detection. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index cb942a9b580f..3a53e0834cf7 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -614,12 +614,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, { idetape_tape_t *tape = drive->driver_data; - if (drive->pc->c[0] == REQUEST_SENSE && - pc->c[0] == REQUEST_SENSE) { - printk(KERN_ERR "ide-tape: possible ide-tape.c bug - " - "Two request sense in serial were issued\n"); - } - if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) drive->failed_pc = pc; -- GitLab From 853280a4dc8e3cc97ff10c1c02234d96078f437b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0375/6080] ide: use blk_run_queue() instead of blk_start_queueing() blk_start_queueing() is being phased out in favor of [__]blk_run_queue(). Switch. Signed-off-by: Tejun Heo --- drivers/ide/ide-park.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 310d03f2b5b7..a914023d6d03 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c @@ -24,11 +24,8 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) start_queue = 1; spin_unlock_irq(&hwif->lock); - if (start_queue) { - spin_lock_irq(q->queue_lock); - blk_start_queueing(q); - spin_unlock_irq(q->queue_lock); - } + if (start_queue) + blk_run_queue(q); return; } spin_unlock_irq(&hwif->lock); -- GitLab From 55f3f399422a4a3f6cb84ea4096dfaddf8817399 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0376/6080] ide: don't set REQ_SOFTBARRIER ide doesn't have to worry about REQ_SOFTBARRIER. Don't set it. Signed-off-by: Tejun Heo --- drivers/ide/ide-disk.c | 1 - drivers/ide/ide-ioctls.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index a9fbe2c31210..c2438804d3c4 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -411,7 +411,6 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) cmd->protocol = ATA_PROT_NODATA; rq->cmd_type = REQ_TYPE_ATA_TASKFILE; - rq->cmd_flags |= REQ_SOFTBARRIER; rq->special = cmd; } diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index c1c25ebbaa1f..5991b23793f2 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -231,7 +231,6 @@ static int generic_drive_reset(ide_drive_t *drive) rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_len = 1; rq->cmd[0] = REQ_DRIVE_RESET; - rq->cmd_flags |= REQ_SOFTBARRIER; if (blk_execute_rq(drive->queue, NULL, rq, 1)) ret = rq->errors; blk_put_request(rq); -- GitLab From 46a802e852c2106d755f697819ea80cd3ffdc222 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0377/6080] ide kill unused ide_cmd->special Impact: removal of unused field No one uses ide_cmd->special anymore. Kill it. Signed-off-by: Tejun Heo --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/ide.h b/include/linux/ide.h index ff65fffb078f..846a1e132407 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -324,7 +324,6 @@ struct ide_cmd { unsigned int cursg_ofs; struct request *rq; /* copy of request */ - void *special; /* valid_t generally */ }; /* ATAPI packet command flags */ -- GitLab From 1873b90cdea038715ec7140fccc2116fb930ffb5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0378/6080] ide-cd: clear sense buffer before issuing request sense Impact: code simplification ide_cd_request_sense_fixup() clears the tail of the sense buffer if the device didn't completely fill it. This patch makes cdrom_queue_request_sense() clear the sense buffer before issuing the command instead of clearing it afterwards. This simplifies code and eases future changes. Signed-off-by: Tejun Heo --- drivers/ide/ide-cd.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3aec19d1fdfc..509f1293cae2 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -217,6 +217,8 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, if (sense == NULL) sense = &info->sense_data; + memset(sense, 0, 18); + /* stuff the sense request in front of our current request */ blk_rq_init(NULL, rq); rq->cmd_type = REQ_TYPE_ATA_PC; @@ -504,14 +506,8 @@ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) * and some drives don't send them. Sigh. */ if (rq->cmd[0] == GPCMD_REQUEST_SENSE && - cmd->nleft > 0 && cmd->nleft <= 5) { - unsigned int ofs = cmd->nbytes - cmd->nleft; - - while (cmd->nleft > 0) { - *((u8 *)rq->data + ofs++) = 0; - cmd->nleft--; - } - } + cmd->nleft > 0 && cmd->nleft <= 5) + cmd->nleft = 0; } int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, -- GitLab From 7f006dc24fae158131116c9472874f12e16cf040 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0379/6080] ide-floppy: block pc always uses bio Impact: remove unnecessary code path Block pc requests always use bio and rq->data is always NULL. No need to worry about !rq->bio cases in idefloppy_block_pc_cmd(). Note that ide-atapi uses ide_pio_bytes() for bio PIO transfer which handle sg fine. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-floppy.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 2b4868d95f8b..3b22e066287e 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -216,15 +216,13 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, ide_init_pc(pc); memcpy(pc->c, rq->cmd, sizeof(pc->c)); pc->rq = rq; - if (rq->data_len && rq_data_dir(rq) == WRITE) - pc->flags |= PC_FLAG_WRITING; - pc->buf = rq->data; - if (rq->bio) + if (rq->data_len) { pc->flags |= PC_FLAG_DMA_OK; - /* - * possibly problematic, doesn't look like ide-floppy correctly - * handled scattered requests if dma fails... - */ + if (rq_data_dir(rq) == WRITE) + pc->flags |= PC_FLAG_WRITING; + } + /* pio will be performed by ide_pio_bytes() which handles sg fine */ + pc->buf = NULL; pc->req_xfer = pc->buf_size = rq->data_len; } -- GitLab From eace4cb04c0edc9388e987bf9bbdef461f6daca4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0380/6080] ide-taskfile: don't abuse rq->buffer Impact: rq->buffer usage cleanup ide_raw_taskfile() directly uses rq->buffer to carry pointer to the data buffer. This complicates both block interface and ide backend request handling. Use blk_rq_map_kern() instead and drop special handling for REQ_TYPE_ATA_TASKFILE from ide_map_sg(). Note that REQ_RW setting is moved upwards as blk_rq_map_kern() uses it to initialize bio rw flag. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-io.c | 5 +---- drivers/ide/ide-taskfile.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 35dc38d3b2c5..9b9e8b1aae5e 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -248,10 +248,7 @@ void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) struct scatterlist *sg = hwif->sg_table; struct request *rq = cmd->rq; - if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { - sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE); - cmd->sg_nents = 1; - } else if (!rq->bio) { + if (!rq->bio) { sg_init_one(sg, rq->data, rq->data_len); cmd->sg_nents = 1; } else diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 4aa6223c11be..f400eb4d4aff 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -424,7 +424,9 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_ATA_TASKFILE; - rq->buffer = buf; + + if (cmd->tf_flags & IDE_TFLAG_WRITE) + rq->cmd_flags |= REQ_RW; /* * (ks) We transfer currently only whole sectors. @@ -432,18 +434,20 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, * if we would find a solution to transfer any size. * To support special commands like READ LONG. */ - rq->hard_nr_sectors = rq->nr_sectors = nsect; - rq->hard_cur_sectors = rq->current_nr_sectors = nsect; - - if (cmd->tf_flags & IDE_TFLAG_WRITE) - rq->cmd_flags |= REQ_RW; + if (nsect) { + error = blk_rq_map_kern(drive->queue, rq, buf, + nsect * SECTOR_SIZE, __GFP_WAIT); + if (error) + goto put_req; + } rq->special = cmd; cmd->rq = rq; error = blk_execute_rq(drive->queue, NULL, rq, 0); - blk_put_request(rq); +put_req: + blk_put_request(rq); return error; } -- GitLab From c267cc1c4db4ccb3406d045a8da8660f0bbfe08d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0381/6080] ide-atapi: don't abuse rq->buffer Impact: rq->buffer usage cleanup ide-atapi uses rq->buffer as private opaque value for internal special requests. rq->special isn't used for these cases (the only case where rq->special is used is for ide-tape rw requests). Use rq->special instead. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-atapi.c | 4 ++-- drivers/ide/ide-floppy.c | 2 +- drivers/ide/ide-tape.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 7201b176d75b..2894577237ba 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -90,7 +90,7 @@ static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, blk_rq_init(NULL, rq); rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_flags |= REQ_PREEMPT; - rq->buffer = (char *)pc; + rq->special = (char *)pc; rq->rq_disk = disk; if (pc->req_xfer) { @@ -119,7 +119,7 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_SPECIAL; - rq->buffer = (char *)pc; + rq->special = (char *)pc; if (pc->req_xfer) { rq->data = pc->buf; diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 3b22e066287e..94600331a271 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -264,7 +264,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, pc = &floppy->queued_pc; idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); } else if (blk_special_request(rq)) { - pc = (struct ide_atapi_pc *) rq->buffer; + pc = (struct ide_atapi_pc *)rq->special; } else if (blk_pc_request(rq)) { pc = &floppy->queued_pc; idefloppy_blockpc_cmd(floppy, pc, rq); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 3a53e0834cf7..aadf53cfac6f 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -828,7 +828,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, goto out; } if (rq->cmd[13] & REQ_IDETAPE_PC1) { - pc = (struct ide_atapi_pc *) rq->buffer; + pc = (struct ide_atapi_pc *)rq->special; rq->cmd[13] &= ~(REQ_IDETAPE_PC1); rq->cmd[13] |= REQ_IDETAPE_PC2; goto out; -- GitLab From cbfd082abfcbed8c57a12636f36e9bead8d6cfc6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0382/6080] ide-cd: don't abuse rq->buffer Impact: rq->buffer usage cleanup ide-cd uses rq->buffer to carry pointer to the original request when issuing REQUEST_SENSE. Use rq->special instead. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-cd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 509f1293cae2..eb3c299d95de 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -232,8 +232,8 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, rq->cmd_type = REQ_TYPE_SENSE; rq->cmd_flags |= REQ_PREEMPT; - /* NOTE! Save the failed command in "rq->buffer" */ - rq->buffer = (void *) failed_command; + /* NOTE! Save the failed command in "rq->special" */ + rq->special = (void *)failed_command; if (failed_command) ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x", @@ -247,10 +247,10 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) { /* - * For REQ_TYPE_SENSE, "rq->buffer" points to the original + * For REQ_TYPE_SENSE, "rq->special" points to the original * failed request */ - struct request *failed = (struct request *)rq->buffer; + struct request *failed = (struct request *)rq->special; struct cdrom_info *info = drive->driver_data; void *sense = &info->sense_data; -- GitLab From a1df5169f9bf08f6067029bfb840a05e282b1b97 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0383/6080] ide: add helpers for preparing sense requests This is in preparation of removing the queueing of a sense request out of the IRQ handler path. Use struct request_sense as a general sense buffer for all ATAPI devices ide-{floppy,tape,cd}. tj: * blk_get_request(__GFP_WAIT) can't be called from do_request() as it can cause deadlock. Converted to use inline struct request and blk_rq_init(). * Added xfer / cdb len selection depending on device type. * All sense prep logics folded into ide_prep_sense() which never fails. * hwif->rq clearing and sense_rq used handling moved into ide_queue_sense_rq(). * blk_rq_map_kern() conversion is moved to later patch. CC: Bartlomiej Zolnierkiewicz CC: FUJITA Tomonori Signed-off-by: Borislav Petkov Signed-off-by: Tejun Heo --- drivers/ide/ide-atapi.c | 61 +++++++++++++++++++++++++++++++++++++++++ include/linux/ide.h | 11 ++++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 2894577237ba..c6e03485a63a 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -191,6 +191,67 @@ void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc) } EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd); +void ide_prep_sense(ide_drive_t *drive, struct request *rq) +{ + struct request_sense *sense = &drive->sense_data; + struct request *sense_rq = &drive->sense_rq; + unsigned int cmd_len, sense_len; + + debug_log("%s: enter\n", __func__); + + switch (drive->media) { + case ide_floppy: + cmd_len = 255; + sense_len = 18; + break; + case ide_tape: + cmd_len = 20; + sense_len = 20; + break; + default: + cmd_len = 18; + sense_len = 18; + } + + BUG_ON(sense_len > sizeof(*sense)); + + if (blk_sense_request(rq) || drive->sense_rq_armed) + return; + + memset(sense, 0, sizeof(*sense)); + + blk_rq_init(rq->q, sense_rq); + sense_rq->rq_disk = rq->rq_disk; + + sense_rq->data = sense; + sense_rq->cmd[0] = GPCMD_REQUEST_SENSE; + sense_rq->cmd[4] = cmd_len; + sense_rq->data_len = sense_len; + + sense_rq->cmd_type = REQ_TYPE_SENSE; + sense_rq->cmd_flags |= REQ_PREEMPT; + + if (drive->media == ide_tape) + sense_rq->cmd[13] = REQ_IDETAPE_PC1; + + drive->sense_rq_armed = true; +} +EXPORT_SYMBOL_GPL(ide_prep_sense); + +void ide_queue_sense_rq(ide_drive_t *drive, void *special) +{ + BUG_ON(!drive->sense_rq_armed); + + drive->sense_rq.special = special; + drive->sense_rq_armed = false; + + drive->hwif->rq = NULL; + + elv_add_request(drive->queue, &drive->sense_rq, + ELEVATOR_INSERT_FRONT, 0); +} +EXPORT_SYMBOL_GPL(ide_queue_sense_rq); + /* * Called when an error was detected during the last packet command. * We queue a request sense packet command in the head of the request list. diff --git a/include/linux/ide.h b/include/linux/ide.h index 846a1e132407..a69ccac56411 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -26,6 +26,9 @@ #include #include +/* for request_sense */ +#include + #if defined(CONFIG_CRIS) || defined(CONFIG_FRV) || defined(CONFIG_MN10300) # define SUPPORT_VLB_SYNC 0 #else @@ -602,6 +605,11 @@ struct ide_drive_s { struct ide_atapi_pc request_sense_pc; struct request request_sense_rq; + + /* current sense rq and buffer */ + bool sense_rq_armed; + struct request sense_rq; + struct request_sense sense_data; }; typedef struct ide_drive_s ide_drive_t; @@ -1175,6 +1183,9 @@ int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); void ide_retry_pc(ide_drive_t *, struct gendisk *); +void ide_prep_sense(ide_drive_t *drive, struct request *rq); +void ide_queue_sense_rq(ide_drive_t *drive, void *special); + int ide_cd_expiry(ide_drive_t *); int ide_cd_get_xferlen(struct request *); -- GitLab From 746d5e43274e9ea6cbd58818afc9239d41fb4e1e Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0384/6080] ide-cd: convert to using generic sense request Preallocate a sense request in the ->do_request method and reinitialize it only on demand, in case it's been consumed in the IRQ handler path. The reason for this is that we don't want to be mapping rq to bio in the IRQ path and introduce all kinds of unnecessary hacks to the block layer. tj: * Both user and kernel PC requests expect sense data to be stored in separate storage other than drive->sense_data. Copy sense data to rq->sense on completion if rq->sense is not NULL. This fixes bogus sense data on PC requests. As a result, remove cdrom_queue_request_sense. CC: Bartlomiej Zolnierkiewicz CC: FUJITA Tomonori Signed-off-by: Borislav Petkov Signed-off-by: Tejun Heo --- drivers/ide/ide-cd.c | 54 ++++++++++---------------------------------- drivers/ide/ide-cd.h | 4 ---- 2 files changed, 12 insertions(+), 46 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index eb3c299d95de..7b21c7eac5b0 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -206,44 +206,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, ide_cd_log_error(drive->name, failed_command, sense); } -static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, - struct request *failed_command) -{ - struct cdrom_info *info = drive->driver_data; - struct request *rq = &drive->request_sense_rq; - - ide_debug_log(IDE_DBG_SENSE, "enter"); - - if (sense == NULL) - sense = &info->sense_data; - - memset(sense, 0, 18); - - /* stuff the sense request in front of our current request */ - blk_rq_init(NULL, rq); - rq->cmd_type = REQ_TYPE_ATA_PC; - rq->rq_disk = info->disk; - - rq->data = sense; - rq->cmd[0] = GPCMD_REQUEST_SENSE; - rq->cmd[4] = 18; - rq->data_len = 18; - - rq->cmd_type = REQ_TYPE_SENSE; - rq->cmd_flags |= REQ_PREEMPT; - - /* NOTE! Save the failed command in "rq->special" */ - rq->special = (void *)failed_command; - - if (failed_command) - ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x", - failed_command->cmd[0]); - - drive->hwif->rq = NULL; - - elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); -} - static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) { /* @@ -251,11 +213,16 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) * failed request */ struct request *failed = (struct request *)rq->special; - struct cdrom_info *info = drive->driver_data; - void *sense = &info->sense_data; + struct request_sense *sense = &drive->sense_data; if (failed) { if (failed->sense) { + /* + * Sense is always read into drive->sense_data. + * Copy back if the failed request has its + * sense pointer set. + */ + memcpy(failed->sense, sense, 18); sense = failed->sense; failed->sense_len = rq->sense_len; } @@ -431,7 +398,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) /* if we got a CHECK_CONDITION status, queue a request sense command */ if (stat & ATA_ERR) - cdrom_queue_request_sense(drive, NULL, NULL); + ide_queue_sense_rq(drive, NULL); return 1; end_request: @@ -445,7 +412,7 @@ end_request: hwif->rq = NULL; - cdrom_queue_request_sense(drive, rq->sense, rq); + ide_queue_sense_rq(drive, rq); return 1; } else return 2; @@ -893,6 +860,9 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, goto out_end; } + /* prepare sense request for this command */ + ide_prep_sense(drive, rq); + memset(&cmd, 0, sizeof(cmd)); if (rq_data_dir(rq)) diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 1d97101099ce..93a3cf1b0f3f 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -87,10 +87,6 @@ struct cdrom_info { struct atapi_toc *toc; - /* The result of the last successful request sense command - on this device. */ - struct request_sense sense_data; - u8 max_speed; /* Max speed of the drive. */ u8 current_speed; /* Current speed of the drive. */ -- GitLab From 6b544fcc8cd0a04eb42de9d1ecdd345e979d6ada Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0385/6080] ide-atapi: convert ide-{floppy,tape} to using preallocated sense buffer Since we're issuing REQ_TYPE_SENSE now we need to allow those types of rqs in the ->do_request callbacks. As a future improvement, sense_len assignment might be unified across all ATAPI devices. Borislav to check with specs and test. As a result, get rid of ide_queue_pc_head() and drive->request_sense_rq. tj: * Init request sense ide_atapi_pc from sense request. In the longer timer, it would probably better to fold ide_create_request_sense_cmd() into its only current user - ide_floppy_get_format_progress(). * ide_retry_pc() no longer takes @disk. CC: Bartlomiej Zolnierkiewicz CC: FUJITA Tomonori Signed-off-by: Borislav Petkov Signed-off-by: Tejun Heo --- drivers/ide/ide-atapi.c | 48 ++++++++++++---------------------------- drivers/ide/ide-floppy.c | 4 +++- drivers/ide/ide-tape.c | 7 ++++-- include/linux/ide.h | 3 +-- 4 files changed, 23 insertions(+), 39 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index c6e03485a63a..972c522516f8 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -79,34 +79,6 @@ void ide_init_pc(struct ide_atapi_pc *pc) } EXPORT_SYMBOL_GPL(ide_init_pc); -/* - * Generate a new packet command request in front of the request queue, before - * the current request, so that it will be processed immediately, on the next - * pass through the driver. - */ -static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, - struct ide_atapi_pc *pc, struct request *rq) -{ - blk_rq_init(NULL, rq); - rq->cmd_type = REQ_TYPE_SPECIAL; - rq->cmd_flags |= REQ_PREEMPT; - rq->special = (char *)pc; - rq->rq_disk = disk; - - if (pc->req_xfer) { - rq->data = pc->buf; - rq->data_len = pc->req_xfer; - } - - memcpy(rq->cmd, pc->c, 12); - if (drive->media == ide_tape) - rq->cmd[13] = REQ_IDETAPE_PC1; - - drive->hwif->rq = NULL; - - elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); -} - /* * Add a special packet command request to the tail of the request queue, * and wait for it to be serviced. @@ -254,18 +226,26 @@ EXPORT_SYMBOL_GPL(ide_queue_sense_rq); /* * Called when an error was detected during the last packet command. - * We queue a request sense packet command in the head of the request list. + * We queue a request sense packet command at the head of the request + * queue. */ -void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) +void ide_retry_pc(ide_drive_t *drive) { - struct request *rq = &drive->request_sense_rq; + struct request *sense_rq = &drive->sense_rq; struct ide_atapi_pc *pc = &drive->request_sense_pc; (void)ide_read_error(drive); - ide_create_request_sense_cmd(drive, pc); + + /* init pc from sense_rq */ + ide_init_pc(pc); + memcpy(pc->c, sense_rq->cmd, 12); + pc->buf = sense_rq->data; + pc->req_xfer = sense_rq->data_len; + if (drive->media == ide_tape) set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - ide_queue_pc_head(drive, disk, pc, rq); + + ide_queue_sense_rq(drive, pc); } EXPORT_SYMBOL_GPL(ide_retry_pc); @@ -404,7 +384,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) debug_log("[cmd %x]: check condition\n", rq->cmd[0]); /* Retry operation */ - ide_retry_pc(drive, rq->rq_disk); + ide_retry_pc(drive); /* queued, but not started */ return ide_stopped; diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 94600331a271..d3302cc891e4 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -263,7 +263,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, } pc = &floppy->queued_pc; idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); - } else if (blk_special_request(rq)) { + } else if (blk_special_request(rq) || blk_sense_request(rq)) { pc = (struct ide_atapi_pc *)rq->special; } else if (blk_pc_request(rq)) { pc = &floppy->queued_pc; @@ -273,6 +273,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, goto out_end; } + ide_prep_sense(drive, rq); + memset(&cmd, 0, sizeof(cmd)); if (rq_data_dir(rq)) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index aadf53cfac6f..8324dfa78a3f 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -695,7 +695,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) printk(KERN_ERR "ide-tape: %s: I/O error, ", tape->name); /* Retry operation */ - ide_retry_pc(drive, tape->disk); + ide_retry_pc(drive); return ide_stopped; } pc->error = 0; @@ -752,7 +752,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, (unsigned long long)rq->sector, rq->nr_sectors, rq->current_nr_sectors); - if (!blk_special_request(rq)) { + if (!(blk_special_request(rq) || blk_sense_request(rq))) { /* We do not support buffer cache originated requests. */ printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " "request queue (%d)\n", drive->name, rq->cmd_type); @@ -840,6 +840,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, BUG(); out: + /* prepare sense request for this command */ + ide_prep_sense(drive, rq); + memset(&cmd, 0, sizeof(cmd)); if (rq_data_dir(rq)) diff --git a/include/linux/ide.h b/include/linux/ide.h index a69ccac56411..9e67ccac3c1f 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -604,7 +604,6 @@ struct ide_drive_s { unsigned long atapi_flags; struct ide_atapi_pc request_sense_pc; - struct request request_sense_rq; /* current sense rq and buffer */ bool sense_rq_armed; @@ -1181,7 +1180,7 @@ int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); -void ide_retry_pc(ide_drive_t *, struct gendisk *); +void ide_retry_pc(ide_drive_t *drive); void ide_prep_sense(ide_drive_t *drive, struct request *rq); void ide_queue_sense_rq(ide_drive_t *drive, void *special); -- GitLab From 5c4be57249e2e09136446597d2fe2a967c6ffef0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0386/6080] ide-cd,atapi: use bio for internal commands Impact: unify request data buffer handling rq->data is used mostly to pass kernel buffer through request queue without using bio. There are only a couple of places which still do this in kernel and converting to bio isn't difficult. This patch converts ide-cd and atapi to use bio instead of rq->data for request sense and internal pc commands. With previous change to unify sense request handling, this is relatively easily achieved by adding blk_rq_map_kern() during sense_rq prep and PC issue. If blk_rq_map_kern() fails for sense, the error is deferred till sense issue and aborts the failed command which triggered the sense. Note that this is a slim possibility as sense prep is done on each command issue, so for the above condition to actually trigger, all preps since the last sense issue till the issue of the request which would require a sense should fail. * do_request functions might sleep now. This should be okay as ide request_fn - do_ide_request() - is invoked only from make_request and plug work. Make sure this is the case by adding might_sleep() to do_ide_request(). * Functions which access the read sense data before the sense request is complete now should access bio_data(sense_rq->bio) as the sense buffer might have been copied during blk_rq_map_kern(). * ide-tape updated to map sg. * cdrom_do_block_pc() now doesn't have to deal with REQ_TYPE_ATA_PC special case. Simplified. * tp_ops->output/input_data path dropped from ide_pc_intr(). Signed-off-by: Tejun Heo --- drivers/ide/ide-atapi.c | 52 ++++++++++++++++++++++++----------------- drivers/ide/ide-cd.c | 28 +++++++++++----------- drivers/ide/ide-io.c | 3 +++ drivers/ide/ide-tape.c | 3 +++ include/linux/ide.h | 2 +- 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 972c522516f8..5cefe12f5622 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -94,16 +94,18 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, rq->special = (char *)pc; if (pc->req_xfer) { - rq->data = pc->buf; - rq->data_len = pc->req_xfer; + error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer, + GFP_NOIO); + if (error) + goto put_req; } memcpy(rq->cmd, pc->c, 12); if (drive->media == ide_tape) rq->cmd[13] = REQ_IDETAPE_PC1; error = blk_execute_rq(drive->queue, disk, rq, 0); +put_req: blk_put_request(rq); - return error; } EXPORT_SYMBOL_GPL(ide_queue_pc_tail); @@ -168,6 +170,7 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) struct request_sense *sense = &drive->sense_data; struct request *sense_rq = &drive->sense_rq; unsigned int cmd_len, sense_len; + int err; debug_log("%s: enter\n", __func__); @@ -193,13 +196,19 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) memset(sense, 0, sizeof(*sense)); blk_rq_init(rq->q, sense_rq); - sense_rq->rq_disk = rq->rq_disk; - sense_rq->data = sense; + err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len, + GFP_NOIO); + if (unlikely(err)) { + if (printk_ratelimit()) + printk(KERN_WARNING "%s: failed to map sense buffer\n", + drive->name); + return; + } + + sense_rq->rq_disk = rq->rq_disk; sense_rq->cmd[0] = GPCMD_REQUEST_SENSE; sense_rq->cmd[4] = cmd_len; - sense_rq->data_len = sense_len; - sense_rq->cmd_type = REQ_TYPE_SENSE; sense_rq->cmd_flags |= REQ_PREEMPT; @@ -210,9 +219,14 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) } EXPORT_SYMBOL_GPL(ide_prep_sense); -void ide_queue_sense_rq(ide_drive_t *drive, void *special) +int ide_queue_sense_rq(ide_drive_t *drive, void *special) { - BUG_ON(!drive->sense_rq_armed); + /* deferred failure from ide_prep_sense() */ + if (!drive->sense_rq_armed) { + printk(KERN_WARNING "%s: failed queue sense request\n", + drive->name); + return -ENOMEM; + } drive->sense_rq.special = special; drive->sense_rq_armed = false; @@ -221,6 +235,7 @@ void ide_queue_sense_rq(ide_drive_t *drive, void *special) elv_add_request(drive->queue, &drive->sense_rq, ELEVATOR_INSERT_FRONT, 0); + return 0; } EXPORT_SYMBOL_GPL(ide_queue_sense_rq); @@ -239,13 +254,14 @@ void ide_retry_pc(ide_drive_t *drive) /* init pc from sense_rq */ ide_init_pc(pc); memcpy(pc->c, sense_rq->cmd, 12); - pc->buf = sense_rq->data; + pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */ pc->req_xfer = sense_rq->data_len; if (drive->media == ide_tape) set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - ide_queue_sense_rq(drive, pc); + if (ide_queue_sense_rq(drive, pc)) + ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); } EXPORT_SYMBOL_GPL(ide_retry_pc); @@ -317,7 +333,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) struct ide_cmd *cmd = &hwif->cmd; struct request *rq = hwif->rq; const struct ide_tp_ops *tp_ops = hwif->tp_ops; - xfer_func_t *xferfunc; unsigned int timeout, done; u16 bcount; u8 stat, ireason, dsc = 0; @@ -411,7 +426,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) rq->errors = -EIO; } - if (drive->media == ide_tape) + if (drive->media == ide_tape && !rq->bio) done = ide_rq_bytes(rq); /* FIXME */ else done = blk_rq_bytes(rq); @@ -448,16 +463,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) return ide_do_reset(drive); } - xferfunc = write ? tp_ops->output_data : tp_ops->input_data; - - if (drive->media == ide_floppy && pc->buf == NULL) { + if (drive->media == ide_tape && pc->bh) + done = drive->pc_io_buffers(drive, pc, bcount, write); + else { done = min_t(unsigned int, bcount, cmd->nleft); ide_pio_bytes(drive, cmd, write, done); - } else if (drive->media == ide_tape && pc->bh) { - done = drive->pc_io_buffers(drive, pc, bcount, write); - } else { - done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred); - xferfunc(drive, NULL, pc->cur_pos, done); } /* Update the current position */ diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 7b21c7eac5b0..392a5bdf2fd3 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -210,10 +210,12 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) { /* * For REQ_TYPE_SENSE, "rq->special" points to the original - * failed request + * failed request. Also, the sense data should be read + * directly from rq which might be different from the original + * sense buffer if it got copied during mapping. */ struct request *failed = (struct request *)rq->special; - struct request_sense *sense = &drive->sense_data; + void *sense = bio_data(rq->bio); if (failed) { if (failed->sense) { @@ -398,7 +400,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) /* if we got a CHECK_CONDITION status, queue a request sense command */ if (stat & ATA_ERR) - ide_queue_sense_rq(drive, NULL); + return ide_queue_sense_rq(drive, NULL) ? 2 : 1; return 1; end_request: @@ -412,8 +414,7 @@ end_request: hwif->rq = NULL; - ide_queue_sense_rq(drive, rq); - return 1; + return ide_queue_sense_rq(drive, rq) ? 2 : 1; } else return 2; } @@ -507,8 +508,12 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, rq->cmd_flags |= cmd_flags; rq->timeout = timeout; if (buffer) { - rq->data = buffer; - rq->data_len = *bufflen; + error = blk_rq_map_kern(drive->queue, rq, buffer, + *bufflen, GFP_NOIO); + if (error) { + blk_put_request(rq); + return error; + } } error = blk_execute_rq(drive->queue, info->disk, rq, 0); @@ -802,15 +807,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) drive->dma = 0; /* sg request */ - if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) { + if (rq->bio) { struct request_queue *q = drive->queue; + char *buf = bio_data(rq->bio); unsigned int alignment; - char *buf; - - if (rq->bio) - buf = bio_data(rq->bio); - else - buf = rq->data; drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 9b9e8b1aae5e..3245c2dbda33 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -481,6 +481,9 @@ void do_ide_request(struct request_queue *q) spin_unlock_irq(q->queue_lock); + /* HLD do_request() callback might sleep, make sure it's okay */ + might_sleep(); + if (ide_lock_host(host, hwif)) goto plug_device_2; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8324dfa78a3f..9b762a2d5d95 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -850,6 +850,9 @@ out: cmd.rq = rq; + ide_init_sg_cmd(&cmd, pc->req_xfer); + ide_map_sg(drive, &cmd); + return ide_tape_issue_pc(drive, &cmd, pc); } diff --git a/include/linux/ide.h b/include/linux/ide.h index 9e67ccac3c1f..1957461ac762 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1183,7 +1183,7 @@ void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); void ide_retry_pc(ide_drive_t *drive); void ide_prep_sense(ide_drive_t *drive, struct request *rq); -void ide_queue_sense_rq(ide_drive_t *drive, void *special); +int ide_queue_sense_rq(ide_drive_t *drive, void *special); int ide_cd_expiry(ide_drive_t *); -- GitLab From fc38b521dcffcb07447cd98fedc56f495c10b90d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:43 +0900 Subject: [PATCH 0387/6080] ide-pm: don't abuse rq->data Impact: cleanup rq->data usage ide-pm uses rq->data to carry pointer to struct request_pm_state through request queue and rq->special is used to carray pointer to local struct ide_cmd, which isn't necessary. Use rq->special for request_pm_state instead and use local ide_cmd in ide_start_power_step(). Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-io.c | 2 +- drivers/ide/ide-pm.c | 38 +++++++++++++++----------------------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 3245c2dbda33..6e3094e22775 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -368,7 +368,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) return execute_drive_cmd(drive, rq); else if (blk_pm_request(rq)) { - struct request_pm_state *pm = rq->data; + struct request_pm_state *pm = rq->special; #ifdef DEBUG_PM printk("%s: start_power_step(step: %d)\n", drive->name, pm->pm_step); diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index 0d8a151c0a01..ba1488bd8430 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c @@ -7,7 +7,6 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; - struct ide_cmd cmd; int ret; /* call ACPI _GTM only once */ @@ -15,11 +14,9 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ide_acpi_get_timing(hwif); memset(&rqpm, 0, sizeof(rqpm)); - memset(&cmd, 0, sizeof(cmd)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_SUSPEND; - rq->special = &cmd; - rq->data = &rqpm; + rq->special = &rqpm; rqpm.pm_step = IDE_PM_START_SUSPEND; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; @@ -41,7 +38,6 @@ int generic_ide_resume(struct device *dev) ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; - struct ide_cmd cmd; int err; /* call ACPI _PS0 / _STM only once */ @@ -53,12 +49,10 @@ int generic_ide_resume(struct device *dev) ide_acpi_exec_tfs(drive); memset(&rqpm, 0, sizeof(rqpm)); - memset(&cmd, 0, sizeof(cmd)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_RESUME; rq->cmd_flags |= REQ_PREEMPT; - rq->special = &cmd; - rq->data = &rqpm; + rq->special = &rqpm; rqpm.pm_step = IDE_PM_START_RESUME; rqpm.pm_state = PM_EVENT_ON; @@ -77,7 +71,7 @@ int generic_ide_resume(struct device *dev) void ide_complete_power_step(ide_drive_t *drive, struct request *rq) { - struct request_pm_state *pm = rq->data; + struct request_pm_state *pm = rq->special; #ifdef DEBUG_PM printk(KERN_INFO "%s: complete_power_step(step: %d)\n", @@ -107,10 +101,8 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq) ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) { - struct request_pm_state *pm = rq->data; - struct ide_cmd *cmd = rq->special; - - memset(cmd, 0, sizeof(*cmd)); + struct request_pm_state *pm = rq->special; + struct ide_cmd cmd = { }; switch (pm->pm_step) { case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ @@ -123,12 +115,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) return ide_stopped; } if (ata_id_flush_ext_enabled(drive->id)) - cmd->tf.command = ATA_CMD_FLUSH_EXT; + cmd.tf.command = ATA_CMD_FLUSH_EXT; else - cmd->tf.command = ATA_CMD_FLUSH; + cmd.tf.command = ATA_CMD_FLUSH; goto out_do_tf; case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ - cmd->tf.command = ATA_CMD_STANDBYNOW1; + cmd.tf.command = ATA_CMD_STANDBYNOW1; goto out_do_tf; case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ ide_set_max_pio(drive); @@ -141,7 +133,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) ide_complete_power_step(drive, rq); return ide_stopped; case IDE_PM_IDLE: /* Resume step 2 (idle) */ - cmd->tf.command = ATA_CMD_IDLEIMMEDIATE; + cmd.tf.command = ATA_CMD_IDLEIMMEDIATE; goto out_do_tf; case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ /* @@ -163,11 +155,11 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) return ide_stopped; out_do_tf: - cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; - cmd->valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; - cmd->protocol = ATA_PROT_NODATA; + cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; + cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; + cmd.protocol = ATA_PROT_NODATA; - return do_rw_taskfile(drive, cmd); + return do_rw_taskfile(drive, &cmd); } /** @@ -181,7 +173,7 @@ out_do_tf: void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) { struct request_queue *q = drive->queue; - struct request_pm_state *pm = rq->data; + struct request_pm_state *pm = rq->special; unsigned long flags; ide_complete_power_step(drive, rq); @@ -207,7 +199,7 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) void ide_check_pm_state(ide_drive_t *drive, struct request *rq) { - struct request_pm_state *pm = rq->data; + struct request_pm_state *pm = rq->special; if (blk_pm_suspend_request(rq) && pm->pm_step == IDE_PM_START_SUSPEND) -- GitLab From ea7066afcd590e4663e6dc010f93704164050f48 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0388/6080] ide-tape,floppy: fix failed command completion after request sense Impact: fix infinite retry loop After a command failed, ide-tape and floppy inserts REQUEST_SENSE in front of the failed command and according to the result, sets pc->retries, flags and errors. After REQUEST_SENSE is complete, the failed command is again at the front of the queue and if the verdict was to terminate the request, the issue functions tries to complete it directly by calling drive->pc_callback() and returning ide_stopped. However, drive->pc_callback() doesn't complete a request. It only prepares for completion of the request. As a result, this creates an infinite loop where the failed request is retried perpetually. Fix it by actually ending the request by calling ide_complete_rq(). Signed-off-by: Tejun Heo --- drivers/ide/ide-floppy.c | 1 + drivers/ide/ide-tape.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index d3302cc891e4..d20704ac3183 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -141,6 +141,7 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, drive->failed_pc = NULL; drive->pc_callback(drive, 0); + ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); return ide_stopped; } diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 9b762a2d5d95..2b9a13671c5f 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -643,6 +643,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, } drive->failed_pc = NULL; drive->pc_callback(drive, 0); + ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); -- GitLab From b3071d190d6757b14af002a9d79832f12de61bce Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0389/6080] ide-atapi,tape,floppy: allow ->pc_callback() to change rq->data_len Impact: allow residual count implementation in ->pc_callback() rq->data_len has two duties - carrying the number of input bytes on issue and carrying residual count back to the issuer on completion. ide-atapi completion callback ->pc_callback() is the right place to do this but currently ide-atapi depends on rq->data_len carrying the original request size after calling ->pc_callback() to complete the pc request. This patch makes ide_pc_intr(), ide_tape_issue_pc() and ide_floppy_issue_pc() cache length to complete before calling ->pc_callback() so that it can modify rq->data_len as necessary. Note: As using rq->data_len for two purposes can make cases like this incorrect in subtle ways, future changes will introduce separate field for residual count. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-atapi.c | 16 ++++++++++------ drivers/ide/ide-floppy.c | 5 ++++- drivers/ide/ide-tape.c | 5 ++++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 5cefe12f5622..3df5442de710 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -409,6 +409,16 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) dsc = 1; + /* + * ->pc_callback() might change rq->data_len for + * residual count, cache total length. + */ + if (!blk_special_request(rq) && + (drive->media == ide_tape && !rq->bio)) + done = ide_rq_bytes(rq); /* FIXME */ + else + done = blk_rq_bytes(rq); + /* Command finished - Call the callback function */ uptodate = drive->pc_callback(drive, dsc); @@ -417,7 +427,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if (blk_special_request(rq)) { rq->errors = 0; - done = blk_rq_bytes(rq); error = 0; } else { @@ -426,11 +435,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) rq->errors = -EIO; } - if (drive->media == ide_tape && !rq->bio) - done = ide_rq_bytes(rq); /* FIXME */ - else - done = blk_rq_bytes(rq); - error = uptodate ? 0 : -EIO; } diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index d20704ac3183..537b7c558033 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -134,14 +134,17 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, drive->pc = pc; if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { + unsigned int done = blk_rq_bytes(drive->hwif->rq); + if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) ide_floppy_report_error(floppy, pc); + /* Giving up */ pc->error = IDE_DRV_ERROR_GENERAL; drive->failed_pc = NULL; drive->pc_callback(drive, 0); - ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); + ide_complete_rq(drive, -EIO, done); return ide_stopped; } diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2b9a13671c5f..8226d52504d0 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -622,6 +622,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, if (pc->retries > IDETAPE_MAX_PC_RETRIES || (pc->flags & PC_FLAG_ABORT)) { + unsigned int done = blk_rq_bytes(drive->hwif->rq); + /* * We will "abort" retrying a packet command in case legitimate * error code was received (crossing a filemark, or end of the @@ -641,9 +643,10 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, /* Giving up */ pc->error = IDE_DRV_ERROR_GENERAL; } + drive->failed_pc = NULL; drive->pc_callback(drive, 0); - ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); + ide_complete_rq(drive, -EIO, done); return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); -- GitLab From 35ab8d3251833e4052aa64b09b08195e949518c7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0390/6080] ide-tape: use single continuous buffer Impact: simpler buffer allocation and handling, kills OOM, fix DMA transfers ide-tape has its own multiple buffer mechanism using struct idetape_bh. It allocates buffer with decreasing order-of-two allocations so that it results in minimum number of segments. However, the implementation is quite complex and works in a way that no other block or ide driver works necessitating a lot of special case handling. The benefit this complex allocation scheme brings is questionable as PIO or DMA the number of segments (16 maximum) doesn't make any noticeable difference and it also doesn't negate the need for multiple order allocation which can fail under memory pressure or high fragmentation although it does lower the highest order necessary by one when the buffer size isn't power of two. As the first step to remove the custom buffer management, this patch makes ide-tape allocate single continous buffer. The maximum order is four. I doubt the change would cause any trouble but if it ever matters, it should be converted to regular sg mechanism like everyone else and even in that case dropping custom buffer handling and moving to standard mechanism first make sense as an intermediate step. This patch makes the first bh to contain the whole buffer and drops multi bh handling code. Following patches will make further changes. This patch has the side effect of killing OOM triggered by allocation path and fixing DMA transfers. Previously, bug in alloc path triggered OOM on command issue and commands were passed to DMA engine without DMA-mapping all the segments. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 256 ++++++++++------------------------------- 1 file changed, 58 insertions(+), 198 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8226d52504d0..b2afbc7bcb6b 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -134,7 +134,6 @@ enum { struct idetape_bh { u32 b_size; atomic_t b_count; - struct idetape_bh *b_reqnext; char *b_data; }; @@ -228,10 +227,6 @@ typedef struct ide_tape_obj { char *b_data; int b_count; - int pages_per_buffer; - /* Wasted space in each stage */ - int excess_bh_size; - /* Measures average tape speed */ unsigned long avg_time; int avg_size; @@ -303,9 +298,7 @@ static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, struct idetape_bh *bh = pc->bh; int count; - while (bcount) { - if (bh == NULL) - break; + if (bcount && bh) { count = min( (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), bcount); @@ -313,15 +306,10 @@ static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, atomic_read(&bh->b_count), count); bcount -= count; atomic_add(count, &bh->b_count); - if (atomic_read(&bh->b_count) == bh->b_size) { - bh = bh->b_reqnext; - if (bh) - atomic_set(&bh->b_count, 0); - } + if (atomic_read(&bh->b_count) == bh->b_size) + pc->bh = NULL; } - pc->bh = bh; - return bcount; } @@ -331,22 +319,14 @@ static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, struct idetape_bh *bh = pc->bh; int count; - while (bcount) { - if (bh == NULL) - break; + if (bcount && bh) { count = min((unsigned int)pc->b_count, (unsigned int)bcount); drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count); bcount -= count; pc->b_data += count; pc->b_count -= count; - if (!pc->b_count) { - bh = bh->b_reqnext; - pc->bh = bh; - if (bh) { - pc->b_data = bh->b_data; - pc->b_count = atomic_read(&bh->b_count); - } - } + if (!pc->b_count) + pc->bh = NULL; } return bcount; @@ -355,24 +335,20 @@ static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) { struct idetape_bh *bh = pc->bh; - int count; unsigned int bcount = pc->xferred; if (pc->flags & PC_FLAG_WRITING) return; - while (bcount) { - if (bh == NULL) { + if (bcount) { + if (bh == NULL || bcount > bh->b_size) { printk(KERN_ERR "ide-tape: bh == NULL in %s\n", __func__); return; } - count = min((unsigned int)bh->b_size, (unsigned int)bcount); - atomic_set(&bh->b_count, count); + atomic_set(&bh->b_count, bcount); if (atomic_read(&bh->b_count) == bh->b_size) - bh = bh->b_reqnext; - bcount -= count; + pc->bh = NULL; } - pc->bh = bh; } /* @@ -439,24 +415,10 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) /* Free data buffers completely. */ static void ide_tape_kfree_buffer(idetape_tape_t *tape) { - struct idetape_bh *prev_bh, *bh = tape->merge_bh; - - while (bh) { - u32 size = bh->b_size; - - while (size) { - unsigned int order = fls(size >> PAGE_SHIFT)-1; - - if (bh->b_data) - free_pages((unsigned long)bh->b_data, order); + struct idetape_bh *bh = tape->merge_bh; - size &= (order-1); - bh->b_data += (1 << order) * PAGE_SIZE; - } - prev_bh = bh; - bh = bh->b_reqnext; - kfree(prev_bh); - } + kfree(bh->b_data); + kfree(bh); } static void ide_tape_handle_dsc(ide_drive_t *); @@ -861,117 +823,50 @@ out: } /* - * The function below uses __get_free_pages to allocate a data buffer of size - * tape->buffer_size (or a bit more). We attempt to combine sequential pages as - * much as possible. - * - * It returns a pointer to the newly allocated buffer, or NULL in case of - * failure. + * It returns a pointer to the newly allocated buffer, or NULL in case + * of failure. */ static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape, - int full, int clear) -{ - struct idetape_bh *prev_bh, *bh, *merge_bh; - int pages = tape->pages_per_buffer; - unsigned int order, b_allocd; - char *b_data = NULL; - - merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); - bh = merge_bh; - if (bh == NULL) - goto abort; - - order = fls(pages) - 1; - bh->b_data = (char *) __get_free_pages(GFP_KERNEL, order); - if (!bh->b_data) - goto abort; - b_allocd = (1 << order) * PAGE_SIZE; - pages &= (order-1); - - if (clear) - memset(bh->b_data, 0, b_allocd); - bh->b_reqnext = NULL; - bh->b_size = b_allocd; - atomic_set(&bh->b_count, full ? bh->b_size : 0); + int full) +{ + struct idetape_bh *bh; - while (pages) { - order = fls(pages) - 1; - b_data = (char *) __get_free_pages(GFP_KERNEL, order); - if (!b_data) - goto abort; - b_allocd = (1 << order) * PAGE_SIZE; - - if (clear) - memset(b_data, 0, b_allocd); - - /* newly allocated page frames below buffer header or ...*/ - if (bh->b_data == b_data + b_allocd) { - bh->b_size += b_allocd; - bh->b_data -= b_allocd; - if (full) - atomic_add(b_allocd, &bh->b_count); - continue; - } - /* they are above the header */ - if (b_data == bh->b_data + bh->b_size) { - bh->b_size += b_allocd; - if (full) - atomic_add(b_allocd, &bh->b_count); - continue; - } - prev_bh = bh; - bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); - if (!bh) { - free_pages((unsigned long) b_data, order); - goto abort; - } - bh->b_reqnext = NULL; - bh->b_data = b_data; - bh->b_size = b_allocd; - atomic_set(&bh->b_count, full ? bh->b_size : 0); - prev_bh->b_reqnext = bh; + bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); + if (!bh) + return NULL; - pages &= (order-1); + bh->b_data = kmalloc(tape->buffer_size, GFP_KERNEL); + if (!bh->b_data) { + kfree(bh); + return NULL; } - bh->b_size -= tape->excess_bh_size; - if (full) - atomic_sub(tape->excess_bh_size, &bh->b_count); - return merge_bh; -abort: - ide_tape_kfree_buffer(tape); - return NULL; + bh->b_size = tape->buffer_size; + atomic_set(&bh->b_count, full ? bh->b_size : 0); + + return bh; } static int idetape_copy_stage_from_user(idetape_tape_t *tape, const char __user *buf, int n) { struct idetape_bh *bh = tape->bh; - int count; int ret = 0; - while (n) { - if (bh == NULL) { + if (n) { + if (bh == NULL || n > bh->b_size - atomic_read(&bh->b_count)) { printk(KERN_ERR "ide-tape: bh == NULL in %s\n", __func__); return 1; } - count = min((unsigned int) - (bh->b_size - atomic_read(&bh->b_count)), - (unsigned int)n); if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, - count)) + n)) ret = 1; - n -= count; - atomic_add(count, &bh->b_count); - buf += count; - if (atomic_read(&bh->b_count) == bh->b_size) { - bh = bh->b_reqnext; - if (bh) - atomic_set(&bh->b_count, 0); - } + atomic_add(n, &bh->b_count); + if (atomic_read(&bh->b_count) == bh->b_size) + tape->bh = NULL; } - tape->bh = bh; + return ret; } @@ -979,30 +874,20 @@ static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf, int n) { struct idetape_bh *bh = tape->bh; - int count; int ret = 0; - while (n) { - if (bh == NULL) { + if (n) { + if (bh == NULL || n > tape->b_count) { printk(KERN_ERR "ide-tape: bh == NULL in %s\n", __func__); return 1; } - count = min(tape->b_count, n); - if (copy_to_user(buf, tape->b_data, count)) + if (copy_to_user(buf, tape->b_data, n)) ret = 1; - n -= count; - tape->b_data += count; - tape->b_count -= count; - buf += count; - if (!tape->b_count) { - bh = bh->b_reqnext; - tape->bh = bh; - if (bh) { - tape->b_data = bh->b_data; - tape->b_count = atomic_read(&bh->b_count); - } - } + tape->b_data += n; + tape->b_count -= n; + if (!tape->b_count) + tape->bh = NULL; } return ret; } @@ -1254,7 +1139,7 @@ static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) static void ide_tape_flush_merge_buffer(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; - int blocks, min; + int blocks; struct idetape_bh *bh; if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { @@ -1269,31 +1154,16 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) if (tape->merge_bh_size) { blocks = tape->merge_bh_size / tape->blk_size; if (tape->merge_bh_size % tape->blk_size) { - unsigned int i; - + unsigned int i = tape->blk_size - + tape->merge_bh_size % tape->blk_size; blocks++; - i = tape->blk_size - tape->merge_bh_size % - tape->blk_size; - bh = tape->bh->b_reqnext; - while (bh) { - atomic_set(&bh->b_count, 0); - bh = bh->b_reqnext; - } bh = tape->bh; - while (i) { - if (bh == NULL) { - printk(KERN_INFO "ide-tape: bug," - " bh NULL\n"); - break; - } - min = min(i, (unsigned int)(bh->b_size - - atomic_read(&bh->b_count))); + if (bh) { memset(bh->b_data + atomic_read(&bh->b_count), - 0, min); - atomic_add(min, &bh->b_count); - i -= min; - bh = bh->b_reqnext; - } + 0, i); + atomic_add(i, &bh->b_count); + } else + printk(KERN_INFO "ide-tape: bug, bh NULL\n"); } (void) idetape_add_chrdev_write_request(drive, blocks); tape->merge_bh_size = 0; @@ -1321,7 +1191,7 @@ static int idetape_init_read(ide_drive_t *drive) " 0 now\n"); tape->merge_bh_size = 0; } - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0); + tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0); if (!tape->merge_bh) return -ENOMEM; tape->chrdev_dir = IDETAPE_DIR_READ; @@ -1368,23 +1238,18 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) static void idetape_pad_zeros(ide_drive_t *drive, int bcount) { idetape_tape_t *tape = drive->driver_data; - struct idetape_bh *bh; + struct idetape_bh *bh = tape->merge_bh; int blocks; while (bcount) { unsigned int count; - bh = tape->merge_bh; count = min(tape->buffer_size, bcount); bcount -= count; blocks = count / tape->blk_size; - while (count) { - atomic_set(&bh->b_count, - min(count, (unsigned int)bh->b_size)); - memset(bh->b_data, 0, atomic_read(&bh->b_count)); - count -= atomic_read(&bh->b_count); - bh = bh->b_reqnext; - } + atomic_set(&bh->b_count, count); + memset(bh->b_data, 0, atomic_read(&bh->b_count)); + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, tape->merge_bh); } @@ -1596,7 +1461,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, "should be 0 now\n"); tape->merge_bh_size = 0; } - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0); + tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0); if (!tape->merge_bh) return -ENOMEM; tape->chrdev_dir = IDETAPE_DIR_WRITE; @@ -1970,7 +1835,7 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) idetape_tape_t *tape = drive->driver_data; ide_tape_flush_merge_buffer(drive); - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0); + tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1); if (tape->merge_bh != NULL) { idetape_pad_zeros(drive, tape->blk_size * (tape->user_bs_factor - 1)); @@ -2201,11 +2066,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) tape->buffer_size = *ctl * tape->blk_size; } buffer_size = tape->buffer_size; - tape->pages_per_buffer = buffer_size / PAGE_SIZE; - if (buffer_size % PAGE_SIZE) { - tape->pages_per_buffer++; - tape->excess_bh_size = PAGE_SIZE - buffer_size % PAGE_SIZE; - } /* select the "best" DSC read/write polling freq */ speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]); -- GitLab From 21d9c5d227593d15630ae83a336d1519653e9b8a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0391/6080] ide-tape: use standard data transfer mechanism Impact: use standard way to transfer data ide-tape uses rq in an interesting way. For r/w requests, rq->special is used to carry a private buffer management structure idetape_bh and rq->nr_sectors and current_nr_sectors are initialized to the number of idetape blocks which isn't necessary 512 bytes. Also, rq->current_nr_sectors is used to report back the residual count in units of idetape blocks. This peculiarity taxes both block layer and ide. ide-atapi has different paths and hooks to accomodate it and what a rq means becomes quite confusing and making changes at the block layer becomes quite difficult and error-prone. This patch makes ide-tape use bio instead. With the previous patch, ide-tape currently is using single contiguos buffer so replacing it isn't difficult. Data buffer is mapped into bio using blk_rq_map_kern() in idetape_queue_rw_tail(). idetape_io_buffers() and idetape_update_buffers() are dropped and pc->bh is set to null to tell ide-atapi to use standard data transfer mechanism and idetape_bh byte counts are updated by the issuer on completion using the residual count. This change also nicely removes the FIXME in ide_pc_intr() where ide-tape rqs need to be completed using ide_rq_bytes() instead of blk_rq_bytes() (although this didn't really matter as the request didn't have bio). Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-atapi.c | 6 +-- drivers/ide/ide-tape.c | 112 +++++++++------------------------------- 2 files changed, 24 insertions(+), 94 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 3df5442de710..b9dd4503cbc7 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -413,11 +413,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) * ->pc_callback() might change rq->data_len for * residual count, cache total length. */ - if (!blk_special_request(rq) && - (drive->media == ide_tape && !rq->bio)) - done = ide_rq_bytes(rq); /* FIXME */ - else - done = blk_rq_bytes(rq); + done = blk_rq_bytes(rq); /* Command finished - Call the callback function */ uptodate = drive->pc_callback(drive, dsc); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b2afbc7bcb6b..b373ac876352 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -292,65 +292,6 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) return tape; } -static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount) -{ - struct idetape_bh *bh = pc->bh; - int count; - - if (bcount && bh) { - count = min( - (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), - bcount); - drive->hwif->tp_ops->input_data(drive, NULL, bh->b_data + - atomic_read(&bh->b_count), count); - bcount -= count; - atomic_add(count, &bh->b_count); - if (atomic_read(&bh->b_count) == bh->b_size) - pc->bh = NULL; - } - - return bcount; -} - -static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount) -{ - struct idetape_bh *bh = pc->bh; - int count; - - if (bcount && bh) { - count = min((unsigned int)pc->b_count, (unsigned int)bcount); - drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count); - bcount -= count; - pc->b_data += count; - pc->b_count -= count; - if (!pc->b_count) - pc->bh = NULL; - } - - return bcount; -} - -static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) -{ - struct idetape_bh *bh = pc->bh; - unsigned int bcount = pc->xferred; - - if (pc->flags & PC_FLAG_WRITING) - return; - if (bcount) { - if (bh == NULL || bcount > bh->b_size) { - printk(KERN_ERR "ide-tape: bh == NULL in %s\n", - __func__); - return; - } - atomic_set(&bh->b_count, bcount); - if (atomic_read(&bh->b_count) == bh->b_size) - pc->bh = NULL; - } -} - /* * called on each failed packet command retry to analyze the request sense. We * currently do not utilize this information. @@ -368,12 +309,10 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) pc->c[0], tape->sense_key, tape->asc, tape->ascq); /* Correct pc->xferred by asking the tape. */ - if (pc->flags & PC_FLAG_DMA_ERROR) { + if (pc->flags & PC_FLAG_DMA_ERROR) pc->xferred = pc->req_xfer - tape->blk_size * get_unaligned_be32(&sense[3]); - idetape_update_buffers(drive, pc); - } /* * If error was the result of a zero-length read or write command, @@ -458,7 +397,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) } tape->first_frame += blocks; - rq->current_nr_sectors -= blocks; + rq->data_len -= blocks * tape->blk_size; if (pc->error) { uptodate = 0; @@ -520,19 +459,6 @@ static void ide_tape_handle_dsc(ide_drive_t *drive) idetape_postpone_request(drive); } -static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount, int write) -{ - unsigned int bleft; - - if (write) - bleft = idetape_output_buffers(drive, pc, bcount); - else - bleft = idetape_input_buffers(drive, pc, bcount); - - return bcount - bleft; -} - /* * Packet Command Interface * @@ -683,7 +609,7 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, ide_init_pc(pc); put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; - pc->bh = bh; + pc->bh = NULL; pc->buf = NULL; pc->buf_size = length * tape->blk_size; pc->req_xfer = pc->buf_size; @@ -1063,10 +989,12 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct idetape_bh *bh) { idetape_tape_t *tape = drive->driver_data; + size_t size = blocks * tape->blk_size; struct request *rq; - int ret, errors; + int ret; debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); + BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_SPECIAL; @@ -1074,21 +1002,29 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, rq->rq_disk = tape->disk; rq->special = (void *)bh; rq->sector = tape->first_frame; - rq->nr_sectors = blocks; - rq->current_nr_sectors = blocks; + + if (size) { + ret = blk_rq_map_kern(drive->queue, rq, bh->b_data, size, + __GFP_WAIT); + if (ret) + goto out_put; + } + blk_execute_rq(drive->queue, tape->disk, rq, 0); - errors = rq->errors; - ret = tape->blk_size * (blocks - rq->current_nr_sectors); - blk_put_request(rq); + /* calculate the number of transferred bytes and update bh */ + size -= rq->data_len; + if (cmd == REQ_IDETAPE_READ) + atomic_add(size, &bh->b_count); - if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) - return 0; + ret = size; + if (rq->errors == IDE_DRV_ERROR_GENERAL) + ret = -EIO; if (tape->merge_bh) idetape_init_merge_buffer(tape); - if (errors == IDE_DRV_ERROR_GENERAL) - return -EIO; +out_put: + blk_put_request(rq); return ret; } @@ -2034,8 +1970,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) u16 *ctl = (u16 *)&tape->caps[12]; drive->pc_callback = ide_tape_callback; - drive->pc_update_buffers = idetape_update_buffers; - drive->pc_io_buffers = ide_tape_io_buffers; drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; -- GitLab From 963da55c4b9eeeb2085ca74ba927cf77bce966d4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0392/6080] ide-tape: kill idetape_bh Impact: kill now unnecessary idetape_bh With everything using standard mechanisms, there is no need for idetape_bh anymore. Kill it and use tape->buf, cur and valid to describe data buffer instead. Changes worth mentioning are... * idetape_queue_rq_tail() now always queue tape->buf and and adjusts buffer state properly before completion. * idetape_pad_zeros() clears the buffer only once. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 305 ++++++++++++----------------------------- 1 file changed, 84 insertions(+), 221 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b373ac876352..d2e9c09b5215 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -131,12 +131,6 @@ enum { IDETAPE_DIR_WRITE = (1 << 2), }; -struct idetape_bh { - u32 b_size; - atomic_t b_count; - char *b_data; -}; - /* Tape door status */ #define DOOR_UNLOCKED 0 #define DOOR_LOCKED 1 @@ -218,14 +212,12 @@ typedef struct ide_tape_obj { /* Data buffer size chosen based on the tape's recommendation */ int buffer_size; - /* merge buffer */ - struct idetape_bh *merge_bh; - /* size of the merge buffer */ - int merge_bh_size; - /* pointer to current buffer head within the merge buffer */ - struct idetape_bh *bh; - char *b_data; - int b_count; + /* Staging buffer of buffer_size bytes */ + void *buf; + /* The read/write cursor */ + void *cur; + /* The number of valid bytes in buf */ + size_t valid; /* Measures average tape speed */ unsigned long avg_time; @@ -351,15 +343,6 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) } } -/* Free data buffers completely. */ -static void ide_tape_kfree_buffer(idetape_tape_t *tape) -{ - struct idetape_bh *bh = tape->merge_bh; - - kfree(bh->b_data); - kfree(bh); -} - static void ide_tape_handle_dsc(ide_drive_t *); static int ide_tape_callback(ide_drive_t *drive, int dsc) @@ -603,8 +586,7 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, struct ide_atapi_pc *pc, struct request *rq, u8 opcode) { - struct idetape_bh *bh = (struct idetape_bh *)rq->special; - unsigned int length = rq->current_nr_sectors; + unsigned int length = rq->nr_sectors; ide_init_pc(pc); put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); @@ -616,14 +598,11 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, if (pc->req_xfer == tape->buffer_size) pc->flags |= PC_FLAG_DMA_OK; - if (opcode == READ_6) { + if (opcode == READ_6) pc->c[0] = READ_6; - atomic_set(&bh->b_count, 0); - } else if (opcode == WRITE_6) { + else if (opcode == WRITE_6) { pc->c[0] = WRITE_6; pc->flags |= PC_FLAG_WRITING; - pc->b_data = bh->b_data; - pc->b_count = atomic_read(&bh->b_count); } memcpy(rq->cmd, pc->c, 12); @@ -639,10 +618,8 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, struct ide_cmd cmd; u8 stat; - debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu," - " current_nr_sectors: %u\n", - (unsigned long long)rq->sector, rq->nr_sectors, - rq->current_nr_sectors); + debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu\n" + (unsigned long long)rq->sector, rq->nr_sectors); if (!(blk_special_request(rq) || blk_sense_request(rq))) { /* We do not support buffer cache originated requests. */ @@ -748,89 +725,6 @@ out: return ide_tape_issue_pc(drive, &cmd, pc); } -/* - * It returns a pointer to the newly allocated buffer, or NULL in case - * of failure. - */ -static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape, - int full) -{ - struct idetape_bh *bh; - - bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); - if (!bh) - return NULL; - - bh->b_data = kmalloc(tape->buffer_size, GFP_KERNEL); - if (!bh->b_data) { - kfree(bh); - return NULL; - } - - bh->b_size = tape->buffer_size; - atomic_set(&bh->b_count, full ? bh->b_size : 0); - - return bh; -} - -static int idetape_copy_stage_from_user(idetape_tape_t *tape, - const char __user *buf, int n) -{ - struct idetape_bh *bh = tape->bh; - int ret = 0; - - if (n) { - if (bh == NULL || n > bh->b_size - atomic_read(&bh->b_count)) { - printk(KERN_ERR "ide-tape: bh == NULL in %s\n", - __func__); - return 1; - } - if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, - n)) - ret = 1; - atomic_add(n, &bh->b_count); - if (atomic_read(&bh->b_count) == bh->b_size) - tape->bh = NULL; - } - - return ret; -} - -static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf, - int n) -{ - struct idetape_bh *bh = tape->bh; - int ret = 0; - - if (n) { - if (bh == NULL || n > tape->b_count) { - printk(KERN_ERR "ide-tape: bh == NULL in %s\n", - __func__); - return 1; - } - if (copy_to_user(buf, tape->b_data, n)) - ret = 1; - tape->b_data += n; - tape->b_count -= n; - if (!tape->b_count) - tape->bh = NULL; - } - return ret; -} - -static void idetape_init_merge_buffer(idetape_tape_t *tape) -{ - struct idetape_bh *bh = tape->merge_bh; - tape->bh = tape->merge_bh; - - if (tape->chrdev_dir == IDETAPE_DIR_WRITE) - atomic_set(&bh->b_count, 0); - else { - tape->b_data = bh->b_data; - tape->b_count = atomic_read(&bh->b_count); - } -} - /* * Write a filemark if write_filemark=1. Flush the device buffers without * writing a filemark otherwise. @@ -928,10 +822,10 @@ static void __ide_tape_discard_merge_buffer(ide_drive_t *drive) return; clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags); - tape->merge_bh_size = 0; - if (tape->merge_bh != NULL) { - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + tape->valid = 0; + if (tape->buf != NULL) { + kfree(tape->buf); + tape->buf = NULL; } tape->chrdev_dir = IDETAPE_DIR_NONE; @@ -985,8 +879,7 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive, * Generate a read/write request for the block device interface and wait for it * to be serviced. */ -static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, - struct idetape_bh *bh) +static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks) { idetape_tape_t *tape = drive->driver_data; size_t size = blocks * tape->blk_size; @@ -1000,11 +893,10 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd[13] = cmd; rq->rq_disk = tape->disk; - rq->special = (void *)bh; rq->sector = tape->first_frame; if (size) { - ret = blk_rq_map_kern(drive->queue, rq, bh->b_data, size, + ret = blk_rq_map_kern(drive->queue, rq, tape->buf, size, __GFP_WAIT); if (ret) goto out_put; @@ -1012,17 +904,17 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, blk_execute_rq(drive->queue, tape->disk, rq, 0); - /* calculate the number of transferred bytes and update bh */ + /* calculate the number of transferred bytes and update buffer state */ size -= rq->data_len; + tape->cur = tape->buf; if (cmd == REQ_IDETAPE_READ) - atomic_add(size, &bh->b_count); + tape->valid = size; + else + tape->valid = 0; ret = size; if (rq->errors == IDE_DRV_ERROR_GENERAL) ret = -EIO; - - if (tape->merge_bh) - idetape_init_merge_buffer(tape); out_put: blk_put_request(rq); return ret; @@ -1064,49 +956,33 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) /* Queue up a character device originated write request. */ static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) { - idetape_tape_t *tape = drive->driver_data; - debug_log(DBG_CHRDEV, "Enter %s\n", __func__); - return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, - blocks, tape->merge_bh); + return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks); } static void ide_tape_flush_merge_buffer(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; int blocks; - struct idetape_bh *bh; if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" " but we are not writing.\n"); return; } - if (tape->merge_bh_size > tape->buffer_size) { - printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n"); - tape->merge_bh_size = tape->buffer_size; - } - if (tape->merge_bh_size) { - blocks = tape->merge_bh_size / tape->blk_size; - if (tape->merge_bh_size % tape->blk_size) { - unsigned int i = tape->blk_size - - tape->merge_bh_size % tape->blk_size; + if (tape->buf) { + blocks = tape->valid / tape->blk_size; + if (tape->valid % tape->blk_size) { blocks++; - bh = tape->bh; - if (bh) { - memset(bh->b_data + atomic_read(&bh->b_count), - 0, i); - atomic_add(i, &bh->b_count); - } else - printk(KERN_INFO "ide-tape: bug, bh NULL\n"); + memset(tape->buf + tape->valid, 0, + tape->blk_size - tape->valid % tape->blk_size); } (void) idetape_add_chrdev_write_request(drive, blocks); - tape->merge_bh_size = 0; } - if (tape->merge_bh != NULL) { - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + if (tape->buf != NULL) { + kfree(tape->buf); + tape->buf = NULL; } tape->chrdev_dir = IDETAPE_DIR_NONE; } @@ -1122,15 +998,15 @@ static int idetape_init_read(ide_drive_t *drive) ide_tape_flush_merge_buffer(drive); idetape_flush_tape_buffers(drive); } - if (tape->merge_bh || tape->merge_bh_size) { - printk(KERN_ERR "ide-tape: merge_bh_size should be" - " 0 now\n"); - tape->merge_bh_size = 0; + if (tape->buf || tape->valid) { + printk(KERN_ERR "ide-tape: valid should be 0 now\n"); + tape->valid = 0; } - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0); - if (!tape->merge_bh) + tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); + if (!tape->buf) return -ENOMEM; tape->chrdev_dir = IDETAPE_DIR_READ; + tape->cur = tape->buf; /* * Issue a read 0 command to ensure that DSC handshake is @@ -1140,11 +1016,10 @@ static int idetape_init_read(ide_drive_t *drive) */ if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { bytes_read = idetape_queue_rw_tail(drive, - REQ_IDETAPE_READ, 0, - tape->merge_bh); + REQ_IDETAPE_READ, 0); if (bytes_read < 0) { - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + kfree(tape->buf); + tape->buf = NULL; tape->chrdev_dir = IDETAPE_DIR_NONE; return bytes_read; } @@ -1157,8 +1032,6 @@ static int idetape_init_read(ide_drive_t *drive) /* called from idetape_chrdev_read() to service a chrdev read request. */ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) { - idetape_tape_t *tape = drive->driver_data; - debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks); /* If we are at a filemark, return a read length of 0 */ @@ -1167,27 +1040,21 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) idetape_init_read(drive); - return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks, - tape->merge_bh); + return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks); } static void idetape_pad_zeros(ide_drive_t *drive, int bcount) { idetape_tape_t *tape = drive->driver_data; - struct idetape_bh *bh = tape->merge_bh; - int blocks; + + memset(tape->buf, 0, tape->buffer_size); while (bcount) { - unsigned int count; + unsigned int count = min(tape->buffer_size, bcount); - count = min(tape->buffer_size, bcount); + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, + count / tape->blk_size); bcount -= count; - blocks = count / tape->blk_size; - atomic_set(&bh->b_count, count); - memset(bh->b_data, 0, atomic_read(&bh->b_count)); - - idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, - tape->merge_bh); } } @@ -1267,7 +1134,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, } if (tape->chrdev_dir == IDETAPE_DIR_READ) { - tape->merge_bh_size = 0; + tape->valid = 0; if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) ++count; ide_tape_discard_merge_buffer(drive, 0); @@ -1333,20 +1200,20 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, return rc; if (count == 0) return (0); - if (tape->merge_bh_size) { - actually_read = min((unsigned int)(tape->merge_bh_size), - (unsigned int)count); - if (idetape_copy_stage_to_user(tape, buf, actually_read)) + if (tape->valid) { + actually_read = min_t(unsigned int, tape->valid, count); + if (copy_to_user(buf, tape->cur, actually_read)) ret = -EFAULT; buf += actually_read; - tape->merge_bh_size -= actually_read; count -= actually_read; + tape->cur += actually_read; + tape->valid -= actually_read; } while (count >= tape->buffer_size) { bytes_read = idetape_add_chrdev_read_request(drive, ctl); if (bytes_read <= 0) goto finish; - if (idetape_copy_stage_to_user(tape, buf, bytes_read)) + if (copy_to_user(buf, tape->cur, bytes_read)) ret = -EFAULT; buf += bytes_read; count -= bytes_read; @@ -1357,10 +1224,11 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, if (bytes_read <= 0) goto finish; temp = min((unsigned long)count, (unsigned long)bytes_read); - if (idetape_copy_stage_to_user(tape, buf, temp)) + if (copy_to_user(buf, tape->cur, temp)) ret = -EFAULT; actually_read += temp; - tape->merge_bh_size = bytes_read-temp; + tape->cur += temp; + tape->valid -= temp; } finish: if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { @@ -1392,16 +1260,15 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { if (tape->chrdev_dir == IDETAPE_DIR_READ) ide_tape_discard_merge_buffer(drive, 1); - if (tape->merge_bh || tape->merge_bh_size) { - printk(KERN_ERR "ide-tape: merge_bh_size " - "should be 0 now\n"); - tape->merge_bh_size = 0; + if (tape->buf || tape->valid) { + printk(KERN_ERR "ide-tape: valid should be 0 now\n"); + tape->valid = 0; } - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0); - if (!tape->merge_bh) + tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); + if (!tape->buf) return -ENOMEM; tape->chrdev_dir = IDETAPE_DIR_WRITE; - idetape_init_merge_buffer(tape); + tape->cur = tape->buf; /* * Issue a write 0 command to ensure that DSC handshake is @@ -1411,11 +1278,10 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, */ if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { ssize_t retval = idetape_queue_rw_tail(drive, - REQ_IDETAPE_WRITE, 0, - tape->merge_bh); + REQ_IDETAPE_WRITE, 0); if (retval < 0) { - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + kfree(tape->buf); + tape->buf = NULL; tape->chrdev_dir = IDETAPE_DIR_NONE; return retval; } @@ -1423,23 +1289,19 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, } if (count == 0) return (0); - if (tape->merge_bh_size) { - if (tape->merge_bh_size >= tape->buffer_size) { - printk(KERN_ERR "ide-tape: bug: merge buf too big\n"); - tape->merge_bh_size = 0; - } - actually_written = min((unsigned int) - (tape->buffer_size - tape->merge_bh_size), - (unsigned int)count); - if (idetape_copy_stage_from_user(tape, buf, actually_written)) - ret = -EFAULT; + if (tape->valid < tape->buffer_size) { + actually_written = min_t(unsigned int, + tape->buffer_size - tape->valid, + count); + if (copy_from_user(tape->cur, buf, actually_written)) + ret = -EFAULT; buf += actually_written; - tape->merge_bh_size += actually_written; count -= actually_written; + tape->cur += actually_written; + tape->valid += actually_written; - if (tape->merge_bh_size == tape->buffer_size) { + if (tape->valid == tape->buffer_size) { ssize_t retval; - tape->merge_bh_size = 0; retval = idetape_add_chrdev_write_request(drive, ctl); if (retval <= 0) return (retval); @@ -1447,7 +1309,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, } while (count >= tape->buffer_size) { ssize_t retval; - if (idetape_copy_stage_from_user(tape, buf, tape->buffer_size)) + if (copy_from_user(tape->cur, buf, tape->buffer_size)) ret = -EFAULT; buf += tape->buffer_size; count -= tape->buffer_size; @@ -1458,9 +1320,10 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, } if (count) { actually_written += count; - if (idetape_copy_stage_from_user(tape, buf, count)) + if (copy_from_user(tape->cur, buf, count)) ret = -EFAULT; - tape->merge_bh_size += count; + tape->cur += count; + tape->valid += count; } return ret ? ret : actually_written; } @@ -1623,7 +1486,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, idetape_flush_tape_buffers(drive); } if (cmd == MTIOCGET || cmd == MTIOCPOS) { - block_offset = tape->merge_bh_size / + block_offset = tape->valid / (tape->blk_size * tape->user_bs_factor); position = idetape_read_position(drive); if (position < 0) @@ -1771,12 +1634,12 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) idetape_tape_t *tape = drive->driver_data; ide_tape_flush_merge_buffer(drive); - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1); - if (tape->merge_bh != NULL) { + tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); + if (tape->buf != NULL) { idetape_pad_zeros(drive, tape->blk_size * (tape->user_bs_factor - 1)); - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + kfree(tape->buf); + tape->buf = NULL; } idetape_write_filemark(drive); idetape_flush_tape_buffers(drive); @@ -2042,7 +1905,7 @@ static void ide_tape_release(struct device *dev) ide_drive_t *drive = tape->drive; struct gendisk *g = tape->disk; - BUG_ON(tape->merge_bh_size); + BUG_ON(tape->valid); drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; drive->driver_data = NULL; -- GitLab From 88f1b941c5c94016a59144a3c94c9ca31eb16205 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0393/6080] ide-tape: unify r/w init paths Impact: cleanup Read and write init paths are almost identical. Unify them into idetape_init_rw(). Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 110 +++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 64 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d2e9c09b5215..4da7fa9bca1e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -987,42 +987,50 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) tape->chrdev_dir = IDETAPE_DIR_NONE; } -static int idetape_init_read(ide_drive_t *drive) +static int idetape_init_rw(ide_drive_t *drive, int dir) { idetape_tape_t *tape = drive->driver_data; - int bytes_read; + int rc; - /* Initialize read operation */ - if (tape->chrdev_dir != IDETAPE_DIR_READ) { - if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { - ide_tape_flush_merge_buffer(drive); - idetape_flush_tape_buffers(drive); - } - if (tape->buf || tape->valid) { - printk(KERN_ERR "ide-tape: valid should be 0 now\n"); - tape->valid = 0; - } - tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); - if (!tape->buf) - return -ENOMEM; - tape->chrdev_dir = IDETAPE_DIR_READ; - tape->cur = tape->buf; + BUG_ON(dir != IDETAPE_DIR_READ && dir != IDETAPE_DIR_WRITE); - /* - * Issue a read 0 command to ensure that DSC handshake is - * switched from completion mode to buffer available mode. - * No point in issuing this if DSC overlap isn't supported, some - * drives (Seagate STT3401A) will return an error. - */ - if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { - bytes_read = idetape_queue_rw_tail(drive, - REQ_IDETAPE_READ, 0); - if (bytes_read < 0) { - kfree(tape->buf); - tape->buf = NULL; - tape->chrdev_dir = IDETAPE_DIR_NONE; - return bytes_read; - } + if (tape->chrdev_dir == dir) + return 0; + + if (tape->chrdev_dir == IDETAPE_DIR_READ) + ide_tape_discard_merge_buffer(drive, 1); + else if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { + ide_tape_flush_merge_buffer(drive); + idetape_flush_tape_buffers(drive); + } + + if (tape->buf || tape->valid) { + printk(KERN_ERR "ide-tape: valid should be 0 now\n"); + tape->valid = 0; + } + + tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); + if (!tape->buf) + return -ENOMEM; + tape->chrdev_dir = dir; + tape->cur = tape->buf; + + /* + * Issue a 0 rw command to ensure that DSC handshake is + * switched from completion mode to buffer available mode. No + * point in issuing this if DSC overlap isn't supported, some + * drives (Seagate STT3401A) will return an error. + */ + if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { + int cmd = dir == IDETAPE_DIR_READ ? REQ_IDETAPE_READ + : REQ_IDETAPE_WRITE; + + rc = idetape_queue_rw_tail(drive, cmd, 0); + if (rc < 0) { + kfree(tape->buf); + tape->buf = NULL; + tape->chrdev_dir = IDETAPE_DIR_NONE; + return rc; } } @@ -1038,7 +1046,7 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) return 0; - idetape_init_read(drive); + idetape_init_rw(drive, IDETAPE_DIR_READ); return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks); } @@ -1195,7 +1203,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, (count % tape->blk_size) == 0) tape->user_bs_factor = count / tape->blk_size; } - rc = idetape_init_read(drive); + rc = idetape_init_rw(drive, IDETAPE_DIR_READ); if (rc < 0) return rc; if (count == 0) @@ -1249,6 +1257,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, ssize_t actually_written = 0; ssize_t ret = 0; u16 ctl = *(u16 *)&tape->caps[12]; + int rc; /* The drive is write protected. */ if (tape->write_prot) @@ -1257,36 +1266,9 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); /* Initialize write operation */ - if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { - if (tape->chrdev_dir == IDETAPE_DIR_READ) - ide_tape_discard_merge_buffer(drive, 1); - if (tape->buf || tape->valid) { - printk(KERN_ERR "ide-tape: valid should be 0 now\n"); - tape->valid = 0; - } - tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); - if (!tape->buf) - return -ENOMEM; - tape->chrdev_dir = IDETAPE_DIR_WRITE; - tape->cur = tape->buf; - - /* - * Issue a write 0 command to ensure that DSC handshake is - * switched from completion mode to buffer available mode. No - * point in issuing this if DSC overlap isn't supported, some - * drives (Seagate STT3401A) will return an error. - */ - if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { - ssize_t retval = idetape_queue_rw_tail(drive, - REQ_IDETAPE_WRITE, 0); - if (retval < 0) { - kfree(tape->buf); - tape->buf = NULL; - tape->chrdev_dir = IDETAPE_DIR_NONE; - return retval; - } - } - } + rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); + if (rc < 0) + return rc; if (count == 0) return (0); if (tape->valid < tape->buffer_size) { -- GitLab From 6bb11dd14f70228f8dab25fd25dabeb9bc74926d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:03 +0900 Subject: [PATCH 0394/6080] ide-tape: use byte size instead of sectors on rw issue functions Impact: cleanup Byte size is what most issue functions deal with, make idetape_queue_rw_tail() and its wrappers take byte size instead of sector counts. idetape_chrdev_read() and write() functions are converted to use tape->buffer_size instead of ctl from tape->cap. This cleans up code a little bit and will ease the next r/w reimplementation. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 45 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 4da7fa9bca1e..d5e9bb286e30 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -879,15 +879,15 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive, * Generate a read/write request for the block device interface and wait for it * to be serviced. */ -static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks) +static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size) { idetape_tape_t *tape = drive->driver_data; - size_t size = blocks * tape->blk_size; struct request *rq; int ret; debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); + BUG_ON(size < 0 || size % tape->blk_size); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_SPECIAL; @@ -954,17 +954,16 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) } /* Queue up a character device originated write request. */ -static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) +static int idetape_add_chrdev_write_request(ide_drive_t *drive, int size) { debug_log(DBG_CHRDEV, "Enter %s\n", __func__); - return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks); + return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, size); } static void ide_tape_flush_merge_buffer(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; - int blocks; if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" @@ -972,15 +971,10 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) return; } if (tape->buf) { - blocks = tape->valid / tape->blk_size; - if (tape->valid % tape->blk_size) { - blocks++; - memset(tape->buf + tape->valid, 0, - tape->blk_size - tape->valid % tape->blk_size); - } - (void) idetape_add_chrdev_write_request(drive, blocks); - } - if (tape->buf != NULL) { + size_t aligned = roundup(tape->valid, tape->blk_size); + + memset(tape->cur, 0, aligned - tape->valid); + idetape_add_chrdev_write_request(drive, aligned); kfree(tape->buf); tape->buf = NULL; } @@ -1038,9 +1032,9 @@ static int idetape_init_rw(ide_drive_t *drive, int dir) } /* called from idetape_chrdev_read() to service a chrdev read request. */ -static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) +static int idetape_add_chrdev_read_request(ide_drive_t *drive, int size) { - debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks); + debug_log(DBG_PROCS, "Enter %s, %d bytes\n", __func__, size); /* If we are at a filemark, return a read length of 0 */ if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) @@ -1048,7 +1042,7 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) idetape_init_rw(drive, IDETAPE_DIR_READ); - return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks); + return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, size); } static void idetape_pad_zeros(ide_drive_t *drive, int bcount) @@ -1060,8 +1054,7 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount) while (bcount) { unsigned int count = min(tape->buffer_size, bcount); - idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, - count / tape->blk_size); + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, count); bcount -= count; } } @@ -1193,7 +1186,6 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, ide_drive_t *drive = tape->drive; ssize_t bytes_read, temp, actually_read = 0, rc; ssize_t ret = 0; - u16 ctl = *(u16 *)&tape->caps[12]; debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); @@ -1218,7 +1210,8 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, tape->valid -= actually_read; } while (count >= tape->buffer_size) { - bytes_read = idetape_add_chrdev_read_request(drive, ctl); + bytes_read = idetape_add_chrdev_read_request(drive, + tape->buffer_size); if (bytes_read <= 0) goto finish; if (copy_to_user(buf, tape->cur, bytes_read)) @@ -1228,7 +1221,8 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, actually_read += bytes_read; } if (count) { - bytes_read = idetape_add_chrdev_read_request(drive, ctl); + bytes_read = idetape_add_chrdev_read_request(drive, + tape->buffer_size); if (bytes_read <= 0) goto finish; temp = min((unsigned long)count, (unsigned long)bytes_read); @@ -1256,7 +1250,6 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, ide_drive_t *drive = tape->drive; ssize_t actually_written = 0; ssize_t ret = 0; - u16 ctl = *(u16 *)&tape->caps[12]; int rc; /* The drive is write protected. */ @@ -1284,7 +1277,8 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, if (tape->valid == tape->buffer_size) { ssize_t retval; - retval = idetape_add_chrdev_write_request(drive, ctl); + retval = idetape_add_chrdev_write_request(drive, + tape->buffer_size); if (retval <= 0) return (retval); } @@ -1295,7 +1289,8 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, ret = -EFAULT; buf += tape->buffer_size; count -= tape->buffer_size; - retval = idetape_add_chrdev_write_request(drive, ctl); + retval = idetape_add_chrdev_write_request(drive, + tape->buffer_size); actually_written += tape->buffer_size; if (retval <= 0) return (retval); -- GitLab From 07bd9686c50c2b1f10e48089d4fb836a971f5177 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:03 +0900 Subject: [PATCH 0395/6080] ide-tape: simplify read/write functions Impact: cleanup idetape_chrdev_read/write() functions are unnecessarily complex when everything can be handled in a single loop. Collapse idetape_add_chrdev_read/write_request() into the rw functions and simplify the implementation. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 149 ++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 99 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d5e9bb286e30..2599579e4174 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -953,14 +953,6 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) pc->flags |= PC_FLAG_WAIT_FOR_DSC; } -/* Queue up a character device originated write request. */ -static int idetape_add_chrdev_write_request(ide_drive_t *drive, int size) -{ - debug_log(DBG_CHRDEV, "Enter %s\n", __func__); - - return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, size); -} - static void ide_tape_flush_merge_buffer(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; @@ -974,7 +966,7 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) size_t aligned = roundup(tape->valid, tape->blk_size); memset(tape->cur, 0, aligned - tape->valid); - idetape_add_chrdev_write_request(drive, aligned); + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, aligned); kfree(tape->buf); tape->buf = NULL; } @@ -1031,20 +1023,6 @@ static int idetape_init_rw(ide_drive_t *drive, int dir) return 0; } -/* called from idetape_chrdev_read() to service a chrdev read request. */ -static int idetape_add_chrdev_read_request(ide_drive_t *drive, int size) -{ - debug_log(DBG_PROCS, "Enter %s, %d bytes\n", __func__, size); - - /* If we are at a filemark, return a read length of 0 */ - if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) - return 0; - - idetape_init_rw(drive, IDETAPE_DIR_READ); - - return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, size); -} - static void idetape_pad_zeros(ide_drive_t *drive, int bcount) { idetape_tape_t *tape = drive->driver_data; @@ -1184,8 +1162,9 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, { struct ide_tape_obj *tape = file->private_data; ide_drive_t *drive = tape->drive; - ssize_t bytes_read, temp, actually_read = 0, rc; + size_t done = 0; ssize_t ret = 0; + int rc; debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); @@ -1195,52 +1174,43 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, (count % tape->blk_size) == 0) tape->user_bs_factor = count / tape->blk_size; } + rc = idetape_init_rw(drive, IDETAPE_DIR_READ); if (rc < 0) return rc; - if (count == 0) - return (0); - if (tape->valid) { - actually_read = min_t(unsigned int, tape->valid, count); - if (copy_to_user(buf, tape->cur, actually_read)) - ret = -EFAULT; - buf += actually_read; - count -= actually_read; - tape->cur += actually_read; - tape->valid -= actually_read; - } - while (count >= tape->buffer_size) { - bytes_read = idetape_add_chrdev_read_request(drive, - tape->buffer_size); - if (bytes_read <= 0) - goto finish; - if (copy_to_user(buf, tape->cur, bytes_read)) - ret = -EFAULT; - buf += bytes_read; - count -= bytes_read; - actually_read += bytes_read; - } - if (count) { - bytes_read = idetape_add_chrdev_read_request(drive, - tape->buffer_size); - if (bytes_read <= 0) - goto finish; - temp = min((unsigned long)count, (unsigned long)bytes_read); - if (copy_to_user(buf, tape->cur, temp)) + + while (done < count) { + size_t todo; + + /* refill if staging buffer is empty */ + if (!tape->valid) { + /* If we are at a filemark, nothing more to read */ + if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) + break; + /* read */ + if (idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, + tape->buffer_size) <= 0) + break; + } + + /* copy out */ + todo = min_t(size_t, count - done, tape->valid); + if (copy_to_user(buf + done, tape->cur, todo)) ret = -EFAULT; - actually_read += temp; - tape->cur += temp; - tape->valid -= temp; + + tape->cur += todo; + tape->valid -= todo; + done += todo; } -finish: - if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { + + if (!done && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); idetape_space_over_filemarks(drive, MTFSF, 1); return 0; } - return ret ? ret : actually_read; + return ret ? ret : done; } static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, @@ -1248,7 +1218,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, { struct ide_tape_obj *tape = file->private_data; ide_drive_t *drive = tape->drive; - ssize_t actually_written = 0; + size_t done = 0; ssize_t ret = 0; int rc; @@ -1262,47 +1232,28 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); if (rc < 0) return rc; - if (count == 0) - return (0); - if (tape->valid < tape->buffer_size) { - actually_written = min_t(unsigned int, - tape->buffer_size - tape->valid, - count); - if (copy_from_user(tape->cur, buf, actually_written)) - ret = -EFAULT; - buf += actually_written; - count -= actually_written; - tape->cur += actually_written; - tape->valid += actually_written; - - if (tape->valid == tape->buffer_size) { - ssize_t retval; - retval = idetape_add_chrdev_write_request(drive, - tape->buffer_size); - if (retval <= 0) - return (retval); - } - } - while (count >= tape->buffer_size) { - ssize_t retval; - if (copy_from_user(tape->cur, buf, tape->buffer_size)) - ret = -EFAULT; - buf += tape->buffer_size; - count -= tape->buffer_size; - retval = idetape_add_chrdev_write_request(drive, - tape->buffer_size); - actually_written += tape->buffer_size; - if (retval <= 0) - return (retval); - } - if (count) { - actually_written += count; - if (copy_from_user(tape->cur, buf, count)) + + while (done < count) { + size_t todo; + + /* flush if staging buffer is full */ + if (tape->valid == tape->buffer_size && + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, + tape->buffer_size) <= 0) + return rc; + + /* copy in */ + todo = min_t(size_t, count - done, + tape->buffer_size - tape->valid); + if (copy_from_user(tape->cur, buf + done, todo)) ret = -EFAULT; - tape->cur += count; - tape->valid += count; + + tape->cur += todo; + tape->valid += todo; + done += todo; } - return ret ? ret : actually_written; + + return ret ? ret : done; } static int idetape_write_filemark(ide_drive_t *drive) -- GitLab From 6d7003877c2f0578f1c08f66d05c3f72ef4ae596 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:03 +0900 Subject: [PATCH 0396/6080] ide-atapi: kill unused fields and callbacks Impact: remove fields and code paths which are no longer necessary Now that ide-tape uses standard mechanisms to transfer data, special case handling for bh handling can be dropped from ide-atapi. Drop the followings. * pc->cur_pos, b_count, bh and b_data * drive->pc_update_buffers() and pc_io_buffers(). Signed-off-by: Tejun Heo --- drivers/ide/ide-atapi.c | 17 ++++------------- drivers/ide/ide-tape.c | 1 - include/linux/ide.h | 12 ------------ 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index b9dd4503cbc7..afe5a4323879 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -359,11 +359,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) drive->name, rq_data_dir(pc->rq) ? "write" : "read"); pc->flags |= PC_FLAG_DMA_ERROR; - } else { + } else pc->xferred = pc->req_xfer; - if (drive->pc_update_buffers) - drive->pc_update_buffers(drive, pc); - } debug_log("%s: DMA finished\n", drive->name); } @@ -463,16 +460,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) return ide_do_reset(drive); } - if (drive->media == ide_tape && pc->bh) - done = drive->pc_io_buffers(drive, pc, bcount, write); - else { - done = min_t(unsigned int, bcount, cmd->nleft); - ide_pio_bytes(drive, cmd, write, done); - } + done = min_t(unsigned int, bcount, cmd->nleft); + ide_pio_bytes(drive, cmd, write, done); - /* Update the current position */ + /* Update transferred byte count */ pc->xferred += done; - pc->cur_pos += done; bcount -= done; @@ -650,7 +642,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) /* We haven't transferred any data yet */ pc->xferred = 0; - pc->cur_pos = pc->buf; valid_tf = IDE_VALID_DEVICE; bcount = ((drive->media == ide_tape) ? diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2599579e4174..8dfc68892d6a 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -591,7 +591,6 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, ide_init_pc(pc); put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; - pc->bh = NULL; pc->buf = NULL; pc->buf_size = length * tape->blk_size; pc->req_xfer = pc->buf_size; diff --git a/include/linux/ide.h b/include/linux/ide.h index 1957461ac762..34c128f0a33c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -362,11 +362,7 @@ struct ide_atapi_pc { /* data buffer */ u8 *buf; - /* current buffer position */ - u8 *cur_pos; int buf_size; - /* missing/available data on the current buffer */ - int b_count; /* the corresponding request */ struct request *rq; @@ -379,10 +375,6 @@ struct ide_atapi_pc { */ u8 pc_buf[IDE_PC_BUFFER_SIZE]; - /* idetape only */ - struct idetape_bh *bh; - char *b_data; - unsigned long timeout; }; @@ -595,10 +587,6 @@ struct ide_drive_s { /* callback for packet commands */ int (*pc_callback)(struct ide_drive_s *, int); - void (*pc_update_buffers)(struct ide_drive_s *, struct ide_atapi_pc *); - int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *, - unsigned int, int); - ide_startstop_t (*irq_handler)(struct ide_drive_s *); unsigned long atapi_flags; -- GitLab From 2c316bb57ad4e9f0f3de2d7ef1ae85530c2a7e69 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:03 +0900 Subject: [PATCH 0397/6080] ide: drop rq->data handling from ide_map_sg() Impact: remove code path which is no longer necessary All IDE data transfers now use rq->bio. Simplify ide_map_sg() accordingly. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-io.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 6e3094e22775..a0309ea661ac 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -248,11 +248,7 @@ void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) struct scatterlist *sg = hwif->sg_table; struct request *rq = cmd->rq; - if (!rq->bio) { - sg_init_one(sg, rq->data, rq->data_len); - cmd->sg_nents = 1; - } else - cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); + cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); } EXPORT_SYMBOL_GPL(ide_map_sg); -- GitLab From e475eedb09ee9a0fd855f3e923aa9af31c17d141 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 15 Apr 2009 10:50:04 +0000 Subject: [PATCH 0398/6080] clocksource: sh_cmt earlytimer support Add Early Platform Driver support to the sh_cmt driver using the earlytimer class. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 1c92c39a53aa..02bae3994abe 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -566,9 +566,19 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) static int __devinit sh_cmt_probe(struct platform_device *pdev) { struct sh_cmt_priv *p = platform_get_drvdata(pdev); + struct sh_cmt_config *cfg = pdev->dev.platform_data; int ret; - p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p) { + pr_info("sh_cmt: %s kept as earlytimer\n", cfg->name); + return 0; + } + + if (is_early_platform_device(pdev)) + p = alloc_bootmem(sizeof(*p)); + else + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) { dev_err(&pdev->dev, "failed to allocate driver data\n"); return -ENOMEM; @@ -576,7 +586,10 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev) ret = sh_cmt_setup(p, pdev); if (ret) { - kfree(p); + if (is_early_platform_device(pdev)) + free_bootmem(__pa(p), sizeof(*p)); + else + kfree(p); platform_set_drvdata(pdev, NULL); } @@ -606,6 +619,7 @@ static void __exit sh_cmt_exit(void) platform_driver_unregister(&sh_cmt_device_driver); } +early_platform_init("earlytimer", &sh_cmt_device_driver); module_init(sh_cmt_init); module_exit(sh_cmt_exit); -- GitLab From eaab89197b733d0f81f07d6c44294b674479fda8 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 15 Apr 2009 10:50:12 +0000 Subject: [PATCH 0399/6080] sh: arch earlytimer support Extend the 32-bit SuperH timer code to register and probe the earlytimer class of Early Platform Drivers. This registers the sh_cmt driver if compiled-in. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/time_32.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c index c34e1e0f9b02..04b8c6ab1667 100644 --- a/arch/sh/kernel/time_32.c +++ b/arch/sh/kernel/time_32.c @@ -17,6 +17,7 @@ #include #include #include /* for rtc_lock */ +#include #include #include #include @@ -228,6 +229,14 @@ void __init time_init(void) local_timer_setup(smp_processor_id()); #endif + /* + * Make sure all compiled-in early timers register themselves. + * Run probe() for one "earlytimer" device. + */ + early_platform_driver_register_all("earlytimer"); + if (early_platform_driver_probe("earlytimer", 1, 0)) + return; + /* * Find the timer to use as the system timer, it will be * initialized for us. -- GitLab From 87a00dc059e3af46303f1f56b0e8df41af988c7b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 15 Apr 2009 10:50:21 +0000 Subject: [PATCH 0400/6080] sh: Add plat_early_device_setup() Add a plat_early_device_setup() function to allow processor-specific code to register Early Platform Data. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/include/asm/device.h | 2 ++ arch/sh/kernel/setup.c | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h index efd511d0803a..8688a88303ee 100644 --- a/arch/sh/include/asm/device.h +++ b/arch/sh/include/asm/device.h @@ -10,3 +10,5 @@ struct platform_device; int platform_resource_setup_memory(struct platform_device *pdev, char *name, unsigned long memsize); +void plat_early_device_setup(void); + diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 04a6004fccc4..22b976d42014 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -328,6 +329,10 @@ static int __init parse_elfcorehdr(char *arg) early_param("elfcorehdr", parse_elfcorehdr); #endif +void __init __attribute__ ((weak)) plat_early_device_setup(void) +{ +} + void __init setup_arch(char **cmdline_p) { enable_mmu(); @@ -381,6 +386,8 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); + plat_early_device_setup(); + sh_mv_setup(); /* -- GitLab From 28fde6863e6ed1f4bfb7cef080e67bf439c20628 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 15 Apr 2009 10:50:30 +0000 Subject: [PATCH 0401/6080] sh: Early Platform Data for SuperH Mobile Use plat_early_device_setup() to register Early Platform Data for SuperH Mobile processors. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 10 ++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 10 ++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 10 ++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 10 ++++++++++ 4 files changed, 40 insertions(+) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index c1549382c87c..cb5b4db1ca25 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -234,6 +234,16 @@ static int __init sh7343_devices_setup(void) } __initcall(sh7343_devices_setup); +static struct platform_device *sh7343_early_devices[] __initdata = { + &cmt_device, +}; + +void __init plat_early_device_setup(void) +{ + early_platform_add_devices(sh7343_early_devices, + ARRAY_SIZE(sh7343_early_devices)); +} + enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 93ecf8ed5c6c..2a771f48e9e0 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -226,6 +226,16 @@ static int __init sh7366_devices_setup(void) } __initcall(sh7366_devices_setup); +static struct platform_device *sh7366_early_devices[] __initdata = { + &cmt_device, +}; + +void __init plat_early_device_setup(void) +{ + early_platform_add_devices(sh7366_early_devices, + ARRAY_SIZE(sh7366_early_devices)); +} + enum { UNUSED=0, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 0e5d204bc792..8f974d0494c9 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -270,6 +270,16 @@ static int __init sh7722_devices_setup(void) } __initcall(sh7722_devices_setup); +static struct platform_device *sh7722_early_devices[] __initdata = { + &cmt_device, +}; + +void __init plat_early_device_setup(void) +{ + early_platform_add_devices(sh7722_early_devices, + ARRAY_SIZE(sh7722_early_devices)); +} + enum { UNUSED=0, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 5338dacbcfba..21a58d63a00d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -281,6 +281,16 @@ static int __init sh7723_devices_setup(void) } __initcall(sh7723_devices_setup); +static struct platform_device *sh7723_early_devices[] __initdata = { + &cmt_device, +}; + +void __init plat_early_device_setup(void) +{ + early_platform_add_devices(sh7723_early_devices, + ARRAY_SIZE(sh7723_early_devices)); +} + enum { UNUSED=0, -- GitLab From d9aed8b95f062b2f96e37b0e07373f36a6e7066d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sun, 19 Apr 2009 13:12:04 +0900 Subject: [PATCH 0402/6080] sh: sh7724: Don't default enable the RTC clock. rtc-sh takes care of this now, so no need to have this always enabled. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 8b87ba8f26bb..195274a74f8d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -275,7 +275,6 @@ static struct platform_device *sh7724_devices[] __initdata = { static int __init sh7724_devices_setup(void) { - clk_always_enable("rtc0"); /* RTC */ clk_always_enable("vpu0"); /* VPU */ clk_always_enable("veu1"); /* VEU3F1 */ clk_always_enable("veu0"); /* VEU3F0 */ -- GitLab From 8fb2bae4b41eb64f6e233e9bd3f3a789fbb04a06 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sun, 19 Apr 2009 13:14:29 +0900 Subject: [PATCH 0403/6080] sh: sh7724: Register CMT as an early platform device here too. Follows the SH7722/SH7723 changes. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 195274a74f8d..8429396acb59 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -288,6 +288,16 @@ static int __init sh7724_devices_setup(void) } device_initcall(sh7724_devices_setup); +static struct platform_device *sh7724_early_devices[] __initdata = { + &cmt_device, +}; + +void __init plat_early_device_setup(void) +{ + early_platform_add_devices(sh7724_early_devices, + ARRAY_SIZE(sh7724_early_devices)); +} + enum { UNUSED = 0, -- GitLab From 3ef8e4e9e4d18910cd03dcd481a5dced437b83cf Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 19 Apr 2009 18:42:58 -0700 Subject: [PATCH 0404/6080] iseries_veth: fix build breakage Reported-by: Stephen Rothwell Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/iseries_veth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 264654da85d1..e44215cb1882 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1077,7 +1077,7 @@ static struct net_device *veth_probe_one(int vlan, memcpy(&port->mac_addr, mac_addr, ETH_ALEN); - dev->netdev = &veth_netdev_ops; + dev->netdev_ops = &veth_netdev_ops; SET_ETHTOOL_OPS(dev, &ops); SET_NETDEV_DEV(dev, vdev); -- GitLab From 9ade1217c9ba39ad2f004a898ddfbb815fd5fe74 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 15:38:25 +0900 Subject: [PATCH 0405/6080] sh: pci: Drop asm-generic/pci.h, so we can use our own fixups. The new PCI code wants its own bus<->resource mappings instead of the generic equivalents, so drop the asm-generic include in preparation. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci.c | 14 ++++++++++++++ arch/sh/include/asm/pci.h | 27 ++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 8aaacc99b710..6d659cd93c9d 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -72,6 +72,20 @@ void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) pci_read_bridge_bases(bus); } +void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res) +{ + region->start = res->start; + region->end = res->end; +} + +void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region) +{ + res->start = region->start; + res->end = region->end; +} + void pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t align) __attribute__ ((weak)); diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index bb2c2fcddc9e..69cb615c3916 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -146,13 +146,34 @@ int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin); int pciauto_assign_resources(int busno, struct pci_channel *hose); #endif -#endif /* __KERNEL__ */ +extern void pcibios_resource_to_bus(struct pci_dev *dev, + struct pci_bus_region *region, struct resource *res); + +extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region); + +static inline struct resource * +pcibios_select_root(struct pci_dev *pdev, struct resource *res) +{ + struct resource *root = NULL; + + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + if (res->flags & IORESOURCE_MEM) + root = &iomem_resource; -/* generic pci stuff */ -#include + return root; +} + +/* Chances are this interrupt is wired PC-style ... */ +static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) +{ + return channel ? 15 : 14; +} /* generic DMA-mapping stuff */ #include +#endif /* __KERNEL__ */ #endif /* __ASM_SH_PCI_H */ -- GitLab From 4c5107e44514a9bde74d0af77982705d602d9e39 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 15:43:36 +0900 Subject: [PATCH 0406/6080] sh: pci: Split out new-style PCI core. This splits off a 'pci-new.c' which is aimed at gradually replacing the pci-auto backend and the arch/sh/drivers/pci/pci.c core respectively. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Kconfig | 10 +- arch/sh/drivers/pci/Makefile | 4 +- arch/sh/drivers/pci/pci-new.c | 248 ++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+), 4 deletions(-) create mode 100644 arch/sh/drivers/pci/pci-new.c diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index 7e816ededed7..efe8cf965a9b 100644 --- a/arch/sh/drivers/pci/Kconfig +++ b/arch/sh/drivers/pci/Kconfig @@ -18,10 +18,17 @@ config SH_PCIDMA_NONCOHERENT bridge integrated with your SH CPU, refer carefully to the chip specs to see if you can say 'N' here. Otherwise, leave it as 'Y'. +# Temporary config option for transitioning off of PCI_AUTO +config PCI_NEW + bool + depends on PCI + default y if CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7780 || \ + CPU_SUBTYPE_SH7785 + # This is also board-specific config PCI_AUTO bool - depends on PCI + depends on PCI && !PCI_NEW default y config PCI_AUTO_UPDATE_RESOURCES @@ -34,4 +41,3 @@ config PCI_AUTO_UPDATE_RESOURCES for some reason, you have a board that simply refuses to work with its resources updated beyond what they are when the device is powered up, set this to N. Everyone else will want this as Y. - diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 5003971476ec..362a1eec73a4 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -2,8 +2,8 @@ # Makefile for the PCI specific kernel interface routines under Linux. # -obj-y += pci.o -obj-$(CONFIG_PCI_AUTO) += pci-auto.o +obj-$(CONFIG_PCI_AUTO) := pci.o pci-auto.o +obj-$(CONFIG_PCI_NEW) := pci-new.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c new file mode 100644 index 000000000000..097eb8811120 --- /dev/null +++ b/arch/sh/drivers/pci/pci-new.c @@ -0,0 +1,248 @@ +/* + * New-style PCI core. + * + * Copyright (c) 2002 M. R. Brown + * Copyright (c) 2004 - 2009 Paul Mundt + * + * 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. + */ +#include +#include +#include +#include +#include + +static int __init pcibios_init(void) +{ + struct pci_channel *p; + struct pci_bus *bus; + int busno; + + /* init channels */ + busno = 0; + for (p = board_pci_channels; p->init; p++) { + if (p->init(p) == 0) + p->enabled = 1; + else + pr_err("Unable to init pci channel %d\n", busno); + busno++; + } + + /* scan the buses */ + busno = 0; + for (p = board_pci_channels; p->init; p++) { + if (p->enabled) { + bus = pci_scan_bus(busno, p->pci_ops, p); + busno = bus->subordinate + 1; + + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + pci_enable_bridges(bus); + } + } + + pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); + + dma_debug_add_bus(&pci_bus_type); + + return 0; +} +subsys_initcall(pcibios_init); + +static void pcibios_fixup_device_resources(struct pci_dev *dev, + struct pci_bus *bus) +{ + /* Update device resources. */ + struct pci_channel *chan = bus->sysdata; + unsigned long offset = 0; + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + if (!dev->resource[i].start) + continue; + if (dev->resource[i].flags & IORESOURCE_PCI_FIXED) + continue; + if (dev->resource[i].flags & IORESOURCE_IO) + offset = chan->io_base; + else if (dev->resource[i].flags & IORESOURCE_MEM) + offset = 0; + + dev->resource[i].start += offset; + dev->resource[i].end += offset; + } +} + + +/* + * Called after each bus is probed, but before its children + * are examined. + */ +void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_dev *dev = bus->self; + struct list_head *ln; + struct pci_channel *chan = bus->sysdata; + + if (!dev) { + bus->resource[0] = chan->io_resource; + bus->resource[1] = chan->mem_resource; + } + + for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { + dev = pci_dev_b(ln); + + if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) + pcibios_fixup_device_resources(dev, bus); + } +} + +void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res) +{ + struct pci_channel *chan = dev->sysdata; + unsigned long offset = 0; + + if (res->flags & IORESOURCE_IO) + offset = chan->io_base; + else if (res->flags & IORESOURCE_MEM) + offset = 0; + + region->start = res->start - offset; + region->end = res->end - offset; +} + +void __devinit +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region) +{ + struct pci_channel *chan = dev->sysdata; + unsigned long offset = 0; + + if (res->flags & IORESOURCE_IO) + offset = chan->io_base; + else if (res->flags & IORESOURCE_MEM) + offset = 0; + + res->start = region->start + offset; + res->end = region->end + offset; +} + +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) + __attribute__ ((weak)); + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + */ +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) +{ + if (res->flags & IORESOURCE_IO) { + resource_size_t start = res->start; + + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } + } +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for(idx=0; idx<6; idx++) { + if (!(mask & (1 << idx))) + continue; + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because " + "of resource collisions\n", pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (dev->resource[PCI_ROM_RESOURCE].start) + cmd |= PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { + printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +/* + * If we set up a device for bus mastering, we need to check and set + * the latency timer as it may not be properly set. + */ +static unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", + pci_name(dev), lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + +void __init pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} + +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + resource_size_t start = pci_resource_start(dev, bar); + resource_size_t len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (unlikely(!len || !start)) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + + /* + * Presently the IORESOURCE_MEM case is a bit special, most + * SH7751 style PCI controllers have PCI memory at a fixed + * location in the address space where no remapping is desired. + * With the IORESOURCE_MEM case more care has to be taken + * to inhibit page table mapping for legacy cores, but this is + * punted off to __ioremap(). + * -- PFM. + */ + if (flags & IORESOURCE_IO) + return ioport_map(start, len); + if (flags & IORESOURCE_MEM) + return ioremap(start, len); + + return NULL; +} +EXPORT_SYMBOL(pci_iomap); + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + iounmap(addr); +} +EXPORT_SYMBOL(pci_iounmap); + +EXPORT_SYMBOL(board_pci_channels); -- GitLab From 9833385131fc4e8c52f95320ab899051d1c06831 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 15:51:45 +0900 Subject: [PATCH 0407/6080] sh: pci: HAVE_PCI_MMAP support. Derived from the MIPS version, now uses pgprot_noncached(). Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 6 +++--- arch/sh/drivers/pci/pci-lib.c | 26 ++++++++++++++++++++++++++ arch/sh/include/asm/pci.h | 3 +++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 arch/sh/drivers/pci/pci-lib.c diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 362a1eec73a4..c8eab14843e5 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -1,9 +1,9 @@ # # Makefile for the PCI specific kernel interface routines under Linux. # - -obj-$(CONFIG_PCI_AUTO) := pci.o pci-auto.o -obj-$(CONFIG_PCI_NEW) := pci-new.o +obj-y += pci-lib.o +obj-$(CONFIG_PCI_AUTO) += pci.o pci-auto.o +obj-$(CONFIG_PCI_NEW) += pci-new.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c new file mode 100644 index 000000000000..1a43a350d574 --- /dev/null +++ b/arch/sh/drivers/pci/pci-lib.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include +#include + +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine) +{ + /* + * I/O space can be accessed via normal processor loads and stores on + * this platform but for now we elect not to do this and portable + * drivers should not do this anyway. + */ + if (mmap_state == pci_mmap_io) + return -EINVAL; + + /* + * Ignore write-combine; for now only return uncached mappings. + */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); +} diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 69cb615c3916..46afd449739d 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -40,6 +40,9 @@ extern struct pci_channel board_pci_channels[]; struct pci_dev; +#define HAVE_PCI_MMAP +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine); extern void pcibios_set_master(struct pci_dev *dev); static inline void pcibios_penalize_isa_irq(int irq, int active) -- GitLab From a3c0e0d0032d5bbfd7dc04827a257c717d432a5b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 16:14:29 +0900 Subject: [PATCH 0408/6080] sh: pci: Consolidate pcibios_align_resource() definitions. This introduces a saner pcibios_align_resource() that can be used regardless of whether pci-auto or pci-new are being used, and consolidates it in pci-lib.c. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7751/pci.c | 9 ++++--- arch/sh/drivers/pci/pci-lib.c | 42 +++++++++++++++++++++++++++++++ arch/sh/drivers/pci/pci-new.c | 23 ----------------- arch/sh/drivers/pci/pci.c | 23 ----------------- arch/sh/include/asm/pci.h | 5 +--- 5 files changed, 49 insertions(+), 53 deletions(-) diff --git a/arch/sh/boards/mach-se/7751/pci.c b/arch/sh/boards/mach-se/7751/pci.c index 203b2923fe7f..9ec64a416b30 100644 --- a/arch/sh/boards/mach-se/7751/pci.c +++ b/arch/sh/boards/mach-se/7751/pci.c @@ -30,6 +30,9 @@ #define PCIC_WRITE(x,v) writel((v), PCI_REG(x)) #define PCIC_READ(x) readl(PCI_REG(x)) +#define xPCIBIOS_MIN_IO board_pci_channels->io_resource->start +#define xPCIBIOS_MIN_MEM board_pci_channels->mem_resource->start + /* * Description: This function sets up and initializes the pcic, sets * up the BARS, maps the DRAM into the address space etc, etc. @@ -97,12 +100,12 @@ int __init pcibios_init_platform(void) * meaning all calls go straight through... use BUG_ON to * catch erroneous assumption. */ - BUG_ON(PCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE); + BUG_ON(xPCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE); - PCIC_WRITE(SH7751_PCIMBR, PCIBIOS_MIN_MEM); + PCIC_WRITE(SH7751_PCIMBR, xPCIBIOS_MIN_MEM); /* Set IOBR for window containing area specified in pci.h */ - PCIC_WRITE(SH7751_PCIIOBR, (PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK)); + PCIC_WRITE(SH7751_PCIIOBR, (xPCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK)); /* All done, may as well say so... */ printk("SH7751 PCI: Finished initialization of the PCI controller\n"); diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c index 1a43a350d574..8ab1a2d1b483 100644 --- a/arch/sh/drivers/pci/pci-lib.c +++ b/arch/sh/drivers/pci/pci-lib.c @@ -4,6 +4,41 @@ #include #include +unsigned long PCIBIOS_MIN_IO = 0x0000; +unsigned long PCIBIOS_MIN_MEM = 0; + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + */ +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) +{ + struct pci_dev *dev = data; + struct pci_channel *chan = dev->sysdata; + resource_size_t start = res->start; + + if (res->flags & IORESOURCE_IO) { + if (start < PCIBIOS_MIN_IO + chan->io_resource->start) + start = PCIBIOS_MIN_IO + chan->io_resource->start; + + /* + * Put everything into 0x00-0xff region modulo 0x400. + */ + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } + } else if (res->flags & IORESOURCE_MEM) { + if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start) + start = PCIBIOS_MIN_MEM + chan->mem_resource->start; + } + + res->start = start; +} + int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { @@ -24,3 +59,10 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, vma->vm_end - vma->vm_start, vma->vm_page_prot); } + +#ifdef CONFIG_HOTPLUG +EXPORT_SYMBOL(pcibios_resource_to_bus); +EXPORT_SYMBOL(pcibios_bus_to_resource); +EXPORT_SYMBOL(PCIBIOS_MIN_IO); +EXPORT_SYMBOL(PCIBIOS_MIN_MEM); +#endif diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c index 097eb8811120..4e9251f3d090 100644 --- a/arch/sh/drivers/pci/pci-new.c +++ b/arch/sh/drivers/pci/pci-new.c @@ -129,29 +129,6 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, res->end = region->end + offset; } -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) - __attribute__ ((weak)); - -/* - * We need to avoid collisions with `mirrored' VGA ports - * and other strange ISA hardware, so we always want the - * addresses to be allocated in the 0x000-0x0ff region - * modulo 0x400. - */ -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) -{ - if (res->flags & IORESOURCE_IO) { - resource_size_t start = res->start; - - if (start & 0x300) { - start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } - } -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd, old_cmd; diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 6d659cd93c9d..f670988e033d 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -86,29 +86,6 @@ void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, res->end = region->end; } -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) - __attribute__ ((weak)); - -/* - * We need to avoid collisions with `mirrored' VGA ports - * and other strange ISA hardware, so we always want the - * addresses to be allocated in the 0x000-0x0ff region - * modulo 0x400. - */ -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) -{ - if (res->flags & IORESOURCE_IO) { - resource_size_t start = res->start; - - if (start & 0x300) { - start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } - } -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd, old_cmd; diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 46afd449739d..5212bf6dd4b1 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -33,10 +33,7 @@ struct pci_channel { */ extern struct pci_channel board_pci_channels[]; -/* ugly as hell, but makes drivers/pci/setup-res.c compile and work */ -#define __PCI_CHAN(bus) ((struct pci_channel *)bus->sysdata) -#define PCIBIOS_MIN_IO __PCI_CHAN(bus)->io_resource->start -#define PCIBIOS_MIN_MEM __PCI_CHAN(bus)->mem_resource->start +extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM; struct pci_dev; -- GitLab From 394b6d2fe624246e258a218dac68d44fe9a8411f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 16:18:46 +0900 Subject: [PATCH 0409/6080] sh: pci: Kill off unused pcibios_fixup(). This is left over cruft that hasn't been used by anything in a long time, kill off bits that weren't purged previously. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-snapgear.c | 5 ----- arch/sh/include/asm/pci.h | 1 - 2 files changed, 6 deletions(-) diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c index dd2c5df28307..b64f2b91be8e 100644 --- a/arch/sh/drivers/pci/ops-snapgear.c +++ b/arch/sh/drivers/pci/ops-snapgear.c @@ -85,8 +85,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) return irq; } - -void __init pcibios_fixup(void) -{ - /* Nothing to fixup .. */ -} diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 5212bf6dd4b1..e8265fd0bb6f 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -138,7 +138,6 @@ static inline void __iomem *__get_pci_io_base(unsigned long port, #endif /* Board-specific fixup routines. */ -void pcibios_fixup(void); int pcibios_init_platform(void); int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin); -- GitLab From 0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 16:38:00 +0900 Subject: [PATCH 0410/6080] sh: pci: Consolidate pci_iomap() and use the generic I/O base. This consolidates the pci_iomap() definitions and reworks how the I/O port base is handled. PCI channels can register their own I/O map base, or if none is provided, the system-wide generic I/O base is used instead. Functionally nothing changes, while this allows us to kill off lots of I/O address special casing and lookups. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-lib.c | 51 +++++++++++++++++++++++++++++++++++ arch/sh/drivers/pci/pci-new.c | 35 ------------------------ arch/sh/drivers/pci/pci.c | 35 ------------------------ arch/sh/include/asm/pci.h | 22 ++------------- arch/sh/kernel/io.c | 4 --- 5 files changed, 53 insertions(+), 94 deletions(-) diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c index 8ab1a2d1b483..654ffcc67d0a 100644 --- a/arch/sh/drivers/pci/pci-lib.c +++ b/arch/sh/drivers/pci/pci-lib.c @@ -60,6 +60,57 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, vma->vm_page_prot); } +static void __iomem *ioport_map_pci(struct pci_dev *dev, + unsigned long port, unsigned int nr) +{ + struct pci_channel *chan = dev->sysdata; + + if (!chan->io_map_base) + chan->io_map_base = generic_io_base; + + return (void __iomem *)(chan->io_map_base + port); +} + +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + resource_size_t start = pci_resource_start(dev, bar); + resource_size_t len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (unlikely(!len || !start)) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + + if (flags & IORESOURCE_IO) + return ioport_map_pci(dev, start, len); + + /* + * Presently the IORESOURCE_MEM case is a bit special, most + * SH7751 style PCI controllers have PCI memory at a fixed + * location in the address space where no remapping is desired. + * With the IORESOURCE_MEM case more care has to be taken + * to inhibit page table mapping for legacy cores, but this is + * punted off to __ioremap(). + * -- PFM. + */ + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + + return ioremap_nocache(start, len); + } + + return NULL; +} +EXPORT_SYMBOL(pci_iomap); + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + iounmap(addr); +} +EXPORT_SYMBOL(pci_iounmap); + #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pcibios_resource_to_bus); EXPORT_SYMBOL(pcibios_bus_to_resource); diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c index 4e9251f3d090..c92e65045c68 100644 --- a/arch/sh/drivers/pci/pci-new.c +++ b/arch/sh/drivers/pci/pci-new.c @@ -187,39 +187,4 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (unlikely(!len || !start)) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - - /* - * Presently the IORESOURCE_MEM case is a bit special, most - * SH7751 style PCI controllers have PCI memory at a fixed - * location in the address space where no remapping is desired. - * With the IORESOURCE_MEM case more care has to be taken - * to inhibit page table mapping for legacy cores, but this is - * punted off to __ioremap(). - * -- PFM. - */ - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) - return ioremap(start, len); - - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - iounmap(addr); -} -EXPORT_SYMBOL(pci_iounmap); - EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index f670988e033d..d39f24091ade 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -144,39 +144,4 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (unlikely(!len || !start)) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - - /* - * Presently the IORESOURCE_MEM case is a bit special, most - * SH7751 style PCI controllers have PCI memory at a fixed - * location in the address space where no remapping is desired. - * With the IORESOURCE_MEM case more care has to be taken - * to inhibit page table mapping for legacy cores, but this is - * punted off to __ioremap(). - * -- PFM. - */ - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) - return ioremap(start, len); - - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - iounmap(addr); -} -EXPORT_SYMBOL(pci_iounmap); - EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index e8265fd0bb6f..532428289772 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -26,6 +26,8 @@ struct pci_channel { int enabled; unsigned long reg_base; unsigned long io_base; + + unsigned long io_map_base; }; /* @@ -110,31 +112,11 @@ static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) } return 0; } - -static inline void __iomem *__get_pci_io_base(unsigned long port, - unsigned long size) -{ - struct pci_channel *p; - struct resource *res; - - for (p = board_pci_channels; p->init; p++) { - res = p->io_resource; - if (p->enabled && (port >= res->start) && - (port + size) <= (res->end + 1)) - return (void __iomem *)(p->io_base + port); - } - return NULL; -} #else static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) { return 0; } -static inline void __iomem *__get_pci_io_base(unsigned long port, - unsigned long size) -{ - return NULL; -} #endif /* Board-specific fixup routines. */ diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c index 59fb020718a3..4f85fffaa557 100644 --- a/arch/sh/kernel/io.c +++ b/arch/sh/kernel/io.c @@ -70,10 +70,6 @@ void __iomem *ioport_map(unsigned long port, unsigned int nr) if (ret) return ret; - ret = __get_pci_io_base(port, nr); - if (ret) - return ret; - return __ioport_map(port, nr); } EXPORT_SYMBOL(ioport_map); -- GitLab From 67667263674663767ddf4250bab2437a00ee780e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Apr 2009 10:49:25 +0200 Subject: [PATCH 0411/6080] ALSA: hda - Fix channels_max setting for CA0110 Added the missing definition of max channels for CA0110, which resulted in an error at opening PCM devices. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_ca0110.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index 7ec41daa3f0c..9398d92f18bd 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c @@ -309,7 +309,7 @@ static int ca0110_build_pcms(struct hda_codec *codec) info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0110_pcm_analog_playback; info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0]; info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = - spec->multiout.num_dacs * 2; + spec->multiout.max_channels; info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0110_pcm_analog_capture; info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs; info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; @@ -418,6 +418,7 @@ static void parse_line_outs(struct hda_codec *codec) } spec->multiout.dac_nids = spec->dacs; spec->multiout.num_dacs = n; + spec->multiout.max_channels = n * 2; } static void parse_hp_out(struct hda_codec *codec) -- GitLab From 7670dc41b51983b369f9adfb8694a580e7b0cef2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Apr 2009 10:51:11 +0200 Subject: [PATCH 0412/6080] ALSA: hda - Use snd_hda_codec_get_pincfg() in patch_ca0110.c Use the new function to reduce the access and allow the user setup via sysfs, too. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_ca0110.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index 9398d92f18bd..392d108c3558 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c @@ -408,8 +408,7 @@ static void parse_line_outs(struct hda_codec *codec) n = 0; for (i = 0; i < cfg->line_outs; i++) { nid = cfg->line_out_pins[i]; - def_conf = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_CONFIG_DEFAULT, 0); + def_conf = snd_hda_codec_get_pincfg(codec, nid); if (!def_conf) continue; /* invalid pin */ if (snd_hda_get_connections(codec, nid, &spec->dacs[i], 1) != 1) @@ -432,8 +431,7 @@ static void parse_hp_out(struct hda_codec *codec) if (!cfg->hp_outs) return; nid = cfg->hp_pins[0]; - def_conf = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_CONFIG_DEFAULT, 0); + def_conf = snd_hda_codec_get_pincfg(codec, nid); if (!def_conf) { cfg->hp_outs = 0; return; -- GitLab From 5438646724c34c2180664a57f862a1da8dd21db1 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 17 Apr 2009 20:44:27 +0000 Subject: [PATCH 0413/6080] ixgbe: fix link down initial state As reported by Andrew Lutomirski All the intel wired ethernet drivers were calling netif_carrier_off and netif_stop_queue (or variants) before calling register_netdevice This is incorrect behavior as was pointed out by davem, and causes ifconfig and friends to report a strange state before first link after the driver was loaded, since without a netif_carrier_off, the stack assumes carrier_on, but before register_netdev, netlink messages are not sent out telling link state. This apparently confused *some* versions of networkmanager. Signed-off-by: Jesse Brandeburg Reported-by: Andrew Lutomirski Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 0d9a3ac043a6..d5d9589ae086 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3459,6 +3459,8 @@ static int ixgbe_open(struct net_device *netdev) if (test_bit(__IXGBE_TESTING, &adapter->state)) return -EBUSY; + netif_carrier_off(netdev); + /* allocate transmit descriptors */ err = ixgbe_setup_all_tx_resources(adapter); if (err) @@ -4772,13 +4774,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* reset the hardware with the new settings */ hw->mac.ops.start_hw(hw); - netif_carrier_off(netdev); - strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); if (err) goto err_register; + /* carrier off reporting is important to ethtool even BEFORE open */ + netif_carrier_off(netdev); + #ifdef CONFIG_IXGBE_DCA if (dca_add_requester(&pdev->dev) == 0) { adapter->flags |= IXGBE_FLAG_DCA_ENABLED; -- GitLab From 3a6d1bc4163fee27c312184d5f1a9cc1e110d300 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 17 Apr 2009 20:44:29 +0000 Subject: [PATCH 0414/6080] ixgb: fix link down initial state As reported by Andrew Lutomirski All the intel wired ethernet drivers were calling netif_carrier_off and netif_stop_queue (or variants) before calling register_netdevice This is incorrect behavior as was pointed out by davem, and causes ifconfig and friends to report a strange state before first link after the driver was loaded, since without a netif_carrier_off, the stack assumes carrier_on, but before register_netdev, netlink messages are not sent out telling link state. This apparently confused *some* versions of networkmanager. in addition this driver appeared to need a netif_start_queue at the end of open. Signed-off-by: Jesse Brandeburg Reported-by: Andrew Lutomirski Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgb/ixgb_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 4a0826b8f6f2..ff741ca110f5 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -471,10 +471,8 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto err_register; - /* we're going to reset, so assume we have no link for now */ - + /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(netdev); - netif_stop_queue(netdev); DPRINTK(PROBE, INFO, "Intel(R) PRO/10GbE Network Connection\n"); ixgb_check_options(adapter); @@ -592,6 +590,8 @@ ixgb_open(struct net_device *netdev) if (err) goto err_setup_tx; + netif_carrier_off(netdev); + /* allocate receive descriptors */ err = ixgb_setup_rx_resources(adapter); @@ -602,6 +602,8 @@ ixgb_open(struct net_device *netdev) if (err) goto err_up; + netif_start_queue(netdev); + return 0; err_up: -- GitLab From b168dfc51604ec293db16dc4d558043585578a2d Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 17 Apr 2009 20:44:32 +0000 Subject: [PATCH 0415/6080] igb: fix link down inital state As reported by Andrew Lutomirski All the intel wired ethernet drivers were calling netif_carrier_off and netif_stop_queue (or variants) before calling register_netdevice This is incorrect behavior as was pointed out by davem, and causes ifconfig and friends to report a strange state before first link after the driver was loaded, since without a netif_carrier_off, the stack assumes carrier_on, but before register_netdev, netlink messages are not sent out telling link state. This apparently confused *some* versions of networkmanager. Signed-off-by: Jesse Brandeburg Reported-by: Andrew Lutomirski Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 08c801490c72..ceaa58554679 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1442,15 +1442,14 @@ static int __devinit igb_probe(struct pci_dev *pdev, * driver. */ igb_get_hw_control(adapter); - /* tell the stack to leave us alone until igb_open() is called */ - netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); - strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); if (err) goto err_register; + /* carrier off reporting is important to ethtool even BEFORE open */ + netif_carrier_off(netdev); + #ifdef CONFIG_IGB_DCA if (dca_add_requester(&pdev->dev) == 0) { adapter->flags |= IGB_FLAG_DCA_ENABLED; @@ -1699,6 +1698,8 @@ static int igb_open(struct net_device *netdev) if (test_bit(__IGB_TESTING, &adapter->state)) return -EBUSY; + netif_carrier_off(netdev); + /* allocate transmit descriptors */ err = igb_setup_all_tx_resources(adapter); if (err) -- GitLab From 9c563d20671e5fbe3045fd79c18b306ccb77b0b6 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 17 Apr 2009 20:44:34 +0000 Subject: [PATCH 0416/6080] e1000e: indicate link down at load As reported by Andrew Lutomirski All the intel wired ethernet drivers were calling netif_carrier_off and netif_stop_queue (or variants) before calling register_netdevice This is incorrect behavior as was pointed out by davem, and causes ifconfig and friends to report a strange state before first link after the driver was loaded, since without a netif_carrier_off, the stack assumes carrier_on, but before register_netdev, netlink messages are not sent out telling link state. This apparently confused *some* versions of networkmanager. Andy tested this for e1000e and confirmed it was working for him. see thread: http://marc.info/?l=linux-netdev&m=123946479705636&w=2 Signed-off-by: Jesse Brandeburg Tested-by: Andy Lutomirski Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000e/netdev.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 1693ed116b16..c0ff550262ff 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -3072,6 +3072,8 @@ static int e1000_open(struct net_device *netdev) if (test_bit(__E1000_TESTING, &adapter->state)) return -EBUSY; + netif_carrier_off(netdev); + /* allocate transmit descriptors */ err = e1000e_setup_tx_resources(adapter); if (err) @@ -5037,15 +5039,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (!(adapter->flags & FLAG_HAS_AMT)) e1000_get_hw_control(adapter); - /* tell the stack to leave us alone until e1000_open() is called */ - netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); - strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); if (err) goto err_register; + /* carrier off reporting is important to ethtool even BEFORE open */ + netif_carrier_off(netdev); + e1000_print_device_info(adapter); return 0; -- GitLab From eb62efd287fe6e12d18083287e38e4a811c28256 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Fri, 17 Apr 2009 20:44:36 +0000 Subject: [PATCH 0417/6080] e1000: init link state correctly As reported by Andrew Lutomirski All the intel wired ethernet drivers were calling netif_carrier_off and netif_stop_queue (or variants) before calling register_netdevice This is incorrect behavior as was pointed out by davem, and causes ifconfig and friends to report a strange state before first link after the driver was loaded. This apparently confused *some* versions of networkmanager. Andy tested this for e1000e and confirmed it was working for him. Signed-off-by: Jesse Brandeburg Reported-by: Andrew Lutomirski Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ef12931d302a..9bdcf4d2ab19 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1234,15 +1234,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev, !e1000_check_mng_mode(hw)) e1000_get_hw_control(adapter); - /* tell the stack to leave us alone until e1000_open() is called */ - netif_carrier_off(netdev); - netif_stop_queue(netdev); - strcpy(netdev->name, "eth%d"); err = register_netdev(netdev); if (err) goto err_register; + /* carrier off reporting is important to ethtool even BEFORE open */ + netif_carrier_off(netdev); + DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n"); cards_found++; @@ -1441,6 +1440,8 @@ static int e1000_open(struct net_device *netdev) if (test_bit(__E1000_TESTING, &adapter->flags)) return -EBUSY; + netif_carrier_off(netdev); + /* allocate transmit descriptors */ err = e1000_setup_all_tx_resources(adapter); if (err) -- GitLab From 99f95f117848088f2708b45c70be73152e78bb8a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 18:24:57 +0900 Subject: [PATCH 0418/6080] sh: pci: Rework fixed region checks in ioremap(). Not all PCI channels have non-translatable memory windows, this is a special property of the on-chip PCIC with its 0xfd00... mapping, handle this explicitly. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 29 +++++++++++------------------ arch/sh/mm/ioremap_32.c | 14 +++++++------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 532428289772..82a9369511b5 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -90,7 +90,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) #endif -#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -99,24 +98,18 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strategy_parameter = ~0UL; } -static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) -{ - struct pci_channel *p; - struct resource *res; - - for (p = board_pci_channels; p->init; p++) { - res = p->mem_resource; - if (p->enabled && (phys_addr >= res->start) && - (phys_addr + size) <= (res->end + 1)) - return 1; - } - return 0; -} +#ifdef CONFIG_SUPERH32 +/* + * If we're on an SH7751 or SH7780 PCI controller, PCI memory is mapped + * at the end of the address space in a special non-translatable area. + */ +#define PCI_MEM_FIXED_START 0xfd000000 +#define PCI_MEM_FIXED_END (PCI_MEM_FIXED_START + 0x01000000) + +#define is_pci_memory_fixed_range(s, e) \ + ((s) >= PCI_MEM_FIXED_START && (e) < PCI_MEM_FIXED_END) #else -static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) -{ - return 0; -} +#define is_pci_memory_fixed_range(s, e) (0) #endif /* Board-specific fixup routines. */ diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c index 7e04cc8f3b9b..da2f4186f2cd 100644 --- a/arch/sh/mm/ioremap_32.c +++ b/arch/sh/mm/ioremap_32.c @@ -46,17 +46,15 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, return NULL; /* - * If we're on an SH7751 or SH7780 PCI controller, PCI memory is - * mapped at the end of the address space (typically 0xfd000000) - * in a non-translatable area, so mapping through page tables for - * this area is not only pointless, but also fundamentally - * broken. Just return the physical address instead. + * If we're in the fixed PCI memory range, mapping through page + * tables is not only pointless, but also fundamentally broken. + * Just return the physical address instead. * * For boards that map a small PCI memory aperture somewhere in * P1/P2 space, ioremap() will already do the right thing, * and we'll never get this far. */ - if (__is_pci_memory(phys_addr, size)) + if (is_pci_memory_fixed_range(phys_addr, size)) return (void __iomem *)phys_addr; #if !defined(CONFIG_PMB_FIXED) @@ -121,7 +119,9 @@ void __iounmap(void __iomem *addr) unsigned long seg = PXSEG(vaddr); struct vm_struct *p; - if (seg < P3SEG || vaddr >= P3_ADDR_MAX || __is_pci_memory(vaddr, 0)) + if (seg < P3SEG || vaddr >= P3_ADDR_MAX) + return; + if (is_pci_memory_fixed_range(vaddr, 0)) return; #ifdef CONFIG_PMB -- GitLab From 7eebb0b28f755e297d355a205bb04945b256db6b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 17 Apr 2009 22:03:10 +0000 Subject: [PATCH 0419/6080] loopback: packet drops accounting We can in some situations drop packets in netif_rx() loopback driver does not report these (unlikely) drops to its stats, and incorrectly change packets/bytes counts. After this patch applied, "ifconfig lo" can reports these drops as in : # ifconfig lo lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:692562900 errors:3228 dropped:3228 overruns:0 frame:0 TX packets:692562900 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:2865674174 (2.6 GiB) TX bytes:2865674174 (2.6 GiB) I initialy chose to reflect those errors only in tx_dropped/tx_errors, but David convinced me that it was really RX errors, as loopback_xmit() really starts a RX process. (calling eth_type_trans() for example, that itself pulls the ethernet header) These errors are accounted in rx_dropped/rx_errors. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/loopback.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index b7d438a367f3..6f71157bea8e 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -62,6 +62,7 @@ struct pcpu_lstats { unsigned long packets; unsigned long bytes; + unsigned long drops; }; /* @@ -71,18 +72,22 @@ struct pcpu_lstats { static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) { struct pcpu_lstats *pcpu_lstats, *lb_stats; + int len; skb_orphan(skb); - skb->protocol = eth_type_trans(skb,dev); + skb->protocol = eth_type_trans(skb, dev); /* it's OK to use per_cpu_ptr() because BHs are off */ pcpu_lstats = dev->ml_priv; lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id()); - lb_stats->bytes += skb->len; - lb_stats->packets++; - netif_rx(skb); + len = skb->len; + if (likely(netif_rx(skb) == NET_RX_SUCCESS)) { + lb_stats->bytes += len; + lb_stats->packets++; + } else + lb_stats->drops++; return 0; } @@ -93,6 +98,7 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev) struct net_device_stats *stats = &dev->stats; unsigned long bytes = 0; unsigned long packets = 0; + unsigned long drops = 0; int i; pcpu_lstats = dev->ml_priv; @@ -102,11 +108,14 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev) lb_stats = per_cpu_ptr(pcpu_lstats, i); bytes += lb_stats->bytes; packets += lb_stats->packets; + drops += lb_stats->drops; } stats->rx_packets = packets; stats->tx_packets = packets; - stats->rx_bytes = bytes; - stats->tx_bytes = bytes; + stats->rx_dropped = drops; + stats->rx_errors = drops; + stats->rx_bytes = bytes; + stats->tx_bytes = bytes; return stats; } -- GitLab From a0f82f64e26929776c58a5c93c2ecb38e3d82815 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Sun, 19 Apr 2009 09:43:48 +0000 Subject: [PATCH 0420/6080] syncookies: remove last_synq_overflow from struct tcp_sock last_synq_overflow eats 4 or 8 bytes in struct tcp_sock, even though it is only used when a listening sockets syn queue is full. We can (ab)use rx_opt.ts_recent_stamp to store the same information; it is not used otherwise as long as a socket is in listen state. Move linger2 around to avoid splitting struct mtu_probe across cacheline boundary on 32 bit arches. Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- include/linux/tcp.h | 4 +--- include/net/tcp.h | 13 +++++++++++++ net/ipv4/syncookies.c | 5 ++--- net/ipv6/syncookies.c | 4 ++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 9d5078bd23a3..8afac76cd748 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -377,7 +377,7 @@ struct tcp_sock { unsigned int keepalive_time; /* time before keep alive takes place */ unsigned int keepalive_intvl; /* time interval between keep alive probes */ - unsigned long last_synq_overflow; + int linger2; /* Receiver side RTT estimation */ struct { @@ -406,8 +406,6 @@ struct tcp_sock { /* TCP MD5 Signagure Option information */ struct tcp_md5sig_info *md5sig_info; #endif - - int linger2; }; static inline struct tcp_sock *tcp_sk(const struct sock *sk) diff --git a/include/net/tcp.h b/include/net/tcp.h index 1b94b9bfe2dc..b55b4891029e 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -265,6 +265,19 @@ static inline int tcp_too_many_orphans(struct sock *sk, int num) atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]); } +/* syncookies: remember time of last synqueue overflow */ +static inline void tcp_synq_overflow(struct sock *sk) +{ + tcp_sk(sk)->rx_opt.ts_recent_stamp = jiffies; +} + +/* syncookies: no recent synqueue overflow on this listening socket? */ +static inline int tcp_synq_no_recent_overflow(const struct sock *sk) +{ + unsigned long last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp; + return time_after(jiffies, last_overflow + TCP_TIMEOUT_INIT); +} + extern struct proto tcp_prot; #define TCP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.tcp_statistics, field) diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index b35a950d2e06..cd2b97f1b6e1 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -161,13 +161,12 @@ static __u16 const msstab[] = { */ __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp) { - struct tcp_sock *tp = tcp_sk(sk); const struct iphdr *iph = ip_hdr(skb); const struct tcphdr *th = tcp_hdr(skb); int mssind; const __u16 mss = *mssp; - tp->last_synq_overflow = jiffies; + tcp_synq_overflow(sk); /* XXX sort msstab[] by probability? Binary search? */ for (mssind = 0; mss > msstab[mssind + 1]; mssind++) @@ -268,7 +267,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, if (!sysctl_tcp_syncookies || !th->ack) goto out; - if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) || + if (tcp_synq_no_recent_overflow(sk) || (mss = cookie_check(skb, cookie)) == 0) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); goto out; diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 711175e0571f..8c2513982b61 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -131,7 +131,7 @@ __u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp) int mssind; const __u16 mss = *mssp; - tcp_sk(sk)->last_synq_overflow = jiffies; + tcp_synq_overflow(sk); for (mssind = 0; mss > msstab[mssind + 1]; mssind++) ; @@ -175,7 +175,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) if (!sysctl_tcp_syncookies || !th->ack) goto out; - if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) || + if (tcp_synq_no_recent_overflow(sk) || (mss = cookie_check(skb, cookie)) == 0) { NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); goto out; -- GitLab From e79066a659b893debe19010179d3f3f015d76d1c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 18:29:22 +0900 Subject: [PATCH 0421/6080] sh: pci: New-style controller registration. This moves off of the board_pci_channels[] approach for bus registration and over to a cleaner register_pci_controller(), all derived from the MIPS code. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-new.c | 97 ++++++++++++++++++++++++-------- arch/sh/drivers/pci/pci-sh7780.c | 87 +++++++++++++--------------- arch/sh/include/asm/pci.h | 29 ++++++---- 3 files changed, 130 insertions(+), 83 deletions(-) diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c index c92e65045c68..78b7292c6aa8 100644 --- a/arch/sh/drivers/pci/pci-new.c +++ b/arch/sh/drivers/pci/pci-new.c @@ -13,40 +13,90 @@ #include #include #include +#include -static int __init pcibios_init(void) +/* + * The PCI controller list. + */ +static struct pci_channel *hose_head, **hose_tail = &hose_head; + +static int pci_initialized; + +static void __devinit pcibios_scanbus(struct pci_channel *hose) { - struct pci_channel *p; + static int next_busno; struct pci_bus *bus; - int busno; - - /* init channels */ - busno = 0; - for (p = board_pci_channels; p->init; p++) { - if (p->init(p) == 0) - p->enabled = 1; - else - pr_err("Unable to init pci channel %d\n", busno); - busno++; + + /* Catch botched conversion attempts */ + BUG_ON(hose->init); + + bus = pci_scan_bus(next_busno, hose->pci_ops, hose); + if (bus) { + next_busno = bus->subordinate + 1; + /* Don't allow 8-bit bus number overflow inside the hose - + reserve some space for bridges. */ + if (next_busno > 224) + next_busno = 0; + + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + pci_enable_bridges(bus); } +} - /* scan the buses */ - busno = 0; - for (p = board_pci_channels; p->init; p++) { - if (p->enabled) { - bus = pci_scan_bus(busno, p->pci_ops, p); - busno = bus->subordinate + 1; +static DEFINE_MUTEX(pci_scan_mutex); - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - pci_enable_bridges(bus); - } +void __devinit register_pci_controller(struct pci_channel *hose) +{ + if (request_resource(&iomem_resource, hose->mem_resource) < 0) + goto out; + if (request_resource(&ioport_resource, hose->io_resource) < 0) { + release_resource(hose->mem_resource); + goto out; + } + + *hose_tail = hose; + hose_tail = &hose->next; + + /* + * Do not panic here but later - this might hapen before console init. + */ + if (!hose->io_map_base) { + printk(KERN_WARNING + "registering PCI controller with io_map_base unset\n"); + } + + /* + * Scan the bus if it is register after the PCI subsystem + * initialization. + */ + if (pci_initialized) { + mutex_lock(&pci_scan_mutex); + pcibios_scanbus(hose); + mutex_unlock(&pci_scan_mutex); } + return; + +out: + printk(KERN_WARNING + "Skipping PCI bus scan due to resource conflict\n"); +} + +static int __init pcibios_init(void) +{ + struct pci_channel *hose; + + /* Scan all of the recorded PCI controllers. */ + for (hose = hose_head; hose; hose = hose->next) + pcibios_scanbus(hose); + pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); dma_debug_add_bus(&pci_bus_type); + pci_initialized = 1; + return 0; } subsys_initcall(pcibios_init); @@ -74,7 +124,6 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev, } } - /* * Called after each bus is probed, but before its children * are examined. @@ -186,5 +235,3 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) { pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } - -EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index f02d9dfcf252..4dd6e3b94a67 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -15,11 +15,47 @@ #include #include "pci-sh4.h" -static int __init sh7780_pci_init(struct pci_channel *chan) +extern u8 pci_cache_line_size; + +static struct resource sh7785_io_resource = { + .name = "SH7785_IO", + .start = SH7780_PCI_IO_BASE, + .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7785_mem_resource = { + .name = "SH7785_mem", + .start = SH7780_PCI_MEMORY_BASE, + .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +static struct pci_channel sh7780_pci_controller = { + .pci_ops = &sh4_pci_ops, + .mem_resource = &sh7785_mem_resource, + .io_resource = &sh7785_io_resource, +}; + +static struct sh4_pci_address_map sh7780_pci_map = { + .window0 = { +#if defined(CONFIG_32BIT) + .base = SH7780_32BIT_DDR_BASE_ADDR, + .size = 0x40000000, +#else + .base = SH7780_CS0_BASE_ADDR, + .size = 0x20000000, +#endif + }, +}; + +static int __init sh7780_pci_init(void) { + struct pci_channel *chan = &sh7780_pci_controller; unsigned int id; const char *type = NULL; int ret; + u32 word; printk(KERN_NOTICE "PCI: Starting intialization.\n"); @@ -54,52 +90,6 @@ static int __init sh7780_pci_init(struct pci_channel *chan) if ((ret = sh4_pci_check_direct(chan)) != 0) return ret; - /* - * Platform specific initialization (BSC registers, and memory space - * mapping) will be called via the platform defined function - * pcibios_init_platform(). - */ - return pcibios_init_platform(); -} - -extern u8 pci_cache_line_size; - -static struct resource sh7785_io_resource = { - .name = "SH7785_IO", - .start = SH7780_PCI_IO_BASE, - .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7785_mem_resource = { - .name = "SH7785_mem", - .start = SH7780_PCI_MEMORY_BASE, - .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -struct pci_channel board_pci_channels[] = { - { sh7780_pci_init, &sh4_pci_ops, &sh7785_io_resource, &sh7785_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - -static struct sh4_pci_address_map sh7780_pci_map = { - .window0 = { -#if defined(CONFIG_32BIT) - .base = SH7780_32BIT_DDR_BASE_ADDR, - .size = 0x40000000, -#else - .base = SH7780_CS0_BASE_ADDR, - .size = 0x20000000, -#endif - }, -}; - -int __init pcibios_init_platform(void) -{ - struct pci_channel *chan = &board_pci_channels[0]; - u32 word; - /* * Set the class and sub-class codes. */ @@ -153,5 +143,8 @@ int __init pcibios_init_platform(void) __set_io_port_base(SH7780_PCI_IO_BASE); + register_pci_controller(chan); + return 0; } +arch_initcall(sh7780_pci_init); diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 82a9369511b5..e057ebdb4618 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -17,17 +17,22 @@ * external) PCI controllers. */ struct pci_channel { - int (*init)(struct pci_channel *chan); - struct pci_ops *pci_ops; - struct resource *io_resource; - struct resource *mem_resource; - int first_devfn; - int last_devfn; - int enabled; - unsigned long reg_base; - unsigned long io_base; - - unsigned long io_map_base; + struct pci_channel *next; + + int (*init)(struct pci_channel *chan); + + struct pci_ops *pci_ops; + struct resource *io_resource; + struct resource *mem_resource; + + int first_devfn; + int last_devfn; + int enabled; + + unsigned long reg_base; + unsigned long io_base; + + unsigned long io_map_base; }; /* @@ -35,6 +40,8 @@ struct pci_channel { */ extern struct pci_channel board_pci_channels[]; +extern void register_pci_controller(struct pci_channel *hose); + extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM; struct pci_dev; -- GitLab From 09cfeb133e3cac39b8b9a2cb1d8ab4f77e396248 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 18:42:00 +0900 Subject: [PATCH 0422/6080] sh: pci: Track io and mem_offset per-channel. This implements a per-hose offset for I/O and mem resources. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-new.c | 18 +++++++++--------- arch/sh/drivers/pci/pci-sh7780.c | 2 ++ arch/sh/include/asm/pci.h | 3 +++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c index 78b7292c6aa8..e8ac8daafc33 100644 --- a/arch/sh/drivers/pci/pci-new.c +++ b/arch/sh/drivers/pci/pci-new.c @@ -105,7 +105,7 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus) { /* Update device resources. */ - struct pci_channel *chan = bus->sysdata; + struct pci_channel *hose = bus->sysdata; unsigned long offset = 0; int i; @@ -115,9 +115,9 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev, if (dev->resource[i].flags & IORESOURCE_PCI_FIXED) continue; if (dev->resource[i].flags & IORESOURCE_IO) - offset = chan->io_base; + offset = hose->io_offset; else if (dev->resource[i].flags & IORESOURCE_MEM) - offset = 0; + offset = hose->mem_offset; dev->resource[i].start += offset; dev->resource[i].end += offset; @@ -150,13 +150,13 @@ void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res) { - struct pci_channel *chan = dev->sysdata; + struct pci_channel *hose = dev->sysdata; unsigned long offset = 0; if (res->flags & IORESOURCE_IO) - offset = chan->io_base; + offset = hose->io_offset; else if (res->flags & IORESOURCE_MEM) - offset = 0; + offset = hose->mem_offset; region->start = res->start - offset; region->end = res->end - offset; @@ -166,13 +166,13 @@ void __devinit pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, struct pci_bus_region *region) { - struct pci_channel *chan = dev->sysdata; + struct pci_channel *hose = dev->sysdata; unsigned long offset = 0; if (res->flags & IORESOURCE_IO) - offset = chan->io_base; + offset = hose->io_offset; else if (res->flags & IORESOURCE_MEM) - offset = 0; + offset = hose->mem_offset; res->start = region->start + offset; res->end = region->end + offset; diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 4dd6e3b94a67..57a3b870a276 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -34,7 +34,9 @@ static struct resource sh7785_mem_resource = { static struct pci_channel sh7780_pci_controller = { .pci_ops = &sh4_pci_ops, .mem_resource = &sh7785_mem_resource, + .mem_offset = 0x00000000, .io_resource = &sh7785_io_resource, + .io_offset = 0x00000000, }; static struct sh4_pci_address_map sh7780_pci_map = { diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index e057ebdb4618..0be20521a1fe 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -25,6 +25,9 @@ struct pci_channel { struct resource *io_resource; struct resource *mem_resource; + unsigned long io_offset; + unsigned long mem_offset; + int first_devfn; int last_devfn; int enabled; -- GitLab From 5160d3f782a5e0cdb3bdaa8a891a1fb9d9ab83ec Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 18:47:21 +0900 Subject: [PATCH 0423/6080] sh: pci: Consolidate bus<->resource mapping in pci-lib. Now that the io and mem offsets are tracked accordingly, the pci-new version of the bus<->resource mappers can be used generically. This moves them in to pci-lib. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-lib.c | 31 +++++++++++++++++++++++++++++++ arch/sh/drivers/pci/pci-new.c | 31 ------------------------------- arch/sh/drivers/pci/pci.c | 14 -------------- 3 files changed, 31 insertions(+), 45 deletions(-) diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c index 654ffcc67d0a..9fd3af9db462 100644 --- a/arch/sh/drivers/pci/pci-lib.c +++ b/arch/sh/drivers/pci/pci-lib.c @@ -39,6 +39,37 @@ void pcibios_align_resource(void *data, struct resource *res, res->start = start; } +void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res) +{ + struct pci_channel *hose = dev->sysdata; + unsigned long offset = 0; + + if (res->flags & IORESOURCE_IO) + offset = hose->io_offset; + else if (res->flags & IORESOURCE_MEM) + offset = hose->mem_offset; + + region->start = res->start - offset; + region->end = res->end - offset; +} + +void __devinit +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region) +{ + struct pci_channel *hose = dev->sysdata; + unsigned long offset = 0; + + if (res->flags & IORESOURCE_IO) + offset = hose->io_offset; + else if (res->flags & IORESOURCE_MEM) + offset = hose->mem_offset; + + res->start = region->start + offset; + res->end = region->end + offset; +} + int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c index e8ac8daafc33..9d426147802b 100644 --- a/arch/sh/drivers/pci/pci-new.c +++ b/arch/sh/drivers/pci/pci-new.c @@ -147,37 +147,6 @@ void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) } } -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_channel *hose = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - region->start = res->start - offset; - region->end = res->end - offset; -} - -void __devinit -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_channel *hose = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - res->start = region->start + offset; - res->end = region->end + offset; -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd, old_cmd; diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index d39f24091ade..c15a6f0ad500 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -72,20 +72,6 @@ void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) pci_read_bridge_bases(bus); } -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - region->start = res->start; - region->end = res->end; -} - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - res->start = region->start; - res->end = region->end; -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd, old_cmd; -- GitLab From 3f8daeacd7ed7a502daf0998e2515cea4f467f21 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 18:53:41 +0900 Subject: [PATCH 0424/6080] sh: pci: Consolidate the remaining common bits. This moves the remaining common bits in to pci-lib. Thereby reducing pci.c/pci-new.c to simple bus fixups and controller registration. As more platforms are moved over, the old code will disappear completely and the pci-new bits will be rolled in to pci-lib, eventually replacing pci.c completely. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-lib.c | 64 +++++++++++++++++++++++++++++++++++ arch/sh/drivers/pci/pci-new.c | 58 ------------------------------- arch/sh/drivers/pci/pci.c | 58 ------------------------------- 3 files changed, 64 insertions(+), 116 deletions(-) diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c index 9fd3af9db462..ea8362945849 100644 --- a/arch/sh/drivers/pci/pci-lib.c +++ b/arch/sh/drivers/pci/pci-lib.c @@ -70,6 +70,70 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, res->end = region->end + offset; } +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1<resource[idx]; + if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) + continue; + if ((idx == PCI_ROM_RESOURCE) && + (!(r->flags & IORESOURCE_ROM_ENABLE))) + continue; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available " + "because of resource collisions\n", + pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +/* + * If we set up a device for bus mastering, we need to check and set + * the latency timer as it may not be properly set. + */ +static unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", + pci_name(dev), lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + +void __init pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} + int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c index 9d426147802b..8c0b136eecb3 100644 --- a/arch/sh/drivers/pci/pci-new.c +++ b/arch/sh/drivers/pci/pci-new.c @@ -146,61 +146,3 @@ void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) pcibios_fixup_device_resources(dev, bus); } } - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for(idx=0; idx<6; idx++) { - if (!(mask & (1 << idx))) - continue; - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", pci_name(dev)); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (dev->resource[PCI_ROM_RESOURCE].start) - cmd |= PCI_COMMAND_MEMORY; - if (cmd != old_cmd) { - printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", - pci_name(dev), old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - -/* - * If we set up a device for bus mastering, we need to check and set - * the latency timer as it may not be properly set. - */ -static unsigned int pcibios_max_latency = 255; - -void pcibios_set_master(struct pci_dev *dev) -{ - u8 lat; - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - if (lat < 16) - lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; - else if (lat > pcibios_max_latency) - lat = pcibios_max_latency; - else - return; - printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", - pci_name(dev), lat); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c15a6f0ad500..8c332b2a4641 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -72,62 +72,4 @@ void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) pci_read_bridge_bases(bus); } -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for(idx=0; idx<6; idx++) { - if (!(mask & (1 << idx))) - continue; - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", pci_name(dev)); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (dev->resource[PCI_ROM_RESOURCE].start) - cmd |= PCI_COMMAND_MEMORY; - if (cmd != old_cmd) { - printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", - pci_name(dev), old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - -/* - * If we set up a device for bus mastering, we need to check and set - * the latency timer as it may not be properly set. - */ -static unsigned int pcibios_max_latency = 255; - -void pcibios_set_master(struct pci_dev *dev) -{ - u8 lat; - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - if (lat < 16) - lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; - else if (lat > pcibios_max_latency) - lat = pcibios_max_latency; - else - return; - printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", - pci_name(dev), lat); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - EXPORT_SYMBOL(board_pci_channels); -- GitLab From 5ba7205fc49ff72e88784c94fb661f93e7ae7d36 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 19:00:32 +0900 Subject: [PATCH 0425/6080] sh: pci: Kill off the now unused hose->io_base. Nothing is using this any more, so kill it off. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/pci-sh7751.c | 8 -------- arch/sh/drivers/pci/pci-sh7780.c | 1 - arch/sh/include/asm/pci.h | 1 - 3 files changed, 10 deletions(-) diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index af8874436d2f..4c08fd7f665d 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -40,7 +40,6 @@ int __init sh7751_pci_init(struct pci_channel *chan) pr_debug("PCI: Starting intialization.\n"); chan->reg_base = 0xfe200000; - chan->io_base = 0xfe240000; /* check for SH7751/SH7751R hardware */ id = pci_read_reg(chan, SH7751_PCICONF0); @@ -136,13 +135,6 @@ int __init sh7751_pcic_init(struct pci_channel *chan, pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); pci_write_reg(chan, word , SH4_PCIMBR); - /* Map IO space into PCI IO window: - * IO addresses will be translated to the PCI IO window base address - */ - pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%lx\n", - chan->io_resource->start, chan->io_resource->end, - chan->io_base + chan->io_resource->start); - /* Make sure the MSB's of IO window are set to access PCI space * correctly */ word = chan->io_resource->start & SH4_PCIIOBR_MASK; diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 57a3b870a276..ae13ff925c61 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -62,7 +62,6 @@ static int __init sh7780_pci_init(void) printk(KERN_NOTICE "PCI: Starting intialization.\n"); chan->reg_base = 0xfe040000; - chan->io_base = 0xfe200000; /* Enable CPU access to the PCIC registers. */ __raw_writel(PCIECR_ENBL, PCIECR); diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 0be20521a1fe..f36c7899295b 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -33,7 +33,6 @@ struct pci_channel { int enabled; unsigned long reg_base; - unsigned long io_base; unsigned long io_map_base; }; -- GitLab From bb3396477bf46c7cae6bd04b969580277957966e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 19:26:45 +0900 Subject: [PATCH 0426/6080] sh: pci: Kill off superfluous lboxre2 pci fixups. This is a verbatim copy of the r2d one, use that instead. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 2 +- arch/sh/drivers/pci/fixups-lboxre2.c | 42 ---------------------------- 2 files changed, 1 insertion(+), 43 deletions(-) delete mode 100644 arch/sh/drivers/pci/fixups-lboxre2.c diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index c8eab14843e5..4cac866d55d4 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -22,5 +22,5 @@ obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o obj-$(CONFIG_SH_TITAN) += ops-titan.o obj-$(CONFIG_SH_LANDISK) += ops-landisk.o -obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o +obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-rts7751r2d.o obj-$(CONFIG_SH_CAYMAN) += ops-cayman.o diff --git a/arch/sh/drivers/pci/fixups-lboxre2.c b/arch/sh/drivers/pci/fixups-lboxre2.c deleted file mode 100644 index a82011d03cb0..000000000000 --- a/arch/sh/drivers/pci/fixups-lboxre2.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * arch/sh/drivers/pci/fixups-lboxre2.c - * - * L-BOX RE2 PCI fixups - * - * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * 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. - */ -#include -#include "pci-sh4.h" - -#define PCIMCR_MRSET_OFF 0xBFFFFFFF -#define PCIMCR_RFSH_OFF 0xFFFFFFFB - -int pci_fixup_pcic(struct pci_channel *chan) -{ - unsigned long bcr1, mcr; - - bcr1 = ctrl_inl(SH7751_BCR1); - bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ - pci_write_reg(chan, bcr1, SH4_PCIBCR1); - - /* Enable all interrupts, so we known what to fix */ - pci_write_reg(chan, 0x0000c3ff, SH4_PCIINTM); - pci_write_reg(chan, 0x0000380f, SH4_PCIAINTM); - pci_write_reg(chan, 0xfb900047, SH7751_PCICONF1); - pci_write_reg(chan, 0xab000001, SH7751_PCICONF4); - - mcr = ctrl_inl(SH7751_MCR); - mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; - pci_write_reg(chan, mcr, SH4_PCIMCR); - - pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5); - pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6); - pci_write_reg(chan, 0x0c000000, SH4_PCILAR0); - pci_write_reg(chan, 0x00000000, SH4_PCILAR1); - - return 0; -} -- GitLab From d556fcc101c4b0d57ac9742ab806a6bfed78eac1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 19:31:20 +0900 Subject: [PATCH 0427/6080] sh: pci: Flag the dreamcast BBA as IORESOURCE_PCI_FIXED. This isn't a real BAR, so prevent any attempts to move it, as we don't wish to encourage a bus luck by overzealous PCI initialization code. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/fixups-dreamcast.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 2bf85cf091e1..48c6381fffaa 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -41,6 +41,13 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev) */ dev->resource[1].start = p->io_resource->start + 0x100; dev->resource[1].end = dev->resource[1].start + 0x200 - 1; + + /* + * This is not a normal BAR, prevent any attempts to move + * the BAR, as this will result in a bus lock. + */ + dev->resource[1].flags |= IORESOURCE_PCI_FIXED; + /* * Redirect dma memory allocations to special memory window. */ -- GitLab From c563bf0965c86cc6087b09c34ca063fe96d6deca Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 19:39:57 +0900 Subject: [PATCH 0428/6080] sh: pci: Kill off dead references to is_pci_ioaddr and friends. Some old boards are still using this in their I/O routines, kill it off. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7751/io.c | 16 ---------------- arch/sh/boards/mach-snapgear/io.c | 16 ---------------- arch/sh/boards/mach-systemh/io.c | 16 ---------------- arch/sh/boards/mach-titan/io.c | 18 ------------------ 4 files changed, 66 deletions(-) diff --git a/arch/sh/boards/mach-se/7751/io.c b/arch/sh/boards/mach-se/7751/io.c index 6287ae570319..6e75bd4459e5 100644 --- a/arch/sh/boards/mach-se/7751/io.c +++ b/arch/sh/boards/mach-se/7751/io.c @@ -34,8 +34,6 @@ unsigned char sh7751se_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned char *)pci_ioaddr(port); else return (*port2adr(port)) & 0xff; } @@ -46,8 +44,6 @@ unsigned char sh7751se_inb_p(unsigned long port) if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - v = *(volatile unsigned char *)pci_ioaddr(port); else v = (*port2adr(port)) & 0xff; ctrl_delay(); @@ -58,8 +54,6 @@ unsigned short sh7751se_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned short *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else @@ -71,8 +65,6 @@ unsigned int sh7751se_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned int *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else @@ -85,8 +77,6 @@ void sh7751se_outb(unsigned char value, unsigned long port) if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; } @@ -95,8 +85,6 @@ void sh7751se_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; ctrl_delay(); @@ -106,8 +94,6 @@ void sh7751se_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned short *)pci_ioaddr(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else @@ -118,8 +104,6 @@ void sh7751se_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned long*)pci_ioaddr(port)) = value; else maybebadio(port); } diff --git a/arch/sh/boards/mach-snapgear/io.c b/arch/sh/boards/mach-snapgear/io.c index 0f4824264557..476650e42dbc 100644 --- a/arch/sh/boards/mach-snapgear/io.c +++ b/arch/sh/boards/mach-snapgear/io.c @@ -36,8 +36,6 @@ unsigned char snapgear_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned char *)pci_ioaddr(port); else return (*port2adr(port)) & 0xff; } @@ -48,8 +46,6 @@ unsigned char snapgear_inb_p(unsigned long port) if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - v = *(volatile unsigned char *)pci_ioaddr(port); else v = (*port2adr(port))&0xff; ctrl_delay(); @@ -60,8 +56,6 @@ unsigned short snapgear_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned short *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else @@ -73,8 +67,6 @@ unsigned int snapgear_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned int *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else @@ -87,8 +79,6 @@ void snapgear_outb(unsigned char value, unsigned long port) if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; } @@ -97,8 +87,6 @@ void snapgear_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; ctrl_delay(); @@ -108,8 +96,6 @@ void snapgear_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned short *)pci_ioaddr(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else @@ -120,8 +106,6 @@ void snapgear_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned long*)pci_ioaddr(port)) = value; else maybebadio(port); } diff --git a/arch/sh/boards/mach-systemh/io.c b/arch/sh/boards/mach-systemh/io.c index dec3db0ee933..15577ff1f715 100644 --- a/arch/sh/boards/mach-systemh/io.c +++ b/arch/sh/boards/mach-systemh/io.c @@ -35,8 +35,6 @@ unsigned char sh7751systemh_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned char *)pci_ioaddr(port); else if (port <= 0x3F1) return *(volatile unsigned char *)ETHER_IOMAP(port); else @@ -49,8 +47,6 @@ unsigned char sh7751systemh_inb_p(unsigned long port) if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - v = *(volatile unsigned char *)pci_ioaddr(port); else if (port <= 0x3F1) v = *(volatile unsigned char *)ETHER_IOMAP(port); else @@ -63,8 +59,6 @@ unsigned short sh7751systemh_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned short *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else if (port <= 0x3F1) @@ -78,8 +72,6 @@ unsigned int sh7751systemh_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned int *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else if (port <= 0x3F1) @@ -94,8 +86,6 @@ void sh7751systemh_outb(unsigned char value, unsigned long port) if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; else if (port <= 0x3F1) *(volatile unsigned char *)ETHER_IOMAP(port) = value; else @@ -106,8 +96,6 @@ void sh7751systemh_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; else if (port <= 0x3F1) *(volatile unsigned char *)ETHER_IOMAP(port) = value; else @@ -119,8 +107,6 @@ void sh7751systemh_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned short *)pci_ioaddr(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else if (port <= 0x3F1) @@ -133,8 +119,6 @@ void sh7751systemh_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned long*)pci_ioaddr(port)) = value; else maybebadio(port); } diff --git a/arch/sh/boards/mach-titan/io.c b/arch/sh/boards/mach-titan/io.c index 053b3ed2ed8d..0130e9826aca 100644 --- a/arch/sh/boards/mach-titan/io.c +++ b/arch/sh/boards/mach-titan/io.c @@ -17,8 +17,6 @@ u8 titan_inb(unsigned long port) { if (PXSEG(port)) return ctrl_inb(port); - else if (is_pci_ioaddr(port)) - return ctrl_inb(pci_ioaddr(port)); return ctrl_inw(port2adr(port)) & 0xff; } @@ -28,8 +26,6 @@ u8 titan_inb_p(unsigned long port) if (PXSEG(port)) v = ctrl_inb(port); - else if (is_pci_ioaddr(port)) - v = ctrl_inb(pci_ioaddr(port)); else v = ctrl_inw(port2adr(port)) & 0xff; ctrl_delay(); @@ -40,8 +36,6 @@ u16 titan_inw(unsigned long port) { if (PXSEG(port)) return ctrl_inw(port); - else if (is_pci_ioaddr(port)) - return ctrl_inw(pci_ioaddr(port)); else if (port >= 0x2000) return ctrl_inw(port2adr(port)); else @@ -53,8 +47,6 @@ u32 titan_inl(unsigned long port) { if (PXSEG(port)) return ctrl_inl(port); - else if (is_pci_ioaddr(port)) - return ctrl_inl(pci_ioaddr(port)); else if (port >= 0x2000) return ctrl_inw(port2adr(port)); else @@ -66,8 +58,6 @@ void titan_outb(u8 value, unsigned long port) { if (PXSEG(port)) ctrl_outb(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outb(value, pci_ioaddr(port)); else ctrl_outw(value, port2adr(port)); } @@ -76,8 +66,6 @@ void titan_outb_p(u8 value, unsigned long port) { if (PXSEG(port)) ctrl_outb(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outb(value, pci_ioaddr(port)); else ctrl_outw(value, port2adr(port)); ctrl_delay(); @@ -87,8 +75,6 @@ void titan_outw(u16 value, unsigned long port) { if (PXSEG(port)) ctrl_outw(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outw(value, pci_ioaddr(port)); else if (port >= 0x2000) ctrl_outw(value, port2adr(port)); else @@ -99,8 +85,6 @@ void titan_outl(u32 value, unsigned long port) { if (PXSEG(port)) ctrl_outl(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outl(value, pci_ioaddr(port)); else maybebadio(port); } @@ -119,8 +103,6 @@ void __iomem *titan_ioport_map(unsigned long port, unsigned int size) { if (PXSEG(port)) return (void __iomem *)port; - else if (is_pci_ioaddr(port)) - return (void __iomem *)pci_ioaddr(port); return (void __iomem *)port2adr(port); } -- GitLab From 0e75148108914062cb46ad3dc8f054a628018df7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 19:48:48 +0900 Subject: [PATCH 0429/6080] sh: pci: Consolidate pcibios_setup() in pci-lib. This wasn't really being used for anything useful, so just stub it in pci-lib. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-dreamcast.c | 6 ----- arch/sh/drivers/pci/ops-sh4.c | 35 +++++++++-------------------- arch/sh/drivers/pci/ops-sh5.c | 5 ----- arch/sh/drivers/pci/pci-lib.c | 5 +++++ 4 files changed, 16 insertions(+), 35 deletions(-) diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c index 5bc81d5b660a..529aa4f27a89 100644 --- a/arch/sh/drivers/pci/ops-dreamcast.c +++ b/arch/sh/drivers/pci/ops-dreamcast.c @@ -154,12 +154,6 @@ static int __init gapspci_init(struct pci_channel *chan) return 0; } -/* Haven't done anything here as yet */ -char * __devinit pcibios_setup(char *str) -{ - return str; -} - struct pci_channel board_pci_channels[] = { { gapspci_init, &gapspci_pci_ops, &gapspci_io_resource, &gapspci_mem_resource, 0, 1 }, diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 2a7f7b50ff0a..7cc1fccf1c52 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c @@ -106,30 +106,27 @@ struct pci_ops sh4_pci_ops = { * Not really related to pci_ops, but it's common and not worth shoving * somewhere else for now.. */ -static unsigned int pci_probe = PCI_PROBE_CONF1; - int __init sh4_pci_check_direct(struct pci_channel *chan) { /* * Check if configuration works. */ - if (pci_probe & PCI_PROBE_CONF1) { - unsigned int tmp = pci_read_reg(chan, SH4_PCIPAR); - - pci_write_reg(chan, P1SEG, SH4_PCIPAR); + unsigned int tmp = pci_read_reg(chan, SH4_PCIPAR); - if (pci_read_reg(chan, SH4_PCIPAR) == P1SEG) { - pci_write_reg(chan, tmp, SH4_PCIPAR); - printk(KERN_INFO "PCI: Using configuration type 1\n"); - request_region(chan->reg_base + SH4_PCIPAR, 8, - "PCI conf1"); - return 0; - } + pci_write_reg(chan, P1SEG, SH4_PCIPAR); + if (pci_read_reg(chan, SH4_PCIPAR) == P1SEG) { pci_write_reg(chan, tmp, SH4_PCIPAR); + printk(KERN_INFO "PCI: Using configuration type 1\n"); + request_region(chan->reg_base + SH4_PCIPAR, 8, + "PCI conf1"); + return 0; } - pr_debug("PCI: pci_check_direct failed\n"); + pci_write_reg(chan, tmp, SH4_PCIPAR); + + printk(KERN_ERR "PCI: %s failed\n", __func__); + return -EINVAL; } @@ -155,16 +152,6 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); -char * __devinit pcibios_setup(char *str) -{ - if (!strcmp(str, "off")) { - pci_probe = 0; - return NULL; - } - - return str; -} - int __attribute__((weak)) pci_fixup_pcic(struct pci_channel *chan) { /* Nothing to do. */ diff --git a/arch/sh/drivers/pci/ops-sh5.c b/arch/sh/drivers/pci/ops-sh5.c index 729e38a6fe07..b10e2d5f4251 100644 --- a/arch/sh/drivers/pci/ops-sh5.c +++ b/arch/sh/drivers/pci/ops-sh5.c @@ -42,11 +42,6 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); -char * __devinit pcibios_setup(char *str) -{ - return str; -} - static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c index ea8362945849..f072acafce6c 100644 --- a/arch/sh/drivers/pci/pci-lib.c +++ b/arch/sh/drivers/pci/pci-lib.c @@ -134,6 +134,11 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } +char * __devinit pcibios_setup(char *str) +{ + return str; +} + int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { -- GitLab From 0db38cea69fc478a5c25b3c915ec680cc5538783 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 19:54:47 +0900 Subject: [PATCH 0430/6080] sh: pci: Kill off legacy ide quirks. These fixups seem to have bitrotted a bit since their introduction in the 2.4 days. As we never had much use for them in the first place, and nothing is using them any more, kill them off the rest of the way. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/ops-sh4.c | 22 ---------------------- arch/sh/drivers/pci/ops-sh5.c | 20 -------------------- 2 files changed, 42 deletions(-) diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index 7cc1fccf1c52..78bebebdc99c 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c @@ -130,28 +130,6 @@ int __init sh4_pci_check_direct(struct pci_channel *chan) return -EINVAL; } -/* Handle generic fixups */ -static void __init pci_fixup_ide_bases(struct pci_dev *d) -{ - int i; - - /* - * PCI IDE controllers use non-standard I/O port decoding, respect it. - */ - if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) - return; - pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d)); - for(i = 0; i < 4; i++) { - struct resource *r = &d->resource[i]; - - if ((r->start & ~0x80) == 0x374) { - r->start |= 2; - r->end = r->start; - } - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); - int __attribute__((weak)) pci_fixup_pcic(struct pci_channel *chan) { /* Nothing to do. */ diff --git a/arch/sh/drivers/pci/ops-sh5.c b/arch/sh/drivers/pci/ops-sh5.c index b10e2d5f4251..4ce95a001b80 100644 --- a/arch/sh/drivers/pci/ops-sh5.c +++ b/arch/sh/drivers/pci/ops-sh5.c @@ -22,26 +22,6 @@ #include #include "pci-sh5.h" -static void __init pci_fixup_ide_bases(struct pci_dev *d) -{ - int i; - - /* - * PCI IDE controllers use non-standard I/O port decoding, respect it. - */ - if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) - return; - printk("PCI: IDE base address fixup for %s\n", pci_name(d)); - for(i=0; i<4; i++) { - struct resource *r = &d->resource[i]; - if ((r->start & ~0x80) == 0x374) { - r->start |= 2; - r->end = r->start; - } - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); - static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { -- GitLab From 3444f5ec49bc6cb901ffea38e085db1d76e1189c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 20:22:05 +0900 Subject: [PATCH 0431/6080] sh: pci: Tidy up the dreamcast PCI support. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 3 +- arch/sh/drivers/pci/ops-dreamcast.c | 98 +++----------------- arch/sh/drivers/pci/pci-dreamcast.c | 105 ++++++++++++++++++++++ arch/sh/include/mach-dreamcast/mach/pci.h | 2 + 4 files changed, 119 insertions(+), 89 deletions(-) create mode 100644 arch/sh/drivers/pci/pci-dreamcast.c diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 4cac866d55d4..2160a06b6c11 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -12,7 +12,8 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o -obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o +obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ + pci-dreamcast.o obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c index 529aa4f27a89..e83d0d3aabe2 100644 --- a/arch/sh/drivers/pci/ops-dreamcast.c +++ b/arch/sh/drivers/pci/ops-dreamcast.c @@ -1,15 +1,9 @@ /* - * arch/sh/drivers/pci/ops-dreamcast.c - * * PCI operations for the Sega Dreamcast * * Copyright (C) 2001, 2002 M. R. Brown * Copyright (C) 2002, 2003 Paul Mundt * - * This file originally bore the message (with enclosed-$): - * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp - * Dreamcast PCI: Supports SEGA Broadband Adaptor only. - * * 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. @@ -23,25 +17,10 @@ #include #include #include - -#include -#include +#include +#include #include -static struct resource gapspci_io_resource = { - .name = "GAPSPCI IO", - .start = GAPSPCI_BBA_CONFIG, - .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1, - .flags = IORESOURCE_IO, -}; - -static struct resource gapspci_mem_resource = { - .name = "GAPSPCI mem", - .start = GAPSPCI_DMA_BASE, - .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - /* * The !gapspci_config_access case really shouldn't happen, ever, unless * someone implicitly messes around with the last devfn value.. otherwise we @@ -76,10 +55,10 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break; - case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break; - case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break; - } + case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break; + case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break; + case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break; + } return PCIBIOS_SUCCESSFUL; } @@ -90,72 +69,15 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; - case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; - case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; + case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; + case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; + case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; } return PCIBIOS_SUCCESSFUL; } -static struct pci_ops gapspci_pci_ops = { +struct pci_ops gapspci_pci_ops = { .read = gapspci_read, .write = gapspci_write, }; - -/* - * gapspci init - */ - -static int __init gapspci_init(struct pci_channel *chan) -{ - char idbuf[16]; - int i; - - /* - * FIXME: All of this wants documenting to some degree, - * even some basic register definitions would be nice. - * - * I haven't seen anything this ugly since.. maple. - */ - - for (i=0; i<16; i++) - idbuf[i] = inb(GAPSPCI_REGS+i); - - if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) - return -ENODEV; - - outl(0x5a14a501, GAPSPCI_REGS+0x18); - - for (i=0; i<1000000; i++) - ; - - if (inl(GAPSPCI_REGS+0x18) != 1) - return -EINVAL; - - outl(0x01000000, GAPSPCI_REGS+0x20); - outl(0x01000000, GAPSPCI_REGS+0x24); - - outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); - outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); - - outl(1, GAPSPCI_REGS+0x14); - outl(1, GAPSPCI_REGS+0x34); - - /* Setting Broadband Adapter */ - outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); - outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); - outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); - outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); - outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); - outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); - outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); - - return 0; -} - -struct pci_channel board_pci_channels[] = { - { gapspci_init, &gapspci_pci_ops, &gapspci_io_resource, - &gapspci_mem_resource, 0, 1 }, - { 0, } -}; diff --git a/arch/sh/drivers/pci/pci-dreamcast.c b/arch/sh/drivers/pci/pci-dreamcast.c new file mode 100644 index 000000000000..0897be5053d4 --- /dev/null +++ b/arch/sh/drivers/pci/pci-dreamcast.c @@ -0,0 +1,105 @@ +/* + * PCI support for the Sega Dreamcast + * + * Copyright (C) 2001, 2002 M. R. Brown + * Copyright (C) 2002, 2003 Paul Mundt + * + * This file originally bore the message (with enclosed-$): + * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp + * Dreamcast PCI: Supports SEGA Broadband Adaptor only. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static struct resource gapspci_io_resource = { + .name = "GAPSPCI IO", + .start = GAPSPCI_BBA_CONFIG, + .end = GAPSPCI_BBA_CONFIG + GAPSPCI_BBA_CONFIG_SIZE - 1, + .flags = IORESOURCE_IO, +}; + +static struct resource gapspci_mem_resource = { + .name = "GAPSPCI mem", + .start = GAPSPCI_DMA_BASE, + .end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +/* + * gapspci init + */ + +static int __init gapspci_init(struct pci_channel *chan) +{ + char idbuf[16]; + int i; + + /* + * FIXME: All of this wants documenting to some degree, + * even some basic register definitions would be nice. + * + * I haven't seen anything this ugly since.. maple. + */ + + for (i=0; i<16; i++) + idbuf[i] = inb(GAPSPCI_REGS+i); + + if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) + return -ENODEV; + + outl(0x5a14a501, GAPSPCI_REGS+0x18); + + for (i=0; i<1000000; i++) + cpu_relax(); + + if (inl(GAPSPCI_REGS+0x18) != 1) + return -EINVAL; + + outl(0x01000000, GAPSPCI_REGS+0x20); + outl(0x01000000, GAPSPCI_REGS+0x24); + + outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); + outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); + + outl(1, GAPSPCI_REGS+0x14); + outl(1, GAPSPCI_REGS+0x34); + + /* Setting Broadband Adapter */ + outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); + outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); + outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); + outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); + outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); + outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); + outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); + + return 0; +} + +struct pci_channel board_pci_channels[] = { + { + .init = gapspci_init, + .pci_ops = &gapspci_pci_ops, + .io_resource = &gapspci_io_resource, + .mem_resource = &gapspci_mem_resource, + .first_devfn = 0, + .last_devfn = 1, + }, { + .init = NULL, + } +}; diff --git a/arch/sh/include/mach-dreamcast/mach/pci.h b/arch/sh/include/mach-dreamcast/mach/pci.h index 75fc9009e092..0314d975e626 100644 --- a/arch/sh/include/mach-dreamcast/mach/pci.h +++ b/arch/sh/include/mach-dreamcast/mach/pci.h @@ -21,5 +21,7 @@ #define GAPSPCI_IRQ HW_EVENT_EXTERNAL +extern struct pci_ops gapspci_pci_ops; + #endif /* __ASM_SH_DREAMCAST_PCI_H */ -- GitLab From 48e4237d96fdcb1237b63bcddb37771f97452eec Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 20:40:48 +0900 Subject: [PATCH 0432/6080] sh: pci: Convert the SH-5 code over to the new interface. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Kconfig | 2 +- arch/sh/drivers/pci/ops-cayman.c | 11 ------ arch/sh/drivers/pci/pci-sh5.c | 58 ++++++++++++-------------------- arch/sh/drivers/pci/pci-sh5.h | 4 --- 4 files changed, 23 insertions(+), 52 deletions(-) diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index efe8cf965a9b..f9fb1d1b623e 100644 --- a/arch/sh/drivers/pci/Kconfig +++ b/arch/sh/drivers/pci/Kconfig @@ -23,7 +23,7 @@ config PCI_NEW bool depends on PCI default y if CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7780 || \ - CPU_SUBTYPE_SH7785 + CPU_SUBTYPE_SH7785 || CPU_SH5 # This is also board-specific config PCI_AUTO diff --git a/arch/sh/drivers/pci/ops-cayman.c b/arch/sh/drivers/pci/ops-cayman.c index cbaaf0234b72..b68b61d22c6c 100644 --- a/arch/sh/drivers/pci/ops-cayman.c +++ b/arch/sh/drivers/pci/ops-cayman.c @@ -75,14 +75,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) return result; } - -struct pci_channel board_pci_channels[] = { - { sh5_pci_init, &sh5_pci_ops, NULL, NULL, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - -int __init pcibios_init_platform(void) -{ - return sh5pci_init(__pa(memory_start), - __pa(memory_end) - __pa(memory_start)); -} diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c index 7750da276284..cf431852213c 100644 --- a/arch/sh/drivers/pci/pci-sh5.c +++ b/arch/sh/drivers/pci/pci-sh5.c @@ -27,12 +27,6 @@ unsigned long pcicr_virt; unsigned long PCI_IO_AREA; -int __init sh5_pci_init(struct pci_channel *chan) -{ - pr_debug("PCI: Starting intialization.\n"); - return pcibios_init_platform(); -} - /* Rounds a number UP to the nearest power of two. Used for * sizing the PCI window. */ @@ -95,8 +89,21 @@ static irqreturn_t pcish5_serr_irq(int irq, void *dev_id) return IRQ_NONE; } -int __init sh5pci_init(unsigned long memStart, unsigned long memSize) +static struct resource sh5_io_resource = { /* place holder */ }; +static struct resource sh5_mem_resource = { /* place holder */ }; + +static struct pci_channel sh5pci_controller = { + .pci_ops = &sh5_pci_ops, + .mem_resource = &sh5_mem_resource, + .mem_offset = 0x00000000, + .io_resource = &sh5_io_resource, + .io_offset = 0x00000000, +}; + +static int __init sh5pci_init(void) { + unsigned long memStart = __pa(memory_start); + unsigned long memSize = __pa(memory_end) - memStart; u32 lsr0; u32 uval; @@ -203,35 +210,14 @@ int __init sh5pci_init(unsigned long memStart, unsigned long memSize) SH5PCI_WRITE(AINTM, ~0); SH5PCI_WRITE(PINTM, ~0); - return 0; -} + sh5_io_resource.start = PCI_IO_AREA; + sh5_io_resource.end = PCI_IO_AREA + 0x10000; -#define xPCIBIOS_MIN_IO board_pci_channels->io_resource->start -#define xPCIBIOS_MIN_MEM board_pci_channels->mem_resource->start + sh5_mem_resource.start = memStart; + sh5_mem_resource.end = memStart + memSize; -void __devinit pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_dev *dev = bus->self; - int i; - - if (dev) { - for (i= 0; i < 3; i++) { - bus->resource[i] = - &dev->resource[PCI_BRIDGE_RESOURCES+i]; - bus->resource[i]->name = bus->name; - } - bus->resource[0]->flags |= IORESOURCE_IO; - bus->resource[1]->flags |= IORESOURCE_MEM; - - /* For now, propagate host limits to the bus; - * we'll adjust them later. */ - bus->resource[0]->end = 64*1024 - 1 ; - bus->resource[1]->end = xPCIBIOS_MIN_MEM+(256*1024*1024)-1; - bus->resource[0]->start = xPCIBIOS_MIN_IO; - bus->resource[1]->start = xPCIBIOS_MIN_MEM; - - /* Turn off downstream PF memory address range by default */ - bus->resource[2]->start = 1024*1024; - bus->resource[2]->end = bus->resource[2]->start - 1; - } + register_pci_controller(&sh5pci_controller); + + return 0; } +arch_initcall(sh5pci_init); diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h index af09f384c7d2..f277628221f3 100644 --- a/arch/sh/drivers/pci/pci-sh5.h +++ b/arch/sh/drivers/pci/pci-sh5.h @@ -107,8 +107,4 @@ extern unsigned long pcicr_virt; extern struct pci_ops sh5_pci_ops; -/* arch/sh/drivers/pci/pci-sh5.c */ -int sh5_pci_init(struct pci_channel *chan); -int sh5pci_init(unsigned long memStart, unsigned long memSize); - #endif /* __PCI_SH5_H */ -- GitLab From a5b08047129f214af1899bd9088605c7adc21ed5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 20:41:45 +0900 Subject: [PATCH 0433/6080] sh: pci: Rename ops-cayman -> fixups-cayman. Now that ops-cayman.c only contains IRQ routing fixups, rename it. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 2 +- arch/sh/drivers/pci/{ops-cayman.c => fixups-cayman.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename arch/sh/drivers/pci/{ops-cayman.c => fixups-cayman.c} (100%) diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 2160a06b6c11..cb2190c3e36b 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -24,4 +24,4 @@ obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o obj-$(CONFIG_SH_TITAN) += ops-titan.o obj-$(CONFIG_SH_LANDISK) += ops-landisk.o obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-rts7751r2d.o -obj-$(CONFIG_SH_CAYMAN) += ops-cayman.o +obj-$(CONFIG_SH_CAYMAN) += fixups-cayman.o diff --git a/arch/sh/drivers/pci/ops-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c similarity index 100% rename from arch/sh/drivers/pci/ops-cayman.c rename to arch/sh/drivers/pci/fixups-cayman.c -- GitLab From 7154b3e80203ee91f9ba7d0a43d3daa05c49d9e9 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Mon, 20 Apr 2009 19:21:35 +0900 Subject: [PATCH 0434/6080] ASoC: TWL4030: Add support Voice DAI Add Voice DAI to support the PCM voice interface of the twl4030 codec. The PCM voice interface can be used with 8-kHz(voice narrowband) or 16-kHz(voice wideband) sampling rates, and 16bits, and mono RX and mono TX or stereo TX. The PCM voice interface has two modes - PCM mode1 : This uses the normal FS polarity and the rising edge of the clock signal. - PCM mode2 : This uses the FS polarity inverted and the falling edge of the clock signal. If the system master clock is not 26MHz or the twl4030 codec mode is not option2, the voice PCM interface is not available. Signed-off-by: Joonyoung Shim Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 173 +++++++++++++++++++++++++++++++++- sound/soc/codecs/twl4030.h | 18 +++- sound/soc/omap/omap2evm.c | 2 +- sound/soc/omap/omap3beagle.c | 2 +- sound/soc/omap/omap3pandora.c | 4 +- sound/soc/omap/overo.c | 2 +- sound/soc/omap/sdp3430.c | 2 +- 7 files changed, 191 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index a1b76d7fd130..cc2968cf6409 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -1484,6 +1484,144 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, return 0; } +static int twl4030_voice_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + u8 infreq; + u8 mode; + + /* If the system master clock is not 26MHz, the voice PCM interface is + * not avilable. + */ + infreq = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL) + & TWL4030_APLL_INFREQ; + + if (infreq != TWL4030_APLL_INFREQ_26000KHZ) { + printk(KERN_ERR "TWL4030 voice startup: " + "MCLK is not 26MHz, call set_sysclk() on init\n"); + return -EINVAL; + } + + /* If the codec mode is not option2, the voice PCM interface is not + * avilable. + */ + mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) + & TWL4030_OPT_MODE; + + if (mode != TWL4030_OPTION_2) { + printk(KERN_ERR "TWL4030 voice startup: " + "the codec mode is not option2\n"); + return -EINVAL; + } + + return 0; +} + +static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + u8 old_mode, mode; + + /* bit rate */ + old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) + & ~(TWL4030_CODECPDZ); + mode = old_mode; + + switch (params_rate(params)) { + case 8000: + mode &= ~(TWL4030_SEL_16K); + break; + case 16000: + mode |= TWL4030_SEL_16K; + break; + default: + printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n", + params_rate(params)); + return -EINVAL; + } + + if (mode != old_mode) { + /* change rate and set CODECPDZ */ + twl4030_codec_enable(codec, 0); + twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); + twl4030_codec_enable(codec, 1); + } + + return 0; +} + +static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u8 infreq; + + switch (freq) { + case 26000000: + infreq = TWL4030_APLL_INFREQ_26000KHZ; + break; + default: + printk(KERN_ERR "TWL4030 voice set sysclk: unknown rate %d\n", + freq); + return -EINVAL; + } + + infreq |= TWL4030_APLL_EN; + twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq); + + return 0; +} + +static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u8 old_format, format; + + /* get format */ + old_format = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF); + format = old_format; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFM: + format &= ~(TWL4030_VIF_SLAVE_EN); + break; + case SND_SOC_DAIFMT_CBS_CFS: + format |= TWL4030_VIF_SLAVE_EN; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_IB_NF: + format &= ~(TWL4030_VIF_FORMAT); + break; + case SND_SOC_DAIFMT_NB_IF: + format |= TWL4030_VIF_FORMAT; + break; + default: + return -EINVAL; + } + + if (format != old_format) { + /* change format and set CODECPDZ */ + twl4030_codec_enable(codec, 0); + twl4030_write(codec, TWL4030_REG_VOICE_IF, format); + twl4030_codec_enable(codec, 1); + } + + return 0; +} + #define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) #define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) @@ -1495,7 +1633,15 @@ static struct snd_soc_dai_ops twl4030_dai_ops = { .set_fmt = twl4030_set_dai_fmt, }; -struct snd_soc_dai twl4030_dai = { +static struct snd_soc_dai_ops twl4030_dai_voice_ops = { + .startup = twl4030_voice_startup, + .hw_params = twl4030_voice_hw_params, + .set_sysclk = twl4030_voice_set_dai_sysclk, + .set_fmt = twl4030_voice_set_dai_fmt, +}; + +struct snd_soc_dai twl4030_dai[] = { +{ .name = "twl4030", .playback = { .stream_name = "Playback", @@ -1510,6 +1656,23 @@ struct snd_soc_dai twl4030_dai = { .rates = TWL4030_RATES, .formats = TWL4030_FORMATS,}, .ops = &twl4030_dai_ops, +}, +{ + .name = "twl4030 Voice", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = &twl4030_dai_voice_ops, +}, }; EXPORT_SYMBOL_GPL(twl4030_dai); @@ -1550,8 +1713,8 @@ static int twl4030_init(struct snd_soc_device *socdev) codec->read = twl4030_read_reg_cache; codec->write = twl4030_write; codec->set_bias_level = twl4030_set_bias_level; - codec->dai = &twl4030_dai; - codec->num_dai = 1; + codec->dai = twl4030_dai; + codec->num_dai = ARRAY_SIZE(twl4030_dai), codec->reg_cache_size = sizeof(twl4030_reg); codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg), GFP_KERNEL); @@ -1645,13 +1808,13 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030); static int __init twl4030_modinit(void) { - return snd_soc_register_dai(&twl4030_dai); + return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); } module_init(twl4030_modinit); static void __exit twl4030_exit(void) { - snd_soc_unregister_dai(&twl4030_dai); + snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); } module_exit(twl4030_exit); diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h index cb63765db1df..981ec609495b 100644 --- a/sound/soc/codecs/twl4030.h +++ b/sound/soc/codecs/twl4030.h @@ -113,6 +113,8 @@ #define TWL4030_SEL_16K 0x04 #define TWL4030_CODECPDZ 0x02 #define TWL4030_OPT_MODE 0x01 +#define TWL4030_OPTION_1 (1 << 0) +#define TWL4030_OPTION_2 (0 << 0) /* TWL4030_REG_MICBIAS_CTL (0x04) Fields */ @@ -171,6 +173,17 @@ #define TWL4030_CLK256FS_EN 0x02 #define TWL4030_AIF_EN 0x01 +/* VOICE_IF (0x0F) Fields */ + +#define TWL4030_VIF_SLAVE_EN 0x80 +#define TWL4030_VIF_DIN_EN 0x40 +#define TWL4030_VIF_DOUT_EN 0x20 +#define TWL4030_VIF_SWAP 0x10 +#define TWL4030_VIF_FORMAT 0x08 +#define TWL4030_VIF_TRI_EN 0x04 +#define TWL4030_VIF_SUB_EN 0x02 +#define TWL4030_VIF_EN 0x01 + /* EAR_CTL (0x21) */ #define TWL4030_EAR_GAIN 0x30 @@ -236,7 +249,10 @@ #define TWL4030_SMOOTH_ANAVOL_EN 0x02 #define TWL4030_DIGMIC_LR_SWAP_EN 0x01 -extern struct snd_soc_dai twl4030_dai; +#define TWL4030_DAI_HIFI 0 +#define TWL4030_DAI_VOICE 1 + +extern struct snd_soc_dai twl4030_dai[2]; extern struct snd_soc_codec_device soc_codec_dev_twl4030; #endif /* End of __TWL4030_AUDIO_H__ */ diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c index 0c2322dcf02a..027e1a40f8a1 100644 --- a/sound/soc/omap/omap2evm.c +++ b/sound/soc/omap/omap2evm.c @@ -86,7 +86,7 @@ static struct snd_soc_dai_link omap2evm_dai = { .name = "TWL4030", .stream_name = "TWL4030", .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai, + .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], .ops = &omap2evm_ops, }; diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c index fd24a4acd2f5..6aa428e07d86 100644 --- a/sound/soc/omap/omap3beagle.c +++ b/sound/soc/omap/omap3beagle.c @@ -83,7 +83,7 @@ static struct snd_soc_dai_link omap3beagle_dai = { .name = "TWL4030", .stream_name = "TWL4030", .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai, + .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], .ops = &omap3beagle_ops, }; diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index fe282d4ef422..ad219aaf7cb8 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -228,14 +228,14 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { .name = "PCM1773", .stream_name = "HiFi Out", .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai, + .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], .ops = &omap3pandora_out_ops, .init = omap3pandora_out_init, }, { .name = "TWL4030", .stream_name = "Line/Mic In", .cpu_dai = &omap_mcbsp_dai[1], - .codec_dai = &twl4030_dai, + .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], .ops = &omap3pandora_in_ops, .init = omap3pandora_in_init, } diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c index a72dc4e159e5..ec4f8fd8b3a2 100644 --- a/sound/soc/omap/overo.c +++ b/sound/soc/omap/overo.c @@ -83,7 +83,7 @@ static struct snd_soc_dai_link overo_dai = { .name = "TWL4030", .stream_name = "TWL4030", .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai, + .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], .ops = &overo_ops, }; diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index 10f1c867f11d..1c7974101a0b 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c @@ -197,7 +197,7 @@ static struct snd_soc_dai_link sdp3430_dai = { .name = "TWL4030", .stream_name = "TWL4030", .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai, + .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], .init = sdp3430_twl4030_init, .ops = &sdp3430_ops, }; -- GitLab From 757e3c16f8bafa2a470aebf9b04671c5d4d18f49 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 21:11:07 +0900 Subject: [PATCH 0435/6080] sh: pci: Rewrite SH7751 PCI support to follow SH7780. This follows the similar sort of scheme that the refactored SH7780 code uses, using a 64MB CS3 mapping to handle the window0 case, and simply discarding window1. This vastly simplifies the code, and allows most of the board-specific setup to go die. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Kconfig | 3 +- arch/sh/drivers/pci/Makefile | 2 +- arch/sh/drivers/pci/ops-landisk.c | 31 ------ arch/sh/drivers/pci/ops-lboxre2.c | 33 ------- arch/sh/drivers/pci/ops-rts7751r2d.c | 34 ------- arch/sh/drivers/pci/ops-sh03.c | 45 --------- arch/sh/drivers/pci/ops-snapgear.c | 49 ---------- arch/sh/drivers/pci/ops-titan.c | 36 ------- arch/sh/drivers/pci/pci-sh7751.c | 135 ++++++++++++++------------- arch/sh/drivers/pci/pci-sh7751.h | 13 +-- 10 files changed, 76 insertions(+), 305 deletions(-) delete mode 100644 arch/sh/drivers/pci/ops-sh03.c diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index f9fb1d1b623e..5aaee3c707b0 100644 --- a/arch/sh/drivers/pci/Kconfig +++ b/arch/sh/drivers/pci/Kconfig @@ -23,7 +23,8 @@ config PCI_NEW bool depends on PCI default y if CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7780 || \ - CPU_SUBTYPE_SH7785 || CPU_SH5 + CPU_SUBTYPE_SH7785 || CPU_SH5 || \ + CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R # This is also board-specific config PCI_AUTO diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index cb2190c3e36b..b8667de19ece 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ pci-dreamcast.o obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o -obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o +obj-$(CONFIG_SH_SH03) += fixups-sh03.o obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o obj-$(CONFIG_SH_SH7785LCR) += fixups-r7780rp.o obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c index 178b77828aa9..bb1a6bb5149e 100644 --- a/arch/sh/drivers/pci/ops-landisk.c +++ b/arch/sh/drivers/pci/ops-landisk.c @@ -15,37 +15,6 @@ #include #include "pci-sh4.h" -static struct resource sh7751_io_resource = { - .name = "SH7751 IO", - .start = SH7751_PCI_IO_BASE, - .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751 mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -struct pci_channel board_pci_channels[] = { - { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff}, - {NULL, NULL, NULL, 0, 0}, -}; - -static struct sh4_pci_address_map sh7751_pci_map = { - .window0 = { - .base = SH7751_CS3_BASE_ADDR, - .size = (64 << 20), /* 64MB */ - }, -}; - -int __init pcibios_init_platform(void) -{ - return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); -} - int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { /* diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c index 91cabd84f028..6db2c209737f 100644 --- a/arch/sh/drivers/pci/ops-lboxre2.c +++ b/arch/sh/drivers/pci/ops-lboxre2.c @@ -21,36 +21,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { return lboxre2_irq_tab[slot]; } - -static struct resource sh7751_io_resource = { - .name = "SH7751_IO", - .start = SH7751_PCI_IO_BASE , - .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751_mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops sh7751_pci_ops; - -struct pci_channel board_pci_channels[] = { - { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - -static struct sh4_pci_address_map sh7751_pci_map = { - .window0 = { - .base = SH7751_CS3_BASE_ADDR, - .size = 0x04000000, - }, -}; - -int __init pcibios_init_platform(void) -{ - return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); -} diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index 96b916c0d6c5..d950b8ab25f1 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -29,37 +29,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { return rts7751r2d_irq_tab[slot]; } - -static struct resource sh7751_io_resource = { - .name = "SH7751_IO", - .start = 0x4000, - .end = SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751_mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops sh7751_pci_ops; - -struct pci_channel board_pci_channels[] = { - { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - -static struct sh4_pci_address_map sh7751_pci_map = { - .window0 = { - .base = SH7751_CS3_BASE_ADDR, - .size = 0x04000000, - }, -}; - -int __init pcibios_init_platform(void) -{ - return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); -} - diff --git a/arch/sh/drivers/pci/ops-sh03.c b/arch/sh/drivers/pci/ops-sh03.c deleted file mode 100644 index 0218135f0bb8..000000000000 --- a/arch/sh/drivers/pci/ops-sh03.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/arch/sh/drivers/pci/ops-sh03.c - * - * PCI initialization for the Interface CTP/PCI-SH03 board - */ - -#include -#include -#include -#include -#include -#include -#include "pci-sh7751.h" - -/* - * Description: This function sets up and initializes the pcic, sets - * up the BARS, maps the DRAM into the address space etc, etc. - */ -int __init pcibios_init_platform(void) -{ - __set_io_port_base(SH7751_PCI_IO_BASE); - return 1; -} - -static struct resource sh7751_io_resource = { - .name = "SH03 IO", - .start = SH7751_PCI_IO_BASE, - .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH03 mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops sh4_pci_ops; - -struct pci_channel board_pci_channels[] = { - { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c index b64f2b91be8e..5a39ecc1adb8 100644 --- a/arch/sh/drivers/pci/ops-snapgear.c +++ b/arch/sh/drivers/pci/ops-snapgear.c @@ -18,55 +18,6 @@ #include #include "pci-sh4.h" -#define SNAPGEAR_PCI_IO 0x4000 -#define SNAPGEAR_PCI_MEM 0xfd000000 - -/* PCI: default LOCAL memory window sizes (seen from PCI bus) */ -#define SNAPGEAR_LSR0_SIZE (64*(1<<20)) //64MB -#define SNAPGEAR_LSR1_SIZE (64*(1<<20)) //64MB - -static struct resource sh7751_io_resource = { - .name = "SH7751 IO", - .start = SNAPGEAR_PCI_IO, - .end = SNAPGEAR_PCI_IO + (64*1024) - 1, /* 64KiB I/O */ - .flags = IORESOURCE_IO, -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751 mem", - .start = SNAPGEAR_PCI_MEM, - .end = SNAPGEAR_PCI_MEM + (64*1024*1024) - 1, /* 64MiB mem */ - .flags = IORESOURCE_MEM, -}; - -struct pci_channel board_pci_channels[] = { - { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, - { 0, } -}; - -static struct sh4_pci_address_map sh7751_pci_map = { - .window0 = { - .base = SH7751_CS2_BASE_ADDR, - .size = SNAPGEAR_LSR0_SIZE, - }, - - .window1 = { - .base = SH7751_CS2_BASE_ADDR, - .size = SNAPGEAR_LSR1_SIZE, - }, -}; - -/* - * Initialize the SnapGear PCI interface - * Setup hardware to be Central Funtion - * Copy the BSR regs to the PCI interface - * Setup PCI windows into local RAM - */ -int __init pcibios_init_platform(void) -{ - return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); -} - int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c index e45bb62bf8ce..3a79fa8254a6 100644 --- a/arch/sh/drivers/pci/ops-titan.c +++ b/arch/sh/drivers/pci/ops-titan.c @@ -36,39 +36,3 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) return irq; } - -static struct resource sh7751_io_resource = { - .name = "SH7751_IO", - .start = SH7751_PCI_IO_BASE, - .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751_mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -struct pci_channel board_pci_channels[] = { - { sh7751_pci_init, &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - -static struct sh4_pci_address_map sh7751_pci_map = { - .window0 = { - .base = SH7751_CS2_BASE_ADDR, - .size = SH7751_MEM_REGION_SIZE*2, /* cs2 and cs3 */ - }, - - .window1 = { - .base = SH7751_CS2_BASE_ADDR, - .size = SH7751_MEM_REGION_SIZE*2, - }, -}; - -int __init pcibios_init_platform(void) -{ - return sh7751_pcic_init(&board_pci_channels[0], &sh7751_pci_map); -} diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c index 4c08fd7f665d..c4fa0bb13976 100644 --- a/arch/sh/drivers/pci/pci-sh7751.c +++ b/arch/sh/drivers/pci/pci-sh7751.c @@ -1,78 +1,41 @@ /* - * Low-Level PCI Support for the SH7751 + * Low-Level PCI Support for the SH7751 * - * Dustin McIntire (dustin@sensoria.com) - * Derived from arch/i386/kernel/pci-*.c which bore the message: - * (c) 1999--2000 Martin Mares + * Copyright (C) 2003 - 2009 Paul Mundt + * Copyright (C) 2001 Dustin McIntire * - * Ported to the new API by Paul Mundt - * With cleanup by Paul van Gool - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. + * With cleanup by Paul van Gool , 2003. * + * 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. */ -#undef DEBUG - #include #include #include #include -#include +#include #include "pci-sh4.h" #include -#include - -/* - * Initialization. Try all known PCI access methods. Note that we support - * using both PCI BIOS and direct access: in such cases, we use I/O ports - * to access config space. - * - * Note that the platform specific initialization (BSC registers, and memory - * space mapping) will be called via the platform defined function - * pcibios_init_platform(). - */ -int __init sh7751_pci_init(struct pci_channel *chan) -{ - unsigned int id; - int ret; - - pr_debug("PCI: Starting intialization.\n"); - - chan->reg_base = 0xfe200000; - - /* check for SH7751/SH7751R hardware */ - id = pci_read_reg(chan, SH7751_PCICONF0); - if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && - id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { - pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); - return -ENODEV; - } - - if ((ret = sh4_pci_check_direct(chan)) != 0) - return ret; - - return pcibios_init_platform(); -} static int __init __area_sdram_check(struct pci_channel *chan, unsigned int area) { - u32 word; + unsigned long word; - word = ctrl_inl(SH7751_BCR1); + word = __raw_readl(SH7751_BCR1); /* check BCR for SDRAM in area */ if (((word >> area) & 1) == 0) { - printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n", + printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%lx\n", area, word); return 0; } pci_write_reg(chan, word, SH4_PCIBCR1); - word = (u16)ctrl_inw(SH7751_BCR2); + word = __raw_readw(SH7751_BCR2); /* check BCR2 for 32bit SDRAM interface*/ if (((word >> (area << 1)) & 0x3) != 0x3) { - printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n", + printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%lx\n", area, word); return 0; } @@ -81,11 +44,56 @@ static int __init __area_sdram_check(struct pci_channel *chan, return 1; } -int __init sh7751_pcic_init(struct pci_channel *chan, - struct sh4_pci_address_map *map) +static struct resource sh7751_io_resource = { + .name = "SH7751_IO", + .start = SH7751_PCI_IO_BASE, + .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7751_mem_resource = { + .name = "SH7785_mem", + .start = SH7751_PCI_MEMORY_BASE, + .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +static struct pci_channel sh7751_pci_controller = { + .pci_ops = &sh4_pci_ops, + .mem_resource = &sh7751_mem_resource, + .mem_offset = 0x00000000, + .io_resource = &sh7751_io_resource, + .io_offset = 0x00000000, +}; + +static struct sh4_pci_address_map sh7751_pci_map = { + .window0 = { + .base = SH7751_CS3_BASE_ADDR, + .size = 0x04000000, + }, +}; + +static int __init sh7751_pci_init(void) { - u32 reg; - u32 word; + struct pci_channel *chan = &sh7751_pci_controller; + unsigned int id; + u32 word, reg; + int ret; + + printk(KERN_NOTICE "PCI: Starting intialization.\n"); + + chan->reg_base = 0xfe200000; + + /* check for SH7751/SH7751R hardware */ + id = pci_read_reg(chan, SH7751_PCICONF0); + if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && + id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { + pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); + return -ENODEV; + } + + if ((ret = sh4_pci_check_direct(chan)) != 0) + return ret; /* Set the BCR's to enable PCI access */ reg = ctrl_inl(SH7751_BCR1); @@ -112,21 +120,13 @@ int __init sh7751_pcic_init(struct pci_channel *chan, /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping - * Window0 = map->window0.size @ non-cached area base = SDRAM - * Window1 = map->window1.size @ cached area base = SDRAM */ - word = map->window0.size - 1; + word = sh7751_pci_map.window0.size - 1; pci_write_reg(chan, word, SH4_PCILSR0); - word = map->window1.size - 1; - pci_write_reg(chan, word, SH4_PCILSR1); /* Set the values on window 0 PCI config registers */ - word = P2SEGADDR(map->window0.base); + word = P2SEGADDR(sh7751_pci_map.window0.base); pci_write_reg(chan, word, SH4_PCILAR0); pci_write_reg(chan, word, SH7751_PCICONF5); - /* Set the values on window 1 PCI config registers */ - word = PHYSADDR(map->window1.base); - pci_write_reg(chan, word, SH4_PCILAR1); - pci_write_reg(chan, word, SH7751_PCICONF6); /* Set the local 16MB PCI memory space window to * the lowest PCI mapped address @@ -144,7 +144,7 @@ int __init sh7751_pcic_init(struct pci_channel *chan, /* Set PCI WCRx, BCRx's, copy from BSC locations */ /* check BCR for SDRAM in specified area */ - switch (map->window0.base) { + switch (sh7751_pci_map.window0.base) { case SH7751_CS0_BASE_ADDR: word = __area_sdram_check(chan, 0); break; case SH7751_CS1_BASE_ADDR: word = __area_sdram_check(chan, 1); break; case SH7751_CS2_BASE_ADDR: word = __area_sdram_check(chan, 2); break; @@ -179,5 +179,10 @@ int __init sh7751_pcic_init(struct pci_channel *chan, word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; pci_write_reg(chan, word, SH4_PCICR); + __set_io_port_base(SH7751_PCI_IO_BASE); + + register_pci_controller(chan); + return 0; } +arch_initcall(sh7751_pci_init); diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h index c390dd2f5e1a..4983a4d20355 100644 --- a/arch/sh/drivers/pci/pci-sh7751.h +++ b/arch/sh/drivers/pci/pci-sh7751.h @@ -57,7 +57,7 @@ #define SH7751_PCICONF2_SCC 0x00FF0000 /* Sub-Class Code */ #define SH7751_PCICONF2_RLPI 0x0000FF00 /* Programming Interface */ #define SH7751_PCICONF2_REV 0x000000FF /* Revision ID */ -#define SH7751_PCICONF3 0xC /* PCI Config Reg 3 */ +#define SH7751_PCICONF3 0xC /* PCI Config Reg 3 */ #define SH7751_PCICONF3_BIST7 0x80000000 /* Bist Supported */ #define SH7751_PCICONF3_BIST6 0x40000000 /* Bist Executing */ #define SH7751_PCICONF3_BIST3_0 0x0F000000 /* Bist Passed */ @@ -72,12 +72,12 @@ #define SH7751_PCICONF5_BASE 0xFFFFFFF0 /* Mem Space Base Addr */ #define SH7751_PCICONF5_LAP 0x00000008 /* Prefetch Enabled */ #define SH7751_PCICONF5_LAT 0x00000006 /* Local Memory type */ - #define SH7751_PCICONF5_ASI 0x00000001 /* Address Space Type */ + #define SH7751_PCICONF5_ASI 0x00000001 /* Address Space Type */ #define SH7751_PCICONF6 0x18 /* PCI Config Reg 6 */ #define SH7751_PCICONF6_BASE 0xFFFFFFF0 /* Mem Space Base Addr */ #define SH7751_PCICONF6_LAP 0x00000008 /* Prefetch Enabled */ #define SH7751_PCICONF6_LAT 0x00000006 /* Local Memory type */ - #define SH7751_PCICONF6_ASI 0x00000001 /* Address Space Type */ + #define SH7751_PCICONF6_ASI 0x00000001 /* Address Space Type */ /* PCICONF7 - PCICONF10 are undefined */ #define SH7751_PCICONF11 0x2C /* PCI Config Reg 11 */ #define SH7751_PCICONF11_SSID 0xFFFF0000 /* Subsystem ID */ @@ -126,11 +126,4 @@ #define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE) #define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE) -struct sh4_pci_address_map; - -/* arch/sh/drivers/pci/pci-sh7751.c */ -int sh7751_pci_init(struct pci_channel *chan); -int sh7751_pcic_init(struct pci_channel *chan, - struct sh4_pci_address_map *map); - #endif /* _PCI_SH7751_H_ */ -- GitLab From 84972ec0c206b73ffb74e5114b574186ce6166b8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 21:17:10 +0900 Subject: [PATCH 0436/6080] sh: pci: Rename SH7751 platform ops files to fixups. None of these contain pci_ops, only IRQ routing bits, rename them accordingly. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 8 ++++---- arch/sh/drivers/pci/{ops-landisk.c => fixups-landisk.c} | 0 arch/sh/drivers/pci/{ops-lboxre2.c => fixups-lboxre2.c} | 0 arch/sh/drivers/pci/{ops-snapgear.c => fixups-snapgear.c} | 0 arch/sh/drivers/pci/{ops-titan.c => fixups-titan.c} | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename arch/sh/drivers/pci/{ops-landisk.c => fixups-landisk.c} (100%) rename arch/sh/drivers/pci/{ops-lboxre2.c => fixups-lboxre2.c} (100%) rename arch/sh/drivers/pci/{ops-snapgear.c => fixups-snapgear.c} (100%) rename arch/sh/drivers/pci/{ops-titan.c => fixups-titan.c} (100%) diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index b8667de19ece..abd931c14965 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -14,14 +14,14 @@ obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ pci-dreamcast.o -obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o +obj-$(CONFIG_SH_SECUREEDGE5410) += fixups-snapgear.o obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o obj-$(CONFIG_SH_SH03) += fixups-sh03.o obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o obj-$(CONFIG_SH_SH7785LCR) += fixups-r7780rp.o obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o -obj-$(CONFIG_SH_TITAN) += ops-titan.o -obj-$(CONFIG_SH_LANDISK) += ops-landisk.o -obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-rts7751r2d.o +obj-$(CONFIG_SH_TITAN) += fixups-titan.o +obj-$(CONFIG_SH_LANDISK) += fixups-landisk.o +obj-$(CONFIG_SH_LBOX_RE2) += fixups-lboxre2.o fixups-rts7751r2d.o obj-$(CONFIG_SH_CAYMAN) += fixups-cayman.o diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/fixups-landisk.c similarity index 100% rename from arch/sh/drivers/pci/ops-landisk.c rename to arch/sh/drivers/pci/fixups-landisk.c diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/fixups-lboxre2.c similarity index 100% rename from arch/sh/drivers/pci/ops-lboxre2.c rename to arch/sh/drivers/pci/fixups-lboxre2.c diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c similarity index 100% rename from arch/sh/drivers/pci/ops-snapgear.c rename to arch/sh/drivers/pci/fixups-snapgear.c diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/fixups-titan.c similarity index 100% rename from arch/sh/drivers/pci/ops-titan.c rename to arch/sh/drivers/pci/fixups-titan.c -- GitLab From 37c8ac361efdbae969eff1a603bc39412d3e873f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 21:27:15 +0900 Subject: [PATCH 0437/6080] sh: pci: Consolidate lboxre2 and r2d IRQ fixups. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 4 ++-- arch/sh/drivers/pci/fixups-lboxre2.c | 23 ------------------ arch/sh/drivers/pci/fixups-rts7751r2d.c | 25 +++++++++++++++++++- arch/sh/drivers/pci/ops-rts7751r2d.c | 31 ------------------------- 4 files changed, 26 insertions(+), 57 deletions(-) delete mode 100644 arch/sh/drivers/pci/fixups-lboxre2.c delete mode 100644 arch/sh/drivers/pci/ops-rts7751r2d.c diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index abd931c14965..fbebd73b22f6 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ pci-dreamcast.o obj-$(CONFIG_SH_SECUREEDGE5410) += fixups-snapgear.o -obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o +obj-$(CONFIG_SH_RTS7751R2D) += fixups-rts7751r2d.o obj-$(CONFIG_SH_SH03) += fixups-sh03.o obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o obj-$(CONFIG_SH_SH7785LCR) += fixups-r7780rp.o @@ -23,5 +23,5 @@ obj-$(CONFIG_SH_SDK7780) += fixups-sdk7780.o obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o obj-$(CONFIG_SH_TITAN) += fixups-titan.o obj-$(CONFIG_SH_LANDISK) += fixups-landisk.o -obj-$(CONFIG_SH_LBOX_RE2) += fixups-lboxre2.o fixups-rts7751r2d.o +obj-$(CONFIG_SH_LBOX_RE2) += fixups-rts7751r2d.o obj-$(CONFIG_SH_CAYMAN) += fixups-cayman.o diff --git a/arch/sh/drivers/pci/fixups-lboxre2.c b/arch/sh/drivers/pci/fixups-lboxre2.c deleted file mode 100644 index 6db2c209737f..000000000000 --- a/arch/sh/drivers/pci/fixups-lboxre2.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * linux/arch/sh/drivers/pci/ops-lboxre2.c - * - * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * PCI initialization for the NTT COMWARE L-BOX RE2 - */ -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -static char lboxre2_irq_tab[] __initdata = { - IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, -}; - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - return lboxre2_irq_tab[slot]; -} diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index 38852334d479..052b354236dc 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -1,21 +1,44 @@ /* * arch/sh/drivers/pci/fixups-rts7751r2d.c * - * RTS7751R2D PCI fixups + * RTS7751R2D / LBOXRE2 PCI fixups * * Copyright (C) 2003 Lineo uSolutions, Inc. * Copyright (C) 2004 Paul Mundt + * Copyright (C) 2007 Nobuhiro Iwamatsu * * 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. */ #include +#include +#include #include "pci-sh4.h" +#include #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB +static u8 rts7751r2d_irq_tab[] __initdata = { + IRQ_PCI_INTA, + IRQ_PCI_INTB, + IRQ_PCI_INTC, + IRQ_PCI_INTD, +}; + +static char lboxre2_irq_tab[] __initdata = { + IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, +}; + +int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +{ + if (mach_is_lboxre2()) + return lboxre2_irq_tab[slot]; + else + return rts7751r2d_irq_tab[slot]; +} + int pci_fixup_pcic(struct pci_channel *chan) { unsigned long bcr1, mcr; diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c deleted file mode 100644 index d950b8ab25f1..000000000000 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * linux/arch/sh/drivers/pci/ops-rts7751r2d.c - * - * Author: Ian DaSilva (idasilva@mvista.com) - * - * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * PCI initialization for the Renesas SH7751R RTS7751R2D board - */ -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -static u8 rts7751r2d_irq_tab[] __initdata = { - IRQ_PCI_INTA, - IRQ_PCI_INTB, - IRQ_PCI_INTC, - IRQ_PCI_INTD, -}; - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - return rts7751r2d_irq_tab[slot]; -} -- GitLab From 951a681bda844491de8699b3bdc6c3899cbd4c9f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 21:34:36 +0900 Subject: [PATCH 0438/6080] sh: pci: Convert dreamcast to new-style interface. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Kconfig | 5 +---- arch/sh/drivers/pci/fixups-dreamcast.c | 2 +- arch/sh/drivers/pci/pci-dreamcast.c | 27 ++++++++++++-------------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index 5aaee3c707b0..1d53496b1498 100644 --- a/arch/sh/drivers/pci/Kconfig +++ b/arch/sh/drivers/pci/Kconfig @@ -20,11 +20,8 @@ config SH_PCIDMA_NONCOHERENT # Temporary config option for transitioning off of PCI_AUTO config PCI_NEW - bool + def_bool y depends on PCI - default y if CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7780 || \ - CPU_SUBTYPE_SH7785 || CPU_SH5 || \ - CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R # This is also board-specific config PCI_AUTO diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 48c6381fffaa..ed7f489936f1 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -30,7 +30,7 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev) { - struct pci_channel *p = board_pci_channels; + struct pci_channel *p = dev->sysdata; printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev)); diff --git a/arch/sh/drivers/pci/pci-dreamcast.c b/arch/sh/drivers/pci/pci-dreamcast.c index 0897be5053d4..210f9d4af141 100644 --- a/arch/sh/drivers/pci/pci-dreamcast.c +++ b/arch/sh/drivers/pci/pci-dreamcast.c @@ -21,7 +21,6 @@ #include #include #include - #include #include #include @@ -40,11 +39,19 @@ static struct resource gapspci_mem_resource = { .flags = IORESOURCE_MEM, }; +static struct pci_channel dreamcast_pci_controller = { + .pci_ops = &gapspci_pci_ops, + .io_resource = &gapspci_io_resource, + .io_offset = 0x00000000, + .mem_resource = &gapspci_mem_resource, + .mem_offset = 0x00000000, +}; + /* * gapspci init */ -static int __init gapspci_init(struct pci_channel *chan) +static int __init gapspci_init(void) { char idbuf[16]; int i; @@ -88,18 +95,8 @@ static int __init gapspci_init(struct pci_channel *chan) outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); + register_pci_controller(&dreamcast_pci_controller); + return 0; } - -struct pci_channel board_pci_channels[] = { - { - .init = gapspci_init, - .pci_ops = &gapspci_pci_ops, - .io_resource = &gapspci_io_resource, - .mem_resource = &gapspci_mem_resource, - .first_devfn = 0, - .last_devfn = 1, - }, { - .init = NULL, - } -}; +arch_initcall(gapspci_init); -- GitLab From 2d5efc190eb415dbff79ffab4f8ea731ab0288a9 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 21:42:59 +0900 Subject: [PATCH 0439/6080] sh: pci: Move the se7751 fixups in to arch/sh/drivers/pci/. The se7751 was still doing the PCI fixups in its own board directory, so we move it over to arch/sh/drivers/pci/ with the rest of the board fixups. It has bitrotted significantly over the years, so will still likely need a bit of work to bring back up to date. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-se/7751/Makefile | 2 - arch/sh/boards/mach-se/7751/pci.c | 150 --------------------------- arch/sh/drivers/pci/Makefile | 1 + arch/sh/drivers/pci/fixups-se7751.c | 111 ++++++++++++++++++++ 4 files changed, 112 insertions(+), 152 deletions(-) delete mode 100644 arch/sh/boards/mach-se/7751/pci.c create mode 100644 arch/sh/drivers/pci/fixups-se7751.c diff --git a/arch/sh/boards/mach-se/7751/Makefile b/arch/sh/boards/mach-se/7751/Makefile index dbc29f3a9de5..e6f4341bfe6e 100644 --- a/arch/sh/boards/mach-se/7751/Makefile +++ b/arch/sh/boards/mach-se/7751/Makefile @@ -3,5 +3,3 @@ # obj-y := setup.o io.o irq.o - -obj-$(CONFIG_PCI) += pci.o diff --git a/arch/sh/boards/mach-se/7751/pci.c b/arch/sh/boards/mach-se/7751/pci.c deleted file mode 100644 index 9ec64a416b30..000000000000 --- a/arch/sh/boards/mach-se/7751/pci.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * linux/arch/sh/boards/se/7751/pci.c - * - * Author: Ian DaSilva (idasilva@mvista.com) - * - * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * PCI initialization for the Hitachi SH7751 Solution Engine board (MS7751SE01) - */ - -#include -#include -#include -#include -#include - -#include -#include "../../../drivers/pci/pci-sh7751.h" - -#define PCIMCR_MRSET_OFF 0xBFFFFFFF -#define PCIMCR_RFSH_OFF 0xFFFFFFFB - -/* - * Only long word accesses of the PCIC's internal local registers and the - * configuration registers from the CPU is supported. - */ -#define PCIC_WRITE(x,v) writel((v), PCI_REG(x)) -#define PCIC_READ(x) readl(PCI_REG(x)) - -#define xPCIBIOS_MIN_IO board_pci_channels->io_resource->start -#define xPCIBIOS_MIN_MEM board_pci_channels->mem_resource->start - -/* - * Description: This function sets up and initializes the pcic, sets - * up the BARS, maps the DRAM into the address space etc, etc. - */ -int __init pcibios_init_platform(void) -{ - unsigned long bcr1, wcr1, wcr2, wcr3, mcr; - unsigned short bcr2; - - /* - * Initialize the slave bus controller on the pcic. The values used - * here should not be hardcoded, but they should be taken from the bsc - * on the processor, to make this function as generic as possible. - * (i.e. Another sbc may usr different SDRAM timing settings -- in order - * for the pcic to work, its settings need to be exactly the same.) - */ - bcr1 = (*(volatile unsigned long*)(SH7751_BCR1)); - bcr2 = (*(volatile unsigned short*)(SH7751_BCR2)); - wcr1 = (*(volatile unsigned long*)(SH7751_WCR1)); - wcr2 = (*(volatile unsigned long*)(SH7751_WCR2)); - wcr3 = (*(volatile unsigned long*)(SH7751_WCR3)); - mcr = (*(volatile unsigned long*)(SH7751_MCR)); - - bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */ - (*(volatile unsigned long*)(SH7751_BCR1)) = bcr1; - - bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ - PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */ - PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */ - PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */ - PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */ - PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */ - mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; - PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */ - - - /* Enable all interrupts, so we know what to fix */ - PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff); - PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f); - - /* Set up standard PCI config registers */ - PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7); /* Bus Master, Mem & I/O access */ - PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */ - PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */ - PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */ - PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */ - PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */ - PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */ - PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */ - PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */ - PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */ - - /* Now turn it on... */ - PCIC_WRITE(SH7751_PCICR, 0xa5000001); - - /* - * Set PCIMBR and PCIIOBR here, assuming a single window - * (16M MEM, 256K IO) is enough. If a larger space is - * needed, the readx/writex and inx/outx functions will - * have to do more (e.g. setting registers for each call). - */ - - /* - * Set the MBR so PCI address is one-to-one with window, - * meaning all calls go straight through... use BUG_ON to - * catch erroneous assumption. - */ - BUG_ON(xPCIBIOS_MIN_MEM != SH7751_PCI_MEMORY_BASE); - - PCIC_WRITE(SH7751_PCIMBR, xPCIBIOS_MIN_MEM); - - /* Set IOBR for window containing area specified in pci.h */ - PCIC_WRITE(SH7751_PCIIOBR, (xPCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK)); - - /* All done, may as well say so... */ - printk("SH7751 PCI: Finished initialization of the PCI controller\n"); - - return 1; -} - -int __init pcibios_map_platform_irq(u8 slot, u8 pin) -{ - switch (slot) { - case 0: return 13; - case 1: return 13; /* AMD Ethernet controller */ - case 2: return -1; - case 3: return -1; - case 4: return -1; - default: - printk("PCI: Bad IRQ mapping request for slot %d\n", slot); - return -1; - } -} - -static struct resource sh7751_io_resource = { - .name = "SH7751 IO", - .start = SH7751_PCI_IO_BASE, - .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751 mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops sh7751_pci_ops; - -struct pci_channel board_pci_channels[] = { - { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index fbebd73b22f6..e388a70d1463 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ pci-dreamcast.o obj-$(CONFIG_SH_SECUREEDGE5410) += fixups-snapgear.o +obj-$(CONFIG_SH_7751_SOLUTION_ENGINE) += fixups-se7751.o obj-$(CONFIG_SH_RTS7751R2D) += fixups-rts7751r2d.o obj-$(CONFIG_SH_SH03) += fixups-sh03.o obj-$(CONFIG_SH_HIGHLANDER) += fixups-r7780rp.o diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c new file mode 100644 index 000000000000..475fa9f0fe2c --- /dev/null +++ b/arch/sh/drivers/pci/fixups-se7751.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include "pci-sh4.h" + +int __init pcibios_map_platform_irq(u8 slot, u8 pin) +{ + switch (slot) { + case 0: return 13; + case 1: return 13; /* AMD Ethernet controller */ + case 2: return -1; + case 3: return -1; + case 4: return -1; + default: + printk("PCI: Bad IRQ mapping request for slot %d\n", slot); + return -1; + } +} + +#define PCIMCR_MRSET_OFF 0xBFFFFFFF +#define PCIMCR_RFSH_OFF 0xFFFFFFFB + +/* + * Only long word accesses of the PCIC's internal local registers and the + * configuration registers from the CPU is supported. + */ +#define PCIC_WRITE(x,v) writel((v), PCI_REG(x)) +#define PCIC_READ(x) readl(PCI_REG(x)) + +/* + * Description: This function sets up and initializes the pcic, sets + * up the BARS, maps the DRAM into the address space etc, etc. + */ +int pci_fixup_pcic(struct pci_channel *chan) +{ + unsigned long bcr1, wcr1, wcr2, wcr3, mcr; + unsigned short bcr2; + + /* + * Initialize the slave bus controller on the pcic. The values used + * here should not be hardcoded, but they should be taken from the bsc + * on the processor, to make this function as generic as possible. + * (i.e. Another sbc may usr different SDRAM timing settings -- in order + * for the pcic to work, its settings need to be exactly the same.) + */ + bcr1 = (*(volatile unsigned long*)(SH7751_BCR1)); + bcr2 = (*(volatile unsigned short*)(SH7751_BCR2)); + wcr1 = (*(volatile unsigned long*)(SH7751_WCR1)); + wcr2 = (*(volatile unsigned long*)(SH7751_WCR2)); + wcr3 = (*(volatile unsigned long*)(SH7751_WCR3)); + mcr = (*(volatile unsigned long*)(SH7751_MCR)); + + bcr1 = bcr1 | 0x00080000; /* Enable Bit 19, BREQEN */ + (*(volatile unsigned long*)(SH7751_BCR1)) = bcr1; + + bcr1 = bcr1 | 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ + PCIC_WRITE(SH7751_PCIBCR1, bcr1); /* PCIC BCR1 */ + PCIC_WRITE(SH7751_PCIBCR2, bcr2); /* PCIC BCR2 */ + PCIC_WRITE(SH7751_PCIWCR1, wcr1); /* PCIC WCR1 */ + PCIC_WRITE(SH7751_PCIWCR2, wcr2); /* PCIC WCR2 */ + PCIC_WRITE(SH7751_PCIWCR3, wcr3); /* PCIC WCR3 */ + mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; + PCIC_WRITE(SH7751_PCIMCR, mcr); /* PCIC MCR */ + + + /* Enable all interrupts, so we know what to fix */ + PCIC_WRITE(SH7751_PCIINTM, 0x0000c3ff); + PCIC_WRITE(SH7751_PCIAINTM, 0x0000380f); + + /* Set up standard PCI config registers */ + PCIC_WRITE(SH7751_PCICONF1, 0xF39000C7); /* Bus Master, Mem & I/O access */ + PCIC_WRITE(SH7751_PCICONF2, 0x00000000); /* PCI Class code & Revision ID */ + PCIC_WRITE(SH7751_PCICONF4, 0xab000001); /* PCI I/O address (local regs) */ + PCIC_WRITE(SH7751_PCICONF5, 0x0c000000); /* PCI MEM address (local RAM) */ + PCIC_WRITE(SH7751_PCICONF6, 0xd0000000); /* PCI MEM address (unused) */ + PCIC_WRITE(SH7751_PCICONF11, 0x35051054); /* PCI Subsystem ID & Vendor ID */ + PCIC_WRITE(SH7751_PCILSR0, 0x03f00000); /* MEM (full 64M exposed) */ + PCIC_WRITE(SH7751_PCILSR1, 0x00000000); /* MEM (unused) */ + PCIC_WRITE(SH7751_PCILAR0, 0x0c000000); /* MEM (direct map from PCI) */ + PCIC_WRITE(SH7751_PCILAR1, 0x00000000); /* MEM (unused) */ + + /* Now turn it on... */ + PCIC_WRITE(SH7751_PCICR, 0xa5000001); + + /* + * Set PCIMBR and PCIIOBR here, assuming a single window + * (16M MEM, 256K IO) is enough. If a larger space is + * needed, the readx/writex and inx/outx functions will + * have to do more (e.g. setting registers for each call). + */ + + /* + * Set the MBR so PCI address is one-to-one with window, + * meaning all calls go straight through... use BUG_ON to + * catch erroneous assumption. + */ + BUG_ON(chan->mem_resource->start != SH7751_PCI_MEMORY_BASE); + + PCIC_WRITE(SH7751_PCIMBR, chan->mem_resource->start); + + /* Set IOBR for window containing area specified in pci.h */ + PCIC_WRITE(SH7751_PCIIOBR, (chan->io_resource->start & SH7751_PCIIOBR_MASK)); + + /* All done, may as well say so... */ + printk("SH7751 PCI: Finished initialization of the PCI controller\n"); + + return 1; +} -- GitLab From 805fcc88999162b361ef0b0ce25782ef65f147d7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 21:46:42 +0900 Subject: [PATCH 0440/6080] sh: pci: Kill off the last remnants of the now unused pci-auto code. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Kconfig | 18 -- arch/sh/drivers/pci/Makefile | 1 - arch/sh/drivers/pci/pci-auto.c | 546 --------------------------------- arch/sh/drivers/pci/pci.c | 75 ----- arch/sh/include/asm/pci.h | 16 - 5 files changed, 656 deletions(-) delete mode 100644 arch/sh/drivers/pci/pci-auto.c delete mode 100644 arch/sh/drivers/pci/pci.c diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index 1d53496b1498..ea903a984f01 100644 --- a/arch/sh/drivers/pci/Kconfig +++ b/arch/sh/drivers/pci/Kconfig @@ -18,24 +18,6 @@ config SH_PCIDMA_NONCOHERENT bridge integrated with your SH CPU, refer carefully to the chip specs to see if you can say 'N' here. Otherwise, leave it as 'Y'. -# Temporary config option for transitioning off of PCI_AUTO config PCI_NEW def_bool y depends on PCI - -# This is also board-specific -config PCI_AUTO - bool - depends on PCI && !PCI_NEW - default y - -config PCI_AUTO_UPDATE_RESOURCES - bool - depends on PCI_AUTO - default y if !SH_DREAMCAST - help - Selecting this option will cause the PCI auto code to leave your - BAR values alone. Otherwise they will be updated automatically. If - for some reason, you have a board that simply refuses to work - with its resources updated beyond what they are when the device - is powered up, set this to N. Everyone else will want this as Y. diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index e388a70d1463..a8350ccfa9d3 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -2,7 +2,6 @@ # Makefile for the PCI specific kernel interface routines under Linux. # obj-y += pci-lib.o -obj-$(CONFIG_PCI_AUTO) += pci.o pci-auto.o obj-$(CONFIG_PCI_NEW) += pci-new.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c deleted file mode 100644 index 1d715ec405b2..000000000000 --- a/arch/sh/drivers/pci/pci-auto.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * PCI autoconfiguration library - * - * Author: Matt Porter - * - * Copyright 2000, 2001 MontaVista Software Inc. - * Copyright 2001 Bradley D. LaRonde - * Copyright 2003 Paul Mundt - * - * 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. - */ - -/* - * Modified for MIPS by Jun Sun, jsun@mvista.com - * - * . Simplify the interface between pci_auto and the rest: a single function. - * . Assign resources from low address to upper address. - * . change most int to u32. - * - * Further modified to include it as mips generic code, ppopov@mvista.com. - * - * 2001-10-26 Bradley D. LaRonde - * - Add a top_bus argument to the "early config" functions so that - * they can set a fake parent bus pointer to convince the underlying - * pci ops to use type 1 configuration for sub busses. - * - Set bridge base and limit registers correctly. - * - Align io and memory base properly before and after bridge setup. - * - Don't fall through to pci_setup_bars for bridge. - * - Reformat the debug output to look more like lspci's output. - * - * Cloned for SuperH by M. R. Brown, mrbrown@0xd6.org - * - * 2003-08-05 Paul Mundt - * - Don't update the BAR values on systems that already have valid addresses - * and don't want these updated for whatever reason, by way of a new config - * option check. However, we still read in the old BAR values so that they - * can still be reported through the debug output. - */ - -#include -#include -#include -#include - -#define DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* - * These functions are used early on before PCI scanning is done - * and all of the pci_dev and pci_bus structures have been created. - */ -static struct pci_dev *fake_pci_dev(struct pci_channel *hose, - int top_bus, int busnr, int devfn) -{ - static struct pci_dev dev; - static struct pci_bus bus; - - dev.bus = &bus; - dev.sysdata = hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - bus.sysdata = hose; - - if(busnr != top_bus) - /* Fake a parent bus structure. */ - bus.parent = &bus; - else - bus.parent = NULL; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -static int early_##rw##_config_##size(struct pci_channel *hose, \ - int top_bus, int bus, int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size( \ - fake_pci_dev(hose, top_bus, bus, devfn), \ - offset, value); \ -} - -EARLY_PCI_OP(read, byte, u8 *) -EARLY_PCI_OP(read, word, u16 *) -EARLY_PCI_OP(read, dword, u32 *) -EARLY_PCI_OP(write, byte, u8) -EARLY_PCI_OP(write, word, u16) -EARLY_PCI_OP(write, dword, u32) - -static struct resource *io_resource_inuse; -static struct resource *mem_resource_inuse; - -static u32 pciauto_lower_iospc; -static u32 pciauto_upper_iospc; - -static u32 pciauto_lower_memspc; -static u32 pciauto_upper_memspc; - -static void __init -pciauto_setup_bars(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int bar_limit) -{ - u32 bar_response, bar_size, bar_value; - u32 bar, addr_mask, bar_nr = 0; - u32 * upper_limit; - u32 * lower_limit; - int found_mem64 = 0; - - for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) { - u32 bar_addr; - - /* Read the old BAR value */ - early_read_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - &bar_addr); - - /* Tickle the BAR and get the response */ - early_write_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - 0xffffffff); - - early_read_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - &bar_response); - - /* - * Write the old BAR value back out, only update the BAR - * if we implicitly want resources to be updated, which - * is done by the generic code further down. -- PFM. - */ - early_write_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - bar_addr); - - /* If BAR is not implemented go to the next BAR */ - if (!bar_response) - continue; - - /* - * Workaround for a BAR that doesn't use its upper word, - * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457). - * bdl - */ - if (!(bar_response & 0xffff0000)) - bar_response |= 0xffff0000; - -retry: - /* Check the BAR type and set our address mask */ - if (bar_response & PCI_BASE_ADDRESS_SPACE) { - addr_mask = PCI_BASE_ADDRESS_IO_MASK; - upper_limit = &pciauto_upper_iospc; - lower_limit = &pciauto_lower_iospc; - DBG(" I/O"); - } else { - if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == - PCI_BASE_ADDRESS_MEM_TYPE_64) - found_mem64 = 1; - - addr_mask = PCI_BASE_ADDRESS_MEM_MASK; - upper_limit = &pciauto_upper_memspc; - lower_limit = &pciauto_lower_memspc; - DBG(" Mem"); - } - - - /* Calculate requested size */ - bar_size = ~(bar_response & addr_mask) + 1; - - /* Allocate a base address */ - bar_value = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; - - if ((bar_value + bar_size) > *upper_limit) { - if (bar_response & PCI_BASE_ADDRESS_SPACE) { - if (io_resource_inuse->child) { - io_resource_inuse = - io_resource_inuse->child; - pciauto_lower_iospc = - io_resource_inuse->start; - pciauto_upper_iospc = - io_resource_inuse->end + 1; - goto retry; - } - - } else { - if (mem_resource_inuse->child) { - mem_resource_inuse = - mem_resource_inuse->child; - pciauto_lower_memspc = - mem_resource_inuse->start; - pciauto_upper_memspc = - mem_resource_inuse->end + 1; - goto retry; - } - } - DBG(" unavailable -- skipping, value %x size %x\n", - bar_value, bar_size); - continue; - } - - if (bar_value < *lower_limit || (bar_value + bar_size) >= *upper_limit) { - DBG(" unavailable -- skipping, value %x size %x\n", - bar_value, bar_size); - continue; - } - -#ifdef CONFIG_PCI_AUTO_UPDATE_RESOURCES - /* Write it out and update our limit */ - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - bar, bar_value); -#endif - - *lower_limit = bar_value + bar_size; - - /* - * If we are a 64-bit decoder then increment to the - * upper 32 bits of the bar and force it to locate - * in the lower 4GB of memory. - */ - if (found_mem64) { - bar += 4; - early_write_config_dword(hose, top_bus, - current_bus, - pci_devfn, - bar, - 0x00000000); - } - - DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size); - - bar_nr++; - } - -} - -static void __init -pciauto_prescan_setup_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) -{ - /* Configure bus number registers */ - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_PRIMARY_BUS, current_bus); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SECONDARY_BUS, sub_bus + 1); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, 0xff); - - /* Align memory and I/O to 1MB and 4KB boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) - & ~(0x100000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) - & ~(0x1000 - 1); - - /* Set base (lower limit) of address range behind bridge. */ - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_MEMORY_BASE, pciauto_lower_memspc >> 16); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_IO_BASE, (pciauto_lower_iospc & 0x0000f000) >> 8); - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_IO_BASE_UPPER16, pciauto_lower_iospc >> 16); - - /* We don't support prefetchable memory for now, so disable */ - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_PREF_MEMORY_BASE, 0); - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_PREF_MEMORY_LIMIT, 0); -} - -static void __init -pciauto_postscan_setup_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) -{ - u32 temp; - - /* - * [jsun] we always bump up baselines a little, so that if there - * nothing behind P2P bridge, we don't wind up overlapping IO/MEM - * spaces. - */ - pciauto_lower_memspc += 1; - pciauto_lower_iospc += 1; - - /* Configure bus number registers */ - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, sub_bus); - - /* Set upper limit of address range behind bridge. */ - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_MEMORY_LIMIT, pciauto_lower_memspc >> 16); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_IO_LIMIT, (pciauto_lower_iospc & 0x0000f000) >> 8); - early_write_config_word(hose, top_bus, current_bus, pci_devfn, - PCI_IO_LIMIT_UPPER16, pciauto_lower_iospc >> 16); - - /* Align memory and I/O to 1MB and 4KB boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) - & ~(0x100000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) - & ~(0x1000 - 1); - - /* Enable memory and I/O accesses, enable bus master */ - early_read_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, &temp); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY - | PCI_COMMAND_MASTER); -} - -static void __init -pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) -{ - /* Configure bus number registers */ - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_PRIMARY_BUS, current_bus); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SECONDARY_BUS, sub_bus + 1); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, 0xff); - - /* Align memory and I/O to 4KB and 4 byte boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) - & ~(0x1000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) - & ~(0x4 - 1); - - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_CB_MEMORY_BASE_0, pciauto_lower_memspc); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_CB_IO_BASE_0, pciauto_lower_iospc); -} - -static void __init -pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, - int top_bus, - int current_bus, - int pci_devfn, - int sub_bus) -{ - u32 temp; - - /* - * [jsun] we always bump up baselines a little, so that if there - * nothing behind P2P bridge, we don't wind up overlapping IO/MEM - * spaces. - */ - pciauto_lower_memspc += 1; - pciauto_lower_iospc += 1; - - /* - * Configure subordinate bus number. The PCI subsystem - * bus scan will renumber buses (reserving three additional - * for this PCI<->CardBus bridge for the case where a CardBus - * adapter contains a P2P or CB2CB bridge. - */ - - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_SUBORDINATE_BUS, sub_bus); - - /* - * Reserve an additional 4MB for mem space and 16KB for - * I/O space. This should cover any additional space - * requirement of unusual CardBus devices with - * additional bridges that can consume more address space. - * - * Although pcmcia-cs currently will reprogram bridge - * windows, the goal is to add an option to leave them - * alone and use the bridge window ranges as the regions - * that are searched for free resources upon hot-insertion - * of a device. This will allow a PCI<->CardBus bridge - * configured by this routine to happily live behind a - * P2P bridge in a system. - */ - /* Align memory and I/O to 4KB and 4 byte boundaries. */ - pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) - & ~(0x1000 - 1); - pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) - & ~(0x4 - 1); - /* Set up memory and I/O filter limits, assume 32-bit I/O space */ - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_CB_MEMORY_LIMIT_0, pciauto_lower_memspc - 1); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_CB_IO_LIMIT_0, pciauto_lower_iospc - 1); - - /* Enable memory and I/O accesses, enable bus master */ - early_read_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, &temp); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER); -} - -#define PCIAUTO_IDE_MODE_MASK 0x05 - -static int __init -pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) -{ - int sub_bus; - u32 pci_devfn, pci_class, cmdstat, found_multi=0; - unsigned short vid, did; - unsigned char header_type; - int devfn_start = 0; - int devfn_stop = 0xff; - - sub_bus = current_bus; - - if (hose->first_devfn) - devfn_start = hose->first_devfn; - if (hose->last_devfn) - devfn_stop = hose->last_devfn; - - for (pci_devfn=devfn_start; pci_devfn> 16, vid, did); - if (pci_class & 0xff) - DBG(" (rev %.2x)", pci_class & 0xff); - DBG("\n"); - - if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { - DBG(" Bridge: primary=%.2x, secondary=%.2x\n", - current_bus, sub_bus + 1); - pciauto_prescan_setup_bridge(hose, top_bus, current_bus, - pci_devfn, sub_bus); - DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", - sub_bus + 1, - pciauto_lower_iospc, pciauto_lower_memspc); - sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); - DBG("Back to bus %.2x\n", current_bus); - pciauto_postscan_setup_bridge(hose, top_bus, current_bus, - pci_devfn, sub_bus); - continue; - } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) { - DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n", - current_bus, sub_bus + 1); - DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); - /* Place CardBus Socket/ExCA registers */ - pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0); - - pciauto_prescan_setup_cardbus_bridge(hose, top_bus, - current_bus, pci_devfn, sub_bus); - - DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", - sub_bus + 1, - pciauto_lower_iospc, pciauto_lower_memspc); - sub_bus = pciauto_bus_scan(hose, top_bus, sub_bus+1); - DBG("Back to bus %.2x, sub_bus is %x\n", current_bus, sub_bus); - pciauto_postscan_setup_cardbus_bridge(hose, top_bus, - current_bus, pci_devfn, sub_bus); - continue; - } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) { - - unsigned char prg_iface; - - early_read_config_byte(hose, top_bus, current_bus, - pci_devfn, PCI_CLASS_PROG, &prg_iface); - if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) { - DBG("Skipping legacy mode IDE controller\n"); - continue; - } - } - - /* - * Found a peripheral, enable some standard - * settings - */ - early_read_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, &cmdstat); - early_write_config_dword(hose, top_bus, current_bus, pci_devfn, - PCI_COMMAND, cmdstat | PCI_COMMAND_IO | - PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER); - early_write_config_byte(hose, top_bus, current_bus, pci_devfn, - PCI_LATENCY_TIMER, 0x80); - - /* Allocate PCI I/O and/or memory space */ - pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_5); - } - return sub_bus; -} - -int __init -pciauto_assign_resources(int busno, struct pci_channel *hose) -{ - /* setup resource limits */ - io_resource_inuse = hose->io_resource; - mem_resource_inuse = hose->mem_resource; - - pciauto_lower_iospc = io_resource_inuse->start; - pciauto_upper_iospc = io_resource_inuse->end + 1; - pciauto_lower_memspc = mem_resource_inuse->start; - pciauto_upper_memspc = mem_resource_inuse->end + 1; - DBG("Autoconfig PCI channel 0x%p\n", hose); - DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n", - busno, pciauto_lower_iospc, pciauto_upper_iospc, - pciauto_lower_memspc, pciauto_upper_memspc); - - return pciauto_bus_scan(hose, busno, busno); -} diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c deleted file mode 100644 index 8c332b2a4641..000000000000 --- a/arch/sh/drivers/pci/pci.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * arch/sh/drivers/pci/pci.c - * - * Copyright (c) 2002 M. R. Brown - * Copyright (c) 2004 - 2006 Paul Mundt - * - * These functions are collected here to reduce duplication of common - * code amongst the many platform-specific PCI support code files. - * - * These routines require the following board-specific routines: - * void pcibios_fixup_irqs(); - * - * See include/asm-sh/pci.h for more information. - * - * 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. - */ -#include -#include -#include -#include -#include - -static int __init pcibios_init(void) -{ - struct pci_channel *p; - struct pci_bus *bus; - int busno; - - /* init channels */ - busno = 0; - for (p = board_pci_channels; p->init; p++) { - if (p->init(p) == 0) - p->enabled = 1; - else - pr_err("Unable to init pci channel %d\n", busno); - busno++; - } - -#ifdef CONFIG_PCI_AUTO - /* assign resources */ - busno = 0; - for (p = board_pci_channels; p->init; p++) - if (p->enabled) - busno = pciauto_assign_resources(busno, p) + 1; -#endif - - /* scan the buses */ - busno = 0; - for (p = board_pci_channels; p->init; p++) { - if (p->enabled) { - bus = pci_scan_bus(busno, p->pci_ops, p); - busno = bus->subordinate + 1; - } - } - - pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); - - dma_debug_add_bus(&pci_bus_type); - - return 0; -} -subsys_initcall(pcibios_init); - -/* - * Called after each bus is probed, but before its children - * are examined. - */ -void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) -{ - pci_read_bridge_bases(bus); -} - -EXPORT_SYMBOL(board_pci_channels); diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index f36c7899295b..f910121559b0 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -19,8 +19,6 @@ struct pci_channel { struct pci_channel *next; - int (*init)(struct pci_channel *chan); - struct pci_ops *pci_ops; struct resource *io_resource; struct resource *mem_resource; @@ -28,20 +26,11 @@ struct pci_channel { unsigned long io_offset; unsigned long mem_offset; - int first_devfn; - int last_devfn; - int enabled; - unsigned long reg_base; unsigned long io_map_base; }; -/* - * Each board initializes this array and terminates it with a NULL entry. - */ -extern struct pci_channel board_pci_channels[]; - extern void register_pci_controller(struct pci_channel *hose); extern unsigned long PCIBIOS_MIN_IO, PCIBIOS_MIN_MEM; @@ -122,13 +111,8 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, #endif /* Board-specific fixup routines. */ -int pcibios_init_platform(void); int pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin); -#ifdef CONFIG_PCI_AUTO -int pciauto_assign_resources(int busno, struct pci_channel *hose); -#endif - extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); -- GitLab From 35bcfffd86aac933205fbf8401e3e7e4dde68264 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 21:51:19 +0900 Subject: [PATCH 0441/6080] sh: pci: Roll pci-lib in to pci-new. Now that the pci-auto cruft is gone, pci-lib can go away. Roll it back in to pci-new.c where it originally split off from. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Makefile | 1 - arch/sh/drivers/pci/pci-lib.c | 219 -------------------------------- arch/sh/drivers/pci/pci-new.c | 226 +++++++++++++++++++++++++++++++++- 3 files changed, 221 insertions(+), 225 deletions(-) delete mode 100644 arch/sh/drivers/pci/pci-lib.c diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index a8350ccfa9d3..eacac7f475d9 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -1,7 +1,6 @@ # # Makefile for the PCI specific kernel interface routines under Linux. # -obj-y += pci-lib.o obj-$(CONFIG_PCI_NEW) += pci-new.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c deleted file mode 100644 index f072acafce6c..000000000000 --- a/arch/sh/drivers/pci/pci-lib.c +++ /dev/null @@ -1,219 +0,0 @@ -#include -#include -#include -#include -#include - -unsigned long PCIBIOS_MIN_IO = 0x0000; -unsigned long PCIBIOS_MIN_MEM = 0; - -/* - * We need to avoid collisions with `mirrored' VGA ports - * and other strange ISA hardware, so we always want the - * addresses to be allocated in the 0x000-0x0ff region - * modulo 0x400. - */ -void pcibios_align_resource(void *data, struct resource *res, - resource_size_t size, resource_size_t align) -{ - struct pci_dev *dev = data; - struct pci_channel *chan = dev->sysdata; - resource_size_t start = res->start; - - if (res->flags & IORESOURCE_IO) { - if (start < PCIBIOS_MIN_IO + chan->io_resource->start) - start = PCIBIOS_MIN_IO + chan->io_resource->start; - - /* - * Put everything into 0x00-0xff region modulo 0x400. - */ - if (start & 0x300) { - start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } - } else if (res->flags & IORESOURCE_MEM) { - if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start) - start = PCIBIOS_MIN_MEM + chan->mem_resource->start; - } - - res->start = start; -} - -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - struct pci_channel *hose = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - region->start = res->start - offset; - region->end = res->end - offset; -} - -void __devinit -pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) -{ - struct pci_channel *hose = dev->sysdata; - unsigned long offset = 0; - - if (res->flags & IORESOURCE_IO) - offset = hose->io_offset; - else if (res->flags & IORESOURCE_MEM) - offset = hose->mem_offset; - - res->start = region->start + offset; - res->end = region->end + offset; -} - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { - /* Only set up the requested stuff */ - if (!(mask & (1<resource[idx]; - if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) - continue; - if ((idx == PCI_ROM_RESOURCE) && - (!(r->flags & IORESOURCE_ROM_ENABLE))) - continue; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available " - "because of resource collisions\n", - pci_name(dev)); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", - pci_name(dev), old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - -/* - * If we set up a device for bus mastering, we need to check and set - * the latency timer as it may not be properly set. - */ -static unsigned int pcibios_max_latency = 255; - -void pcibios_set_master(struct pci_dev *dev) -{ - u8 lat; - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - if (lat < 16) - lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; - else if (lat > pcibios_max_latency) - lat = pcibios_max_latency; - else - return; - printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", - pci_name(dev), lat); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -char * __devinit pcibios_setup(char *str) -{ - return str; -} - -int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) -{ - /* - * I/O space can be accessed via normal processor loads and stores on - * this platform but for now we elect not to do this and portable - * drivers should not do this anyway. - */ - if (mmap_state == pci_mmap_io) - return -EINVAL; - - /* - * Ignore write-combine; for now only return uncached mappings. - */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - vma->vm_end - vma->vm_start, - vma->vm_page_prot); -} - -static void __iomem *ioport_map_pci(struct pci_dev *dev, - unsigned long port, unsigned int nr) -{ - struct pci_channel *chan = dev->sysdata; - - if (!chan->io_map_base) - chan->io_map_base = generic_io_base; - - return (void __iomem *)(chan->io_map_base + port); -} - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - resource_size_t start = pci_resource_start(dev, bar); - resource_size_t len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (unlikely(!len || !start)) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - - if (flags & IORESOURCE_IO) - return ioport_map_pci(dev, start, len); - - /* - * Presently the IORESOURCE_MEM case is a bit special, most - * SH7751 style PCI controllers have PCI memory at a fixed - * location in the address space where no remapping is desired. - * With the IORESOURCE_MEM case more care has to be taken - * to inhibit page table mapping for legacy cores, but this is - * punted off to __ioremap(). - * -- PFM. - */ - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - - return ioremap_nocache(start, len); - } - - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - iounmap(addr); -} -EXPORT_SYMBOL(pci_iounmap); - -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_resource_to_bus); -EXPORT_SYMBOL(pcibios_bus_to_resource); -EXPORT_SYMBOL(PCIBIOS_MIN_IO); -EXPORT_SYMBOL(PCIBIOS_MIN_MEM); -#endif diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c index 8c0b136eecb3..54d77cbb8b39 100644 --- a/arch/sh/drivers/pci/pci-new.c +++ b/arch/sh/drivers/pci/pci-new.c @@ -1,20 +1,28 @@ /* * New-style PCI core. * - * Copyright (c) 2002 M. R. Brown * Copyright (c) 2004 - 2009 Paul Mundt + * Copyright (c) 2002 M. R. Brown + * + * Modelled after arch/mips/pci/pci.c: + * Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org) * * 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. */ #include +#include #include #include +#include #include #include #include +unsigned long PCIBIOS_MIN_IO = 0x0000; +unsigned long PCIBIOS_MIN_MEM = 0; + /* * The PCI controller list. */ @@ -27,9 +35,6 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose) static int next_busno; struct pci_bus *bus; - /* Catch botched conversion attempts */ - BUG_ON(hose->init); - bus = pci_scan_bus(next_busno, hose->pci_ops, hose); if (bus) { next_busno = bus->subordinate + 1; @@ -128,7 +133,7 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev, * Called after each bus is probed, but before its children * are examined. */ -void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) +void __devinit pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev = bus->self; struct list_head *ln; @@ -146,3 +151,214 @@ void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) pcibios_fixup_device_resources(dev, bus); } } + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + */ +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) +{ + struct pci_dev *dev = data; + struct pci_channel *chan = dev->sysdata; + resource_size_t start = res->start; + + if (res->flags & IORESOURCE_IO) { + if (start < PCIBIOS_MIN_IO + chan->io_resource->start) + start = PCIBIOS_MIN_IO + chan->io_resource->start; + + /* + * Put everything into 0x00-0xff region modulo 0x400. + */ + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } + } else if (res->flags & IORESOURCE_MEM) { + if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start) + start = PCIBIOS_MIN_MEM + chan->mem_resource->start; + } + + res->start = start; +} + +void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res) +{ + struct pci_channel *hose = dev->sysdata; + unsigned long offset = 0; + + if (res->flags & IORESOURCE_IO) + offset = hose->io_offset; + else if (res->flags & IORESOURCE_MEM) + offset = hose->mem_offset; + + region->start = res->start - offset; + region->end = res->end - offset; +} + +void __devinit +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region) +{ + struct pci_channel *hose = dev->sysdata; + unsigned long offset = 0; + + if (res->flags & IORESOURCE_IO) + offset = hose->io_offset; + else if (res->flags & IORESOURCE_MEM) + offset = hose->mem_offset; + + res->start = region->start + offset; + res->end = region->end + offset; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1<resource[idx]; + if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) + continue; + if ((idx == PCI_ROM_RESOURCE) && + (!(r->flags & IORESOURCE_ROM_ENABLE))) + continue; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available " + "because of resource collisions\n", + pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +/* + * If we set up a device for bus mastering, we need to check and set + * the latency timer as it may not be properly set. + */ +static unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", + pci_name(dev), lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + +void __init pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} + +char * __devinit pcibios_setup(char *str) +{ + return str; +} + +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine) +{ + /* + * I/O space can be accessed via normal processor loads and stores on + * this platform but for now we elect not to do this and portable + * drivers should not do this anyway. + */ + if (mmap_state == pci_mmap_io) + return -EINVAL; + + /* + * Ignore write-combine; for now only return uncached mappings. + */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); +} + +static void __iomem *ioport_map_pci(struct pci_dev *dev, + unsigned long port, unsigned int nr) +{ + struct pci_channel *chan = dev->sysdata; + + if (!chan->io_map_base) + chan->io_map_base = generic_io_base; + + return (void __iomem *)(chan->io_map_base + port); +} + +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + resource_size_t start = pci_resource_start(dev, bar); + resource_size_t len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (unlikely(!len || !start)) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + + if (flags & IORESOURCE_IO) + return ioport_map_pci(dev, start, len); + + /* + * Presently the IORESOURCE_MEM case is a bit special, most + * SH7751 style PCI controllers have PCI memory at a fixed + * location in the address space where no remapping is desired. + * With the IORESOURCE_MEM case more care has to be taken + * to inhibit page table mapping for legacy cores, but this is + * punted off to __ioremap(). + * -- PFM. + */ + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + + return ioremap_nocache(start, len); + } + + return NULL; +} +EXPORT_SYMBOL(pci_iomap); + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + iounmap(addr); +} +EXPORT_SYMBOL(pci_iounmap); + +#ifdef CONFIG_HOTPLUG +EXPORT_SYMBOL(pcibios_resource_to_bus); +EXPORT_SYMBOL(pcibios_bus_to_resource); +EXPORT_SYMBOL(PCIBIOS_MIN_IO); +EXPORT_SYMBOL(PCIBIOS_MIN_MEM); +#endif -- GitLab From cf242007a1eb29dcf93d1cb34713ec9b3f4a0e1b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Apr 2009 21:53:33 +0900 Subject: [PATCH 0442/6080] sh: pci: Rename pci-new.c to pci.c. pci-new.c is now in a state to replace the old pci.c, rename it accordingly. Signed-off-by: Paul Mundt --- arch/sh/drivers/pci/Kconfig | 4 ---- arch/sh/drivers/pci/Makefile | 2 +- arch/sh/drivers/pci/{pci-new.c => pci.c} | 0 3 files changed, 1 insertion(+), 5 deletions(-) rename arch/sh/drivers/pci/{pci-new.c => pci.c} (100%) diff --git a/arch/sh/drivers/pci/Kconfig b/arch/sh/drivers/pci/Kconfig index ea903a984f01..e8db585a6638 100644 --- a/arch/sh/drivers/pci/Kconfig +++ b/arch/sh/drivers/pci/Kconfig @@ -17,7 +17,3 @@ config SH_PCIDMA_NONCOHERENT code will not have to flush the CPU's caches. If you have a PCI host bridge integrated with your SH CPU, refer carefully to the chip specs to see if you can say 'N' here. Otherwise, leave it as 'Y'. - -config PCI_NEW - def_bool y - depends on PCI diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index eacac7f475d9..d2ffc477549a 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -1,7 +1,7 @@ # # Makefile for the PCI specific kernel interface routines under Linux. # -obj-$(CONFIG_PCI_NEW) += pci-new.o +obj-y += pci.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7751R) += pci-sh7751.o ops-sh4.o diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci.c similarity index 100% rename from arch/sh/drivers/pci/pci-new.c rename to arch/sh/drivers/pci/pci.c -- GitLab From d24e473e5b2ca86d1288b9416227ccc603313d0f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 13:32:07 +0200 Subject: [PATCH 0443/6080] perf_counter: copy in Git's top Makefile We'd like to have a similar user-space structure as Git has, for the perfcounter tools - so copy in Git's toplevel makefile as-is. We'll strip it down in subsequent commits to make it fit the perfcounters code. The Git version used: 66996ec: Sync with 1.6.2.4 Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 1735 ++++++++++++++++++++++++++- 1 file changed, 1724 insertions(+), 11 deletions(-) diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index 1dd37ee7dbdc..6e0838b03ad1 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -1,18 +1,1731 @@ -BINS = kerneltop perfstat perf-record perf-report +# The default target of this Makefile is... +all:: -all: $(BINS) +# Define V=1 to have a more verbose compile. +# +# Define SNPRINTF_RETURNS_BOGUS if your are on a system which snprintf() +# or vsnprintf() return -1 instead of number of characters which would +# have been written to the final string if enough space had been available. +# +# Define FREAD_READS_DIRECTORIES if your are on a system which succeeds +# when attempting to read from an fopen'ed directory. +# +# Define NO_OPENSSL environment variable if you do not have OpenSSL. +# This also implies MOZILLA_SHA1. +# +# Define NO_CURL if you do not have libcurl installed. git-http-pull and +# git-http-push are not built, and you cannot use http:// and https:// +# transports. +# +# Define CURLDIR=/foo/bar if your curl header and library files are in +# /foo/bar/include and /foo/bar/lib directories. +# +# Define NO_EXPAT if you do not have expat installed. git-http-push is +# not built, and you cannot push using http:// and https:// transports. +# +# Define EXPATDIR=/foo/bar if your expat header and library files are in +# /foo/bar/include and /foo/bar/lib directories. +# +# Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent. +# +# Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks +# d_type in struct dirent (latest Cygwin -- will be fixed soonish). +# +# Define NO_C99_FORMAT if your formatted IO functions (printf/scanf et.al.) +# do not support the 'size specifiers' introduced by C99, namely ll, hh, +# j, z, t. (representing long long int, char, intmax_t, size_t, ptrdiff_t). +# some C compilers supported these specifiers prior to C99 as an extension. +# +# Define NO_STRCASESTR if you don't have strcasestr. +# +# Define NO_MEMMEM if you don't have memmem. +# +# Define NO_STRLCPY if you don't have strlcpy. +# +# Define NO_STRTOUMAX if you don't have strtoumax in the C library. +# If your compiler also does not support long long or does not have +# strtoull, define NO_STRTOULL. +# +# Define NO_SETENV if you don't have setenv in the C library. +# +# Define NO_UNSETENV if you don't have unsetenv in the C library. +# +# Define NO_MKDTEMP if you don't have mkdtemp in the C library. +# +# Define NO_SYS_SELECT_H if you don't have sys/select.h. +# +# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link. +# Enable it on Windows. By default, symrefs are still used. +# +# Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability +# tests. These tests take up a significant amount of the total test time +# but are not needed unless you plan to talk to SVN repos. +# +# Define NO_FINK if you are building on Darwin/Mac OS X, have Fink +# installed in /sw, but don't want GIT to link against any libraries +# installed there. If defined you may specify your own (or Fink's) +# include directories and library directories by defining CFLAGS +# and LDFLAGS appropriately. +# +# Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X, +# have DarwinPorts installed in /opt/local, but don't want GIT to +# link against any libraries installed there. If defined you may +# specify your own (or DarwinPort's) include directories and +# library directories by defining CFLAGS and LDFLAGS appropriately. +# +# Define PPC_SHA1 environment variable when running make to make use of +# a bundled SHA1 routine optimized for PowerPC. +# +# Define ARM_SHA1 environment variable when running make to make use of +# a bundled SHA1 routine optimized for ARM. +# +# Define MOZILLA_SHA1 environment variable when running make to make use of +# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast +# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default +# choice) has very fast version optimized for i586. +# +# Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin). +# +# Define NEEDS_LIBICONV if linking with libc is not enough (Darwin). +# +# Define NEEDS_SOCKET if linking with libc is not enough (SunOS, +# Patrick Mauritz). +# +# Define NO_MMAP if you want to avoid mmap. +# +# Define NO_PTHREADS if you do not have or do not want to use Pthreads. +# +# Define NO_PREAD if you have a problem with pread() system call (e.g. +# cygwin.dll before v1.5.22). +# +# Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is +# generally faster on your platform than accessing the working directory. +# +# Define NO_TRUSTABLE_FILEMODE if your filesystem may claim to support +# the executable mode bit, but doesn't really do so. +# +# Define NO_IPV6 if you lack IPv6 support and getaddrinfo(). +# +# Define NO_SOCKADDR_STORAGE if your platform does not have struct +# sockaddr_storage. +# +# Define NO_ICONV if your libc does not properly support iconv. +# +# Define OLD_ICONV if your library has an old iconv(), where the second +# (input buffer pointer) parameter is declared with type (const char **). +# +# Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. +# +# Define NO_R_TO_GCC_LINKER if your gcc does not like "-R/path/lib" +# that tells runtime paths to dynamic libraries; +# "-Wl,-rpath=/path/lib" is used instead. +# +# Define USE_NSEC below if you want git to care about sub-second file mtimes +# and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and +# it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely +# randomly break unless your underlying filesystem supports those sub-second +# times (my ext3 doesn't). +# +# Define USE_ST_TIMESPEC if your "struct stat" uses "st_ctimespec" instead of +# "st_ctim" +# +# Define NO_NSEC if your "struct stat" does not have "st_ctim.tv_nsec" +# available. This automatically turns USE_NSEC off. +# +# Define USE_STDEV below if you want git to care about the underlying device +# change being considered an inode change from the update-index perspective. +# +# Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks +# field that counts the on-disk footprint in 512-byte blocks. +# +# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8 +# +# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72. +# +# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's +# MakeMaker (e.g. using ActiveState under Cygwin). +# +# Define NO_PERL if you do not want Perl scripts or libraries at all. +# +# Define NO_TCLTK if you do not want Tcl/Tk GUI. +# +# The TCL_PATH variable governs the location of the Tcl interpreter +# used to optimize git-gui for your system. Only used if NO_TCLTK +# is not set. Defaults to the bare 'tclsh'. +# +# The TCLTK_PATH variable governs the location of the Tcl/Tk interpreter. +# If not set it defaults to the bare 'wish'. If it is set to the empty +# string then NO_TCLTK will be forced (this is used by configure script). +# +# Define THREADED_DELTA_SEARCH if you have pthreads and wish to exploit +# parallel delta searching when packing objects. +# +# Define INTERNAL_QSORT to use Git's implementation of qsort(), which +# is a simplified version of the merge sort used in glibc. This is +# recommended if Git triggers O(n^2) behavior in your platform's qsort(). +# +# Define NO_EXTERNAL_GREP if you don't want "git grep" to ever call +# your external grep (e.g., if your system lacks grep, if its grep is +# broken, or spawning external process is slower than built-in grep git has). -kerneltop: kerneltop.c ../../include/linux/perf_counter.h - cc -O6 -Wall -lrt -o $@ $< +GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE + @$(SHELL_PATH) ./GIT-VERSION-GEN +-include GIT-VERSION-FILE -perf-record: perf-record.c ../../include/linux/perf_counter.h - cc -O6 -Wall -lrt -o $@ $< +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') +uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not') +uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not') +uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not') +uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not') +uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not') -perf-report: perf-report.cc ../../include/linux/perf_counter.h - g++ -O6 -Wall -lrt -o $@ $< +# CFLAGS and LDFLAGS are for the users to override from the command line. -perfstat: kerneltop - ln -sf kerneltop perfstat +CFLAGS = -g -O2 -Wall +LDFLAGS = +ALL_CFLAGS = $(CFLAGS) +ALL_LDFLAGS = $(LDFLAGS) +STRIP ?= strip + +# Among the variables below, these: +# gitexecdir +# template_dir +# mandir +# infodir +# htmldir +# ETC_GITCONFIG (but not sysconfdir) +# can be specified as a relative path some/where/else; +# this is interpreted as relative to $(prefix) and "git" at +# runtime figures out where they are based on the path to the executable. +# This can help installing the suite in a relocatable way. + +prefix = $(HOME) +bindir_relative = bin +bindir = $(prefix)/$(bindir_relative) +mandir = share/man +infodir = share/info +gitexecdir = libexec/git-core +sharedir = $(prefix)/share +template_dir = share/git-core/templates +htmldir = share/doc/git-doc +ifeq ($(prefix),/usr) +sysconfdir = /etc +ETC_GITCONFIG = $(sysconfdir)/gitconfig +else +sysconfdir = $(prefix)/etc +ETC_GITCONFIG = etc/gitconfig +endif +lib = lib +# DESTDIR= + +# default configuration for gitweb +GITWEB_CONFIG = gitweb_config.perl +GITWEB_CONFIG_SYSTEM = /etc/gitweb.conf +GITWEB_HOME_LINK_STR = projects +GITWEB_SITENAME = +GITWEB_PROJECTROOT = /pub/git +GITWEB_PROJECT_MAXDEPTH = 2007 +GITWEB_EXPORT_OK = +GITWEB_STRICT_EXPORT = +GITWEB_BASE_URL = +GITWEB_LIST = +GITWEB_HOMETEXT = indextext.html +GITWEB_CSS = gitweb.css +GITWEB_LOGO = git-logo.png +GITWEB_FAVICON = git-favicon.png +GITWEB_SITE_HEADER = +GITWEB_SITE_FOOTER = + +export prefix bindir sharedir sysconfdir + +CC = gcc +AR = ar +RM = rm -f +TAR = tar +FIND = find +INSTALL = install +RPMBUILD = rpmbuild +TCL_PATH = tclsh +TCLTK_PATH = wish +PTHREAD_LIBS = -lpthread + +export TCL_PATH TCLTK_PATH + +# sparse is architecture-neutral, which means that we need to tell it +# explicitly what architecture to check for. Fix this up for yours.. +SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ + + + +### --- END CONFIGURATION SECTION --- + +# Those must not be GNU-specific; they are shared with perl/ which may +# be built by a different compiler. (Note that this is an artifact now +# but it still might be nice to keep that distinction.) +BASIC_CFLAGS = +BASIC_LDFLAGS = + +# Guard against environment variables +BUILTIN_OBJS = +BUILT_INS = +COMPAT_CFLAGS = +COMPAT_OBJS = +LIB_H = +LIB_OBJS = +PROGRAMS = +SCRIPT_PERL = +SCRIPT_SH = +TEST_PROGRAMS = + +SCRIPT_SH += git-am.sh +SCRIPT_SH += git-bisect.sh +SCRIPT_SH += git-difftool--helper.sh +SCRIPT_SH += git-filter-branch.sh +SCRIPT_SH += git-lost-found.sh +SCRIPT_SH += git-merge-octopus.sh +SCRIPT_SH += git-merge-one-file.sh +SCRIPT_SH += git-merge-resolve.sh +SCRIPT_SH += git-mergetool.sh +SCRIPT_SH += git-mergetool--lib.sh +SCRIPT_SH += git-parse-remote.sh +SCRIPT_SH += git-pull.sh +SCRIPT_SH += git-quiltimport.sh +SCRIPT_SH += git-rebase--interactive.sh +SCRIPT_SH += git-rebase.sh +SCRIPT_SH += git-repack.sh +SCRIPT_SH += git-request-pull.sh +SCRIPT_SH += git-sh-setup.sh +SCRIPT_SH += git-stash.sh +SCRIPT_SH += git-submodule.sh +SCRIPT_SH += git-web--browse.sh + +SCRIPT_PERL += git-add--interactive.perl +SCRIPT_PERL += git-difftool.perl +SCRIPT_PERL += git-archimport.perl +SCRIPT_PERL += git-cvsexportcommit.perl +SCRIPT_PERL += git-cvsimport.perl +SCRIPT_PERL += git-cvsserver.perl +SCRIPT_PERL += git-relink.perl +SCRIPT_PERL += git-send-email.perl +SCRIPT_PERL += git-svn.perl + +SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ + $(patsubst %.perl,%,$(SCRIPT_PERL)) \ + git-instaweb + +# Empty... +EXTRA_PROGRAMS = + +# ... and all the rest that could be moved out of bindir to gitexecdir +PROGRAMS += $(EXTRA_PROGRAMS) +PROGRAMS += git-fast-import$X +PROGRAMS += git-hash-object$X +PROGRAMS += git-index-pack$X +PROGRAMS += git-merge-index$X +PROGRAMS += git-merge-tree$X +PROGRAMS += git-mktag$X +PROGRAMS += git-mktree$X +PROGRAMS += git-pack-redundant$X +PROGRAMS += git-patch-id$X +PROGRAMS += git-shell$X +PROGRAMS += git-show-index$X +PROGRAMS += git-unpack-file$X +PROGRAMS += git-update-server-info$X +PROGRAMS += git-upload-pack$X +PROGRAMS += git-var$X + +# List built-in command $C whose implementation cmd_$C() is not in +# builtin-$C.o but is linked in as part of some other command. +BUILT_INS += $(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS)) + +BUILT_INS += git-cherry$X +BUILT_INS += git-cherry-pick$X +BUILT_INS += git-format-patch$X +BUILT_INS += git-fsck-objects$X +BUILT_INS += git-get-tar-commit-id$X +BUILT_INS += git-init$X +BUILT_INS += git-merge-subtree$X +BUILT_INS += git-peek-remote$X +BUILT_INS += git-repo-config$X +BUILT_INS += git-show$X +BUILT_INS += git-stage$X +BUILT_INS += git-status$X +BUILT_INS += git-whatchanged$X + +# what 'all' will build and 'install' will install, in gitexecdir +ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) + +# what 'all' will build but not install in gitexecdir +OTHER_PROGRAMS = git$X +ifndef NO_PERL +OTHER_PROGRAMS += gitweb/gitweb.cgi +endif + +# Set paths to tools early so that they can be used for version tests. +ifndef SHELL_PATH + SHELL_PATH = /bin/sh +endif +ifndef PERL_PATH + PERL_PATH = /usr/bin/perl +endif + +export PERL_PATH + +LIB_FILE=libgit.a +XDIFF_LIB=xdiff/lib.a + +LIB_H += archive.h +LIB_H += attr.h +LIB_H += blob.h +LIB_H += builtin.h +LIB_H += cache.h +LIB_H += cache-tree.h +LIB_H += commit.h +LIB_H += compat/cygwin.h +LIB_H += compat/mingw.h +LIB_H += csum-file.h +LIB_H += decorate.h +LIB_H += delta.h +LIB_H += diffcore.h +LIB_H += diff.h +LIB_H += dir.h +LIB_H += fsck.h +LIB_H += git-compat-util.h +LIB_H += graph.h +LIB_H += grep.h +LIB_H += hash.h +LIB_H += help.h +LIB_H += levenshtein.h +LIB_H += list-objects.h +LIB_H += ll-merge.h +LIB_H += log-tree.h +LIB_H += mailmap.h +LIB_H += merge-recursive.h +LIB_H += object.h +LIB_H += pack.h +LIB_H += pack-refs.h +LIB_H += pack-revindex.h +LIB_H += parse-options.h +LIB_H += patch-ids.h +LIB_H += pkt-line.h +LIB_H += progress.h +LIB_H += quote.h +LIB_H += reflog-walk.h +LIB_H += refs.h +LIB_H += remote.h +LIB_H += rerere.h +LIB_H += revision.h +LIB_H += run-command.h +LIB_H += sha1-lookup.h +LIB_H += sideband.h +LIB_H += sigchain.h +LIB_H += strbuf.h +LIB_H += string-list.h +LIB_H += tag.h +LIB_H += transport.h +LIB_H += tree.h +LIB_H += tree-walk.h +LIB_H += unpack-trees.h +LIB_H += userdiff.h +LIB_H += utf8.h +LIB_H += wt-status.h + +LIB_OBJS += abspath.o +LIB_OBJS += alias.o +LIB_OBJS += alloc.o +LIB_OBJS += archive.o +LIB_OBJS += archive-tar.o +LIB_OBJS += archive-zip.o +LIB_OBJS += attr.o +LIB_OBJS += base85.o +LIB_OBJS += bisect.o +LIB_OBJS += blob.o +LIB_OBJS += branch.o +LIB_OBJS += bundle.o +LIB_OBJS += cache-tree.o +LIB_OBJS += color.o +LIB_OBJS += combine-diff.o +LIB_OBJS += commit.o +LIB_OBJS += config.o +LIB_OBJS += connect.o +LIB_OBJS += convert.o +LIB_OBJS += copy.o +LIB_OBJS += csum-file.o +LIB_OBJS += ctype.o +LIB_OBJS += date.o +LIB_OBJS += decorate.o +LIB_OBJS += diffcore-break.o +LIB_OBJS += diffcore-delta.o +LIB_OBJS += diffcore-order.o +LIB_OBJS += diffcore-pickaxe.o +LIB_OBJS += diffcore-rename.o +LIB_OBJS += diff-delta.o +LIB_OBJS += diff-lib.o +LIB_OBJS += diff-no-index.o +LIB_OBJS += diff.o +LIB_OBJS += dir.o +LIB_OBJS += editor.o +LIB_OBJS += entry.o +LIB_OBJS += environment.o +LIB_OBJS += exec_cmd.o +LIB_OBJS += fsck.o +LIB_OBJS += graph.o +LIB_OBJS += grep.o +LIB_OBJS += hash.o +LIB_OBJS += help.o +LIB_OBJS += ident.o +LIB_OBJS += levenshtein.o +LIB_OBJS += list-objects.o +LIB_OBJS += ll-merge.o +LIB_OBJS += lockfile.o +LIB_OBJS += log-tree.o +LIB_OBJS += mailmap.o +LIB_OBJS += match-trees.o +LIB_OBJS += merge-file.o +LIB_OBJS += merge-recursive.o +LIB_OBJS += name-hash.o +LIB_OBJS += object.o +LIB_OBJS += pack-check.o +LIB_OBJS += pack-refs.o +LIB_OBJS += pack-revindex.o +LIB_OBJS += pack-write.o +LIB_OBJS += pager.o +LIB_OBJS += parse-options.o +LIB_OBJS += patch-delta.o +LIB_OBJS += patch-ids.o +LIB_OBJS += path.o +LIB_OBJS += pkt-line.o +LIB_OBJS += preload-index.o +LIB_OBJS += pretty.o +LIB_OBJS += progress.o +LIB_OBJS += quote.o +LIB_OBJS += reachable.o +LIB_OBJS += read-cache.o +LIB_OBJS += reflog-walk.o +LIB_OBJS += refs.o +LIB_OBJS += remote.o +LIB_OBJS += rerere.o +LIB_OBJS += revision.o +LIB_OBJS += run-command.o +LIB_OBJS += server-info.o +LIB_OBJS += setup.o +LIB_OBJS += sha1-lookup.o +LIB_OBJS += sha1_file.o +LIB_OBJS += sha1_name.o +LIB_OBJS += shallow.o +LIB_OBJS += sideband.o +LIB_OBJS += sigchain.o +LIB_OBJS += strbuf.o +LIB_OBJS += string-list.o +LIB_OBJS += symlinks.o +LIB_OBJS += tag.o +LIB_OBJS += trace.o +LIB_OBJS += transport.o +LIB_OBJS += tree-diff.o +LIB_OBJS += tree.o +LIB_OBJS += tree-walk.o +LIB_OBJS += unpack-trees.o +LIB_OBJS += usage.o +LIB_OBJS += userdiff.o +LIB_OBJS += utf8.o +LIB_OBJS += walker.o +LIB_OBJS += wrapper.o +LIB_OBJS += write_or_die.o +LIB_OBJS += ws.o +LIB_OBJS += wt-status.o +LIB_OBJS += xdiff-interface.o + +BUILTIN_OBJS += builtin-add.o +BUILTIN_OBJS += builtin-annotate.o +BUILTIN_OBJS += builtin-apply.o +BUILTIN_OBJS += builtin-archive.o +BUILTIN_OBJS += builtin-bisect--helper.o +BUILTIN_OBJS += builtin-blame.o +BUILTIN_OBJS += builtin-branch.o +BUILTIN_OBJS += builtin-bundle.o +BUILTIN_OBJS += builtin-cat-file.o +BUILTIN_OBJS += builtin-check-attr.o +BUILTIN_OBJS += builtin-check-ref-format.o +BUILTIN_OBJS += builtin-checkout-index.o +BUILTIN_OBJS += builtin-checkout.o +BUILTIN_OBJS += builtin-clean.o +BUILTIN_OBJS += builtin-clone.o +BUILTIN_OBJS += builtin-commit-tree.o +BUILTIN_OBJS += builtin-commit.o +BUILTIN_OBJS += builtin-config.o +BUILTIN_OBJS += builtin-count-objects.o +BUILTIN_OBJS += builtin-describe.o +BUILTIN_OBJS += builtin-diff-files.o +BUILTIN_OBJS += builtin-diff-index.o +BUILTIN_OBJS += builtin-diff-tree.o +BUILTIN_OBJS += builtin-diff.o +BUILTIN_OBJS += builtin-fast-export.o +BUILTIN_OBJS += builtin-fetch--tool.o +BUILTIN_OBJS += builtin-fetch-pack.o +BUILTIN_OBJS += builtin-fetch.o +BUILTIN_OBJS += builtin-fmt-merge-msg.o +BUILTIN_OBJS += builtin-for-each-ref.o +BUILTIN_OBJS += builtin-fsck.o +BUILTIN_OBJS += builtin-gc.o +BUILTIN_OBJS += builtin-grep.o +BUILTIN_OBJS += builtin-help.o +BUILTIN_OBJS += builtin-init-db.o +BUILTIN_OBJS += builtin-log.o +BUILTIN_OBJS += builtin-ls-files.o +BUILTIN_OBJS += builtin-ls-remote.o +BUILTIN_OBJS += builtin-ls-tree.o +BUILTIN_OBJS += builtin-mailinfo.o +BUILTIN_OBJS += builtin-mailsplit.o +BUILTIN_OBJS += builtin-merge.o +BUILTIN_OBJS += builtin-merge-base.o +BUILTIN_OBJS += builtin-merge-file.o +BUILTIN_OBJS += builtin-merge-ours.o +BUILTIN_OBJS += builtin-merge-recursive.o +BUILTIN_OBJS += builtin-mv.o +BUILTIN_OBJS += builtin-name-rev.o +BUILTIN_OBJS += builtin-pack-objects.o +BUILTIN_OBJS += builtin-pack-refs.o +BUILTIN_OBJS += builtin-prune-packed.o +BUILTIN_OBJS += builtin-prune.o +BUILTIN_OBJS += builtin-push.o +BUILTIN_OBJS += builtin-read-tree.o +BUILTIN_OBJS += builtin-receive-pack.o +BUILTIN_OBJS += builtin-reflog.o +BUILTIN_OBJS += builtin-remote.o +BUILTIN_OBJS += builtin-rerere.o +BUILTIN_OBJS += builtin-reset.o +BUILTIN_OBJS += builtin-rev-list.o +BUILTIN_OBJS += builtin-rev-parse.o +BUILTIN_OBJS += builtin-revert.o +BUILTIN_OBJS += builtin-rm.o +BUILTIN_OBJS += builtin-send-pack.o +BUILTIN_OBJS += builtin-shortlog.o +BUILTIN_OBJS += builtin-show-branch.o +BUILTIN_OBJS += builtin-show-ref.o +BUILTIN_OBJS += builtin-stripspace.o +BUILTIN_OBJS += builtin-symbolic-ref.o +BUILTIN_OBJS += builtin-tag.o +BUILTIN_OBJS += builtin-tar-tree.o +BUILTIN_OBJS += builtin-unpack-objects.o +BUILTIN_OBJS += builtin-update-index.o +BUILTIN_OBJS += builtin-update-ref.o +BUILTIN_OBJS += builtin-upload-archive.o +BUILTIN_OBJS += builtin-verify-pack.o +BUILTIN_OBJS += builtin-verify-tag.o +BUILTIN_OBJS += builtin-write-tree.o + +GITLIBS = $(LIB_FILE) $(XDIFF_LIB) +EXTLIBS = + +# +# Platform specific tweaks +# + +# We choose to avoid "if .. else if .. else .. endif endif" +# because maintaining the nesting to match is a pain. If +# we had "elif" things would have been much nicer... + +ifeq ($(uname_S),Linux) + NO_STRLCPY = YesPlease + THREADED_DELTA_SEARCH = YesPlease +endif +ifeq ($(uname_S),GNU/kFreeBSD) + NO_STRLCPY = YesPlease + THREADED_DELTA_SEARCH = YesPlease +endif +ifeq ($(uname_S),UnixWare) + CC = cc + NEEDS_SOCKET = YesPlease + NEEDS_NSL = YesPlease + NEEDS_SSL_WITH_CRYPTO = YesPlease + NEEDS_LIBICONV = YesPlease + SHELL_PATH = /usr/local/bin/bash + NO_IPV6 = YesPlease + NO_HSTRERROR = YesPlease + BASIC_CFLAGS += -Kthread + BASIC_CFLAGS += -I/usr/local/include + BASIC_LDFLAGS += -L/usr/local/lib + INSTALL = ginstall + TAR = gtar + NO_STRCASESTR = YesPlease + NO_MEMMEM = YesPlease +endif +ifeq ($(uname_S),SCO_SV) + ifeq ($(uname_R),3.2) + CFLAGS = -O2 + endif + ifeq ($(uname_R),5) + CC = cc + BASIC_CFLAGS += -Kthread + endif + NEEDS_SOCKET = YesPlease + NEEDS_NSL = YesPlease + NEEDS_SSL_WITH_CRYPTO = YesPlease + NEEDS_LIBICONV = YesPlease + SHELL_PATH = /usr/bin/bash + NO_IPV6 = YesPlease + NO_HSTRERROR = YesPlease + BASIC_CFLAGS += -I/usr/local/include + BASIC_LDFLAGS += -L/usr/local/lib + NO_STRCASESTR = YesPlease + NO_MEMMEM = YesPlease + INSTALL = ginstall + TAR = gtar +endif +ifeq ($(uname_S),Darwin) + NEEDS_SSL_WITH_CRYPTO = YesPlease + NEEDS_LIBICONV = YesPlease + ifeq ($(shell expr "$(uname_R)" : '[15678]\.'),2) + OLD_ICONV = UnfortunatelyYes + endif + ifeq ($(shell expr "$(uname_R)" : '[15]\.'),2) + NO_STRLCPY = YesPlease + endif + NO_MEMMEM = YesPlease + THREADED_DELTA_SEARCH = YesPlease + USE_ST_TIMESPEC = YesPlease +endif +ifeq ($(uname_S),SunOS) + NEEDS_SOCKET = YesPlease + NEEDS_NSL = YesPlease + SHELL_PATH = /bin/bash + NO_STRCASESTR = YesPlease + NO_MEMMEM = YesPlease + NO_HSTRERROR = YesPlease + NO_MKDTEMP = YesPlease + OLD_ICONV = UnfortunatelyYes + ifeq ($(uname_R),5.8) + NO_UNSETENV = YesPlease + NO_SETENV = YesPlease + NO_C99_FORMAT = YesPlease + NO_STRTOUMAX = YesPlease + endif + ifeq ($(uname_R),5.9) + NO_UNSETENV = YesPlease + NO_SETENV = YesPlease + NO_C99_FORMAT = YesPlease + NO_STRTOUMAX = YesPlease + endif + INSTALL = ginstall + TAR = gtar + BASIC_CFLAGS += -D__EXTENSIONS__ +endif +ifeq ($(uname_O),Cygwin) + NO_D_TYPE_IN_DIRENT = YesPlease + NO_D_INO_IN_DIRENT = YesPlease + NO_STRCASESTR = YesPlease + NO_MEMMEM = YesPlease + NO_SYMLINK_HEAD = YesPlease + NEEDS_LIBICONV = YesPlease + NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes + NO_TRUSTABLE_FILEMODE = UnfortunatelyYes + OLD_ICONV = UnfortunatelyYes + # There are conflicting reports about this. + # On some boxes NO_MMAP is needed, and not so elsewhere. + # Try commenting this out if you suspect MMAP is more efficient + NO_MMAP = YesPlease + NO_IPV6 = YesPlease + X = .exe +endif +ifeq ($(uname_S),FreeBSD) + NEEDS_LIBICONV = YesPlease + NO_MEMMEM = YesPlease + BASIC_CFLAGS += -I/usr/local/include + BASIC_LDFLAGS += -L/usr/local/lib + DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease + USE_ST_TIMESPEC = YesPlease + THREADED_DELTA_SEARCH = YesPlease + ifeq ($(shell expr "$(uname_R)" : '4\.'),2) + PTHREAD_LIBS = -pthread + NO_UINTMAX_T = YesPlease + NO_STRTOUMAX = YesPlease + endif +endif +ifeq ($(uname_S),OpenBSD) + NO_STRCASESTR = YesPlease + NO_MEMMEM = YesPlease + NEEDS_LIBICONV = YesPlease + BASIC_CFLAGS += -I/usr/local/include + BASIC_LDFLAGS += -L/usr/local/lib + THREADED_DELTA_SEARCH = YesPlease +endif +ifeq ($(uname_S),NetBSD) + ifeq ($(shell expr "$(uname_R)" : '[01]\.'),2) + NEEDS_LIBICONV = YesPlease + endif + BASIC_CFLAGS += -I/usr/pkg/include + BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib + THREADED_DELTA_SEARCH = YesPlease +endif +ifeq ($(uname_S),AIX) + NO_STRCASESTR=YesPlease + NO_MEMMEM = YesPlease + NO_MKDTEMP = YesPlease + NO_STRLCPY = YesPlease + NO_NSEC = YesPlease + FREAD_READS_DIRECTORIES = UnfortunatelyYes + INTERNAL_QSORT = UnfortunatelyYes + NEEDS_LIBICONV=YesPlease + BASIC_CFLAGS += -D_LARGE_FILES + ifneq ($(shell expr "$(uname_V)" : '[1234]'),1) + THREADED_DELTA_SEARCH = YesPlease + else + NO_PTHREADS = YesPlease + endif +endif +ifeq ($(uname_S),GNU) + # GNU/Hurd + NO_STRLCPY=YesPlease +endif +ifeq ($(uname_S),IRIX64) + NO_IPV6=YesPlease + NO_SETENV=YesPlease + NO_STRCASESTR=YesPlease + NO_MEMMEM = YesPlease + NO_STRLCPY = YesPlease + NO_SOCKADDR_STORAGE=YesPlease + SHELL_PATH=/usr/gnu/bin/bash + BASIC_CFLAGS += -DPATH_MAX=1024 + # for now, build 32-bit version + BASIC_LDFLAGS += -L/usr/lib32 +endif +ifeq ($(uname_S),HP-UX) + NO_IPV6=YesPlease + NO_SETENV=YesPlease + NO_STRCASESTR=YesPlease + NO_MEMMEM = YesPlease + NO_STRLCPY = YesPlease + NO_MKDTEMP = YesPlease + NO_UNSETENV = YesPlease + NO_HSTRERROR = YesPlease + NO_SYS_SELECT_H = YesPlease + SNPRINTF_RETURNS_BOGUS = YesPlease +endif +ifneq (,$(findstring CYGWIN,$(uname_S))) + COMPAT_OBJS += compat/cygwin.o +endif +ifneq (,$(findstring MINGW,$(uname_S))) + NO_PREAD = YesPlease + NO_OPENSSL = YesPlease + NO_CURL = YesPlease + NO_SYMLINK_HEAD = YesPlease + NO_IPV6 = YesPlease + NO_SETENV = YesPlease + NO_UNSETENV = YesPlease + NO_STRCASESTR = YesPlease + NO_STRLCPY = YesPlease + NO_MEMMEM = YesPlease + NO_PTHREADS = YesPlease + NEEDS_LIBICONV = YesPlease + OLD_ICONV = YesPlease + NO_C99_FORMAT = YesPlease + NO_STRTOUMAX = YesPlease + NO_MKDTEMP = YesPlease + SNPRINTF_RETURNS_BOGUS = YesPlease + NO_SVN_TESTS = YesPlease + NO_PERL_MAKEMAKER = YesPlease + RUNTIME_PREFIX = YesPlease + NO_POSIX_ONLY_PROGRAMS = YesPlease + NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease + NO_NSEC = YesPlease + USE_WIN32_MMAP = YesPlease + COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch + COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1 + COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" + COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/regex/regex.o compat/winansi.o + EXTLIBS += -lws2_32 + X = .exe +endif +ifneq (,$(findstring arm,$(uname_M))) + ARM_SHA1 = YesPlease +endif + +-include config.mak.autogen +-include config.mak + +ifeq ($(uname_S),Darwin) + ifndef NO_FINK + ifeq ($(shell test -d /sw/lib && echo y),y) + BASIC_CFLAGS += -I/sw/include + BASIC_LDFLAGS += -L/sw/lib + endif + endif + ifndef NO_DARWIN_PORTS + ifeq ($(shell test -d /opt/local/lib && echo y),y) + BASIC_CFLAGS += -I/opt/local/include + BASIC_LDFLAGS += -L/opt/local/lib + endif + endif + PTHREAD_LIBS = +endif + +ifndef CC_LD_DYNPATH + ifdef NO_R_TO_GCC_LINKER + # Some gcc does not accept and pass -R to the linker to specify + # the runtime dynamic library path. + CC_LD_DYNPATH = -Wl,-rpath, + else + CC_LD_DYNPATH = -R + endif +endif + +ifdef NO_CURL + BASIC_CFLAGS += -DNO_CURL +else + ifdef CURLDIR + # Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case. + BASIC_CFLAGS += -I$(CURLDIR)/include + CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib) -lcurl + else + CURL_LIBCURL = -lcurl + endif + BUILTIN_OBJS += builtin-http-fetch.o + EXTLIBS += $(CURL_LIBCURL) + LIB_OBJS += http.o http-walker.o + curl_check := $(shell (echo 070908; curl-config --vernum) | sort -r | sed -ne 2p) + ifeq "$(curl_check)" "070908" + ifndef NO_EXPAT + PROGRAMS += git-http-push$X + endif + endif + ifndef NO_EXPAT + ifdef EXPATDIR + BASIC_CFLAGS += -I$(EXPATDIR)/include + EXPAT_LIBEXPAT = -L$(EXPATDIR)/$(lib) $(CC_LD_DYNPATH)$(EXPATDIR)/$(lib) -lexpat + else + EXPAT_LIBEXPAT = -lexpat + endif + endif +endif + +ifdef ZLIB_PATH + BASIC_CFLAGS += -I$(ZLIB_PATH)/include + EXTLIBS += -L$(ZLIB_PATH)/$(lib) $(CC_LD_DYNPATH)$(ZLIB_PATH)/$(lib) +endif +EXTLIBS += -lz + +ifndef NO_POSIX_ONLY_PROGRAMS + PROGRAMS += git-daemon$X + PROGRAMS += git-imap-send$X +endif +ifndef NO_OPENSSL + OPENSSL_LIBSSL = -lssl + ifdef OPENSSLDIR + BASIC_CFLAGS += -I$(OPENSSLDIR)/include + OPENSSL_LINK = -L$(OPENSSLDIR)/$(lib) $(CC_LD_DYNPATH)$(OPENSSLDIR)/$(lib) + else + OPENSSL_LINK = + endif +else + BASIC_CFLAGS += -DNO_OPENSSL + MOZILLA_SHA1 = 1 + OPENSSL_LIBSSL = +endif +ifdef NEEDS_SSL_WITH_CRYPTO + LIB_4_CRYPTO = $(OPENSSL_LINK) -lcrypto -lssl +else + LIB_4_CRYPTO = $(OPENSSL_LINK) -lcrypto +endif +ifdef NEEDS_LIBICONV + ifdef ICONVDIR + BASIC_CFLAGS += -I$(ICONVDIR)/include + ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib) + else + ICONV_LINK = + endif + EXTLIBS += $(ICONV_LINK) -liconv +endif +ifdef NEEDS_SOCKET + EXTLIBS += -lsocket +endif +ifdef NEEDS_NSL + EXTLIBS += -lnsl +endif +ifdef NO_D_TYPE_IN_DIRENT + BASIC_CFLAGS += -DNO_D_TYPE_IN_DIRENT +endif +ifdef NO_D_INO_IN_DIRENT + BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT +endif +ifdef NO_ST_BLOCKS_IN_STRUCT_STAT + BASIC_CFLAGS += -DNO_ST_BLOCKS_IN_STRUCT_STAT +endif +ifdef USE_NSEC + BASIC_CFLAGS += -DUSE_NSEC +endif +ifdef USE_ST_TIMESPEC + BASIC_CFLAGS += -DUSE_ST_TIMESPEC +endif +ifdef NO_NSEC + BASIC_CFLAGS += -DNO_NSEC +endif +ifdef NO_C99_FORMAT + BASIC_CFLAGS += -DNO_C99_FORMAT +endif +ifdef SNPRINTF_RETURNS_BOGUS + COMPAT_CFLAGS += -DSNPRINTF_RETURNS_BOGUS + COMPAT_OBJS += compat/snprintf.o +endif +ifdef FREAD_READS_DIRECTORIES + COMPAT_CFLAGS += -DFREAD_READS_DIRECTORIES + COMPAT_OBJS += compat/fopen.o +endif +ifdef NO_SYMLINK_HEAD + BASIC_CFLAGS += -DNO_SYMLINK_HEAD +endif +ifdef NO_STRCASESTR + COMPAT_CFLAGS += -DNO_STRCASESTR + COMPAT_OBJS += compat/strcasestr.o +endif +ifdef NO_STRLCPY + COMPAT_CFLAGS += -DNO_STRLCPY + COMPAT_OBJS += compat/strlcpy.o +endif +ifdef NO_STRTOUMAX + COMPAT_CFLAGS += -DNO_STRTOUMAX + COMPAT_OBJS += compat/strtoumax.o +endif +ifdef NO_STRTOULL + COMPAT_CFLAGS += -DNO_STRTOULL +endif +ifdef NO_SETENV + COMPAT_CFLAGS += -DNO_SETENV + COMPAT_OBJS += compat/setenv.o +endif +ifdef NO_MKDTEMP + COMPAT_CFLAGS += -DNO_MKDTEMP + COMPAT_OBJS += compat/mkdtemp.o +endif +ifdef NO_UNSETENV + COMPAT_CFLAGS += -DNO_UNSETENV + COMPAT_OBJS += compat/unsetenv.o +endif +ifdef NO_SYS_SELECT_H + BASIC_CFLAGS += -DNO_SYS_SELECT_H +endif +ifdef NO_MMAP + COMPAT_CFLAGS += -DNO_MMAP + COMPAT_OBJS += compat/mmap.o +else + ifdef USE_WIN32_MMAP + COMPAT_CFLAGS += -DUSE_WIN32_MMAP + COMPAT_OBJS += compat/win32mmap.o + endif +endif +ifdef NO_PREAD + COMPAT_CFLAGS += -DNO_PREAD + COMPAT_OBJS += compat/pread.o +endif +ifdef NO_FAST_WORKING_DIRECTORY + BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY +endif +ifdef NO_TRUSTABLE_FILEMODE + BASIC_CFLAGS += -DNO_TRUSTABLE_FILEMODE +endif +ifdef NO_IPV6 + BASIC_CFLAGS += -DNO_IPV6 +endif +ifdef NO_UINTMAX_T + BASIC_CFLAGS += -Duintmax_t=uint32_t +endif +ifdef NO_SOCKADDR_STORAGE +ifdef NO_IPV6 + BASIC_CFLAGS += -Dsockaddr_storage=sockaddr_in +else + BASIC_CFLAGS += -Dsockaddr_storage=sockaddr_in6 +endif +endif +ifdef NO_INET_NTOP + LIB_OBJS += compat/inet_ntop.o +endif +ifdef NO_INET_PTON + LIB_OBJS += compat/inet_pton.o +endif + +ifdef NO_ICONV + BASIC_CFLAGS += -DNO_ICONV +endif + +ifdef OLD_ICONV + BASIC_CFLAGS += -DOLD_ICONV +endif + +ifdef NO_DEFLATE_BOUND + BASIC_CFLAGS += -DNO_DEFLATE_BOUND +endif + +ifdef PPC_SHA1 + SHA1_HEADER = "ppc/sha1.h" + LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o +else +ifdef ARM_SHA1 + SHA1_HEADER = "arm/sha1.h" + LIB_OBJS += arm/sha1.o arm/sha1_arm.o +else +ifdef MOZILLA_SHA1 + SHA1_HEADER = "mozilla-sha1/sha1.h" + LIB_OBJS += mozilla-sha1/sha1.o +else + SHA1_HEADER = + EXTLIBS += $(LIB_4_CRYPTO) +endif +endif +endif +ifdef NO_PERL_MAKEMAKER + export NO_PERL_MAKEMAKER +endif +ifdef NO_HSTRERROR + COMPAT_CFLAGS += -DNO_HSTRERROR + COMPAT_OBJS += compat/hstrerror.o +endif +ifdef NO_MEMMEM + COMPAT_CFLAGS += -DNO_MEMMEM + COMPAT_OBJS += compat/memmem.o +endif +ifdef INTERNAL_QSORT + COMPAT_CFLAGS += -DINTERNAL_QSORT + COMPAT_OBJS += compat/qsort.o +endif +ifdef RUNTIME_PREFIX + COMPAT_CFLAGS += -DRUNTIME_PREFIX +endif + +ifdef NO_PTHREADS + THREADED_DELTA_SEARCH = + BASIC_CFLAGS += -DNO_PTHREADS +else + EXTLIBS += $(PTHREAD_LIBS) +endif + +ifdef THREADED_DELTA_SEARCH + BASIC_CFLAGS += -DTHREADED_DELTA_SEARCH + LIB_OBJS += thread-utils.o +endif +ifdef DIR_HAS_BSD_GROUP_SEMANTICS + COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS +endif +ifdef NO_EXTERNAL_GREP + BASIC_CFLAGS += -DNO_EXTERNAL_GREP +endif + +ifeq ($(TCLTK_PATH),) +NO_TCLTK=NoThanks +endif + +ifeq ($(PERL_PATH),) +NO_PERL=NoThanks +endif + +QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir +QUIET_SUBDIR1 = + +ifneq ($(findstring $(MAKEFLAGS),w),w) +PRINT_DIR = --no-print-directory +else # "make -w" +NO_SUBDIR = : +endif + +ifneq ($(findstring $(MAKEFLAGS),s),s) +ifndef V + QUIET_CC = @echo ' ' CC $@; + QUIET_AR = @echo ' ' AR $@; + QUIET_LINK = @echo ' ' LINK $@; + QUIET_BUILT_IN = @echo ' ' BUILTIN $@; + QUIET_GEN = @echo ' ' GEN $@; + QUIET_SUBDIR0 = +@subdir= + QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ + $(MAKE) $(PRINT_DIR) -C $$subdir + export V + export QUIET_GEN + export QUIET_BUILT_IN +endif +endif + +ifdef ASCIIDOC8 + export ASCIIDOC8 +endif + +# Shell quote (do not use $(call) to accommodate ancient setups); + +SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER)) +ETC_GITCONFIG_SQ = $(subst ','\'',$(ETC_GITCONFIG)) + +DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) +bindir_SQ = $(subst ','\'',$(bindir)) +bindir_relative_SQ = $(subst ','\'',$(bindir_relative)) +mandir_SQ = $(subst ','\'',$(mandir)) +infodir_SQ = $(subst ','\'',$(infodir)) +gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) +template_dir_SQ = $(subst ','\'',$(template_dir)) +htmldir_SQ = $(subst ','\'',$(htmldir)) +prefix_SQ = $(subst ','\'',$(prefix)) + +SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) +PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) +TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH)) + +LIBS = $(GITLIBS) $(EXTLIBS) + +BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \ + $(COMPAT_CFLAGS) +LIB_OBJS += $(COMPAT_OBJS) + +ALL_CFLAGS += $(BASIC_CFLAGS) +ALL_LDFLAGS += $(BASIC_LDFLAGS) + +export TAR INSTALL DESTDIR SHELL_PATH + + +### Build rules + +SHELL = $(SHELL_PATH) + +all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS +ifneq (,$X) + $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$p' -ef '$p$X' || $(RM) '$p';) +endif + +all:: +ifndef NO_TCLTK + $(QUIET_SUBDIR0)git-gui $(QUIET_SUBDIR1) gitexecdir='$(gitexec_instdir_SQ)' all + $(QUIET_SUBDIR0)gitk-git $(QUIET_SUBDIR1) all +endif +ifndef NO_PERL + $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all +endif + $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) + +please_set_SHELL_PATH_to_a_more_modern_shell: + @$$(:) + +shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell + +strip: $(PROGRAMS) git$X + $(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X + +git.o: git.c common-cmds.h GIT-CFLAGS + $(QUIET_CC)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \ + '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ + $(ALL_CFLAGS) -c $(filter %.c,$^) + +git$X: git.o $(BUILTIN_OBJS) $(GITLIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \ + $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) + +builtin-help.o: builtin-help.c common-cmds.h GIT-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ + '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ + '-DGIT_MAN_PATH="$(mandir_SQ)"' \ + '-DGIT_INFO_PATH="$(infodir_SQ)"' $< + +$(BUILT_INS): git$X + $(QUIET_BUILT_IN)$(RM) $@ && \ + ln git$X $@ 2>/dev/null || \ + ln -s git$X $@ 2>/dev/null || \ + cp git$X $@ + +common-cmds.h: ./generate-cmdlist.sh command-list.txt + +common-cmds.h: $(wildcard Documentation/git-*.txt) + $(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@ + +$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh + $(QUIET_GEN)$(RM) $@ $@+ && \ + sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ + -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ + -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ + -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ + $@.sh >$@+ && \ + chmod +x $@+ && \ + mv $@+ $@ + +ifndef NO_PERL +$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak + +perl/perl.mak: GIT-CFLAGS perl/Makefile perl/Makefile.PL + $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F) + +$(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl + $(QUIET_GEN)$(RM) $@ $@+ && \ + INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \ + sed -e '1{' \ + -e ' s|#!.*perl|#!$(PERL_PATH_SQ)|' \ + -e ' h' \ + -e ' s=.*=use lib (split(/:/, $$ENV{GITPERLLIB} || "@@INSTLIBDIR@@"));=' \ + -e ' H' \ + -e ' x' \ + -e '}' \ + -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \ + -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + $@.perl >$@+ && \ + chmod +x $@+ && \ + mv $@+ $@ + +gitweb/gitweb.cgi: gitweb/gitweb.perl + $(QUIET_GEN)$(RM) $@ $@+ && \ + sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \ + -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \ + -e 's|++GIT_BINDIR++|$(bindir)|g' \ + -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \ + -e 's|++GITWEB_CONFIG_SYSTEM++|$(GITWEB_CONFIG_SYSTEM)|g' \ + -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \ + -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \ + -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \ + -e 's|"++GITWEB_PROJECT_MAXDEPTH++"|$(GITWEB_PROJECT_MAXDEPTH)|g' \ + -e 's|++GITWEB_EXPORT_OK++|$(GITWEB_EXPORT_OK)|g' \ + -e 's|++GITWEB_STRICT_EXPORT++|$(GITWEB_STRICT_EXPORT)|g' \ + -e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \ + -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \ + -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \ + -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \ + -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \ + -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \ + -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \ + -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \ + $< >$@+ && \ + chmod +x $@+ && \ + mv $@+ $@ + +git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css + $(QUIET_GEN)$(RM) $@ $@+ && \ + sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ + -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ + -e '/@@GITWEB_CGI@@/r gitweb/gitweb.cgi' \ + -e '/@@GITWEB_CGI@@/d' \ + -e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \ + -e '/@@GITWEB_CSS@@/d' \ + -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ + $@.sh > $@+ && \ + chmod +x $@+ && \ + mv $@+ $@ +else # NO_PERL +$(patsubst %.perl,%,$(SCRIPT_PERL)) git-instaweb: % : unimplemented.sh + $(QUIET_GEN)$(RM) $@ $@+ && \ + sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ + -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \ + unimplemented.sh >$@+ && \ + chmod +x $@+ && \ + mv $@+ $@ +endif # NO_PERL + +configure: configure.ac + $(QUIET_GEN)$(RM) $@ $<+ && \ + sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + $< > $<+ && \ + autoconf -o $@ $<+ && \ + $(RM) $<+ + +# These can record GIT_VERSION +git.o git.spec \ + $(patsubst %.sh,%,$(SCRIPT_SH)) \ + $(patsubst %.perl,%,$(SCRIPT_PERL)) \ + : GIT-VERSION-FILE + +%.o: %.c GIT-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< +%.s: %.c GIT-CFLAGS + $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< +%.o: %.S + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< + +exec_cmd.o: exec_cmd.c GIT-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ + '-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \ + '-DBINDIR="$(bindir_relative_SQ)"' \ + '-DPREFIX="$(prefix_SQ)"' \ + $< + +builtin-init-db.o: builtin-init-db.c GIT-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $< + +config.o: config.c GIT-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"' $< + +http.o: http.c GIT-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DGIT_USER_AGENT='"git/$(GIT_VERSION)"' $< + +ifdef NO_EXPAT +http-walker.o: http-walker.c http.h GIT-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DNO_EXPAT $< +endif + +git-%$X: %.o $(GITLIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) + +git-imap-send$X: imap-send.o $(GITLIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ + $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) + +http.o http-walker.o http-push.o transport.o: http.h + +git-http-push$X: revision.o http.o http-push.o $(GITLIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ + $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) + +$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) +$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) +builtin-revert.o wt-status.o: wt-status.h + +$(LIB_FILE): $(LIB_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) + +XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \ + xdiff/xmerge.o xdiff/xpatience.o +$(XDIFF_OBJS): xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \ + xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h + +$(XDIFF_LIB): $(XDIFF_OBJS) + $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(XDIFF_OBJS) + + +doc: + $(MAKE) -C Documentation all + +man: + $(MAKE) -C Documentation man + +html: + $(MAKE) -C Documentation html + +info: + $(MAKE) -C Documentation info + +pdf: + $(MAKE) -C Documentation pdf + +TAGS: + $(RM) TAGS + $(FIND) . -name '*.[hcS]' -print | xargs etags -a + +tags: + $(RM) tags + $(FIND) . -name '*.[hcS]' -print | xargs ctags -a + +cscope: + $(RM) cscope* + $(FIND) . -name '*.[hcS]' -print | xargs cscope -b + +### Detect prefix changes +TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\ + $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ) + +GIT-CFLAGS: .FORCE-GIT-CFLAGS + @FLAGS='$(TRACK_CFLAGS)'; \ + if test x"$$FLAGS" != x"`cat GIT-CFLAGS 2>/dev/null`" ; then \ + echo 1>&2 " * new build flags or prefix"; \ + echo "$$FLAGS" >GIT-CFLAGS; \ + fi + +# We need to apply sq twice, once to protect from the shell +# that runs GIT-BUILD-OPTIONS, and then again to protect it +# and the first level quoting from the shell that runs "echo". +GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS + @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@ + @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@ + @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@ + @echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@ + +### Detect Tck/Tk interpreter path changes +ifndef NO_TCLTK +TRACK_VARS = $(subst ','\'',-DTCLTK_PATH='$(TCLTK_PATH_SQ)') + +GIT-GUI-VARS: .FORCE-GIT-GUI-VARS + @VARS='$(TRACK_VARS)'; \ + if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \ + echo 1>&2 " * new Tcl/Tk interpreter location"; \ + echo "$$VARS" >$@; \ + fi + +.PHONY: .FORCE-GIT-GUI-VARS +endif + +### Testing rules + +TEST_PROGRAMS += test-chmtime$X +TEST_PROGRAMS += test-ctype$X +TEST_PROGRAMS += test-date$X +TEST_PROGRAMS += test-delta$X +TEST_PROGRAMS += test-dump-cache-tree$X +TEST_PROGRAMS += test-genrandom$X +TEST_PROGRAMS += test-match-trees$X +TEST_PROGRAMS += test-parse-options$X +TEST_PROGRAMS += test-path-utils$X +TEST_PROGRAMS += test-sha1$X +TEST_PROGRAMS += test-sigchain$X + +all:: $(TEST_PROGRAMS) + +# GNU make supports exporting all variables by "export" without parameters. +# However, the environment gets quite big, and some programs have problems +# with that. + +export NO_SVN_TESTS + +test: all + $(MAKE) -C t/ all + +test-ctype$X: ctype.o + +test-date$X: date.o ctype.o + +test-delta$X: diff-delta.o patch-delta.o + +test-parse-options$X: parse-options.o + +.PRECIOUS: $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS)) + +test-%$X: test-%.o $(GITLIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) + +check-sha1:: test-sha1$X + ./test-sha1.sh + +check: common-cmds.h + if sparse; \ + then \ + for i in *.c; \ + do \ + sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \ + done; \ + else \ + echo 2>&1 "Did you mean 'make test'?"; \ + exit 1; \ + fi + +remove-dashes: + ./fixup-builtins $(BUILT_INS) $(PROGRAMS) $(SCRIPTS) + +### Installation rules + +ifneq ($(filter /%,$(firstword $(template_dir))),) +template_instdir = $(template_dir) +else +template_instdir = $(prefix)/$(template_dir) +endif +export template_instdir + +ifneq ($(filter /%,$(firstword $(gitexecdir))),) +gitexec_instdir = $(gitexecdir) +else +gitexec_instdir = $(prefix)/$(gitexecdir) +endif +gitexec_instdir_SQ = $(subst ','\'',$(gitexec_instdir)) +export gitexec_instdir + +install: all + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' + $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' + $(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X git-shell$X git-cvsserver '$(DESTDIR_SQ)$(bindir_SQ)' + $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install + $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install +ifndef NO_TCLTK + $(MAKE) -C gitk-git install + $(MAKE) -C git-gui gitexecdir='$(gitexec_instdir_SQ)' install +endif +ifneq (,$X) + $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';) +endif + bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \ + execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \ + { $(RM) "$$execdir/git-add$X" && \ + ln "$$bindir/git$X" "$$execdir/git-add$X" 2>/dev/null || \ + cp "$$bindir/git$X" "$$execdir/git-add$X"; } && \ + { for p in $(filter-out git-add$X,$(BUILT_INS)); do \ + $(RM) "$$execdir/$$p" && \ + ln "$$execdir/git-add$X" "$$execdir/$$p" 2>/dev/null || \ + ln -s "git-add$X" "$$execdir/$$p" 2>/dev/null || \ + cp "$$execdir/git-add$X" "$$execdir/$$p" || exit; \ + done } && \ + ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X" + +install-doc: + $(MAKE) -C Documentation install + +install-man: + $(MAKE) -C Documentation install-man + +install-html: + $(MAKE) -C Documentation install-html + +install-info: + $(MAKE) -C Documentation install-info + +install-pdf: + $(MAKE) -C Documentation install-pdf + +quick-install-doc: + $(MAKE) -C Documentation quick-install + +quick-install-man: + $(MAKE) -C Documentation quick-install-man + +quick-install-html: + $(MAKE) -C Documentation quick-install-html + + + +### Maintainer's dist rules + +git.spec: git.spec.in + sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@+ + mv $@+ $@ + +GIT_TARNAME=git-$(GIT_VERSION) +dist: git.spec git-archive$(X) configure + ./git-archive --format=tar \ + --prefix=$(GIT_TARNAME)/ HEAD^{tree} > $(GIT_TARNAME).tar + @mkdir -p $(GIT_TARNAME) + @cp git.spec configure $(GIT_TARNAME) + @echo $(GIT_VERSION) > $(GIT_TARNAME)/version + @$(MAKE) -C git-gui TARDIR=../$(GIT_TARNAME)/git-gui dist-version + $(TAR) rf $(GIT_TARNAME).tar \ + $(GIT_TARNAME)/git.spec \ + $(GIT_TARNAME)/configure \ + $(GIT_TARNAME)/version \ + $(GIT_TARNAME)/git-gui/version + @$(RM) -r $(GIT_TARNAME) + gzip -f -9 $(GIT_TARNAME).tar + +rpm: dist + $(RPMBUILD) -ta $(GIT_TARNAME).tar.gz + +htmldocs = git-htmldocs-$(GIT_VERSION) +manpages = git-manpages-$(GIT_VERSION) +dist-doc: + $(RM) -r .doc-tmp-dir + mkdir .doc-tmp-dir + $(MAKE) -C Documentation WEBDOC_DEST=../.doc-tmp-dir install-webdoc + cd .doc-tmp-dir && $(TAR) cf ../$(htmldocs).tar . + gzip -n -9 -f $(htmldocs).tar + : + $(RM) -r .doc-tmp-dir + mkdir -p .doc-tmp-dir/man1 .doc-tmp-dir/man5 .doc-tmp-dir/man7 + $(MAKE) -C Documentation DESTDIR=./ \ + man1dir=../.doc-tmp-dir/man1 \ + man5dir=../.doc-tmp-dir/man5 \ + man7dir=../.doc-tmp-dir/man7 \ + install + cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar . + gzip -n -9 -f $(manpages).tar + $(RM) -r .doc-tmp-dir + +### Cleaning rules + +distclean: clean + $(RM) configure clean: - rm $(BINS) + $(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \ + $(LIB_FILE) $(XDIFF_LIB) + $(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X + $(RM) $(TEST_PROGRAMS) + $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope* + $(RM) -r autom4te.cache + $(RM) config.log config.mak.autogen config.mak.append config.status config.cache + $(RM) -r $(GIT_TARNAME) .doc-tmp-dir + $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz + $(RM) $(htmldocs).tar.gz $(manpages).tar.gz + $(MAKE) -C Documentation/ clean +ifndef NO_PERL + $(RM) gitweb/gitweb.cgi + $(MAKE) -C perl clean +endif + $(MAKE) -C templates/ clean + $(MAKE) -C t/ clean +ifndef NO_TCLTK + $(MAKE) -C gitk-git clean + $(MAKE) -C git-gui clean +endif + $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS + +.PHONY: all install clean strip +.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell +.PHONY: .FORCE-GIT-VERSION-FILE TAGS tags cscope .FORCE-GIT-CFLAGS +.PHONY: .FORCE-GIT-BUILD-OPTIONS + +### Check documentation +# +check-docs:: + @(for v in $(ALL_PROGRAMS) $(BUILT_INS) git gitk; \ + do \ + case "$$v" in \ + git-merge-octopus | git-merge-ours | git-merge-recursive | \ + git-merge-resolve | git-merge-subtree | \ + git-fsck-objects | git-init-db | \ + git-?*--?* ) continue ;; \ + esac ; \ + test -f "Documentation/$$v.txt" || \ + echo "no doc: $$v"; \ + sed -e '/^#/d' command-list.txt | \ + grep -q "^$$v[ ]" || \ + case "$$v" in \ + git) ;; \ + *) echo "no link: $$v";; \ + esac ; \ + done; \ + ( \ + sed -e '/^#/d' \ + -e 's/[ ].*//' \ + -e 's/^/listed /' command-list.txt; \ + ls -1 Documentation/git*txt | \ + sed -e 's|Documentation/|documented |' \ + -e 's/\.txt//'; \ + ) | while read how cmd; \ + do \ + case "$$how,$$cmd" in \ + *,git-citool | \ + *,git-gui | \ + *,git-help | \ + documented,gitattributes | \ + documented,gitignore | \ + documented,gitmodules | \ + documented,gitcli | \ + documented,git-tools | \ + documented,gitcore-tutorial | \ + documented,gitcvs-migration | \ + documented,gitdiffcore | \ + documented,gitglossary | \ + documented,githooks | \ + documented,gitrepository-layout | \ + documented,gittutorial | \ + documented,gittutorial-2 | \ + sentinel,not,matching,is,ok ) continue ;; \ + esac; \ + case " $(ALL_PROGRAMS) $(BUILT_INS) git gitk " in \ + *" $$cmd "*) ;; \ + *) echo "removed but $$how: $$cmd" ;; \ + esac; \ + done ) | sort + +### Make sure built-ins do not have dups and listed in git.c +# +check-builtins:: + ./check-builtins.sh + +### Test suite coverage testing +# +.PHONY: coverage coverage-clean coverage-build coverage-report + +coverage: + $(MAKE) coverage-build + $(MAKE) coverage-report + +coverage-clean: + rm -f *.gcda *.gcno + +COVERAGE_CFLAGS = $(CFLAGS) -O0 -ftest-coverage -fprofile-arcs +COVERAGE_LDFLAGS = $(CFLAGS) -O0 -lgcov + +coverage-build: coverage-clean + $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" all + $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" \ + -j1 test + +coverage-report: + gcov -b *.c + grep '^function.*called 0 ' *.c.gcov \ + | sed -e 's/\([^:]*\)\.gcov: *function \([^ ]*\) called.*/\1: \2/' \ + | tee coverage-untested-functions -- GitLab From 0780060124011b94af55830939c86cc0916be0f5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 15:00:56 +0200 Subject: [PATCH 0444/6080] perf_counter tools: add in basic glue from Git First very raw version at having a central 'perf' command and a list of subcommands: perf top perf stat perf record perf report ... This is done by picking up Git's collection of utility functions, and hacking them to build fine in this new environment. Signed-off-by: Ingo Molnar --- Documentation/perf_counter/.gitignore | 179 +++ Documentation/perf_counter/Makefile | 1037 +++--------- Documentation/perf_counter/PERF-BUILD-OPTIONS | 4 + Documentation/perf_counter/PERF-CFLAGS | 1 + Documentation/perf_counter/PERF-VERSION-FILE | 1 + Documentation/perf_counter/PERF-VERSION-GEN | 42 + Documentation/perf_counter/abspath.c | 117 ++ Documentation/perf_counter/alias.c | 77 + Documentation/perf_counter/builtin-help.c | 463 ++++++ Documentation/perf_counter/builtin-top.c | 1411 +++++++++++++++++ Documentation/perf_counter/builtin.h | 18 + Documentation/perf_counter/cache.h | 97 ++ Documentation/perf_counter/command-list.txt | 4 + Documentation/perf_counter/config.c | 966 +++++++++++ Documentation/perf_counter/ctype.c | 26 + Documentation/perf_counter/exec_cmd.c | 165 ++ Documentation/perf_counter/exec_cmd.h | 13 + .../perf_counter/generate-cmdlist.sh | 24 + Documentation/perf_counter/help.c | 366 +++++ Documentation/perf_counter/help.h | 29 + Documentation/perf_counter/levenshtein.c | 84 + Documentation/perf_counter/levenshtein.h | 8 + Documentation/perf_counter/parse-options.c | 495 ++++++ Documentation/perf_counter/parse-options.h | 172 ++ Documentation/perf_counter/path.c | 392 +++++ Documentation/perf_counter/perf.c | 411 +++++ Documentation/perf_counter/quote.c | 478 ++++++ Documentation/perf_counter/quote.h | 68 + Documentation/perf_counter/run-command.c | 395 +++++ Documentation/perf_counter/run-command.h | 93 ++ Documentation/perf_counter/strbuf.c | 359 +++++ Documentation/perf_counter/strbuf.h | 137 ++ Documentation/perf_counter/usage.c | 80 + Documentation/perf_counter/util.h | 394 +++++ Documentation/perf_counter/wrapper.c | 206 +++ 35 files changed, 7953 insertions(+), 859 deletions(-) create mode 100644 Documentation/perf_counter/.gitignore create mode 100644 Documentation/perf_counter/PERF-BUILD-OPTIONS create mode 100644 Documentation/perf_counter/PERF-CFLAGS create mode 100644 Documentation/perf_counter/PERF-VERSION-FILE create mode 100755 Documentation/perf_counter/PERF-VERSION-GEN create mode 100644 Documentation/perf_counter/abspath.c create mode 100644 Documentation/perf_counter/alias.c create mode 100644 Documentation/perf_counter/builtin-help.c create mode 100644 Documentation/perf_counter/builtin-top.c create mode 100644 Documentation/perf_counter/builtin.h create mode 100644 Documentation/perf_counter/cache.h create mode 100644 Documentation/perf_counter/command-list.txt create mode 100644 Documentation/perf_counter/config.c create mode 100644 Documentation/perf_counter/ctype.c create mode 100644 Documentation/perf_counter/exec_cmd.c create mode 100644 Documentation/perf_counter/exec_cmd.h create mode 100755 Documentation/perf_counter/generate-cmdlist.sh create mode 100644 Documentation/perf_counter/help.c create mode 100644 Documentation/perf_counter/help.h create mode 100644 Documentation/perf_counter/levenshtein.c create mode 100644 Documentation/perf_counter/levenshtein.h create mode 100644 Documentation/perf_counter/parse-options.c create mode 100644 Documentation/perf_counter/parse-options.h create mode 100644 Documentation/perf_counter/path.c create mode 100644 Documentation/perf_counter/perf.c create mode 100644 Documentation/perf_counter/quote.c create mode 100644 Documentation/perf_counter/quote.h create mode 100644 Documentation/perf_counter/run-command.c create mode 100644 Documentation/perf_counter/run-command.h create mode 100644 Documentation/perf_counter/strbuf.c create mode 100644 Documentation/perf_counter/strbuf.h create mode 100644 Documentation/perf_counter/usage.c create mode 100644 Documentation/perf_counter/util.h create mode 100644 Documentation/perf_counter/wrapper.c diff --git a/Documentation/perf_counter/.gitignore b/Documentation/perf_counter/.gitignore new file mode 100644 index 000000000000..41c0b20a76ce --- /dev/null +++ b/Documentation/perf_counter/.gitignore @@ -0,0 +1,179 @@ +GIT-BUILD-OPTIONS +GIT-CFLAGS +GIT-GUI-VARS +GIT-VERSION-FILE +git +git-add +git-add--interactive +git-am +git-annotate +git-apply +git-archimport +git-archive +git-bisect +git-bisect--helper +git-blame +git-branch +git-bundle +git-cat-file +git-check-attr +git-check-ref-format +git-checkout +git-checkout-index +git-cherry +git-cherry-pick +git-clean +git-clone +git-commit +git-commit-tree +git-config +git-count-objects +git-cvsexportcommit +git-cvsimport +git-cvsserver +git-daemon +git-diff +git-diff-files +git-diff-index +git-diff-tree +git-difftool +git-difftool--helper +git-describe +git-fast-export +git-fast-import +git-fetch +git-fetch--tool +git-fetch-pack +git-filter-branch +git-fmt-merge-msg +git-for-each-ref +git-format-patch +git-fsck +git-fsck-objects +git-gc +git-get-tar-commit-id +git-grep +git-hash-object +git-help +git-http-fetch +git-http-push +git-imap-send +git-index-pack +git-init +git-init-db +git-instaweb +git-log +git-lost-found +git-ls-files +git-ls-remote +git-ls-tree +git-mailinfo +git-mailsplit +git-merge +git-merge-base +git-merge-index +git-merge-file +git-merge-tree +git-merge-octopus +git-merge-one-file +git-merge-ours +git-merge-recursive +git-merge-resolve +git-merge-subtree +git-mergetool +git-mergetool--lib +git-mktag +git-mktree +git-name-rev +git-mv +git-pack-redundant +git-pack-objects +git-pack-refs +git-parse-remote +git-patch-id +git-peek-remote +git-prune +git-prune-packed +git-pull +git-push +git-quiltimport +git-read-tree +git-rebase +git-rebase--interactive +git-receive-pack +git-reflog +git-relink +git-remote +git-repack +git-repo-config +git-request-pull +git-rerere +git-reset +git-rev-list +git-rev-parse +git-revert +git-rm +git-send-email +git-send-pack +git-sh-setup +git-shell +git-shortlog +git-show +git-show-branch +git-show-index +git-show-ref +git-stage +git-stash +git-status +git-stripspace +git-submodule +git-svn +git-symbolic-ref +git-tag +git-tar-tree +git-unpack-file +git-unpack-objects +git-update-index +git-update-ref +git-update-server-info +git-upload-archive +git-upload-pack +git-var +git-verify-pack +git-verify-tag +git-web--browse +git-whatchanged +git-write-tree +git-core-*/?* +gitk-wish +gitweb/gitweb.cgi +test-chmtime +test-ctype +test-date +test-delta +test-dump-cache-tree +test-genrandom +test-match-trees +test-parse-options +test-path-utils +test-sha1 +test-sigchain +common-cmds.h +*.tar.gz +*.dsc +*.deb +git.spec +*.exe +*.[aos] +*.py[co] +config.mak +autom4te.cache +config.cache +config.log +config.status +config.mak.autogen +config.mak.append +configure +tags +TAGS +cscope* diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index 6e0838b03ad1..11809b943fc3 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -13,16 +13,9 @@ all:: # Define NO_OPENSSL environment variable if you do not have OpenSSL. # This also implies MOZILLA_SHA1. # -# Define NO_CURL if you do not have libcurl installed. git-http-pull and -# git-http-push are not built, and you cannot use http:// and https:// -# transports. -# # Define CURLDIR=/foo/bar if your curl header and library files are in # /foo/bar/include and /foo/bar/lib directories. # -# Define NO_EXPAT if you do not have expat installed. git-http-push is -# not built, and you cannot push using http:// and https:// transports. -# # Define EXPATDIR=/foo/bar if your expat header and library files are in # /foo/bar/include and /foo/bar/lib directories. # @@ -40,8 +33,6 @@ all:: # # Define NO_MEMMEM if you don't have memmem. # -# Define NO_STRLCPY if you don't have strlcpy. -# # Define NO_STRTOUMAX if you don't have strtoumax in the C library. # If your compiler also does not support long long or does not have # strtoull, define NO_STRTOULL. @@ -54,7 +45,7 @@ all:: # # Define NO_SYS_SELECT_H if you don't have sys/select.h. # -# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link. +# Define NO_SYMLINK_HEAD if you never want .perf/HEAD to be a symbolic link. # Enable it on Windows. By default, symrefs are still used. # # Define NO_SVN_TESTS if you want to skip time-consuming SVN interoperability @@ -62,13 +53,13 @@ all:: # but are not needed unless you plan to talk to SVN repos. # # Define NO_FINK if you are building on Darwin/Mac OS X, have Fink -# installed in /sw, but don't want GIT to link against any libraries +# installed in /sw, but don't want PERF to link against any libraries # installed there. If defined you may specify your own (or Fink's) # include directories and library directories by defining CFLAGS # and LDFLAGS appropriately. # # Define NO_DARWIN_PORTS if you are building on Darwin/Mac OS X, -# have DarwinPorts installed in /opt/local, but don't want GIT to +# have DarwinPorts installed in /opt/local, but don't want PERF to # link against any libraries installed there. If defined you may # specify your own (or DarwinPort's) include directories and # library directories by defining CFLAGS and LDFLAGS appropriately. @@ -120,7 +111,7 @@ all:: # that tells runtime paths to dynamic libraries; # "-Wl,-rpath=/path/lib" is used instead. # -# Define USE_NSEC below if you want git to care about sub-second file mtimes +# Define USE_NSEC below if you want perf to care about sub-second file mtimes # and ctimes. Note that you need recent glibc (at least 2.2.4) for this, and # it will BREAK YOUR LOCAL DIFFS! show-diff and anything using it will likely # randomly break unless your underlying filesystem supports those sub-second @@ -132,7 +123,7 @@ all:: # Define NO_NSEC if your "struct stat" does not have "st_ctim.tv_nsec" # available. This automatically turns USE_NSEC off. # -# Define USE_STDEV below if you want git to care about the underlying device +# Define USE_STDEV below if you want perf to care about the underlying device # change being considered an inode change from the update-index perspective. # # Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks @@ -150,27 +141,24 @@ all:: # Define NO_TCLTK if you do not want Tcl/Tk GUI. # # The TCL_PATH variable governs the location of the Tcl interpreter -# used to optimize git-gui for your system. Only used if NO_TCLTK +# used to optimize perf-gui for your system. Only used if NO_TCLTK # is not set. Defaults to the bare 'tclsh'. # # The TCLTK_PATH variable governs the location of the Tcl/Tk interpreter. # If not set it defaults to the bare 'wish'. If it is set to the empty # string then NO_TCLTK will be forced (this is used by configure script). # -# Define THREADED_DELTA_SEARCH if you have pthreads and wish to exploit -# parallel delta searching when packing objects. -# # Define INTERNAL_QSORT to use Git's implementation of qsort(), which # is a simplified version of the merge sort used in glibc. This is # recommended if Git triggers O(n^2) behavior in your platform's qsort(). # -# Define NO_EXTERNAL_GREP if you don't want "git grep" to ever call +# Define NO_EXTERNAL_GREP if you don't want "perf grep" to ever call # your external grep (e.g., if your system lacks grep, if its grep is -# broken, or spawning external process is slower than built-in grep git has). +# broken, or spawning external process is slower than built-in grep perf has). -GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE - @$(SHELL_PATH) ./GIT-VERSION-GEN --include GIT-VERSION-FILE +PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE + @$(SHELL_PATH) ./PERF-VERSION-GEN +-include PERF-VERSION-FILE uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not') @@ -182,20 +170,20 @@ uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not') # CFLAGS and LDFLAGS are for the users to override from the command line. CFLAGS = -g -O2 -Wall -LDFLAGS = +LDFLAGS = -lpthread -lrt ALL_CFLAGS = $(CFLAGS) ALL_LDFLAGS = $(LDFLAGS) STRIP ?= strip # Among the variables below, these: -# gitexecdir +# perfexecdir # template_dir # mandir # infodir # htmldir -# ETC_GITCONFIG (but not sysconfdir) +# ETC_PERFCONFIG (but not sysconfdir) # can be specified as a relative path some/where/else; -# this is interpreted as relative to $(prefix) and "git" at +# this is interpreted as relative to $(prefix) and "perf" at # runtime figures out where they are based on the path to the executable. # This can help installing the suite in a relocatable way. @@ -204,38 +192,20 @@ bindir_relative = bin bindir = $(prefix)/$(bindir_relative) mandir = share/man infodir = share/info -gitexecdir = libexec/git-core +perfexecdir = libexec/perf-core sharedir = $(prefix)/share -template_dir = share/git-core/templates -htmldir = share/doc/git-doc +template_dir = share/perf-core/templates +htmldir = share/doc/perf-doc ifeq ($(prefix),/usr) sysconfdir = /etc -ETC_GITCONFIG = $(sysconfdir)/gitconfig +ETC_PERFCONFIG = $(sysconfdir)/perfconfig else sysconfdir = $(prefix)/etc -ETC_GITCONFIG = etc/gitconfig +ETC_PERFCONFIG = etc/perfconfig endif lib = lib # DESTDIR= -# default configuration for gitweb -GITWEB_CONFIG = gitweb_config.perl -GITWEB_CONFIG_SYSTEM = /etc/gitweb.conf -GITWEB_HOME_LINK_STR = projects -GITWEB_SITENAME = -GITWEB_PROJECTROOT = /pub/git -GITWEB_PROJECT_MAXDEPTH = 2007 -GITWEB_EXPORT_OK = -GITWEB_STRICT_EXPORT = -GITWEB_BASE_URL = -GITWEB_LIST = -GITWEB_HOMETEXT = indextext.html -GITWEB_CSS = gitweb.css -GITWEB_LOGO = git-logo.png -GITWEB_FAVICON = git-favicon.png -GITWEB_SITE_HEADER = -GITWEB_SITE_FOOTER = - export prefix bindir sharedir sysconfdir CC = gcc @@ -277,89 +247,46 @@ SCRIPT_PERL = SCRIPT_SH = TEST_PROGRAMS = -SCRIPT_SH += git-am.sh -SCRIPT_SH += git-bisect.sh -SCRIPT_SH += git-difftool--helper.sh -SCRIPT_SH += git-filter-branch.sh -SCRIPT_SH += git-lost-found.sh -SCRIPT_SH += git-merge-octopus.sh -SCRIPT_SH += git-merge-one-file.sh -SCRIPT_SH += git-merge-resolve.sh -SCRIPT_SH += git-mergetool.sh -SCRIPT_SH += git-mergetool--lib.sh -SCRIPT_SH += git-parse-remote.sh -SCRIPT_SH += git-pull.sh -SCRIPT_SH += git-quiltimport.sh -SCRIPT_SH += git-rebase--interactive.sh -SCRIPT_SH += git-rebase.sh -SCRIPT_SH += git-repack.sh -SCRIPT_SH += git-request-pull.sh -SCRIPT_SH += git-sh-setup.sh -SCRIPT_SH += git-stash.sh -SCRIPT_SH += git-submodule.sh -SCRIPT_SH += git-web--browse.sh - -SCRIPT_PERL += git-add--interactive.perl -SCRIPT_PERL += git-difftool.perl -SCRIPT_PERL += git-archimport.perl -SCRIPT_PERL += git-cvsexportcommit.perl -SCRIPT_PERL += git-cvsimport.perl -SCRIPT_PERL += git-cvsserver.perl -SCRIPT_PERL += git-relink.perl -SCRIPT_PERL += git-send-email.perl -SCRIPT_PERL += git-svn.perl +# +# No scripts right now: +# + +# SCRIPT_SH += perf-am.sh + +# +# No Perl scripts right now: +# + +# SCRIPT_PERL += perf-add--interactive.perl SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ - $(patsubst %.perl,%,$(SCRIPT_PERL)) \ - git-instaweb + $(patsubst %.perl,%,$(SCRIPT_PERL)) # Empty... EXTRA_PROGRAMS = -# ... and all the rest that could be moved out of bindir to gitexecdir +# ... and all the rest that could be moved out of bindir to perfexecdir PROGRAMS += $(EXTRA_PROGRAMS) -PROGRAMS += git-fast-import$X -PROGRAMS += git-hash-object$X -PROGRAMS += git-index-pack$X -PROGRAMS += git-merge-index$X -PROGRAMS += git-merge-tree$X -PROGRAMS += git-mktag$X -PROGRAMS += git-mktree$X -PROGRAMS += git-pack-redundant$X -PROGRAMS += git-patch-id$X -PROGRAMS += git-shell$X -PROGRAMS += git-show-index$X -PROGRAMS += git-unpack-file$X -PROGRAMS += git-update-server-info$X -PROGRAMS += git-upload-pack$X -PROGRAMS += git-var$X + +# +# None right now: +# +# PROGRAMS += perf-fast-import$X # List built-in command $C whose implementation cmd_$C() is not in # builtin-$C.o but is linked in as part of some other command. -BUILT_INS += $(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS)) - -BUILT_INS += git-cherry$X -BUILT_INS += git-cherry-pick$X -BUILT_INS += git-format-patch$X -BUILT_INS += git-fsck-objects$X -BUILT_INS += git-get-tar-commit-id$X -BUILT_INS += git-init$X -BUILT_INS += git-merge-subtree$X -BUILT_INS += git-peek-remote$X -BUILT_INS += git-repo-config$X -BUILT_INS += git-show$X -BUILT_INS += git-stage$X -BUILT_INS += git-status$X -BUILT_INS += git-whatchanged$X - -# what 'all' will build and 'install' will install, in gitexecdir +BUILT_INS += $(patsubst builtin-%.o,perf-%$X,$(BUILTIN_OBJS)) + +# +# None right now: +# +# BUILT_INS += perf-init $X + +# what 'all' will build and 'install' will install, in perfexecdir ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) -# what 'all' will build but not install in gitexecdir -OTHER_PROGRAMS = git$X -ifndef NO_PERL -OTHER_PROGRAMS += gitweb/gitweb.cgi -endif +# what 'all' will build but not install in perfexecdir +OTHER_PROGRAMS = perf$X # Set paths to tools early so that they can be used for version tests. ifndef SHELL_PATH @@ -371,250 +298,34 @@ endif export PERL_PATH -LIB_FILE=libgit.a -XDIFF_LIB=xdiff/lib.a - -LIB_H += archive.h -LIB_H += attr.h -LIB_H += blob.h -LIB_H += builtin.h -LIB_H += cache.h -LIB_H += cache-tree.h -LIB_H += commit.h -LIB_H += compat/cygwin.h -LIB_H += compat/mingw.h -LIB_H += csum-file.h -LIB_H += decorate.h -LIB_H += delta.h -LIB_H += diffcore.h -LIB_H += diff.h -LIB_H += dir.h -LIB_H += fsck.h -LIB_H += git-compat-util.h -LIB_H += graph.h -LIB_H += grep.h -LIB_H += hash.h -LIB_H += help.h +LIB_FILE=libperf.a + +LIB_H += ../../include/linux/perf_counter.h LIB_H += levenshtein.h -LIB_H += list-objects.h -LIB_H += ll-merge.h -LIB_H += log-tree.h -LIB_H += mailmap.h -LIB_H += merge-recursive.h -LIB_H += object.h -LIB_H += pack.h -LIB_H += pack-refs.h -LIB_H += pack-revindex.h LIB_H += parse-options.h -LIB_H += patch-ids.h -LIB_H += pkt-line.h -LIB_H += progress.h LIB_H += quote.h -LIB_H += reflog-walk.h -LIB_H += refs.h -LIB_H += remote.h -LIB_H += rerere.h -LIB_H += revision.h -LIB_H += run-command.h -LIB_H += sha1-lookup.h -LIB_H += sideband.h -LIB_H += sigchain.h LIB_H += strbuf.h -LIB_H += string-list.h -LIB_H += tag.h -LIB_H += transport.h -LIB_H += tree.h -LIB_H += tree-walk.h -LIB_H += unpack-trees.h -LIB_H += userdiff.h -LIB_H += utf8.h -LIB_H += wt-status.h +LIB_H += run-command.h LIB_OBJS += abspath.o LIB_OBJS += alias.o -LIB_OBJS += alloc.o -LIB_OBJS += archive.o -LIB_OBJS += archive-tar.o -LIB_OBJS += archive-zip.o -LIB_OBJS += attr.o -LIB_OBJS += base85.o -LIB_OBJS += bisect.o -LIB_OBJS += blob.o -LIB_OBJS += branch.o -LIB_OBJS += bundle.o -LIB_OBJS += cache-tree.o -LIB_OBJS += color.o -LIB_OBJS += combine-diff.o -LIB_OBJS += commit.o LIB_OBJS += config.o -LIB_OBJS += connect.o -LIB_OBJS += convert.o -LIB_OBJS += copy.o -LIB_OBJS += csum-file.o LIB_OBJS += ctype.o -LIB_OBJS += date.o -LIB_OBJS += decorate.o -LIB_OBJS += diffcore-break.o -LIB_OBJS += diffcore-delta.o -LIB_OBJS += diffcore-order.o -LIB_OBJS += diffcore-pickaxe.o -LIB_OBJS += diffcore-rename.o -LIB_OBJS += diff-delta.o -LIB_OBJS += diff-lib.o -LIB_OBJS += diff-no-index.o -LIB_OBJS += diff.o -LIB_OBJS += dir.o -LIB_OBJS += editor.o -LIB_OBJS += entry.o -LIB_OBJS += environment.o LIB_OBJS += exec_cmd.o -LIB_OBJS += fsck.o -LIB_OBJS += graph.o -LIB_OBJS += grep.o -LIB_OBJS += hash.o LIB_OBJS += help.o -LIB_OBJS += ident.o LIB_OBJS += levenshtein.o -LIB_OBJS += list-objects.o -LIB_OBJS += ll-merge.o -LIB_OBJS += lockfile.o -LIB_OBJS += log-tree.o -LIB_OBJS += mailmap.o -LIB_OBJS += match-trees.o -LIB_OBJS += merge-file.o -LIB_OBJS += merge-recursive.o -LIB_OBJS += name-hash.o -LIB_OBJS += object.o -LIB_OBJS += pack-check.o -LIB_OBJS += pack-refs.o -LIB_OBJS += pack-revindex.o -LIB_OBJS += pack-write.o -LIB_OBJS += pager.o LIB_OBJS += parse-options.o -LIB_OBJS += patch-delta.o -LIB_OBJS += patch-ids.o LIB_OBJS += path.o -LIB_OBJS += pkt-line.o -LIB_OBJS += preload-index.o -LIB_OBJS += pretty.o -LIB_OBJS += progress.o -LIB_OBJS += quote.o -LIB_OBJS += reachable.o -LIB_OBJS += read-cache.o -LIB_OBJS += reflog-walk.o -LIB_OBJS += refs.o -LIB_OBJS += remote.o -LIB_OBJS += rerere.o -LIB_OBJS += revision.o LIB_OBJS += run-command.o -LIB_OBJS += server-info.o -LIB_OBJS += setup.o -LIB_OBJS += sha1-lookup.o -LIB_OBJS += sha1_file.o -LIB_OBJS += sha1_name.o -LIB_OBJS += shallow.o -LIB_OBJS += sideband.o -LIB_OBJS += sigchain.o +LIB_OBJS += quote.o LIB_OBJS += strbuf.o -LIB_OBJS += string-list.o -LIB_OBJS += symlinks.o -LIB_OBJS += tag.o -LIB_OBJS += trace.o -LIB_OBJS += transport.o -LIB_OBJS += tree-diff.o -LIB_OBJS += tree.o -LIB_OBJS += tree-walk.o -LIB_OBJS += unpack-trees.o LIB_OBJS += usage.o -LIB_OBJS += userdiff.o -LIB_OBJS += utf8.o -LIB_OBJS += walker.o LIB_OBJS += wrapper.o -LIB_OBJS += write_or_die.o -LIB_OBJS += ws.o -LIB_OBJS += wt-status.o -LIB_OBJS += xdiff-interface.o - -BUILTIN_OBJS += builtin-add.o -BUILTIN_OBJS += builtin-annotate.o -BUILTIN_OBJS += builtin-apply.o -BUILTIN_OBJS += builtin-archive.o -BUILTIN_OBJS += builtin-bisect--helper.o -BUILTIN_OBJS += builtin-blame.o -BUILTIN_OBJS += builtin-branch.o -BUILTIN_OBJS += builtin-bundle.o -BUILTIN_OBJS += builtin-cat-file.o -BUILTIN_OBJS += builtin-check-attr.o -BUILTIN_OBJS += builtin-check-ref-format.o -BUILTIN_OBJS += builtin-checkout-index.o -BUILTIN_OBJS += builtin-checkout.o -BUILTIN_OBJS += builtin-clean.o -BUILTIN_OBJS += builtin-clone.o -BUILTIN_OBJS += builtin-commit-tree.o -BUILTIN_OBJS += builtin-commit.o -BUILTIN_OBJS += builtin-config.o -BUILTIN_OBJS += builtin-count-objects.o -BUILTIN_OBJS += builtin-describe.o -BUILTIN_OBJS += builtin-diff-files.o -BUILTIN_OBJS += builtin-diff-index.o -BUILTIN_OBJS += builtin-diff-tree.o -BUILTIN_OBJS += builtin-diff.o -BUILTIN_OBJS += builtin-fast-export.o -BUILTIN_OBJS += builtin-fetch--tool.o -BUILTIN_OBJS += builtin-fetch-pack.o -BUILTIN_OBJS += builtin-fetch.o -BUILTIN_OBJS += builtin-fmt-merge-msg.o -BUILTIN_OBJS += builtin-for-each-ref.o -BUILTIN_OBJS += builtin-fsck.o -BUILTIN_OBJS += builtin-gc.o -BUILTIN_OBJS += builtin-grep.o + BUILTIN_OBJS += builtin-help.o -BUILTIN_OBJS += builtin-init-db.o -BUILTIN_OBJS += builtin-log.o -BUILTIN_OBJS += builtin-ls-files.o -BUILTIN_OBJS += builtin-ls-remote.o -BUILTIN_OBJS += builtin-ls-tree.o -BUILTIN_OBJS += builtin-mailinfo.o -BUILTIN_OBJS += builtin-mailsplit.o -BUILTIN_OBJS += builtin-merge.o -BUILTIN_OBJS += builtin-merge-base.o -BUILTIN_OBJS += builtin-merge-file.o -BUILTIN_OBJS += builtin-merge-ours.o -BUILTIN_OBJS += builtin-merge-recursive.o -BUILTIN_OBJS += builtin-mv.o -BUILTIN_OBJS += builtin-name-rev.o -BUILTIN_OBJS += builtin-pack-objects.o -BUILTIN_OBJS += builtin-pack-refs.o -BUILTIN_OBJS += builtin-prune-packed.o -BUILTIN_OBJS += builtin-prune.o -BUILTIN_OBJS += builtin-push.o -BUILTIN_OBJS += builtin-read-tree.o -BUILTIN_OBJS += builtin-receive-pack.o -BUILTIN_OBJS += builtin-reflog.o -BUILTIN_OBJS += builtin-remote.o -BUILTIN_OBJS += builtin-rerere.o -BUILTIN_OBJS += builtin-reset.o -BUILTIN_OBJS += builtin-rev-list.o -BUILTIN_OBJS += builtin-rev-parse.o -BUILTIN_OBJS += builtin-revert.o -BUILTIN_OBJS += builtin-rm.o -BUILTIN_OBJS += builtin-send-pack.o -BUILTIN_OBJS += builtin-shortlog.o -BUILTIN_OBJS += builtin-show-branch.o -BUILTIN_OBJS += builtin-show-ref.o -BUILTIN_OBJS += builtin-stripspace.o -BUILTIN_OBJS += builtin-symbolic-ref.o -BUILTIN_OBJS += builtin-tag.o -BUILTIN_OBJS += builtin-tar-tree.o -BUILTIN_OBJS += builtin-unpack-objects.o -BUILTIN_OBJS += builtin-update-index.o -BUILTIN_OBJS += builtin-update-ref.o -BUILTIN_OBJS += builtin-upload-archive.o -BUILTIN_OBJS += builtin-verify-pack.o -BUILTIN_OBJS += builtin-verify-tag.o -BUILTIN_OBJS += builtin-write-tree.o - -GITLIBS = $(LIB_FILE) $(XDIFF_LIB) +BUILTIN_OBJS += builtin-top.o + +PERFLIBS = $(LIB_FILE) EXTLIBS = # @@ -625,221 +336,6 @@ EXTLIBS = # because maintaining the nesting to match is a pain. If # we had "elif" things would have been much nicer... -ifeq ($(uname_S),Linux) - NO_STRLCPY = YesPlease - THREADED_DELTA_SEARCH = YesPlease -endif -ifeq ($(uname_S),GNU/kFreeBSD) - NO_STRLCPY = YesPlease - THREADED_DELTA_SEARCH = YesPlease -endif -ifeq ($(uname_S),UnixWare) - CC = cc - NEEDS_SOCKET = YesPlease - NEEDS_NSL = YesPlease - NEEDS_SSL_WITH_CRYPTO = YesPlease - NEEDS_LIBICONV = YesPlease - SHELL_PATH = /usr/local/bin/bash - NO_IPV6 = YesPlease - NO_HSTRERROR = YesPlease - BASIC_CFLAGS += -Kthread - BASIC_CFLAGS += -I/usr/local/include - BASIC_LDFLAGS += -L/usr/local/lib - INSTALL = ginstall - TAR = gtar - NO_STRCASESTR = YesPlease - NO_MEMMEM = YesPlease -endif -ifeq ($(uname_S),SCO_SV) - ifeq ($(uname_R),3.2) - CFLAGS = -O2 - endif - ifeq ($(uname_R),5) - CC = cc - BASIC_CFLAGS += -Kthread - endif - NEEDS_SOCKET = YesPlease - NEEDS_NSL = YesPlease - NEEDS_SSL_WITH_CRYPTO = YesPlease - NEEDS_LIBICONV = YesPlease - SHELL_PATH = /usr/bin/bash - NO_IPV6 = YesPlease - NO_HSTRERROR = YesPlease - BASIC_CFLAGS += -I/usr/local/include - BASIC_LDFLAGS += -L/usr/local/lib - NO_STRCASESTR = YesPlease - NO_MEMMEM = YesPlease - INSTALL = ginstall - TAR = gtar -endif -ifeq ($(uname_S),Darwin) - NEEDS_SSL_WITH_CRYPTO = YesPlease - NEEDS_LIBICONV = YesPlease - ifeq ($(shell expr "$(uname_R)" : '[15678]\.'),2) - OLD_ICONV = UnfortunatelyYes - endif - ifeq ($(shell expr "$(uname_R)" : '[15]\.'),2) - NO_STRLCPY = YesPlease - endif - NO_MEMMEM = YesPlease - THREADED_DELTA_SEARCH = YesPlease - USE_ST_TIMESPEC = YesPlease -endif -ifeq ($(uname_S),SunOS) - NEEDS_SOCKET = YesPlease - NEEDS_NSL = YesPlease - SHELL_PATH = /bin/bash - NO_STRCASESTR = YesPlease - NO_MEMMEM = YesPlease - NO_HSTRERROR = YesPlease - NO_MKDTEMP = YesPlease - OLD_ICONV = UnfortunatelyYes - ifeq ($(uname_R),5.8) - NO_UNSETENV = YesPlease - NO_SETENV = YesPlease - NO_C99_FORMAT = YesPlease - NO_STRTOUMAX = YesPlease - endif - ifeq ($(uname_R),5.9) - NO_UNSETENV = YesPlease - NO_SETENV = YesPlease - NO_C99_FORMAT = YesPlease - NO_STRTOUMAX = YesPlease - endif - INSTALL = ginstall - TAR = gtar - BASIC_CFLAGS += -D__EXTENSIONS__ -endif -ifeq ($(uname_O),Cygwin) - NO_D_TYPE_IN_DIRENT = YesPlease - NO_D_INO_IN_DIRENT = YesPlease - NO_STRCASESTR = YesPlease - NO_MEMMEM = YesPlease - NO_SYMLINK_HEAD = YesPlease - NEEDS_LIBICONV = YesPlease - NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes - NO_TRUSTABLE_FILEMODE = UnfortunatelyYes - OLD_ICONV = UnfortunatelyYes - # There are conflicting reports about this. - # On some boxes NO_MMAP is needed, and not so elsewhere. - # Try commenting this out if you suspect MMAP is more efficient - NO_MMAP = YesPlease - NO_IPV6 = YesPlease - X = .exe -endif -ifeq ($(uname_S),FreeBSD) - NEEDS_LIBICONV = YesPlease - NO_MEMMEM = YesPlease - BASIC_CFLAGS += -I/usr/local/include - BASIC_LDFLAGS += -L/usr/local/lib - DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease - USE_ST_TIMESPEC = YesPlease - THREADED_DELTA_SEARCH = YesPlease - ifeq ($(shell expr "$(uname_R)" : '4\.'),2) - PTHREAD_LIBS = -pthread - NO_UINTMAX_T = YesPlease - NO_STRTOUMAX = YesPlease - endif -endif -ifeq ($(uname_S),OpenBSD) - NO_STRCASESTR = YesPlease - NO_MEMMEM = YesPlease - NEEDS_LIBICONV = YesPlease - BASIC_CFLAGS += -I/usr/local/include - BASIC_LDFLAGS += -L/usr/local/lib - THREADED_DELTA_SEARCH = YesPlease -endif -ifeq ($(uname_S),NetBSD) - ifeq ($(shell expr "$(uname_R)" : '[01]\.'),2) - NEEDS_LIBICONV = YesPlease - endif - BASIC_CFLAGS += -I/usr/pkg/include - BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib - THREADED_DELTA_SEARCH = YesPlease -endif -ifeq ($(uname_S),AIX) - NO_STRCASESTR=YesPlease - NO_MEMMEM = YesPlease - NO_MKDTEMP = YesPlease - NO_STRLCPY = YesPlease - NO_NSEC = YesPlease - FREAD_READS_DIRECTORIES = UnfortunatelyYes - INTERNAL_QSORT = UnfortunatelyYes - NEEDS_LIBICONV=YesPlease - BASIC_CFLAGS += -D_LARGE_FILES - ifneq ($(shell expr "$(uname_V)" : '[1234]'),1) - THREADED_DELTA_SEARCH = YesPlease - else - NO_PTHREADS = YesPlease - endif -endif -ifeq ($(uname_S),GNU) - # GNU/Hurd - NO_STRLCPY=YesPlease -endif -ifeq ($(uname_S),IRIX64) - NO_IPV6=YesPlease - NO_SETENV=YesPlease - NO_STRCASESTR=YesPlease - NO_MEMMEM = YesPlease - NO_STRLCPY = YesPlease - NO_SOCKADDR_STORAGE=YesPlease - SHELL_PATH=/usr/gnu/bin/bash - BASIC_CFLAGS += -DPATH_MAX=1024 - # for now, build 32-bit version - BASIC_LDFLAGS += -L/usr/lib32 -endif -ifeq ($(uname_S),HP-UX) - NO_IPV6=YesPlease - NO_SETENV=YesPlease - NO_STRCASESTR=YesPlease - NO_MEMMEM = YesPlease - NO_STRLCPY = YesPlease - NO_MKDTEMP = YesPlease - NO_UNSETENV = YesPlease - NO_HSTRERROR = YesPlease - NO_SYS_SELECT_H = YesPlease - SNPRINTF_RETURNS_BOGUS = YesPlease -endif -ifneq (,$(findstring CYGWIN,$(uname_S))) - COMPAT_OBJS += compat/cygwin.o -endif -ifneq (,$(findstring MINGW,$(uname_S))) - NO_PREAD = YesPlease - NO_OPENSSL = YesPlease - NO_CURL = YesPlease - NO_SYMLINK_HEAD = YesPlease - NO_IPV6 = YesPlease - NO_SETENV = YesPlease - NO_UNSETENV = YesPlease - NO_STRCASESTR = YesPlease - NO_STRLCPY = YesPlease - NO_MEMMEM = YesPlease - NO_PTHREADS = YesPlease - NEEDS_LIBICONV = YesPlease - OLD_ICONV = YesPlease - NO_C99_FORMAT = YesPlease - NO_STRTOUMAX = YesPlease - NO_MKDTEMP = YesPlease - SNPRINTF_RETURNS_BOGUS = YesPlease - NO_SVN_TESTS = YesPlease - NO_PERL_MAKEMAKER = YesPlease - RUNTIME_PREFIX = YesPlease - NO_POSIX_ONLY_PROGRAMS = YesPlease - NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease - NO_NSEC = YesPlease - USE_WIN32_MMAP = YesPlease - COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch - COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1 - COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" - COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/regex/regex.o compat/winansi.o - EXTLIBS += -lws2_32 - X = .exe -endif -ifneq (,$(findstring arm,$(uname_M))) - ARM_SHA1 = YesPlease -endif - -include config.mak.autogen -include config.mak @@ -869,72 +365,12 @@ ifndef CC_LD_DYNPATH endif endif -ifdef NO_CURL - BASIC_CFLAGS += -DNO_CURL -else - ifdef CURLDIR - # Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case. - BASIC_CFLAGS += -I$(CURLDIR)/include - CURL_LIBCURL = -L$(CURLDIR)/$(lib) $(CC_LD_DYNPATH)$(CURLDIR)/$(lib) -lcurl - else - CURL_LIBCURL = -lcurl - endif - BUILTIN_OBJS += builtin-http-fetch.o - EXTLIBS += $(CURL_LIBCURL) - LIB_OBJS += http.o http-walker.o - curl_check := $(shell (echo 070908; curl-config --vernum) | sort -r | sed -ne 2p) - ifeq "$(curl_check)" "070908" - ifndef NO_EXPAT - PROGRAMS += git-http-push$X - endif - endif - ifndef NO_EXPAT - ifdef EXPATDIR - BASIC_CFLAGS += -I$(EXPATDIR)/include - EXPAT_LIBEXPAT = -L$(EXPATDIR)/$(lib) $(CC_LD_DYNPATH)$(EXPATDIR)/$(lib) -lexpat - else - EXPAT_LIBEXPAT = -lexpat - endif - endif -endif - ifdef ZLIB_PATH BASIC_CFLAGS += -I$(ZLIB_PATH)/include EXTLIBS += -L$(ZLIB_PATH)/$(lib) $(CC_LD_DYNPATH)$(ZLIB_PATH)/$(lib) endif EXTLIBS += -lz -ifndef NO_POSIX_ONLY_PROGRAMS - PROGRAMS += git-daemon$X - PROGRAMS += git-imap-send$X -endif -ifndef NO_OPENSSL - OPENSSL_LIBSSL = -lssl - ifdef OPENSSLDIR - BASIC_CFLAGS += -I$(OPENSSLDIR)/include - OPENSSL_LINK = -L$(OPENSSLDIR)/$(lib) $(CC_LD_DYNPATH)$(OPENSSLDIR)/$(lib) - else - OPENSSL_LINK = - endif -else - BASIC_CFLAGS += -DNO_OPENSSL - MOZILLA_SHA1 = 1 - OPENSSL_LIBSSL = -endif -ifdef NEEDS_SSL_WITH_CRYPTO - LIB_4_CRYPTO = $(OPENSSL_LINK) -lcrypto -lssl -else - LIB_4_CRYPTO = $(OPENSSL_LINK) -lcrypto -endif -ifdef NEEDS_LIBICONV - ifdef ICONVDIR - BASIC_CFLAGS += -I$(ICONVDIR)/include - ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib) - else - ICONV_LINK = - endif - EXTLIBS += $(ICONV_LINK) -liconv -endif ifdef NEEDS_SOCKET EXTLIBS += -lsocket endif @@ -977,10 +413,6 @@ ifdef NO_STRCASESTR COMPAT_CFLAGS += -DNO_STRCASESTR COMPAT_OBJS += compat/strcasestr.o endif -ifdef NO_STRLCPY - COMPAT_CFLAGS += -DNO_STRLCPY - COMPAT_OBJS += compat/strlcpy.o -endif ifdef NO_STRTOUMAX COMPAT_CFLAGS += -DNO_STRTOUMAX COMPAT_OBJS += compat/strtoumax.o @@ -1090,17 +522,6 @@ ifdef RUNTIME_PREFIX COMPAT_CFLAGS += -DRUNTIME_PREFIX endif -ifdef NO_PTHREADS - THREADED_DELTA_SEARCH = - BASIC_CFLAGS += -DNO_PTHREADS -else - EXTLIBS += $(PTHREAD_LIBS) -endif - -ifdef THREADED_DELTA_SEARCH - BASIC_CFLAGS += -DTHREADED_DELTA_SEARCH - LIB_OBJS += thread-utils.o -endif ifdef DIR_HAS_BSD_GROUP_SEMANTICS COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS endif @@ -1148,14 +569,14 @@ endif # Shell quote (do not use $(call) to accommodate ancient setups); SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER)) -ETC_GITCONFIG_SQ = $(subst ','\'',$(ETC_GITCONFIG)) +ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG)) DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) bindir_SQ = $(subst ','\'',$(bindir)) bindir_relative_SQ = $(subst ','\'',$(bindir_relative)) mandir_SQ = $(subst ','\'',$(mandir)) infodir_SQ = $(subst ','\'',$(infodir)) -gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) +perfexecdir_SQ = $(subst ','\'',$(perfexecdir)) template_dir_SQ = $(subst ','\'',$(template_dir)) htmldir_SQ = $(subst ','\'',$(htmldir)) prefix_SQ = $(subst ','\'',$(prefix)) @@ -1164,7 +585,7 @@ SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH)) -LIBS = $(GITLIBS) $(EXTLIBS) +LIBS = $(PERFLIBS) $(EXTLIBS) BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \ $(COMPAT_CFLAGS) @@ -1180,15 +601,15 @@ export TAR INSTALL DESTDIR SHELL_PATH SHELL = $(SHELL_PATH) -all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) GIT-BUILD-OPTIONS +all:: shell_compatibility_test $(ALL_PROGRAMS) $(BUILT_INS) $(OTHER_PROGRAMS) PERF-BUILD-OPTIONS ifneq (,$X) - $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), test '$p' -ef '$p$X' || $(RM) '$p';) + $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), test '$p' -ef '$p$X' || $(RM) '$p';) endif all:: ifndef NO_TCLTK - $(QUIET_SUBDIR0)git-gui $(QUIET_SUBDIR1) gitexecdir='$(gitexec_instdir_SQ)' all - $(QUIET_SUBDIR0)gitk-git $(QUIET_SUBDIR1) all + $(QUIET_SUBDIR0)perf-gui $(QUIET_SUBDIR1) perfexecdir='$(perfexec_instdir_SQ)' all + $(QUIET_SUBDIR0)perfk-perf $(QUIET_SUBDIR1) all endif ifndef NO_PERL $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all @@ -1200,33 +621,33 @@ please_set_SHELL_PATH_to_a_more_modern_shell: shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell -strip: $(PROGRAMS) git$X - $(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X +strip: $(PROGRAMS) perf$X + $(STRIP) $(STRIP_OPTS) $(PROGRAMS) perf$X -git.o: git.c common-cmds.h GIT-CFLAGS - $(QUIET_CC)$(CC) -DGIT_VERSION='"$(GIT_VERSION)"' \ - '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ +perf.o: perf.c common-cmds.h PERF-CFLAGS + $(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \ + '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ $(ALL_CFLAGS) -c $(filter %.c,$^) -git$X: git.o $(BUILTIN_OBJS) $(GITLIBS) - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \ +perf$X: perf.o $(BUILTIN_OBJS) $(PERFLIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ perf.o \ $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) -builtin-help.o: builtin-help.c common-cmds.h GIT-CFLAGS +builtin-help.o: builtin-help.c common-cmds.h PERF-CFLAGS $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ - '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ - '-DGIT_MAN_PATH="$(mandir_SQ)"' \ - '-DGIT_INFO_PATH="$(infodir_SQ)"' $< + '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ + '-DPERF_MAN_PATH="$(mandir_SQ)"' \ + '-DPERF_INFO_PATH="$(infodir_SQ)"' $< -$(BUILT_INS): git$X +$(BUILT_INS): perf$X $(QUIET_BUILT_IN)$(RM) $@ && \ - ln git$X $@ 2>/dev/null || \ - ln -s git$X $@ 2>/dev/null || \ - cp git$X $@ + ln perf$X $@ 2>/dev/null || \ + ln -s perf$X $@ 2>/dev/null || \ + cp perf$X $@ common-cmds.h: ./generate-cmdlist.sh command-list.txt -common-cmds.h: $(wildcard Documentation/git-*.txt) +common-cmds.h: $(wildcard Documentation/perf-*.txt) $(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh @@ -1234,152 +655,55 @@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ - -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + -e 's/@@PERF_VERSION@@/$(PERF_VERSION)/g' \ -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ $@.sh >$@+ && \ chmod +x $@+ && \ mv $@+ $@ -ifndef NO_PERL -$(patsubst %.perl,%,$(SCRIPT_PERL)): perl/perl.mak - -perl/perl.mak: GIT-CFLAGS perl/Makefile perl/Makefile.PL - $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' $(@F) - -$(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl - $(QUIET_GEN)$(RM) $@ $@+ && \ - INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \ - sed -e '1{' \ - -e ' s|#!.*perl|#!$(PERL_PATH_SQ)|' \ - -e ' h' \ - -e ' s=.*=use lib (split(/:/, $$ENV{GITPERLLIB} || "@@INSTLIBDIR@@"));=' \ - -e ' H' \ - -e ' x' \ - -e '}' \ - -e 's|@@INSTLIBDIR@@|'"$$INSTLIBDIR"'|g' \ - -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ - $@.perl >$@+ && \ - chmod +x $@+ && \ - mv $@+ $@ - -gitweb/gitweb.cgi: gitweb/gitweb.perl - $(QUIET_GEN)$(RM) $@ $@+ && \ - sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \ - -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \ - -e 's|++GIT_BINDIR++|$(bindir)|g' \ - -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \ - -e 's|++GITWEB_CONFIG_SYSTEM++|$(GITWEB_CONFIG_SYSTEM)|g' \ - -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \ - -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \ - -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \ - -e 's|"++GITWEB_PROJECT_MAXDEPTH++"|$(GITWEB_PROJECT_MAXDEPTH)|g' \ - -e 's|++GITWEB_EXPORT_OK++|$(GITWEB_EXPORT_OK)|g' \ - -e 's|++GITWEB_STRICT_EXPORT++|$(GITWEB_STRICT_EXPORT)|g' \ - -e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \ - -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \ - -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \ - -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \ - -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \ - -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \ - -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \ - -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \ - $< >$@+ && \ - chmod +x $@+ && \ - mv $@+ $@ - -git-instaweb: git-instaweb.sh gitweb/gitweb.cgi gitweb/gitweb.css - $(QUIET_GEN)$(RM) $@ $@+ && \ - sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ - -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ - -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ - -e '/@@GITWEB_CGI@@/r gitweb/gitweb.cgi' \ - -e '/@@GITWEB_CGI@@/d' \ - -e '/@@GITWEB_CSS@@/r gitweb/gitweb.css' \ - -e '/@@GITWEB_CSS@@/d' \ - -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ - $@.sh > $@+ && \ - chmod +x $@+ && \ - mv $@+ $@ -else # NO_PERL -$(patsubst %.perl,%,$(SCRIPT_PERL)) git-instaweb: % : unimplemented.sh - $(QUIET_GEN)$(RM) $@ $@+ && \ - sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ - -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \ - unimplemented.sh >$@+ && \ - chmod +x $@+ && \ - mv $@+ $@ -endif # NO_PERL - configure: configure.ac $(QUIET_GEN)$(RM) $@ $<+ && \ - sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + sed -e 's/@@PERF_VERSION@@/$(PERF_VERSION)/g' \ $< > $<+ && \ autoconf -o $@ $<+ && \ $(RM) $<+ -# These can record GIT_VERSION -git.o git.spec \ +# These can record PERF_VERSION +perf.o perf.spec \ $(patsubst %.sh,%,$(SCRIPT_SH)) \ $(patsubst %.perl,%,$(SCRIPT_PERL)) \ - : GIT-VERSION-FILE + : PERF-VERSION-FILE -%.o: %.c GIT-CFLAGS +%.o: %.c PERF-CFLAGS $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< -%.s: %.c GIT-CFLAGS +%.s: %.c PERF-CFLAGS $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< %.o: %.S $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< -exec_cmd.o: exec_cmd.c GIT-CFLAGS +exec_cmd.o: exec_cmd.c PERF-CFLAGS $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ - '-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \ + '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \ '-DBINDIR="$(bindir_relative_SQ)"' \ '-DPREFIX="$(prefix_SQ)"' \ $< -builtin-init-db.o: builtin-init-db.c GIT-CFLAGS - $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $< - -config.o: config.c GIT-CFLAGS - $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"' $< +builtin-init-db.o: builtin-init-db.c PERF-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $< -http.o: http.c GIT-CFLAGS - $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DGIT_USER_AGENT='"git/$(GIT_VERSION)"' $< +config.o: config.c PERF-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< -ifdef NO_EXPAT -http-walker.o: http-walker.c http.h GIT-CFLAGS - $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DNO_EXPAT $< -endif - -git-%$X: %.o $(GITLIBS) +perf-%$X: %.o $(PERFLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) -git-imap-send$X: imap-send.o $(GITLIBS) - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ - $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) - -http.o http-walker.o http-push.o transport.o: http.h - -git-http-push$X: revision.o http.o http-push.o $(GITLIBS) - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ - $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) - $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) -$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) +$(patsubst perf-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) builtin-revert.o wt-status.o: wt-status.h $(LIB_FILE): $(LIB_OBJS) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) -XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \ - xdiff/xmerge.o xdiff/xpatience.o -$(XDIFF_OBJS): xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \ - xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h - -$(XDIFF_LIB): $(XDIFF_OBJS) - $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(XDIFF_OBJS) - - doc: $(MAKE) -C Documentation all @@ -1409,19 +733,19 @@ cscope: ### Detect prefix changes TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\ - $(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ) + $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ) -GIT-CFLAGS: .FORCE-GIT-CFLAGS +PERF-CFLAGS: .FORCE-PERF-CFLAGS @FLAGS='$(TRACK_CFLAGS)'; \ - if test x"$$FLAGS" != x"`cat GIT-CFLAGS 2>/dev/null`" ; then \ + if test x"$$FLAGS" != x"`cat PERF-CFLAGS 2>/dev/null`" ; then \ echo 1>&2 " * new build flags or prefix"; \ - echo "$$FLAGS" >GIT-CFLAGS; \ + echo "$$FLAGS" >PERF-CFLAGS; \ fi # We need to apply sq twice, once to protect from the shell -# that runs GIT-BUILD-OPTIONS, and then again to protect it +# that runs PERF-BUILD-OPTIONS, and then again to protect it # and the first level quoting from the shell that runs "echo". -GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS +PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@ @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@ @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@ @@ -1431,14 +755,14 @@ GIT-BUILD-OPTIONS: .FORCE-GIT-BUILD-OPTIONS ifndef NO_TCLTK TRACK_VARS = $(subst ','\'',-DTCLTK_PATH='$(TCLTK_PATH_SQ)') -GIT-GUI-VARS: .FORCE-GIT-GUI-VARS +PERF-GUI-VARS: .FORCE-PERF-GUI-VARS @VARS='$(TRACK_VARS)'; \ if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \ echo 1>&2 " * new Tcl/Tk interpreter location"; \ echo "$$VARS" >$@; \ fi -.PHONY: .FORCE-GIT-GUI-VARS +.PHONY: .FORCE-PERF-GUI-VARS endif ### Testing rules @@ -1476,7 +800,7 @@ test-parse-options$X: parse-options.o .PRECIOUS: $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS)) -test-%$X: test-%.o $(GITLIBS) +test-%$X: test-%.o $(PERFLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) check-sha1:: test-sha1$X @@ -1506,40 +830,40 @@ template_instdir = $(prefix)/$(template_dir) endif export template_instdir -ifneq ($(filter /%,$(firstword $(gitexecdir))),) -gitexec_instdir = $(gitexecdir) +ifneq ($(filter /%,$(firstword $(perfexecdir))),) +perfexec_instdir = $(perfexecdir) else -gitexec_instdir = $(prefix)/$(gitexecdir) +perfexec_instdir = $(prefix)/$(perfexecdir) endif -gitexec_instdir_SQ = $(subst ','\'',$(gitexec_instdir)) -export gitexec_instdir +perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir)) +export perfexec_instdir install: all $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' - $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' - $(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X git-shell$X git-cvsserver '$(DESTDIR_SQ)$(bindir_SQ)' + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' + $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' + $(INSTALL) perf$X perf-upload-pack$X perf-receive-pack$X perf-upload-archive$X perf-shell$X perf-cvsserver '$(DESTDIR_SQ)$(bindir_SQ)' $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install ifndef NO_TCLTK - $(MAKE) -C gitk-git install - $(MAKE) -C git-gui gitexecdir='$(gitexec_instdir_SQ)' install + $(MAKE) -C perfk-perf install + $(MAKE) -C perf-gui perfexecdir='$(perfexec_instdir_SQ)' install endif ifneq (,$X) - $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) git$X)), $(RM) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)/$p';) + $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';) endif bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \ - execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \ - { $(RM) "$$execdir/git-add$X" && \ - ln "$$bindir/git$X" "$$execdir/git-add$X" 2>/dev/null || \ - cp "$$bindir/git$X" "$$execdir/git-add$X"; } && \ - { for p in $(filter-out git-add$X,$(BUILT_INS)); do \ + execdir=$$(cd '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' && pwd) && \ + { $(RM) "$$execdir/perf-add$X" && \ + ln "$$bindir/perf$X" "$$execdir/perf-add$X" 2>/dev/null || \ + cp "$$bindir/perf$X" "$$execdir/perf-add$X"; } && \ + { for p in $(filter-out perf-add$X,$(BUILT_INS)); do \ $(RM) "$$execdir/$$p" && \ - ln "$$execdir/git-add$X" "$$execdir/$$p" 2>/dev/null || \ - ln -s "git-add$X" "$$execdir/$$p" 2>/dev/null || \ - cp "$$execdir/git-add$X" "$$execdir/$$p" || exit; \ + ln "$$execdir/perf-add$X" "$$execdir/$$p" 2>/dev/null || \ + ln -s "perf-add$X" "$$execdir/$$p" 2>/dev/null || \ + cp "$$execdir/perf-add$X" "$$execdir/$$p" || exit; \ done } && \ - ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X" + ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/perf-add$X" install-doc: $(MAKE) -C Documentation install @@ -1569,31 +893,31 @@ quick-install-html: ### Maintainer's dist rules -git.spec: git.spec.in - sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@+ +perf.spec: perf.spec.in + sed -e 's/@@VERSION@@/$(PERF_VERSION)/g' < $< > $@+ mv $@+ $@ -GIT_TARNAME=git-$(GIT_VERSION) -dist: git.spec git-archive$(X) configure - ./git-archive --format=tar \ - --prefix=$(GIT_TARNAME)/ HEAD^{tree} > $(GIT_TARNAME).tar - @mkdir -p $(GIT_TARNAME) - @cp git.spec configure $(GIT_TARNAME) - @echo $(GIT_VERSION) > $(GIT_TARNAME)/version - @$(MAKE) -C git-gui TARDIR=../$(GIT_TARNAME)/git-gui dist-version - $(TAR) rf $(GIT_TARNAME).tar \ - $(GIT_TARNAME)/git.spec \ - $(GIT_TARNAME)/configure \ - $(GIT_TARNAME)/version \ - $(GIT_TARNAME)/git-gui/version - @$(RM) -r $(GIT_TARNAME) - gzip -f -9 $(GIT_TARNAME).tar +PERF_TARNAME=perf-$(PERF_VERSION) +dist: perf.spec perf-archive$(X) configure + ./perf-archive --format=tar \ + --prefix=$(PERF_TARNAME)/ HEAD^{tree} > $(PERF_TARNAME).tar + @mkdir -p $(PERF_TARNAME) + @cp perf.spec configure $(PERF_TARNAME) + @echo $(PERF_VERSION) > $(PERF_TARNAME)/version + @$(MAKE) -C perf-gui TARDIR=../$(PERF_TARNAME)/perf-gui dist-version + $(TAR) rf $(PERF_TARNAME).tar \ + $(PERF_TARNAME)/perf.spec \ + $(PERF_TARNAME)/configure \ + $(PERF_TARNAME)/version \ + $(PERF_TARNAME)/perf-gui/version + @$(RM) -r $(PERF_TARNAME) + gzip -f -9 $(PERF_TARNAME).tar rpm: dist - $(RPMBUILD) -ta $(GIT_TARNAME).tar.gz + $(RPMBUILD) -ta $(PERF_TARNAME).tar.gz -htmldocs = git-htmldocs-$(GIT_VERSION) -manpages = git-manpages-$(GIT_VERSION) +htmldocs = perf-htmldocs-$(PERF_VERSION) +manpages = perf-manpages-$(PERF_VERSION) dist-doc: $(RM) -r .doc-tmp-dir mkdir .doc-tmp-dir @@ -1618,51 +942,46 @@ distclean: clean $(RM) configure clean: - $(RM) *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \ - $(LIB_FILE) $(XDIFF_LIB) - $(RM) $(ALL_PROGRAMS) $(BUILT_INS) git$X + $(RM) *.o $(LIB_FILE) + $(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X $(RM) $(TEST_PROGRAMS) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope* $(RM) -r autom4te.cache $(RM) config.log config.mak.autogen config.mak.append config.status config.cache - $(RM) -r $(GIT_TARNAME) .doc-tmp-dir - $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz + $(RM) -r $(PERF_TARNAME) .doc-tmp-dir + $(RM) $(PERF_TARNAME).tar.gz perf-core_$(PERF_VERSION)-*.tar.gz $(RM) $(htmldocs).tar.gz $(manpages).tar.gz $(MAKE) -C Documentation/ clean -ifndef NO_PERL - $(RM) gitweb/gitweb.cgi - $(MAKE) -C perl clean -endif $(MAKE) -C templates/ clean $(MAKE) -C t/ clean ifndef NO_TCLTK - $(MAKE) -C gitk-git clean - $(MAKE) -C git-gui clean + $(MAKE) -C perfk-perf clean + $(MAKE) -C perf-gui clean endif - $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-GUI-VARS GIT-BUILD-OPTIONS + $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-GUI-VARS PERF-BUILD-OPTIONS .PHONY: all install clean strip .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell -.PHONY: .FORCE-GIT-VERSION-FILE TAGS tags cscope .FORCE-GIT-CFLAGS -.PHONY: .FORCE-GIT-BUILD-OPTIONS +.PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS +.PHONY: .FORCE-PERF-BUILD-OPTIONS ### Check documentation # check-docs:: - @(for v in $(ALL_PROGRAMS) $(BUILT_INS) git gitk; \ + @(for v in $(ALL_PROGRAMS) $(BUILT_INS) perf perfk; \ do \ case "$$v" in \ - git-merge-octopus | git-merge-ours | git-merge-recursive | \ - git-merge-resolve | git-merge-subtree | \ - git-fsck-objects | git-init-db | \ - git-?*--?* ) continue ;; \ + perf-merge-octopus | perf-merge-ours | perf-merge-recursive | \ + perf-merge-resolve | perf-merge-subtree | \ + perf-fsck-objects | perf-init-db | \ + perf-?*--?* ) continue ;; \ esac ; \ test -f "Documentation/$$v.txt" || \ echo "no doc: $$v"; \ sed -e '/^#/d' command-list.txt | \ grep -q "^$$v[ ]" || \ case "$$v" in \ - git) ;; \ + perf) ;; \ *) echo "no link: $$v";; \ esac ; \ done; \ @@ -1670,37 +989,37 @@ check-docs:: sed -e '/^#/d' \ -e 's/[ ].*//' \ -e 's/^/listed /' command-list.txt; \ - ls -1 Documentation/git*txt | \ + ls -1 Documentation/perf*txt | \ sed -e 's|Documentation/|documented |' \ -e 's/\.txt//'; \ ) | while read how cmd; \ do \ case "$$how,$$cmd" in \ - *,git-citool | \ - *,git-gui | \ - *,git-help | \ - documented,gitattributes | \ - documented,gitignore | \ - documented,gitmodules | \ - documented,gitcli | \ - documented,git-tools | \ - documented,gitcore-tutorial | \ - documented,gitcvs-migration | \ - documented,gitdiffcore | \ - documented,gitglossary | \ - documented,githooks | \ - documented,gitrepository-layout | \ - documented,gittutorial | \ - documented,gittutorial-2 | \ + *,perf-citool | \ + *,perf-gui | \ + *,perf-help | \ + documented,perfattributes | \ + documented,perfignore | \ + documented,perfmodules | \ + documented,perfcli | \ + documented,perf-tools | \ + documented,perfcore-tutorial | \ + documented,perfcvs-migration | \ + documented,perfdiffcore | \ + documented,perfglossary | \ + documented,perfhooks | \ + documented,perfrepository-layout | \ + documented,perftutorial | \ + documented,perftutorial-2 | \ sentinel,not,matching,is,ok ) continue ;; \ esac; \ - case " $(ALL_PROGRAMS) $(BUILT_INS) git gitk " in \ + case " $(ALL_PROGRAMS) $(BUILT_INS) perf perfk " in \ *" $$cmd "*) ;; \ *) echo "removed but $$how: $$cmd" ;; \ esac; \ done ) | sort -### Make sure built-ins do not have dups and listed in git.c +### Make sure built-ins do not have dups and listed in perf.c # check-builtins:: ./check-builtins.sh diff --git a/Documentation/perf_counter/PERF-BUILD-OPTIONS b/Documentation/perf_counter/PERF-BUILD-OPTIONS new file mode 100644 index 000000000000..46d8d6ceb2f4 --- /dev/null +++ b/Documentation/perf_counter/PERF-BUILD-OPTIONS @@ -0,0 +1,4 @@ +SHELL_PATH='/bin/sh' +TAR='tar' +NO_CURL='' +NO_PERL='' diff --git a/Documentation/perf_counter/PERF-CFLAGS b/Documentation/perf_counter/PERF-CFLAGS new file mode 100644 index 000000000000..f24906ca688d --- /dev/null +++ b/Documentation/perf_counter/PERF-CFLAGS @@ -0,0 +1 @@ +-g -O2 -Wall -DSHA1_HEADER='' : /home/mingo/bin:libexec/perf-core:share/perf-core/templates:/home/mingo diff --git a/Documentation/perf_counter/PERF-VERSION-FILE b/Documentation/perf_counter/PERF-VERSION-FILE new file mode 100644 index 000000000000..328e244c0c81 --- /dev/null +++ b/Documentation/perf_counter/PERF-VERSION-FILE @@ -0,0 +1 @@ +PERF_VERSION = 0.0.1.PERF diff --git a/Documentation/perf_counter/PERF-VERSION-GEN b/Documentation/perf_counter/PERF-VERSION-GEN new file mode 100755 index 000000000000..c561d1538c03 --- /dev/null +++ b/Documentation/perf_counter/PERF-VERSION-GEN @@ -0,0 +1,42 @@ +#!/bin/sh + +GVF=PERF-VERSION-FILE +DEF_VER=v0.0.1.PERF + +LF=' +' + +# First see if there is a version file (included in release tarballs), +# then try git-describe, then default. +if test -f version +then + VN=$(cat version) || VN="$DEF_VER" +elif test -d .git -o -f .git && + VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && + case "$VN" in + *$LF*) (exit 1) ;; + v[0-9]*) + git update-index -q --refresh + test -z "$(git diff-index --name-only HEAD --)" || + VN="$VN-dirty" ;; + esac +then + VN=$(echo "$VN" | sed -e 's/-/./g'); +else + VN="$DEF_VER" +fi + +VN=$(expr "$VN" : v*'\(.*\)') + +if test -r $GVF +then + VC=$(sed -e 's/^PERF_VERSION = //' <$GVF) +else + VC=unset +fi +test "$VN" = "$VC" || { + echo >&2 "PERF_VERSION = $VN" + echo "PERF_VERSION = $VN" >$GVF +} + + diff --git a/Documentation/perf_counter/abspath.c b/Documentation/perf_counter/abspath.c new file mode 100644 index 000000000000..649f34f83365 --- /dev/null +++ b/Documentation/perf_counter/abspath.c @@ -0,0 +1,117 @@ +#include "cache.h" + +/* + * Do not use this for inspecting *tracked* content. When path is a + * symlink to a directory, we do not want to say it is a directory when + * dealing with tracked content in the working tree. + */ +int is_directory(const char *path) +{ + struct stat st; + return (!stat(path, &st) && S_ISDIR(st.st_mode)); +} + +/* We allow "recursive" symbolic links. Only within reason, though. */ +#define MAXDEPTH 5 + +const char *make_absolute_path(const char *path) +{ + static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1]; + char cwd[1024] = ""; + int buf_index = 1, len; + + int depth = MAXDEPTH; + char *last_elem = NULL; + struct stat st; + + if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) + die ("Too long path: %.*s", 60, path); + + while (depth--) { + if (!is_directory(buf)) { + char *last_slash = strrchr(buf, '/'); + if (last_slash) { + *last_slash = '\0'; + last_elem = xstrdup(last_slash + 1); + } else { + last_elem = xstrdup(buf); + *buf = '\0'; + } + } + + if (*buf) { + if (!*cwd && !getcwd(cwd, sizeof(cwd))) + die ("Could not get current working directory"); + + if (chdir(buf)) + die ("Could not switch to '%s'", buf); + } + if (!getcwd(buf, PATH_MAX)) + die ("Could not get current working directory"); + + if (last_elem) { + int len = strlen(buf); + if (len + strlen(last_elem) + 2 > PATH_MAX) + die ("Too long path name: '%s/%s'", + buf, last_elem); + buf[len] = '/'; + strcpy(buf + len + 1, last_elem); + free(last_elem); + last_elem = NULL; + } + + if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) { + len = readlink(buf, next_buf, PATH_MAX); + if (len < 0) + die ("Invalid symlink: %s", buf); + if (PATH_MAX <= len) + die("symbolic link too long: %s", buf); + next_buf[len] = '\0'; + buf = next_buf; + buf_index = 1 - buf_index; + next_buf = bufs[buf_index]; + } else + break; + } + + if (*cwd && chdir(cwd)) + die ("Could not change back to '%s'", cwd); + + return buf; +} + +static const char *get_pwd_cwd(void) +{ + static char cwd[PATH_MAX + 1]; + char *pwd; + struct stat cwd_stat, pwd_stat; + if (getcwd(cwd, PATH_MAX) == NULL) + return NULL; + pwd = getenv("PWD"); + if (pwd && strcmp(pwd, cwd)) { + stat(cwd, &cwd_stat); + if (!stat(pwd, &pwd_stat) && + pwd_stat.st_dev == cwd_stat.st_dev && + pwd_stat.st_ino == cwd_stat.st_ino) { + strlcpy(cwd, pwd, PATH_MAX); + } + } + return cwd; +} + +const char *make_nonrelative_path(const char *path) +{ + static char buf[PATH_MAX + 1]; + + if (is_absolute_path(path)) { + if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) + die("Too long path: %.*s", 60, path); + } else { + const char *cwd = get_pwd_cwd(); + if (!cwd) + die("Cannot determine the current working directory"); + if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX) + die("Too long path: %.*s", 60, path); + } + return buf; +} diff --git a/Documentation/perf_counter/alias.c b/Documentation/perf_counter/alias.c new file mode 100644 index 000000000000..9b3dd2b428df --- /dev/null +++ b/Documentation/perf_counter/alias.c @@ -0,0 +1,77 @@ +#include "cache.h" + +static const char *alias_key; +static char *alias_val; + +static int alias_lookup_cb(const char *k, const char *v, void *cb) +{ + if (!prefixcmp(k, "alias.") && !strcmp(k+6, alias_key)) { + if (!v) + return config_error_nonbool(k); + alias_val = strdup(v); + return 0; + } + return 0; +} + +char *alias_lookup(const char *alias) +{ + alias_key = alias; + alias_val = NULL; + perf_config(alias_lookup_cb, NULL); + return alias_val; +} + +int split_cmdline(char *cmdline, const char ***argv) +{ + int src, dst, count = 0, size = 16; + char quoted = 0; + + *argv = malloc(sizeof(char*) * size); + + /* split alias_string */ + (*argv)[count++] = cmdline; + for (src = dst = 0; cmdline[src];) { + char c = cmdline[src]; + if (!quoted && isspace(c)) { + cmdline[dst++] = 0; + while (cmdline[++src] + && isspace(cmdline[src])) + ; /* skip */ + if (count >= size) { + size += 16; + *argv = realloc(*argv, sizeof(char*) * size); + } + (*argv)[count++] = cmdline + dst; + } else if (!quoted && (c == '\'' || c == '"')) { + quoted = c; + src++; + } else if (c == quoted) { + quoted = 0; + src++; + } else { + if (c == '\\' && quoted != '\'') { + src++; + c = cmdline[src]; + if (!c) { + free(*argv); + *argv = NULL; + return error("cmdline ends with \\"); + } + } + cmdline[dst++] = c; + src++; + } + } + + cmdline[dst] = 0; + + if (quoted) { + free(*argv); + *argv = NULL; + return error("unclosed quote"); + } + + return count; +} + diff --git a/Documentation/perf_counter/builtin-help.c b/Documentation/perf_counter/builtin-help.c new file mode 100644 index 000000000000..125fcc2f4901 --- /dev/null +++ b/Documentation/perf_counter/builtin-help.c @@ -0,0 +1,463 @@ +/* + * builtin-help.c + * + * Builtin help command + */ +#include "cache.h" +#include "builtin.h" +#include "exec_cmd.h" +#include "common-cmds.h" +#include "parse-options.h" +#include "run-command.h" +#include "help.h" + +static struct man_viewer_list { + struct man_viewer_list *next; + char name[FLEX_ARRAY]; +} *man_viewer_list; + +static struct man_viewer_info_list { + struct man_viewer_info_list *next; + const char *info; + char name[FLEX_ARRAY]; +} *man_viewer_info_list; + +enum help_format { + HELP_FORMAT_MAN, + HELP_FORMAT_INFO, + HELP_FORMAT_WEB, +}; + +static int show_all = 0; +static enum help_format help_format = HELP_FORMAT_MAN; +static struct option builtin_help_options[] = { + OPT_BOOLEAN('a', "all", &show_all, "print all available commands"), + OPT_SET_INT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN), + OPT_SET_INT('w', "web", &help_format, "show manual in web browser", + HELP_FORMAT_WEB), + OPT_SET_INT('i', "info", &help_format, "show info page", + HELP_FORMAT_INFO), + OPT_END(), +}; + +static const char * const builtin_help_usage[] = { + "perf help [--all] [--man|--web|--info] [command]", + NULL +}; + +static enum help_format parse_help_format(const char *format) +{ + if (!strcmp(format, "man")) + return HELP_FORMAT_MAN; + if (!strcmp(format, "info")) + return HELP_FORMAT_INFO; + if (!strcmp(format, "web") || !strcmp(format, "html")) + return HELP_FORMAT_WEB; + die("unrecognized help format '%s'", format); +} + +static const char *get_man_viewer_info(const char *name) +{ + struct man_viewer_info_list *viewer; + + for (viewer = man_viewer_info_list; viewer; viewer = viewer->next) + { + if (!strcasecmp(name, viewer->name)) + return viewer->info; + } + return NULL; +} + +static int check_emacsclient_version(void) +{ + struct strbuf buffer = STRBUF_INIT; + struct child_process ec_process; + const char *argv_ec[] = { "emacsclient", "--version", NULL }; + int version; + + /* emacsclient prints its version number on stderr */ + memset(&ec_process, 0, sizeof(ec_process)); + ec_process.argv = argv_ec; + ec_process.err = -1; + ec_process.stdout_to_stderr = 1; + if (start_command(&ec_process)) { + fprintf(stderr, "Failed to start emacsclient.\n"); + return -1; + } + strbuf_read(&buffer, ec_process.err, 20); + close(ec_process.err); + + /* + * Don't bother checking return value, because "emacsclient --version" + * seems to always exits with code 1. + */ + finish_command(&ec_process); + + if (prefixcmp(buffer.buf, "emacsclient")) { + fprintf(stderr, "Failed to parse emacsclient version.\n"); + strbuf_release(&buffer); + return -1; + } + + strbuf_remove(&buffer, 0, strlen("emacsclient")); + version = atoi(buffer.buf); + + if (version < 22) { + fprintf(stderr, + "emacsclient version '%d' too old (< 22).\n", + version); + strbuf_release(&buffer); + return -1; + } + + strbuf_release(&buffer); + return 0; +} + +static void exec_woman_emacs(const char* path, const char *page) +{ + if (!check_emacsclient_version()) { + /* This works only with emacsclient version >= 22. */ + struct strbuf man_page = STRBUF_INIT; + + if (!path) + path = "emacsclient"; + strbuf_addf(&man_page, "(woman \"%s\")", page); + execlp(path, "emacsclient", "-e", man_page.buf, NULL); + warning("failed to exec '%s': %s", path, strerror(errno)); + } +} + +static void exec_man_konqueror(const char* path, const char *page) +{ + const char *display = getenv("DISPLAY"); + if (display && *display) { + struct strbuf man_page = STRBUF_INIT; + const char *filename = "kfmclient"; + + /* It's simpler to launch konqueror using kfmclient. */ + if (path) { + const char *file = strrchr(path, '/'); + if (file && !strcmp(file + 1, "konqueror")) { + char *new = strdup(path); + char *dest = strrchr(new, '/'); + + /* strlen("konqueror") == strlen("kfmclient") */ + strcpy(dest + 1, "kfmclient"); + path = new; + } + if (file) + filename = file; + } else + path = "kfmclient"; + strbuf_addf(&man_page, "man:%s(1)", page); + execlp(path, filename, "newTab", man_page.buf, NULL); + warning("failed to exec '%s': %s", path, strerror(errno)); + } +} + +static void exec_man_man(const char* path, const char *page) +{ + if (!path) + path = "man"; + execlp(path, "man", page, NULL); + warning("failed to exec '%s': %s", path, strerror(errno)); +} + +static void exec_man_cmd(const char *cmd, const char *page) +{ + struct strbuf shell_cmd = STRBUF_INIT; + strbuf_addf(&shell_cmd, "%s %s", cmd, page); + execl("/bin/sh", "sh", "-c", shell_cmd.buf, NULL); + warning("failed to exec '%s': %s", cmd, strerror(errno)); +} + +static void add_man_viewer(const char *name) +{ + struct man_viewer_list **p = &man_viewer_list; + size_t len = strlen(name); + + while (*p) + p = &((*p)->next); + *p = calloc(1, (sizeof(**p) + len + 1)); + strncpy((*p)->name, name, len); +} + +static int supported_man_viewer(const char *name, size_t len) +{ + return (!strncasecmp("man", name, len) || + !strncasecmp("woman", name, len) || + !strncasecmp("konqueror", name, len)); +} + +static void do_add_man_viewer_info(const char *name, + size_t len, + const char *value) +{ + struct man_viewer_info_list *new = calloc(1, sizeof(*new) + len + 1); + + strncpy(new->name, name, len); + new->info = strdup(value); + new->next = man_viewer_info_list; + man_viewer_info_list = new; +} + +static int add_man_viewer_path(const char *name, + size_t len, + const char *value) +{ + if (supported_man_viewer(name, len)) + do_add_man_viewer_info(name, len, value); + else + warning("'%s': path for unsupported man viewer.\n" + "Please consider using 'man..cmd' instead.", + name); + + return 0; +} + +static int add_man_viewer_cmd(const char *name, + size_t len, + const char *value) +{ + if (supported_man_viewer(name, len)) + warning("'%s': cmd for supported man viewer.\n" + "Please consider using 'man..path' instead.", + name); + else + do_add_man_viewer_info(name, len, value); + + return 0; +} + +static int add_man_viewer_info(const char *var, const char *value) +{ + const char *name = var + 4; + const char *subkey = strrchr(name, '.'); + + if (!subkey) + return error("Config with no key for man viewer: %s", name); + + if (!strcmp(subkey, ".path")) { + if (!value) + return config_error_nonbool(var); + return add_man_viewer_path(name, subkey - name, value); + } + if (!strcmp(subkey, ".cmd")) { + if (!value) + return config_error_nonbool(var); + return add_man_viewer_cmd(name, subkey - name, value); + } + + warning("'%s': unsupported man viewer sub key.", subkey); + return 0; +} + +static int perf_help_config(const char *var, const char *value, void *cb) +{ + if (!strcmp(var, "help.format")) { + if (!value) + return config_error_nonbool(var); + help_format = parse_help_format(value); + return 0; + } + if (!strcmp(var, "man.viewer")) { + if (!value) + return config_error_nonbool(var); + add_man_viewer(value); + return 0; + } + if (!prefixcmp(var, "man.")) + return add_man_viewer_info(var, value); + + return perf_default_config(var, value, cb); +} + +static struct cmdnames main_cmds, other_cmds; + +void list_common_cmds_help(void) +{ + int i, longest = 0; + + for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { + if (longest < strlen(common_cmds[i].name)) + longest = strlen(common_cmds[i].name); + } + + puts("The most commonly used perf commands are:"); + for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { + printf(" %s ", common_cmds[i].name); + mput_char(' ', longest - strlen(common_cmds[i].name)); + puts(common_cmds[i].help); + } +} + +static int is_perf_command(const char *s) +{ + return is_in_cmdlist(&main_cmds, s) || + is_in_cmdlist(&other_cmds, s); +} + +static const char *prepend(const char *prefix, const char *cmd) +{ + size_t pre_len = strlen(prefix); + size_t cmd_len = strlen(cmd); + char *p = malloc(pre_len + cmd_len + 1); + memcpy(p, prefix, pre_len); + strcpy(p + pre_len, cmd); + return p; +} + +static const char *cmd_to_page(const char *perf_cmd) +{ + if (!perf_cmd) + return "perf"; + else if (!prefixcmp(perf_cmd, "perf")) + return perf_cmd; + else if (is_perf_command(perf_cmd)) + return prepend("perf-", perf_cmd); + else + return prepend("perf", perf_cmd); +} + +static void setup_man_path(void) +{ + struct strbuf new_path = STRBUF_INIT; + const char *old_path = getenv("MANPATH"); + + /* We should always put ':' after our path. If there is no + * old_path, the ':' at the end will let 'man' to try + * system-wide paths after ours to find the manual page. If + * there is old_path, we need ':' as delimiter. */ + strbuf_addstr(&new_path, system_path(PERF_MAN_PATH)); + strbuf_addch(&new_path, ':'); + if (old_path) + strbuf_addstr(&new_path, old_path); + + setenv("MANPATH", new_path.buf, 1); + + strbuf_release(&new_path); +} + +static void exec_viewer(const char *name, const char *page) +{ + const char *info = get_man_viewer_info(name); + + if (!strcasecmp(name, "man")) + exec_man_man(info, page); + else if (!strcasecmp(name, "woman")) + exec_woman_emacs(info, page); + else if (!strcasecmp(name, "konqueror")) + exec_man_konqueror(info, page); + else if (info) + exec_man_cmd(info, page); + else + warning("'%s': unknown man viewer.", name); +} + +static void show_man_page(const char *perf_cmd) +{ + struct man_viewer_list *viewer; + const char *page = cmd_to_page(perf_cmd); + const char *fallback = getenv("PERF_MAN_VIEWER"); + + setup_man_path(); + for (viewer = man_viewer_list; viewer; viewer = viewer->next) + { + exec_viewer(viewer->name, page); /* will return when unable */ + } + if (fallback) + exec_viewer(fallback, page); + exec_viewer("man", page); + die("no man viewer handled the request"); +} + +static void show_info_page(const char *perf_cmd) +{ + const char *page = cmd_to_page(perf_cmd); + setenv("INFOPATH", system_path(PERF_INFO_PATH), 1); + execlp("info", "info", "perfman", page, NULL); +} + +static void get_html_page_path(struct strbuf *page_path, const char *page) +{ + struct stat st; + const char *html_path = system_path(PERF_HTML_PATH); + + /* Check that we have a perf documentation directory. */ + if (stat(mkpath("%s/perf.html", html_path), &st) + || !S_ISREG(st.st_mode)) + die("'%s': not a documentation directory.", html_path); + + strbuf_init(page_path, 0); + strbuf_addf(page_path, "%s/%s.html", html_path, page); +} + +/* + * If open_html is not defined in a platform-specific way (see for + * example compat/mingw.h), we use the script web--browse to display + * HTML. + */ +#ifndef open_html +void open_html(const char *path) +{ + execl_perf_cmd("web--browse", "-c", "help.browser", path, NULL); +} +#endif + +static void show_html_page(const char *perf_cmd) +{ + const char *page = cmd_to_page(perf_cmd); + struct strbuf page_path; /* it leaks but we exec bellow */ + + get_html_page_path(&page_path, page); + + open_html(page_path.buf); +} + +int cmd_help(int argc, const char **argv, const char *prefix) +{ + int nonperf; + const char *alias; + load_command_list("perf-", &main_cmds, &other_cmds); + + /* setup_perf_directory_gently(&nonperf); */ + perf_config(perf_help_config, NULL); + + argc = parse_options(argc, argv, builtin_help_options, + builtin_help_usage, 0); + + if (show_all) { + printf("usage: %s\n\n", perf_usage_string); + list_commands("perf commands", &main_cmds, &other_cmds); + printf("%s\n", perf_more_info_string); + return 0; + } + + if (!argv[0]) { + printf("usage: %s\n\n", perf_usage_string); + list_common_cmds_help(); + printf("\n%s\n", perf_more_info_string); + return 0; + } + + alias = alias_lookup(argv[0]); + if (alias && !is_perf_command(argv[0])) { + printf("`perf %s' is aliased to `%s'\n", argv[0], alias); + return 0; + } + + switch (help_format) { + case HELP_FORMAT_MAN: + show_man_page(argv[0]); + break; + case HELP_FORMAT_INFO: + show_info_page(argv[0]); + break; + case HELP_FORMAT_WEB: + show_html_page(argv[0]); + break; + } + + return 0; +} diff --git a/Documentation/perf_counter/builtin-top.c b/Documentation/perf_counter/builtin-top.c new file mode 100644 index 000000000000..9d2c769e5f83 --- /dev/null +++ b/Documentation/perf_counter/builtin-top.c @@ -0,0 +1,1411 @@ +/* + * kerneltop.c: show top kernel functions - performance counters showcase + + Build with: + + cc -O6 -Wall -c -o kerneltop.o kerneltop.c -lrt + + Sample output: + +------------------------------------------------------------------------------ + KernelTop: 2669 irqs/sec [NMI, cache-misses/cache-refs], (all, cpu: 2) +------------------------------------------------------------------------------ + + weight RIP kernel function + ______ ________________ _______________ + + 35.20 - ffffffff804ce74b : skb_copy_and_csum_dev + 33.00 - ffffffff804cb740 : sock_alloc_send_skb + 31.26 - ffffffff804ce808 : skb_push + 22.43 - ffffffff80510004 : tcp_established_options + 19.00 - ffffffff8027d250 : find_get_page + 15.76 - ffffffff804e4fc9 : eth_type_trans + 15.20 - ffffffff804d8baa : dst_release + 14.86 - ffffffff804cf5d8 : skb_release_head_state + 14.00 - ffffffff802217d5 : read_hpet + 12.00 - ffffffff804ffb7f : __ip_local_out + 11.97 - ffffffff804fc0c8 : ip_local_deliver_finish + 8.54 - ffffffff805001a3 : ip_queue_xmit + */ + +/* + * perfstat: /usr/bin/time -alike performance counter statistics utility + + It summarizes the counter events of all tasks (and child tasks), + covering all CPUs that the command (or workload) executes on. + It only counts the per-task events of the workload started, + independent of how many other tasks run on those CPUs. + + Sample output: + + $ ./perfstat -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null + + Performance counter stats for 'ls': + + 163516953 instructions + 2295 cache-misses + 2855182 branch-misses + */ + + /* + * Copyright (C) 2008, Red Hat Inc, Ingo Molnar + * + * Improvements and fixes by: + * + * Arjan van de Ven + * Yanmin Zhang + * Wu Fengguang + * Mike Galbraith + * Paul Mackerras + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "util.h" + +#define _GNU_SOURCE +#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/linux/perf_counter.h" + + +/* + * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all + * counters in the current task. + */ +#define PR_TASK_PERF_COUNTERS_DISABLE 31 +#define PR_TASK_PERF_COUNTERS_ENABLE 32 + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define rdclock() \ +({ \ + struct timespec ts; \ + \ + clock_gettime(CLOCK_MONOTONIC, &ts); \ + ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ +}) + +/* + * Pick up some kernel type conventions: + */ +#define __user +#define asmlinkage + +#ifdef __x86_64__ +#define __NR_perf_counter_open 295 +#define rmb() asm volatile("lfence" ::: "memory") +#define cpu_relax() asm volatile("rep; nop" ::: "memory"); +#endif + +#ifdef __i386__ +#define __NR_perf_counter_open 333 +#define rmb() asm volatile("lfence" ::: "memory") +#define cpu_relax() asm volatile("rep; nop" ::: "memory"); +#endif + +#ifdef __powerpc__ +#define __NR_perf_counter_open 319 +#define rmb() asm volatile ("sync" ::: "memory") +#define cpu_relax() asm volatile ("" ::: "memory"); +#endif + +#define unlikely(x) __builtin_expect(!!(x), 0) +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + +asmlinkage int sys_perf_counter_open( + struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, + int cpu, + int group_fd, + unsigned long flags) +{ + return syscall( + __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); +} + +#define MAX_COUNTERS 64 +#define MAX_NR_CPUS 256 + +#define EID(type, id) (((__u64)(type) << PERF_COUNTER_TYPE_SHIFT) | (id)) + +static int run_perfstat = 0; +static int system_wide = 0; + +static int nr_counters = 0; +static __u64 event_id[MAX_COUNTERS] = { + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), + + EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), + EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), + EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), + EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), +}; +static int default_interval = 100000; +static int event_count[MAX_COUNTERS]; +static int fd[MAX_NR_CPUS][MAX_COUNTERS]; + +static __u64 count_filter = 100; + +static int tid = -1; +static int profile_cpu = -1; +static int nr_cpus = 0; +static int nmi = 1; +static unsigned int realtime_prio = 0; +static int group = 0; +static unsigned int page_size; +static unsigned int mmap_pages = 16; +static int use_mmap = 0; +static int use_munmap = 0; + +static char *vmlinux; + +static char *sym_filter; +static unsigned long filter_start; +static unsigned long filter_end; + +static int delay_secs = 2; +static int zero; +static int dump_symtab; + +static int scale; + +struct source_line { + uint64_t EIP; + unsigned long count; + char *line; + struct source_line *next; +}; + +static struct source_line *lines; +static struct source_line **lines_tail; + +const unsigned int default_count[] = { + 1000000, + 1000000, + 10000, + 10000, + 1000000, + 10000, +}; + +static char *hw_event_names[] = { + "CPU cycles", + "instructions", + "cache references", + "cache misses", + "branches", + "branch misses", + "bus cycles", +}; + +static char *sw_event_names[] = { + "cpu clock ticks", + "task clock ticks", + "pagefaults", + "context switches", + "CPU migrations", + "minor faults", + "major faults", +}; + +struct event_symbol { + __u64 event; + char *symbol; +}; + +static struct event_symbol event_symbols[] = { + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cpu-cycles", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cycles", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), "instructions", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), "cache-references", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), "cache-misses", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branch-instructions", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branches", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_MISSES), "branch-misses", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BUS_CYCLES), "bus-cycles", }, + + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK), "cpu-clock", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), "task-clock", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "page-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MIN), "minor-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MAJ), "major-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "context-switches", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "cs", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "cpu-migrations", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "migrations", }, +}; + +#define __PERF_COUNTER_FIELD(config, name) \ + ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT) + +#define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW) +#define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG) +#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE) +#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT) + +static void display_events_help(void) +{ + unsigned int i; + __u64 e; + + printf( + " -e EVENT --event=EVENT # symbolic-name abbreviations"); + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + int type, id; + + e = event_symbols[i].event; + type = PERF_COUNTER_TYPE(e); + id = PERF_COUNTER_ID(e); + + printf("\n %d:%d: %-20s", + type, id, event_symbols[i].symbol); + } + + printf("\n" + " rNNN: raw PMU events (eventsel+umask)\n\n"); +} + +static void display_perfstat_help(void) +{ + printf( + "Usage: perfstat [] \n\n" + "PerfStat Options (up to %d event types can be specified):\n\n", + MAX_COUNTERS); + + display_events_help(); + + printf( + " -l # scale counter values\n" + " -a # system-wide collection\n"); + exit(0); +} + +static void display_help(void) +{ + if (run_perfstat) + return display_perfstat_help(); + + printf( + "Usage: kerneltop []\n" + " Or: kerneltop -S [] COMMAND [ARGS]\n\n" + "KernelTop Options (up to %d event types can be specified at once):\n\n", + MAX_COUNTERS); + + display_events_help(); + + printf( + " -S --stat # perfstat COMMAND\n" + " -a # system-wide collection (for perfstat)\n\n" + " -c CNT --count=CNT # event period to sample\n\n" + " -C CPU --cpu=CPU # CPU (-1 for all) [default: -1]\n" + " -p PID --pid=PID # PID of sampled task (-1 for all) [default: -1]\n\n" + " -l # show scale factor for RR events\n" + " -d delay --delay= # sampling/display delay [default: 2]\n" + " -f CNT --filter=CNT # min-event-count filter [default: 100]\n\n" + " -r prio --realtime= # event acquisition runs with SCHED_FIFO policy\n" + " -s symbol --symbol= # function to be showed annotated one-shot\n" + " -x path --vmlinux= # the vmlinux binary, required for -s use\n" + " -z --zero # zero counts after display\n" + " -D --dump_symtab # dump symbol table to stderr on startup\n" + " -m pages --mmap_pages= # number of mmap data pages\n" + " -M --mmap_info # print mmap info stream\n" + " -U --munmap_info # print munmap info stream\n" + ); + + exit(0); +} + +static char *event_name(int ctr) +{ + __u64 config = event_id[ctr]; + int type = PERF_COUNTER_TYPE(config); + int id = PERF_COUNTER_ID(config); + static char buf[32]; + + if (PERF_COUNTER_RAW(config)) { + sprintf(buf, "raw 0x%llx", PERF_COUNTER_CONFIG(config)); + return buf; + } + + switch (type) { + case PERF_TYPE_HARDWARE: + if (id < PERF_HW_EVENTS_MAX) + return hw_event_names[id]; + return "unknown-hardware"; + + case PERF_TYPE_SOFTWARE: + if (id < PERF_SW_EVENTS_MAX) + return sw_event_names[id]; + return "unknown-software"; + + default: + break; + } + + return "unknown"; +} + +/* + * Each event can have multiple symbolic names. + * Symbolic names are (almost) exactly matched. + */ +static __u64 match_event_symbols(char *str) +{ + __u64 config, id; + int type; + unsigned int i; + + if (sscanf(str, "r%llx", &config) == 1) + return config | PERF_COUNTER_RAW_MASK; + + if (sscanf(str, "%d:%llu", &type, &id) == 2) + return EID(type, id); + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + if (!strncmp(str, event_symbols[i].symbol, + strlen(event_symbols[i].symbol))) + return event_symbols[i].event; + } + + return ~0ULL; +} + +static int parse_events(char *str) +{ + __u64 config; + +again: + if (nr_counters == MAX_COUNTERS) + return -1; + + config = match_event_symbols(str); + if (config == ~0ULL) + return -1; + + event_id[nr_counters] = config; + nr_counters++; + + str = strstr(str, ","); + if (str) { + str++; + goto again; + } + + return 0; +} + + +/* + * perfstat + */ + +char fault_here[1000000]; + +static void create_perfstat_counter(int counter) +{ + struct perf_counter_hw_event hw_event; + + memset(&hw_event, 0, sizeof(hw_event)); + hw_event.config = event_id[counter]; + hw_event.record_type = 0; + hw_event.nmi = 0; + if (scale) + hw_event.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | + PERF_FORMAT_TOTAL_TIME_RUNNING; + + if (system_wide) { + int cpu; + for (cpu = 0; cpu < nr_cpus; cpu ++) { + fd[cpu][counter] = sys_perf_counter_open(&hw_event, -1, cpu, -1, 0); + if (fd[cpu][counter] < 0) { + printf("perfstat error: syscall returned with %d (%s)\n", + fd[cpu][counter], strerror(errno)); + exit(-1); + } + } + } else { + hw_event.inherit = 1; + hw_event.disabled = 1; + + fd[0][counter] = sys_perf_counter_open(&hw_event, 0, -1, -1, 0); + if (fd[0][counter] < 0) { + printf("perfstat error: syscall returned with %d (%s)\n", + fd[0][counter], strerror(errno)); + exit(-1); + } + } +} + +int do_perfstat(int argc, char *argv[]) +{ + unsigned long long t0, t1; + int counter; + ssize_t res; + int status; + int pid; + + if (!system_wide) + nr_cpus = 1; + + for (counter = 0; counter < nr_counters; counter++) + create_perfstat_counter(counter); + + argc -= optind; + argv += optind; + + if (!argc) + display_help(); + + /* + * Enable counters and exec the command: + */ + t0 = rdclock(); + prctl(PR_TASK_PERF_COUNTERS_ENABLE); + + if ((pid = fork()) < 0) + perror("failed to fork"); + if (!pid) { + if (execvp(argv[0], argv)) { + perror(argv[0]); + exit(-1); + } + } + while (wait(&status) >= 0) + ; + prctl(PR_TASK_PERF_COUNTERS_DISABLE); + t1 = rdclock(); + + fflush(stdout); + + fprintf(stderr, "\n"); + fprintf(stderr, " Performance counter stats for \'%s\':\n", + argv[0]); + fprintf(stderr, "\n"); + + for (counter = 0; counter < nr_counters; counter++) { + int cpu, nv; + __u64 count[3], single_count[3]; + int scaled; + + count[0] = count[1] = count[2] = 0; + nv = scale ? 3 : 1; + for (cpu = 0; cpu < nr_cpus; cpu ++) { + res = read(fd[cpu][counter], + single_count, nv * sizeof(__u64)); + assert(res == nv * sizeof(__u64)); + + count[0] += single_count[0]; + if (scale) { + count[1] += single_count[1]; + count[2] += single_count[2]; + } + } + + scaled = 0; + if (scale) { + if (count[2] == 0) { + fprintf(stderr, " %14s %-20s\n", + "", event_name(counter)); + continue; + } + if (count[2] < count[1]) { + scaled = 1; + count[0] = (unsigned long long) + ((double)count[0] * count[1] / count[2] + 0.5); + } + } + + if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK) || + event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK)) { + + double msecs = (double)count[0] / 1000000; + + fprintf(stderr, " %14.6f %-20s (msecs)", + msecs, event_name(counter)); + } else { + fprintf(stderr, " %14Ld %-20s (events)", + count[0], event_name(counter)); + } + if (scaled) + fprintf(stderr, " (scaled from %.2f%%)", + (double) count[2] / count[1] * 100); + fprintf(stderr, "\n"); + } + fprintf(stderr, "\n"); + fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", + (double)(t1-t0)/1e6); + fprintf(stderr, "\n"); + + return 0; +} + +/* + * Symbols + */ + +static uint64_t min_ip; +static uint64_t max_ip = -1ll; + +struct sym_entry { + unsigned long long addr; + char *sym; + unsigned long count[MAX_COUNTERS]; + int skip; + struct source_line *source; +}; + +#define MAX_SYMS 100000 + +static int sym_table_count; + +struct sym_entry *sym_filter_entry; + +static struct sym_entry sym_table[MAX_SYMS]; + +static void show_details(struct sym_entry *sym); + +/* + * Ordering weight: count-1 * count-2 * ... / count-n + */ +static double sym_weight(const struct sym_entry *sym) +{ + double weight; + int counter; + + weight = sym->count[0]; + + for (counter = 1; counter < nr_counters-1; counter++) + weight *= sym->count[counter]; + + weight /= (sym->count[counter] + 1); + + return weight; +} + +static int compare(const void *__sym1, const void *__sym2) +{ + const struct sym_entry *sym1 = __sym1, *sym2 = __sym2; + + return sym_weight(sym1) < sym_weight(sym2); +} + +static long events; +static long userspace_events; +static const char CONSOLE_CLEAR[] = ""; + +static struct sym_entry tmp[MAX_SYMS]; + +static void print_sym_table(void) +{ + int i, printed; + int counter; + float events_per_sec = events/delay_secs; + float kevents_per_sec = (events-userspace_events)/delay_secs; + float sum_kevents = 0.0; + + events = userspace_events = 0; + memcpy(tmp, sym_table, sizeof(sym_table[0])*sym_table_count); + qsort(tmp, sym_table_count, sizeof(tmp[0]), compare); + + for (i = 0; i < sym_table_count && tmp[i].count[0]; i++) + sum_kevents += tmp[i].count[0]; + + write(1, CONSOLE_CLEAR, strlen(CONSOLE_CLEAR)); + + printf( +"------------------------------------------------------------------------------\n"); + printf( " KernelTop:%8.0f irqs/sec kernel:%4.1f%% [%s, ", + events_per_sec, + 100.0 - (100.0*((events_per_sec-kevents_per_sec)/events_per_sec)), + nmi ? "NMI" : "IRQ"); + + if (nr_counters == 1) + printf("%d ", event_count[0]); + + for (counter = 0; counter < nr_counters; counter++) { + if (counter) + printf("/"); + + printf("%s", event_name(counter)); + } + + printf( "], "); + + if (tid != -1) + printf(" (tid: %d", tid); + else + printf(" (all"); + + if (profile_cpu != -1) + printf(", cpu: %d)\n", profile_cpu); + else { + if (tid != -1) + printf(")\n"); + else + printf(", %d CPUs)\n", nr_cpus); + } + + printf("------------------------------------------------------------------------------\n\n"); + + if (nr_counters == 1) + printf(" events pcnt"); + else + printf(" weight events pcnt"); + + printf(" RIP kernel function\n" + " ______ ______ _____ ________________ _______________\n\n" + ); + + for (i = 0, printed = 0; i < sym_table_count; i++) { + float pcnt; + int count; + + if (printed <= 18 && tmp[i].count[0] >= count_filter) { + pcnt = 100.0 - (100.0*((sum_kevents-tmp[i].count[0])/sum_kevents)); + + if (nr_counters == 1) + printf("%19.2f - %4.1f%% - %016llx : %s\n", + sym_weight(tmp + i), + pcnt, tmp[i].addr, tmp[i].sym); + else + printf("%8.1f %10ld - %4.1f%% - %016llx : %s\n", + sym_weight(tmp + i), + tmp[i].count[0], + pcnt, tmp[i].addr, tmp[i].sym); + printed++; + } + /* + * Add decay to the counts: + */ + for (count = 0; count < nr_counters; count++) + sym_table[i].count[count] = zero ? 0 : sym_table[i].count[count] * 7 / 8; + } + + if (sym_filter_entry) + show_details(sym_filter_entry); + + { + struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; + + if (poll(&stdin_poll, 1, 0) == 1) { + printf("key pressed - exiting.\n"); + exit(0); + } + } +} + +static void *display_thread(void *arg) +{ + printf("KernelTop refresh period: %d seconds\n", delay_secs); + + while (!sleep(delay_secs)) + print_sym_table(); + + return NULL; +} + +static int read_symbol(FILE *in, struct sym_entry *s) +{ + static int filter_match = 0; + char *sym, stype; + char str[500]; + int rc, pos; + + rc = fscanf(in, "%llx %c %499s", &s->addr, &stype, str); + if (rc == EOF) + return -1; + + assert(rc == 3); + + /* skip until end of line: */ + pos = strlen(str); + do { + rc = fgetc(in); + if (rc == '\n' || rc == EOF || pos >= 499) + break; + str[pos] = rc; + pos++; + } while (1); + str[pos] = 0; + + sym = str; + + /* Filter out known duplicates and non-text symbols. */ + if (!strcmp(sym, "_text")) + return 1; + if (!min_ip && !strcmp(sym, "_stext")) + return 1; + if (!strcmp(sym, "_etext") || !strcmp(sym, "_sinittext")) + return 1; + if (stype != 'T' && stype != 't') + return 1; + if (!strncmp("init_module", sym, 11) || !strncmp("cleanup_module", sym, 14)) + return 1; + if (strstr(sym, "_text_start") || strstr(sym, "_text_end")) + return 1; + + s->sym = malloc(strlen(str)); + assert(s->sym); + + strcpy((char *)s->sym, str); + s->skip = 0; + + /* Tag events to be skipped. */ + if (!strcmp("default_idle", s->sym) || !strcmp("cpu_idle", s->sym)) + s->skip = 1; + else if (!strcmp("enter_idle", s->sym) || !strcmp("exit_idle", s->sym)) + s->skip = 1; + else if (!strcmp("mwait_idle", s->sym)) + s->skip = 1; + + if (filter_match == 1) { + filter_end = s->addr; + filter_match = -1; + if (filter_end - filter_start > 10000) { + printf("hm, too large filter symbol <%s> - skipping.\n", + sym_filter); + printf("symbol filter start: %016lx\n", filter_start); + printf(" end: %016lx\n", filter_end); + filter_end = filter_start = 0; + sym_filter = NULL; + sleep(1); + } + } + if (filter_match == 0 && sym_filter && !strcmp(s->sym, sym_filter)) { + filter_match = 1; + filter_start = s->addr; + } + + return 0; +} + +int compare_addr(const void *__sym1, const void *__sym2) +{ + const struct sym_entry *sym1 = __sym1, *sym2 = __sym2; + + return sym1->addr > sym2->addr; +} + +static void sort_symbol_table(void) +{ + int i, dups; + + do { + qsort(sym_table, sym_table_count, sizeof(sym_table[0]), compare_addr); + for (i = 0, dups = 0; i < sym_table_count; i++) { + if (sym_table[i].addr == sym_table[i+1].addr) { + sym_table[i+1].addr = -1ll; + dups++; + } + } + sym_table_count -= dups; + } while(dups); +} + +static void parse_symbols(void) +{ + struct sym_entry *last; + + FILE *kallsyms = fopen("/proc/kallsyms", "r"); + + if (!kallsyms) { + printf("Could not open /proc/kallsyms - no CONFIG_KALLSYMS_ALL=y?\n"); + exit(-1); + } + + while (!feof(kallsyms)) { + if (read_symbol(kallsyms, &sym_table[sym_table_count]) == 0) { + sym_table_count++; + assert(sym_table_count <= MAX_SYMS); + } + } + + sort_symbol_table(); + min_ip = sym_table[0].addr; + max_ip = sym_table[sym_table_count-1].addr; + last = sym_table + sym_table_count++; + + last->addr = -1ll; + last->sym = ""; + + if (filter_end) { + int count; + for (count=0; count < sym_table_count; count ++) { + if (!strcmp(sym_table[count].sym, sym_filter)) { + sym_filter_entry = &sym_table[count]; + break; + } + } + } + if (dump_symtab) { + int i; + + for (i = 0; i < sym_table_count; i++) + fprintf(stderr, "%llx %s\n", + sym_table[i].addr, sym_table[i].sym); + } +} + +/* + * Source lines + */ + +static void parse_vmlinux(char *filename) +{ + FILE *file; + char command[PATH_MAX*2]; + if (!filename) + return; + + sprintf(command, "objdump --start-address=0x%016lx --stop-address=0x%016lx -dS %s", filter_start, filter_end, filename); + + file = popen(command, "r"); + if (!file) + return; + + lines_tail = &lines; + while (!feof(file)) { + struct source_line *src; + size_t dummy = 0; + char *c; + + src = malloc(sizeof(struct source_line)); + assert(src != NULL); + memset(src, 0, sizeof(struct source_line)); + + if (getline(&src->line, &dummy, file) < 0) + break; + if (!src->line) + break; + + c = strchr(src->line, '\n'); + if (c) + *c = 0; + + src->next = NULL; + *lines_tail = src; + lines_tail = &src->next; + + if (strlen(src->line)>8 && src->line[8] == ':') + src->EIP = strtoull(src->line, NULL, 16); + if (strlen(src->line)>8 && src->line[16] == ':') + src->EIP = strtoull(src->line, NULL, 16); + } + pclose(file); +} + +static void record_precise_ip(uint64_t ip) +{ + struct source_line *line; + + for (line = lines; line; line = line->next) { + if (line->EIP == ip) + line->count++; + if (line->EIP > ip) + break; + } +} + +static void lookup_sym_in_vmlinux(struct sym_entry *sym) +{ + struct source_line *line; + char pattern[PATH_MAX]; + sprintf(pattern, "<%s>:", sym->sym); + + for (line = lines; line; line = line->next) { + if (strstr(line->line, pattern)) { + sym->source = line; + break; + } + } +} + +static void show_lines(struct source_line *line_queue, int line_queue_count) +{ + int i; + struct source_line *line; + + line = line_queue; + for (i = 0; i < line_queue_count; i++) { + printf("%8li\t%s\n", line->count, line->line); + line = line->next; + } +} + +#define TRACE_COUNT 3 + +static void show_details(struct sym_entry *sym) +{ + struct source_line *line; + struct source_line *line_queue = NULL; + int displayed = 0; + int line_queue_count = 0; + + if (!sym->source) + lookup_sym_in_vmlinux(sym); + if (!sym->source) + return; + + printf("Showing details for %s\n", sym->sym); + + line = sym->source; + while (line) { + if (displayed && strstr(line->line, ">:")) + break; + + if (!line_queue_count) + line_queue = line; + line_queue_count ++; + + if (line->count >= count_filter) { + show_lines(line_queue, line_queue_count); + line_queue_count = 0; + line_queue = NULL; + } else if (line_queue_count > TRACE_COUNT) { + line_queue = line_queue->next; + line_queue_count --; + } + + line->count = 0; + displayed++; + if (displayed > 300) + break; + line = line->next; + } +} + +/* + * Binary search in the histogram table and record the hit: + */ +static void record_ip(uint64_t ip, int counter) +{ + int left_idx, middle_idx, right_idx, idx; + unsigned long left, middle, right; + + record_precise_ip(ip); + + left_idx = 0; + right_idx = sym_table_count-1; + assert(ip <= max_ip && ip >= min_ip); + + while (left_idx + 1 < right_idx) { + middle_idx = (left_idx + right_idx) / 2; + + left = sym_table[ left_idx].addr; + middle = sym_table[middle_idx].addr; + right = sym_table[ right_idx].addr; + + if (!(left <= middle && middle <= right)) { + printf("%016lx...\n%016lx...\n%016lx\n", left, middle, right); + printf("%d %d %d\n", left_idx, middle_idx, right_idx); + } + assert(left <= middle && middle <= right); + if (!(left <= ip && ip <= right)) { + printf(" left: %016lx\n", left); + printf(" ip: %016lx\n", (unsigned long)ip); + printf("right: %016lx\n", right); + } + assert(left <= ip && ip <= right); + /* + * [ left .... target .... middle .... right ] + * => right := middle + */ + if (ip < middle) { + right_idx = middle_idx; + continue; + } + /* + * [ left .... middle ... target ... right ] + * => left := middle + */ + left_idx = middle_idx; + } + + idx = left_idx; + + if (!sym_table[idx].skip) + sym_table[idx].count[counter]++; + else events--; +} + +static void process_event(uint64_t ip, int counter) +{ + events++; + + if (ip < min_ip || ip > max_ip) { + userspace_events++; + return; + } + + record_ip(ip, counter); +} + +static void process_options(int argc, char *argv[]) +{ + int error = 0, counter; + + if (strstr(argv[0], "perfstat")) + run_perfstat = 1; + + for (;;) { + int option_index = 0; + /** Options for getopt */ + static struct option long_options[] = { + {"count", required_argument, NULL, 'c'}, + {"cpu", required_argument, NULL, 'C'}, + {"delay", required_argument, NULL, 'd'}, + {"dump_symtab", no_argument, NULL, 'D'}, + {"event", required_argument, NULL, 'e'}, + {"filter", required_argument, NULL, 'f'}, + {"group", required_argument, NULL, 'g'}, + {"help", no_argument, NULL, 'h'}, + {"nmi", required_argument, NULL, 'n'}, + {"mmap_info", no_argument, NULL, 'M'}, + {"mmap_pages", required_argument, NULL, 'm'}, + {"munmap_info", no_argument, NULL, 'U'}, + {"pid", required_argument, NULL, 'p'}, + {"realtime", required_argument, NULL, 'r'}, + {"scale", no_argument, NULL, 'l'}, + {"symbol", required_argument, NULL, 's'}, + {"stat", no_argument, NULL, 'S'}, + {"vmlinux", required_argument, NULL, 'x'}, + {"zero", no_argument, NULL, 'z'}, + {NULL, 0, NULL, 0 } + }; + int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hln:m:p:r:s:Sx:zMU", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'a': system_wide = 1; break; + case 'c': default_interval = atoi(optarg); break; + case 'C': + /* CPU and PID are mutually exclusive */ + if (tid != -1) { + printf("WARNING: CPU switch overriding PID\n"); + sleep(1); + tid = -1; + } + profile_cpu = atoi(optarg); break; + case 'd': delay_secs = atoi(optarg); break; + case 'D': dump_symtab = 1; break; + + case 'e': error = parse_events(optarg); break; + + case 'f': count_filter = atoi(optarg); break; + case 'g': group = atoi(optarg); break; + case 'h': display_help(); break; + case 'l': scale = 1; break; + case 'n': nmi = atoi(optarg); break; + case 'p': + /* CPU and PID are mutually exclusive */ + if (profile_cpu != -1) { + printf("WARNING: PID switch overriding CPU\n"); + sleep(1); + profile_cpu = -1; + } + tid = atoi(optarg); break; + case 'r': realtime_prio = atoi(optarg); break; + case 's': sym_filter = strdup(optarg); break; + case 'S': run_perfstat = 1; break; + case 'x': vmlinux = strdup(optarg); break; + case 'z': zero = 1; break; + case 'm': mmap_pages = atoi(optarg); break; + case 'M': use_mmap = 1; break; + case 'U': use_munmap = 1; break; + default: error = 1; break; + } + } + if (error) + display_help(); + + if (!nr_counters) { + if (run_perfstat) + nr_counters = 8; + else { + nr_counters = 1; + event_id[0] = 0; + } + } + + for (counter = 0; counter < nr_counters; counter++) { + if (event_count[counter]) + continue; + + event_count[counter] = default_interval; + } +} + +struct mmap_data { + int counter; + void *base; + unsigned int mask; + unsigned int prev; +}; + +static unsigned int mmap_read_head(struct mmap_data *md) +{ + struct perf_counter_mmap_page *pc = md->base; + int head; + + head = pc->data_head; + rmb(); + + return head; +} + +struct timeval last_read, this_read; + +static void mmap_read(struct mmap_data *md) +{ + unsigned int head = mmap_read_head(md); + unsigned int old = md->prev; + unsigned char *data = md->base + page_size; + int diff; + + gettimeofday(&this_read, NULL); + + /* + * If we're further behind than half the buffer, there's a chance + * the writer will bite our tail and screw up the events under us. + * + * If we somehow ended up ahead of the head, we got messed up. + * + * In either case, truncate and restart at head. + */ + diff = head - old; + if (diff > md->mask / 2 || diff < 0) { + struct timeval iv; + unsigned long msecs; + + timersub(&this_read, &last_read, &iv); + msecs = iv.tv_sec*1000 + iv.tv_usec/1000; + + fprintf(stderr, "WARNING: failed to keep up with mmap data." + " Last read %lu msecs ago.\n", msecs); + + /* + * head points to a known good entry, start there. + */ + old = head; + } + + last_read = this_read; + + for (; old != head;) { + struct ip_event { + struct perf_event_header header; + __u64 ip; + __u32 pid, tid; + }; + struct mmap_event { + struct perf_event_header header; + __u32 pid, tid; + __u64 start; + __u64 len; + __u64 pgoff; + char filename[PATH_MAX]; + }; + + typedef union event_union { + struct perf_event_header header; + struct ip_event ip; + struct mmap_event mmap; + } event_t; + + event_t *event = (event_t *)&data[old & md->mask]; + + event_t event_copy; + + unsigned int size = event->header.size; + + /* + * Event straddles the mmap boundary -- header should always + * be inside due to u64 alignment of output. + */ + if ((old & md->mask) + size != ((old + size) & md->mask)) { + unsigned int offset = old; + unsigned int len = min(sizeof(*event), size), cpy; + void *dst = &event_copy; + + do { + cpy = min(md->mask + 1 - (offset & md->mask), len); + memcpy(dst, &data[offset & md->mask], cpy); + offset += cpy; + dst += cpy; + len -= cpy; + } while (len); + + event = &event_copy; + } + + old += size; + + if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { + if (event->header.type & PERF_RECORD_IP) + process_event(event->ip.ip, md->counter); + } else { + switch (event->header.type) { + case PERF_EVENT_MMAP: + case PERF_EVENT_MUNMAP: + printf("%s: %Lu %Lu %Lu %s\n", + event->header.type == PERF_EVENT_MMAP + ? "mmap" : "munmap", + event->mmap.start, + event->mmap.len, + event->mmap.pgoff, + event->mmap.filename); + break; + } + } + } + + md->prev = old; +} + +int cmd_top(int argc, const char **argv, const char *prefix) +{ + struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; + struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; + struct perf_counter_hw_event hw_event; + pthread_t thread; + int i, counter, group_fd, nr_poll = 0; + unsigned int cpu; + int ret; + + page_size = sysconf(_SC_PAGE_SIZE); + + process_options(argc, argv); + + nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + assert(nr_cpus <= MAX_NR_CPUS); + assert(nr_cpus >= 0); + + if (run_perfstat) + return do_perfstat(argc, argv); + + if (tid != -1 || profile_cpu != -1) + nr_cpus = 1; + + parse_symbols(); + if (vmlinux && sym_filter_entry) + parse_vmlinux(vmlinux); + + for (i = 0; i < nr_cpus; i++) { + group_fd = -1; + for (counter = 0; counter < nr_counters; counter++) { + + cpu = profile_cpu; + if (tid == -1 && profile_cpu == -1) + cpu = i; + + memset(&hw_event, 0, sizeof(hw_event)); + hw_event.config = event_id[counter]; + hw_event.irq_period = event_count[counter]; + hw_event.record_type = PERF_RECORD_IP | PERF_RECORD_TID; + hw_event.nmi = nmi; + hw_event.mmap = use_mmap; + hw_event.munmap = use_munmap; + + fd[i][counter] = sys_perf_counter_open(&hw_event, tid, cpu, group_fd, 0); + if (fd[i][counter] < 0) { + int err = errno; + printf("kerneltop error: syscall returned with %d (%s)\n", + fd[i][counter], strerror(err)); + if (err == EPERM) + printf("Are you root?\n"); + exit(-1); + } + assert(fd[i][counter] >= 0); + fcntl(fd[i][counter], F_SETFL, O_NONBLOCK); + + /* + * First counter acts as the group leader: + */ + if (group && group_fd == -1) + group_fd = fd[i][counter]; + + event_array[nr_poll].fd = fd[i][counter]; + event_array[nr_poll].events = POLLIN; + nr_poll++; + + mmap_array[i][counter].counter = counter; + mmap_array[i][counter].prev = 0; + mmap_array[i][counter].mask = mmap_pages*page_size - 1; + mmap_array[i][counter].base = mmap(NULL, (mmap_pages+1)*page_size, + PROT_READ, MAP_SHARED, fd[i][counter], 0); + if (mmap_array[i][counter].base == MAP_FAILED) { + printf("kerneltop error: failed to mmap with %d (%s)\n", + errno, strerror(errno)); + exit(-1); + } + } + } + + if (pthread_create(&thread, NULL, display_thread, NULL)) { + printf("Could not create display thread.\n"); + exit(-1); + } + + if (realtime_prio) { + struct sched_param param; + + param.sched_priority = realtime_prio; + if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { + printf("Could not set realtime priority.\n"); + exit(-1); + } + } + + while (1) { + int hits = events; + + for (i = 0; i < nr_cpus; i++) { + for (counter = 0; counter < nr_counters; counter++) + mmap_read(&mmap_array[i][counter]); + } + + if (hits == events) + ret = poll(event_array, nr_poll, 100); + } + + return 0; +} diff --git a/Documentation/perf_counter/builtin.h b/Documentation/perf_counter/builtin.h new file mode 100644 index 000000000000..41637444ce2d --- /dev/null +++ b/Documentation/perf_counter/builtin.h @@ -0,0 +1,18 @@ +#ifndef BUILTIN_H +#define BUILTIN_H + +#include "util.h" +#include "strbuf.h" + +extern const char perf_version_string[]; +extern const char perf_usage_string[]; +extern const char perf_more_info_string[]; + +extern void list_common_cmds_help(void); +extern const char *help_unknown_cmd(const char *cmd); +extern void prune_packed_objects(int); +extern int read_line_with_nul(char *buf, int size, FILE *file); +extern int check_pager_config(const char *cmd); + +extern int cmd_top(int argc, const char **argv, const char *prefix); +#endif diff --git a/Documentation/perf_counter/cache.h b/Documentation/perf_counter/cache.h new file mode 100644 index 000000000000..dc085640a57d --- /dev/null +++ b/Documentation/perf_counter/cache.h @@ -0,0 +1,97 @@ +#ifndef CACHE_H +#define CACHE_H + +#include "util.h" +#include "strbuf.h" + +#define PERF_DIR_ENVIRONMENT "PERF_DIR" +#define PERF_WORK_TREE_ENVIRONMENT "PERF_WORK_TREE" +#define DEFAULT_PERF_DIR_ENVIRONMENT ".perf" +#define DB_ENVIRONMENT "PERF_OBJECT_DIRECTORY" +#define INDEX_ENVIRONMENT "PERF_INDEX_FILE" +#define GRAFT_ENVIRONMENT "PERF_GRAFT_FILE" +#define TEMPLATE_DIR_ENVIRONMENT "PERF_TEMPLATE_DIR" +#define CONFIG_ENVIRONMENT "PERF_CONFIG" +#define EXEC_PATH_ENVIRONMENT "PERF_EXEC_PATH" +#define CEILING_DIRECTORIES_ENVIRONMENT "PERF_CEILING_DIRECTORIES" +#define PERFATTRIBUTES_FILE ".perfattributes" +#define INFOATTRIBUTES_FILE "info/attributes" +#define ATTRIBUTE_MACRO_PREFIX "[attr]" + +typedef int (*config_fn_t)(const char *, const char *, void *); +extern int perf_default_config(const char *, const char *, void *); +extern int perf_config_from_file(config_fn_t fn, const char *, void *); +extern int perf_config(config_fn_t fn, void *); +extern int perf_parse_ulong(const char *, unsigned long *); +extern int perf_config_int(const char *, const char *); +extern unsigned long perf_config_ulong(const char *, const char *); +extern int perf_config_bool_or_int(const char *, const char *, int *); +extern int perf_config_bool(const char *, const char *); +extern int perf_config_string(const char **, const char *, const char *); +extern int perf_config_set(const char *, const char *); +extern int perf_config_set_multivar(const char *, const char *, const char *, int); +extern int perf_config_rename_section(const char *, const char *); +extern const char *perf_etc_perfconfig(void); +extern int check_repository_format_version(const char *var, const char *value, void *cb); +extern int perf_config_system(void); +extern int perf_config_global(void); +extern int config_error_nonbool(const char *); +extern const char *config_exclusive_filename; + +#define MAX_PERFNAME (1000) +extern char perf_default_email[MAX_PERFNAME]; +extern char perf_default_name[MAX_PERFNAME]; +extern int user_ident_explicitly_given; + +extern const char *perf_log_output_encoding; +extern const char *perf_mailmap_file; + +/* IO helper functions */ +extern void maybe_flush_or_die(FILE *, const char *); +extern int copy_fd(int ifd, int ofd); +extern int copy_file(const char *dst, const char *src, int mode); +extern ssize_t read_in_full(int fd, void *buf, size_t count); +extern ssize_t write_in_full(int fd, const void *buf, size_t count); +extern void write_or_die(int fd, const void *buf, size_t count); +extern int write_or_whine(int fd, const void *buf, size_t count, const char *msg); +extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg); +extern void fsync_or_die(int fd, const char *); + +/* pager.c */ +extern void setup_pager(void); +extern const char *pager_program; +extern int pager_in_use(void); +extern int pager_use_color; + +extern const char *editor_program; +extern const char *excludes_file; + +char *alias_lookup(const char *alias); +int split_cmdline(char *cmdline, const char ***argv); + +#define alloc_nr(x) (((x)+16)*3/2) + +/* + * Realloc the buffer pointed at by variable 'x' so that it can hold + * at least 'nr' entries; the number of entries currently allocated + * is 'alloc', using the standard growing factor alloc_nr() macro. + * + * DO NOT USE any expression with side-effect for 'x' or 'alloc'. + */ +#define ALLOC_GROW(x, nr, alloc) \ + do { \ + if ((nr) > alloc) { \ + if (alloc_nr(alloc) < (nr)) \ + alloc = (nr); \ + else \ + alloc = alloc_nr(alloc); \ + x = xrealloc((x), alloc * sizeof(*(x))); \ + } \ + } while(0) + + +static inline int is_absolute_path(const char *path) +{ + return path[0] == '/'; +} +#endif /* CACHE_H */ diff --git a/Documentation/perf_counter/command-list.txt b/Documentation/perf_counter/command-list.txt new file mode 100644 index 000000000000..1eab3659b206 --- /dev/null +++ b/Documentation/perf_counter/command-list.txt @@ -0,0 +1,4 @@ +# List of known perf commands. +# command name category [deprecated] [common] +perf-top mainporcelain common + diff --git a/Documentation/perf_counter/config.c b/Documentation/perf_counter/config.c new file mode 100644 index 000000000000..672d53959334 --- /dev/null +++ b/Documentation/perf_counter/config.c @@ -0,0 +1,966 @@ +/* + * GIT - The information manager from hell + * + * Copyright (C) Linus Torvalds, 2005 + * Copyright (C) Johannes Schindelin, 2005 + * + */ +#include "util.h" +#include "cache.h" +#include "exec_cmd.h" + +#define MAXNAME (256) + +static FILE *config_file; +static const char *config_file_name; +static int config_linenr; +static int config_file_eof; +static int zlib_compression_seen; + +const char *config_exclusive_filename = NULL; + +static int get_next_char(void) +{ + int c; + FILE *f; + + c = '\n'; + if ((f = config_file) != NULL) { + c = fgetc(f); + if (c == '\r') { + /* DOS like systems */ + c = fgetc(f); + if (c != '\n') { + ungetc(c, f); + c = '\r'; + } + } + if (c == '\n') + config_linenr++; + if (c == EOF) { + config_file_eof = 1; + c = '\n'; + } + } + return c; +} + +static char *parse_value(void) +{ + static char value[1024]; + int quote = 0, comment = 0, len = 0, space = 0; + + for (;;) { + int c = get_next_char(); + if (len >= sizeof(value) - 1) + return NULL; + if (c == '\n') { + if (quote) + return NULL; + value[len] = 0; + return value; + } + if (comment) + continue; + if (isspace(c) && !quote) { + space = 1; + continue; + } + if (!quote) { + if (c == ';' || c == '#') { + comment = 1; + continue; + } + } + if (space) { + if (len) + value[len++] = ' '; + space = 0; + } + if (c == '\\') { + c = get_next_char(); + switch (c) { + case '\n': + continue; + case 't': + c = '\t'; + break; + case 'b': + c = '\b'; + break; + case 'n': + c = '\n'; + break; + /* Some characters escape as themselves */ + case '\\': case '"': + break; + /* Reject unknown escape sequences */ + default: + return NULL; + } + value[len++] = c; + continue; + } + if (c == '"') { + quote = 1-quote; + continue; + } + value[len++] = c; + } +} + +static inline int iskeychar(int c) +{ + return isalnum(c) || c == '-'; +} + +static int get_value(config_fn_t fn, void *data, char *name, unsigned int len) +{ + int c; + char *value; + + /* Get the full name */ + for (;;) { + c = get_next_char(); + if (config_file_eof) + break; + if (!iskeychar(c)) + break; + name[len++] = tolower(c); + if (len >= MAXNAME) + return -1; + } + name[len] = 0; + while (c == ' ' || c == '\t') + c = get_next_char(); + + value = NULL; + if (c != '\n') { + if (c != '=') + return -1; + value = parse_value(); + if (!value) + return -1; + } + return fn(name, value, data); +} + +static int get_extended_base_var(char *name, int baselen, int c) +{ + do { + if (c == '\n') + return -1; + c = get_next_char(); + } while (isspace(c)); + + /* We require the format to be '[base "extension"]' */ + if (c != '"') + return -1; + name[baselen++] = '.'; + + for (;;) { + int c = get_next_char(); + if (c == '\n') + return -1; + if (c == '"') + break; + if (c == '\\') { + c = get_next_char(); + if (c == '\n') + return -1; + } + name[baselen++] = c; + if (baselen > MAXNAME / 2) + return -1; + } + + /* Final ']' */ + if (get_next_char() != ']') + return -1; + return baselen; +} + +static int get_base_var(char *name) +{ + int baselen = 0; + + for (;;) { + int c = get_next_char(); + if (config_file_eof) + return -1; + if (c == ']') + return baselen; + if (isspace(c)) + return get_extended_base_var(name, baselen, c); + if (!iskeychar(c) && c != '.') + return -1; + if (baselen > MAXNAME / 2) + return -1; + name[baselen++] = tolower(c); + } +} + +static int perf_parse_file(config_fn_t fn, void *data) +{ + int comment = 0; + int baselen = 0; + static char var[MAXNAME]; + + /* U+FEFF Byte Order Mark in UTF8 */ + static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf"; + const unsigned char *bomptr = utf8_bom; + + for (;;) { + int c = get_next_char(); + if (bomptr && *bomptr) { + /* We are at the file beginning; skip UTF8-encoded BOM + * if present. Sane editors won't put this in on their + * own, but e.g. Windows Notepad will do it happily. */ + if ((unsigned char) c == *bomptr) { + bomptr++; + continue; + } else { + /* Do not tolerate partial BOM. */ + if (bomptr != utf8_bom) + break; + /* No BOM at file beginning. Cool. */ + bomptr = NULL; + } + } + if (c == '\n') { + if (config_file_eof) + return 0; + comment = 0; + continue; + } + if (comment || isspace(c)) + continue; + if (c == '#' || c == ';') { + comment = 1; + continue; + } + if (c == '[') { + baselen = get_base_var(var); + if (baselen <= 0) + break; + var[baselen++] = '.'; + var[baselen] = 0; + continue; + } + if (!isalpha(c)) + break; + var[baselen] = tolower(c); + if (get_value(fn, data, var, baselen+1) < 0) + break; + } + die("bad config file line %d in %s", config_linenr, config_file_name); +} + +static int parse_unit_factor(const char *end, unsigned long *val) +{ + if (!*end) + return 1; + else if (!strcasecmp(end, "k")) { + *val *= 1024; + return 1; + } + else if (!strcasecmp(end, "m")) { + *val *= 1024 * 1024; + return 1; + } + else if (!strcasecmp(end, "g")) { + *val *= 1024 * 1024 * 1024; + return 1; + } + return 0; +} + +static int perf_parse_long(const char *value, long *ret) +{ + if (value && *value) { + char *end; + long val = strtol(value, &end, 0); + unsigned long factor = 1; + if (!parse_unit_factor(end, &factor)) + return 0; + *ret = val * factor; + return 1; + } + return 0; +} + +int perf_parse_ulong(const char *value, unsigned long *ret) +{ + if (value && *value) { + char *end; + unsigned long val = strtoul(value, &end, 0); + if (!parse_unit_factor(end, &val)) + return 0; + *ret = val; + return 1; + } + return 0; +} + +static void die_bad_config(const char *name) +{ + if (config_file_name) + die("bad config value for '%s' in %s", name, config_file_name); + die("bad config value for '%s'", name); +} + +int perf_config_int(const char *name, const char *value) +{ + long ret = 0; + if (!perf_parse_long(value, &ret)) + die_bad_config(name); + return ret; +} + +unsigned long perf_config_ulong(const char *name, const char *value) +{ + unsigned long ret; + if (!perf_parse_ulong(value, &ret)) + die_bad_config(name); + return ret; +} + +int perf_config_bool_or_int(const char *name, const char *value, int *is_bool) +{ + *is_bool = 1; + if (!value) + return 1; + if (!*value) + return 0; + if (!strcasecmp(value, "true") || !strcasecmp(value, "yes") || !strcasecmp(value, "on")) + return 1; + if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off")) + return 0; + *is_bool = 0; + return perf_config_int(name, value); +} + +int perf_config_bool(const char *name, const char *value) +{ + int discard; + return !!perf_config_bool_or_int(name, value, &discard); +} + +int perf_config_string(const char **dest, const char *var, const char *value) +{ + if (!value) + return config_error_nonbool(var); + *dest = strdup(value); + return 0; +} + +static int perf_default_core_config(const char *var, const char *value) +{ + /* Add other config variables here and to Documentation/config.txt. */ + return 0; +} + +int perf_default_config(const char *var, const char *value, void *dummy) +{ + if (!prefixcmp(var, "core.")) + return perf_default_core_config(var, value); + + /* Add other config variables here and to Documentation/config.txt. */ + return 0; +} + +int perf_config_from_file(config_fn_t fn, const char *filename, void *data) +{ + int ret; + FILE *f = fopen(filename, "r"); + + ret = -1; + if (f) { + config_file = f; + config_file_name = filename; + config_linenr = 1; + config_file_eof = 0; + ret = perf_parse_file(fn, data); + fclose(f); + config_file_name = NULL; + } + return ret; +} + +const char *perf_etc_perfconfig(void) +{ + static const char *system_wide; + if (!system_wide) + system_wide = system_path(ETC_PERFCONFIG); + return system_wide; +} + +static int perf_env_bool(const char *k, int def) +{ + const char *v = getenv(k); + return v ? perf_config_bool(k, v) : def; +} + +int perf_config_system(void) +{ + return !perf_env_bool("PERF_CONFIG_NOSYSTEM", 0); +} + +int perf_config_global(void) +{ + return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0); +} + +int perf_config(config_fn_t fn, void *data) +{ + int ret = 0, found = 0; + char *repo_config = NULL; + const char *home = NULL; + + /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */ + if (config_exclusive_filename) + return perf_config_from_file(fn, config_exclusive_filename, data); + if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) { + ret += perf_config_from_file(fn, perf_etc_perfconfig(), + data); + found += 1; + } + + home = getenv("HOME"); + if (perf_config_global() && home) { + char *user_config = strdup(mkpath("%s/.perfconfig", home)); + if (!access(user_config, R_OK)) { + ret += perf_config_from_file(fn, user_config, data); + found += 1; + } + free(user_config); + } + + repo_config = perf_pathdup("config"); + if (!access(repo_config, R_OK)) { + ret += perf_config_from_file(fn, repo_config, data); + found += 1; + } + free(repo_config); + if (found == 0) + return -1; + return ret; +} + +/* + * Find all the stuff for perf_config_set() below. + */ + +#define MAX_MATCHES 512 + +static struct { + int baselen; + char* key; + int do_not_match; + regex_t* value_regex; + int multi_replace; + size_t offset[MAX_MATCHES]; + enum { START, SECTION_SEEN, SECTION_END_SEEN, KEY_SEEN } state; + int seen; +} store; + +static int matches(const char* key, const char* value) +{ + return !strcmp(key, store.key) && + (store.value_regex == NULL || + (store.do_not_match ^ + !regexec(store.value_regex, value, 0, NULL, 0))); +} + +static int store_aux(const char* key, const char* value, void *cb) +{ + const char *ep; + size_t section_len; + + switch (store.state) { + case KEY_SEEN: + if (matches(key, value)) { + if (store.seen == 1 && store.multi_replace == 0) { + warning("%s has multiple values", key); + } else if (store.seen >= MAX_MATCHES) { + error("too many matches for %s", key); + return 1; + } + + store.offset[store.seen] = ftell(config_file); + store.seen++; + } + break; + case SECTION_SEEN: + /* + * What we are looking for is in store.key (both + * section and var), and its section part is baselen + * long. We found key (again, both section and var). + * We would want to know if this key is in the same + * section as what we are looking for. We already + * know we are in the same section as what should + * hold store.key. + */ + ep = strrchr(key, '.'); + section_len = ep - key; + + if ((section_len != store.baselen) || + memcmp(key, store.key, section_len+1)) { + store.state = SECTION_END_SEEN; + break; + } + + /* + * Do not increment matches: this is no match, but we + * just made sure we are in the desired section. + */ + store.offset[store.seen] = ftell(config_file); + /* fallthru */ + case SECTION_END_SEEN: + case START: + if (matches(key, value)) { + store.offset[store.seen] = ftell(config_file); + store.state = KEY_SEEN; + store.seen++; + } else { + if (strrchr(key, '.') - key == store.baselen && + !strncmp(key, store.key, store.baselen)) { + store.state = SECTION_SEEN; + store.offset[store.seen] = ftell(config_file); + } + } + } + return 0; +} + +static int write_error(const char *filename) +{ + error("failed to write new configuration file %s", filename); + + /* Same error code as "failed to rename". */ + return 4; +} + +static int store_write_section(int fd, const char* key) +{ + const char *dot; + int i, success; + struct strbuf sb = STRBUF_INIT; + + dot = memchr(key, '.', store.baselen); + if (dot) { + strbuf_addf(&sb, "[%.*s \"", (int)(dot - key), key); + for (i = dot - key + 1; i < store.baselen; i++) { + if (key[i] == '"' || key[i] == '\\') + strbuf_addch(&sb, '\\'); + strbuf_addch(&sb, key[i]); + } + strbuf_addstr(&sb, "\"]\n"); + } else { + strbuf_addf(&sb, "[%.*s]\n", store.baselen, key); + } + + success = write_in_full(fd, sb.buf, sb.len) == sb.len; + strbuf_release(&sb); + + return success; +} + +static int store_write_pair(int fd, const char* key, const char* value) +{ + int i, success; + int length = strlen(key + store.baselen + 1); + const char *quote = ""; + struct strbuf sb = STRBUF_INIT; + + /* + * Check to see if the value needs to be surrounded with a dq pair. + * Note that problematic characters are always backslash-quoted; this + * check is about not losing leading or trailing SP and strings that + * follow beginning-of-comment characters (i.e. ';' and '#') by the + * configuration parser. + */ + if (value[0] == ' ') + quote = "\""; + for (i = 0; value[i]; i++) + if (value[i] == ';' || value[i] == '#') + quote = "\""; + if (i && value[i - 1] == ' ') + quote = "\""; + + strbuf_addf(&sb, "\t%.*s = %s", + length, key + store.baselen + 1, quote); + + for (i = 0; value[i]; i++) + switch (value[i]) { + case '\n': + strbuf_addstr(&sb, "\\n"); + break; + case '\t': + strbuf_addstr(&sb, "\\t"); + break; + case '"': + case '\\': + strbuf_addch(&sb, '\\'); + default: + strbuf_addch(&sb, value[i]); + break; + } + strbuf_addf(&sb, "%s\n", quote); + + success = write_in_full(fd, sb.buf, sb.len) == sb.len; + strbuf_release(&sb); + + return success; +} + +static ssize_t find_beginning_of_line(const char* contents, size_t size, + size_t offset_, int* found_bracket) +{ + size_t equal_offset = size, bracket_offset = size; + ssize_t offset; + +contline: + for (offset = offset_-2; offset > 0 + && contents[offset] != '\n'; offset--) + switch (contents[offset]) { + case '=': equal_offset = offset; break; + case ']': bracket_offset = offset; break; + } + if (offset > 0 && contents[offset-1] == '\\') { + offset_ = offset; + goto contline; + } + if (bracket_offset < equal_offset) { + *found_bracket = 1; + offset = bracket_offset+1; + } else + offset++; + + return offset; +} + +int perf_config_set(const char* key, const char* value) +{ + return perf_config_set_multivar(key, value, NULL, 0); +} + +/* + * If value==NULL, unset in (remove from) config, + * if value_regex!=NULL, disregard key/value pairs where value does not match. + * if multi_replace==0, nothing, or only one matching key/value is replaced, + * else all matching key/values (regardless how many) are removed, + * before the new pair is written. + * + * Returns 0 on success. + * + * This function does this: + * + * - it locks the config file by creating ".perf/config.lock" + * + * - it then parses the config using store_aux() as validator to find + * the position on the key/value pair to replace. If it is to be unset, + * it must be found exactly once. + * + * - the config file is mmap()ed and the part before the match (if any) is + * written to the lock file, then the changed part and the rest. + * + * - the config file is removed and the lock file rename()d to it. + * + */ +int perf_config_set_multivar(const char* key, const char* value, + const char* value_regex, int multi_replace) +{ + int i, dot; + int fd = -1, in_fd; + int ret; + char* config_filename; + const char* last_dot = strrchr(key, '.'); + + if (config_exclusive_filename) + config_filename = strdup(config_exclusive_filename); + else + config_filename = perf_pathdup("config"); + + /* + * Since "key" actually contains the section name and the real + * key name separated by a dot, we have to know where the dot is. + */ + + if (last_dot == NULL) { + error("key does not contain a section: %s", key); + ret = 2; + goto out_free; + } + store.baselen = last_dot - key; + + store.multi_replace = multi_replace; + + /* + * Validate the key and while at it, lower case it for matching. + */ + store.key = malloc(strlen(key) + 1); + dot = 0; + for (i = 0; key[i]; i++) { + unsigned char c = key[i]; + if (c == '.') + dot = 1; + /* Leave the extended basename untouched.. */ + if (!dot || i > store.baselen) { + if (!iskeychar(c) || (i == store.baselen+1 && !isalpha(c))) { + error("invalid key: %s", key); + free(store.key); + ret = 1; + goto out_free; + } + c = tolower(c); + } else if (c == '\n') { + error("invalid key (newline): %s", key); + free(store.key); + ret = 1; + goto out_free; + } + store.key[i] = c; + } + store.key[i] = 0; + + /* + * If .perf/config does not exist yet, write a minimal version. + */ + in_fd = open(config_filename, O_RDONLY); + if ( in_fd < 0 ) { + free(store.key); + + if ( ENOENT != errno ) { + error("opening %s: %s", config_filename, + strerror(errno)); + ret = 3; /* same as "invalid config file" */ + goto out_free; + } + /* if nothing to unset, error out */ + if (value == NULL) { + ret = 5; + goto out_free; + } + + store.key = (char*)key; + if (!store_write_section(fd, key) || + !store_write_pair(fd, key, value)) + goto write_err_out; + } else { + struct stat st; + char* contents; + size_t contents_sz, copy_begin, copy_end; + int i, new_line = 0; + + if (value_regex == NULL) + store.value_regex = NULL; + else { + if (value_regex[0] == '!') { + store.do_not_match = 1; + value_regex++; + } else + store.do_not_match = 0; + + store.value_regex = (regex_t*)malloc(sizeof(regex_t)); + if (regcomp(store.value_regex, value_regex, + REG_EXTENDED)) { + error("invalid pattern: %s", value_regex); + free(store.value_regex); + ret = 6; + goto out_free; + } + } + + store.offset[0] = 0; + store.state = START; + store.seen = 0; + + /* + * After this, store.offset will contain the *end* offset + * of the last match, or remain at 0 if no match was found. + * As a side effect, we make sure to transform only a valid + * existing config file. + */ + if (perf_config_from_file(store_aux, config_filename, NULL)) { + error("invalid config file %s", config_filename); + free(store.key); + if (store.value_regex != NULL) { + regfree(store.value_regex); + free(store.value_regex); + } + ret = 3; + goto out_free; + } + + free(store.key); + if (store.value_regex != NULL) { + regfree(store.value_regex); + free(store.value_regex); + } + + /* if nothing to unset, or too many matches, error out */ + if ((store.seen == 0 && value == NULL) || + (store.seen > 1 && multi_replace == 0)) { + ret = 5; + goto out_free; + } + + fstat(in_fd, &st); + contents_sz = xsize_t(st.st_size); + contents = mmap(NULL, contents_sz, PROT_READ, + MAP_PRIVATE, in_fd, 0); + close(in_fd); + + if (store.seen == 0) + store.seen = 1; + + for (i = 0, copy_begin = 0; i < store.seen; i++) { + if (store.offset[i] == 0) { + store.offset[i] = copy_end = contents_sz; + } else if (store.state != KEY_SEEN) { + copy_end = store.offset[i]; + } else + copy_end = find_beginning_of_line( + contents, contents_sz, + store.offset[i]-2, &new_line); + + if (copy_end > 0 && contents[copy_end-1] != '\n') + new_line = 1; + + /* write the first part of the config */ + if (copy_end > copy_begin) { + if (write_in_full(fd, contents + copy_begin, + copy_end - copy_begin) < + copy_end - copy_begin) + goto write_err_out; + if (new_line && + write_in_full(fd, "\n", 1) != 1) + goto write_err_out; + } + copy_begin = store.offset[i]; + } + + /* write the pair (value == NULL means unset) */ + if (value != NULL) { + if (store.state == START) { + if (!store_write_section(fd, key)) + goto write_err_out; + } + if (!store_write_pair(fd, key, value)) + goto write_err_out; + } + + /* write the rest of the config */ + if (copy_begin < contents_sz) + if (write_in_full(fd, contents + copy_begin, + contents_sz - copy_begin) < + contents_sz - copy_begin) + goto write_err_out; + + munmap(contents, contents_sz); + } + + ret = 0; + +out_free: + free(config_filename); + return ret; + +write_err_out: + goto out_free; + +} + +static int section_name_match (const char *buf, const char *name) +{ + int i = 0, j = 0, dot = 0; + for (; buf[i] && buf[i] != ']'; i++) { + if (!dot && isspace(buf[i])) { + dot = 1; + if (name[j++] != '.') + break; + for (i++; isspace(buf[i]); i++) + ; /* do nothing */ + if (buf[i] != '"') + break; + continue; + } + if (buf[i] == '\\' && dot) + i++; + else if (buf[i] == '"' && dot) { + for (i++; isspace(buf[i]); i++) + ; /* do_nothing */ + break; + } + if (buf[i] != name[j++]) + break; + } + return (buf[i] == ']' && name[j] == 0); +} + +/* if new_name == NULL, the section is removed instead */ +int perf_config_rename_section(const char *old_name, const char *new_name) +{ + int ret = 0, remove = 0; + char *config_filename; + int out_fd; + char buf[1024]; + + if (config_exclusive_filename) + config_filename = strdup(config_exclusive_filename); + else + config_filename = perf_pathdup("config"); + if (out_fd < 0) { + ret = error("could not lock config file %s", config_filename); + goto out; + } + + if (!(config_file = fopen(config_filename, "rb"))) { + /* no config file means nothing to rename, no error */ + goto unlock_and_out; + } + + while (fgets(buf, sizeof(buf), config_file)) { + int i; + int length; + for (i = 0; buf[i] && isspace(buf[i]); i++) + ; /* do nothing */ + if (buf[i] == '[') { + /* it's a section */ + if (section_name_match (&buf[i+1], old_name)) { + ret++; + if (new_name == NULL) { + remove = 1; + continue; + } + store.baselen = strlen(new_name); + if (!store_write_section(out_fd, new_name)) { + goto out; + } + continue; + } + remove = 0; + } + if (remove) + continue; + length = strlen(buf); + if (write_in_full(out_fd, buf, length) != length) { + goto out; + } + } + fclose(config_file); + unlock_and_out: + out: + free(config_filename); + return ret; +} + +/* + * Call this to report error for your variable that should not + * get a boolean value (i.e. "[my] var" means "true"). + */ +int config_error_nonbool(const char *var) +{ + return error("Missing value for '%s'", var); +} diff --git a/Documentation/perf_counter/ctype.c b/Documentation/perf_counter/ctype.c new file mode 100644 index 000000000000..b90ec004f29c --- /dev/null +++ b/Documentation/perf_counter/ctype.c @@ -0,0 +1,26 @@ +/* + * Sane locale-independent, ASCII ctype. + * + * No surprises, and works with signed and unsigned chars. + */ +#include "cache.h" + +enum { + S = GIT_SPACE, + A = GIT_ALPHA, + D = GIT_DIGIT, + G = GIT_GLOB_SPECIAL, /* *, ?, [, \\ */ + R = GIT_REGEX_SPECIAL, /* $, (, ), +, ., ^, {, | * */ +}; + +unsigned char sane_ctype[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0, /* 0.. 15 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16.. 31 */ + S, 0, 0, 0, R, 0, 0, 0, R, R, G, R, 0, 0, R, 0, /* 32.. 47 */ + D, D, D, D, D, D, D, D, D, D, 0, 0, 0, 0, 0, G, /* 48.. 63 */ + 0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, /* 64.. 79 */ + A, A, A, A, A, A, A, A, A, A, A, G, G, 0, R, 0, /* 80.. 95 */ + 0, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, /* 96..111 */ + A, A, A, A, A, A, A, A, A, A, A, R, R, 0, 0, 0, /* 112..127 */ + /* Nothing in the 128.. range */ +}; diff --git a/Documentation/perf_counter/exec_cmd.c b/Documentation/perf_counter/exec_cmd.c new file mode 100644 index 000000000000..d39292263153 --- /dev/null +++ b/Documentation/perf_counter/exec_cmd.c @@ -0,0 +1,165 @@ +#include "cache.h" +#include "exec_cmd.h" +#include "quote.h" +#define MAX_ARGS 32 + +extern char **environ; +static const char *argv_exec_path; +static const char *argv0_path; + +const char *system_path(const char *path) +{ +#ifdef RUNTIME_PREFIX + static const char *prefix; +#else + static const char *prefix = PREFIX; +#endif + struct strbuf d = STRBUF_INIT; + + if (is_absolute_path(path)) + return path; + +#ifdef RUNTIME_PREFIX + assert(argv0_path); + assert(is_absolute_path(argv0_path)); + + if (!prefix && + !(prefix = strip_path_suffix(argv0_path, PERF_EXEC_PATH)) && + !(prefix = strip_path_suffix(argv0_path, BINDIR)) && + !(prefix = strip_path_suffix(argv0_path, "perf"))) { + prefix = PREFIX; + fprintf(stderr, "RUNTIME_PREFIX requested, " + "but prefix computation failed. " + "Using static fallback '%s'.\n", prefix); + } +#endif + + strbuf_addf(&d, "%s/%s", prefix, path); + path = strbuf_detach(&d, NULL); + return path; +} + +const char *perf_extract_argv0_path(const char *argv0) +{ + const char *slash; + + if (!argv0 || !*argv0) + return NULL; + slash = argv0 + strlen(argv0); + + while (argv0 <= slash && !is_dir_sep(*slash)) + slash--; + + if (slash >= argv0) { + argv0_path = strndup(argv0, slash - argv0); + return slash + 1; + } + + return argv0; +} + +void perf_set_argv_exec_path(const char *exec_path) +{ + argv_exec_path = exec_path; + /* + * Propagate this setting to external programs. + */ + setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1); +} + + +/* Returns the highest-priority, location to look for perf programs. */ +const char *perf_exec_path(void) +{ + const char *env; + + if (argv_exec_path) + return argv_exec_path; + + env = getenv(EXEC_PATH_ENVIRONMENT); + if (env && *env) { + return env; + } + + return system_path(PERF_EXEC_PATH); +} + +static void add_path(struct strbuf *out, const char *path) +{ + if (path && *path) { + if (is_absolute_path(path)) + strbuf_addstr(out, path); + else + strbuf_addstr(out, make_nonrelative_path(path)); + + strbuf_addch(out, PATH_SEP); + } +} + +void setup_path(void) +{ + const char *old_path = getenv("PATH"); + struct strbuf new_path = STRBUF_INIT; + + add_path(&new_path, perf_exec_path()); + add_path(&new_path, argv0_path); + + if (old_path) + strbuf_addstr(&new_path, old_path); + else + strbuf_addstr(&new_path, "/usr/local/bin:/usr/bin:/bin"); + + setenv("PATH", new_path.buf, 1); + + strbuf_release(&new_path); +} + +const char **prepare_perf_cmd(const char **argv) +{ + int argc; + const char **nargv; + + for (argc = 0; argv[argc]; argc++) + ; /* just counting */ + nargv = malloc(sizeof(*nargv) * (argc + 2)); + + nargv[0] = "perf"; + for (argc = 0; argv[argc]; argc++) + nargv[argc + 1] = argv[argc]; + nargv[argc + 1] = NULL; + return nargv; +} + +int execv_perf_cmd(const char **argv) { + const char **nargv = prepare_perf_cmd(argv); + + /* execvp() can only ever return if it fails */ + execvp("perf", (char **)nargv); + + free(nargv); + return -1; +} + + +int execl_perf_cmd(const char *cmd,...) +{ + int argc; + const char *argv[MAX_ARGS + 1]; + const char *arg; + va_list param; + + va_start(param, cmd); + argv[0] = cmd; + argc = 1; + while (argc < MAX_ARGS) { + arg = argv[argc++] = va_arg(param, char *); + if (!arg) + break; + } + va_end(param); + if (MAX_ARGS <= argc) + return error("too many args to run %s", cmd); + + argv[argc] = NULL; + return execv_perf_cmd(argv); +} diff --git a/Documentation/perf_counter/exec_cmd.h b/Documentation/perf_counter/exec_cmd.h new file mode 100644 index 000000000000..effe25eb1545 --- /dev/null +++ b/Documentation/perf_counter/exec_cmd.h @@ -0,0 +1,13 @@ +#ifndef PERF_EXEC_CMD_H +#define PERF_EXEC_CMD_H + +extern void perf_set_argv_exec_path(const char *exec_path); +extern const char *perf_extract_argv0_path(const char *path); +extern const char *perf_exec_path(void); +extern void setup_path(void); +extern const char **prepare_perf_cmd(const char **argv); +extern int execv_perf_cmd(const char **argv); /* NULL terminated */ +extern int execl_perf_cmd(const char *cmd, ...); +extern const char *system_path(const char *path); + +#endif /* PERF_EXEC_CMD_H */ diff --git a/Documentation/perf_counter/generate-cmdlist.sh b/Documentation/perf_counter/generate-cmdlist.sh new file mode 100755 index 000000000000..75c68d948fd3 --- /dev/null +++ b/Documentation/perf_counter/generate-cmdlist.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +echo "/* Automatically generated by $0 */ +struct cmdname_help +{ + char name[16]; + char help[80]; +}; + +static struct cmdname_help common_cmds[] = {" + +sed -n -e 's/^git-\([^ ]*\)[ ].* common.*/\1/p' command-list.txt | +sort | +while read cmd +do + sed -n ' + /^NAME/,/git-'"$cmd"'/H + ${ + x + s/.*git-'"$cmd"' - \(.*\)/ {"'"$cmd"'", "\1"},/ + p + }' "Documentation/git-$cmd.txt" +done +echo "};" diff --git a/Documentation/perf_counter/help.c b/Documentation/perf_counter/help.c new file mode 100644 index 000000000000..ec0116721660 --- /dev/null +++ b/Documentation/perf_counter/help.c @@ -0,0 +1,366 @@ +#include "cache.h" +#include "builtin.h" +#include "exec_cmd.h" +#include "levenshtein.h" +#include "help.h" + +/* most GUI terminals set COLUMNS (although some don't export it) */ +static int term_columns(void) +{ + char *col_string = getenv("COLUMNS"); + int n_cols; + + if (col_string && (n_cols = atoi(col_string)) > 0) + return n_cols; + +#ifdef TIOCGWINSZ + { + struct winsize ws; + if (!ioctl(1, TIOCGWINSZ, &ws)) { + if (ws.ws_col) + return ws.ws_col; + } + } +#endif + + return 80; +} + +void add_cmdname(struct cmdnames *cmds, const char *name, int len) +{ + struct cmdname *ent = malloc(sizeof(*ent) + len + 1); + + ent->len = len; + memcpy(ent->name, name, len); + ent->name[len] = 0; + + ALLOC_GROW(cmds->names, cmds->cnt + 1, cmds->alloc); + cmds->names[cmds->cnt++] = ent; +} + +static void clean_cmdnames(struct cmdnames *cmds) +{ + int i; + for (i = 0; i < cmds->cnt; ++i) + free(cmds->names[i]); + free(cmds->names); + cmds->cnt = 0; + cmds->alloc = 0; +} + +static int cmdname_compare(const void *a_, const void *b_) +{ + struct cmdname *a = *(struct cmdname **)a_; + struct cmdname *b = *(struct cmdname **)b_; + return strcmp(a->name, b->name); +} + +static void uniq(struct cmdnames *cmds) +{ + int i, j; + + if (!cmds->cnt) + return; + + for (i = j = 1; i < cmds->cnt; i++) + if (strcmp(cmds->names[i]->name, cmds->names[i-1]->name)) + cmds->names[j++] = cmds->names[i]; + + cmds->cnt = j; +} + +void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) +{ + int ci, cj, ei; + int cmp; + + ci = cj = ei = 0; + while (ci < cmds->cnt && ei < excludes->cnt) { + cmp = strcmp(cmds->names[ci]->name, excludes->names[ei]->name); + if (cmp < 0) + cmds->names[cj++] = cmds->names[ci++]; + else if (cmp == 0) + ci++, ei++; + else if (cmp > 0) + ei++; + } + + while (ci < cmds->cnt) + cmds->names[cj++] = cmds->names[ci++]; + + cmds->cnt = cj; +} + +static void pretty_print_string_list(struct cmdnames *cmds, int longest) +{ + int cols = 1, rows; + int space = longest + 1; /* min 1 SP between words */ + int max_cols = term_columns() - 1; /* don't print *on* the edge */ + int i, j; + + if (space < max_cols) + cols = max_cols / space; + rows = (cmds->cnt + cols - 1) / cols; + + for (i = 0; i < rows; i++) { + printf(" "); + + for (j = 0; j < cols; j++) { + int n = j * rows + i; + int size = space; + if (n >= cmds->cnt) + break; + if (j == cols-1 || n + rows >= cmds->cnt) + size = 1; + printf("%-*s", size, cmds->names[n]->name); + } + putchar('\n'); + } +} + +static int is_executable(const char *name) +{ + struct stat st; + + if (stat(name, &st) || /* stat, not lstat */ + !S_ISREG(st.st_mode)) + return 0; + +#ifdef __MINGW32__ + /* cannot trust the executable bit, peek into the file instead */ + char buf[3] = { 0 }; + int n; + int fd = open(name, O_RDONLY); + st.st_mode &= ~S_IXUSR; + if (fd >= 0) { + n = read(fd, buf, 2); + if (n == 2) + /* DOS executables start with "MZ" */ + if (!strcmp(buf, "#!") || !strcmp(buf, "MZ")) + st.st_mode |= S_IXUSR; + close(fd); + } +#endif + return st.st_mode & S_IXUSR; +} + +static void list_commands_in_dir(struct cmdnames *cmds, + const char *path, + const char *prefix) +{ + int prefix_len; + DIR *dir = opendir(path); + struct dirent *de; + struct strbuf buf = STRBUF_INIT; + int len; + + if (!dir) + return; + if (!prefix) + prefix = "perf-"; + prefix_len = strlen(prefix); + + strbuf_addf(&buf, "%s/", path); + len = buf.len; + + while ((de = readdir(dir)) != NULL) { + int entlen; + + if (prefixcmp(de->d_name, prefix)) + continue; + + strbuf_setlen(&buf, len); + strbuf_addstr(&buf, de->d_name); + if (!is_executable(buf.buf)) + continue; + + entlen = strlen(de->d_name) - prefix_len; + if (has_extension(de->d_name, ".exe")) + entlen -= 4; + + add_cmdname(cmds, de->d_name + prefix_len, entlen); + } + closedir(dir); + strbuf_release(&buf); +} + +void load_command_list(const char *prefix, + struct cmdnames *main_cmds, + struct cmdnames *other_cmds) +{ + const char *env_path = getenv("PATH"); + const char *exec_path = perf_exec_path(); + + if (exec_path) { + list_commands_in_dir(main_cmds, exec_path, prefix); + qsort(main_cmds->names, main_cmds->cnt, + sizeof(*main_cmds->names), cmdname_compare); + uniq(main_cmds); + } + + if (env_path) { + char *paths, *path, *colon; + path = paths = strdup(env_path); + while (1) { + if ((colon = strchr(path, PATH_SEP))) + *colon = 0; + if (!exec_path || strcmp(path, exec_path)) + list_commands_in_dir(other_cmds, path, prefix); + + if (!colon) + break; + path = colon + 1; + } + free(paths); + + qsort(other_cmds->names, other_cmds->cnt, + sizeof(*other_cmds->names), cmdname_compare); + uniq(other_cmds); + } + exclude_cmds(other_cmds, main_cmds); +} + +void list_commands(const char *title, struct cmdnames *main_cmds, + struct cmdnames *other_cmds) +{ + int i, longest = 0; + + for (i = 0; i < main_cmds->cnt; i++) + if (longest < main_cmds->names[i]->len) + longest = main_cmds->names[i]->len; + for (i = 0; i < other_cmds->cnt; i++) + if (longest < other_cmds->names[i]->len) + longest = other_cmds->names[i]->len; + + if (main_cmds->cnt) { + const char *exec_path = perf_exec_path(); + printf("available %s in '%s'\n", title, exec_path); + printf("----------------"); + mput_char('-', strlen(title) + strlen(exec_path)); + putchar('\n'); + pretty_print_string_list(main_cmds, longest); + putchar('\n'); + } + + if (other_cmds->cnt) { + printf("%s available from elsewhere on your $PATH\n", title); + printf("---------------------------------------"); + mput_char('-', strlen(title)); + putchar('\n'); + pretty_print_string_list(other_cmds, longest); + putchar('\n'); + } +} + +int is_in_cmdlist(struct cmdnames *c, const char *s) +{ + int i; + for (i = 0; i < c->cnt; i++) + if (!strcmp(s, c->names[i]->name)) + return 1; + return 0; +} + +static int autocorrect; +static struct cmdnames aliases; + +static int perf_unknown_cmd_config(const char *var, const char *value, void *cb) +{ + if (!strcmp(var, "help.autocorrect")) + autocorrect = perf_config_int(var,value); + /* Also use aliases for command lookup */ + if (!prefixcmp(var, "alias.")) + add_cmdname(&aliases, var + 6, strlen(var + 6)); + + return perf_default_config(var, value, cb); +} + +static int levenshtein_compare(const void *p1, const void *p2) +{ + const struct cmdname *const *c1 = p1, *const *c2 = p2; + const char *s1 = (*c1)->name, *s2 = (*c2)->name; + int l1 = (*c1)->len; + int l2 = (*c2)->len; + return l1 != l2 ? l1 - l2 : strcmp(s1, s2); +} + +static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) +{ + int i; + ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); + + for (i = 0; i < old->cnt; i++) + cmds->names[cmds->cnt++] = old->names[i]; + free(old->names); + old->cnt = 0; + old->names = NULL; +} + +const char *help_unknown_cmd(const char *cmd) +{ + int i, n, best_similarity = 0; + struct cmdnames main_cmds, other_cmds; + + memset(&main_cmds, 0, sizeof(main_cmds)); + memset(&other_cmds, 0, sizeof(main_cmds)); + memset(&aliases, 0, sizeof(aliases)); + + perf_config(perf_unknown_cmd_config, NULL); + + load_command_list("perf-", &main_cmds, &other_cmds); + + add_cmd_list(&main_cmds, &aliases); + add_cmd_list(&main_cmds, &other_cmds); + qsort(main_cmds.names, main_cmds.cnt, + sizeof(main_cmds.names), cmdname_compare); + uniq(&main_cmds); + + /* This reuses cmdname->len for similarity index */ + for (i = 0; i < main_cmds.cnt; ++i) + main_cmds.names[i]->len = + levenshtein(cmd, main_cmds.names[i]->name, 0, 2, 1, 4); + + qsort(main_cmds.names, main_cmds.cnt, + sizeof(*main_cmds.names), levenshtein_compare); + + if (!main_cmds.cnt) + die ("Uh oh. Your system reports no Git commands at all."); + + best_similarity = main_cmds.names[0]->len; + n = 1; + while (n < main_cmds.cnt && best_similarity == main_cmds.names[n]->len) + ++n; + if (autocorrect && n == 1) { + const char *assumed = main_cmds.names[0]->name; + main_cmds.names[0] = NULL; + clean_cmdnames(&main_cmds); + fprintf(stderr, "WARNING: You called a Git program named '%s', " + "which does not exist.\n" + "Continuing under the assumption that you meant '%s'\n", + cmd, assumed); + if (autocorrect > 0) { + fprintf(stderr, "in %0.1f seconds automatically...\n", + (float)autocorrect/10.0); + poll(NULL, 0, autocorrect * 100); + } + return assumed; + } + + fprintf(stderr, "perf: '%s' is not a perf-command. See 'perf --help'.\n", cmd); + + if (best_similarity < 6) { + fprintf(stderr, "\nDid you mean %s?\n", + n < 2 ? "this": "one of these"); + + for (i = 0; i < n; i++) + fprintf(stderr, "\t%s\n", main_cmds.names[i]->name); + } + + exit(1); +} + +int cmd_version(int argc, const char **argv, const char *prefix) +{ + printf("perf version %s\n", perf_version_string); + return 0; +} diff --git a/Documentation/perf_counter/help.h b/Documentation/perf_counter/help.h new file mode 100644 index 000000000000..56bc15406ffc --- /dev/null +++ b/Documentation/perf_counter/help.h @@ -0,0 +1,29 @@ +#ifndef HELP_H +#define HELP_H + +struct cmdnames { + int alloc; + int cnt; + struct cmdname { + size_t len; /* also used for similarity index in help.c */ + char name[FLEX_ARRAY]; + } **names; +}; + +static inline void mput_char(char c, unsigned int num) +{ + while(num--) + putchar(c); +} + +void load_command_list(const char *prefix, + struct cmdnames *main_cmds, + struct cmdnames *other_cmds); +void add_cmdname(struct cmdnames *cmds, const char *name, int len); +/* Here we require that excludes is a sorted list. */ +void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes); +int is_in_cmdlist(struct cmdnames *c, const char *s); +void list_commands(const char *title, struct cmdnames *main_cmds, + struct cmdnames *other_cmds); + +#endif /* HELP_H */ diff --git a/Documentation/perf_counter/levenshtein.c b/Documentation/perf_counter/levenshtein.c new file mode 100644 index 000000000000..e521d1516df6 --- /dev/null +++ b/Documentation/perf_counter/levenshtein.c @@ -0,0 +1,84 @@ +#include "cache.h" +#include "levenshtein.h" + +/* + * This function implements the Damerau-Levenshtein algorithm to + * calculate a distance between strings. + * + * Basically, it says how many letters need to be swapped, substituted, + * deleted from, or added to string1, at least, to get string2. + * + * The idea is to build a distance matrix for the substrings of both + * strings. To avoid a large space complexity, only the last three rows + * are kept in memory (if swaps had the same or higher cost as one deletion + * plus one insertion, only two rows would be needed). + * + * At any stage, "i + 1" denotes the length of the current substring of + * string1 that the distance is calculated for. + * + * row2 holds the current row, row1 the previous row (i.e. for the substring + * of string1 of length "i"), and row0 the row before that. + * + * In other words, at the start of the big loop, row2[j + 1] contains the + * Damerau-Levenshtein distance between the substring of string1 of length + * "i" and the substring of string2 of length "j + 1". + * + * All the big loop does is determine the partial minimum-cost paths. + * + * It does so by calculating the costs of the path ending in characters + * i (in string1) and j (in string2), respectively, given that the last + * operation is a substition, a swap, a deletion, or an insertion. + * + * This implementation allows the costs to be weighted: + * + * - w (as in "sWap") + * - s (as in "Substitution") + * - a (for insertion, AKA "Add") + * - d (as in "Deletion") + * + * Note that this algorithm calculates a distance _iff_ d == a. + */ +int levenshtein(const char *string1, const char *string2, + int w, int s, int a, int d) +{ + int len1 = strlen(string1), len2 = strlen(string2); + int *row0 = malloc(sizeof(int) * (len2 + 1)); + int *row1 = malloc(sizeof(int) * (len2 + 1)); + int *row2 = malloc(sizeof(int) * (len2 + 1)); + int i, j; + + for (j = 0; j <= len2; j++) + row1[j] = j * a; + for (i = 0; i < len1; i++) { + int *dummy; + + row2[0] = (i + 1) * d; + for (j = 0; j < len2; j++) { + /* substitution */ + row2[j + 1] = row1[j] + s * (string1[i] != string2[j]); + /* swap */ + if (i > 0 && j > 0 && string1[i - 1] == string2[j] && + string1[i] == string2[j - 1] && + row2[j + 1] > row0[j - 1] + w) + row2[j + 1] = row0[j - 1] + w; + /* deletion */ + if (row2[j + 1] > row1[j + 1] + d) + row2[j + 1] = row1[j + 1] + d; + /* insertion */ + if (row2[j + 1] > row2[j] + a) + row2[j + 1] = row2[j] + a; + } + + dummy = row0; + row0 = row1; + row1 = row2; + row2 = dummy; + } + + i = row1[len2]; + free(row0); + free(row1); + free(row2); + + return i; +} diff --git a/Documentation/perf_counter/levenshtein.h b/Documentation/perf_counter/levenshtein.h new file mode 100644 index 000000000000..0173abeef52c --- /dev/null +++ b/Documentation/perf_counter/levenshtein.h @@ -0,0 +1,8 @@ +#ifndef LEVENSHTEIN_H +#define LEVENSHTEIN_H + +int levenshtein(const char *string1, const char *string2, + int swap_penalty, int substition_penalty, + int insertion_penalty, int deletion_penalty); + +#endif diff --git a/Documentation/perf_counter/parse-options.c b/Documentation/perf_counter/parse-options.c new file mode 100644 index 000000000000..7464f34e5407 --- /dev/null +++ b/Documentation/perf_counter/parse-options.c @@ -0,0 +1,495 @@ +#include "util.h" +#include "parse-options.h" +#include "cache.h" + +#define OPT_SHORT 1 +#define OPT_UNSET 2 + +static int opterror(const struct option *opt, const char *reason, int flags) +{ + if (flags & OPT_SHORT) + return error("switch `%c' %s", opt->short_name, reason); + if (flags & OPT_UNSET) + return error("option `no-%s' %s", opt->long_name, reason); + return error("option `%s' %s", opt->long_name, reason); +} + +static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt, + int flags, const char **arg) +{ + if (p->opt) { + *arg = p->opt; + p->opt = NULL; + } else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) { + *arg = (const char *)opt->defval; + } else if (p->argc > 1) { + p->argc--; + *arg = *++p->argv; + } else + return opterror(opt, "requires a value", flags); + return 0; +} + +static int get_value(struct parse_opt_ctx_t *p, + const struct option *opt, int flags) +{ + const char *s, *arg; + const int unset = flags & OPT_UNSET; + + if (unset && p->opt) + return opterror(opt, "takes no value", flags); + if (unset && (opt->flags & PARSE_OPT_NONEG)) + return opterror(opt, "isn't available", flags); + + if (!(flags & OPT_SHORT) && p->opt) { + switch (opt->type) { + case OPTION_CALLBACK: + if (!(opt->flags & PARSE_OPT_NOARG)) + break; + /* FALLTHROUGH */ + case OPTION_BOOLEAN: + case OPTION_BIT: + case OPTION_SET_INT: + case OPTION_SET_PTR: + return opterror(opt, "takes no value", flags); + default: + break; + } + } + + switch (opt->type) { + case OPTION_BIT: + if (unset) + *(int *)opt->value &= ~opt->defval; + else + *(int *)opt->value |= opt->defval; + return 0; + + case OPTION_BOOLEAN: + *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1; + return 0; + + case OPTION_SET_INT: + *(int *)opt->value = unset ? 0 : opt->defval; + return 0; + + case OPTION_SET_PTR: + *(void **)opt->value = unset ? NULL : (void *)opt->defval; + return 0; + + case OPTION_STRING: + if (unset) + *(const char **)opt->value = NULL; + else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) + *(const char **)opt->value = (const char *)opt->defval; + else + return get_arg(p, opt, flags, (const char **)opt->value); + return 0; + + case OPTION_CALLBACK: + if (unset) + return (*opt->callback)(opt, NULL, 1) ? (-1) : 0; + if (opt->flags & PARSE_OPT_NOARG) + return (*opt->callback)(opt, NULL, 0) ? (-1) : 0; + if (opt->flags & PARSE_OPT_OPTARG && !p->opt) + return (*opt->callback)(opt, NULL, 0) ? (-1) : 0; + if (get_arg(p, opt, flags, &arg)) + return -1; + return (*opt->callback)(opt, arg, 0) ? (-1) : 0; + + case OPTION_INTEGER: + if (unset) { + *(int *)opt->value = 0; + return 0; + } + if (opt->flags & PARSE_OPT_OPTARG && !p->opt) { + *(int *)opt->value = opt->defval; + return 0; + } + if (get_arg(p, opt, flags, &arg)) + return -1; + *(int *)opt->value = strtol(arg, (char **)&s, 10); + if (*s) + return opterror(opt, "expects a numerical value", flags); + return 0; + + default: + die("should not happen, someone must be hit on the forehead"); + } +} + +static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options) +{ + for (; options->type != OPTION_END; options++) { + if (options->short_name == *p->opt) { + p->opt = p->opt[1] ? p->opt + 1 : NULL; + return get_value(p, options, OPT_SHORT); + } + } + return -2; +} + +static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, + const struct option *options) +{ + const char *arg_end = strchr(arg, '='); + const struct option *abbrev_option = NULL, *ambiguous_option = NULL; + int abbrev_flags = 0, ambiguous_flags = 0; + + if (!arg_end) + arg_end = arg + strlen(arg); + + for (; options->type != OPTION_END; options++) { + const char *rest; + int flags = 0; + + if (!options->long_name) + continue; + + rest = skip_prefix(arg, options->long_name); + if (options->type == OPTION_ARGUMENT) { + if (!rest) + continue; + if (*rest == '=') + return opterror(options, "takes no value", flags); + if (*rest) + continue; + p->out[p->cpidx++] = arg - 2; + return 0; + } + if (!rest) { + /* abbreviated? */ + if (!strncmp(options->long_name, arg, arg_end - arg)) { +is_abbreviated: + if (abbrev_option) { + /* + * If this is abbreviated, it is + * ambiguous. So when there is no + * exact match later, we need to + * error out. + */ + ambiguous_option = abbrev_option; + ambiguous_flags = abbrev_flags; + } + if (!(flags & OPT_UNSET) && *arg_end) + p->opt = arg_end + 1; + abbrev_option = options; + abbrev_flags = flags; + continue; + } + /* negated and abbreviated very much? */ + if (!prefixcmp("no-", arg)) { + flags |= OPT_UNSET; + goto is_abbreviated; + } + /* negated? */ + if (strncmp(arg, "no-", 3)) + continue; + flags |= OPT_UNSET; + rest = skip_prefix(arg + 3, options->long_name); + /* abbreviated and negated? */ + if (!rest && !prefixcmp(options->long_name, arg + 3)) + goto is_abbreviated; + if (!rest) + continue; + } + if (*rest) { + if (*rest != '=') + continue; + p->opt = rest + 1; + } + return get_value(p, options, flags); + } + + if (ambiguous_option) + return error("Ambiguous option: %s " + "(could be --%s%s or --%s%s)", + arg, + (ambiguous_flags & OPT_UNSET) ? "no-" : "", + ambiguous_option->long_name, + (abbrev_flags & OPT_UNSET) ? "no-" : "", + abbrev_option->long_name); + if (abbrev_option) + return get_value(p, abbrev_option, abbrev_flags); + return -2; +} + +static void check_typos(const char *arg, const struct option *options) +{ + if (strlen(arg) < 3) + return; + + if (!prefixcmp(arg, "no-")) { + error ("did you mean `--%s` (with two dashes ?)", arg); + exit(129); + } + + for (; options->type != OPTION_END; options++) { + if (!options->long_name) + continue; + if (!prefixcmp(options->long_name, arg)) { + error ("did you mean `--%s` (with two dashes ?)", arg); + exit(129); + } + } +} + +void parse_options_start(struct parse_opt_ctx_t *ctx, + int argc, const char **argv, int flags) +{ + memset(ctx, 0, sizeof(*ctx)); + ctx->argc = argc - 1; + ctx->argv = argv + 1; + ctx->out = argv; + ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0); + ctx->flags = flags; + if ((flags & PARSE_OPT_KEEP_UNKNOWN) && + (flags & PARSE_OPT_STOP_AT_NON_OPTION)) + die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together"); +} + +static int usage_with_options_internal(const char * const *, + const struct option *, int); + +int parse_options_step(struct parse_opt_ctx_t *ctx, + const struct option *options, + const char * const usagestr[]) +{ + int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); + + /* we must reset ->opt, unknown short option leave it dangling */ + ctx->opt = NULL; + + for (; ctx->argc; ctx->argc--, ctx->argv++) { + const char *arg = ctx->argv[0]; + + if (*arg != '-' || !arg[1]) { + if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION) + break; + ctx->out[ctx->cpidx++] = ctx->argv[0]; + continue; + } + + if (arg[1] != '-') { + ctx->opt = arg + 1; + if (internal_help && *ctx->opt == 'h') + return parse_options_usage(usagestr, options); + switch (parse_short_opt(ctx, options)) { + case -1: + return parse_options_usage(usagestr, options); + case -2: + goto unknown; + } + if (ctx->opt) + check_typos(arg + 1, options); + while (ctx->opt) { + if (internal_help && *ctx->opt == 'h') + return parse_options_usage(usagestr, options); + switch (parse_short_opt(ctx, options)) { + case -1: + return parse_options_usage(usagestr, options); + case -2: + /* fake a short option thing to hide the fact that we may have + * started to parse aggregated stuff + * + * This is leaky, too bad. + */ + ctx->argv[0] = strdup(ctx->opt - 1); + *(char *)ctx->argv[0] = '-'; + goto unknown; + } + } + continue; + } + + if (!arg[2]) { /* "--" */ + if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) { + ctx->argc--; + ctx->argv++; + } + break; + } + + if (internal_help && !strcmp(arg + 2, "help-all")) + return usage_with_options_internal(usagestr, options, 1); + if (internal_help && !strcmp(arg + 2, "help")) + return parse_options_usage(usagestr, options); + switch (parse_long_opt(ctx, arg + 2, options)) { + case -1: + return parse_options_usage(usagestr, options); + case -2: + goto unknown; + } + continue; +unknown: + if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN)) + return PARSE_OPT_UNKNOWN; + ctx->out[ctx->cpidx++] = ctx->argv[0]; + ctx->opt = NULL; + } + return PARSE_OPT_DONE; +} + +int parse_options_end(struct parse_opt_ctx_t *ctx) +{ + memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out)); + ctx->out[ctx->cpidx + ctx->argc] = NULL; + return ctx->cpidx + ctx->argc; +} + +int parse_options(int argc, const char **argv, const struct option *options, + const char * const usagestr[], int flags) +{ + struct parse_opt_ctx_t ctx; + + parse_options_start(&ctx, argc, argv, flags); + switch (parse_options_step(&ctx, options, usagestr)) { + case PARSE_OPT_HELP: + exit(129); + case PARSE_OPT_DONE: + break; + default: /* PARSE_OPT_UNKNOWN */ + if (ctx.argv[0][1] == '-') { + error("unknown option `%s'", ctx.argv[0] + 2); + } else { + error("unknown switch `%c'", *ctx.opt); + } + usage_with_options(usagestr, options); + } + + return parse_options_end(&ctx); +} + +#define USAGE_OPTS_WIDTH 24 +#define USAGE_GAP 2 + +int usage_with_options_internal(const char * const *usagestr, + const struct option *opts, int full) +{ + if (!usagestr) + return PARSE_OPT_HELP; + + fprintf(stderr, "usage: %s\n", *usagestr++); + while (*usagestr && **usagestr) + fprintf(stderr, " or: %s\n", *usagestr++); + while (*usagestr) { + fprintf(stderr, "%s%s\n", + **usagestr ? " " : "", + *usagestr); + usagestr++; + } + + if (opts->type != OPTION_GROUP) + fputc('\n', stderr); + + for (; opts->type != OPTION_END; opts++) { + size_t pos; + int pad; + + if (opts->type == OPTION_GROUP) { + fputc('\n', stderr); + if (*opts->help) + fprintf(stderr, "%s\n", opts->help); + continue; + } + if (!full && (opts->flags & PARSE_OPT_HIDDEN)) + continue; + + pos = fprintf(stderr, " "); + if (opts->short_name) + pos += fprintf(stderr, "-%c", opts->short_name); + if (opts->long_name && opts->short_name) + pos += fprintf(stderr, ", "); + if (opts->long_name) + pos += fprintf(stderr, "--%s", opts->long_name); + + switch (opts->type) { + case OPTION_ARGUMENT: + break; + case OPTION_INTEGER: + if (opts->flags & PARSE_OPT_OPTARG) + if (opts->long_name) + pos += fprintf(stderr, "[=]"); + else + pos += fprintf(stderr, "[]"); + else + pos += fprintf(stderr, " "); + break; + case OPTION_CALLBACK: + if (opts->flags & PARSE_OPT_NOARG) + break; + /* FALLTHROUGH */ + case OPTION_STRING: + if (opts->argh) { + if (opts->flags & PARSE_OPT_OPTARG) + if (opts->long_name) + pos += fprintf(stderr, "[=<%s>]", opts->argh); + else + pos += fprintf(stderr, "[<%s>]", opts->argh); + else + pos += fprintf(stderr, " <%s>", opts->argh); + } else { + if (opts->flags & PARSE_OPT_OPTARG) + if (opts->long_name) + pos += fprintf(stderr, "[=...]"); + else + pos += fprintf(stderr, "[...]"); + else + pos += fprintf(stderr, " ..."); + } + break; + default: /* OPTION_{BIT,BOOLEAN,SET_INT,SET_PTR} */ + break; + } + + if (pos <= USAGE_OPTS_WIDTH) + pad = USAGE_OPTS_WIDTH - pos; + else { + fputc('\n', stderr); + pad = USAGE_OPTS_WIDTH; + } + fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help); + } + fputc('\n', stderr); + + return PARSE_OPT_HELP; +} + +void usage_with_options(const char * const *usagestr, + const struct option *opts) +{ + usage_with_options_internal(usagestr, opts, 0); + exit(129); +} + +int parse_options_usage(const char * const *usagestr, + const struct option *opts) +{ + return usage_with_options_internal(usagestr, opts, 0); +} + + +/*----- some often used options -----*/ +#include "cache.h" + +int parse_opt_verbosity_cb(const struct option *opt, const char *arg, + int unset) +{ + int *target = opt->value; + + if (unset) + /* --no-quiet, --no-verbose */ + *target = 0; + else if (opt->short_name == 'v') { + if (*target >= 0) + (*target)++; + else + *target = 1; + } else { + if (*target <= 0) + (*target)--; + else + *target = -1; + } + return 0; +} diff --git a/Documentation/perf_counter/parse-options.h b/Documentation/perf_counter/parse-options.h new file mode 100644 index 000000000000..a81c7faff68e --- /dev/null +++ b/Documentation/perf_counter/parse-options.h @@ -0,0 +1,172 @@ +#ifndef PARSE_OPTIONS_H +#define PARSE_OPTIONS_H + +enum parse_opt_type { + /* special types */ + OPTION_END, + OPTION_ARGUMENT, + OPTION_GROUP, + /* options with no arguments */ + OPTION_BIT, + OPTION_BOOLEAN, /* _INCR would have been a better name */ + OPTION_SET_INT, + OPTION_SET_PTR, + /* options with arguments (usually) */ + OPTION_STRING, + OPTION_INTEGER, + OPTION_CALLBACK, +}; + +enum parse_opt_flags { + PARSE_OPT_KEEP_DASHDASH = 1, + PARSE_OPT_STOP_AT_NON_OPTION = 2, + PARSE_OPT_KEEP_ARGV0 = 4, + PARSE_OPT_KEEP_UNKNOWN = 8, + PARSE_OPT_NO_INTERNAL_HELP = 16, +}; + +enum parse_opt_option_flags { + PARSE_OPT_OPTARG = 1, + PARSE_OPT_NOARG = 2, + PARSE_OPT_NONEG = 4, + PARSE_OPT_HIDDEN = 8, + PARSE_OPT_LASTARG_DEFAULT = 16, +}; + +struct option; +typedef int parse_opt_cb(const struct option *, const char *arg, int unset); + +/* + * `type`:: + * holds the type of the option, you must have an OPTION_END last in your + * array. + * + * `short_name`:: + * the character to use as a short option name, '\0' if none. + * + * `long_name`:: + * the long option name, without the leading dashes, NULL if none. + * + * `value`:: + * stores pointers to the values to be filled. + * + * `argh`:: + * token to explain the kind of argument this option wants. Keep it + * homogenous across the repository. + * + * `help`:: + * the short help associated to what the option does. + * Must never be NULL (except for OPTION_END). + * OPTION_GROUP uses this pointer to store the group header. + * + * `flags`:: + * mask of parse_opt_option_flags. + * PARSE_OPT_OPTARG: says that the argument is optionnal (not for BOOLEANs) + * PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs + * PARSE_OPT_NONEG: says that this option cannot be negated + * PARSE_OPT_HIDDEN this option is skipped in the default usage, showed in + * the long one. + * + * `callback`:: + * pointer to the callback to use for OPTION_CALLBACK. + * + * `defval`:: + * default value to fill (*->value) with for PARSE_OPT_OPTARG. + * OPTION_{BIT,SET_INT,SET_PTR} store the {mask,integer,pointer} to put in + * the value when met. + * CALLBACKS can use it like they want. + */ +struct option { + enum parse_opt_type type; + int short_name; + const char *long_name; + void *value; + const char *argh; + const char *help; + + int flags; + parse_opt_cb *callback; + intptr_t defval; +}; + +#define OPT_END() { OPTION_END } +#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) } +#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) } +#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) } +#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) } +#define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, (h), 0, NULL, (i) } +#define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) } +#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), NULL, (h) } +#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) } +#define OPT_DATE(s, l, v, h) \ + { OPTION_CALLBACK, (s), (l), (v), "time",(h), 0, \ + parse_opt_approxidate_cb } +#define OPT_CALLBACK(s, l, v, a, h, f) \ + { OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) } + +/* parse_options() will filter out the processed options and leave the + * non-option argments in argv[]. + * Returns the number of arguments left in argv[]. + */ +extern int parse_options(int argc, const char **argv, + const struct option *options, + const char * const usagestr[], int flags); + +extern NORETURN void usage_with_options(const char * const *usagestr, + const struct option *options); + +/*----- incremantal advanced APIs -----*/ + +enum { + PARSE_OPT_HELP = -1, + PARSE_OPT_DONE, + PARSE_OPT_UNKNOWN, +}; + +/* + * It's okay for the caller to consume argv/argc in the usual way. + * Other fields of that structure are private to parse-options and should not + * be modified in any way. + */ +struct parse_opt_ctx_t { + const char **argv; + const char **out; + int argc, cpidx; + const char *opt; + int flags; +}; + +extern int parse_options_usage(const char * const *usagestr, + const struct option *opts); + +extern void parse_options_start(struct parse_opt_ctx_t *ctx, + int argc, const char **argv, int flags); + +extern int parse_options_step(struct parse_opt_ctx_t *ctx, + const struct option *options, + const char * const usagestr[]); + +extern int parse_options_end(struct parse_opt_ctx_t *ctx); + + +/*----- some often used options -----*/ +extern int parse_opt_abbrev_cb(const struct option *, const char *, int); +extern int parse_opt_approxidate_cb(const struct option *, const char *, int); +extern int parse_opt_verbosity_cb(const struct option *, const char *, int); + +#define OPT__VERBOSE(var) OPT_BOOLEAN('v', "verbose", (var), "be verbose") +#define OPT__QUIET(var) OPT_BOOLEAN('q', "quiet", (var), "be quiet") +#define OPT__VERBOSITY(var) \ + { OPTION_CALLBACK, 'v', "verbose", (var), NULL, "be more verbose", \ + PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \ + { OPTION_CALLBACK, 'q', "quiet", (var), NULL, "be more quiet", \ + PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 } +#define OPT__DRY_RUN(var) OPT_BOOLEAN('n', "dry-run", (var), "dry run") +#define OPT__ABBREV(var) \ + { OPTION_CALLBACK, 0, "abbrev", (var), "n", \ + "use digits to display SHA-1s", \ + PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 } + +extern const char *parse_options_fix_filename(const char *prefix, const char *file); + +#endif diff --git a/Documentation/perf_counter/path.c b/Documentation/perf_counter/path.c new file mode 100644 index 000000000000..891b612ec1a9 --- /dev/null +++ b/Documentation/perf_counter/path.c @@ -0,0 +1,392 @@ +/* + * I'm tired of doing "vsnprintf()" etc just to open a + * file, so here's a "return static buffer with printf" + * interface for paths. + * + * It's obviously not thread-safe. Sue me. But it's quite + * useful for doing things like + * + * f = open(mkpath("%s/%s.perf", base, name), O_RDONLY); + * + * which is what it's designed for. + */ +#include "cache.h" + +static char bad_path[] = "/bad-path/"; +/* + * Two hacks: + */ + +static char *get_perf_dir(void) +{ + return "."; +} + +size_t strlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = strlen(src); + + if (size) { + size_t len = (ret >= size) ? size - 1 : ret; + memcpy(dest, src, len); + dest[len] = '\0'; + } + return ret; +} + + +static char *get_pathname(void) +{ + static char pathname_array[4][PATH_MAX]; + static int index; + return pathname_array[3 & ++index]; +} + +static char *cleanup_path(char *path) +{ + /* Clean it up */ + if (!memcmp(path, "./", 2)) { + path += 2; + while (*path == '/') + path++; + } + return path; +} + +char *mksnpath(char *buf, size_t n, const char *fmt, ...) +{ + va_list args; + unsigned len; + + va_start(args, fmt); + len = vsnprintf(buf, n, fmt, args); + va_end(args); + if (len >= n) { + strlcpy(buf, bad_path, n); + return buf; + } + return cleanup_path(buf); +} + +static char *perf_vsnpath(char *buf, size_t n, const char *fmt, va_list args) +{ + const char *perf_dir = get_perf_dir(); + size_t len; + + len = strlen(perf_dir); + if (n < len + 1) + goto bad; + memcpy(buf, perf_dir, len); + if (len && !is_dir_sep(perf_dir[len-1])) + buf[len++] = '/'; + len += vsnprintf(buf + len, n - len, fmt, args); + if (len >= n) + goto bad; + return cleanup_path(buf); +bad: + strlcpy(buf, bad_path, n); + return buf; +} + +char *perf_snpath(char *buf, size_t n, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + (void)perf_vsnpath(buf, n, fmt, args); + va_end(args); + return buf; +} + +char *perf_pathdup(const char *fmt, ...) +{ + char path[PATH_MAX]; + va_list args; + va_start(args, fmt); + (void)perf_vsnpath(path, sizeof(path), fmt, args); + va_end(args); + return xstrdup(path); +} + +char *mkpath(const char *fmt, ...) +{ + va_list args; + unsigned len; + char *pathname = get_pathname(); + + va_start(args, fmt); + len = vsnprintf(pathname, PATH_MAX, fmt, args); + va_end(args); + if (len >= PATH_MAX) + return bad_path; + return cleanup_path(pathname); +} + +char *perf_path(const char *fmt, ...) +{ + const char *perf_dir = get_perf_dir(); + char *pathname = get_pathname(); + va_list args; + unsigned len; + + len = strlen(perf_dir); + if (len > PATH_MAX-100) + return bad_path; + memcpy(pathname, perf_dir, len); + if (len && perf_dir[len-1] != '/') + pathname[len++] = '/'; + va_start(args, fmt); + len += vsnprintf(pathname + len, PATH_MAX - len, fmt, args); + va_end(args); + if (len >= PATH_MAX) + return bad_path; + return cleanup_path(pathname); +} + + +/* perf_mkstemp() - create tmp file honoring TMPDIR variable */ +int perf_mkstemp(char *path, size_t len, const char *template) +{ + const char *tmp; + size_t n; + + tmp = getenv("TMPDIR"); + if (!tmp) + tmp = "/tmp"; + n = snprintf(path, len, "%s/%s", tmp, template); + if (len <= n) { + errno = ENAMETOOLONG; + return -1; + } + return mkstemp(path); +} + + +static char *user_path(char *buf, char *path, int sz) +{ + struct passwd *pw; + char *slash; + int len, baselen; + + if (!path || path[0] != '~') + return NULL; + path++; + slash = strchr(path, '/'); + if (path[0] == '/' || !path[0]) { + pw = getpwuid(getuid()); + } + else { + if (slash) { + *slash = 0; + pw = getpwnam(path); + *slash = '/'; + } + else + pw = getpwnam(path); + } + if (!pw || !pw->pw_dir || sz <= strlen(pw->pw_dir)) + return NULL; + baselen = strlen(pw->pw_dir); + memcpy(buf, pw->pw_dir, baselen); + while ((1 < baselen) && (buf[baselen-1] == '/')) { + buf[baselen-1] = 0; + baselen--; + } + if (slash && slash[1]) { + len = strlen(slash); + if (sz <= baselen + len) + return NULL; + memcpy(buf + baselen, slash, len + 1); + } + return buf; +} + +const char *make_relative_path(const char *abs, const char *base) +{ + static char buf[PATH_MAX + 1]; + int baselen; + if (!base) + return abs; + baselen = strlen(base); + if (prefixcmp(abs, base)) + return abs; + if (abs[baselen] == '/') + baselen++; + else if (base[baselen - 1] != '/') + return abs; + strcpy(buf, abs + baselen); + return buf; +} + +/* + * It is okay if dst == src, but they should not overlap otherwise. + * + * Performs the following normalizations on src, storing the result in dst: + * - Ensures that components are separated by '/' (Windows only) + * - Squashes sequences of '/'. + * - Removes "." components. + * - Removes ".." components, and the components the precede them. + * Returns failure (non-zero) if a ".." component appears as first path + * component anytime during the normalization. Otherwise, returns success (0). + * + * Note that this function is purely textual. It does not follow symlinks, + * verify the existence of the path, or make any system calls. + */ +int normalize_path_copy(char *dst, const char *src) +{ + char *dst0; + + if (has_dos_drive_prefix(src)) { + *dst++ = *src++; + *dst++ = *src++; + } + dst0 = dst; + + if (is_dir_sep(*src)) { + *dst++ = '/'; + while (is_dir_sep(*src)) + src++; + } + + for (;;) { + char c = *src; + + /* + * A path component that begins with . could be + * special: + * (1) "." and ends -- ignore and terminate. + * (2) "./" -- ignore them, eat slash and continue. + * (3) ".." and ends -- strip one and terminate. + * (4) "../" -- strip one, eat slash and continue. + */ + if (c == '.') { + if (!src[1]) { + /* (1) */ + src++; + } else if (is_dir_sep(src[1])) { + /* (2) */ + src += 2; + while (is_dir_sep(*src)) + src++; + continue; + } else if (src[1] == '.') { + if (!src[2]) { + /* (3) */ + src += 2; + goto up_one; + } else if (is_dir_sep(src[2])) { + /* (4) */ + src += 3; + while (is_dir_sep(*src)) + src++; + goto up_one; + } + } + } + + /* copy up to the next '/', and eat all '/' */ + while ((c = *src++) != '\0' && !is_dir_sep(c)) + *dst++ = c; + if (is_dir_sep(c)) { + *dst++ = '/'; + while (is_dir_sep(c)) + c = *src++; + src--; + } else if (!c) + break; + continue; + + up_one: + /* + * dst0..dst is prefix portion, and dst[-1] is '/'; + * go up one level. + */ + dst--; /* go to trailing '/' */ + if (dst <= dst0) + return -1; + /* Windows: dst[-1] cannot be backslash anymore */ + while (dst0 < dst && dst[-1] != '/') + dst--; + } + *dst = '\0'; + return 0; +} + +/* + * path = Canonical absolute path + * prefix_list = Colon-separated list of absolute paths + * + * Determines, for each path in prefix_list, whether the "prefix" really + * is an ancestor directory of path. Returns the length of the longest + * ancestor directory, excluding any trailing slashes, or -1 if no prefix + * is an ancestor. (Note that this means 0 is returned if prefix_list is + * "/".) "/foo" is not considered an ancestor of "/foobar". Directories + * are not considered to be their own ancestors. path must be in a + * canonical form: empty components, or "." or ".." components are not + * allowed. prefix_list may be null, which is like "". + */ +int longest_ancestor_length(const char *path, const char *prefix_list) +{ + char buf[PATH_MAX+1]; + const char *ceil, *colon; + int len, max_len = -1; + + if (prefix_list == NULL || !strcmp(path, "/")) + return -1; + + for (colon = ceil = prefix_list; *colon; ceil = colon+1) { + for (colon = ceil; *colon && *colon != PATH_SEP; colon++); + len = colon - ceil; + if (len == 0 || len > PATH_MAX || !is_absolute_path(ceil)) + continue; + strlcpy(buf, ceil, len+1); + if (normalize_path_copy(buf, buf) < 0) + continue; + len = strlen(buf); + if (len > 0 && buf[len-1] == '/') + buf[--len] = '\0'; + + if (!strncmp(path, buf, len) && + path[len] == '/' && + len > max_len) { + max_len = len; + } + } + + return max_len; +} + +/* strip arbitrary amount of directory separators at end of path */ +static inline int chomp_trailing_dir_sep(const char *path, int len) +{ + while (len && is_dir_sep(path[len - 1])) + len--; + return len; +} + +/* + * If path ends with suffix (complete path components), returns the + * part before suffix (sans trailing directory separators). + * Otherwise returns NULL. + */ +char *strip_path_suffix(const char *path, const char *suffix) +{ + int path_len = strlen(path), suffix_len = strlen(suffix); + + while (suffix_len) { + if (!path_len) + return NULL; + + if (is_dir_sep(path[path_len - 1])) { + if (!is_dir_sep(suffix[suffix_len - 1])) + return NULL; + path_len = chomp_trailing_dir_sep(path, path_len); + suffix_len = chomp_trailing_dir_sep(suffix, suffix_len); + } + else if (path[--path_len] != suffix[--suffix_len]) + return NULL; + } + + if (path_len && !is_dir_sep(path[path_len - 1])) + return NULL; + return xstrndup(path, chomp_trailing_dir_sep(path, path_len)); +} diff --git a/Documentation/perf_counter/perf.c b/Documentation/perf_counter/perf.c new file mode 100644 index 000000000000..9256f6a16446 --- /dev/null +++ b/Documentation/perf_counter/perf.c @@ -0,0 +1,411 @@ +#include "builtin.h" +#include "exec_cmd.h" +#include "cache.h" +//#include "quote.h" +#include "run-command.h" + +const char perf_usage_string[] = + "perf [--version] [--exec-path[=PERF_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--bare] [--perf-dir=PERF_DIR] [--work-tree=PERF_WORK_TREE] [--help] COMMAND [ARGS]"; + +const char perf_more_info_string[] = + "See 'perf help COMMAND' for more information on a specific command."; + +static int use_pager = -1; +struct pager_config { + const char *cmd; + int val; +}; + +static int pager_command_config(const char *var, const char *value, void *data) +{ + struct pager_config *c = data; + if (!prefixcmp(var, "pager.") && !strcmp(var + 6, c->cmd)) + c->val = perf_config_bool(var, value); + return 0; +} + +/* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ +int check_pager_config(const char *cmd) +{ + struct pager_config c; + c.cmd = cmd; + c.val = -1; + perf_config(pager_command_config, &c); + return c.val; +} + +static void commit_pager_choice(void) { + switch (use_pager) { + case 0: + setenv("PERF_PAGER", "cat", 1); + break; + case 1: + /* setup_pager(); */ + break; + default: + break; + } +} + +static int handle_options(const char*** argv, int* argc, int* envchanged) +{ + int handled = 0; + + while (*argc > 0) { + const char *cmd = (*argv)[0]; + if (cmd[0] != '-') + break; + + /* + * For legacy reasons, the "version" and "help" + * commands can be written with "--" prepended + * to make them look like flags. + */ + if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version")) + break; + + /* + * Check remaining flags. + */ + if (!prefixcmp(cmd, "--exec-path")) { + cmd += 11; + if (*cmd == '=') + perf_set_argv_exec_path(cmd + 1); + else { + puts(perf_exec_path()); + exit(0); + } + } else if (!strcmp(cmd, "--html-path")) { + puts(system_path(PERF_HTML_PATH)); + exit(0); + } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) { + use_pager = 1; + } else if (!strcmp(cmd, "--no-pager")) { + use_pager = 0; + if (envchanged) + *envchanged = 1; + } else if (!strcmp(cmd, "--perf-dir")) { + if (*argc < 2) { + fprintf(stderr, "No directory given for --perf-dir.\n" ); + usage(perf_usage_string); + } + setenv(PERF_DIR_ENVIRONMENT, (*argv)[1], 1); + if (envchanged) + *envchanged = 1; + (*argv)++; + (*argc)--; + handled++; + } else if (!prefixcmp(cmd, "--perf-dir=")) { + setenv(PERF_DIR_ENVIRONMENT, cmd + 10, 1); + if (envchanged) + *envchanged = 1; + } else if (!strcmp(cmd, "--work-tree")) { + if (*argc < 2) { + fprintf(stderr, "No directory given for --work-tree.\n" ); + usage(perf_usage_string); + } + setenv(PERF_WORK_TREE_ENVIRONMENT, (*argv)[1], 1); + if (envchanged) + *envchanged = 1; + (*argv)++; + (*argc)--; + } else if (!prefixcmp(cmd, "--work-tree=")) { + setenv(PERF_WORK_TREE_ENVIRONMENT, cmd + 12, 1); + if (envchanged) + *envchanged = 1; + } else { + fprintf(stderr, "Unknown option: %s\n", cmd); + usage(perf_usage_string); + } + + (*argv)++; + (*argc)--; + handled++; + } + return handled; +} + +static int handle_alias(int *argcp, const char ***argv) +{ + int envchanged = 0, ret = 0, saved_errno = errno; + int count, option_count; + const char** new_argv; + const char *alias_command; + char *alias_string; + int unused_nonperf; + + alias_command = (*argv)[0]; + alias_string = alias_lookup(alias_command); + if (alias_string) { + if (alias_string[0] == '!') { + if (*argcp > 1) { + struct strbuf buf; + + strbuf_init(&buf, PATH_MAX); + strbuf_addstr(&buf, alias_string); + sq_quote_argv(&buf, (*argv) + 1, PATH_MAX); + free(alias_string); + alias_string = buf.buf; + } + ret = system(alias_string + 1); + if (ret >= 0 && WIFEXITED(ret) && + WEXITSTATUS(ret) != 127) + exit(WEXITSTATUS(ret)); + die("Failed to run '%s' when expanding alias '%s'", + alias_string + 1, alias_command); + } + count = split_cmdline(alias_string, &new_argv); + if (count < 0) + die("Bad alias.%s string", alias_command); + option_count = handle_options(&new_argv, &count, &envchanged); + if (envchanged) + die("alias '%s' changes environment variables\n" + "You can use '!perf' in the alias to do this.", + alias_command); + memmove(new_argv - option_count, new_argv, + count * sizeof(char *)); + new_argv -= option_count; + + if (count < 1) + die("empty alias for %s", alias_command); + + if (!strcmp(alias_command, new_argv[0])) + die("recursive alias: %s", alias_command); + + new_argv = realloc(new_argv, sizeof(char*) * + (count + *argcp + 1)); + /* insert after command name */ + memcpy(new_argv + count, *argv + 1, sizeof(char*) * *argcp); + new_argv[count+*argcp] = NULL; + + *argv = new_argv; + *argcp += count - 1; + + ret = 1; + } + + errno = saved_errno; + + return ret; +} + +const char perf_version_string[] = PERF_VERSION; + +#define RUN_SETUP (1<<0) +#define USE_PAGER (1<<1) +/* + * require working tree to be present -- anything uses this needs + * RUN_SETUP for reading from the configuration file. + */ +#define NEED_WORK_TREE (1<<2) + +struct cmd_struct { + const char *cmd; + int (*fn)(int, const char **, const char *); + int option; +}; + +static int run_builtin(struct cmd_struct *p, int argc, const char **argv) +{ + int status; + struct stat st; + const char *prefix; + + prefix = NULL; + if (p->option & RUN_SETUP) + prefix = NULL; /* setup_perf_directory(); */ + + if (use_pager == -1 && p->option & RUN_SETUP) + use_pager = check_pager_config(p->cmd); + if (use_pager == -1 && p->option & USE_PAGER) + use_pager = 1; + commit_pager_choice(); + + if (p->option & NEED_WORK_TREE) + /* setup_work_tree() */; + + status = p->fn(argc, argv, prefix); + if (status) + return status & 0xff; + + /* Somebody closed stdout? */ + if (fstat(fileno(stdout), &st)) + return 0; + /* Ignore write errors for pipes and sockets.. */ + if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) + return 0; + + /* Check for ENOSPC and EIO errors.. */ + if (fflush(stdout)) + die("write failure on standard output: %s", strerror(errno)); + if (ferror(stdout)) + die("unknown write failure on standard output"); + if (fclose(stdout)) + die("close failed on standard output: %s", strerror(errno)); + return 0; +} + +static void handle_internal_command(int argc, const char **argv) +{ + const char *cmd = argv[0]; + static struct cmd_struct commands[] = { + { "top", cmd_top, 0 }, + }; + int i; + static const char ext[] = STRIP_EXTENSION; + + if (sizeof(ext) > 1) { + i = strlen(argv[0]) - strlen(ext); + if (i > 0 && !strcmp(argv[0] + i, ext)) { + char *argv0 = strdup(argv[0]); + argv[0] = cmd = argv0; + argv0[i] = '\0'; + } + } + + /* Turn "perf cmd --help" into "perf help cmd" */ + if (argc > 1 && !strcmp(argv[1], "--help")) { + argv[1] = argv[0]; + argv[0] = cmd = "help"; + } + + for (i = 0; i < ARRAY_SIZE(commands); i++) { + struct cmd_struct *p = commands+i; + if (strcmp(p->cmd, cmd)) + continue; + exit(run_builtin(p, argc, argv)); + } +} + +static void execv_dashed_external(const char **argv) +{ + struct strbuf cmd = STRBUF_INIT; + const char *tmp; + int status; + + strbuf_addf(&cmd, "perf-%s", argv[0]); + + /* + * argv[0] must be the perf command, but the argv array + * belongs to the caller, and may be reused in + * subsequent loop iterations. Save argv[0] and + * restore it on error. + */ + tmp = argv[0]; + argv[0] = cmd.buf; + + /* + * if we fail because the command is not found, it is + * OK to return. Otherwise, we just pass along the status code. + */ + status = run_command_v_opt(argv, 0); + if (status != -ERR_RUN_COMMAND_EXEC) { + if (IS_RUN_COMMAND_ERR(status)) + die("unable to run '%s'", argv[0]); + exit(-status); + } + errno = ENOENT; /* as if we called execvp */ + + argv[0] = tmp; + + strbuf_release(&cmd); +} + +static int run_argv(int *argcp, const char ***argv) +{ + int done_alias = 0; + + while (1) { + /* See if it's an internal command */ + handle_internal_command(*argcp, *argv); + + /* .. then try the external ones */ + execv_dashed_external(*argv); + + /* It could be an alias -- this works around the insanity + * of overriding "perf log" with "perf show" by having + * alias.log = show + */ + if (done_alias || !handle_alias(argcp, argv)) + break; + done_alias = 1; + } + + return done_alias; +} + + +int main(int argc, const char **argv) +{ + const char *cmd; + + cmd = perf_extract_argv0_path(argv[0]); + if (!cmd) + cmd = "perf-help"; + + /* + * "perf-xxxx" is the same as "perf xxxx", but we obviously: + * + * - cannot take flags in between the "perf" and the "xxxx". + * - cannot execute it externally (since it would just do + * the same thing over again) + * + * So we just directly call the internal command handler, and + * die if that one cannot handle it. + */ + if (!prefixcmp(cmd, "perf-")) { + cmd += 4; + argv[0] = cmd; + handle_internal_command(argc, argv); + die("cannot handle %s internally", cmd); + } + + /* Look for flags.. */ + argv++; + argc--; + handle_options(&argv, &argc, NULL); + commit_pager_choice(); + if (argc > 0) { + if (!prefixcmp(argv[0], "--")) + argv[0] += 2; + } else { + /* The user didn't specify a command; give them help */ + printf("usage: %s\n\n", perf_usage_string); + list_common_cmds_help(); + printf("\n%s\n", perf_more_info_string); + exit(1); + } + cmd = argv[0]; + + /* + * We use PATH to find perf commands, but we prepend some higher + * precidence paths: the "--exec-path" option, the PERF_EXEC_PATH + * environment, and the $(perfexecdir) from the Makefile at build + * time. + */ + setup_path(); + + while (1) { + static int done_help = 0; + static int was_alias = 0; + was_alias = run_argv(&argc, &argv); + if (errno != ENOENT) + break; + if (was_alias) { + fprintf(stderr, "Expansion of alias '%s' failed; " + "'%s' is not a perf-command\n", + cmd, argv[0]); + exit(1); + } + if (!done_help) { + cmd = argv[0] = help_unknown_cmd(cmd); + done_help = 1; + } else + break; + } + + fprintf(stderr, "Failed to run command '%s': %s\n", + cmd, strerror(errno)); + + return 1; +} diff --git a/Documentation/perf_counter/quote.c b/Documentation/perf_counter/quote.c new file mode 100644 index 000000000000..7a49fcf69671 --- /dev/null +++ b/Documentation/perf_counter/quote.c @@ -0,0 +1,478 @@ +#include "cache.h" +#include "quote.h" + +int quote_path_fully = 1; + +/* Help to copy the thing properly quoted for the shell safety. + * any single quote is replaced with '\'', any exclamation point + * is replaced with '\!', and the whole thing is enclosed in a + * + * E.g. + * original sq_quote result + * name ==> name ==> 'name' + * a b ==> a b ==> 'a b' + * a'b ==> a'\''b ==> 'a'\''b' + * a!b ==> a'\!'b ==> 'a'\!'b' + */ +static inline int need_bs_quote(char c) +{ + return (c == '\'' || c == '!'); +} + +void sq_quote_buf(struct strbuf *dst, const char *src) +{ + char *to_free = NULL; + + if (dst->buf == src) + to_free = strbuf_detach(dst, NULL); + + strbuf_addch(dst, '\''); + while (*src) { + size_t len = strcspn(src, "'!"); + strbuf_add(dst, src, len); + src += len; + while (need_bs_quote(*src)) { + strbuf_addstr(dst, "'\\"); + strbuf_addch(dst, *src++); + strbuf_addch(dst, '\''); + } + } + strbuf_addch(dst, '\''); + free(to_free); +} + +void sq_quote_print(FILE *stream, const char *src) +{ + char c; + + fputc('\'', stream); + while ((c = *src++)) { + if (need_bs_quote(c)) { + fputs("'\\", stream); + fputc(c, stream); + fputc('\'', stream); + } else { + fputc(c, stream); + } + } + fputc('\'', stream); +} + +void sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen) +{ + int i; + + /* Copy into destination buffer. */ + strbuf_grow(dst, 255); + for (i = 0; argv[i]; ++i) { + strbuf_addch(dst, ' '); + sq_quote_buf(dst, argv[i]); + if (maxlen && dst->len > maxlen) + die("Too many or long arguments"); + } +} + +char *sq_dequote_step(char *arg, char **next) +{ + char *dst = arg; + char *src = arg; + char c; + + if (*src != '\'') + return NULL; + for (;;) { + c = *++src; + if (!c) + return NULL; + if (c != '\'') { + *dst++ = c; + continue; + } + /* We stepped out of sq */ + switch (*++src) { + case '\0': + *dst = 0; + if (next) + *next = NULL; + return arg; + case '\\': + c = *++src; + if (need_bs_quote(c) && *++src == '\'') { + *dst++ = c; + continue; + } + /* Fallthrough */ + default: + if (!next || !isspace(*src)) + return NULL; + do { + c = *++src; + } while (isspace(c)); + *dst = 0; + *next = src; + return arg; + } + } +} + +char *sq_dequote(char *arg) +{ + return sq_dequote_step(arg, NULL); +} + +int sq_dequote_to_argv(char *arg, const char ***argv, int *nr, int *alloc) +{ + char *next = arg; + + if (!*arg) + return 0; + do { + char *dequoted = sq_dequote_step(next, &next); + if (!dequoted) + return -1; + ALLOC_GROW(*argv, *nr + 1, *alloc); + (*argv)[(*nr)++] = dequoted; + } while (next); + + return 0; +} + +/* 1 means: quote as octal + * 0 means: quote as octal if (quote_path_fully) + * -1 means: never quote + * c: quote as "\\c" + */ +#define X8(x) x, x, x, x, x, x, x, x +#define X16(x) X8(x), X8(x) +static signed char const sq_lookup[256] = { + /* 0 1 2 3 4 5 6 7 */ + /* 0x00 */ 1, 1, 1, 1, 1, 1, 1, 'a', + /* 0x08 */ 'b', 't', 'n', 'v', 'f', 'r', 1, 1, + /* 0x10 */ X16(1), + /* 0x20 */ -1, -1, '"', -1, -1, -1, -1, -1, + /* 0x28 */ X16(-1), X16(-1), X16(-1), + /* 0x58 */ -1, -1, -1, -1,'\\', -1, -1, -1, + /* 0x60 */ X16(-1), X8(-1), + /* 0x78 */ -1, -1, -1, -1, -1, -1, -1, 1, + /* 0x80 */ /* set to 0 */ +}; + +static inline int sq_must_quote(char c) +{ + return sq_lookup[(unsigned char)c] + quote_path_fully > 0; +} + +/* returns the longest prefix not needing a quote up to maxlen if positive. + This stops at the first \0 because it's marked as a character needing an + escape */ +static size_t next_quote_pos(const char *s, ssize_t maxlen) +{ + size_t len; + if (maxlen < 0) { + for (len = 0; !sq_must_quote(s[len]); len++); + } else { + for (len = 0; len < maxlen && !sq_must_quote(s[len]); len++); + } + return len; +} + +/* + * C-style name quoting. + * + * (1) if sb and fp are both NULL, inspect the input name and counts the + * number of bytes that are needed to hold c_style quoted version of name, + * counting the double quotes around it but not terminating NUL, and + * returns it. + * However, if name does not need c_style quoting, it returns 0. + * + * (2) if sb or fp are not NULL, it emits the c_style quoted version + * of name, enclosed with double quotes if asked and needed only. + * Return value is the same as in (1). + */ +static size_t quote_c_style_counted(const char *name, ssize_t maxlen, + struct strbuf *sb, FILE *fp, int no_dq) +{ +#undef EMIT +#define EMIT(c) \ + do { \ + if (sb) strbuf_addch(sb, (c)); \ + if (fp) fputc((c), fp); \ + count++; \ + } while (0) +#define EMITBUF(s, l) \ + do { \ + if (sb) strbuf_add(sb, (s), (l)); \ + if (fp) fwrite((s), (l), 1, fp); \ + count += (l); \ + } while (0) + + size_t len, count = 0; + const char *p = name; + + for (;;) { + int ch; + + len = next_quote_pos(p, maxlen); + if (len == maxlen || !p[len]) + break; + + if (!no_dq && p == name) + EMIT('"'); + + EMITBUF(p, len); + EMIT('\\'); + p += len; + ch = (unsigned char)*p++; + if (sq_lookup[ch] >= ' ') { + EMIT(sq_lookup[ch]); + } else { + EMIT(((ch >> 6) & 03) + '0'); + EMIT(((ch >> 3) & 07) + '0'); + EMIT(((ch >> 0) & 07) + '0'); + } + } + + EMITBUF(p, len); + if (p == name) /* no ending quote needed */ + return 0; + + if (!no_dq) + EMIT('"'); + return count; +} + +size_t quote_c_style(const char *name, struct strbuf *sb, FILE *fp, int nodq) +{ + return quote_c_style_counted(name, -1, sb, fp, nodq); +} + +void quote_two_c_style(struct strbuf *sb, const char *prefix, const char *path, int nodq) +{ + if (quote_c_style(prefix, NULL, NULL, 0) || + quote_c_style(path, NULL, NULL, 0)) { + if (!nodq) + strbuf_addch(sb, '"'); + quote_c_style(prefix, sb, NULL, 1); + quote_c_style(path, sb, NULL, 1); + if (!nodq) + strbuf_addch(sb, '"'); + } else { + strbuf_addstr(sb, prefix); + strbuf_addstr(sb, path); + } +} + +void write_name_quoted(const char *name, FILE *fp, int terminator) +{ + if (terminator) { + quote_c_style(name, NULL, fp, 0); + } else { + fputs(name, fp); + } + fputc(terminator, fp); +} + +extern void write_name_quotedpfx(const char *pfx, size_t pfxlen, + const char *name, FILE *fp, int terminator) +{ + int needquote = 0; + + if (terminator) { + needquote = next_quote_pos(pfx, pfxlen) < pfxlen + || name[next_quote_pos(name, -1)]; + } + if (needquote) { + fputc('"', fp); + quote_c_style_counted(pfx, pfxlen, NULL, fp, 1); + quote_c_style(name, NULL, fp, 1); + fputc('"', fp); + } else { + fwrite(pfx, pfxlen, 1, fp); + fputs(name, fp); + } + fputc(terminator, fp); +} + +/* quote path as relative to the given prefix */ +char *quote_path_relative(const char *in, int len, + struct strbuf *out, const char *prefix) +{ + int needquote; + + if (len < 0) + len = strlen(in); + + /* "../" prefix itself does not need quoting, but "in" might. */ + needquote = next_quote_pos(in, len) < len; + strbuf_setlen(out, 0); + strbuf_grow(out, len); + + if (needquote) + strbuf_addch(out, '"'); + if (prefix) { + int off = 0; + while (prefix[off] && off < len && prefix[off] == in[off]) + if (prefix[off] == '/') { + prefix += off + 1; + in += off + 1; + len -= off + 1; + off = 0; + } else + off++; + + for (; *prefix; prefix++) + if (*prefix == '/') + strbuf_addstr(out, "../"); + } + + quote_c_style_counted (in, len, out, NULL, 1); + + if (needquote) + strbuf_addch(out, '"'); + if (!out->len) + strbuf_addstr(out, "./"); + + return out->buf; +} + +/* + * C-style name unquoting. + * + * Quoted should point at the opening double quote. + * + Returns 0 if it was able to unquote the string properly, and appends the + * result in the strbuf `sb'. + * + Returns -1 in case of error, and doesn't touch the strbuf. Though note + * that this function will allocate memory in the strbuf, so calling + * strbuf_release is mandatory whichever result unquote_c_style returns. + * + * Updates endp pointer to point at one past the ending double quote if given. + */ +int unquote_c_style(struct strbuf *sb, const char *quoted, const char **endp) +{ + size_t oldlen = sb->len, len; + int ch, ac; + + if (*quoted++ != '"') + return -1; + + for (;;) { + len = strcspn(quoted, "\"\\"); + strbuf_add(sb, quoted, len); + quoted += len; + + switch (*quoted++) { + case '"': + if (endp) + *endp = quoted; + return 0; + case '\\': + break; + default: + goto error; + } + + switch ((ch = *quoted++)) { + case 'a': ch = '\a'; break; + case 'b': ch = '\b'; break; + case 'f': ch = '\f'; break; + case 'n': ch = '\n'; break; + case 'r': ch = '\r'; break; + case 't': ch = '\t'; break; + case 'v': ch = '\v'; break; + + case '\\': case '"': + break; /* verbatim */ + + /* octal values with first digit over 4 overflow */ + case '0': case '1': case '2': case '3': + ac = ((ch - '0') << 6); + if ((ch = *quoted++) < '0' || '7' < ch) + goto error; + ac |= ((ch - '0') << 3); + if ((ch = *quoted++) < '0' || '7' < ch) + goto error; + ac |= (ch - '0'); + ch = ac; + break; + default: + goto error; + } + strbuf_addch(sb, ch); + } + + error: + strbuf_setlen(sb, oldlen); + return -1; +} + +/* quoting as a string literal for other languages */ + +void perl_quote_print(FILE *stream, const char *src) +{ + const char sq = '\''; + const char bq = '\\'; + char c; + + fputc(sq, stream); + while ((c = *src++)) { + if (c == sq || c == bq) + fputc(bq, stream); + fputc(c, stream); + } + fputc(sq, stream); +} + +void python_quote_print(FILE *stream, const char *src) +{ + const char sq = '\''; + const char bq = '\\'; + const char nl = '\n'; + char c; + + fputc(sq, stream); + while ((c = *src++)) { + if (c == nl) { + fputc(bq, stream); + fputc('n', stream); + continue; + } + if (c == sq || c == bq) + fputc(bq, stream); + fputc(c, stream); + } + fputc(sq, stream); +} + +void tcl_quote_print(FILE *stream, const char *src) +{ + char c; + + fputc('"', stream); + while ((c = *src++)) { + switch (c) { + case '[': case ']': + case '{': case '}': + case '$': case '\\': case '"': + fputc('\\', stream); + default: + fputc(c, stream); + break; + case '\f': + fputs("\\f", stream); + break; + case '\r': + fputs("\\r", stream); + break; + case '\n': + fputs("\\n", stream); + break; + case '\t': + fputs("\\t", stream); + break; + case '\v': + fputs("\\v", stream); + break; + } + } + fputc('"', stream); +} diff --git a/Documentation/perf_counter/quote.h b/Documentation/perf_counter/quote.h new file mode 100644 index 000000000000..66730f2bff3c --- /dev/null +++ b/Documentation/perf_counter/quote.h @@ -0,0 +1,68 @@ +#ifndef QUOTE_H +#define QUOTE_H + +#include +#include + +/* Help to copy the thing properly quoted for the shell safety. + * any single quote is replaced with '\'', any exclamation point + * is replaced with '\!', and the whole thing is enclosed in a + * single quote pair. + * + * For example, if you are passing the result to system() as an + * argument: + * + * sprintf(cmd, "foobar %s %s", sq_quote(arg0), sq_quote(arg1)) + * + * would be appropriate. If the system() is going to call ssh to + * run the command on the other side: + * + * sprintf(cmd, "git-diff-tree %s %s", sq_quote(arg0), sq_quote(arg1)); + * sprintf(rcmd, "ssh %s %s", sq_quote(host), sq_quote(cmd)); + * + * Note that the above examples leak memory! Remember to free result from + * sq_quote() in a real application. + * + * sq_quote_buf() writes to an existing buffer of specified size; it + * will return the number of characters that would have been written + * excluding the final null regardless of the buffer size. + */ + +extern void sq_quote_print(FILE *stream, const char *src); + +extern void sq_quote_buf(struct strbuf *, const char *src); +extern void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen); + +/* This unwraps what sq_quote() produces in place, but returns + * NULL if the input does not look like what sq_quote would have + * produced. + */ +extern char *sq_dequote(char *); + +/* + * Same as the above, but can be used to unwrap many arguments in the + * same string separated by space. "next" is changed to point to the + * next argument that should be passed as first parameter. When there + * is no more argument to be dequoted, "next" is updated to point to NULL. + */ +extern char *sq_dequote_step(char *arg, char **next); +extern int sq_dequote_to_argv(char *arg, const char ***argv, int *nr, int *alloc); + +extern int unquote_c_style(struct strbuf *, const char *quoted, const char **endp); +extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq); +extern void quote_two_c_style(struct strbuf *, const char *, const char *, int); + +extern void write_name_quoted(const char *name, FILE *, int terminator); +extern void write_name_quotedpfx(const char *pfx, size_t pfxlen, + const char *name, FILE *, int terminator); + +/* quote path as relative to the given prefix */ +char *quote_path_relative(const char *in, int len, + struct strbuf *out, const char *prefix); + +/* quoting as a string literal for other languages */ +extern void perl_quote_print(FILE *stream, const char *src); +extern void python_quote_print(FILE *stream, const char *src); +extern void tcl_quote_print(FILE *stream, const char *src); + +#endif diff --git a/Documentation/perf_counter/run-command.c b/Documentation/perf_counter/run-command.c new file mode 100644 index 000000000000..b2f5e854f40a --- /dev/null +++ b/Documentation/perf_counter/run-command.c @@ -0,0 +1,395 @@ +#include "cache.h" +#include "run-command.h" +#include "exec_cmd.h" + +static inline void close_pair(int fd[2]) +{ + close(fd[0]); + close(fd[1]); +} + +static inline void dup_devnull(int to) +{ + int fd = open("/dev/null", O_RDWR); + dup2(fd, to); + close(fd); +} + +int start_command(struct child_process *cmd) +{ + int need_in, need_out, need_err; + int fdin[2], fdout[2], fderr[2]; + + /* + * In case of errors we must keep the promise to close FDs + * that have been passed in via ->in and ->out. + */ + + need_in = !cmd->no_stdin && cmd->in < 0; + if (need_in) { + if (pipe(fdin) < 0) { + if (cmd->out > 0) + close(cmd->out); + return -ERR_RUN_COMMAND_PIPE; + } + cmd->in = fdin[1]; + } + + need_out = !cmd->no_stdout + && !cmd->stdout_to_stderr + && cmd->out < 0; + if (need_out) { + if (pipe(fdout) < 0) { + if (need_in) + close_pair(fdin); + else if (cmd->in) + close(cmd->in); + return -ERR_RUN_COMMAND_PIPE; + } + cmd->out = fdout[0]; + } + + need_err = !cmd->no_stderr && cmd->err < 0; + if (need_err) { + if (pipe(fderr) < 0) { + if (need_in) + close_pair(fdin); + else if (cmd->in) + close(cmd->in); + if (need_out) + close_pair(fdout); + else if (cmd->out) + close(cmd->out); + return -ERR_RUN_COMMAND_PIPE; + } + cmd->err = fderr[0]; + } + +#ifndef __MINGW32__ + fflush(NULL); + cmd->pid = fork(); + if (!cmd->pid) { + if (cmd->no_stdin) + dup_devnull(0); + else if (need_in) { + dup2(fdin[0], 0); + close_pair(fdin); + } else if (cmd->in) { + dup2(cmd->in, 0); + close(cmd->in); + } + + if (cmd->no_stderr) + dup_devnull(2); + else if (need_err) { + dup2(fderr[1], 2); + close_pair(fderr); + } + + if (cmd->no_stdout) + dup_devnull(1); + else if (cmd->stdout_to_stderr) + dup2(2, 1); + else if (need_out) { + dup2(fdout[1], 1); + close_pair(fdout); + } else if (cmd->out > 1) { + dup2(cmd->out, 1); + close(cmd->out); + } + + if (cmd->dir && chdir(cmd->dir)) + die("exec %s: cd to %s failed (%s)", cmd->argv[0], + cmd->dir, strerror(errno)); + if (cmd->env) { + for (; *cmd->env; cmd->env++) { + if (strchr(*cmd->env, '=')) + putenv((char*)*cmd->env); + else + unsetenv(*cmd->env); + } + } + if (cmd->preexec_cb) + cmd->preexec_cb(); + if (cmd->perf_cmd) { + execv_perf_cmd(cmd->argv); + } else { + execvp(cmd->argv[0], (char *const*) cmd->argv); + } + exit(127); + } +#else + int s0 = -1, s1 = -1, s2 = -1; /* backups of stdin, stdout, stderr */ + const char **sargv = cmd->argv; + char **env = environ; + + if (cmd->no_stdin) { + s0 = dup(0); + dup_devnull(0); + } else if (need_in) { + s0 = dup(0); + dup2(fdin[0], 0); + } else if (cmd->in) { + s0 = dup(0); + dup2(cmd->in, 0); + } + + if (cmd->no_stderr) { + s2 = dup(2); + dup_devnull(2); + } else if (need_err) { + s2 = dup(2); + dup2(fderr[1], 2); + } + + if (cmd->no_stdout) { + s1 = dup(1); + dup_devnull(1); + } else if (cmd->stdout_to_stderr) { + s1 = dup(1); + dup2(2, 1); + } else if (need_out) { + s1 = dup(1); + dup2(fdout[1], 1); + } else if (cmd->out > 1) { + s1 = dup(1); + dup2(cmd->out, 1); + } + + if (cmd->dir) + die("chdir in start_command() not implemented"); + if (cmd->env) { + env = copy_environ(); + for (; *cmd->env; cmd->env++) + env = env_setenv(env, *cmd->env); + } + + if (cmd->perf_cmd) { + cmd->argv = prepare_perf_cmd(cmd->argv); + } + + cmd->pid = mingw_spawnvpe(cmd->argv[0], cmd->argv, env); + + if (cmd->env) + free_environ(env); + if (cmd->perf_cmd) + free(cmd->argv); + + cmd->argv = sargv; + if (s0 >= 0) + dup2(s0, 0), close(s0); + if (s1 >= 0) + dup2(s1, 1), close(s1); + if (s2 >= 0) + dup2(s2, 2), close(s2); +#endif + + if (cmd->pid < 0) { + int err = errno; + if (need_in) + close_pair(fdin); + else if (cmd->in) + close(cmd->in); + if (need_out) + close_pair(fdout); + else if (cmd->out) + close(cmd->out); + if (need_err) + close_pair(fderr); + return err == ENOENT ? + -ERR_RUN_COMMAND_EXEC : + -ERR_RUN_COMMAND_FORK; + } + + if (need_in) + close(fdin[0]); + else if (cmd->in) + close(cmd->in); + + if (need_out) + close(fdout[1]); + else if (cmd->out) + close(cmd->out); + + if (need_err) + close(fderr[1]); + + return 0; +} + +static int wait_or_whine(pid_t pid) +{ + for (;;) { + int status, code; + pid_t waiting = waitpid(pid, &status, 0); + + if (waiting < 0) { + if (errno == EINTR) + continue; + error("waitpid failed (%s)", strerror(errno)); + return -ERR_RUN_COMMAND_WAITPID; + } + if (waiting != pid) + return -ERR_RUN_COMMAND_WAITPID_WRONG_PID; + if (WIFSIGNALED(status)) + return -ERR_RUN_COMMAND_WAITPID_SIGNAL; + + if (!WIFEXITED(status)) + return -ERR_RUN_COMMAND_WAITPID_NOEXIT; + code = WEXITSTATUS(status); + switch (code) { + case 127: + return -ERR_RUN_COMMAND_EXEC; + case 0: + return 0; + default: + return -code; + } + } +} + +int finish_command(struct child_process *cmd) +{ + return wait_or_whine(cmd->pid); +} + +int run_command(struct child_process *cmd) +{ + int code = start_command(cmd); + if (code) + return code; + return finish_command(cmd); +} + +static void prepare_run_command_v_opt(struct child_process *cmd, + const char **argv, + int opt) +{ + memset(cmd, 0, sizeof(*cmd)); + cmd->argv = argv; + cmd->no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0; + cmd->perf_cmd = opt & RUN_PERF_CMD ? 1 : 0; + cmd->stdout_to_stderr = opt & RUN_COMMAND_STDOUT_TO_STDERR ? 1 : 0; +} + +int run_command_v_opt(const char **argv, int opt) +{ + struct child_process cmd; + prepare_run_command_v_opt(&cmd, argv, opt); + return run_command(&cmd); +} + +int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env) +{ + struct child_process cmd; + prepare_run_command_v_opt(&cmd, argv, opt); + cmd.dir = dir; + cmd.env = env; + return run_command(&cmd); +} + +#ifdef __MINGW32__ +static __stdcall unsigned run_thread(void *data) +{ + struct async *async = data; + return async->proc(async->fd_for_proc, async->data); +} +#endif + +int start_async(struct async *async) +{ + int pipe_out[2]; + + if (pipe(pipe_out) < 0) + return error("cannot create pipe: %s", strerror(errno)); + async->out = pipe_out[0]; + +#ifndef __MINGW32__ + /* Flush stdio before fork() to avoid cloning buffers */ + fflush(NULL); + + async->pid = fork(); + if (async->pid < 0) { + error("fork (async) failed: %s", strerror(errno)); + close_pair(pipe_out); + return -1; + } + if (!async->pid) { + close(pipe_out[0]); + exit(!!async->proc(pipe_out[1], async->data)); + } + close(pipe_out[1]); +#else + async->fd_for_proc = pipe_out[1]; + async->tid = (HANDLE) _beginthreadex(NULL, 0, run_thread, async, 0, NULL); + if (!async->tid) { + error("cannot create thread: %s", strerror(errno)); + close_pair(pipe_out); + return -1; + } +#endif + return 0; +} + +int finish_async(struct async *async) +{ +#ifndef __MINGW32__ + int ret = 0; + + if (wait_or_whine(async->pid)) + ret = error("waitpid (async) failed"); +#else + DWORD ret = 0; + if (WaitForSingleObject(async->tid, INFINITE) != WAIT_OBJECT_0) + ret = error("waiting for thread failed: %lu", GetLastError()); + else if (!GetExitCodeThread(async->tid, &ret)) + ret = error("cannot get thread exit code: %lu", GetLastError()); + CloseHandle(async->tid); +#endif + return ret; +} + +int run_hook(const char *index_file, const char *name, ...) +{ + struct child_process hook; + const char **argv = NULL, *env[2]; + char index[PATH_MAX]; + va_list args; + int ret; + size_t i = 0, alloc = 0; + + if (access(perf_path("hooks/%s", name), X_OK) < 0) + return 0; + + va_start(args, name); + ALLOC_GROW(argv, i + 1, alloc); + argv[i++] = perf_path("hooks/%s", name); + while (argv[i-1]) { + ALLOC_GROW(argv, i + 1, alloc); + argv[i++] = va_arg(args, const char *); + } + va_end(args); + + memset(&hook, 0, sizeof(hook)); + hook.argv = argv; + hook.no_stdin = 1; + hook.stdout_to_stderr = 1; + if (index_file) { + snprintf(index, sizeof(index), "PERF_INDEX_FILE=%s", index_file); + env[0] = index; + env[1] = NULL; + hook.env = env; + } + + ret = start_command(&hook); + free(argv); + if (ret) { + warning("Could not spawn %s", argv[0]); + return ret; + } + ret = finish_command(&hook); + if (ret == -ERR_RUN_COMMAND_WAITPID_SIGNAL) + warning("%s exited due to uncaught signal", argv[0]); + + return ret; +} diff --git a/Documentation/perf_counter/run-command.h b/Documentation/perf_counter/run-command.h new file mode 100644 index 000000000000..328289f23669 --- /dev/null +++ b/Documentation/perf_counter/run-command.h @@ -0,0 +1,93 @@ +#ifndef RUN_COMMAND_H +#define RUN_COMMAND_H + +enum { + ERR_RUN_COMMAND_FORK = 10000, + ERR_RUN_COMMAND_EXEC, + ERR_RUN_COMMAND_PIPE, + ERR_RUN_COMMAND_WAITPID, + ERR_RUN_COMMAND_WAITPID_WRONG_PID, + ERR_RUN_COMMAND_WAITPID_SIGNAL, + ERR_RUN_COMMAND_WAITPID_NOEXIT, +}; +#define IS_RUN_COMMAND_ERR(x) (-(x) >= ERR_RUN_COMMAND_FORK) + +struct child_process { + const char **argv; + pid_t pid; + /* + * Using .in, .out, .err: + * - Specify 0 for no redirections (child inherits stdin, stdout, + * stderr from parent). + * - Specify -1 to have a pipe allocated as follows: + * .in: returns the writable pipe end; parent writes to it, + * the readable pipe end becomes child's stdin + * .out, .err: returns the readable pipe end; parent reads from + * it, the writable pipe end becomes child's stdout/stderr + * The caller of start_command() must close the returned FDs + * after it has completed reading from/writing to it! + * - Specify > 0 to set a channel to a particular FD as follows: + * .in: a readable FD, becomes child's stdin + * .out: a writable FD, becomes child's stdout/stderr + * .err > 0 not supported + * The specified FD is closed by start_command(), even in case + * of errors! + */ + int in; + int out; + int err; + const char *dir; + const char *const *env; + unsigned no_stdin:1; + unsigned no_stdout:1; + unsigned no_stderr:1; + unsigned perf_cmd:1; /* if this is to be perf sub-command */ + unsigned stdout_to_stderr:1; + void (*preexec_cb)(void); +}; + +int start_command(struct child_process *); +int finish_command(struct child_process *); +int run_command(struct child_process *); + +extern int run_hook(const char *index_file, const char *name, ...); + +#define RUN_COMMAND_NO_STDIN 1 +#define RUN_PERF_CMD 2 /*If this is to be perf sub-command */ +#define RUN_COMMAND_STDOUT_TO_STDERR 4 +int run_command_v_opt(const char **argv, int opt); + +/* + * env (the environment) is to be formatted like environ: "VAR=VALUE". + * To unset an environment variable use just "VAR". + */ +int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env); + +/* + * The purpose of the following functions is to feed a pipe by running + * a function asynchronously and providing output that the caller reads. + * + * It is expected that no synchronization and mutual exclusion between + * the caller and the feed function is necessary so that the function + * can run in a thread without interfering with the caller. + */ +struct async { + /* + * proc writes to fd and closes it; + * returns 0 on success, non-zero on failure + */ + int (*proc)(int fd, void *data); + void *data; + int out; /* caller reads from here and closes it */ +#ifndef __MINGW32__ + pid_t pid; +#else + HANDLE tid; + int fd_for_proc; +#endif +}; + +int start_async(struct async *async); +int finish_async(struct async *async); + +#endif diff --git a/Documentation/perf_counter/strbuf.c b/Documentation/perf_counter/strbuf.c new file mode 100644 index 000000000000..eaba09306802 --- /dev/null +++ b/Documentation/perf_counter/strbuf.c @@ -0,0 +1,359 @@ +#include "cache.h" + +int prefixcmp(const char *str, const char *prefix) +{ + for (; ; str++, prefix++) + if (!*prefix) + return 0; + else if (*str != *prefix) + return (unsigned char)*prefix - (unsigned char)*str; +} + +/* + * Used as the default ->buf value, so that people can always assume + * buf is non NULL and ->buf is NUL terminated even for a freshly + * initialized strbuf. + */ +char strbuf_slopbuf[1]; + +void strbuf_init(struct strbuf *sb, size_t hint) +{ + sb->alloc = sb->len = 0; + sb->buf = strbuf_slopbuf; + if (hint) + strbuf_grow(sb, hint); +} + +void strbuf_release(struct strbuf *sb) +{ + if (sb->alloc) { + free(sb->buf); + strbuf_init(sb, 0); + } +} + +char *strbuf_detach(struct strbuf *sb, size_t *sz) +{ + char *res = sb->alloc ? sb->buf : NULL; + if (sz) + *sz = sb->len; + strbuf_init(sb, 0); + return res; +} + +void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc) +{ + strbuf_release(sb); + sb->buf = buf; + sb->len = len; + sb->alloc = alloc; + strbuf_grow(sb, 0); + sb->buf[sb->len] = '\0'; +} + +void strbuf_grow(struct strbuf *sb, size_t extra) +{ + if (sb->len + extra + 1 <= sb->len) + die("you want to use way too much memory"); + if (!sb->alloc) + sb->buf = NULL; + ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc); +} + +void strbuf_trim(struct strbuf *sb) +{ + char *b = sb->buf; + while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1])) + sb->len--; + while (sb->len > 0 && isspace(*b)) { + b++; + sb->len--; + } + memmove(sb->buf, b, sb->len); + sb->buf[sb->len] = '\0'; +} +void strbuf_rtrim(struct strbuf *sb) +{ + while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1])) + sb->len--; + sb->buf[sb->len] = '\0'; +} + +void strbuf_ltrim(struct strbuf *sb) +{ + char *b = sb->buf; + while (sb->len > 0 && isspace(*b)) { + b++; + sb->len--; + } + memmove(sb->buf, b, sb->len); + sb->buf[sb->len] = '\0'; +} + +void strbuf_tolower(struct strbuf *sb) +{ + int i; + for (i = 0; i < sb->len; i++) + sb->buf[i] = tolower(sb->buf[i]); +} + +struct strbuf **strbuf_split(const struct strbuf *sb, int delim) +{ + int alloc = 2, pos = 0; + char *n, *p; + struct strbuf **ret; + struct strbuf *t; + + ret = calloc(alloc, sizeof(struct strbuf *)); + p = n = sb->buf; + while (n < sb->buf + sb->len) { + int len; + n = memchr(n, delim, sb->len - (n - sb->buf)); + if (pos + 1 >= alloc) { + alloc = alloc * 2; + ret = realloc(ret, sizeof(struct strbuf *) * alloc); + } + if (!n) + n = sb->buf + sb->len - 1; + len = n - p + 1; + t = malloc(sizeof(struct strbuf)); + strbuf_init(t, len); + strbuf_add(t, p, len); + ret[pos] = t; + ret[++pos] = NULL; + p = ++n; + } + return ret; +} + +void strbuf_list_free(struct strbuf **sbs) +{ + struct strbuf **s = sbs; + + while (*s) { + strbuf_release(*s); + free(*s++); + } + free(sbs); +} + +int strbuf_cmp(const struct strbuf *a, const struct strbuf *b) +{ + int len = a->len < b->len ? a->len: b->len; + int cmp = memcmp(a->buf, b->buf, len); + if (cmp) + return cmp; + return a->len < b->len ? -1: a->len != b->len; +} + +void strbuf_splice(struct strbuf *sb, size_t pos, size_t len, + const void *data, size_t dlen) +{ + if (pos + len < pos) + die("you want to use way too much memory"); + if (pos > sb->len) + die("`pos' is too far after the end of the buffer"); + if (pos + len > sb->len) + die("`pos + len' is too far after the end of the buffer"); + + if (dlen >= len) + strbuf_grow(sb, dlen - len); + memmove(sb->buf + pos + dlen, + sb->buf + pos + len, + sb->len - pos - len); + memcpy(sb->buf + pos, data, dlen); + strbuf_setlen(sb, sb->len + dlen - len); +} + +void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len) +{ + strbuf_splice(sb, pos, 0, data, len); +} + +void strbuf_remove(struct strbuf *sb, size_t pos, size_t len) +{ + strbuf_splice(sb, pos, len, NULL, 0); +} + +void strbuf_add(struct strbuf *sb, const void *data, size_t len) +{ + strbuf_grow(sb, len); + memcpy(sb->buf + sb->len, data, len); + strbuf_setlen(sb, sb->len + len); +} + +void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len) +{ + strbuf_grow(sb, len); + memcpy(sb->buf + sb->len, sb->buf + pos, len); + strbuf_setlen(sb, sb->len + len); +} + +void strbuf_addf(struct strbuf *sb, const char *fmt, ...) +{ + int len; + va_list ap; + + if (!strbuf_avail(sb)) + strbuf_grow(sb, 64); + va_start(ap, fmt); + len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + va_end(ap); + if (len < 0) + die("your vsnprintf is broken"); + if (len > strbuf_avail(sb)) { + strbuf_grow(sb, len); + va_start(ap, fmt); + len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + va_end(ap); + if (len > strbuf_avail(sb)) { + die("this should not happen, your snprintf is broken"); + } + } + strbuf_setlen(sb, sb->len + len); +} + +void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, + void *context) +{ + for (;;) { + const char *percent; + size_t consumed; + + percent = strchrnul(format, '%'); + strbuf_add(sb, format, percent - format); + if (!*percent) + break; + format = percent + 1; + + consumed = fn(sb, format, context); + if (consumed) + format += consumed; + else + strbuf_addch(sb, '%'); + } +} + +size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, + void *context) +{ + struct strbuf_expand_dict_entry *e = context; + size_t len; + + for (; e->placeholder && (len = strlen(e->placeholder)); e++) { + if (!strncmp(placeholder, e->placeholder, len)) { + if (e->value) + strbuf_addstr(sb, e->value); + return len; + } + } + return 0; +} + +size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f) +{ + size_t res; + size_t oldalloc = sb->alloc; + + strbuf_grow(sb, size); + res = fread(sb->buf + sb->len, 1, size, f); + if (res > 0) + strbuf_setlen(sb, sb->len + res); + else if (res < 0 && oldalloc == 0) + strbuf_release(sb); + return res; +} + +ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint) +{ + size_t oldlen = sb->len; + size_t oldalloc = sb->alloc; + + strbuf_grow(sb, hint ? hint : 8192); + for (;;) { + ssize_t cnt; + + cnt = read(fd, sb->buf + sb->len, sb->alloc - sb->len - 1); + if (cnt < 0) { + if (oldalloc == 0) + strbuf_release(sb); + else + strbuf_setlen(sb, oldlen); + return -1; + } + if (!cnt) + break; + sb->len += cnt; + strbuf_grow(sb, 8192); + } + + sb->buf[sb->len] = '\0'; + return sb->len - oldlen; +} + +#define STRBUF_MAXLINK (2*PATH_MAX) + +int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint) +{ + size_t oldalloc = sb->alloc; + + if (hint < 32) + hint = 32; + + while (hint < STRBUF_MAXLINK) { + int len; + + strbuf_grow(sb, hint); + len = readlink(path, sb->buf, hint); + if (len < 0) { + if (errno != ERANGE) + break; + } else if (len < hint) { + strbuf_setlen(sb, len); + return 0; + } + + /* .. the buffer was too small - try again */ + hint *= 2; + } + if (oldalloc == 0) + strbuf_release(sb); + return -1; +} + +int strbuf_getline(struct strbuf *sb, FILE *fp, int term) +{ + int ch; + + strbuf_grow(sb, 0); + if (feof(fp)) + return EOF; + + strbuf_reset(sb); + while ((ch = fgetc(fp)) != EOF) { + if (ch == term) + break; + strbuf_grow(sb, 1); + sb->buf[sb->len++] = ch; + } + if (ch == EOF && sb->len == 0) + return EOF; + + sb->buf[sb->len] = '\0'; + return 0; +} + +int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint) +{ + int fd, len; + + fd = open(path, O_RDONLY); + if (fd < 0) + return -1; + len = strbuf_read(sb, fd, hint); + close(fd); + if (len < 0) + return -1; + + return len; +} diff --git a/Documentation/perf_counter/strbuf.h b/Documentation/perf_counter/strbuf.h new file mode 100644 index 000000000000..9ee908a3ec5d --- /dev/null +++ b/Documentation/perf_counter/strbuf.h @@ -0,0 +1,137 @@ +#ifndef STRBUF_H +#define STRBUF_H + +/* + * Strbuf's can be use in many ways: as a byte array, or to store arbitrary + * long, overflow safe strings. + * + * Strbufs has some invariants that are very important to keep in mind: + * + * 1. the ->buf member is always malloc-ed, hence strbuf's can be used to + * build complex strings/buffers whose final size isn't easily known. + * + * It is NOT legal to copy the ->buf pointer away. + * `strbuf_detach' is the operation that detachs a buffer from its shell + * while keeping the shell valid wrt its invariants. + * + * 2. the ->buf member is a byte array that has at least ->len + 1 bytes + * allocated. The extra byte is used to store a '\0', allowing the ->buf + * member to be a valid C-string. Every strbuf function ensure this + * invariant is preserved. + * + * Note that it is OK to "play" with the buffer directly if you work it + * that way: + * + * strbuf_grow(sb, SOME_SIZE); + * ... Here, the memory array starting at sb->buf, and of length + * ... strbuf_avail(sb) is all yours, and you are sure that + * ... strbuf_avail(sb) is at least SOME_SIZE. + * strbuf_setlen(sb, sb->len + SOME_OTHER_SIZE); + * + * Of course, SOME_OTHER_SIZE must be smaller or equal to strbuf_avail(sb). + * + * Doing so is safe, though if it has to be done in many places, adding the + * missing API to the strbuf module is the way to go. + * + * XXX: do _not_ assume that the area that is yours is of size ->alloc - 1 + * even if it's true in the current implementation. Alloc is somehow a + * "private" member that should not be messed with. + */ + +#include + +extern char strbuf_slopbuf[]; +struct strbuf { + size_t alloc; + size_t len; + char *buf; +}; + +#define STRBUF_INIT { 0, 0, strbuf_slopbuf } + +/*----- strbuf life cycle -----*/ +extern void strbuf_init(struct strbuf *, size_t); +extern void strbuf_release(struct strbuf *); +extern char *strbuf_detach(struct strbuf *, size_t *); +extern void strbuf_attach(struct strbuf *, void *, size_t, size_t); +static inline void strbuf_swap(struct strbuf *a, struct strbuf *b) { + struct strbuf tmp = *a; + *a = *b; + *b = tmp; +} + +/*----- strbuf size related -----*/ +static inline size_t strbuf_avail(const struct strbuf *sb) { + return sb->alloc ? sb->alloc - sb->len - 1 : 0; +} + +extern void strbuf_grow(struct strbuf *, size_t); + +static inline void strbuf_setlen(struct strbuf *sb, size_t len) { + if (!sb->alloc) + strbuf_grow(sb, 0); + assert(len < sb->alloc); + sb->len = len; + sb->buf[len] = '\0'; +} +#define strbuf_reset(sb) strbuf_setlen(sb, 0) + +/*----- content related -----*/ +extern void strbuf_trim(struct strbuf *); +extern void strbuf_rtrim(struct strbuf *); +extern void strbuf_ltrim(struct strbuf *); +extern int strbuf_cmp(const struct strbuf *, const struct strbuf *); +extern void strbuf_tolower(struct strbuf *); + +extern struct strbuf **strbuf_split(const struct strbuf *, int delim); +extern void strbuf_list_free(struct strbuf **); + +/*----- add data in your buffer -----*/ +static inline void strbuf_addch(struct strbuf *sb, int c) { + strbuf_grow(sb, 1); + sb->buf[sb->len++] = c; + sb->buf[sb->len] = '\0'; +} + +extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t); +extern void strbuf_remove(struct strbuf *, size_t pos, size_t len); + +/* splice pos..pos+len with given data */ +extern void strbuf_splice(struct strbuf *, size_t pos, size_t len, + const void *, size_t); + +extern void strbuf_add(struct strbuf *, const void *, size_t); +static inline void strbuf_addstr(struct strbuf *sb, const char *s) { + strbuf_add(sb, s, strlen(s)); +} +static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2) { + strbuf_add(sb, sb2->buf, sb2->len); +} +extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len); + +typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context); +extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context); +struct strbuf_expand_dict_entry { + const char *placeholder; + const char *value; +}; +extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context); + +__attribute__((format(printf,2,3))) +extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); + +extern size_t strbuf_fread(struct strbuf *, size_t, FILE *); +/* XXX: if read fails, any partial read is undone */ +extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint); +extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint); +extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint); + +extern int strbuf_getline(struct strbuf *, FILE *, int); + +extern void stripspace(struct strbuf *buf, int skip_comments); +extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env); + +extern int strbuf_branchname(struct strbuf *sb, const char *name); +extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name); + +#endif /* STRBUF_H */ diff --git a/Documentation/perf_counter/usage.c b/Documentation/perf_counter/usage.c new file mode 100644 index 000000000000..7a10421fe6b4 --- /dev/null +++ b/Documentation/perf_counter/usage.c @@ -0,0 +1,80 @@ +/* + * GIT - The information manager from hell + * + * Copyright (C) Linus Torvalds, 2005 + */ +#include "util.h" + +static void report(const char *prefix, const char *err, va_list params) +{ + char msg[1024]; + vsnprintf(msg, sizeof(msg), err, params); + fprintf(stderr, "%s%s\n", prefix, msg); +} + +static NORETURN void usage_builtin(const char *err) +{ + fprintf(stderr, "usage: %s\n", err); + exit(129); +} + +static NORETURN void die_builtin(const char *err, va_list params) +{ + report("fatal: ", err, params); + exit(128); +} + +static void error_builtin(const char *err, va_list params) +{ + report("error: ", err, params); +} + +static void warn_builtin(const char *warn, va_list params) +{ + report("warning: ", warn, params); +} + +/* If we are in a dlopen()ed .so write to a global variable would segfault + * (ugh), so keep things static. */ +static void (*usage_routine)(const char *err) NORETURN = usage_builtin; +static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin; +static void (*error_routine)(const char *err, va_list params) = error_builtin; +static void (*warn_routine)(const char *err, va_list params) = warn_builtin; + +void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN) +{ + die_routine = routine; +} + +void usage(const char *err) +{ + usage_routine(err); +} + +void die(const char *err, ...) +{ + va_list params; + + va_start(params, err); + die_routine(err, params); + va_end(params); +} + +int error(const char *err, ...) +{ + va_list params; + + va_start(params, err); + error_routine(err, params); + va_end(params); + return -1; +} + +void warning(const char *warn, ...) +{ + va_list params; + + va_start(params, warn); + warn_routine(warn, params); + va_end(params); +} diff --git a/Documentation/perf_counter/util.h b/Documentation/perf_counter/util.h new file mode 100644 index 000000000000..13f8bdce7600 --- /dev/null +++ b/Documentation/perf_counter/util.h @@ -0,0 +1,394 @@ +#ifndef GIT_COMPAT_UTIL_H +#define GIT_COMPAT_UTIL_H + +#define _FILE_OFFSET_BITS 64 + +#ifndef FLEX_ARRAY +/* + * See if our compiler is known to support flexible array members. + */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define FLEX_ARRAY /* empty */ +#elif defined(__GNUC__) +# if (__GNUC__ >= 3) +# define FLEX_ARRAY /* empty */ +# else +# define FLEX_ARRAY 0 /* older GNU extension */ +# endif +#endif + +/* + * Otherwise, default to safer but a bit wasteful traditional style + */ +#ifndef FLEX_ARRAY +# define FLEX_ARRAY 1 +#endif +#endif + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +#ifdef __GNUC__ +#define TYPEOF(x) (__typeof__(x)) +#else +#define TYPEOF(x) +#endif + +#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits)))) +#define HAS_MULTI_BITS(i) ((i) & ((i) - 1)) /* checks if an integer has more than 1 bit set */ + +/* Approximation of the length of the decimal representation of this type. */ +#define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1) + +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && !defined(_M_UNIX) +#define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */ +#define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */ +#endif +#define _ALL_SOURCE 1 +#define _GNU_SOURCE 1 +#define _BSD_SOURCE 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef __MINGW32__ +#include +#include +#include +#include +#ifndef NO_SYS_SELECT_H +#include +#endif +#include +#include +#include +#include +#include +#include +#if defined(__CYGWIN__) +#undef _XOPEN_SOURCE +#include +#define _XOPEN_SOURCE 600 +#include "compat/cygwin.h" +#else +#undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */ +#include +#define _ALL_SOURCE 1 +#endif +#else /* __MINGW32__ */ +/* pull in Windows compatibility stuff */ +#include "compat/mingw.h" +#endif /* __MINGW32__ */ + +#ifndef NO_ICONV +#include +#endif + +#ifndef NO_OPENSSL +#include +#include +#endif + +/* On most systems would have given us this, but + * not on some systems (e.g. GNU/Hurd). + */ +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +#ifndef PRIuMAX +#define PRIuMAX "llu" +#endif + +#ifndef PRIu32 +#define PRIu32 "u" +#endif + +#ifndef PRIx32 +#define PRIx32 "x" +#endif + +#ifndef PATH_SEP +#define PATH_SEP ':' +#endif + +#ifndef STRIP_EXTENSION +#define STRIP_EXTENSION "" +#endif + +#ifndef has_dos_drive_prefix +#define has_dos_drive_prefix(path) 0 +#endif + +#ifndef is_dir_sep +#define is_dir_sep(c) ((c) == '/') +#endif + +#ifdef __GNUC__ +#define NORETURN __attribute__((__noreturn__)) +#else +#define NORETURN +#ifndef __attribute__ +#define __attribute__(x) +#endif +#endif + +/* General helper functions */ +extern void usage(const char *err) NORETURN; +extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); +extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); +extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); + +extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); + +extern int prefixcmp(const char *str, const char *prefix); +extern time_t tm_to_time_t(const struct tm *tm); + +static inline const char *skip_prefix(const char *str, const char *prefix) +{ + size_t len = strlen(prefix); + return strncmp(str, prefix, len) ? NULL : str + len; +} + +#if defined(NO_MMAP) || defined(USE_WIN32_MMAP) + +#ifndef PROT_READ +#define PROT_READ 1 +#define PROT_WRITE 2 +#define MAP_PRIVATE 1 +#define MAP_FAILED ((void*)-1) +#endif + +#define mmap git_mmap +#define munmap git_munmap +extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); +extern int git_munmap(void *start, size_t length); + +#else /* NO_MMAP || USE_WIN32_MMAP */ + +#include + +#endif /* NO_MMAP || USE_WIN32_MMAP */ + +#ifdef NO_MMAP + +/* This value must be multiple of (pagesize * 2) */ +#define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024) + +#else /* NO_MMAP */ + +/* This value must be multiple of (pagesize * 2) */ +#define DEFAULT_PACKED_GIT_WINDOW_SIZE \ + (sizeof(void*) >= 8 \ + ? 1 * 1024 * 1024 * 1024 \ + : 32 * 1024 * 1024) + +#endif /* NO_MMAP */ + +#ifdef NO_ST_BLOCKS_IN_STRUCT_STAT +#define on_disk_bytes(st) ((st).st_size) +#else +#define on_disk_bytes(st) ((st).st_blocks * 512) +#endif + +#define DEFAULT_PACKED_GIT_LIMIT \ + ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256)) + +#ifdef NO_PREAD +#define pread git_pread +extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset); +#endif +/* + * Forward decl that will remind us if its twin in cache.h changes. + * This function is used in compat/pread.c. But we can't include + * cache.h there. + */ +extern ssize_t read_in_full(int fd, void *buf, size_t count); + +#ifdef NO_SETENV +#define setenv gitsetenv +extern int gitsetenv(const char *, const char *, int); +#endif + +#ifdef NO_MKDTEMP +#define mkdtemp gitmkdtemp +extern char *gitmkdtemp(char *); +#endif + +#ifdef NO_UNSETENV +#define unsetenv gitunsetenv +extern void gitunsetenv(const char *); +#endif + +#ifdef NO_STRCASESTR +#define strcasestr gitstrcasestr +extern char *gitstrcasestr(const char *haystack, const char *needle); +#endif + +#ifdef NO_STRLCPY +#define strlcpy gitstrlcpy +extern size_t gitstrlcpy(char *, const char *, size_t); +#endif + +#ifdef NO_STRTOUMAX +#define strtoumax gitstrtoumax +extern uintmax_t gitstrtoumax(const char *, char **, int); +#endif + +#ifdef NO_HSTRERROR +#define hstrerror githstrerror +extern const char *githstrerror(int herror); +#endif + +#ifdef NO_MEMMEM +#define memmem gitmemmem +void *gitmemmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen); +#endif + +#ifdef FREAD_READS_DIRECTORIES +#ifdef fopen +#undef fopen +#endif +#define fopen(a,b) git_fopen(a,b) +extern FILE *git_fopen(const char*, const char*); +#endif + +#ifdef SNPRINTF_RETURNS_BOGUS +#define snprintf git_snprintf +extern int git_snprintf(char *str, size_t maxsize, + const char *format, ...); +#define vsnprintf git_vsnprintf +extern int git_vsnprintf(char *str, size_t maxsize, + const char *format, va_list ap); +#endif + +#ifdef __GLIBC_PREREQ +#if __GLIBC_PREREQ(2, 1) +#define HAVE_STRCHRNUL +#endif +#endif + +#ifndef HAVE_STRCHRNUL +#define strchrnul gitstrchrnul +static inline char *gitstrchrnul(const char *s, int c) +{ + while (*s && *s != c) + s++; + return (char *)s; +} +#endif + +static inline size_t xsize_t(off_t len) +{ + return (size_t)len; +} + +static inline int has_extension(const char *filename, const char *ext) +{ + size_t len = strlen(filename); + size_t extlen = strlen(ext); + return len > extlen && !memcmp(filename + len - extlen, ext, extlen); +} + +/* Sane ctype - no locale, and works with signed chars */ +#undef isascii +#undef isspace +#undef isdigit +#undef isalpha +#undef isalnum +#undef tolower +#undef toupper +extern unsigned char sane_ctype[256]; +#define GIT_SPACE 0x01 +#define GIT_DIGIT 0x02 +#define GIT_ALPHA 0x04 +#define GIT_GLOB_SPECIAL 0x08 +#define GIT_REGEX_SPECIAL 0x10 +#define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0) +#define isascii(x) (((x) & ~0x7f) == 0) +#define isspace(x) sane_istest(x,GIT_SPACE) +#define isdigit(x) sane_istest(x,GIT_DIGIT) +#define isalpha(x) sane_istest(x,GIT_ALPHA) +#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) +#define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL) +#define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL) +#define tolower(x) sane_case((unsigned char)(x), 0x20) +#define toupper(x) sane_case((unsigned char)(x), 0) + +static inline int sane_case(int x, int high) +{ + if (sane_istest(x, GIT_ALPHA)) + x = (x & ~0x20) | high; + return x; +} + +static inline int strtoul_ui(char const *s, int base, unsigned int *result) +{ + unsigned long ul; + char *p; + + errno = 0; + ul = strtoul(s, &p, base); + if (errno || *p || p == s || (unsigned int) ul != ul) + return -1; + *result = ul; + return 0; +} + +static inline int strtol_i(char const *s, int base, int *result) +{ + long ul; + char *p; + + errno = 0; + ul = strtol(s, &p, base); + if (errno || *p || p == s || (int) ul != ul) + return -1; + *result = ul; + return 0; +} + +#ifdef INTERNAL_QSORT +void git_qsort(void *base, size_t nmemb, size_t size, + int(*compar)(const void *, const void *)); +#define qsort git_qsort +#endif + +#ifndef DIR_HAS_BSD_GROUP_SEMANTICS +# define FORCE_DIR_SET_GID S_ISGID +#else +# define FORCE_DIR_SET_GID 0 +#endif + +#ifdef NO_NSEC +#undef USE_NSEC +#define ST_CTIME_NSEC(st) 0 +#define ST_MTIME_NSEC(st) 0 +#else +#ifdef USE_ST_TIMESPEC +#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctimespec.tv_nsec)) +#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtimespec.tv_nsec)) +#else +#define ST_CTIME_NSEC(st) ((unsigned int)((st).st_ctim.tv_nsec)) +#define ST_MTIME_NSEC(st) ((unsigned int)((st).st_mtim.tv_nsec)) +#endif +#endif + +#endif diff --git a/Documentation/perf_counter/wrapper.c b/Documentation/perf_counter/wrapper.c new file mode 100644 index 000000000000..6350d65f6d9e --- /dev/null +++ b/Documentation/perf_counter/wrapper.c @@ -0,0 +1,206 @@ +/* + * Various trivial helper wrappers around standard functions + */ +#include "cache.h" + +/* + * There's no pack memory to release - but stay close to the Git + * version so wrap this away: + */ +static inline void release_pack_memory(size_t size, int flag) +{ +} + +char *xstrdup(const char *str) +{ + char *ret = strdup(str); + if (!ret) { + release_pack_memory(strlen(str) + 1, -1); + ret = strdup(str); + if (!ret) + die("Out of memory, strdup failed"); + } + return ret; +} + +void *xmalloc(size_t size) +{ + void *ret = malloc(size); + if (!ret && !size) + ret = malloc(1); + if (!ret) { + release_pack_memory(size, -1); + ret = malloc(size); + if (!ret && !size) + ret = malloc(1); + if (!ret) + die("Out of memory, malloc failed"); + } +#ifdef XMALLOC_POISON + memset(ret, 0xA5, size); +#endif + return ret; +} + +/* + * xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of + * "data" to the allocated memory, zero terminates the allocated memory, + * and returns a pointer to the allocated memory. If the allocation fails, + * the program dies. + */ +void *xmemdupz(const void *data, size_t len) +{ + char *p = xmalloc(len + 1); + memcpy(p, data, len); + p[len] = '\0'; + return p; +} + +char *xstrndup(const char *str, size_t len) +{ + char *p = memchr(str, '\0', len); + return xmemdupz(str, p ? p - str : len); +} + +void *xrealloc(void *ptr, size_t size) +{ + void *ret = realloc(ptr, size); + if (!ret && !size) + ret = realloc(ptr, 1); + if (!ret) { + release_pack_memory(size, -1); + ret = realloc(ptr, size); + if (!ret && !size) + ret = realloc(ptr, 1); + if (!ret) + die("Out of memory, realloc failed"); + } + return ret; +} + +void *xcalloc(size_t nmemb, size_t size) +{ + void *ret = calloc(nmemb, size); + if (!ret && (!nmemb || !size)) + ret = calloc(1, 1); + if (!ret) { + release_pack_memory(nmemb * size, -1); + ret = calloc(nmemb, size); + if (!ret && (!nmemb || !size)) + ret = calloc(1, 1); + if (!ret) + die("Out of memory, calloc failed"); + } + return ret; +} + +void *xmmap(void *start, size_t length, + int prot, int flags, int fd, off_t offset) +{ + void *ret = mmap(start, length, prot, flags, fd, offset); + if (ret == MAP_FAILED) { + if (!length) + return NULL; + release_pack_memory(length, fd); + ret = mmap(start, length, prot, flags, fd, offset); + if (ret == MAP_FAILED) + die("Out of memory? mmap failed: %s", strerror(errno)); + } + return ret; +} + +/* + * xread() is the same a read(), but it automatically restarts read() + * operations with a recoverable error (EAGAIN and EINTR). xread() + * DOES NOT GUARANTEE that "len" bytes is read even if the data is available. + */ +ssize_t xread(int fd, void *buf, size_t len) +{ + ssize_t nr; + while (1) { + nr = read(fd, buf, len); + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return nr; + } +} + +/* + * xwrite() is the same a write(), but it automatically restarts write() + * operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT + * GUARANTEE that "len" bytes is written even if the operation is successful. + */ +ssize_t xwrite(int fd, const void *buf, size_t len) +{ + ssize_t nr; + while (1) { + nr = write(fd, buf, len); + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) + continue; + return nr; + } +} + +ssize_t read_in_full(int fd, void *buf, size_t count) +{ + char *p = buf; + ssize_t total = 0; + + while (count > 0) { + ssize_t loaded = xread(fd, p, count); + if (loaded <= 0) + return total ? total : loaded; + count -= loaded; + p += loaded; + total += loaded; + } + + return total; +} + +ssize_t write_in_full(int fd, const void *buf, size_t count) +{ + const char *p = buf; + ssize_t total = 0; + + while (count > 0) { + ssize_t written = xwrite(fd, p, count); + if (written < 0) + return -1; + if (!written) { + errno = ENOSPC; + return -1; + } + count -= written; + p += written; + total += written; + } + + return total; +} + +int xdup(int fd) +{ + int ret = dup(fd); + if (ret < 0) + die("dup failed: %s", strerror(errno)); + return ret; +} + +FILE *xfdopen(int fd, const char *mode) +{ + FILE *stream = fdopen(fd, mode); + if (stream == NULL) + die("Out of memory? fdopen failed: %s", strerror(errno)); + return stream; +} + +int xmkstemp(char *template) +{ + int fd; + + fd = mkstemp(template); + if (fd < 0) + die("Unable to create temporary file: %s", strerror(errno)); + return fd; +} -- GitLab From 6f06ccbc86f8a02aa32271263249657ce484eb25 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 15:22:22 +0200 Subject: [PATCH 0445/6080] perf_counter tools: clean up after introduction of the Git command framework Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 207 +--------------------- Documentation/perf_counter/builtin-help.c | 2 - Documentation/perf_counter/builtin-top.c | 17 +- Documentation/perf_counter/cache.h | 20 +++ Documentation/perf_counter/config.c | 95 +--------- Documentation/perf_counter/path.c | 39 ---- Documentation/perf_counter/perf.c | 3 +- Documentation/perf_counter/util.h | 14 ++ 8 files changed, 45 insertions(+), 352 deletions(-) diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index 11809b943fc3..1b6026555547 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -138,16 +138,6 @@ all:: # # Define NO_PERL if you do not want Perl scripts or libraries at all. # -# Define NO_TCLTK if you do not want Tcl/Tk GUI. -# -# The TCL_PATH variable governs the location of the Tcl interpreter -# used to optimize perf-gui for your system. Only used if NO_TCLTK -# is not set. Defaults to the bare 'tclsh'. -# -# The TCLTK_PATH variable governs the location of the Tcl/Tk interpreter. -# If not set it defaults to the bare 'wish'. If it is set to the empty -# string then NO_TCLTK will be forced (this is used by configure script). -# # Define INTERNAL_QSORT to use Git's implementation of qsort(), which # is a simplified version of the merge sort used in glibc. This is # recommended if Git triggers O(n^2) behavior in your platform's qsort(). @@ -215,12 +205,8 @@ TAR = tar FIND = find INSTALL = install RPMBUILD = rpmbuild -TCL_PATH = tclsh -TCLTK_PATH = wish PTHREAD_LIBS = -lpthread -export TCL_PATH TCLTK_PATH - # sparse is architecture-neutral, which means that we need to tell it # explicitly what architecture to check for. Fix this up for yours.. SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ @@ -529,10 +515,6 @@ ifdef NO_EXTERNAL_GREP BASIC_CFLAGS += -DNO_EXTERNAL_GREP endif -ifeq ($(TCLTK_PATH),) -NO_TCLTK=NoThanks -endif - ifeq ($(PERL_PATH),) NO_PERL=NoThanks endif @@ -583,7 +565,6 @@ prefix_SQ = $(subst ','\'',$(prefix)) SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) -TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH)) LIBS = $(PERFLIBS) $(EXTLIBS) @@ -607,14 +588,6 @@ ifneq (,$X) endif all:: -ifndef NO_TCLTK - $(QUIET_SUBDIR0)perf-gui $(QUIET_SUBDIR1) perfexecdir='$(perfexec_instdir_SQ)' all - $(QUIET_SUBDIR0)perfk-perf $(QUIET_SUBDIR1) all -endif -ifndef NO_PERL - $(QUIET_SUBDIR0)perl $(QUIET_SUBDIR1) PERL_PATH='$(PERL_PATH_SQ)' prefix='$(prefix_SQ)' all -endif - $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) please_set_SHELL_PATH_to_a_more_modern_shell: @$$(:) @@ -704,21 +677,6 @@ builtin-revert.o wt-status.o: wt-status.h $(LIB_FILE): $(LIB_OBJS) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) -doc: - $(MAKE) -C Documentation all - -man: - $(MAKE) -C Documentation man - -html: - $(MAKE) -C Documentation html - -info: - $(MAKE) -C Documentation info - -pdf: - $(MAKE) -C Documentation pdf - TAGS: $(RM) TAGS $(FIND) . -name '*.[hcS]' -print | xargs etags -a @@ -751,33 +709,12 @@ PERF-BUILD-OPTIONS: .FORCE-PERF-BUILD-OPTIONS @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@ @echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@ -### Detect Tck/Tk interpreter path changes -ifndef NO_TCLTK -TRACK_VARS = $(subst ','\'',-DTCLTK_PATH='$(TCLTK_PATH_SQ)') - -PERF-GUI-VARS: .FORCE-PERF-GUI-VARS - @VARS='$(TRACK_VARS)'; \ - if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \ - echo 1>&2 " * new Tcl/Tk interpreter location"; \ - echo "$$VARS" >$@; \ - fi - -.PHONY: .FORCE-PERF-GUI-VARS -endif - ### Testing rules -TEST_PROGRAMS += test-chmtime$X -TEST_PROGRAMS += test-ctype$X -TEST_PROGRAMS += test-date$X -TEST_PROGRAMS += test-delta$X -TEST_PROGRAMS += test-dump-cache-tree$X -TEST_PROGRAMS += test-genrandom$X -TEST_PROGRAMS += test-match-trees$X -TEST_PROGRAMS += test-parse-options$X -TEST_PROGRAMS += test-path-utils$X -TEST_PROGRAMS += test-sha1$X -TEST_PROGRAMS += test-sigchain$X +# +# None right now: +# +# TEST_PROGRAMS += test-something$X all:: $(TEST_PROGRAMS) @@ -787,25 +724,6 @@ all:: $(TEST_PROGRAMS) export NO_SVN_TESTS -test: all - $(MAKE) -C t/ all - -test-ctype$X: ctype.o - -test-date$X: date.o ctype.o - -test-delta$X: diff-delta.o patch-delta.o - -test-parse-options$X: parse-options.o - -.PRECIOUS: $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS)) - -test-%$X: test-%.o $(PERFLIBS) - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) - -check-sha1:: test-sha1$X - ./test-sha1.sh - check: common-cmds.h if sparse; \ then \ @@ -845,10 +763,6 @@ install: all $(INSTALL) perf$X perf-upload-pack$X perf-receive-pack$X perf-upload-archive$X perf-shell$X perf-cvsserver '$(DESTDIR_SQ)$(bindir_SQ)' $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install -ifndef NO_TCLTK - $(MAKE) -C perfk-perf install - $(MAKE) -C perf-gui perfexecdir='$(perfexec_instdir_SQ)' install -endif ifneq (,$X) $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';) endif @@ -865,32 +779,6 @@ endif done } && \ ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/perf-add$X" -install-doc: - $(MAKE) -C Documentation install - -install-man: - $(MAKE) -C Documentation install-man - -install-html: - $(MAKE) -C Documentation install-html - -install-info: - $(MAKE) -C Documentation install-info - -install-pdf: - $(MAKE) -C Documentation install-pdf - -quick-install-doc: - $(MAKE) -C Documentation quick-install - -quick-install-man: - $(MAKE) -C Documentation quick-install-man - -quick-install-html: - $(MAKE) -C Documentation quick-install-html - - - ### Maintainer's dist rules perf.spec: perf.spec.in @@ -904,38 +792,16 @@ dist: perf.spec perf-archive$(X) configure @mkdir -p $(PERF_TARNAME) @cp perf.spec configure $(PERF_TARNAME) @echo $(PERF_VERSION) > $(PERF_TARNAME)/version - @$(MAKE) -C perf-gui TARDIR=../$(PERF_TARNAME)/perf-gui dist-version $(TAR) rf $(PERF_TARNAME).tar \ $(PERF_TARNAME)/perf.spec \ $(PERF_TARNAME)/configure \ - $(PERF_TARNAME)/version \ - $(PERF_TARNAME)/perf-gui/version + $(PERF_TARNAME)/version @$(RM) -r $(PERF_TARNAME) gzip -f -9 $(PERF_TARNAME).tar rpm: dist $(RPMBUILD) -ta $(PERF_TARNAME).tar.gz -htmldocs = perf-htmldocs-$(PERF_VERSION) -manpages = perf-manpages-$(PERF_VERSION) -dist-doc: - $(RM) -r .doc-tmp-dir - mkdir .doc-tmp-dir - $(MAKE) -C Documentation WEBDOC_DEST=../.doc-tmp-dir install-webdoc - cd .doc-tmp-dir && $(TAR) cf ../$(htmldocs).tar . - gzip -n -9 -f $(htmldocs).tar - : - $(RM) -r .doc-tmp-dir - mkdir -p .doc-tmp-dir/man1 .doc-tmp-dir/man5 .doc-tmp-dir/man7 - $(MAKE) -C Documentation DESTDIR=./ \ - man1dir=../.doc-tmp-dir/man1 \ - man5dir=../.doc-tmp-dir/man5 \ - man7dir=../.doc-tmp-dir/man7 \ - install - cd .doc-tmp-dir && $(TAR) cf ../$(manpages).tar . - gzip -n -9 -f $(manpages).tar - $(RM) -r .doc-tmp-dir - ### Cleaning rules distclean: clean @@ -951,74 +817,13 @@ clean: $(RM) -r $(PERF_TARNAME) .doc-tmp-dir $(RM) $(PERF_TARNAME).tar.gz perf-core_$(PERF_VERSION)-*.tar.gz $(RM) $(htmldocs).tar.gz $(manpages).tar.gz - $(MAKE) -C Documentation/ clean - $(MAKE) -C templates/ clean - $(MAKE) -C t/ clean -ifndef NO_TCLTK - $(MAKE) -C perfk-perf clean - $(MAKE) -C perf-gui clean -endif - $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-GUI-VARS PERF-BUILD-OPTIONS + $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-BUILD-OPTIONS .PHONY: all install clean strip .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS .PHONY: .FORCE-PERF-BUILD-OPTIONS -### Check documentation -# -check-docs:: - @(for v in $(ALL_PROGRAMS) $(BUILT_INS) perf perfk; \ - do \ - case "$$v" in \ - perf-merge-octopus | perf-merge-ours | perf-merge-recursive | \ - perf-merge-resolve | perf-merge-subtree | \ - perf-fsck-objects | perf-init-db | \ - perf-?*--?* ) continue ;; \ - esac ; \ - test -f "Documentation/$$v.txt" || \ - echo "no doc: $$v"; \ - sed -e '/^#/d' command-list.txt | \ - grep -q "^$$v[ ]" || \ - case "$$v" in \ - perf) ;; \ - *) echo "no link: $$v";; \ - esac ; \ - done; \ - ( \ - sed -e '/^#/d' \ - -e 's/[ ].*//' \ - -e 's/^/listed /' command-list.txt; \ - ls -1 Documentation/perf*txt | \ - sed -e 's|Documentation/|documented |' \ - -e 's/\.txt//'; \ - ) | while read how cmd; \ - do \ - case "$$how,$$cmd" in \ - *,perf-citool | \ - *,perf-gui | \ - *,perf-help | \ - documented,perfattributes | \ - documented,perfignore | \ - documented,perfmodules | \ - documented,perfcli | \ - documented,perf-tools | \ - documented,perfcore-tutorial | \ - documented,perfcvs-migration | \ - documented,perfdiffcore | \ - documented,perfglossary | \ - documented,perfhooks | \ - documented,perfrepository-layout | \ - documented,perftutorial | \ - documented,perftutorial-2 | \ - sentinel,not,matching,is,ok ) continue ;; \ - esac; \ - case " $(ALL_PROGRAMS) $(BUILT_INS) perf perfk " in \ - *" $$cmd "*) ;; \ - *) echo "removed but $$how: $$cmd" ;; \ - esac; \ - done ) | sort - ### Make sure built-ins do not have dups and listed in perf.c # check-builtins:: diff --git a/Documentation/perf_counter/builtin-help.c b/Documentation/perf_counter/builtin-help.c index 125fcc2f4901..a136d619db37 100644 --- a/Documentation/perf_counter/builtin-help.c +++ b/Documentation/perf_counter/builtin-help.c @@ -417,11 +417,9 @@ static void show_html_page(const char *perf_cmd) int cmd_help(int argc, const char **argv, const char *prefix) { - int nonperf; const char *alias; load_command_list("perf-", &main_cmds, &other_cmds); - /* setup_perf_directory_gently(&nonperf); */ perf_config(perf_help_config, NULL); argc = parse_options(argc, argv, builtin_help_options, diff --git a/Documentation/perf_counter/builtin-top.c b/Documentation/perf_counter/builtin-top.c index 9d2c769e5f83..601bddbc30d5 100644 --- a/Documentation/perf_counter/builtin-top.c +++ b/Documentation/perf_counter/builtin-top.c @@ -63,15 +63,6 @@ #include "util.h" -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -103,8 +94,6 @@ #define PR_TASK_PERF_COUNTERS_DISABLE 31 #define PR_TASK_PERF_COUNTERS_ENABLE 32 -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - #define rdclock() \ ({ \ struct timespec ts; \ @@ -1077,7 +1066,7 @@ static void process_event(uint64_t ip, int counter) record_ip(ip, counter); } -static void process_options(int argc, char *argv[]) +static void process_options(int argc, char **argv) { int error = 0, counter; @@ -1255,7 +1244,7 @@ static void mmap_read(struct mmap_data *md) event_t event_copy; - unsigned int size = event->header.size; + size_t size = event->header.size; /* * Event straddles the mmap boundary -- header should always @@ -1301,7 +1290,7 @@ static void mmap_read(struct mmap_data *md) md->prev = old; } -int cmd_top(int argc, const char **argv, const char *prefix) +int cmd_top(int argc, char **argv, const char *prefix) { struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; diff --git a/Documentation/perf_counter/cache.h b/Documentation/perf_counter/cache.h index dc085640a57d..71080512fa86 100644 --- a/Documentation/perf_counter/cache.h +++ b/Documentation/perf_counter/cache.h @@ -94,4 +94,24 @@ static inline int is_absolute_path(const char *path) { return path[0] == '/'; } + +const char *make_absolute_path(const char *path); +const char *make_nonrelative_path(const char *path); +const char *make_relative_path(const char *abs, const char *base); +int normalize_path_copy(char *dst, const char *src); +int longest_ancestor_length(const char *path, const char *prefix_list); +char *strip_path_suffix(const char *path, const char *suffix); + +extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); +extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2))); + +extern char *mksnpath(char *buf, size_t n, const char *fmt, ...) + __attribute__((format (printf, 3, 4))); +extern char *perf_snpath(char *buf, size_t n, const char *fmt, ...) + __attribute__((format (printf, 3, 4))); +extern char *perf_pathdup(const char *fmt, ...) + __attribute__((format (printf, 1, 2))); + +extern size_t strlcpy(char *dest, const char *src, size_t size); + #endif /* CACHE_H */ diff --git a/Documentation/perf_counter/config.c b/Documentation/perf_counter/config.c index 672d53959334..3dd13faa6a27 100644 --- a/Documentation/perf_counter/config.c +++ b/Documentation/perf_counter/config.c @@ -15,7 +15,6 @@ static FILE *config_file; static const char *config_file_name; static int config_linenr; static int config_file_eof; -static int zlib_compression_seen; const char *config_exclusive_filename = NULL; @@ -533,14 +532,6 @@ static int store_aux(const char* key, const char* value, void *cb) return 0; } -static int write_error(const char *filename) -{ - error("failed to write new configuration file %s", filename); - - /* Same error code as "failed to rename". */ - return 4; -} - static int store_write_section(int fd, const char* key) { const char *dot; @@ -673,7 +664,7 @@ int perf_config_set_multivar(const char* key, const char* value, { int i, dot; int fd = -1, in_fd; - int ret; + int ret = 0; char* config_filename; const char* last_dot = strrchr(key, '.'); @@ -872,90 +863,6 @@ write_err_out: } -static int section_name_match (const char *buf, const char *name) -{ - int i = 0, j = 0, dot = 0; - for (; buf[i] && buf[i] != ']'; i++) { - if (!dot && isspace(buf[i])) { - dot = 1; - if (name[j++] != '.') - break; - for (i++; isspace(buf[i]); i++) - ; /* do nothing */ - if (buf[i] != '"') - break; - continue; - } - if (buf[i] == '\\' && dot) - i++; - else if (buf[i] == '"' && dot) { - for (i++; isspace(buf[i]); i++) - ; /* do_nothing */ - break; - } - if (buf[i] != name[j++]) - break; - } - return (buf[i] == ']' && name[j] == 0); -} - -/* if new_name == NULL, the section is removed instead */ -int perf_config_rename_section(const char *old_name, const char *new_name) -{ - int ret = 0, remove = 0; - char *config_filename; - int out_fd; - char buf[1024]; - - if (config_exclusive_filename) - config_filename = strdup(config_exclusive_filename); - else - config_filename = perf_pathdup("config"); - if (out_fd < 0) { - ret = error("could not lock config file %s", config_filename); - goto out; - } - - if (!(config_file = fopen(config_filename, "rb"))) { - /* no config file means nothing to rename, no error */ - goto unlock_and_out; - } - - while (fgets(buf, sizeof(buf), config_file)) { - int i; - int length; - for (i = 0; buf[i] && isspace(buf[i]); i++) - ; /* do nothing */ - if (buf[i] == '[') { - /* it's a section */ - if (section_name_match (&buf[i+1], old_name)) { - ret++; - if (new_name == NULL) { - remove = 1; - continue; - } - store.baselen = strlen(new_name); - if (!store_write_section(out_fd, new_name)) { - goto out; - } - continue; - } - remove = 0; - } - if (remove) - continue; - length = strlen(buf); - if (write_in_full(out_fd, buf, length) != length) { - goto out; - } - } - fclose(config_file); - unlock_and_out: - out: - free(config_filename); - return ret; -} - /* * Call this to report error for your variable that should not * get a boolean value (i.e. "[my] var" means "true"). diff --git a/Documentation/perf_counter/path.c b/Documentation/perf_counter/path.c index 891b612ec1a9..a501a40dd2cb 100644 --- a/Documentation/perf_counter/path.c +++ b/Documentation/perf_counter/path.c @@ -161,45 +161,6 @@ int perf_mkstemp(char *path, size_t len, const char *template) } -static char *user_path(char *buf, char *path, int sz) -{ - struct passwd *pw; - char *slash; - int len, baselen; - - if (!path || path[0] != '~') - return NULL; - path++; - slash = strchr(path, '/'); - if (path[0] == '/' || !path[0]) { - pw = getpwuid(getuid()); - } - else { - if (slash) { - *slash = 0; - pw = getpwnam(path); - *slash = '/'; - } - else - pw = getpwnam(path); - } - if (!pw || !pw->pw_dir || sz <= strlen(pw->pw_dir)) - return NULL; - baselen = strlen(pw->pw_dir); - memcpy(buf, pw->pw_dir, baselen); - while ((1 < baselen) && (buf[baselen-1] == '/')) { - buf[baselen-1] = 0; - baselen--; - } - if (slash && slash[1]) { - len = strlen(slash); - if (sz <= baselen + len) - return NULL; - memcpy(buf + baselen, slash, len + 1); - } - return buf; -} - const char *make_relative_path(const char *abs, const char *base) { static char buf[PATH_MAX + 1]; diff --git a/Documentation/perf_counter/perf.c b/Documentation/perf_counter/perf.c index 9256f6a16446..63f8a892c0df 100644 --- a/Documentation/perf_counter/perf.c +++ b/Documentation/perf_counter/perf.c @@ -1,7 +1,7 @@ #include "builtin.h" #include "exec_cmd.h" #include "cache.h" -//#include "quote.h" +#include "quote.h" #include "run-command.h" const char perf_usage_string[] = @@ -132,7 +132,6 @@ static int handle_alias(int *argcp, const char ***argv) const char** new_argv; const char *alias_command; char *alias_string; - int unused_nonperf; alias_command = (*argv)[0]; alias_string = alias_lookup(alias_command); diff --git a/Documentation/perf_counter/util.h b/Documentation/perf_counter/util.h index 13f8bdce7600..36e40c38e093 100644 --- a/Documentation/perf_counter/util.h +++ b/Documentation/perf_counter/util.h @@ -295,6 +295,20 @@ static inline char *gitstrchrnul(const char *s, int c) } #endif +/* + * Wrappers: + */ +extern char *xstrdup(const char *str); +extern void *xmalloc(size_t size); +extern void *xmemdupz(const void *data, size_t len); +extern char *xstrndup(const char *str, size_t len); +extern void *xrealloc(void *ptr, size_t size); +extern void *xcalloc(size_t nmemb, size_t size); +extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); +extern ssize_t xread(int fd, void *buf, size_t len); +extern ssize_t xwrite(int fd, const void *buf, size_t len); +extern int xdup(int fd); +extern FILE *xfdopen(int fd, const char *mode); static inline size_t xsize_t(off_t len) { return (size_t)len; -- GitLab From ddcacfa0febff6454dba6cea1931f3020a9f6c24 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 15:37:32 +0200 Subject: [PATCH 0446/6080] perf_counter tools: separate kerneltop into 'perf top' and 'perf stat' Lets use the Git framework of built-in commands. Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 1 + Documentation/perf_counter/builtin-stat.c | 592 ++++++++ Documentation/perf_counter/builtin-top.c | 204 +-- Documentation/perf_counter/builtin.h | 3 +- Documentation/perf_counter/command-list.txt | 1 + Documentation/perf_counter/kerneltop.c | 1409 ------------------- Documentation/perf_counter/perf.c | 1 + 7 files changed, 601 insertions(+), 1610 deletions(-) create mode 100644 Documentation/perf_counter/builtin-stat.c delete mode 100644 Documentation/perf_counter/kerneltop.c diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index 1b6026555547..fb8b71744e59 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -309,6 +309,7 @@ LIB_OBJS += usage.o LIB_OBJS += wrapper.o BUILTIN_OBJS += builtin-help.o +BUILTIN_OBJS += builtin-stat.o BUILTIN_OBJS += builtin-top.o PERFLIBS = $(LIB_FILE) diff --git a/Documentation/perf_counter/builtin-stat.c b/Documentation/perf_counter/builtin-stat.c new file mode 100644 index 000000000000..169a2d1783fc --- /dev/null +++ b/Documentation/perf_counter/builtin-stat.c @@ -0,0 +1,592 @@ +/* + * kerneltop.c: show top kernel functions - performance counters showcase + + Build with: + + cc -O6 -Wall -c -o kerneltop.o kerneltop.c -lrt + + Sample output: + +------------------------------------------------------------------------------ + KernelTop: 2669 irqs/sec [NMI, cache-misses/cache-refs], (all, cpu: 2) +------------------------------------------------------------------------------ + + weight RIP kernel function + ______ ________________ _______________ + + 35.20 - ffffffff804ce74b : skb_copy_and_csum_dev + 33.00 - ffffffff804cb740 : sock_alloc_send_skb + 31.26 - ffffffff804ce808 : skb_push + 22.43 - ffffffff80510004 : tcp_established_options + 19.00 - ffffffff8027d250 : find_get_page + 15.76 - ffffffff804e4fc9 : eth_type_trans + 15.20 - ffffffff804d8baa : dst_release + 14.86 - ffffffff804cf5d8 : skb_release_head_state + 14.00 - ffffffff802217d5 : read_hpet + 12.00 - ffffffff804ffb7f : __ip_local_out + 11.97 - ffffffff804fc0c8 : ip_local_deliver_finish + 8.54 - ffffffff805001a3 : ip_queue_xmit + */ + +/* + * perfstat: /usr/bin/time -alike performance counter statistics utility + + It summarizes the counter events of all tasks (and child tasks), + covering all CPUs that the command (or workload) executes on. + It only counts the per-task events of the workload started, + independent of how many other tasks run on those CPUs. + + Sample output: + + $ ./perfstat -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null + + Performance counter stats for 'ls': + + 163516953 instructions + 2295 cache-misses + 2855182 branch-misses + */ + + /* + * Copyright (C) 2008, Red Hat Inc, Ingo Molnar + * + * Improvements and fixes by: + * + * Arjan van de Ven + * Yanmin Zhang + * Wu Fengguang + * Mike Galbraith + * Paul Mackerras + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../../include/linux/perf_counter.h" + + +/* + * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all + * counters in the current task. + */ +#define PR_TASK_PERF_COUNTERS_DISABLE 31 +#define PR_TASK_PERF_COUNTERS_ENABLE 32 + +#define rdclock() \ +({ \ + struct timespec ts; \ + \ + clock_gettime(CLOCK_MONOTONIC, &ts); \ + ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ +}) + +/* + * Pick up some kernel type conventions: + */ +#define __user +#define asmlinkage + +#ifdef __x86_64__ +#define __NR_perf_counter_open 295 +#define rmb() asm volatile("lfence" ::: "memory") +#define cpu_relax() asm volatile("rep; nop" ::: "memory"); +#endif + +#ifdef __i386__ +#define __NR_perf_counter_open 333 +#define rmb() asm volatile("lfence" ::: "memory") +#define cpu_relax() asm volatile("rep; nop" ::: "memory"); +#endif + +#ifdef __powerpc__ +#define __NR_perf_counter_open 319 +#define rmb() asm volatile ("sync" ::: "memory") +#define cpu_relax() asm volatile ("" ::: "memory"); +#endif + +#define unlikely(x) __builtin_expect(!!(x), 0) +#define min(x, y) ({ \ + typeof(x) _min1 = (x); \ + typeof(y) _min2 = (y); \ + (void) (&_min1 == &_min2); \ + _min1 < _min2 ? _min1 : _min2; }) + +extern asmlinkage int sys_perf_counter_open( + struct perf_counter_hw_event *hw_event_uptr __user, + pid_t pid, + int cpu, + int group_fd, + unsigned long flags); + +#define MAX_COUNTERS 64 +#define MAX_NR_CPUS 256 + +#define EID(type, id) (((__u64)(type) << PERF_COUNTER_TYPE_SHIFT) | (id)) + +static int system_wide = 0; + +static int nr_counters = 0; +static __u64 event_id[MAX_COUNTERS] = { + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), + EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), + + EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), + EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), + EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), + EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), +}; +static int default_interval = 100000; +static int event_count[MAX_COUNTERS]; +static int fd[MAX_NR_CPUS][MAX_COUNTERS]; + +static int tid = -1; +static int profile_cpu = -1; +static int nr_cpus = 0; +static int nmi = 1; +static int group = 0; +static unsigned int page_size; + +static int zero; + +static int scale; + +static const unsigned int default_count[] = { + 1000000, + 1000000, + 10000, + 10000, + 1000000, + 10000, +}; + +static char *hw_event_names[] = { + "CPU cycles", + "instructions", + "cache references", + "cache misses", + "branches", + "branch misses", + "bus cycles", +}; + +static char *sw_event_names[] = { + "cpu clock ticks", + "task clock ticks", + "pagefaults", + "context switches", + "CPU migrations", + "minor faults", + "major faults", +}; + +struct event_symbol { + __u64 event; + char *symbol; +}; + +static struct event_symbol event_symbols[] = { + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cpu-cycles", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cycles", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), "instructions", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), "cache-references", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), "cache-misses", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branch-instructions", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branches", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_MISSES), "branch-misses", }, + {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BUS_CYCLES), "bus-cycles", }, + + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK), "cpu-clock", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), "task-clock", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "page-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MIN), "minor-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MAJ), "major-faults", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "context-switches", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "cs", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "cpu-migrations", }, + {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "migrations", }, +}; + +#define __PERF_COUNTER_FIELD(config, name) \ + ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT) + +#define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW) +#define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG) +#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE) +#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT) + +static void display_events_help(void) +{ + unsigned int i; + __u64 e; + + printf( + " -e EVENT --event=EVENT # symbolic-name abbreviations"); + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + int type, id; + + e = event_symbols[i].event; + type = PERF_COUNTER_TYPE(e); + id = PERF_COUNTER_ID(e); + + printf("\n %d:%d: %-20s", + type, id, event_symbols[i].symbol); + } + + printf("\n" + " rNNN: raw PMU events (eventsel+umask)\n\n"); +} + +static void display_help(void) +{ + printf( + "Usage: perfstat [] \n\n" + "PerfStat Options (up to %d event types can be specified):\n\n", + MAX_COUNTERS); + + display_events_help(); + + printf( + " -l # scale counter values\n" + " -a # system-wide collection\n"); + exit(0); +} + +static char *event_name(int ctr) +{ + __u64 config = event_id[ctr]; + int type = PERF_COUNTER_TYPE(config); + int id = PERF_COUNTER_ID(config); + static char buf[32]; + + if (PERF_COUNTER_RAW(config)) { + sprintf(buf, "raw 0x%llx", PERF_COUNTER_CONFIG(config)); + return buf; + } + + switch (type) { + case PERF_TYPE_HARDWARE: + if (id < PERF_HW_EVENTS_MAX) + return hw_event_names[id]; + return "unknown-hardware"; + + case PERF_TYPE_SOFTWARE: + if (id < PERF_SW_EVENTS_MAX) + return sw_event_names[id]; + return "unknown-software"; + + default: + break; + } + + return "unknown"; +} + +/* + * Each event can have multiple symbolic names. + * Symbolic names are (almost) exactly matched. + */ +static __u64 match_event_symbols(char *str) +{ + __u64 config, id; + int type; + unsigned int i; + + if (sscanf(str, "r%llx", &config) == 1) + return config | PERF_COUNTER_RAW_MASK; + + if (sscanf(str, "%d:%llu", &type, &id) == 2) + return EID(type, id); + + for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { + if (!strncmp(str, event_symbols[i].symbol, + strlen(event_symbols[i].symbol))) + return event_symbols[i].event; + } + + return ~0ULL; +} + +static int parse_events(char *str) +{ + __u64 config; + +again: + if (nr_counters == MAX_COUNTERS) + return -1; + + config = match_event_symbols(str); + if (config == ~0ULL) + return -1; + + event_id[nr_counters] = config; + nr_counters++; + + str = strstr(str, ","); + if (str) { + str++; + goto again; + } + + return 0; +} + + +/* + * perfstat + */ + +char fault_here[1000000]; + +static void create_perfstat_counter(int counter) +{ + struct perf_counter_hw_event hw_event; + + memset(&hw_event, 0, sizeof(hw_event)); + hw_event.config = event_id[counter]; + hw_event.record_type = 0; + hw_event.nmi = 0; + if (scale) + hw_event.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | + PERF_FORMAT_TOTAL_TIME_RUNNING; + + if (system_wide) { + int cpu; + for (cpu = 0; cpu < nr_cpus; cpu ++) { + fd[cpu][counter] = sys_perf_counter_open(&hw_event, -1, cpu, -1, 0); + if (fd[cpu][counter] < 0) { + printf("perfstat error: syscall returned with %d (%s)\n", + fd[cpu][counter], strerror(errno)); + exit(-1); + } + } + } else { + hw_event.inherit = 1; + hw_event.disabled = 1; + + fd[0][counter] = sys_perf_counter_open(&hw_event, 0, -1, -1, 0); + if (fd[0][counter] < 0) { + printf("perfstat error: syscall returned with %d (%s)\n", + fd[0][counter], strerror(errno)); + exit(-1); + } + } +} + +int do_perfstat(int argc, char *argv[]) +{ + unsigned long long t0, t1; + int counter; + ssize_t res; + int status; + int pid; + + if (!system_wide) + nr_cpus = 1; + + for (counter = 0; counter < nr_counters; counter++) + create_perfstat_counter(counter); + + argc -= optind; + argv += optind; + + if (!argc) + display_help(); + + /* + * Enable counters and exec the command: + */ + t0 = rdclock(); + prctl(PR_TASK_PERF_COUNTERS_ENABLE); + + if ((pid = fork()) < 0) + perror("failed to fork"); + if (!pid) { + if (execvp(argv[0], argv)) { + perror(argv[0]); + exit(-1); + } + } + while (wait(&status) >= 0) + ; + prctl(PR_TASK_PERF_COUNTERS_DISABLE); + t1 = rdclock(); + + fflush(stdout); + + fprintf(stderr, "\n"); + fprintf(stderr, " Performance counter stats for \'%s\':\n", + argv[0]); + fprintf(stderr, "\n"); + + for (counter = 0; counter < nr_counters; counter++) { + int cpu, nv; + __u64 count[3], single_count[3]; + int scaled; + + count[0] = count[1] = count[2] = 0; + nv = scale ? 3 : 1; + for (cpu = 0; cpu < nr_cpus; cpu ++) { + res = read(fd[cpu][counter], + single_count, nv * sizeof(__u64)); + assert(res == nv * sizeof(__u64)); + + count[0] += single_count[0]; + if (scale) { + count[1] += single_count[1]; + count[2] += single_count[2]; + } + } + + scaled = 0; + if (scale) { + if (count[2] == 0) { + fprintf(stderr, " %14s %-20s\n", + "", event_name(counter)); + continue; + } + if (count[2] < count[1]) { + scaled = 1; + count[0] = (unsigned long long) + ((double)count[0] * count[1] / count[2] + 0.5); + } + } + + if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK) || + event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK)) { + + double msecs = (double)count[0] / 1000000; + + fprintf(stderr, " %14.6f %-20s (msecs)", + msecs, event_name(counter)); + } else { + fprintf(stderr, " %14Ld %-20s (events)", + count[0], event_name(counter)); + } + if (scaled) + fprintf(stderr, " (scaled from %.2f%%)", + (double) count[2] / count[1] * 100); + fprintf(stderr, "\n"); + } + fprintf(stderr, "\n"); + fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", + (double)(t1-t0)/1e6); + fprintf(stderr, "\n"); + + return 0; +} + +static void process_options(int argc, char **argv) +{ + int error = 0, counter; + + for (;;) { + int option_index = 0; + /** Options for getopt */ + static struct option long_options[] = { + {"count", required_argument, NULL, 'c'}, + {"cpu", required_argument, NULL, 'C'}, + {"delay", required_argument, NULL, 'd'}, + {"dump_symtab", no_argument, NULL, 'D'}, + {"event", required_argument, NULL, 'e'}, + {"filter", required_argument, NULL, 'f'}, + {"group", required_argument, NULL, 'g'}, + {"help", no_argument, NULL, 'h'}, + {"nmi", required_argument, NULL, 'n'}, + {"munmap_info", no_argument, NULL, 'U'}, + {"pid", required_argument, NULL, 'p'}, + {"realtime", required_argument, NULL, 'r'}, + {"scale", no_argument, NULL, 'l'}, + {"symbol", required_argument, NULL, 's'}, + {"stat", no_argument, NULL, 'S'}, + {"vmlinux", required_argument, NULL, 'x'}, + {"zero", no_argument, NULL, 'z'}, + {NULL, 0, NULL, 0 } + }; + int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hln:m:p:r:s:Sx:zMU", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'a': system_wide = 1; break; + case 'c': default_interval = atoi(optarg); break; + case 'C': + /* CPU and PID are mutually exclusive */ + if (tid != -1) { + printf("WARNING: CPU switch overriding PID\n"); + sleep(1); + tid = -1; + } + profile_cpu = atoi(optarg); break; + + case 'e': error = parse_events(optarg); break; + + case 'g': group = atoi(optarg); break; + case 'h': display_help(); break; + case 'l': scale = 1; break; + case 'n': nmi = atoi(optarg); break; + case 'p': + /* CPU and PID are mutually exclusive */ + if (profile_cpu != -1) { + printf("WARNING: PID switch overriding CPU\n"); + sleep(1); + profile_cpu = -1; + } + tid = atoi(optarg); break; + case 'z': zero = 1; break; + default: error = 1; break; + } + } + if (error) + display_help(); + + if (!nr_counters) { + nr_counters = 8; + } + + for (counter = 0; counter < nr_counters; counter++) { + if (event_count[counter]) + continue; + + event_count[counter] = default_interval; + } +} + +int cmd_stat(int argc, char **argv, const char *prefix) +{ + page_size = sysconf(_SC_PAGE_SIZE); + + process_options(argc, argv); + + nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); + assert(nr_cpus <= MAX_NR_CPUS); + assert(nr_cpus >= 0); + + return do_perfstat(argc, argv); +} diff --git a/Documentation/perf_counter/builtin-top.c b/Documentation/perf_counter/builtin-top.c index 601bddbc30d5..98e8690b6bcb 100644 --- a/Documentation/perf_counter/builtin-top.c +++ b/Documentation/perf_counter/builtin-top.c @@ -28,25 +28,6 @@ 8.54 - ffffffff805001a3 : ip_queue_xmit */ -/* - * perfstat: /usr/bin/time -alike performance counter statistics utility - - It summarizes the counter events of all tasks (and child tasks), - covering all CPUs that the command (or workload) executes on. - It only counts the per-task events of the workload started, - independent of how many other tasks run on those CPUs. - - Sample output: - - $ ./perfstat -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null - - Performance counter stats for 'ls': - - 163516953 instructions - 2295 cache-misses - 2855182 branch-misses - */ - /* * Copyright (C) 2008, Red Hat Inc, Ingo Molnar * @@ -149,7 +130,6 @@ asmlinkage int sys_perf_counter_open( #define EID(type, id) (((__u64)(type) << PERF_COUNTER_TYPE_SHIFT) | (id)) -static int run_perfstat = 0; static int system_wide = 0; static int nr_counters = 0; @@ -203,7 +183,7 @@ struct source_line { static struct source_line *lines; static struct source_line **lines_tail; -const unsigned int default_count[] = { +static const unsigned int default_count[] = { 1000000, 1000000, 10000, @@ -291,26 +271,8 @@ static void display_events_help(void) " rNNN: raw PMU events (eventsel+umask)\n\n"); } -static void display_perfstat_help(void) -{ - printf( - "Usage: perfstat [] \n\n" - "PerfStat Options (up to %d event types can be specified):\n\n", - MAX_COUNTERS); - - display_events_help(); - - printf( - " -l # scale counter values\n" - " -a # system-wide collection\n"); - exit(0); -} - static void display_help(void) { - if (run_perfstat) - return display_perfstat_help(); - printf( "Usage: kerneltop []\n" " Or: kerneltop -S [] COMMAND [ARGS]\n\n" @@ -320,8 +282,6 @@ static void display_help(void) display_events_help(); printf( - " -S --stat # perfstat COMMAND\n" - " -a # system-wide collection (for perfstat)\n\n" " -c CNT --count=CNT # event period to sample\n\n" " -C CPU --cpu=CPU # CPU (-1 for all) [default: -1]\n" " -p PID --pid=PID # PID of sampled task (-1 for all) [default: -1]\n\n" @@ -420,151 +380,6 @@ again: return 0; } - -/* - * perfstat - */ - -char fault_here[1000000]; - -static void create_perfstat_counter(int counter) -{ - struct perf_counter_hw_event hw_event; - - memset(&hw_event, 0, sizeof(hw_event)); - hw_event.config = event_id[counter]; - hw_event.record_type = 0; - hw_event.nmi = 0; - if (scale) - hw_event.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | - PERF_FORMAT_TOTAL_TIME_RUNNING; - - if (system_wide) { - int cpu; - for (cpu = 0; cpu < nr_cpus; cpu ++) { - fd[cpu][counter] = sys_perf_counter_open(&hw_event, -1, cpu, -1, 0); - if (fd[cpu][counter] < 0) { - printf("perfstat error: syscall returned with %d (%s)\n", - fd[cpu][counter], strerror(errno)); - exit(-1); - } - } - } else { - hw_event.inherit = 1; - hw_event.disabled = 1; - - fd[0][counter] = sys_perf_counter_open(&hw_event, 0, -1, -1, 0); - if (fd[0][counter] < 0) { - printf("perfstat error: syscall returned with %d (%s)\n", - fd[0][counter], strerror(errno)); - exit(-1); - } - } -} - -int do_perfstat(int argc, char *argv[]) -{ - unsigned long long t0, t1; - int counter; - ssize_t res; - int status; - int pid; - - if (!system_wide) - nr_cpus = 1; - - for (counter = 0; counter < nr_counters; counter++) - create_perfstat_counter(counter); - - argc -= optind; - argv += optind; - - if (!argc) - display_help(); - - /* - * Enable counters and exec the command: - */ - t0 = rdclock(); - prctl(PR_TASK_PERF_COUNTERS_ENABLE); - - if ((pid = fork()) < 0) - perror("failed to fork"); - if (!pid) { - if (execvp(argv[0], argv)) { - perror(argv[0]); - exit(-1); - } - } - while (wait(&status) >= 0) - ; - prctl(PR_TASK_PERF_COUNTERS_DISABLE); - t1 = rdclock(); - - fflush(stdout); - - fprintf(stderr, "\n"); - fprintf(stderr, " Performance counter stats for \'%s\':\n", - argv[0]); - fprintf(stderr, "\n"); - - for (counter = 0; counter < nr_counters; counter++) { - int cpu, nv; - __u64 count[3], single_count[3]; - int scaled; - - count[0] = count[1] = count[2] = 0; - nv = scale ? 3 : 1; - for (cpu = 0; cpu < nr_cpus; cpu ++) { - res = read(fd[cpu][counter], - single_count, nv * sizeof(__u64)); - assert(res == nv * sizeof(__u64)); - - count[0] += single_count[0]; - if (scale) { - count[1] += single_count[1]; - count[2] += single_count[2]; - } - } - - scaled = 0; - if (scale) { - if (count[2] == 0) { - fprintf(stderr, " %14s %-20s\n", - "", event_name(counter)); - continue; - } - if (count[2] < count[1]) { - scaled = 1; - count[0] = (unsigned long long) - ((double)count[0] * count[1] / count[2] + 0.5); - } - } - - if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK) || - event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK)) { - - double msecs = (double)count[0] / 1000000; - - fprintf(stderr, " %14.6f %-20s (msecs)", - msecs, event_name(counter)); - } else { - fprintf(stderr, " %14Ld %-20s (events)", - count[0], event_name(counter)); - } - if (scaled) - fprintf(stderr, " (scaled from %.2f%%)", - (double) count[2] / count[1] * 100); - fprintf(stderr, "\n"); - } - fprintf(stderr, "\n"); - fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", - (double)(t1-t0)/1e6); - fprintf(stderr, "\n"); - - return 0; -} - /* * Symbols */ @@ -805,7 +620,7 @@ static int read_symbol(FILE *in, struct sym_entry *s) return 0; } -int compare_addr(const void *__sym1, const void *__sym2) +static int compare_addr(const void *__sym1, const void *__sym2) { const struct sym_entry *sym1 = __sym1, *sym2 = __sym2; @@ -1070,9 +885,6 @@ static void process_options(int argc, char **argv) { int error = 0, counter; - if (strstr(argv[0], "perfstat")) - run_perfstat = 1; - for (;;) { int option_index = 0; /** Options for getopt */ @@ -1134,7 +946,6 @@ static void process_options(int argc, char **argv) tid = atoi(optarg); break; case 'r': realtime_prio = atoi(optarg); break; case 's': sym_filter = strdup(optarg); break; - case 'S': run_perfstat = 1; break; case 'x': vmlinux = strdup(optarg); break; case 'z': zero = 1; break; case 'm': mmap_pages = atoi(optarg); break; @@ -1147,12 +958,8 @@ static void process_options(int argc, char **argv) display_help(); if (!nr_counters) { - if (run_perfstat) - nr_counters = 8; - else { - nr_counters = 1; - event_id[0] = 0; - } + nr_counters = 1; + event_id[0] = 0; } for (counter = 0; counter < nr_counters; counter++) { @@ -1308,9 +1115,6 @@ int cmd_top(int argc, char **argv, const char *prefix) assert(nr_cpus <= MAX_NR_CPUS); assert(nr_cpus >= 0); - if (run_perfstat) - return do_perfstat(argc, argv); - if (tid != -1 || profile_cpu != -1) nr_cpus = 1; diff --git a/Documentation/perf_counter/builtin.h b/Documentation/perf_counter/builtin.h index 41637444ce2d..a3bb6cd6bed3 100644 --- a/Documentation/perf_counter/builtin.h +++ b/Documentation/perf_counter/builtin.h @@ -14,5 +14,6 @@ extern void prune_packed_objects(int); extern int read_line_with_nul(char *buf, int size, FILE *file); extern int check_pager_config(const char *cmd); -extern int cmd_top(int argc, const char **argv, const char *prefix); +extern int cmd_top(int argc, char **argv, const char *prefix); +extern int cmd_stat(int argc, char **argv, const char *prefix); #endif diff --git a/Documentation/perf_counter/command-list.txt b/Documentation/perf_counter/command-list.txt index 1eab3659b206..52455d46bfb5 100644 --- a/Documentation/perf_counter/command-list.txt +++ b/Documentation/perf_counter/command-list.txt @@ -1,4 +1,5 @@ # List of known perf commands. # command name category [deprecated] [common] perf-top mainporcelain common +perf-stat mainporcelain common diff --git a/Documentation/perf_counter/kerneltop.c b/Documentation/perf_counter/kerneltop.c deleted file mode 100644 index 042c1b83a872..000000000000 --- a/Documentation/perf_counter/kerneltop.c +++ /dev/null @@ -1,1409 +0,0 @@ -/* - * kerneltop.c: show top kernel functions - performance counters showcase - - Build with: - - cc -O6 -Wall -c -o kerneltop.o kerneltop.c -lrt - - Sample output: - ------------------------------------------------------------------------------- - KernelTop: 2669 irqs/sec [NMI, cache-misses/cache-refs], (all, cpu: 2) ------------------------------------------------------------------------------- - - weight RIP kernel function - ______ ________________ _______________ - - 35.20 - ffffffff804ce74b : skb_copy_and_csum_dev - 33.00 - ffffffff804cb740 : sock_alloc_send_skb - 31.26 - ffffffff804ce808 : skb_push - 22.43 - ffffffff80510004 : tcp_established_options - 19.00 - ffffffff8027d250 : find_get_page - 15.76 - ffffffff804e4fc9 : eth_type_trans - 15.20 - ffffffff804d8baa : dst_release - 14.86 - ffffffff804cf5d8 : skb_release_head_state - 14.00 - ffffffff802217d5 : read_hpet - 12.00 - ffffffff804ffb7f : __ip_local_out - 11.97 - ffffffff804fc0c8 : ip_local_deliver_finish - 8.54 - ffffffff805001a3 : ip_queue_xmit - */ - -/* - * perfstat: /usr/bin/time -alike performance counter statistics utility - - It summarizes the counter events of all tasks (and child tasks), - covering all CPUs that the command (or workload) executes on. - It only counts the per-task events of the workload started, - independent of how many other tasks run on those CPUs. - - Sample output: - - $ ./perfstat -e 1 -e 3 -e 5 ls -lR /usr/include/ >/dev/null - - Performance counter stats for 'ls': - - 163516953 instructions - 2295 cache-misses - 2855182 branch-misses - */ - - /* - * Copyright (C) 2008, Red Hat Inc, Ingo Molnar - * - * Improvements and fixes by: - * - * Arjan van de Ven - * Yanmin Zhang - * Wu Fengguang - * Mike Galbraith - * Paul Mackerras - * - * Released under the GPL v2. (and only v2, not any later version) - */ - -#define _GNU_SOURCE -#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/linux/perf_counter.h" - - -/* - * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all - * counters in the current task. - */ -#define PR_TASK_PERF_COUNTERS_DISABLE 31 -#define PR_TASK_PERF_COUNTERS_ENABLE 32 - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -#define rdclock() \ -({ \ - struct timespec ts; \ - \ - clock_gettime(CLOCK_MONOTONIC, &ts); \ - ts.tv_sec * 1000000000ULL + ts.tv_nsec; \ -}) - -/* - * Pick up some kernel type conventions: - */ -#define __user -#define asmlinkage - -#ifdef __x86_64__ -#define __NR_perf_counter_open 295 -#define rmb() asm volatile("lfence" ::: "memory") -#define cpu_relax() asm volatile("rep; nop" ::: "memory"); -#endif - -#ifdef __i386__ -#define __NR_perf_counter_open 333 -#define rmb() asm volatile("lfence" ::: "memory") -#define cpu_relax() asm volatile("rep; nop" ::: "memory"); -#endif - -#ifdef __powerpc__ -#define __NR_perf_counter_open 319 -#define rmb() asm volatile ("sync" ::: "memory") -#define cpu_relax() asm volatile ("" ::: "memory"); -#endif - -#define unlikely(x) __builtin_expect(!!(x), 0) -#define min(x, y) ({ \ - typeof(x) _min1 = (x); \ - typeof(y) _min2 = (y); \ - (void) (&_min1 == &_min2); \ - _min1 < _min2 ? _min1 : _min2; }) - -asmlinkage int sys_perf_counter_open( - struct perf_counter_hw_event *hw_event_uptr __user, - pid_t pid, - int cpu, - int group_fd, - unsigned long flags) -{ - return syscall( - __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); -} - -#define MAX_COUNTERS 64 -#define MAX_NR_CPUS 256 - -#define EID(type, id) (((__u64)(type) << PERF_COUNTER_TYPE_SHIFT) | (id)) - -static int run_perfstat = 0; -static int system_wide = 0; - -static int nr_counters = 0; -static __u64 event_id[MAX_COUNTERS] = { - EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), - EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), - EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), - EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), - - EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), - EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), - EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), - EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), -}; -static int default_interval = 100000; -static int event_count[MAX_COUNTERS]; -static int fd[MAX_NR_CPUS][MAX_COUNTERS]; - -static __u64 count_filter = 100; - -static int tid = -1; -static int profile_cpu = -1; -static int nr_cpus = 0; -static int nmi = 1; -static unsigned int realtime_prio = 0; -static int group = 0; -static unsigned int page_size; -static unsigned int mmap_pages = 16; -static int use_mmap = 0; -static int use_munmap = 0; - -static char *vmlinux; - -static char *sym_filter; -static unsigned long filter_start; -static unsigned long filter_end; - -static int delay_secs = 2; -static int zero; -static int dump_symtab; - -static int scale; - -struct source_line { - uint64_t EIP; - unsigned long count; - char *line; - struct source_line *next; -}; - -static struct source_line *lines; -static struct source_line **lines_tail; - -const unsigned int default_count[] = { - 1000000, - 1000000, - 10000, - 10000, - 1000000, - 10000, -}; - -static char *hw_event_names[] = { - "CPU cycles", - "instructions", - "cache references", - "cache misses", - "branches", - "branch misses", - "bus cycles", -}; - -static char *sw_event_names[] = { - "cpu clock ticks", - "task clock ticks", - "pagefaults", - "context switches", - "CPU migrations", - "minor faults", - "major faults", -}; - -struct event_symbol { - __u64 event; - char *symbol; -}; - -static struct event_symbol event_symbols[] = { - {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cpu-cycles", }, - {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CPU_CYCLES), "cycles", }, - {EID(PERF_TYPE_HARDWARE, PERF_COUNT_INSTRUCTIONS), "instructions", }, - {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_REFERENCES), "cache-references", }, - {EID(PERF_TYPE_HARDWARE, PERF_COUNT_CACHE_MISSES), "cache-misses", }, - {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branch-instructions", }, - {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_INSTRUCTIONS), "branches", }, - {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BRANCH_MISSES), "branch-misses", }, - {EID(PERF_TYPE_HARDWARE, PERF_COUNT_BUS_CYCLES), "bus-cycles", }, - - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK), "cpu-clock", }, - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK), "task-clock", }, - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "page-faults", }, - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS), "faults", }, - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MIN), "minor-faults", }, - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_PAGE_FAULTS_MAJ), "major-faults", }, - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "context-switches", }, - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CONTEXT_SWITCHES), "cs", }, - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "cpu-migrations", }, - {EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_MIGRATIONS), "migrations", }, -}; - -#define __PERF_COUNTER_FIELD(config, name) \ - ((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT) - -#define PERF_COUNTER_RAW(config) __PERF_COUNTER_FIELD(config, RAW) -#define PERF_COUNTER_CONFIG(config) __PERF_COUNTER_FIELD(config, CONFIG) -#define PERF_COUNTER_TYPE(config) __PERF_COUNTER_FIELD(config, TYPE) -#define PERF_COUNTER_ID(config) __PERF_COUNTER_FIELD(config, EVENT) - -static void display_events_help(void) -{ - unsigned int i; - __u64 e; - - printf( - " -e EVENT --event=EVENT # symbolic-name abbreviations"); - - for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { - int type, id; - - e = event_symbols[i].event; - type = PERF_COUNTER_TYPE(e); - id = PERF_COUNTER_ID(e); - - printf("\n %d:%d: %-20s", - type, id, event_symbols[i].symbol); - } - - printf("\n" - " rNNN: raw PMU events (eventsel+umask)\n\n"); -} - -static void display_perfstat_help(void) -{ - printf( - "Usage: perfstat [] \n\n" - "PerfStat Options (up to %d event types can be specified):\n\n", - MAX_COUNTERS); - - display_events_help(); - - printf( - " -l # scale counter values\n" - " -a # system-wide collection\n"); - exit(0); -} - -static void display_help(void) -{ - if (run_perfstat) - return display_perfstat_help(); - - printf( - "Usage: kerneltop []\n" - " Or: kerneltop -S [] COMMAND [ARGS]\n\n" - "KernelTop Options (up to %d event types can be specified at once):\n\n", - MAX_COUNTERS); - - display_events_help(); - - printf( - " -S --stat # perfstat COMMAND\n" - " -a # system-wide collection (for perfstat)\n\n" - " -c CNT --count=CNT # event period to sample\n\n" - " -C CPU --cpu=CPU # CPU (-1 for all) [default: -1]\n" - " -p PID --pid=PID # PID of sampled task (-1 for all) [default: -1]\n\n" - " -l # show scale factor for RR events\n" - " -d delay --delay= # sampling/display delay [default: 2]\n" - " -f CNT --filter=CNT # min-event-count filter [default: 100]\n\n" - " -r prio --realtime= # event acquisition runs with SCHED_FIFO policy\n" - " -s symbol --symbol= # function to be showed annotated one-shot\n" - " -x path --vmlinux= # the vmlinux binary, required for -s use\n" - " -z --zero # zero counts after display\n" - " -D --dump_symtab # dump symbol table to stderr on startup\n" - " -m pages --mmap_pages= # number of mmap data pages\n" - " -M --mmap_info # print mmap info stream\n" - " -U --munmap_info # print munmap info stream\n" - ); - - exit(0); -} - -static char *event_name(int ctr) -{ - __u64 config = event_id[ctr]; - int type = PERF_COUNTER_TYPE(config); - int id = PERF_COUNTER_ID(config); - static char buf[32]; - - if (PERF_COUNTER_RAW(config)) { - sprintf(buf, "raw 0x%llx", PERF_COUNTER_CONFIG(config)); - return buf; - } - - switch (type) { - case PERF_TYPE_HARDWARE: - if (id < PERF_HW_EVENTS_MAX) - return hw_event_names[id]; - return "unknown-hardware"; - - case PERF_TYPE_SOFTWARE: - if (id < PERF_SW_EVENTS_MAX) - return sw_event_names[id]; - return "unknown-software"; - - default: - break; - } - - return "unknown"; -} - -/* - * Each event can have multiple symbolic names. - * Symbolic names are (almost) exactly matched. - */ -static __u64 match_event_symbols(char *str) -{ - __u64 config, id; - int type; - unsigned int i; - - if (sscanf(str, "r%llx", &config) == 1) - return config | PERF_COUNTER_RAW_MASK; - - if (sscanf(str, "%d:%llu", &type, &id) == 2) - return EID(type, id); - - for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { - if (!strncmp(str, event_symbols[i].symbol, - strlen(event_symbols[i].symbol))) - return event_symbols[i].event; - } - - return ~0ULL; -} - -static int parse_events(char *str) -{ - __u64 config; - -again: - if (nr_counters == MAX_COUNTERS) - return -1; - - config = match_event_symbols(str); - if (config == ~0ULL) - return -1; - - event_id[nr_counters] = config; - nr_counters++; - - str = strstr(str, ","); - if (str) { - str++; - goto again; - } - - return 0; -} - - -/* - * perfstat - */ - -char fault_here[1000000]; - -static void create_perfstat_counter(int counter) -{ - struct perf_counter_hw_event hw_event; - - memset(&hw_event, 0, sizeof(hw_event)); - hw_event.config = event_id[counter]; - hw_event.record_type = 0; - hw_event.nmi = 0; - if (scale) - hw_event.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | - PERF_FORMAT_TOTAL_TIME_RUNNING; - - if (system_wide) { - int cpu; - for (cpu = 0; cpu < nr_cpus; cpu ++) { - fd[cpu][counter] = sys_perf_counter_open(&hw_event, -1, cpu, -1, 0); - if (fd[cpu][counter] < 0) { - printf("perfstat error: syscall returned with %d (%s)\n", - fd[cpu][counter], strerror(errno)); - exit(-1); - } - } - } else { - hw_event.inherit = 1; - hw_event.disabled = 1; - - fd[0][counter] = sys_perf_counter_open(&hw_event, 0, -1, -1, 0); - if (fd[0][counter] < 0) { - printf("perfstat error: syscall returned with %d (%s)\n", - fd[0][counter], strerror(errno)); - exit(-1); - } - } -} - -int do_perfstat(int argc, char *argv[]) -{ - unsigned long long t0, t1; - int counter; - ssize_t res; - int status; - int pid; - - if (!system_wide) - nr_cpus = 1; - - for (counter = 0; counter < nr_counters; counter++) - create_perfstat_counter(counter); - - argc -= optind; - argv += optind; - - if (!argc) - display_help(); - - /* - * Enable counters and exec the command: - */ - t0 = rdclock(); - prctl(PR_TASK_PERF_COUNTERS_ENABLE); - - if ((pid = fork()) < 0) - perror("failed to fork"); - if (!pid) { - if (execvp(argv[0], argv)) { - perror(argv[0]); - exit(-1); - } - } - while (wait(&status) >= 0) - ; - prctl(PR_TASK_PERF_COUNTERS_DISABLE); - t1 = rdclock(); - - fflush(stdout); - - fprintf(stderr, "\n"); - fprintf(stderr, " Performance counter stats for \'%s\':\n", - argv[0]); - fprintf(stderr, "\n"); - - for (counter = 0; counter < nr_counters; counter++) { - int cpu, nv; - __u64 count[3], single_count[3]; - int scaled; - - count[0] = count[1] = count[2] = 0; - nv = scale ? 3 : 1; - for (cpu = 0; cpu < nr_cpus; cpu ++) { - res = read(fd[cpu][counter], - single_count, nv * sizeof(__u64)); - assert(res == nv * sizeof(__u64)); - - count[0] += single_count[0]; - if (scale) { - count[1] += single_count[1]; - count[2] += single_count[2]; - } - } - - scaled = 0; - if (scale) { - if (count[2] == 0) { - fprintf(stderr, " %14s %-20s\n", - "", event_name(counter)); - continue; - } - if (count[2] < count[1]) { - scaled = 1; - count[0] = (unsigned long long) - ((double)count[0] * count[1] / count[2] + 0.5); - } - } - - if (event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_CPU_CLOCK) || - event_id[counter] == EID(PERF_TYPE_SOFTWARE, PERF_COUNT_TASK_CLOCK)) { - - double msecs = (double)count[0] / 1000000; - - fprintf(stderr, " %14.6f %-20s (msecs)", - msecs, event_name(counter)); - } else { - fprintf(stderr, " %14Ld %-20s (events)", - count[0], event_name(counter)); - } - if (scaled) - fprintf(stderr, " (scaled from %.2f%%)", - (double) count[2] / count[1] * 100); - fprintf(stderr, "\n"); - } - fprintf(stderr, "\n"); - fprintf(stderr, " Wall-clock time elapsed: %12.6f msecs\n", - (double)(t1-t0)/1e6); - fprintf(stderr, "\n"); - - return 0; -} - -/* - * Symbols - */ - -static uint64_t min_ip; -static uint64_t max_ip = -1ll; - -struct sym_entry { - unsigned long long addr; - char *sym; - unsigned long count[MAX_COUNTERS]; - int skip; - struct source_line *source; -}; - -#define MAX_SYMS 100000 - -static int sym_table_count; - -struct sym_entry *sym_filter_entry; - -static struct sym_entry sym_table[MAX_SYMS]; - -static void show_details(struct sym_entry *sym); - -/* - * Ordering weight: count-1 * count-2 * ... / count-n - */ -static double sym_weight(const struct sym_entry *sym) -{ - double weight; - int counter; - - weight = sym->count[0]; - - for (counter = 1; counter < nr_counters-1; counter++) - weight *= sym->count[counter]; - - weight /= (sym->count[counter] + 1); - - return weight; -} - -static int compare(const void *__sym1, const void *__sym2) -{ - const struct sym_entry *sym1 = __sym1, *sym2 = __sym2; - - return sym_weight(sym1) < sym_weight(sym2); -} - -static long events; -static long userspace_events; -static const char CONSOLE_CLEAR[] = ""; - -static struct sym_entry tmp[MAX_SYMS]; - -static void print_sym_table(void) -{ - int i, printed; - int counter; - float events_per_sec = events/delay_secs; - float kevents_per_sec = (events-userspace_events)/delay_secs; - float sum_kevents = 0.0; - - events = userspace_events = 0; - memcpy(tmp, sym_table, sizeof(sym_table[0])*sym_table_count); - qsort(tmp, sym_table_count, sizeof(tmp[0]), compare); - - for (i = 0; i < sym_table_count && tmp[i].count[0]; i++) - sum_kevents += tmp[i].count[0]; - - write(1, CONSOLE_CLEAR, strlen(CONSOLE_CLEAR)); - - printf( -"------------------------------------------------------------------------------\n"); - printf( " KernelTop:%8.0f irqs/sec kernel:%4.1f%% [%s, ", - events_per_sec, - 100.0 - (100.0*((events_per_sec-kevents_per_sec)/events_per_sec)), - nmi ? "NMI" : "IRQ"); - - if (nr_counters == 1) - printf("%d ", event_count[0]); - - for (counter = 0; counter < nr_counters; counter++) { - if (counter) - printf("/"); - - printf("%s", event_name(counter)); - } - - printf( "], "); - - if (tid != -1) - printf(" (tid: %d", tid); - else - printf(" (all"); - - if (profile_cpu != -1) - printf(", cpu: %d)\n", profile_cpu); - else { - if (tid != -1) - printf(")\n"); - else - printf(", %d CPUs)\n", nr_cpus); - } - - printf("------------------------------------------------------------------------------\n\n"); - - if (nr_counters == 1) - printf(" events pcnt"); - else - printf(" weight events pcnt"); - - printf(" RIP kernel function\n" - " ______ ______ _____ ________________ _______________\n\n" - ); - - for (i = 0, printed = 0; i < sym_table_count; i++) { - float pcnt; - int count; - - if (printed <= 18 && tmp[i].count[0] >= count_filter) { - pcnt = 100.0 - (100.0*((sum_kevents-tmp[i].count[0])/sum_kevents)); - - if (nr_counters == 1) - printf("%19.2f - %4.1f%% - %016llx : %s\n", - sym_weight(tmp + i), - pcnt, tmp[i].addr, tmp[i].sym); - else - printf("%8.1f %10ld - %4.1f%% - %016llx : %s\n", - sym_weight(tmp + i), - tmp[i].count[0], - pcnt, tmp[i].addr, tmp[i].sym); - printed++; - } - /* - * Add decay to the counts: - */ - for (count = 0; count < nr_counters; count++) - sym_table[i].count[count] = zero ? 0 : sym_table[i].count[count] * 7 / 8; - } - - if (sym_filter_entry) - show_details(sym_filter_entry); - - { - struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; - - if (poll(&stdin_poll, 1, 0) == 1) { - printf("key pressed - exiting.\n"); - exit(0); - } - } -} - -static void *display_thread(void *arg) -{ - printf("KernelTop refresh period: %d seconds\n", delay_secs); - - while (!sleep(delay_secs)) - print_sym_table(); - - return NULL; -} - -static int read_symbol(FILE *in, struct sym_entry *s) -{ - static int filter_match = 0; - char *sym, stype; - char str[500]; - int rc, pos; - - rc = fscanf(in, "%llx %c %499s", &s->addr, &stype, str); - if (rc == EOF) - return -1; - - assert(rc == 3); - - /* skip until end of line: */ - pos = strlen(str); - do { - rc = fgetc(in); - if (rc == '\n' || rc == EOF || pos >= 499) - break; - str[pos] = rc; - pos++; - } while (1); - str[pos] = 0; - - sym = str; - - /* Filter out known duplicates and non-text symbols. */ - if (!strcmp(sym, "_text")) - return 1; - if (!min_ip && !strcmp(sym, "_stext")) - return 1; - if (!strcmp(sym, "_etext") || !strcmp(sym, "_sinittext")) - return 1; - if (stype != 'T' && stype != 't') - return 1; - if (!strncmp("init_module", sym, 11) || !strncmp("cleanup_module", sym, 14)) - return 1; - if (strstr(sym, "_text_start") || strstr(sym, "_text_end")) - return 1; - - s->sym = malloc(strlen(str)); - assert(s->sym); - - strcpy((char *)s->sym, str); - s->skip = 0; - - /* Tag events to be skipped. */ - if (!strcmp("default_idle", s->sym) || !strcmp("cpu_idle", s->sym)) - s->skip = 1; - else if (!strcmp("enter_idle", s->sym) || !strcmp("exit_idle", s->sym)) - s->skip = 1; - else if (!strcmp("mwait_idle", s->sym)) - s->skip = 1; - - if (filter_match == 1) { - filter_end = s->addr; - filter_match = -1; - if (filter_end - filter_start > 10000) { - printf("hm, too large filter symbol <%s> - skipping.\n", - sym_filter); - printf("symbol filter start: %016lx\n", filter_start); - printf(" end: %016lx\n", filter_end); - filter_end = filter_start = 0; - sym_filter = NULL; - sleep(1); - } - } - if (filter_match == 0 && sym_filter && !strcmp(s->sym, sym_filter)) { - filter_match = 1; - filter_start = s->addr; - } - - return 0; -} - -int compare_addr(const void *__sym1, const void *__sym2) -{ - const struct sym_entry *sym1 = __sym1, *sym2 = __sym2; - - return sym1->addr > sym2->addr; -} - -static void sort_symbol_table(void) -{ - int i, dups; - - do { - qsort(sym_table, sym_table_count, sizeof(sym_table[0]), compare_addr); - for (i = 0, dups = 0; i < sym_table_count; i++) { - if (sym_table[i].addr == sym_table[i+1].addr) { - sym_table[i+1].addr = -1ll; - dups++; - } - } - sym_table_count -= dups; - } while(dups); -} - -static void parse_symbols(void) -{ - struct sym_entry *last; - - FILE *kallsyms = fopen("/proc/kallsyms", "r"); - - if (!kallsyms) { - printf("Could not open /proc/kallsyms - no CONFIG_KALLSYMS_ALL=y?\n"); - exit(-1); - } - - while (!feof(kallsyms)) { - if (read_symbol(kallsyms, &sym_table[sym_table_count]) == 0) { - sym_table_count++; - assert(sym_table_count <= MAX_SYMS); - } - } - - sort_symbol_table(); - min_ip = sym_table[0].addr; - max_ip = sym_table[sym_table_count-1].addr; - last = sym_table + sym_table_count++; - - last->addr = -1ll; - last->sym = ""; - - if (filter_end) { - int count; - for (count=0; count < sym_table_count; count ++) { - if (!strcmp(sym_table[count].sym, sym_filter)) { - sym_filter_entry = &sym_table[count]; - break; - } - } - } - if (dump_symtab) { - int i; - - for (i = 0; i < sym_table_count; i++) - fprintf(stderr, "%llx %s\n", - sym_table[i].addr, sym_table[i].sym); - } -} - -/* - * Source lines - */ - -static void parse_vmlinux(char *filename) -{ - FILE *file; - char command[PATH_MAX*2]; - if (!filename) - return; - - sprintf(command, "objdump --start-address=0x%016lx --stop-address=0x%016lx -dS %s", filter_start, filter_end, filename); - - file = popen(command, "r"); - if (!file) - return; - - lines_tail = &lines; - while (!feof(file)) { - struct source_line *src; - size_t dummy = 0; - char *c; - - src = malloc(sizeof(struct source_line)); - assert(src != NULL); - memset(src, 0, sizeof(struct source_line)); - - if (getline(&src->line, &dummy, file) < 0) - break; - if (!src->line) - break; - - c = strchr(src->line, '\n'); - if (c) - *c = 0; - - src->next = NULL; - *lines_tail = src; - lines_tail = &src->next; - - if (strlen(src->line)>8 && src->line[8] == ':') - src->EIP = strtoull(src->line, NULL, 16); - if (strlen(src->line)>8 && src->line[16] == ':') - src->EIP = strtoull(src->line, NULL, 16); - } - pclose(file); -} - -static void record_precise_ip(uint64_t ip) -{ - struct source_line *line; - - for (line = lines; line; line = line->next) { - if (line->EIP == ip) - line->count++; - if (line->EIP > ip) - break; - } -} - -static void lookup_sym_in_vmlinux(struct sym_entry *sym) -{ - struct source_line *line; - char pattern[PATH_MAX]; - sprintf(pattern, "<%s>:", sym->sym); - - for (line = lines; line; line = line->next) { - if (strstr(line->line, pattern)) { - sym->source = line; - break; - } - } -} - -static void show_lines(struct source_line *line_queue, int line_queue_count) -{ - int i; - struct source_line *line; - - line = line_queue; - for (i = 0; i < line_queue_count; i++) { - printf("%8li\t%s\n", line->count, line->line); - line = line->next; - } -} - -#define TRACE_COUNT 3 - -static void show_details(struct sym_entry *sym) -{ - struct source_line *line; - struct source_line *line_queue = NULL; - int displayed = 0; - int line_queue_count = 0; - - if (!sym->source) - lookup_sym_in_vmlinux(sym); - if (!sym->source) - return; - - printf("Showing details for %s\n", sym->sym); - - line = sym->source; - while (line) { - if (displayed && strstr(line->line, ">:")) - break; - - if (!line_queue_count) - line_queue = line; - line_queue_count ++; - - if (line->count >= count_filter) { - show_lines(line_queue, line_queue_count); - line_queue_count = 0; - line_queue = NULL; - } else if (line_queue_count > TRACE_COUNT) { - line_queue = line_queue->next; - line_queue_count --; - } - - line->count = 0; - displayed++; - if (displayed > 300) - break; - line = line->next; - } -} - -/* - * Binary search in the histogram table and record the hit: - */ -static void record_ip(uint64_t ip, int counter) -{ - int left_idx, middle_idx, right_idx, idx; - unsigned long left, middle, right; - - record_precise_ip(ip); - - left_idx = 0; - right_idx = sym_table_count-1; - assert(ip <= max_ip && ip >= min_ip); - - while (left_idx + 1 < right_idx) { - middle_idx = (left_idx + right_idx) / 2; - - left = sym_table[ left_idx].addr; - middle = sym_table[middle_idx].addr; - right = sym_table[ right_idx].addr; - - if (!(left <= middle && middle <= right)) { - printf("%016lx...\n%016lx...\n%016lx\n", left, middle, right); - printf("%d %d %d\n", left_idx, middle_idx, right_idx); - } - assert(left <= middle && middle <= right); - if (!(left <= ip && ip <= right)) { - printf(" left: %016lx\n", left); - printf(" ip: %016lx\n", (unsigned long)ip); - printf("right: %016lx\n", right); - } - assert(left <= ip && ip <= right); - /* - * [ left .... target .... middle .... right ] - * => right := middle - */ - if (ip < middle) { - right_idx = middle_idx; - continue; - } - /* - * [ left .... middle ... target ... right ] - * => left := middle - */ - left_idx = middle_idx; - } - - idx = left_idx; - - if (!sym_table[idx].skip) - sym_table[idx].count[counter]++; - else events--; -} - -static void process_event(uint64_t ip, int counter) -{ - events++; - - if (ip < min_ip || ip > max_ip) { - userspace_events++; - return; - } - - record_ip(ip, counter); -} - -static void process_options(int argc, char *argv[]) -{ - int error = 0, counter; - - if (strstr(argv[0], "perfstat")) - run_perfstat = 1; - - for (;;) { - int option_index = 0; - /** Options for getopt */ - static struct option long_options[] = { - {"count", required_argument, NULL, 'c'}, - {"cpu", required_argument, NULL, 'C'}, - {"delay", required_argument, NULL, 'd'}, - {"dump_symtab", no_argument, NULL, 'D'}, - {"event", required_argument, NULL, 'e'}, - {"filter", required_argument, NULL, 'f'}, - {"group", required_argument, NULL, 'g'}, - {"help", no_argument, NULL, 'h'}, - {"nmi", required_argument, NULL, 'n'}, - {"mmap_info", no_argument, NULL, 'M'}, - {"mmap_pages", required_argument, NULL, 'm'}, - {"munmap_info", no_argument, NULL, 'U'}, - {"pid", required_argument, NULL, 'p'}, - {"realtime", required_argument, NULL, 'r'}, - {"scale", no_argument, NULL, 'l'}, - {"symbol", required_argument, NULL, 's'}, - {"stat", no_argument, NULL, 'S'}, - {"vmlinux", required_argument, NULL, 'x'}, - {"zero", no_argument, NULL, 'z'}, - {NULL, 0, NULL, 0 } - }; - int c = getopt_long(argc, argv, "+:ac:C:d:De:f:g:hln:m:p:r:s:Sx:zMU", - long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'a': system_wide = 1; break; - case 'c': default_interval = atoi(optarg); break; - case 'C': - /* CPU and PID are mutually exclusive */ - if (tid != -1) { - printf("WARNING: CPU switch overriding PID\n"); - sleep(1); - tid = -1; - } - profile_cpu = atoi(optarg); break; - case 'd': delay_secs = atoi(optarg); break; - case 'D': dump_symtab = 1; break; - - case 'e': error = parse_events(optarg); break; - - case 'f': count_filter = atoi(optarg); break; - case 'g': group = atoi(optarg); break; - case 'h': display_help(); break; - case 'l': scale = 1; break; - case 'n': nmi = atoi(optarg); break; - case 'p': - /* CPU and PID are mutually exclusive */ - if (profile_cpu != -1) { - printf("WARNING: PID switch overriding CPU\n"); - sleep(1); - profile_cpu = -1; - } - tid = atoi(optarg); break; - case 'r': realtime_prio = atoi(optarg); break; - case 's': sym_filter = strdup(optarg); break; - case 'S': run_perfstat = 1; break; - case 'x': vmlinux = strdup(optarg); break; - case 'z': zero = 1; break; - case 'm': mmap_pages = atoi(optarg); break; - case 'M': use_mmap = 1; break; - case 'U': use_munmap = 1; break; - default: error = 1; break; - } - } - if (error) - display_help(); - - if (!nr_counters) { - if (run_perfstat) - nr_counters = 8; - else { - nr_counters = 1; - event_id[0] = 0; - } - } - - for (counter = 0; counter < nr_counters; counter++) { - if (event_count[counter]) - continue; - - event_count[counter] = default_interval; - } -} - -struct mmap_data { - int counter; - void *base; - unsigned int mask; - unsigned int prev; -}; - -static unsigned int mmap_read_head(struct mmap_data *md) -{ - struct perf_counter_mmap_page *pc = md->base; - int head; - - head = pc->data_head; - rmb(); - - return head; -} - -struct timeval last_read, this_read; - -static void mmap_read(struct mmap_data *md) -{ - unsigned int head = mmap_read_head(md); - unsigned int old = md->prev; - unsigned char *data = md->base + page_size; - int diff; - - gettimeofday(&this_read, NULL); - - /* - * If we're further behind than half the buffer, there's a chance - * the writer will bite our tail and screw up the events under us. - * - * If we somehow ended up ahead of the head, we got messed up. - * - * In either case, truncate and restart at head. - */ - diff = head - old; - if (diff > md->mask / 2 || diff < 0) { - struct timeval iv; - unsigned long msecs; - - timersub(&this_read, &last_read, &iv); - msecs = iv.tv_sec*1000 + iv.tv_usec/1000; - - fprintf(stderr, "WARNING: failed to keep up with mmap data." - " Last read %lu msecs ago.\n", msecs); - - /* - * head points to a known good entry, start there. - */ - old = head; - } - - last_read = this_read; - - for (; old != head;) { - struct ip_event { - struct perf_event_header header; - __u64 ip; - __u32 pid, tid; - }; - struct mmap_event { - struct perf_event_header header; - __u32 pid, tid; - __u64 start; - __u64 len; - __u64 pgoff; - char filename[PATH_MAX]; - }; - - typedef union event_union { - struct perf_event_header header; - struct ip_event ip; - struct mmap_event mmap; - } event_t; - - event_t *event = (event_t *)&data[old & md->mask]; - - event_t event_copy; - - unsigned int size = event->header.size; - - /* - * Event straddles the mmap boundary -- header should always - * be inside due to u64 alignment of output. - */ - if ((old & md->mask) + size != ((old + size) & md->mask)) { - unsigned int offset = old; - unsigned int len = min(sizeof(*event), size), cpy; - void *dst = &event_copy; - - do { - cpy = min(md->mask + 1 - (offset & md->mask), len); - memcpy(dst, &data[offset & md->mask], cpy); - offset += cpy; - dst += cpy; - len -= cpy; - } while (len); - - event = &event_copy; - } - - old += size; - - if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { - if (event->header.type & PERF_RECORD_IP) - process_event(event->ip.ip, md->counter); - } else { - switch (event->header.type) { - case PERF_EVENT_MMAP: - case PERF_EVENT_MUNMAP: - printf("%s: %Lu %Lu %Lu %s\n", - event->header.type == PERF_EVENT_MMAP - ? "mmap" : "munmap", - event->mmap.start, - event->mmap.len, - event->mmap.pgoff, - event->mmap.filename); - break; - } - } - } - - md->prev = old; -} - -int main(int argc, char *argv[]) -{ - struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; - struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; - struct perf_counter_hw_event hw_event; - pthread_t thread; - int i, counter, group_fd, nr_poll = 0; - unsigned int cpu; - int ret; - - page_size = sysconf(_SC_PAGE_SIZE); - - process_options(argc, argv); - - nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); - assert(nr_cpus <= MAX_NR_CPUS); - assert(nr_cpus >= 0); - - if (run_perfstat) - return do_perfstat(argc, argv); - - if (tid != -1 || profile_cpu != -1) - nr_cpus = 1; - - parse_symbols(); - if (vmlinux && sym_filter_entry) - parse_vmlinux(vmlinux); - - for (i = 0; i < nr_cpus; i++) { - group_fd = -1; - for (counter = 0; counter < nr_counters; counter++) { - - cpu = profile_cpu; - if (tid == -1 && profile_cpu == -1) - cpu = i; - - memset(&hw_event, 0, sizeof(hw_event)); - hw_event.config = event_id[counter]; - hw_event.irq_period = event_count[counter]; - hw_event.record_type = PERF_RECORD_IP | PERF_RECORD_TID; - hw_event.nmi = nmi; - hw_event.mmap = use_mmap; - hw_event.munmap = use_munmap; - - fd[i][counter] = sys_perf_counter_open(&hw_event, tid, cpu, group_fd, 0); - if (fd[i][counter] < 0) { - int err = errno; - printf("kerneltop error: syscall returned with %d (%s)\n", - fd[i][counter], strerror(err)); - if (err == EPERM) - printf("Are you root?\n"); - exit(-1); - } - assert(fd[i][counter] >= 0); - fcntl(fd[i][counter], F_SETFL, O_NONBLOCK); - - /* - * First counter acts as the group leader: - */ - if (group && group_fd == -1) - group_fd = fd[i][counter]; - - event_array[nr_poll].fd = fd[i][counter]; - event_array[nr_poll].events = POLLIN; - nr_poll++; - - mmap_array[i][counter].counter = counter; - mmap_array[i][counter].prev = 0; - mmap_array[i][counter].mask = mmap_pages*page_size - 1; - mmap_array[i][counter].base = mmap(NULL, (mmap_pages+1)*page_size, - PROT_READ, MAP_SHARED, fd[i][counter], 0); - if (mmap_array[i][counter].base == MAP_FAILED) { - printf("kerneltop error: failed to mmap with %d (%s)\n", - errno, strerror(errno)); - exit(-1); - } - } - } - - if (pthread_create(&thread, NULL, display_thread, NULL)) { - printf("Could not create display thread.\n"); - exit(-1); - } - - if (realtime_prio) { - struct sched_param param; - - param.sched_priority = realtime_prio; - if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { - printf("Could not set realtime priority.\n"); - exit(-1); - } - } - - while (1) { - int hits = events; - - for (i = 0; i < nr_cpus; i++) { - for (counter = 0; counter < nr_counters; counter++) - mmap_read(&mmap_array[i][counter]); - } - - if (hits == events) - ret = poll(event_array, nr_poll, 100); - } - - return 0; -} diff --git a/Documentation/perf_counter/perf.c b/Documentation/perf_counter/perf.c index 63f8a892c0df..ff8658f2a2f1 100644 --- a/Documentation/perf_counter/perf.c +++ b/Documentation/perf_counter/perf.c @@ -249,6 +249,7 @@ static void handle_internal_command(int argc, const char **argv) const char *cmd = argv[0]; static struct cmd_struct commands[] = { { "top", cmd_top, 0 }, + { "stat", cmd_stat, 0 }, }; int i; static const char ext[] = STRIP_EXTENSION; -- GitLab From 1d8c8b209e9351a7de1307d7b9b6df4222b8d742 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 15:52:29 +0200 Subject: [PATCH 0447/6080] perf_counter tools: add help texts Add Documentation/perf-stat.txt and Documentation/perf-top.txt. The template that was used for it: Documentation/git-add.txt from Git. Fix up small bugs to make these help texts show up both in the 'perf' common-command summary output screen, and on the individual help screens. Signed-off-by: Ingo Molnar --- .../perf_counter/Documentation/perf-stat.txt | 76 +++++++++++++++++++ .../perf_counter/Documentation/perf-top.txt | 61 +++++++++++++++ Documentation/perf_counter/builtin.h | 4 +- .../perf_counter/generate-cmdlist.sh | 8 +- 4 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 Documentation/perf_counter/Documentation/perf-stat.txt create mode 100644 Documentation/perf_counter/Documentation/perf-top.txt diff --git a/Documentation/perf_counter/Documentation/perf-stat.txt b/Documentation/perf_counter/Documentation/perf-stat.txt new file mode 100644 index 000000000000..7fcab271e570 --- /dev/null +++ b/Documentation/perf_counter/Documentation/perf-stat.txt @@ -0,0 +1,76 @@ +perf-stat(1) +========== + +NAME +---- +perf-stat - Run a command and gather performance counter statistics + +SYNOPSIS +-------- +[verse] +'perf stat' [-e | --event=EVENT] [-l] [-a] + +DESCRIPTION +----------- +This command runs a command and gathers performance counter statistics +from it. + + +OPTIONS +------- +...:: + Any command you can specify in a shell. + +-e:: +--event=:: + 0:0: cpu-cycles + 0:0: cycles + 0:1: instructions + 0:2: cache-references + 0:3: cache-misses + 0:4: branch-instructions + 0:4: branches + 0:5: branch-misses + 0:6: bus-cycles + 1:0: cpu-clock + 1:1: task-clock + 1:2: page-faults + 1:2: faults + 1:5: minor-faults + 1:6: major-faults + 1:3: context-switches + 1:3: cs + 1:4: cpu-migrations + 1:4: migrations + rNNN: raw PMU events (eventsel+umask) + +-a:: + system-wide collection + +-l:: + scale counter values + +Configuration +------------- + +EXAMPLES +-------- + +$ perf stat sleep 1 + + Performance counter stats for 'sleep': + + 0.678356 task clock ticks (msecs) + 7 context switches (events) + 4 CPU migrations (events) + 232 pagefaults (events) + 1810403 CPU cycles (events) + 946759 instructions (events) + 18952 cache references (events) + 4885 cache misses (events) + + Wall-clock time elapsed: 1001.252894 msecs + +SEE ALSO +-------- +linkperf:git-tops[1] diff --git a/Documentation/perf_counter/Documentation/perf-top.txt b/Documentation/perf_counter/Documentation/perf-top.txt new file mode 100644 index 000000000000..057333b72534 --- /dev/null +++ b/Documentation/perf_counter/Documentation/perf-top.txt @@ -0,0 +1,61 @@ +perf-top(1) +========== + +NAME +---- +perf-top - Run a command and profile it + +SYNOPSIS +-------- +[verse] +'perf top' [-e | --event=EVENT] [-l] [-a] + +DESCRIPTION +----------- +This command runs a command and gathers a performance counter profile +from it. + + +OPTIONS +------- +...:: + Any command you can specify in a shell. + +-e:: +--event=:: + 0:0: cpu-cycles + 0:0: cycles + 0:1: instructions + 0:2: cache-references + 0:3: cache-misses + 0:4: branch-instructions + 0:4: branches + 0:5: branch-misses + 0:6: bus-cycles + 1:0: cpu-clock + 1:1: task-clock + 1:2: page-faults + 1:2: faults + 1:5: minor-faults + 1:6: major-faults + 1:3: context-switches + 1:3: cs + 1:4: cpu-migrations + 1:4: migrations + rNNN: raw PMU events (eventsel+umask) + +-a:: + system-wide collection + +-l:: + scale counter values + +Configuration +------------- + +EXAMPLES +-------- + +SEE ALSO +-------- +linkperf:git-stat[1] diff --git a/Documentation/perf_counter/builtin.h b/Documentation/perf_counter/builtin.h index a3bb6cd6bed3..605323c691f1 100644 --- a/Documentation/perf_counter/builtin.h +++ b/Documentation/perf_counter/builtin.h @@ -14,6 +14,6 @@ extern void prune_packed_objects(int); extern int read_line_with_nul(char *buf, int size, FILE *file); extern int check_pager_config(const char *cmd); -extern int cmd_top(int argc, char **argv, const char *prefix); -extern int cmd_stat(int argc, char **argv, const char *prefix); +extern int cmd_top(int argc, const char **argv, const char *prefix); +extern int cmd_stat(int argc, const char **argv, const char *prefix); #endif diff --git a/Documentation/perf_counter/generate-cmdlist.sh b/Documentation/perf_counter/generate-cmdlist.sh index 75c68d948fd3..f06f6fd148f8 100755 --- a/Documentation/perf_counter/generate-cmdlist.sh +++ b/Documentation/perf_counter/generate-cmdlist.sh @@ -9,16 +9,16 @@ struct cmdname_help static struct cmdname_help common_cmds[] = {" -sed -n -e 's/^git-\([^ ]*\)[ ].* common.*/\1/p' command-list.txt | +sed -n -e 's/^perf-\([^ ]*\)[ ].* common.*/\1/p' command-list.txt | sort | while read cmd do sed -n ' - /^NAME/,/git-'"$cmd"'/H + /^NAME/,/perf-'"$cmd"'/H ${ x - s/.*git-'"$cmd"' - \(.*\)/ {"'"$cmd"'", "\1"},/ + s/.*perf-'"$cmd"' - \(.*\)/ {"'"$cmd"'", "\1"},/ p - }' "Documentation/git-$cmd.txt" + }' "Documentation/perf-$cmd.txt" done echo "};" -- GitLab From e33e0a43736307512422e41aee6e24d5a8c39181 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 15:58:01 +0200 Subject: [PATCH 0448/6080] perf_counter tools: add 'perf record' command Move perf-record.c into the perf suite of commands. Signed-off-by: Ingo Molnar --- .../Documentation/perf-record.txt | 63 +++++++++++++++++++ Documentation/perf_counter/Makefile | 1 + .../{perf-record.c => builtin-record.c} | 30 +-------- Documentation/perf_counter/builtin.h | 3 +- Documentation/perf_counter/command-list.txt | 3 +- Documentation/perf_counter/perf.c | 3 +- 6 files changed, 73 insertions(+), 30 deletions(-) create mode 100644 Documentation/perf_counter/Documentation/perf-record.txt rename Documentation/perf_counter/{perf-record.c => builtin-record.c} (95%) diff --git a/Documentation/perf_counter/Documentation/perf-record.txt b/Documentation/perf_counter/Documentation/perf-record.txt new file mode 100644 index 000000000000..d07700e35eb2 --- /dev/null +++ b/Documentation/perf_counter/Documentation/perf-record.txt @@ -0,0 +1,63 @@ +perf-record(1) +========== + +NAME +---- +perf-record - Run a command and record its profile into output.perf + +SYNOPSIS +-------- +[verse] +'perf record' [-e | --event=EVENT] [-l] [-a] + +DESCRIPTION +----------- +This command runs a command and gathers a performance counter profile +from it, into output.perf - without displaying anything. + +This file can then be inspected later on, using 'perf report'. + + +OPTIONS +------- +...:: + Any command you can specify in a shell. + +-e:: +--event=:: + 0:0: cpu-cycles + 0:0: cycles + 0:1: instructions + 0:2: cache-references + 0:3: cache-misses + 0:4: branch-instructions + 0:4: branches + 0:5: branch-misses + 0:6: bus-cycles + 1:0: cpu-clock + 1:1: task-clock + 1:2: page-faults + 1:2: faults + 1:5: minor-faults + 1:6: major-faults + 1:3: context-switches + 1:3: cs + 1:4: cpu-migrations + 1:4: migrations + rNNN: raw PMU events (eventsel+umask) + +-a:: + system-wide collection + +-l:: + scale counter values + +Configuration +------------- + +EXAMPLES +-------- + +SEE ALSO +-------- +linkperf:git-stat[1] diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index fb8b71744e59..b6c665eb22e4 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -309,6 +309,7 @@ LIB_OBJS += usage.o LIB_OBJS += wrapper.o BUILTIN_OBJS += builtin-help.o +BUILTIN_OBJS += builtin-record.o BUILTIN_OBJS += builtin-stat.o BUILTIN_OBJS += builtin-top.o diff --git a/Documentation/perf_counter/perf-record.c b/Documentation/perf_counter/builtin-record.c similarity index 95% rename from Documentation/perf_counter/perf-record.c rename to Documentation/perf_counter/builtin-record.c index 614de7c468b2..4a50abf843ee 100644 --- a/Documentation/perf_counter/perf-record.c +++ b/Documentation/perf_counter/builtin-record.c @@ -81,16 +81,12 @@ (void) (&_min1 == &_min2); \ _min1 < _min2 ? _min1 : _min2; }) -asmlinkage int sys_perf_counter_open( +extern asmlinkage int sys_perf_counter_open( struct perf_counter_hw_event *hw_event_uptr __user, pid_t pid, int cpu, int group_fd, - unsigned long flags) -{ - return syscall( - __NR_perf_counter_open, hw_event_uptr, pid, cpu, group_fd, flags); -} + unsigned long flags); #define MAX_COUNTERS 64 #define MAX_NR_CPUS 256 @@ -119,26 +115,6 @@ const unsigned int default_count[] = { 10000, }; -static char *hw_event_names[] = { - "CPU cycles", - "instructions", - "cache references", - "cache misses", - "branches", - "branch misses", - "bus cycles", -}; - -static char *sw_event_names[] = { - "cpu clock ticks", - "task clock ticks", - "pagefaults", - "context switches", - "CPU migrations", - "minor faults", - "major faults", -}; - struct event_symbol { __u64 event; char *symbol; @@ -414,7 +390,7 @@ static void sigchld_handler(int sig) done = 1; } -int main(int argc, char *argv[]) +int cmd_record(int argc, const char **argv) { struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; diff --git a/Documentation/perf_counter/builtin.h b/Documentation/perf_counter/builtin.h index 605323c691f1..5854b1715f54 100644 --- a/Documentation/perf_counter/builtin.h +++ b/Documentation/perf_counter/builtin.h @@ -14,6 +14,7 @@ extern void prune_packed_objects(int); extern int read_line_with_nul(char *buf, int size, FILE *file); extern int check_pager_config(const char *cmd); -extern int cmd_top(int argc, const char **argv, const char *prefix); +extern int cmd_record(int argc, const char **argv, const char *prefix); extern int cmd_stat(int argc, const char **argv, const char *prefix); +extern int cmd_top(int argc, const char **argv, const char *prefix); #endif diff --git a/Documentation/perf_counter/command-list.txt b/Documentation/perf_counter/command-list.txt index 52455d46bfb5..d15210aa0cae 100644 --- a/Documentation/perf_counter/command-list.txt +++ b/Documentation/perf_counter/command-list.txt @@ -1,5 +1,6 @@ # List of known perf commands. # command name category [deprecated] [common] -perf-top mainporcelain common +perf-record mainporcelain common perf-stat mainporcelain common +perf-top mainporcelain common diff --git a/Documentation/perf_counter/perf.c b/Documentation/perf_counter/perf.c index ff8658f2a2f1..e849dd66b5ef 100644 --- a/Documentation/perf_counter/perf.c +++ b/Documentation/perf_counter/perf.c @@ -248,8 +248,9 @@ static void handle_internal_command(int argc, const char **argv) { const char *cmd = argv[0]; static struct cmd_struct commands[] = { - { "top", cmd_top, 0 }, + { "record", cmd_record, 0 }, { "stat", cmd_stat, 0 }, + { "top", cmd_top, 0 }, }; int i; static const char ext[] = STRIP_EXTENSION; -- GitLab From cc13a5913797365b683212f5fca5fb04bb3582eb Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 16:01:30 +0200 Subject: [PATCH 0449/6080] perf_counter tools: fix --version Hook up the 'perf version' built-in command. Signed-off-by: Ingo Molnar --- Documentation/perf_counter/builtin.h | 1 + Documentation/perf_counter/perf.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/perf_counter/builtin.h b/Documentation/perf_counter/builtin.h index 5854b1715f54..aec5ae388e66 100644 --- a/Documentation/perf_counter/builtin.h +++ b/Documentation/perf_counter/builtin.h @@ -17,4 +17,5 @@ extern int check_pager_config(const char *cmd); extern int cmd_record(int argc, const char **argv, const char *prefix); extern int cmd_stat(int argc, const char **argv, const char *prefix); extern int cmd_top(int argc, const char **argv, const char *prefix); +extern int cmd_version(int argc, const char **argv, const char *prefix); #endif diff --git a/Documentation/perf_counter/perf.c b/Documentation/perf_counter/perf.c index e849dd66b5ef..20d508c77293 100644 --- a/Documentation/perf_counter/perf.c +++ b/Documentation/perf_counter/perf.c @@ -5,7 +5,7 @@ #include "run-command.h" const char perf_usage_string[] = - "perf [--version] [--exec-path[=PERF_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--bare] [--perf-dir=PERF_DIR] [--work-tree=PERF_WORK_TREE] [--help] COMMAND [ARGS]"; + "perf [--version] [--help] COMMAND [ARGS]"; const char perf_more_info_string[] = "See 'perf help COMMAND' for more information on a specific command."; @@ -251,6 +251,7 @@ static void handle_internal_command(int argc, const char **argv) { "record", cmd_record, 0 }, { "stat", cmd_stat, 0 }, { "top", cmd_top, 0 }, + { "version", cmd_version, 0 }, }; int i; static const char ext[] = STRIP_EXTENSION; -- GitLab From 6142fdd968c76a0f2ee753c39bd5be8d1bb4ef04 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 16:05:55 +0200 Subject: [PATCH 0450/6080] perf_counter tools: add 'perf help' Signed-off-by: Ingo Molnar --- .../perf_counter/Documentation/perf-help.txt | 38 +++++++++++++++++++ Documentation/perf_counter/builtin.h | 1 + Documentation/perf_counter/perf.c | 1 + 3 files changed, 40 insertions(+) create mode 100644 Documentation/perf_counter/Documentation/perf-help.txt diff --git a/Documentation/perf_counter/Documentation/perf-help.txt b/Documentation/perf_counter/Documentation/perf-help.txt new file mode 100644 index 000000000000..f85fed5a7edb --- /dev/null +++ b/Documentation/perf_counter/Documentation/perf-help.txt @@ -0,0 +1,38 @@ +perf-help(1) +=========== + +NAME +---- +perf-help - display help information about perf + +SYNOPSIS +-------- +'perf help' [-a|--all] [COMMAND] + +DESCRIPTION +----------- + +With no options and no COMMAND given, the synopsis of the 'perf' +command and a list of the most commonly used perf commands are printed +on the standard output. + +If the option '--all' or '-a' is given, then all available commands are +printed on the standard output. + +If a perf command is named, a manual page for that command is brought +up. The 'man' program is used by default for this purpose, but this +can be overridden by other options or configuration variables. + +Note that `perf --help ...` is identical to `perf help ...` because the +former is internally converted into the latter. + +OPTIONS +------- +-a:: +--all:: + Prints all the available commands on the standard output. This + option supersedes any other option. + +PERF +---- +Part of the linkperf:perf[1] suite diff --git a/Documentation/perf_counter/builtin.h b/Documentation/perf_counter/builtin.h index aec5ae388e66..800f86c1d445 100644 --- a/Documentation/perf_counter/builtin.h +++ b/Documentation/perf_counter/builtin.h @@ -14,6 +14,7 @@ extern void prune_packed_objects(int); extern int read_line_with_nul(char *buf, int size, FILE *file); extern int check_pager_config(const char *cmd); +extern int cmd_help(int argc, const char **argv, const char *prefix); extern int cmd_record(int argc, const char **argv, const char *prefix); extern int cmd_stat(int argc, const char **argv, const char *prefix); extern int cmd_top(int argc, const char **argv, const char *prefix); diff --git a/Documentation/perf_counter/perf.c b/Documentation/perf_counter/perf.c index 20d508c77293..8d6faecdc15d 100644 --- a/Documentation/perf_counter/perf.c +++ b/Documentation/perf_counter/perf.c @@ -248,6 +248,7 @@ static void handle_internal_command(int argc, const char **argv) { const char *cmd = argv[0]; static struct cmd_struct commands[] = { + { "help", cmd_help, 0 }, { "record", cmd_record, 0 }, { "stat", cmd_stat, 0 }, { "top", cmd_top, 0 }, -- GitLab From 125e702b09a28a502e145fb434678ee27720fc48 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 16:13:46 +0200 Subject: [PATCH 0451/6080] perf_counter tools: fix 'make install' Remove Git leftovers from this area. Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index b6c665eb22e4..690045e49692 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -255,9 +255,9 @@ EXTRA_PROGRAMS = PROGRAMS += $(EXTRA_PROGRAMS) # -# None right now: +# Single 'perf' binary right now: # -# PROGRAMS += perf-fast-import$X +PROGRAMS += perf # List built-in command $C whose implementation cmd_$C() is not in # builtin-$C.o but is linked in as part of some other command. @@ -762,24 +762,9 @@ install: all $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' - $(INSTALL) perf$X perf-upload-pack$X perf-receive-pack$X perf-upload-archive$X perf-shell$X perf-cvsserver '$(DESTDIR_SQ)$(bindir_SQ)' - $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install - $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install ifneq (,$X) $(foreach p,$(patsubst %$X,%,$(filter %$X,$(ALL_PROGRAMS) $(BUILT_INS) perf$X)), $(RM) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/$p';) endif - bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \ - execdir=$$(cd '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' && pwd) && \ - { $(RM) "$$execdir/perf-add$X" && \ - ln "$$bindir/perf$X" "$$execdir/perf-add$X" 2>/dev/null || \ - cp "$$bindir/perf$X" "$$execdir/perf-add$X"; } && \ - { for p in $(filter-out perf-add$X,$(BUILT_INS)); do \ - $(RM) "$$execdir/$$p" && \ - ln "$$execdir/perf-add$X" "$$execdir/$$p" 2>/dev/null || \ - ln -s "perf-add$X" "$$execdir/$$p" 2>/dev/null || \ - cp "$$execdir/perf-add$X" "$$execdir/$$p" || exit; \ - done } && \ - ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/perf-add$X" ### Maintainer's dist rules -- GitLab From cd0f2d4736ae8efabc60e54ecc8f677d0eddce02 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 20 Apr 2009 16:56:59 +0100 Subject: [PATCH 0452/6080] ASoC: Factor out generic widget power checks This will form a basis for further power check refactoring: the overall goal of these changes is to allow us to check power separately to applying it, allowing improvements in the power sequencing algorithms. Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index a6d73379ab32..28e6e324ccfb 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -581,6 +581,19 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) return 0; } +/* Generic check to see if a widget should be powered. + */ +static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) +{ + int in, out; + + in = is_connected_input_ep(w); + dapm_clear_walk(w->codec); + out = is_connected_output_ep(w); + dapm_clear_walk(w->codec); + return out != 0 && in != 0; +} + /* * Scan a single DAPM widget for a complete audio path and update the * power status appropriately. @@ -653,11 +666,7 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event, } /* all other widgets */ - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - power = (out != 0 && in != 0) ? 1 : 0; + power = dapm_generic_check_power(w); power_change = (w->power == power) ? 0 : 1; w->power = power; -- GitLab From 6ea31b9f0a0307e16656af27fcda3160e2a64a1b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 20 Apr 2009 17:15:41 +0100 Subject: [PATCH 0453/6080] ASoC: Factor out DAPM power checks for DACs and ADCs This also switches us to using a switch statement for the widget type in dapm_power_widget(). Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 81 ++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 28e6e324ccfb..22522e2d83a4 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -594,6 +594,34 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) return out != 0 && in != 0; } +/* Check to see if an ADC has power */ +static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) +{ + int in; + + if (w->active) { + in = is_connected_input_ep(w); + dapm_clear_walk(w->codec); + return in != 0; + } else { + return dapm_generic_check_power(w); + } +} + +/* Check to see if a DAC has power */ +static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) +{ + int out; + + if (w->active) { + out = is_connected_output_ep(w); + dapm_clear_walk(w->codec); + return out != 0; + } else { + return dapm_generic_check_power(w); + } +} + /* * Scan a single DAPM widget for a complete audio path and update the * power status appropriately. @@ -601,36 +629,23 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) static int dapm_power_widget(struct snd_soc_codec *codec, int event, struct snd_soc_dapm_widget *w) { - int in, out, power_change, power, ret; + int power, ret; - /* vmid - no action */ - if (w->id == snd_soc_dapm_vmid) + /* Work out the new power state */ + switch (w->id) { + case snd_soc_dapm_vmid: + /* No action required */ return 0; - /* active ADC */ - if (w->id == snd_soc_dapm_adc && w->active) { - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - power = (in != 0) ? 1 : 0; - if (power == w->power) - return 0; - w->power = power; - return dapm_generic_apply_power(w); - } + case snd_soc_dapm_adc: + power = dapm_adc_check_power(w); + break; - /* active DAC */ - if (w->id == snd_soc_dapm_dac && w->active) { - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - power = (out != 0) ? 1 : 0; - if (power == w->power) - return 0; - w->power = power; - return dapm_generic_apply_power(w); - } + case snd_soc_dapm_dac: + power = dapm_dac_check_power(w); + break; - /* pre and post event widgets */ - if (w->id == snd_soc_dapm_pre) { + case snd_soc_dapm_pre: if (!w->event) return 0; @@ -646,8 +661,8 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event, return ret; } return 0; - } - if (w->id == snd_soc_dapm_post) { + + case snd_soc_dapm_post: if (!w->event) return 0; @@ -663,15 +678,15 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event, return ret; } return 0; - } - /* all other widgets */ - power = dapm_generic_check_power(w); - power_change = (w->power == power) ? 0 : 1; - w->power = power; + default: + power = dapm_generic_check_power(w); + break; + } - if (!power_change) + if (w->power == power) return 0; + w->power = power; return dapm_generic_apply_power(w); } -- GitLab From b75576d76d4be50196773f36709cb7a4f5ac2ab7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 20 Apr 2009 17:56:13 +0100 Subject: [PATCH 0454/6080] ASoC: Make the DAPM power check an operation on the widget Rather than having switch statements at point of use make the DAPM power check a member of the widget structure and set it when we instantiate the widget. Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 2 ++ sound/soc/soc-dapm.c | 27 +++++++++++++-------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index fcc929da0339..839a97b63269 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -367,6 +367,8 @@ struct snd_soc_dapm_widget { unsigned char suspend:1; /* was active before suspend */ unsigned char pmdown:1; /* waiting for timeout */ + int (*power_check)(struct snd_soc_dapm_widget *w); + /* external events */ unsigned short event_flags; /* flags to specify event types */ int (*event)(struct snd_soc_dapm_widget*, struct snd_kcontrol *, int); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 22522e2d83a4..d3d17354e76c 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -631,20 +631,7 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event, { int power, ret; - /* Work out the new power state */ switch (w->id) { - case snd_soc_dapm_vmid: - /* No action required */ - return 0; - - case snd_soc_dapm_adc: - power = dapm_adc_check_power(w); - break; - - case snd_soc_dapm_dac: - power = dapm_dac_check_power(w); - break; - case snd_soc_dapm_pre: if (!w->event) return 0; @@ -680,10 +667,13 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event, return 0; default: - power = dapm_generic_check_power(w); break; } + if (!w->power_check) + return 0; + + power = w->power_check(w); if (w->power == power) return 0; w->power = power; @@ -1147,15 +1137,22 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) case snd_soc_dapm_switch: case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: + w->power_check = dapm_generic_check_power; dapm_new_mixer(codec, w); break; case snd_soc_dapm_mux: case snd_soc_dapm_value_mux: + w->power_check = dapm_generic_check_power; dapm_new_mux(codec, w); break; case snd_soc_dapm_adc: + w->power_check = dapm_adc_check_power; + break; case snd_soc_dapm_dac: + w->power_check = dapm_dac_check_power; + break; case snd_soc_dapm_pga: + w->power_check = dapm_generic_check_power; dapm_new_pga(codec, w); break; case snd_soc_dapm_input: @@ -1165,6 +1162,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) case snd_soc_dapm_hp: case snd_soc_dapm_mic: case snd_soc_dapm_line: + w->power_check = dapm_generic_check_power; + break; case snd_soc_dapm_vmid: case snd_soc_dapm_pre: case snd_soc_dapm_post: -- GitLab From f1f9b3b1795da8625e0e6096813c9d18d4a344ce Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 20 Apr 2009 20:38:21 +0200 Subject: [PATCH 0455/6080] perfcounters, sched: remove __task_delta_exec() This function was left orphan by the latest round of sw-counter cleanups. [ Impact: remove unused kernel function ] Signed-off-by: Ingo Molnar --- include/linux/kernel_stat.h | 1 - kernel/sched.c | 23 ----------------------- 2 files changed, 24 deletions(-) diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 080d1fd461d7..a77c6007dc99 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -85,7 +85,6 @@ static inline unsigned int kstat_irqs(unsigned int irq) /* * Lock/unlock the current runqueue - to extract task statistics: */ -extern unsigned long long __task_delta_exec(struct task_struct *tsk, int update); extern unsigned long long task_delta_exec(struct task_struct *); extern void account_user_time(struct task_struct *, cputime_t, cputime_t); diff --git a/kernel/sched.c b/kernel/sched.c index b66a08c2480e..a69278eef425 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4546,29 +4546,6 @@ DEFINE_PER_CPU(struct kernel_stat, kstat); EXPORT_PER_CPU_SYMBOL(kstat); -/* - * Return any ns on the sched_clock that have not yet been banked in - * @p in case that task is currently running. - */ -unsigned long long __task_delta_exec(struct task_struct *p, int update) -{ - s64 delta_exec; - struct rq *rq; - - rq = task_rq(p); - WARN_ON_ONCE(!runqueue_is_locked()); - WARN_ON_ONCE(!task_current(rq, p)); - - if (update) - update_rq_clock(rq); - - delta_exec = rq->clock - p->se.exec_start; - - WARN_ON_ONCE(delta_exec < 0); - - return delta_exec; -} - /* * Return any ns on the sched_clock that have not yet been banked in * @p in case that task is currently running. -- GitLab From 2ecf0a57c60dcb588f310d94412118e15c510532 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 21 Apr 2009 12:16:56 +0900 Subject: [PATCH 0456/6080] ide-dma: don't reset request fields on dma_timeout_retry() Impact: drop unnecessary code Now that everything uses bio and block operations, there is no need to reset request fields manually when retrying a request. Every field is guaranteed to be always valid. Drop unnecessary request field resetting from ide_dma_timeout_retry(). Signed-off-by: Tejun Heo --- drivers/ide/ide-dma.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index a0b8cab1d9a6..d9123ecae4a9 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -510,23 +510,11 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) /* * un-busy drive etc and make sure request is sane */ - rq = hwif->rq; - if (!rq) - goto out; - - hwif->rq = NULL; - - rq->errors = 0; - - if (!rq->bio) - goto out; - - rq->sector = rq->bio->bi_sector; - rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9; - rq->hard_cur_sectors = rq->current_nr_sectors; - rq->buffer = bio_data(rq->bio); -out: + if (rq) { + hwif->rq = NULL; + rq->errors = 0; + } return ret; } -- GitLab From cd474f2d548af3c0eb932d9d47ec11483861aa6f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Apr 2009 08:53:08 +0200 Subject: [PATCH 0457/6080] ALSA: Remove deprecated snd_card_new() Signed-off-by: Takashi Iwai --- include/sound/core.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/sound/core.h b/include/sound/core.h index 3dea79829acc..a26bbdcc6765 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -300,16 +300,6 @@ int snd_card_create(int idx, const char *id, struct module *module, int extra_size, struct snd_card **card_ret); -static inline __deprecated -struct snd_card *snd_card_new(int idx, const char *id, - struct module *module, int extra_size) -{ - struct snd_card *card; - if (snd_card_create(idx, id, module, extra_size, &card) < 0) - return NULL; - return card; -} - int snd_card_disconnect(struct snd_card *card); int snd_card_free(struct snd_card *card); int snd_card_free_when_closed(struct snd_card *card); -- GitLab From ef9dfa4b1052af23a603de382d4665b2d1fccc61 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Apr 2009 08:53:41 +0200 Subject: [PATCH 0458/6080] ALSA: Remove deprecated include/sound/driver.h Signed-off-by: Takashi Iwai --- include/sound/driver.h | 1 - 1 file changed, 1 deletion(-) delete mode 100644 include/sound/driver.h diff --git a/include/sound/driver.h b/include/sound/driver.h deleted file mode 100644 index f0359437d01a..000000000000 --- a/include/sound/driver.h +++ /dev/null @@ -1 +0,0 @@ -#warning "This file is deprecated" -- GitLab From 624f8e5082efd0348ccf7e3d3f4bfc41efead26c Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 20 Apr 2009 06:55:01 +0000 Subject: [PATCH 0459/6080] tg3: Allow screaming interrupt detection The tg3 driver's ISR is coded to accept interrupts as its own if the status block tag does not equal the last tag the driver has seen. The last_tag field is updated from tg3_poll. In a screaming interrupt situation from another device sharing tg3's IRQ, tg3_poll does not get a chance to be called, so the last_tag will always be out of sync with the status block tag. Consequently, the driver will continually declare the screaming interrupts as its own, thus thwarting the screaming interrupt detection logic. This patch solves the problem by creating a new last_irq_tag member and recording the status block tag in the ISR. The ISR then checks the last_irq_tag for interrupt ownership. Many thanks to John Marvin for the detailed bug report and analysis and Michael Chan for the bugfix. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Tested-by: John Marvin Signed-off-by: David S. Miller --- drivers/net/tg3.c | 29 +++++++++++++++++------------ drivers/net/tg3.h | 1 + 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 201be425643a..e4fa02c79278 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4656,6 +4656,7 @@ static int tg3_poll(struct napi_struct *napi, int budget) * so we must read it before checking for more work. */ tp->last_tag = sblk->status_tag; + tp->last_irq_tag = tp->last_tag; rmb(); } else sblk->status &= ~SD_STATUS_UPDATED; @@ -4811,7 +4812,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id) * Reading the PCI State register will confirm whether the * interrupt is ours and will flush the status block. */ - if (unlikely(sblk->status_tag == tp->last_tag)) { + if (unlikely(sblk->status_tag == tp->last_irq_tag)) { if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) || (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { handled = 0; @@ -4831,18 +4832,22 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id) * excessive spurious interrupts can be worse in some cases. */ tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + + /* + * In a shared interrupt configuration, sometimes other devices' + * interrupts will scream. We record the current status tag here + * so that the above check can report that the screaming interrupts + * are unhandled. Eventually they will be silenced. + */ + tp->last_irq_tag = sblk->status_tag; + if (tg3_irq_sync(tp)) goto out; - if (napi_schedule_prep(&tp->napi)) { - prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); - /* Update last_tag to mark that this status has been - * seen. Because interrupt may be shared, we may be - * racing with tg3_poll(), so only update last_tag - * if tg3_poll() is not scheduled. - */ - tp->last_tag = sblk->status_tag; - __napi_schedule(&tp->napi); - } + + prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); + + napi_schedule(&tp->napi); + out: return IRQ_RETVAL(handled); } @@ -6156,6 +6161,7 @@ static int tg3_chip_reset(struct tg3 *tp) tp->hw_status->status_tag = 0; } tp->last_tag = 0; + tp->last_irq_tag = 0; smp_mb(); synchronize_irq(tp->pdev->irq); @@ -7138,7 +7144,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(100); tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); - tp->last_tag = 0; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { tw32_f(DMAC_MODE, DMAC_MODE_ENABLE); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index cb4c62abdd21..ca71a49a3fd5 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2501,6 +2501,7 @@ struct tg3 { struct tg3_hw_status *hw_status; dma_addr_t status_mapping; u32 last_tag; + u32 last_irq_tag; u32 msg_enable; -- GitLab From df259d8cba7d7880dc04d34c7a6e0ce15fbc9644 Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 20 Apr 2009 06:57:14 +0000 Subject: [PATCH 0460/6080] tg3: Handle NVRAM absent cases Some 57780 ASIC revision parts do not have NVRAM. Code the driver so that it is tolerant of this configuration. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 36 ++++++++++++++++++++++++++++++++---- drivers/net/tg3.h | 1 + 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e4fa02c79278..9b04954b6943 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8544,6 +8544,9 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u32 i, offset, len, b_offset, b_count; __be32 val; + if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) + return -EINVAL; + if (tp->link_config.phy_is_low_power) return -EAGAIN; @@ -8609,7 +8612,8 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, if (tp->link_config.phy_is_low_power) return -EAGAIN; - if (eeprom->magic != TG3_EEPROM_MAGIC) + if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || + eeprom->magic != TG3_EEPROM_MAGIC) return -EINVAL; offset = eeprom->offset; @@ -9206,6 +9210,9 @@ static int tg3_test_nvram(struct tg3 *tp) __be32 *buf; int i, j, k, err = 0, size; + if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) + return 0; + if (tg3_nvram_read(tp, 0, &magic) != 0) return -EIO; @@ -10188,7 +10195,8 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp) { u32 val; - if (tg3_nvram_read(tp, 0, &val) != 0) + if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || + tg3_nvram_read(tp, 0, &val) != 0) return; /* Selfboot format */ @@ -10570,6 +10578,7 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp) } break; default: + tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM; return; } @@ -11370,7 +11379,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp) unsigned int i; u32 magic; - if (tg3_nvram_read(tp, 0x0, &magic)) + if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || + tg3_nvram_read(tp, 0x0, &magic)) goto out_not_found; if (magic == TG3_EEPROM_MAGIC) { @@ -11462,6 +11472,15 @@ static void __devinit tg3_read_partno(struct tg3 *tp) out_not_found: if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) strcpy(tp->board_part_number, "BCM95906"); + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780) + strcpy(tp->board_part_number, "BCM57780"); + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760) + strcpy(tp->board_part_number, "BCM57760"); + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && + tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790) + strcpy(tp->board_part_number, "BCM57790"); else strcpy(tp->board_part_number, "none"); } @@ -11672,6 +11691,14 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) { u32 val; + if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) { + tp->fw_ver[0] = 's'; + tp->fw_ver[1] = 'b'; + tp->fw_ver[2] = '\0'; + + return; + } + if (tg3_nvram_read(tp, 0, &val)) return; @@ -12459,7 +12486,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) } if (!addr_ok) { /* Next, try NVRAM. */ - if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) && + if (!(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) && + !tg3_nvram_read_be32(tp, mac_offset + 0, &hi) && !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) { memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2); memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo)); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index ca71a49a3fd5..afbabf283c51 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2636,6 +2636,7 @@ struct tg3 { #define TG3_FLG3_CLKREQ_BUG 0x00000800 #define TG3_FLG3_PHY_ENABLE_APD 0x00001000 #define TG3_FLG3_5755_PLUS 0x00002000 +#define TG3_FLG3_NO_NVRAM 0x00004000 struct timer_list timer; u16 timer_counter; -- GitLab From 33466d938f43ab65312466ba5472b9c6ee200cce Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 20 Apr 2009 06:57:41 +0000 Subject: [PATCH 0461/6080] tg3: Prevent send BD corruption On rare occasions, send BD corruptions can occur. This patch fixes the problem by increasing the L1 entry threshold to 4 milliseconds. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 7 +++++++ drivers/net/tg3.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 9b04954b6943..ed7a86df98cd 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -6717,6 +6717,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(TG3_CPMU_HST_ACC, val); } + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) { + val = tr32(PCIE_PWR_MGMT_THRESH) & ~PCIE_PWR_MGMT_L1_THRESH_MSK; + val |= PCIE_PWR_MGMT_EXT_ASPM_TMR_EN | + PCIE_PWR_MGMT_L1_THRESH_4MS; + tw32(PCIE_PWR_MGMT_THRESH, val); + } + /* This works around an issue with Athlon chipsets on * B3 tigon3 silicon. This bit has no effect on any * other revision. But do not set this on PCI Express diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index afbabf283c51..f1016cb1a89a 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -1697,6 +1697,8 @@ #define PCIE_PWR_MGMT_THRESH 0x00007d28 #define PCIE_PWR_MGMT_L1_THRESH_MSK 0x0000ff00 +#define PCIE_PWR_MGMT_L1_THRESH_4MS 0x0000ff00 +#define PCIE_PWR_MGMT_EXT_ASPM_TMR_EN 0x01000000 /* OTP bit definitions */ -- GitLab From 8d519ab2866c92f5d722085492a124f016f601aa Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 20 Apr 2009 06:58:01 +0000 Subject: [PATCH 0462/6080] tg3: Allow 5761 WOL and LED fixes to 5761S too The 5761 WOL and LED fixes used the PCI device ID to as the activation key. The 5761S requires the same process. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ed7a86df98cd..c5c3d2853144 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1950,7 +1950,8 @@ static void tg3_frob_aux_power(struct tg3 *tp) GRC_LCLCTRL_GPIO_OUTPUT0 | GRC_LCLCTRL_GPIO_OUTPUT1), 100); - } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) { + } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) { /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */ u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 | @@ -12183,7 +12184,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; - if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) { + if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 || + tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) { /* Turn off the debug UART. */ tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL; if (tp->tg3_flags2 & TG3_FLG2_IS_NIC) -- GitLab From 9cf74ebb634fe79587cf9a1d5ff971391dd12e1b Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 20 Apr 2009 06:58:27 +0000 Subject: [PATCH 0463/6080] tg3: Limit CLKREQ fix to A[01] of 57780 asic rev This patch restricts the CLKREQ bugfix to the A0 and A1 revisions of 57780 ASIC rev chips. Signed-off-by: Matt Carlson Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 3 ++- drivers/net/tg3.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index c5c3d2853144..0501fb48a004 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -11992,7 +11992,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) + tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 || + tp->pci_chip_rev_id == CHIPREV_ID_57780_A1) tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG; } } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) { diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index f1016cb1a89a..b3347c41a1a3 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -95,6 +95,8 @@ #define CHIPREV_ID_5752_A1 0x6001 #define CHIPREV_ID_5714_A2 0x9002 #define CHIPREV_ID_5906_A1 0xc001 +#define CHIPREV_ID_57780_A0 0x57780000 +#define CHIPREV_ID_57780_A1 0x57780001 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 #define ASIC_REV_5701 0x00 -- GitLab From daba2a631d2b7831b6a021b36d61314a9153526e Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 20 Apr 2009 06:58:52 +0000 Subject: [PATCH 0464/6080] tg3: Restore LAA sooner in shutdown sequence After a shutdown reset, the LAA needs to be restored before posting the post-reset signature in shared memory. If the LAA is not restored before then, the bootcode will assume the factory default MAC address and WOL will not work with the LAA. Signed-off-by: Matt Carlson Signed-off-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 0501fb48a004..f2b7ff80df98 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2456,8 +2456,6 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) } } - __tg3_set_mac_addr(tp, 0); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { u32 val; @@ -6357,6 +6355,8 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent) tg3_abort_hw(tp, silent); err = tg3_chip_reset(tp); + __tg3_set_mac_addr(tp, 0); + tg3_write_sig_legacy(tp, kind); tg3_write_sig_post_reset(tp, kind); -- GitLab From bb9e63e27117b469a151c61fb0045a8ec4cced5d Mon Sep 17 00:00:00 2001 From: Matt Carlson Date: Mon, 20 Apr 2009 07:13:31 +0000 Subject: [PATCH 0465/6080] tg3: Update version to 3.99 This patch updates the tg3 version to 3.99. Signed-off-by: Matt Carlson Signed-off-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 f2b7ff80df98..eb65e25989f3 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.98" -#define DRV_MODULE_RELDATE "February 25, 2009" +#define DRV_MODULE_VERSION "3.99" +#define DRV_MODULE_RELDATE "April 20, 2009" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- GitLab From 03ad032bb78b2732b607ed198e951240e1d21e59 Mon Sep 17 00:00:00 2001 From: Peter Holik Date: Sat, 18 Apr 2009 07:24:17 +0000 Subject: [PATCH 0466/6080] export usbnet_get_ethernet_addr from usbnet and fixed cdc_ether.c because of using the same function get_ethernet_addr as cdc_ether.c i export usbnet_get_ethernet_addr from usbnet and fixed cdc_ether (suggested by Oliver Neukum). Signed-off-by: Peter Holik Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ether.c | 33 +-------------------------------- drivers/net/usb/usbnet.c | 31 +++++++++++++++++++++++++++++++ include/linux/usb/usbnet.h | 1 + 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 55e8ecc3a9e5..01fd528306ec 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -389,36 +388,6 @@ static void cdc_status(struct usbnet *dev, struct urb *urb) } } -static u8 nibble(unsigned char c) -{ - if (likely(isdigit(c))) - return c - '0'; - c = toupper(c); - if (likely(isxdigit(c))) - return 10 + c - 'A'; - return 0; -} - -static inline int -get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e) -{ - int tmp, i; - unsigned char buf [13]; - - tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf); - if (tmp != 12) { - dev_dbg(&dev->udev->dev, - "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp); - if (tmp >= 0) - tmp = -EINVAL; - return tmp; - } - for (i = tmp = 0; i < 6; i++, tmp += 2) - dev->net->dev_addr [i] = - (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]); - return 0; -} - static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) { int status; @@ -428,7 +397,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) if (status < 0) return status; - status = get_ethernet_addr(dev, info->ether); + status = usbnet_get_ethernet_addr(dev, info->ether->iMACAddress); if (status < 0) { usb_set_intfdata(info->data, NULL); usb_driver_release_interface(driver_of(intf), info->data); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 2b8b9036aff6..c94de6243140 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -156,6 +157,36 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf) } EXPORT_SYMBOL_GPL(usbnet_get_endpoints); +static u8 nibble(unsigned char c) +{ + if (likely(isdigit(c))) + return c - '0'; + c = toupper(c); + if (likely(isxdigit(c))) + return 10 + c - 'A'; + return 0; +} + +int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress) +{ + int tmp, i; + unsigned char buf [13]; + + tmp = usb_string(dev->udev, iMACAddress, buf, sizeof buf); + if (tmp != 12) { + dev_dbg(&dev->udev->dev, + "bad MAC string %d fetch, %d\n", iMACAddress, tmp); + if (tmp >= 0) + tmp = -EINVAL; + return tmp; + } + for (i = tmp = 0; i < 6; i++, tmp += 2) + dev->net->dev_addr [i] = + (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]); + return 0; +} +EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr); + static void intr_complete (struct urb *urb); static int init_status (struct usbnet *dev, struct usb_interface *intf) diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 36fabb95c7d3..5d44059f6d63 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -183,6 +183,7 @@ extern void usbnet_tx_timeout (struct net_device *net); extern int usbnet_change_mtu (struct net_device *net, int new_mtu); extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *); +extern int usbnet_get_ethernet_addr(struct usbnet *, int); extern void usbnet_defer_kevent (struct usbnet *, int); extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); extern void usbnet_unlink_rx_urbs(struct usbnet *); -- GitLab From 4510d7cb8b4e7d389652b8a4f89fad469a5ecc92 Mon Sep 17 00:00:00 2001 From: Peter Holik Date: Sat, 18 Apr 2009 07:24:21 +0000 Subject: [PATCH 0467/6080] usb driver for intellon int51x1 based PLC like devolo dlan duo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usb driver for intellon int51x1 based PLC like devolo dlan duo with improvements suggested by the guys of the mailinglist: - name and prefix with int51x1 (Florian Fainelli) - use conversion functions cpu_to_le16 / le16_to_cpu (Oliver Neukum) - use pskb_may_pull instead of skb->len (Ilpo Järvinen) - better code in tx_fixup (Ilpo Järvinen) - use gotos for error handling (Ilpo Järvinen) - better description (Jon Smirl) Signed-off-by: Peter Holik Signed-off-by: David S. Miller --- drivers/net/usb/Kconfig | 8 ++ drivers/net/usb/Makefile | 1 + drivers/net/usb/int51x1.c | 253 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100644 drivers/net/usb/int51x1.c diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 8ee21030e9ac..e00b5b1f6743 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -345,4 +345,12 @@ config USB_HSO To compile this driver as a module, choose M here: the module will be called hso. +config USB_NET_INT51X1 + tristate "Intellon PLC based usb adapter" + depends on USB_USBNET + help + Choose this option if you're using a 14Mb USB-based PLC + (Powerline Communications) solution with an Intellon + INT51x1/INT5200 chip, like the "devolo dLan duo". + endmenu diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 88a87eeb376a..f4402a06e52c 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -19,4 +19,5 @@ obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o obj-$(CONFIG_USB_USBNET) += usbnet.o +obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c new file mode 100644 index 000000000000..55cf7081de10 --- /dev/null +++ b/drivers/net/usb/int51x1.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2009 Peter Holik + * + * Intellon usb PLC (Powerline Communications) usb net driver + * + * http://www.tandel.be/downloads/INT51X1_Datasheet.pdf + * + * Based on the work of Jan 'RedBully' Seiffert + */ + +/* + * 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 + +#define INT51X1_VENDOR_ID 0x09e1 +#define INT51X1_PRODUCT_ID 0x5121 + +#define INT51X1_HEADER_SIZE 2 /* 2 byte header */ + +#define PACKET_TYPE_PROMISCUOUS (1 << 0) +#define PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */ +#define PACKET_TYPE_DIRECTED (1 << 2) +#define PACKET_TYPE_BROADCAST (1 << 3) +#define PACKET_TYPE_MULTICAST (1 << 4) /* filtered */ + +#define SET_ETHERNET_PACKET_FILTER 0x43 + +static int int51x1_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + int len; + + if (!(pskb_may_pull(skb, INT51X1_HEADER_SIZE))) { + deverr(dev, "unexpected tiny rx frame"); + return 0; + } + + len = le16_to_cpu(*(__le16 *)&skb->data[skb->len - 2]); + + skb_trim(skb, len); + + return 1; +} + +static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev, + struct sk_buff *skb, gfp_t flags) +{ + int pack_len = skb->len; + int pack_with_header_len = pack_len + INT51X1_HEADER_SIZE; + int headroom = skb_headroom(skb); + int tailroom = skb_tailroom(skb); + int need_tail = 0; + __le16 *len; + + /* if packet and our header is smaler than 64 pad to 64 (+ ZLP) */ + if ((pack_with_header_len) < dev->maxpacket) + need_tail = dev->maxpacket - pack_with_header_len + 1; + /* + * usbnet would send a ZLP if packetlength mod urbsize == 0 for us, + * but we need to know ourself, because this would add to the length + * we send down to the device... + */ + else if (!(pack_with_header_len % dev->maxpacket)) + need_tail = 1; + + if (!skb_cloned(skb) && + (headroom + tailroom >= need_tail + INT51X1_HEADER_SIZE)) { + if (headroom < INT51X1_HEADER_SIZE || tailroom < need_tail) { + skb->data = memmove(skb->head + INT51X1_HEADER_SIZE, + skb->data, skb->len); + skb_set_tail_pointer(skb, skb->len); + } + } else { + struct sk_buff *skb2; + + skb2 = skb_copy_expand(skb, + INT51X1_HEADER_SIZE, + need_tail, + flags); + dev_kfree_skb_any(skb); + if (!skb2) + return NULL; + skb = skb2; + } + + pack_len += need_tail; + pack_len &= 0x07ff; + + len = (__le16 *) __skb_push(skb, INT51X1_HEADER_SIZE); + *len = cpu_to_le16(pack_len); + + if(need_tail) + memset(__skb_put(skb, need_tail), 0, need_tail); + + return skb; +} + +static void int51x1_async_cmd_callback(struct urb *urb) +{ + struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; + int status = urb->status; + + if (status < 0) + dev_warn(&urb->dev->dev, "async callback failed with %d\n", status); + + kfree(req); + usb_free_urb(urb); +} + +static void int51x1_set_multicast(struct net_device *netdev) +{ + struct usb_ctrlrequest *req; + int status; + struct urb *urb; + struct usbnet *dev = netdev_priv(netdev); + u16 filter = PACKET_TYPE_DIRECTED | PACKET_TYPE_BROADCAST; + + if (netdev->flags & IFF_PROMISC) { + /* do not expect to see traffic of other PLCs */ + filter |= PACKET_TYPE_PROMISCUOUS; + devinfo(dev, "promiscuous mode enabled"); + } else if (netdev->mc_count || + (netdev->flags & IFF_ALLMULTI)) { + filter |= PACKET_TYPE_ALL_MULTICAST; + devdbg(dev, "receive all multicast enabled"); + } else { + /* ~PROMISCUOUS, ~MULTICAST */ + devdbg(dev, "receive own packets only"); + } + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { + devwarn(dev, "Error allocating URB"); + return; + } + + req = kmalloc(sizeof(*req), GFP_ATOMIC); + if (!req) { + devwarn(dev, "Error allocating control msg"); + goto out; + } + + req->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + req->bRequest = SET_ETHERNET_PACKET_FILTER; + req->wValue = cpu_to_le16(filter); + req->wIndex = 0; + req->wLength = 0; + + usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), + (void *)req, NULL, 0, + int51x1_async_cmd_callback, + (void *)req); + + status = usb_submit_urb(urb, GFP_ATOMIC); + if (status < 0) { + devwarn(dev, "Error submitting control msg, sts=%d", status); + goto out1; + } + return; +out1: + kfree(req); +out: + usb_free_urb(urb); +} + +static const struct net_device_ops int51x1_netdev_ops = { + .ndo_open = usbnet_open, + .ndo_stop = usbnet_stop, + .ndo_start_xmit = usbnet_start_xmit, + .ndo_tx_timeout = usbnet_tx_timeout, + .ndo_change_mtu = usbnet_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_multicast_list = int51x1_set_multicast, +}; + +static int int51x1_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int status = usbnet_get_ethernet_addr(dev, 3); + + if (status) + return status; + + dev->net->hard_header_len += INT51X1_HEADER_SIZE; + dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; + dev->net->netdev_ops = &int51x1_netdev_ops; + + return usbnet_get_endpoints(dev, intf); +} + +static const struct driver_info int51x1_info = { + .description = "Intellon usb powerline adapter", + .bind = int51x1_bind, + .rx_fixup = int51x1_rx_fixup, + .tx_fixup = int51x1_tx_fixup, + .in = 1, + .out = 2, + .flags = FLAG_ETHER, +}; + +static const struct usb_device_id products[] = { + { + USB_DEVICE(INT51X1_VENDOR_ID, INT51X1_PRODUCT_ID), + .driver_info = (unsigned long) &int51x1_info, + }, + {}, +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver int51x1_driver = { + .name = "int51x1", + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, +}; + +static int __init int51x1_init(void) +{ + return usb_register(&int51x1_driver); +} +module_init(int51x1_init); + +static void __exit int51x1_exit(void) +{ + usb_deregister(&int51x1_driver); +} +module_exit(int51x1_exit); + +MODULE_AUTHOR("Peter Holik"); +MODULE_DESCRIPTION("Intellon usb powerline adapter"); +MODULE_LICENSE("GPL"); -- GitLab From b1b67dd45a6b629eb41553856805aaa1614fbb83 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 20 Apr 2009 04:49:28 +0000 Subject: [PATCH 0468/6080] net: factor out ethtool invocation of vlan/macvlan drivers Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 22 +++------------------- include/linux/netdevice.h | 24 +++++++++++++++++++++++- net/8021q/vlan_dev.c | 23 +++-------------------- 3 files changed, 29 insertions(+), 40 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 214a8cf2b708..329cd50d0e29 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -374,36 +374,20 @@ static void macvlan_ethtool_get_drvinfo(struct net_device *dev, static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev) { const struct macvlan_dev *vlan = netdev_priv(dev); - struct net_device *lowerdev = vlan->lowerdev; - - if (lowerdev->ethtool_ops == NULL || - lowerdev->ethtool_ops->get_rx_csum == NULL) - return 0; - return lowerdev->ethtool_ops->get_rx_csum(lowerdev); + return dev_ethtool_get_rx_csum(vlan->lowerdev); } static int macvlan_ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { const struct macvlan_dev *vlan = netdev_priv(dev); - struct net_device *lowerdev = vlan->lowerdev; - - if (!lowerdev->ethtool_ops || - !lowerdev->ethtool_ops->get_settings) - return -EOPNOTSUPP; - - return lowerdev->ethtool_ops->get_settings(lowerdev, cmd); + return dev_ethtool_get_settings(vlan->lowerdev, cmd); } static u32 macvlan_ethtool_get_flags(struct net_device *dev) { const struct macvlan_dev *vlan = netdev_priv(dev); - struct net_device *lowerdev = vlan->lowerdev; - - if (!lowerdev->ethtool_ops || - !lowerdev->ethtool_ops->get_flags) - return 0; - return lowerdev->ethtool_ops->get_flags(lowerdev); + return dev_ethtool_get_flags(vlan->lowerdev); } static const struct ethtool_ops macvlan_ethtool_ops = { diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 54db3ebf2193..31167451d08d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -42,6 +42,7 @@ #include #include +#include #include #include #ifdef CONFIG_DCB @@ -49,7 +50,6 @@ #endif struct vlan_group; -struct ethtool_ops; struct netpoll_info; /* 802.11 specific */ struct wireless_dev; @@ -1906,6 +1906,28 @@ static inline int skb_bond_should_drop(struct sk_buff *skb) } extern struct pernet_operations __net_initdata loopback_net_ops; + +static inline int dev_ethtool_get_settings(struct net_device *dev, + struct ethtool_cmd *cmd) +{ + if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings) + return -EOPNOTSUPP; + return dev->ethtool_ops->get_settings(dev, cmd); +} + +static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev) +{ + if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum) + return 0; + return dev->ethtool_ops->get_rx_csum(dev); +} + +static inline u32 dev_ethtool_get_flags(struct net_device *dev) +{ + if (!dev->ethtool_ops || !dev->ethtool_ops->get_flags) + return 0; + return dev->ethtool_ops->get_flags(dev); +} #endif /* __KERNEL__ */ #endif /* _LINUX_DEV_H */ diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 6b0921364014..04dc8c8a6854 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -666,13 +666,7 @@ static int vlan_ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { const struct vlan_dev_info *vlan = vlan_dev_info(dev); - struct net_device *real_dev = vlan->real_dev; - - if (!real_dev->ethtool_ops || - !real_dev->ethtool_ops->get_settings) - return -EOPNOTSUPP; - - return real_dev->ethtool_ops->get_settings(real_dev, cmd); + return dev_ethtool_get_settings(vlan->real_dev, cmd); } static void vlan_ethtool_get_drvinfo(struct net_device *dev, @@ -686,24 +680,13 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev, static u32 vlan_ethtool_get_rx_csum(struct net_device *dev) { const struct vlan_dev_info *vlan = vlan_dev_info(dev); - struct net_device *real_dev = vlan->real_dev; - - if (real_dev->ethtool_ops == NULL || - real_dev->ethtool_ops->get_rx_csum == NULL) - return 0; - return real_dev->ethtool_ops->get_rx_csum(real_dev); + return dev_ethtool_get_rx_csum(vlan->real_dev); } static u32 vlan_ethtool_get_flags(struct net_device *dev) { const struct vlan_dev_info *vlan = vlan_dev_info(dev); - struct net_device *real_dev = vlan->real_dev; - - if (!(real_dev->features & NETIF_F_HW_VLAN_RX) || - real_dev->ethtool_ops == NULL || - real_dev->ethtool_ops->get_flags == NULL) - return 0; - return real_dev->ethtool_ops->get_flags(real_dev); + return dev_ethtool_get_flags(vlan->real_dev); } static const struct ethtool_ops vlan_ethtool_ops = { -- GitLab From d035fbccc4edd2bd69d9314faf03ba832b85a1d7 Mon Sep 17 00:00:00 2001 From: Jianjun Kong Date: Mon, 20 Apr 2009 04:05:34 +0000 Subject: [PATCH 0469/6080] rtl8139: unify the struct's name unify the struct's name of "struct rtl8139_private *np" to "struct rtl8139_private *tp" most of them like this: struct rtl8139_private *tp = netdev_priv(dev); Signed-off-by: Amos Kong Signed-off-by: David S. Miller --- drivers/net/8139too.c | 92 +++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 29df398b7727..00fe1301a9c4 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -2292,11 +2292,11 @@ static int rtl8139_close (struct net_device *dev) other threads or interrupts aren't messing with the 8139. */ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { - struct rtl8139_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mmio_addr; + struct rtl8139_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; - spin_lock_irq(&np->lock); - if (rtl_chip_info[np->chipset].flags & HasLWake) { + spin_lock_irq(&tp->lock); + if (rtl_chip_info[tp->chipset].flags & HasLWake) { u8 cfg3 = RTL_R8 (Config3); u8 cfg5 = RTL_R8 (Config5); @@ -2317,7 +2317,7 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (cfg5 & Cfg5_BWF) wol->wolopts |= WAKE_BCAST; } - spin_unlock_irq(&np->lock); + spin_unlock_irq(&tp->lock); } @@ -2326,19 +2326,19 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) aren't messing with the 8139. */ static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { - struct rtl8139_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->mmio_addr; + struct rtl8139_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; u32 support; u8 cfg3, cfg5; - support = ((rtl_chip_info[np->chipset].flags & HasLWake) + support = ((rtl_chip_info[tp->chipset].flags & HasLWake) ? (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST) : 0); if (wol->wolopts & ~support) return -EINVAL; - spin_lock_irq(&np->lock); + spin_lock_irq(&tp->lock); cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic); if (wol->wolopts & WAKE_PHY) cfg3 |= Cfg3_LinkUp; @@ -2359,87 +2359,87 @@ static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (wol->wolopts & WAKE_BCAST) cfg5 |= Cfg5_BWF; RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */ - spin_unlock_irq(&np->lock); + spin_unlock_irq(&tp->lock); return 0; } static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct rtl8139_private *np = netdev_priv(dev); + struct rtl8139_private *tp = netdev_priv(dev); strcpy(info->driver, DRV_NAME); strcpy(info->version, DRV_VERSION); - strcpy(info->bus_info, pci_name(np->pci_dev)); - info->regdump_len = np->regs_len; + strcpy(info->bus_info, pci_name(tp->pci_dev)); + info->regdump_len = tp->regs_len; } static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct rtl8139_private *np = netdev_priv(dev); - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii, cmd); - spin_unlock_irq(&np->lock); + struct rtl8139_private *tp = netdev_priv(dev); + spin_lock_irq(&tp->lock); + mii_ethtool_gset(&tp->mii, cmd); + spin_unlock_irq(&tp->lock); return 0; } static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct rtl8139_private *np = netdev_priv(dev); + struct rtl8139_private *tp = netdev_priv(dev); int rc; - spin_lock_irq(&np->lock); - rc = mii_ethtool_sset(&np->mii, cmd); - spin_unlock_irq(&np->lock); + spin_lock_irq(&tp->lock); + rc = mii_ethtool_sset(&tp->mii, cmd); + spin_unlock_irq(&tp->lock); return rc; } static int rtl8139_nway_reset(struct net_device *dev) { - struct rtl8139_private *np = netdev_priv(dev); - return mii_nway_restart(&np->mii); + struct rtl8139_private *tp = netdev_priv(dev); + return mii_nway_restart(&tp->mii); } static u32 rtl8139_get_link(struct net_device *dev) { - struct rtl8139_private *np = netdev_priv(dev); - return mii_link_ok(&np->mii); + struct rtl8139_private *tp = netdev_priv(dev); + return mii_link_ok(&tp->mii); } static u32 rtl8139_get_msglevel(struct net_device *dev) { - struct rtl8139_private *np = netdev_priv(dev); - return np->msg_enable; + struct rtl8139_private *tp = netdev_priv(dev); + return tp->msg_enable; } static void rtl8139_set_msglevel(struct net_device *dev, u32 datum) { - struct rtl8139_private *np = netdev_priv(dev); - np->msg_enable = datum; + struct rtl8139_private *tp = netdev_priv(dev); + tp->msg_enable = datum; } static int rtl8139_get_regs_len(struct net_device *dev) { - struct rtl8139_private *np; + struct rtl8139_private *tp; /* TODO: we are too slack to do reg dumping for pio, for now */ if (use_io) return 0; - np = netdev_priv(dev); - return np->regs_len; + tp = netdev_priv(dev); + return tp->regs_len; } static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) { - struct rtl8139_private *np; + struct rtl8139_private *tp; /* TODO: we are too slack to do reg dumping for pio, for now */ if (use_io) return; - np = netdev_priv(dev); + tp = netdev_priv(dev); regs->version = RTL_REGS_VER; - spin_lock_irq(&np->lock); - memcpy_fromio(regbuf, np->mmio_addr, regs->len); - spin_unlock_irq(&np->lock); + spin_lock_irq(&tp->lock); + memcpy_fromio(regbuf, tp->mmio_addr, regs->len); + spin_unlock_irq(&tp->lock); } static int rtl8139_get_sset_count(struct net_device *dev, int sset) @@ -2454,12 +2454,12 @@ static int rtl8139_get_sset_count(struct net_device *dev, int sset) static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) { - struct rtl8139_private *np = netdev_priv(dev); + struct rtl8139_private *tp = netdev_priv(dev); - data[0] = np->xstats.early_rx; - data[1] = np->xstats.tx_buf_mapped; - data[2] = np->xstats.tx_timeouts; - data[3] = np->xstats.rx_lost_in_ring; + data[0] = tp->xstats.early_rx; + data[1] = tp->xstats.tx_buf_mapped; + data[2] = tp->xstats.tx_timeouts; + data[3] = tp->xstats.rx_lost_in_ring; } static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data) @@ -2486,15 +2486,15 @@ static const struct ethtool_ops rtl8139_ethtool_ops = { static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct rtl8139_private *np = netdev_priv(dev); + struct rtl8139_private *tp = netdev_priv(dev); int rc; if (!netif_running(dev)) return -EINVAL; - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL); - spin_unlock_irq(&np->lock); + spin_lock_irq(&tp->lock); + rc = generic_mii_ioctl(&tp->mii, if_mii(rq), cmd, NULL); + spin_unlock_irq(&tp->lock); return rc; } -- GitLab From 0cededf3ffbb775c3716aa1d246338fdc24b1259 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Fri, 17 Apr 2009 12:03:48 +0000 Subject: [PATCH 0470/6080] ucc_geth: Move freeing of TX packets to NAPI context This will make the system alot more responsive while ping flooding the ucc_geth ethernet interface. Also set NAPI weight to 64 as this is a common value. Signed-off-by: Joakim Tjernlund Signed-off-by: Anton Vorontsov Signed-off-by: David S. Miller --- drivers/net/ucc_geth.c | 31 +++++++++++-------------------- drivers/net/ucc_geth.h | 1 - 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index d3f39e86eb95..98f961e92ca9 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3216,7 +3216,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) dev->stats.tx_packets++; /* Free the sk buffer associated with this TxBD */ - dev_kfree_skb_irq(ugeth-> + dev_kfree_skb(ugeth-> tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]); ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL; ugeth->skb_dirtytx[txQ] = @@ -3250,9 +3250,15 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget) for (i = 0; i < ug_info->numQueuesRx; i++) howmany += ucc_geth_rx(ugeth, i, budget - howmany); + /* Tx event processing */ + spin_lock(&ugeth->lock); + for (i = 0; i < ug_info->numQueuesTx; i++) + ucc_geth_tx(ugeth->ndev, i); + spin_unlock(&ugeth->lock); + if (howmany < budget) { napi_complete(napi); - setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS); + setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS); } return howmany; @@ -3266,8 +3272,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) struct ucc_geth_info *ug_info; register u32 ucce; register u32 uccm; - register u32 tx_mask; - u8 i; ugeth_vdbg("%s: IN", __func__); @@ -3281,27 +3285,14 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) out_be32(uccf->p_ucce, ucce); /* check for receive events that require processing */ - if (ucce & UCCE_RX_EVENTS) { + if (ucce & (UCCE_RX_EVENTS | UCCE_TX_EVENTS)) { if (napi_schedule_prep(&ugeth->napi)) { - uccm &= ~UCCE_RX_EVENTS; + uccm &= ~(UCCE_RX_EVENTS | UCCE_TX_EVENTS); out_be32(uccf->p_uccm, uccm); __napi_schedule(&ugeth->napi); } } - /* Tx event processing */ - if (ucce & UCCE_TX_EVENTS) { - spin_lock(&ugeth->lock); - tx_mask = UCC_GETH_UCCE_TXB0; - for (i = 0; i < ug_info->numQueuesTx; i++) { - if (ucce & tx_mask) - ucc_geth_tx(dev, i); - ucce &= ~tx_mask; - tx_mask <<= 1; - } - spin_unlock(&ugeth->lock); - } - /* Errors and other events */ if (ucce & UCCE_OTHER) { if (ucce & UCC_GETH_UCCE_BSY) @@ -3734,7 +3725,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma dev->netdev_ops = &ucc_geth_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); - netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT); + netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64); dev->mtu = 1500; ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 2f8ee7c87efe..602764799df0 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -852,7 +852,6 @@ struct ucc_geth_hardware_statistics { /* Driver definitions */ #define TX_BD_RING_LEN 0x10 #define RX_BD_RING_LEN 0x10 -#define UCC_GETH_DEV_WEIGHT TX_BD_RING_LEN #define TX_RING_MOD_MASK(size) (size-1) #define RX_RING_MOD_MASK(size) (size-1) -- GitLab From 92c7c8a7d6e03eb4c0a3c5888e35dbc45f24744c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Mar 2009 07:32:14 +0100 Subject: [PATCH 0471/6080] ALSA: hda - Cache PCM and STREAM parameters queries Cache quries for PCM and STREAM parameters as well as ampcap and pincap sharing the hash table. This will reduce the superfluous access of the same codec verbs. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 97 ++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 36 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a4e5e5952115..3d8bf39e6d98 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1053,6 +1053,8 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream); /* FIXME: more better hash key? */ #define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) #define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) +#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24)) +#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24)) #define INFO_AMP_CAPS (1<<0) #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) @@ -1143,19 +1145,32 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, } EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps); -u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) +static unsigned int +query_caps_hash(struct hda_codec *codec, hda_nid_t nid, u32 key, + unsigned int (*func)(struct hda_codec *, hda_nid_t)) { struct hda_amp_info *info; - info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid)); + info = get_alloc_amp_hash(codec, key); if (!info) return 0; if (!info->head.val) { - info->amp_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); info->head.val |= INFO_AMP_CAPS; + info->amp_caps = func(codec, nid); } return info->amp_caps; } + +static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid) +{ + return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); +} + +u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) +{ + return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid), + read_pin_cap); +} EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); /* @@ -2538,6 +2553,41 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, } EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); +static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid) +{ + unsigned int val = 0; + if (nid != codec->afg && + (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) + val = snd_hda_param_read(codec, nid, AC_PAR_PCM); + if (!val || val == -1) + val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); + if (!val || val == -1) + return 0; + return val; +} + +static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid) +{ + return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid), + get_pcm_param); +} + +static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid) +{ + unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); + if (!streams || streams == -1) + streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); + if (!streams || streams == -1) + return 0; + return streams; +} + +static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid) +{ + return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid), + get_stream_param); +} + /** * snd_hda_query_supported_pcm - query the supported PCM rates and formats * @codec: the HDA codec @@ -2556,15 +2606,8 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, { unsigned int i, val, wcaps; - val = 0; wcaps = get_wcaps(codec, nid); - if (nid != codec->afg && (wcaps & AC_WCAP_FORMAT_OVRD)) { - val = snd_hda_param_read(codec, nid, AC_PAR_PCM); - if (val == -1) - return -EIO; - } - if (!val) - val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); + val = query_pcm_param(codec, nid); if (ratesp) { u32 rates = 0; @@ -2586,15 +2629,9 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, u64 formats = 0; unsigned int streams, bps; - streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); - if (streams == -1) + streams = query_stream_param(codec, nid); + if (!streams) return -EIO; - if (!streams) { - streams = snd_hda_param_read(codec, codec->afg, - AC_PAR_STREAM); - if (streams == -1) - return -EIO; - } bps = 0; if (streams & AC_SUPFMT_PCM) { @@ -2668,17 +2705,9 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, int i; unsigned int val = 0, rate, stream; - if (nid != codec->afg && - (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) { - val = snd_hda_param_read(codec, nid, AC_PAR_PCM); - if (val == -1) - return 0; - } - if (!val) { - val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); - if (val == -1) - return 0; - } + val = query_pcm_param(codec, nid); + if (!val) + return 0; rate = format & 0xff00; for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) @@ -2690,12 +2719,8 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, if (i >= AC_PAR_PCM_RATE_BITS) return 0; - stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); - if (stream == -1) - return 0; - if (!stream && nid != codec->afg) - stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); - if (!stream || stream == -1) + stream = query_stream_param(codec, nid); + if (!stream) return 0; if (stream & AC_SUPFMT_PCM) { -- GitLab From b613291fb21a2d74eb8323d97fe9aa5d281b306c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Mar 2009 07:36:09 +0100 Subject: [PATCH 0472/6080] ALSA: hda - Retry codec-verbs at errors The current error-recovery scheme for the codec communication errors doesn't work always well. Especially falling back to the single-command mode causes the fatal problem on many systems. In this patch, the problematic verb is re-issued again after the error (even with polling mode) instead of the single-cmd mode. The single-cmd mode will be used only when specified via the command option explicitly, mainly just for testing. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 17 +++++++++++++---- sound/pci/hda/hda_codec.h | 1 + sound/pci/hda/hda_intel.c | 19 ++++++++++--------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 3d8bf39e6d98..1736ccbebc72 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -174,14 +174,23 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, unsigned int verb, unsigned int parm) { struct hda_bus *bus = codec->bus; - unsigned int res; + unsigned int cmd, res; + int repeated = 0; - res = make_codec_cmd(codec, nid, direct, verb, parm); + cmd = make_codec_cmd(codec, nid, direct, verb, parm); snd_hda_power_up(codec); mutex_lock(&bus->cmd_mutex); - if (!bus->ops.command(bus, res)) + again: + if (!bus->ops.command(bus, cmd)) { res = bus->ops.get_response(bus); - else + if (res == -1 && bus->rirb_error) { + if (repeated++ < 1) { + snd_printd(KERN_WARNING "hda_codec: " + "Trying verb 0x%08x again\n", cmd); + goto again; + } + } + } else res = (unsigned int)-1; mutex_unlock(&bus->cmd_mutex); snd_hda_power_down(codec); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 2fdecf4b0eb6..cd8979c7670b 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -623,6 +623,7 @@ struct hda_bus { /* misc op flags */ unsigned int needs_damn_long_delay :1; unsigned int shutdown :1; /* being unloaded */ + unsigned int rirb_error:1; /* error in codec communication */ }; /* diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 30829ee920c3..803b72098ed3 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -604,6 +604,7 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) } if (!chip->rirb.cmds) { smp_rmb(); + bus->rirb_error = 0; return chip->rirb.res; /* the last value */ } if (time_after(jiffies, timeout)) @@ -623,8 +624,10 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) chip->irq = -1; pci_disable_msi(chip->pci); chip->msi = 0; - if (azx_acquire_irq(chip, 1) < 0) + if (azx_acquire_irq(chip, 1) < 0) { + bus->rirb_error = 1; return -1; + } goto again; } @@ -644,14 +647,12 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) return -1; } - snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " - "switching to single_cmd mode: last cmd=0x%08x\n", - chip->last_cmd); - chip->rirb.rp = azx_readb(chip, RIRBWP); - chip->rirb.cmds = 0; - /* switch to single_cmd mode */ - chip->single_cmd = 1; - azx_free_cmd_io(chip); + snd_printk(KERN_ERR "hda_intel: azx_get_response timeout (ERROR): " + "last cmd=0x%08x\n", chip->last_cmd); + spin_lock_irq(&chip->reg_lock); + chip->rirb.cmds = 0; /* reset the index */ + bus->rirb_error = 1; + spin_unlock_irq(&chip->reg_lock); return -1; } -- GitLab From 586be3fcf97eec22fbc0ef6d67e823706aea7167 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Mar 2009 07:43:24 +0100 Subject: [PATCH 0473/6080] ALSA: hda - Add debug prints for Realtek auto-init Added a couple of debug prints to show the checked id numbers in alc_subsystem_id(). Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 82097790f6f3..ee92c73df083 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1022,6 +1022,9 @@ static void alc_subsystem_id(struct hda_codec *codec, if (codec->vendor_id == 0x10ec0260) nid = 0x17; ass = snd_hda_codec_get_pincfg(codec, nid); + snd_printd("realtek: No valid SSID, " + "checking pincfg 0x%08x for NID 0x%x\n", + nid, ass); if (!(ass & 1) && !(ass & 0x100000)) return; if ((ass >> 30) != 1) /* no physical connection */ @@ -1036,6 +1039,8 @@ static void alc_subsystem_id(struct hda_codec *codec, if (((ass >> 16) & 0xf) != tmp) return; do_sku: + snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", + ass & 0xffff, codec->vendor_id); /* * 0 : override * 1 : Swap Jack -- GitLab From a3b48c88f2d5a34c0e25aec0a3dab8069e5a9a72 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Apr 2009 13:37:29 +0200 Subject: [PATCH 0474/6080] ALSA: hda - minor optimization in hda_set_power_state() Check the target power-state before checking EAPD exception to reduce unneeded verb executions. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index b649033a4c81..b91f6ed5cc58 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2348,7 +2348,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, if (wcaps & AC_WCAP_POWER) { unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; - if (wid_type == AC_WID_PIN) { + if (power_state == AC_PWRST_D3 && + wid_type == AC_WID_PIN) { unsigned int pincap; /* * don't power down the widget if it controls @@ -2360,7 +2361,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, nid, 0, AC_VERB_GET_EAPD_BTLENABLE, 0); eapd &= 0x02; - if (power_state == AC_PWRST_D3 && eapd) + if (eapd) continue; } } -- GitLab From 0a1ec07a67bd8b0033dace237249654d015efa21 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 20 Apr 2009 01:25:46 +0000 Subject: [PATCH 0475/6080] net: skb_copy_datagram_const_iovec() There's an skb_copy_datagram_iovec() to copy out of a paged skb, but it modifies the iovec, and does not support starting at an offset in the destination. We want both in tun.c, so let's add the function. It's a carbon copy of skb_copy_datagram_iovec() with enough changes to be annoying. Signed-off-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- include/linux/skbuff.h | 5 +++ include/linux/socket.h | 2 + net/core/datagram.c | 92 ++++++++++++++++++++++++++++++++++++++++++ net/core/iovec.c | 26 ++++++++++++ 4 files changed, 125 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 5fd389162f01..af2b21bdda83 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1717,6 +1717,11 @@ extern int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, struct iovec *from, int len); +extern int skb_copy_datagram_const_iovec(const struct sk_buff *from, + int offset, + const struct iovec *to, + int to_offset, + int size); extern void skb_free_datagram(struct sock *sk, struct sk_buff *skb); extern int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); diff --git a/include/linux/socket.h b/include/linux/socket.h index 421afb4d29b0..171b08db9c4f 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -318,6 +318,8 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata, extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode); extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); +extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, + int offset, int len); extern int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, int __user *ulen); extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr); extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); diff --git a/net/core/datagram.c b/net/core/datagram.c index d0de644b378d..4dbb05cd572b 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -338,6 +338,98 @@ fault: return -EFAULT; } +/** + * skb_copy_datagram_const_iovec - Copy a datagram to an iovec. + * @skb: buffer to copy + * @offset: offset in the buffer to start copying from + * @to: io vector to copy to + * @to_offset: offset in the io vector to start copying to + * @len: amount of data to copy from buffer to iovec + * + * Returns 0 or -EFAULT. + * Note: the iovec is not modified during the copy. + */ +int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset, + const struct iovec *to, int to_offset, + int len) +{ + int start = skb_headlen(skb); + int i, copy = start - offset; + + /* Copy header. */ + if (copy > 0) { + if (copy > len) + copy = len; + if (memcpy_toiovecend(to, skb->data + offset, to_offset, copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + to_offset += copy; + } + + /* Copy paged appendix. Hmm... why does this look so complicated? */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + int end; + + WARN_ON(start > offset + len); + + end = start + skb_shinfo(skb)->frags[i].size; + if ((copy = end - offset) > 0) { + int err; + u8 *vaddr; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + struct page *page = frag->page; + + if (copy > len) + copy = len; + vaddr = kmap(page); + err = memcpy_toiovecend(to, vaddr + frag->page_offset + + offset - start, to_offset, copy); + kunmap(page); + if (err) + goto fault; + if (!(len -= copy)) + return 0; + offset += copy; + to_offset += copy; + } + start = end; + } + + if (skb_shinfo(skb)->frag_list) { + struct sk_buff *list = skb_shinfo(skb)->frag_list; + + for (; list; list = list->next) { + int end; + + WARN_ON(start > offset + len); + + end = start + list->len; + if ((copy = end - offset) > 0) { + if (copy > len) + copy = len; + if (skb_copy_datagram_const_iovec(list, + offset - start, + to, to_offset, + copy)) + goto fault; + if ((len -= copy) == 0) + return 0; + offset += copy; + to_offset += copy; + } + start = end; + } + } + if (!len) + return 0; + +fault: + return -EFAULT; +} +EXPORT_SYMBOL(skb_copy_datagram_const_iovec); + /** * skb_copy_datagram_from_iovec - Copy a datagram from an iovec. * @skb: buffer to copy diff --git a/net/core/iovec.c b/net/core/iovec.c index 4c9c0121c9da..a215545c0a34 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c @@ -97,6 +97,31 @@ int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) return 0; } +/* + * Copy kernel to iovec. Returns -EFAULT on error. + */ + +int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, + int offset, int len) +{ + int copy; + for (; len > 0; ++iov) { + /* Skip over the finished iovecs */ + if (unlikely(offset >= iov->iov_len)) { + offset -= iov->iov_len; + continue; + } + copy = min_t(unsigned int, iov->iov_len - offset, len); + offset = 0; + if (copy_to_user(iov->iov_base, kdata, copy)) + return -EFAULT; + kdata += copy; + len -= copy; + } + + return 0; +} + /* * Copy iovec to kernel. Returns -EFAULT on error. * @@ -236,3 +261,4 @@ EXPORT_SYMBOL(csum_partial_copy_fromiovecend); EXPORT_SYMBOL(memcpy_fromiovec); EXPORT_SYMBOL(memcpy_fromiovecend); EXPORT_SYMBOL(memcpy_toiovec); +EXPORT_SYMBOL(memcpy_toiovecend); -- GitLab From 43b39dcdbdf823a1c0ac1f2aa2d76bd2f210adc8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 20 Apr 2009 01:25:59 +0000 Subject: [PATCH 0476/6080] tun: fix tun_chr_aio_read so that aio works aio_read gets const struct iovec * but tun_chr_aio_read casts this to struct iovec * and modifies the iovec. As a result, attempts to use io_submit to get packets from a tun device fail with weird errors such as EINVAL. Fix by using the new skb_copy_datagram_const_iovec. Signed-off-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/net/tun.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 735bf41c654a..3b513e29d392 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -683,7 +683,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, /* Put packet to the user space buffer */ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, struct sk_buff *skb, - struct iovec *iv, int len) + const struct iovec *iv, int len) { struct tun_pi pi = { 0, skb->protocol }; ssize_t total = 0; @@ -697,7 +697,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, pi.flags |= TUN_PKT_STRIP; } - if (memcpy_toiovec(iv, (void *) &pi, sizeof(pi))) + if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi))) return -EFAULT; total += sizeof(pi); } @@ -730,14 +730,15 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, gso.csum_offset = skb->csum_offset; } /* else everything is zero */ - if (unlikely(memcpy_toiovec(iv, (void *)&gso, sizeof(gso)))) + if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, + sizeof(gso)))) return -EFAULT; total += sizeof(gso); } len = min_t(int, skb->len, len); - skb_copy_datagram_iovec(skb, 0, iv, len); + skb_copy_datagram_const_iovec(skb, 0, iv, total, len); total += len; tun->dev->stats.tx_packets++; @@ -792,7 +793,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, } netif_wake_queue(tun->dev); - ret = tun_put_user(tun, skb, (struct iovec *) iv, len); + ret = tun_put_user(tun, skb, iv, len); kfree_skb(skb); break; } -- GitLab From 6f26c9a7555e5bcca3560919db9b852015077dae Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 20 Apr 2009 01:26:11 +0000 Subject: [PATCH 0477/6080] tun: fix tun_chr_aio_write so that aio works aio_write gets const struct iovec * but tun_chr_aio_write casts this to struct iovec * and modifies the iovec. As a result, attempts to use io_submit to send packets to a tun device fail with weird errors such as EINVAL. Since tun is the only user of skb_copy_datagram_from_iovec, we can fix this simply by changing the later so that it does not touch the iovec passed to it. Signed-off-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/net/tun.c | 13 ++++++++----- include/linux/skbuff.h | 3 ++- include/linux/socket.h | 4 ++-- net/core/datagram.c | 20 ++++++++++++++------ net/core/iovec.c | 7 ++++--- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 3b513e29d392..589f0ca668d6 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -540,31 +540,34 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun, /* Get packet from user space buffer */ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, - struct iovec *iv, size_t count, + const struct iovec *iv, size_t count, int noblock) { struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; struct sk_buff *skb; size_t len = count, align = 0; struct virtio_net_hdr gso = { 0 }; + int offset = 0; if (!(tun->flags & TUN_NO_PI)) { if ((len -= sizeof(pi)) > count) return -EINVAL; - if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) + if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi))) return -EFAULT; + offset += sizeof(pi); } if (tun->flags & TUN_VNET_HDR) { if ((len -= sizeof(gso)) > count) return -EINVAL; - if (memcpy_fromiovec((void *)&gso, iv, sizeof(gso))) + if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) return -EFAULT; if (gso.hdr_len > len) return -EINVAL; + offset += sizeof(pi); } if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { @@ -581,7 +584,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, return PTR_ERR(skb); } - if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) { + if (skb_copy_datagram_from_iovec(skb, 0, iv, offset, len)) { tun->dev->stats.rx_dropped++; kfree_skb(skb); return -EFAULT; @@ -673,7 +676,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count); - result = tun_get_user(tun, (struct iovec *)iv, iov_length(iv, count), + result = tun_get_user(tun, iv, iov_length(iv, count), file->f_flags & O_NONBLOCK); tun_put(tun); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index af2b21bdda83..1b5c3d298f43 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1715,7 +1715,8 @@ extern int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, struct iovec *iov); extern int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, - struct iovec *from, + const struct iovec *from, + int from_offset, int len); extern int skb_copy_datagram_const_iovec(const struct sk_buff *from, int offset, diff --git a/include/linux/socket.h b/include/linux/socket.h index 171b08db9c4f..42a0396f2c59 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -309,8 +309,8 @@ struct ucred { #ifdef __KERNEL__ extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); -extern int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, - int offset, int len); +extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, + int offset, int len); extern int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset, diff --git a/net/core/datagram.c b/net/core/datagram.c index 4dbb05cd572b..914d5fa773b4 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -435,13 +435,15 @@ EXPORT_SYMBOL(skb_copy_datagram_const_iovec); * @skb: buffer to copy * @offset: offset in the buffer to start copying to * @from: io vector to copy to + * @from_offset: offset in the io vector to start copying from * @len: amount of data to copy to buffer from iovec * * Returns 0 or -EFAULT. - * Note: the iovec is modified during the copy. + * Note: the iovec is not modified during the copy. */ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, - struct iovec *from, int len) + const struct iovec *from, int from_offset, + int len) { int start = skb_headlen(skb); int i, copy = start - offset; @@ -450,11 +452,12 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, if (copy > 0) { if (copy > len) copy = len; - if (memcpy_fromiovec(skb->data + offset, from, copy)) + if (memcpy_fromiovecend(skb->data + offset, from, 0, copy)) goto fault; if ((len -= copy) == 0) return 0; offset += copy; + from_offset += copy; } /* Copy paged appendix. Hmm... why does this look so complicated? */ @@ -473,8 +476,9 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, if (copy > len) copy = len; vaddr = kmap(page); - err = memcpy_fromiovec(vaddr + frag->page_offset + - offset - start, from, copy); + err = memcpy_fromiovecend(vaddr + frag->page_offset + + offset - start, + from, from_offset, copy); kunmap(page); if (err) goto fault; @@ -482,6 +486,7 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, if (!(len -= copy)) return 0; offset += copy; + from_offset += copy; } start = end; } @@ -500,11 +505,14 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset, copy = len; if (skb_copy_datagram_from_iovec(list, offset - start, - from, copy)) + from, + from_offset, + copy)) goto fault; if ((len -= copy) == 0) return 0; offset += copy; + from_offset += copy; } start = end; } diff --git a/net/core/iovec.c b/net/core/iovec.c index a215545c0a34..40a76ce19d9f 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c @@ -147,10 +147,11 @@ int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len) } /* - * For use with ip_build_xmit + * Copy iovec from kernel. Returns -EFAULT on error. */ -int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset, - int len) + +int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, + int offset, int len) { /* Skip over the finished iovecs */ while (offset >= iov->iov_len) { -- GitLab From dfed0ef9b3ff9e37903920b6938ed33344ad0b3d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Apr 2009 18:33:12 +0200 Subject: [PATCH 0478/6080] ALSA: hda - Fix a typo in debug print for realtek auto-detection The NID and ASS numbers were swapped... Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a6ec87a5c066..887712046c00 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1026,7 +1026,7 @@ static void alc_subsystem_id(struct hda_codec *codec, ass = snd_hda_codec_get_pincfg(codec, nid); snd_printd("realtek: No valid SSID, " "checking pincfg 0x%08x for NID 0x%x\n", - nid, ass); + ass, nid); if (!(ass & 1) && !(ass & 0x100000)) return; if ((ass >> 30) != 1) /* no physical connection */ -- GitLab From 19bdc9d061bcb71efd2b53083d96b59bbe1a1751 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 17 Apr 2009 05:26:31 +0000 Subject: [PATCH 0479/6080] clocksource: sh_cmt clocksource support Add clocksource support to the sh_cmt driver. With this in place we can do tickless with a single CMT channel. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 66 ++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 02bae3994abe..c24756489612 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -47,6 +47,7 @@ struct sh_cmt_priv { unsigned long rate; spinlock_t lock; struct clock_event_device ced; + struct clocksource cs; unsigned long total_cycles; }; @@ -376,6 +377,68 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) spin_unlock_irqrestore(&p->lock, flags); } +static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs) +{ + return container_of(cs, struct sh_cmt_priv, cs); +} + +static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) +{ + struct sh_cmt_priv *p = cs_to_sh_cmt(cs); + unsigned long flags, raw; + unsigned long value; + int has_wrapped; + + spin_lock_irqsave(&p->lock, flags); + value = p->total_cycles; + raw = sh_cmt_get_counter(p, &has_wrapped); + + if (unlikely(has_wrapped)) + raw = p->match_value; + spin_unlock_irqrestore(&p->lock, flags); + + return value + raw; +} + +static int sh_cmt_clocksource_enable(struct clocksource *cs) +{ + struct sh_cmt_priv *p = cs_to_sh_cmt(cs); + int ret; + + p->total_cycles = 0; + + ret = sh_cmt_start(p, FLAG_CLOCKSOURCE); + if (ret) + return ret; + + /* TODO: calculate good shift from rate and counter bit width */ + cs->shift = 0; + cs->mult = clocksource_hz2mult(p->rate, cs->shift); + return 0; +} + +static void sh_cmt_clocksource_disable(struct clocksource *cs) +{ + sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); +} + +static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, + char *name, unsigned long rating) +{ + struct clocksource *cs = &p->cs; + + cs->name = name; + cs->rating = rating; + cs->read = sh_cmt_clocksource_read; + cs->enable = sh_cmt_clocksource_enable; + cs->disable = sh_cmt_clocksource_disable; + cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); + cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; + pr_info("sh_cmt: %s used as clock source\n", cs->name); + clocksource_register(cs); + return 0; +} + static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced) { return container_of(ced, struct sh_cmt_priv, ced); @@ -483,6 +546,9 @@ int sh_cmt_register(struct sh_cmt_priv *p, char *name, if (clockevent_rating) sh_cmt_register_clockevent(p, name, clockevent_rating); + if (clocksource_rating) + sh_cmt_register_clocksource(p, name, clocksource_rating); + return 0; } -- GitLab From bf98a82633b97fb638fcee0fae3c0de54d1f7b05 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Tue, 21 Apr 2009 18:12:11 -0700 Subject: [PATCH 0480/6080] sa1100_ir: fix build breakage Fix simple typo. Caused by commit a1de966682551debbe690672e760487cc555c05f ("irda/sa1100_ir: convert to net_device_ops"). Reported-by: Stephen Rothwell Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/irda/sa1100_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 4ed763670a97..2aeb2e6aec1b 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -925,7 +925,7 @@ static int sa1100_irda_probe(struct platform_device *pdev) goto err_mem_5; dev->netdev_ops = &sa1100_irda_netdev_ops; - dev->ir = IRQ_Ser2ICP; + dev->irq = IRQ_Ser2ICP; irda_init_max_qos_capabilies(&si->qos); -- GitLab From 4cb9be7ab47820a1fa747569f5f035a5f628c91b Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 21 Apr 2009 18:42:05 +0000 Subject: [PATCH 0481/6080] e1000/e1000e/igb/ixgb: do not use netif_wake_queue un-necessarily It was pointed out that the Intel wired ethernet drivers do not need to wake the tx queue since netif_carrier_on/off will take care of the qdisc management in order to guarantee the correct handling of the transmit routine enable state. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/e1000/e1000_main.c | 4 ++-- drivers/net/e1000e/netdev.c | 8 ++++---- drivers/net/igb/igb_main.c | 4 ++-- drivers/net/ixgb/ixgb_main.c | 5 ++--- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 112e6b039983..71d4fe15976a 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -498,6 +498,8 @@ int e1000_up(struct e1000_adapter *adapter) e1000_irq_enable(adapter); + netif_wake_queue(adapter->netdev); + /* fire a link change interrupt to start the watchdog */ ew32(ICS, E1000_ICS_LSC); return 0; @@ -2591,7 +2593,6 @@ static void e1000_watchdog(unsigned long data) ew32(TCTL, tctl); netif_carrier_on(netdev); - netif_wake_queue(netdev); mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ)); adapter->smartspeed = 0; } else { @@ -2608,7 +2609,6 @@ static void e1000_watchdog(unsigned long data) printk(KERN_INFO "e1000: %s NIC Link is Down\n", netdev->name); netif_carrier_off(netdev); - netif_stop_queue(netdev); mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ)); /* 80003ES2LAN workaround-- diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 9048f8e6a8ce..da6b37e05bea 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -2826,6 +2826,8 @@ int e1000e_up(struct e1000_adapter *adapter) e1000_configure_msix(adapter); e1000_irq_enable(adapter); + netif_wake_queue(adapter->netdev); + /* fire a link change interrupt to start the watchdog */ ew32(ICS, E1000_ICS_LSC); return 0; @@ -2848,7 +2850,7 @@ void e1000e_down(struct e1000_adapter *adapter) ew32(RCTL, rctl & ~E1000_RCTL_EN); /* flush and sleep below */ - netif_tx_stop_all_queues(netdev); + netif_stop_queue(netdev); /* disable transmits in the hardware */ tctl = er32(TCTL); @@ -3130,7 +3132,7 @@ static int e1000_open(struct net_device *netdev) e1000_irq_enable(adapter); - netif_tx_start_all_queues(netdev); + netif_start_queue(netdev); /* fire a link status change interrupt to start the watchdog */ ew32(ICS, E1000_ICS_LSC); @@ -3600,7 +3602,6 @@ static void e1000_watchdog_task(struct work_struct *work) phy->ops.cfg_on_link_up(hw); netif_carrier_on(netdev); - netif_tx_wake_all_queues(netdev); if (!test_bit(__E1000_DOWN, &adapter->state)) mod_timer(&adapter->phy_info_timer, @@ -3614,7 +3615,6 @@ static void e1000_watchdog_task(struct work_struct *work) printk(KERN_INFO "e1000e: %s NIC Link is Down\n", adapter->netdev->name); netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); if (!test_bit(__E1000_DOWN, &adapter->state)) mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ)); diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index ceaa58554679..183235d46aee 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -942,6 +942,8 @@ int igb_up(struct igb_adapter *adapter) rd32(E1000_ICR); igb_irq_enable(adapter); + netif_tx_start_all_queues(adapter->netdev); + /* Fire a link change interrupt to start the watchdog. */ wr32(E1000_ICS, E1000_ICS_LSC); return 0; @@ -2664,7 +2666,6 @@ static void igb_watchdog_task(struct work_struct *work) } netif_carrier_on(netdev); - netif_tx_wake_all_queues(netdev); igb_ping_all_vfs(adapter); @@ -2681,7 +2682,6 @@ static void igb_watchdog_task(struct work_struct *work) printk(KERN_INFO "igb: %s NIC Link is Down\n", netdev->name); netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); igb_ping_all_vfs(adapter); diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index ff741ca110f5..cb9ecc48f6d0 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -266,6 +266,8 @@ ixgb_up(struct ixgb_adapter *adapter) napi_enable(&adapter->napi); ixgb_irq_enable(adapter); + netif_wake_queue(netdev); + mod_timer(&adapter->watchdog_timer, jiffies); return 0; @@ -1118,7 +1120,6 @@ ixgb_watchdog(unsigned long data) adapter->link_speed = 10000; adapter->link_duplex = FULL_DUPLEX; netif_carrier_on(netdev); - netif_wake_queue(netdev); } } else { if (netif_carrier_ok(netdev)) { @@ -1127,8 +1128,6 @@ ixgb_watchdog(unsigned long data) printk(KERN_INFO "ixgb: %s NIC Link is Down\n", netdev->name); netif_carrier_off(netdev); - netif_stop_queue(netdev); - } } -- GitLab From 362b76edb78923face033e18e4ffc85df8db0f28 Mon Sep 17 00:00:00 2001 From: Mateusz Mandera Date: Wed, 22 Apr 2009 02:24:28 -0700 Subject: [PATCH 0482/6080] 8390p: Get rid of init_module/cleanup_module This trivial patch just "gets rid of" init_module and cleanup_module from drivers/net/8390p.c Signed-off-by: Mateusz Mandera Signed-off-by: David S. Miller --- drivers/net/8390p.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c index 6ec11dafdb18..cacdd86a27d0 100644 --- a/drivers/net/8390p.c +++ b/drivers/net/8390p.c @@ -91,16 +91,15 @@ void NS8390p_init(struct net_device *dev, int startp) } EXPORT_SYMBOL(NS8390p_init); -#if defined(MODULE) - -int init_module(void) +static int __init 8390p_init_module(void) { return 0; } -void cleanup_module(void) +static void __exit 8390p_cleanup_module(void) { } -#endif /* MODULE */ +module_init(8390p_init_module); +module_exit(8390p_cleanup_module); MODULE_LICENSE("GPL"); -- GitLab From 1b4246a1fc487370665bf6c55aac8eae379642c0 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Wed, 22 Apr 2009 10:56:50 +0900 Subject: [PATCH 0483/6080] ASoC: OMAP: Add checking to detect bufferless pcms Add checking in hw_params and prepare to detect bufferless pcms(i.e. BT <--> codec). Signed-off-by: Joonyoung Shim Signed-off-by: Mark Brown --- sound/soc/omap/omap-pcm.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 07cf7f46b584..6454e15f7d28 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -87,8 +87,10 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; int err = 0; + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma_data) - return -ENODEV; + return 0; snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); @@ -134,6 +136,11 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) struct omap_pcm_dma_data *dma_data = prtd->dma_data; struct omap_dma_channel_params dma_params; + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ + if (!prtd->dma_data) + return 0; + memset(&dma_params, 0, sizeof(dma_params)); /* * Note: Regardless of interface data formats supported by OMAP McBSP -- GitLab From 246d0a17f5e09af0794960164269fc8988a8811c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 22 Apr 2009 18:24:55 +0100 Subject: [PATCH 0484/6080] ASoC: Add power supply widget to DAPM Many modern CODECs have shared resources on chip which must be enabled for portions of the chip to work but which can be disabled at other times in order to achieve power savings. Examples of such resources include power supplies and some internal clocks. Since these widgets are dependencies for the audio path but do not carry audio signals they require slightly different handling to most widgets - they do not contribute to the audio path and so should not be counted as either inputs or outputs during path walks. Cases where one supply provides a supply for another will require additional work. There is also room for more optimisation of the graph walking to avoid repeated checks for the same thing. Signed-off-by: Mark Brown --- Documentation/sound/alsa/soc/dapm.txt | 1 + include/sound/soc-dapm.h | 7 ++++- sound/soc/soc-dapm.c | 44 ++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Documentation/sound/alsa/soc/dapm.txt b/Documentation/sound/alsa/soc/dapm.txt index 9e6763264a2e..9ac842be9b4f 100644 --- a/Documentation/sound/alsa/soc/dapm.txt +++ b/Documentation/sound/alsa/soc/dapm.txt @@ -62,6 +62,7 @@ Audio DAPM widgets fall into a number of types:- o Mic - Mic (and optional Jack) o Line - Line Input/Output (and optional Jack) o Speaker - Speaker + o Supply - Power or clock supply widget used by other widgets. o Pre - Special PRE widget (exec before all others) o Post - Special POST widget (exec after all others) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 839a97b63269..533f9f256496 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -154,12 +154,16 @@ .shift = wshift, .invert = winvert, \ .event = wevent, .event_flags = wflags} -/* generic register modifier widget */ +/* generic widgets */ #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ { .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \ .reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \ .on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \ .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} +#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \ +{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \ + .shift = wshift, .invert = winvert, .event = wevent, \ + .event_flags = wflags} /* dapm kcontrol types */ #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \ @@ -308,6 +312,7 @@ enum snd_soc_dapm_type { snd_soc_dapm_vmid, /* codec bias/vmid - to minimise pops */ snd_soc_dapm_pre, /* machine specific pre widget - exec first */ snd_soc_dapm_post, /* machine specific post widget - exec last */ + snd_soc_dapm_supply, /* power/clock supply */ }; /* diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d3d17354e76c..7847f80e96d1 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -52,17 +52,19 @@ /* dapm power sequences - make this per codec in the future */ static int dapm_up_seq[] = { - snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, - snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac, - snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga, - snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post + snd_soc_dapm_pre, snd_soc_dapm_supply, snd_soc_dapm_micbias, + snd_soc_dapm_mic, snd_soc_dapm_mux, snd_soc_dapm_value_mux, + snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, + snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, + snd_soc_dapm_post }; static int dapm_down_seq[] = { snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias, - snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post + snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_supply, + snd_soc_dapm_post }; static int dapm_status = 1; @@ -165,6 +167,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, case snd_soc_dapm_dac: case snd_soc_dapm_micbias: case snd_soc_dapm_vmid: + case snd_soc_dapm_supply: p->connect = 1; break; /* does effect routing - dynamically connected */ @@ -435,6 +438,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) struct snd_soc_dapm_path *path; int con = 0; + if (widget->id == snd_soc_dapm_supply) + return 0; + if (widget->id == snd_soc_dapm_adc && widget->active) return 1; @@ -471,6 +477,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) struct snd_soc_dapm_path *path; int con = 0; + if (widget->id == snd_soc_dapm_supply) + return 0; + /* active stream ? */ if (widget->id == snd_soc_dapm_dac && widget->active) return 1; @@ -622,6 +631,26 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) } } +/* Check to see if a power supply is needed */ +static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) +{ + struct snd_soc_dapm_path *path; + int power = 0; + + /* Check if one of our outputs is connected */ + list_for_each_entry(path, &w->sinks, list_source) { + if (path->sink && path->sink->power_check && + path->sink->power_check(path->sink)) { + power = 1; + break; + } + } + + dapm_clear_walk(w->codec); + + return power; +} + /* * Scan a single DAPM widget for a complete audio path and update the * power status appropriately. @@ -752,6 +781,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action) case snd_soc_dapm_pga: case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: + case snd_soc_dapm_supply: if (w->name) { in = is_connected_input_ep(w); dapm_clear_walk(w->codec); @@ -880,6 +910,7 @@ static ssize_t dapm_widget_show(struct device *dev, case snd_soc_dapm_pga: case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: + case snd_soc_dapm_supply: if (w->name) count += sprintf(buf + count, "%s: %s\n", w->name, w->power ? "On":"Off"); @@ -1044,6 +1075,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, case snd_soc_dapm_vmid: case snd_soc_dapm_pre: case snd_soc_dapm_post: + case snd_soc_dapm_supply: list_add(&path->list, &codec->dapm_paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); @@ -1164,6 +1196,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) case snd_soc_dapm_line: w->power_check = dapm_generic_check_power; break; + case snd_soc_dapm_supply: + w->power_check = dapm_supply_check_power; case snd_soc_dapm_vmid: case snd_soc_dapm_pre: case snd_soc_dapm_post: -- GitLab From 42768a12822c3a0a6d7db69445281db975938294 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 22 Apr 2009 18:39:39 +0100 Subject: [PATCH 0485/6080] ASoC: Use DAPM supply widget for WM8903 charge pump Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 53 +++++++++++++++------------------------ 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index c5391841d41f..a3a489da008f 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -217,7 +217,6 @@ struct wm8903_priv { int sysclk; /* Reference counts */ - int charge_pump_users; int class_w_users; int playback_active; int capture_active; @@ -373,6 +372,15 @@ static void wm8903_reset(struct snd_soc_codec *codec) #define WM8903_OUTPUT_INT 0x2 #define WM8903_OUTPUT_IN 0x1 +static int wm8903_cp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + WARN_ON(event != SND_SOC_DAPM_POST_PMU); + mdelay(4); + + return 0; +} + /* * Event for headphone and line out amplifier power changes. Special * power up/down sequences are required in order to maximise pop/click @@ -382,12 +390,9 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - struct wm8903_priv *wm8903 = codec->private_data; - struct i2c_client *i2c = codec->control_data; u16 val; u16 reg; int shift; - u16 cp_reg = wm8903_read(codec, WM8903_CHARGE_PUMP_0); switch (w->reg) { case WM8903_POWER_MANAGEMENT_2: @@ -419,18 +424,6 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, /* Short the output */ val &= ~(WM8903_OUTPUT_SHORT << shift); wm8903_write(codec, reg, val); - - wm8903->charge_pump_users++; - - dev_dbg(&i2c->dev, "Charge pump use count now %d\n", - wm8903->charge_pump_users); - - if (wm8903->charge_pump_users == 1) { - dev_dbg(&i2c->dev, "Enabling charge pump\n"); - wm8903_write(codec, WM8903_CHARGE_PUMP_0, - cp_reg | WM8903_CP_ENA); - mdelay(4); - } } if (event & SND_SOC_DAPM_POST_PMU) { @@ -464,19 +457,6 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, wm8903_write(codec, reg, val); } - if (event & SND_SOC_DAPM_POST_PMD) { - wm8903->charge_pump_users--; - - dev_dbg(&i2c->dev, "Charge pump use count now %d\n", - wm8903->charge_pump_users); - - if (wm8903->charge_pump_users == 0) { - dev_dbg(&i2c->dev, "Disabling charge pump\n"); - wm8903_write(codec, WM8903_CHARGE_PUMP_0, - cp_reg & ~WM8903_CP_ENA); - } - } - return 0; } @@ -844,26 +824,28 @@ SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 1, 0, NULL, 0, wm8903_output_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 0, 0, NULL, 0, wm8903_output_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0, NULL, 0, wm8903_output_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0, NULL, 0, wm8903_output_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, NULL, 0), SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, + wm8903_cp_event, SND_SOC_DAPM_POST_PMU), }; static const struct snd_soc_dapm_route intercon[] = { @@ -951,6 +933,11 @@ static const struct snd_soc_dapm_route intercon[] = { { "ROP", NULL, "Right Speaker PGA" }, { "RON", NULL, "Right Speaker PGA" }, + + { "Left Headphone Output PGA", NULL, "Charge Pump" }, + { "Right Headphone Output PGA", NULL, "Charge Pump" }, + { "Left Line Output PGA", NULL, "Charge Pump" }, + { "Right Line Output PGA", NULL, "Charge Pump" }, }; static int wm8903_add_widgets(struct snd_soc_codec *codec) -- GitLab From c2aef4ffd24dab5c8e94c66e4042ad39d38bcf39 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 22 Apr 2009 20:04:44 +0100 Subject: [PATCH 0486/6080] ASoC: Support CLK_DSP in WM8903 CLK_DSP provides a master clock for the DAC and ADC related functionality on the device. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index a3a489da008f..27c8b94c0551 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -846,6 +846,7 @@ SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0, SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, wm8903_cp_event, SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), }; static const struct snd_soc_dapm_route intercon[] = { @@ -891,7 +892,12 @@ static const struct snd_soc_dapm_route intercon[] = { { "Right Input PGA", NULL, "Right Input Mode Mux" }, { "ADCL", NULL, "Left Input PGA" }, + { "ADCL", NULL, "CLK_DSP" }, { "ADCR", NULL, "Right Input PGA" }, + { "ADCR", NULL, "CLK_DSP" }, + + { "DACL", NULL, "CLK_DSP" }, + { "DACR", NULL, "CLK_DSP" }, { "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" }, { "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" }, -- GitLab From 4dbfe8097157fde1f8054f48f991ea45833852cd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 22 Apr 2009 20:32:40 +0100 Subject: [PATCH 0487/6080] ASoC: Optimise configuration of WM8903 DC servo Modify the default startup sequence in the chip to set the DC servo dither level for optimal performance. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 27c8b94c0551..de0a58507202 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -978,6 +978,11 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec, wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA); + /* Change DC servo dither level in startup sequence */ + wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); + wm8903_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); + wm8903_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); + wm8903_run_sequence(codec, 0); wm8903_sync_reg_cache(codec, codec->reg_cache); -- GitLab From d7d5c5476a12333a33b7a14ebb10eccc729c01cb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 22 Apr 2009 21:03:50 +0100 Subject: [PATCH 0488/6080] ASoC: Actively manage the DC servo for WM8903 Save a little extra power by enabling the DC servo offset correction for the output channels only when the relevant channels are enabled. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index de0a58507202..0bab5c6bd64a 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -392,14 +392,18 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, struct snd_soc_codec *codec = w->codec; u16 val; u16 reg; + u16 dcs_reg; + u16 dcs_bit; int shift; switch (w->reg) { case WM8903_POWER_MANAGEMENT_2: reg = WM8903_ANALOGUE_HP_0; + dcs_bit = 0 + w->shift; break; case WM8903_POWER_MANAGEMENT_3: reg = WM8903_ANALOGUE_LINEOUT_0; + dcs_bit = 2 + w->shift; break; default: BUG(); @@ -439,6 +443,11 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, val |= (WM8903_OUTPUT_OUT << shift); wm8903_write(codec, reg, val); + /* Enable the DC servo */ + dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0); + dcs_reg |= dcs_bit; + wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg); + /* Remove the short */ val |= (WM8903_OUTPUT_SHORT << shift); wm8903_write(codec, reg, val); @@ -451,6 +460,11 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, val &= ~(WM8903_OUTPUT_SHORT << shift); wm8903_write(codec, reg, val); + /* Disable the DC servo */ + dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0); + dcs_reg &= ~dcs_bit; + wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg); + /* Then disable the intermediate and output stages */ val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | WM8903_OUTPUT_IN) << shift); -- GitLab From 727fb909e541ebd09d5b552afef02a147978c151 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 22 Apr 2009 21:06:14 +0100 Subject: [PATCH 0489/6080] ASoC: Remove redundant rate constraint for WM8903 This is now handled by symmetric_rates. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 0bab5c6bd64a..bec418af97c9 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1289,14 +1289,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream, if (wm8903->master_substream) { master_runtime = wm8903->master_substream->runtime; - dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n", - master_runtime->sample_bits, - master_runtime->rate); - - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - master_runtime->rate, - master_runtime->rate); + dev_dbg(&i2c->dev, "Constraining to %d bits\n", + master_runtime->sample_bits); snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -- GitLab From 291ce18ceb84aca79368369885eec2d329ae16c5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 22 Apr 2009 21:36:14 +0100 Subject: [PATCH 0490/6080] ASoC: Implement WM8903 digital sidetone support Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index bec418af97c9..d8a9222fbf74 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -533,6 +533,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, /* ALSA can only do steps of .01dB */ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); +static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0); static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0); @@ -651,6 +652,16 @@ static const struct soc_enum rinput_inv_enum = SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text); +static const char *sidetone_text[] = { + "None", "Left", "Right" +}; + +static const struct soc_enum lsidetone_enum = + SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 2, 3, sidetone_text); + +static const struct soc_enum rsidetone_enum = + SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); + static const struct snd_kcontrol_new wm8903_snd_controls[] = { /* Input PGAs - No TLV since the scale depends on PGA mode */ @@ -694,6 +705,9 @@ SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, SOC_ENUM("ADC Companding Mode", adc_companding), SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0), +SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8, + 12, 0, digital_sidetone_tlv), + /* DAC */ SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), @@ -756,6 +770,12 @@ static const struct snd_kcontrol_new rinput_mux = static const struct snd_kcontrol_new rinput_inv_mux = SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum); +static const struct snd_kcontrol_new lsidetone_mux = + SOC_DAPM_ENUM("DACL Sidetone Mux", lsidetone_enum); + +static const struct snd_kcontrol_new rsidetone_mux = + SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); + static const struct snd_kcontrol_new left_output_mixer[] = { SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), @@ -822,6 +842,9 @@ SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0), SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0), +SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), +SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), + SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0), SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0), @@ -910,7 +933,14 @@ static const struct snd_soc_dapm_route intercon[] = { { "ADCR", NULL, "Right Input PGA" }, { "ADCR", NULL, "CLK_DSP" }, + { "DACL Sidetone", "Left", "ADCL" }, + { "DACL Sidetone", "Right", "ADCR" }, + { "DACR Sidetone", "Left", "ADCL" }, + { "DACR Sidetone", "Right", "ADCR" }, + + { "DACL", NULL, "DACL Sidetone" }, { "DACL", NULL, "CLK_DSP" }, + { "DACR", NULL, "DACR Sidetone" }, { "DACR", NULL, "CLK_DSP" }, { "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" }, -- GitLab From f74d0f5cacb7023422098dd5c98e3ce06787ba56 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 25 Mar 2009 08:30:15 +0300 Subject: [PATCH 0491/6080] p54spi: mask value read from SPI_ADRS_DMA_WRITE_CTRL in p54spi_wait_bit Mask value read from SPI_ADRS_DMA_WRITE_CTRL in p54spi_wait_bit. Without this, 'fw_upload not allowed to DMA write' is observed at both N800 and N810. Signed-off-by: Max Filippov Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index d1fe577de3d4..55402729d21b 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -171,7 +171,7 @@ static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits) for (i = 0; i < 2000; i++) { p54spi_spi_read(priv, reg, &buffer, sizeof(buffer)); - if (buffer == bits) + if ((buffer & bits) == bits) return 1; msleep(1); -- GitLab From 5e3af1d2d3e6c0011b4c22514d39c73dcbc6674f Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Wed, 25 Mar 2009 13:45:01 +0100 Subject: [PATCH 0492/6080] p54spi: fix p54spi_upload_firmware Instead of firmware itself p54_upload_firmware was sending to the device content of struct firmware and the following random garbage. Notice '&' before priv->firmware->data at p54spi_spi_write. But simple removing of '&' sign triggered BUG_ON at dma_cache_maint. Thus kmemdup - kfree workaround. Signed-off-by: Max Filippov Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi.c | 34 +++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 55402729d21b..bed894ae04b5 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -228,8 +228,15 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev) static int p54spi_upload_firmware(struct ieee80211_hw *dev) { struct p54s_priv *priv = dev->priv; - unsigned long fw_len, fw_addr; - long _fw_len; + unsigned long fw_len, _fw_len; + unsigned int offset = 0; + int err = 0; + u8 *fw; + + fw_len = priv->firmware->size; + fw = kmemdup(priv->firmware->data, fw_len, GFP_KERNEL); + if (!fw) + return -ENOMEM; /* stop the device */ p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16( @@ -244,9 +251,6 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev) msleep(TARGET_BOOT_SLEEP); - fw_addr = ISL38XX_DEV_FIRMWARE_ADDR; - fw_len = priv->firmware->size; - while (fw_len > 0) { _fw_len = min_t(long, fw_len, SPI_MAX_PACKET_SIZE); @@ -257,23 +261,20 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev) cpu_to_le32(HOST_ALLOWED)) == 0) { dev_err(&priv->spi->dev, "fw_upload not allowed " "to DMA write."); - return -EAGAIN; + err = -EAGAIN; + goto out; } p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN, cpu_to_le16(_fw_len)); - p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE, - cpu_to_le32(fw_addr)); + p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE, cpu_to_le32( + ISL38XX_DEV_FIRMWARE_ADDR + offset)); p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, - &priv->firmware->data, _fw_len); + (fw + offset), _fw_len); fw_len -= _fw_len; - fw_addr += _fw_len; - - /* FIXME: I think this doesn't work if firmware is large, - * this loop goes to second round. fw->data is not - * increased at all! */ + offset += _fw_len; } BUG_ON(fw_len != 0); @@ -292,7 +293,10 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev) p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16( SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT)); msleep(TARGET_BOOT_SLEEP); - return 0; + +out: + kfree(fw); + return err; } static void p54spi_power_off(struct p54s_priv *priv) -- GitLab From 684d6b360222f31b6b9be9a63aa5c6ed5674c890 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Wed, 25 Mar 2009 09:51:16 -0700 Subject: [PATCH 0493/6080] libertas: support mesh for various firmware versions CMD_MESH_CONFIG command ID and a couple of structure members in TxPD, RxPD have been changed in firmware version 10.x.y.z and newer. Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 26 +++++++++++++-- drivers/net/wireless/libertas/defs.h | 21 ++++++++++++ drivers/net/wireless/libertas/dev.h | 1 + drivers/net/wireless/libertas/host.h | 3 +- drivers/net/wireless/libertas/hostcmd.h | 28 +++++++++++++--- drivers/net/wireless/libertas/main.c | 44 +++++++++++++++---------- drivers/net/wireless/libertas/rx.c | 33 +++++-------------- drivers/net/wireless/libertas/tx.c | 8 +++-- drivers/net/wireless/libertas/types.h | 2 ++ 9 files changed, 116 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 8c3605cdc64c..c455b9abbfc0 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -119,6 +119,19 @@ int lbs_update_hw_spec(struct lbs_private *priv) lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n", cmd.hwifversion, cmd.version); + /* Determine mesh_fw_ver from fwrelease and fwcapinfo */ + /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */ + /* 5.110.22 have mesh command with 0xa3 command id */ + /* 10.0.0.p0 FW brings in mesh config command with different id */ + /* Check FW version MSB and initialize mesh_fw_ver */ + if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5) + priv->mesh_fw_ver = MESH_FW_OLD; + else if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) && + (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK)) + priv->mesh_fw_ver = MESH_FW_NEW; + else + priv->mesh_fw_ver = MESH_NONE; + /* Clamp region code to 8-bit since FW spec indicates that it should * only ever be 8-bit, even though the field size is 16-bit. Some firmware * returns non-zero high 8 bits here. @@ -1036,17 +1049,26 @@ static int __lbs_mesh_config_send(struct lbs_private *priv, uint16_t action, uint16_t type) { int ret; + u16 command = CMD_MESH_CONFIG_OLD; lbs_deb_enter(LBS_DEB_CMD); - cmd->hdr.command = cpu_to_le16(CMD_MESH_CONFIG); + /* + * Command id is 0xac for v10 FW along with mesh interface + * id in bits 14-13-12. + */ + if (priv->mesh_fw_ver == MESH_FW_NEW) + command = CMD_MESH_CONFIG | + (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET); + + cmd->hdr.command = cpu_to_le16(command); cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config)); cmd->hdr.result = 0; cmd->type = cpu_to_le16(type); cmd->action = cpu_to_le16(action); - ret = lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd); + ret = lbs_cmd_with_response(priv, command, cmd); lbs_deb_leave(LBS_DEB_CMD); return ret; diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index e8dfde39abfc..48da157d6cda 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h @@ -227,6 +227,20 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in #define TxPD_CONTROL_WDS_FRAME (1<<17) #define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME +/** Mesh interface ID */ +#define MESH_IFACE_ID 0x0001 +/** Mesh id should be in bits 14-13-12 */ +#define MESH_IFACE_BIT_OFFSET 0x000c +/** Mesh enable bit in FW capability */ +#define MESH_CAPINFO_ENABLE_MASK (1<<16) + +/** FW definition from Marvell v5 */ +#define MRVL_FW_V5 (0x05) +/** FW definition from Marvell v10 */ +#define MRVL_FW_V10 (0x0a) +/** FW major revision definition */ +#define MRVL_FW_MAJOR_REV(x) ((x)>>24) + /** RxPD status */ #define MRVDRV_RXPD_STATUS_OK 0x0001 @@ -380,6 +394,13 @@ enum KEY_INFO_WPA { KEY_INFO_WPA_ENABLED = 0x04 }; +/** mesh_fw_ver */ +enum _mesh_fw_ver { + MESH_NONE = 0, /* MESH is not supported */ + MESH_FW_OLD, /* MESH is supported in FW V5 */ + MESH_FW_NEW, /* MESH is supported in FW V10 and newer */ +}; + /* Default values for fwt commands. */ #define FWT_DEFAULT_METRIC 0 #define FWT_DEFAULT_DIR 1 diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 27e81fd97c94..cbaafa653b6a 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -101,6 +101,7 @@ struct lbs_mesh_stats { /** Private structure for the MV device */ struct lbs_private { int mesh_open; + int mesh_fw_ver; int infra_open; int mesh_autostart_enabled; diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index d4457ef808a6..8ff8ac9d817e 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h @@ -83,7 +83,8 @@ #define CMD_FWT_ACCESS 0x0095 #define CMD_802_11_MONITOR_MODE 0x0098 #define CMD_MESH_ACCESS 0x009b -#define CMD_MESH_CONFIG 0x00a3 +#define CMD_MESH_CONFIG_OLD 0x00a3 +#define CMD_MESH_CONFIG 0x00ac #define CMD_SET_BOOT2_VER 0x00a5 #define CMD_802_11_BEACON_CTRL 0x00b0 diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index a899aeb676bb..391c54ab2b09 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h @@ -13,8 +13,19 @@ /* TxPD descriptor */ struct txpd { - /* Current Tx packet status */ - __le32 tx_status; + /* union to cope up with later FW revisions */ + union { + /* Current Tx packet status */ + __le32 tx_status; + struct { + /* BSS type: client, AP, etc. */ + u8 bss_type; + /* BSS number */ + u8 bss_num; + /* Reserved */ + __le16 reserved; + } bss; + } u; /* Tx control */ __le32 tx_control; __le32 tx_packet_location; @@ -36,8 +47,17 @@ struct txpd { /* RxPD Descriptor */ struct rxpd { - /* Current Rx packet status */ - __le16 status; + /* union to cope up with later FW revisions */ + union { + /* Current Rx packet status */ + __le16 status; + struct { + /* BSS type: client, AP, etc. */ + u8 bss_type; + /* BSS number */ + u8 bss_num; + } bss; + } u; /* SNR */ u8 snr; diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 8ae935ac32f1..89575e448015 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1307,8 +1307,10 @@ int lbs_start_card(struct lbs_private *priv) lbs_update_channel(priv); - /* 5.0.16p0 is known to NOT support any mesh */ - if (priv->fwrelease > 0x05001000) { + /* Check mesh FW version and appropriately send the mesh start + * command + */ + if (priv->mesh_fw_ver == MESH_FW_OLD) { /* Enable mesh, if supported, and work out which TLV it uses. 0x100 + 291 is an unofficial value used in 5.110.20.pXX 0x100 + 37 is the official value used in 5.110.21.pXX @@ -1322,27 +1324,35 @@ int lbs_start_card(struct lbs_private *priv) It's just that 5.110.20.pXX will not have done anything useful */ - priv->mesh_tlv = 0x100 + 291; + priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID; if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, priv->curbssparams.channel)) { - priv->mesh_tlv = 0x100 + 37; + priv->mesh_tlv = TLV_TYPE_MESH_ID; if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, priv->curbssparams.channel)) priv->mesh_tlv = 0; } - if (priv->mesh_tlv) { - lbs_add_mesh(priv); - - if (device_create_file(&dev->dev, &dev_attr_lbs_mesh)) - lbs_pr_err("cannot register lbs_mesh attribute\n"); - - /* While rtap isn't related to mesh, only mesh-enabled - * firmware implements the rtap functionality via - * CMD_802_11_MONITOR_MODE. - */ - if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) - lbs_pr_err("cannot register lbs_rtap attribute\n"); - } + } else if (priv->mesh_fw_ver == MESH_FW_NEW) { + /* 10.0.0.pXX new firmwares should succeed with TLV + * 0x100+37; Do not invoke command with old TLV. + */ + priv->mesh_tlv = TLV_TYPE_MESH_ID; + if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START, + priv->curbssparams.channel)) + priv->mesh_tlv = 0; + } + if (priv->mesh_tlv) { + lbs_add_mesh(priv); + + if (device_create_file(&dev->dev, &dev_attr_lbs_mesh)) + lbs_pr_err("cannot register lbs_mesh attribute\n"); + + /* While rtap isn't related to mesh, only mesh-enabled + * firmware implements the rtap functionality via + * CMD_802_11_MONITOR_MODE. + */ + if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) + lbs_pr_err("cannot register lbs_rtap attribute\n"); } lbs_debugfs_init_one(priv, dev); diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 8e669775cb5d..820c22d9220f 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -160,8 +160,15 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) p_rx_pkt = (struct rxpackethdr *) skb->data; p_rx_pd = &p_rx_pkt->rx_pd; - if (priv->mesh_dev && (p_rx_pd->rx_control & RxPD_MESH_FRAME)) - dev = priv->mesh_dev; + if (priv->mesh_dev) { + if (priv->mesh_fw_ver == MESH_FW_OLD) { + if (p_rx_pd->rx_control & RxPD_MESH_FRAME) + dev = priv->mesh_dev; + } else if (priv->mesh_fw_ver == MESH_FW_NEW) { + if (p_rx_pd->u.bss.bss_num == MESH_IFACE_ID) + dev = priv->mesh_dev; + } + } lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min_t(unsigned int, skb->len, 100)); @@ -174,18 +181,6 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) goto done; } - /* - * Check rxpd status and update 802.3 stat, - */ - if (!(p_rx_pd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) { - lbs_deb_rx("rx err: frame received with bad status\n"); - lbs_pr_alert("rxpd not ok\n"); - dev->stats.rx_errors++; - ret = 0; - dev_kfree_skb(skb); - goto done; - } - lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n", skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); @@ -334,14 +329,6 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, goto done; } - /* - * Check rxpd status and update 802.3 stat, - */ - if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) { - //lbs_deb_rx("rx err: frame received with bad status\n"); - dev->stats.rx_errors++; - } - lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n", skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); @@ -353,8 +340,6 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, radiotap_hdr.hdr.it_pad = 0; radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr)); radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT); - if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) - radiotap_hdr.flags |= IEEE80211_RADIOTAP_F_BADFCS; radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate); /* XXX must check no carryout */ radiotap_hdr.antsignal = prxpd->snr + prxpd->nf; diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index f10aa39a6b68..160cfd8311c0 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -132,8 +132,12 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) txpd->tx_packet_length = cpu_to_le16(pkt_len); txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd)); - if (dev == priv->mesh_dev) - txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME); + if (dev == priv->mesh_dev) { + if (priv->mesh_fw_ver == MESH_FW_OLD) + txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME); + else if (priv->mesh_fw_ver == MESH_FW_NEW) + txpd->u.bss.bss_num = MESH_IFACE_ID; + } lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd)); diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h index fb7a2d1a2525..de03b9c9c204 100644 --- a/drivers/net/wireless/libertas/types.h +++ b/drivers/net/wireless/libertas/types.h @@ -94,6 +94,8 @@ struct ieeetypes_assocrsp { #define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) #define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) #define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23) +#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37) +#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291) /** TLV related data structures*/ struct mrvlietypesheader { -- GitLab From 4f5cab969bdbec1ab0c5b690282372b4978123ac Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Thu, 26 Mar 2009 06:38:25 +0300 Subject: [PATCH 0494/6080] p54spi: fix p54spi_tx_frame DMA transfer initiation and skb cleanup p54spi_tx_frame wasn't waiting for HOST_ALLOWED in SPI_ADRS_DMA_WRITE_CTRL. This resulted in frequent 'WR_READY timeout' on beacon resubmission. Also don't free skb on error path, as it gets freed on p54spi_wq_tx. Signed-off-by: Max Filippov Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi.c | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index bed894ae04b5..f8af09610180 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -179,6 +179,25 @@ static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits) return 0; } +static int p54spi_spi_write_dma(struct p54s_priv *priv, __le32 base, + const void *buf, size_t len) +{ + p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL, + cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE)); + + if (p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL, + cpu_to_le32(HOST_ALLOWED)) == 0) { + dev_err(&priv->spi->dev, "spi_write_dma not allowed " + "to DMA write."); + return -EAGAIN; + } + + p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN, cpu_to_le16(len)); + p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE, base); + p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, buf, len); + return 0; +} + static int p54spi_request_firmware(struct ieee80211_hw *dev) { struct p54s_priv *priv = dev->priv; @@ -254,24 +273,11 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev) while (fw_len > 0) { _fw_len = min_t(long, fw_len, SPI_MAX_PACKET_SIZE); - p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL, - cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE)); - - if (p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL, - cpu_to_le32(HOST_ALLOWED)) == 0) { - dev_err(&priv->spi->dev, "fw_upload not allowed " - "to DMA write."); - err = -EAGAIN; + err = p54spi_spi_write_dma(priv, cpu_to_le32( + ISL38XX_DEV_FIRMWARE_ADDR + offset), + (fw + offset), _fw_len); + if (err < 0) goto out; - } - - p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN, - cpu_to_le16(_fw_len)); - p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE, cpu_to_le32( - ISL38XX_DEV_FIRMWARE_ADDR + offset)); - - p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, - (fw + offset), _fw_len); fw_len -= _fw_len; offset += _fw_len; @@ -418,27 +424,21 @@ static irqreturn_t p54spi_interrupt(int irq, void *config) static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb) { struct p54_hdr *hdr = (struct p54_hdr *) skb->data; - struct p54s_dma_regs dma_regs; unsigned long timeout; int ret = 0; u32 ints; p54spi_wakeup(priv); - dma_regs.cmd = cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE); - dma_regs.len = cpu_to_le16(skb->len); - dma_regs.addr = hdr->req_id; - - p54spi_spi_write(priv, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs, - sizeof(dma_regs)); - - p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, skb->data, skb->len); + ret = p54spi_spi_write_dma(priv, hdr->req_id, skb->data, skb->len); + if (ret < 0) + goto out; timeout = jiffies + 2 * HZ; ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); while (!(ints & SPI_HOST_INT_WR_READY)) { if (time_after(jiffies, timeout)) { - dev_err(&priv->spi->dev, "WR_READY timeout"); + dev_err(&priv->spi->dev, "WR_READY timeout\n"); ret = -1; goto out; } @@ -448,9 +448,9 @@ static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb) p54spi_int_ack(priv, SPI_HOST_INT_WR_READY); p54spi_sleep(priv); -out: if (FREE_AFTER_TX(skb)) p54_free_skb(priv->hw, skb); +out: return ret; } -- GitLab From 6da3a13e4fcab0ff58592087d28bd283caf23d88 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 26 Mar 2009 10:14:08 -0700 Subject: [PATCH 0495/6080] iwlwifi: merge and better support of suspend/resume for iwlagn and iwl3945 With mac80211's help to call stop() and start() in mac80211 suspend/resume function, both iwlagn and iwl3945 no longer calling stop() and start(); remove un-necessary STATUS_IN_SUSPEND bit from both header files and functions, Move apm_ops.stop() function into pci_suspend() to ensure DMA is stopped before go into suspend mode. iwl3945 has the similar suspend/resume function as iwlagn, so move both functions to iwlcore to be shared by both drivers. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.h | 1 - drivers/net/wireless/iwlwifi/iwl-agn.c | 54 ++---------------- drivers/net/wireless/iwlwifi/iwl-core.c | 40 +++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 5 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 62 +++------------------ 6 files changed, 56 insertions(+), 108 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index ab7aaf6872c7..29bc0d2656bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -162,7 +162,6 @@ struct iwl3945_frame { #define STATUS_TEMPERATURE 8 #define STATUS_GEO_CONFIGURED 9 #define STATUS_EXIT_PENDING 10 -#define STATUS_IN_SUSPEND 11 #define STATUS_STATISTICS 12 #define STATUS_SCANNING 13 #define STATUS_SCAN_ABORTING 14 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3889158b359c..2cb073efb95d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1654,7 +1654,7 @@ static void __iwl_down(struct iwl_priv *priv) ieee80211_stop_queues(priv->hw); /* If we have not previously called iwl_init() then - * clear all bits but the RF Kill and SUSPEND bits and return */ + * clear all bits but the RF Kill bits and return */ if (!iwl_is_init(priv)) { priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | @@ -1662,23 +1662,19 @@ static void __iwl_down(struct iwl_priv *priv) STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | - test_bit(STATUS_IN_SUSPEND, &priv->status) << - STATUS_IN_SUSPEND | test_bit(STATUS_EXIT_PENDING, &priv->status) << STATUS_EXIT_PENDING; goto exit; } - /* ...otherwise clear out all the status bits but the RF Kill and - * SUSPEND bits and continue taking the NIC down. */ + /* ...otherwise clear out all the status bits but the RF Kill + * bits and continue taking the NIC down. */ priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | - test_bit(STATUS_IN_SUSPEND, &priv->status) << - STATUS_IN_SUSPEND | test_bit(STATUS_FW_ERROR, &priv->status) << STATUS_FW_ERROR | test_bit(STATUS_EXIT_PENDING, &priv->status) << @@ -1703,7 +1699,7 @@ static void __iwl_down(struct iwl_priv *priv) udelay(5); /* FIXME: apm_ops.suspend(priv) */ - if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) + if (exit_pending) priv->cfg->ops->lib->apm_ops.stop(priv); else priv->cfg->ops->lib->apm_ops.reset(priv); @@ -2064,9 +2060,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw) IWL_DEBUG_INFO(priv, "Start UP work done.\n"); - if (test_bit(STATUS_IN_SUSPEND, &priv->status)) - return 0; - /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from * mac80211 will not be run successfully. */ ret = wait_event_interruptible_timeout(priv->wait_command_queue, @@ -3566,45 +3559,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) ieee80211_free_hw(priv->hw); } -#ifdef CONFIG_PM - -static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct iwl_priv *priv = pci_get_drvdata(pdev); - - if (priv->is_open) { - set_bit(STATUS_IN_SUSPEND, &priv->status); - iwl_mac_stop(priv->hw); - priv->is_open = 1; - } - - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - - return 0; -} - -static int iwl_pci_resume(struct pci_dev *pdev) -{ - struct iwl_priv *priv = pci_get_drvdata(pdev); - int ret; - - pci_set_power_state(pdev, PCI_D0); - ret = pci_enable_device(pdev); - if (ret) - return ret; - pci_restore_state(pdev); - iwl_enable_interrupts(priv); - - if (priv->is_open) - iwl_mac_start(priv->hw); - - clear_bit(STATUS_IN_SUSPEND, &priv->status); - return 0; -} - -#endif /* CONFIG_PM */ /***************************************************************************** * diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c54fb93e9d72..2e44d6e19e2b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2112,3 +2112,43 @@ void iwl_rx_reply_error(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_rx_reply_error); +#ifdef CONFIG_PM + +int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct iwl_priv *priv = pci_get_drvdata(pdev); + + /* + * This function is called when system goes into suspend state + * mac80211 will call iwl_mac_stop() from the mac80211 suspend function + * first but since iwl_mac_stop() has no knowledge of who the caller is, + * it will not call apm_ops.stop() to stop the DMA operation. + * Calling apm_ops.stop here to make sure we stop the DMA. + */ + priv->cfg->ops->lib->apm_ops.stop(priv); + + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + return 0; +} +EXPORT_SYMBOL(iwl_pci_suspend); + +int iwl_pci_resume(struct pci_dev *pdev) +{ + struct iwl_priv *priv = pci_get_drvdata(pdev); + int ret; + + pci_set_power_state(pdev, PCI_D0); + ret = pci_enable_device(pdev); + if (ret) + return ret; + pci_restore_state(pdev); + iwl_enable_interrupts(priv); + + return 0; +} +EXPORT_SYMBOL(iwl_pci_resume); + +#endif /* CONFIG_PM */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index a8eac8c3c1fa..5d4904584686 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -432,6 +432,10 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv) pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); return pci_lnk_ctl; } +#ifdef CONFIG_PM +int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state); +int iwl_pci_resume(struct pci_dev *pdev); +#endif /* CONFIG_PM */ /***************************************************** * Error Handling Debugging @@ -458,7 +462,6 @@ void iwlcore_free_geos(struct iwl_priv *priv); #define STATUS_TEMPERATURE 8 #define STATUS_GEO_CONFIGURED 9 #define STATUS_EXIT_PENDING 10 -#define STATUS_IN_SUSPEND 11 #define STATUS_STATISTICS 12 #define STATUS_SCANNING 13 #define STATUS_SCAN_ABORTING 14 diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 64eb585f1578..af1d1214b184 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -456,8 +456,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, test_bit(STATUS_GEO_CONFIGURED, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", test_bit(STATUS_EXIT_PENDING, &priv->status)); - pos += scnprintf(buf + pos, bufsz - pos, "STATUS_IN_SUSPEND:\t %d\n", - test_bit(STATUS_IN_SUSPEND, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", test_bit(STATUS_STATISTICS, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index da61ecd62882..afb838b39a6c 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2996,7 +2996,7 @@ static void __iwl3945_down(struct iwl_priv *priv) ieee80211_stop_queues(priv->hw); /* If we have not previously called iwl3945_init() then - * clear all bits but the RF Kill and SUSPEND bits and return */ + * clear all bits but the RF Kill bits and return */ if (!iwl_is_init(priv)) { priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | @@ -3004,23 +3004,19 @@ static void __iwl3945_down(struct iwl_priv *priv) STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | - test_bit(STATUS_IN_SUSPEND, &priv->status) << - STATUS_IN_SUSPEND | test_bit(STATUS_EXIT_PENDING, &priv->status) << STATUS_EXIT_PENDING; goto exit; } - /* ...otherwise clear out all the status bits but the RF Kill and - * SUSPEND bits and continue taking the NIC down. */ + /* ...otherwise clear out all the status bits but the RF Kill + * bits and continue taking the NIC down. */ priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << STATUS_RF_KILL_SW | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | - test_bit(STATUS_IN_SUSPEND, &priv->status) << - STATUS_IN_SUSPEND | test_bit(STATUS_FW_ERROR, &priv->status) << STATUS_FW_ERROR | test_bit(STATUS_EXIT_PENDING, &priv->status) << @@ -3044,7 +3040,7 @@ static void __iwl3945_down(struct iwl_priv *priv) udelay(5); - if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) + if (exit_pending) priv->cfg->ops->lib->apm_ops.stop(priv); else priv->cfg->ops->lib->apm_ops.reset(priv); @@ -3097,10 +3093,8 @@ static int __iwl3945_up(struct iwl_priv *priv) clear_bit(STATUS_RF_KILL_HW, &priv->status); else { set_bit(STATUS_RF_KILL_HW, &priv->status); - if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) { - IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); - return -ENODEV; - } + IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); + return -ENODEV; } iwl_write32(priv, CSR_INT, 0xFFFFFFFF); @@ -3592,9 +3586,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) IWL_DEBUG_INFO(priv, "Start UP work.\n"); - if (test_bit(STATUS_IN_SUSPEND, &priv->status)) - return 0; - /* Wait for START_ALIVE from ucode. Otherwise callbacks from * mac80211 will not be run successfully. */ ret = wait_event_interruptible_timeout(priv->wait_command_queue, @@ -5233,43 +5224,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) ieee80211_free_hw(priv->hw); } -#ifdef CONFIG_PM - -static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct iwl_priv *priv = pci_get_drvdata(pdev); - - if (priv->is_open) { - set_bit(STATUS_IN_SUSPEND, &priv->status); - iwl3945_mac_stop(priv->hw); - priv->is_open = 1; - } - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - - return 0; -} - -static int iwl3945_pci_resume(struct pci_dev *pdev) -{ - struct iwl_priv *priv = pci_get_drvdata(pdev); - int ret; - - pci_set_power_state(pdev, PCI_D0); - ret = pci_enable_device(pdev); - if (ret) - return ret; - pci_restore_state(pdev); - - if (priv->is_open) - iwl3945_mac_start(priv->hw); - - clear_bit(STATUS_IN_SUSPEND, &priv->status); - return 0; -} - -#endif /* CONFIG_PM */ /***************************************************************************** * @@ -5283,8 +5237,8 @@ static struct pci_driver iwl3945_driver = { .probe = iwl3945_pci_probe, .remove = __devexit_p(iwl3945_pci_remove), #ifdef CONFIG_PM - .suspend = iwl3945_pci_suspend, - .resume = iwl3945_pci_resume, + .suspend = iwl_pci_suspend, + .resume = iwl_pci_resume, #endif }; -- GitLab From 488829f1b141858944a24fd793220fa1d52cd9a6 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Thu, 26 Mar 2009 10:14:10 -0700 Subject: [PATCH 0496/6080] iwl3945: use iwl_mac_conf_tx 3945 now uses iwl_mac_conf_tx. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 43 ------------------ drivers/net/wireless/iwlwifi/iwl-core.c | 43 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 48 +-------------------- 4 files changed, 46 insertions(+), 90 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 2cb073efb95d..1f5ee55778f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2628,49 +2628,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } -static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - int q; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; - } - - if (queue >= AC_NUM) { - IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); - return 0; - } - - q = AC_NUM - 1 - queue; - - spin_lock_irqsave(&priv->lock, flags); - - priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); - priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); - priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; - priv->qos_data.def_qos_parm.ac[q].edca_txop = - cpu_to_le16((params->txop * 32)); - - priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; - priv->qos_data.qos_active = 1; - - if (priv->iw_mode == NL80211_IFTYPE_AP) - iwl_activate_qos(priv, 1); - else if (priv->assoc_id && iwl_is_associated(priv)) - iwl_activate_qos(priv, 0); - - spin_unlock_irqrestore(&priv->lock, flags); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - return 0; -} - static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2e44d6e19e2b..7609bfced10f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2112,6 +2112,49 @@ void iwl_rx_reply_error(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_rx_reply_error); +int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + int q; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return -EIO; + } + + if (queue >= AC_NUM) { + IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); + return 0; + } + + q = AC_NUM - 1 - queue; + + spin_lock_irqsave(&priv->lock, flags); + + priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); + priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); + priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; + priv->qos_data.def_qos_parm.ac[q].edca_txop = + cpu_to_le16((params->txop * 32)); + + priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; + priv->qos_data.qos_active = 1; + + if (priv->iw_mode == NL80211_IFTYPE_AP) + iwl_activate_qos(priv, 1); + else if (priv->assoc_id && iwl_is_associated(priv)) + iwl_activate_qos(priv, 0); + + spin_unlock_irqrestore(&priv->lock, flags); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + return 0; +} +EXPORT_SYMBOL(iwl_mac_conf_tx); #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 5d4904584686..d56edcd97aa0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -225,6 +225,8 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, void iwl_hw_detect(struct iwl_priv *priv); void iwl_reset_qos(struct iwl_priv *priv); void iwl_activate_qos(struct iwl_priv *priv, u8 force); +int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params); void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt); int iwl_check_rxon_cmd(struct iwl_priv *priv); int iwl_full_rxon_required(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index afb838b39a6c..ed31030c7643 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4100,52 +4100,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } -static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - int q; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; - } - - if (queue >= AC_NUM) { - IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue); - return 0; - } - - q = AC_NUM - 1 - queue; - - spin_lock_irqsave(&priv->lock, flags); - - priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); - priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); - priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; - priv->qos_data.def_qos_parm.ac[q].edca_txop = - cpu_to_le16((params->txop * 32)); - - priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; - priv->qos_data.qos_active = 1; - - spin_unlock_irqrestore(&priv->lock, flags); - - mutex_lock(&priv->mutex); - if (priv->iw_mode == NL80211_IFTYPE_AP) - iwl_activate_qos(priv, 1); - else if (priv->assoc_id && iwl_is_associated(priv)) - iwl_activate_qos(priv, 0); - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - return 0; -} - static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw, struct ieee80211_tx_queue_stats *stats) { @@ -4809,7 +4763,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .configure_filter = iwl_configure_filter, .set_key = iwl3945_mac_set_key, .get_tx_stats = iwl3945_mac_get_tx_stats, - .conf_tx = iwl3945_mac_conf_tx, + .conf_tx = iwl_mac_conf_tx, .reset_tsf = iwl3945_mac_reset_tsf, .bss_info_changed = iwl3945_bss_info_changed, .hw_scan = iwl_mac_hw_scan -- GitLab From 9f201a87831af9458df1eda65941c955f2da87ed Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 27 Mar 2009 07:50:53 +0300 Subject: [PATCH 0497/6080] p54spi: compensate firmware alignment bug in p54spi_rx Firmware may insert up to 4 padding bytes after the lmac header, but it does not amend the size of SPI data transfer. Such packets has correct data size in header, thus referencing past the end of allocated skb. Put extra 4 bytes to the end of the received skb to compensate for this case. Signed-off-by: Max Filippov Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index f8af09610180..52023127cf37 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -395,7 +395,12 @@ static int p54spi_rx(struct p54s_priv *priv) return 0; } - skb = dev_alloc_skb(len); + + /* Firmware may insert up to 4 padding bytes after the lmac header, + * but it does not amend the size of SPI data transfer. + * Such packets has correct data size in header, thus referencing + * past the end of allocated skb. Reserve extra 4 bytes for this case */ + skb = dev_alloc_skb(len + 4); if (!skb) { dev_err(&priv->spi->dev, "could not alloc skb"); return 0; @@ -403,6 +408,9 @@ static int p54spi_rx(struct p54s_priv *priv) p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, skb_put(skb, len), len); p54spi_sleep(priv); + /* Put additional bytes to compensate for the possible + * alignment-caused truncation */ + skb_put(skb, 4); if (p54_rx(priv->hw, skb) == 0) dev_kfree_skb(skb); -- GitLab From b0741a1a2b00d9b4d88ba60016c88e42f176e4d6 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Fri, 27 Mar 2009 13:08:45 +0530 Subject: [PATCH 0498/6080] mac80211: Don't access managed mode bits in non-managed mode This fixes a stupid bug introduced in 25f85c31d4f.. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- net/mac80211/wext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 959aa8379ccf..a52fb3a4a455 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -675,7 +675,7 @@ static int ieee80211_ioctl_siwencode(struct net_device *dev, !sdata->default_key, keybuf, erq->length); - if (!ret) { + if (!ret && sdata->vif.type == NL80211_IFTYPE_STATION) { if (remove) sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED; else -- GitLab From f4a11bb0c2d5968ea35f95bdbabdd453862f202a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Mar 2009 12:40:28 +0100 Subject: [PATCH 0499/6080] nl80211: validate some input better This patch changes nl80211 to: * validate that any IE input is a valid IE (stream) * move some validation code before locking * require that a reason code is given for both deauth/disassoc Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 114 ++++++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 37 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2456e4ee445e..2f449ddcbc72 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -118,6 +118,36 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, }; +/* IE validation */ +static bool is_valid_ie_attr(const struct nlattr *attr) +{ + const u8 *pos; + int len; + + if (!attr) + return true; + + pos = nla_data(attr); + len = nla_len(attr); + + while (len) { + u8 elemlen; + + if (len < 2) + return false; + len -= 2; + + elemlen = pos[1]; + if (elemlen > len) + return false; + + len -= elemlen; + pos += 2 + elemlen; + } + + return true; +} + /* message building helper */ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq, int flags, u8 cmd) @@ -1069,6 +1099,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) struct beacon_parameters params; int haveinfo = 0; + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) + return -EINVAL; + rtnl_lock(); err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); @@ -2442,6 +2475,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) enum ieee80211_band band; size_t ie_len; + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) + return -EINVAL; + rtnl_lock(); err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); @@ -2710,6 +2746,12 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) struct wiphy *wiphy; int err; + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) + return -EINVAL; + + if (!info->attrs[NL80211_ATTR_MAC]) + return -EINVAL; + rtnl_lock(); err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); @@ -2731,11 +2773,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (!info->attrs[NL80211_ATTR_MAC]) { - err = -EINVAL; - goto out; - } - wiphy = &drv->wiphy; memset(&req, 0, sizeof(req)); @@ -2788,6 +2825,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) struct wiphy *wiphy; int err; + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) + return -EINVAL; + + if (!info->attrs[NL80211_ATTR_MAC] || + !info->attrs[NL80211_ATTR_SSID]) + return -EINVAL; + rtnl_lock(); err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); @@ -2809,12 +2853,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (!info->attrs[NL80211_ATTR_MAC] || - !info->attrs[NL80211_ATTR_SSID]) { - err = -EINVAL; - goto out; - } - wiphy = &drv->wiphy; memset(&req, 0, sizeof(req)); @@ -2856,6 +2894,15 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) struct wiphy *wiphy; int err; + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) + return -EINVAL; + + if (!info->attrs[NL80211_ATTR_MAC]) + return -EINVAL; + + if (!info->attrs[NL80211_ATTR_REASON_CODE]) + return -EINVAL; + rtnl_lock(); err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); @@ -2877,24 +2924,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (!info->attrs[NL80211_ATTR_MAC]) { - err = -EINVAL; - goto out; - } - wiphy = &drv->wiphy; memset(&req, 0, sizeof(req)); req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - if (info->attrs[NL80211_ATTR_REASON_CODE]) { - req.reason_code = - nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); - if (req.reason_code == 0) { - /* Reason Code 0 is reserved */ - err = -EINVAL; - goto out; - } + req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); + if (req.reason_code == 0) { + /* Reason Code 0 is reserved */ + err = -EINVAL; + goto out; } if (info->attrs[NL80211_ATTR_IE]) { @@ -2920,6 +2959,15 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) struct wiphy *wiphy; int err; + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) + return -EINVAL; + + if (!info->attrs[NL80211_ATTR_MAC]) + return -EINVAL; + + if (!info->attrs[NL80211_ATTR_REASON_CODE]) + return -EINVAL; + rtnl_lock(); err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); @@ -2941,24 +2989,16 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) goto out; } - if (!info->attrs[NL80211_ATTR_MAC]) { - err = -EINVAL; - goto out; - } - wiphy = &drv->wiphy; memset(&req, 0, sizeof(req)); req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - if (info->attrs[NL80211_ATTR_REASON_CODE]) { - req.reason_code = - nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); - if (req.reason_code == 0) { - /* Reason Code 0 is reserved */ - err = -EINVAL; - goto out; - } + req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); + if (req.reason_code == 0) { + /* Reason Code 0 is reserved */ + err = -EINVAL; + goto out; } if (info->attrs[NL80211_ATTR_IE]) { -- GitLab From c1c6b14b22af0f85d05a70405dc3fba5de840c7b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 30 Mar 2009 11:32:46 +0200 Subject: [PATCH 0500/6080] rfkill: remove deprecated state constants I only did superficial review, but these constants are stupid to have and without proper warnings nobody will review the code anyway, no amount of shouting will help. Also fix wimax to use correct states. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- arch/arm/mach-pxa/tosa-bt.c | 4 ++-- drivers/net/usb/hso.c | 4 ++-- include/linux/rfkill.h | 8 -------- net/wimax/op-rfkill.c | 8 ++++---- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c index fb0294bd4310..bde42aa29374 100644 --- a/arch/arm/mach-pxa/tosa-bt.c +++ b/arch/arm/mach-pxa/tosa-bt.c @@ -38,9 +38,9 @@ static void tosa_bt_off(struct tosa_bt_data *data) static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) { pr_info("BT_RADIO going: %s\n", - state == RFKILL_STATE_ON ? "on" : "off"); + state == RFKILL_STATE_UNBLOCKED ? "on" : "off"); - if (state == RFKILL_STATE_ON) { + if (state == RFKILL_STATE_UNBLOCKED) { pr_info("TOSA_BT: going ON\n"); tosa_bt_on(data); } else { diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index f84b78d94c40..d696e5fbc176 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2484,7 +2484,7 @@ static int add_net_device(struct hso_device *hso_dev) static int hso_radio_toggle(void *data, enum rfkill_state state) { struct hso_device *hso_dev = data; - int enabled = (state == RFKILL_STATE_ON); + int enabled = (state == RFKILL_STATE_UNBLOCKED); int rv; mutex_lock(&hso_dev->mutex); @@ -2522,7 +2522,7 @@ static void hso_create_rfkill(struct hso_device *hso_dev, snprintf(rfkn, 20, "hso-%d", interface->altsetting->desc.bInterfaceNumber); hso_net->rfkill->name = rfkn; - hso_net->rfkill->state = RFKILL_STATE_ON; + hso_net->rfkill->state = RFKILL_STATE_UNBLOCKED; hso_net->rfkill->data = hso_dev; hso_net->rfkill->toggle_radio = hso_radio_toggle; if (rfkill_register(hso_net->rfkill) < 0) { diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 164332cbb77c..e1ec7d9aa49c 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -52,14 +52,6 @@ enum rfkill_state { RFKILL_STATE_MAX, /* marker for last valid state */ }; -/* - * These are DEPRECATED, drivers using them should be verified to - * comply with the rfkill usage guidelines in Documentation/rfkill.txt - * and then converted to use the new names for rfkill_state - */ -#define RFKILL_STATE_OFF RFKILL_STATE_SOFT_BLOCKED -#define RFKILL_STATE_ON RFKILL_STATE_UNBLOCKED - /** * struct rfkill - rfkill control structure. * @name: Name of the switch. diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c index 2b75aee04217..870032faece2 100644 --- a/net/wimax/op-rfkill.c +++ b/net/wimax/op-rfkill.c @@ -113,7 +113,7 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev, if (state != wimax_dev->rf_hw) { wimax_dev->rf_hw = state; rfkill_state = state == WIMAX_RF_ON ? - RFKILL_STATE_OFF : RFKILL_STATE_ON; + RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; if (wimax_dev->rf_hw == WIMAX_RF_ON && wimax_dev->rf_sw == WIMAX_RF_ON) wimax_state = WIMAX_ST_READY; @@ -259,10 +259,10 @@ int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state) d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state); switch (state) { - case RFKILL_STATE_ON: + case RFKILL_STATE_SOFT_BLOCKED: rf_state = WIMAX_RF_OFF; break; - case RFKILL_STATE_OFF: + case RFKILL_STATE_UNBLOCKED: rf_state = WIMAX_RF_ON; break; default: @@ -361,7 +361,7 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev) wimax_dev->rfkill = rfkill; rfkill->name = wimax_dev->name; - rfkill->state = RFKILL_STATE_OFF; + rfkill->state = RFKILL_STATE_UNBLOCKED; rfkill->data = wimax_dev; rfkill->toggle_radio = wimax_rfkill_toggle_radio; rfkill->user_claim_unsupported = 1; -- GitLab From 621cac85297de5ba655e3430b007dd2e0da91da6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Mar 2009 14:14:31 +0100 Subject: [PATCH 0501/6080] rfkill: remove user_claim stuff Almost all drivers do not support user_claim, so remove it completely and always report -EOPNOTSUPP to userspace. Since userspace cannot really drive rfkill _anyway_ (due to the odd restrictions imposed by the documentation) having this code is just pointless. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- Documentation/rfkill.txt | 16 +++----- drivers/net/wireless/ath9k/main.c | 1 - drivers/net/wireless/b43/rfkill.c | 1 - drivers/net/wireless/b43legacy/rfkill.c | 1 - drivers/net/wireless/iwlwifi/iwl-rfkill.c | 1 - drivers/platform/x86/acer-wmi.c | 1 - drivers/platform/x86/hp-wmi.c | 3 -- drivers/platform/x86/sony-laptop.c | 4 -- drivers/platform/x86/toshiba_acpi.c | 1 - include/linux/rfkill.h | 6 --- net/rfkill/rfkill.c | 45 ++--------------------- net/wimax/op-rfkill.c | 1 - 12 files changed, 9 insertions(+), 72 deletions(-) diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt index 4d3ee317a4a3..40c3a3f10816 100644 --- a/Documentation/rfkill.txt +++ b/Documentation/rfkill.txt @@ -521,16 +521,12 @@ status of the system. Input devices may issue events that are related to rfkill. These are the various KEY_* events and SW_* events supported by rfkill-input.c. -******IMPORTANT****** -When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF AN RFKILL -SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it -has set to true the user_claim attribute for that particular switch. This rule -is *absolute*; do NOT violate it. -******IMPORTANT****** - -Userspace must not assume it is the only source of control for rfkill switches. -Their state CAN and WILL change due to firmware actions, direct user actions, -and the rfkill-input EPO override for *_RFKILL_ALL. +Userspace may not change the state of an rfkill switch in response to an +input event, it should refrain from changing states entirely. + +Userspace cannot assume it is the only source of control for rfkill switches. +Their state can change due to firmware actions, direct user actions, and the +rfkill-input EPO override for *_RFKILL_ALL. When rfkill-input is not active, userspace must initiate a rfkill status change by writing to the "state" attribute in order for anything to happen. diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 13d4e6756c99..0607df20e497 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1267,7 +1267,6 @@ static int ath_init_sw_rfkill(struct ath_softc *sc) sc->rf_kill.rfkill->data = sc; sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio; sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED; - sc->rf_kill.rfkill->user_claim_unsupported = 1; return 0; } diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index afad42358693..9e1d00bc24d3 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -139,7 +139,6 @@ void b43_rfkill_init(struct b43_wldev *dev) rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; rfk->rfkill->data = dev; rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle; - rfk->rfkill->user_claim_unsupported = 1; rfk->poll_dev = input_allocate_polled_device(); if (!rfk->poll_dev) { diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index b32bf6a94f19..4b0c7d27a51f 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c @@ -142,7 +142,6 @@ void b43legacy_rfkill_init(struct b43legacy_wldev *dev) rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; rfk->rfkill->data = dev; rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; - rfk->rfkill->user_claim_unsupported = 1; rfk->poll_dev = input_allocate_polled_device(); if (!rfk->poll_dev) { diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index 2ad9faf1508a..65605ad44e4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c @@ -91,7 +91,6 @@ int iwl_rfkill_init(struct iwl_priv *priv) priv->rfkill->data = priv; priv->rfkill->state = RFKILL_STATE_UNBLOCKED; priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill; - priv->rfkill->user_claim_unsupported = 1; priv->rfkill->dev.class->suspend = NULL; priv->rfkill->dev.class->resume = NULL; diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 0f6e43bf4fc2..62d02b3c998e 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -1005,7 +1005,6 @@ enum rfkill_type type, char *name, u32 cap) *data = cap; rfkill_dev->data = data; rfkill_dev->toggle_radio = acer_rfkill_set; - rfkill_dev->user_claim_unsupported = 1; err = rfkill_register(rfkill_dev); if (err) { diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 50d9019de2be..fe171fad12cf 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -434,7 +434,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) wifi_rfkill->name = "hp-wifi"; wifi_rfkill->state = hp_wmi_wifi_state(); wifi_rfkill->toggle_radio = hp_wmi_wifi_set; - wifi_rfkill->user_claim_unsupported = 1; err = rfkill_register(wifi_rfkill); if (err) goto add_sysfs_error; @@ -446,7 +445,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) bluetooth_rfkill->name = "hp-bluetooth"; bluetooth_rfkill->state = hp_wmi_bluetooth_state(); bluetooth_rfkill->toggle_radio = hp_wmi_bluetooth_set; - bluetooth_rfkill->user_claim_unsupported = 1; err = rfkill_register(bluetooth_rfkill); if (err) goto register_bluetooth_error; @@ -457,7 +455,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) wwan_rfkill->name = "hp-wwan"; wwan_rfkill->state = hp_wmi_wwan_state(); wwan_rfkill->toggle_radio = hp_wmi_wwan_set; - wwan_rfkill->user_claim_unsupported = 1; err = rfkill_register(wwan_rfkill); if (err) goto register_wwan_err; diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index d3c92d777bde..184e99e72684 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -1097,7 +1097,6 @@ static int sony_nc_setup_wifi_rfkill(struct acpi_device *device) sony_wifi_rfkill->name = "sony-wifi"; sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set; sony_wifi_rfkill->get_state = sony_nc_rfkill_get; - sony_wifi_rfkill->user_claim_unsupported = 1; sony_wifi_rfkill->data = (void *)SONY_WIFI; err = rfkill_register(sony_wifi_rfkill); if (err) @@ -1119,7 +1118,6 @@ static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device) sony_bluetooth_rfkill->name = "sony-bluetooth"; sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set; sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get; - sony_bluetooth_rfkill->user_claim_unsupported = 1; sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH; err = rfkill_register(sony_bluetooth_rfkill); if (err) @@ -1140,7 +1138,6 @@ static int sony_nc_setup_wwan_rfkill(struct acpi_device *device) sony_wwan_rfkill->name = "sony-wwan"; sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set; sony_wwan_rfkill->get_state = sony_nc_rfkill_get; - sony_wwan_rfkill->user_claim_unsupported = 1; sony_wwan_rfkill->data = (void *)SONY_WWAN; err = rfkill_register(sony_wwan_rfkill); if (err) @@ -1161,7 +1158,6 @@ static int sony_nc_setup_wimax_rfkill(struct acpi_device *device) sony_wimax_rfkill->name = "sony-wimax"; sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set; sony_wimax_rfkill->get_state = sony_nc_rfkill_get; - sony_wimax_rfkill->user_claim_unsupported = 1; sony_wimax_rfkill->data = (void *)SONY_WIMAX; err = rfkill_register(sony_wimax_rfkill); if (err) diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 9f187265db8e..4345089f5171 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -803,7 +803,6 @@ static int __init toshiba_acpi_init(void) toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name; toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio; - toshiba_acpi.rfk_dev->user_claim_unsupported = 1; toshiba_acpi.rfk_dev->data = &toshiba_acpi; if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) { diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index e1ec7d9aa49c..de18ef227e00 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -58,9 +58,6 @@ enum rfkill_state { * @type: Radio type which the button controls, the value stored * here should be a value from enum rfkill_type. * @state: State of the switch, "UNBLOCKED" means radio can operate. - * @user_claim_unsupported: Whether the hardware supports exclusive - * RF-kill control by userspace. Set this before registering. - * @user_claim: Set when the switch is controlled exlusively by userspace. * @mutex: Guards switch state transitions. It serializes callbacks * and also protects the state. * @data: Pointer to the RF button drivers private data which will be @@ -83,9 +80,6 @@ struct rfkill { const char *name; enum rfkill_type type; - bool user_claim_unsupported; - bool user_claim; - /* the mutex serializes callbacks and also protects * the state */ struct mutex mutex; diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 3eaa39403c13..df1269c5ca70 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -200,7 +200,7 @@ static void __rfkill_switch_all(const enum rfkill_type type, rfkill_global_states[type].current_state = state; list_for_each_entry(rfkill, &rfkill_list, node) { - if ((!rfkill->user_claim) && (rfkill->type == type)) { + if (rfkill->type == type) { mutex_lock(&rfkill->mutex); rfkill_toggle_radio(rfkill, state, 0); mutex_unlock(&rfkill->mutex); @@ -447,53 +447,14 @@ static ssize_t rfkill_claim_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct rfkill *rfkill = to_rfkill(dev); - - return sprintf(buf, "%d\n", rfkill->user_claim); + return sprintf(buf, "%d\n", 0); } static ssize_t rfkill_claim_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct rfkill *rfkill = to_rfkill(dev); - unsigned long claim_tmp; - bool claim; - int error; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (rfkill->user_claim_unsupported) - return -EOPNOTSUPP; - - error = strict_strtoul(buf, 0, &claim_tmp); - if (error) - return error; - claim = !!claim_tmp; - - /* - * Take the global lock to make sure the kernel is not in - * the middle of rfkill_switch_all - */ - error = mutex_lock_killable(&rfkill_global_mutex); - if (error) - return error; - - if (rfkill->user_claim != claim) { - if (!claim && !rfkill_epo_lock_active) { - mutex_lock(&rfkill->mutex); - rfkill_toggle_radio(rfkill, - rfkill_global_states[rfkill->type].current_state, - 0); - mutex_unlock(&rfkill->mutex); - } - rfkill->user_claim = claim; - } - - mutex_unlock(&rfkill_global_mutex); - - return error ? error : count; + return -EOPNOTSUPP; } static struct device_attribute rfkill_dev_attrs[] = { diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c index 870032faece2..a3616e2ccb8a 100644 --- a/net/wimax/op-rfkill.c +++ b/net/wimax/op-rfkill.c @@ -364,7 +364,6 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev) rfkill->state = RFKILL_STATE_UNBLOCKED; rfkill->data = wimax_dev; rfkill->toggle_radio = wimax_rfkill_toggle_radio; - rfkill->user_claim_unsupported = 1; /* Initialize the input device for the hw key */ input_dev = input_allocate_device(); -- GitLab From fd7fbb17bec7b055fafec4d0ae3bfb4ed60cad8b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 27 Mar 2009 14:16:44 +0100 Subject: [PATCH 0502/6080] rfkill-input: remove unused code There's a lot of rfkill-input code that cannot ever be compiled and is useless until somebody needs and tests it -- therefore remove it. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/rfkill/rfkill-input.c | 69 --------------------------------------- 1 file changed, 69 deletions(-) diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c index 84efde97c5a7..60a34f3b5f65 100644 --- a/net/rfkill/rfkill-input.c +++ b/net/rfkill/rfkill-input.c @@ -47,12 +47,6 @@ enum rfkill_global_sched_op { RFKILL_GLOBAL_OP_UNBLOCK, }; -/* - * Currently, the code marked with RFKILL_NEED_SWSET is inactive. - * If handling of EV_SW SW_WLAN/WWAN/BLUETOOTH/etc is needed in the - * future, when such events are added, that code will be necessary. - */ - struct rfkill_task { struct delayed_work dwork; @@ -65,14 +59,6 @@ struct rfkill_task { /* pending regular switch operations (1=pending) */ unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; -#ifdef RFKILL_NEED_SWSET - /* set operation pending (1=pending) */ - unsigned long sw_setpending[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; - - /* desired state for pending set operation (1=unblock) */ - unsigned long sw_newstate[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; -#endif - /* should the state be complemented (1=yes) */ unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; @@ -111,24 +97,6 @@ static void __rfkill_handle_global_op(enum rfkill_global_sched_op op) } } -#ifdef RFKILL_NEED_SWSET -static void __rfkill_handle_normal_op(const enum rfkill_type type, - const bool sp, const bool s, const bool c) -{ - enum rfkill_state state; - - if (sp) - state = (s) ? RFKILL_STATE_UNBLOCKED : - RFKILL_STATE_SOFT_BLOCKED; - else - state = rfkill_get_global_state(type); - - if (c) - state = rfkill_state_complement(state); - - rfkill_switch_all(type, state); -} -#else static void __rfkill_handle_normal_op(const enum rfkill_type type, const bool c) { @@ -140,7 +108,6 @@ static void __rfkill_handle_normal_op(const enum rfkill_type type, rfkill_switch_all(type, state); } -#endif static void rfkill_task_handler(struct work_struct *work) { @@ -171,21 +138,11 @@ static void rfkill_task_handler(struct work_struct *work) i < RFKILL_TYPE_MAX) { if (test_and_clear_bit(i, task->sw_pending)) { bool c; -#ifdef RFKILL_NEED_SWSET - bool sp, s; - sp = test_and_clear_bit(i, - task->sw_setpending); - s = test_bit(i, task->sw_newstate); -#endif c = test_and_clear_bit(i, task->sw_togglestate); spin_unlock_irq(&task->lock); -#ifdef RFKILL_NEED_SWSET - __rfkill_handle_normal_op(i, sp, s, c); -#else __rfkill_handle_normal_op(i, c); -#endif spin_lock_irq(&task->lock); } @@ -238,32 +195,6 @@ static void rfkill_schedule_global_op(enum rfkill_global_sched_op op) spin_unlock_irqrestore(&rfkill_task.lock, flags); } -#ifdef RFKILL_NEED_SWSET -/* Use this if you need to add EV_SW SW_WLAN/WWAN/BLUETOOTH/etc handling */ - -static void rfkill_schedule_set(enum rfkill_type type, - enum rfkill_state desired_state) -{ - unsigned long flags; - - if (rfkill_is_epo_lock_active()) - return; - - spin_lock_irqsave(&rfkill_task.lock, flags); - if (!rfkill_task.global_op_pending) { - set_bit(type, rfkill_task.sw_pending); - set_bit(type, rfkill_task.sw_setpending); - clear_bit(type, rfkill_task.sw_togglestate); - if (desired_state) - set_bit(type, rfkill_task.sw_newstate); - else - clear_bit(type, rfkill_task.sw_newstate); - rfkill_schedule_ratelimited(); - } - spin_unlock_irqrestore(&rfkill_task.lock, flags); -} -#endif - static void rfkill_schedule_toggle(enum rfkill_type type) { unsigned long flags; -- GitLab From 07f62d01c1f476a3b328a44faafdfd103a4dedc3 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 27 Mar 2009 22:20:27 +0800 Subject: [PATCH 0503/6080] cfg80211: remove duplicated #include Remove duplicated #include in include/net/cfg80211.h. Signed-off-by: Huang Weiyi Signed-off-by: John W. Linville --- include/net/cfg80211.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5389afdc1297..d1b8f0d53c57 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -10,7 +10,6 @@ #include #include /* remove once we remove the wext stuff */ -#include /* * 802.11 configuration in-kernel interface -- GitLab From c0ed418977edf60f1df9933e1ccd48920a28eb66 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Fri, 27 Mar 2009 22:21:36 +0800 Subject: [PATCH 0504/6080] nl80211: remove duplicated #include Remove duplicated #include in net/wireless/core.h. Signed-off-by: Huang Weiyi Signed-off-by: John W. Linville --- net/wireless/core.h | 1 - 1 file changed, 1 deletion(-) diff --git a/net/wireless/core.h b/net/wireless/core.h index 0a592e4295f0..fcee83a0c9bb 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include -- GitLab From 1778092e1739155acec35a3bccee2fb8a1ae4e91 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 27 Mar 2009 20:52:47 +0200 Subject: [PATCH 0505/6080] nl80211: Require auth type for NL80211_CMD_AUTHENTICATE NL80211_ATTR_AUTH_TYPE is a required parameter for NL80211_CMD_AUTHENTICATE. We are currently (by chance) defaulting to open system authentication if the attribute is not specified. It is better to just reject the invalid command. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2f449ddcbc72..c04df6a6af78 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2752,6 +2752,9 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NL80211_ATTR_MAC]) return -EINVAL; + if (!info->attrs[NL80211_ATTR_AUTH_TYPE]) + return -EINVAL; + rtnl_lock(); err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); @@ -2798,13 +2801,10 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); } - if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { - req.auth_type = - nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); - if (!nl80211_valid_auth_type(req.auth_type)) { - err = -EINVAL; - goto out; - } + req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); + if (!nl80211_valid_auth_type(req.auth_type)) { + err = -EINVAL; + goto out; } err = drv->ops->auth(&drv->wiphy, dev, &req); -- GitLab From 53b46b8444f600cc1744521ea096ea0c5d494dd0 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 27 Mar 2009 20:53:56 +0200 Subject: [PATCH 0506/6080] nl80211: Generate deauth/disassoc event for locally generated frames Previously, nl80211 mlme events were generated only for received deauthentication and disassociation frames. We need to do the same for locally generated ones in order to let applications know that we disconnected (e.g., when AP does not reply to a probe). Rename the nl80211 and cfg80211 functions (s/rx_//) to make it clearer that they are used for both received and locally generated frames. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- include/net/cfg80211.h | 16 ++++++++-------- net/mac80211/mlme.c | 8 ++++++-- net/wireless/mlme.c | 13 ++++++------- net/wireless/nl80211.c | 11 +++++------ net/wireless/nl80211.h | 12 ++++++------ 5 files changed, 31 insertions(+), 29 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index d1b8f0d53c57..ec33096fc655 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -917,28 +917,28 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len); /** - * cfg80211_send_rx_deauth - notification of processed deauthentication + * cfg80211_send_deauth - notification of processed deauthentication * @dev: network device * @buf: deauthentication frame (header + body) * @len: length of the frame data * * This function is called whenever deauthentication has been processed in - * station mode. + * station mode. This includes both received deauthentication frames and + * locally generated ones. */ -void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf, - size_t len); +void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); /** - * cfg80211_send_rx_disassoc - notification of processed disassociation + * cfg80211_send_disassoc - notification of processed disassociation * @dev: network device * @buf: disassociation response frame (header + body) * @len: length of the frame data * * This function is called whenever disassociation has been processed in - * station mode. + * station mode. This includes both received disassociation frames and locally + * generated ones. */ -void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf, - size_t len); +void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); /** * cfg80211_hold_bss - exclude bss from expiration diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 132938b073dc..08db02c237c9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -325,6 +325,10 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, /* u.deauth.reason_code == u.disassoc.reason_code */ mgmt->u.deauth.reason_code = cpu_to_le16(reason); + if (stype == IEEE80211_STYPE_DEAUTH) + cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len); + else + cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len); ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); } @@ -1187,7 +1191,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, ieee80211_set_disassoc(sdata, true, false, 0); ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED; - cfg80211_send_rx_deauth(sdata->dev, (u8 *) mgmt, len); + cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, len); } @@ -1218,7 +1222,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, } ieee80211_set_disassoc(sdata, false, false, reason_code); - cfg80211_send_rx_disassoc(sdata->dev, (u8 *) mgmt, len); + cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, len); } diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index bec5721b6f99..33ff7cca496b 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -28,19 +28,18 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) } EXPORT_SYMBOL(cfg80211_send_rx_assoc); -void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf, size_t len) +void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len) { struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - nl80211_send_rx_deauth(rdev, dev, buf, len); + nl80211_send_deauth(rdev, dev, buf, len); } -EXPORT_SYMBOL(cfg80211_send_rx_deauth); +EXPORT_SYMBOL(cfg80211_send_deauth); -void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf, - size_t len) +void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len) { struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - nl80211_send_rx_disassoc(rdev, dev, buf, len); + nl80211_send_disassoc(rdev, dev, buf, len); } -EXPORT_SYMBOL(cfg80211_send_rx_disassoc); +EXPORT_SYMBOL(cfg80211_send_disassoc); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c04df6a6af78..195424eee77d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3415,17 +3415,16 @@ void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE); } -void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev, - struct net_device *netdev, const u8 *buf, - size_t len) +void nl80211_send_deauth(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *buf, size_t len) { nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_DEAUTHENTICATE); } -void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev, - struct net_device *netdev, const u8 *buf, - size_t len) +void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *buf, + size_t len) { nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_DISASSOCIATE); diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index b77af4ab80be..55686fc264f0 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -17,11 +17,11 @@ extern void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *buf, size_t len); -extern void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev, - struct net_device *netdev, - const u8 *buf, size_t len); -extern void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev, - struct net_device *netdev, - const u8 *buf, size_t len); +extern void nl80211_send_deauth(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *buf, size_t len); +extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *buf, size_t len); #endif /* __NET_WIRELESS_NL80211_H */ -- GitLab From a3b8b0569fbef725597f05278ec58083321f6e9d Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 27 Mar 2009 21:59:49 +0200 Subject: [PATCH 0507/6080] nl80211: Add Michael MIC failure event Define a new nl80211 event, NL80211_CMD_MICHAEL_MIC_FAILURE, to be used to notify user space about locally detected Michael MIC failures. This matches with the MLME-MICHAELMICFAILURE.indication() primitive. Since we do not actually have TSC in the skb anymore when mac80211_ev_michael_mic_failure() is called, that function is changed to take in the TSC as an optional parameter instead of as a requirement to include the TSC after the hdr field (which we did not really follow). For now, TSC is not included in the events from mac80211, but it could be added at some point. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- include/linux/nl80211.h | 28 ++++++++++++++++++++++++++ include/net/cfg80211.h | 16 +++++++++++++++ net/mac80211/event.c | 17 ++++++++-------- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/rx.c | 2 +- net/mac80211/wpa.c | 2 +- net/wireless/mlme.c | 10 ++++++++++ net/wireless/nl80211.c | 40 ++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 5 +++++ 9 files changed, 111 insertions(+), 11 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index cbe8ce3bf486..27f230f063b3 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -199,6 +199,14 @@ * NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to * MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives). * + * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael + * MIC (part of TKIP) failure; sent on the "mlme" multicast group; the + * event includes %NL80211_ATTR_MAC to describe the source MAC address of + * the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key + * type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and + * %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this + * event matches with MLME-MICHAELMICFAILURE.indication() primitive + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -260,6 +268,8 @@ enum nl80211_commands { NL80211_CMD_DEAUTHENTICATE, NL80211_CMD_DISASSOCIATE, + NL80211_CMD_MICHAEL_MIC_FAILURE, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -408,6 +418,9 @@ enum nl80211_commands { * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and * %NL80211_CMD_DISASSOCIATE, u16 * + * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as + * a u32 + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -492,6 +505,8 @@ enum nl80211_attrs { NL80211_ATTR_AUTH_TYPE, NL80211_ATTR_REASON_CODE, + NL80211_ATTR_KEY_TYPE, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -1062,4 +1077,17 @@ enum nl80211_auth_type { NL80211_AUTHTYPE_FT, NL80211_AUTHTYPE_NETWORK_EAP, }; + +/** + * enum nl80211_key_type - Key Type + * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key + * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key + * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS) + */ +enum nl80211_key_type { + NL80211_KEYTYPE_GROUP, + NL80211_KEYTYPE_PAIRWISE, + NL80211_KEYTYPE_PEERKEY, +}; + #endif /* __LINUX_NL80211_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ec33096fc655..f8bf0c86650b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -957,4 +957,20 @@ void cfg80211_hold_bss(struct cfg80211_bss *bss); */ void cfg80211_unhold_bss(struct cfg80211_bss *bss); +/** + * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP) + * @dev: network device + * @addr: The source MAC address of the frame + * @key_type: The key type that the received frame used + * @key_id: Key identifier (0..3) + * @tsc: The TSC value of the frame that generated the MIC failure (6 octets) + * + * This function is called whenever the local MAC detects a MIC failure in a + * received frame. This matches with MLME-MICHAELMICFAILURE.indication() + * primitive. + */ +void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, + enum nl80211_key_type key_type, int key_id, + const u8 *tsc); + #endif /* __NET_CFG80211_H */ diff --git a/net/mac80211/event.c b/net/mac80211/event.c index 0d95561c0ee0..f288d01a6344 100644 --- a/net/mac80211/event.c +++ b/net/mac80211/event.c @@ -12,12 +12,12 @@ #include "ieee80211_i.h" /* - * indicate a failed Michael MIC to userspace; the passed packet - * (in the variable hdr) must be long enough to extract the TKIP - * fields like TSC + * Indicate a failed Michael MIC to userspace. If the caller knows the TSC of + * the frame that generated the MIC failure (i.e., if it was provided by the + * driver or is still in the frame), it should provide that information. */ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, - struct ieee80211_hdr *hdr) + struct ieee80211_hdr *hdr, const u8 *tsc) { union iwreq_data wrqu; char *buf = kmalloc(128, GFP_ATOMIC); @@ -34,8 +34,9 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke kfree(buf); } - /* - * TODO: re-add support for sending MIC failure indication - * with all info via nl80211 - */ + cfg80211_michael_mic_failure(sdata->dev, hdr->addr2, + (hdr->addr1[0] & 0x01) ? + NL80211_KEYTYPE_GROUP : + NL80211_KEYTYPE_PAIRWISE, + keyidx, tsc); } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e6ed78cb16b3..312347d102c8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1060,7 +1060,7 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, int rate, int erp, int short_preamble); void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, - struct ieee80211_hdr *hdr); + struct ieee80211_hdr *hdr, const u8 *tsc); void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, int encrypt); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5fa7aedd90ed..19c4b4589fee 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1932,7 +1932,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, !ieee80211_is_auth(hdr->frame_control)) goto ignore; - mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr); + mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL); ignore: dev_kfree_skb(rx->skb); rx->skb = NULL; diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 4f8bfea278f2..dcfae8884b86 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -122,7 +122,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) return RX_DROP_UNUSABLE; mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, - (void *) skb->data); + (void *) skb->data, NULL); return RX_DROP_UNUSABLE; } diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 33ff7cca496b..1407244a647e 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -43,3 +43,13 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len) nl80211_send_disassoc(rdev, dev, buf, len); } EXPORT_SYMBOL(cfg80211_send_disassoc); + +void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, + enum nl80211_key_type key_type, int key_id, + const u8 *tsc) +{ + struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc); +} +EXPORT_SYMBOL(cfg80211_michael_mic_failure); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 195424eee77d..1394115cde95 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3430,6 +3430,46 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, NL80211_CMD_DISASSOCIATE); } +void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *addr, + enum nl80211_key_type key_type, int key_id, + const u8 *tsc) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE); + if (!hdr) { + nlmsg_free(msg); + return; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); + if (addr) + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); + NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type); + NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id); + if (tsc) + NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); + + if (genlmsg_end(msg, hdr) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL); + return; + + nla_put_failure: + genlmsg_cancel(msg, hdr); + nlmsg_free(msg); +} + /* initialisation/exit functions */ int nl80211_init(void) diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 55686fc264f0..e4b92cccd157 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -23,5 +23,10 @@ extern void nl80211_send_deauth(struct cfg80211_registered_device *rdev, extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *buf, size_t len); +extern void +nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *addr, + enum nl80211_key_type key_type, + int key_id, const u8 *tsc); #endif /* __NET_WIRELESS_NL80211_H */ -- GitLab From 295936c56672e82369c6d989e27d3a87495808e4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 27 Mar 2009 17:21:05 -0400 Subject: [PATCH 0508/6080] ath9k: Update maintainers for ath9k This has been the case really, we just forgot to update it. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 2dc197c362b3..6dfcb6d03a97 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -888,6 +888,12 @@ P: Luis R. Rodriguez M: lrodriguez@atheros.com P: Jouni Malinen M: jmalinen@atheros.com +P: Sujith Manoharan +M: Sujith.Manoharan@atheros.com +P: Vasanthakumar Thiagarajan +M: vasanth@atheros.com +P: Senthil Balasubramanian +M: senthilkumar@atheros.com L: linux-wireless@vger.kernel.org L: ath9k-devel@lists.ath9k.org S: Supported -- GitLab From 807e37394b5a1dc23a2908b59f34edbbae67e9ea Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Fri, 27 Mar 2009 17:47:27 -0400 Subject: [PATCH 0509/6080] ath5k: fix scanning in AR2424 AR5K_PHY_PLL_40MHZ_5413 should not be ORed with AR5K_PHY_MODE_RAD_RF5112 for 5 GHz channels. The incorrect PLL value breaks scanning in the countries where 5 GHz channels are allowed. Signed-off-by: Pavel Roskin Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c index cb5e15f97095..775fdf78554b 100644 --- a/drivers/net/wireless/ath5k/reset.c +++ b/drivers/net/wireless/ath5k/reset.c @@ -358,7 +358,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) mode |= AR5K_PHY_MODE_FREQ_5GHZ; if (ah->ah_radio == AR5K_RF5413) - clock |= AR5K_PHY_PLL_40MHZ_5413; + clock = AR5K_PHY_PLL_40MHZ_5413; else clock |= AR5K_PHY_PLL_40MHZ; -- GitLab From 32c1628f153a5468cf48be5e5c04cd599ae9e01d Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 28 Mar 2009 01:46:14 +0100 Subject: [PATCH 0510/6080] ar9170: fix hang on stop This patch fixes a locking problem which freezes the network core. The deadlock goes as follows: - ar9170_op_stop - is called 1. change the state to IDLE 2. > take the MUTEX < 3. cancel_SYNC all pending work, which means "block until a work_struct's callback has terminated" => if filter_config_work was queued it tries to get the MUTEX, before checking the device state... Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ar9170/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ar9170/main.c index 5996ff9f7f47..5f55754d968f 100644 --- a/drivers/net/wireless/ar9170/main.c +++ b/drivers/net/wireless/ar9170/main.c @@ -742,8 +742,9 @@ static void ar9170_op_stop(struct ieee80211_hw *hw) if (IS_STARTED(ar)) ar->state = AR9170_IDLE; - mutex_lock(&ar->mutex); + flush_workqueue(ar->hw->workqueue); + mutex_lock(&ar->mutex); cancel_delayed_work_sync(&ar->tx_status_janitor); cancel_work_sync(&ar->filter_config_work); cancel_work_sync(&ar->beacon_work); @@ -1123,10 +1124,10 @@ static void ar9170_set_filters(struct work_struct *work) filter_config_work); int err; - mutex_lock(&ar->mutex); if (unlikely(!IS_STARTED(ar))) - goto unlock; + return ; + mutex_lock(&ar->mutex); if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) { err = ar9170_set_operating_mode(ar); if (err) -- GitLab From 440ddadaee6d0d5e8a7ee53ac913f78a8e5570a1 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 28 Mar 2009 20:51:24 +0100 Subject: [PATCH 0511/6080] rt2x00: Move Move pci_dev specific access to rt2x00pci pci_dev->irq and pci_name(pci_dev) access should be limited to rt2x00pci only. This is more generic and allows a rt2x00 pci driver to be controlled as PCI device but also as platform driver (needed for rt2800pci SoC support). Signed-off-by: Felix Fietkau Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2400pci.c | 2 +- drivers/net/wireless/rt2x00/rt2500pci.c | 2 +- drivers/net/wireless/rt2x00/rt2x00.h | 18 ++++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00pci.c | 16 ++++++++++++---- drivers/net/wireless/rt2x00/rt61pci.c | 7 +------ drivers/net/wireless/rt2x00/rt61pci.h | 6 ------ 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 0f08773328c6..411eb9cbb4e5 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1361,7 +1361,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) */ value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); rt2x00pci_register_read(rt2x00dev, CSR0, ®); - rt2x00_set_chip(rt2x00dev, RT2460, value, reg); + rt2x00_set_chip_rf(rt2x00dev, value, reg); if (!rt2x00_rf(&rt2x00dev->chip, RF2420) && !rt2x00_rf(&rt2x00dev->chip, RF2421)) { diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 276a8232aaa0..e1be67ca23d8 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1525,7 +1525,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) */ value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); rt2x00pci_register_read(rt2x00dev, CSR0, ®); - rt2x00_set_chip(rt2x00dev, RT2560, value, reg); + rt2x00_set_chip_rf(rt2x00dev, value, reg); if (!rt2x00_rf(&rt2x00dev->chip, RF2522) && !rt2x00_rf(&rt2x00dev->chip, RF2523) && diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 84bd6f19acb0..e03d69975ea4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -671,6 +671,12 @@ struct rt2x00_dev { */ unsigned long flags; + /* + * Device information, Bus IRQ and name (PCI, SoC) + */ + int irq; + const char *name; + /* * Chipset identification. */ @@ -860,6 +866,18 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev, rt2x00dev->chip.rev = rev; } +static inline void rt2x00_set_chip_rt(struct rt2x00_dev *rt2x00dev, + const u16 rt) +{ + rt2x00dev->chip.rt = rt; +} + +static inline void rt2x00_set_chip_rf(struct rt2x00_dev *rt2x00dev, + const u16 rf, const u32 rev) +{ + rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev); +} + static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip) { return (chipset->rt == chip); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 9730b4f8fd26..cdd5154bd4c0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -170,7 +170,6 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) { - struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev); struct data_queue *queue; int status; @@ -186,11 +185,11 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) /* * Register interrupt handler. */ - status = request_irq(pci_dev->irq, rt2x00dev->ops->lib->irq_handler, - IRQF_SHARED, pci_name(pci_dev), rt2x00dev); + status = request_irq(rt2x00dev->irq, rt2x00dev->ops->lib->irq_handler, + IRQF_SHARED, rt2x00dev->name, rt2x00dev); if (status) { ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n", - pci_dev->irq, status); + rt2x00dev->irq, status); goto exit; } @@ -270,6 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) struct ieee80211_hw *hw; struct rt2x00_dev *rt2x00dev; int retval; + u16 chip; retval = pci_request_regions(pci_dev, pci_name(pci_dev)); if (retval) { @@ -307,6 +307,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) rt2x00dev->dev = &pci_dev->dev; rt2x00dev->ops = ops; rt2x00dev->hw = hw; + rt2x00dev->irq = pci_dev->irq; + rt2x00dev->name = pci_name(pci_dev); + + /* + * Determine RT chipset by reading PCI header. + */ + pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip); + rt2x00_set_chip_rt(rt2x00dev, chip); retval = rt2x00pci_alloc_reg(rt2x00dev); if (retval) diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 2ca8b7a9722c..4346cd1494bc 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2308,7 +2308,6 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) u32 reg; u16 value; u16 eeprom; - u16 device; /* * Read EEPROM word for configuration. @@ -2317,14 +2316,10 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Identify RF chipset. - * To determine the RT chip we have to read the - * PCI header of the device. */ - pci_read_config_word(to_pci_dev(rt2x00dev->dev), - PCI_CONFIG_HEADER_DEVICE, &device); value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); - rt2x00_set_chip(rt2x00dev, device, value, reg); + rt2x00_set_chip_rf(rt2x00dev, value, reg); if (!rt2x00_rf(&rt2x00dev->chip, RF5225) && !rt2x00_rf(&rt2x00dev->chip, RF5325) && diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 41e8959919f6..6c71f77c8165 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -62,12 +62,6 @@ * PCI registers. */ -/* - * PCI Configuration Header - */ -#define PCI_CONFIG_HEADER_VENDOR 0x0000 -#define PCI_CONFIG_HEADER_DEVICE 0x0002 - /* * HOST_CMD_CSR: For HOST to interrupt embedded processor */ -- GitLab From a57e2e84b65d1b89c4b1effeceb27b181226b950 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 28 Mar 2009 20:51:41 +0100 Subject: [PATCH 0512/6080] rt2x00: Fix Sparse warning rt2x00link_reset_qual() is not declared in a header, and is only internally used within rt2x00link.c. It should be declared as static. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 7eb5cd7e5f32..eb9b981b9139 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -387,7 +387,7 @@ void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna) rt2x00link_antenna_reset(rt2x00dev); } -void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev) +static void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev) { struct link_qual *qual = &rt2x00dev->link.qual; -- GitLab From 616de35da94df8748771a014ef898360d5f4d0c8 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 29 Mar 2009 13:19:31 +0200 Subject: [PATCH 0513/6080] b43: Do not "select" HW_RANDOM Auto-depend on HW_RANDOM, rather than "select"ing it. This way the user has the choice to enable or disable HWRNG support. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/Kconfig | 8 +++++++- drivers/net/wireless/b43/b43.h | 4 +++- drivers/net/wireless/b43/main.c | 8 +++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index aab71a70ba78..21572e40b79d 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -3,7 +3,6 @@ config B43 depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA select SSB select FW_LOADER - select HW_RANDOM ---help--- b43 is a driver for the Broadcom 43xx series wireless devices. @@ -106,6 +105,13 @@ config B43_RFKILL depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43) default y +# This config option automatically enables b43 HW-RNG support, +# if the HW-RNG core is enabled. +config B43_HWRNG + bool + depends on B43 && (HW_RANDOM = y || HW_RANDOM = B43) + default y + config B43_DEBUG bool "Broadcom 43xx debugging" depends on B43 diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index beaf18d6e8a7..cc1db7e5c664 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -625,9 +625,11 @@ struct b43_wl { /* Stats about the wireless interface */ struct ieee80211_low_level_stats ieee_stats; +#ifdef CONFIG_B43_HWRNG struct hwrng rng; - u8 rng_initialized; + bool rng_initialized; char rng_name[30 + 1]; +#endif /* CONFIG_B43_HWRNG */ /* The RF-kill button */ struct b43_rfkill rfkill; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 79b685e300c7..09e0c60d96df 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2980,6 +2980,7 @@ static void b43_security_init(struct b43_wldev *dev) b43_clear_keys(dev); } +#ifdef CONFIG_B43_HWRNG static int b43_rng_read(struct hwrng *rng, u32 *data) { struct b43_wl *wl = (struct b43_wl *)rng->priv; @@ -2995,17 +2996,21 @@ static int b43_rng_read(struct hwrng *rng, u32 *data) return (sizeof(u16)); } +#endif /* CONFIG_B43_HWRNG */ static void b43_rng_exit(struct b43_wl *wl) { +#ifdef CONFIG_B43_HWRNG if (wl->rng_initialized) hwrng_unregister(&wl->rng); +#endif /* CONFIG_B43_HWRNG */ } static int b43_rng_init(struct b43_wl *wl) { - int err; + int err = 0; +#ifdef CONFIG_B43_HWRNG snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name), "%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy)); wl->rng.name = wl->rng_name; @@ -3018,6 +3023,7 @@ static int b43_rng_init(struct b43_wl *wl) b43err(wl, "Failed to register the random " "number generator (%d)\n", err); } +#endif /* CONFIG_B43_HWRNG */ return err; } -- GitLab From 8782b41d13c8e5f9a201477d3c15edf9fe7c372c Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Mon, 30 Mar 2009 14:17:00 +0530 Subject: [PATCH 0514/6080] ath9k: No need to abort Rx path when autosleep is enabled. For chipsets supporting autosleep feature, there is no need to abort Rx engine since they are capable of automatically going back to sleep after receiving a packet. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 0607df20e497..97cf83fa8555 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -2325,26 +2325,33 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ieee80211_conf *conf = &hw->conf; + struct ath_hw *ah = sc->sc_ah; mutex_lock(&sc->mutex); if (changed & IEEE80211_CONF_CHANGE_PS) { if (conf->flags & IEEE80211_CONF_PS) { - if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { - sc->imask |= ATH9K_INT_TIM_TIMER; - ath9k_hw_set_interrupts(sc->sc_ah, - sc->imask); + if (!(ah->caps.hw_caps & + ATH9K_HW_CAP_AUTOSLEEP)) { + if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { + sc->imask |= ATH9K_INT_TIM_TIMER; + ath9k_hw_set_interrupts(sc->sc_ah, + sc->imask); + } + ath9k_hw_setrxabort(sc->sc_ah, 1); } - ath9k_hw_setrxabort(sc->sc_ah, 1); ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); } else { ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); - ath9k_hw_setrxabort(sc->sc_ah, 0); - sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; - if (sc->imask & ATH9K_INT_TIM_TIMER) { - sc->imask &= ~ATH9K_INT_TIM_TIMER; - ath9k_hw_set_interrupts(sc->sc_ah, - sc->imask); + if (!(ah->caps.hw_caps & + ATH9K_HW_CAP_AUTOSLEEP)) { + ath9k_hw_setrxabort(sc->sc_ah, 0); + sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; + if (sc->imask & ATH9K_INT_TIM_TIMER) { + sc->imask &= ~ATH9K_INT_TIM_TIMER; + ath9k_hw_set_interrupts(sc->sc_ah, + sc->imask); + } } } } -- GitLab From bdbdf46daa6dccb472f56559854477faddc44de9 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:22 +0530 Subject: [PATCH 0515/6080] ath9k: Remove a few unused flags This patch removes unused HW capability flags and HW operation variables, and a chainmask flag that we don't use anywhere. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 25 +++++++------- drivers/net/wireless/ath9k/hw.c | 21 ------------ drivers/net/wireless/ath9k/hw.h | 52 +++++++++++------------------- drivers/net/wireless/ath9k/main.c | 2 -- drivers/net/wireless/ath9k/rc.h | 1 - 5 files changed, 30 insertions(+), 71 deletions(-) diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 7b1b40aaf09d..1dfc3816a2d8 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -525,19 +525,18 @@ struct ath_rfkill { #define SC_OP_BEACONS BIT(1) #define SC_OP_RXAGGR BIT(2) #define SC_OP_TXAGGR BIT(3) -#define SC_OP_CHAINMASK_UPDATE BIT(4) -#define SC_OP_FULL_RESET BIT(5) -#define SC_OP_PREAMBLE_SHORT BIT(6) -#define SC_OP_PROTECT_ENABLE BIT(7) -#define SC_OP_RXFLUSH BIT(8) -#define SC_OP_LED_ASSOCIATED BIT(9) -#define SC_OP_RFKILL_REGISTERED BIT(10) -#define SC_OP_RFKILL_SW_BLOCKED BIT(11) -#define SC_OP_RFKILL_HW_BLOCKED BIT(12) -#define SC_OP_WAIT_FOR_BEACON BIT(13) -#define SC_OP_LED_ON BIT(14) -#define SC_OP_SCANNING BIT(15) -#define SC_OP_TSF_RESET BIT(16) +#define SC_OP_FULL_RESET BIT(4) +#define SC_OP_PREAMBLE_SHORT BIT(5) +#define SC_OP_PROTECT_ENABLE BIT(6) +#define SC_OP_RXFLUSH BIT(7) +#define SC_OP_LED_ASSOCIATED BIT(8) +#define SC_OP_RFKILL_REGISTERED BIT(9) +#define SC_OP_RFKILL_SW_BLOCKED BIT(10) +#define SC_OP_RFKILL_HW_BLOCKED BIT(11) +#define SC_OP_WAIT_FOR_BEACON BIT(12) +#define SC_OP_LED_ON BIT(13) +#define SC_OP_SCANNING BIT(14) +#define SC_OP_TSF_RESET BIT(15) struct ath_bus_ops { void (*read_cachesize)(struct ath_softc *sc, int *csz); diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index b15eaf8417ff..13d8c2a4efae 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -363,10 +363,7 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah) ah->config.ack_6mb = 0x0; ah->config.cwm_ignore_extcca = 0; ah->config.pcie_powersave_enable = 0; - ah->config.pcie_l1skp_enable = 0; ah->config.pcie_clock_req = 0; - ah->config.pcie_power_reset = 0x100; - ah->config.pcie_restore = 0; ah->config.pcie_waen = 0; ah->config.analog_shiftreg = 1; ah->config.ht_enable = 1; @@ -375,13 +372,6 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah) ah->config.cck_trig_high = 200; ah->config.cck_trig_low = 100; ah->config.enable_ani = 1; - ah->config.noise_immunity_level = 4; - ah->config.ofdm_weaksignal_det = 1; - ah->config.cck_weaksignal_thr = 0; - ah->config.spur_immunity_level = 2; - ah->config.firstep_level = 0; - ah->config.rssi_thr_high = 40; - ah->config.rssi_thr_low = 7; ah->config.diversity_control = 0; ah->config.antenna_switch_swap = 0; @@ -3343,8 +3333,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP; pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM; - pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD; - if (ah->config.ht_enable) pCap->hw_caps |= ATH9K_HW_CAP_HT; else @@ -3368,7 +3356,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->keycache_size = AR_KEYTABLE_SIZE; pCap->hw_caps |= ATH9K_HW_CAP_FASTCC; - pCap->num_mr_retries = 4; pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; if (AR_SREV_9285_10_OR_LATER(ah)) @@ -3378,14 +3365,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah) else pCap->num_gpio_pins = AR_NUM_GPIO; - if (AR_SREV_9280_10_OR_LATER(ah)) { - pCap->hw_caps |= ATH9K_HW_CAP_WOW; - pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT; - } else { - pCap->hw_caps &= ~ATH9K_HW_CAP_WOW; - pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT; - } - if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) { pCap->hw_caps |= ATH9K_HW_CAP_CST; pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX; diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h index 0b594e0ee260..5ba6a4b60356 100644 --- a/drivers/net/wireless/ath9k/hw.h +++ b/drivers/net/wireless/ath9k/hw.h @@ -124,29 +124,24 @@ enum wireless_mode { }; enum ath9k_hw_caps { - ATH9K_HW_CAP_CHAN_SPREAD = BIT(0), - ATH9K_HW_CAP_MIC_AESCCM = BIT(1), - ATH9K_HW_CAP_MIC_CKIP = BIT(2), - ATH9K_HW_CAP_MIC_TKIP = BIT(3), - ATH9K_HW_CAP_CIPHER_AESCCM = BIT(4), - ATH9K_HW_CAP_CIPHER_CKIP = BIT(5), - ATH9K_HW_CAP_CIPHER_TKIP = BIT(6), - ATH9K_HW_CAP_VEOL = BIT(7), - ATH9K_HW_CAP_BSSIDMASK = BIT(8), - ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(9), - ATH9K_HW_CAP_CHAN_HALFRATE = BIT(10), - ATH9K_HW_CAP_CHAN_QUARTERRATE = BIT(11), - ATH9K_HW_CAP_HT = BIT(12), - ATH9K_HW_CAP_GTT = BIT(13), - ATH9K_HW_CAP_FASTCC = BIT(14), - ATH9K_HW_CAP_RFSILENT = BIT(15), - ATH9K_HW_CAP_WOW = BIT(16), - ATH9K_HW_CAP_CST = BIT(17), - ATH9K_HW_CAP_ENHANCEDPM = BIT(18), - ATH9K_HW_CAP_AUTOSLEEP = BIT(19), - ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20), - ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21), - ATH9K_HW_CAP_BT_COEX = BIT(22) + ATH9K_HW_CAP_MIC_AESCCM = BIT(0), + ATH9K_HW_CAP_MIC_CKIP = BIT(1), + ATH9K_HW_CAP_MIC_TKIP = BIT(2), + ATH9K_HW_CAP_CIPHER_AESCCM = BIT(3), + ATH9K_HW_CAP_CIPHER_CKIP = BIT(4), + ATH9K_HW_CAP_CIPHER_TKIP = BIT(5), + ATH9K_HW_CAP_VEOL = BIT(6), + ATH9K_HW_CAP_BSSIDMASK = BIT(7), + ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(8), + ATH9K_HW_CAP_HT = BIT(9), + ATH9K_HW_CAP_GTT = BIT(10), + ATH9K_HW_CAP_FASTCC = BIT(11), + ATH9K_HW_CAP_RFSILENT = BIT(12), + ATH9K_HW_CAP_CST = BIT(13), + ATH9K_HW_CAP_ENHANCEDPM = BIT(14), + ATH9K_HW_CAP_AUTOSLEEP = BIT(15), + ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16), + ATH9K_HW_CAP_BT_COEX = BIT(17) }; enum ath9k_capability_type { @@ -166,7 +161,6 @@ struct ath9k_hw_capabilities { u16 keycache_size; u16 low_5ghz_chan, high_5ghz_chan; u16 low_2ghz_chan, high_2ghz_chan; - u16 num_mr_retries; u16 rts_aggr_limit; u8 tx_chainmask; u8 rx_chainmask; @@ -184,11 +178,8 @@ struct ath9k_ops_config { int ack_6mb; int cwm_ignore_extcca; u8 pcie_powersave_enable; - u8 pcie_l1skp_enable; u8 pcie_clock_req; u32 pcie_waen; - int pcie_power_reset; - u8 pcie_restore; u8 analog_shiftreg; u8 ht_enable; u32 ofdm_trig_low; @@ -196,13 +187,6 @@ struct ath9k_ops_config { u32 cck_trig_high; u32 cck_trig_low; u32 enable_ani; - u8 noise_immunity_level; - u32 ofdm_weaksignal_det; - u32 cck_weaksignal_thr; - u8 spur_immunity_level; - u8 firstep_level; - int8_t rssi_thr_high; - int8_t rssi_thr_low; u16 diversity_control; u16 antenna_switch_swap; int serialize_regmode; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 97cf83fa8555..74fe777b54e4 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -287,7 +287,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, } spin_unlock_bh(&sc->sc_resetlock); - sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE; sc->sc_flags &= ~SC_OP_FULL_RESET; if (ath_startrecv(sc) != 0) { @@ -416,7 +415,6 @@ set_timer: */ void ath_update_chainmask(struct ath_softc *sc, int is_ht) { - sc->sc_flags |= SC_OP_CHAINMASK_UPDATE; if (is_ht || (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) { sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask; diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h index 199a3ce57d64..ec72dd29da00 100644 --- a/drivers/net/wireless/ath9k/rc.h +++ b/drivers/net/wireless/ath9k/rc.h @@ -24,7 +24,6 @@ struct ath_softc; #define ATH_RATE_MAX 30 #define RATE_TABLE_SIZE 64 #define MAX_TX_RATE_PHY 48 -#define WLAN_CTRL_FRAME_SIZE (2+2+6+4) /* VALID_ALL - valid for 20/40/Legacy, * VALID - Legacy only, -- GitLab From 6ed6a05e5c8061cdcd69a418c90c5f11979ce650 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:24 +0530 Subject: [PATCH 0516/6080] ath9k: Remove redundant chainmask check We get the valid chainmasks on HW attach, checking it again during reset is redundant. This patch removes the check. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/hw.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 13d8c2a4efae..22ef93f3d47c 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -2189,14 +2189,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ah->txchainmask = sc->tx_chainmask; ah->rxchainmask = sc->rx_chainmask; - if (AR_SREV_9285(ah)) { - ah->txchainmask &= 0x1; - ah->rxchainmask &= 0x1; - } else if (AR_SREV_9280(ah)) { - ah->txchainmask &= 0x3; - ah->rxchainmask &= 0x3; - } - if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) return -EIO; -- GitLab From d8baa9392666d1c50ef42e9f6fbbb0cf536327b9 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:25 +0530 Subject: [PATCH 0517/6080] ath9k: Cleanup debug messages Clean debug messages to use appropriate levels, remove useless messages, and trim the number of debug levels. Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ani.c | 8 +-- drivers/net/wireless/ath9k/beacon.c | 7 +- drivers/net/wireless/ath9k/debug.h | 24 +++---- drivers/net/wireless/ath9k/eeprom.c | 24 +++---- drivers/net/wireless/ath9k/hw.c | 101 ++++++++++++---------------- drivers/net/wireless/ath9k/mac.c | 63 ++++++++++------- drivers/net/wireless/ath9k/main.c | 6 +- drivers/net/wireless/ath9k/phy.c | 4 +- drivers/net/wireless/ath9k/phy.h | 3 - drivers/net/wireless/ath9k/recv.c | 4 +- 10 files changed, 115 insertions(+), 129 deletions(-) diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c index 6c5e887d50d7..1aeafb511ddd 100644 --- a/drivers/net/wireless/ath9k/ani.c +++ b/drivers/net/wireless/ath9k/ani.c @@ -569,8 +569,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, DPRINTF(ah->ah_sc, ATH_DBG_ANI, "phyCnt1 0x%x, resetting " "counter value to 0x%x\n", - phyCnt1, - aniState->ofdmPhyErrBase); + phyCnt1, aniState->ofdmPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_MASK_1, @@ -580,8 +579,7 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, DPRINTF(ah->ah_sc, ATH_DBG_ANI, "phyCnt2 0x%x, resetting " "counter value to 0x%x\n", - phyCnt2, - aniState->cckPhyErrBase); + phyCnt2, aniState->cckPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_MASK_2, @@ -667,7 +665,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 cc = REG_READ(ah, AR_CCCNT); if (cycles == 0 || cycles > cc) { - DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, + DPRINTF(ah->ah_sc, ATH_DBG_ANI, "cycle counter wrap. ExtBusy = 0\n"); good = 0; } else { diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index ec995730632d..5b2752b43be4 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -43,7 +43,7 @@ static int ath_beaconq_config(struct ath_softc *sc) if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) { DPRINTF(sc, ATH_DBG_FATAL, - "unable to update h/w beacon queue parameters\n"); + "Unable to update h/w beacon queue parameters\n"); return 0; } else { ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); @@ -132,11 +132,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, avp = (void *)vif->drv_priv; cabq = sc->beacon.cabq; - if (avp->av_bcbuf == NULL) { - DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n", - avp, avp->av_bcbuf); + if (avp->av_bcbuf == NULL) return NULL; - } /* Release the old beacon first */ diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath9k/debug.h index 7b0e5419d2bc..23298b90b52b 100644 --- a/drivers/net/wireless/ath9k/debug.h +++ b/drivers/net/wireless/ath9k/debug.h @@ -19,20 +19,16 @@ enum ATH_DEBUG { ATH_DBG_RESET = 0x00000001, - ATH_DBG_REG_IO = 0x00000002, - ATH_DBG_QUEUE = 0x00000004, - ATH_DBG_EEPROM = 0x00000008, - ATH_DBG_CALIBRATE = 0x00000010, - ATH_DBG_CHANNEL = 0x00000020, - ATH_DBG_INTERRUPT = 0x00000040, - ATH_DBG_REGULATORY = 0x00000080, - ATH_DBG_ANI = 0x00000100, - ATH_DBG_POWER_MGMT = 0x00000200, - ATH_DBG_XMIT = 0x00000400, - ATH_DBG_BEACON = 0x00001000, - ATH_DBG_CONFIG = 0x00002000, - ATH_DBG_KEYCACHE = 0x00004000, - ATH_DBG_FATAL = 0x00008000, + ATH_DBG_QUEUE = 0x00000002, + ATH_DBG_EEPROM = 0x00000004, + ATH_DBG_CALIBRATE = 0x00000008, + ATH_DBG_INTERRUPT = 0x00000010, + ATH_DBG_REGULATORY = 0x00000020, + ATH_DBG_ANI = 0x00000040, + ATH_DBG_XMIT = 0x00000080, + ATH_DBG_BEACON = 0x00000100, + ATH_DBG_CONFIG = 0x00000200, + ATH_DBG_FATAL = 0x00000400, ATH_DBG_ANY = 0xffffffff }; diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c index ffc36b0361c7..44fee5ae8925 100644 --- a/drivers/net/wireless/ath9k/eeprom.c +++ b/drivers/net/wireless/ath9k/eeprom.c @@ -783,11 +783,11 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, ((pdadcValues[4 * j + 3] & 0xFF) << 24); REG_WRITE(ah, regOffset, reg32); - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "PDADC (%d,%4x): %4.4x %8.8x\n", i, regChainOffset, regOffset, reg32); - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "PDADC: Chain %d | " "PDADC %3d Value %3d | " "PDADC %3d Value %3d | " @@ -910,7 +910,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, ah->eep_ops->get_eeprom_rev(ah) <= 2) twiceMaxEdgePower = AR5416_MAX_RATE_POWER; - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " "EXT_ADDITIVE %d\n", ctlMode, numCtlModes, isHt40CtlMode, @@ -918,7 +918,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " "chan %d\n", @@ -941,7 +941,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, IS_CHAN_2GHZ(chan), AR5416_EEP4K_NUM_BAND_EDGES); - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, " MATCH-EE_IDX %d: ch %d is2 %d " "2xMinEdge %d chainmask %d chains %d\n", i, freq, IS_CHAN_2GHZ(chan), @@ -961,7 +961,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, " SEL-Min ctlMode %d pCtlMode %d " "2xMaxEdge %d sP %d minCtlPwr %d\n", ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, @@ -2234,11 +2234,11 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, ((pdadcValues[4 * j + 3] & 0xFF) << 24); REG_WRITE(ah, regOffset, reg32); - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "PDADC (%d,%4x): %4.4x %8.8x\n", i, regChainOffset, regOffset, reg32); - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "PDADC: Chain %d | PDADC %3d " "Value %3d | PDADC %3d Value %3d | " "PDADC %3d Value %3d | PDADC %3d " @@ -2415,14 +2415,14 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, ah->eep_ops->get_eeprom_rev(ah) <= 2) twiceMaxEdgePower = AR5416_MAX_RATE_POWER; - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " "EXT_ADDITIVE %d\n", ctlMode, numCtlModes, isHt40CtlMode, (pCtlMode[ctlMode] & EXT_ADDITIVE)); for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, " LOOP-Ctlidx %d: cfgCtl 0x%2.2x " "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " "chan %d\n", @@ -2441,7 +2441,7 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1], IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES); - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, " MATCH-EE_IDX %d: ch %d is2 %d " "2xMinEdge %d chainmask %d chains %d\n", i, freq, IS_CHAN_2GHZ(chan), @@ -2460,7 +2460,7 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, minCtlPower = min(twiceMaxEdgePower, scaledPower); - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, " SEL-Min ctlMode %d pCtlMode %d " "2xMaxEdge %d sP %d minCtlPwr %d\n", ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 22ef93f3d47c..169d8efa69dc 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -97,7 +97,7 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) udelay(AH_TIME_QUANTUM); } - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_ANY, "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", timeout, reg, REG_READ(ah, reg), mask, val); @@ -181,7 +181,7 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah, } break; default: - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Unknown phy %u (rate ix %u)\n", rates->info[rateix].phy, rateix); txTime = 0; @@ -306,7 +306,7 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) REG_WRITE(ah, addr, wrData); rdData = REG_READ(ah, addr); if (rdData != wrData) { - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "address test failed " "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", addr, wrData, rdData); @@ -318,7 +318,7 @@ static bool ath9k_hw_chip_test(struct ath_hw *ah) REG_WRITE(ah, addr, wrData); rdData = REG_READ(ah, addr); if (wrData != rdData) { - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "address test failed " "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", addr, wrData, rdData); @@ -453,8 +453,8 @@ static int ath9k_hw_rfattach(struct ath_hw *ah) rfStatus = ath9k_hw_init_rf(ah, &ecode); if (!rfStatus) { - DPRINTF(ah->ah_sc, ATH_DBG_RESET, - "RF setup failed, status %u\n", ecode); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "RF setup failed, status: %u\n", ecode); return ecode; } @@ -478,10 +478,9 @@ static int ath9k_hw_rf_claim(struct ath_hw *ah) case AR_RAD2122_SREV_MAJOR: break; default: - DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "5G Radio Chip Rev 0x%02X is not " - "supported by this driver\n", - ah->hw_version.analog5GhzRev); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "Radio Chip Rev 0x%02X not supported\n", + val & AR_RADIO_SREV_MAJOR); return -EOPNOTSUPP; } @@ -503,12 +502,8 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah) ah->macaddr[2 * i] = eeval >> 8; ah->macaddr[2 * i + 1] = eeval & 0xff; } - if (sum == 0 || sum == 0xffff * 3) { - DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "mac address read failed: %pM\n", - ah->macaddr); + if (sum == 0 || sum == 0xffff * 3) return -EADDRNOTAVAIL; - } return 0; } @@ -565,11 +560,8 @@ static int ath9k_hw_post_attach(struct ath_hw *ah) { int ecode; - if (!ath9k_hw_chip_test(ah)) { - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, - "hardware self-test failed\n"); + if (!ath9k_hw_chip_test(ah)) return -ENODEV; - } ecode = ath9k_hw_rf_claim(ah); if (ecode != 0) @@ -611,13 +603,13 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, ah->intr_mitigation = true; if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { - DPRINTF(sc, ATH_DBG_RESET, "Couldn't reset chip\n"); + DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n"); ecode = -EIO; goto bad; } if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { - DPRINTF(sc, ATH_DBG_RESET, "Couldn't wakeup chip\n"); + DPRINTF(sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n"); ecode = -EIO; goto bad; } @@ -640,7 +632,7 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) && (ah->hw_version.macVersion != AR_SREV_VERSION_9160) && (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) { - DPRINTF(sc, ATH_DBG_RESET, + DPRINTF(sc, ATH_DBG_FATAL, "Mac Chip Rev 0x%02x.%x is not supported by " "this driver\n", ah->hw_version.macVersion, ah->hw_version.macRev); @@ -680,10 +672,6 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, if (AR_SREV_9280_10_OR_LATER(ah)) ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; - DPRINTF(sc, ATH_DBG_RESET, - "This Mac Chip Rev 0x%02x.%x is \n", - ah->hw_version.macVersion, ah->hw_version.macRev); - if (AR_SREV_9285_12_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, @@ -875,8 +863,8 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, ecode = ath9k_hw_init_macaddr(ah); if (ecode != 0) { - DPRINTF(sc, ATH_DBG_RESET, - "failed initializing mac address\n"); + DPRINTF(sc, ATH_DBG_FATAL, + "Failed to initialize MAC address\n"); goto bad; } @@ -1193,23 +1181,23 @@ static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, switch (ah->hw_version.devid) { case AR9280_DEVID_PCI: if (reg == 0x7894) { - DPRINTF(ah->ah_sc, ATH_DBG_ANY, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "ini VAL: %x EEPROM: %x\n", value, (pBase->version & 0xff)); if ((pBase->version & 0xff) > 0x0a) { - DPRINTF(ah->ah_sc, ATH_DBG_ANY, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "PWDCLKIND: %d\n", pBase->pwdclkind); value &= ~AR_AN_TOP2_PWDCLKIND; value |= AR_AN_TOP2_PWDCLKIND & (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S); } else { - DPRINTF(ah->ah_sc, ATH_DBG_ANY, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "PWDCLKIND Earlier Rev\n"); } - DPRINTF(ah->ah_sc, ATH_DBG_ANY, + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "final ini VAL: %x\n", value); } break; @@ -1356,13 +1344,13 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, min((u32) MAX_RATE_POWER, (u32) ah->regulatory.power_limit)); if (status != 0) { - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, - "error init'ing transmit power\n"); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "Error initializing transmit power\n"); return -EIO; } if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "ar5416SetRfRegs failed\n"); return -EIO; } @@ -1668,7 +1656,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) { - DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Could not kill baseband RX\n"); return false; } @@ -1677,14 +1665,14 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, if (AR_SREV_9280_10_OR_LATER(ah)) { if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { - DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "failed to set channel\n"); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "Failed to set channel\n"); return false; } } else { if (!(ath9k_hw_set_channel(ah, chan))) { - DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, - "failed to set channel\n"); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "Failed to set channel\n"); return false; } } @@ -1696,7 +1684,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, min((u32) MAX_RATE_POWER, (u32) ah->regulatory.power_limit)) != 0) { DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, - "error init'ing transmit power\n"); + "Error initializing transmit power\n"); return false; } @@ -2224,7 +2212,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_mark_phy_inactive(ah); if (!ath9k_hw_chip_reset(ah, chan)) { - DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n"); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n"); return -EINVAL; } @@ -2367,8 +2355,8 @@ bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry) u32 keyType; if (entry >= ah->caps.keycache_size) { - DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "entry %u out of range\n", entry); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "keychache entry %u out of range\n", entry); return false; } @@ -2404,8 +2392,8 @@ bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) u32 macHi, macLo; if (entry >= ah->caps.keycache_size) { - DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "entry %u out of range\n", entry); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "keychache entry %u out of range\n", entry); return false; } @@ -2436,8 +2424,8 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, u32 keyType; if (entry >= pCap->keycache_size) { - DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, - "entry %u out of range\n", entry); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "keycache entry %u out of range\n", entry); return false; } @@ -2447,7 +2435,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, break; case ATH9K_CIPHER_AES_CCM: if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { - DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, + DPRINTF(ah->ah_sc, ATH_DBG_ANY, "AES-CCM not supported by mac rev 0x%x\n", ah->hw_version.macRev); return false; @@ -2458,14 +2446,14 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, keyType = AR_KEYTABLE_TYPE_TKIP; if (ATH9K_IS_MIC_ENABLED(ah) && entry + 64 >= pCap->keycache_size) { - DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, + DPRINTF(ah->ah_sc, ATH_DBG_ANY, "entry %u inappropriate for TKIP\n", entry); return false; } break; case ATH9K_CIPHER_WEP: if (k->kv_len < LEN_WEP40) { - DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, + DPRINTF(ah->ah_sc, ATH_DBG_ANY, "WEP key length %u too small\n", k->kv_len); return false; } @@ -2480,7 +2468,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, keyType = AR_KEYTABLE_TYPE_CLR; break; default: - DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "cipher %u not supported\n", k->kv_type); return false; } @@ -2698,7 +2686,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) AR_RTC_FORCE_WAKE_EN); } if (i == 0) { - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Failed to wakeup in %uus\n", POWER_UP_TIME / 20); return false; } @@ -2719,9 +2707,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) "UNDEFINED" }; - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n", - modes[ah->power_mode], modes[mode], - setChip ? "set chip " : ""); + DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n", + modes[ah->power_mode], modes[mode]); switch (mode) { case ATH9K_PM_AWAKE: @@ -2735,7 +2722,7 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) ath9k_set_power_network_sleep(ah, setChip); break; default: - DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Unknown power mode %u\n", mode); return false; } diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c index e0a6dee45839..8ae4ec21667b 100644 --- a/drivers/net/wireless/ath9k/mac.c +++ b/drivers/net/wireless/ath9k/mac.c @@ -49,7 +49,7 @@ bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp) bool ath9k_hw_txstart(struct ath_hw *ah, u32 q) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q); REG_WRITE(ah, AR_Q_TXE, 1 << q); @@ -110,13 +110,15 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; if (q >= pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, " + "invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, " + "inactive queue: %u\n", q); return false; } @@ -146,7 +148,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) break; DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, - "TSF have moved while trying to set " + "TSF has moved while trying to set " "quiet time TSF: 0x%08x\n", tsfLow); } @@ -158,8 +160,8 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) wait = wait_time; while (ath9k_hw_numtxpending(ah, q)) { if ((--wait) == 0) { - DPRINTF(ah->ah_sc, ATH_DBG_XMIT, - "Failed to stop Tx DMA in 100 " + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, + "Failed to stop TX DMA in 100 " "msec after killing last frame\n"); break; } @@ -454,17 +456,19 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, struct ath9k_tx_queue_info *qi; if (q >= pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, " + "invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, " + "inactive queue: %u\n", q); return false; } - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %p\n", qi); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q); qi->tqi_ver = qinfo->tqi_ver; qi->tqi_subtype = qinfo->tqi_subtype; @@ -521,13 +525,15 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, struct ath9k_tx_queue_info *qi; if (q >= pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, " + "invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n"); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, " + "inactive queue: %u\n", q); return false; } @@ -575,22 +581,23 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, ATH9K_TX_QUEUE_INACTIVE) break; if (q == pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, - "no available tx queue\n"); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "No available TX queue\n"); return -1; } break; default: - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "bad tx queue type %u\n", type); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid TX queue type: %u\n", + type); return -1; } - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q); qi = &ah->txq[q]; if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, - "tx queue %u already active\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "TX queue: %u already active\n", q); return -1; } memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); @@ -620,16 +627,18 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) struct ath9k_tx_queue_info *qi; if (q >= pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, " + "invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, " + "inactive queue: %u\n", q); return false; } - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TX queue: %u\n", q); qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; ah->txok_interrupt_mask &= ~(1 << q); @@ -650,17 +659,19 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) u32 cwMin, chanCwMin, value; if (q >= pCap->total_queues) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, " + "invalid queue: %u\n", q); return false; } qi = &ah->txq[q]; if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, " + "inactive queue: %u\n", q); return true; } - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "reset queue %u\n", q); + DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q); if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { if (chan && IS_CHAN_B(chan)) @@ -894,7 +905,7 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set) reg = REG_READ(ah, AR_OBS_BUS_1); DPRINTF(ah->ah_sc, ATH_DBG_FATAL, - "rx failed to go idle in 10 ms RXSM=0x%x\n", reg); + "RX failed to go idle in 10 ms RXSM=0x%x\n", reg); return false; } @@ -949,8 +960,8 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah) } if (i == 0) { - DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, - "dma failed to stop in %d ms " + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "DMA failed to stop in %d ms " "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", AH_RX_STOP_DMA_TIMEOUT / 1000, REG_READ(ah, AR_CR), diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 74fe777b54e4..1b43cb41363c 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -674,7 +674,7 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key, memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) { /* TX MIC entry failed. No need to proceed further */ - DPRINTF(sc, ATH_DBG_KEYCACHE, + DPRINTF(sc, ATH_DBG_FATAL, "Setting TX MIC Key Failed\n"); return 0; } @@ -1400,7 +1400,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) /* Get the hardware key cache size. */ sc->keymax = ah->caps.keycache_size; if (sc->keymax > ATH_KEYMAX) { - DPRINTF(sc, ATH_DBG_KEYCACHE, + DPRINTF(sc, ATH_DBG_ANY, "Warning, using only %u entries in %u key cache\n", ATH_KEYMAX, sc->keymax); sc->keymax = ATH_KEYMAX; @@ -2602,7 +2602,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); - DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n"); + DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n"); switch (cmd) { case SET_KEY: diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c index 8bcba906929a..5ec9ce91d979 100644 --- a/drivers/net/wireless/ath9k/phy.c +++ b/drivers/net/wireless/ath9k/phy.c @@ -46,7 +46,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) channelSel = ((freq - 704) * 2 - 3040) / 10; bModeSynth = 1; } else { - DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid channel %u MHz\n", freq); return false; } @@ -79,7 +79,7 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8); aModeRefSel = ath9k_hw_reverse_bits(1, 2); } else { - DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid channel %u MHz\n", freq); return false; } diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h index 0f7f8e0c9c95..296d0e985f25 100644 --- a/drivers/net/wireless/ath9k/phy.h +++ b/drivers/net/wireless/ath9k/phy.h @@ -556,9 +556,6 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, int r; \ for (r = 0; r < ((iniarray)->ia_rows); r++) { \ REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \ - DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, \ - "RF 0x%x V 0x%x\n", \ - INI_RA((iniarray), r, 0), (regData)[r]); \ DO_DELAY(regWr); \ } \ } while (0) diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index dd1f30156740..efa57ae8901c 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -320,7 +320,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; - DPRINTF(sc, ATH_DBG_CONFIG, + DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error() on RX init\n"); error = -ENOMEM; break; @@ -675,7 +675,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) bf->bf_buf_addr))) { dev_kfree_skb_any(requeue_skb); bf->bf_mpdu = NULL; - DPRINTF(sc, ATH_DBG_CONFIG, + DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error() on RX\n"); break; } -- GitLab From eef7a57430c83b0419ba943bb1650ed5c349d454 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:28 +0530 Subject: [PATCH 0518/6080] ath9k: Change return value of ath9k_hw_fill_cap_info This routine always return true, checking for false in the return value is invalid. Fix this. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/hw.c | 10 ++-------- drivers/net/wireless/ath9k/hw.h | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 169d8efa69dc..4ad1508e4752 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -837,11 +837,7 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, if (AR_SREV_9280_20(ah)) ath9k_hw_init_txgain_ini(ah); - if (!ath9k_hw_fill_cap_info(ah)) { - DPRINTF(sc, ATH_DBG_RESET, "failed ath9k_hw_fill_cap_info\n"); - ecode = -EINVAL; - goto bad; - } + ath9k_hw_fill_cap_info(ah); if ((ah->hw_version.devid == AR9280_DEVID_PCI) && test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) { @@ -3228,7 +3224,7 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, /* HW Capabilities */ /*******************/ -bool ath9k_hw_fill_cap_info(struct ath_hw *ah) +void ath9k_hw_fill_cap_info(struct ath_hw *ah) { struct ath9k_hw_capabilities *pCap = &ah->caps; u16 capField = 0, eeval; @@ -3403,8 +3399,6 @@ bool ath9k_hw_fill_cap_info(struct ath_hw *ah) ah->btactive_gpio = 6; ah->wlanactive_gpio = 5; } - - return true; } bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h index 5ba6a4b60356..c50faae22c59 100644 --- a/drivers/net/wireless/ath9k/hw.h +++ b/drivers/net/wireless/ath9k/hw.h @@ -557,7 +557,7 @@ struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error); void ath9k_hw_rfdetach(struct ath_hw *ah); int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, bool bChannelChange); -bool ath9k_hw_fill_cap_info(struct ath_hw *ah); +void ath9k_hw_fill_cap_info(struct ath_hw *ah); bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, u32 capability, u32 *result); bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, -- GitLab From 0ef1f168b6bc82b0b157c568e764b75961867970 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:35 +0530 Subject: [PATCH 0519/6080] ath9k: Remove redundant variable for Interrupt Mitigation The state is already stored in ath9k_ops_config, so remove the duplicate variable in ath_hw. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/hw.c | 14 +++++--------- drivers/net/wireless/ath9k/hw.h | 3 +-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 4ad1508e4752..bb208f51b561 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -380,7 +380,7 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah) ah->config.spurchans[i][1] = AR_NO_SPUR; } - ah->config.intr_mitigation = 1; + ah->config.intr_mitigation = true; /* * We need this for PCI devices only (Cardbus, PCI, miniPCI) @@ -599,9 +599,6 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, ath9k_hw_set_defaults(ah); - if (ah->config.intr_mitigation != 0) - ah->intr_mitigation = true; - if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n"); ecode = -EIO; @@ -1028,7 +1025,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, AR_IMR_RXORN | AR_IMR_BCNMISC; - if (ah->intr_mitigation) + if (ah->config.intr_mitigation) ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; else ah->mask_reg |= AR_IMR_RXOK; @@ -2301,8 +2298,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REG_WRITE(ah, AR_OBS, 8); - if (ah->intr_mitigation) { - + if (ah->config.intr_mitigation) { REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); } @@ -2908,7 +2904,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) *masked = isr & ATH9K_INT_COMMON; - if (ah->intr_mitigation) { + if (ah->config.intr_mitigation) { if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) *masked |= ATH9K_INT_RX; } @@ -3026,7 +3022,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) } if (ints & ATH9K_INT_RX) { mask |= AR_IMR_RXERR; - if (ah->intr_mitigation) + if (ah->config.intr_mitigation) mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; else mask |= AR_IMR_RXOK | AR_IMR_RXDESC; diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h index c50faae22c59..5a1128ddb464 100644 --- a/drivers/net/wireless/ath9k/hw.h +++ b/drivers/net/wireless/ath9k/hw.h @@ -190,7 +190,7 @@ struct ath9k_ops_config { u16 diversity_control; u16 antenna_switch_swap; int serialize_regmode; - int intr_mitigation; + bool intr_mitigation; #define SPUR_DISABLE 0 #define SPUR_ENABLE_IOCTL 1 #define SPUR_ENABLE_EEPROM 2 @@ -524,7 +524,6 @@ struct ath_hw { enum ath9k_ani_cmd ani_function; u32 intr_txqs; - bool intr_mitigation; enum ath9k_ht_extprotspacing extprotspacing; u8 txchainmask; u8 rxchainmask; -- GitLab From a22be22ab8fe571cce88d0d30b49f297a563c4a7 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:36 +0530 Subject: [PATCH 0520/6080] ath9k: Avoid unneeded casts Change the void pointer to struct sk_buff and access bf_mpdu directly, removing all casts in the process. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath9k/beacon.c | 10 +++++----- drivers/net/wireless/ath9k/xmit.c | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 1dfc3816a2d8..9adc991cb05f 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -130,7 +130,7 @@ struct ath_buf { struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or an aggregate) */ struct ath_buf *bf_next; /* next subframe in the aggregate */ - void *bf_mpdu; /* enclosing frame structure */ + struct sk_buff *bf_mpdu; /* enclosing frame structure */ struct ath_desc *bf_desc; /* virtual addr of desc */ dma_addr_t bf_daddr; /* physical addr of desc */ dma_addr_t bf_buf_addr; /* physical addr of data buffer */ diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index 5b2752b43be4..eb4759fc6a0d 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -59,7 +59,7 @@ static int ath_beaconq_config(struct ath_softc *sc) static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, struct ath_buf *bf) { - struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; + struct sk_buff *skb = bf->bf_mpdu; struct ath_hw *ah = sc->sc_ah; struct ath_desc *ds; struct ath9k_11n_rate_series series[4]; @@ -138,7 +138,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, /* Release the old beacon first */ bf = avp->av_bcbuf; - skb = (struct sk_buff *)bf->bf_mpdu; + skb = bf->bf_mpdu; if (skb) { dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); @@ -226,7 +226,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, return; bf = avp->av_bcbuf; - skb = (struct sk_buff *) bf->bf_mpdu; + skb = bf->bf_mpdu; ath_beacon_setup(sc, avp, bf); @@ -299,7 +299,7 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) /* release the previous beacon frame, if it already exists. */ bf = avp->av_bcbuf; if (bf->bf_mpdu != NULL) { - skb = (struct sk_buff *)bf->bf_mpdu; + skb = bf->bf_mpdu; dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); @@ -371,7 +371,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) bf = avp->av_bcbuf; if (bf->bf_mpdu != NULL) { - struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; + struct sk_buff *skb = bf->bf_mpdu; dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 689bdbf78808..87bbeaa6432f 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -283,7 +283,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; bool rc_update = true; - skb = (struct sk_buff *)bf->bf_mpdu; + skb = bf->bf_mpdu; hdr = (struct ieee80211_hdr *)skb->data; rcu_read_lock(); @@ -444,7 +444,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, u16 aggr_limit, legacy = 0, maxampdu; int i; - skb = (struct sk_buff *)bf->bf_mpdu; + skb = bf->bf_mpdu; tx_info = IEEE80211_SKB_CB(skb); rates = tx_info->control.rates; tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0]; @@ -1452,7 +1452,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); - skb = (struct sk_buff *)bf->bf_mpdu; + skb = bf->bf_mpdu; tx_info = IEEE80211_SKB_CB(skb); rates = tx_info->control.rates; hdr = (struct ieee80211_hdr *)skb->data; @@ -1586,7 +1586,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_control *txctl) { - struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; + struct sk_buff *skb = bf->bf_mpdu; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ath_node *an = NULL; @@ -1860,7 +1860,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad, int txok, bool update_rc) { - struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; + struct sk_buff *skb = bf->bf_mpdu; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); -- GitLab From a119cc492fc720de7fcaf7c1b9394d6c025d276d Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:38 +0530 Subject: [PATCH 0521/6080] ath9k: Cleanup buffer status handling Using a u32 to store a single flag is overkill. Use a bool to store whether the buffer is stale or not. Also, use u8 instead of u32 to store the buffer type. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 13 +++++++------ drivers/net/wireless/ath9k/xmit.c | 9 ++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 9adc991cb05f..e6c39c1c1a28 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -74,13 +74,17 @@ struct ath_config { /*************************/ #define ATH_TXBUF_RESET(_bf) do { \ - (_bf)->bf_status = 0; \ + (_bf)->bf_stale = false; \ (_bf)->bf_lastbf = NULL; \ (_bf)->bf_next = NULL; \ memset(&((_bf)->bf_state), 0, \ sizeof(struct ath_buf_state)); \ } while (0) +#define ATH_RXBUF_RESET(_bf) do { \ + (_bf)->bf_stale = false; \ + } while (0) + /** * enum buffer_type - Buffer type flags * @@ -106,7 +110,7 @@ struct ath_buf_state { int bfs_seqno; int bfs_tidno; int bfs_retries; - u32 bf_type; + u8 bf_type; u32 bfs_keyix; enum ath9k_key_type bfs_keytype; }; @@ -134,15 +138,12 @@ struct ath_buf { struct ath_desc *bf_desc; /* virtual addr of desc */ dma_addr_t bf_daddr; /* physical addr of desc */ dma_addr_t bf_buf_addr; /* physical addr of data buffer */ - u32 bf_status; + bool bf_stale; u16 bf_flags; struct ath_buf_state bf_state; dma_addr_t bf_dmacontext; }; -#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0) -#define ATH_BUFSTATUS_STALE 0x00000002 - struct ath_descdma { const char *dd_name; struct ath_desc *dd_desc; diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 87bbeaa6432f..735256faa0b2 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -380,8 +380,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar); } else { /* retry the un-acked ones */ - if (bf->bf_next == NULL && - bf_last->bf_status & ATH_BUFSTATUS_STALE) { + if (bf->bf_next == NULL && bf_last->bf_stale) { struct ath_buf *tbf; tbf = ath_clone_txbuf(sc, bf_last); @@ -1004,7 +1003,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) bf = list_first_entry(&txq->axq_q, struct ath_buf, list); - if (bf->bf_status & ATH_BUFSTATUS_STALE) { + if (bf->bf_stale) { list_del(&bf->list); spin_unlock_bh(&txq->axq_lock); @@ -1941,7 +1940,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) * it with the STALE flag. */ bf_held = NULL; - if (bf->bf_status & ATH_BUFSTATUS_STALE) { + if (bf->bf_stale) { bf_held = bf; if (list_is_last(&bf_held->list, &txq->axq_q)) { txq->axq_link = NULL; @@ -1982,7 +1981,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) * however leave the last descriptor back as the holding * descriptor for hw. */ - lastbf->bf_status |= ATH_BUFSTATUS_STALE; + lastbf->bf_stale = true; INIT_LIST_HEAD(&bf_head); if (!list_is_singular(&lastbf->list)) list_cut_position(&bf_head, -- GitLab From ae459af12816b507aed3fcb2b9fc933c212ea12e Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:40 +0530 Subject: [PATCH 0522/6080] ath9k: Remove a couple of unused variables in descriptor handling Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 2 -- drivers/net/wireless/ath9k/main.c | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index e6c39c1c1a28..dc42ad129b23 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -145,12 +145,10 @@ struct ath_buf { }; struct ath_descdma { - const char *dd_name; struct ath_desc *dd_desc; dma_addr_t dd_desc_paddr; u32 dd_desc_len; struct ath_buf *dd_bufptr; - dma_addr_t dd_dmacontext; }; int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 1b43cb41363c..f5a541b864ce 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1789,7 +1789,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, goto fail; } - dd->dd_name = name; dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; /* @@ -1819,7 +1818,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, } ds = dd->dd_desc; DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", - dd->dd_name, ds, (u32) dd->dd_desc_len, + name, ds, (u32) dd->dd_desc_len, ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); /* allocate buffers */ -- GitLab From 5cc93992cc4cf12ddfe63c8a5be2d509e6678e99 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:41 +0530 Subject: [PATCH 0523/6080] ath9k: Remove unused structures struct aggr_rifs_param and ath_tx_stat are not used anywhere. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index dc42ad129b23..9a12f76988da 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -294,26 +294,6 @@ struct ath_tx_control { #define ATH_TX_XRETRY 0x02 #define ATH_TX_BAR 0x04 -/* All RSSI values are noise floor adjusted */ -struct ath_tx_stat { - int rssi; - int rssictl[ATH_MAX_ANTENNA]; - int rssiextn[ATH_MAX_ANTENNA]; - int rateieee; - int rateKbps; - int ratecode; - int flags; - u32 airtime; /* time on air per final tx rate */ -}; - -struct aggr_rifs_param { - int param_max_frames; - int param_max_len; - int param_rl; - int param_al; - struct ath_rc_series *param_rcs; -}; - struct ath_node { struct ath_softc *an_sc; struct ath_atx_tid tid[WME_NUM_TID]; -- GitLab From 7dd58748592db1e5a77cfbddb8beffcfdb0242fe Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:42 +0530 Subject: [PATCH 0524/6080] ath9k: Check for root debugfs file Creation of the root debugfs file could have failed for some reason, check properly before proceeding in this case. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/debug.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c index fdf9528fa49b..97df20cbf528 100644 --- a/drivers/net/wireless/ath9k/debug.c +++ b/drivers/net/wireless/ath9k/debug.c @@ -498,6 +498,9 @@ int ath9k_init_debug(struct ath_softc *sc) { sc->debug.debug_mask = ath9k_debug; + if (!ath9k_debugfs_root) + return -ENOENT; + sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), ath9k_debugfs_root); if (!sc->debug.debugfs_phy) -- GitLab From 4658b985170d9d0c88304d2d4459938b600f8c0b Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:43 +0530 Subject: [PATCH 0525/6080] ath9k: Remove TIM from the interrupt mask We never handle TIM, TIM_TIMER is used instead. Remove this and the unnecessary swBeaconProcess variable. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 1 - drivers/net/wireless/ath9k/main.c | 14 -------------- 2 files changed, 15 deletions(-) diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 9a12f76988da..0ef89bb73f31 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -66,7 +66,6 @@ struct ath_config { u32 ath_aggr_prot; u16 txpowlimit; u8 cabqReadytime; - u8 swBeaconProcess; }; /*************************/ diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index f5a541b864ce..0c1cc2d62a80 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1542,9 +1542,6 @@ static int ath_init(u16 devid, struct ath_softc *sc) sc->beacon.bslot_aphy[i] = NULL; } - /* save MISC configurations */ - sc->config.swBeaconProcess = 1; - /* setup channels and rates */ sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; @@ -2253,17 +2250,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, sc->imask |= ATH9K_INT_TSFOOR; } - /* - * Some hardware processes the TIM IE and fires an - * interrupt when the TIM bit is set. For hardware - * that does, if not overridden by configuration, - * enable the TIM interrupt when operating as station. - */ - if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) && - (conf->type == NL80211_IFTYPE_STATION) && - !sc->config.swBeaconProcess) - sc->imask |= ATH9K_INT_TIM; - ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); if (conf->type == NL80211_IFTYPE_AP) { -- GitLab From 797fe5cbefdb91f796502677e3a6623262eb9fcd Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:45 +0530 Subject: [PATCH 0526/6080] ath9k: Remove the useless do..while loops These are unnecessary constructs in a function. This patch removes these from both RX and TX init routines. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath9k/recv.c | 83 ++++++++++++++---------------- drivers/net/wireless/ath9k/xmit.c | 40 ++++++-------- 3 files changed, 57 insertions(+), 68 deletions(-) diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h index 0ef89bb73f31..c92d46fa9d51 100644 --- a/drivers/net/wireless/ath9k/ath9k.h +++ b/drivers/net/wireless/ath9k/ath9k.h @@ -340,7 +340,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); int ath_tx_init(struct ath_softc *sc, int nbufs); -int ath_tx_cleanup(struct ath_softc *sc); +void ath_tx_cleanup(struct ath_softc *sc); struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb); int ath_txq_update(struct ath_softc *sc, int qnum, struct ath9k_tx_queue_info *q); diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index efa57ae8901c..b46badd21f73 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -283,54 +283,51 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) struct ath_buf *bf; int error = 0; - do { - spin_lock_init(&sc->rx.rxflushlock); - sc->sc_flags &= ~SC_OP_RXFLUSH; - spin_lock_init(&sc->rx.rxbuflock); - - sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN, - min(sc->cachelsz, - (u16)64)); + spin_lock_init(&sc->rx.rxflushlock); + sc->sc_flags &= ~SC_OP_RXFLUSH; + spin_lock_init(&sc->rx.rxbuflock); - DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", - sc->cachelsz, sc->rx.bufsize); + sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN, + min(sc->cachelsz, (u16)64)); - /* Initialize rx descriptors */ + DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", + sc->cachelsz, sc->rx.bufsize); - error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, - "rx", nbufs, 1); - if (error != 0) { - DPRINTF(sc, ATH_DBG_FATAL, - "failed to allocate rx descriptors: %d\n", error); - break; - } + /* Initialize rx descriptors */ - list_for_each_entry(bf, &sc->rx.rxbuf, list) { - skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL); - if (skb == NULL) { - error = -ENOMEM; - break; - } + error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, + "rx", nbufs, 1); + if (error != 0) { + DPRINTF(sc, ATH_DBG_FATAL, + "failed to allocate rx descriptors: %d\n", error); + goto err; + } - bf->bf_mpdu = skb; - bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, - sc->rx.bufsize, - DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(sc->dev, - bf->bf_buf_addr))) { - dev_kfree_skb_any(skb); - bf->bf_mpdu = NULL; - DPRINTF(sc, ATH_DBG_FATAL, - "dma_mapping_error() on RX init\n"); - error = -ENOMEM; - break; - } - bf->bf_dmacontext = bf->bf_buf_addr; + list_for_each_entry(bf, &sc->rx.rxbuf, list) { + skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL); + if (skb == NULL) { + error = -ENOMEM; + goto err; } - sc->rx.rxlink = NULL; - } while (0); + bf->bf_mpdu = skb; + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, + sc->rx.bufsize, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(sc->dev, + bf->bf_buf_addr))) { + dev_kfree_skb_any(skb); + bf->bf_mpdu = NULL; + DPRINTF(sc, ATH_DBG_FATAL, + "dma_mapping_error() on RX init\n"); + error = -ENOMEM; + goto err; + } + bf->bf_dmacontext = bf->bf_buf_addr; + } + sc->rx.rxlink = NULL; +err: if (error) ath_rx_cleanup(sc); @@ -345,10 +342,8 @@ void ath_rx_cleanup(struct ath_softc *sc) list_for_each_entry(bf, &sc->rx.rxbuf, list) { skb = bf->bf_mpdu; if (skb) { - dma_unmap_single(sc->dev, - bf->bf_buf_addr, - sc->rx.bufsize, - DMA_FROM_DEVICE); + dma_unmap_single(sc->dev, bf->bf_buf_addr, + sc->rx.bufsize, DMA_FROM_DEVICE); dev_kfree_skb(skb); } } diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 735256faa0b2..628b780d8844 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -2047,44 +2047,38 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) { int error = 0; - do { - spin_lock_init(&sc->tx.txbuflock); + spin_lock_init(&sc->tx.txbuflock); - error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, - "tx", nbufs, 1); - if (error != 0) { - DPRINTF(sc, ATH_DBG_FATAL, - "Failed to allocate tx descriptors: %d\n", - error); - break; - } - - error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, - "beacon", ATH_BCBUF, 1); - if (error != 0) { - DPRINTF(sc, ATH_DBG_FATAL, - "Failed to allocate beacon descriptors: %d\n", - error); - break; - } + error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, + "tx", nbufs, 1); + if (error != 0) { + DPRINTF(sc, ATH_DBG_FATAL, + "Failed to allocate tx descriptors: %d\n", error); + goto err; + } - } while (0); + error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, + "beacon", ATH_BCBUF, 1); + if (error != 0) { + DPRINTF(sc, ATH_DBG_FATAL, + "Failed to allocate beacon descriptors: %d\n", error); + goto err; + } +err: if (error != 0) ath_tx_cleanup(sc); return error; } -int ath_tx_cleanup(struct ath_softc *sc) +void ath_tx_cleanup(struct ath_softc *sc) { if (sc->beacon.bdma.dd_desc_len != 0) ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf); if (sc->tx.txdma.dd_desc_len != 0) ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); - - return 0; } void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) -- GitLab From 1ffb0610be915650cff44c69dc6728215eae08c0 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:46 +0530 Subject: [PATCH 0527/6080] ath9k: Initialize values when setting up the queue parameters Also fix a small typo. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 0c1cc2d62a80..0917def0e081 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -922,7 +922,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); } else { - DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n"); + DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); sc->curaid = 0; } } @@ -2036,8 +2036,7 @@ static int ath9k_start(struct ieee80211_hw *hw) * here except setup the interrupt mask. */ if (ath_startrecv(sc) != 0) { - DPRINTF(sc, ATH_DBG_FATAL, - "Unable to start recv logic\n"); + DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n"); r = -EIO; goto mutex_unlock; } @@ -2551,6 +2550,8 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, mutex_lock(&sc->mutex); + memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); + qi.tqi_aifs = params->aifs; qi.tqi_cwmin = params->cw_min; qi.tqi_cwmax = params->cw_max; -- GitLab From 87792efc7d20a21844eb7f4247e7b9027e783ec0 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:48 +0530 Subject: [PATCH 0528/6080] ath9k: Trivial fix to handle AMPDU params properly Handle aggregation params only when aggregation is supported. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 0917def0e081..99a6852871e2 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -434,12 +434,12 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta) an = (struct ath_node *)sta->drv_priv; - if (sc->sc_flags & SC_OP_TXAGGR) + if (sc->sc_flags & SC_OP_TXAGGR) { ath_tx_node_init(sc, an); - - an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + - sta->ht_cap.ampdu_factor); - an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); + an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + + sta->ht_cap.ampdu_factor); + an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); + } } static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) -- GitLab From 063d8be37d6f5818976a1185db4af55c5a5ae809 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:49 +0530 Subject: [PATCH 0529/6080] ath9k: Clean Interrupt handling routine This patch cleans up the ISR, removing a unnecessary do..while loop, and waking up the chip before getting the pending interrupts. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/main.c | 197 ++++++++++++++---------------- 1 file changed, 95 insertions(+), 102 deletions(-) diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 99a6852871e2..76c58cc74b27 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -456,133 +456,124 @@ static void ath9k_tasklet(unsigned long data) u32 status = sc->intrstatus; if (status & ATH9K_INT_FATAL) { - /* need a chip reset */ ath_reset(sc, false); return; - } else { + } - if (status & - (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { - spin_lock_bh(&sc->rx.rxflushlock); - ath_rx_tasklet(sc, 0); - spin_unlock_bh(&sc->rx.rxflushlock); - } - /* XXX: optimize this */ - if (status & ATH9K_INT_TX) - ath_tx_tasklet(sc); + if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { + spin_lock_bh(&sc->rx.rxflushlock); + ath_rx_tasklet(sc, 0); + spin_unlock_bh(&sc->rx.rxflushlock); } + if (status & ATH9K_INT_TX) + ath_tx_tasklet(sc); + /* re-enable hardware interrupt */ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); } irqreturn_t ath_isr(int irq, void *dev) { +#define SCHED_INTR ( \ + ATH9K_INT_FATAL | \ + ATH9K_INT_RXORN | \ + ATH9K_INT_RXEOL | \ + ATH9K_INT_RX | \ + ATH9K_INT_TX | \ + ATH9K_INT_BMISS | \ + ATH9K_INT_CST | \ + ATH9K_INT_TSFOOR) + struct ath_softc *sc = dev; struct ath_hw *ah = sc->sc_ah; enum ath9k_int status; bool sched = false; - do { - if (sc->sc_flags & SC_OP_INVALID) { - /* - * The hardware is not ready/present, don't - * touch anything. Note this can happen early - * on if the IRQ is shared. - */ - return IRQ_NONE; - } - if (!ath9k_hw_intrpend(ah)) { /* shared irq, not for us */ - return IRQ_NONE; - } + /* + * The hardware is not ready/present, don't + * touch anything. Note this can happen early + * on if the IRQ is shared. + */ + if (sc->sc_flags & SC_OP_INVALID) + return IRQ_NONE; - /* - * Figure out the reason(s) for the interrupt. Note - * that the hal returns a pseudo-ISR that may include - * bits we haven't explicitly enabled so we mask the - * value to insure we only process bits we requested. - */ - ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ + ath9k_ps_wakeup(sc); - status &= sc->imask; /* discard unasked-for bits */ + /* shared irq, not for us */ + + if (!ath9k_hw_intrpend(ah)) { + ath9k_ps_restore(sc); + return IRQ_NONE; + } + + /* + * Figure out the reason(s) for the interrupt. Note + * that the hal returns a pseudo-ISR that may include + * bits we haven't explicitly enabled so we mask the + * value to insure we only process bits we requested. + */ + ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ + status &= sc->imask; /* discard unasked-for bits */ + + /* + * If there are no status bits set, then this interrupt was not + * for me (should have been caught above). + */ + if (!status) { + ath9k_ps_restore(sc); + return IRQ_NONE; + } + /* Cache the status */ + sc->intrstatus = status; + + if (status & SCHED_INTR) + sched = true; + + /* + * If a FATAL or RXORN interrupt is received, we have to reset the + * chip immediately. + */ + if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN)) + goto chip_reset; + + if (status & ATH9K_INT_SWBA) + tasklet_schedule(&sc->bcon_tasklet); + + if (status & ATH9K_INT_TXURN) + ath9k_hw_updatetxtriglevel(ah, true); + + if (status & ATH9K_INT_MIB) { /* - * If there are no status bits set, then this interrupt was not - * for me (should have been caught above). + * Disable interrupts until we service the MIB + * interrupt; otherwise it will continue to + * fire. */ - if (!status) - return IRQ_NONE; - - sc->intrstatus = status; - ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(ah, 0); + /* + * Let the hal handle the event. We assume + * it will clear whatever condition caused + * the interrupt. + */ + ath9k_hw_procmibevent(ah, &sc->nodestats); + ath9k_hw_set_interrupts(ah, sc->imask); + } - if (status & ATH9K_INT_FATAL) { - /* need a chip reset */ - sched = true; - } else if (status & ATH9K_INT_RXORN) { - /* need a chip reset */ + if (status & ATH9K_INT_TIM_TIMER) { + if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { + /* Clear RxAbort bit so that we can + * receive frames */ + ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); + ath9k_hw_setrxabort(ah, 0); sched = true; - } else { - if (status & ATH9K_INT_SWBA) { - /* schedule a tasklet for beacon handling */ - tasklet_schedule(&sc->bcon_tasklet); - } - if (status & ATH9K_INT_RXEOL) { - /* - * NB: the hardware should re-read the link when - * RXE bit is written, but it doesn't work - * at least on older hardware revs. - */ - sched = true; - } - - if (status & ATH9K_INT_TXURN) - /* bump tx trigger level */ - ath9k_hw_updatetxtriglevel(ah, true); - /* XXX: optimize this */ - if (status & ATH9K_INT_RX) - sched = true; - if (status & ATH9K_INT_TX) - sched = true; - if (status & ATH9K_INT_BMISS) - sched = true; - /* carrier sense timeout */ - if (status & ATH9K_INT_CST) - sched = true; - if (status & ATH9K_INT_MIB) { - /* - * Disable interrupts until we service the MIB - * interrupt; otherwise it will continue to - * fire. - */ - ath9k_hw_set_interrupts(ah, 0); - /* - * Let the hal handle the event. We assume - * it will clear whatever condition caused - * the interrupt. - */ - ath9k_hw_procmibevent(ah, &sc->nodestats); - ath9k_hw_set_interrupts(ah, sc->imask); - } - if (status & ATH9K_INT_TIM_TIMER) { - if (!(ah->caps.hw_caps & - ATH9K_HW_CAP_AUTOSLEEP)) { - /* Clear RxAbort bit so that we can - * receive frames */ - ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); - ath9k_hw_setrxabort(ah, 0); - sched = true; - sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; - } - } - if (status & ATH9K_INT_TSFOOR) { - /* FIXME: Handle this interrupt for power save */ - sched = true; - } + sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; } - ath9k_ps_restore(sc); - } while (0); + } +chip_reset: + + ath9k_ps_restore(sc); ath_debug_stat_interrupt(sc, status); if (sched) { @@ -592,6 +583,8 @@ irqreturn_t ath_isr(int irq, void *dev) } return IRQ_HANDLED; + +#undef SCHED_INTR } static u32 ath_get_extchanmode(struct ath_softc *sc, -- GitLab From c6483cfe7147534719197c03a99848f49e004308 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:56 +0530 Subject: [PATCH 0530/6080] ath9k: Determine number of streams from HT capabilities The number of streams supported by a STA can be determined directly from the HT capabilities. Remove the redundant variable storing the stream cap. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/rc.c | 18 ++++++++---------- drivers/net/wireless/ath9k/rc.h | 2 -- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 824ccbb8b7b8..a6933ccab483 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -524,7 +524,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, u32 valid; for (i = 0; i < rate_table->rate_cnt; i++) { - valid = (ath_rc_priv->single_stream ? + valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? rate_table->info[i].valid_single_stream : rate_table->info[i].valid); if (valid == 1) { @@ -557,9 +557,9 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, for (i = 0; i < rateset->rs_nrates; i++) { for (j = 0; j < rate_table->rate_cnt; j++) { u32 phy = rate_table->info[j].phy; - u32 valid = (ath_rc_priv->single_stream ? - rate_table->info[j].valid_single_stream : - rate_table->info[j].valid); + u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? + rate_table->info[j].valid_single_stream : + rate_table->info[j].valid); u8 rate = rateset->rs_rates[i]; u8 dot11rate = rate_table->info[j].dot11rate; @@ -603,7 +603,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, for (i = 0; i < rateset->rs_nrates; i++) { for (j = 0; j < rate_table->rate_cnt; j++) { u32 phy = rate_table->info[j].phy; - u32 valid = (ath_rc_priv->single_stream ? + u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? rate_table->info[j].valid_single_stream : rate_table->info[j].valid); u8 rate = rateset->rs_rates[i]; @@ -740,9 +740,10 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc, if (rate > (ath_rc_priv->rate_table_size - 1)) rate = ath_rc_priv->rate_table_size - 1; - ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) || + ASSERT((rate_table->info[rate].valid && + (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) || (rate_table->info[rate].valid_single_stream && - ath_rc_priv->single_stream)); + !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))); return rate; } @@ -1422,9 +1423,6 @@ static void ath_rc_init(struct ath_softc *sc, } ath_rc_priv->rc_phy_mode = ath_rc_priv->ht_cap & WLAN_RC_40_FLAG; - /* Set stream capability */ - ath_rc_priv->single_stream = (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1; - if (!rateset->rs_nrates) { /* No working rate, just initialize valid rates */ hi = ath_rc_init_validrates(ath_rc_priv, rate_table, diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h index ec72dd29da00..bdfd2052077c 100644 --- a/drivers/net/wireless/ath9k/rc.h +++ b/drivers/net/wireless/ath9k/rc.h @@ -157,7 +157,6 @@ struct ath_rateset { * @probe_interval: interval for ratectrl to probe for other rates * @prev_data_rix: rate idx of last data frame * @ht_cap: HT capabilities - * @single_stream: When TRUE, only single TX stream possible * @neg_rates: Negotatied rates * @neg_ht_rates: Negotiated HT rates */ @@ -175,7 +174,6 @@ struct ath_rate_priv { u8 max_valid_rate; u8 valid_rate_index[RATE_TABLE_SIZE]; u8 ht_cap; - u8 single_stream; u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE]; u8 rc_phy_mode; -- GitLab From f5c38ef06e005705ef87b7a77752c183bacb94cc Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 30 Mar 2009 15:28:57 +0530 Subject: [PATCH 0531/6080] ath9k: Fix bug in determining HT40 mode This patch fixes a bug in checking for HT40 mode. The STA's mode can be determined from the cached HT capabilities, use that and remove the redundant variable 'rc_phy_mode'. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/rc.c | 6 ++---- drivers/net/wireless/ath9k/rc.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index a6933ccab483..a13668b9b6dc 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -1321,7 +1321,7 @@ static void ath_rc_tx_status(struct ath_softc *sc, * 40 to 20 => don't update */ if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && - (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) + !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG)) return; rix = ath_rc_get_rateindex(rate_table, &rates[i]); @@ -1346,9 +1346,8 @@ static void ath_rc_tx_status(struct ath_softc *sc, /* If HT40 and we have switched mode from 40 to 20 => don't update */ if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && - (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) { + !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG)) return; - } rix = ath_rc_get_rateindex(rate_table, &rates[i]); ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, @@ -1421,7 +1420,6 @@ static void ath_rc_init(struct ath_softc *sc, ath_rc_priv->valid_phy_rateidx[i][j] = 0; ath_rc_priv->valid_phy_ratecnt[i] = 0; } - ath_rc_priv->rc_phy_mode = ath_rc_priv->ht_cap & WLAN_RC_40_FLAG; if (!rateset->rs_nrates) { /* No working rate, just initialize valid rates */ diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h index bdfd2052077c..e3abd76103fd 100644 --- a/drivers/net/wireless/ath9k/rc.h +++ b/drivers/net/wireless/ath9k/rc.h @@ -176,7 +176,6 @@ struct ath_rate_priv { u8 ht_cap; u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE]; - u8 rc_phy_mode; u8 rate_max_phy; u32 rssi_time; u32 rssi_down_time; -- GitLab From d5522e039586fdf72493225a88b944f726b69671 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 30 Mar 2009 13:23:35 +0200 Subject: [PATCH 0532/6080] mac80211: move ieee80211_enable_ht function to mlme.c It really belongs into that file since it is only relevant for managed mode. Move 1:1, not even whitespace changes, but make it static and remove from header file. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ht.c | 83 -------------------------------------- net/mac80211/ieee80211_i.h | 3 -- net/mac80211/mlme.c | 83 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 86 deletions(-) diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 4e3c72f20de7..73bd427750ef 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -83,89 +83,6 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, ht_cap->mcs.rx_mask[32/8] |= 1; } -/* - * ieee80211_enable_ht should be called only after the operating band - * has been determined as ht configuration depends on the hw's - * HT abilities for a specific band. - */ -u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, - struct ieee80211_ht_info *hti, - u16 ap_ht_cap_flags) -{ - struct ieee80211_local *local = sdata->local; - struct ieee80211_supported_band *sband; - struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - struct ieee80211_bss_ht_conf ht; - struct sta_info *sta; - u32 changed = 0; - bool enable_ht = true, ht_changed; - enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; - - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - - memset(&ht, 0, sizeof(ht)); - - /* HT is not supported */ - if (!sband->ht_cap.ht_supported) - enable_ht = false; - - /* check that channel matches the right operating channel */ - if (local->hw.conf.channel->center_freq != - ieee80211_channel_to_frequency(hti->control_chan)) - enable_ht = false; - - if (enable_ht) { - channel_type = NL80211_CHAN_HT20; - - if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && - (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && - (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { - switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { - case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: - channel_type = NL80211_CHAN_HT40PLUS; - break; - case IEEE80211_HT_PARAM_CHA_SEC_BELOW: - channel_type = NL80211_CHAN_HT40MINUS; - break; - } - } - } - - ht_changed = conf_is_ht(&local->hw.conf) != enable_ht || - channel_type != local->hw.conf.channel_type; - - local->oper_channel_type = channel_type; - - if (ht_changed) { - /* channel_type change automatically detected */ - ieee80211_hw_config(local, 0); - - rcu_read_lock(); - - sta = sta_info_get(local, ifmgd->bssid); - if (sta) - rate_control_rate_update(local, sband, sta, - IEEE80211_RC_HT_CHANGED); - - rcu_read_unlock(); - - } - - /* disable HT */ - if (!enable_ht) - return 0; - - ht.operation_mode = le16_to_cpu(hti->operation_mode); - - /* if bss configuration changed store the new one */ - if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) { - changed |= BSS_CHANGED_HT; - sdata->vif.bss_conf.ht = ht; - } - - return changed; -} - void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta) { int i; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 312347d102c8..73d9f894ed5d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -995,9 +995,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, struct ieee80211_ht_cap *ht_cap_ie, struct ieee80211_sta_ht_cap *ht_cap); -u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, - struct ieee80211_ht_info *hti, - u16 ap_ht_cap_flags); void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, const u8 *da, u16 tid, diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 08db02c237c9..4ce5b9c22324 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -80,6 +80,89 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss, return count; } +/* + * ieee80211_enable_ht should be called only after the operating band + * has been determined as ht configuration depends on the hw's + * HT abilities for a specific band. + */ +static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, + struct ieee80211_ht_info *hti, + u16 ap_ht_cap_flags) +{ + struct ieee80211_local *local = sdata->local; + struct ieee80211_supported_band *sband; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_bss_ht_conf ht; + struct sta_info *sta; + u32 changed = 0; + bool enable_ht = true, ht_changed; + enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; + + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + + memset(&ht, 0, sizeof(ht)); + + /* HT is not supported */ + if (!sband->ht_cap.ht_supported) + enable_ht = false; + + /* check that channel matches the right operating channel */ + if (local->hw.conf.channel->center_freq != + ieee80211_channel_to_frequency(hti->control_chan)) + enable_ht = false; + + if (enable_ht) { + channel_type = NL80211_CHAN_HT20; + + if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) && + (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && + (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) { + switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + channel_type = NL80211_CHAN_HT40PLUS; + break; + case IEEE80211_HT_PARAM_CHA_SEC_BELOW: + channel_type = NL80211_CHAN_HT40MINUS; + break; + } + } + } + + ht_changed = conf_is_ht(&local->hw.conf) != enable_ht || + channel_type != local->hw.conf.channel_type; + + local->oper_channel_type = channel_type; + + if (ht_changed) { + /* channel_type change automatically detected */ + ieee80211_hw_config(local, 0); + + rcu_read_lock(); + + sta = sta_info_get(local, ifmgd->bssid); + if (sta) + rate_control_rate_update(local, sband, sta, + IEEE80211_RC_HT_CHANGED); + + rcu_read_unlock(); + + } + + /* disable HT */ + if (!enable_ht) + return 0; + + ht.operation_mode = le16_to_cpu(hti->operation_mode); + + /* if bss configuration changed store the new one */ + if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) { + changed |= BSS_CHANGED_HT; + sdata->vif.bss_conf.ht = ht; + } + + return changed; +} + /* frame sending functions */ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) -- GitLab From 42639fcd443d97a9a471f4b8269620286dd7036b Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 30 Mar 2009 08:05:29 -0400 Subject: [PATCH 0533/6080] ath5k: reduce exported channel list Claiming every available 5 ghz channel has a couple of negative side-effects: scanning takes a long time, and the channel list overflows the available buffer space for netlink commands, resulting in: $ iw phy phy0 info command failed: No buffer space available (-105) This patch adds a modparam so people who want to see all the channels can do so by passing all_channels=1. By default users will see a smaller list of channels. This also halves scan time, from 10 seconds down to less than 5 when using world regulatory. Changes-licensed-under: 3-Clause-BSD Signed-off-by: Bob Copeland Reported-by: Simon Farnsworth Tested-By: Simon Farnsworth Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index a08bc8a4fb69..d8c60c53d953 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -64,6 +64,10 @@ static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); +static int modparam_all_channels; +module_param_named(all_channels, modparam_all_channels, int, 0444); +MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); + /******************\ * Internal defines * @@ -862,6 +866,20 @@ ath5k_ieee2mhz(short chan) return 2212 + chan * 20; } +/* + * Returns true for the channel numbers used without all_channels modparam. + */ +static bool ath5k_is_standard_channel(short chan) +{ + return ((chan <= 14) || + /* UNII 1,2 */ + ((chan & 3) == 0 && chan >= 36 && chan <= 64) || + /* midband */ + ((chan & 3) == 0 && chan >= 100 && chan <= 140) || + /* UNII-3 */ + ((chan & 3) == 1 && chan >= 149 && chan <= 165)); +} + static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels, @@ -899,6 +917,9 @@ ath5k_copy_channels(struct ath5k_hw *ah, if (!ath5k_channel_ok(ah, freq, chfreq)) continue; + if (!modparam_all_channels && !ath5k_is_standard_channel(ch)) + continue; + /* Write channel info and increment counter */ channels[count].center_freq = freq; channels[count].band = (chfreq == CHANNEL_2GHZ) ? -- GitLab From ae3d2462f89db4592ea71e8f6e326d4b38dc952c Mon Sep 17 00:00:00 2001 From: Masakazu Mokuno Date: Mon, 30 Mar 2009 11:04:04 -0700 Subject: [PATCH 0534/6080] net/ps3: Update maintainer Update the MAINTAINERS entry for PS3 NETWORK SUPPORT. CC: Masakazu Mokuno Signed-off-by: Geoff Levand Signed-off-by: John W. Linville --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 6dfcb6d03a97..3dfe1a7c9a93 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4427,8 +4427,8 @@ S: Maintained F: drivers/ata/sata_promise.* PS3 NETWORK SUPPORT -P: Masakazu Mokuno -M: mokuno@sm.sony.co.jp +P: Geoff Levand +M: geoffrey.levand@am.sony.com L: netdev@vger.kernel.org L: cbe-oss-dev@ozlabs.org S: Supported -- GitLab From cf3a9579f61c643c15c172da0baf5429578b0ba3 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 25 Mar 2009 03:11:58 +0100 Subject: [PATCH 0535/6080] p54: clean up p54.h's struct p54_common This patch rearrange and regroups most elements in p54_common. Signed-off-by: Christian Lamparter Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54.h | 67 +++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index ecf8b6ed5a47..04d95a143383 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h @@ -133,55 +133,72 @@ struct p54_led_dev { struct p54_common { struct ieee80211_hw *hw; - u32 rx_start; - u32 rx_end; - struct sk_buff_head tx_queue; void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb); int (*open)(struct ieee80211_hw *dev); void (*stop)(struct ieee80211_hw *dev); - int mode; + struct sk_buff_head tx_queue; + struct mutex conf_mutex; + + /* memory management (as seen by the firmware) */ + u32 rx_start; + u32 rx_end; u16 rx_mtu; u8 headroom; u8 tailroom; - struct mutex conf_mutex; - u8 mac_addr[ETH_ALEN]; - u8 bssid[ETH_ALEN]; + + /* firmware/hardware info */ + unsigned int tx_hdr_len; + unsigned int fw_var; + unsigned int fw_interface; + u8 version; + + /* (e)DCF / QOS state */ + bool use_short_slot; + struct ieee80211_tx_queue_stats tx_stats[8]; + struct p54_edcf_queue_param qos_params[8]; + + /* Radio data */ + u16 rxhw; u8 rx_diversity_mask; u8 tx_diversity_mask; + unsigned int output_power; + int noise; + /* calibration, output power limit and rssi<->dBm conversation data */ struct pda_iq_autocal_entry *iq_autocal; unsigned int iq_autocal_len; - struct p54_cal_database *output_limit; struct p54_cal_database *curve_data; + struct p54_cal_database *output_limit; struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS]; + + /* BBP/MAC state */ + u8 mac_addr[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u16 wakeup_timer; unsigned int filter_flags; - bool use_short_slot; - u16 rxhw; - u8 version; - unsigned int tx_hdr_len; - unsigned int fw_var; - unsigned int fw_interface; - unsigned int output_power; - u32 tsf_low32; - u32 tsf_high32; + int mode; + u32 tsf_low32, tsf_high32; u32 basic_rate_mask; - u16 wakeup_timer; u16 aid; - struct ieee80211_tx_queue_stats tx_stats[8]; - struct p54_edcf_queue_param qos_params[8]; - struct ieee80211_low_level_stats stats; - struct delayed_work work; struct sk_buff *cached_beacon; - int noise; - void *eeprom; - struct completion eeprom_comp; + + /* cryptographic engine information */ u8 privacy_caps; u8 rx_keycache_size; + /* LED management */ #ifdef CONFIG_P54_LEDS struct p54_led_dev assoc_led; struct p54_led_dev tx_led; #endif /* CONFIG_P54_LEDS */ u16 softled_state; /* bit field of glowing LEDs */ + + /* statistics */ + struct ieee80211_low_level_stats stats; + struct delayed_work work; + + /* eeprom handling */ + void *eeprom; + struct completion eeprom_comp; }; int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); -- GitLab From dce072580e095d1fb7be59a1be30dc0e8307821b Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 25 Mar 2009 03:12:18 +0100 Subject: [PATCH 0536/6080] p54: more SoftLED updates This patch hopefully finishes the SoftLED code: - It adds two more LEDs (rx and radio). (the FW claims it can support up to 16 LEDs, but I doubt that any vendor put more than 4 on a board) - update the LEDs in a _delayed_ workqueue. No one reported any more crashes. (see: "PATCH] p54: fix race condition in memory management") So we can stop burning the mm code. Signed-off-by: Christian Lamparter Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54.h | 9 +-- drivers/net/wireless/p54/p54common.c | 84 +++++++++++++++++++++------- 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 04d95a143383..4499035359a6 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h @@ -125,6 +125,7 @@ struct p54_led_dev { struct led_classdev led_dev; char name[P54_LED_MAX_NAME_LEN + 1]; + unsigned int toggled; unsigned int index; unsigned int registered; }; @@ -186,10 +187,10 @@ struct p54_common { u8 rx_keycache_size; /* LED management */ -#ifdef CONFIG_P54_LEDS - struct p54_led_dev assoc_led; - struct p54_led_dev tx_led; -#endif /* CONFIG_P54_LEDS */ +#ifdef CONFIG_MAC80211_LEDS + struct p54_led_dev leds[4]; + struct delayed_work led_work; +#endif /* CONFIG_MAC80211_LEDS */ u16 softled_state; /* bit field of glowing LEDs */ /* statistics */ diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index c8f0232ee5e0..696067e69ee4 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -2088,6 +2088,9 @@ static void p54_stop(struct ieee80211_hw *dev) priv->softled_state = 0; p54_set_leds(dev); +#ifdef CONFIG_P54_LEDS + cancel_delayed_work_sync(&priv->led_work); +#endif /* CONFIG_P54_LEDS */ cancel_delayed_work_sync(&priv->work); if (priv->cached_beacon) p54_tx_cancel(dev, priv->cached_beacon); @@ -2421,6 +2424,43 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, } #ifdef CONFIG_P54_LEDS +static void p54_update_leds(struct work_struct *work) +{ + struct p54_common *priv = container_of(work, struct p54_common, + led_work.work); + int err, i, tmp, blink_delay = 400; + bool rerun = false; + + /* Don't toggle the LED, when the device is down. */ + if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) + return ; + + for (i = 0; i < ARRAY_SIZE(priv->leds); i++) + if (priv->leds[i].toggled) { + priv->softled_state |= BIT(i); + + tmp = 70 + 200 / (priv->leds[i].toggled); + if (tmp < blink_delay) + blink_delay = tmp; + + if (priv->leds[i].led_dev.brightness == LED_OFF) + rerun = true; + + priv->leds[i].toggled = + !!priv->leds[i].led_dev.brightness; + } else + priv->softled_state &= ~BIT(i); + + err = p54_set_leds(priv->hw); + if (err && net_ratelimit()) + printk(KERN_ERR "%s: failed to update LEDs.\n", + wiphy_name(priv->hw->wiphy)); + + if (rerun) + queue_delayed_work(priv->hw->workqueue, &priv->led_work, + msecs_to_jiffies(blink_delay)); +} + static void p54_led_brightness_set(struct led_classdev *led_dev, enum led_brightness brightness) { @@ -2428,28 +2468,23 @@ static void p54_led_brightness_set(struct led_classdev *led_dev, led_dev); struct ieee80211_hw *dev = led->hw_dev; struct p54_common *priv = dev->priv; - int err; - /* Don't toggle the LED, when the device is down. */ if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) return ; - if (brightness != LED_OFF) - priv->softled_state |= BIT(led->index); - else - priv->softled_state &= ~BIT(led->index); - - err = p54_set_leds(dev); - if (err && net_ratelimit()) - printk(KERN_ERR "%s: failed to update %s LED.\n", - wiphy_name(dev->wiphy), led_dev->name); + if (brightness) { + led->toggled++; + queue_delayed_work(priv->hw->workqueue, &priv->led_work, + HZ/10); + } } static int p54_register_led(struct ieee80211_hw *dev, - struct p54_led_dev *led, unsigned int led_index, char *name, char *trigger) { + struct p54_common *priv = dev->priv; + struct p54_led_dev *led = &priv->leds[led_index]; int err; if (led->registered) @@ -2482,19 +2517,30 @@ static int p54_init_leds(struct ieee80211_hw *dev) * TODO: * Figure out if the EEPROM contains some hints about the number * of available/programmable LEDs of the device. - * But for now, we can assume that we have two programmable LEDs. */ - err = p54_register_led(dev, &priv->assoc_led, 0, "assoc", + INIT_DELAYED_WORK(&priv->led_work, p54_update_leds); + + err = p54_register_led(dev, 0, "assoc", ieee80211_get_assoc_led_name(dev)); if (err) return err; - err = p54_register_led(dev, &priv->tx_led, 1, "tx", + err = p54_register_led(dev, 1, "tx", ieee80211_get_tx_led_name(dev)); if (err) return err; + err = p54_register_led(dev, 2, "rx", + ieee80211_get_rx_led_name(dev)); + if (err) + return err; + + err = p54_register_led(dev, 3, "radio", + ieee80211_get_radio_led_name(dev)); + if (err) + return err; + err = p54_set_leds(dev); return err; } @@ -2502,11 +2548,11 @@ static int p54_init_leds(struct ieee80211_hw *dev) static void p54_unregister_leds(struct ieee80211_hw *dev) { struct p54_common *priv = dev->priv; + int i; - if (priv->tx_led.registered) - led_classdev_unregister(&priv->tx_led.led_dev); - if (priv->assoc_led.registered) - led_classdev_unregister(&priv->assoc_led.led_dev); + for (i = 0; i < ARRAY_SIZE(priv->leds); i++) + if (priv->leds[i].registered) + led_classdev_unregister(&priv->leds[i].led_dev); } #endif /* CONFIG_P54_LEDS */ -- GitLab From f13027af5cd567757c18b85776232e31a2ba55d4 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 25 Mar 2009 03:12:49 +0100 Subject: [PATCH 0537/6080] p54: add beacon filtering support This patch adds beacon filtering support to p54. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54.h | 1 + drivers/net/wireless/p54/p54common.c | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 4499035359a6..d6354faaa2bc 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h @@ -134,6 +134,7 @@ struct p54_led_dev { struct p54_common { struct ieee80211_hw *hw; + struct ieee80211_vif *vif; void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb); int (*open)(struct ieee80211_hw *dev); void (*stop)(struct ieee80211_hw *dev); diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 696067e69ee4..cb490584cb8e 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -1044,6 +1044,7 @@ static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb) static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb) { + struct p54_common *priv = dev->priv; struct p54_hdr *hdr = (struct p54_hdr *) skb->data; struct p54_trap *trap = (struct p54_trap *) hdr->data; u16 event = le16_to_cpu(trap->event); @@ -1057,6 +1058,8 @@ static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb) wiphy_name(dev->wiphy), freq); break; case P54_TRAP_NO_BEACON: + if (priv->vif) + ieee80211_beacon_loss(priv->vif); break; case P54_TRAP_SCAN: break; @@ -1939,7 +1942,8 @@ static int p54_set_ps(struct ieee80211_hw *dev) int i; if (dev->conf.flags & IEEE80211_CONF_PS) - mode = P54_PSM | P54_PSM_DTIM | P54_PSM_MCBC; + mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM | + P54_PSM_CHECKSUM | P54_PSM_MCBC; else mode = P54_PSM_CAM; @@ -1957,9 +1961,10 @@ static int p54_set_ps(struct ieee80211_hw *dev) psm->intervals[i].periods = cpu_to_le16(1); } - psm->beacon_rssi_skip_max = 60; + psm->beacon_rssi_skip_max = 200; psm->rssi_delta_threshold = 0; - psm->nr = 0; + psm->nr = 10; + psm->exclude[0] = 0; priv->tx(dev, skb); @@ -2114,6 +2119,8 @@ static int p54_add_interface(struct ieee80211_hw *dev, return -EOPNOTSUPP; } + priv->vif = conf->vif; + switch (conf->type) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: @@ -2138,6 +2145,7 @@ static void p54_remove_interface(struct ieee80211_hw *dev, struct p54_common *priv = dev->priv; mutex_lock(&priv->conf_mutex); + priv->vif = NULL; if (priv->cached_beacon) p54_tx_cancel(dev, priv->cached_beacon); priv->mode = NL80211_IFTYPE_MONITOR; @@ -2590,7 +2598,8 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) skb_queue_head_init(&priv->tx_queue); dev->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_NOISE_DBM; + IEEE80211_HW_NOISE_DBM | + IEEE80211_HW_BEACON_FILTER; dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | -- GitLab From 5c8fa4f7e7fcceabb3b37d7ec66d3e7115a4bba3 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 26 Mar 2009 23:39:53 +0200 Subject: [PATCH 0538/6080] rndis_wlan: initiate cfg80211 conversion Signed-off-by: John W. Linville Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 114 ++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index db91db776508..c995d7c3139c 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include @@ -316,12 +318,44 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, #define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set)) +static const struct ieee80211_channel rndis_channels[] = { + { .center_freq = 2412 }, + { .center_freq = 2417 }, + { .center_freq = 2422 }, + { .center_freq = 2427 }, + { .center_freq = 2432 }, + { .center_freq = 2437 }, + { .center_freq = 2442 }, + { .center_freq = 2447 }, + { .center_freq = 2452 }, + { .center_freq = 2457 }, + { .center_freq = 2462 }, + { .center_freq = 2467 }, + { .center_freq = 2472 }, + { .center_freq = 2484 }, +}; + +static const struct ieee80211_rate rndis_rates[] = { + { .bitrate = 10 }, + { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, + { .bitrate = 60 }, + { .bitrate = 90 }, + { .bitrate = 120 }, + { .bitrate = 180 }, + { .bitrate = 240 }, + { .bitrate = 360 }, + { .bitrate = 480 }, + { .bitrate = 540 } +}; + /* RNDIS device private data */ struct rndis_wext_private { - char name[32]; - struct usbnet *usbdev; + struct wireless_dev wdev; + struct workqueue_struct *workqueue; struct delayed_work stats_work; struct work_struct work; @@ -329,6 +363,10 @@ struct rndis_wext_private { spinlock_t stats_lock; unsigned long work_pending; + struct ieee80211_supported_band band; + struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)]; + struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)]; + struct iw_statistics iwstats; struct iw_statistics privstats; @@ -369,7 +407,8 @@ struct rndis_wext_private { }; -static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 }; +struct cfg80211_ops rndis_config_ops = { }; +void *rndis_wiphy_privid = &rndis_wiphy_privid; static const int bcm4320_power_output[4] = { 25, 50, 75, 100 }; @@ -1151,15 +1190,15 @@ static int rndis_iw_get_range(struct net_device *dev, /* fill in 802.11g rates */ if (has_80211g_rates) { num = range->num_bitrates; - for (i = 0; i < ARRAY_SIZE(rates_80211g); i++) { + for (i = 4; i < ARRAY_SIZE(rndis_rates); i++) { for (j = 0; j < num; j++) { if (range->bitrate[j] == - rates_80211g[i] * 1000000) + rndis_rates[i].bitrate * 100000) break; } if (j == num) range->bitrate[range->num_bitrates++] = - rates_80211g[i] * 1000000; + rndis_rates[i].bitrate * 100000; if (range->num_bitrates == IW_MAX_BITRATES) break; } @@ -1204,17 +1243,6 @@ static int rndis_iw_get_range(struct net_device *dev, } -static int rndis_iw_get_name(struct net_device *dev, - struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ - struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); - - strcpy(wrqu->name, priv->name); - return 0; -} - - static int rndis_iw_set_essid(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *essid) { @@ -2165,7 +2193,7 @@ static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev) static const iw_handler rndis_iw_handler[] = { IW_IOCTL(SIOCSIWCOMMIT) = rndis_iw_commit, - IW_IOCTL(SIOCGIWNAME) = rndis_iw_get_name, + IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, IW_IOCTL(SIOCSIWFREQ) = rndis_iw_set_freq, IW_IOCTL(SIOCGIWFREQ) = rndis_iw_get_freq, IW_IOCTL(SIOCSIWMODE) = rndis_iw_set_mode, @@ -2338,12 +2366,6 @@ static int rndis_wext_get_caps(struct usbnet *usbdev) break; } } - if (priv->caps & CAP_MODE_80211A) - strcat(priv->name, "a"); - if (priv->caps & CAP_MODE_80211B) - strcat(priv->name, "b"); - if (priv->caps & CAP_MODE_80211G) - strcat(priv->name, "g"); } return retval; @@ -2538,20 +2560,28 @@ static const struct net_device_ops rndis_wext_netdev_ops = { static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) { + struct wiphy *wiphy; struct rndis_wext_private *priv; int retval, len; __le32 tmp; - /* allocate rndis private data */ - priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL); - if (!priv) + /* allocate wiphy and rndis private data + * NOTE: We only support a single virtual interface, so wiphy + * and wireless_dev are somewhat synonymous for this device. + */ + wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wext_private)); + if (!wiphy) return -ENOMEM; + priv = wiphy_priv(wiphy); + usbdev->net->ieee80211_ptr = &priv->wdev; + priv->wdev.wiphy = wiphy; + priv->wdev.iftype = NL80211_IFTYPE_STATION; + /* These have to be initialized before calling generic_rndis_bind(). * Otherwise we'll be in big trouble in rndis_wext_early_init(). */ usbdev->driver_priv = priv; - strcpy(priv->name, "IEEE802.11"); usbdev->net->wireless_handlers = &rndis_iw_handlers; priv->usbdev = usbdev; @@ -2595,7 +2625,31 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; + /* fill-out wiphy structure and register w/ cfg80211 */ + memcpy(wiphy->perm_addr, usbdev->net->dev_addr, ETH_ALEN); + wiphy->privid = rndis_wiphy_privid; + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) + | BIT(NL80211_IFTYPE_ADHOC); + wiphy->max_scan_ssids = 1; + + /* TODO: fill-out band information based on priv->caps */ rndis_wext_get_caps(usbdev); + + memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); + memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); + priv->band.channels = priv->channels; + priv->band.n_channels = ARRAY_SIZE(rndis_channels); + priv->band.bitrates = priv->rates; + priv->band.n_bitrates = ARRAY_SIZE(rndis_rates); + wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; + + set_wiphy_dev(wiphy, &usbdev->udev->dev); + + if (wiphy_register(wiphy)) { + wiphy_free(wiphy); + return -ENODEV; + } + set_default_iw_params(usbdev); /* turn radio on */ @@ -2632,9 +2686,11 @@ static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) if (priv && priv->wpa_ie_len) kfree(priv->wpa_ie); - kfree(priv); rndis_unbind(usbdev, intf); + + wiphy_unregister(priv->wdev.wiphy); + wiphy_free(priv->wdev.wiphy); } -- GitLab From 964c1d417e4738d359ba263921a7b9c18fa711c4 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 26 Mar 2009 23:40:01 +0200 Subject: [PATCH 0539/6080] rndis_wlan: convert get/set mode to cfg80211 Signed-off-by: John W. Linville [edit: made rndis_change_virtual_intf static] Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 95 ++++++++++++++----------------- 1 file changed, 43 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index c995d7c3139c..a8758603e01c 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -406,8 +406,17 @@ struct rndis_wext_private { u8 command_buffer[COMMAND_BUFFER_SIZE]; }; +/* + * cfg80211 ops + */ +static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params); + +struct cfg80211_ops rndis_config_ops = { + .change_virtual_intf = rndis_change_virtual_intf, +}; -struct cfg80211_ops rndis_config_ops = { }; void *rndis_wiphy_privid = &rndis_wiphy_privid; static const int bcm4320_power_output[4] = { 25, 50, 75, 100 }; @@ -1124,6 +1133,37 @@ static void set_multicast_list(struct usbnet *usbdev) } +/* + * cfg80211 ops + */ +static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params) +{ + struct net_device *dev; + struct usbnet *usbdev; + int mode; + + /* we're under RTNL */ + dev = __dev_get_by_index(&init_net, ifindex); + if (!dev) + return -ENODEV; + usbdev = netdev_priv(dev); + + switch (type) { + case NL80211_IFTYPE_ADHOC: + mode = ndis_80211_infra_adhoc; + break; + case NL80211_IFTYPE_STATION: + mode = ndis_80211_infra_infra; + break; + default: + return -EINVAL; + } + + return set_infra_mode(usbdev, mode); +} + /* * wireless extension handlers */ @@ -1450,55 +1490,6 @@ static int rndis_iw_get_auth(struct net_device *dev, } -static int rndis_iw_get_mode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); - - switch (priv->infra_mode) { - case ndis_80211_infra_adhoc: - wrqu->mode = IW_MODE_ADHOC; - break; - case ndis_80211_infra_infra: - wrqu->mode = IW_MODE_INFRA; - break; - /*case ndis_80211_infra_auto_unknown:*/ - default: - wrqu->mode = IW_MODE_AUTO; - break; - } - devdbg(usbdev, "SIOCGIWMODE: %08x", wrqu->mode); - return 0; -} - - -static int rndis_iw_set_mode(struct net_device *dev, - struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ - struct usbnet *usbdev = netdev_priv(dev); - int mode; - - devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode); - - switch (wrqu->mode) { - case IW_MODE_ADHOC: - mode = ndis_80211_infra_adhoc; - break; - case IW_MODE_INFRA: - mode = ndis_80211_infra_infra; - break; - /*case IW_MODE_AUTO:*/ - default: - mode = ndis_80211_infra_auto_unknown; - break; - } - - return set_infra_mode(usbdev, mode); -} - - static int rndis_iw_set_encode(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { @@ -2196,8 +2187,8 @@ static const iw_handler rndis_iw_handler[] = IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, IW_IOCTL(SIOCSIWFREQ) = rndis_iw_set_freq, IW_IOCTL(SIOCGIWFREQ) = rndis_iw_get_freq, - IW_IOCTL(SIOCSIWMODE) = rndis_iw_set_mode, - IW_IOCTL(SIOCGIWMODE) = rndis_iw_get_mode, + IW_IOCTL(SIOCSIWMODE) = (iw_handler) cfg80211_wext_siwmode, + IW_IOCTL(SIOCGIWMODE) = (iw_handler) cfg80211_wext_giwmode, IW_IOCTL(SIOCGIWRANGE) = rndis_iw_get_range, IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid, IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid, -- GitLab From 06aa7afaaa21a4e7f1bcb196bd3f29193924a603 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 26 Mar 2009 23:40:09 +0200 Subject: [PATCH 0540/6080] cfg80211: add cfg80211_inform_bss Added cfg80211_inform_bss() for full-mac devices to use. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- include/net/cfg80211.h | 8 +++++++ net/wireless/scan.c | 49 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f8bf0c86650b..2b1f6c69773c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -863,6 +863,14 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, struct ieee80211_mgmt *mgmt, size_t len, s32 signal, gfp_t gfp); +struct cfg80211_bss* +cfg80211_inform_bss(struct wiphy *wiphy, + struct ieee80211_channel *channel, + const u8 *bssid, + u64 timestamp, u16 capability, u16 beacon_interval, + const u8 *ie, size_t ielen, + s32 signal, gfp_t gfp); + struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, struct ieee80211_channel *channel, const u8 *bssid, diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 2ae65b39b529..1396248dc5cc 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -414,6 +414,55 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, return found; } +struct cfg80211_bss* +cfg80211_inform_bss(struct wiphy *wiphy, + struct ieee80211_channel *channel, + const u8 *bssid, + u64 timestamp, u16 capability, u16 beacon_interval, + const u8 *ie, size_t ielen, + s32 signal, gfp_t gfp) +{ + struct cfg80211_internal_bss *res; + size_t privsz; + + if (WARN_ON(!wiphy)) + return NULL; + + privsz = wiphy->bss_priv_size; + + if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC && + (signal < 0 || signal > 100))) + return NULL; + + res = kzalloc(sizeof(*res) + privsz + ielen, gfp); + if (!res) + return NULL; + + memcpy(res->pub.bssid, bssid, ETH_ALEN); + res->pub.channel = channel; + res->pub.signal = signal; + res->pub.tsf = timestamp; + res->pub.beacon_interval = beacon_interval; + res->pub.capability = capability; + /* point to after the private area */ + res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz; + memcpy(res->pub.information_elements, ie, ielen); + res->pub.len_information_elements = ielen; + + kref_init(&res->ref); + + res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, 0); + if (!res) + return NULL; + + if (res->pub.capability & WLAN_CAPABILITY_ESS) + regulatory_hint_found_beacon(wiphy, channel, gfp); + + /* cfg80211_bss_update gives us a referenced result */ + return &res->pub; +} +EXPORT_SYMBOL(cfg80211_inform_bss); + struct cfg80211_bss * cfg80211_inform_bss_frame(struct wiphy *wiphy, struct ieee80211_channel *channel, -- GitLab From 4bd7f03e915b6946307ce57f20718c6547734b5d Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 26 Mar 2009 23:40:16 +0200 Subject: [PATCH 0541/6080] rndis_wlan: change quality level scale Change quality level scale to match cfg80211 CFG80211_SIGNAL_TYPE_UNSPEC. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index a8758603e01c..9e7956d9c6be 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1269,7 +1269,7 @@ static int rndis_iw_get_range(struct net_device *dev, range->max_frag = 2346; range->max_qual.qual = 100; - range->max_qual.level = 154; + range->max_qual.level = 100; range->max_qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; @@ -1712,7 +1712,7 @@ static char *rndis_translate_scan(struct net_device *dev, devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi)); iwe.cmd = IWEVQUAL; iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->rssi)); - iwe.u.qual.level = le32_to_cpu(bssid->rssi); + iwe.u.qual.level = level_to_qual(le32_to_cpu(bssid->rssi)); iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; @@ -2400,7 +2400,7 @@ static void rndis_update_wireless_stats(struct work_struct *work) if (ret == 0) { memset(&iwstats.qual, 0, sizeof(iwstats.qual)); iwstats.qual.qual = level_to_qual(le32_to_cpu(rssi)); - iwstats.qual.level = le32_to_cpu(rssi); + iwstats.qual.level = level_to_qual(le32_to_cpu(rssi)); iwstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_INVALID; -- GitLab From 4d2a369ec09167f423c0783b1cf85cee8102544f Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 26 Mar 2009 23:40:23 +0200 Subject: [PATCH 0542/6080] rndis_wlan: convert get range to cfg80211 Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 110 +----------------------------- 1 file changed, 2 insertions(+), 108 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 9e7956d9c6be..4252903cf89a 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1176,113 +1176,6 @@ static int rndis_iw_commit(struct net_device *dev, } -static int rndis_iw_get_range(struct net_device *dev, - struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); - int len, ret, i, j, num, has_80211g_rates; - u8 rates[8]; - __le32 tx_power; - - devdbg(usbdev, "SIOCGIWRANGE"); - - /* clear iw_range struct */ - memset(range, 0, sizeof(*range)); - wrqu->data.length = sizeof(*range); - - range->txpower_capa = IW_TXPOW_MWATT; - range->num_txpower = 1; - if (priv->caps & CAP_SUPPORT_TXPOWER) { - len = sizeof(tx_power); - ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, - &tx_power, &len); - if (ret == 0 && le32_to_cpu(tx_power) != 0xFF) - range->txpower[0] = le32_to_cpu(tx_power); - else - range->txpower[0] = get_bcm4320_power(priv); - } else - range->txpower[0] = get_bcm4320_power(priv); - - len = sizeof(rates); - ret = rndis_query_oid(usbdev, OID_802_11_SUPPORTED_RATES, &rates, - &len); - has_80211g_rates = 0; - if (ret == 0) { - j = 0; - for (i = 0; i < len; i++) { - if (rates[i] == 0) - break; - range->bitrate[j] = (rates[i] & 0x7f) * 500000; - /* check for non 802.11b rates */ - if (range->bitrate[j] == 6000000 || - range->bitrate[j] == 9000000 || - (range->bitrate[j] >= 12000000 && - range->bitrate[j] != 22000000)) - has_80211g_rates = 1; - j++; - } - range->num_bitrates = j; - } else - range->num_bitrates = 0; - - /* fill in 802.11g rates */ - if (has_80211g_rates) { - num = range->num_bitrates; - for (i = 4; i < ARRAY_SIZE(rndis_rates); i++) { - for (j = 0; j < num; j++) { - if (range->bitrate[j] == - rndis_rates[i].bitrate * 100000) - break; - } - if (j == num) - range->bitrate[range->num_bitrates++] = - rndis_rates[i].bitrate * 100000; - if (range->num_bitrates == IW_MAX_BITRATES) - break; - } - - /* estimated max real througput in bps */ - range->throughput = 54 * 1000 * 1000 / 2; - - /* ~35% more with afterburner */ - if (priv->param_afterburner) - range->throughput = range->throughput / 100 * 135; - } else { - /* estimated max real througput in bps */ - range->throughput = 11 * 1000 * 1000 / 2; - } - - range->num_channels = 14; - - for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) { - range->freq[i].i = i + 1; - range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000; - range->freq[i].e = 1; - } - range->num_frequency = i; - - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - range->max_qual.qual = 100; - range->max_qual.level = 100; - range->max_qual.updated = IW_QUAL_QUAL_UPDATED - | IW_QUAL_LEVEL_UPDATED - | IW_QUAL_NOISE_INVALID; - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = WIRELESS_EXT; - - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - return 0; -} - - static int rndis_iw_set_essid(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *essid) { @@ -2189,7 +2082,7 @@ static const iw_handler rndis_iw_handler[] = IW_IOCTL(SIOCGIWFREQ) = rndis_iw_get_freq, IW_IOCTL(SIOCSIWMODE) = (iw_handler) cfg80211_wext_siwmode, IW_IOCTL(SIOCGIWMODE) = (iw_handler) cfg80211_wext_giwmode, - IW_IOCTL(SIOCGIWRANGE) = rndis_iw_get_range, + IW_IOCTL(SIOCGIWRANGE) = (iw_handler) cfg80211_wext_giwrange, IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid, IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid, IW_IOCTL(SIOCSIWSCAN) = rndis_iw_set_scan, @@ -2633,6 +2526,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) priv->band.bitrates = priv->rates; priv->band.n_bitrates = ARRAY_SIZE(rndis_rates); wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; + wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; set_wiphy_dev(wiphy, &usbdev->udev->dev); -- GitLab From 71a7b26d3e6404e43574f80236c00eaa39b2525e Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 26 Mar 2009 23:40:31 +0200 Subject: [PATCH 0543/6080] rndis_wlan: convert scan to cfg80211 Convert scan function to cfg80211. Unlike old scan code new code waits 1 sec before getting scan data from device and passing forward to cfg80211. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 341 +++++++++++++----------------- 1 file changed, 147 insertions(+), 194 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 4252903cf89a..239e6a14eae2 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -356,8 +356,11 @@ struct rndis_wext_private { struct wireless_dev wdev; + struct cfg80211_scan_request *scan_request; + struct workqueue_struct *workqueue; struct delayed_work stats_work; + struct delayed_work scan_work; struct work_struct work; struct mutex command_lock; spinlock_t stats_lock; @@ -413,8 +416,12 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex, enum nl80211_iftype type, u32 *flags, struct vif_params *params); +static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_scan_request *request); + struct cfg80211_ops rndis_config_ops = { .change_virtual_intf = rndis_change_virtual_intf, + .scan = rndis_scan, }; void *rndis_wiphy_privid = &rndis_wiphy_privid; @@ -1164,6 +1171,142 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex, return set_infra_mode(usbdev, mode); } + +#define SCAN_DELAY_JIFFIES (HZ) +static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_scan_request *request) +{ + struct usbnet *usbdev = netdev_priv(dev); + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); + int ret; + __le32 tmp; + + devdbg(usbdev, "cfg80211.scan"); + + if (!request) + return -EINVAL; + + if (priv->scan_request && priv->scan_request != request) + return -EBUSY; + + priv->scan_request = request; + + tmp = cpu_to_le32(1); + ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, + sizeof(tmp)); + if (ret == 0) { + /* Wait before retrieving scan results from device */ + queue_delayed_work(priv->workqueue, &priv->scan_work, + SCAN_DELAY_JIFFIES); + } + + return ret; +} + + +static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, + struct ndis_80211_bssid_ex *bssid) +{ + struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); + struct ieee80211_channel *channel; + s32 signal; + u64 timestamp; + u16 capability; + u16 beacon_interval; + struct ndis_80211_fixed_ies *fixed; + int ie_len, bssid_len; + u8 *ie; + + /* parse bssid structure */ + bssid_len = le32_to_cpu(bssid->length); + + if (bssid_len < sizeof(struct ndis_80211_bssid_ex) + + sizeof(struct ndis_80211_fixed_ies)) + return NULL; + + fixed = (struct ndis_80211_fixed_ies *)bssid->ies; + + ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies)); + ie_len = min(bssid_len - (int)sizeof(*bssid), + (int)le32_to_cpu(bssid->ie_length)); + ie_len -= sizeof(struct ndis_80211_fixed_ies); + if (ie_len < 0) + return NULL; + + /* extract data for cfg80211_inform_bss */ + channel = ieee80211_get_channel(priv->wdev.wiphy, + KHZ_TO_MHZ(le32_to_cpu(bssid->config.ds_config))); + if (!channel) + return NULL; + + signal = level_to_qual(le32_to_cpu(bssid->rssi)); + timestamp = le64_to_cpu(*(__le64 *)fixed->timestamp); + capability = le16_to_cpu(fixed->capabilities); + beacon_interval = le16_to_cpu(fixed->beacon_interval); + + return cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac, + timestamp, capability, beacon_interval, ie, ie_len, signal, + GFP_KERNEL); +} + + +static int rndis_check_bssid_list(struct usbnet *usbdev) +{ + void *buf = NULL; + struct ndis_80211_bssid_list_ex *bssid_list; + struct ndis_80211_bssid_ex *bssid; + int ret = -EINVAL, len, count, bssid_len; + + devdbg(usbdev, "check_bssid_list"); + + len = CONTROL_BUFFER_SIZE; + buf = kmalloc(len, GFP_KERNEL); + if (!buf) { + ret = -ENOMEM; + goto out; + } + + ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len); + if (ret != 0) + goto out; + + bssid_list = buf; + bssid = bssid_list->bssid; + bssid_len = le32_to_cpu(bssid->length); + count = le32_to_cpu(bssid_list->num_items); + devdbg(usbdev, "check_bssid_list: %d BSSIDs found", count); + + while (count && ((void *)bssid + bssid_len) <= (buf + len)) { + rndis_bss_info_update(usbdev, bssid); + + bssid = (void *)bssid + bssid_len; + bssid_len = le32_to_cpu(bssid->length); + count--; + } + +out: + kfree(buf); + return ret; +} + + +static void rndis_get_scan_results(struct work_struct *work) +{ + struct rndis_wext_private *priv = + container_of(work, struct rndis_wext_private, scan_work.work); + struct usbnet *usbdev = priv->usbdev; + int ret; + + devdbg(usbdev, "get_scan_results"); + + ret = rndis_check_bssid_list(usbdev); + + cfg80211_scan_done(priv->scan_request, ret < 0); + + priv->scan_request = NULL; +} + + /* * wireless extension handlers */ @@ -1531,198 +1674,6 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, } -static int rndis_iw_set_scan(struct net_device *dev, - struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ - struct usbnet *usbdev = netdev_priv(dev); - union iwreq_data evt; - int ret = -EINVAL; - __le32 tmp; - - devdbg(usbdev, "SIOCSIWSCAN"); - - if (wrqu->data.flags == 0) { - tmp = cpu_to_le32(1); - ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, - sizeof(tmp)); - evt.data.flags = 0; - evt.data.length = 0; - wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL); - } - return ret; -} - - -static char *rndis_translate_scan(struct net_device *dev, - struct iw_request_info *info, char *cev, - char *end_buf, - struct ndis_80211_bssid_ex *bssid) -{ - struct usbnet *usbdev = netdev_priv(dev); - u8 *ie; - char *current_val; - int bssid_len, ie_len, i; - u32 beacon, atim; - struct iw_event iwe; - unsigned char sbuf[32]; - - bssid_len = le32_to_cpu(bssid->length); - - devdbg(usbdev, "BSSID %pM", bssid->mac); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); - cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN); - - devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length), - bssid->ssid.essid); - iwe.cmd = SIOCGIWESSID; - iwe.u.essid.length = le32_to_cpu(bssid->ssid.length); - iwe.u.essid.flags = 1; - cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid); - - devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra)); - iwe.cmd = SIOCGIWMODE; - switch (le32_to_cpu(bssid->net_infra)) { - case ndis_80211_infra_adhoc: - iwe.u.mode = IW_MODE_ADHOC; - break; - case ndis_80211_infra_infra: - iwe.u.mode = IW_MODE_INFRA; - break; - /*case ndis_80211_infra_auto_unknown:*/ - default: - iwe.u.mode = IW_MODE_AUTO; - break; - } - cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN); - - devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config)); - iwe.cmd = SIOCGIWFREQ; - dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq); - cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN); - - devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi)); - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = level_to_qual(le32_to_cpu(bssid->rssi)); - iwe.u.qual.level = level_to_qual(le32_to_cpu(bssid->rssi)); - iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED - | IW_QUAL_LEVEL_UPDATED - | IW_QUAL_NOISE_INVALID; - cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN); - - devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy)); - iwe.cmd = SIOCGIWENCODE; - iwe.u.data.length = 0; - if (le32_to_cpu(bssid->privacy) == ndis_80211_priv_accept_all) - iwe.u.data.flags = IW_ENCODE_DISABLED; - else - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - - cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL); - - devdbg(usbdev, "RATES:"); - current_val = cev + iwe_stream_lcp_len(info); - iwe.cmd = SIOCGIWRATE; - for (i = 0; i < sizeof(bssid->rates); i++) { - if (bssid->rates[i] & 0x7f) { - iwe.u.bitrate.value = - ((bssid->rates[i] & 0x7f) * - 500000); - devdbg(usbdev, " %d", iwe.u.bitrate.value); - current_val = iwe_stream_add_value(info, cev, - current_val, end_buf, &iwe, - IW_EV_PARAM_LEN); - } - } - - if ((current_val - cev) > iwe_stream_lcp_len(info)) - cev = current_val; - - beacon = le32_to_cpu(bssid->config.beacon_period); - devdbg(usbdev, "BCN_INT %d", beacon); - iwe.cmd = IWEVCUSTOM; - snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon); - iwe.u.data.length = strlen(sbuf); - cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf); - - atim = le32_to_cpu(bssid->config.atim_window); - devdbg(usbdev, "ATIM %d", atim); - iwe.cmd = IWEVCUSTOM; - snprintf(sbuf, sizeof(sbuf), "atim=%u", atim); - iwe.u.data.length = strlen(sbuf); - cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf); - - ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies)); - ie_len = min(bssid_len - (int)sizeof(*bssid), - (int)le32_to_cpu(bssid->ie_length)); - ie_len -= sizeof(struct ndis_80211_fixed_ies); - while (ie_len >= 2 && 2 + ie[1] <= ie_len) { - if ((ie[0] == WLAN_EID_GENERIC && ie[1] >= 4 && - memcmp(ie + 2, "\x00\x50\xf2\x01", 4) == 0) || - ie[0] == WLAN_EID_RSN) { - devdbg(usbdev, "IE: WPA%d", - (ie[0] == WLAN_EID_RSN) ? 2 : 1); - iwe.cmd = IWEVGENIE; - /* arbitrary cut-off at 64 */ - iwe.u.data.length = min(ie[1] + 2, 64); - cev = iwe_stream_add_point(info, cev, end_buf, &iwe, ie); - } - - ie_len -= 2 + ie[1]; - ie += 2 + ie[1]; - } - - return cev; -} - - -static int rndis_iw_get_scan(struct net_device *dev, - struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ - struct usbnet *usbdev = netdev_priv(dev); - void *buf = NULL; - char *cev = extra; - struct ndis_80211_bssid_list_ex *bssid_list; - struct ndis_80211_bssid_ex *bssid; - int ret = -EINVAL, len, count, bssid_len; - - devdbg(usbdev, "SIOCGIWSCAN"); - - len = CONTROL_BUFFER_SIZE; - buf = kmalloc(len, GFP_KERNEL); - if (!buf) { - ret = -ENOMEM; - goto out; - } - - ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len); - - if (ret != 0) - goto out; - - bssid_list = buf; - bssid = bssid_list->bssid; - bssid_len = le32_to_cpu(bssid->length); - count = le32_to_cpu(bssid_list->num_items); - devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count); - - while (count && ((void *)bssid + bssid_len) <= (buf + len)) { - cev = rndis_translate_scan(dev, info, cev, - extra + IW_SCAN_MAX_DATA, bssid); - bssid = (void *)bssid + bssid_len; - bssid_len = le32_to_cpu(bssid->length); - count--; - } - -out: - wrqu->data.length = cev - extra; - wrqu->data.flags = 0; - kfree(buf); - return ret; -} - - static int rndis_iw_set_genie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { @@ -2085,8 +2036,8 @@ static const iw_handler rndis_iw_handler[] = IW_IOCTL(SIOCGIWRANGE) = (iw_handler) cfg80211_wext_giwrange, IW_IOCTL(SIOCSIWAP) = rndis_iw_set_bssid, IW_IOCTL(SIOCGIWAP) = rndis_iw_get_bssid, - IW_IOCTL(SIOCSIWSCAN) = rndis_iw_set_scan, - IW_IOCTL(SIOCGIWSCAN) = rndis_iw_get_scan, + IW_IOCTL(SIOCSIWSCAN) = (iw_handler) cfg80211_wext_siwscan, + IW_IOCTL(SIOCGIWSCAN) = (iw_handler) cfg80211_wext_giwscan, IW_IOCTL(SIOCSIWESSID) = rndis_iw_set_essid, IW_IOCTL(SIOCGIWESSID) = rndis_iw_get_essid, IW_IOCTL(SIOCSIWNICKN) = rndis_iw_set_nick, @@ -2547,6 +2498,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); queue_delayed_work(priv->workqueue, &priv->stats_work, round_jiffies_relative(STATS_UPDATE_JIFFIES)); + INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); INIT_WORK(&priv->work, rndis_wext_worker); return 0; @@ -2565,6 +2517,7 @@ static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) disassociate(usbdev, 0); cancel_delayed_work_sync(&priv->stats_work); + cancel_delayed_work_sync(&priv->scan_work); cancel_work_sync(&priv->work); flush_workqueue(priv->workqueue); destroy_workqueue(priv->workqueue); -- GitLab From 55a3757a5703ebc58612ffbfbcb7f193dae17df7 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Fri, 27 Mar 2009 12:45:30 -0700 Subject: [PATCH 0544/6080] iwlwifi: change check triggering device restart after rfkill change The STATUS_ALIVE value cannot be used because it is cleared when interface is brought down and will not be set if rfkill is enabled when interface is started again. The interface can thus not be brought up if rfkill was enabled before stopping the interface and disabled after starting the interface. Change the test to use priv->is_open instead, this will be set when interface is started whether rfkill is enabled or not. Thanks to Helmut Schaa for the suggested fix. Signed-off-by: Reinette Chatre Acked-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7609bfced10f..82abb1f9087f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2054,7 +2054,7 @@ void iwl_bg_rf_kill(struct work_struct *work) "HW and/or SW RF Kill no longer active, restarting " "device\n"); if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && - test_bit(STATUS_ALIVE, &priv->status)) + priv->is_open) queue_work(priv->workqueue, &priv->restart); } else { /* make sure mac80211 stop sending Tx frame */ -- GitLab From fc2ada30cacc28c96eabc598d3ef294338d8dcf5 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 30 Mar 2009 22:30:27 -0400 Subject: [PATCH 0545/6080] ath9k: separate ath9k specific code from ath9k_regd_get_ctl() Until ath5k and ath9k share common channel structures, they will have to implement their own get_ctl() function. Split out the portion that only relies on the current band and reg domain so that it can be common code. Signed-off-by: Bob Copeland Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 36 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 4ca625102291..43ed35ba95cf 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -16,6 +16,7 @@ #include #include +#include #include "ath9k.h" #include "regd_common.h" @@ -492,28 +493,37 @@ int ath9k_regd_init(struct ath_hw *ah) return 0; } -u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan) +static +u32 ath9k_regd_get_band_ctl(struct ath_hw *ah, enum ieee80211_band band) { - u32 ctl = NO_CTL; - if (!ah->regulatory.regpair || (ah->regulatory.country_code == CTRY_DEFAULT && is_wwr_sku(ath9k_regd_get_eepromRD(ah)))) { - if (IS_CHAN_B(chan)) - ctl = SD_NO_CTL | CTL_11B; - else if (IS_CHAN_G(chan)) - ctl = SD_NO_CTL | CTL_11G; - else - ctl = SD_NO_CTL | CTL_11A; - return ctl; + return SD_NO_CTL; + } + + switch (band) { + case IEEE80211_BAND_2GHZ: + return ah->regulatory.regpair->reg_2ghz_ctl; + case IEEE80211_BAND_5GHZ: + return ah->regulatory.regpair->reg_5ghz_ctl; + default: + return NO_CTL; } + return NO_CTL; +} + +u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan) +{ + u32 ctl = ath9k_regd_get_band_ctl(ah, chan->chan->band); + if (IS_CHAN_B(chan)) - ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B; + ctl |= CTL_11B; else if (IS_CHAN_G(chan)) - ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11G; + ctl |= CTL_11G; else - ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A; + ctl |= CTL_11A; return ctl; } -- GitLab From c02cf3738c9dbc446c160b9d49a001eb2be316c8 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 30 Mar 2009 22:30:28 -0400 Subject: [PATCH 0546/6080] ath9k: pass regd structure directly to regulatory functions All regulatory information is encapsulated by the ath9k_regulatory struct, so we can now change all the callers to take that directly instead of struct ath_hw. This in turn will enable us to move the regulatory functions to common code also used by ath5k, since both can use this regulatory struct. Signed-off-by: Bob Copeland Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/hw.c | 6 +- drivers/net/wireless/ath9k/main.c | 18 +++-- drivers/net/wireless/ath9k/regd.c | 118 +++++++++++++++--------------- drivers/net/wireless/ath9k/regd.h | 17 +++-- 4 files changed, 86 insertions(+), 73 deletions(-) diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index bb208f51b561..a8465bb418a9 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -1331,7 +1331,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, ath9k_olc_init(ah); status = ah->eep_ops->set_txpower(ah, chan, - ath9k_regd_get_ctl(ah, chan), + ath9k_regd_get_ctl(&ah->regulatory, chan), channel->max_antenna_gain * 2, channel->max_power * 2, min((u32) MAX_RATE_POWER, @@ -1671,7 +1671,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, } if (ah->eep_ops->set_txpower(ah, chan, - ath9k_regd_get_ctl(ah, chan), + ath9k_regd_get_ctl(&ah->regulatory, chan), channel->max_antenna_gain * 2, channel->max_power * 2, min((u32) MAX_RATE_POWER, @@ -3710,7 +3710,7 @@ bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER); if (ah->eep_ops->set_txpower(ah, chan, - ath9k_regd_get_ctl(ah, chan), + ath9k_regd_get_ctl(&ah->regulatory, chan), channel->max_antenna_gain * 2, channel->max_power * 2, min((u32) MAX_RATE_POWER, diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 76c58cc74b27..3647a47d939d 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1406,7 +1406,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) for (i = 0; i < sc->keymax; i++) ath9k_hw_keyreset(ah, (u16) i); - if (ath9k_regd_init(sc->sc_ah)) + if (ath9k_regd_init(&sc->sc_ah->regulatory)) goto bad; /* default to MONITOR mode */ @@ -1614,6 +1614,7 @@ int ath_attach(u16 devid, struct ath_softc *sc) struct ieee80211_hw *hw = sc->hw; const struct ieee80211_regdomain *regd; int error = 0, i; + struct ath9k_regulatory *reg; DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); @@ -1621,6 +1622,8 @@ int ath_attach(u16 devid, struct ath_softc *sc) if (error != 0) return error; + reg = &sc->sc_ah->regulatory; + /* get mac address from hardware and set in mac80211 */ SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr); @@ -1653,10 +1656,10 @@ int ath_attach(u16 devid, struct ath_softc *sc) goto error_attach; #endif - if (ath9k_is_world_regd(sc->sc_ah)) { + if (ath9k_is_world_regd(reg)) { /* Anything applied here (prior to wiphy registration) gets * saved on the wiphy orig_* parameters */ - regd = ath9k_world_regdomain(sc->sc_ah); + regd = ath9k_world_regdomain(reg); hw->wiphy->custom_regulatory = true; hw->wiphy->strict_regulatory = false; } else { @@ -1667,7 +1670,9 @@ int ath_attach(u16 devid, struct ath_softc *sc) } wiphy_apply_custom_regulatory(hw->wiphy, regd); ath9k_reg_apply_radar_flags(hw->wiphy); - ath9k_reg_apply_world_flags(hw->wiphy, NL80211_REGDOM_SET_BY_DRIVER); + ath9k_reg_apply_world_flags(hw->wiphy, + NL80211_REGDOM_SET_BY_DRIVER, + reg); INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); @@ -1675,9 +1680,8 @@ int ath_attach(u16 devid, struct ath_softc *sc) error = ieee80211_register_hw(hw); - if (!ath9k_is_world_regd(sc->sc_ah)) { - error = regulatory_hint(hw->wiphy, - sc->sc_ah->regulatory.alpha2); + if (!ath9k_is_world_regd(reg)) { + error = regulatory_hint(hw->wiphy, reg->alpha2); if (error) goto error_attach; } diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 43ed35ba95cf..7eaa59e4a7d1 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -113,14 +113,14 @@ static inline bool is_wwr_sku(u16 regd) (regd == WORLD); } -static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah) +static u16 ath9k_regd_get_eepromRD(struct ath9k_regulatory *reg) { - return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG; + return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; } -bool ath9k_is_world_regd(struct ath_hw *ah) +bool ath9k_is_world_regd(struct ath9k_regulatory *reg) { - return is_wwr_sku(ath9k_regd_get_eepromRD(ah)); + return is_wwr_sku(ath9k_regd_get_eepromRD(reg)); } const struct ieee80211_regdomain *ath9k_default_world_regdomain(void) @@ -129,9 +129,10 @@ const struct ieee80211_regdomain *ath9k_default_world_regdomain(void) return &ath9k_world_regdom_64; } -const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah) +const struct +ieee80211_regdomain *ath9k_world_regdomain(struct ath9k_regulatory *reg) { - switch (ah->regulatory.regpair->regDmnEnum) { + switch (reg->regpair->regDmnEnum) { case 0x60: case 0x61: case 0x62: @@ -312,14 +313,10 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy) } void ath9k_reg_apply_world_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator) + enum nl80211_reg_initiator initiator, + struct ath9k_regulatory *reg) { - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; - struct ath_hw *ah = sc->sc_ah; - - switch (ah->regulatory.regpair->regDmnEnum) { + switch (reg->regpair->regDmnEnum) { case 0x60: case 0x63: case 0x66: @@ -334,12 +331,9 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, return; } -int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +static int ath9k_reg_notifier_apply(struct wiphy *wiphy, + struct regulatory_request *request, struct ath9k_regulatory *reg) { - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; - /* We always apply this */ ath9k_reg_apply_radar_flags(wiphy); @@ -349,17 +343,28 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) case NL80211_REGDOM_SET_BY_USER: break; case NL80211_REGDOM_SET_BY_COUNTRY_IE: - if (ath9k_is_world_regd(sc->sc_ah)) - ath9k_reg_apply_world_flags(wiphy, request->initiator); + if (ath9k_is_world_regd(reg)) + ath9k_reg_apply_world_flags(wiphy, request->initiator, + reg); break; } return 0; } -bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah) +int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath9k_regulatory *reg = &sc->sc_ah->regulatory; + + return ath9k_reg_notifier_apply(wiphy, request, reg); +} + +bool ath9k_regd_is_eeprom_valid(struct ath9k_regulatory *reg) { - u16 rd = ath9k_regd_get_eepromRD(ah); + u16 rd = ath9k_regd_get_eepromRD(reg); int i; if (rd & COUNTRY_ERD_FLAG) { @@ -374,8 +379,8 @@ bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah) if (regDomainPairs[i].regDmnEnum == rd) return true; } - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "invalid regulatory domain/country code 0x%x\n", rd); + printk(KERN_DEBUG + "ath9k: invalid regulatory domain/country code 0x%x\n", rd); return false; } @@ -434,41 +439,40 @@ ath9k_get_regpair(int regdmn) return NULL; } -int ath9k_regd_init(struct ath_hw *ah) +int ath9k_regd_init(struct ath9k_regulatory *reg) { struct country_code_to_enum_rd *country = NULL; u16 regdmn; - if (!ath9k_regd_is_eeprom_valid(ah)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Invalid EEPROM contents\n"); + if (!ath9k_regd_is_eeprom_valid(reg)) { + printk(KERN_DEBUG "ath9k: Invalid EEPROM contents\n"); return -EINVAL; } - regdmn = ath9k_regd_get_eepromRD(ah); - ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn); + regdmn = ath9k_regd_get_eepromRD(reg); + reg->country_code = ath9k_regd_get_default_country(regdmn); - if (ah->regulatory.country_code == CTRY_DEFAULT && + if (reg->country_code == CTRY_DEFAULT && regdmn == CTRY_DEFAULT) - ah->regulatory.country_code = CTRY_UNITED_STATES; + reg->country_code = CTRY_UNITED_STATES; - if (ah->regulatory.country_code == CTRY_DEFAULT) { + if (reg->country_code == CTRY_DEFAULT) { country = NULL; } else { - country = ath9k_regd_find_country(ah->regulatory.country_code); + country = ath9k_regd_find_country(reg->country_code); if (country == NULL) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Country is NULL!!!!, cc= %d\n", - ah->regulatory.country_code); + printk(KERN_DEBUG + "ath9k: Country is NULL!!!!, cc= %d\n", + reg->country_code); return -EINVAL; } else regdmn = country->regDmnEnum; } - ah->regulatory.regpair = ath9k_get_regpair(regdmn); + reg->regpair = ath9k_get_regpair(regdmn); - if (!ah->regulatory.regpair) { - DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + if (!reg->regpair) { + printk(KERN_DEBUG "ath9k: " "No regulatory domain pair found, cannot continue\n"); return -EINVAL; } @@ -477,36 +481,36 @@ int ath9k_regd_init(struct ath_hw *ah) country = ath9k_regd_find_country_by_rd(regdmn); if (country) { - ah->regulatory.alpha2[0] = country->isoName[0]; - ah->regulatory.alpha2[1] = country->isoName[1]; + reg->alpha2[0] = country->isoName[0]; + reg->alpha2[1] = country->isoName[1]; } else { - ah->regulatory.alpha2[0] = '0'; - ah->regulatory.alpha2[1] = '0'; + reg->alpha2[0] = '0'; + reg->alpha2[1] = '0'; } - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Country alpha2 being used: %c%c\n" - "Regulatory.Regpair detected: 0x%0x\n", - ah->regulatory.alpha2[0], ah->regulatory.alpha2[1], - ah->regulatory.regpair->regDmnEnum); + printk(KERN_DEBUG "ath9k: Country alpha2 being used: %c%c\n", + reg->alpha2[0], reg->alpha2[1]); + printk(KERN_DEBUG "ath9k: Regpair detected: 0x%0x\n", + reg->regpair->regDmnEnum); return 0; } static -u32 ath9k_regd_get_band_ctl(struct ath_hw *ah, enum ieee80211_band band) +u32 ath9k_regd_get_band_ctl(struct ath9k_regulatory *reg, + enum ieee80211_band band) { - if (!ah->regulatory.regpair || - (ah->regulatory.country_code == CTRY_DEFAULT && - is_wwr_sku(ath9k_regd_get_eepromRD(ah)))) { + if (!reg->regpair || + (reg->country_code == CTRY_DEFAULT && + is_wwr_sku(ath9k_regd_get_eepromRD(reg)))) { return SD_NO_CTL; } switch (band) { case IEEE80211_BAND_2GHZ: - return ah->regulatory.regpair->reg_2ghz_ctl; + return reg->regpair->reg_2ghz_ctl; case IEEE80211_BAND_5GHZ: - return ah->regulatory.regpair->reg_5ghz_ctl; + return reg->regpair->reg_5ghz_ctl; default: return NO_CTL; } @@ -514,9 +518,9 @@ u32 ath9k_regd_get_band_ctl(struct ath_hw *ah, enum ieee80211_band band) return NO_CTL; } -u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan) +u32 ath9k_regd_get_ctl(struct ath9k_regulatory *reg, struct ath9k_channel *chan) { - u32 ctl = ath9k_regd_get_band_ctl(ah, chan->chan->band); + u32 ctl = ath9k_regd_get_band_ctl(reg, chan->chan->band); if (IS_CHAN_B(chan)) ctl |= CTL_11B; diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h index 9f5fbd4eea7a..61fa42ebfbc4 100644 --- a/drivers/net/wireless/ath9k/regd.h +++ b/drivers/net/wireless/ath9k/regd.h @@ -17,6 +17,8 @@ #ifndef REGD_H #define REGD_H +#include + #define COUNTRY_ERD_FLAG 0x8000 #define WORLDWIDE_ROAMING_FLAG 0x4000 @@ -233,15 +235,18 @@ enum CountryCode { CTRY_BELGIUM2 = 5002 }; -bool ath9k_is_world_regd(struct ath_hw *ah); -const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah); +bool ath9k_is_world_regd(struct ath9k_regulatory *reg); +const struct ieee80211_regdomain *ath9k_world_regdomain( + struct ath9k_regulatory *reg); const struct ieee80211_regdomain *ath9k_default_world_regdomain(void); void ath9k_reg_apply_world_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator); + enum nl80211_reg_initiator, + struct ath9k_regulatory *reg); void ath9k_reg_apply_radar_flags(struct wiphy *wiphy); -int ath9k_regd_init(struct ath_hw *ah); -bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah); -u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan); +int ath9k_regd_init(struct ath9k_regulatory *reg); +bool ath9k_regd_is_eeprom_valid(struct ath9k_regulatory *reg); +u32 ath9k_regd_get_ctl(struct ath9k_regulatory *reg, + struct ath9k_channel *chan); int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); #endif -- GitLab From 3a702e49c03ba959e3f5bb2b74ec9921a81c8c98 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 30 Mar 2009 22:30:29 -0400 Subject: [PATCH 0547/6080] atheros: introduce ath module containing common ath5k/ath9k/ar9170 code This change creates a new module, ath.ko, which includes code that can be shared between ath5k, ath9k and ar9170. For now, extract most of the ath9k regulatory code so it can also be used in ath5k. Signed-off-by: Bob Copeland Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 1 + drivers/net/wireless/ath/Kconfig | 4 + drivers/net/wireless/ath/Makefile | 3 + drivers/net/wireless/{ath9k => ath}/regd.c | 154 ++++++++---------- drivers/net/wireless/{ath9k => ath}/regd.h | 48 ++++-- .../net/wireless/{ath9k => ath}/regd_common.h | 0 drivers/net/wireless/ath9k/Kconfig | 1 + drivers/net/wireless/ath9k/Makefile | 1 - drivers/net/wireless/ath9k/eeprom.h | 2 + drivers/net/wireless/ath9k/hw.c | 15 ++ drivers/net/wireless/ath9k/hw.h | 5 +- drivers/net/wireless/ath9k/main.c | 31 ++-- 13 files changed, 155 insertions(+), 111 deletions(-) create mode 100644 drivers/net/wireless/ath/Kconfig create mode 100644 drivers/net/wireless/ath/Makefile rename drivers/net/wireless/{ath9k => ath}/regd.c (75%) rename drivers/net/wireless/{ath9k => ath}/regd.h (81%) rename drivers/net/wireless/{ath9k => ath}/regd_common.h (100%) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 8a0823588c51..9e2c7e26fcbf 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -483,6 +483,7 @@ config MWL8K will be called mwl8k. If unsure, say N. source "drivers/net/wireless/p54/Kconfig" +source "drivers/net/wireless/ath/Kconfig" source "drivers/net/wireless/ath5k/Kconfig" source "drivers/net/wireless/ath9k/Kconfig" source "drivers/net/wireless/ar9170/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 50e7fba7f0ea..104639e2783d 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_P54_COMMON) += p54/ +obj-$(CONFIG_ATH_COMMON) += ath/ obj-$(CONFIG_ATH5K) += ath5k/ obj-$(CONFIG_ATH9K) += ath9k/ obj-$(CONFIG_AR9170_USB) += ar9170/ diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig new file mode 100644 index 000000000000..c2873a24baae --- /dev/null +++ b/drivers/net/wireless/ath/Kconfig @@ -0,0 +1,4 @@ +config ATH_COMMON + tristate "Atheros Wireless Cards Shared Support" + depends on ATH5K || ATH9K + diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile new file mode 100644 index 000000000000..bc77646f90ad --- /dev/null +++ b/drivers/net/wireless/ath/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_ATH_COMMON) += ath.o +ath-objs := regd.o + diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath/regd.c similarity index 75% rename from drivers/net/wireless/ath9k/regd.c rename to drivers/net/wireless/ath/regd.c index 7eaa59e4a7d1..4d3935b6fbdd 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -16,8 +16,10 @@ #include #include +#include +#include #include -#include "ath9k.h" +#include "regd.h" #include "regd_common.h" /* @@ -56,7 +58,7 @@ /* Can be used for: * 0x60, 0x61, 0x62 */ -static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = { +static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = { .n_reg_rules = 5, .alpha2 = "99", .reg_rules = { @@ -66,7 +68,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = { }; /* Can be used by 0x63 and 0x65 */ -static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = { +static const struct ieee80211_regdomain ath_world_regdom_63_65 = { .n_reg_rules = 4, .alpha2 = "99", .reg_rules = { @@ -77,7 +79,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = { }; /* Can be used by 0x64 only */ -static const struct ieee80211_regdomain ath9k_world_regdom_64 = { +static const struct ieee80211_regdomain ath_world_regdom_64 = { .n_reg_rules = 3, .alpha2 = "99", .reg_rules = { @@ -87,7 +89,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_64 = { }; /* Can be used by 0x66 and 0x69 */ -static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = { +static const struct ieee80211_regdomain ath_world_regdom_66_69 = { .n_reg_rules = 3, .alpha2 = "99", .reg_rules = { @@ -97,7 +99,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = { }; /* Can be used by 0x67, 0x6A and 0x68 */ -static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = { +static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = { .n_reg_rules = 4, .alpha2 = "99", .reg_rules = { @@ -113,50 +115,53 @@ static inline bool is_wwr_sku(u16 regd) (regd == WORLD); } -static u16 ath9k_regd_get_eepromRD(struct ath9k_regulatory *reg) +static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) { return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; } -bool ath9k_is_world_regd(struct ath9k_regulatory *reg) +bool ath_is_world_regd(struct ath_regulatory *reg) { - return is_wwr_sku(ath9k_regd_get_eepromRD(reg)); + return is_wwr_sku(ath_regd_get_eepromRD(reg)); } +EXPORT_SYMBOL(ath_is_world_regd); -const struct ieee80211_regdomain *ath9k_default_world_regdomain(void) +const struct ieee80211_regdomain *ath_default_world_regdomain(void) { /* this is the most restrictive */ - return &ath9k_world_regdom_64; + return &ath_world_regdom_64; } +EXPORT_SYMBOL(ath_default_world_regdomain); const struct -ieee80211_regdomain *ath9k_world_regdomain(struct ath9k_regulatory *reg) +ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) { switch (reg->regpair->regDmnEnum) { case 0x60: case 0x61: case 0x62: - return &ath9k_world_regdom_60_61_62; + return &ath_world_regdom_60_61_62; case 0x63: case 0x65: - return &ath9k_world_regdom_63_65; + return &ath_world_regdom_63_65; case 0x64: - return &ath9k_world_regdom_64; + return &ath_world_regdom_64; case 0x66: case 0x69: - return &ath9k_world_regdom_66_69; + return &ath_world_regdom_66_69; case 0x67: case 0x68: case 0x6A: - return &ath9k_world_regdom_67_68_6A; + return &ath_world_regdom_67_68_6A; default: WARN_ON(1); - return ath9k_default_world_regdomain(); + return ath_default_world_regdomain(); } } +EXPORT_SYMBOL(ath_world_regdomain); /* Frequency is one where radar detection is required */ -static bool ath9k_is_radar_freq(u16 center_freq) +static bool ath_is_radar_freq(u16 center_freq) { return (center_freq >= 5260 && center_freq <= 5700); } @@ -170,7 +175,7 @@ static bool ath9k_is_radar_freq(u16 center_freq) * received a beacon on a channel we can enable active scan and * adhoc (or beaconing). */ -static void ath9k_reg_apply_beaconing_flags( +static void ath_reg_apply_beaconing_flags( struct wiphy *wiphy, enum nl80211_reg_initiator initiator) { @@ -193,7 +198,7 @@ static void ath9k_reg_apply_beaconing_flags( ch = &sband->channels[i]; - if (ath9k_is_radar_freq(ch->center_freq) || + if (ath_is_radar_freq(ch->center_freq) || (ch->flags & IEEE80211_CHAN_RADAR)) continue; @@ -229,7 +234,7 @@ static void ath9k_reg_apply_beaconing_flags( } /* Allows active scan scan on Ch 12 and 13 */ -static void ath9k_reg_apply_active_scan_flags( +static void ath_reg_apply_active_scan_flags( struct wiphy *wiphy, enum nl80211_reg_initiator initiator) { @@ -280,7 +285,7 @@ static void ath9k_reg_apply_active_scan_flags( } /* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ -void ath9k_reg_apply_radar_flags(struct wiphy *wiphy) +void ath_reg_apply_radar_flags(struct wiphy *wiphy) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; @@ -293,7 +298,7 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy) for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; - if (!ath9k_is_radar_freq(ch->center_freq)) + if (!ath_is_radar_freq(ch->center_freq)) continue; /* We always enable radar detection/DFS on this * frequency range. Additionally we also apply on @@ -311,31 +316,33 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy) IEEE80211_CHAN_PASSIVE_SCAN; } } +EXPORT_SYMBOL(ath_reg_apply_radar_flags); -void ath9k_reg_apply_world_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator, - struct ath9k_regulatory *reg) +void ath_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct ath_regulatory *reg) { switch (reg->regpair->regDmnEnum) { case 0x60: case 0x63: case 0x66: case 0x67: - ath9k_reg_apply_beaconing_flags(wiphy, initiator); + ath_reg_apply_beaconing_flags(wiphy, initiator); break; case 0x68: - ath9k_reg_apply_beaconing_flags(wiphy, initiator); - ath9k_reg_apply_active_scan_flags(wiphy, initiator); + ath_reg_apply_beaconing_flags(wiphy, initiator); + ath_reg_apply_active_scan_flags(wiphy, initiator); break; } return; } +EXPORT_SYMBOL(ath_reg_apply_world_flags); -static int ath9k_reg_notifier_apply(struct wiphy *wiphy, - struct regulatory_request *request, struct ath9k_regulatory *reg) +int ath_reg_notifier_apply(struct wiphy *wiphy, + struct regulatory_request *request, struct ath_regulatory *reg) { /* We always apply this */ - ath9k_reg_apply_radar_flags(wiphy); + ath_reg_apply_radar_flags(wiphy); switch (request->initiator) { case NL80211_REGDOM_SET_BY_DRIVER: @@ -343,28 +350,19 @@ static int ath9k_reg_notifier_apply(struct wiphy *wiphy, case NL80211_REGDOM_SET_BY_USER: break; case NL80211_REGDOM_SET_BY_COUNTRY_IE: - if (ath9k_is_world_regd(reg)) - ath9k_reg_apply_world_flags(wiphy, request->initiator, - reg); + if (ath_is_world_regd(reg)) + ath_reg_apply_world_flags(wiphy, request->initiator, + reg); break; } return 0; } +EXPORT_SYMBOL(ath_reg_notifier_apply); -int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) { - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; - struct ath9k_regulatory *reg = &sc->sc_ah->regulatory; - - return ath9k_reg_notifier_apply(wiphy, request, reg); -} - -bool ath9k_regd_is_eeprom_valid(struct ath9k_regulatory *reg) -{ - u16 rd = ath9k_regd_get_eepromRD(reg); + u16 rd = ath_regd_get_eepromRD(reg); int i; if (rd & COUNTRY_ERD_FLAG) { @@ -380,13 +378,14 @@ bool ath9k_regd_is_eeprom_valid(struct ath9k_regulatory *reg) return true; } printk(KERN_DEBUG - "ath9k: invalid regulatory domain/country code 0x%x\n", rd); + "ath: invalid regulatory domain/country code 0x%x\n", rd); return false; } +EXPORT_SYMBOL(ath_regd_is_eeprom_valid); /* EEPROM country code to regpair mapping */ static struct country_code_to_enum_rd* -ath9k_regd_find_country(u16 countryCode) +ath_regd_find_country(u16 countryCode) { int i; @@ -399,7 +398,7 @@ ath9k_regd_find_country(u16 countryCode) /* EEPROM rd code to regpair mapping */ static struct country_code_to_enum_rd* -ath9k_regd_find_country_by_rd(int regdmn) +ath_regd_find_country_by_rd(int regdmn) { int i; @@ -411,13 +410,13 @@ ath9k_regd_find_country_by_rd(int regdmn) } /* Returns the map of the EEPROM set RD to a country code */ -static u16 ath9k_regd_get_default_country(u16 rd) +static u16 ath_regd_get_default_country(u16 rd) { if (rd & COUNTRY_ERD_FLAG) { struct country_code_to_enum_rd *country = NULL; u16 cc = rd & ~COUNTRY_ERD_FLAG; - country = ath9k_regd_find_country(cc); + country = ath_regd_find_country(cc); if (country != NULL) return cc; } @@ -426,7 +425,7 @@ static u16 ath9k_regd_get_default_country(u16 rd) } static struct reg_dmn_pair_mapping* -ath9k_get_regpair(int regdmn) +ath_get_regpair(int regdmn) { int i; @@ -439,18 +438,18 @@ ath9k_get_regpair(int regdmn) return NULL; } -int ath9k_regd_init(struct ath9k_regulatory *reg) +int ath_regd_init(struct ath_regulatory *reg) { struct country_code_to_enum_rd *country = NULL; u16 regdmn; - if (!ath9k_regd_is_eeprom_valid(reg)) { - printk(KERN_DEBUG "ath9k: Invalid EEPROM contents\n"); + if (!ath_regd_is_eeprom_valid(reg)) { + printk(KERN_DEBUG "ath: Invalid EEPROM contents\n"); return -EINVAL; } - regdmn = ath9k_regd_get_eepromRD(reg); - reg->country_code = ath9k_regd_get_default_country(regdmn); + regdmn = ath_regd_get_eepromRD(reg); + reg->country_code = ath_regd_get_default_country(regdmn); if (reg->country_code == CTRY_DEFAULT && regdmn == CTRY_DEFAULT) @@ -459,26 +458,26 @@ int ath9k_regd_init(struct ath9k_regulatory *reg) if (reg->country_code == CTRY_DEFAULT) { country = NULL; } else { - country = ath9k_regd_find_country(reg->country_code); + country = ath_regd_find_country(reg->country_code); if (country == NULL) { printk(KERN_DEBUG - "ath9k: Country is NULL!!!!, cc= %d\n", + "ath: Country is NULL!!!!, cc= %d\n", reg->country_code); return -EINVAL; } else regdmn = country->regDmnEnum; } - reg->regpair = ath9k_get_regpair(regdmn); + reg->regpair = ath_get_regpair(regdmn); if (!reg->regpair) { - printk(KERN_DEBUG "ath9k: " + printk(KERN_DEBUG "ath: " "No regulatory domain pair found, cannot continue\n"); return -EINVAL; } if (!country) - country = ath9k_regd_find_country_by_rd(regdmn); + country = ath_regd_find_country_by_rd(regdmn); if (country) { reg->alpha2[0] = country->isoName[0]; @@ -488,21 +487,21 @@ int ath9k_regd_init(struct ath9k_regulatory *reg) reg->alpha2[1] = '0'; } - printk(KERN_DEBUG "ath9k: Country alpha2 being used: %c%c\n", + printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n", reg->alpha2[0], reg->alpha2[1]); - printk(KERN_DEBUG "ath9k: Regpair detected: 0x%0x\n", + printk(KERN_DEBUG "ath: Regpair detected: 0x%0x\n", reg->regpair->regDmnEnum); return 0; } +EXPORT_SYMBOL(ath_regd_init); -static -u32 ath9k_regd_get_band_ctl(struct ath9k_regulatory *reg, - enum ieee80211_band band) +u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, + enum ieee80211_band band) { if (!reg->regpair || (reg->country_code == CTRY_DEFAULT && - is_wwr_sku(ath9k_regd_get_eepromRD(reg)))) { + is_wwr_sku(ath_regd_get_eepromRD(reg)))) { return SD_NO_CTL; } @@ -517,17 +516,4 @@ u32 ath9k_regd_get_band_ctl(struct ath9k_regulatory *reg, return NO_CTL; } - -u32 ath9k_regd_get_ctl(struct ath9k_regulatory *reg, struct ath9k_channel *chan) -{ - u32 ctl = ath9k_regd_get_band_ctl(reg, chan->chan->band); - - if (IS_CHAN_B(chan)) - ctl |= CTL_11B; - else if (IS_CHAN_G(chan)) - ctl |= CTL_11G; - else - ctl |= CTL_11A; - - return ctl; -} +EXPORT_SYMBOL(ath_regd_get_band_ctl); diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath/regd.h similarity index 81% rename from drivers/net/wireless/ath9k/regd.h rename to drivers/net/wireless/ath/regd.h index 61fa42ebfbc4..981f5cf2bdb8 100644 --- a/drivers/net/wireless/ath9k/regd.h +++ b/drivers/net/wireless/ath/regd.h @@ -19,6 +19,24 @@ #include +#include +#include + +#define NO_CTL 0xff +#define SD_NO_CTL 0xE0 +#define NO_CTL 0xff +#define CTL_MODE_M 7 +#define CTL_11A 0 +#define CTL_11B 1 +#define CTL_11G 2 +#define CTL_2GHT20 5 +#define CTL_5GHT20 6 +#define CTL_2GHT40 7 +#define CTL_5GHT40 8 + +#define CTRY_DEBUG 0x1ff +#define CTRY_DEFAULT 0 + #define COUNTRY_ERD_FLAG 0x8000 #define WORLDWIDE_ROAMING_FLAG 0x4000 @@ -42,7 +60,7 @@ struct country_code_to_enum_rd { const char *isoName; }; -struct ath9k_regulatory { +struct ath_regulatory { char alpha2[2]; u16 country_code; u16 max_power_level; @@ -235,18 +253,20 @@ enum CountryCode { CTRY_BELGIUM2 = 5002 }; -bool ath9k_is_world_regd(struct ath9k_regulatory *reg); -const struct ieee80211_regdomain *ath9k_world_regdomain( - struct ath9k_regulatory *reg); -const struct ieee80211_regdomain *ath9k_default_world_regdomain(void); -void ath9k_reg_apply_world_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator, - struct ath9k_regulatory *reg); -void ath9k_reg_apply_radar_flags(struct wiphy *wiphy); -int ath9k_regd_init(struct ath9k_regulatory *reg); -bool ath9k_regd_is_eeprom_valid(struct ath9k_regulatory *reg); -u32 ath9k_regd_get_ctl(struct ath9k_regulatory *reg, - struct ath9k_channel *chan); -int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); +bool ath_is_world_regd(struct ath_regulatory *reg); +const +struct ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg); +const struct ieee80211_regdomain *ath_default_world_regdomain(void); +void ath_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator, + struct ath_regulatory *reg); +void ath_reg_apply_radar_flags(struct wiphy *wiphy); +int ath_regd_init(struct ath_regulatory *reg); +bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg); +u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, + enum ieee80211_band band); +int ath_reg_notifier_apply(struct wiphy *wiphy, + struct regulatory_request *request, + struct ath_regulatory *reg); #endif diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath/regd_common.h similarity index 100% rename from drivers/net/wireless/ath9k/regd_common.h rename to drivers/net/wireless/ath/regd_common.h diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig index 90a8dd873786..0ed1ac312aa6 100644 --- a/drivers/net/wireless/ath9k/Kconfig +++ b/drivers/net/wireless/ath9k/Kconfig @@ -2,6 +2,7 @@ config ATH9K tristate "Atheros 802.11n wireless cards support" depends on PCI && MAC80211 && WLAN_80211 depends on RFKILL || RFKILL=n + select ATH_COMMON select MAC80211_LEDS select LEDS_CLASS select NEW_LEDS diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile index 1a4d4eab6fe8..783bc39eb2ff 100644 --- a/drivers/net/wireless/ath9k/Makefile +++ b/drivers/net/wireless/ath9k/Makefile @@ -4,7 +4,6 @@ ath9k-y += hw.o \ calib.o \ ani.o \ phy.o \ - regd.o \ beacon.o \ main.o \ recv.o \ diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath9k/eeprom.h index 25b68c881ff1..9a7715df5cff 100644 --- a/drivers/net/wireless/ath9k/eeprom.h +++ b/drivers/net/wireless/ath9k/eeprom.h @@ -17,6 +17,8 @@ #ifndef EEPROM_H #define EEPROM_H +#include + #define AH_USE_EEPROM 0x1 #ifdef __BIG_ENDIAN diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index a8465bb418a9..24299e65fdcf 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -1220,6 +1220,21 @@ static void ath9k_olc_init(struct ath_hw *ah) ah->PDADCdelta = 0; } +static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, + struct ath9k_channel *chan) +{ + u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band); + + if (IS_CHAN_B(chan)) + ctl |= CTL_11B; + else if (IS_CHAN_G(chan)) + ctl |= CTL_11G; + else + ctl |= CTL_11A; + + return ctl; +} + static int ath9k_hw_process_ini(struct ath_hw *ah, struct ath9k_channel *chan, enum ath9k_ht_macmode macmode) diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h index 5a1128ddb464..984ac7da09d6 100644 --- a/drivers/net/wireless/ath9k/hw.h +++ b/drivers/net/wireless/ath9k/hw.h @@ -25,10 +25,11 @@ #include "ani.h" #include "eeprom.h" #include "calib.h" -#include "regd.h" #include "reg.h" #include "phy.h" +#include "../ath/regd.h" + #define ATHEROS_VENDOR_ID 0x168c #define AR5416_DEVID_PCI 0x0023 #define AR5416_DEVID_PCIE 0x0024 @@ -404,7 +405,7 @@ struct ath_hw { struct ath9k_hw_version hw_version; struct ath9k_ops_config config; struct ath9k_hw_capabilities caps; - struct ath9k_regulatory regulatory; + struct ath_regulatory regulatory; struct ath9k_channel channels[38]; struct ath9k_channel *curchan; diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 3647a47d939d..d779f00c9b9d 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1406,7 +1406,7 @@ static int ath_init(u16 devid, struct ath_softc *sc) for (i = 0; i < sc->keymax; i++) ath9k_hw_keyreset(ah, (u16) i); - if (ath9k_regd_init(&sc->sc_ah->regulatory)) + if (ath_regd_init(&sc->sc_ah->regulatory)) goto bad; /* default to MONITOR mode */ @@ -1570,6 +1570,17 @@ bad: return error; } +static int ath9k_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath_regulatory *reg = &sc->sc_ah->regulatory; + + return ath_reg_notifier_apply(wiphy, request, reg); +} + void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) { hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | @@ -1614,7 +1625,7 @@ int ath_attach(u16 devid, struct ath_softc *sc) struct ieee80211_hw *hw = sc->hw; const struct ieee80211_regdomain *regd; int error = 0, i; - struct ath9k_regulatory *reg; + struct ath_regulatory *reg; DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); @@ -1656,23 +1667,23 @@ int ath_attach(u16 devid, struct ath_softc *sc) goto error_attach; #endif - if (ath9k_is_world_regd(reg)) { + if (ath_is_world_regd(reg)) { /* Anything applied here (prior to wiphy registration) gets * saved on the wiphy orig_* parameters */ - regd = ath9k_world_regdomain(reg); + regd = ath_world_regdomain(reg); hw->wiphy->custom_regulatory = true; hw->wiphy->strict_regulatory = false; } else { /* This gets applied in the case of the absense of CRDA, * it's our own custom world regulatory domain, similar to * cfg80211's but we enable passive scanning */ - regd = ath9k_default_world_regdomain(); + regd = ath_default_world_regdomain(); } wiphy_apply_custom_regulatory(hw->wiphy, regd); - ath9k_reg_apply_radar_flags(hw->wiphy); - ath9k_reg_apply_world_flags(hw->wiphy, - NL80211_REGDOM_SET_BY_DRIVER, - reg); + ath_reg_apply_radar_flags(hw->wiphy); + ath_reg_apply_world_flags(hw->wiphy, + NL80211_REGDOM_SET_BY_DRIVER, + reg); INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); @@ -1680,7 +1691,7 @@ int ath_attach(u16 devid, struct ath_softc *sc) error = ieee80211_register_hw(hw); - if (!ath9k_is_world_regd(reg)) { + if (!ath_is_world_regd(reg)) { error = regulatory_hint(hw->wiphy, reg->alpha2); if (error) goto error_attach; -- GitLab From e3bb249be89dd387e78ca382d08fad31745edac9 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 30 Mar 2009 22:30:30 -0400 Subject: [PATCH 0548/6080] ath: move more setup code into ath_regd_init Setup the wiphy regulatory parameters when first initializing the Atheros regulatory module. We can remove five exported symbols this way and simplify the driver code for both ath5k and ath9k. Signed-off-by: Bob Copeland Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 55 +++++++++++++++++++++++-------- drivers/net/wireless/ath/regd.h | 12 ++----- drivers/net/wireless/ath9k/main.c | 47 ++++++++------------------ 3 files changed, 58 insertions(+), 56 deletions(-) diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 4d3935b6fbdd..3ccf21cceb5a 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -126,14 +126,13 @@ bool ath_is_world_regd(struct ath_regulatory *reg) } EXPORT_SYMBOL(ath_is_world_regd); -const struct ieee80211_regdomain *ath_default_world_regdomain(void) +static const struct ieee80211_regdomain *ath_default_world_regdomain(void) { /* this is the most restrictive */ return &ath_world_regdom_64; } -EXPORT_SYMBOL(ath_default_world_regdomain); -const struct +static const struct ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) { switch (reg->regpair->regDmnEnum) { @@ -158,7 +157,6 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) return ath_default_world_regdomain(); } } -EXPORT_SYMBOL(ath_world_regdomain); /* Frequency is one where radar detection is required */ static bool ath_is_radar_freq(u16 center_freq) @@ -285,7 +283,7 @@ static void ath_reg_apply_active_scan_flags( } /* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ -void ath_reg_apply_radar_flags(struct wiphy *wiphy) +static void ath_reg_apply_radar_flags(struct wiphy *wiphy) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; @@ -316,11 +314,10 @@ void ath_reg_apply_radar_flags(struct wiphy *wiphy) IEEE80211_CHAN_PASSIVE_SCAN; } } -EXPORT_SYMBOL(ath_reg_apply_radar_flags); -void ath_reg_apply_world_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator, - struct ath_regulatory *reg) +static void ath_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct ath_regulatory *reg) { switch (reg->regpair->regDmnEnum) { case 0x60: @@ -336,7 +333,6 @@ void ath_reg_apply_world_flags(struct wiphy *wiphy, } return; } -EXPORT_SYMBOL(ath_reg_apply_world_flags); int ath_reg_notifier_apply(struct wiphy *wiphy, struct regulatory_request *request, struct ath_regulatory *reg) @@ -360,7 +356,7 @@ int ath_reg_notifier_apply(struct wiphy *wiphy, } EXPORT_SYMBOL(ath_reg_notifier_apply); -bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) +static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) { u16 rd = ath_regd_get_eepromRD(reg); int i; @@ -381,7 +377,6 @@ bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) "ath: invalid regulatory domain/country code 0x%x\n", rd); return false; } -EXPORT_SYMBOL(ath_regd_is_eeprom_valid); /* EEPROM country code to regpair mapping */ static struct country_code_to_enum_rd* @@ -438,7 +433,40 @@ ath_get_regpair(int regdmn) return NULL; } -int ath_regd_init(struct ath_regulatory *reg) +static int ath_regd_init_wiphy(struct ath_regulatory *reg, struct wiphy *wiphy, + int (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) +{ + const struct ieee80211_regdomain *regd; + + wiphy->reg_notifier = reg_notifier; + wiphy->strict_regulatory = true; + + if (ath_is_world_regd(reg)) { + /* + * Anything applied here (prior to wiphy registration) gets + * saved on the wiphy orig_* parameters + */ + regd = ath_world_regdomain(reg); + wiphy->custom_regulatory = true; + wiphy->strict_regulatory = false; + } else { + /* + * This gets applied in the case of the absense of CRDA, + * it's our own custom world regulatory domain, similar to + * cfg80211's but we enable passive scanning. + */ + regd = ath_default_world_regdomain(); + } + wiphy_apply_custom_regulatory(wiphy, regd); + ath_reg_apply_radar_flags(wiphy); + ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); + return 0; +} + +int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, + int (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) { struct country_code_to_enum_rd *country = NULL; u16 regdmn; @@ -492,6 +520,7 @@ int ath_regd_init(struct ath_regulatory *reg) printk(KERN_DEBUG "ath: Regpair detected: 0x%0x\n", reg->regpair->regDmnEnum); + ath_regd_init_wiphy(reg, wiphy, reg_notifier); return 0; } EXPORT_SYMBOL(ath_regd_init); diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h index 981f5cf2bdb8..eba7c7123b50 100644 --- a/drivers/net/wireless/ath/regd.h +++ b/drivers/net/wireless/ath/regd.h @@ -254,15 +254,9 @@ enum CountryCode { }; bool ath_is_world_regd(struct ath_regulatory *reg); -const -struct ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg); -const struct ieee80211_regdomain *ath_default_world_regdomain(void); -void ath_reg_apply_world_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator, - struct ath_regulatory *reg); -void ath_reg_apply_radar_flags(struct wiphy *wiphy); -int ath_regd_init(struct ath_regulatory *reg); -bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg); +int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, + int (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)); u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, enum ieee80211_band band); int ath_reg_notifier_apply(struct wiphy *wiphy, diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index d779f00c9b9d..8b6a7ea4e59b 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -1352,6 +1352,17 @@ void ath_detach(struct ath_softc *sc) ath9k_ps_restore(sc); } +static int ath9k_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; + struct ath_regulatory *reg = &sc->sc_ah->regulatory; + + return ath_reg_notifier_apply(wiphy, request, reg); +} + static int ath_init(u16 devid, struct ath_softc *sc) { struct ath_hw *ah = NULL; @@ -1406,7 +1417,8 @@ static int ath_init(u16 devid, struct ath_softc *sc) for (i = 0; i < sc->keymax; i++) ath9k_hw_keyreset(ah, (u16) i); - if (ath_regd_init(&sc->sc_ah->regulatory)) + if (ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy, + ath9k_reg_notifier)) goto bad; /* default to MONITOR mode */ @@ -1570,17 +1582,6 @@ bad: return error; } -static int ath9k_reg_notifier(struct wiphy *wiphy, - struct regulatory_request *request) -{ - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath_wiphy *aphy = hw->priv; - struct ath_softc *sc = aphy->sc; - struct ath_regulatory *reg = &sc->sc_ah->regulatory; - - return ath_reg_notifier_apply(wiphy, request, reg); -} - void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) { hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | @@ -1600,9 +1601,6 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); - hw->wiphy->reg_notifier = ath9k_reg_notifier; - hw->wiphy->strict_regulatory = true; - hw->queues = 4; hw->max_rates = 4; hw->channel_change_time = 5000; @@ -1623,7 +1621,6 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) int ath_attach(u16 devid, struct ath_softc *sc) { struct ieee80211_hw *hw = sc->hw; - const struct ieee80211_regdomain *regd; int error = 0, i; struct ath_regulatory *reg; @@ -1667,24 +1664,6 @@ int ath_attach(u16 devid, struct ath_softc *sc) goto error_attach; #endif - if (ath_is_world_regd(reg)) { - /* Anything applied here (prior to wiphy registration) gets - * saved on the wiphy orig_* parameters */ - regd = ath_world_regdomain(reg); - hw->wiphy->custom_regulatory = true; - hw->wiphy->strict_regulatory = false; - } else { - /* This gets applied in the case of the absense of CRDA, - * it's our own custom world regulatory domain, similar to - * cfg80211's but we enable passive scanning */ - regd = ath_default_world_regdomain(); - } - wiphy_apply_custom_regulatory(hw->wiphy, regd); - ath_reg_apply_radar_flags(hw->wiphy); - ath_reg_apply_world_flags(hw->wiphy, - NL80211_REGDOM_SET_BY_DRIVER, - reg); - INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); sc->wiphy_scheduler_int = msecs_to_jiffies(500); -- GitLab From f769c36bd71ebe8d7a5f83764f0428d36ebced35 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 30 Mar 2009 22:30:31 -0400 Subject: [PATCH 0549/6080] ath5k: use regulatory infrastructure Make ath5k select the ath module and add in the hooks to make the eeprom regulatory hint and reg notifier take effect. Changes to attach.c Changes-licensed-under: ISC Changes to base.c Changes-licensed-under: 3-Clause-BSD Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/Kconfig | 1 + drivers/net/wireless/ath5k/ath5k.h | 5 +++-- drivers/net/wireless/ath5k/base.c | 20 ++++++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath5k/Kconfig index 75383a5df992..509b6f94f73b 100644 --- a/drivers/net/wireless/ath5k/Kconfig +++ b/drivers/net/wireless/ath5k/Kconfig @@ -1,6 +1,7 @@ config ATH5K tristate "Atheros 5xxx wireless cards support" depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL + select ATH_COMMON select MAC80211_LEDS select LEDS_CLASS select NEW_LEDS diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index 0b616e72fe05..48c18d11c507 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h @@ -27,6 +27,8 @@ #include #include +#include "../ath/regd.h" + /* RX/TX descriptor hw structs * TODO: Driver part should only see sw structs */ #include "desc.h" @@ -1039,8 +1041,6 @@ struct ath5k_hw { bool ah_5ghz; bool ah_2ghz; -#define ah_regdomain ah_capabilities.cap_regdomain.reg_current -#define ah_regdomain_hw ah_capabilities.cap_regdomain.reg_hw #define ah_modes ah_capabilities.cap_mode #define ah_ee_version ah_capabilities.cap_eeprom.ee_version @@ -1065,6 +1065,7 @@ struct ath5k_hw { u32 ah_gpio[AR5K_MAX_GPIO]; int ah_gpio_npins; + struct ath_regulatory ah_regulatory; struct ath5k_capabilities ah_capabilities; struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index d8c60c53d953..ff6d4f839734 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -709,6 +709,15 @@ err_no_irq: * Driver Initialization * \***********************/ +static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ath5k_softc *sc = hw->priv; + struct ath_regulatory *reg = &sc->ah->ah_regulatory; + + return ath_reg_notifier_apply(wiphy, request, reg); +} + static int ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) { @@ -797,12 +806,23 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) memset(sc->bssidmask, 0xff, ETH_ALEN); ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); + ah->ah_regulatory.current_rd = + ah->ah_capabilities.cap_eeprom.ee_regdomain; + ret = ath_regd_init(&ah->ah_regulatory, hw->wiphy, ath5k_reg_notifier); + if (ret) { + ATH5K_ERR(sc, "can't initialize regulatory system\n"); + goto err_queues; + } + ret = ieee80211_register_hw(hw); if (ret) { ATH5K_ERR(sc, "can't register ieee80211 hw\n"); goto err_queues; } + if (!ath_is_world_regd(&sc->ah->ah_regulatory)) + regulatory_hint(hw->wiphy, sc->ah->ah_regulatory.alpha2); + ath5k_init_leds(sc); return 0; -- GitLab From 1878f77e13b9d720b78c4f818b94bfd4a7f596e5 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 30 Mar 2009 22:30:32 -0400 Subject: [PATCH 0550/6080] Make ar9170 use common ath reg code Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ar9170/Kconfig | 1 + drivers/net/wireless/ar9170/ar9170.h | 3 +++ drivers/net/wireless/ar9170/main.c | 18 ++++++++++++++++++ drivers/net/wireless/ath/Kconfig | 2 +- 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ar9170/Kconfig b/drivers/net/wireless/ar9170/Kconfig index de4281fda129..b99e3263ee6d 100644 --- a/drivers/net/wireless/ar9170/Kconfig +++ b/drivers/net/wireless/ar9170/Kconfig @@ -2,6 +2,7 @@ config AR9170_USB tristate "Atheros AR9170 802.11n USB support" depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL select FW_LOADER + select ATH_COMMON help This is a driver for the Atheros "otus" 802.11n USB devices. diff --git a/drivers/net/wireless/ar9170/ar9170.h b/drivers/net/wireless/ar9170/ar9170.h index f4fb2e94aea0..87c19859ba70 100644 --- a/drivers/net/wireless/ar9170/ar9170.h +++ b/drivers/net/wireless/ar9170/ar9170.h @@ -48,6 +48,8 @@ #include "eeprom.h" #include "hw.h" +#include "../ath/regd.h" + #define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1) enum ar9170_bw { @@ -151,6 +153,7 @@ struct ar9170 { /* EEPROM */ struct ar9170_eeprom eeprom; + struct ath_regulatory regulatory; /* global tx status for unregistered Stations. */ struct sk_buff_head global_tx_status; diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ar9170/main.c index 5f55754d968f..8de0ff9f580b 100644 --- a/drivers/net/wireless/ar9170/main.c +++ b/drivers/net/wireless/ar9170/main.c @@ -1620,12 +1620,24 @@ static int ar9170_read_eeprom(struct ar9170 *ar) else ar->hw->channel_change_time = 80 * 1000; + ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); + ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]); + /* second part of wiphy init */ SET_IEEE80211_PERM_ADDR(ar->hw, addr); return bands ? 0 : -EINVAL; } +static int ar9170_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ar9170 *ar = hw->priv; + + return ath_reg_notifier_apply(wiphy, request, &ar->regulatory); +} + int ar9170_register(struct ar9170 *ar, struct device *pdev) { int err; @@ -1635,10 +1647,16 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev) if (err) goto err_out; + err = ath_regd_init(&ar->regulatory, ar->hw->wiphy, + ar9170_reg_notifier); + err = ieee80211_register_hw(ar->hw); if (err) goto err_out; + if (!ath_is_world_regd(&ar->regulatory)) + regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2); + err = ar9170_init_leds(ar); if (err) goto err_unreg; diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index c2873a24baae..76517a45a212 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -1,4 +1,4 @@ config ATH_COMMON tristate "Atheros Wireless Cards Shared Support" - depends on ATH5K || ATH9K + depends on ATH5K || ATH9K || AR9170_USB -- GitLab From 203c4805e91786f9a010bc7945a0fde70c9da28e Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 30 Mar 2009 22:30:33 -0400 Subject: [PATCH 0551/6080] atheros: put atheros wireless drivers into ath/ Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 3 --- drivers/net/wireless/Makefile | 3 --- drivers/net/wireless/ath/Kconfig | 6 +++++- drivers/net/wireless/ath/Makefile | 4 ++++ drivers/net/wireless/{ => ath}/ar9170/Kconfig | 0 drivers/net/wireless/{ => ath}/ar9170/Makefile | 0 drivers/net/wireless/{ => ath}/ar9170/ar9170.h | 2 +- drivers/net/wireless/{ => ath}/ar9170/cmd.c | 0 drivers/net/wireless/{ => ath}/ar9170/cmd.h | 0 drivers/net/wireless/{ => ath}/ar9170/eeprom.h | 0 drivers/net/wireless/{ => ath}/ar9170/hw.h | 0 drivers/net/wireless/{ => ath}/ar9170/led.c | 0 drivers/net/wireless/{ => ath}/ar9170/mac.c | 0 drivers/net/wireless/{ => ath}/ar9170/main.c | 0 drivers/net/wireless/{ => ath}/ar9170/phy.c | 0 drivers/net/wireless/{ => ath}/ar9170/usb.c | 0 drivers/net/wireless/{ => ath}/ar9170/usb.h | 0 drivers/net/wireless/{ => ath}/ath5k/Kconfig | 0 drivers/net/wireless/{ => ath}/ath5k/Makefile | 0 drivers/net/wireless/{ => ath}/ath5k/ath5k.h | 2 +- drivers/net/wireless/{ => ath}/ath5k/attach.c | 0 drivers/net/wireless/{ => ath}/ath5k/base.c | 0 drivers/net/wireless/{ => ath}/ath5k/base.h | 0 drivers/net/wireless/{ => ath}/ath5k/caps.c | 0 drivers/net/wireless/{ => ath}/ath5k/debug.c | 0 drivers/net/wireless/{ => ath}/ath5k/debug.h | 0 drivers/net/wireless/{ => ath}/ath5k/desc.c | 0 drivers/net/wireless/{ => ath}/ath5k/desc.h | 0 drivers/net/wireless/{ => ath}/ath5k/dma.c | 0 drivers/net/wireless/{ => ath}/ath5k/eeprom.c | 0 drivers/net/wireless/{ => ath}/ath5k/eeprom.h | 0 drivers/net/wireless/{ => ath}/ath5k/gpio.c | 0 drivers/net/wireless/{ => ath}/ath5k/initvals.c | 0 drivers/net/wireless/{ => ath}/ath5k/led.c | 0 drivers/net/wireless/{ => ath}/ath5k/pcu.c | 0 drivers/net/wireless/{ => ath}/ath5k/phy.c | 0 drivers/net/wireless/{ => ath}/ath5k/qcu.c | 0 drivers/net/wireless/{ => ath}/ath5k/reg.h | 0 drivers/net/wireless/{ => ath}/ath5k/reset.c | 0 drivers/net/wireless/{ => ath}/ath5k/rfbuffer.h | 0 drivers/net/wireless/{ => ath}/ath5k/rfgain.h | 0 drivers/net/wireless/{ => ath}/ath9k/Kconfig | 0 drivers/net/wireless/{ => ath}/ath9k/Makefile | 0 drivers/net/wireless/{ => ath}/ath9k/ahb.c | 0 drivers/net/wireless/{ => ath}/ath9k/ani.c | 0 drivers/net/wireless/{ => ath}/ath9k/ani.h | 0 drivers/net/wireless/{ => ath}/ath9k/ath9k.h | 0 drivers/net/wireless/{ => ath}/ath9k/beacon.c | 0 drivers/net/wireless/{ => ath}/ath9k/calib.c | 0 drivers/net/wireless/{ => ath}/ath9k/calib.h | 0 drivers/net/wireless/{ => ath}/ath9k/debug.c | 0 drivers/net/wireless/{ => ath}/ath9k/debug.h | 0 drivers/net/wireless/{ => ath}/ath9k/eeprom.c | 0 drivers/net/wireless/{ => ath}/ath9k/eeprom.h | 0 drivers/net/wireless/{ => ath}/ath9k/hw.c | 0 drivers/net/wireless/{ => ath}/ath9k/hw.h | 2 +- drivers/net/wireless/{ => ath}/ath9k/initvals.h | 0 drivers/net/wireless/{ => ath}/ath9k/mac.c | 0 drivers/net/wireless/{ => ath}/ath9k/mac.h | 0 drivers/net/wireless/{ => ath}/ath9k/main.c | 0 drivers/net/wireless/{ => ath}/ath9k/pci.c | 0 drivers/net/wireless/{ => ath}/ath9k/phy.c | 0 drivers/net/wireless/{ => ath}/ath9k/phy.h | 0 drivers/net/wireless/{ => ath}/ath9k/rc.c | 0 drivers/net/wireless/{ => ath}/ath9k/rc.h | 0 drivers/net/wireless/{ => ath}/ath9k/recv.c | 0 drivers/net/wireless/{ => ath}/ath9k/reg.h | 0 drivers/net/wireless/{ => ath}/ath9k/virtual.c | 0 drivers/net/wireless/{ => ath}/ath9k/xmit.c | 0 69 files changed, 12 insertions(+), 10 deletions(-) rename drivers/net/wireless/{ => ath}/ar9170/Kconfig (100%) rename drivers/net/wireless/{ => ath}/ar9170/Makefile (100%) rename drivers/net/wireless/{ => ath}/ar9170/ar9170.h (99%) rename drivers/net/wireless/{ => ath}/ar9170/cmd.c (100%) rename drivers/net/wireless/{ => ath}/ar9170/cmd.h (100%) rename drivers/net/wireless/{ => ath}/ar9170/eeprom.h (100%) rename drivers/net/wireless/{ => ath}/ar9170/hw.h (100%) rename drivers/net/wireless/{ => ath}/ar9170/led.c (100%) rename drivers/net/wireless/{ => ath}/ar9170/mac.c (100%) rename drivers/net/wireless/{ => ath}/ar9170/main.c (100%) rename drivers/net/wireless/{ => ath}/ar9170/phy.c (100%) rename drivers/net/wireless/{ => ath}/ar9170/usb.c (100%) rename drivers/net/wireless/{ => ath}/ar9170/usb.h (100%) rename drivers/net/wireless/{ => ath}/ath5k/Kconfig (100%) rename drivers/net/wireless/{ => ath}/ath5k/Makefile (100%) rename drivers/net/wireless/{ => ath}/ath5k/ath5k.h (99%) rename drivers/net/wireless/{ => ath}/ath5k/attach.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/base.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/base.h (100%) rename drivers/net/wireless/{ => ath}/ath5k/caps.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/debug.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/debug.h (100%) rename drivers/net/wireless/{ => ath}/ath5k/desc.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/desc.h (100%) rename drivers/net/wireless/{ => ath}/ath5k/dma.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/eeprom.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/eeprom.h (100%) rename drivers/net/wireless/{ => ath}/ath5k/gpio.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/initvals.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/led.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/pcu.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/phy.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/qcu.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/reg.h (100%) rename drivers/net/wireless/{ => ath}/ath5k/reset.c (100%) rename drivers/net/wireless/{ => ath}/ath5k/rfbuffer.h (100%) rename drivers/net/wireless/{ => ath}/ath5k/rfgain.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/Kconfig (100%) rename drivers/net/wireless/{ => ath}/ath9k/Makefile (100%) rename drivers/net/wireless/{ => ath}/ath9k/ahb.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/ani.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/ani.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/ath9k.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/beacon.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/calib.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/calib.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/debug.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/debug.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/eeprom.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/eeprom.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/hw.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/hw.h (99%) rename drivers/net/wireless/{ => ath}/ath9k/initvals.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/mac.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/mac.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/main.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/pci.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/phy.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/phy.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/rc.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/rc.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/recv.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/reg.h (100%) rename drivers/net/wireless/{ => ath}/ath9k/virtual.c (100%) rename drivers/net/wireless/{ => ath}/ath9k/xmit.c (100%) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 9e2c7e26fcbf..8f279e7bd049 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -484,9 +484,6 @@ config MWL8K source "drivers/net/wireless/p54/Kconfig" source "drivers/net/wireless/ath/Kconfig" -source "drivers/net/wireless/ath5k/Kconfig" -source "drivers/net/wireless/ath9k/Kconfig" -source "drivers/net/wireless/ar9170/Kconfig" source "drivers/net/wireless/ipw2x00/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig" source "drivers/net/wireless/hostap/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 104639e2783d..0625e91b5995 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -56,8 +56,5 @@ obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_P54_COMMON) += p54/ obj-$(CONFIG_ATH_COMMON) += ath/ -obj-$(CONFIG_ATH5K) += ath5k/ -obj-$(CONFIG_ATH9K) += ath9k/ -obj-$(CONFIG_AR9170_USB) += ar9170/ obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index 76517a45a212..d26e7b485315 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -1,4 +1,8 @@ config ATH_COMMON - tristate "Atheros Wireless Cards Shared Support" + tristate "Atheros Wireless Cards" depends on ATH5K || ATH9K || AR9170_USB +source "drivers/net/wireless/ath/ath5k/Kconfig" +source "drivers/net/wireless/ath/ath9k/Kconfig" +source "drivers/net/wireless/ath/ar9170/Kconfig" + diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index bc77646f90ad..a005b919233f 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile @@ -1,3 +1,7 @@ +obj-$(CONFIG_ATH5K) += ath5k/ +obj-$(CONFIG_ATH9K) += ath9k/ +obj-$(CONFIG_AR9170_USB) += ar9170/ + obj-$(CONFIG_ATH_COMMON) += ath.o ath-objs := regd.o diff --git a/drivers/net/wireless/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig similarity index 100% rename from drivers/net/wireless/ar9170/Kconfig rename to drivers/net/wireless/ath/ar9170/Kconfig diff --git a/drivers/net/wireless/ar9170/Makefile b/drivers/net/wireless/ath/ar9170/Makefile similarity index 100% rename from drivers/net/wireless/ar9170/Makefile rename to drivers/net/wireless/ath/ar9170/Makefile diff --git a/drivers/net/wireless/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h similarity index 99% rename from drivers/net/wireless/ar9170/ar9170.h rename to drivers/net/wireless/ath/ar9170/ar9170.h index 87c19859ba70..f797495faa56 100644 --- a/drivers/net/wireless/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h @@ -48,7 +48,7 @@ #include "eeprom.h" #include "hw.h" -#include "../ath/regd.h" +#include "../regd.h" #define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1) diff --git a/drivers/net/wireless/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c similarity index 100% rename from drivers/net/wireless/ar9170/cmd.c rename to drivers/net/wireless/ath/ar9170/cmd.c diff --git a/drivers/net/wireless/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h similarity index 100% rename from drivers/net/wireless/ar9170/cmd.h rename to drivers/net/wireless/ath/ar9170/cmd.h diff --git a/drivers/net/wireless/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h similarity index 100% rename from drivers/net/wireless/ar9170/eeprom.h rename to drivers/net/wireless/ath/ar9170/eeprom.h diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h similarity index 100% rename from drivers/net/wireless/ar9170/hw.h rename to drivers/net/wireless/ath/ar9170/hw.h diff --git a/drivers/net/wireless/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c similarity index 100% rename from drivers/net/wireless/ar9170/led.c rename to drivers/net/wireless/ath/ar9170/led.c diff --git a/drivers/net/wireless/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c similarity index 100% rename from drivers/net/wireless/ar9170/mac.c rename to drivers/net/wireless/ath/ar9170/mac.c diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c similarity index 100% rename from drivers/net/wireless/ar9170/main.c rename to drivers/net/wireless/ath/ar9170/main.c diff --git a/drivers/net/wireless/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c similarity index 100% rename from drivers/net/wireless/ar9170/phy.c rename to drivers/net/wireless/ath/ar9170/phy.c diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c similarity index 100% rename from drivers/net/wireless/ar9170/usb.c rename to drivers/net/wireless/ath/ar9170/usb.c diff --git a/drivers/net/wireless/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h similarity index 100% rename from drivers/net/wireless/ar9170/usb.h rename to drivers/net/wireless/ath/ar9170/usb.h diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig similarity index 100% rename from drivers/net/wireless/ath5k/Kconfig rename to drivers/net/wireless/ath/ath5k/Kconfig diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile similarity index 100% rename from drivers/net/wireless/ath5k/Makefile rename to drivers/net/wireless/ath/ath5k/Makefile diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h similarity index 99% rename from drivers/net/wireless/ath5k/ath5k.h rename to drivers/net/wireless/ath/ath5k/ath5k.h index 48c18d11c507..60c6d2edc4b9 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -27,7 +27,7 @@ #include #include -#include "../ath/regd.h" +#include "../regd.h" /* RX/TX descriptor hw structs * TODO: Driver part should only see sw structs */ diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c similarity index 100% rename from drivers/net/wireless/ath5k/attach.c rename to drivers/net/wireless/ath/ath5k/attach.c diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c similarity index 100% rename from drivers/net/wireless/ath5k/base.c rename to drivers/net/wireless/ath/ath5k/base.c diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h similarity index 100% rename from drivers/net/wireless/ath5k/base.h rename to drivers/net/wireless/ath/ath5k/base.h diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c similarity index 100% rename from drivers/net/wireless/ath5k/caps.c rename to drivers/net/wireless/ath/ath5k/caps.c diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c similarity index 100% rename from drivers/net/wireless/ath5k/debug.c rename to drivers/net/wireless/ath/ath5k/debug.c diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h similarity index 100% rename from drivers/net/wireless/ath5k/debug.h rename to drivers/net/wireless/ath/ath5k/debug.h diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c similarity index 100% rename from drivers/net/wireless/ath5k/desc.c rename to drivers/net/wireless/ath/ath5k/desc.c diff --git a/drivers/net/wireless/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h similarity index 100% rename from drivers/net/wireless/ath5k/desc.h rename to drivers/net/wireless/ath/ath5k/desc.h diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c similarity index 100% rename from drivers/net/wireless/ath5k/dma.c rename to drivers/net/wireless/ath/ath5k/dma.c diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c similarity index 100% rename from drivers/net/wireless/ath5k/eeprom.c rename to drivers/net/wireless/ath/ath5k/eeprom.c diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h similarity index 100% rename from drivers/net/wireless/ath5k/eeprom.h rename to drivers/net/wireless/ath/ath5k/eeprom.h diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath/ath5k/gpio.c similarity index 100% rename from drivers/net/wireless/ath5k/gpio.c rename to drivers/net/wireless/ath/ath5k/gpio.c diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c similarity index 100% rename from drivers/net/wireless/ath5k/initvals.c rename to drivers/net/wireless/ath/ath5k/initvals.c diff --git a/drivers/net/wireless/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c similarity index 100% rename from drivers/net/wireless/ath5k/led.c rename to drivers/net/wireless/ath/ath5k/led.c diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c similarity index 100% rename from drivers/net/wireless/ath5k/pcu.c rename to drivers/net/wireless/ath/ath5k/pcu.c diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c similarity index 100% rename from drivers/net/wireless/ath5k/phy.c rename to drivers/net/wireless/ath/ath5k/phy.c diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c similarity index 100% rename from drivers/net/wireless/ath5k/qcu.c rename to drivers/net/wireless/ath/ath5k/qcu.c diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h similarity index 100% rename from drivers/net/wireless/ath5k/reg.h rename to drivers/net/wireless/ath/ath5k/reg.h diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c similarity index 100% rename from drivers/net/wireless/ath5k/reset.c rename to drivers/net/wireless/ath/ath5k/reset.c diff --git a/drivers/net/wireless/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h similarity index 100% rename from drivers/net/wireless/ath5k/rfbuffer.h rename to drivers/net/wireless/ath/ath5k/rfbuffer.h diff --git a/drivers/net/wireless/ath5k/rfgain.h b/drivers/net/wireless/ath/ath5k/rfgain.h similarity index 100% rename from drivers/net/wireless/ath5k/rfgain.h rename to drivers/net/wireless/ath/ath5k/rfgain.h diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig similarity index 100% rename from drivers/net/wireless/ath9k/Kconfig rename to drivers/net/wireless/ath/ath9k/Kconfig diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile similarity index 100% rename from drivers/net/wireless/ath9k/Makefile rename to drivers/net/wireless/ath/ath9k/Makefile diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c similarity index 100% rename from drivers/net/wireless/ath9k/ahb.c rename to drivers/net/wireless/ath/ath9k/ahb.c diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c similarity index 100% rename from drivers/net/wireless/ath9k/ani.c rename to drivers/net/wireless/ath/ath9k/ani.c diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h similarity index 100% rename from drivers/net/wireless/ath9k/ani.h rename to drivers/net/wireless/ath/ath9k/ani.h diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h similarity index 100% rename from drivers/net/wireless/ath9k/ath9k.h rename to drivers/net/wireless/ath/ath9k/ath9k.h diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c similarity index 100% rename from drivers/net/wireless/ath9k/beacon.c rename to drivers/net/wireless/ath/ath9k/beacon.c diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c similarity index 100% rename from drivers/net/wireless/ath9k/calib.c rename to drivers/net/wireless/ath/ath9k/calib.c diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h similarity index 100% rename from drivers/net/wireless/ath9k/calib.h rename to drivers/net/wireless/ath/ath9k/calib.h diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c similarity index 100% rename from drivers/net/wireless/ath9k/debug.c rename to drivers/net/wireless/ath/ath9k/debug.c diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h similarity index 100% rename from drivers/net/wireless/ath9k/debug.h rename to drivers/net/wireless/ath/ath9k/debug.h diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c similarity index 100% rename from drivers/net/wireless/ath9k/eeprom.c rename to drivers/net/wireless/ath/ath9k/eeprom.c diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h similarity index 100% rename from drivers/net/wireless/ath9k/eeprom.h rename to drivers/net/wireless/ath/ath9k/eeprom.h diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c similarity index 100% rename from drivers/net/wireless/ath9k/hw.c rename to drivers/net/wireless/ath/ath9k/hw.c diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h similarity index 99% rename from drivers/net/wireless/ath9k/hw.h rename to drivers/net/wireless/ath/ath9k/hw.h index 984ac7da09d6..5c4127e6c1c6 100644 --- a/drivers/net/wireless/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -28,7 +28,7 @@ #include "reg.h" #include "phy.h" -#include "../ath/regd.h" +#include "../regd.h" #define ATHEROS_VENDOR_ID 0x168c #define AR5416_DEVID_PCI 0x0023 diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h similarity index 100% rename from drivers/net/wireless/ath9k/initvals.h rename to drivers/net/wireless/ath/ath9k/initvals.h diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c similarity index 100% rename from drivers/net/wireless/ath9k/mac.c rename to drivers/net/wireless/ath/ath9k/mac.c diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h similarity index 100% rename from drivers/net/wireless/ath9k/mac.h rename to drivers/net/wireless/ath/ath9k/mac.h diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c similarity index 100% rename from drivers/net/wireless/ath9k/main.c rename to drivers/net/wireless/ath/ath9k/main.c diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c similarity index 100% rename from drivers/net/wireless/ath9k/pci.c rename to drivers/net/wireless/ath/ath9k/pci.c diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c similarity index 100% rename from drivers/net/wireless/ath9k/phy.c rename to drivers/net/wireless/ath/ath9k/phy.c diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h similarity index 100% rename from drivers/net/wireless/ath9k/phy.h rename to drivers/net/wireless/ath/ath9k/phy.h diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c similarity index 100% rename from drivers/net/wireless/ath9k/rc.c rename to drivers/net/wireless/ath/ath9k/rc.c diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h similarity index 100% rename from drivers/net/wireless/ath9k/rc.h rename to drivers/net/wireless/ath/ath9k/rc.h diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c similarity index 100% rename from drivers/net/wireless/ath9k/recv.c rename to drivers/net/wireless/ath/ath9k/recv.c diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h similarity index 100% rename from drivers/net/wireless/ath9k/reg.h rename to drivers/net/wireless/ath/ath9k/reg.h diff --git a/drivers/net/wireless/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c similarity index 100% rename from drivers/net/wireless/ath9k/virtual.c rename to drivers/net/wireless/ath/ath9k/virtual.c diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c similarity index 100% rename from drivers/net/wireless/ath9k/xmit.c rename to drivers/net/wireless/ath/ath9k/xmit.c -- GitLab From 6b2b2ffbef7750e51bfa74e92229ecee10b59307 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 30 Mar 2009 22:30:34 -0400 Subject: [PATCH 0552/6080] ath: space cleanup Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 3ccf21cceb5a..4b5c851b81ff 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -173,9 +173,9 @@ static bool ath_is_radar_freq(u16 center_freq) * received a beacon on a channel we can enable active scan and * adhoc (or beaconing). */ -static void ath_reg_apply_beaconing_flags( - struct wiphy *wiphy, - enum nl80211_reg_initiator initiator) +static void +ath_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) { enum ieee80211_band band; struct ieee80211_supported_band *sband; @@ -232,9 +232,9 @@ static void ath_reg_apply_beaconing_flags( } /* Allows active scan scan on Ch 12 and 13 */ -static void ath_reg_apply_active_scan_flags( - struct wiphy *wiphy, - enum nl80211_reg_initiator initiator) +static void +ath_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; @@ -316,8 +316,8 @@ static void ath_reg_apply_radar_flags(struct wiphy *wiphy) } static void ath_reg_apply_world_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator, - struct ath_regulatory *reg) + enum nl80211_reg_initiator initiator, + struct ath_regulatory *reg) { switch (reg->regpair->regDmnEnum) { case 0x60: @@ -335,7 +335,8 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy, } int ath_reg_notifier_apply(struct wiphy *wiphy, - struct regulatory_request *request, struct ath_regulatory *reg) + struct regulatory_request *request, + struct ath_regulatory *reg) { /* We always apply this */ ath_reg_apply_radar_flags(wiphy); @@ -433,8 +434,10 @@ ath_get_regpair(int regdmn) return NULL; } -static int ath_regd_init_wiphy(struct ath_regulatory *reg, struct wiphy *wiphy, - int (*reg_notifier)(struct wiphy *wiphy, +static int +ath_regd_init_wiphy(struct ath_regulatory *reg, + struct wiphy *wiphy, + int (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)) { const struct ieee80211_regdomain *regd; @@ -464,9 +467,11 @@ static int ath_regd_init_wiphy(struct ath_regulatory *reg, struct wiphy *wiphy, return 0; } -int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, - int (*reg_notifier)(struct wiphy *wiphy, - struct regulatory_request *request)) +int +ath_regd_init(struct ath_regulatory *reg, + struct wiphy *wiphy, + int (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) { struct country_code_to_enum_rd *country = NULL; u16 regdmn; -- GitLab From 75c2148fa5330c6de741fc96e3308f57d846a6b4 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 30 Mar 2009 22:30:35 -0400 Subject: [PATCH 0553/6080] ath5k: sparse fix ath5k_led_on needs to be static drivers/net/wireless/ath/ath5k/led.c:81:6: warning: symbol 'ath5k_led_on' was not declared. Should it be static? Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/led.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 19555fb79c9b..006f7716168e 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -78,7 +78,7 @@ void ath5k_led_enable(struct ath5k_softc *sc) } } -void ath5k_led_on(struct ath5k_softc *sc) +static void ath5k_led_on(struct ath5k_softc *sc) { if (!test_bit(ATH_STAT_LEDSOFT, sc->status)) return; -- GitLab From 18a8365992a8041aa178ae9ad5f0d951d0457230 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 31 Mar 2009 12:12:05 +0200 Subject: [PATCH 0554/6080] cfg80211: introduce scan IE limit attribute This patch introduces a new attribute for a wiphy that tells userspace how long the information elements added to a probe request frame can be at most. It also updates the at76 to advertise that it cannot support that, and, for now until I can fix that, iwlwifi too. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/at76c50x-usb.c | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 1 + include/linux/nl80211.h | 4 ++++ include/net/wireless.h | 1 + net/mac80211/main.c | 13 ++++++++++++- net/mac80211/util.c | 2 ++ net/wireless/nl80211.c | 7 +++++++ 7 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 69248ded5102..55f947ac56d1 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c @@ -2250,6 +2250,7 @@ static int at76_init_new_device(struct at76_priv *priv, /* mac80211 initialisation */ priv->hw->wiphy->max_scan_ssids = 1; + priv->hw->wiphy->max_scan_ie_len = 0; priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band; priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 82abb1f9087f..ef55f91374a1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1306,6 +1306,7 @@ int iwl_setup_mac(struct iwl_priv *priv) hw->wiphy->custom_regulatory = true; hw->wiphy->max_scan_ssids = 1; + hw->wiphy->max_scan_ie_len = 0; /* XXX for now */ /* Default value; 4 EDCA QOS priorities */ hw->queues = 4; diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 27f230f063b3..209cacee5285 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -390,6 +390,8 @@ enum nl80211_commands { * * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with * a single scan request, a wiphy attribute. + * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements + * that can be added to a scan request * * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz) * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive @@ -507,6 +509,8 @@ enum nl80211_attrs { NL80211_ATTR_KEY_TYPE, + NL80211_ATTR_MAX_SCAN_IE_LEN, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/wireless.h b/include/net/wireless.h index 64a76208580c..2bcdeda46d81 100644 --- a/include/net/wireless.h +++ b/include/net/wireless.h @@ -222,6 +222,7 @@ struct wiphy { int bss_priv_size; u8 max_scan_ssids; + u16 max_scan_ie_len; /* If multiple wiphys are registered and you're handed e.g. * a regular netdev with assigned ieee80211_ptr, you won't diff --git a/net/mac80211/main.c b/net/mac80211/main.c index fbcbed6cad01..ee58a7873699 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -728,7 +728,18 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, return NULL; wiphy->privid = mac80211_wiphy_privid; - wiphy->max_scan_ssids = 4; + + if (!ops->hw_scan) { + /* For hw_scan, driver needs to set these up. */ + wiphy->max_scan_ssids = 4; + + /* we support a maximum of 32 rates in cfg80211 */ + wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN + - 2 - 32 /* SSID */ + - 4 - 32 /* (ext) supp rates */; + + } + /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ wiphy->bss_priv_size = sizeof(struct ieee80211_bss) - sizeof(struct cfg80211_bss); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index fdf432f14554..05caf34f31da 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -890,6 +890,8 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, *pos = rate->bitrate / 5; } + /* if adding more here, adjust max_scan_ie_len */ + if (ie) memcpy(skb_put(skb, ie_len), ie, ie_len); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1394115cde95..447fa1790b4e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -181,6 +181,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, dev->wiphy.max_scan_ssids); + NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, + dev->wiphy.max_scan_ie_len); nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); if (!nl_modes) @@ -2528,6 +2530,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) else ie_len = 0; + if (ie_len > wiphy->max_scan_ie_len) { + err = -EINVAL; + goto out; + } + request = kzalloc(sizeof(*request) + sizeof(*ssid) * n_ssids + sizeof(channel) * n_channels -- GitLab From de95a54b1aebe5592cae971ca5e5d9ec6a381a17 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Apr 2009 11:58:36 +0200 Subject: [PATCH 0555/6080] mac80211: pass all probe request IEs to driver Instead of just passing the cfg80211-requested IEs, pass the locally generated ones as well. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 2 +- include/net/mac80211.h | 13 ++++--- net/mac80211/ieee80211_i.h | 9 ++++- net/mac80211/main.c | 49 +++++++++++++++-------- net/mac80211/scan.c | 24 +++++++++++- net/mac80211/util.c | 79 +++++++++++++++++++++++--------------- net/wireless/nl80211.c | 3 +- 7 files changed, 123 insertions(+), 56 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 2b1f6c69773c..d303c269a693 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -503,7 +503,7 @@ struct cfg80211_scan_request { int n_ssids; struct ieee80211_channel **channels; u32 n_channels; - u8 *ie; + const u8 *ie; size_t ie_len; /* internal */ diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3b83a80e3fe0..2c6f976831b5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1330,11 +1330,14 @@ enum ieee80211_ampdu_mlme_action { * the scan state machine in stack. The scan must honour the channel * configuration done by the regulatory agent in the wiphy's * registered bands. The hardware (or the driver) needs to make sure - * that power save is disabled. When the scan finishes, - * ieee80211_scan_completed() must be called; note that it also must - * be called when the scan cannot finish because the hardware is - * turned off! Anything else is a bug! Returns a negative error code - * which will be seen in userspace. + * that power save is disabled. + * The @req ie/ie_len members are rewritten by mac80211 to contain the + * entire IEs after the SSID, so that drivers need not look at these + * at all but just send them after the SSID -- mac80211 includes the + * (extended) supported rates and HT information (where applicable). + * When the scan finishes, ieee80211_scan_completed() must be called; + * note that it also must be called when the scan cannot finish due to + * any error unless this callback returned a negative error code. * * @sw_scan_start: Notifier function that is called just before a software scan * is started. Can be NULL, if the driver doesn't need this notification. diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 73d9f894ed5d..cb80a80504e6 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -671,7 +671,10 @@ struct ieee80211_local { struct cfg80211_scan_request int_scan_req; struct cfg80211_scan_request *scan_req; struct ieee80211_channel *scan_channel; + const u8 *orig_ies; + int orig_ies_len; int scan_channel_idx; + int scan_ies_len; enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; unsigned long last_scan_completed; @@ -1090,9 +1093,11 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, u16 transaction, u16 auth_alg, u8 *extra, size_t extra_len, const u8 *bssid, int encrypt); +int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, + const u8 *ie, size_t ie_len); void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, - u8 *ssid, size_t ssid_len, - u8 *ie, size_t ie_len); + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len); void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, const size_t supp_rates_len, diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ee58a7873699..b3bbe78821d9 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -729,22 +729,12 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, wiphy->privid = mac80211_wiphy_privid; - if (!ops->hw_scan) { - /* For hw_scan, driver needs to set these up. */ - wiphy->max_scan_ssids = 4; - - /* we support a maximum of 32 rates in cfg80211 */ - wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN - - 2 - 32 /* SSID */ - - 4 - 32 /* (ext) supp rates */; - - } - /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ wiphy->bss_priv_size = sizeof(struct ieee80211_bss) - sizeof(struct cfg80211_bss); local = wiphy_priv(wiphy); + local->hw.wiphy = wiphy; local->hw.priv = (char *)local + @@ -831,7 +821,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) enum ieee80211_band band; struct net_device *mdev; struct ieee80211_master_priv *mpriv; - int channels, i, j; + int channels, i, j, max_bitrates; /* * generic code guarantees at least one band, @@ -839,18 +829,23 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) * that hw.conf.channel is assigned */ channels = 0; + max_bitrates = 0; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { struct ieee80211_supported_band *sband; sband = local->hw.wiphy->bands[band]; - if (sband && !local->oper_channel) { + if (!sband) + continue; + if (!local->oper_channel) { /* init channel we're on */ local->hw.conf.channel = local->oper_channel = local->scan_channel = &sband->channels[0]; } - if (sband) - channels += sband->n_channels; + channels += sband->n_channels; + + if (max_bitrates < sband->n_bitrates) + max_bitrates = sband->n_bitrates; } local->int_scan_req.n_channels = channels; @@ -870,6 +865,30 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; + /* + * Calculate scan IE length -- we need this to alloc + * memory and to subtract from the driver limit. It + * includes the (extended) supported rates and HT + * information -- SSID is the driver's responsibility. + */ + local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */ + + if (!local->ops->hw_scan) { + /* For hw_scan, driver needs to set these up. */ + local->hw.wiphy->max_scan_ssids = 4; + local->hw.wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; + } + + /* + * If the driver supports any scan IEs, then assume the + * limit includes the IEs mac80211 will add, otherwise + * leave it at zero and let the driver sort it out; we + * still pass our IEs to the driver but userspace will + * not be allowed to in that case. + */ + if (local->hw.wiphy->max_scan_ie_len) + local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; + result = wiphy_register(local->hw.wiphy); if (result < 0) goto fail_wiphy_register; diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 3bf9839f5916..4ec1bfc7f6a9 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -285,6 +285,12 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) if (WARN_ON(!local->scan_req)) return; + if (local->hw_scanning) { + kfree(local->scan_req->ie); + local->scan_req->ie = local->orig_ies; + local->scan_req->ie_len = local->orig_ies_len; + } + if (local->scan_req != &local->int_scan_req) cfg80211_scan_done(local->scan_req, aborted); local->scan_req = NULL; @@ -457,12 +463,28 @@ int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata, } if (local->ops->hw_scan) { - int rc; + u8 *ies; + int rc, ielen; + + ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN + + local->scan_ies_len + req->ie_len, GFP_KERNEL); + if (!ies) + return -ENOMEM; + + ielen = ieee80211_build_preq_ies(local, ies, + req->ie, req->ie_len); + local->orig_ies = req->ie; + local->orig_ies_len = req->ie_len; + req->ie = ies; + req->ie_len = ielen; local->hw_scanning = true; rc = local->ops->hw_scan(local_to_hw(local), req); if (rc) { local->hw_scanning = false; + kfree(ies); + req->ie_len = local->orig_ies_len; + req->ie = local->orig_ies; return rc; } local->scan_sdata = scan_sdata; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 05caf34f31da..72b091317a7c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -831,16 +831,57 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, ieee80211_tx_skb(sdata, skb, encrypt); } +int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, + const u8 *ie, size_t ie_len) +{ + struct ieee80211_supported_band *sband; + u8 *pos, *supp_rates_len, *esupp_rates_len = NULL; + int i; + + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + + pos = buffer; + + *pos++ = WLAN_EID_SUPP_RATES; + supp_rates_len = pos; + *pos++ = 0; + + for (i = 0; i < sband->n_bitrates; i++) { + struct ieee80211_rate *rate = &sband->bitrates[i]; + + if (esupp_rates_len) { + *esupp_rates_len += 1; + } else if (*supp_rates_len == 8) { + *pos++ = WLAN_EID_EXT_SUPP_RATES; + esupp_rates_len = pos; + *pos++ = 1; + } else + *supp_rates_len += 1; + + *pos++ = rate->bitrate / 5; + } + + /* + * If adding more here, adjust code in main.c + * that calculates local->scan_ies_len. + */ + + if (ie) { + memcpy(pos, ie, ie_len); + pos += ie_len; + } + + return pos - buffer; +} + void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, - u8 *ssid, size_t ssid_len, - u8 *ie, size_t ie_len) + const u8 *ssid, size_t ssid_len, + const u8 *ie, size_t ie_len) { struct ieee80211_local *local = sdata->local; - struct ieee80211_supported_band *sband; struct sk_buff *skb; struct ieee80211_mgmt *mgmt; - u8 *pos, *supp_rates, *esupp_rates = NULL; - int i; + u8 *pos; skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + ie_len); @@ -867,33 +908,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, *pos++ = WLAN_EID_SSID; *pos++ = ssid_len; memcpy(pos, ssid, ssid_len); + pos += ssid_len; - supp_rates = skb_put(skb, 2); - supp_rates[0] = WLAN_EID_SUPP_RATES; - supp_rates[1] = 0; - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - - for (i = 0; i < sband->n_bitrates; i++) { - struct ieee80211_rate *rate = &sband->bitrates[i]; - if (esupp_rates) { - pos = skb_put(skb, 1); - esupp_rates[1]++; - } else if (supp_rates[1] == 8) { - esupp_rates = skb_put(skb, 3); - esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES; - esupp_rates[1] = 1; - pos = &esupp_rates[2]; - } else { - pos = skb_put(skb, 1); - supp_rates[1]++; - } - *pos = rate->bitrate / 5; - } - - /* if adding more here, adjust max_scan_ie_len */ - - if (ie) - memcpy(skb_put(skb, ie_len), ie, ie_len); + skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len)); ieee80211_tx_skb(sdata, skb, 0); } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 447fa1790b4e..68c51022e9dd 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -2597,7 +2597,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_IE]) { request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); - memcpy(request->ie, nla_data(info->attrs[NL80211_ATTR_IE]), + memcpy((void *)request->ie, + nla_data(info->attrs[NL80211_ATTR_IE]), request->ie_len); } -- GitLab From 5ef2d41afb7fce2315d12a8aaebe0c9f1b50755b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 31 Mar 2009 12:12:07 +0200 Subject: [PATCH 0556/6080] mac80211: include HT capabilities in probe request Include the HT capabilities in the probe request frame. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/main.c | 5 +++++ net/mac80211/util.c | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index b3bbe78821d9..679b3a14f11f 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -822,6 +822,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) struct net_device *mdev; struct ieee80211_master_priv *mpriv; int channels, i, j, max_bitrates; + bool supp_ht; /* * generic code guarantees at least one band, @@ -830,6 +831,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) */ channels = 0; max_bitrates = 0; + supp_ht = false; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { struct ieee80211_supported_band *sband; @@ -846,6 +848,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (max_bitrates < sband->n_bitrates) max_bitrates = sband->n_bitrates; + supp_ht = supp_ht || sband->ht_cap.ht_supported; } local->int_scan_req.n_channels = channels; @@ -872,6 +875,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) * information -- SSID is the driver's responsibility. */ local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */ + if (supp_ht) + local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); if (!local->ops->hw_scan) { /* For hw_scan, driver needs to set these up. */ diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 72b091317a7c..1ff83532120f 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -861,6 +861,22 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, *pos++ = rate->bitrate / 5; } + if (sband->ht_cap.ht_supported) { + __le16 tmp = cpu_to_le16(sband->ht_cap.cap); + + *pos++ = WLAN_EID_HT_CAPABILITY; + *pos++ = sizeof(struct ieee80211_ht_cap); + memset(pos, 0, sizeof(struct ieee80211_ht_cap)); + memcpy(pos, &tmp, sizeof(u16)); + pos += sizeof(u16); + /* TODO: needs a define here for << 2 */ + *pos++ = sband->ht_cap.ampdu_factor | + (sband->ht_cap.ampdu_density << 2); + memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); + pos += sizeof(sband->ht_cap.mcs); + pos += 2 + 4 + 1; /* ext info, BF cap, antsel */ + } + /* * If adding more here, adjust code in main.c * that calculates local->scan_ies_len. -- GitLab From 66174bbea0b9c5bd4b7d060fed26bf5ec912c422 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 1 Apr 2009 17:23:54 +0300 Subject: [PATCH 0557/6080] mac80211: Report rejected association to user space SME When using nl80211 association, we need to send association response with a failure code to user space SME instead of just internally trying to send out the same (re)association request again couple of times. This fixes problems in association process getting stuck on a failure when user space is not notified in any way that something actually failed. Signed-off-by: Jouni Malinen Acked-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4ce5b9c22324..90267afa8e69 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1374,6 +1374,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, * association next time. This works around some broken APs * which do not correctly reject reassociation requests. */ ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET; + cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len); + if (ifmgd->flags & IEEE80211_STA_EXT_SME) { + /* Wait for SME to decide what to do next */ + ifmgd->state = IEEE80211_STA_MLME_DISABLED; + } return; } -- GitLab From 910cfee363feda81cd5af4939ed9e0d27677b43f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 1 Apr 2009 10:42:36 -0500 Subject: [PATCH 0558/6080] b43legacy: Do not select HW_RANDOM Auto-depend on HW_RANDOM, rather than "select"ing it. This way the user has the choice to enable or disable HWRNG support. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/Kconfig | 8 +++++++- drivers/net/wireless/b43legacy/b43legacy.h | 2 ++ drivers/net/wireless/b43legacy/main.c | 8 +++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index aef2298d37ac..d4f628a74bbd 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig @@ -3,7 +3,6 @@ config B43LEGACY depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA select SSB select FW_LOADER - select HW_RANDOM ---help--- b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and BCM4303) and early model 802.11g chips (BCM4306 Ver. 2) used in the @@ -51,6 +50,13 @@ config B43LEGACY_RFKILL depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY) default y +# This config option automatically enables b43 HW-RNG support, +# if the HW-RNG core is enabled. +config B43LEGACY_HWRNG + bool + depends on B43LEGACY && (HW_RANDOM = y || HW_RANDOM = B43LEGACY) + default y + config B43LEGACY_DEBUG bool "Broadcom 43xx-legacy debugging" depends on B43LEGACY diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 97b0e06dfe21..4cdde4ad17c0 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -596,9 +596,11 @@ struct b43legacy_wl { /* Stats about the wireless interface */ struct ieee80211_low_level_stats ieee_stats; +#ifdef CONFIG_B43LEGACY_HWRNG struct hwrng rng; u8 rng_initialized; char rng_name[30 + 1]; +#endif /* The RF-kill button */ struct b43legacy_rfkill rfkill; diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 879edc786713..81dbbc1c591a 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2297,6 +2297,7 @@ static void b43legacy_security_init(struct b43legacy_wldev *dev) dev->max_nr_keys - 8); } +#ifdef CONFIG_B43LEGACY_HWRNG static int b43legacy_rng_read(struct hwrng *rng, u32 *data) { struct b43legacy_wl *wl = (struct b43legacy_wl *)rng->priv; @@ -2312,17 +2313,21 @@ static int b43legacy_rng_read(struct hwrng *rng, u32 *data) return (sizeof(u16)); } +#endif static void b43legacy_rng_exit(struct b43legacy_wl *wl) { +#ifdef CONFIG_B43LEGACY_HWRNG if (wl->rng_initialized) hwrng_unregister(&wl->rng); +#endif } static int b43legacy_rng_init(struct b43legacy_wl *wl) { - int err; + int err = 0; +#ifdef CONFIG_B43LEGACY_HWRNG snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name), "%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy)); wl->rng.name = wl->rng_name; @@ -2336,6 +2341,7 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl) "number generator (%d)\n", err); } +#endif return err; } -- GitLab From 64cdb0e3b8a5e5393cb64328ce0c844b7cf3a40e Mon Sep 17 00:00:00 2001 From: Fabio Rossi Date: Wed, 1 Apr 2009 20:37:50 +0200 Subject: [PATCH 0559/6080] ath5k: fix interpolation with equal power levels When the EEPROM contains weird values for the power levels we have to fix the interpolation process. Signed-off-by: Fabio Rossi Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/phy.c | 49 ++++++++++++++++------------ 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 9e2faae5ae94..b48b29dca3d2 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1487,28 +1487,35 @@ ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR, { s8 tmp; s16 min_pwrL, min_pwrR; - s16 pwr_i = pwrL[0]; - - do { - pwr_i--; - tmp = (s8) ath5k_get_interpolated_value(pwr_i, - pwrL[0], pwrL[1], - stepL[0], stepL[1]); - - } while (tmp > 1); - - min_pwrL = pwr_i; - - pwr_i = pwrR[0]; - do { - pwr_i--; - tmp = (s8) ath5k_get_interpolated_value(pwr_i, - pwrR[0], pwrR[1], - stepR[0], stepR[1]); - - } while (tmp > 1); + s16 pwr_i; + + if (pwrL[0] == pwrL[1]) + min_pwrL = pwrL[0]; + else { + pwr_i = pwrL[0]; + do { + pwr_i--; + tmp = (s8) ath5k_get_interpolated_value(pwr_i, + pwrL[0], pwrL[1], + stepL[0], stepL[1]); + } while (tmp > 1); + + min_pwrL = pwr_i; + } - min_pwrR = pwr_i; + if (pwrR[0] == pwrR[1]) + min_pwrR = pwrR[0]; + else { + pwr_i = pwrR[0]; + do { + pwr_i--; + tmp = (s8) ath5k_get_interpolated_value(pwr_i, + pwrR[0], pwrR[1], + stepR[0], stepR[1]); + } while (tmp > 1); + + min_pwrR = pwr_i; + } /* Keep the right boundary so that it works for both curves */ return max(min_pwrL, min_pwrR); -- GitLab From 11397a656f14466421bac503f0f3aaadf9486120 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 1 Apr 2009 14:33:23 -0700 Subject: [PATCH 0560/6080] iwlwifi: adding triple stream rate support for MIMO3 Adding ht triple_stream_basic_rates for MIMO3 supports Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index ef55f91374a1..84ac1cec6f5b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1117,6 +1117,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode) memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN); priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; + priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff; } EXPORT_SYMBOL(iwl_connection_init_rx_config); -- GitLab From 584a0f00636d34f71a80f5b550a305f1a1620693 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 1 Apr 2009 14:33:24 -0700 Subject: [PATCH 0561/6080] iwlwifi: adding MIMO3 support in rate scaling Separated the MIMO tpt matrix into MIMO2 and MIMO3, adding MIMO3 support in rate scaling algorithm. If the device support 3x3, then utilize all three antenna (A/B/C) for tx to improve throughput. Adding rs_switch_to_mimo3() function to allow switch to mimo3 modulation mode from other modes(legacy/siso/mimo2). Adding rs_move_mimo3_to_other() function to allow switch from mimo3 modulation mode to either siso or mimo2; also support toggle between SGI and NGI. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 331 ++++++++++++++++++++-- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 18 ++ 2 files changed, 325 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index cab7842a73aa..7cdbcfe483f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -191,7 +191,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits * "G" is the only table that supports CCK (the first 4 rates). */ -/*FIXME:RS:need to separate tables for MIMO2/MIMO3*/ + static s32 expected_tpt_A[IWL_RATE_COUNT] = { 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186 }; @@ -208,11 +208,11 @@ static s32 expected_tpt_siso20MHzSGI[IWL_RATE_COUNT] = { 0, 0, 0, 0, 46, 46, 82, 110, 132, 168, 192, 202, 211 }; -static s32 expected_tpt_mimo20MHz[IWL_RATE_COUNT] = { +static s32 expected_tpt_mimo2_20MHz[IWL_RATE_COUNT] = { 0, 0, 0, 0, 74, 74, 123, 155, 179, 214, 236, 244, 251 }; -static s32 expected_tpt_mimo20MHzSGI[IWL_RATE_COUNT] = { +static s32 expected_tpt_mimo2_20MHzSGI[IWL_RATE_COUNT] = { 0, 0, 0, 0, 81, 81, 131, 164, 188, 222, 243, 251, 257 }; @@ -224,14 +224,31 @@ static s32 expected_tpt_siso40MHzSGI[IWL_RATE_COUNT] = { 0, 0, 0, 0, 83, 83, 135, 169, 193, 229, 250, 257, 264 }; -static s32 expected_tpt_mimo40MHz[IWL_RATE_COUNT] = { +static s32 expected_tpt_mimo2_40MHz[IWL_RATE_COUNT] = { 0, 0, 0, 0, 123, 123, 182, 214, 235, 264, 279, 285, 289 }; -static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = { +static s32 expected_tpt_mimo2_40MHzSGI[IWL_RATE_COUNT] = { 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 }; +/* Expected throughput metric MIMO3 */ +static s32 expected_tpt_mimo3_20MHz[IWL_RATE_COUNT] = { + 0, 0, 0, 0, 99, 99, 153, 186, 208, 239, 256, 263, 268 +}; + +static s32 expected_tpt_mimo3_20MHzSGI[IWL_RATE_COUNT] = { + 0, 0, 0, 0, 106, 106, 162, 194, 215, 246, 262, 268, 273 +}; + +static s32 expected_tpt_mimo3_40MHz[IWL_RATE_COUNT] = { + 0, 0, 0, 0, 152, 152, 211, 239, 255, 279, 290, 294, 297 +}; + +static s32 expected_tpt_mimo3_40MHzSGI[IWL_RATE_COUNT] = { + 0, 0, 0, 0, 160, 160, 219, 245, 261, 284, 294, 297, 300 +}; + static inline u8 rs_extract_rate(u32 rate_n_flags) { return (u8)(rate_n_flags & 0xFF); @@ -1011,17 +1028,26 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta, tbl->expected_tpt = expected_tpt_siso20MHzSGI; else tbl->expected_tpt = expected_tpt_siso20MHz; - - } else if (is_mimo(tbl->lq_type)) { /* FIXME:need to separate mimo2/3 */ + } else if (is_mimo2(tbl->lq_type)) { + if (tbl->is_fat && !lq_sta->is_dup) + if (tbl->is_SGI) + tbl->expected_tpt = expected_tpt_mimo2_40MHzSGI; + else + tbl->expected_tpt = expected_tpt_mimo2_40MHz; + else if (tbl->is_SGI) + tbl->expected_tpt = expected_tpt_mimo2_20MHzSGI; + else + tbl->expected_tpt = expected_tpt_mimo2_20MHz; + } else if (is_mimo3(tbl->lq_type)) { if (tbl->is_fat && !lq_sta->is_dup) if (tbl->is_SGI) - tbl->expected_tpt = expected_tpt_mimo40MHzSGI; + tbl->expected_tpt = expected_tpt_mimo3_40MHzSGI; else - tbl->expected_tpt = expected_tpt_mimo40MHz; + tbl->expected_tpt = expected_tpt_mimo3_40MHz; else if (tbl->is_SGI) - tbl->expected_tpt = expected_tpt_mimo20MHzSGI; + tbl->expected_tpt = expected_tpt_mimo3_20MHzSGI; else - tbl->expected_tpt = expected_tpt_mimo20MHz; + tbl->expected_tpt = expected_tpt_mimo3_20MHz; } else tbl->expected_tpt = expected_tpt_G; } @@ -1130,7 +1156,7 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, } /* - * Set up search table for MIMO + * Set up search table for MIMO2 */ static int rs_switch_to_mimo2(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, @@ -1183,7 +1209,73 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index); IWL_DEBUG_RATE(priv, "LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask); + if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { + IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n", + rate, rate_mask); + return -1; + } + tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green); + + IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n", + tbl->current_rate, is_green); + return 0; +} + +/* + * Set up search table for MIMO3 + */ +static int rs_switch_to_mimo3(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, + struct ieee80211_conf *conf, + struct ieee80211_sta *sta, + struct iwl_scale_tbl_info *tbl, int index) +{ + u16 rate_mask; + s32 rate; + s8 is_green = lq_sta->is_green; + + if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) + return -1; + + if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) + == WLAN_HT_CAP_SM_PS_STATIC) + return -1; + + /* Need both Tx chains/antennas to support MIMO */ + if (priv->hw_params.tx_chains_num < 3) + return -1; + + IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n"); + + tbl->lq_type = LQ_MIMO3; + tbl->is_dup = lq_sta->is_dup; + tbl->action = 0; + rate_mask = lq_sta->active_mimo3_rate; + + if (priv->current_ht_config.supported_chan_width + == IWL_CHANNEL_WIDTH_40MHZ) + tbl->is_fat = 1; + else + tbl->is_fat = 0; + /* FIXME: - don't toggle SGI here + if (tbl->is_fat) { + if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY) + tbl->is_SGI = 1; + else + tbl->is_SGI = 0; + } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY) + tbl->is_SGI = 1; + else + tbl->is_SGI = 0; + */ + + rs_set_expected_tpt_table(lq_sta, tbl); + + rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index); + + IWL_DEBUG_RATE(priv, "LQ: MIMO3 best rate %d mask %X\n", + rate, rate_mask); if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) { IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n", rate, rate_mask); @@ -1342,9 +1434,29 @@ static int rs_move_legacy_other(struct iwl_priv *priv, goto out; } break; + + case IWL_LEGACY_SWITCH_MIMO3_ABC: + IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO3\n"); + + /* Set up search table to try MIMO3 */ + memcpy(search_tbl, tbl, sz); + search_tbl->is_SGI = 0; + + search_tbl->ant_type = ANT_ABC; + + if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type)) + break; + + ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta, + search_tbl, index); + if (!ret) { + lq_sta->action_counter = 0; + goto out; + } + break; } tbl->action++; - if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC) + if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; if (tbl->action == start_action) @@ -1357,7 +1469,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, out: lq_sta->search_better_tbl = 1; tbl->action++; - if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC) + if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; return 0; @@ -1457,9 +1569,23 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, rate_n_flags_from_tbl(priv, search_tbl, index, is_green); goto out; + case IWL_SISO_SWITCH_MIMO3_ABC: + IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n"); + memcpy(search_tbl, tbl, sz); + search_tbl->is_SGI = 0; + search_tbl->ant_type = ANT_ABC; + + if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type)) + break; + + ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta, + search_tbl, index); + if (!ret) + goto out; + break; } tbl->action++; - if (tbl->action > IWL_SISO_SWITCH_GI) + if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) tbl->action = IWL_SISO_SWITCH_ANTENNA1; if (tbl->action == start_action) @@ -1471,15 +1597,15 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, out: lq_sta->search_better_tbl = 1; tbl->action++; - if (tbl->action > IWL_SISO_SWITCH_GI) + if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC) tbl->action = IWL_SISO_SWITCH_ANTENNA1; return 0; } /* - * Try to switch to new modulation mode from MIMO + * Try to switch to new modulation mode from MIMO2 */ -static int rs_move_mimo_to_other(struct iwl_priv *priv, +static int rs_move_mimo2_to_other(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, struct ieee80211_conf *conf, struct ieee80211_sta *sta, int index) @@ -1501,7 +1627,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, switch (tbl->action) { case IWL_MIMO2_SWITCH_ANTENNA1: case IWL_MIMO2_SWITCH_ANTENNA2: - IWL_DEBUG_RATE(priv, "LQ: MIMO toggle Antennas\n"); + IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle Antennas\n"); if (tx_chains_num <= 2) break; @@ -1549,9 +1675,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, HT_SHORT_GI_40MHZ)) break; - IWL_DEBUG_RATE(priv, "LQ: MIMO toggle SGI/NGI\n"); + IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n"); - /* Set up new search table for MIMO */ + /* Set up new search table for MIMO2 */ memcpy(search_tbl, tbl, sz); search_tbl->is_SGI = !tbl->is_SGI; rs_set_expected_tpt_table(lq_sta, search_tbl); @@ -1571,9 +1697,24 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, index, is_green); goto out; + case IWL_MIMO2_SWITCH_MIMO3_ABC: + IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to MIMO3\n"); + memcpy(search_tbl, tbl, sz); + search_tbl->is_SGI = 0; + search_tbl->ant_type = ANT_ABC; + + if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type)) + break; + + ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta, + search_tbl, index); + if (!ret) + goto out; + + break; } tbl->action++; - if (tbl->action > IWL_MIMO2_SWITCH_GI) + if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC) tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; if (tbl->action == start_action) @@ -1584,12 +1725,149 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, out: lq_sta->search_better_tbl = 1; tbl->action++; - if (tbl->action > IWL_MIMO2_SWITCH_GI) + if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC) tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; return 0; } +/* + * Try to switch to new modulation mode from MIMO3 + */ +static int rs_move_mimo3_to_other(struct iwl_priv *priv, + struct iwl_lq_sta *lq_sta, + struct ieee80211_conf *conf, + struct ieee80211_sta *sta, int index) +{ + s8 is_green = lq_sta->is_green; + struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + struct iwl_scale_tbl_info *search_tbl = + &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); + struct iwl_rate_scale_data *window = &(tbl->win[index]); + u32 sz = (sizeof(struct iwl_scale_tbl_info) - + (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); + u8 start_action = tbl->action; + u8 valid_tx_ant = priv->hw_params.valid_tx_ant; + u8 tx_chains_num = priv->hw_params.tx_chains_num; + int ret; + + for (;;) { + lq_sta->action_counter++; + switch (tbl->action) { + case IWL_MIMO3_SWITCH_ANTENNA1: + case IWL_MIMO3_SWITCH_ANTENNA2: + IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle Antennas\n"); + + if (tx_chains_num <= 3) + break; + + if (window->success_ratio >= IWL_RS_GOOD_RATIO) + break; + + memcpy(search_tbl, tbl, sz); + if (rs_toggle_antenna(valid_tx_ant, + &search_tbl->current_rate, search_tbl)) + goto out; + break; + case IWL_MIMO3_SWITCH_SISO_A: + case IWL_MIMO3_SWITCH_SISO_B: + case IWL_MIMO3_SWITCH_SISO_C: + IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to SISO\n"); + + /* Set up new search table for SISO */ + memcpy(search_tbl, tbl, sz); + + if (tbl->action == IWL_MIMO3_SWITCH_SISO_A) + search_tbl->ant_type = ANT_A; + else if (tbl->action == IWL_MIMO3_SWITCH_SISO_B) + search_tbl->ant_type = ANT_B; + else + search_tbl->ant_type = ANT_C; + + if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type)) + break; + + ret = rs_switch_to_siso(priv, lq_sta, conf, sta, + search_tbl, index); + if (!ret) + goto out; + + break; + + case IWL_MIMO3_SWITCH_MIMO2_AB: + case IWL_MIMO3_SWITCH_MIMO2_AC: + case IWL_MIMO3_SWITCH_MIMO2_BC: + IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to MIMO2\n"); + + memcpy(search_tbl, tbl, sz); + search_tbl->is_SGI = 0; + if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB) + search_tbl->ant_type = ANT_AB; + else if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC) + search_tbl->ant_type = ANT_AC; + else + search_tbl->ant_type = ANT_BC; + + if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type)) + break; + + ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, + search_tbl, index); + if (!ret) + goto out; + + break; + + case IWL_MIMO3_SWITCH_GI: + if (!tbl->is_fat && + !(priv->current_ht_config.sgf & + HT_SHORT_GI_20MHZ)) + break; + if (tbl->is_fat && + !(priv->current_ht_config.sgf & + HT_SHORT_GI_40MHZ)) + break; + + IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle SGI/NGI\n"); + + /* Set up new search table for MIMO */ + memcpy(search_tbl, tbl, sz); + search_tbl->is_SGI = !tbl->is_SGI; + rs_set_expected_tpt_table(lq_sta, search_tbl); + /* + * If active table already uses the fastest possible + * modulation (dual stream with short guard interval), + * and it's working well, there's no need to look + * for a better type of modulation! + */ + if (tbl->is_SGI) { + s32 tpt = lq_sta->last_tpt / 100; + if (tpt >= search_tbl->expected_tpt[index]) + break; + } + search_tbl->current_rate = + rate_n_flags_from_tbl(priv, search_tbl, + index, is_green); + goto out; + } + tbl->action++; + if (tbl->action > IWL_MIMO3_SWITCH_GI) + tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; + + if (tbl->action == start_action) + break; + } + search_tbl->lq_type = LQ_NONE; + return 0; + out: + lq_sta->search_better_tbl = 1; + tbl->action++; + if (tbl->action > IWL_MIMO3_SWITCH_GI) + tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; + return 0; + +} + /* * Check whether we should continue using same modulation mode, or * begin search for a new mode, based on: @@ -1997,8 +2275,10 @@ lq_update: rs_move_legacy_other(priv, lq_sta, conf, sta, index); else if (is_siso(tbl->lq_type)) rs_move_siso_to_other(priv, lq_sta, conf, sta, index); + else if (is_mimo2(tbl->lq_type)) + rs_move_mimo2_to_other(priv, lq_sta, conf, sta, index); else - rs_move_mimo_to_other(priv, lq_sta, conf, sta, index); + rs_move_mimo3_to_other(priv, lq_sta, conf, sta, index); /* If new "search" mode was selected, set up in uCode table */ if (lq_sta->search_better_tbl) { @@ -2362,6 +2642,9 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv, } else if (num_of_ant(tbl_type.ant_type) == 2) { lq_cmd->general_params.dual_stream_ant_msk = tbl_type.ant_type; + } else if (num_of_ant(tbl_type.ant_type) == 3) { + lq_cmd->general_params.dual_stream_ant_msk = + tbl_type.ant_type; } /* otherwise we don't modify the existing value */ index++; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index ab59acc405d9..9cd90ba5ef95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -241,6 +241,7 @@ enum { #define IWL_LEGACY_SWITCH_MIMO2_AB 3 #define IWL_LEGACY_SWITCH_MIMO2_AC 4 #define IWL_LEGACY_SWITCH_MIMO2_BC 5 +#define IWL_LEGACY_SWITCH_MIMO3_ABC 6 /* possible actions when in siso mode */ #define IWL_SISO_SWITCH_ANTENNA1 0 @@ -249,6 +250,8 @@ enum { #define IWL_SISO_SWITCH_MIMO2_AC 3 #define IWL_SISO_SWITCH_MIMO2_BC 4 #define IWL_SISO_SWITCH_GI 5 +#define IWL_SISO_SWITCH_MIMO3_ABC 6 + /* possible actions when in mimo mode */ #define IWL_MIMO2_SWITCH_ANTENNA1 0 @@ -257,6 +260,21 @@ enum { #define IWL_MIMO2_SWITCH_SISO_B 3 #define IWL_MIMO2_SWITCH_SISO_C 4 #define IWL_MIMO2_SWITCH_GI 5 +#define IWL_MIMO2_SWITCH_MIMO3_ABC 6 + + +/* possible actions when in mimo3 mode */ +#define IWL_MIMO3_SWITCH_ANTENNA1 0 +#define IWL_MIMO3_SWITCH_ANTENNA2 1 +#define IWL_MIMO3_SWITCH_SISO_A 2 +#define IWL_MIMO3_SWITCH_SISO_B 3 +#define IWL_MIMO3_SWITCH_SISO_C 4 +#define IWL_MIMO3_SWITCH_MIMO2_AB 5 +#define IWL_MIMO3_SWITCH_MIMO2_AC 6 +#define IWL_MIMO3_SWITCH_MIMO2_BC 7 +#define IWL_MIMO3_SWITCH_GI 8 + + /*FIXME:RS:add possible actions for MIMO3*/ -- GitLab From 3eb9296970e70902593b15ed3080e389954cf5f5 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 1 Apr 2009 14:33:25 -0700 Subject: [PATCH 0562/6080] iwlwifi: add debug messages when start aggregation queue This patch adding few more debug messages if encounter error when driver try to start tx aggregation queue. Also change from IWL_ERR to IWL_DEBUG_HT is the HW legacy queue is empty when driver request to move to aggregation queue. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-tx.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1f117a49c569..c734c5f7e976 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -1170,8 +1170,10 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) __func__, ra, tid); sta_id = iwl_find_station(priv, ra); - if (sta_id == IWL_INVALID_STATION) + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Start AGG on invalid station\n"); return -ENXIO; + } if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) { IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n"); @@ -1179,8 +1181,10 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) } txq_id = iwl_txq_ctx_activate_free(priv); - if (txq_id == -1) + if (txq_id == -1) { + IWL_ERR(priv, "No free aggregation queue available\n"); return -ENXIO; + } spin_lock_irqsave(&priv->sta_lock, flags); tid_data = &priv->stations[sta_id].tid[tid]; @@ -1194,7 +1198,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) return ret; if (tid_data->tfds_in_queue == 0) { - IWL_ERR(priv, "HW queue is empty\n"); + IWL_DEBUG_HT(priv, "HW queue is empty\n"); tid_data->agg.state = IWL_AGG_ON; ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid); } else { -- GitLab From a4ed90d60c39c5aef9a170d7693f61175acb22e0 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 2 Apr 2009 14:08:07 -0400 Subject: [PATCH 0563/6080] cfg80211: respect API on orig_flags on channel for beacon hint As part of our documented API we always respect the orig_flag settings on a channel. We forgot to follow this for the beacon hints. Acked-by: Johannes Berg Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/reg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 6c1993d99902..4af4304cec3e 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1070,12 +1070,14 @@ static void handle_reg_beacon(struct wiphy *wiphy, if (likely(chan->center_freq != reg_beacon->chan.center_freq)) return; - if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) { + if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) && + !(chan->orig_flags & IEEE80211_CHAN_PASSIVE_SCAN)) { chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; REG_DEBUG_BEACON_FLAG("active scanning"); } - if (chan->flags & IEEE80211_CHAN_NO_IBSS) { + if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && + !(chan->orig_flags & IEEE80211_CHAN_NO_IBSS)) { chan->flags &= ~IEEE80211_CHAN_NO_IBSS; REG_DEBUG_BEACON_FLAG("beaconing"); } -- GitLab From 5dab3b8a68cc97a7e6b9f79f5de05803c8e55a3c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 2 Apr 2009 14:08:08 -0400 Subject: [PATCH 0564/6080] cfg80211: add netlink channel put helper This adds a netlink channel put helper, nl80211_msg_put_channel(), which we will also make use of later for the beacon hints events. Acked-by: Johannes Berg Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 68c51022e9dd..7285bdc4e598 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -156,6 +156,30 @@ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq, return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd); } +static int nl80211_msg_put_channel(struct sk_buff *msg, + struct ieee80211_channel *chan) +{ + NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ, + chan->center_freq); + + if (chan->flags & IEEE80211_CHAN_DISABLED) + NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED); + if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) + NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN); + if (chan->flags & IEEE80211_CHAN_NO_IBSS) + NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS); + if (chan->flags & IEEE80211_CHAN_RADAR) + NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR); + + NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, + DBM_TO_MBM(chan->max_power)); + + return 0; + + nla_put_failure: + return -ENOBUFS; +} + /* netlink command implementations */ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, @@ -234,20 +258,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, goto nla_put_failure; chan = &dev->wiphy.bands[band]->channels[i]; - NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ, - chan->center_freq); - - if (chan->flags & IEEE80211_CHAN_DISABLED) - NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED); - if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) - NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN); - if (chan->flags & IEEE80211_CHAN_NO_IBSS) - NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS); - if (chan->flags & IEEE80211_CHAN_RADAR) - NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR); - - NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, - DBM_TO_MBM(chan->max_power)); + + if (nl80211_msg_put_channel(msg, chan)) + goto nla_put_failure; nla_nest_end(msg, nl_freq); } -- GitLab From 6bad8766620a3c8b64afa981502fdb543e3cfd6c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 2 Apr 2009 14:08:09 -0400 Subject: [PATCH 0565/6080] cfg80211: send regulatory beacon hint events to userspace This informs userspace when a change has occured on a world roaming wiphy's channel which has lifted some restrictions due to a regulatory beacon hint. Because this is now sent to userspace through the regulatory multicast group we remove the debug prints we used to use as they are no longer necessary. Acked-by: Johannes Berg Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- include/linux/nl80211.h | 34 +++++++++++++++++++++++++- net/wireless/nl80211.c | 54 +++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 5 ++++ net/wireless/reg.c | 28 ++++++++++----------- 4 files changed, 106 insertions(+), 15 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 209cacee5285..05ba3539b77e 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -7,7 +7,7 @@ * Copyright 2008 Michael Wu * Copyright 2008 Luis Carlos Cobo * Copyright 2008 Michael Buesch - * Copyright 2008 Luis R. Rodriguez + * Copyright 2008, 2009 Luis R. Rodriguez * Copyright 2008 Jouni Malinen * Copyright 2008 Colin McCabe * @@ -166,6 +166,22 @@ * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on * to (%NL80211_ATTR_REG_ALPHA2). + * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon + * has been found while world roaming thus enabling active scan or + * any mode of operation that initiates TX (beacons) on a channel + * where we would not have been able to do either before. As an example + * if you are world roaming (regulatory domain set to world or if your + * driver is using a custom world roaming regulatory domain) and while + * doing a passive scan on the 5 GHz band you find an AP there (if not + * on a DFS channel) you will now be able to actively scan for that AP + * or use AP mode on your card on that same channel. Note that this will + * never be used for channels 1-11 on the 2 GHz band as they are always + * enabled world wide. This beacon hint is only sent if your device had + * either disabled active scanning or beaconing on a channel. We send to + * userspace the wiphy on which we removed a restriction from + * (%NL80211_ATTR_WIPHY) and the channel on which this occurred + * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER) + * the beacon hint was processed. * * @NL80211_CMD_AUTHENTICATE: authentication request and notification. * This command is used both as a command (request to authenticate) and @@ -270,6 +286,8 @@ enum nl80211_commands { NL80211_CMD_MICHAEL_MIC_FAILURE, + NL80211_CMD_REG_BEACON_HINT, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -288,6 +306,7 @@ enum nl80211_commands { #define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE #define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE +#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT /** * enum nl80211_attrs - nl80211 netlink attributes @@ -423,6 +442,17 @@ enum nl80211_commands { * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as * a u32 * + * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change + * due to considerations from a beacon hint. This attribute reflects + * the state of the channel _before_ the beacon hint processing. This + * attributes consists of a nested attribute containing + * NL80211_FREQUENCY_ATTR_* + * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change + * due to considerations from a beacon hint. This attribute reflects + * the state of the channel _after_ the beacon hint processing. This + * attributes consists of a nested attribute containing + * NL80211_FREQUENCY_ATTR_* + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -511,6 +541,8 @@ enum nl80211_attrs { NL80211_ATTR_MAX_SCAN_IE_LEN, + NL80211_ATTR_FREQ_BEFORE, + NL80211_ATTR_FREQ_AFTER, /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7285bdc4e598..85b5aa3c76f8 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3491,6 +3491,60 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, nlmsg_free(msg); } +void nl80211_send_beacon_hint_event(struct wiphy *wiphy, + struct ieee80211_channel *channel_before, + struct ieee80211_channel *channel_after) +{ + struct sk_buff *msg; + void *hdr; + struct nlattr *nl_freq; + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT); + if (!hdr) { + nlmsg_free(msg); + return; + } + + /* + * Since we are applying the beacon hint to a wiphy we know its + * wiphy_idx is valid + */ + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)); + + /* Before */ + nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE); + if (!nl_freq) + goto nla_put_failure; + if (nl80211_msg_put_channel(msg, channel_before)) + goto nla_put_failure; + nla_nest_end(msg, nl_freq); + + /* After */ + nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER); + if (!nl_freq) + goto nla_put_failure; + if (nl80211_msg_put_channel(msg, channel_after)) + goto nla_put_failure; + nla_nest_end(msg, nl_freq); + + if (genlmsg_end(msg, hdr) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC); + + return; + +nla_put_failure: + genlmsg_cancel(msg, hdr); + nlmsg_free(msg); +} + /* initialisation/exit functions */ int nl80211_init(void) diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index e4b92cccd157..b3aaa59afa08 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -29,4 +29,9 @@ nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, enum nl80211_key_type key_type, int key_id, const u8 *tsc); +extern void +nl80211_send_beacon_hint_event(struct wiphy *wiphy, + struct ieee80211_channel *channel_before, + struct ieee80211_channel *channel_after); + #endif /* __NET_WIRELESS_NL80211_H */ diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 4af4304cec3e..574e217bcc86 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1049,18 +1049,10 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx, struct reg_beacon *reg_beacon) { -#ifdef CONFIG_CFG80211_REG_DEBUG -#define REG_DEBUG_BEACON_FLAG(desc) \ - printk(KERN_DEBUG "cfg80211: Enabling " desc " on " \ - "frequency: %d MHz (Ch %d) on %s\n", \ - reg_beacon->chan.center_freq, \ - ieee80211_frequency_to_channel(reg_beacon->chan.center_freq), \ - wiphy_name(wiphy)); -#else -#define REG_DEBUG_BEACON_FLAG(desc) do {} while (0) -#endif struct ieee80211_supported_band *sband; struct ieee80211_channel *chan; + bool channel_changed = false; + struct ieee80211_channel chan_before; assert_cfg80211_lock(); @@ -1070,20 +1062,28 @@ static void handle_reg_beacon(struct wiphy *wiphy, if (likely(chan->center_freq != reg_beacon->chan.center_freq)) return; + if (chan->beacon_found) + return; + + chan->beacon_found = true; + + chan_before.center_freq = chan->center_freq; + chan_before.flags = chan->flags; + if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) && !(chan->orig_flags & IEEE80211_CHAN_PASSIVE_SCAN)) { chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; - REG_DEBUG_BEACON_FLAG("active scanning"); + channel_changed = true; } if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && !(chan->orig_flags & IEEE80211_CHAN_NO_IBSS)) { chan->flags &= ~IEEE80211_CHAN_NO_IBSS; - REG_DEBUG_BEACON_FLAG("beaconing"); + channel_changed = true; } - chan->beacon_found = true; -#undef REG_DEBUG_BEACON_FLAG + if (channel_changed) + nl80211_send_beacon_hint_event(wiphy, &chan_before, chan); } /* -- GitLab From 25e47c18ac4d8ad09c2ed4b99c1dbbcb7e3d2c51 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 2 Apr 2009 20:14:06 +0200 Subject: [PATCH 0566/6080] cfg80211: add cipher capabilities This adds the necessary code and fields to let drivers specify their cipher capabilities and exports them to userspace. Also update mac80211 to export the ciphers it has. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 ++++ include/net/wireless.h | 5 +++++ net/mac80211/main.c | 14 ++++++++++++++ net/wireless/nl80211.c | 14 +++++++++++++- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 05ba3539b77e..c01423888db9 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -453,6 +453,9 @@ enum nl80211_commands { * attributes consists of a nested attribute containing * NL80211_FREQUENCY_ATTR_* * + * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported + * cipher suites + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -540,6 +543,7 @@ enum nl80211_attrs { NL80211_ATTR_KEY_TYPE, NL80211_ATTR_MAX_SCAN_IE_LEN, + NL80211_ATTR_CIPHER_SUITES, NL80211_ATTR_FREQ_BEFORE, NL80211_ATTR_FREQ_AFTER, diff --git a/include/net/wireless.h b/include/net/wireless.h index 2bcdeda46d81..44c2642d3c06 100644 --- a/include/net/wireless.h +++ b/include/net/wireless.h @@ -205,6 +205,8 @@ struct ieee80211_supported_band { * on the reg_notifier() if it chooses to ignore future * regulatory domain changes caused by other drivers. * @signal_type: signal type reported in &struct cfg80211_bss. + * @cipher_suites: supported cipher suites + * @n_cipher_suites: number of supported cipher suites */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -224,6 +226,9 @@ struct wiphy { u8 max_scan_ssids; u16 max_scan_ie_len; + int n_cipher_suites; + const u32 *cipher_suites; + /* If multiple wiphys are registered and you're handed e.g. * a regular netdev with assigned ieee80211_ptr, you won't * know whether it points to a wiphy your driver has registered diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 679b3a14f11f..c1145be72da4 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -823,6 +823,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) struct ieee80211_master_priv *mpriv; int channels, i, j, max_bitrates; bool supp_ht; + static const u32 cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, + + /* keep last -- depends on hw flags! */ + WLAN_CIPHER_SUITE_AES_CMAC + }; /* * generic code guarantees at least one band, @@ -894,6 +903,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (local->hw.wiphy->max_scan_ie_len) local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; + local->hw.wiphy->cipher_suites = cipher_suites; + local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) + local->hw.wiphy->n_cipher_suites--; + result = wiphy_register(local->hw.wiphy); if (result < 0) goto fail_wiphy_register; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 85b5aa3c76f8..d33cab0e0fb2 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -208,6 +208,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, dev->wiphy.max_scan_ie_len); + NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, + sizeof(u32) * dev->wiphy.n_cipher_suites, + dev->wiphy.cipher_suites); + nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); if (!nl_modes) goto nla_put_failure; @@ -979,7 +983,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *drv; - int err; + int err, i; struct net_device *dev; struct key_params params; u8 key_idx = 0; @@ -1048,6 +1052,14 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) if (err) goto unlock_rtnl; + for (i = 0; i < drv->wiphy.n_cipher_suites; i++) + if (params.cipher == drv->wiphy.cipher_suites[i]) + break; + if (i == drv->wiphy.n_cipher_suites) { + err = -EINVAL; + goto out; + } + if (!drv->ops->add_key) { err = -EOPNOTSUPP; goto out; -- GitLab From b26ed97c75e1538176c09f29c423a3f8a75868a7 Mon Sep 17 00:00:00 2001 From: Anna Neal Date: Thu, 2 Apr 2009 14:44:09 -0700 Subject: [PATCH 0567/6080] libertas: increase spi driver thread priority Currently, the libertas main thread contends with the spi driver thread in the TX path. To improve throughput, ensure that the driver thread has higher scheduling priority than the libertas main thread. Do this by making the libertas spi driver thread a low priority real time thread. We measured an average throughput improvement of 13%. Signed-off-by: Anna Neal Signed-off-by: Andrey Yurovsky Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_spi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 07311e71af92..97493e2f4109 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -1020,6 +1020,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) struct libertas_spi_platform_data *pdata = spi->dev.platform_data; int err = 0; u32 scratch; + struct sched_param param = { .sched_priority = 1 }; lbs_deb_enter(LBS_DEB_SPI); @@ -1123,6 +1124,9 @@ static int __devinit if_spi_probe(struct spi_device *spi) lbs_pr_err("error creating SPI thread: err=%d\n", err); goto remove_card; } + if (sched_setscheduler(card->spi_thread, SCHED_FIFO, ¶m)) + lbs_pr_err("Error setting scheduler, using default.\n"); + err = request_irq(spi->irq, if_spi_host_interrupt, IRQF_TRIGGER_FALLING, "libertas_spi", card); if (err) { -- GitLab From 6a362bb1c9f900f7e6daeee52ff2d538badae49b Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sun, 5 Apr 2009 11:01:20 -0400 Subject: [PATCH 0568/6080] ath5k: add support for Fukato Datacask Jupiter LEDs This adds support for the LEDs on the Jupiter netbook. Reported-by: Martin Bammer Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/led.c | 2 ++ include/linux/pci_ids.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 006f7716168e..cbdc0b308429 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -67,6 +67,8 @@ static const struct pci_device_id ath5k_led_devices[] = { { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) }, /* Acer Extensa 5620z (nekoreeve@gmail.com) */ { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) }, + /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */ + { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) }, { } }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ee98cd570885..ea061e290d02 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2313,6 +2313,8 @@ #define PCI_VENDOR_ID_QMI 0x1a32 +#define PCI_VENDOR_ID_AZWAVE 0x1a3b + #define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 -- GitLab From 87cbfd06889256cac945b37c7f62f4ce7f44b34a Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 6 Apr 2009 01:03:09 +0400 Subject: [PATCH 0569/6080] p54spi: get rid of busy-wait loops p54spi_wakeup and p54spi_tx_frame used busy-waiting loop to poll for 'ready' bits in SPI_ADRS_HOST_INTERRUPTS register. With this change in place 'WR_READY timeout' messages do not show anymore. Signed-off-by: Max Filippov Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi.c | 41 +++++++++++-------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 52023127cf37..59a5e778bb08 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -167,14 +167,13 @@ static const struct p54spi_spi_reg p54spi_registers_array[] = static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits) { int i; - __le32 buffer; for (i = 0; i < 2000; i++) { - p54spi_spi_read(priv, reg, &buffer, sizeof(buffer)); + __le32 buffer = p54spi_read32(priv, reg); if ((buffer & bits) == bits) return 1; - msleep(1); + msleep(0); } return 0; } @@ -185,10 +184,10 @@ static int p54spi_spi_write_dma(struct p54s_priv *priv, __le32 base, p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL, cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE)); - if (p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL, - cpu_to_le32(HOST_ALLOWED)) == 0) { + if (!p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL, + cpu_to_le32(HOST_ALLOWED))) { dev_err(&priv->spi->dev, "spi_write_dma not allowed " - "to DMA write."); + "to DMA write.\n"); return -EAGAIN; } @@ -330,21 +329,15 @@ static inline void p54spi_int_ack(struct p54s_priv *priv, u32 val) static void p54spi_wakeup(struct p54s_priv *priv) { - unsigned long timeout; - u32 ints; - /* wake the chip */ p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS, cpu_to_le32(SPI_TARGET_INT_WAKEUP)); /* And wait for the READY interrupt */ - timeout = jiffies + HZ; - - ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); - while (!(ints & SPI_HOST_INT_READY)) { - if (time_after(jiffies, timeout)) - goto out; - ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); + if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS, + cpu_to_le32(SPI_HOST_INT_READY))) { + dev_err(&priv->spi->dev, "INT_READY timeout\n"); + goto out; } p54spi_int_ack(priv, SPI_HOST_INT_READY); @@ -432,9 +425,7 @@ static irqreturn_t p54spi_interrupt(int irq, void *config) static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb) { struct p54_hdr *hdr = (struct p54_hdr *) skb->data; - unsigned long timeout; int ret = 0; - u32 ints; p54spi_wakeup(priv); @@ -442,15 +433,11 @@ static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb) if (ret < 0) goto out; - timeout = jiffies + 2 * HZ; - ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); - while (!(ints & SPI_HOST_INT_WR_READY)) { - if (time_after(jiffies, timeout)) { - dev_err(&priv->spi->dev, "WR_READY timeout\n"); - ret = -1; - goto out; - } - ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS); + if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS, + cpu_to_le32(SPI_HOST_INT_WR_READY))) { + dev_err(&priv->spi->dev, "WR_READY timeout\n"); + ret = -1; + goto out; } p54spi_int_ack(priv, SPI_HOST_INT_WR_READY); -- GitLab From e45d8e534b67580eedd9b4910ccc16d6dd3cceff Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Mon, 6 Apr 2009 15:50:56 -0700 Subject: [PATCH 0570/6080] libertas: add support for Marvell SD8688 chip libertas: add support for Marvell SD8688 chip Use RxPD->pkt_ptr to locate eth803 header in the packet received since SD8688/v10 firmware allows a gap between RxPD and eth803 header. Set SDIO block size to 256 for CMD53. The maximum block size for SD8688 WLAN function is set to 512 in TPLFE_MAX_BLK_SIZE. But using 512 as block size results upto 2K bytes data (4 blocks) being transferred and causes buffer overflow in firmware. Both changes above are backward compatible with earlier firmware versions for SD8385/SD8686. The SDIO_DEVICE_IDs for SD8688 chip are added in include/linux/mmc/sdio_ids.h Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 4 ++-- drivers/net/wireless/libertas/if_sdio.c | 17 +++++++++++++---- drivers/net/wireless/libertas/if_sdio.h | 2 ++ drivers/net/wireless/libertas/rx.c | 15 ++++++++------- include/linux/mmc/sdio_ids.h | 2 ++ 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 8f279e7bd049..ad99470ae92d 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -146,10 +146,10 @@ config LIBERTAS_CS A driver for Marvell Libertas 8385 CompactFlash devices. config LIBERTAS_SDIO - tristate "Marvell Libertas 8385 and 8686 SDIO 802.11b/g cards" + tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards" depends on LIBERTAS && MMC ---help--- - A driver for Marvell Libertas 8385 and 8686 SDIO devices. + A driver for Marvell Libertas 8385/8686/8688 SDIO devices. config LIBERTAS_SPI tristate "Marvell Libertas 8686 SPI 802.11b/g cards" diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 76f4c653d641..55864c10f9f1 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -48,8 +48,11 @@ static char *lbs_fw_name = NULL; module_param_named(fw_name, lbs_fw_name, charp, 0644); static const struct sdio_device_id if_sdio_ids[] = { - { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) }, - { /* end: all zeroes */ }, + { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, + SDIO_DEVICE_ID_MARVELL_LIBERTAS) }, + { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, + SDIO_DEVICE_ID_MARVELL_8688WLAN) }, + { /* end: all zeroes */ }, }; MODULE_DEVICE_TABLE(sdio, if_sdio_ids); @@ -73,6 +76,12 @@ static struct if_sdio_model if_sdio_models[] = { .helper = "sd8686_helper.bin", .firmware = "sd8686.bin", }, + { + /* 8688 */ + .model = 0x10, + .helper = "sd8688_helper.bin", + .firmware = "sd8688.bin", + }, }; struct if_sdio_packet { @@ -488,7 +497,7 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) ret = 0; release: - sdio_set_block_size(card->func, 0); + sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE); sdio_release_host(card->func); kfree(chunk_buffer); release_fw: @@ -624,7 +633,7 @@ static int if_sdio_prog_real(struct if_sdio_card *card) ret = 0; release: - sdio_set_block_size(card->func, 0); + sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE); sdio_release_host(card->func); kfree(chunk_buffer); release_fw: diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h index 533bdfbf5d2a..37ada2c29aa9 100644 --- a/drivers/net/wireless/libertas/if_sdio.h +++ b/drivers/net/wireless/libertas/if_sdio.h @@ -42,4 +42,6 @@ #define IF_SDIO_EVENT 0x80fc +#define IF_SDIO_BLOCK_SIZE 256 + #endif diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 820c22d9220f..bd845d09f174 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -25,7 +25,6 @@ struct rfc1042hdr { } __attribute__ ((packed)); struct rxpackethdr { - struct rxpd rx_pd; struct eth803hdr eth803_hdr; struct rfc1042hdr rfc1042_hdr; } __attribute__ ((packed)); @@ -158,8 +157,9 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) if (priv->monitormode) return process_rxed_802_11_packet(priv, skb); - p_rx_pkt = (struct rxpackethdr *) skb->data; - p_rx_pd = &p_rx_pkt->rx_pd; + p_rx_pd = (struct rxpd *) skb->data; + p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd + + le32_to_cpu(p_rx_pd->pkt_ptr)); if (priv->mesh_dev) { if (priv->mesh_fw_ver == MESH_FW_OLD) { if (p_rx_pd->rx_control & RxPD_MESH_FRAME) @@ -181,8 +181,9 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) goto done; } - lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n", - skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); + lbs_deb_rx("rx data: skb->len - pkt_ptr = %d-%zd = %zd\n", + skb->len, le32_to_cpu(p_rx_pd->pkt_ptr), + skb->len - le32_to_cpu(p_rx_pd->pkt_ptr)); lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr, sizeof(p_rx_pkt->eth803_hdr.dest_addr)); @@ -216,14 +217,14 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) /* Chop off the rxpd + the excess memory from the 802.2/llc/snap header * that was removed */ - hdrchop = (u8 *) p_ethhdr - (u8 *) p_rx_pkt; + hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd; } else { lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP", (u8 *) & p_rx_pkt->rfc1042_hdr, sizeof(p_rx_pkt->rfc1042_hdr)); /* Chop off the rxpd */ - hdrchop = (u8 *) & p_rx_pkt->eth803_hdr - (u8 *) p_rx_pkt; + hdrchop = (u8 *)&p_rx_pkt->eth803_hdr - (u8 *)p_rx_pd; } /* Chop off the leading header bytes so the skb points to the start of diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index ea1bf5ba092f..c7211ab6dd4b 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -25,5 +25,7 @@ #define SDIO_VENDOR_ID_MARVELL 0x02df #define SDIO_DEVICE_ID_MARVELL_LIBERTAS 0x9103 +#define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 +#define SDIO_DEVICE_ID_MARVELL_8688BT 0x9105 #endif -- GitLab From 4499b23933b44bf9e56d1a29b51d9a62941f9fa4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 8 Apr 2009 02:55:34 +0200 Subject: [PATCH 0571/6080] mac80211: re-upload keys only after telling driver about association In the normal WPA or RSN case keys are only configured after associating, so we should do that in that order when resuming as well. It shouldn't really matter since we do not send any data at either point, but iwlwifi prefers it this way and it does seem more natural. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/pm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 027302326498..2b4c95cd9daf 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -127,11 +127,6 @@ int __ieee80211_resume(struct ieee80211_hw *hw) rcu_read_unlock(); - /* add back keys */ - list_for_each_entry(sdata, &local->interfaces, list) - if (netif_running(sdata->dev)) - ieee80211_enable_keys(sdata); - /* setup RTS threshold */ if (local->ops->set_rts_threshold) local->ops->set_rts_threshold(hw, local->rts_threshold); @@ -172,6 +167,11 @@ int __ieee80211_resume(struct ieee80211_hw *hw) } } + /* add back keys */ + list_for_each_entry(sdata, &local->interfaces, list) + if (netif_running(sdata->dev)) + ieee80211_enable_keys(sdata); + ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); -- GitLab From de2b3e864aa908e613dd9912def88af7877d85f3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 8 Apr 2009 12:54:41 +0200 Subject: [PATCH 0572/6080] mac80211: update injection documentation We don't currently support antenna or rate setting, so remove that. Also update the link -- the current one is dead and the wiki can be kept updated easier. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- .../networking/mac80211-injection.txt | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt index 84906ef3ed6e..b30e81ad5307 100644 --- a/Documentation/networking/mac80211-injection.txt +++ b/Documentation/networking/mac80211-injection.txt @@ -12,38 +12,22 @@ following format: The radiotap format is discussed in ./Documentation/networking/radiotap-headers.txt. -Despite 13 radiotap argument types are currently defined, most only make sense +Despite many radiotap parameters being currently defined, most only make sense to appear on received packets. The following information is parsed from the radiotap headers and used to control injection: - * IEEE80211_RADIOTAP_RATE - - rate in 500kbps units, automatic if invalid or not present - - - * IEEE80211_RADIOTAP_ANTENNA - - antenna to use, automatic if not present - - - * IEEE80211_RADIOTAP_DBM_TX_POWER - - transmit power in dBm, automatic if not present - - * IEEE80211_RADIOTAP_FLAGS IEEE80211_RADIOTAP_F_FCS: FCS will be removed and recalculated IEEE80211_RADIOTAP_F_WEP: frame will be encrypted if key available IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the - current fragmentation threshold. Note that - this flag is only reliable when software - fragmentation is enabled) + current fragmentation threshold. + The injection code can also skip all other currently defined radiotap fields facilitating replay of captured radiotap headers directly. -Here is an example valid radiotap header defining these three parameters +Here is an example valid radiotap header defining some parameters 0x00, 0x00, // <-- radiotap version 0x0b, 0x00, // <- radiotap header length @@ -72,8 +56,8 @@ interface), along the following lines: ... r = pcap_inject(ppcap, u8aSendBuffer, nLength); -You can also find sources for a complete inject test applet here: +You can also find a link to a complete inject application here: -http://penumbra.warmcat.com/_twk/tiki-index.php?page=packetspammer +http://wireless.kernel.org/en/users/Documentation/packetspammer Andy Green -- GitLab From 5bbe233b9bafabc08a5404d54b9fa086e8390fc7 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:35 -0700 Subject: [PATCH 0573/6080] iwl3945: use iwl_bss_info_changed 3945 can use iwl_bss_info_changed. A new lib op is created for post_assoicate to distinguish between 3945 and iwlwifi's post_associate operations. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 50 +++++++ drivers/net/wireless/iwlwifi/iwl-3945.h | 2 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 138 +------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 136 +++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 7 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 116 +--------------- 8 files changed, 204 insertions(+), 247 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 2399328e8de7..519e8922d9f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1964,6 +1964,50 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) return 0; } +static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) +{ + int rc = 0; + struct iwl_rx_packet *res = NULL; + struct iwl3945_rxon_assoc_cmd rxon_assoc; + struct iwl_host_cmd cmd = { + .id = REPLY_RXON_ASSOC, + .len = sizeof(rxon_assoc), + .meta.flags = CMD_WANT_SKB, + .data = &rxon_assoc, + }; + const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; + const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; + + if ((rxon1->flags == rxon2->flags) && + (rxon1->filter_flags == rxon2->filter_flags) && + (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && + (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { + IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); + return 0; + } + + rxon_assoc.flags = priv->staging_rxon.flags; + rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; + rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; + rxon_assoc.reserved = 0; + + rc = iwl_send_cmd_sync(priv, &cmd); + if (rc) + return rc; + + res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + if (res->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); + rc = -EIO; + } + + priv->alloc_rxb_skb--; + dev_kfree_skb_any(cmd.meta.u.skb); + + return rc; +} + /* will add 3945 channel switch cmd handling later */ int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel) { @@ -2729,6 +2773,10 @@ static int iwl3945_load_bsm(struct iwl_priv *priv) return 0; } +static struct iwl_hcmd_ops iwl3945_hcmd = { + .rxon_assoc = iwl3945_send_rxon_assoc, +}; + static struct iwl_lib_ops iwl3945_lib = { .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl3945_hw_txq_free_tfd, @@ -2758,6 +2806,7 @@ static struct iwl_lib_ops iwl3945_lib = { }, .send_tx_power = iwl3945_send_tx_power, .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, + .post_associate = iwl3945_post_associate, }; static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { @@ -2767,6 +2816,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { static struct iwl_ops iwl3945_ops = { .lib = &iwl3945_lib, + .hcmd = &iwl3945_hcmd, .utils = &iwl3945_hcmd_utils, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 29bc0d2656bc..13b191f155ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -276,7 +276,7 @@ extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); extern void iwl3945_disable_events(struct iwl_priv *priv); extern int iwl4965_get_temperature(const struct iwl_priv *priv); - +extern void iwl3945_post_associate(struct iwl_priv *priv); /** * iwl3945_hw_find_station - Find station id for a given BSSID * @bssid: MAC address of station ID to find diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 847a6220c5e6..37544afbebe6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2324,6 +2324,7 @@ static struct iwl_lib_ops iwl4965_lib = { .send_tx_power = iwl4965_send_tx_power, .update_chain_flags = iwl_update_chain_flags, .temperature = iwl4965_temperature_calib, + .post_associate = iwl_post_associate, }; static struct iwl_ops iwl4965_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index e5ca2511a81a..837dbad80e5e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1527,6 +1527,7 @@ struct iwl_lib_ops iwl5000_lib = { .calib_version = iwl5000_eeprom_calib_version, .query_addr = iwl5000_eeprom_query_addr, }, + .post_associate = iwl_post_associate, }; struct iwl_ops iwl5000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1f5ee55778f1..d14146fa751f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -531,76 +531,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv, * ******************************************************************************/ -static void iwl_ht_conf(struct iwl_priv *priv, - struct ieee80211_bss_conf *bss_conf) -{ - struct ieee80211_sta_ht_cap *ht_conf; - struct iwl_ht_info *iwl_conf = &priv->current_ht_config; - struct ieee80211_sta *sta; - - IWL_DEBUG_MAC80211(priv, "enter: \n"); - - if (!iwl_conf->is_ht) - return; - - - /* - * It is totally wrong to base global information on something - * that is valid only when associated, alas, this driver works - * that way and I don't know how to fix it. - */ - - rcu_read_lock(); - sta = ieee80211_find_sta(priv->hw, priv->bssid); - if (!sta) { - rcu_read_unlock(); - return; - } - ht_conf = &sta->ht_cap; - - if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) - iwl_conf->sgf |= HT_SHORT_GI_20MHZ; - if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) - iwl_conf->sgf |= HT_SHORT_GI_40MHZ; - - iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); - iwl_conf->max_amsdu_size = - !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); - - iwl_conf->supported_chan_width = - !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); - - /* - * XXX: The HT configuration needs to be moved into iwl_mac_config() - * to be done there correctly. - */ - - iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; - if (conf_is_ht40_minus(&priv->hw->conf)) - iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; - else if (conf_is_ht40_plus(&priv->hw->conf)) - iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - - /* If no above or below channel supplied disable FAT channel */ - if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && - iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) - iwl_conf->supported_chan_width = 0; - - iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2); - - memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); - - iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0; - iwl_conf->ht_protection = - bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; - iwl_conf->non_GF_STA_present = - !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); - - rcu_read_unlock(); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} - #define MAX_UCODE_BEACON_INTERVAL 4096 static u16 iwl_adjust_beacon_interval(u16 beacon_val) @@ -1911,7 +1841,7 @@ static void iwl_bg_rx_replenish(struct work_struct *data) #define IWL_DELAY_NEXT_SCAN (HZ*2) -static void iwl_post_associate(struct iwl_priv *priv) +void iwl_post_associate(struct iwl_priv *priv) { struct ieee80211_conf *conf = NULL; int ret = 0; @@ -2482,70 +2412,6 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw, } -#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) -static void iwl_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) -{ - struct iwl_priv *priv = hw->priv; - - IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); - - if (changes & BSS_CHANGED_ERP_PREAMBLE) { - IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - } - - if (changes & BSS_CHANGED_ERP_CTS_PROT) { - IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) - priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; - else - priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; - } - - if (changes & BSS_CHANGED_HT) { - iwl_ht_conf(priv, bss_conf); - iwl_set_rxon_chain(priv); - } - - if (changes & BSS_CHANGED_ASSOC) { - IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); - /* This should never happen as this function should - * never be called from interrupt context. */ - if (WARN_ON_ONCE(in_interrupt())) - return; - if (bss_conf->assoc) { - priv->assoc_id = bss_conf->aid; - priv->beacon_int = bss_conf->beacon_int; - priv->power_data.dtim_period = bss_conf->dtim_period; - priv->timestamp = bss_conf->timestamp; - priv->assoc_capability = bss_conf->assoc_capability; - - /* we have just associated, don't start scan too early - * leave time for EAPOL exchange to complete - */ - priv->next_scan_jiffies = jiffies + - IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; - mutex_lock(&priv->mutex); - iwl_post_associate(priv); - mutex_unlock(&priv->mutex); - } else { - priv->assoc_id = 0; - IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc); - } - } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { - IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes); - iwl_send_rxon_assoc(priv); - } - -} - static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, struct ieee80211_key_conf *keyconf, const u8 *addr, u32 iv32, u16 *phase1key) @@ -2825,7 +2691,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) iwl_reset_qos(priv); - iwl_post_associate(priv); + priv->cfg->ops->lib->post_associate(priv); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 84ac1cec6f5b..15691829e023 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2157,6 +2157,142 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, return 0; } EXPORT_SYMBOL(iwl_mac_conf_tx); + +static void iwl_ht_conf(struct iwl_priv *priv, + struct ieee80211_bss_conf *bss_conf) +{ + struct ieee80211_sta_ht_cap *ht_conf; + struct iwl_ht_info *iwl_conf = &priv->current_ht_config; + struct ieee80211_sta *sta; + + IWL_DEBUG_MAC80211(priv, "enter: \n"); + + if (!iwl_conf->is_ht) + return; + + + /* + * It is totally wrong to base global information on something + * that is valid only when associated, alas, this driver works + * that way and I don't know how to fix it. + */ + + rcu_read_lock(); + sta = ieee80211_find_sta(priv->hw, priv->bssid); + if (!sta) { + rcu_read_unlock(); + return; + } + ht_conf = &sta->ht_cap; + + if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) + iwl_conf->sgf |= HT_SHORT_GI_20MHZ; + if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) + iwl_conf->sgf |= HT_SHORT_GI_40MHZ; + + iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); + iwl_conf->max_amsdu_size = + !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); + + iwl_conf->supported_chan_width = + !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40); + + /* + * XXX: The HT configuration needs to be moved into iwl_mac_config() + * to be done there correctly. + */ + + iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; + if (conf_is_ht40_minus(&priv->hw->conf)) + iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; + else if (conf_is_ht40_plus(&priv->hw->conf)) + iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + + /* If no above or below channel supplied disable FAT channel */ + if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE && + iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) + iwl_conf->supported_chan_width = 0; + + iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2); + + memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); + + iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0; + iwl_conf->ht_protection = + bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; + iwl_conf->non_GF_STA_present = + !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + + rcu_read_unlock(); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} + +#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) +void iwl_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes) +{ + struct iwl_priv *priv = hw->priv; + + IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); + + if (changes & BSS_CHANGED_ERP_PREAMBLE) { + IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", + bss_conf->use_short_preamble); + if (bss_conf->use_short_preamble) + priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + } + + if (changes & BSS_CHANGED_ERP_CTS_PROT) { + IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); + if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) + priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; + else + priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + } + + if (changes & BSS_CHANGED_HT) { + iwl_ht_conf(priv, bss_conf); + iwl_set_rxon_chain(priv); + } + + if (changes & BSS_CHANGED_ASSOC) { + IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); + /* This should never happen as this function should + * never be called from interrupt context. */ + if (WARN_ON_ONCE(in_interrupt())) + return; + if (bss_conf->assoc) { + priv->assoc_id = bss_conf->aid; + priv->beacon_int = bss_conf->beacon_int; + priv->power_data.dtim_period = bss_conf->dtim_period; + priv->timestamp = bss_conf->timestamp; + priv->assoc_capability = bss_conf->assoc_capability; + + /* we have just associated, don't start scan too early + * leave time for EAPOL exchange to complete + */ + priv->next_scan_jiffies = jiffies + + IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; + mutex_lock(&priv->mutex); + priv->cfg->ops->lib->post_associate(priv); + mutex_unlock(&priv->mutex); + } else { + priv->assoc_id = 0; + IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc); + } + } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { + IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes); + iwl_send_rxon_assoc(priv); + } + +} +EXPORT_SYMBOL(iwl_bss_info_changed); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index d56edcd97aa0..4ad8465ae5fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -149,6 +149,8 @@ struct iwl_lib_ops { int (*send_tx_power) (struct iwl_priv *priv); void (*update_chain_flags)(struct iwl_priv *priv); void (*temperature) (struct iwl_priv *priv); + void (*post_associate) (struct iwl_priv *priv); + /* eeprom operations (as defined in iwl-eeprom.h) */ struct iwl_eeprom_ops eeprom_ops; }; @@ -251,6 +253,11 @@ int iwl_setup_mac(struct iwl_priv *priv); int iwl_set_hw_params(struct iwl_priv *priv); int iwl_init_drv(struct iwl_priv *priv); void iwl_uninit_drv(struct iwl_priv *priv); +void iwl_post_associate(struct iwl_priv *priv); +void iwl_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes); /***************************************************** * RX handlers. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index ed31030c7643..6f44abc2dce0 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -233,50 +233,6 @@ u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flag } -static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) -{ - int rc = 0; - struct iwl_rx_packet *res = NULL; - struct iwl3945_rxon_assoc_cmd rxon_assoc; - struct iwl_host_cmd cmd = { - .id = REPLY_RXON_ASSOC, - .len = sizeof(rxon_assoc), - .meta.flags = CMD_WANT_SKB, - .data = &rxon_assoc, - }; - const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; - const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; - - if ((rxon1->flags == rxon2->flags) && - (rxon1->filter_flags == rxon2->filter_flags) && - (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && - (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { - IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n"); - return 0; - } - - rxon_assoc.flags = priv->staging_rxon.flags; - rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; - rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; - rxon_assoc.reserved = 0; - - rc = iwl_send_cmd_sync(priv, &cmd); - if (rc) - return rc; - - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; - if (res->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); - rc = -EIO; - } - - priv->alloc_rxb_skb--; - dev_kfree_skb_any(cmd.meta.u.skb); - - return rc; -} - /** * iwl3945_get_antenna_flags - Get antenna flags for RXON command * @priv: eeprom and antenna fields are used to determine antenna flags @@ -352,7 +308,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) * iwl3945_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ if (!iwl_full_rxon_required(priv)) { - rc = iwl3945_send_rxon_assoc(priv); + rc = iwl_send_rxon_assoc(priv); if (rc) { IWL_ERR(priv, "Error setting RXON_ASSOC " "configuration (%d).\n", rc); @@ -3450,9 +3406,11 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) mutex_unlock(&priv->mutex); } +static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed); + #define IWL_DELAY_NEXT_SCAN (HZ*2) -static void iwl3945_post_associate(struct iwl_priv *priv) +void iwl3945_post_associate(struct iwl_priv *priv) { int rc = 0; struct ieee80211_conf *conf = NULL; @@ -3542,8 +3500,6 @@ static void iwl3945_post_associate(struct iwl_priv *priv) priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; } -static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed); - /***************************************************************************** * * mac80211 entry point functions @@ -3982,66 +3938,6 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); } -#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) - -static void iwl3945_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) -{ - struct iwl_priv *priv = hw->priv; - - IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); - - if (changes & BSS_CHANGED_ERP_PREAMBLE) { - IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; - else - priv->staging_rxon.flags &= - ~RXON_FLG_SHORT_PREAMBLE_MSK; - } - - if (changes & BSS_CHANGED_ERP_CTS_PROT) { - IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", - bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) - priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; - else - priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; - } - - if (changes & BSS_CHANGED_ASSOC) { - IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); - /* This should never happen as this function should - * never be called from interrupt context. */ - if (WARN_ON_ONCE(in_interrupt())) - return; - if (bss_conf->assoc) { - priv->assoc_id = bss_conf->aid; - priv->beacon_int = bss_conf->beacon_int; - priv->timestamp = bss_conf->timestamp; - priv->assoc_capability = bss_conf->assoc_capability; - priv->power_data.dtim_period = bss_conf->dtim_period; - priv->next_scan_jiffies = jiffies + - IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; - mutex_lock(&priv->mutex); - iwl3945_post_associate(priv); - mutex_unlock(&priv->mutex); - } else { - priv->assoc_id = 0; - IWL_DEBUG_MAC80211(priv, - "DISASSOC %d\n", bss_conf->assoc); - } - } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { - IWL_DEBUG_MAC80211(priv, - "Associated Changes %d\n", changes); - iwl3945_send_rxon_assoc(priv); - } - -} - static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -4227,7 +4123,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk iwl_reset_qos(priv); - iwl3945_post_associate(priv); + priv->cfg->ops->lib->post_associate(priv); return 0; @@ -4765,7 +4661,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .get_tx_stats = iwl3945_mac_get_tx_stats, .conf_tx = iwl_mac_conf_tx, .reset_tsf = iwl3945_mac_reset_tsf, - .bss_info_changed = iwl3945_bss_info_changed, + .bss_info_changed = iwl_bss_info_changed, .hw_scan = iwl_mac_hw_scan }; -- GitLab From 9944b938f23fdd1ce2f5da190f771f176bb51eef Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:36 -0700 Subject: [PATCH 0574/6080] iwl3945: use iwl_mac_beacon_update 3945 can use iwl_mac_beacon_update. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 43 ------------------ drivers/net/wireless/iwlwifi/iwl-core.c | 41 +++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 49 +-------------------- 4 files changed, 44 insertions(+), 90 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d14146fa751f..124a477ebd99 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1443,10 +1443,6 @@ static int iwl_read_ucode(struct iwl_priv *priv) return ret; } -/* temporary */ -static int iwl_mac_beacon_update(struct ieee80211_hw *hw, - struct sk_buff *skb); - /** * iwl_alive_start - called after REPLY_ALIVE notification received * from protocol/runtime uCode (initialization uCode's @@ -2657,45 +2653,6 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "leave\n"); } -static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - __le64 timestamp; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; - } - - if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { - IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n"); - return -EIO; - } - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - - priv->ibss_beacon = skb; - - priv->assoc_id = 0; - timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; - priv->timestamp = le64_to_cpu(timestamp); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - spin_unlock_irqrestore(&priv->lock, flags); - - iwl_reset_qos(priv); - - priv->cfg->ops->lib->post_associate(priv); - - - return 0; -} /***************************************************************************** * diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 15691829e023..eaeeb4dae0ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2293,6 +2293,47 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_bss_info_changed); +int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + __le64 timestamp; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return -EIO; + } + + if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { + IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n"); + return -EIO; + } + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->ibss_beacon) + dev_kfree_skb(priv->ibss_beacon); + + priv->ibss_beacon = skb; + + priv->assoc_id = 0; + timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; + priv->timestamp = le64_to_cpu(timestamp); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_reset_qos(priv); + + priv->cfg->ops->lib->post_associate(priv); + + + return 0; +} +EXPORT_SYMBOL(iwl_mac_beacon_update); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4ad8465ae5fb..04473858b9b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -258,6 +258,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); +int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); /***************************************************** * RX handlers. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 6f44abc2dce0..857393a69016 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2792,11 +2792,6 @@ static void iwl3945_init_alive_start(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->restart); } - -/* temporary */ -static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, - struct sk_buff *skb); - /** * iwl3945_alive_start - called after REPLY_ALIVE notification received * from protocol/runtime uCode (initialization uCode's @@ -2904,7 +2899,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) struct sk_buff *beacon = ieee80211_beacon_get(priv->hw, priv->vif); if (beacon) - iwl3945_mac_beacon_update(priv->hw, beacon); + iwl_mac_beacon_update(priv->hw, beacon); } return; @@ -3837,7 +3832,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, if (!beacon) return -ENOMEM; mutex_lock(&priv->mutex); - rc = iwl3945_mac_beacon_update(hw, beacon); + rc = iwl_mac_beacon_update(hw, beacon); mutex_unlock(&priv->mutex); if (rc) return rc; @@ -4089,46 +4084,6 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) } -static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - __le64 timestamp; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; - } - - if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { - IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n"); - return -EIO; - } - - spin_lock_irqsave(&priv->lock, flags); - - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - - priv->ibss_beacon = skb; - - priv->assoc_id = 0; - timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; - priv->timestamp = le64_to_cpu(timestamp); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - spin_unlock_irqrestore(&priv->lock, flags); - - iwl_reset_qos(priv); - - priv->cfg->ops->lib->post_associate(priv); - - - return 0; -} - /***************************************************************************** * * sysfs attributes -- GitLab From e0158e61108bdadd70865c2149dc829a5c84dd73 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:37 -0700 Subject: [PATCH 0575/6080] iwlwifi: add commit_rxon lib Patch adds commit_rxon lib operation to iwlwifi and iwl3945 drivers. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 145 ++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-3945.h | 1 + drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 32 ++-- drivers/net/wireless/iwlwifi/iwl-core.h | 6 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 174 ++------------------ 7 files changed, 185 insertions(+), 175 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 519e8922d9f4..9a0fb80023ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2008,6 +2008,150 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) return rc; } +/** + * iwl3945_commit_rxon - commit staging_rxon to hardware + * + * The RXON command in staging_rxon is committed to the hardware and + * the active_rxon structure is updated with the new data. This + * function correctly transitions out of the RXON_ASSOC_MSK state if + * a HW tune is required based on the RXON structure changes. + */ +static int iwl3945_commit_rxon(struct iwl_priv *priv) +{ + /* cast away the const for active_rxon in this function */ + struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon; + struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon; + int rc = 0; + bool new_assoc = + !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); + + if (!iwl_is_alive(priv)) + return -1; + + /* always get timestamp with Rx frame */ + staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK; + + /* select antenna */ + staging_rxon->flags &= + ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); + staging_rxon->flags |= iwl3945_get_antenna_flags(priv); + + rc = iwl_check_rxon_cmd(priv); + if (rc) { + IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); + return -EINVAL; + } + + /* If we don't need to send a full RXON, we can use + * iwl3945_rxon_assoc_cmd which is used to reconfigure filter + * and other flags for the current radio configuration. */ + if (!iwl_full_rxon_required(priv)) { + rc = iwl_send_rxon_assoc(priv); + if (rc) { + IWL_ERR(priv, "Error setting RXON_ASSOC " + "configuration (%d).\n", rc); + return rc; + } + + memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); + + return 0; + } + + /* If we are currently associated and the new config requires + * an RXON_ASSOC and the new config wants the associated mask enabled, + * we must clear the associated from the active configuration + * before we apply the new config */ + if (iwl_is_associated(priv) && new_assoc) { + IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); + active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; + + /* + * reserved4 and 5 could have been filled by the iwlcore code. + * Let's clear them before pushing to the 3945. + */ + active_rxon->reserved4 = 0; + active_rxon->reserved5 = 0; + rc = iwl_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl3945_rxon_cmd), + &priv->active_rxon); + + /* If the mask clearing failed then we set + * active_rxon back to what it was previously */ + if (rc) { + active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; + IWL_ERR(priv, "Error clearing ASSOC_MSK on current " + "configuration (%d).\n", rc); + return rc; + } + } + + IWL_DEBUG_INFO(priv, "Sending RXON\n" + "* with%s RXON_FILTER_ASSOC_MSK\n" + "* channel = %d\n" + "* bssid = %pM\n", + (new_assoc ? "" : "out"), + le16_to_cpu(staging_rxon->channel), + staging_rxon->bssid_addr); + + /* + * reserved4 and 5 could have been filled by the iwlcore code. + * Let's clear them before pushing to the 3945. + */ + staging_rxon->reserved4 = 0; + staging_rxon->reserved5 = 0; + + iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto); + + /* Apply the new configuration */ + rc = iwl_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl3945_rxon_cmd), + staging_rxon); + if (rc) { + IWL_ERR(priv, "Error setting new configuration (%d).\n", rc); + return rc; + } + + memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); + + iwl3945_clear_stations_table(priv); + + /* If we issue a new RXON command which required a tune then we must + * send a new TXPOWER command or we won't be able to Tx any frames */ + rc = priv->cfg->ops->lib->send_tx_power(priv); + if (rc) { + IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); + return rc; + } + + /* Add the broadcast address so we can send broadcast frames */ + if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) == + IWL_INVALID_STATION) { + IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); + return -EIO; + } + + /* If we have set the ASSOC_MSK and we are in BSS mode then + * add the IWL_AP_ID to the station rate table */ + if (iwl_is_associated(priv) && + (priv->iw_mode == NL80211_IFTYPE_STATION)) + if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, + 1, 0) + == IWL_INVALID_STATION) { + IWL_ERR(priv, "Error adding AP address for transmit\n"); + return -EIO; + } + + /* Init the hardware's rate fallback order based on the band */ + rc = iwl3945_init_hw_rate_table(priv); + if (rc) { + IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc); + return -EIO; + } + + return 0; +} + /* will add 3945 channel switch cmd handling later */ int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel) { @@ -2775,6 +2919,7 @@ static int iwl3945_load_bsm(struct iwl_priv *priv) static struct iwl_hcmd_ops iwl3945_hcmd = { .rxon_assoc = iwl3945_send_rxon_assoc, + .commit_rxon = iwl3945_commit_rxon, }; static struct iwl_lib_ops iwl3945_lib = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 13b191f155ad..8e3e8161526a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -207,6 +207,7 @@ extern int iwl3945_send_add_station(struct iwl_priv *priv, struct iwl3945_addsta_cmd *sta, u8 flags); extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid, int is_ap, u8 flags); +extern void iwl3945_clear_stations_table(struct iwl_priv *priv); extern int iwl3945_power_init_handle(struct iwl_priv *priv); extern int iwl3945_eeprom_init(struct iwl_priv *priv); extern int iwl3945_calc_db_from_ratio(int sig_ratio); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 37544afbebe6..053e42091124 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2271,6 +2271,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) static struct iwl_hcmd_ops iwl4965_hcmd = { .rxon_assoc = iwl4965_send_rxon_assoc, + .commit_rxon = iwl_commit_rxon, }; static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 837dbad80e5e..410cba221610 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1474,6 +1474,7 @@ int iwl5000_calc_rssi(struct iwl_priv *priv, struct iwl_hcmd_ops iwl5000_hcmd = { .rxon_assoc = iwl5000_send_rxon_assoc, + .commit_rxon = iwl_commit_rxon, }; struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 124a477ebd99..50ef649b1c97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -102,7 +102,7 @@ MODULE_ALIAS("iwl4965"); * function correctly transitions out of the RXON_ASSOC_MSK state if * a HW tune is required based on the RXON structure changes. */ -static int iwl_commit_rxon(struct iwl_priv *priv) +int iwl_commit_rxon(struct iwl_priv *priv) { /* cast away the const for active_rxon in this function */ struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; @@ -247,7 +247,7 @@ void iwl_update_chain_flags(struct iwl_priv *priv) { iwl_set_rxon_chain(priv); - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); } static void iwl_clear_free_frames(struct iwl_priv *priv) @@ -606,7 +606,7 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode) return -EAGAIN; } - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); return 0; } @@ -1000,7 +1000,7 @@ static void iwl_error_recovery(struct iwl_priv *priv) memcpy(&priv->staging_rxon, &priv->recovery_rxon, sizeof(priv->staging_rxon)); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); iwl_rxon_add_station(priv, priv->bssid, 1); @@ -1509,7 +1509,7 @@ static void iwl_alive_start(struct iwl_priv *priv) iwl_reset_run_time_calib(priv); /* Configure the adapter for unassociated operation */ - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); /* At this point, the NIC is initialized and operational */ iwl_rf_kill_ct_config(priv); @@ -1865,7 +1865,7 @@ void iwl_post_associate(struct iwl_priv *priv) conf = ieee80211_get_hw_conf(priv->hw); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); iwl_setup_rxon_timing(priv); ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, @@ -1900,7 +1900,7 @@ void iwl_post_associate(struct iwl_priv *priv) } - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); switch (priv->iw_mode) { case NL80211_IFTYPE_STATION: @@ -2211,7 +2211,7 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) if (memcmp(&priv->active_rxon, &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); else IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n"); @@ -2235,7 +2235,7 @@ static void iwl_config_ap(struct iwl_priv *priv) /* RXON - unassoc (to set timing command) */ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); /* RXON Timing */ iwl_setup_rxon_timing(priv); @@ -2271,7 +2271,7 @@ static void iwl_config_ap(struct iwl_priv *priv) } /* restore RXON assoc */ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); spin_lock_irqsave(&priv->lock, flags); iwl_activate_qos(priv, 1); spin_unlock_irqrestore(&priv->lock, flags); @@ -2365,7 +2365,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, if (priv->iw_mode == NL80211_IFTYPE_AP) iwl_config_ap(priv); else { - rc = iwl_commit_rxon(priv); + rc = iwlcore_commit_rxon(priv); if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) iwl_rxon_add_station( priv, priv->active_rxon.bssid_addr, 1); @@ -2374,7 +2374,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, } else { iwl_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); } done: @@ -2396,7 +2396,7 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw, if (iwl_is_ready_rf(priv)) { iwl_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); } if (priv->vif == conf->vif) { priv->vif = NULL; @@ -2623,7 +2623,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) if (priv->iw_mode != NL80211_IFTYPE_AP) { iwl_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); } iwl_power_update_mode(priv, 0); @@ -2803,7 +2803,7 @@ static ssize_t store_flags(struct device *d, else { IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags); priv->staging_rxon.flags = cpu_to_le32(flags); - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); } } mutex_unlock(&priv->mutex); @@ -2844,7 +2844,7 @@ static ssize_t store_filter_flags(struct device *d, "0x%04X\n", filter_flags); priv->staging_rxon.filter_flags = cpu_to_le32(filter_flags); - iwl_commit_rxon(priv); + iwlcore_commit_rxon(priv); } } mutex_unlock(&priv->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 04473858b9b5..c7e05953cb75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -85,6 +85,7 @@ struct iwl_cmd; struct iwl_hcmd_ops { int (*rxon_assoc)(struct iwl_priv *priv); + int (*commit_rxon)(struct iwl_priv *priv); }; struct iwl_hcmd_utils_ops { u16 (*get_hcmd_size)(u8 cmd_id, u16 len); @@ -259,6 +260,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *bss_conf, u32 changes); int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); +int iwl_commit_rxon(struct iwl_priv *priv); /***************************************************** * RX handlers. @@ -541,6 +543,10 @@ static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) { return priv->cfg->ops->hcmd->rxon_assoc(priv); } +static inline int iwlcore_commit_rxon(struct iwl_priv *priv) +{ + return priv->cfg->ops->hcmd->commit_rxon(priv); +} static inline const struct ieee80211_supported_band *iwl_get_hw_mode( struct iwl_priv *priv, enum ieee80211_band band) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 857393a69016..e96a726dc5c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -149,7 +149,7 @@ out: * * NOTE: This does not clear or otherwise alter the device's station table. */ -static void iwl3945_clear_stations_table(struct iwl_priv *priv) +void iwl3945_clear_stations_table(struct iwl_priv *priv) { unsigned long flags; @@ -270,150 +270,6 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv) return 0; /* "diversity" is default if error */ } -/** - * iwl3945_commit_rxon - commit staging_rxon to hardware - * - * The RXON command in staging_rxon is committed to the hardware and - * the active_rxon structure is updated with the new data. This - * function correctly transitions out of the RXON_ASSOC_MSK state if - * a HW tune is required based on the RXON structure changes. - */ -static int iwl3945_commit_rxon(struct iwl_priv *priv) -{ - /* cast away the const for active_rxon in this function */ - struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon; - struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon; - int rc = 0; - bool new_assoc = - !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); - - if (!iwl_is_alive(priv)) - return -1; - - /* always get timestamp with Rx frame */ - staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK; - - /* select antenna */ - staging_rxon->flags &= - ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); - staging_rxon->flags |= iwl3945_get_antenna_flags(priv); - - rc = iwl_check_rxon_cmd(priv); - if (rc) { - IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); - return -EINVAL; - } - - /* If we don't need to send a full RXON, we can use - * iwl3945_rxon_assoc_cmd which is used to reconfigure filter - * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv)) { - rc = iwl_send_rxon_assoc(priv); - if (rc) { - IWL_ERR(priv, "Error setting RXON_ASSOC " - "configuration (%d).\n", rc); - return rc; - } - - memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - - return 0; - } - - /* If we are currently associated and the new config requires - * an RXON_ASSOC and the new config wants the associated mask enabled, - * we must clear the associated from the active configuration - * before we apply the new config */ - if (iwl_is_associated(priv) && new_assoc) { - IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); - active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - - /* - * reserved4 and 5 could have been filled by the iwlcore code. - * Let's clear them before pushing to the 3945. - */ - active_rxon->reserved4 = 0; - active_rxon->reserved5 = 0; - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl3945_rxon_cmd), - &priv->active_rxon); - - /* If the mask clearing failed then we set - * active_rxon back to what it was previously */ - if (rc) { - active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK; - IWL_ERR(priv, "Error clearing ASSOC_MSK on current " - "configuration (%d).\n", rc); - return rc; - } - } - - IWL_DEBUG_INFO(priv, "Sending RXON\n" - "* with%s RXON_FILTER_ASSOC_MSK\n" - "* channel = %d\n" - "* bssid = %pM\n", - (new_assoc ? "" : "out"), - le16_to_cpu(staging_rxon->channel), - staging_rxon->bssid_addr); - - /* - * reserved4 and 5 could have been filled by the iwlcore code. - * Let's clear them before pushing to the 3945. - */ - staging_rxon->reserved4 = 0; - staging_rxon->reserved5 = 0; - - iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto); - - /* Apply the new configuration */ - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl3945_rxon_cmd), - staging_rxon); - if (rc) { - IWL_ERR(priv, "Error setting new configuration (%d).\n", rc); - return rc; - } - - memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - - iwl3945_clear_stations_table(priv); - - /* If we issue a new RXON command which required a tune then we must - * send a new TXPOWER command or we won't be able to Tx any frames */ - rc = priv->cfg->ops->lib->send_tx_power(priv); - if (rc) { - IWL_ERR(priv, "Error setting Tx power (%d).\n", rc); - return rc; - } - - /* Add the broadcast address so we can send broadcast frames */ - if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) == - IWL_INVALID_STATION) { - IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); - return -EIO; - } - - /* If we have set the ASSOC_MSK and we are in BSS mode then - * add the IWL_AP_ID to the station rate table */ - if (iwl_is_associated(priv) && - (priv->iw_mode == NL80211_IFTYPE_STATION)) - if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, - 1, 0) - == IWL_INVALID_STATION) { - IWL_ERR(priv, "Error adding AP address for transmit\n"); - return -EIO; - } - - /* Init the hardware's rate fallback order based on the band */ - rc = iwl3945_init_hw_rate_table(priv); - if (rc) { - IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc); - return -EIO; - } - - return 0; -} - static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, struct ieee80211_key_conf *keyconf, u8 sta_id) @@ -745,7 +601,7 @@ static int iwl3945_set_mode(struct iwl_priv *priv, int mode) return -EAGAIN; } - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); return 0; } @@ -2025,7 +1881,7 @@ static void iwl3945_error_recovery(struct iwl_priv *priv) memcpy(&priv->staging_rxon, &priv->recovery_rxon, sizeof(priv->staging_rxon)); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); iwl3945_add_station(priv, priv->bssid, 1, 0); @@ -2881,7 +2737,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) iwl_send_bt_config(priv); /* Configure the adapter for unassociated operation */ - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); iwl3945_reg_txpower_periodic(priv); @@ -3430,7 +3286,7 @@ void iwl3945_post_associate(struct iwl_priv *priv) conf = ieee80211_get_hw_conf(priv->hw); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); iwl3945_setup_rxon_timing(priv); @@ -3463,7 +3319,7 @@ void iwl3945_post_associate(struct iwl_priv *priv) } - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); switch (priv->iw_mode) { case NL80211_IFTYPE_STATION: @@ -3740,7 +3596,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed) if (memcmp(&priv->active_rxon, &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); else IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n"); @@ -3764,7 +3620,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv) /* RXON - unassoc (to set timing command) */ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); /* RXON Timing */ memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); @@ -3800,7 +3656,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv) } /* restore RXON assoc */ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); iwl3945_add_station(priv, iwl_bcast_addr, 0, 0); } iwl3945_send_beacon_cmd(priv); @@ -3891,7 +3747,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, if (priv->iw_mode == NL80211_IFTYPE_AP) iwl3945_config_ap(priv); else { - rc = iwl3945_commit_rxon(priv); + rc = iwlcore_commit_rxon(priv); if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0); @@ -3900,7 +3756,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, } else { iwl_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); } done: @@ -3922,7 +3778,7 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, if (iwl_is_ready_rf(priv)) { iwl_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); } if (priv->vif == conf->vif) { priv->vif = NULL; @@ -4065,7 +3921,7 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) if (priv->iw_mode != NL80211_IFTYPE_AP) { iwl_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); } /* Per mac80211.h: This is only used in IBSS mode... */ @@ -4191,7 +4047,7 @@ static ssize_t store_flags(struct device *d, IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", flags); priv->staging_rxon.flags = cpu_to_le32(flags); - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); } } mutex_unlock(&priv->mutex); @@ -4227,7 +4083,7 @@ static ssize_t store_filter_flags(struct device *d, "0x%04X\n", filter_flags); priv->staging_rxon.filter_flags = cpu_to_le32(filter_flags); - iwl3945_commit_rxon(priv); + iwlcore_commit_rxon(priv); } } mutex_unlock(&priv->mutex); -- GitLab From f45c271493c37d2d80177582191acc1a4e446297 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:38 -0700 Subject: [PATCH 0576/6080] iwl3945: delay mode setting Delay mode setting till uCode is ready. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index e96a726dc5c9..0ad89fb90d05 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2758,6 +2758,9 @@ static void iwl3945_alive_start(struct iwl_priv *priv) iwl_mac_beacon_update(priv->hw, beacon); } + if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) + iwl3945_set_mode(priv, priv->iw_mode); + return; restart: @@ -3497,8 +3500,8 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); } - if (iwl_is_ready(priv)) - iwl3945_set_mode(priv, conf->type); + if (iwl3945_set_mode(priv, conf->type) == -EAGAIN) + set_bit(STATUS_MODE_PENDING, &priv->status); mutex_unlock(&priv->mutex); -- GitLab From 79fa455a995057b6559fcd2a02e8b089b2e2e288 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:39 -0700 Subject: [PATCH 0577/6080] iwlwifi: add station management ops This patch adds declarations for station management ops to iwlwifi drivers. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 10 ++++++++++ drivers/net/wireless/iwlwifi/iwl-4965.c | 7 +++++++ drivers/net/wireless/iwlwifi/iwl-5000.c | 8 ++++++++ drivers/net/wireless/iwlwifi/iwl-6000.c | 1 + drivers/net/wireless/iwlwifi/iwl-core.h | 13 +++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 6 files changed, 40 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 9a0fb80023ab..fb08295417f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2954,6 +2954,15 @@ static struct iwl_lib_ops iwl3945_lib = { .post_associate = iwl3945_post_associate, }; +static struct iwl_station_mgmt_ops iwl3945_station_mgmt = { + .add_station = iwl3945_add_station, +#if 0 + .remove_station = iwl3945_remove_station, +#endif + .find_station = iwl3945_hw_find_station, + .clear_station_table = iwl3945_clear_stations_table, +}; + static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { .get_hcmd_size = iwl3945_get_hcmd_size, .build_addsta_hcmd = iwl3945_build_addsta_hcmd, @@ -2963,6 +2972,7 @@ static struct iwl_ops iwl3945_ops = { .lib = &iwl3945_lib, .hcmd = &iwl3945_hcmd, .utils = &iwl3945_hcmd_utils, + .smgmt = &iwl3945_station_mgmt, }; static struct iwl_cfg iwl3945_bg_cfg = { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 053e42091124..e3d1e30e62b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2268,6 +2268,12 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) cancel_work_sync(&priv->txpower_work); } +static struct iwl_station_mgmt_ops iwl4965_station_mgmt = { + .add_station_ht = iwl_add_station_flags, + .remove_station = iwl_remove_station, + .find_station = iwl_find_station, + .clear_station_table = iwl_clear_stations_table, +}; static struct iwl_hcmd_ops iwl4965_hcmd = { .rxon_assoc = iwl4965_send_rxon_assoc, @@ -2332,6 +2338,7 @@ static struct iwl_ops iwl4965_ops = { .lib = &iwl4965_lib, .hcmd = &iwl4965_hcmd, .utils = &iwl4965_hcmd_utils, + .smgmt = &iwl4965_station_mgmt, }; struct iwl_cfg iwl4965_agn_cfg = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 410cba221610..1344943a5f36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1472,6 +1472,13 @@ int iwl5000_calc_rssi(struct iwl_priv *priv, return max_rssi - agc - IWL49_RSSI_OFFSET; } +struct iwl_station_mgmt_ops iwl5000_station_mgmt = { + .add_station_ht = iwl_add_station_flags, + .remove_station = iwl_remove_station, + .find_station = iwl_find_station, + .clear_station_table = iwl_clear_stations_table, +}; + struct iwl_hcmd_ops iwl5000_hcmd = { .rxon_assoc = iwl5000_send_rxon_assoc, .commit_rxon = iwl_commit_rxon, @@ -1535,6 +1542,7 @@ struct iwl_ops iwl5000_ops = { .lib = &iwl5000_lib, .hcmd = &iwl5000_hcmd, .utils = &iwl5000_hcmd_utils, + .smgmt = &iwl5000_station_mgmt, }; struct iwl_mod_params iwl50_mod_params = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index edfa5e149f71..ee271d7f6120 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -72,6 +72,7 @@ static struct iwl_ops iwl6000_ops = { .lib = &iwl5000_lib, .hcmd = &iwl5000_hcmd, .utils = &iwl6000_hcmd_utils, + .smgmt = &iwl5000_station_mgmt, }; struct iwl_cfg iwl6000_2ag_cfg = { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index c7e05953cb75..8b7f5bd2c8e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -83,10 +83,22 @@ struct iwl_cmd; #define IWL_SKU_A 0x2 #define IWL_SKU_N 0x8 +struct iwl_station_mgmt_ops { + u8 (*add_station_ht)(struct iwl_priv *priv, const u8 *addr, + int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info); + u8 (*add_station)(struct iwl_priv *priv, const u8 *addr, + int is_ap, u8 flags); + int (*remove_station)(struct iwl_priv *priv, const u8 *addr, + int is_ap); + u8 (*find_station)(struct iwl_priv *priv, const u8 *addr); + void (*clear_station_table)(struct iwl_priv *priv); +}; + struct iwl_hcmd_ops { int (*rxon_assoc)(struct iwl_priv *priv); int (*commit_rxon)(struct iwl_priv *priv); }; + struct iwl_hcmd_utils_ops { u16 (*get_hcmd_size)(u8 cmd_id, u16 len); u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); @@ -160,6 +172,7 @@ struct iwl_ops { const struct iwl_lib_ops *lib; const struct iwl_hcmd_ops *hcmd; const struct iwl_hcmd_utils_ops *utils; + const struct iwl_station_mgmt_ops *smgmt; }; struct iwl_mod_params { diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index ec9a13846edd..59930f398f31 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -70,6 +70,7 @@ extern struct iwl_ops iwl5000_ops; extern struct iwl_lib_ops iwl5000_lib; extern struct iwl_hcmd_ops iwl5000_hcmd; extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils; +extern struct iwl_station_mgmt_ops iwl5000_station_mgmt; /* shared functions from iwl-5000.c */ extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len); -- GitLab From 40ace5b385ccf8a4d4d096b353b7f1baac1d014b Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:40 -0700 Subject: [PATCH 0578/6080] iwl3945: replace station function with station ops Patch replaces station function used in driver by station management ops in 3945. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 8 +++--- drivers/net/wireless/iwlwifi/iwl3945-base.c | 29 +++++++++++---------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index fb08295417f0..7c0c7992b596 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2114,7 +2114,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - iwl3945_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ @@ -2125,7 +2125,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) } /* Add the broadcast address so we can send broadcast frames */ - if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) == + if (priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0) == IWL_INVALID_STATION) { IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); return -EIO; @@ -2135,8 +2135,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) * add the IWL_AP_ID to the station rate table */ if (iwl_is_associated(priv) && (priv->iw_mode == NL80211_IFTYPE_STATION)) - if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, - 1, 0) + if (priv->cfg->ops->smgmt->add_station(priv, + priv->active_rxon.bssid_addr, 1, 0) == IWL_INVALID_STATION) { IWL_ERR(priv, "Error adding AP address for transmit\n"); return -EIO; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 0ad89fb90d05..f5f39cc28102 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -588,7 +588,7 @@ static int iwl3945_set_mode(struct iwl_priv *priv, int mode) iwl_connection_init_rx_config(priv, mode); - iwl3945_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* don't commit rxon if rf-kill is on*/ if (!iwl_is_ready_rf(priv)) @@ -734,7 +734,7 @@ static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) /* If we are an AP, then find the station, or use BCAST */ case NL80211_IFTYPE_AP: - sta_id = iwl3945_hw_find_station(priv, hdr->addr1); + sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; return priv->hw_params.bcast_sta_id; @@ -743,11 +743,12 @@ static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) * or create a new station table entry */ case NL80211_IFTYPE_ADHOC: { /* Create new station table entry */ - sta_id = iwl3945_hw_find_station(priv, hdr->addr1); + sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; - sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC); + sta_id = priv->cfg->ops->smgmt->add_station(priv, + hdr->addr1, 0, CMD_ASYNC); if (sta_id != IWL_INVALID_STATION) return sta_id; @@ -1883,7 +1884,7 @@ static void iwl3945_error_recovery(struct iwl_priv *priv) priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv); - iwl3945_add_station(priv, priv->bssid, 1, 0); + priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 1, 0); spin_lock_irqsave(&priv->lock, flags); priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); @@ -2678,7 +2679,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) goto restart; } - iwl3945_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); rc = iwl_grab_nic_access(priv); if (rc) { @@ -2783,7 +2784,7 @@ static void __iwl3945_down(struct iwl_priv *priv) set_bit(STATUS_EXIT_PENDING, &priv->status); iwl3945_led_unregister(priv); - iwl3945_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); @@ -2940,7 +2941,7 @@ static int __iwl3945_up(struct iwl_priv *priv) for (i = 0; i < MAX_HW_RESTARTS; i++) { - iwl3945_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* load bootstrap state machine, * load bootstrap program into processor's memory, @@ -3332,7 +3333,7 @@ void iwl3945_post_associate(struct iwl_priv *priv) case NL80211_IFTYPE_ADHOC: priv->assoc_id = 1; - iwl3945_add_station(priv, priv->bssid, 0, 0); + priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0); iwl3945_sync_sta(priv, IWL_STA_ID, (priv->band == IEEE80211_BAND_5GHZ) ? IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, @@ -3660,7 +3661,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv) /* restore RXON assoc */ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv); - iwl3945_add_station(priv, iwl_bcast_addr, 0, 0); + priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0); } iwl3945_send_beacon_cmd(priv); @@ -3752,7 +3753,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, else { rc = iwlcore_commit_rxon(priv); if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) - iwl3945_add_station(priv, + priv->cfg->ops->smgmt->add_station(priv, priv->active_rxon.bssid_addr, 1, 0); } @@ -3814,7 +3815,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, static_key = !iwl_is_associated(priv); if (!static_key) { - sta_id = iwl3945_hw_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", addr); @@ -4497,7 +4498,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) mutex_init(&priv->mutex); /* Clear the driver's (not device's) station table */ - iwl3945_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); priv->data_retry_limit = -1; priv->ieee_channels = NULL; @@ -4860,7 +4861,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) iwl3945_hw_txq_ctx_free(priv); iwl3945_unset_hw_params(priv); - iwl3945_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /*netif_stop_queue(dev); */ flush_workqueue(priv->workqueue); -- GitLab From e11bc0286a4ff8f4e5cdefbcce0878d29c03c630 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:41 -0700 Subject: [PATCH 0579/6080] iwlwifi: use station management ops Patch replaces station management functions with ops declared. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 16 ++++++++++------ drivers/net/wireless/iwlwifi/iwl-agn.c | 14 +++++++------- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 20 ++++++++++---------- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 1344943a5f36..26f30a7ecb1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -678,7 +678,7 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv) goto restart; } - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); ret = priv->cfg->ops->lib->alive_notify(priv); if (ret) { IWL_WARN(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 7cdbcfe483f3..a99512807f63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2453,13 +2453,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && !lq_sta->ibss_sta_added) { - u8 sta_id = iwl_find_station(priv, hdr->addr1); + u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, + hdr->addr1); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", hdr->addr1); - sta_id = iwl_add_station_flags(priv, hdr->addr1, - 0, CMD_ASYNC, NULL); + sta_id = priv->cfg->ops->smgmt->add_station_ht(priv, + hdr->addr1, 0, + CMD_ASYNC, NULL); } if ((sta_id != IWL_INVALID_STATION)) { lq_sta->lq.sta_id = sta_id; @@ -2526,15 +2528,17 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, lq_sta->ibss_sta_added = 0; if (priv->iw_mode == NL80211_IFTYPE_AP) { - u8 sta_id = iwl_find_station(priv, sta->addr); + u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, + sta->addr); /* for IBSS the call are from tasklet */ IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr); - sta_id = iwl_add_station_flags(priv, sta->addr, - 0, CMD_ASYNC, NULL); + sta_id = priv->cfg->ops->smgmt->add_station_ht(priv, + sta->addr, 0, + CMD_ASYNC, NULL); } if ((sta_id != IWL_INVALID_STATION)) { lq_sta->lq.sta_id = sta_id; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 50ef649b1c97..565a441052eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -188,7 +188,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); } - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); if (!priv->error_recovering) priv->start_calib = 0; @@ -593,7 +593,7 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode) iwl_set_rxon_chain(priv); memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* dont commit rxon if rf-kill is on*/ if (!iwl_is_ready_rf(priv)) @@ -1471,7 +1471,7 @@ static void iwl_alive_start(struct iwl_priv *priv) goto restart; } - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); ret = priv->cfg->ops->lib->alive_notify(priv); if (ret) { IWL_WARN(priv, @@ -1557,7 +1557,7 @@ static void __iwl_down(struct iwl_priv *priv) iwl_leds_unregister(priv); - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); @@ -1708,7 +1708,7 @@ static int __iwl_up(struct iwl_priv *priv) for (i = 0; i < MAX_HW_RESTARTS; i++) { - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); /* load bootstrap state machine, * load bootstrap program into processor's memory, @@ -2439,7 +2439,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } addr = sta ? sta->addr : iwl_bcast_addr; - sta_id = iwl_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", addr); @@ -3311,7 +3311,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) iwl_rx_queue_free(priv, &priv->rxq); iwl_hw_txq_ctx_free(priv); - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); iwl_eeprom_free(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index eaeeb4dae0ed..0532d99b9085 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1368,7 +1368,7 @@ int iwl_init_drv(struct iwl_priv *priv) mutex_init(&priv->mutex); /* Clear the driver's (not device's) station table */ - iwl_clear_stations_table(priv); + priv->cfg->ops->smgmt->clear_station_table(priv); priv->data_retry_limit = -1; priv->ieee_channels = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 5798fe49c771..5816368ffc40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -75,7 +75,7 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) return IWL_AP_ID; } else { u8 *da = ieee80211_get_DA(hdr); - return iwl_find_station(priv, da); + return priv->cfg->ops->smgmt->find_station(priv, da); } } EXPORT_SYMBOL(iwl_get_ra_sta_id); @@ -300,7 +300,7 @@ EXPORT_SYMBOL(iwl_add_station_flags); static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) { unsigned long flags; - u8 sta_id = iwl_find_station(priv, addr); + u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); BUG_ON(sta_id == IWL_INVALID_STATION); @@ -758,7 +758,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv, int i; DECLARE_MAC_BUF(mac); - sta_id = iwl_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", addr); @@ -1019,7 +1019,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) rcu_read_unlock(); } - sta_id = iwl_add_station_flags(priv, addr, is_ap, + sta_id = priv->cfg->ops->smgmt->add_station_ht(priv, addr, is_ap, 0, cur_ht_config); /* Set up default rate scaling table in device's station table */ @@ -1053,7 +1053,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) /* If we are an AP, then find the station, or use BCAST */ case NL80211_IFTYPE_AP: - sta_id = iwl_find_station(priv, hdr->addr1); + sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; return priv->hw_params.bcast_sta_id; @@ -1061,12 +1061,12 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) /* If this frame is going out to an IBSS network, find the station, * or create a new station table entry */ case NL80211_IFTYPE_ADHOC: - sta_id = iwl_find_station(priv, hdr->addr1); + sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; /* Create new station table entry */ - sta_id = iwl_add_station_flags(priv, hdr->addr1, + sta_id = priv->cfg->ops->smgmt->add_station_ht(priv, hdr->addr1, 0, CMD_ASYNC, NULL); if (sta_id != IWL_INVALID_STATION) @@ -1115,7 +1115,7 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, unsigned long flags; int sta_id; - sta_id = iwl_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) return -ENXIO; @@ -1137,7 +1137,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid) unsigned long flags; int sta_id; - sta_id = iwl_find_station(priv, addr); + sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); return -ENXIO; @@ -1172,7 +1172,7 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) { /* FIXME: need locking over ps_status ??? */ - u8 sta_id = iwl_find_station(priv, addr); + u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); if (sta_id != IWL_INVALID_STATION) { u8 sta_awake = priv->stations[sta_id]. -- GitLab From 06fd3d86a426848dbd8db27b7257a4eb4be8cfae Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:42 -0700 Subject: [PATCH 0580/6080] iwl3945/iwlwifi: unify add_station function Patch unifies the add_station function for 3945 and iwlwifi drivers. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-3945.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-3945.h | 2 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.h | 4 +--- drivers/net/wireless/iwlwifi/iwl-sta.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 12 ++++++------ 9 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index af6b9d444778..f63a9c5ba262 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -719,7 +719,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n", hdr->addr1); sta_id = iwl3945_add_station(priv, - hdr->addr1, 0, CMD_ASYNC); + hdr->addr1, 0, CMD_ASYNC, NULL); } if (sta_id != IWL_INVALID_STATION) rs_sta->ibss_sta_added = 1; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 7c0c7992b596..a854feba82c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2125,7 +2125,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) } /* Add the broadcast address so we can send broadcast frames */ - if (priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0) == + if (priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL) == IWL_INVALID_STATION) { IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); return -EIO; @@ -2136,7 +2136,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) if (iwl_is_associated(priv) && (priv->iw_mode == NL80211_IFTYPE_STATION)) if (priv->cfg->ops->smgmt->add_station(priv, - priv->active_rxon.bssid_addr, 1, 0) + priv->active_rxon.bssid_addr, 1, 0, NULL) == IWL_INVALID_STATION) { IWL_ERR(priv, "Error adding AP address for transmit\n"); return -EIO; diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 8e3e8161526a..88628b23efd9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -206,7 +206,7 @@ struct iwl3945_addsta_cmd; extern int iwl3945_send_add_station(struct iwl_priv *priv, struct iwl3945_addsta_cmd *sta, u8 flags); extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid, - int is_ap, u8 flags); + int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info); extern void iwl3945_clear_stations_table(struct iwl_priv *priv); extern int iwl3945_power_init_handle(struct iwl_priv *priv); extern int iwl3945_eeprom_init(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index e3d1e30e62b5..e98849edafd5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2269,7 +2269,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) } static struct iwl_station_mgmt_ops iwl4965_station_mgmt = { - .add_station_ht = iwl_add_station_flags, + .add_station = iwl_add_station_flags, .remove_station = iwl_remove_station, .find_station = iwl_find_station, .clear_station_table = iwl_clear_stations_table, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 26f30a7ecb1a..52ee77347328 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1473,7 +1473,7 @@ int iwl5000_calc_rssi(struct iwl_priv *priv, } struct iwl_station_mgmt_ops iwl5000_station_mgmt = { - .add_station_ht = iwl_add_station_flags, + .add_station = iwl_add_station_flags, .remove_station = iwl_remove_station, .find_station = iwl_find_station, .clear_station_table = iwl_clear_stations_table, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index a99512807f63..b1818a3d1e51 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2459,7 +2459,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", hdr->addr1); - sta_id = priv->cfg->ops->smgmt->add_station_ht(priv, + sta_id = priv->cfg->ops->smgmt->add_station(priv, hdr->addr1, 0, CMD_ASYNC, NULL); } @@ -2536,7 +2536,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr); - sta_id = priv->cfg->ops->smgmt->add_station_ht(priv, + sta_id = priv->cfg->ops->smgmt->add_station(priv, sta->addr, 0, CMD_ASYNC, NULL); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 8b7f5bd2c8e3..383590cd8b02 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -84,10 +84,8 @@ struct iwl_cmd; #define IWL_SKU_N 0x8 struct iwl_station_mgmt_ops { - u8 (*add_station_ht)(struct iwl_priv *priv, const u8 *addr, - int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info); u8 (*add_station)(struct iwl_priv *priv, const u8 *addr, - int is_ap, u8 flags); + int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info); int (*remove_station)(struct iwl_priv *priv, const u8 *addr, int is_ap); u8 (*find_station)(struct iwl_priv *priv, const u8 *addr); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 5816368ffc40..b8f18c697888 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1019,7 +1019,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) rcu_read_unlock(); } - sta_id = priv->cfg->ops->smgmt->add_station_ht(priv, addr, is_ap, + sta_id = priv->cfg->ops->smgmt->add_station(priv, addr, is_ap, 0, cur_ht_config); /* Set up default rate scaling table in device's station table */ @@ -1066,7 +1066,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) return sta_id; /* Create new station table entry */ - sta_id = priv->cfg->ops->smgmt->add_station_ht(priv, hdr->addr1, + sta_id = priv->cfg->ops->smgmt->add_station(priv, hdr->addr1, 0, CMD_ASYNC, NULL); if (sta_id != IWL_INVALID_STATION) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index f5f39cc28102..566914569104 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -164,7 +164,7 @@ void iwl3945_clear_stations_table(struct iwl_priv *priv) /** * iwl3945_add_station - Add station to station tables in driver and device */ -u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) +u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info) { int i; int index = IWL_INVALID_STATION; @@ -748,7 +748,7 @@ static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) return sta_id; sta_id = priv->cfg->ops->smgmt->add_station(priv, - hdr->addr1, 0, CMD_ASYNC); + hdr->addr1, 0, CMD_ASYNC, NULL); if (sta_id != IWL_INVALID_STATION) return sta_id; @@ -1884,7 +1884,7 @@ static void iwl3945_error_recovery(struct iwl_priv *priv) priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv); - priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 1, 0); + priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 1, 0, NULL); spin_lock_irqsave(&priv->lock, flags); priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); @@ -3333,7 +3333,7 @@ void iwl3945_post_associate(struct iwl_priv *priv) case NL80211_IFTYPE_ADHOC: priv->assoc_id = 1; - priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0); + priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0, NULL); iwl3945_sync_sta(priv, IWL_STA_ID, (priv->band == IEEE80211_BAND_5GHZ) ? IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, @@ -3661,7 +3661,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv) /* restore RXON assoc */ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; iwlcore_commit_rxon(priv); - priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0); + priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL); } iwl3945_send_beacon_cmd(priv); @@ -3754,7 +3754,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, rc = iwlcore_commit_rxon(priv); if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) priv->cfg->ops->smgmt->add_station(priv, - priv->active_rxon.bssid_addr, 1, 0); + priv->active_rxon.bssid_addr, 1, 0, NULL); } } else { -- GitLab From f5d3026683da45e00c49a24999ad0d256e4651d5 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:43 -0700 Subject: [PATCH 0581/6080] iwl3945: use iwl_get_sta_id from iwlwifi iwl3945 can now use iwl_get_sta_id. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 61 +-------------------- 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 566914569104..7f35017d9df2 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -712,65 +712,6 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, tx->next_frame_len = 0; } -/** - * iwl3945_get_sta_id - Find station's index within station table - */ -static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) -{ - int sta_id; - u16 fc = le16_to_cpu(hdr->frame_control); - - /* If this frame is broadcast or management, use broadcast station id */ - if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || - is_multicast_ether_addr(hdr->addr1)) - return priv->hw_params.bcast_sta_id; - - switch (priv->iw_mode) { - - /* If we are a client station in a BSS network, use the special - * AP station entry (that's the only station we communicate with) */ - case NL80211_IFTYPE_STATION: - return IWL_AP_ID; - - /* If we are an AP, then find the station, or use BCAST */ - case NL80211_IFTYPE_AP: - sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); - if (sta_id != IWL_INVALID_STATION) - return sta_id; - return priv->hw_params.bcast_sta_id; - - /* If this frame is going out to an IBSS network, find the station, - * or create a new station table entry */ - case NL80211_IFTYPE_ADHOC: { - /* Create new station table entry */ - sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); - if (sta_id != IWL_INVALID_STATION) - return sta_id; - - sta_id = priv->cfg->ops->smgmt->add_station(priv, - hdr->addr1, 0, CMD_ASYNC, NULL); - - if (sta_id != IWL_INVALID_STATION) - return sta_id; - - IWL_DEBUG_DROP(priv, "Station %pM not in station map. " - "Defaulting to broadcast...\n", - hdr->addr1); - iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); - return priv->hw_params.bcast_sta_id; - } - /* If we are in monitor mode, use BCAST. This is required for - * packet injection. */ - case NL80211_IFTYPE_MONITOR: - return priv->hw_params.bcast_sta_id; - - default: - IWL_WARN(priv, "Unknown mode of operation: %d\n", - priv->iw_mode); - return priv->hw_params.bcast_sta_id; - } -} - /* * start REPLY_TX command process */ @@ -836,7 +777,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); /* Find (or create) index into station table for destination station */ - sta_id = iwl3945_get_sta_id(priv, hdr); + sta_id = iwl_get_sta_id(priv, hdr); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); -- GitLab From 45823531662028a8cbd68906c20e887bb287c85e Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:44 -0700 Subject: [PATCH 0582/6080] iwlwifi: add set_rxon_chain op add set_rxon_chain op to iwlwifi cfg ops in preparation of future 3945 porting work. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 23 +++++++++++++++++------ drivers/net/wireless/iwlwifi/iwl-core.c | 11 ++++++++--- drivers/net/wireless/iwlwifi/iwl-core.h | 1 + 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index e98849edafd5..ab25e6ab59d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2278,6 +2278,7 @@ static struct iwl_station_mgmt_ops iwl4965_station_mgmt = { static struct iwl_hcmd_ops iwl4965_hcmd = { .rxon_assoc = iwl4965_send_rxon_assoc, .commit_rxon = iwl_commit_rxon, + .set_rxon_chain = iwl_set_rxon_chain, }; static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 52ee77347328..cf622a14bfe2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1482,6 +1482,7 @@ struct iwl_station_mgmt_ops iwl5000_station_mgmt = { struct iwl_hcmd_ops iwl5000_hcmd = { .rxon_assoc = iwl5000_send_rxon_assoc, .commit_rxon = iwl_commit_rxon, + .set_rxon_chain = iwl_set_rxon_chain, }; struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 565a441052eb..11e17923ad01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -246,7 +246,8 @@ int iwl_commit_rxon(struct iwl_priv *priv) void iwl_update_chain_flags(struct iwl_priv *priv) { - iwl_set_rxon_chain(priv); + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); iwlcore_commit_rxon(priv); } @@ -590,7 +591,10 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv) static int iwl_set_mode(struct iwl_priv *priv, int mode) { iwl_connection_init_rx_config(priv, mode); - iwl_set_rxon_chain(priv); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); + memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); priv->cfg->ops->smgmt->clear_station_table(priv); @@ -1499,7 +1503,10 @@ static void iwl_alive_start(struct iwl_priv *priv) } else { /* Initialize our rx_config data */ iwl_connection_init_rx_config(priv, priv->iw_mode); - iwl_set_rxon_chain(priv); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); + memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); } @@ -1878,7 +1885,9 @@ void iwl_post_associate(struct iwl_priv *priv) iwl_set_rxon_ht(priv, &priv->current_ht_config); - iwl_set_rxon_chain(priv); + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", @@ -2182,7 +2191,8 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) } /* call to ensure that 4965 rx_chain is set properly in monitor mode */ - iwl_set_rxon_chain(priv); + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { if (conf->radio_enabled && @@ -2245,7 +2255,8 @@ static void iwl_config_ap(struct iwl_priv *priv) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); - iwl_set_rxon_chain(priv); + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); /* FIXME: what should be the assoc_id for AP? */ priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 0532d99b9085..cca37af3243f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -821,7 +821,8 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); - iwl_set_rxon_chain(priv); + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X " "rxon flags 0x%X operation mode :0x%X " @@ -1380,7 +1381,9 @@ int iwl_init_drv(struct iwl_priv *priv) priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED; /* Choose which receivers/antennas to use */ - iwl_set_rxon_chain(priv); + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); + iwl_init_scan_params(priv); iwl_reset_qos(priv); @@ -2257,7 +2260,9 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, if (changes & BSS_CHANGED_HT) { iwl_ht_conf(priv, bss_conf); - iwl_set_rxon_chain(priv); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); } if (changes & BSS_CHANGED_ASSOC) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 383590cd8b02..f5eff747e964 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -95,6 +95,7 @@ struct iwl_station_mgmt_ops { struct iwl_hcmd_ops { int (*rxon_assoc)(struct iwl_priv *priv); int (*commit_rxon)(struct iwl_priv *priv); + void (*set_rxon_chain)(struct iwl_priv *priv); }; struct iwl_hcmd_utils_ops { -- GitLab From 727882d62477ed45d248e8cd6d53cf794537b073 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:45 -0700 Subject: [PATCH 0583/6080] iwl3945: use iwl_set_mode in 3945 3945 can now use iwl_set_mode from iwlcore library. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 27 ------------- drivers/net/wireless/iwlwifi/iwl-core.c | 42 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 40 +------------------- 4 files changed, 45 insertions(+), 65 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 11e17923ad01..479fcf142707 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -588,33 +588,6 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv) le16_to_cpu(priv->rxon_timing.atim_window)); } -static int iwl_set_mode(struct iwl_priv *priv, int mode) -{ - iwl_connection_init_rx_config(priv, mode); - - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); - - memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); - - priv->cfg->ops->smgmt->clear_station_table(priv); - - /* dont commit rxon if rf-kill is on*/ - if (!iwl_is_ready_rf(priv)) - return -EAGAIN; - - cancel_delayed_work(&priv->scan_check); - if (iwl_scan_cancel_timeout(priv, 100)) { - IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); - IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); - return -EAGAIN; - } - - iwlcore_commit_rxon(priv); - - return 0; -} - /****************************************************************************** * * Generic RX handler implementations diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index cca37af3243f..01e7604bf33f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2339,6 +2339,48 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) } EXPORT_SYMBOL(iwl_mac_beacon_update); +int iwl_set_mode(struct iwl_priv *priv, int mode) +{ + if (mode == NL80211_IFTYPE_ADHOC) { + const struct iwl_channel_info *ch_info; + + ch_info = iwl_get_channel_info(priv, + priv->band, + le16_to_cpu(priv->staging_rxon.channel)); + + if (!ch_info || !is_channel_ibss(ch_info)) { + IWL_ERR(priv, "channel %d not IBSS channel\n", + le16_to_cpu(priv->staging_rxon.channel)); + return -EINVAL; + } + } + + iwl_connection_init_rx_config(priv, mode); + + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); + + memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); + + priv->cfg->ops->smgmt->clear_station_table(priv); + + /* dont commit rxon if rf-kill is on*/ + if (!iwl_is_ready_rf(priv)) + return -EAGAIN; + + cancel_delayed_work(&priv->scan_check); + if (iwl_scan_cancel_timeout(priv, 100)) { + IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); + IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); + return -EAGAIN; + } + + iwlcore_commit_rxon(priv); + + return 0; +} +EXPORT_SYMBOL(iwl_set_mode); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index f5eff747e964..49df47a53b5d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -273,6 +273,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, u32 changes); int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); int iwl_commit_rxon(struct iwl_priv *priv); +int iwl_set_mode(struct iwl_priv *priv, int mode); /***************************************************** * RX handlers. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 7f35017d9df2..666c1fff62b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -570,42 +570,6 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv) le16_to_cpu(priv->rxon_timing.atim_window)); } -static int iwl3945_set_mode(struct iwl_priv *priv, int mode) -{ - if (mode == NL80211_IFTYPE_ADHOC) { - const struct iwl_channel_info *ch_info; - - ch_info = iwl_get_channel_info(priv, - priv->band, - le16_to_cpu(priv->staging_rxon.channel)); - - if (!ch_info || !is_channel_ibss(ch_info)) { - IWL_ERR(priv, "channel %d not IBSS channel\n", - le16_to_cpu(priv->staging_rxon.channel)); - return -EINVAL; - } - } - - iwl_connection_init_rx_config(priv, mode); - - priv->cfg->ops->smgmt->clear_station_table(priv); - - /* don't commit rxon if rf-kill is on*/ - if (!iwl_is_ready_rf(priv)) - return -EAGAIN; - - cancel_delayed_work(&priv->scan_check); - if (iwl_scan_cancel_timeout(priv, 100)) { - IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); - IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); - return -EAGAIN; - } - - iwlcore_commit_rxon(priv); - - return 0; -} - static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, struct ieee80211_tx_info *info, struct iwl_cmd *cmd, @@ -2701,7 +2665,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) } if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) - iwl3945_set_mode(priv, priv->iw_mode); + iwl_set_mode(priv, priv->iw_mode); return; @@ -3442,7 +3406,7 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); } - if (iwl3945_set_mode(priv, conf->type) == -EAGAIN) + if (iwl_set_mode(priv, conf->type) == -EAGAIN) set_bit(STATUS_MODE_PENDING, &priv->status); mutex_unlock(&priv->mutex); -- GitLab From cbb6ab94b66cfb7136e640191a9628c5a71220a3 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:46 -0700 Subject: [PATCH 0584/6080] iwl3945: use iwl_mac_add_interface from iwlwifi Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 36 -------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 37 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 37 +-------------------- 4 files changed, 40 insertions(+), 72 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 479fcf142707..7e7b584ec257 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2036,42 +2036,6 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } -static int iwl_mac_add_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - - IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type); - - if (priv->vif) { - IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); - return -EOPNOTSUPP; - } - - spin_lock_irqsave(&priv->lock, flags); - priv->vif = conf->vif; - priv->iw_mode = conf->type; - - spin_unlock_irqrestore(&priv->lock, flags); - - mutex_lock(&priv->mutex); - - if (conf->mac_addr) { - IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr); - memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); - } - - if (iwl_set_mode(priv, conf->type) == -EAGAIN) - /* we are not ready, will run again when ready */ - set_bit(STATUS_MODE_PENDING, &priv->status); - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - return 0; -} - /** * iwl_mac_config - mac80211 config callback * diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 01e7604bf33f..e08aee9b2b8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2381,6 +2381,43 @@ int iwl_set_mode(struct iwl_priv *priv, int mode) } EXPORT_SYMBOL(iwl_set_mode); +int iwl_mac_add_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + + IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type); + + if (priv->vif) { + IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); + return -EOPNOTSUPP; + } + + spin_lock_irqsave(&priv->lock, flags); + priv->vif = conf->vif; + priv->iw_mode = conf->type; + + spin_unlock_irqrestore(&priv->lock, flags); + + mutex_lock(&priv->mutex); + + if (conf->mac_addr) { + IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr); + memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); + } + + if (iwl_set_mode(priv, conf->type) == -EAGAIN) + /* we are not ready, will run again when ready */ + set_bit(STATUS_MODE_PENDING, &priv->status); + + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + return 0; +} +EXPORT_SYMBOL(iwl_mac_add_interface); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 49df47a53b5d..7df54405bef7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -274,6 +274,8 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); int iwl_commit_rxon(struct iwl_priv *priv); int iwl_set_mode(struct iwl_priv *priv, int mode); +int iwl_mac_add_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf); /***************************************************** * RX handlers. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 666c1fff62b2..955e50a124b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3380,41 +3380,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } -static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - - IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type); - - if (priv->vif) { - IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); - return -EOPNOTSUPP; - } - - spin_lock_irqsave(&priv->lock, flags); - priv->vif = conf->vif; - priv->iw_mode = conf->type; - - spin_unlock_irqrestore(&priv->lock, flags); - - mutex_lock(&priv->mutex); - - if (conf->mac_addr) { - IWL_DEBUG_MAC80211(priv, "Set: %pM\n", conf->mac_addr); - memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); - } - - if (iwl_set_mode(priv, conf->type) == -EAGAIN) - set_bit(STATUS_MODE_PENDING, &priv->status); - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - return 0; -} - /** * iwl3945_mac_config - mac80211 config callback * @@ -4372,7 +4337,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .tx = iwl3945_mac_tx, .start = iwl3945_mac_start, .stop = iwl3945_mac_stop, - .add_interface = iwl3945_mac_add_interface, + .add_interface = iwl_mac_add_interface, .remove_interface = iwl3945_mac_remove_interface, .config = iwl3945_mac_config, .config_interface = iwl3945_mac_config_interface, -- GitLab From d8052319f2a7d1ee86248df00193110ad1946a33 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:47 -0700 Subject: [PATCH 0585/6080] iwl3945: use iwl_mac_remove_interface from iwlwifi 3945 can now use iwl_mac_remove_interface from iwlwifi Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 24 -------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 25 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 25 +-------------------- 4 files changed, 28 insertions(+), 48 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7e7b584ec257..5cc30a223cf0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2332,30 +2332,6 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, return 0; } -static void iwl_mac_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) -{ - struct iwl_priv *priv = hw->priv; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - mutex_lock(&priv->mutex); - - if (iwl_is_ready_rf(priv)) { - iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); - } - if (priv->vif == conf->vif) { - priv->vif = NULL; - memset(priv->bssid, 0, ETH_ALEN); - } - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - -} - static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, struct ieee80211_key_conf *keyconf, const u8 *addr, u32 iv32, u16 *phase1key) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index e08aee9b2b8c..b8afd9b81fb8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2418,6 +2418,31 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_mac_add_interface); +void iwl_mac_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) +{ + struct iwl_priv *priv = hw->priv; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + mutex_lock(&priv->mutex); + + if (iwl_is_ready_rf(priv)) { + iwl_scan_cancel_timeout(priv, 100); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv); + } + if (priv->vif == conf->vif) { + priv->vif = NULL; + memset(priv->bssid, 0, ETH_ALEN); + } + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + +} +EXPORT_SYMBOL(iwl_mac_remove_interface); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7df54405bef7..5dc33065f0ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -276,6 +276,8 @@ int iwl_commit_rxon(struct iwl_priv *priv); int iwl_set_mode(struct iwl_priv *priv, int mode); int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf); +void iwl_mac_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf); /***************************************************** * RX handlers. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 955e50a124b5..f82a9dc82eef 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3640,29 +3640,6 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, return 0; } -static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) -{ - struct iwl_priv *priv = hw->priv; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - mutex_lock(&priv->mutex); - - if (iwl_is_ready_rf(priv)) { - iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); - } - if (priv->vif == conf->vif) { - priv->vif = NULL; - memset(priv->bssid, 0, ETH_ALEN); - } - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} - static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -4338,7 +4315,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .start = iwl3945_mac_start, .stop = iwl3945_mac_stop, .add_interface = iwl_mac_add_interface, - .remove_interface = iwl3945_mac_remove_interface, + .remove_interface = iwl_mac_remove_interface, .config = iwl3945_mac_config, .config_interface = iwl3945_mac_config_interface, .configure_filter = iwl_configure_filter, -- GitLab From 4808368dad3263ac46e71f037c0dcd2dcf082525 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:48 -0700 Subject: [PATCH 0586/6080] iwl3945: use iwl_mac_config from iwlwifi 3945 can now use iwl_mac_config from iwlwifi Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 133 ------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 136 ++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 106 +-------------- 4 files changed, 138 insertions(+), 238 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5cc30a223cf0..4640996aa298 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2036,139 +2036,6 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } -/** - * iwl_mac_config - mac80211 config callback - * - * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to - * be set inappropriately and the driver currently sets the hardware up to - * use it whenever needed. - */ -static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) -{ - struct iwl_priv *priv = hw->priv; - const struct iwl_channel_info *ch_info; - struct ieee80211_conf *conf = &hw->conf; - unsigned long flags = 0; - int ret = 0; - u16 ch; - int scan_active = 0; - - mutex_lock(&priv->mutex); - IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", - conf->channel->hw_value, changed); - - if (unlikely(!priv->cfg->mod_params->disable_hw_scan && - test_bit(STATUS_SCANNING, &priv->status))) { - scan_active = 1; - IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); - } - - - /* during scanning mac80211 will delay channel setting until - * scan finish with changed = 0 - */ - if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { - if (scan_active) - goto set_ch_out; - - ch = ieee80211_frequency_to_channel(conf->channel->center_freq); - ch_info = iwl_get_channel_info(priv, conf->channel->band, ch); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); - ret = -EINVAL; - goto set_ch_out; - } - - if (priv->iw_mode == NL80211_IFTYPE_ADHOC && - !is_channel_ibss(ch_info)) { - IWL_ERR(priv, "channel %d in band %d not " - "IBSS channel\n", - conf->channel->hw_value, conf->channel->band); - ret = -EINVAL; - goto set_ch_out; - } - - priv->current_ht_config.is_ht = conf_is_ht(conf); - - spin_lock_irqsave(&priv->lock, flags); - - - /* if we are switching from ht to 2.4 clear flags - * from any ht related info since 2.4 does not - * support ht */ - if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) - priv->staging_rxon.flags = 0; - - iwl_set_rxon_channel(priv, conf->channel); - - iwl_set_flags_for_band(priv, conf->channel->band); - spin_unlock_irqrestore(&priv->lock, flags); - set_ch_out: - /* The list of supported rates and rate mask can be different - * for each band; since the band may have changed, reset - * the rate mask to what mac80211 lists */ - iwl_set_rate(priv); - } - - if (changed & IEEE80211_CONF_CHANGE_PS) { - if (conf->flags & IEEE80211_CONF_PS) - ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); - else - ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); - if (ret) - IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); - - } - - if (changed & IEEE80211_CONF_CHANGE_POWER) { - IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", - priv->tx_power_user_lmt, conf->power_level); - - iwl_set_tx_power(priv, conf->power_level, false); - } - - /* call to ensure that 4965 rx_chain is set properly in monitor mode */ - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); - - if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { - if (conf->radio_enabled && - iwl_radio_kill_sw_enable_radio(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " - "waiting for uCode\n"); - goto out; - } - - if (!conf->radio_enabled) - iwl_radio_kill_sw_disable_radio(priv); - } - - if (!conf->radio_enabled) { - IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); - goto out; - } - - if (!iwl_is_ready(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - goto out; - } - - if (scan_active) - goto out; - - if (memcmp(&priv->active_rxon, - &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwlcore_commit_rxon(priv); - else - IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n"); - - -out: - IWL_DEBUG_MAC80211(priv, "leave\n"); - mutex_unlock(&priv->mutex); - return ret; -} - static void iwl_config_ap(struct iwl_priv *priv) { int ret = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index b8afd9b81fb8..4369fc8978f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2443,6 +2443,142 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_mac_remove_interface); +/** + * iwl_mac_config - mac80211 config callback + * + * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to + * be set inappropriately and the driver currently sets the hardware up to + * use it whenever needed. + */ +int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) +{ + struct iwl_priv *priv = hw->priv; + const struct iwl_channel_info *ch_info; + struct ieee80211_conf *conf = &hw->conf; + unsigned long flags = 0; + int ret = 0; + u16 ch; + int scan_active = 0; + + mutex_lock(&priv->mutex); + + if (!iwl_is_ready(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + ret = -EIO; + goto out; + } + + IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", + conf->channel->hw_value, changed); + + if (unlikely(!priv->cfg->mod_params->disable_hw_scan && + test_bit(STATUS_SCANNING, &priv->status))) { + scan_active = 1; + IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); + } + + + /* during scanning mac80211 will delay channel setting until + * scan finish with changed = 0 + */ + if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) { + if (scan_active) + goto set_ch_out; + + ch = ieee80211_frequency_to_channel(conf->channel->center_freq); + ch_info = iwl_get_channel_info(priv, conf->channel->band, ch); + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); + ret = -EINVAL; + goto set_ch_out; + } + + if (priv->iw_mode == NL80211_IFTYPE_ADHOC && + !is_channel_ibss(ch_info)) { + IWL_ERR(priv, "channel %d in band %d not " + "IBSS channel\n", + conf->channel->hw_value, conf->channel->band); + ret = -EINVAL; + goto set_ch_out; + } + + priv->current_ht_config.is_ht = conf_is_ht(conf); + + spin_lock_irqsave(&priv->lock, flags); + + + /* if we are switching from ht to 2.4 clear flags + * from any ht related info since 2.4 does not + * support ht */ + if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) + priv->staging_rxon.flags = 0; + + iwl_set_rxon_channel(priv, conf->channel); + + iwl_set_flags_for_band(priv, conf->channel->band); + spin_unlock_irqrestore(&priv->lock, flags); + set_ch_out: + /* The list of supported rates and rate mask can be different + * for each band; since the band may have changed, reset + * the rate mask to what mac80211 lists */ + iwl_set_rate(priv); + } + + if (changed & IEEE80211_CONF_CHANGE_PS) { + if (conf->flags & IEEE80211_CONF_PS) + ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); + else + ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); + if (ret) + IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); + + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n", + priv->tx_power_user_lmt, conf->power_level); + + iwl_set_tx_power(priv, conf->power_level, false); + } + + /* call to ensure that 4965 rx_chain is set properly in monitor mode */ + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv); + + if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { + if (conf->radio_enabled && + iwl_radio_kill_sw_enable_radio(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " + "waiting for uCode\n"); + goto out; + } + + if (!conf->radio_enabled) + iwl_radio_kill_sw_disable_radio(priv); + } + + if (!conf->radio_enabled) { + IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); + goto out; + } + + if (scan_active) + goto out; + + if (memcmp(&priv->active_rxon, + &priv->staging_rxon, sizeof(priv->staging_rxon))) + iwlcore_commit_rxon(priv); + else + IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n"); + + +out: + IWL_DEBUG_MAC80211(priv, "leave\n"); + mutex_unlock(&priv->mutex); + return ret; +} +EXPORT_SYMBOL(iwl_mac_config); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 5dc33065f0ba..da8fae52a5d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -278,6 +278,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf); void iwl_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf); +int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); /***************************************************** * RX handlers. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index f82a9dc82eef..c5644a5e50c9 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3166,8 +3166,6 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) mutex_unlock(&priv->mutex); } -static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed); - #define IWL_DELAY_NEXT_SCAN (HZ*2) void iwl3945_post_associate(struct iwl_priv *priv) @@ -3380,108 +3378,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } -/** - * iwl3945_mac_config - mac80211 config callback - * - * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to - * be set inappropriately and the driver currently sets the hardware up to - * use it whenever needed. - */ -static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed) -{ - struct iwl_priv *priv = hw->priv; - const struct iwl_channel_info *ch_info; - struct ieee80211_conf *conf = &hw->conf; - unsigned long flags; - int ret = 0; - - mutex_lock(&priv->mutex); - IWL_DEBUG_MAC80211(priv, "enter to channel %d\n", - conf->channel->hw_value); - - if (!iwl_is_ready(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - ret = -EIO; - goto out; - } - - if (unlikely(!iwl3945_mod_params.disable_hw_scan && - test_bit(STATUS_SCANNING, &priv->status))) { - IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); - set_bit(STATUS_CONF_PENDING, &priv->status); - mutex_unlock(&priv->mutex); - return 0; - } - - spin_lock_irqsave(&priv->lock, flags); - - ch_info = iwl_get_channel_info(priv, conf->channel->band, - conf->channel->hw_value); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_SCAN(priv, - "Channel %d [%d] is INVALID for this band.\n", - conf->channel->hw_value, conf->channel->band); - IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); - spin_unlock_irqrestore(&priv->lock, flags); - ret = -EINVAL; - goto out; - } - - iwl_set_rxon_channel(priv, conf->channel); - - iwl_set_flags_for_band(priv, conf->channel->band); - - /* The list of supported rates and rate mask can be different - * for each phymode; since the phymode may have changed, reset - * the rate mask to what mac80211 lists */ - iwl_set_rate(priv); - - spin_unlock_irqrestore(&priv->lock, flags); - -#ifdef IEEE80211_CONF_CHANNEL_SWITCH - if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) { - iwl3945_hw_channel_switch(priv, conf->channel); - goto out; - } -#endif - - if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { - if (conf->radio_enabled && - iwl_radio_kill_sw_enable_radio(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " - "waiting for uCode\n"); - goto out; - } - - if (!conf->radio_enabled) { - iwl_radio_kill_sw_disable_radio(priv); - IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); - goto out; - } - } - - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF kill\n"); - ret = -EIO; - goto out; - } - - iwl_set_rate(priv); - - if (memcmp(&priv->active_rxon, - &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwlcore_commit_rxon(priv); - else - IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n"); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - -out: - clear_bit(STATUS_CONF_PENDING, &priv->status); - mutex_unlock(&priv->mutex); - return ret; -} - static void iwl3945_config_ap(struct iwl_priv *priv) { int rc = 0; @@ -4316,7 +4212,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .stop = iwl3945_mac_stop, .add_interface = iwl_mac_add_interface, .remove_interface = iwl_mac_remove_interface, - .config = iwl3945_mac_config, + .config = iwl_mac_config, .config_interface = iwl3945_mac_config_interface, .configure_filter = iwl_configure_filter, .set_key = iwl3945_mac_set_key, -- GitLab From 60690a6a38cc03142a0c5aaed64cf043e707457d Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:49 -0700 Subject: [PATCH 0587/6080] iwlwifi: add config_ap lib op add config_ap lib op to iwlwifi and iwl3945 in preparation of future 3945 porting actions. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.c | 1 + drivers/net/wireless/iwlwifi/iwl-3945.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.h | 7 ++++++- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++-- 7 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index a854feba82c8..edc0cb38033d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2952,6 +2952,7 @@ static struct iwl_lib_ops iwl3945_lib = { .send_tx_power = iwl3945_send_tx_power, .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr, .post_associate = iwl3945_post_associate, + .config_ap = iwl3945_config_ap, }; static struct iwl_station_mgmt_ops iwl3945_station_mgmt = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 88628b23efd9..4f5473e01617 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -278,6 +278,8 @@ extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, extern void iwl3945_disable_events(struct iwl_priv *priv); extern int iwl4965_get_temperature(const struct iwl_priv *priv); extern void iwl3945_post_associate(struct iwl_priv *priv); +extern void iwl3945_config_ap(struct iwl_priv *priv); + /** * iwl3945_hw_find_station - Find station id for a given BSSID * @bssid: MAC address of station ID to find diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index ab25e6ab59d5..e4762e530345 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2333,6 +2333,7 @@ static struct iwl_lib_ops iwl4965_lib = { .update_chain_flags = iwl_update_chain_flags, .temperature = iwl4965_temperature_calib, .post_associate = iwl_post_associate, + .config_ap = iwl_config_ap, }; static struct iwl_ops iwl4965_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index cf622a14bfe2..5bbb4f953364 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1537,6 +1537,7 @@ struct iwl_lib_ops iwl5000_lib = { .query_addr = iwl5000_eeprom_query_addr, }, .post_associate = iwl_post_associate, + .config_ap = iwl_config_ap, }; struct iwl_ops iwl5000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4640996aa298..97f8322e0661 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2036,7 +2036,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } -static void iwl_config_ap(struct iwl_priv *priv) +void iwl_config_ap(struct iwl_priv *priv) { int ret = 0; unsigned long flags; @@ -2178,7 +2178,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, memcpy(priv->bssid, conf->bssid, ETH_ALEN); if (priv->iw_mode == NL80211_IFTYPE_AP) - iwl_config_ap(priv); + iwlcore_config_ap(priv); else { rc = iwlcore_commit_rxon(priv); if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index da8fae52a5d6..af559b07cc8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -162,6 +162,7 @@ struct iwl_lib_ops { void (*update_chain_flags)(struct iwl_priv *priv); void (*temperature) (struct iwl_priv *priv); void (*post_associate) (struct iwl_priv *priv); + void (*config_ap) (struct iwl_priv *priv); /* eeprom operations (as defined in iwl-eeprom.h) */ struct iwl_eeprom_ops eeprom_ops; @@ -279,6 +280,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, void iwl_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf); int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); +void iwl_config_ap(struct iwl_priv *priv); /***************************************************** * RX handlers. @@ -565,7 +567,10 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv) { return priv->cfg->ops->hcmd->commit_rxon(priv); } - +static inline void iwlcore_config_ap(struct iwl_priv *priv) +{ + priv->cfg->ops->lib->config_ap(priv); +} static inline const struct ieee80211_supported_band *iwl_get_hw_mode( struct iwl_priv *priv, enum ieee80211_band band) { diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index c5644a5e50c9..ad6f5ebeaf7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3378,7 +3378,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } -static void iwl3945_config_ap(struct iwl_priv *priv) +void iwl3945_config_ap(struct iwl_priv *priv) { int rc = 0; @@ -3515,7 +3515,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, memcpy(priv->bssid, conf->bssid, ETH_ALEN); if (priv->iw_mode == NL80211_IFTYPE_AP) - iwl3945_config_ap(priv); + iwlcore_config_ap(priv); else { rc = iwlcore_commit_rxon(priv); if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) -- GitLab From 5ee5811e24b20d49ea553fda568433effbab7a62 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:50 -0700 Subject: [PATCH 0588/6080] iwl3945: use iwl_mac_config_interface from iwlwifi 3945 can now use iwl_mac_config_interface from iwlwifi. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 100 ------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 100 +++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 3 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 102 +------------------- 4 files changed, 104 insertions(+), 201 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 97f8322e0661..edfece6e0d4c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2099,106 +2099,6 @@ void iwl_config_ap(struct iwl_priv *priv) * clear sta table, add BCAST sta... */ } - -static int iwl_mac_config_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_if_conf *conf) -{ - struct iwl_priv *priv = hw->priv; - int rc; - - if (conf == NULL) - return -EIO; - - if (priv->vif != vif) { - IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n"); - return 0; - } - - if (priv->iw_mode == NL80211_IFTYPE_ADHOC && - conf->changed & IEEE80211_IFCC_BEACON) { - struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); - if (!beacon) - return -ENOMEM; - mutex_lock(&priv->mutex); - rc = iwl_mac_beacon_update(hw, beacon); - mutex_unlock(&priv->mutex); - if (rc) - return rc; - } - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - mutex_lock(&priv->mutex); - - if (conf->bssid) - IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid); - -/* - * very dubious code was here; the probe filtering flag is never set: - * - if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && - !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { - */ - - if (priv->iw_mode == NL80211_IFTYPE_AP) { - if (!conf->bssid) { - conf->bssid = priv->mac_addr; - memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); - IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n", - conf->bssid); - } - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - - priv->ibss_beacon = ieee80211_beacon_get(hw, vif); - } - - if (iwl_is_rfkill(priv)) - goto done; - - if (conf->bssid && !is_zero_ether_addr(conf->bssid) && - !is_multicast_ether_addr(conf->bssid)) { - /* If there is currently a HW scan going on in the background - * then we need to cancel it else the RXON below will fail. */ - if (iwl_scan_cancel_timeout(priv, 100)) { - IWL_WARN(priv, "Aborted scan still in progress " - "after 100ms\n"); - IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); - mutex_unlock(&priv->mutex); - return -EAGAIN; - } - memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN); - - /* TODO: Audit driver for usage of these members and see - * if mac80211 deprecates them (priv->bssid looks like it - * shouldn't be there, but I haven't scanned the IBSS code - * to verify) - jpk */ - memcpy(priv->bssid, conf->bssid, ETH_ALEN); - - if (priv->iw_mode == NL80211_IFTYPE_AP) - iwlcore_config_ap(priv); - else { - rc = iwlcore_commit_rxon(priv); - if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) - iwl_rxon_add_station( - priv, priv->active_rxon.bssid_addr, 1); - } - - } else { - iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); - } - - done: - IWL_DEBUG_MAC80211(priv, "leave\n"); - mutex_unlock(&priv->mutex); - - return 0; -} - static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, struct ieee80211_key_conf *keyconf, const u8 *addr, u32 iv32, u16 *phase1key) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4369fc8978f9..e8b74fc82515 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2579,6 +2579,106 @@ out: } EXPORT_SYMBOL(iwl_mac_config); +int iwl_mac_config_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_if_conf *conf) +{ + struct iwl_priv *priv = hw->priv; + int rc; + + if (conf == NULL) + return -EIO; + + if (priv->vif != vif) { + IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n"); + return 0; + } + + if (priv->iw_mode == NL80211_IFTYPE_ADHOC && + conf->changed & IEEE80211_IFCC_BEACON) { + struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); + if (!beacon) + return -ENOMEM; + mutex_lock(&priv->mutex); + rc = iwl_mac_beacon_update(hw, beacon); + mutex_unlock(&priv->mutex); + if (rc) + return rc; + } + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + mutex_lock(&priv->mutex); + + if (conf->bssid) + IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid); + +/* + * very dubious code was here; the probe filtering flag is never set: + * + if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && + !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { + */ + + if (priv->iw_mode == NL80211_IFTYPE_AP) { + if (!conf->bssid) { + conf->bssid = priv->mac_addr; + memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); + IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n", + conf->bssid); + } + if (priv->ibss_beacon) + dev_kfree_skb(priv->ibss_beacon); + + priv->ibss_beacon = ieee80211_beacon_get(hw, vif); + } + + if (iwl_is_rfkill(priv)) + goto done; + + if (conf->bssid && !is_zero_ether_addr(conf->bssid) && + !is_multicast_ether_addr(conf->bssid)) { + /* If there is currently a HW scan going on in the background + * then we need to cancel it else the RXON below will fail. */ + if (iwl_scan_cancel_timeout(priv, 100)) { + IWL_WARN(priv, "Aborted scan still in progress " + "after 100ms\n"); + IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); + mutex_unlock(&priv->mutex); + return -EAGAIN; + } + memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN); + + /* TODO: Audit driver for usage of these members and see + * if mac80211 deprecates them (priv->bssid looks like it + * shouldn't be there, but I haven't scanned the IBSS code + * to verify) - jpk */ + memcpy(priv->bssid, conf->bssid, ETH_ALEN); + + if (priv->iw_mode == NL80211_IFTYPE_AP) + iwlcore_config_ap(priv); + else { + rc = iwlcore_commit_rxon(priv); + if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) + iwl_rxon_add_station( + priv, priv->active_rxon.bssid_addr, 1); + } + + } else { + iwl_scan_cancel_timeout(priv, 100); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv); + } + + done: + IWL_DEBUG_MAC80211(priv, "leave\n"); + mutex_unlock(&priv->mutex); + + return 0; +} +EXPORT_SYMBOL(iwl_mac_config_interface); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index af559b07cc8e..92a42c880488 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -281,6 +281,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf); int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); void iwl_config_ap(struct iwl_priv *priv); +int iwl_mac_config_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_if_conf *conf); /***************************************************** * RX handlers. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index ad6f5ebeaf7a..3461768e5a2b 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3436,106 +3436,6 @@ void iwl3945_config_ap(struct iwl_priv *priv) * clear sta table, add BCAST sta... */ } -static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_if_conf *conf) -{ - struct iwl_priv *priv = hw->priv; - int rc; - - if (conf == NULL) - return -EIO; - - if (priv->vif != vif) { - IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n"); - return 0; - } - - /* handle this temporarily here */ - if (priv->iw_mode == NL80211_IFTYPE_ADHOC && - conf->changed & IEEE80211_IFCC_BEACON) { - struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); - if (!beacon) - return -ENOMEM; - mutex_lock(&priv->mutex); - rc = iwl_mac_beacon_update(hw, beacon); - mutex_unlock(&priv->mutex); - if (rc) - return rc; - } - - if (!iwl_is_alive(priv)) - return -EAGAIN; - - mutex_lock(&priv->mutex); - - if (conf->bssid) - IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid); - -/* - * very dubious code was here; the probe filtering flag is never set: - * - if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && - !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { - */ - - if (priv->iw_mode == NL80211_IFTYPE_AP) { - if (!conf->bssid) { - conf->bssid = priv->mac_addr; - memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); - IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n", - conf->bssid); - } - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - - priv->ibss_beacon = ieee80211_beacon_get(hw, vif); - } - - if (iwl_is_rfkill(priv)) - goto done; - - if (conf->bssid && !is_zero_ether_addr(conf->bssid) && - !is_multicast_ether_addr(conf->bssid)) { - /* If there is currently a HW scan going on in the background - * then we need to cancel it else the RXON below will fail. */ - if (iwl_scan_cancel_timeout(priv, 100)) { - IWL_WARN(priv, "Aborted scan still in progress " - "after 100ms\n"); - IWL_DEBUG_MAC80211(priv, "leaving:scan abort failed\n"); - mutex_unlock(&priv->mutex); - return -EAGAIN; - } - memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN); - - /* TODO: Audit driver for usage of these members and see - * if mac80211 deprecates them (priv->bssid looks like it - * shouldn't be there, but I haven't scanned the IBSS code - * to verify) - jpk */ - memcpy(priv->bssid, conf->bssid, ETH_ALEN); - - if (priv->iw_mode == NL80211_IFTYPE_AP) - iwlcore_config_ap(priv); - else { - rc = iwlcore_commit_rxon(priv); - if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) - priv->cfg->ops->smgmt->add_station(priv, - priv->active_rxon.bssid_addr, 1, 0, NULL); - } - - } else { - iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); - } - - done: - IWL_DEBUG_MAC80211(priv, "leave\n"); - mutex_unlock(&priv->mutex); - - return 0; -} - static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, struct ieee80211_sta *sta, @@ -4213,7 +4113,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .add_interface = iwl_mac_add_interface, .remove_interface = iwl_mac_remove_interface, .config = iwl_mac_config, - .config_interface = iwl3945_mac_config_interface, + .config_interface = iwl_mac_config_interface, .configure_filter = iwl_configure_filter, .set_key = iwl3945_mac_set_key, .get_tx_stats = iwl3945_mac_get_tx_stats, -- GitLab From aa89f31e708d469f5dd824c59c98e4856a2e3572 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:51 -0700 Subject: [PATCH 0589/6080] iwl3945: use iwl_mac_get_tx_stats from iwlwifi 3945 can now use iwl_mac_get_tx_stats from iwlwifi. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 35 ------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 36 ++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 37 +-------------------- 4 files changed, 39 insertions(+), 71 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index edfece6e0d4c..3ebf80fbebab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2223,41 +2223,6 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, return 0; } -static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, - struct ieee80211_tx_queue_stats *stats) -{ - struct iwl_priv *priv = hw->priv; - int i, avail; - struct iwl_tx_queue *txq; - struct iwl_queue *q; - unsigned long flags; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; - } - - spin_lock_irqsave(&priv->lock, flags); - - for (i = 0; i < AC_NUM; i++) { - txq = &priv->txq[i]; - q = &txq->q; - avail = iwl_queue_space(q); - - stats[i].len = q->n_window - avail; - stats[i].limit = q->n_window - q->high_mark; - stats[i].count = q->n_window; - - } - spin_unlock_irqrestore(&priv->lock, flags); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - - return 0; -} - static int iwl_mac_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index e8b74fc82515..144630b25491 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2679,6 +2679,42 @@ int iwl_mac_config_interface(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_mac_config_interface); +int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, + struct ieee80211_tx_queue_stats *stats) +{ + struct iwl_priv *priv = hw->priv; + int i, avail; + struct iwl_tx_queue *txq; + struct iwl_queue *q; + unsigned long flags; + + IWL_DEBUG_MAC80211(priv, "enter\n"); + + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return -EIO; + } + + spin_lock_irqsave(&priv->lock, flags); + + for (i = 0; i < AC_NUM; i++) { + txq = &priv->txq[i]; + q = &txq->q; + avail = iwl_queue_space(q); + + stats[i].len = q->n_window - avail; + stats[i].limit = q->n_window - q->high_mark; + stats[i].count = q->n_window; + + } + spin_unlock_irqrestore(&priv->lock, flags); + + IWL_DEBUG_MAC80211(priv, "leave\n"); + + return 0; +} +EXPORT_SYMBOL(iwl_mac_get_tx_stats); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 92a42c880488..7e0d0ed0a5db 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -284,6 +284,8 @@ void iwl_config_ap(struct iwl_priv *priv); int iwl_mac_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_if_conf *conf); +int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, + struct ieee80211_tx_queue_stats *stats); /***************************************************** * RX handlers. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 3461768e5a2b..07883b264b7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3494,41 +3494,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } -static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw, - struct ieee80211_tx_queue_stats *stats) -{ - struct iwl_priv *priv = hw->priv; - int i, avail; - struct iwl_tx_queue *txq; - struct iwl_queue *q; - unsigned long flags; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; - } - - spin_lock_irqsave(&priv->lock, flags); - - for (i = 0; i < AC_NUM; i++) { - txq = &priv->txq[i]; - q = &txq->q; - avail = iwl_queue_space(q); - - stats[i].len = q->n_window - avail; - stats[i].limit = q->n_window - q->high_mark; - stats[i].count = q->n_window; - - } - spin_unlock_irqrestore(&priv->lock, flags); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - - return 0; -} - static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; @@ -4116,7 +4081,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .config_interface = iwl_mac_config_interface, .configure_filter = iwl_configure_filter, .set_key = iwl3945_mac_set_key, - .get_tx_stats = iwl3945_mac_get_tx_stats, + .get_tx_stats = iwl_mac_get_tx_stats, .conf_tx = iwl_mac_conf_tx, .reset_tsf = iwl3945_mac_reset_tsf, .bss_info_changed = iwl_bss_info_changed, -- GitLab From bd564261d7dd3660f7a5ba308a867c6bb23de6a2 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Wed, 8 Apr 2009 11:26:52 -0700 Subject: [PATCH 0590/6080] iwl3945: use iwl_mac_reset_tsf from iwlwifi 3945 can now use iwl_mac_reset_tsf from iwlwifi. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 75 --------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 75 +++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 60 +---------------- 4 files changed, 77 insertions(+), 134 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3ebf80fbebab..9dda3d547d0d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2235,81 +2235,6 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw, return 0; } -static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - - mutex_lock(&priv->mutex); - IWL_DEBUG_MAC80211(priv, "enter\n"); - - spin_lock_irqsave(&priv->lock, flags); - memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); - spin_unlock_irqrestore(&priv->lock, flags); - - iwl_reset_qos(priv); - - spin_lock_irqsave(&priv->lock, flags); - priv->assoc_id = 0; - priv->assoc_capability = 0; - priv->assoc_station_added = 0; - - /* new association get rid of ibss beacon skb */ - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - - priv->ibss_beacon = NULL; - - priv->beacon_int = priv->hw->conf.beacon_int; - priv->timestamp = 0; - if ((priv->iw_mode == NL80211_IFTYPE_STATION)) - priv->beacon_int = 0; - - spin_unlock_irqrestore(&priv->lock, flags); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - mutex_unlock(&priv->mutex); - return; - } - - /* we are restarting association process - * clear RXON_FILTER_ASSOC_MSK bit - */ - if (priv->iw_mode != NL80211_IFTYPE_AP) { - iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); - } - - iwl_power_update_mode(priv, 0); - - /* Per mac80211.h: This is only used in IBSS mode... */ - if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { - - /* switch to CAM during association period. - * the ucode will block any association/authentication - * frome during assiciation period if it can not hear - * the AP because of PM. the timer enable PM back is - * association do not complete - */ - if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN | - IEEE80211_CHAN_RADAR)) - iwl_power_disable_management(priv, 3000); - - IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); - mutex_unlock(&priv->mutex); - return; - } - - iwl_set_rate(priv); - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); -} - - /***************************************************************************** * * sysfs attributes diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 144630b25491..c523cc339eaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2715,6 +2715,81 @@ int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, } EXPORT_SYMBOL(iwl_mac_get_tx_stats); +void iwl_mac_reset_tsf(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + unsigned long flags; + + mutex_lock(&priv->mutex); + IWL_DEBUG_MAC80211(priv, "enter\n"); + + spin_lock_irqsave(&priv->lock, flags); + memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); + spin_unlock_irqrestore(&priv->lock, flags); + + iwl_reset_qos(priv); + + spin_lock_irqsave(&priv->lock, flags); + priv->assoc_id = 0; + priv->assoc_capability = 0; + priv->assoc_station_added = 0; + + /* new association get rid of ibss beacon skb */ + if (priv->ibss_beacon) + dev_kfree_skb(priv->ibss_beacon); + + priv->ibss_beacon = NULL; + + priv->beacon_int = priv->hw->conf.beacon_int; + priv->timestamp = 0; + if ((priv->iw_mode == NL80211_IFTYPE_STATION)) + priv->beacon_int = 0; + + spin_unlock_irqrestore(&priv->lock, flags); + + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + mutex_unlock(&priv->mutex); + return; + } + + /* we are restarting association process + * clear RXON_FILTER_ASSOC_MSK bit + */ + if (priv->iw_mode != NL80211_IFTYPE_AP) { + iwl_scan_cancel_timeout(priv, 100); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv); + } + + iwl_power_update_mode(priv, 0); + + /* Per mac80211.h: This is only used in IBSS mode... */ + if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { + + /* switch to CAM during association period. + * the ucode will block any association/authentication + * frome during assiciation period if it can not hear + * the AP because of PM. the timer enable PM back is + * association do not complete + */ + if (priv->hw->conf.channel->flags & + (IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_RADAR)) + iwl_power_disable_management(priv, 3000); + + IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); + mutex_unlock(&priv->mutex); + return; + } + + iwl_set_rate(priv); + + mutex_unlock(&priv->mutex); + + IWL_DEBUG_MAC80211(priv, "leave\n"); +} +EXPORT_SYMBOL(iwl_mac_reset_tsf); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7e0d0ed0a5db..df90c261b6b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -286,6 +286,7 @@ int iwl_mac_config_interface(struct ieee80211_hw *hw, struct ieee80211_if_conf *conf); int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, struct ieee80211_tx_queue_stats *stats); +void iwl_mac_reset_tsf(struct ieee80211_hw *hw); /***************************************************** * RX handlers. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 07883b264b7e..ed497551a860 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3494,64 +3494,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return ret; } -static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) -{ - struct iwl_priv *priv = hw->priv; - unsigned long flags; - - mutex_lock(&priv->mutex); - IWL_DEBUG_MAC80211(priv, "enter\n"); - - iwl_reset_qos(priv); - - spin_lock_irqsave(&priv->lock, flags); - priv->assoc_id = 0; - priv->assoc_capability = 0; - - /* new association get rid of ibss beacon skb */ - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - - priv->ibss_beacon = NULL; - - priv->beacon_int = priv->hw->conf.beacon_int; - priv->timestamp = 0; - if ((priv->iw_mode == NL80211_IFTYPE_STATION)) - priv->beacon_int = 0; - - spin_unlock_irqrestore(&priv->lock, flags); - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - mutex_unlock(&priv->mutex); - return; - } - - /* we are restarting association process - * clear RXON_FILTER_ASSOC_MSK bit - */ - if (priv->iw_mode != NL80211_IFTYPE_AP) { - iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); - } - - /* Per mac80211.h: This is only used in IBSS mode... */ - if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { - - IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); - mutex_unlock(&priv->mutex); - return; - } - - iwl_set_rate(priv); - - mutex_unlock(&priv->mutex); - - IWL_DEBUG_MAC80211(priv, "leave\n"); - -} - /***************************************************************************** * * sysfs attributes @@ -4083,7 +4025,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .set_key = iwl3945_mac_set_key, .get_tx_stats = iwl_mac_get_tx_stats, .conf_tx = iwl_mac_conf_tx, - .reset_tsf = iwl3945_mac_reset_tsf, + .reset_tsf = iwl_mac_reset_tsf, .bss_info_changed = iwl_bss_info_changed, .hw_scan = iwl_mac_hw_scan }; -- GitLab From 12b9681721adb34b7ec42aa973ab96692998153d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 8 Apr 2009 11:39:27 -0700 Subject: [PATCH 0591/6080] iwlwifi: Display decoded rate/mcs information This patch adding MCS information in rate_scale_table, it help for debugging rate scaling algorithm, easy to understand what is the current rate scale table and matching modulation, plus the last mcs used for tx. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 40 ++++++++++++++++++++--- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 7 ++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index b1818a3d1e51..786b11d52b45 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -167,6 +167,8 @@ struct iwl_lq_sta { /* used to be in sta_info */ int last_txrate_idx; + /* last tx rate_n_flags */ + u32 last_rate_n_flags; }; static void rs_rate_scale_perform(struct iwl_priv *priv, @@ -249,6 +251,23 @@ static s32 expected_tpt_mimo3_40MHzSGI[IWL_RATE_COUNT] = { 0, 0, 0, 0, 160, 160, 219, 245, 261, 284, 294, 297, 300 }; +/* mbps, mcs */ +const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { + {"1", ""}, + {"2", ""}, + {"5.5", ""}, + {"11", ""}, + {"6", "BPSK 1/2"}, + {"9", "BPSK 1/2"}, + {"12", "QPSK 1/2"}, + {"18", "QPSK 3/4"}, + {"24", "16QAM 1/2"}, + {"36", "16QAM 3/4"}, + {"48", "64QAM 2/3"}, + {"54", "64QAM 3/4"}, + {"60", "64QAM 5/6"} +}; + static inline u8 rs_extract_rate(u32 rate_n_flags) { return (u8)(rate_n_flags & 0xFF); @@ -919,6 +938,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, * else look up the rate that was, finally, successful. */ tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags); + lq_sta->last_rate_n_flags = tx_rate; rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index); /* Update frame history window with "success" if Tx got ACKed ... */ @@ -2826,6 +2846,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, char *buff; int desc = 0; int i = 0; + int index = 0; ssize_t ret; struct iwl_lq_sta *lq_sta = file->private_data; @@ -2857,6 +2878,8 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, (tbl->is_fat) ? "40MHz" : "20MHz"); desc += sprintf(buff+desc, " %s\n", (tbl->is_SGI) ? "SGI" : ""); } + desc += sprintf(buff+desc, "last tx rate=0x%X\n", + lq_sta->last_rate_n_flags); desc += sprintf(buff+desc, "general:" "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", lq_sta->lq.general_params.flags, @@ -2877,10 +2900,19 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, lq_sta->lq.general_params.start_rate_index[2], lq_sta->lq.general_params.start_rate_index[3]); - - for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) - desc += sprintf(buff+desc, " rate[%d] 0x%X\n", - i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags)); + for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { + index = iwl_hwrate_to_plcp_idx( + le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags)); + if (is_legacy(tbl->lq_type)) { + desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n", + i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags), + iwl_rate_mcs[index].mbps); + } else { + desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps (%s)\n", + i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags), + iwl_rate_mcs[index].mbps, iwl_rate_mcs[index].mcs); + } + } ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); kfree(buff); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 9cd90ba5ef95..f875136bc5dc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -325,6 +325,13 @@ enum iwl_table_type { #define ANT_BC (ANT_B | ANT_C) #define ANT_ABC (ANT_AB | ANT_C) +#define IWL_MAX_MCS_DISPLAY_SIZE 12 + +struct iwl_rate_mcs_info { + char mbps[IWL_MAX_MCS_DISPLAY_SIZE]; + char mcs[IWL_MAX_MCS_DISPLAY_SIZE]; +}; + static inline u8 num_of_ant(u8 mask) { return !!((mask) & ANT_A) + -- GitLab From ddfcf999274838a8dfb0ccf8e69fc1e50eea3341 Mon Sep 17 00:00:00 2001 From: Daniel C Halperin Date: Wed, 8 Apr 2009 11:39:28 -0700 Subject: [PATCH 0592/6080] iwlwifi: do not set dual_stream_ant_msk for 3 streams This patch fixes a bug introduced by commit "iwlwifi: adding MIMO3 support in rate scaling". We should not set the dual_stream_ant_msk (for 2x2 MIMO) when using a 3x3 rate, this will cause a SYSASSERT in uCode. Note: there is no triple_stream_ant_msk, because all three antennas are used. Signed-off-by: Daniel C Halperin Acked-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 786b11d52b45..98b6b37951b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2666,9 +2666,6 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv, } else if (num_of_ant(tbl_type.ant_type) == 2) { lq_cmd->general_params.dual_stream_ant_msk = tbl_type.ant_type; - } else if (num_of_ant(tbl_type.ant_type) == 3) { - lq_cmd->general_params.dual_stream_ant_msk = - tbl_type.ant_type; } /* otherwise we don't modify the existing value */ index++; -- GitLab From 3a6502927f763f05069d1b84af3a05b38eb1a818 Mon Sep 17 00:00:00 2001 From: Mohamed Abbas Date: Wed, 8 Apr 2009 11:39:29 -0700 Subject: [PATCH 0593/6080] iwlagn: Sync rxon active with changes We need to sync rxon_active with changes after we commit rxon_assoc, without rxon_active will still have the old data that cause iwl_send_rxon_assoc to fail with no change in rxon command. Signed-off-by: Mohamed Abbas Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c523cc339eaf..8f121fa3f325 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2238,6 +2238,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, u32 changes) { struct iwl_priv *priv = hw->priv; + int ret; IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); @@ -2292,7 +2293,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, } } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes); - iwl_send_rxon_assoc(priv); + ret = iwl_send_rxon_assoc(priv); + if (!ret) + /* Sync active_rxon with latest change. */ + memcpy((void *)&priv->active_rxon, + &priv->staging_rxon, + sizeof(struct iwl_rxon_cmd)); } } -- GitLab From c2105fa7b68547a414095cfbf59bf513a9aae3ce Mon Sep 17 00:00:00 2001 From: Daniel C Halperin Date: Wed, 8 Apr 2009 11:39:30 -0700 Subject: [PATCH 0594/6080] iwlwifi: check triple_stream_basic_rates in iwl_full_rxon_required For completeness, we should also make sure that the 3x3 MIMO rates are also checked when seeing if one rxon struct matches another. Signed-off-by: Daniel C Halperin Acked-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8f121fa3f325..5877293bd21f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -735,6 +735,8 @@ int iwl_full_rxon_required(struct iwl_priv *priv) priv->active_rxon.ofdm_ht_single_stream_basic_rates) || (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || + (priv->staging_rxon.ofdm_ht_triple_stream_basic_rates != + priv->active_rxon.ofdm_ht_triple_stream_basic_rates) || (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) return 1; -- GitLab From 1620108910b07bc41f4ad462ca56e899faf7e61a Mon Sep 17 00:00:00 2001 From: Mohamed Abbas Date: Wed, 8 Apr 2009 11:39:31 -0700 Subject: [PATCH 0595/6080] iwlcore: fix channel display in debugfs Fix displaying of wrong channel information when user query channel through debugfs Signed-off-by: Mohamed Abbas Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index af1d1214b184..5b8c83939bf0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -389,7 +389,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, channels[i].max_power, channels[i].flags & IEEE80211_CHAN_RADAR ? " (IEEE 802.11h required)" : "", - (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS) + ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) || (channels[i].flags & IEEE80211_CHAN_RADAR)) ? "" : ", IBSS", -- GitLab From a83b9141b540f96dd59409c6487828e880113a29 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 8 Apr 2009 11:39:32 -0700 Subject: [PATCH 0596/6080] iwlwifi: adding interrupt counter in debugfs for debugging This patch adds interrupt statistics report to debugfs, this can help to understand number of interrupts happened which including HW/SW error for easier and better debugging. in /sys/kernel/debug/ieee80211/phyN/iwlagn/data directory use "cat interrupt" to view the current interrupt counter use "echo 0 > interrupt" to clear interrupt counter Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 26 +++++- drivers/net/wireless/iwlwifi/iwl-core.c | 6 ++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-debug.h | 1 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 92 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 18 +++++ 6 files changed, 141 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 9dda3d547d0d..12de63e9c720 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -911,6 +911,7 @@ void iwl_rx_handle(struct iwl_priv *priv) IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); + priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; } else { /* No handling needed */ IWL_DEBUG_RX(priv, @@ -1035,6 +1036,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* Tell the device to stop sending interrupts */ iwl_disable_interrupts(priv); + priv->isr_stats.hw++; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_HW_ERR; @@ -1047,13 +1049,17 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) #ifdef CONFIG_IWLWIFI_DEBUG if (priv->debug_level & (IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ - if (inta & CSR_INT_BIT_SCD) + if (inta & CSR_INT_BIT_SCD) { IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " "the frame/frames.\n"); + priv->isr_stats.sch++; + } /* Alive notification via Rx interrupt will do the real work */ - if (inta & CSR_INT_BIT_ALIVE) + if (inta & CSR_INT_BIT_ALIVE) { IWL_DEBUG_ISR(priv, "Alive interrupt\n"); + priv->isr_stats.alive++; + } } #endif /* Safely ignore these bits for debug checks below */ @@ -1069,6 +1075,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", hw_rf_kill ? "disable radio" : "enable radio"); + priv->isr_stats.rfkill++; + /* driver only loads ucode once setting the interface up. * the driver allows loading the ucode even if the radio * is killed. Hence update the killswitch state here. The @@ -1088,6 +1096,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* Chip got too hot and stopped itself */ if (inta & CSR_INT_BIT_CT_KILL) { IWL_ERR(priv, "Microcode CT kill error detected.\n"); + priv->isr_stats.ctkill++; handled |= CSR_INT_BIT_CT_KILL; } @@ -1095,6 +1104,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) if (inta & CSR_INT_BIT_SW_ERR) { IWL_ERR(priv, "Microcode SW error detected. " " Restarting 0x%X.\n", inta); + priv->isr_stats.sw++; + priv->isr_stats.sw_err = inta; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } @@ -1110,6 +1121,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) iwl_txq_update_write_ptr(priv, &priv->txq[4]); iwl_txq_update_write_ptr(priv, &priv->txq[5]); + priv->isr_stats.wakeup++; + handled |= CSR_INT_BIT_WAKEUP; } @@ -1118,19 +1131,23 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) * notifications from uCode come through here*/ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { iwl_rx_handle(priv); + priv->isr_stats.rx++; handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); } if (inta & CSR_INT_BIT_FH_TX) { IWL_DEBUG_ISR(priv, "Tx interrupt\n"); + priv->isr_stats.tx++; handled |= CSR_INT_BIT_FH_TX; /* FH finished to write, send event */ priv->ucode_write_complete = 1; wake_up_interruptible(&priv->wait_command_queue); } - if (inta & ~handled) + if (inta & ~handled) { IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); + priv->isr_stats.unhandled++; + } if (inta & ~CSR_INI_SET_MASK) { IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", @@ -1155,6 +1172,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } + /****************************************************************************** * * uCode download functions @@ -1983,6 +2001,8 @@ static int iwl_mac_start(struct ieee80211_hw *hw) out: priv->is_open = 1; + /* default to MONITOR mode */ + priv->iw_mode = NL80211_IFTYPE_MONITOR; IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5877293bd21f..f23175240289 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2119,6 +2119,12 @@ void iwl_rx_reply_error(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_rx_reply_error); +void iwl_clear_isr_stats(struct iwl_priv *priv) +{ + memset(&priv->isr_stats, 0, sizeof(priv->isr_stats)); +} +EXPORT_SYMBOL(iwl_clear_isr_stats); + int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index df90c261b6b5..8773d733a54e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -480,6 +480,7 @@ int iwl_pci_resume(struct pci_dev *pdev); ******************************************************/ void iwl_dump_nic_error_log(struct iwl_priv *priv); void iwl_dump_nic_event_log(struct iwl_priv *priv); +void iwl_clear_isr_stats(struct iwl_priv *priv); /***************************************************** * GEOS diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 65d1a7f2db9e..db069801bc41 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -75,6 +75,7 @@ struct iwl_debugfs { struct dentry *file_log_event; struct dentry *file_channels; struct dentry *file_status; + struct dentry *file_interrupt; } dbgfs_data_files; struct dir_rf_files { struct dentry *file_disable_sensitivity; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 5b8c83939bf0..ffc4be3842b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -473,6 +473,95 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } +static ssize_t iwl_dbgfs_interrupt_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + int pos = 0; + int cnt = 0; + char *buf; + int bufsz = 24 * 64; /* 24 items * 64 char per item */ + ssize_t ret; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + pos += scnprintf(buf + pos, bufsz - pos, + "Interrupt Statistics Report:\n"); + + pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", + priv->isr_stats.hw); + pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", + priv->isr_stats.sw); + if (priv->isr_stats.sw > 0) { + pos += scnprintf(buf + pos, bufsz - pos, + "\tLast Restarting Code: 0x%X\n", + priv->isr_stats.sw_err); + } +#ifdef CONFIG_IWLWIFI_DEBUG + pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", + priv->isr_stats.sch); + pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", + priv->isr_stats.alive); +#endif + pos += scnprintf(buf + pos, bufsz - pos, + "HW RF KILL switch toggled:\t %u\n", + priv->isr_stats.rfkill); + + pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", + priv->isr_stats.ctkill); + + pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", + priv->isr_stats.wakeup); + + pos += scnprintf(buf + pos, bufsz - pos, + "Rx command responses:\t\t %u\n", + priv->isr_stats.rx); + for (cnt = 0; cnt < REPLY_MAX; cnt++) { + if (priv->isr_stats.rx_handlers[cnt] > 0) + pos += scnprintf(buf + pos, bufsz - pos, + "\tRx handler[%36s]:\t\t %u\n", + get_cmd_string(cnt), + priv->isr_stats.rx_handlers[cnt]); + } + + pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", + priv->isr_stats.tx); + + pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", + priv->isr_stats.unhandled); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} + +static ssize_t iwl_dbgfs_interrupt_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + u32 reset_flag; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%x", &reset_flag) != 1) + return -EFAULT; + if (reset_flag == 0) + iwl_clear_isr_stats(priv); + + return count; +} + + DEBUGFS_READ_WRITE_FILE_OPS(sram); DEBUGFS_WRITE_FILE_OPS(log_event); DEBUGFS_READ_FILE_OPS(eeprom); @@ -481,6 +570,7 @@ DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_FILE_OPS(channels); DEBUGFS_READ_FILE_OPS(status); +DEBUGFS_READ_WRITE_FILE_OPS(interrupt); /* * Create the debugfs files and directories @@ -516,6 +606,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(tx_statistics, data); DEBUGFS_ADD_FILE(channels, data); DEBUGFS_ADD_FILE(status, data); + DEBUGFS_ADD_FILE(interrupt, data); DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); DEBUGFS_ADD_BOOL(disable_chain_noise, rf, &priv->disable_chain_noise_cal); @@ -546,6 +637,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); + DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt); DEBUGFS_REMOVE(priv->dbgfs->dir_data); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 59930f398f31..0922e33a7d42 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -819,6 +819,21 @@ enum { MEASUREMENT_ACTIVE = (1 << 1), }; +/* interrupt statistics */ +struct isr_statistics { + u32 hw; + u32 sw; + u32 sw_err; + u32 sch; + u32 alive; + u32 rfkill; + u32 ctkill; + u32 wakeup; + u32 rx; + u32 rx_handlers[REPLY_MAX]; + u32 tx; + u32 unhandled; +}; #define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */ @@ -975,6 +990,9 @@ struct iwl_priv { u64 bytes; } tx_stats[3], rx_stats[3]; + /* counts interrupts */ + struct isr_statistics isr_stats; + struct iwl_power_mgr power_data; struct iwl_notif_statistics statistics; -- GitLab From a2caba6b5fc4e046edfefb1db82f52b939b526a5 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 14 Apr 2009 11:45:57 -0400 Subject: [PATCH 0597/6080] libertas: fix warning about %zd: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/libertas/rx.c: In function ‘lbs_process_rxed_packet’: drivers/net/wireless/libertas/rx.c:184: warning: format ‘%zd’ expects type ‘signed size_t’, but argument 4 has type ‘__le32’ drivers/net/wireless/libertas/rx.c:184: warning: format ‘%zd’ expects type ‘signed size_t’, but argument 5 has type ‘unsigned int’ Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index bd845d09f174..65f02cc6752f 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -182,8 +182,8 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) } lbs_deb_rx("rx data: skb->len - pkt_ptr = %d-%zd = %zd\n", - skb->len, le32_to_cpu(p_rx_pd->pkt_ptr), - skb->len - le32_to_cpu(p_rx_pd->pkt_ptr)); + skb->len, (size_t)le32_to_cpu(p_rx_pd->pkt_ptr), + skb->len - (size_t)le32_to_cpu(p_rx_pd->pkt_ptr)); lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr, sizeof(p_rx_pkt->eth803_hdr.dest_addr)); -- GitLab From 137907287789607f2a2586ad625e7b8c646b3425 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Wed, 8 Apr 2009 21:26:27 +0200 Subject: [PATCH 0598/6080] b43: Remove unnecessary MMIO in interrupt hotpath This removes unnecessary MMIO accesses in the interrupt hotpath. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 4 +-- drivers/net/wireless/b43/main.c | 61 ++++++++++----------------------- 2 files changed, 21 insertions(+), 44 deletions(-) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index cc1db7e5c664..4e8ad841c3c5 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -778,8 +778,8 @@ struct b43_wldev { /* Reason code of the last interrupt. */ u32 irq_reason; u32 dma_reason[6]; - /* saved irq enable/disable state bitfield. */ - u32 irq_savedstate; + /* The currently active generic-interrupt mask. */ + u32 irq_mask; /* Link Quality calculation context. */ struct b43_noise_calculation noisecalc; /* if > 0 MAC is suspended. if == 0 MAC is enabled. */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 09e0c60d96df..a97c6ff0f12e 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -673,32 +673,6 @@ static void b43_short_slot_timing_disable(struct b43_wldev *dev) b43_set_slot_time(dev, 20); } -/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable. - * Returns the _previously_ enabled IRQ mask. - */ -static inline u32 b43_interrupt_enable(struct b43_wldev *dev, u32 mask) -{ - u32 old_mask; - - old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); - b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask | mask); - - return old_mask; -} - -/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable. - * Returns the _previously_ enabled IRQ mask. - */ -static inline u32 b43_interrupt_disable(struct b43_wldev *dev, u32 mask) -{ - u32 old_mask; - - old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); - b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask & ~mask); - - return old_mask; -} - /* Synchronize IRQ top- and bottom-half. * IRQs must be masked before calling this. * This must not be called with the irq_lock held. @@ -1593,7 +1567,7 @@ static void handle_irq_beacon(struct b43_wldev *dev) /* This is the bottom half of the asynchronous beacon update. */ /* Ignore interrupt in the future. */ - dev->irq_savedstate &= ~B43_IRQ_BEACON; + dev->irq_mask &= ~B43_IRQ_BEACON; cmd = b43_read32(dev, B43_MMIO_MACCMD); beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID); @@ -1602,7 +1576,7 @@ static void handle_irq_beacon(struct b43_wldev *dev) /* Schedule interrupt manually, if busy. */ if (beacon0_valid && beacon1_valid) { b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON); - dev->irq_savedstate |= B43_IRQ_BEACON; + dev->irq_mask |= B43_IRQ_BEACON; return; } @@ -1641,11 +1615,9 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { spin_lock_irq(&wl->irq_lock); /* update beacon right away or defer to irq */ - dev->irq_savedstate = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); handle_irq_beacon(dev); /* The handler might have updated the IRQ mask. */ - b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, - dev->irq_savedstate); + b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask); mmiowb(); spin_unlock_irq(&wl->irq_lock); } @@ -1879,7 +1851,7 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev) if (reason & B43_IRQ_TX_OK) handle_irq_transmit_status(dev); - b43_interrupt_enable(dev, dev->irq_savedstate); + b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask); mmiowb(); spin_unlock_irqrestore(&dev->wl->irq_lock, flags); } @@ -1893,7 +1865,9 @@ static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason) b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]); b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]); b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]); +/* Unused ring b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]); +*/ } /* Interrupt handler top-half */ @@ -1903,18 +1877,19 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id) struct b43_wldev *dev = dev_id; u32 reason; - if (!dev) - return IRQ_NONE; + B43_WARN_ON(!dev); spin_lock(&dev->wl->irq_lock); - if (b43_status(dev) < B43_STAT_STARTED) + if (unlikely(b43_status(dev) < B43_STAT_STARTED)) { + /* This can only happen on shared IRQ lines. */ goto out; + } reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON); if (reason == 0xffffffff) /* shared IRQ */ goto out; ret = IRQ_HANDLED; - reason &= b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); + reason &= dev->irq_mask; if (!reason) goto out; @@ -1928,16 +1903,18 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id) & 0x0001DC00; dev->dma_reason[4] = b43_read32(dev, B43_MMIO_DMA4_REASON) & 0x0000DC00; +/* Unused ring dev->dma_reason[5] = b43_read32(dev, B43_MMIO_DMA5_REASON) & 0x0000DC00; +*/ b43_interrupt_ack(dev, reason); /* disable all IRQs. They are enabled again in the bottom half. */ - dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL); + b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); /* save the reason code and call our bottom half. */ dev->irq_reason = reason; tasklet_schedule(&dev->isr_tasklet); - out: +out: mmiowb(); spin_unlock(&dev->wl->irq_lock); @@ -3799,7 +3776,7 @@ static void b43_wireless_core_stop(struct b43_wldev *dev) * setting the status to INITIALIZED, as the interrupt handler * won't care about IRQs then. */ spin_lock_irqsave(&wl->irq_lock, flags); - dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL); + b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */ spin_unlock_irqrestore(&wl->irq_lock, flags); b43_synchronize_irq(dev); @@ -3840,7 +3817,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev) /* Start data flow (TX/RX). */ b43_mac_enable(dev); - b43_interrupt_enable(dev, dev->irq_savedstate); + b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask); /* Start maintainance work */ b43_periodic_tasks_setup(dev); @@ -4003,9 +3980,9 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev) /* IRQ related flags */ dev->irq_reason = 0; memset(dev->dma_reason, 0, sizeof(dev->dma_reason)); - dev->irq_savedstate = B43_IRQ_MASKTEMPLATE; + dev->irq_mask = B43_IRQ_MASKTEMPLATE; if (b43_modparam_verbose < B43_VERBOSITY_DEBUG) - dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR; + dev->irq_mask &= ~B43_IRQ_PHY_TXERR; dev->mac_suspended = 1; -- GitLab From 492301fb5d12e4a77a1010ad2b6f1ed306014123 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 9 Apr 2009 22:14:19 -0500 Subject: [PATCH 0599/6080] rfkill: Fix broken rfkill LED in 2.6.30-rc1 The rfkill system fails to issue a LED trigger event when the rfkill state changes. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- net/rfkill/rfkill.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index df1269c5ca70..e2d4510623f2 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -96,6 +96,7 @@ static void update_rfkill_state(struct rfkill *rfkill) } mutex_unlock(&rfkill->mutex); } + rfkill_led_trigger(rfkill, rfkill->state); } /** @@ -136,8 +137,9 @@ static int rfkill_toggle_radio(struct rfkill *rfkill, oldstate = rfkill->state; if (rfkill->get_state && !force && - !rfkill->get_state(rfkill->data, &newstate)) + !rfkill->get_state(rfkill->data, &newstate)) { rfkill->state = newstate; + } switch (state) { case RFKILL_STATE_HARD_BLOCKED: @@ -172,6 +174,7 @@ static int rfkill_toggle_radio(struct rfkill *rfkill, if (force || rfkill->state != oldstate) rfkill_uevent(rfkill); + rfkill_led_trigger(rfkill, rfkill->state); return retval; } @@ -204,6 +207,7 @@ static void __rfkill_switch_all(const enum rfkill_type type, mutex_lock(&rfkill->mutex); rfkill_toggle_radio(rfkill, state, 0); mutex_unlock(&rfkill->mutex); + rfkill_led_trigger(rfkill, rfkill->state); } } } @@ -256,6 +260,7 @@ void rfkill_epo(void) RFKILL_STATE_SOFT_BLOCKED; } mutex_unlock(&rfkill_global_mutex); + rfkill_led_trigger(rfkill, rfkill->state); } EXPORT_SYMBOL_GPL(rfkill_epo); @@ -358,6 +363,7 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state) rfkill_uevent(rfkill); mutex_unlock(&rfkill->mutex); + rfkill_led_trigger(rfkill, rfkill->state); return 0; } @@ -520,6 +526,7 @@ static int rfkill_resume(struct device *dev) 1); mutex_unlock(&rfkill->mutex); + rfkill_led_trigger(rfkill, rfkill->state); } return 0; -- GitLab From 6dfe9a884fec67070fc7502ad82f7eb328950b72 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 11 Apr 2009 03:58:01 +0200 Subject: [PATCH 0600/6080] p54: utilize all available key slots for decryption offload This patch takes care of outstanding TODOs: /* TODO: some devices have 4 more free slots for rx keys */ Now the driver can utilize all available key slots instead of just 4. Obviously, this helps most in AP/IBSS(/MESH) mode, when we have to use more different keys. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54.h | 1 + drivers/net/wireless/p54/p54common.c | 101 ++++++++++++++++++++------- 2 files changed, 75 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index d6354faaa2bc..7fda1a9e263b 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h @@ -186,6 +186,7 @@ struct p54_common { /* cryptographic engine information */ u8 privacy_caps; u8 rx_keycache_size; + unsigned long *used_rxkeys; /* LED management */ #ifdef CONFIG_MAC80211_LEDS diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index cb490584cb8e..7bd4fdf83349 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -249,7 +249,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) dev->queues = P54_QUEUE_AC_NUM; } - if (!modparam_nohwcrypt) + if (!modparam_nohwcrypt) { printk(KERN_INFO "%s: cryptographic accelerator " "WEP:%s, TKIP:%s, CCMP:%s\n", wiphy_name(dev->wiphy), @@ -259,6 +259,26 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ? "YES" : "no"); + if (priv->rx_keycache_size) { + /* + * NOTE: + * + * The firmware provides at most 255 (0 - 254) slots + * for keys which are then used to offload decryption. + * As a result the 255 entry (aka 0xff) can be used + * safely by the driver to mark keys that didn't fit + * into the full cache. This trick saves us from + * keeping a extra list for uploaded keys. + */ + + priv->used_rxkeys = kzalloc(BITS_TO_LONGS( + priv->rx_keycache_size), GFP_KERNEL); + + if (!priv->used_rxkeys) + return -ENOMEM; + } + } + return 0; } EXPORT_SYMBOL_GPL(p54_parse_firmware); @@ -2355,61 +2375,84 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, struct p54_common *priv = dev->priv; struct sk_buff *skb; struct p54_keycache *rxkey; + int slot, ret = 0; u8 algo = 0; if (modparam_nohwcrypt) return -EOPNOTSUPP; - if (cmd == DISABLE_KEY) - algo = 0; - else { + mutex_lock(&priv->conf_mutex); + if (cmd == SET_KEY) { switch (key->alg) { case ALG_TKIP: if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL | - BR_DESC_PRIV_CAP_TKIP))) - return -EOPNOTSUPP; + BR_DESC_PRIV_CAP_TKIP))) { + ret = -EOPNOTSUPP; + goto out_unlock; + } key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; algo = P54_CRYPTO_TKIPMICHAEL; break; case ALG_WEP: - if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) - return -EOPNOTSUPP; + if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) { + ret = -EOPNOTSUPP; + goto out_unlock; + } key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; algo = P54_CRYPTO_WEP; break; case ALG_CCMP: - if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) - return -EOPNOTSUPP; + if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) { + ret = -EOPNOTSUPP; + goto out_unlock; + } key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; algo = P54_CRYPTO_AESCCMP; break; default: - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; + goto out_unlock; } - } + slot = bitmap_find_free_region(priv->used_rxkeys, + priv->rx_keycache_size, 0); - if (key->keyidx > priv->rx_keycache_size) { - /* - * The device supports the choosen algorithm, but the firmware - * does not provide enough key slots to store all of them. - * So, incoming frames have to be decoded by the mac80211 stack, - * but we can still offload encryption for outgoing frames. - */ + if (slot < 0) { + /* + * The device supports the choosen algorithm, but the + * firmware does not provide enough key slots to store + * all of them. + * But encryption offload for outgoing frames is always + * possible, so we just pretend that the upload was + * successful and do the decryption in software. + */ - return 0; + /* mark the key as invalid. */ + key->hw_key_idx = 0xff; + goto out_unlock; + } + } else { + slot = key->hw_key_idx; + + if (slot == 0xff) { + /* This key was not uploaded into the rx key cache. */ + + goto out_unlock; + } + + bitmap_release_region(priv->used_rxkeys, slot, 0); + algo = 0; } - mutex_lock(&priv->conf_mutex); skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey), - P54_CONTROL_TYPE_RX_KEYCACHE, GFP_ATOMIC); + P54_CONTROL_TYPE_RX_KEYCACHE, GFP_KERNEL); if (!skb) { - mutex_unlock(&priv->conf_mutex); - return -ENOMEM; + bitmap_release_region(priv->used_rxkeys, slot, 0); + ret = -ENOSPC; + goto out_unlock; } - /* TODO: some devices have 4 more free slots for rx keys */ rxkey = (struct p54_keycache *)skb_put(skb, sizeof(*rxkey)); - rxkey->entry = key->keyidx; + rxkey->entry = slot; rxkey->key_id = key->keyidx; rxkey->key_type = algo; if (sta) @@ -2427,8 +2470,11 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, } priv->tx(dev, skb); + key->hw_key_idx = slot; + +out_unlock: mutex_unlock(&priv->conf_mutex); - return 0; + return ret; } #ifdef CONFIG_P54_LEDS @@ -2662,6 +2708,7 @@ void p54_free_common(struct ieee80211_hw *dev) kfree(priv->iq_autocal); kfree(priv->output_limit); kfree(priv->curve_data); + kfree(priv->used_rxkeys); #ifdef CONFIG_P54_LEDS p54_unregister_leds(dev); -- GitLab From 4312a86b6840bca503603e918996b139fa3293ba Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 11 Apr 2009 03:58:14 +0200 Subject: [PATCH 0601/6080] p54: remove obsolet signal quality calculation The signal quality percentage is now calculated by mac80211 stack. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 7bd4fdf83349..b18fc93a8bce 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -769,8 +769,6 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) rx_status.signal = p54_rssi_to_dbm(dev, hdr->rssi); rx_status.noise = priv->noise; - /* XX correct? */ - rx_status.qual = (100 * hdr->rssi) / 127; if (hdr->rate & 0x10) rx_status.flag |= RX_FLAG_SHORTPRE; if (dev->conf.channel->band == IEEE80211_BAND_5GHZ) -- GitLab From 7edfab7adef45a09b459cb7f5957f476108f5e77 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 11 Apr 2009 13:32:46 +0200 Subject: [PATCH 0602/6080] cfg80211: convert mutex assert to macro That will make the various cases where the WARN_ON can happen distinguishable. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/core.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/wireless/core.h b/net/wireless/core.h index fcee83a0c9bb..02668b02e331 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -73,10 +73,7 @@ bool wiphy_idx_valid(int wiphy_idx) extern struct mutex cfg80211_mutex; extern struct list_head cfg80211_drv_list; -static inline void assert_cfg80211_lock(void) -{ - WARN_ON(!mutex_is_locked(&cfg80211_mutex)); -} +#define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex)) /* * You can use this to mark a wiphy_idx as not having an associated wiphy. -- GitLab From 7858e07b7ccf1d2fd5898a405c93d022d3f1f42d Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 11 Apr 2009 11:25:24 -0500 Subject: [PATCH 0603/6080] b43legacy: Fixes for beaconing This patch ports the beaconing fixes from commit a82d992261f "b43: Beaconing fixes" to b43legacy. Basically it prevents the card from triggering the beacon IRQ over and over again. Signed-off-by: Larry Finger Acked-by: Michael Buesch Tested-by: David Ellingsworth Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/b43legacy.h | 4 +- drivers/net/wireless/b43legacy/main.c | 47 ++++++++++++++++++---- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 4cdde4ad17c0..ad4794a0a327 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -59,7 +59,8 @@ #define B43legacy_MMIO_XMITSTAT_1 0x174 #define B43legacy_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */ #define B43legacy_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */ - +#define B43legacy_MMIO_TSF_CFP_REP 0x188 +#define B43legacy_MMIO_TSF_CFP_START 0x18C /* 32-bit DMA */ #define B43legacy_MMIO_DMA32_BASE0 0x200 #define B43legacy_MMIO_DMA32_BASE1 0x220 @@ -616,6 +617,7 @@ struct b43legacy_wl { struct sk_buff *current_beacon; bool beacon0_uploaded; bool beacon1_uploaded; + struct work_struct beacon_update_trigger; }; /* Pointers to the firmware data and meta information about it. */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 81dbbc1c591a..4f3f01629465 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1013,7 +1013,8 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, b43legacywarn(dev->wl, "Did not find a valid TIM IE in the " "beacon template packet. AP or IBSS operation " "may be broken.\n"); - } + } else + b43legacydbg(dev->wl, "Updated beacon template\n"); } static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, @@ -1133,6 +1134,27 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, kfree(probe_resp_data); } +static void b43legacy_beacon_update_trigger_work(struct work_struct *work) +{ + struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl, + beacon_update_trigger); + struct b43legacy_wldev *dev; + + mutex_lock(&wl->mutex); + dev = wl->current_dev; + if (likely(dev && (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED))) { + /* Force the microcode to trigger the + * beacon update bottom-half IRQ. */ + spin_lock_irq(&wl->irq_lock); + b43legacy_write32(dev, B43legacy_MMIO_MACCMD, + b43legacy_read32(dev, B43legacy_MMIO_MACCMD) + | B43legacy_MACCMD_BEACON0_VALID + | B43legacy_MACCMD_BEACON1_VALID); + spin_unlock_irq(&wl->irq_lock); + } + mutex_unlock(&wl->mutex); +} + /* Asynchronously update the packet templates in template RAM. * Locking: Requires wl->irq_lock to be locked. */ static void b43legacy_update_templates(struct b43legacy_wl *wl) @@ -1156,25 +1178,31 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl) wl->current_beacon = beacon; wl->beacon0_uploaded = 0; wl->beacon1_uploaded = 0; + queue_work(wl->hw->workqueue, &wl->beacon_update_trigger); } static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, u16 beacon_int) { b43legacy_time_lock(dev); - if (dev->dev->id.revision >= 3) - b43legacy_write32(dev, 0x188, (beacon_int << 16)); - else { + if (dev->dev->id.revision >= 3) { + b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_REP, + (beacon_int << 16)); + b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_START, + (beacon_int << 10)); + } else { b43legacy_write16(dev, 0x606, (beacon_int >> 6)); b43legacy_write16(dev, 0x610, beacon_int); } b43legacy_time_unlock(dev); + b43legacydbg(dev->wl, "Set beacon interval to %u\n", beacon_int); } static void handle_irq_beacon(struct b43legacy_wldev *dev) { struct b43legacy_wl *wl = dev->wl; u32 cmd; + u32 beacon0_valid, beacon1_valid; if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) return; @@ -1182,7 +1210,11 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev) /* This is the bottom half of the asynchronous beacon update. */ cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); - if (!(cmd & B43legacy_MACCMD_BEACON0_VALID)) { + beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID); + beacon1_valid = (cmd & B43legacy_MACCMD_BEACON1_VALID); + cmd &= ~(B43legacy_MACCMD_BEACON0_VALID | B43legacy_MACCMD_BEACON1_VALID); + + if (!beacon0_valid) { if (!wl->beacon0_uploaded) { b43legacy_write_beacon_template(dev, 0x68, B43legacy_SHM_SH_BTL0, @@ -1193,8 +1225,7 @@ static void handle_irq_beacon(struct b43legacy_wldev *dev) wl->beacon0_uploaded = 1; } cmd |= B43legacy_MACCMD_BEACON0_VALID; - } - if (!(cmd & B43legacy_MACCMD_BEACON1_VALID)) { + } else if (!beacon1_valid) { if (!wl->beacon1_uploaded) { b43legacy_write_beacon_template(dev, 0x468, B43legacy_SHM_SH_BTL1, @@ -3435,6 +3466,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) struct b43legacy_wldev *dev = wl->current_dev; b43legacy_rfkill_exit(dev); + cancel_work_sync(&(wl->beacon_update_trigger)); mutex_lock(&wl->mutex); if (b43legacy_status(dev) >= B43legacy_STAT_STARTED) @@ -3766,6 +3798,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev) spin_lock_init(&wl->leds_lock); mutex_init(&wl->mutex); INIT_LIST_HEAD(&wl->devlist); + INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work); ssb_set_devtypedata(dev, wl); b43legacyinfo(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id); -- GitLab From 2d1f96dd90a20c25243cc3b13e9f21d72f00aba0 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 11 Apr 2009 11:26:01 -0500 Subject: [PATCH 0604/6080] b43legacy: Clean up beacon IRQ This patch ports commit c97a4ccc1fad35d3 "b43: Fix beacon BH update" to b43legacy. It fixes beacon updating in the bottomhalf. In case the device is busy, we will defer to later in the IRQ handler. Signed-off-by: Larry Finger Acked-by: Michael Buesch Tested-by: David Ellingsworth Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/b43legacy.h | 2 +- drivers/net/wireless/b43legacy/main.c | 164 +++++++++++++++------ drivers/net/wireless/b43legacy/xmit.c | 2 +- drivers/net/wireless/b43legacy/xmit.h | 4 +- 4 files changed, 121 insertions(+), 51 deletions(-) diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index ad4794a0a327..da59ef02b6ef 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -259,7 +259,6 @@ #define B43legacy_IRQ_ALL 0xFFFFFFFF #define B43legacy_IRQ_MASKTEMPLATE (B43legacy_IRQ_MAC_SUSPENDED | \ - B43legacy_IRQ_BEACON | \ B43legacy_IRQ_TBTT_INDI | \ B43legacy_IRQ_ATIM_END | \ B43legacy_IRQ_PMQ | \ @@ -617,6 +616,7 @@ struct b43legacy_wl { struct sk_buff *current_beacon; bool beacon0_uploaded; bool beacon1_uploaded; + bool beacon_templates_virgin; /* Never wrote the templates? */ struct work_struct beacon_update_trigger; }; diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 4f3f01629465..ee202b4f77b5 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -955,23 +955,54 @@ static void b43legacy_write_template_common(struct b43legacy_wldev *dev, size + sizeof(struct b43legacy_plcp_hdr6)); } +/* Convert a b43legacy antenna number value to the PHY TX control value. */ +static u16 b43legacy_antenna_to_phyctl(int antenna) +{ + switch (antenna) { + case B43legacy_ANTENNA0: + return B43legacy_TX4_PHY_ANT0; + case B43legacy_ANTENNA1: + return B43legacy_TX4_PHY_ANT1; + } + return B43legacy_TX4_PHY_ANTLAST; +} + static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, u16 ram_offset, - u16 shm_size_offset, u8 rate) + u16 shm_size_offset) { unsigned int i, len, variable_len; const struct ieee80211_mgmt *bcn; const u8 *ie; bool tim_found = 0; + unsigned int rate; + u16 ctl; + int antenna; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon); bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data); len = min((size_t)dev->wl->current_beacon->len, 0x200 - sizeof(struct b43legacy_plcp_hdr6)); + rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value; b43legacy_write_template_common(dev, (const u8 *)bcn, len, ram_offset, shm_size_offset, rate); + /* Write the PHY TX control parameters. */ + antenna = B43legacy_ANTENNA_DEFAULT; + antenna = b43legacy_antenna_to_phyctl(antenna); + ctl = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED, + B43legacy_SHM_SH_BEACPHYCTL); + /* We can't send beacons with short preamble. Would get PHY errors. */ + ctl &= ~B43legacy_TX4_PHY_SHORTPRMBL; + ctl &= ~B43legacy_TX4_PHY_ANT; + ctl &= ~B43legacy_TX4_PHY_ENC; + ctl |= antenna; + ctl |= B43legacy_TX4_PHY_ENC_CCK; + b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, + B43legacy_SHM_SH_BEACPHYCTL, ctl); + /* Find the position of the TIM and the DTIM_period value * and write them to SHM. */ ie = bcn->u.beacon.variable; @@ -1026,7 +1057,7 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, __le16 dur; plcp.data = 0; - b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate); + b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value); dur = ieee80211_generic_frame_duration(dev->wl->hw, dev->wl->vif, size, @@ -1130,10 +1161,82 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, 0x200 - sizeof(struct b43legacy_plcp_hdr6)); b43legacy_write_template_common(dev, probe_resp_data, size, ram_offset, - shm_size_offset, rate->bitrate); + shm_size_offset, rate->hw_value); kfree(probe_resp_data); } +static void b43legacy_upload_beacon0(struct b43legacy_wldev *dev) +{ + struct b43legacy_wl *wl = dev->wl; + + if (wl->beacon0_uploaded) + return; + b43legacy_write_beacon_template(dev, 0x68, 0x18); + /* FIXME: Probe resp upload doesn't really belong here, + * but we don't use that feature anyway. */ + b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, + &__b43legacy_ratetable[3]); + wl->beacon0_uploaded = 1; +} + +static void b43legacy_upload_beacon1(struct b43legacy_wldev *dev) +{ + struct b43legacy_wl *wl = dev->wl; + + if (wl->beacon1_uploaded) + return; + b43legacy_write_beacon_template(dev, 0x468, 0x1A); + wl->beacon1_uploaded = 1; +} + +static void handle_irq_beacon(struct b43legacy_wldev *dev) +{ + struct b43legacy_wl *wl = dev->wl; + u32 cmd, beacon0_valid, beacon1_valid; + + if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) + return; + + /* This is the bottom half of the asynchronous beacon update. */ + + /* Ignore interrupt in the future. */ + dev->irq_savedstate &= ~B43legacy_IRQ_BEACON; + + cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); + beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID); + beacon1_valid = (cmd & B43legacy_MACCMD_BEACON1_VALID); + + /* Schedule interrupt manually, if busy. */ + if (beacon0_valid && beacon1_valid) { + b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, B43legacy_IRQ_BEACON); + dev->irq_savedstate |= B43legacy_IRQ_BEACON; + return; + } + + if (unlikely(wl->beacon_templates_virgin)) { + /* We never uploaded a beacon before. + * Upload both templates now, but only mark one valid. */ + wl->beacon_templates_virgin = 0; + b43legacy_upload_beacon0(dev); + b43legacy_upload_beacon1(dev); + cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); + cmd |= B43legacy_MACCMD_BEACON0_VALID; + b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd); + } else { + if (!beacon0_valid) { + b43legacy_upload_beacon0(dev); + cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); + cmd |= B43legacy_MACCMD_BEACON0_VALID; + b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd); + } else if (!beacon1_valid) { + b43legacy_upload_beacon1(dev); + cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); + cmd |= B43legacy_MACCMD_BEACON1_VALID; + b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd); + } + } +} + static void b43legacy_beacon_update_trigger_work(struct work_struct *work) { struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl, @@ -1143,13 +1246,14 @@ static void b43legacy_beacon_update_trigger_work(struct work_struct *work) mutex_lock(&wl->mutex); dev = wl->current_dev; if (likely(dev && (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED))) { - /* Force the microcode to trigger the - * beacon update bottom-half IRQ. */ spin_lock_irq(&wl->irq_lock); - b43legacy_write32(dev, B43legacy_MMIO_MACCMD, - b43legacy_read32(dev, B43legacy_MMIO_MACCMD) - | B43legacy_MACCMD_BEACON0_VALID - | B43legacy_MACCMD_BEACON1_VALID); + /* update beacon right away or defer to irq */ + dev->irq_savedstate = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); + handle_irq_beacon(dev); + /* The handler might have updated the IRQ mask. */ + b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, + dev->irq_savedstate); + mmiowb(); spin_unlock_irq(&wl->irq_lock); } mutex_unlock(&wl->mutex); @@ -1198,45 +1302,6 @@ static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, b43legacydbg(dev->wl, "Set beacon interval to %u\n", beacon_int); } -static void handle_irq_beacon(struct b43legacy_wldev *dev) -{ - struct b43legacy_wl *wl = dev->wl; - u32 cmd; - u32 beacon0_valid, beacon1_valid; - - if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) - return; - - /* This is the bottom half of the asynchronous beacon update. */ - - cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); - beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID); - beacon1_valid = (cmd & B43legacy_MACCMD_BEACON1_VALID); - cmd &= ~(B43legacy_MACCMD_BEACON0_VALID | B43legacy_MACCMD_BEACON1_VALID); - - if (!beacon0_valid) { - if (!wl->beacon0_uploaded) { - b43legacy_write_beacon_template(dev, 0x68, - B43legacy_SHM_SH_BTL0, - B43legacy_CCK_RATE_1MB); - b43legacy_write_probe_resp_template(dev, 0x268, - B43legacy_SHM_SH_PRTLEN, - &__b43legacy_ratetable[3]); - wl->beacon0_uploaded = 1; - } - cmd |= B43legacy_MACCMD_BEACON0_VALID; - } else if (!beacon1_valid) { - if (!wl->beacon1_uploaded) { - b43legacy_write_beacon_template(dev, 0x468, - B43legacy_SHM_SH_BTL1, - B43legacy_CCK_RATE_1MB); - wl->beacon1_uploaded = 1; - } - cmd |= B43legacy_MACCMD_BEACON1_VALID; - } - b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd); -} - static void handle_irq_ucode_debug(struct b43legacy_wldev *dev) { } @@ -3429,6 +3494,9 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) memset(wl->bssid, 0, ETH_ALEN); memset(wl->mac_addr, 0, ETH_ALEN); wl->filter_flags = 0; + wl->beacon0_uploaded = 0; + wl->beacon1_uploaded = 0; + wl->beacon_templates_virgin = 1; mutex_lock(&wl->mutex); diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 12fca99f7578..b8e39dd06e99 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -274,7 +274,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, /* PHY TX Control word */ if (rate_ofdm) - phy_ctl |= B43legacy_TX4_PHY_OFDM; + phy_ctl |= B43legacy_TX4_PHY_ENC_OFDM; if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL; switch (info->antenna_sel_tx) { diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h index 62e09d02788f..91633087a20b 100644 --- a/drivers/net/wireless/b43legacy/xmit.h +++ b/drivers/net/wireless/b43legacy/xmit.h @@ -67,7 +67,9 @@ struct b43legacy_txhdr_fw3 { #define B43legacy_TX4_EFT_RTSFBOFDM 0x0010 /* RTS/CTS fallback rate type */ /* PHY TX control word */ -#define B43legacy_TX4_PHY_OFDM 0x0001 /* Data frame rate type */ +#define B43legacy_TX4_PHY_ENC 0x0003 /* Data frame encoding */ +#define B43legacy_TX4_PHY_ENC_CCK 0x0000 /* CCK */ +#define B43legacy_TX4_PHY_ENC_OFDM 0x0001 /* Data frame rate type */ #define B43legacy_TX4_PHY_SHORTPRMBL 0x0010 /* Use short preamble */ #define B43legacy_TX4_PHY_ANT 0x03C0 /* Antenna selection */ #define B43legacy_TX4_PHY_ANT0 0x0000 /* Use antenna 0 */ -- GitLab From a89bff9a78b2bf51e21a961b473b5be94b22f12e Mon Sep 17 00:00:00 2001 From: Steven Luo Date: Sun, 12 Apr 2009 02:57:54 -0700 Subject: [PATCH 0605/6080] ath9k: reset after PCI FATAL/PERR interrupts ath9k_hw_getisr() doesn't appear to set anything in the status mask for PCI FATAL or PERR interrupts (AR_INTR_SYNC_HOST1_FATAL/PERR), which the open-source HAL seems to do. This means that the card isn't reset after these interrupts. This patch seems to fix a problem where the wireless drops out with an "ath9k: received PCI FATAL interrupt" in dmesg after some time; the hardware is an AR5416 in an ASUS WL-500W running 2.6.28.7 (OpenWRT) and compat-wireless 2009-03-31. Signed-off-by: Steven Luo Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 24299e65fdcf..9cb85b0e9851 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2976,6 +2976,7 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) DPRINTF(ah->ah_sc, ATH_DBG_ANY, "received PCI PERR interrupt\n"); } + *masked |= ATH9K_INT_FATAL; } if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, -- GitLab From d2f5b3a6778ae86fd93cb01ccac16aa0b079e441 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:25 +0530 Subject: [PATCH 0606/6080] ath9k: Handle ASPM properly for RFKILL Radio enable/disable have to handle ASPM state properly. This patch fixes it. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 8b6a7ea4e59b..1a9bf7ece4a5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1089,10 +1089,10 @@ void ath_radio_enable(struct ath_softc *sc) int r; ath9k_ps_wakeup(sc); - spin_lock_bh(&sc->sc_resetlock); + ath9k_hw_configpcipowersave(ah, 0); + spin_lock_bh(&sc->sc_resetlock); r = ath9k_hw_reset(ah, ah->curchan, false); - if (r) { DPRINTF(sc, ATH_DBG_FATAL, "Unable to reset channel %u (%uMhz) ", @@ -1154,6 +1154,7 @@ void ath_radio_disable(struct ath_softc *sc) spin_unlock_bh(&sc->sc_resetlock); ath9k_hw_phy_disable(ah); + ath9k_hw_configpcipowersave(ah, 1); ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); ath9k_ps_restore(sc); } -- GitLab From 675902ef822c114c0dac17ed10eed43eb8f5c9ec Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:34 +0530 Subject: [PATCH 0607/6080] ath9k: Fix memleak on TX DMA failure The driver-specific region has to be freed in case of a DMA mapping failure. Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 628b780d8844..faf2cab49ea3 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1572,8 +1572,9 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, skb->len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { bf->bf_mpdu = NULL; - DPRINTF(sc, ATH_DBG_CONFIG, - "dma_mapping_error() on TX\n"); + kfree(tx_info_priv); + tx_info->rate_driver_data[0] = NULL; + DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error() on TX\n"); return -ENOMEM; } -- GitLab From 9c07a7777f44c7e39accec5ad8c4293d6a9b2a47 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:36 +0530 Subject: [PATCH 0608/6080] ath9k: Fix bug in scan termination A full HW reset needs to be done on termination of a scan run. Not setting SC_OP_FULL_RESET resulted in doing a fast channel change. Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1a9bf7ece4a5..b2d129f50339 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -2749,6 +2749,7 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) mutex_lock(&sc->mutex); aphy->state = ATH_WIPHY_ACTIVE; sc->sc_flags &= ~SC_OP_SCANNING; + sc->sc_flags |= SC_OP_FULL_RESET; mutex_unlock(&sc->mutex); } -- GitLab From 822b0dfc135cf205379ea62aae7a5b393811b238 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:38 +0530 Subject: [PATCH 0609/6080] ath9k: Remove unused channel flags Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 5c4127e6c1c6..7e37570608bc 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -266,13 +266,6 @@ enum ath9k_int { #define CHANNEL_HT40PLUS 0x20000 #define CHANNEL_HT40MINUS 0x40000 -#define CHANNEL_INTERFERENCE 0x01 -#define CHANNEL_DFS 0x02 -#define CHANNEL_4MS_LIMIT 0x04 -#define CHANNEL_DFS_CLEAR 0x08 -#define CHANNEL_DISALLOW_ADHOC 0x10 -#define CHANNEL_PER_11D_ADHOC 0x20 - #define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM) #define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK) #define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM) @@ -303,10 +296,6 @@ struct ath9k_channel { int16_t rawNoiseFloor; }; -#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \ - (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \ - (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \ - (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS)) #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \ (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \ @@ -314,7 +303,6 @@ struct ath9k_channel { #define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0) #define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0) #define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) -#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0) #define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) #define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) #define IS_CHAN_A_5MHZ_SPACED(_c) \ -- GitLab From db2f63f60a087ed29ae04310c1076c61f77a5d20 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:41 +0530 Subject: [PATCH 0610/6080] ath9k: Fix bug in checking HT flag The operating HT mode is stored in chanmode and not channelFlags. Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index e2d62e97131c..d0b675562d40 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -883,7 +883,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) { REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); - if (chan->channelFlags & CHANNEL_HT20) { + if (IS_CHAN_HT20(chan)) { REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, -- GitLab From a451aa66dcb14efcb7addf1d8edcac8df76a97b6 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:43 +0530 Subject: [PATCH 0611/6080] ath9k: Fix bug in determining calibration support ADC gain calibration has to be done for all non 2GHZ-HT20 channels. Regression from "ath9k: use ieee80211_conf on ath9k_hw_iscal_supported()" Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index d0b675562d40..3195c0b9a6a7 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -284,8 +284,8 @@ static bool ath9k_hw_iscal_supported(struct ath_hw *ah, return true; case ADC_GAIN_CAL: case ADC_DC_CAL: - if (conf->channel->band == IEEE80211_BAND_5GHZ && - conf_is_ht20(conf)) + if (!(conf->channel->band == IEEE80211_BAND_2GHZ && + conf_is_ht20(conf))) return true; break; } -- GitLab From 415f738ecf41b427921b503ecfd427e26f89dc23 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:46 +0530 Subject: [PATCH 0612/6080] ath9k: Initialize ANI timers The various ANI timers have to be initialized properly when starting the calibration timer. Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index b2d129f50339..9564b73ded51 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -407,6 +407,18 @@ set_timer: mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); } +static void ath_start_ani(struct ath_softc *sc) +{ + unsigned long timestamp = jiffies_to_msecs(jiffies); + + sc->ani.longcal_timer = timestamp; + sc->ani.shortcal_timer = timestamp; + sc->ani.checkani_timer = timestamp; + + mod_timer(&sc->ani.timer, + jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); +} + /* * Update tx/rx chainmask. For legacy association, * hard code chainmask to 1x1, for 11n association, use @@ -911,9 +923,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER; - /* Start ANI */ - mod_timer(&sc->ani.timer, - jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); + ath_start_ani(sc); } else { DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n"); sc->curaid = 0; @@ -2239,12 +2249,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); - if (conf->type == NL80211_IFTYPE_AP) { - /* TODO: is this a suitable place to start ANI for AP mode? */ - /* Start ANI */ - mod_timer(&sc->ani.timer, - jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); - } + if (conf->type == NL80211_IFTYPE_AP) + ath_start_ani(sc); out: mutex_unlock(&sc->mutex); -- GitLab From 379f04407c92d84f2506385b66fb9fc89ecd96c3 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:48 +0530 Subject: [PATCH 0613/6080] ath9k: Cleanup calibration interface This patch cleans up the functions dealing with calibration, using proper return values. ath9k_hw_per_calibration(), ath9k_hw_calibrate now return bool values instead of setting error values in the function arguments. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 27 +++++++++++----------- drivers/net/wireless/ath/ath9k/calib.h | 3 +-- drivers/net/wireless/ath/ath9k/main.c | 32 ++++++++------------------ 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 3195c0b9a6a7..a0661bb96723 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -238,13 +238,12 @@ static void ath9k_hw_reset_calibration(struct ath_hw *ah, ah->cal_samples = 0; } -static void ath9k_hw_per_calibration(struct ath_hw *ah, +static bool ath9k_hw_per_calibration(struct ath_hw *ah, struct ath9k_channel *ichan, u8 rxchainmask, - struct hal_cal_list *currCal, - bool *isCalDone) + struct hal_cal_list *currCal) { - *isCalDone = false; + bool iscaldone = false; if (currCal->calState == CAL_RUNNING) { if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) & @@ -263,7 +262,7 @@ static void ath9k_hw_per_calibration(struct ath_hw *ah, currCal->calData->calPostProc(ah, numChains); ichan->CalValid |= currCal->calData->calType; currCal->calState = CAL_DONE; - *isCalDone = true; + iscaldone = true; } else { ath9k_hw_setup_calibration(ah, currCal); } @@ -271,6 +270,8 @@ static void ath9k_hw_per_calibration(struct ath_hw *ah, } else if (!(ichan->CalValid & currCal->calData->calType)) { ath9k_hw_reset_calibration(ah, currCal); } + + return iscaldone; } /* Assumes you are talking about the currently configured channel */ @@ -841,23 +842,21 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah) } bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, - u8 rxchainmask, bool longcal, - bool *isCalDone) + u8 rxchainmask, bool longcal) { + bool iscaldone = true; struct hal_cal_list *currCal = ah->cal_list_curr; - *isCalDone = true; - if (currCal && (currCal->calState == CAL_RUNNING || currCal->calState == CAL_WAITING)) { - ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal, - isCalDone); - if (*isCalDone) { + iscaldone = ath9k_hw_per_calibration(ah, chan, + rxchainmask, currCal); + if (iscaldone) { ah->cal_list_curr = currCal = currCal->calNext; if (currCal->calState == CAL_WAITING) { - *isCalDone = false; + iscaldone = false; ath9k_hw_reset_calibration(ah, currCal); } } @@ -877,7 +876,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, chan->channelFlags &= ~CHANNEL_CW_INT; } - return true; + return iscaldone; } static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 1c74bd50700d..ac71ed966a1b 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -116,8 +116,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah, void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah); s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, - u8 rxchainmask, bool longcal, - bool *isCalDone); + u8 rxchainmask, bool longcal); bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9564b73ded51..8bf2bf36fd6d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -367,28 +367,16 @@ static void ath_ani_calibrate(unsigned long data) /* Perform calibration if necessary */ if (longcal || shortcal) { - bool iscaldone = false; - - if (ath9k_hw_calibrate(ah, ah->curchan, - sc->rx_chainmask, longcal, - &iscaldone)) { - if (longcal) - sc->ani.noise_floor = - ath9k_hw_getchan_noise(ah, - ah->curchan); - - DPRINTF(sc, ATH_DBG_ANI, - "calibrate chan %u/%x nf: %d\n", - ah->curchan->channel, - ah->curchan->channelFlags, - sc->ani.noise_floor); - } else { - DPRINTF(sc, ATH_DBG_ANY, - "calibrate chan %u/%x failed\n", - ah->curchan->channel, - ah->curchan->channelFlags); - } - sc->ani.caldone = iscaldone; + sc->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan, + sc->rx_chainmask, longcal); + + if (longcal) + sc->ani.noise_floor = ath9k_hw_getchan_noise(ah, + ah->curchan); + + DPRINTF(sc, ATH_DBG_ANI," calibrate chan %u/%x nf: %d\n", + ah->curchan->channel, ah->curchan->channelFlags, + sc->ani.noise_floor); } } -- GitLab From cbfe946860ffc718c5d99a6b740e33ac95fe8b8d Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:56 +0530 Subject: [PATCH 0614/6080] ath9k: Use a consistent naming convention This patch replaces old 'hal_' prefixes with 'ath9k_'. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 28 ++++++++++++------------ drivers/net/wireless/ath/ath9k/calib.h | 30 +++++++++++++------------- drivers/net/wireless/ath/ath9k/hw.h | 16 +++++++------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index a0661bb96723..67375adf23c0 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -186,7 +186,7 @@ static bool getNoiseFloorThresh(struct ath_hw *ah, } static void ath9k_hw_setup_calibration(struct ath_hw *ah, - struct hal_cal_list *currCal) + struct ath9k_cal_list *currCal) { REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, @@ -220,7 +220,7 @@ static void ath9k_hw_setup_calibration(struct ath_hw *ah, } static void ath9k_hw_reset_calibration(struct ath_hw *ah, - struct hal_cal_list *currCal) + struct ath9k_cal_list *currCal) { int i; @@ -241,7 +241,7 @@ static void ath9k_hw_reset_calibration(struct ath_hw *ah, static bool ath9k_hw_per_calibration(struct ath_hw *ah, struct ath9k_channel *ichan, u8 rxchainmask, - struct hal_cal_list *currCal) + struct ath9k_cal_list *currCal) { bool iscaldone = false; @@ -276,7 +276,7 @@ static bool ath9k_hw_per_calibration(struct ath_hw *ah, /* Assumes you are talking about the currently configured channel */ static bool ath9k_hw_iscal_supported(struct ath_hw *ah, - enum hal_cal_types calType) + enum ath9k_cal_types calType) { struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; @@ -499,7 +499,7 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) { u32 iOddMeasOffset, iEvenMeasOffset, val, i; int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; - const struct hal_percal_data *calData = + const struct ath9k_percal_data *calData = ah->cal_list_curr->calData; u32 numSamples = (1 << (calData->calCountMax + 5)) * calData->calNumSamples; @@ -556,7 +556,7 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) bool ath9k_hw_reset_calvalid(struct ath_hw *ah) { struct ieee80211_conf *conf = &ah->ah_sc->hw->conf; - struct hal_cal_list *currCal = ah->cal_list_curr; + struct ath9k_cal_list *currCal = ah->cal_list_curr; if (!ah->curchan) return true; @@ -845,7 +845,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, u8 rxchainmask, bool longcal) { bool iscaldone = true; - struct hal_cal_list *currCal = ah->cal_list_curr; + struct ath9k_cal_list *currCal = ah->cal_list_curr; if (currCal && (currCal->calState == CAL_RUNNING || @@ -1008,49 +1008,49 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, return true; } -const struct hal_percal_data iq_cal_multi_sample = { +const struct ath9k_percal_data iq_cal_multi_sample = { IQ_MISMATCH_CAL, MAX_CAL_SAMPLES, PER_MIN_LOG_COUNT, ath9k_hw_iqcal_collect, ath9k_hw_iqcalibrate }; -const struct hal_percal_data iq_cal_single_sample = { +const struct ath9k_percal_data iq_cal_single_sample = { IQ_MISMATCH_CAL, MIN_CAL_SAMPLES, PER_MAX_LOG_COUNT, ath9k_hw_iqcal_collect, ath9k_hw_iqcalibrate }; -const struct hal_percal_data adc_gain_cal_multi_sample = { +const struct ath9k_percal_data adc_gain_cal_multi_sample = { ADC_GAIN_CAL, MAX_CAL_SAMPLES, PER_MIN_LOG_COUNT, ath9k_hw_adc_gaincal_collect, ath9k_hw_adc_gaincal_calibrate }; -const struct hal_percal_data adc_gain_cal_single_sample = { +const struct ath9k_percal_data adc_gain_cal_single_sample = { ADC_GAIN_CAL, MIN_CAL_SAMPLES, PER_MAX_LOG_COUNT, ath9k_hw_adc_gaincal_collect, ath9k_hw_adc_gaincal_calibrate }; -const struct hal_percal_data adc_dc_cal_multi_sample = { +const struct ath9k_percal_data adc_dc_cal_multi_sample = { ADC_DC_CAL, MAX_CAL_SAMPLES, PER_MIN_LOG_COUNT, ath9k_hw_adc_dccal_collect, ath9k_hw_adc_dccal_calibrate }; -const struct hal_percal_data adc_dc_cal_single_sample = { +const struct ath9k_percal_data adc_dc_cal_single_sample = { ADC_DC_CAL, MIN_CAL_SAMPLES, PER_MAX_LOG_COUNT, ath9k_hw_adc_dccal_collect, ath9k_hw_adc_dccal_calibrate }; -const struct hal_percal_data adc_init_dc_cal = { +const struct ath9k_percal_data adc_init_dc_cal = { ADC_DC_INIT_CAL, MIN_CAL_SAMPLES, INIT_LOG_COUNT, diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index ac71ed966a1b..fe5367f14148 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -17,13 +17,13 @@ #ifndef CALIB_H #define CALIB_H -extern const struct hal_percal_data iq_cal_multi_sample; -extern const struct hal_percal_data iq_cal_single_sample; -extern const struct hal_percal_data adc_gain_cal_multi_sample; -extern const struct hal_percal_data adc_gain_cal_single_sample; -extern const struct hal_percal_data adc_dc_cal_multi_sample; -extern const struct hal_percal_data adc_dc_cal_single_sample; -extern const struct hal_percal_data adc_init_dc_cal; +extern const struct ath9k_percal_data iq_cal_multi_sample; +extern const struct ath9k_percal_data iq_cal_single_sample; +extern const struct ath9k_percal_data adc_gain_cal_multi_sample; +extern const struct ath9k_percal_data adc_gain_cal_single_sample; +extern const struct ath9k_percal_data adc_dc_cal_multi_sample; +extern const struct ath9k_percal_data adc_dc_cal_single_sample; +extern const struct ath9k_percal_data adc_init_dc_cal; #define AR_PHY_CCA_MAX_GOOD_VALUE -85 #define AR_PHY_CCA_MAX_HIGH_VALUE -62 @@ -67,14 +67,14 @@ struct ar5416IniArray { } \ } while (0) -enum hal_cal_types { +enum ath9k_cal_types { ADC_DC_INIT_CAL = 0x1, ADC_GAIN_CAL = 0x2, ADC_DC_CAL = 0x4, IQ_MISMATCH_CAL = 0x8 }; -enum hal_cal_state { +enum ath9k_cal_state { CAL_INACTIVE, CAL_WAITING, CAL_RUNNING, @@ -87,18 +87,18 @@ enum hal_cal_state { #define PER_MIN_LOG_COUNT 2 #define PER_MAX_LOG_COUNT 10 -struct hal_percal_data { - enum hal_cal_types calType; +struct ath9k_percal_data { + enum ath9k_cal_types calType; u32 calNumSamples; u32 calCountMax; void (*calCollect) (struct ath_hw *); void (*calPostProc) (struct ath_hw *, u8); }; -struct hal_cal_list { - const struct hal_percal_data *calData; - enum hal_cal_state calState; - struct hal_cal_list *calNext; +struct ath9k_cal_list { + const struct ath9k_percal_data *calData; + enum ath9k_cal_state calState; + struct ath9k_cal_list *calNext; }; struct ath9k_nfcal_hist { diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 7e37570608bc..ab3412672e36 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -436,14 +436,14 @@ struct ath_hw { enum ath9k_ant_setting diversity_control; /* Calibration */ - enum hal_cal_types supp_cals; - struct hal_cal_list iq_caldata; - struct hal_cal_list adcgain_caldata; - struct hal_cal_list adcdc_calinitdata; - struct hal_cal_list adcdc_caldata; - struct hal_cal_list *cal_list; - struct hal_cal_list *cal_list_last; - struct hal_cal_list *cal_list_curr; + enum ath9k_cal_types supp_cals; + struct ath9k_cal_list iq_caldata; + struct ath9k_cal_list adcgain_caldata; + struct ath9k_cal_list adcdc_calinitdata; + struct ath9k_cal_list adcdc_caldata; + struct ath9k_cal_list *cal_list; + struct ath9k_cal_list *cal_list_last; + struct ath9k_cal_list *cal_list_curr; #define totalPowerMeasI meas0.unsign #define totalPowerMeasQ meas1.unsign #define totalIqCorrMeas meas2.sign -- GitLab From 04d19ddd254b404703151ab25aa5041e50ff40f7 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:56:59 +0530 Subject: [PATCH 0615/6080] ath9k: Fix bug in calibration initialization This patch fixes a bug in ath9k_hw_init_cal() where the wrong calibration was being done for non-AR9285 chipsets. Also add a few helpful comments. Cc: stable@kernel.org Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 61 ++++++++++---------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 67375adf23c0..08f690279789 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -918,83 +918,66 @@ static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) return true; } -bool ath9k_hw_init_cal(struct ath_hw *ah, - struct ath9k_channel *chan) +bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) { if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) { if (!ar9285_clc(ah, chan)) return false; - } else if (AR_SREV_9280_10_OR_LATER(ah)) { - REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); - REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); - REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); + } else { + if (AR_SREV_9280_10_OR_LATER(ah)) { + REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); + REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); + } - /* Kick off the cal */ + /* Calibrate the AGC */ REG_WRITE(ah, AR_PHY_AGC_CONTROL, - REG_READ(ah, AR_PHY_AGC_CONTROL) | - AR_PHY_AGC_CONTROL_CAL); + REG_READ(ah, AR_PHY_AGC_CONTROL) | + AR_PHY_AGC_CONTROL_CAL); - if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, - AR_PHY_AGC_CONTROL_CAL, 0, - AH_WAIT_TIMEOUT)) { + /* Poll for offset calibration complete */ + if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, + 0, AH_WAIT_TIMEOUT)) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration failed to complete in 1ms; " "noisy environment?\n"); return false; } - REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); - REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); - REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); - } - - /* Calibrate the AGC */ - REG_WRITE(ah, AR_PHY_AGC_CONTROL, - REG_READ(ah, AR_PHY_AGC_CONTROL) | - AR_PHY_AGC_CONTROL_CAL); - - if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, - 0, AH_WAIT_TIMEOUT)) { - DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "offset calibration failed to complete in 1ms; " - "noisy environment?\n"); - return false; - } - - if (AR_SREV_9280_10_OR_LATER(ah)) { - REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); - REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); + if (AR_SREV_9280_10_OR_LATER(ah)) { + REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); + REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); + } } /* Do PA Calibration */ if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah)) ath9k_hw_9285_pa_cal(ah); - /* Do NF Calibration */ + /* Do NF Calibration after DC offset and other calibrations */ REG_WRITE(ah, AR_PHY_AGC_CONTROL, - REG_READ(ah, AR_PHY_AGC_CONTROL) | - AR_PHY_AGC_CONTROL_NF); + REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF); ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; + /* Enable IQ, ADC Gain and ADC DC offset CALs */ if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) { INIT_CAL(&ah->adcgain_caldata); INSERT_CAL(ah, &ah->adcgain_caldata); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "enabling ADC Gain Calibration.\n"); + "enabling ADC Gain Calibration.\n"); } if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) { INIT_CAL(&ah->adcdc_caldata); INSERT_CAL(ah, &ah->adcdc_caldata); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "enabling ADC DC Calibration.\n"); + "enabling ADC DC Calibration.\n"); } if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { INIT_CAL(&ah->iq_caldata); INSERT_CAL(ah, &ah->iq_caldata); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, - "enabling IQ Calibration.\n"); + "enabling IQ Calibration.\n"); } ah->cal_list_curr = ah->cal_list; -- GitLab From 386aeacfa8912e1accffc47e30ffe0c0ecfe71e5 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 13 Apr 2009 21:57:01 +0530 Subject: [PATCH 0616/6080] ath9k: Remove CHANNEL_CW_INT handling in ath9k_hw_calibrate It is already handled properly in ath9k_hw_getnf. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/calib.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 08f690279789..a197041d76b5 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -871,9 +871,6 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_getnf(ah, chan); ath9k_hw_loadnf(ah, ah->curchan); ath9k_hw_start_nfcal(ah); - - if (chan->channelFlags & CHANNEL_CW_INT) - chan->channelFlags &= ~CHANNEL_CW_INT; } return iscaldone; -- GitLab From 06bfd0d3dbe965de4f60079955cca19d7e853c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Stefanik?= Date: Mon, 13 Apr 2009 21:54:27 +0200 Subject: [PATCH 0617/6080] rtl8187: Remove the "8187B chip detected" message when probing RTL8187B cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This message appears to be nothing more than a leftover of the experimental-8187B era. Also, we print the HW type in the hwaddr line, making this message reduntant. And it's definitely not important enough to be a KERN_WARNING. Signed-off-by: Gábor Stefanik Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index fd81884b9c7d..d6d4001812a7 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -1470,9 +1470,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, (*channel++).hw_value = txpwr >> 8; } - if (priv->is_rtl8187b) - printk(KERN_WARNING "rtl8187: 8187B chip detected.\n"); - /* * XXX: Once this driver supports anything that requires * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ. -- GitLab From a1c555802a62c845520d2486d783c9bb1d5e68a9 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 14 Apr 2009 22:11:20 +0200 Subject: [PATCH 0618/6080] ath: add module information This patch adds licensing, author information and a description to the module. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/Makefile | 3 +-- drivers/net/wireless/ath/main.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 drivers/net/wireless/ath/main.c diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index a005b919233f..4bb0132ada37 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile @@ -3,5 +3,4 @@ obj-$(CONFIG_ATH9K) += ath9k/ obj-$(CONFIG_AR9170_USB) += ar9170/ obj-$(CONFIG_ATH_COMMON) += ath.o -ath-objs := regd.o - +ath-objs := main.o regd.o diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c new file mode 100644 index 000000000000..9949b11cb151 --- /dev/null +++ b/drivers/net/wireless/ath/main.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +MODULE_AUTHOR("Atheros Communications"); +MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards."); +MODULE_LICENSE("Dual BSD/GPL"); -- GitLab From f2753ddbadb0873a98421415882318251bbd9eaa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 14 Apr 2009 10:09:24 +0200 Subject: [PATCH 0619/6080] mac80211: add hardware restart function Some hardware defects may require the hardware to be re-initialised completely from scratch. Drivers would need much information (for instance the current MAC address, crypto keys, beaconing information, etc.) stored duplicated from mac80211 to be able to do this, so let mac80211 help them. The new ieee80211_restart_hw() function requires the same code as resuming, so move that code into a new ieee80211_reconfig() function in util.c and leave only the suspend code in pm.c. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 14 +++++ net/mac80211/ieee80211_i.h | 13 +++- net/mac80211/main.c | 24 ++++++++ net/mac80211/pm.c | 110 ++-------------------------------- net/mac80211/util.c | 118 +++++++++++++++++++++++++++++++++++++ 5 files changed, 172 insertions(+), 107 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 2c6f976831b5..a593bedcfeda 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1575,6 +1575,20 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw); */ void ieee80211_free_hw(struct ieee80211_hw *hw); +/** + * ieee80211_restart_hw - restart hardware completely + * + * Call this function when the hardware was restarted for some reason + * (hardware error, ...) and the driver is unable to restore its state + * by itself. mac80211 assumes that at this point the driver/hardware + * is completely uninitialised and stopped, it starts the process by + * calling the ->start() operation. The driver will need to reset all + * internal state that it has prior to calling this function. + * + * @hw: the hardware to restart + */ +void ieee80211_restart_hw(struct ieee80211_hw *hw); + /* trick to avoid symbol clashes with the ieee80211 subsystem */ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_rx_status *status); diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index cb80a80504e6..13d6f890ced4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -748,6 +748,8 @@ struct ieee80211_local { int user_power_level; /* in dBm */ int power_constr_level; /* in dBm */ + struct work_struct restart_work; + #ifdef CONFIG_MAC80211_DEBUGFS struct local_debugfsdentries { struct dentry *rcdir; @@ -1036,15 +1038,22 @@ void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, u16 capab_info, u8 *pwr_constr_elem, u8 pwr_constr_elem_len); -/* Suspend/resume */ +/* Suspend/resume and hw reconfiguration */ +int ieee80211_reconfig(struct ieee80211_local *local); + #ifdef CONFIG_PM int __ieee80211_suspend(struct ieee80211_hw *hw); -int __ieee80211_resume(struct ieee80211_hw *hw); + +static inline int __ieee80211_resume(struct ieee80211_hw *hw) +{ + return ieee80211_reconfig(hw_to_local(hw)); +} #else static inline int __ieee80211_suspend(struct ieee80211_hw *hw) { return 0; } + static inline int __ieee80211_resume(struct ieee80211_hw *hw) { return 0; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c1145be72da4..80c0e28bf549 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -696,6 +696,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) } EXPORT_SYMBOL(ieee80211_tx_status); +static void ieee80211_restart_work(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, restart_work); + + rtnl_lock(); + ieee80211_reconfig(local); + rtnl_unlock(); +} + +void ieee80211_restart_hw(struct ieee80211_hw *hw) +{ + struct ieee80211_local *local = hw_to_local(hw); + + /* use this reason, __ieee80211_resume will unblock it */ + ieee80211_stop_queues_by_reason(hw, + IEEE80211_QUEUE_STOP_REASON_SUSPEND); + + schedule_work(&local->restart_work); +} +EXPORT_SYMBOL(ieee80211_restart_hw); + struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, const struct ieee80211_ops *ops) { @@ -768,6 +790,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); + INIT_WORK(&local->restart_work, ieee80211_restart_work); + INIT_WORK(&local->dynamic_ps_enable_work, ieee80211_dynamic_ps_enable_work); INIT_WORK(&local->dynamic_ps_disable_work, diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 2b4c95cd9daf..b38986c9deef 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -72,108 +72,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) return 0; } -int __ieee80211_resume(struct ieee80211_hw *hw) -{ - struct ieee80211_local *local = hw_to_local(hw); - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_init_conf conf; - struct sta_info *sta; - unsigned long flags; - int res; - - /* restart hardware */ - if (local->open_count) { - res = local->ops->start(hw); - - ieee80211_led_radio(local, hw->conf.radio_enabled); - } - - /* add interfaces */ - list_for_each_entry(sdata, &local->interfaces, list) { - if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_MONITOR && - netif_running(sdata->dev)) { - conf.vif = &sdata->vif; - conf.type = sdata->vif.type; - conf.mac_addr = sdata->dev->dev_addr; - res = local->ops->add_interface(hw, &conf); - } - } - - /* add STAs back */ - if (local->ops->sta_notify) { - spin_lock_irqsave(&local->sta_lock, flags); - list_for_each_entry(sta, &local->sta_list, list) { - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - sdata = container_of(sdata->bss, - struct ieee80211_sub_if_data, - u.ap); - - local->ops->sta_notify(hw, &sdata->vif, - STA_NOTIFY_ADD, &sta->sta); - } - spin_unlock_irqrestore(&local->sta_lock, flags); - } - - /* Clear Suspend state so that ADDBA requests can be processed */ - - rcu_read_lock(); - - if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { - list_for_each_entry_rcu(sta, &local->sta_list, list) { - clear_sta_flags(sta, WLAN_STA_SUSPEND); - } - } - - rcu_read_unlock(); - - /* setup RTS threshold */ - if (local->ops->set_rts_threshold) - local->ops->set_rts_threshold(hw, local->rts_threshold); - - /* reconfigure hardware */ - ieee80211_hw_config(local, ~0); - - netif_addr_lock_bh(local->mdev); - ieee80211_configure_filter(local); - netif_addr_unlock_bh(local->mdev); - - /* Finally also reconfigure all the BSS information */ - list_for_each_entry(sdata, &local->interfaces, list) { - u32 changed = ~0; - if (!netif_running(sdata->dev)) - continue; - switch (sdata->vif.type) { - case NL80211_IFTYPE_STATION: - /* disable beacon change bits */ - changed &= ~IEEE80211_IFCC_BEACON; - /* fall through */ - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_MESH_POINT: - WARN_ON(ieee80211_if_config(sdata, changed)); - ieee80211_bss_info_change_notify(sdata, ~0); - break; - case NL80211_IFTYPE_WDS: - break; - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_MONITOR: - /* ignore virtual */ - break; - case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: - WARN_ON(1); - break; - } - } - - /* add back keys */ - list_for_each_entry(sdata, &local->interfaces, list) - if (netif_running(sdata->dev)) - ieee80211_enable_keys(sdata); - - ieee80211_wake_queues_by_reason(hw, - IEEE80211_QUEUE_STOP_REASON_SUSPEND); - - return 0; -} +/* + * __ieee80211_resume() is a static inline which just calls + * ieee80211_reconfig(), which is also needed for hardware + * hang/firmware failure/etc. recovery. + */ diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 1ff83532120f..b361e2acfce9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -28,6 +28,7 @@ #include "rate.h" #include "mesh.h" #include "wme.h" +#include "led.h" /* privid for wiphys to determine whether they belong to us or not */ void *mac80211_wiphy_privid = &mac80211_wiphy_privid; @@ -966,3 +967,120 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local, } return supp_rates; } + +int ieee80211_reconfig(struct ieee80211_local *local) +{ + struct ieee80211_hw *hw = &local->hw; + struct ieee80211_sub_if_data *sdata; + struct ieee80211_if_init_conf conf; + struct sta_info *sta; + unsigned long flags; + int res; + + /* restart hardware */ + if (local->open_count) { + res = local->ops->start(hw); + + ieee80211_led_radio(local, hw->conf.radio_enabled); + } + + /* add interfaces */ + list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && + sdata->vif.type != NL80211_IFTYPE_MONITOR && + netif_running(sdata->dev)) { + conf.vif = &sdata->vif; + conf.type = sdata->vif.type; + conf.mac_addr = sdata->dev->dev_addr; + res = local->ops->add_interface(hw, &conf); + } + } + + /* add STAs back */ + if (local->ops->sta_notify) { + spin_lock_irqsave(&local->sta_lock, flags); + list_for_each_entry(sta, &local->sta_list, list) { + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + sdata = container_of(sdata->bss, + struct ieee80211_sub_if_data, + u.ap); + + local->ops->sta_notify(hw, &sdata->vif, + STA_NOTIFY_ADD, &sta->sta); + } + spin_unlock_irqrestore(&local->sta_lock, flags); + } + + /* Clear Suspend state so that ADDBA requests can be processed */ + + rcu_read_lock(); + + if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { + list_for_each_entry_rcu(sta, &local->sta_list, list) { + clear_sta_flags(sta, WLAN_STA_SUSPEND); + } + } + + rcu_read_unlock(); + + /* setup RTS threshold */ + if (local->ops->set_rts_threshold) + local->ops->set_rts_threshold(hw, local->rts_threshold); + + /* reconfigure hardware */ + ieee80211_hw_config(local, ~0); + + netif_addr_lock_bh(local->mdev); + ieee80211_configure_filter(local); + netif_addr_unlock_bh(local->mdev); + + /* Finally also reconfigure all the BSS information */ + list_for_each_entry(sdata, &local->interfaces, list) { + u32 changed = ~0; + if (!netif_running(sdata->dev)) + continue; + switch (sdata->vif.type) { + case NL80211_IFTYPE_STATION: + /* disable beacon change bits */ + changed &= ~IEEE80211_IFCC_BEACON; + /* fall through */ + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_MESH_POINT: + /* + * Driver's config_interface can fail if rfkill is + * enabled. Accommodate this return code. + * FIXME: When mac80211 has knowledge of rfkill + * state the code below can change back to: + * WARN(ieee80211_if_config(sdata, changed)); + * ieee80211_bss_info_change_notify(sdata, ~0); + */ + if (ieee80211_if_config(sdata, changed)) + printk(KERN_DEBUG "%s: failed to configure interface during resume\n", + sdata->dev->name); + else + ieee80211_bss_info_change_notify(sdata, ~0); + break; + case NL80211_IFTYPE_WDS: + break; + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_MONITOR: + /* ignore virtual */ + break; + case NL80211_IFTYPE_UNSPECIFIED: + case __NL80211_IFTYPE_AFTER_LAST: + WARN_ON(1); + break; + } + } + + /* add back keys */ + list_for_each_entry(sdata, &local->interfaces, list) + if (netif_running(sdata->dev)) + ieee80211_enable_keys(sdata); + + ieee80211_wake_queues_by_reason(hw, + IEEE80211_QUEUE_STOP_REASON_SUSPEND); + + return 0; +} -- GitLab From 882b709230246de3359b04b195ad3e80b93b73ef Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Tue, 14 Apr 2009 16:21:01 +0530 Subject: [PATCH 0620/6080] ath9k: Disable autosleep feature for AR9285 based chipsets. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 9cb85b0e9851..ec2a7a40b00d 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -3377,7 +3377,8 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah) (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) || (ah->hw_version.macVersion == AR_SREV_VERSION_9160) || (ah->hw_version.macVersion == AR_SREV_VERSION_9100) || - (ah->hw_version.macVersion == AR_SREV_VERSION_9280)) + (ah->hw_version.macVersion == AR_SREV_VERSION_9280) || + (ah->hw_version.macVersion == AR_SREV_VERSION_9285)) pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; else pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; -- GitLab From 45f483c00299807a1635d6ee327957b796b60076 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 14 Apr 2009 22:19:29 +0200 Subject: [PATCH 0621/6080] p54: remove module_ stubs Christoph Hellwig pointed out that these stubs are unnecessary. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index b18fc93a8bce..bc1bd72392a4 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -2713,15 +2713,3 @@ void p54_free_common(struct ieee80211_hw *dev) #endif /* CONFIG_P54_LEDS */ } EXPORT_SYMBOL_GPL(p54_free_common); - -static int __init p54_init(void) -{ - return 0; -} - -static void __exit p54_exit(void) -{ -} - -module_init(p54_init); -module_exit(p54_exit); -- GitLab From 77ded01cc25744245c58a369d24e251833e995bd Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Wed, 15 Apr 2009 07:57:32 -0400 Subject: [PATCH 0622/6080] ath5k: fix initvals errors This patch corrects a few errors in the initvals tables to match those in the HAL tables. Namely, remove a couple of repetitions, fix some turbo mode errors, and correct a register for the CCK rate power table. Changes-licensed-under: ISC Signed-off-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/initvals.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c index 61fb621ed20d..18eb5190ce4b 100644 --- a/drivers/net/wireless/ath/ath5k/initvals.c +++ b/drivers/net/wireless/ath/ath5k/initvals.c @@ -537,8 +537,6 @@ static const struct ath5k_ini ar5212_ini_common_start[] = { { AR5K_DCU_TX_FILTER_1(15), 0x00000000 }, { AR5K_DCU_TX_FILTER_CLR, 0x00000000 }, { AR5K_DCU_TX_FILTER_SET, 0x00000000 }, - { AR5K_DCU_TX_FILTER_CLR, 0x00000000 }, - { AR5K_DCU_TX_FILTER_SET, 0x00000000 }, { AR5K_STA_ID1, 0x00000000 }, { AR5K_BSS_ID0, 0x00000000 }, { AR5K_BSS_ID1, 0x00000000 }, @@ -669,7 +667,7 @@ static const struct ath5k_ini ar5212_ini_common_start[] = { /*{ AR5K_PHY(650), 0x000001b5 },*/ { AR5K_PHY(651), 0x00000000 }, { AR5K_PHY_TXPOWER_RATE3, 0x20202020 }, - { AR5K_PHY_TXPOWER_RATE2, 0x20202020 }, + { AR5K_PHY_TXPOWER_RATE4, 0x20202020 }, /*{ AR5K_PHY(655), 0x13c889af },*/ { AR5K_PHY(656), 0x38490a20 }, { AR5K_PHY(657), 0x00007bb6 }, @@ -718,7 +716,7 @@ static const struct ath5k_ini_mode ar5212_ini_mode_start[] = { { AR5K_PHY_SETTLING, { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } }, { AR5K_PHY_AGCCTL, - { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } }, + { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d10 } }, { AR5K_PHY_NF, { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, { AR5K_PHY_WEAK_OFDM_HIGH_THR, @@ -799,7 +797,7 @@ static const struct ath5k_ini_mode rf5112_ini_mode_end[] = { { AR5K_PHY_DESIRED_SIZE, { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, { AR5K_PHY_SIG, - { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } }, + { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7e800d2e } }, { AR5K_PHY_AGCCOARSE, { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } }, { AR5K_PHY_WEAK_OFDM_LOW_THR, -- GitLab From 56d2ac763829d2443075e8266dd00166ee11c80d Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Wed, 15 Apr 2009 07:57:33 -0400 Subject: [PATCH 0623/6080] ath5k: use tasklet_hi_schedule for beacon queue For embedded platforms, beacon transmission can be starved when flooded with data packets. Prioritize beacons by giving the beacon queue the first shot when the isr completes. Changes-licensed-under: 3-Clause-BSD Signed-off-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index ff6d4f839734..ef8523e418e2 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2496,7 +2496,7 @@ ath5k_intr(int irq, void *dev_id) tasklet_schedule(&sc->restq); } else { if (status & AR5K_INT_SWBA) { - tasklet_schedule(&sc->beacontq); + tasklet_hi_schedule(&sc->beacontq); } if (status & AR5K_INT_RXEOL) { /* -- GitLab From 46802a4f07cd2367d584bb1a2e6998d22d4d4f3a Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Wed, 15 Apr 2009 07:57:34 -0400 Subject: [PATCH 0624/6080] ath5k: use bool for modparams Current code uses int types, but both modparams are boolean values. Changes-licensed-under: 3-Clause-BSD Signed-off-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index ef8523e418e2..3bde18f91450 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -61,11 +61,11 @@ static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */ static int modparam_nohwcrypt; -module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); +module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); static int modparam_all_channels; -module_param_named(all_channels, modparam_all_channels, int, 0444); +module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); -- GitLab From c57ca81576e7ca0369ea52c9ac5f35d0f6ca1270 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Wed, 15 Apr 2009 07:57:35 -0400 Subject: [PATCH 0625/6080] ath5k: use rx hw descriptor pointer for self-linked check This patch simplifies the code used to detect when the self-linked DMA buffer is still in use by hardware, by checking the hardware's rxdp register instead of looking at the software buffer list. Signed-off-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 24 ++++-------------------- drivers/net/wireless/ath/ath5k/base.h | 1 - drivers/net/wireless/ath/ath5k/dma.c | 2 -- 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 3bde18f91450..1a6e72fe7be9 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1780,7 +1780,7 @@ ath5k_tasklet_rx(unsigned long data) struct sk_buff *skb, *next_skb; dma_addr_t next_skb_addr; struct ath5k_softc *sc = (void *)data; - struct ath5k_buf *bf, *bf_last; + struct ath5k_buf *bf; struct ath5k_desc *ds; int ret; int hdrlen; @@ -1791,7 +1791,6 @@ ath5k_tasklet_rx(unsigned long data) ATH5K_WARN(sc, "empty rx buf pool\n"); goto unlock; } - bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list); do { rxs.flag = 0; @@ -1800,24 +1799,9 @@ ath5k_tasklet_rx(unsigned long data) skb = bf->skb; ds = bf->desc; - /* - * last buffer must not be freed to ensure proper hardware - * function. When the hardware finishes also a packet next to - * it, we are sure, it doesn't use it anymore and we can go on. - */ - if (bf_last == bf) - bf->flags |= 1; - if (bf->flags) { - struct ath5k_buf *bf_next = list_entry(bf->list.next, - struct ath5k_buf, list); - ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc, - &rs); - if (ret) - break; - bf->flags &= ~1; - /* skip the overwritten one (even status is martian) */ - goto next; - } + /* bail if HW is still using self-linked descriptor */ + if (ath5k_hw_get_rxdp(sc->ah) == bf->daddr) + break; ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs); if (unlikely(ret == -EINPROGRESS)) diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 822956114cd7..852b2c189fd8 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -56,7 +56,6 @@ struct ath5k_buf { struct list_head list; - unsigned int flags; /* rx descriptor flags */ struct ath5k_desc *desc; /* virtual addr of desc */ dma_addr_t daddr; /* physical addr of desc */ struct sk_buff *skb; /* skbuff for buf */ diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index b65b4feb2d28..941b51130a6f 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -80,8 +80,6 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) * ath5k_hw_get_rxdp - Get RX Descriptor's address * * @ah: The &struct ath5k_hw - * - * XXX: Is RXDP read and clear ? */ u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah) { -- GitLab From 26925042b6b105995ee54c6015e95f0caf9632d6 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Wed, 15 Apr 2009 07:57:36 -0400 Subject: [PATCH 0626/6080] ath5k: manipulate rxlink and descriptor address under rxbuf lock Grabbing an ath5k_buf then dropping the lock is racy because the referenced descriptor can be obtained in another thread and released before the buffer is handed to the hardware. Likewise, manipulating sc->rxlink without the lock can lead to having multiple self-linked hardware descriptors. Changes-licensed-under: 3-Clause-BSD Signed-off-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 1a6e72fe7be9..c8c658bfcf9d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1618,9 +1618,8 @@ ath5k_rx_start(struct ath5k_softc *sc) ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n", sc->cachelsz, sc->rxbufsize); - sc->rxlink = NULL; - spin_lock_bh(&sc->rxbuflock); + sc->rxlink = NULL; list_for_each_entry(bf, &sc->rxbuf, list) { ret = ath5k_rxbuf_setup(sc, bf); if (ret != 0) { @@ -1629,9 +1628,9 @@ ath5k_rx_start(struct ath5k_softc *sc) } } bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); + ath5k_hw_set_rxdp(ah, bf->daddr); spin_unlock_bh(&sc->rxbuflock); - ath5k_hw_set_rxdp(ah, bf->daddr); ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ ath5k_mode_setup(sc); /* set filters, etc. */ ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ -- GitLab From 85efc86eb7c6cbb1c8ce8d99b10b948be033fbb9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 13 Apr 2009 21:41:46 -0400 Subject: [PATCH 0627/6080] atheros: fix propagation of bad EEPROM on regulatory init When the EEPROM is not in good condition we cannot continue so we currently bail out but only ath5k is bailing out properly. Both ath9k and ar9170 were proceeding and if a user were to run into this they'd see an obscure panic. Lets propagate the error as intended and make sure we inform the user by lifting the error message from debug to a kernel error. Stable note: You can find a port of this page here: http://bombadil.infradead.org/~mcgrof/patches/ath9k/ath9k-fix-eeprom.patch.txt Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/main.c | 2 ++ drivers/net/wireless/ath/ath9k/main.c | 5 +++-- drivers/net/wireless/ath/regd.c | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 8de0ff9f580b..857416c80199 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -1649,6 +1649,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev) err = ath_regd_init(&ar->regulatory, ar->hw->wiphy, ar9170_reg_notifier); + if (err) + goto err_out; err = ieee80211_register_hw(ar->hw); if (err) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 8bf2bf36fd6d..2398d4f45f28 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1416,8 +1416,9 @@ static int ath_init(u16 devid, struct ath_softc *sc) for (i = 0; i < sc->keymax; i++) ath9k_hw_keyreset(ah, (u16) i); - if (ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy, - ath9k_reg_notifier)) + error = ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy, + ath9k_reg_notifier); + if (error) goto bad; /* default to MONITOR mode */ diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 4b5c851b81ff..526c7f1308db 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -477,7 +477,7 @@ ath_regd_init(struct ath_regulatory *reg, u16 regdmn; if (!ath_regd_is_eeprom_valid(reg)) { - printk(KERN_DEBUG "ath: Invalid EEPROM contents\n"); + printk(KERN_ERR "ath: Invalid EEPROM contents\n"); return -EINVAL; } -- GitLab From fade5db4f227bf59874efd6023f39d345e17e2a4 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 17 Apr 2009 15:14:22 +0200 Subject: [PATCH 0628/6080] p54: deactivate broken powersave function (part 2) This patch deactivates powersave in station mode. It does not work correctly yet, so the code does more harm than good. (I split the original patch and sent part of it for 2.6.30, which didn't have the IEEE80211_HW_BEACON_FILTER flag. -- JWL) Reported-by: Johannes Berg Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index bc1bd72392a4..5368aa33dab8 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -2642,8 +2642,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) skb_queue_head_init(&priv->tx_queue); dev->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_NOISE_DBM | - IEEE80211_HW_BEACON_FILTER; + IEEE80211_HW_NOISE_DBM; dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | -- GitLab From dc7d243d75b906cc964c12caa3b2eebe953a69be Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 24 Mar 2009 21:33:43 +0100 Subject: [PATCH 0629/6080] Add support for CF8381 WiFi card. A detection function was added for identifying CF8381. Signed-off-by: Marek Vasut Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_cs.c | 34 +++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index cedeac6322fe..2a5b083bf9bd 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -273,7 +273,28 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r */ #define IF_CS_PRODUCT_ID 0x0000001C #define IF_CS_CF8385_B1_REV 0x12 +#define IF_CS_CF8381_B3_REV 0x04 +/* + * Used to detect other cards than CF8385 since their revisions of silicon + * doesn't match those from CF8385, eg. CF8381 B3 works with this driver. + */ +#define CF8381_MANFID 0x02db +#define CF8381_CARDID 0x6064 +#define CF8385_MANFID 0x02df +#define CF8385_CARDID 0x8103 + +static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev) +{ + return (p_dev->manf_id == CF8381_MANFID && + p_dev->card_id == CF8381_CARDID); +} + +static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev) +{ + return (p_dev->manf_id == CF8385_MANFID && + p_dev->card_id == CF8385_CARDID); +} /********************************************************************/ /* I/O and interrupt handling */ @@ -757,6 +778,7 @@ static void if_cs_release(struct pcmcia_device *p_dev) static int if_cs_probe(struct pcmcia_device *p_dev) { int ret = -ENOMEM; + unsigned int prod_id; struct lbs_private *priv; struct if_cs_card *card; /* CIS parsing */ @@ -859,7 +881,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev) p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); /* Check if we have a current silicon */ - if (if_cs_read8(card, IF_CS_PRODUCT_ID) < IF_CS_CF8385_B1_REV) { + prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID); + if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) { + lbs_pr_err("old chips like 8381 rev B3 aren't supported\n"); + ret = -ENODEV; + goto out2; + } + + if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) { lbs_pr_err("old chips like 8385 rev B1 aren't supported\n"); ret = -ENODEV; goto out2; @@ -950,7 +979,8 @@ static void if_cs_detach(struct pcmcia_device *p_dev) /********************************************************************/ static struct pcmcia_device_id if_cs_ids[] = { - PCMCIA_DEVICE_MANF_CARD(0x02df, 0x8103), + PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID), + PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID), PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); -- GitLab From 965bedadc01d34027455d5d5b67063ef0209c955 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Apr 2009 13:17:24 +0200 Subject: [PATCH 0630/6080] mac80211: improve powersave implementation When you have multiple virtual interfaces the current implementation requires setting them up properly from userspace, which is undesirable when we want to default to power save mode. Keep track of powersave requested from userspace per managed mode interface, and only enable powersave globally when exactly one managed mode interface is active and has powersave turned on. Second, only start the dynPS timer when PS is turned on, and properly turn it off when PS is turned off. Third, fix the scan_sdata abuse in the dynps code. Finally, also reorder the code and refactor the code that enables PS or the dynps timer instead of having it copied in two places. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 9 +- net/mac80211/iface.c | 4 + net/mac80211/mlme.c | 228 +++++++++++++++++++++++-------------- net/mac80211/scan.c | 2 +- net/mac80211/wext.c | 43 ++----- 5 files changed, 165 insertions(+), 121 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 13d6f890ced4..ff40dd7b523a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -295,6 +295,8 @@ struct ieee80211_if_managed { int auth_tries; /* retries for auth req */ int assoc_tries; /* retries for assoc req */ + bool powersave; /* powersave requested for this iface */ + unsigned long request; unsigned long last_probe; @@ -739,8 +741,12 @@ struct ieee80211_local { int wifi_wme_noack_test; unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ - bool powersave; bool pspolling; + /* + * PS can only be enabled when we have exactly one managed + * interface (and monitors) in PS, this then points there. + */ + struct ieee80211_sub_if_data *ps_sdata; struct work_struct dynamic_ps_enable_work; struct work_struct dynamic_ps_disable_work; struct timer_list dynamic_ps_timer; @@ -932,6 +938,7 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); void ieee80211_send_pspoll(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata); +void ieee80211_recalc_ps(struct ieee80211_local *local); /* IBSS code */ int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 91e8e1bacaaa..6240f76e2a43 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -317,6 +317,8 @@ static int ieee80211_open(struct net_device *dev) ieee80211_set_wmm_default(sdata); } + ieee80211_recalc_ps(local); + /* * ieee80211_sta_work is disabled while network interface * is down. Therefore, some configuration changes may not @@ -572,6 +574,8 @@ static int ieee80211_stop(struct net_device *dev) hw_reconf_flags = 0; } + ieee80211_recalc_ps(local); + /* do after stop to avoid reconfiguring when we stop anyway */ if (hw_reconf_flags) ieee80211_hw_config(local, hw_reconf_flags); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 90267afa8e69..06d9a1d23252 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -446,6 +446,145 @@ void ieee80211_send_pspoll(struct ieee80211_local *local, ieee80211_tx_skb(sdata, skb, 0); } +void ieee80211_send_nullfunc(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + int powersave) +{ + struct sk_buff *skb; + struct ieee80211_hdr *nullfunc; + __le16 fc; + + if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) + return; + + skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); + if (!skb) { + printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc " + "frame\n", sdata->dev->name); + return; + } + skb_reserve(skb, local->hw.extra_tx_headroom); + + nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); + memset(nullfunc, 0, 24); + fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | + IEEE80211_FCTL_TODS); + if (powersave) + fc |= cpu_to_le16(IEEE80211_FCTL_PM); + nullfunc->frame_control = fc; + memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN); + memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); + memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN); + + ieee80211_tx_skb(sdata, skb, 0); +} + +/* powersave */ +static void ieee80211_enable_ps(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_conf *conf = &local->hw.conf; + + if (conf->dynamic_ps_timeout > 0 && + !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) { + mod_timer(&local->dynamic_ps_timer, jiffies + + msecs_to_jiffies(conf->dynamic_ps_timeout)); + } else { + if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) + ieee80211_send_nullfunc(local, sdata, 1); + conf->flags |= IEEE80211_CONF_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); + } +} + +static void ieee80211_change_ps(struct ieee80211_local *local) +{ + struct ieee80211_conf *conf = &local->hw.conf; + + if (local->ps_sdata) { + if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)) + return; + + ieee80211_enable_ps(local, local->ps_sdata); + } else if (conf->flags & IEEE80211_CONF_PS) { + conf->flags &= ~IEEE80211_CONF_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); + del_timer_sync(&local->dynamic_ps_timer); + cancel_work_sync(&local->dynamic_ps_enable_work); + } +} + +/* need to hold RTNL or interface lock */ +void ieee80211_recalc_ps(struct ieee80211_local *local) +{ + struct ieee80211_sub_if_data *sdata, *found = NULL; + int count = 0; + + if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) { + local->ps_sdata = NULL; + return; + } + + list_for_each_entry(sdata, &local->interfaces, list) { + if (!netif_running(sdata->dev)) + continue; + if (sdata->vif.type != NL80211_IFTYPE_STATION) + continue; + found = sdata; + count++; + } + + if (count == 1 && found->u.mgd.powersave) + local->ps_sdata = found; + else + local->ps_sdata = NULL; + + ieee80211_change_ps(local); +} + +void ieee80211_dynamic_ps_disable_work(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, + dynamic_ps_disable_work); + + if (local->hw.conf.flags & IEEE80211_CONF_PS) { + local->hw.conf.flags &= ~IEEE80211_CONF_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); + } + + ieee80211_wake_queues_by_reason(&local->hw, + IEEE80211_QUEUE_STOP_REASON_PS); +} + +void ieee80211_dynamic_ps_enable_work(struct work_struct *work) +{ + struct ieee80211_local *local = + container_of(work, struct ieee80211_local, + dynamic_ps_enable_work); + struct ieee80211_sub_if_data *sdata = local->ps_sdata; + + /* can only happen when PS was just disabled anyway */ + if (!sdata) + return; + + if (local->hw.conf.flags & IEEE80211_CONF_PS) + return; + + if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) + ieee80211_send_nullfunc(local, sdata, 1); + + local->hw.conf.flags |= IEEE80211_CONF_PS; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); +} + +void ieee80211_dynamic_ps_timer(unsigned long data) +{ + struct ieee80211_local *local = (void *) data; + + queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); +} + /* MLME */ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, struct ieee80211_if_managed *ifmgd, @@ -721,19 +860,9 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_info_changed |= BSS_CHANGED_BASIC_RATES; ieee80211_bss_info_change_notify(sdata, bss_info_changed); - if (local->powersave) { - if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) && - local->hw.conf.dynamic_ps_timeout > 0) { - mod_timer(&local->dynamic_ps_timer, jiffies + - msecs_to_jiffies( - local->hw.conf.dynamic_ps_timeout)); - } else { - if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) - ieee80211_send_nullfunc(local, sdata, 1); - conf->flags |= IEEE80211_CONF_PS; - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); - } - } + /* will be same as sdata */ + if (local->ps_sdata) + ieee80211_enable_ps(local, sdata); netif_tx_start_all_queues(sdata->dev); netif_carrier_on(sdata->dev); @@ -2195,76 +2324,3 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) ieee80211_restart_sta_timer(sdata); rcu_read_unlock(); } - -void ieee80211_dynamic_ps_disable_work(struct work_struct *work) -{ - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, - dynamic_ps_disable_work); - - if (local->hw.conf.flags & IEEE80211_CONF_PS) { - local->hw.conf.flags &= ~IEEE80211_CONF_PS; - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); - } - - ieee80211_wake_queues_by_reason(&local->hw, - IEEE80211_QUEUE_STOP_REASON_PS); -} - -void ieee80211_dynamic_ps_enable_work(struct work_struct *work) -{ - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, - dynamic_ps_enable_work); - /* XXX: using scan_sdata is completely broken! */ - struct ieee80211_sub_if_data *sdata = local->scan_sdata; - - if (local->hw.conf.flags & IEEE80211_CONF_PS) - return; - - if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK && sdata) - ieee80211_send_nullfunc(local, sdata, 1); - - local->hw.conf.flags |= IEEE80211_CONF_PS; - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); -} - -void ieee80211_dynamic_ps_timer(unsigned long data) -{ - struct ieee80211_local *local = (void *) data; - - queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); -} - -void ieee80211_send_nullfunc(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - int powersave) -{ - struct sk_buff *skb; - struct ieee80211_hdr *nullfunc; - __le16 fc; - - if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) - return; - - skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc " - "frame\n", sdata->dev->name); - return; - } - skb_reserve(skb, local->hw.extra_tx_headroom); - - nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); - memset(nullfunc, 0, 24); - fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | - IEEE80211_FCTL_TODS); - if (powersave) - fc |= cpu_to_le16(IEEE80211_FCTL_PM); - nullfunc->frame_control = fc; - memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN); - memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); - memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN); - - ieee80211_tx_skb(sdata, skb, 0); -} diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 4ec1bfc7f6a9..20df861c6c4c 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -253,7 +253,7 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; - if (!local->powersave) + if (!local->ps_sdata) ieee80211_send_nullfunc(local, sdata, 0); else { /* diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index a52fb3a4a455..81f63e57027f 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -747,7 +747,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev, struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_conf *conf = &local->hw.conf; - int ret = 0, timeout = 0; + int timeout = 0; bool ps; if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) @@ -779,42 +779,19 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev, timeout = wrq->value / 1000; set: - if (ps == local->powersave && timeout == conf->dynamic_ps_timeout) - return ret; + if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout) + return 0; - local->powersave = ps; + sdata->u.mgd.powersave = ps; conf->dynamic_ps_timeout = timeout; if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) - ret = ieee80211_hw_config(local, - IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT); - - if (!(sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)) - return ret; + ieee80211_hw_config(local, + IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT); - if (conf->dynamic_ps_timeout > 0 && - !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) { - mod_timer(&local->dynamic_ps_timer, jiffies + - msecs_to_jiffies(conf->dynamic_ps_timeout)); - } else { - if (local->powersave) { - if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) - ieee80211_send_nullfunc(local, sdata, 1); - conf->flags |= IEEE80211_CONF_PS; - ret = ieee80211_hw_config(local, - IEEE80211_CONF_CHANGE_PS); - } else { - conf->flags &= ~IEEE80211_CONF_PS; - ret = ieee80211_hw_config(local, - IEEE80211_CONF_CHANGE_PS); - if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) - ieee80211_send_nullfunc(local, sdata, 0); - del_timer_sync(&local->dynamic_ps_timer); - cancel_work_sync(&local->dynamic_ps_enable_work); - } - } + ieee80211_recalc_ps(local); - return ret; + return 0; } static int ieee80211_ioctl_giwpower(struct net_device *dev, @@ -822,9 +799,9 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev, union iwreq_data *wrqu, char *extra) { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - wrqu->power.disabled = !local->powersave; + wrqu->power.disabled = !sdata->u.mgd.powersave; return 0; } -- GitLab From 10f644a47b76d3e61b98f2d02ce9690b94c51ee5 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Apr 2009 13:17:25 +0200 Subject: [PATCH 0631/6080] mac80211: disable powersave if pm_qos asks for low latency When an application asks for a latency lower than the beacon interval there's nothing we can do -- we need to stay awake and not have the AP buffer frames for us. Add code to automatically calculate this constraint in mac80211 so drivers need not concern themselves with it. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 9 +++++++++ net/mac80211/ieee80211_i.h | 5 ++++- net/mac80211/iface.c | 4 ++-- net/mac80211/main.c | 31 ++++++++++++++++++++++++------- net/mac80211/mlme.c | 36 ++++++++++++++++++++++++++++++++---- net/mac80211/wext.c | 2 +- 6 files changed, 72 insertions(+), 15 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 4b501b48ce86..53563d53b5ad 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -1383,4 +1383,13 @@ static inline int ieee80211_freq_to_ofdm_chan(int s_freq, int freq) return -1; } +/** + * ieee80211_tu_to_usec - convert time units (TU) to microseconds + * @tu: the TUs + */ +static inline unsigned long ieee80211_tu_to_usec(unsigned long tu) +{ + return 1024 * tu; +} + #endif /* LINUX_IEEE80211_H */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ff40dd7b523a..b1d18d967d8c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -750,6 +750,7 @@ struct ieee80211_local { struct work_struct dynamic_ps_enable_work; struct work_struct dynamic_ps_disable_work; struct timer_list dynamic_ps_timer; + struct notifier_block network_latency_notifier; int user_power_level; /* in dBm */ int power_constr_level; /* in dBm */ @@ -938,7 +939,9 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); void ieee80211_send_pspoll(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata); -void ieee80211_recalc_ps(struct ieee80211_local *local); +void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency); +int ieee80211_max_network_latency(struct notifier_block *nb, + unsigned long data, void *dummy); /* IBSS code */ int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 6240f76e2a43..5d60deb219d3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -317,7 +317,7 @@ static int ieee80211_open(struct net_device *dev) ieee80211_set_wmm_default(sdata); } - ieee80211_recalc_ps(local); + ieee80211_recalc_ps(local, -1); /* * ieee80211_sta_work is disabled while network interface @@ -574,7 +574,7 @@ static int ieee80211_stop(struct net_device *dev) hw_reconf_flags = 0; } - ieee80211_recalc_ps(local); + ieee80211_recalc_ps(local, -1); /* do after stop to avoid reconfiguring when we stop anyway */ if (hw_reconf_flags) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 80c0e28bf549..049ce8639806 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -1038,25 +1039,38 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) } } + local->network_latency_notifier.notifier_call = + ieee80211_max_network_latency; + result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY, + &local->network_latency_notifier); + + if (result) { + rtnl_lock(); + goto fail_pm_qos; + } + return 0; -fail_wep: + fail_pm_qos: + ieee80211_led_exit(local); + ieee80211_remove_interfaces(local); + fail_wep: rate_control_deinitialize(local); -fail_rate: + fail_rate: unregister_netdevice(local->mdev); local->mdev = NULL; -fail_dev: + fail_dev: rtnl_unlock(); sta_info_stop(local); -fail_sta_info: + fail_sta_info: debugfs_hw_del(local); destroy_workqueue(local->hw.workqueue); -fail_workqueue: + fail_workqueue: if (local->mdev) free_netdev(local->mdev); -fail_mdev_alloc: + fail_mdev_alloc: wiphy_unregister(local->hw.wiphy); -fail_wiphy_register: + fail_wiphy_register: kfree(local->int_scan_req.channels); return result; } @@ -1069,6 +1083,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) tasklet_kill(&local->tx_pending_tasklet); tasklet_kill(&local->tasklet); + pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, + &local->network_latency_notifier); + rtnl_lock(); /* diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 06d9a1d23252..c39a214e7ad0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -515,7 +516,7 @@ static void ieee80211_change_ps(struct ieee80211_local *local) } /* need to hold RTNL or interface lock */ -void ieee80211_recalc_ps(struct ieee80211_local *local) +void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) { struct ieee80211_sub_if_data *sdata, *found = NULL; int count = 0; @@ -534,10 +535,22 @@ void ieee80211_recalc_ps(struct ieee80211_local *local) count++; } - if (count == 1 && found->u.mgd.powersave) - local->ps_sdata = found; - else + if (count == 1 && found->u.mgd.powersave) { + s32 beaconint_us; + + if (latency < 0) + latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY); + + beaconint_us = ieee80211_tu_to_usec( + found->vif.bss_conf.beacon_int); + + if (beaconint_us > latency) + local->ps_sdata = NULL; + else + local->ps_sdata = found; + } else { local->ps_sdata = NULL; + } ieee80211_change_ps(local); } @@ -2324,3 +2337,18 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) ieee80211_restart_sta_timer(sdata); rcu_read_unlock(); } + +int ieee80211_max_network_latency(struct notifier_block *nb, + unsigned long data, void *dummy) +{ + s32 latency_usec = (s32) data; + struct ieee80211_local *local = + container_of(nb, struct ieee80211_local, + network_latency_notifier); + + mutex_lock(&local->iflist_mtx); + ieee80211_recalc_ps(local, latency_usec); + mutex_unlock(&local->iflist_mtx); + + return 0; +} diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 81f63e57027f..1c4664b8b1a0 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -789,7 +789,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev, ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT); - ieee80211_recalc_ps(local); + ieee80211_recalc_ps(local, -1); return 0; } -- GitLab From d91f36db51661018f6d54ff5966e283bcec4c545 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Apr 2009 13:17:26 +0200 Subject: [PATCH 0632/6080] mac80211: implement beacon filtering in software Regardless of whether the hardware implements beacon filtering, there's no need to process all beacons in software all the time throughout the stack (mac80211 does a lot, then cfg80211, then in the future possibly userspace). This patch implements the "best possible" beacon filtering in mac80211. "Best possible" means that it can look for changes in all requested information elements, and distinguish vendor IEs by their OUI. In the future, we will add nl80211 API for userspace to request information elements and vendor IE OUIs to watch -- drivers can then implement the best they can do while software implements it fully. It is unclear whether or not this actually saves CPU time, but the data is all in the cache already so it should be fairly cheap. The additional _testing_, however, has great benefit; Without this, and on hardware that doesn't implement beacon filtering, wrong assumptions about, for example, scan result updates could quickly creep into code. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ieee80211_i.h | 5 ++++ net/mac80211/mlme.c | 52 +++++++++++++++++++++++++++++--------- net/mac80211/util.c | 23 +++++++++++++++-- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b1d18d967d8c..38c980612518 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -308,6 +308,8 @@ struct ieee80211_if_managed { int auth_alg; /* currently used IEEE 802.11 authentication algorithm */ int auth_transaction; + u32 beacon_crc; + enum { IEEE80211_MFP_DISABLED, IEEE80211_MFP_OPTIONAL, @@ -1085,6 +1087,9 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, int encrypt); void ieee802_11_parse_elems(u8 *start, size_t len, struct ieee802_11_elems *elems); +u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, + struct ieee802_11_elems *elems, + u64 filter, u32 crc); int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq); u32 ieee80211_mandatory_rates(struct ieee80211_local *local, enum ieee80211_band band); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c39a214e7ad0..7a8d4c494246 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -1752,46 +1753,73 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; } +/* + * This is the canonical list of information elements we care about, + * the filter code also gives us all changes to the Microsoft OUI + * (00:50:F2) vendor IE which is used for WMM which we need to track. + * + * We implement beacon filtering in software since that means we can + * avoid processing the frame here and in cfg80211, and userspace + * will not be able to tell whether the hardware supports it or not. + * + * XXX: This list needs to be dynamic -- userspace needs to be able to + * add items it requires. It also needs to be able to tell us to + * look out for other vendor IEs. + */ +static const u64 care_about_ies = + BIT(WLAN_EID_COUNTRY) | + BIT(WLAN_EID_ERP_INFO) | + BIT(WLAN_EID_CHANNEL_SWITCH) | + BIT(WLAN_EID_PWR_CONSTRAINT) | + BIT(WLAN_EID_HT_CAPABILITY) | + BIT(WLAN_EID_HT_INFORMATION); + static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_rx_status *rx_status) { - struct ieee80211_if_managed *ifmgd; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; size_t baselen; struct ieee802_11_elems elems; struct ieee80211_local *local = sdata->local; u32 changed = 0; - bool erp_valid, directed_tim; + bool erp_valid, directed_tim = false; u8 erp_value = 0; + u32 ncrc; /* Process beacon from the current BSS */ baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; if (baselen > len) return; - ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); - - ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true); - - if (sdata->vif.type != NL80211_IFTYPE_STATION) + if (rx_status->freq != local->hw.conf.channel->center_freq) return; - ifmgd = &sdata->u.mgd; - if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED) || memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0) return; - if (rx_status->freq != local->hw.conf.channel->center_freq) + ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); + ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, + len - baselen, &elems, + care_about_ies, ncrc); + + if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) + directed_tim = ieee80211_check_tim(&elems, ifmgd->aid); + + ncrc = crc32_be(ncrc, (void *)&directed_tim, sizeof(directed_tim)); + + if (ncrc == ifmgd->beacon_crc) return; + ifmgd->beacon_crc = ncrc; + + ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true); ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, elems.wmm_param_len); if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { - directed_tim = ieee80211_check_tim(&elems, ifmgd->aid); - if (directed_tim) { if (local->hw.conf.dynamic_ps_timeout > 0) { local->hw.conf.flags &= ~IEEE80211_CONF_PS; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index b361e2acfce9..3dd490fa4b68 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -536,9 +537,17 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); void ieee802_11_parse_elems(u8 *start, size_t len, struct ieee802_11_elems *elems) +{ + ieee802_11_parse_elems_crc(start, len, elems, 0, 0); +} + +u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, + struct ieee802_11_elems *elems, + u64 filter, u32 crc) { size_t left = len; u8 *pos = start; + bool calc_crc = filter != 0; memset(elems, 0, sizeof(*elems)); elems->ie_start = start; @@ -552,7 +561,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len, left -= 2; if (elen > left) - return; + break; + + if (calc_crc && id < 64 && (filter & BIT(id))) + crc = crc32_be(crc, pos - 2, elen + 2); switch (id) { case WLAN_EID_SSID: @@ -587,15 +599,20 @@ void ieee802_11_parse_elems(u8 *start, size_t len, elems->challenge = pos; elems->challenge_len = elen; break; - case WLAN_EID_WPA: + case WLAN_EID_VENDOR_SPECIFIC: if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && pos[2] == 0xf2) { /* Microsoft OUI (00:50:F2) */ + + if (calc_crc) + crc = crc32_be(crc, pos - 2, elen + 2); + if (pos[3] == 1) { /* OUI Type 1 - WPA IE */ elems->wpa = pos; elems->wpa_len = elen; } else if (elen >= 5 && pos[3] == 2) { + /* OUI Type 2 - WMM IE */ if (pos[4] == 0) { elems->wmm_info = pos; elems->wmm_info_len = elen; @@ -680,6 +697,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len, left -= elen; pos += elen; } + + return crc; } void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) -- GitLab From bbbdff9e00449928f228867076a07bdfecd3dca8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Apr 2009 13:27:42 +0200 Subject: [PATCH 0633/6080] mac80211: enable PS by default Enable PS by default (depending on Kconfig) -- rely on drivers to control the level using pm_qos. Due to the previous patch we turn off PS when necessary due to latency requirements. This has a Kconfig symbol so people can, if they really want, configure the default in their kernels. We may want to keep it at "default y" only in wireless-testing for a while. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/Kconfig | 16 ++++++++++++++++ net/mac80211/mlme.c | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index ecc3faf9f11a..9cbf545e95a2 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -11,6 +11,22 @@ config MAC80211 This option enables the hardware independent IEEE 802.11 networking stack. +config MAC80211_DEFAULT_PS + bool "enable powersave by default" + depends on MAC80211 + default y + help + This option enables powersave mode by default. + + If this causes your applications to misbehave you should fix your + applications instead -- they need to register their network + latency requirement, see Documentation/power/pm_qos_interface.txt. + +config MAC80211_DEFAULT_PS_VALUE + int + default 1 if MAC80211_DEFAULT_PS + default 0 + menu "Rate control algorithm selection" depends on MAC80211 != n diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7a8d4c494246..a16c9d724be1 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2192,6 +2192,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_managed *ifmgd; + u32 hw_flags; ifmgd = &sdata->u.mgd; INIT_WORK(&ifmgd->work, ieee80211_sta_work); @@ -2211,6 +2212,13 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) IEEE80211_STA_AUTO_CHANNEL_SEL; if (sdata->local->hw.queues >= 4) ifmgd->flags |= IEEE80211_STA_WMM_ENABLED; + + hw_flags = sdata->local->hw.flags; + + if (hw_flags & IEEE80211_HW_SUPPORTS_PS) { + ifmgd->powersave = CONFIG_MAC80211_DEFAULT_PS_VALUE; + sdata->local->hw.conf.dynamic_ps_timeout = 500; + } } /* configuration hooks */ -- GitLab From 955394c98c9cb79bdb3e6b479695af3a90ea0623 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 16 Apr 2009 17:04:25 +0200 Subject: [PATCH 0634/6080] mac80211: document powersaving/beacon filter future Document what mac80211 will do in the future to help save power. We're not quite there yet, but a plan helps. Also, while at it, fix the docs wrt. multicast traffic. Signed-off-by: Johannes Berg Reviewed-by: Kalle Valo Signed-off-by: John W. Linville --- include/net/mac80211.h | 60 +++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index a593bedcfeda..52808bdcc6ca 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1109,11 +1109,9 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * need software support for parsing the TIM bitmap. This is also supported * by mac80211 by combining the %IEEE80211_HW_SUPPORTS_PS and * %IEEE80211_HW_PS_NULLFUNC_STACK flags. The hardware is of course still - * required to pass up beacons. Additionally, in this case, mac80211 will - * wake up the hardware when multicast traffic is announced in the beacon. - * - * FIXME: I don't think we can be fast enough in software when we want to - * receive multicast traffic? + * required to pass up beacons. The hardware is still required to handle + * waking up for multicast traffic; if it cannot the driver must handle that + * as best as it can, mac80211 is too slow. * * Dynamic powersave mode is an extension to normal powersave mode in which * the hardware stays awake for a user-specified period of time after sending @@ -1134,11 +1132,53 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * way the host will only receive beacons where some relevant information * (for example ERP protection or WMM settings) have changed. * - * Beacon filter support is informed with %IEEE80211_HW_BEACON_FILTER flag. - * The driver needs to enable beacon filter support whenever power save is - * enabled, that is %IEEE80211_CONF_PS is set. When power save is enabled, - * the stack will not check for beacon miss at all and the driver needs to - * notify about complete loss of beacons with ieee80211_beacon_loss(). + * Beacon filter support is advertised with the %IEEE80211_HW_BEACON_FILTER + * hardware capability. The driver needs to enable beacon filter support + * whenever power save is enabled, that is %IEEE80211_CONF_PS is set. When + * power save is enabled, the stack will not check for beacon loss and the + * driver needs to notify about loss of beacons with ieee80211_beacon_loss(). + * + * The time (or number of beacons missed) until the firmware notifies the + * driver of a beacon loss event (which in turn causes the driver to call + * ieee80211_beacon_loss()) should be configurable and will be controlled + * by mac80211 and the roaming algorithm in the future. + * + * Since there may be constantly changing information elements that nothing + * in the software stack cares about, we will, in the future, have mac80211 + * tell the driver which information elements are interesting in the sense + * that we want to see changes in them. This will include + * - a list of information element IDs + * - a list of OUIs for the vendor information element + * + * Ideally, the hardware would filter out any beacons without changes in the + * requested elements, but if it cannot support that it may, at the expense + * of some efficiency, filter out only a subset. For example, if the device + * doesn't support checking for OUIs it should pass up all changes in all + * vendor information elements. + * + * Note that change, for the sake of simplification, also includes information + * elements appearing or disappearing from the beacon. + * + * Some hardware supports an "ignore list" instead, just make sure nothing + * that was requested is on the ignore list, and include commonly changing + * information element IDs in the ignore list, for example 11 (BSS load) and + * the various vendor-assigned IEs with unknown contents (128, 129, 133-136, + * 149, 150, 155, 156, 173, 176, 178, 179, 219); for forward compatibility + * it could also include some currently unused IDs. + * + * + * In addition to these capabilities, hardware should support notifying the + * host of changes in the beacon RSSI. This is relevant to implement roaming + * when no traffic is flowing (when traffic is flowing we see the RSSI of + * the received data packets). This can consist in notifying the host when + * the RSSI changes significantly or when it drops below or rises above + * configurable thresholds. In the future these thresholds will also be + * configured by mac80211 (which gets them from userspace) to implement + * them as the roaming algorithm requires. + * + * If the hardware cannot implement this, the driver should ask it to + * periodically pass beacon frames to the host so that software can do the + * signal strength threshold checking. */ /** -- GitLab From 357303e2b61272b191f2e5d782d94fdd8f50fd71 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 16 Apr 2009 18:44:53 +0300 Subject: [PATCH 0635/6080] mac80211: Allow scan to be requested in AP mode We can allow scan requests in AP mode as long as the interface has not yet been configured to send out Beacon frames (or if beaconing has been disabled prior to the scan request). This makes it easier to scan for neighboring BSSes during AP initialization and makes it possible to run a scan without setting the interface down, if needed. Without this change, the only available option would be to set the interface down, move into station mode, and set the interface up, prior to requesting the scan. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index e677b751d468..520efa8a0791 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1167,7 +1167,8 @@ static int ieee80211_scan(struct wiphy *wiphy, if (sdata->vif.type != NL80211_IFTYPE_STATION && sdata->vif.type != NL80211_IFTYPE_ADHOC && - sdata->vif.type != NL80211_IFTYPE_MESH_POINT) + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && + (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon)) return -EOPNOTSUPP; return ieee80211_request_scan(sdata, req); -- GitLab From a027087a6b4c7d985b872cac3e19ce023670792e Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Thu, 16 Apr 2009 19:56:38 -0500 Subject: [PATCH 0636/6080] rtl8187: Implement TX/RX blink for LED The following patch implements some control over the LED on RTL8187B and RTL8187L devices. Triggers are registered for TX and RX. Whenever the trigger event occurs, the LED is turned off for 1/20 second, then turned back on. Note: For those RTL8187X devices that are built into the computer and have a LED that is expected to be controlled with a radio switch, this patch will not operate that LED. That will take a separate patch to be prepared later. Signed-off-by: Larry Finger Signed-off-by: Herton Ronaldo Krzesinski Tested-by: Hin-Tak Leung Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 7 + drivers/net/wireless/rtl818x/Makefile | 2 +- drivers/net/wireless/rtl818x/rtl8187.h | 7 + drivers/net/wireless/rtl818x/rtl8187_dev.c | 18 +- drivers/net/wireless/rtl818x/rtl8187_leds.c | 218 ++++++++++++++++++++ drivers/net/wireless/rtl818x/rtl8187_leds.h | 57 +++++ 6 files changed, 305 insertions(+), 4 deletions(-) create mode 100644 drivers/net/wireless/rtl818x/rtl8187_leds.c create mode 100644 drivers/net/wireless/rtl818x/rtl8187_leds.h diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index ad99470ae92d..11c248180982 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -433,6 +433,13 @@ config RTL8187 Thanks to Realtek for their support! +# If possible, automatically enable LEDs for RTL8187. + +config RTL8187_LEDS + bool + depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187) + default y + config ADM8211 tristate "ADMtek ADM8211 support" depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile index c113b3e69046..37e3d4db0c40 100644 --- a/drivers/net/wireless/rtl818x/Makefile +++ b/drivers/net/wireless/rtl818x/Makefile @@ -1,5 +1,5 @@ rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o -rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o +rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o obj-$(CONFIG_RTL8180) += rtl8180.o obj-$(CONFIG_RTL8187) += rtl8187.o diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h index 9718f61809cf..622196dc078e 100644 --- a/drivers/net/wireless/rtl818x/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187.h @@ -16,6 +16,7 @@ #define RTL8187_H #include "rtl818x.h" +#include "rtl8187_leds.h" #define RTL8187_EEPROM_TXPWR_BASE 0x05 #define RTL8187_EEPROM_MAC_ADDR 0x07 @@ -102,6 +103,12 @@ struct rtl8187_priv { struct usb_anchor anchored; struct delayed_work work; struct ieee80211_hw *dev; +#ifdef CONFIG_RTL8187_LEDS + struct rtl8187_led led_tx; + struct rtl8187_led led_rx; + struct delayed_work led_on; + struct delayed_work led_off; +#endif u16 txpwr_base; u8 asic_rev; u8 is_rtl8187b; diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index d6d4001812a7..ac558da92aac 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -29,6 +29,9 @@ #include "rtl8187.h" #include "rtl8187_rtl8225.h" +#ifdef CONFIG_RTL8187_LEDS +#include "rtl8187_leds.h" +#endif MODULE_AUTHOR("Michael Wu "); MODULE_AUTHOR("Andrea Merello "); @@ -734,10 +737,10 @@ static const u8 rtl8187b_reg_table[][3] = { {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0}, {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0}, {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0}, - {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x91, 0x03, 0}, + {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x4C, 0x00, 2}, - {0x4C, 0x00, 2}, {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, - {0x8E, 0x08, 0}, {0x8F, 0x00, 0} + {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0}, + {0x8F, 0x00, 0} }; static int rtl8187b_init_hw(struct ieee80211_hw *dev) @@ -1501,6 +1504,12 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, wiphy_name(dev->wiphy), dev->wiphy->perm_addr, chip_name, priv->asic_rev, priv->rf->name); +#ifdef CONFIG_RTL8187_LEDS + eeprom_93cx6_read(&eeprom, 0x3F, ®); + reg &= 0xFF; + rtl8187_leds_init(dev, reg); +#endif + return 0; err_free_dev: @@ -1518,6 +1527,9 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf) if (!dev) return; +#ifdef CONFIG_RTL8187_LEDS + rtl8187_leds_exit(dev); +#endif ieee80211_unregister_hw(dev); priv = dev->priv; diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c new file mode 100644 index 000000000000..b44253592243 --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c @@ -0,0 +1,218 @@ +/* + * Linux LED driver for RTL8187 + * + * Copyright 2009 Larry Finger + * + * Based on the LED handling in the r8187 driver, which is: + * Copyright (c) Realtek Semiconductor Corp. All rights reserved. + * + * Thanks to Realtek for their support! + * + * 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. + */ + +#ifdef CONFIG_RTL8187_LEDS + +#include +#include +#include + +#include "rtl8187.h" +#include "rtl8187_leds.h" + +static void led_turn_on(struct work_struct *work) +{ + /* As this routine does read/write operations on the hardware, it must + * be run from a work queue. + */ + u8 reg; + struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, + led_on.work); + struct rtl8187_led *led = &priv->led_tx; + + /* Don't change the LED, when the device is down. */ + if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) + return ; + + /* Skip if the LED is not registered. */ + if (!led->dev) + return; + mutex_lock(&priv->conf_mutex); + switch (led->ledpin) { + case LED_PIN_GPIO0: + rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00); + break; + case LED_PIN_LED0: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 4); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_LED1: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 5); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_HW: + default: + break; + } + mutex_unlock(&priv->conf_mutex); +} + +static void led_turn_off(struct work_struct *work) +{ + /* As this routine does read/write operations on the hardware, it must + * be run from a work queue. + */ + u8 reg; + struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv, + led_off.work); + struct rtl8187_led *led = &priv->led_tx; + + /* Don't change the LED, when the device is down. */ + if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) + return ; + + /* Skip if the LED is not registered. */ + if (!led->dev) + return; + mutex_lock(&priv->conf_mutex); + switch (led->ledpin) { + case LED_PIN_GPIO0: + rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01); + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01); + break; + case LED_PIN_LED0: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 4); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_LED1: + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 5); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); + break; + case LED_PIN_HW: + default: + break; + } + mutex_unlock(&priv->conf_mutex); +} + +/* Callback from the LED subsystem. */ +static void rtl8187_led_brightness_set(struct led_classdev *led_dev, + enum led_brightness brightness) +{ + struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led, + led_dev); + struct ieee80211_hw *hw = led->dev; + struct rtl8187_priv *priv = hw->priv; + + if (brightness == LED_OFF) { + queue_delayed_work(hw->workqueue, &priv->led_off, 0); + /* The LED is off for 1/20 sec so that it just blinks. */ + queue_delayed_work(hw->workqueue, &priv->led_on, HZ / 20); + } else + queue_delayed_work(hw->workqueue, &priv->led_on, 0); +} + +static int rtl8187_register_led(struct ieee80211_hw *dev, + struct rtl8187_led *led, const char *name, + const char *default_trigger, u8 ledpin) +{ + int err; + struct rtl8187_priv *priv = dev->priv; + + if (led->dev) + return -EEXIST; + if (!default_trigger) + return -EINVAL; + led->dev = dev; + led->ledpin = ledpin; + strncpy(led->name, name, sizeof(led->name)); + + led->led_dev.name = led->name; + led->led_dev.default_trigger = default_trigger; + led->led_dev.brightness_set = rtl8187_led_brightness_set; + + err = led_classdev_register(&priv->udev->dev, &led->led_dev); + if (err) { + printk(KERN_INFO "LEDs: Failed to register %s\n", name); + led->dev = NULL; + return err; + } + return 0; +} + +static void rtl8187_unregister_led(struct rtl8187_led *led) +{ + led_classdev_unregister(&led->led_dev); + led->dev = NULL; +} + +void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid) +{ + struct rtl8187_priv *priv = dev->priv; + char name[RTL8187_LED_MAX_NAME_LEN + 1]; + u8 ledpin; + int err; + + /* According to the vendor driver, the LED operation depends on the + * customer ID encoded in the EEPROM + */ + printk(KERN_INFO "rtl8187: Customer ID is 0x%02X\n", custid); + switch (custid) { + case EEPROM_CID_RSVD0: + case EEPROM_CID_RSVD1: + case EEPROM_CID_SERCOMM_PS: + case EEPROM_CID_QMI: + case EEPROM_CID_DELL: + case EEPROM_CID_TOSHIBA: + ledpin = LED_PIN_GPIO0; + break; + case EEPROM_CID_ALPHA0: + ledpin = LED_PIN_LED0; + break; + case EEPROM_CID_HW: + ledpin = LED_PIN_HW; + break; + default: + ledpin = LED_PIN_GPIO0; + } + + INIT_DELAYED_WORK(&priv->led_on, led_turn_on); + INIT_DELAYED_WORK(&priv->led_off, led_turn_off); + + snprintf(name, sizeof(name), + "rtl8187-%s::tx", wiphy_name(dev->wiphy)); + err = rtl8187_register_led(dev, &priv->led_tx, name, + ieee80211_get_tx_led_name(dev), ledpin); + if (err) + goto error; + snprintf(name, sizeof(name), + "rtl8187-%s::rx", wiphy_name(dev->wiphy)); + err = rtl8187_register_led(dev, &priv->led_rx, name, + ieee80211_get_rx_led_name(dev), ledpin); + if (!err) { + queue_delayed_work(dev->workqueue, &priv->led_on, 0); + return; + } + /* registration of RX LED failed - unregister TX */ + rtl8187_unregister_led(&priv->led_tx); +error: + /* If registration of either failed, cancel delayed work */ + cancel_delayed_work_sync(&priv->led_off); + cancel_delayed_work_sync(&priv->led_on); +} + +void rtl8187_leds_exit(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + + rtl8187_unregister_led(&priv->led_tx); + /* turn the LED off before exiting */ + queue_delayed_work(dev->workqueue, &priv->led_off, 0); + cancel_delayed_work_sync(&priv->led_off); + rtl8187_unregister_led(&priv->led_rx); +} +#endif /* def CONFIG_RTL8187_LED */ + diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h new file mode 100644 index 000000000000..a0332027aead --- /dev/null +++ b/drivers/net/wireless/rtl818x/rtl8187_leds.h @@ -0,0 +1,57 @@ +/* + * Definitions for RTL8187 leds + * + * Copyright 2009 Larry Finger + * + * Based on the LED handling in the r8187 driver, which is: + * Copyright (c) Realtek Semiconductor 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 version 2 as + * published by the Free Software Foundation. + */ + +#ifndef RTL8187_LED_H +#define RTL8187_LED_H + +#ifdef CONFIG_RTL8187_LEDS + +#define RTL8187_LED_MAX_NAME_LEN 21 + +#include +#include + +enum { + LED_PIN_LED0, + LED_PIN_LED1, + LED_PIN_GPIO0, + LED_PIN_HW +}; + +enum { + EEPROM_CID_RSVD0 = 0x00, + EEPROM_CID_RSVD1 = 0xFF, + EEPROM_CID_ALPHA0 = 0x01, + EEPROM_CID_SERCOMM_PS = 0x02, + EEPROM_CID_HW = 0x03, + EEPROM_CID_TOSHIBA = 0x04, + EEPROM_CID_QMI = 0x07, + EEPROM_CID_DELL = 0x08 +}; + +struct rtl8187_led { + struct ieee80211_hw *dev; + /* The LED class device */ + struct led_classdev led_dev; + /* The pin/method used to control the led */ + u8 ledpin; + /* The unique name string for this LED device. */ + char name[RTL8187_LED_MAX_NAME_LEN + 1]; +}; + +void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code); +void rtl8187_leds_exit(struct ieee80211_hw *dev); + +#endif /* def CONFIG_RTL8187_LED */ + +#endif /* RTL8187_LED_H */ -- GitLab From d577e7cdb1be027bc51ee1030bc7fd647ea6d0da Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 18 Apr 2009 18:30:13 +0200 Subject: [PATCH 0637/6080] p54: fix ps-poll delivery in ap mode PS-Polled frames must be sent with OUT_NOCANCEL flag set, or the firmware will reject all of them, at the station is still blacklisted. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 5368aa33dab8..71394968d450 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -1473,7 +1473,8 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb, if (info->control.sta) *aid = info->control.sta->aid; - else + + if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; break; } -- GitLab From fef99929cd6b409a67a35e41f7c177bade5bca34 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 18 Apr 2009 19:39:15 +0200 Subject: [PATCH 0638/6080] mac80211: set CLEAR_PS for pspolled frames This patch sets IEEE80211_TX_CTL_CLEAR_PS_FILT for outgoing frames for a half-wake station. this is necessary if one wants to get ps-poll working properly with a p54 ap. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/tx.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 3fb04a86444d..f336cc731df6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -409,8 +409,24 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) sta->sta.addr); } #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ - clear_sta_flags(sta, WLAN_STA_PSPOLL); + if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) { + /* + * The sleeping station with pending data is now snoozing. + * It queried us for its buffered frames and will go back + * to deep sleep once it got everything. + * + * inform the driver, in case the hardware does powersave + * frame filtering and keeps a station blacklist on its own + * (e.g: p54), so that frames can be delivered unimpeded. + * + * Note: It should be save to disable the filter now. + * As, it is really unlikely that we still have any pending + * frame for this station in the hw's buffers/fifos left, + * that is not rejected with a unsuccessful tx_status yet. + */ + info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; + } return TX_CONTINUE; } -- GitLab From d726405af6c8c81d2ee5e6a29301c68b9d4c574f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 19 Apr 2009 16:23:20 +0200 Subject: [PATCH 0639/6080] nl80211: send wiphy along with netdev When listing all wireless netdevs in the system this is useful to print which wiphy they belong to. Just add the attribute, any program that doesn't care will just ignore it. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d33cab0e0fb2..d2cfde659e76 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -538,6 +538,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, + struct cfg80211_registered_device *rdev, struct net_device *dev) { void *hdr; @@ -547,6 +548,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, return -1; NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name); NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype); return genlmsg_end(msg, hdr); @@ -581,7 +583,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * } if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, - wdev->netdev) < 0) { + dev, wdev->netdev) < 0) { mutex_unlock(&dev->devlist_mtx); goto out; } @@ -615,7 +617,8 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) if (!msg) goto out_err; - if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0) + if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, + dev, netdev) < 0) goto out_free; dev_put(netdev); -- GitLab From 691597cb26f236ac7471f1adf925a134c86799d6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 19 Apr 2009 19:57:45 +0200 Subject: [PATCH 0640/6080] cfg80211/mac80211: move wext SIWMLME into cfg80211 Since we have ->deauth and ->disassoc we can support the wext SIWMLME call directly without driver wext handlers. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 3 +++ net/mac80211/cfg.c | 12 ++++------ net/mac80211/mlme.c | 6 ----- net/mac80211/wext.c | 25 +-------------------- net/wireless/wext-compat.c | 46 +++++++++++++++++++++++++++++++++++++- 5 files changed, 53 insertions(+), 39 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index d303c269a693..019a41efa0bb 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -833,6 +833,9 @@ int cfg80211_wext_siwscan(struct net_device *dev, int cfg80211_wext_giwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra); +int cfg80211_wext_siwmlme(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra); int cfg80211_wext_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 520efa8a0791..daf75287e92a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1268,22 +1268,18 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_deauth_request *req) { - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - /* TODO: req->ie */ + /* TODO: req->ie, req->peer_addr */ return ieee80211_sta_deauthenticate(sdata, req->reason_code); } static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req) { - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - /* TODO: req->ie */ + /* TODO: req->ie, req->peer_addr */ return ieee80211_sta_disassociate(sdata, req->reason_code); } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a16c9d724be1..428742d7f440 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2338,9 +2338,6 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", sdata->dev->name, reason); - if (sdata->vif.type != NL80211_IFTYPE_STATION) - return -EINVAL; - ieee80211_set_disassoc(sdata, true, true, reason); return 0; } @@ -2352,9 +2349,6 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason) printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", sdata->dev->name, reason); - if (sdata->vif.type != NL80211_IFTYPE_STATION) - return -EINVAL; - if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED)) return -ENOLINK; diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 1c4664b8b1a0..896704cf94e1 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -612,29 +612,6 @@ static int ieee80211_ioctl_giwretry(struct net_device *dev, return 0; } -static int ieee80211_ioctl_siwmlme(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct ieee80211_sub_if_data *sdata; - struct iw_mlme *mlme = (struct iw_mlme *) extra; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (!(sdata->vif.type == NL80211_IFTYPE_STATION)) - return -EINVAL; - - switch (mlme->cmd) { - case IW_MLME_DEAUTH: - /* TODO: mlme->addr.sa_data */ - return ieee80211_sta_deauthenticate(sdata, mlme->reason_code); - case IW_MLME_DISASSOC: - /* TODO: mlme->addr.sa_data */ - return ieee80211_sta_disassociate(sdata, mlme->reason_code); - default: - return -EOPNOTSUPP; - } -} - static int ieee80211_ioctl_siwencode(struct net_device *dev, struct iw_request_info *info, @@ -1076,7 +1053,7 @@ static const iw_handler ieee80211_handler[] = (iw_handler) NULL, /* SIOCGIWTHRSPY */ (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */ (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */ - (iw_handler) ieee80211_ioctl_siwmlme, /* SIOCSIWMLME */ + (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */ (iw_handler) NULL, /* SIOCGIWAPLIST */ (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */ diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 0fd1db6e95bb..6fd7bf7b4481 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -206,7 +207,6 @@ int cfg80211_wext_giwrange(struct net_device *dev, range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { int i; struct ieee80211_supported_band *sband; @@ -241,3 +241,47 @@ int cfg80211_wext_giwrange(struct net_device *dev, return 0; } EXPORT_SYMBOL(cfg80211_wext_giwrange); + +int cfg80211_wext_siwmlme(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct iw_mlme *mlme = (struct iw_mlme *)extra; + struct cfg80211_registered_device *rdev; + union { + struct cfg80211_disassoc_request disassoc; + struct cfg80211_deauth_request deauth; + } cmd; + + if (!wdev) + return -EOPNOTSUPP; + + rdev = wiphy_to_dev(wdev->wiphy); + + if (wdev->iftype != NL80211_IFTYPE_STATION) + return -EINVAL; + + if (mlme->addr.sa_family != ARPHRD_ETHER) + return -EINVAL; + + memset(&cmd, 0, sizeof(cmd)); + + switch (mlme->cmd) { + case IW_MLME_DEAUTH: + if (!rdev->ops->deauth) + return -EOPNOTSUPP; + cmd.deauth.peer_addr = mlme->addr.sa_data; + cmd.deauth.reason_code = mlme->reason_code; + return rdev->ops->deauth(wdev->wiphy, dev, &cmd.deauth); + case IW_MLME_DISASSOC: + if (!rdev->ops->disassoc) + return -EOPNOTSUPP; + cmd.disassoc.peer_addr = mlme->addr.sa_data; + cmd.disassoc.reason_code = mlme->reason_code; + return rdev->ops->disassoc(wdev->wiphy, dev, &cmd.disassoc); + default: + return -EOPNOTSUPP; + } +} +EXPORT_SYMBOL(cfg80211_wext_siwmlme); -- GitLab From 04a773ade0680d862b479d7219973df60f7a3834 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 19 Apr 2009 21:24:32 +0200 Subject: [PATCH 0641/6080] cfg80211/nl80211: add IBSS API This adds IBSS API along with (preliminary) wext handlers. The wext handlers can only do IBSS so you need to call them from your own wext handlers if the mode is IBSS. The nl80211 API requires * an SSID * a channel (frequency) for the case that a new IBSS has to be created It optionally supports * a flag to fix the channel * a fixed BSSID The cfg80211 code also takes care to leave the IBSS before the netdev is set down. If wireless extensions are used, it also caches values when the interface is down and instructs the driver to join when the interface is set up. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 18 ++ include/net/cfg80211.h | 72 ++++++++ include/net/wireless.h | 14 ++ net/wireless/Makefile | 2 +- net/wireless/core.c | 16 ++ net/wireless/core.h | 8 + net/wireless/ibss.c | 360 +++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.c | 182 +++++++++++++++++-- net/wireless/nl80211.h | 4 + net/wireless/wext-compat.c | 30 ++++ 10 files changed, 693 insertions(+), 13 deletions(-) create mode 100644 net/wireless/ibss.c diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index c01423888db9..25ce3e42bd10 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -223,6 +223,15 @@ * %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this * event matches with MLME-MICHAELMICFAILURE.indication() primitive * + * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a + * FREQ attribute (for the initial frequency if no peer can be found) + * and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those + * should be fixed rather than automatically determined. Can only be + * executed on a network interface that is UP, and fixed BSSID/FREQ + * may be rejected. + * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is + * determined by the network interface. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -288,6 +297,9 @@ enum nl80211_commands { NL80211_CMD_REG_BEACON_HINT, + NL80211_CMD_JOIN_IBSS, + NL80211_CMD_LEAVE_IBSS, + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ @@ -456,6 +468,9 @@ enum nl80211_commands { * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported * cipher suites * + * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look + * for other networks on different channels + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -547,6 +562,9 @@ enum nl80211_attrs { NL80211_ATTR_FREQ_BEFORE, NL80211_ATTR_FREQ_AFTER, + + NL80211_ATTR_FREQ_FIXED, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 019a41efa0bb..5287a3e56e7c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -657,6 +657,31 @@ struct cfg80211_disassoc_request { size_t ie_len; }; +/** + * struct cfg80211_ibss_params - IBSS parameters + * + * This structure defines the IBSS parameters for the join_ibss() + * method. + * + * @ssid: The SSID, will always be non-null. + * @ssid_len: The length of the SSID, will always be non-zero. + * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not + * search for IBSSs with a different BSSID. + * @channel: The channel to use if no IBSS can be found to join. + * @channel_fixed: The channel should be fixed -- do not search for + * IBSSs to join on other channels. + * @ie: information element(s) to include in the beacon + * @ie_len: length of that + */ +struct cfg80211_ibss_params { + u8 *ssid; + u8 *bssid; + struct ieee80211_channel *channel; + u8 *ie; + u8 ssid_len, ie_len; + bool channel_fixed; +}; + /** * struct cfg80211_ops - backend description for wireless configuration * @@ -732,6 +757,11 @@ struct cfg80211_disassoc_request { * @assoc: Request to (re)associate with the specified peer * @deauth: Request to deauthenticate from the specified peer * @disassoc: Request to disassociate from the specified peer + * + * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call + * cfg80211_ibss_joined(), also call that function when changing BSSID due + * to a merge. + * @leave_ibss: Leave the IBSS. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy); @@ -817,6 +847,10 @@ struct cfg80211_ops { struct cfg80211_deauth_request *req); int (*disassoc)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_disassoc_request *req); + + int (*join_ibss)(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_ibss_params *params); + int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); }; /* temporary wext handlers */ @@ -839,6 +873,28 @@ int cfg80211_wext_siwmlme(struct net_device *dev, int cfg80211_wext_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra); +int cfg80211_ibss_wext_siwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra); +int cfg80211_ibss_wext_giwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra); +int cfg80211_ibss_wext_siwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid); +int cfg80211_ibss_wext_giwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid); +int cfg80211_ibss_wext_siwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra); +int cfg80211_ibss_wext_giwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra); + +/* wext helper for now (to be removed) */ +struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, + struct iw_freq *freq); /** * cfg80211_scan_done - notify that scan finished @@ -984,4 +1040,20 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, enum nl80211_key_type key_type, int key_id, const u8 *tsc); +/** + * cfg80211_ibss_joined - notify cfg80211 that device joined an IBSS + * + * @dev: network device + * @bssid: the BSSID of the IBSS joined + * @gfp: allocation flags + * + * This function notifies cfg80211 that the device joined an IBSS or + * switched to a different BSSID. Before this function can be called, + * either a beacon has to have been received from the IBSS, or one of + * the cfg80211_inform_bss{,_frame} functions must have been called + * with the locally generated beacon -- this guarantees that there is + * always a scan result for this IBSS. cfg80211 will handle the rest. + */ +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); + #endif /* __NET_CFG80211_H */ diff --git a/include/net/wireless.h b/include/net/wireless.h index 44c2642d3c06..abd27b033331 100644 --- a/include/net/wireless.h +++ b/include/net/wireless.h @@ -265,6 +265,8 @@ struct wiphy { * * @wiphy: pointer to hardware description * @iftype: interface type + * @list: (private) + * @netdev (private) */ struct wireless_dev { struct wiphy *wiphy; @@ -273,6 +275,18 @@ struct wireless_dev { /* private to the generic wireless code */ struct list_head list; struct net_device *netdev; + + /* currently used for IBSS - might be rearranged in the future */ + struct cfg80211_bss *current_bss; + u8 bssid[ETH_ALEN]; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 ssid_len; + +#ifdef CONFIG_WIRELESS_EXT + /* wext data */ + struct cfg80211_ibss_params wext; + u8 wext_bssid[ETH_ALEN]; +#endif }; /** diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 6d1e7b27b752..14ea01c4a103 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o -cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o +cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/wireless/core.c b/net/wireless/core.c index d1f556535f6d..de1ac51ae4e5 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -450,6 +450,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, dev->ieee80211_ptr->netdev = dev; mutex_unlock(&rdev->devlist_mtx); break; + case NETDEV_GOING_DOWN: + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) + break; + if (!dev->ieee80211_ptr->ssid_len) + break; + cfg80211_leave_ibss(rdev, dev); + break; + case NETDEV_UP: +#ifdef CONFIG_WIRELESS_EXT + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) + break; + if (!dev->ieee80211_ptr->wext.ssid_len) + break; + cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext); + break; +#endif case NETDEV_UNREGISTER: mutex_lock(&rdev->devlist_mtx); if (!list_empty(&dev->ieee80211_ptr->list)) { diff --git a/net/wireless/core.h b/net/wireless/core.h index 02668b02e331..2ef3595fd6e0 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -144,4 +144,12 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev); void cfg80211_bss_age(struct cfg80211_registered_device *dev, unsigned long age_secs); +/* IBSS */ +int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct cfg80211_ibss_params *params); +void cfg80211_clear_ibss(struct net_device *dev); +int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, + struct net_device *dev); + #endif /* __NET_WIRELESS_CORE_H */ diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c new file mode 100644 index 000000000000..2bf42fdef3a1 --- /dev/null +++ b/net/wireless/ibss.c @@ -0,0 +1,360 @@ +/* + * Some IBSS support code for cfg80211. + * + * Copyright 2009 Johannes Berg + */ + +#include +#include +#include +#include +#include "nl80211.h" + + +void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_bss *bss; +#ifdef CONFIG_WIRELESS_EXT + union iwreq_data wrqu; +#endif + + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) + return; + + if (WARN_ON(!wdev->ssid_len)) + return; + + if (memcmp(bssid, wdev->bssid, ETH_ALEN) == 0) + return; + + bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, + wdev->ssid, wdev->ssid_len, + WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); + + if (WARN_ON(!bss)) + return; + + if (wdev->current_bss) { + cfg80211_unhold_bss(wdev->current_bss); + cfg80211_put_bss(wdev->current_bss); + } + + cfg80211_hold_bss(bss); + wdev->current_bss = bss; + memcpy(wdev->bssid, bssid, ETH_ALEN); + + nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, gfp); +#ifdef CONFIG_WIRELESS_EXT + memset(&wrqu, 0, sizeof(wrqu)); + memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); + wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); +#endif +} +EXPORT_SYMBOL(cfg80211_ibss_joined); + +int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct cfg80211_ibss_params *params) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; + + if (wdev->ssid_len) + return -EALREADY; + +#ifdef CONFIG_WIRELESS_EXT + wdev->wext.channel = params->channel; +#endif + err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); + + if (err) + return err; + + memcpy(wdev->ssid, params->ssid, params->ssid_len); + wdev->ssid_len = params->ssid_len; + + return 0; +} + +void cfg80211_clear_ibss(struct net_device *dev) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + if (wdev->current_bss) { + cfg80211_unhold_bss(wdev->current_bss); + cfg80211_put_bss(wdev->current_bss); + } + + wdev->current_bss = NULL; + wdev->ssid_len = 0; + memset(wdev->bssid, 0, ETH_ALEN); +} + +int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + int err; + + err = rdev->ops->leave_ibss(&rdev->wiphy, dev); + + if (err) + return err; + + cfg80211_clear_ibss(dev); + + return 0; +} + +#ifdef CONFIG_WIRELESS_EXT +static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev) +{ + enum ieee80211_band band; + int i; + + /* try to find an IBSS channel if none requested ... */ + if (!wdev->wext.channel) { + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + struct ieee80211_supported_band *sband; + struct ieee80211_channel *chan; + + sband = rdev->wiphy.bands[band]; + if (!sband) + continue; + + for (i = 0; i < sband->n_channels; i++) { + chan = &sband->channels[i]; + if (chan->flags & IEEE80211_CHAN_NO_IBSS) + continue; + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + wdev->wext.channel = chan; + break; + } + + if (wdev->wext.channel) + break; + } + + if (!wdev->wext.channel) + return -EINVAL; + } + + /* don't join -- SSID is not there */ + if (!wdev->wext.ssid_len) + return 0; + + if (!netif_running(wdev->netdev)) + return 0; + + return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), + wdev->netdev, &wdev->wext); +} + +int cfg80211_ibss_wext_siwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct ieee80211_channel *chan; + int err; + + /* call only for ibss! */ + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) + return -EINVAL; + + if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss) + return -EOPNOTSUPP; + + chan = cfg80211_wext_freq(wdev->wiphy, freq); + if (chan && IS_ERR(chan)) + return PTR_ERR(chan); + + if (chan && + (chan->flags & IEEE80211_CHAN_NO_IBSS || + chan->flags & IEEE80211_CHAN_DISABLED)) + return -EINVAL; + + if (wdev->wext.channel == chan) + return 0; + + if (wdev->ssid_len) { + err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev); + if (err) + return err; + } + + if (chan) { + wdev->wext.channel = chan; + wdev->wext.channel_fixed = true; + } else { + /* cfg80211_ibss_wext_join will pick one if needed */ + wdev->wext.channel_fixed = false; + } + + return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); +} +/* temporary symbol - mark GPL - in the future the handler won't be */ +EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq); + +int cfg80211_ibss_wext_giwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct ieee80211_channel *chan = NULL; + + /* call only for ibss! */ + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) + return -EINVAL; + + if (wdev->current_bss) + chan = wdev->current_bss->channel; + else if (wdev->wext.channel) + chan = wdev->wext.channel; + + if (chan) { + freq->m = chan->center_freq; + freq->e = 6; + return 0; + } + + /* no channel if not joining */ + return -EINVAL; +} +/* temporary symbol - mark GPL - in the future the handler won't be */ +EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq); + +int cfg80211_ibss_wext_siwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + size_t len = data->length; + int err; + + /* call only for ibss! */ + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) + return -EINVAL; + + if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss) + return -EOPNOTSUPP; + + if (wdev->ssid_len) { + err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev); + if (err) + return err; + } + + /* iwconfig uses nul termination in SSID.. */ + if (len > 0 && ssid[len - 1] == '\0') + len--; + + wdev->wext.ssid = wdev->ssid; + memcpy(wdev->wext.ssid, ssid, len); + wdev->wext.ssid_len = len; + + return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); +} +/* temporary symbol - mark GPL - in the future the handler won't be */ +EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid); + +int cfg80211_ibss_wext_giwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + /* call only for ibss! */ + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) + return -EINVAL; + + data->flags = 0; + + if (wdev->ssid_len) { + data->flags = 1; + data->length = wdev->ssid_len; + memcpy(ssid, wdev->ssid, data->length); + } else if (wdev->wext.ssid) { + data->flags = 1; + data->length = wdev->wext.ssid_len; + memcpy(ssid, wdev->wext.ssid, data->length); + } + + return 0; +} +/* temporary symbol - mark GPL - in the future the handler won't be */ +EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid); + +int cfg80211_ibss_wext_siwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + u8 *bssid = ap_addr->sa_data; + int err; + + /* call only for ibss! */ + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) + return -EINVAL; + + if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss) + return -EOPNOTSUPP; + + if (ap_addr->sa_family != ARPHRD_ETHER) + return -EINVAL; + + /* automatic mode */ + if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) + bssid = NULL; + + /* both automatic */ + if (!bssid && !wdev->wext.bssid) + return 0; + + /* fixed already - and no change */ + if (wdev->wext.bssid && bssid && + compare_ether_addr(bssid, wdev->wext.bssid) == 0) + return 0; + + if (wdev->ssid_len) { + err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev); + if (err) + return err; + } + + if (bssid) { + memcpy(wdev->wext_bssid, bssid, ETH_ALEN); + wdev->wext.bssid = wdev->wext_bssid; + } else + wdev->wext.bssid = NULL; + + return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); +} +/* temporary symbol - mark GPL - in the future the handler won't be */ +EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap); + +int cfg80211_ibss_wext_giwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + /* call only for ibss! */ + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) + return -EINVAL; + + ap_addr->sa_family = ARPHRD_ETHER; + + if (wdev->wext.bssid) { + memcpy(ap_addr->sa_data, wdev->wext.bssid, ETH_ALEN); + return 0; + } + + memcpy(ap_addr->sa_data, wdev->bssid, ETH_ALEN); + return 0; +} +/* temporary symbol - mark GPL - in the future the handler won't be */ +EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap); +#endif diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d2cfde659e76..16f86356ac97 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -116,6 +116,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { .len = IEEE80211_MAX_SSID_LEN }, [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 }, [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, + [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG }, }; /* IE validation */ @@ -322,6 +323,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, CMD(assoc, ASSOCIATE); CMD(deauth, DEAUTHENTICATE); CMD(disassoc, DISASSOCIATE); + CMD(join_ibss, JOIN_IBSS); #undef CMD nla_nest_end(msg, nl_cmds); @@ -668,7 +670,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *drv; struct vif_params params; int err, ifindex; - enum nl80211_iftype type; + enum nl80211_iftype otype, ntype; struct net_device *dev; u32 _flags, *flags = NULL; bool change = false; @@ -682,30 +684,27 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) goto unlock_rtnl; ifindex = dev->ifindex; - type = dev->ieee80211_ptr->iftype; + otype = ntype = dev->ieee80211_ptr->iftype; dev_put(dev); if (info->attrs[NL80211_ATTR_IFTYPE]) { - enum nl80211_iftype ntype; - ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); - if (type != ntype) + if (otype != ntype) change = true; - type = ntype; - if (type > NL80211_IFTYPE_MAX) { + if (ntype > NL80211_IFTYPE_MAX) { err = -EINVAL; goto unlock; } } if (!drv->ops->change_virtual_intf || - !(drv->wiphy.interface_modes & (1 << type))) { + !(drv->wiphy.interface_modes & (1 << ntype))) { err = -EOPNOTSUPP; goto unlock; } if (info->attrs[NL80211_ATTR_MESH_ID]) { - if (type != NL80211_IFTYPE_MESH_POINT) { + if (ntype != NL80211_IFTYPE_MESH_POINT) { err = -EINVAL; goto unlock; } @@ -715,7 +714,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) } if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { - if (type != NL80211_IFTYPE_MONITOR) { + if (ntype != NL80211_IFTYPE_MONITOR) { err = -EINVAL; goto unlock; } @@ -730,12 +729,17 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) if (change) err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, - type, flags, ¶ms); + ntype, flags, ¶ms); else err = 0; dev = __dev_get_by_index(&init_net, ifindex); - WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type)); + WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype)); + + if (dev && !err && (ntype != otype)) { + if (otype == NL80211_IFTYPE_ADHOC) + cfg80211_clear_ibss(dev); + } unlock: cfg80211_put_dev(drv); @@ -3052,6 +3056,114 @@ unlock_rtnl: return err; } +static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *drv; + struct net_device *dev; + struct cfg80211_ibss_params ibss; + struct wiphy *wiphy; + int err; + + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) + return -EINVAL; + + if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || + !info->attrs[NL80211_ATTR_SSID] || + !nla_len(info->attrs[NL80211_ATTR_SSID])) + return -EINVAL; + + rtnl_lock(); + + err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); + if (err) + goto unlock_rtnl; + + if (!drv->ops->join_ibss) { + err = -EOPNOTSUPP; + goto out; + } + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { + err = -EOPNOTSUPP; + goto out; + } + + if (!netif_running(dev)) { + err = -ENETDOWN; + goto out; + } + + wiphy = &drv->wiphy; + memset(&ibss, 0, sizeof(ibss)); + + if (info->attrs[NL80211_ATTR_MAC]) + ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); + ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); + ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); + + if (info->attrs[NL80211_ATTR_IE]) { + ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]); + ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); + } + + ibss.channel = ieee80211_get_channel(wiphy, + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); + if (!ibss.channel || + ibss.channel->flags & IEEE80211_CHAN_NO_IBSS || + ibss.channel->flags & IEEE80211_CHAN_DISABLED) { + err = -EINVAL; + goto out; + } + + ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; + + err = cfg80211_join_ibss(drv, dev, &ibss); + +out: + cfg80211_put_dev(drv); + dev_put(dev); +unlock_rtnl: + rtnl_unlock(); + return err; +} + +static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *drv; + struct net_device *dev; + int err; + + rtnl_lock(); + + err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); + if (err) + goto unlock_rtnl; + + if (!drv->ops->leave_ibss) { + err = -EOPNOTSUPP; + goto out; + } + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { + err = -EOPNOTSUPP; + goto out; + } + + if (!netif_running(dev)) { + err = -ENETDOWN; + goto out; + } + + err = cfg80211_leave_ibss(drv, dev); + +out: + cfg80211_put_dev(drv); + dev_put(dev); +unlock_rtnl: + rtnl_unlock(); + return err; +} + static struct genl_ops nl80211_ops[] = { { .cmd = NL80211_CMD_GET_WIPHY, @@ -3253,6 +3365,18 @@ static struct genl_ops nl80211_ops[] = { .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, }, + { + .cmd = NL80211_CMD_JOIN_IBSS, + .doit = nl80211_join_ibss, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + }, + { + .cmd = NL80211_CMD_LEAVE_IBSS, + .doit = nl80211_leave_ibss, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + }, }; static struct genl_multicast_group nl80211_mlme_mcgrp = { .name = "mlme", @@ -3466,6 +3590,40 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, NL80211_CMD_DISASSOCIATE); } +void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *bssid, + gfp_t gfp) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, gfp); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS); + if (!hdr) { + nlmsg_free(msg); + return; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid); + + if (genlmsg_end(msg, hdr) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); + return; + + nla_put_failure: + genlmsg_cancel(msg, hdr); + nlmsg_free(msg); +} + void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *addr, enum nl80211_key_type key_type, int key_id, diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index b3aaa59afa08..17d2d8bfaf75 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -34,4 +34,8 @@ nl80211_send_beacon_hint_event(struct wiphy *wiphy, struct ieee80211_channel *channel_before, struct ieee80211_channel *channel_after); +void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *bssid, + gfp_t gfp); + #endif /* __NET_WIRELESS_NL80211_H */ diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 6fd7bf7b4481..57eaea26b67a 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -285,3 +285,33 @@ int cfg80211_wext_siwmlme(struct net_device *dev, } } EXPORT_SYMBOL(cfg80211_wext_siwmlme); + + +/** + * cfg80211_wext_freq - get wext frequency for non-"auto" + * @wiphy: the wiphy + * @freq: the wext freq encoding + * + * Returns a channel, %NULL for auto, or an ERR_PTR for errors! + */ +struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, + struct iw_freq *freq) +{ + if (freq->e == 0) { + if (freq->m < 0) + return NULL; + else + return ieee80211_get_channel(wiphy, + ieee80211_channel_to_frequency(freq->m)); + } else { + int i, div = 1000000; + for (i = 0; i < freq->e; i++) + div /= 10; + if (div > 0) + return ieee80211_get_channel(wiphy, freq->m / div); + else + return ERR_PTR(-EINVAL); + } + +} +EXPORT_SYMBOL(cfg80211_wext_freq); -- GitLab From af8cdcd828ad751fae8e6cbfe94eef9f2f23b14b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 19 Apr 2009 21:25:43 +0200 Subject: [PATCH 0642/6080] mac80211: convert to cfg80211 IBSS API This converts mac80211 to the new cfg80211 IBSS API, the wext handling functions are called where appropriate. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/cfg.c | 17 ++ net/mac80211/ibss.c | 347 ++++++++++++++++++------------------- net/mac80211/ieee80211_i.h | 35 ++-- net/mac80211/iface.c | 12 +- net/mac80211/main.c | 2 +- net/mac80211/scan.c | 2 - net/mac80211/sta_info.c | 71 +------- net/mac80211/sta_info.h | 3 +- net/mac80211/tx.c | 6 +- net/mac80211/wext.c | 63 +++---- 10 files changed, 228 insertions(+), 330 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index daf75287e92a..14013dc64474 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1283,6 +1283,21 @@ static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, return ieee80211_sta_disassociate(sdata, req->reason_code); } +static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_ibss_params *params) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + return ieee80211_ibss_join(sdata, params); +} + +static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + return ieee80211_ibss_leave(sdata); +} + struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -1319,4 +1334,6 @@ struct cfg80211_ops mac80211_config_ops = { .assoc = ieee80211_assoc, .deauth = ieee80211_deauth, .disassoc = ieee80211_disassoc, + .join_ibss = ieee80211_join_ibss, + .leave_ibss = ieee80211_leave_ibss, }; diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 3201e1f96365..4f7a54518be4 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -59,74 +59,59 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.bssid, 0); } -static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, - const u8 *bssid, const int beacon_int, - const int freq, - const size_t supp_rates_len, - const u8 *supp_rates, - const u16 capability, u64 tsf) +static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, + const u8 *bssid, const int beacon_int, + struct ieee80211_channel *chan, + const size_t supp_rates_len, + const u8 *supp_rates, + const u16 capability, u64 tsf) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; - int res = 0, rates, i, j; + int rates, i, j; struct sk_buff *skb; struct ieee80211_mgmt *mgmt; u8 *pos; struct ieee80211_supported_band *sband; - union iwreq_data wrqu; if (local->ops->reset_tsf) { /* Reset own TSF to allow time synchronization work. */ local->ops->reset_tsf(local_to_hw(local)); } - if ((ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) && - memcmp(ifibss->bssid, bssid, ETH_ALEN) == 0) - return res; + skb = ifibss->skb; + rcu_assign_pointer(ifibss->presp, NULL); + synchronize_rcu(); + skb->data = skb->head; + skb->len = 0; + skb_reset_tail_pointer(skb); + skb_reserve(skb, sdata->local->hw.extra_tx_headroom); - skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); - if (!skb) { - printk(KERN_DEBUG "%s: failed to allocate buffer for probe " - "response\n", sdata->dev->name); - return -ENOMEM; - } - - if (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) { - /* Remove possible STA entries from other IBSS networks. */ - sta_info_flush_delayed(sdata); - } + if (memcmp(ifibss->bssid, bssid, ETH_ALEN)) + sta_info_flush(sdata->local, sdata); memcpy(ifibss->bssid, bssid, ETH_ALEN); - res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); - if (res) - return res; local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10; - sdata->drop_unencrypted = capability & - WLAN_CAPABILITY_PRIVACY ? 1 : 0; - - res = ieee80211_set_freq(sdata, freq); + sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; - if (res) - return res; + ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + local->oper_channel = chan; + local->oper_channel_type = NL80211_CHAN_NO_HT; + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); + sband = local->hw.wiphy->bands[chan->band]; /* Build IBSS probe response */ - - skb_reserve(skb, local->hw.extra_tx_headroom); - - mgmt = (struct ieee80211_mgmt *) - skb_put(skb, 24 + sizeof(mgmt->u.beacon)); + mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon)); memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); memset(mgmt->da, 0xff, ETH_ALEN); memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); - mgmt->u.beacon.beacon_int = - cpu_to_le16(local->hw.conf.beacon_int); + mgmt->u.beacon.beacon_int = cpu_to_le16(local->hw.conf.beacon_int); mgmt->u.beacon.timestamp = cpu_to_le64(tsf); mgmt->u.beacon.capab_info = cpu_to_le16(capability); @@ -147,7 +132,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, pos = skb_put(skb, 2 + 1); *pos++ = WLAN_EID_DS_PARAMS; *pos++ = 1; - *pos++ = ieee80211_frequency_to_channel(freq); + *pos++ = ieee80211_frequency_to_channel(chan->center_freq); } pos = skb_put(skb, 2 + 2); @@ -165,12 +150,15 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, memcpy(pos, &supp_rates[8], rates); } - ifibss->probe_resp = skb; + if (ifibss->ie_len) + memcpy(skb_put(skb, ifibss->ie_len), + ifibss->ie, ifibss->ie_len); + + rcu_assign_pointer(ifibss->presp, skb); ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | IEEE80211_IFCC_BEACON_ENABLED); - rates = 0; for (i = 0; i < supp_rates_len; i++) { int bitrate = (supp_rates[i] & 0x7f) * 5; @@ -181,27 +169,24 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates); - ifibss->flags |= IEEE80211_IBSS_PREV_BSSID_SET; ifibss->state = IEEE80211_IBSS_MLME_JOINED; - mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); + mod_timer(&ifibss->timer, + round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); - memset(&wrqu, 0, sizeof(wrqu)); - memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); - wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL); - - return res; + cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel, + mgmt, skb->len, 0, GFP_KERNEL); + cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); } -static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, - struct ieee80211_bss *bss) +static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, + struct ieee80211_bss *bss) { - return __ieee80211_sta_join_ibss(sdata, - bss->cbss.bssid, - bss->cbss.beacon_interval, - bss->cbss.channel->center_freq, - bss->supp_rates_len, bss->supp_rates, - bss->cbss.capability, - bss->cbss.tsf); + __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid, + bss->cbss.beacon_interval, + bss->cbss.channel, + bss->supp_rates_len, bss->supp_rates, + bss->cbss.capability, + bss->cbss.tsf); } static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, @@ -277,7 +262,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, goto put_bss; /* we use a fixed BSSID */ - if (sdata->u.ibss.flags & IEEE80211_IBSS_BSSID_SET) + if (sdata->u.ibss.bssid) goto put_bss; /* not an IBSS */ @@ -369,13 +354,14 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, struct sta_info *sta; int band = local->hw.conf.channel->band; - /* TODO: Could consider removing the least recently used entry and - * allow new one to be added. */ + /* + * XXX: Consider removing the least recently used entry and + * allow new one to be added. + */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: No room for a new IBSS STA " - "entry %pM\n", sdata->dev->name, addr); - } + if (net_ratelimit()) + printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n", + sdata->dev->name, addr); return NULL; } @@ -432,14 +418,15 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); + mod_timer(&ifibss->timer, + round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT); + if (ieee80211_sta_active_ibss(sdata)) return; - if ((ifibss->flags & IEEE80211_IBSS_BSSID_SET) && - (!(ifibss->flags & IEEE80211_IBSS_AUTO_CHANNEL_SEL))) + if (ifibss->fixed_channel) return; printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " @@ -455,7 +442,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) ieee80211_request_scan(sdata, &sdata->local->int_scan_req); } -static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) +static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; @@ -466,7 +453,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) u16 capability; int i; - if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) { + if (ifibss->fixed_bssid) { memcpy(bssid, ifibss->bssid, ETH_ALEN); } else { /* Generate random, not broadcast, locally administered BSSID. Mix in @@ -482,7 +469,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", sdata->dev->name, bssid); - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + sband = local->hw.wiphy->bands[ifibss->channel->band]; if (local->hw.conf.beacon_int == 0) local->hw.conf.beacon_int = 100; @@ -500,24 +487,20 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) *pos++ = (u8) (rate / 5); } - return __ieee80211_sta_join_ibss(sdata, - bssid, local->hw.conf.beacon_int, - local->hw.conf.channel->center_freq, - sband->n_bitrates, supp_rates, - capability, 0); + __ieee80211_sta_join_ibss(sdata, bssid, local->hw.conf.beacon_int, + ifibss->channel, sband->n_bitrates, + supp_rates, capability, 0); } -static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) +static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_local *local = sdata->local; struct ieee80211_bss *bss; + struct ieee80211_channel *chan = NULL; const u8 *bssid = NULL; int active_ibss; - if (ifibss->ssid_len == 0) - return -EINVAL; - active_ibss = ieee80211_sta_active_ibss(sdata); #ifdef CONFIG_MAC80211_IBSS_DEBUG printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", @@ -525,11 +508,15 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) #endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (active_ibss) - return 0; + return; - if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) + if (ifibss->fixed_bssid) + bssid = ifibss->bssid; + if (ifibss->fixed_channel) + chan = ifibss->channel; + if (!is_zero_ether_addr(ifibss->bssid)) bssid = ifibss->bssid; - bss = (void *)cfg80211_get_bss(local->hw.wiphy, NULL, bssid, + bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid, ifibss->ssid, ifibss->ssid_len, WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); @@ -540,18 +527,14 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) "%pM\n", bss->cbss.bssid, ifibss->bssid); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ - if (bss && - (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) || - memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN))) { - int ret; - + if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) { printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" " based on configured SSID\n", sdata->dev->name, bss->cbss.bssid); - ret = ieee80211_sta_join_ibss(sdata, bss); + ieee80211_sta_join_ibss(sdata, bss); ieee80211_rx_bss_put(local, bss); - return ret; + return; } else if (bss) ieee80211_rx_bss_put(local, bss); @@ -562,29 +545,31 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) /* Selected IBSS not found in current scan results - try to scan */ if (ifibss->state == IEEE80211_IBSS_MLME_JOINED && !ieee80211_sta_active_ibss(sdata)) { - mod_timer(&ifibss->timer, jiffies + - IEEE80211_IBSS_MERGE_INTERVAL); - } else if (time_after(jiffies, local->last_scan_completed + + mod_timer(&ifibss->timer, + round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); + } else if (time_after(jiffies, ifibss->last_scan_completed + IEEE80211_SCAN_INTERVAL)) { printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " "join\n", sdata->dev->name); /* XXX maybe racy? */ if (local->scan_req) - return -EBUSY; + return; memcpy(local->int_scan_req.ssids[0].ssid, ifibss->ssid, IEEE80211_MAX_SSID_LEN); - local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len; - return ieee80211_request_scan(sdata, &local->int_scan_req); + local->int_scan_req.ssids[0].ssid_len = + ifibss->ssid_len; + ieee80211_request_scan(sdata, &local->int_scan_req); } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) { int interval = IEEE80211_SCAN_INTERVAL; if (time_after(jiffies, ifibss->ibss_join_req + IEEE80211_IBSS_JOIN_TIMEOUT)) { - if (!(local->oper_channel->flags & - IEEE80211_CHAN_NO_IBSS)) - return ieee80211_sta_create_ibss(sdata); + if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) { + ieee80211_sta_create_ibss(sdata); + return; + } printk(KERN_DEBUG "%s: IBSS not allowed on" " %d MHz\n", sdata->dev->name, local->hw.conf.channel->center_freq); @@ -595,11 +580,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) } ifibss->state = IEEE80211_IBSS_MLME_SEARCH; - mod_timer(&ifibss->timer, jiffies + interval); - return 0; + mod_timer(&ifibss->timer, + round_jiffies(jiffies + interval)); } - - return 0; } static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, @@ -614,7 +597,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, u8 *pos, *end; if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || - len < 24 + 2 || !ifibss->probe_resp) + len < 24 + 2 || !ifibss->presp) return; if (local->ops->tx_last_beacon) @@ -649,13 +632,13 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, } if (pos[1] != 0 && (pos[1] != ifibss->ssid_len || - memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len) != 0)) { + !memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) { /* Ignore ProbeReq for foreign SSID */ return; } /* Reply with ProbeResp */ - skb = skb_copy(ifibss->probe_resp, GFP_KERNEL); + skb = skb_copy(ifibss->presp, GFP_KERNEL); if (!skb) return; @@ -794,89 +777,21 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata) setup_timer(&ifibss->timer, ieee80211_ibss_timer, (unsigned long) sdata); skb_queue_head_init(&ifibss->skb_queue); - - ifibss->flags |= IEEE80211_IBSS_AUTO_BSSID_SEL | - IEEE80211_IBSS_AUTO_CHANNEL_SEL; -} - -int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata) -{ - struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - - ifibss->flags &= ~IEEE80211_IBSS_PREV_BSSID_SET; - - if (ifibss->ssid_len) - ifibss->flags |= IEEE80211_IBSS_SSID_SET; - else - ifibss->flags &= ~IEEE80211_IBSS_SSID_SET; - - ifibss->ibss_join_req = jiffies; - ifibss->state = IEEE80211_IBSS_MLME_SEARCH; - set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request); - - return 0; -} - -int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len) -{ - struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - - if (len > IEEE80211_MAX_SSID_LEN) - return -EINVAL; - - if (ifibss->ssid_len != len || memcmp(ifibss->ssid, ssid, len) != 0) { - memset(ifibss->ssid, 0, sizeof(ifibss->ssid)); - memcpy(ifibss->ssid, ssid, len); - ifibss->ssid_len = len; - } - - return ieee80211_ibss_commit(sdata); -} - -int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len) -{ - struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - - memcpy(ssid, ifibss->ssid, ifibss->ssid_len); - *len = ifibss->ssid_len; - - return 0; -} - -int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid) -{ - struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - - if (is_valid_ether_addr(bssid)) { - memcpy(ifibss->bssid, bssid, ETH_ALEN); - ifibss->flags |= IEEE80211_IBSS_BSSID_SET; - } else { - memset(ifibss->bssid, 0, ETH_ALEN); - ifibss->flags &= ~IEEE80211_IBSS_BSSID_SET; - } - - if (netif_running(sdata->dev)) { - if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) { - printk(KERN_DEBUG "%s: Failed to config new BSSID to " - "the low-level driver\n", sdata->dev->name); - } - } - - return ieee80211_ibss_commit(sdata); } /* scan finished notification */ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) { - struct ieee80211_sub_if_data *sdata = local->scan_sdata; - struct ieee80211_if_ibss *ifibss; + struct ieee80211_sub_if_data *sdata; - if (sdata && sdata->vif.type == NL80211_IFTYPE_ADHOC) { - ifibss = &sdata->u.ibss; - if ((!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) || - !ieee80211_sta_active_ibss(sdata)) - ieee80211_sta_find_ibss(sdata); + rcu_read_lock(); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (sdata->vif.type != NL80211_IFTYPE_ADHOC) + continue; + sdata->u.ibss.last_scan_completed = jiffies; + ieee80211_sta_find_ibss(sdata); } + rcu_read_unlock(); } ieee80211_rx_result @@ -906,3 +821,71 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, return RX_DROP_MONITOR; } + +int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, + struct cfg80211_ibss_params *params) +{ + struct sk_buff *skb; + + memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); + sdata->u.ibss.ssid_len = params->ssid_len; + + if (params->bssid) { + memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); + sdata->u.ibss.fixed_bssid = true; + } else + sdata->u.ibss.fixed_bssid = false; + + sdata->u.ibss.channel = params->channel; + sdata->u.ibss.fixed_channel = params->channel_fixed; + + if (params->ie) { + sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, + GFP_KERNEL); + if (sdata->u.ibss.ie) + sdata->u.ibss.ie_len = params->ie_len; + } + + skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom + + 36 /* bitrates */ + + 34 /* SSID */ + + 3 /* DS params */ + + 4 /* IBSS params */ + + params->ie_len); + if (!skb) + return -ENOMEM; + + sdata->u.ibss.skb = skb; + sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; + sdata->u.ibss.ibss_join_req = jiffies; + + set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); + queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work); + + return 0; +} + +int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) +{ + struct sk_buff *skb; + + del_timer_sync(&sdata->u.ibss.timer); + clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); + cancel_work_sync(&sdata->u.ibss.work); + clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); + + sta_info_flush(sdata->local, sdata); + + /* remove beacon */ + kfree(sdata->u.ibss.ie); + skb = sdata->u.ibss.presp; + rcu_assign_pointer(sdata->u.ibss.presp, NULL); + ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED); + synchronize_rcu(); + kfree_skb(skb); + + skb_queue_purge(&sdata->u.ibss.skb_queue); + memset(sdata->u.ibss.bssid, 0, ETH_ALEN); + + return 0; +} diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 38c980612518..e770c1e8e08c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -323,14 +323,6 @@ struct ieee80211_if_managed { size_t sme_auth_ie_len; }; -enum ieee80211_ibss_flags { - IEEE80211_IBSS_AUTO_CHANNEL_SEL = BIT(0), - IEEE80211_IBSS_AUTO_BSSID_SEL = BIT(1), - IEEE80211_IBSS_BSSID_SET = BIT(2), - IEEE80211_IBSS_PREV_BSSID_SET = BIT(3), - IEEE80211_IBSS_SSID_SET = BIT(4), -}; - enum ieee80211_ibss_request { IEEE80211_IBSS_REQ_RUN = 0, }; @@ -341,17 +333,20 @@ struct ieee80211_if_ibss { struct sk_buff_head skb_queue; - u8 ssid[IEEE80211_MAX_SSID_LEN]; - u8 ssid_len; - - u32 flags; + unsigned long request; + unsigned long last_scan_completed; + bool fixed_bssid; + bool fixed_channel; u8 bssid[ETH_ALEN]; - - unsigned long request; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 ssid_len, ie_len; + u8 *ie; + struct ieee80211_channel *channel; unsigned long ibss_join_req; - struct sk_buff *probe_resp; /* ProbeResp template for IBSS */ + /* probe response/beacon for IBSS */ + struct sk_buff *presp, *skb; enum { IEEE80211_IBSS_MLME_SEARCH, @@ -630,8 +625,6 @@ struct ieee80211_local { spinlock_t sta_lock; unsigned long num_sta; struct list_head sta_list; - struct list_head sta_flush_list; - struct work_struct sta_flush_work; struct sta_info *sta_hash[STA_HASH_SIZE]; struct timer_list sta_cleanup; @@ -681,7 +674,6 @@ struct ieee80211_local { int scan_ies_len; enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; - unsigned long last_scan_completed; struct delayed_work scan_work; struct ieee80211_sub_if_data *scan_sdata; enum nl80211_channel_type oper_channel_type; @@ -946,10 +938,6 @@ int ieee80211_max_network_latency(struct notifier_block *nb, unsigned long data, void *dummy); /* IBSS code */ -int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata); -int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len); -int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len); -int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid); void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); ieee80211_rx_result @@ -957,6 +945,9 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, struct ieee80211_rx_status *rx_status); struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, u8 *bssid, u8 *addr, u32 supp_rates); +int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, + struct cfg80211_ibss_params *params); +int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata); /* scan/BSS handling */ void ieee80211_scan_work(struct work_struct *work); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 5d60deb219d3..52425975bbbe 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -235,11 +235,7 @@ static int ieee80211_open(struct net_device *dev) netif_addr_unlock_bh(local->mdev); break; case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - if (sdata->vif.type == NL80211_IFTYPE_STATION) - sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET; - else - sdata->u.ibss.flags &= ~IEEE80211_IBSS_PREV_BSSID_SET; + sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET; /* fall through */ default: conf.vif = &sdata->vif; @@ -327,8 +323,6 @@ static int ieee80211_open(struct net_device *dev) */ if (sdata->vif.type == NL80211_IFTYPE_STATION) queue_work(local->hw.workqueue, &sdata->u.mgd.work); - else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - queue_work(local->hw.workqueue, &sdata->u.ibss.work); netif_tx_start_all_queues(dev); @@ -499,7 +493,6 @@ static int ieee80211_stop(struct net_device *dev) /* fall through */ case NL80211_IFTYPE_ADHOC: if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - memset(sdata->u.ibss.bssid, 0, ETH_ALEN); del_timer_sync(&sdata->u.ibss.timer); cancel_work_sync(&sdata->u.ibss.work); synchronize_rcu(); @@ -653,7 +646,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev) mesh_rmc_free(sdata); break; case NL80211_IFTYPE_ADHOC: - kfree_skb(sdata->u.ibss.probe_resp); + if (WARN_ON(sdata->u.ibss.presp)) + kfree_skb(sdata->u.ibss.presp); break; case NL80211_IFTYPE_STATION: kfree(sdata->u.mgd.extra_ie); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 049ce8639806..d26fc399285e 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -209,7 +209,7 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) !!rcu_dereference(sdata->u.ap.beacon); break; case NL80211_IFTYPE_ADHOC: - conf.enable_beacon = !!sdata->u.ibss.probe_resp; + conf.enable_beacon = !!sdata->u.ibss.presp; break; case NL80211_IFTYPE_MESH_POINT: conf.enable_beacon = true; diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 20df861c6c4c..f25b07feabf9 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -295,8 +295,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) cfg80211_scan_done(local->scan_req, aborted); local->scan_req = NULL; - local->last_scan_completed = jiffies; - if (local->hw_scanning) { local->hw_scanning = false; /* diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index c5f14e6bbde2..654a8e963ccb 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -686,41 +686,10 @@ static void sta_info_debugfs_add_work(struct work_struct *work) } #endif -static void __ieee80211_run_pending_flush(struct ieee80211_local *local) -{ - struct sta_info *sta; - unsigned long flags; - - ASSERT_RTNL(); - - spin_lock_irqsave(&local->sta_lock, flags); - while (!list_empty(&local->sta_flush_list)) { - sta = list_first_entry(&local->sta_flush_list, - struct sta_info, list); - list_del(&sta->list); - spin_unlock_irqrestore(&local->sta_lock, flags); - sta_info_destroy(sta); - spin_lock_irqsave(&local->sta_lock, flags); - } - spin_unlock_irqrestore(&local->sta_lock, flags); -} - -static void ieee80211_sta_flush_work(struct work_struct *work) -{ - struct ieee80211_local *local = - container_of(work, struct ieee80211_local, sta_flush_work); - - rtnl_lock(); - __ieee80211_run_pending_flush(local); - rtnl_unlock(); -} - void sta_info_init(struct ieee80211_local *local) { spin_lock_init(&local->sta_lock); INIT_LIST_HEAD(&local->sta_list); - INIT_LIST_HEAD(&local->sta_flush_list); - INIT_WORK(&local->sta_flush_work, ieee80211_sta_flush_work); setup_timer(&local->sta_cleanup, sta_info_cleanup, (unsigned long)local); @@ -741,7 +710,6 @@ int sta_info_start(struct ieee80211_local *local) void sta_info_stop(struct ieee80211_local *local) { del_timer(&local->sta_cleanup); - cancel_work_sync(&local->sta_flush_work); #ifdef CONFIG_MAC80211_DEBUGFS /* * Make sure the debugfs adding work isn't pending after this @@ -752,10 +720,7 @@ void sta_info_stop(struct ieee80211_local *local) cancel_work_sync(&local->sta_debugfs_add); #endif - rtnl_lock(); sta_info_flush(local, NULL); - __ieee80211_run_pending_flush(local); - rtnl_unlock(); } /** @@ -767,7 +732,7 @@ void sta_info_stop(struct ieee80211_local *local) * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs */ int sta_info_flush(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata) + struct ieee80211_sub_if_data *sdata) { struct sta_info *sta, *tmp; LIST_HEAD(tmp_list); @@ -775,7 +740,6 @@ int sta_info_flush(struct ieee80211_local *local, unsigned long flags; might_sleep(); - ASSERT_RTNL(); spin_lock_irqsave(&local->sta_lock, flags); list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { @@ -795,39 +759,6 @@ int sta_info_flush(struct ieee80211_local *local, return ret; } -/** - * sta_info_flush_delayed - flush matching STA entries from the STA table - * - * This function unlinks all stations for a given interface and queues - * them for freeing. Note that the workqueue function scheduled here has - * to run before any new keys can be added to the system to avoid set_key() - * callback ordering issues. - * - * @sdata: the interface - */ -void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata) -{ - struct ieee80211_local *local = sdata->local; - struct sta_info *sta, *tmp; - unsigned long flags; - bool work = false; - - spin_lock_irqsave(&local->sta_lock, flags); - list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { - if (sdata == sta->sdata) { - __sta_info_unlink(&sta); - if (sta) { - list_add_tail(&sta->list, - &local->sta_flush_list); - work = true; - } - } - } - if (work) - schedule_work(&local->sta_flush_work); - spin_unlock_irqrestore(&local->sta_lock, flags); -} - void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, unsigned long exp_time) { diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 5534d489f506..31a8990ce401 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -442,8 +442,7 @@ void sta_info_init(struct ieee80211_local *local); int sta_info_start(struct ieee80211_local *local); void sta_info_stop(struct ieee80211_local *local); int sta_info_flush(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata); -void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata); + struct ieee80211_sub_if_data *sdata); void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, unsigned long exp_time); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index f336cc731df6..c53d77db3e4f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -2102,18 +2102,18 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; struct ieee80211_hdr *hdr; + struct sk_buff *presp = rcu_dereference(ifibss->presp); - if (!ifibss->probe_resp) + if (!presp) goto out; - skb = skb_copy(ifibss->probe_resp, GFP_ATOMIC); + skb = skb_copy(presp, GFP_ATOMIC); if (!skb) goto out; hdr = (struct ieee80211_hdr *) skb->data; hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); - } else if (ieee80211_vif_is_mesh(&sdata->vif)) { struct ieee80211_mgmt *mgmt; u8 *pos; diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 896704cf94e1..eb63fc148019 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -149,17 +149,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_CHANNEL_SEL; + return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); else if (sdata->vif.type == NL80211_IFTYPE_STATION) sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL; /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ if (freq->e == 0) { if (freq->m < 0) { - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - sdata->u.ibss.flags |= - IEEE80211_IBSS_AUTO_CHANNEL_SEL; - else if (sdata->vif.type == NL80211_IFTYPE_STATION) + if (sdata->vif.type == NL80211_IFTYPE_STATION) sdata->u.mgd.flags |= IEEE80211_STA_AUTO_CHANNEL_SEL; return 0; @@ -183,6 +180,10 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev, struct iw_freq *freq, char *extra) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + if (sdata->vif.type == NL80211_IFTYPE_ADHOC) + return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); freq->m = local->hw.conf.channel->center_freq; freq->e = 6; @@ -195,15 +196,17 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid) { - struct ieee80211_sub_if_data *sdata; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); size_t len = data->length; int ret; + if (sdata->vif.type == NL80211_IFTYPE_ADHOC) + return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); + /* iwconfig uses nul termination in SSID.. */ if (len > 0 && ssid[len - 1] == '\0') len--; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (sdata->vif.type == NL80211_IFTYPE_STATION) { if (data->flags) sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; @@ -217,8 +220,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev, sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; ieee80211_sta_req_auth(sdata); return 0; - } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - return ieee80211_ibss_set_ssid(sdata, ssid, len); + } return -EOPNOTSUPP; } @@ -229,9 +231,13 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev, struct iw_point *data, char *ssid) { size_t len; - struct ieee80211_sub_if_data *sdata; + sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + if (sdata->vif.type == NL80211_IFTYPE_ADHOC) + return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); + if (sdata->vif.type == NL80211_IFTYPE_STATION) { int res = ieee80211_sta_get_ssid(sdata, ssid, &len); if (res == 0) { @@ -240,14 +246,6 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev, } else data->flags = 0; return res; - } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - int res = ieee80211_ibss_get_ssid(sdata, ssid, &len); - if (res == 0) { - data->length = len; - data->flags = 1; - } else - data->flags = 0; - return res; } return -EOPNOTSUPP; @@ -258,9 +256,11 @@ static int ieee80211_ioctl_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { - struct ieee80211_sub_if_data *sdata; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + if (sdata->vif.type == NL80211_IFTYPE_ADHOC) + return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); - sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (sdata->vif.type == NL80211_IFTYPE_STATION) { int ret; @@ -277,16 +277,6 @@ static int ieee80211_ioctl_siwap(struct net_device *dev, sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; ieee80211_sta_req_auth(sdata); return 0; - } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - if (is_zero_ether_addr((u8 *) &ap_addr->sa_data)) - sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL | - IEEE80211_IBSS_AUTO_CHANNEL_SEL; - else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data)) - sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL; - else - sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_BSSID_SEL; - - return ieee80211_ibss_set_bssid(sdata, (u8 *) &ap_addr->sa_data); } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { /* * If it is necessary to update the WDS peer address @@ -312,9 +302,11 @@ static int ieee80211_ioctl_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { - struct ieee80211_sub_if_data *sdata; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + if (sdata->vif.type == NL80211_IFTYPE_ADHOC) + return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); - sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (sdata->vif.type == NL80211_IFTYPE_STATION) { if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) { ap_addr->sa_family = ARPHRD_ETHER; @@ -322,13 +314,6 @@ static int ieee80211_ioctl_giwap(struct net_device *dev, } else memset(&ap_addr->sa_data, 0, ETH_ALEN); return 0; - } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - if (sdata->u.ibss.state == IEEE80211_IBSS_MLME_JOINED) { - ap_addr->sa_family = ARPHRD_ETHER; - memcpy(&ap_addr->sa_data, sdata->u.ibss.bssid, ETH_ALEN); - } else - memset(&ap_addr->sa_data, 0, ETH_ALEN); - return 0; } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { ap_addr->sa_family = ARPHRD_ETHER; memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); -- GitLab From d323655372590c533c275b1d798f9d1221efb5c6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Apr 2009 14:31:42 +0200 Subject: [PATCH 0643/6080] cfg80211: clean up includes Trying to separate header files into net/wireless.h and net/cfg80211.h has been a source of confusion. Remove net/wireless.h (because there also is the linux/wireless.h) and subsume everything into net/cfg80211.h -- except the definitions for regulatory structures which get moved to a new header net/regulatory.h. The "new" net/cfg80211.h is now divided into sections. There are no real changes in this patch but code shuffling and some very minor documentation fixes. I have also, to make things reflect reality, put in a copyright line for Luis to net/regulatory.h since that is probably exclusively written by him but was formerly in a file that only had my copyright line. Signed-off-by: Johannes Berg Cc: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/ar9170.h | 2 +- drivers/net/wireless/ath/ar9170/usb.h | 2 +- drivers/net/wireless/ath/ath9k/eeprom.h | 2 +- drivers/net/wireless/ath/regd.c | 1 - drivers/net/wireless/ath/regd.h | 1 - drivers/net/wireless/rndis_wlan.c | 1 - include/net/cfg80211.h | 709 +++++++++++++++++++---- include/net/mac80211.h | 1 - include/net/regulatory.h | 101 ++++ include/net/wireless.h | 492 ---------------- net/mac80211/ht.c | 1 - net/mac80211/ieee80211_i.h | 1 - net/mac80211/spectmgmt.c | 2 +- net/wireless/core.c | 1 - net/wireless/core.h | 1 - net/wireless/ibss.c | 1 - net/wireless/reg.c | 1 - net/wireless/util.c | 6 +- net/wireless/wext-compat.c | 1 - 19 files changed, 690 insertions(+), 637 deletions(-) create mode 100644 include/net/regulatory.h delete mode 100644 include/net/wireless.h diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index f797495faa56..2522a190fdfb 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h @@ -40,7 +40,7 @@ #include #include -#include +#include #include #ifdef CONFIG_AR9170_LEDS #include diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h index f5852924cd64..ac42586495d8 100644 --- a/drivers/net/wireless/ath/ar9170/usb.h +++ b/drivers/net/wireless/ath/ar9170/usb.h @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #include #include "eeprom.h" diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 9a7715df5cff..7c59dc47f912 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -17,7 +17,7 @@ #ifndef EEPROM_H #define EEPROM_H -#include +#include #define AH_USE_EEPROM 0x1 diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 526c7f1308db..fdf07c822081 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "regd.h" #include "regd_common.h" diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h index eba7c7123b50..07291ccb23f2 100644 --- a/drivers/net/wireless/ath/regd.h +++ b/drivers/net/wireless/ath/regd.h @@ -20,7 +20,6 @@ #include #include -#include #define NO_CTL 0xff #define SD_NO_CTL 0xE0 diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 239e6a14eae2..43e0ba61df24 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5287a3e56e7c..601eac64b02d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1,70 +1,217 @@ #ifndef __NET_CFG80211_H #define __NET_CFG80211_H +/* + * 802.11 device and configuration interface + * + * Copyright 2006-2009 Johannes Berg + * + * 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 + /* remove once we remove the wext stuff */ +#include +#include + /* - * 802.11 configuration in-kernel interface + * wireless hardware capability structures + */ + +/** + * enum ieee80211_band - supported frequency bands + * + * The bands are assigned this way because the supported + * bitrates differ in these bands. * - * Copyright 2006, 2007 Johannes Berg + * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band + * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7) */ +enum ieee80211_band { + IEEE80211_BAND_2GHZ, + IEEE80211_BAND_5GHZ, + + /* keep last */ + IEEE80211_NUM_BANDS +}; /** - * struct vif_params - describes virtual interface parameters - * @mesh_id: mesh ID to use - * @mesh_id_len: length of the mesh ID + * enum ieee80211_channel_flags - channel flags + * + * Channel flags set by the regulatory control code. + * + * @IEEE80211_CHAN_DISABLED: This channel is disabled. + * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted + * on this channel. + * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. + * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. + * @IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel + * is not permitted. + * @IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel + * is not permitted. */ -struct vif_params { - u8 *mesh_id; - int mesh_id_len; +enum ieee80211_channel_flags { + IEEE80211_CHAN_DISABLED = 1<<0, + IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, + IEEE80211_CHAN_NO_IBSS = 1<<2, + IEEE80211_CHAN_RADAR = 1<<3, + IEEE80211_CHAN_NO_FAT_ABOVE = 1<<4, + IEEE80211_CHAN_NO_FAT_BELOW = 1<<5, }; -/* Radiotap header iteration - * implemented in net/wireless/radiotap.c - * docs in Documentation/networking/radiotap-headers.txt +/** + * struct ieee80211_channel - channel definition + * + * This structure describes a single channel for use + * with cfg80211. + * + * @center_freq: center frequency in MHz + * @max_bandwidth: maximum allowed bandwidth for this channel, in MHz + * @hw_value: hardware-specific value for the channel + * @flags: channel flags from &enum ieee80211_channel_flags. + * @orig_flags: channel flags at registration time, used by regulatory + * code to support devices with additional restrictions + * @band: band this channel belongs to. + * @max_antenna_gain: maximum antenna gain in dBi + * @max_power: maximum transmission power (in dBm) + * @beacon_found: helper to regulatory code to indicate when a beacon + * has been found on this channel. Use regulatory_hint_found_beacon() + * to enable this, this is is useful only on 5 GHz band. + * @orig_mag: internal use + * @orig_mpwr: internal use */ +struct ieee80211_channel { + enum ieee80211_band band; + u16 center_freq; + u8 max_bandwidth; + u16 hw_value; + u32 flags; + int max_antenna_gain; + int max_power; + bool beacon_found; + u32 orig_flags; + int orig_mag, orig_mpwr; +}; + /** - * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args - * @rtheader: pointer to the radiotap header we are walking through - * @max_length: length of radiotap header in cpu byte ordering - * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg - * @this_arg: pointer to current radiotap arg - * @arg_index: internal next argument index - * @arg: internal next argument pointer - * @next_bitmap: internal pointer to next present u32 - * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present + * enum ieee80211_rate_flags - rate flags + * + * Hardware/specification flags for rates. These are structured + * in a way that allows using the same bitrate structure for + * different bands/PHY modes. + * + * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short + * preamble on this bitrate; only relevant in 2.4GHz band and + * with CCK rates. + * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate + * when used with 802.11a (on the 5 GHz band); filled by the + * core code when registering the wiphy. + * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate + * when used with 802.11b (on the 2.4 GHz band); filled by the + * core code when registering the wiphy. + * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate + * when used with 802.11g (on the 2.4 GHz band); filled by the + * core code when registering the wiphy. + * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. */ +enum ieee80211_rate_flags { + IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, + IEEE80211_RATE_MANDATORY_A = 1<<1, + IEEE80211_RATE_MANDATORY_B = 1<<2, + IEEE80211_RATE_MANDATORY_G = 1<<3, + IEEE80211_RATE_ERP_G = 1<<4, +}; -struct ieee80211_radiotap_iterator { - struct ieee80211_radiotap_header *rtheader; - int max_length; - int this_arg_index; - u8 *this_arg; +/** + * struct ieee80211_rate - bitrate definition + * + * This structure describes a bitrate that an 802.11 PHY can + * operate with. The two values @hw_value and @hw_value_short + * are only for driver use when pointers to this structure are + * passed around. + * + * @flags: rate-specific flags + * @bitrate: bitrate in units of 100 Kbps + * @hw_value: driver/hardware value for this rate + * @hw_value_short: driver/hardware value for this rate when + * short preamble is used + */ +struct ieee80211_rate { + u32 flags; + u16 bitrate; + u16 hw_value, hw_value_short; +}; - int arg_index; - u8 *arg; - __le32 *next_bitmap; - u32 bitmap_shifter; +/** + * struct ieee80211_sta_ht_cap - STA's HT capabilities + * + * This structure describes most essential parameters needed + * to describe 802.11n HT capabilities for an STA. + * + * @ht_supported: is HT supported by the STA + * @cap: HT capabilities map as described in 802.11n spec + * @ampdu_factor: Maximum A-MPDU length factor + * @ampdu_density: Minimum A-MPDU spacing + * @mcs: Supported MCS rates + */ +struct ieee80211_sta_ht_cap { + u16 cap; /* use IEEE80211_HT_CAP_ */ + bool ht_supported; + u8 ampdu_factor; + u8 ampdu_density; + struct ieee80211_mcs_info mcs; }; -extern int ieee80211_radiotap_iterator_init( - struct ieee80211_radiotap_iterator *iterator, - struct ieee80211_radiotap_header *radiotap_header, - int max_length); +/** + * struct ieee80211_supported_band - frequency band definition + * + * This structure describes a frequency band a wiphy + * is able to operate in. + * + * @channels: Array of channels the hardware can operate in + * in this band. + * @band: the band this structure represents + * @n_channels: Number of channels in @channels + * @bitrates: Array of bitrates the hardware can operate with + * in this band. Must be sorted to give a valid "supported + * rates" IE, i.e. CCK rates first, then OFDM. + * @n_bitrates: Number of bitrates in @bitrates + */ +struct ieee80211_supported_band { + struct ieee80211_channel *channels; + struct ieee80211_rate *bitrates; + enum ieee80211_band band; + int n_channels; + int n_bitrates; + struct ieee80211_sta_ht_cap ht_cap; +}; -extern int ieee80211_radiotap_iterator_next( - struct ieee80211_radiotap_iterator *iterator); +/* + * Wireless hardware/device configuration structures and methods + */ +/** + * struct vif_params - describes virtual interface parameters + * @mesh_id: mesh ID to use + * @mesh_id_len: length of the mesh ID + */ +struct vif_params { + u8 *mesh_id; + int mesh_id_len; +}; - /** +/** * struct key_params - key information * * Information about a key @@ -347,92 +494,6 @@ struct bss_parameters { u8 basic_rates_len; }; -/** - * enum environment_cap - Environment parsed from country IE - * @ENVIRON_ANY: indicates country IE applies to both indoor and - * outdoor operation. - * @ENVIRON_INDOOR: indicates country IE applies only to indoor operation - * @ENVIRON_OUTDOOR: indicates country IE applies only to outdoor operation - */ -enum environment_cap { - ENVIRON_ANY, - ENVIRON_INDOOR, - ENVIRON_OUTDOOR, -}; - -/** - * struct regulatory_request - used to keep track of regulatory requests - * - * @wiphy_idx: this is set if this request's initiator is - * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This - * can be used by the wireless core to deal with conflicts - * and potentially inform users of which devices specifically - * cased the conflicts. - * @initiator: indicates who sent this request, could be any of - * of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*) - * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested - * regulatory domain. We have a few special codes: - * 00 - World regulatory domain - * 99 - built by driver but a specific alpha2 cannot be determined - * 98 - result of an intersection between two regulatory domains - * @intersect: indicates whether the wireless core should intersect - * the requested regulatory domain with the presently set regulatory - * domain. - * @country_ie_checksum: checksum of the last processed and accepted - * country IE - * @country_ie_env: lets us know if the AP is telling us we are outdoor, - * indoor, or if it doesn't matter - * @list: used to insert into the reg_requests_list linked list - */ -struct regulatory_request { - int wiphy_idx; - enum nl80211_reg_initiator initiator; - char alpha2[2]; - bool intersect; - u32 country_ie_checksum; - enum environment_cap country_ie_env; - struct list_head list; -}; - -struct ieee80211_freq_range { - u32 start_freq_khz; - u32 end_freq_khz; - u32 max_bandwidth_khz; -}; - -struct ieee80211_power_rule { - u32 max_antenna_gain; - u32 max_eirp; -}; - -struct ieee80211_reg_rule { - struct ieee80211_freq_range freq_range; - struct ieee80211_power_rule power_rule; - u32 flags; -}; - -struct ieee80211_regdomain { - u32 n_reg_rules; - char alpha2[2]; - struct ieee80211_reg_rule reg_rules[]; -}; - -#define MHZ_TO_KHZ(freq) ((freq) * 1000) -#define KHZ_TO_MHZ(freq) ((freq) / 1000) -#define DBI_TO_MBI(gain) ((gain) * 100) -#define MBI_TO_DBI(gain) ((gain) / 100) -#define DBM_TO_MBM(gain) ((gain) * 100) -#define MBM_TO_DBM(gain) ((gain) / 100) - -#define REG_RULE(start, end, bw, gain, eirp, reg_flags) { \ - .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \ - .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \ - .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \ - .power_rule.max_antenna_gain = DBI_TO_MBI(gain), \ - .power_rule.max_eirp = DBM_TO_MBM(eirp), \ - .flags = reg_flags, \ - } - struct mesh_config { /* Timeouts in ms */ /* Mesh plink management parameters */ @@ -853,7 +914,396 @@ struct cfg80211_ops { int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); }; -/* temporary wext handlers */ +/* + * wireless hardware and networking interfaces structures + * and registration/helper functions + */ + +/** + * struct wiphy - wireless hardware description + * @idx: the wiphy index assigned to this item + * @class_dev: the class device representing /sys/class/ieee80211/ + * @custom_regulatory: tells us the driver for this device + * has its own custom regulatory domain and cannot identify the + * ISO / IEC 3166 alpha2 it belongs to. When this is enabled + * we will disregard the first regulatory hint (when the + * initiator is %REGDOM_SET_BY_CORE). + * @strict_regulatory: tells us the driver for this device will ignore + * regulatory domain settings until it gets its own regulatory domain + * via its regulatory_hint(). After its gets its own regulatory domain + * it will only allow further regulatory domain settings to further + * enhance compliance. For example if channel 13 and 14 are disabled + * by this regulatory domain no user regulatory domain can enable these + * channels at a later time. This can be used for devices which do not + * have calibration information gauranteed for frequencies or settings + * outside of its regulatory domain. + * @reg_notifier: the driver's regulatory notification callback + * @regd: the driver's regulatory domain, if one was requested via + * the regulatory_hint() API. This can be used by the driver + * on the reg_notifier() if it chooses to ignore future + * regulatory domain changes caused by other drivers. + * @signal_type: signal type reported in &struct cfg80211_bss. + * @cipher_suites: supported cipher suites + * @n_cipher_suites: number of supported cipher suites + */ +struct wiphy { + /* assign these fields before you register the wiphy */ + + /* permanent MAC address */ + u8 perm_addr[ETH_ALEN]; + + /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ + u16 interface_modes; + + bool custom_regulatory; + bool strict_regulatory; + + enum cfg80211_signal_type signal_type; + + int bss_priv_size; + u8 max_scan_ssids; + u16 max_scan_ie_len; + + int n_cipher_suites; + const u32 *cipher_suites; + + /* If multiple wiphys are registered and you're handed e.g. + * a regular netdev with assigned ieee80211_ptr, you won't + * know whether it points to a wiphy your driver has registered + * or not. Assign this to something global to your driver to + * help determine whether you own this wiphy or not. */ + void *privid; + + struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; + + /* Lets us get back the wiphy on the callback */ + int (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request); + + /* fields below are read-only, assigned by cfg80211 */ + + const struct ieee80211_regdomain *regd; + + /* the item in /sys/class/ieee80211/ points to this, + * you need use set_wiphy_dev() (see below) */ + struct device dev; + + /* dir in debugfs: ieee80211/ */ + struct dentry *debugfsdir; + + char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); +}; + +/** + * wiphy_priv - return priv from wiphy + * + * @wiphy: the wiphy whose priv pointer to return + */ +static inline void *wiphy_priv(struct wiphy *wiphy) +{ + BUG_ON(!wiphy); + return &wiphy->priv; +} + +/** + * set_wiphy_dev - set device pointer for wiphy + * + * @wiphy: The wiphy whose device to bind + * @dev: The device to parent it to + */ +static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev) +{ + wiphy->dev.parent = dev; +} + +/** + * wiphy_dev - get wiphy dev pointer + * + * @wiphy: The wiphy whose device struct to look up + */ +static inline struct device *wiphy_dev(struct wiphy *wiphy) +{ + return wiphy->dev.parent; +} + +/** + * wiphy_name - get wiphy name + * + * @wiphy: The wiphy whose name to return + */ +static inline const char *wiphy_name(struct wiphy *wiphy) +{ + return dev_name(&wiphy->dev); +} + +/** + * wiphy_new - create a new wiphy for use with cfg80211 + * + * @ops: The configuration operations for this device + * @sizeof_priv: The size of the private area to allocate + * + * Create a new wiphy and associate the given operations with it. + * @sizeof_priv bytes are allocated for private use. + * + * The returned pointer must be assigned to each netdev's + * ieee80211_ptr for proper operation. + */ +struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv); + +/** + * wiphy_register - register a wiphy with cfg80211 + * + * @wiphy: The wiphy to register. + * + * Returns a non-negative wiphy index or a negative error code. + */ +extern int wiphy_register(struct wiphy *wiphy); + +/** + * wiphy_unregister - deregister a wiphy from cfg80211 + * + * @wiphy: The wiphy to unregister. + * + * After this call, no more requests can be made with this priv + * pointer, but the call may sleep to wait for an outstanding + * request that is being handled. + */ +extern void wiphy_unregister(struct wiphy *wiphy); + +/** + * wiphy_free - free wiphy + * + * @wiphy: The wiphy to free + */ +extern void wiphy_free(struct wiphy *wiphy); + +/** + * struct wireless_dev - wireless per-netdev state + * + * This structure must be allocated by the driver/stack + * that uses the ieee80211_ptr field in struct net_device + * (this is intentional so it can be allocated along with + * the netdev.) + * + * @wiphy: pointer to hardware description + * @iftype: interface type + * @list: (private) Used to collect the interfaces + * @netdev: (private) Used to reference back to the netdev + * @current_bss: (private) Used by the internal configuration code + * @bssid: (private) Used by the internal configuration code + * @ssid: (private) Used by the internal configuration code + * @ssid_len: (private) Used by the internal configuration code + * @wext: (private) Used by the internal wireless extensions compat code + * @wext_bssid: (private) Used by the internal wireless extensions compat code + */ +struct wireless_dev { + struct wiphy *wiphy; + enum nl80211_iftype iftype; + + /* private to the generic wireless code */ + struct list_head list; + struct net_device *netdev; + + /* currently used for IBSS - might be rearranged in the future */ + struct cfg80211_bss *current_bss; + u8 bssid[ETH_ALEN]; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 ssid_len; + +#ifdef CONFIG_WIRELESS_EXT + /* wext data */ + struct cfg80211_ibss_params wext; + u8 wext_bssid[ETH_ALEN]; +#endif +}; + +/** + * wdev_priv - return wiphy priv from wireless_dev + * + * @wdev: The wireless device whose wiphy's priv pointer to return + */ +static inline void *wdev_priv(struct wireless_dev *wdev) +{ + BUG_ON(!wdev); + return wiphy_priv(wdev->wiphy); +} + +/* + * Utility functions + */ + +/** + * ieee80211_channel_to_frequency - convert channel number to frequency + */ +extern int ieee80211_channel_to_frequency(int chan); + +/** + * ieee80211_frequency_to_channel - convert frequency to channel number + */ +extern int ieee80211_frequency_to_channel(int freq); + +/* + * Name indirection necessary because the ieee80211 code also has + * a function named "ieee80211_get_channel", so if you include + * cfg80211's header file you get cfg80211's version, if you try + * to include both header files you'll (rightfully!) get a symbol + * clash. + */ +extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy, + int freq); +/** + * ieee80211_get_channel - get channel struct from wiphy for specified frequency + */ +static inline struct ieee80211_channel * +ieee80211_get_channel(struct wiphy *wiphy, int freq) +{ + return __ieee80211_get_channel(wiphy, freq); +} + +/** + * ieee80211_get_response_rate - get basic rate for a given rate + * + * @sband: the band to look for rates in + * @basic_rates: bitmap of basic rates + * @bitrate: the bitrate for which to find the basic rate + * + * This function returns the basic rate corresponding to a given + * bitrate, that is the next lower bitrate contained in the basic + * rate map, which is, for this function, given as a bitmap of + * indices of rates in the band's bitrate table. + */ +struct ieee80211_rate * +ieee80211_get_response_rate(struct ieee80211_supported_band *sband, + u32 basic_rates, int bitrate); + +/* + * Radiotap parsing functions -- for controlled injection support + * + * Implemented in net/wireless/radiotap.c + * Documentation in Documentation/networking/radiotap-headers.txt + */ + +/** + * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args + * @rtheader: pointer to the radiotap header we are walking through + * @max_length: length of radiotap header in cpu byte ordering + * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg + * @this_arg: pointer to current radiotap arg + * @arg_index: internal next argument index + * @arg: internal next argument pointer + * @next_bitmap: internal pointer to next present u32 + * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present + */ + +struct ieee80211_radiotap_iterator { + struct ieee80211_radiotap_header *rtheader; + int max_length; + int this_arg_index; + u8 *this_arg; + + int arg_index; + u8 *arg; + __le32 *next_bitmap; + u32 bitmap_shifter; +}; + +extern int ieee80211_radiotap_iterator_init( + struct ieee80211_radiotap_iterator *iterator, + struct ieee80211_radiotap_header *radiotap_header, + int max_length); + +extern int ieee80211_radiotap_iterator_next( + struct ieee80211_radiotap_iterator *iterator); + +/* + * Regulatory helper functions for wiphys + */ + +/** + * regulatory_hint - driver hint to the wireless core a regulatory domain + * @wiphy: the wireless device giving the hint (used only for reporting + * conflicts) + * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain + * should be in. If @rd is set this should be NULL. Note that if you + * set this to NULL you should still set rd->alpha2 to some accepted + * alpha2. + * + * Wireless drivers can use this function to hint to the wireless core + * what it believes should be the current regulatory domain by + * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory + * domain should be in or by providing a completely build regulatory domain. + * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried + * for a regulatory domain structure for the respective country. + * + * The wiphy must have been registered to cfg80211 prior to this call. + * For cfg80211 drivers this means you must first use wiphy_register(), + * for mac80211 drivers you must first use ieee80211_register_hw(). + * + * Drivers should check the return value, its possible you can get + * an -ENOMEM. + */ +extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2); + +/** + * regulatory_hint_11d - hints a country IE as a regulatory domain + * @wiphy: the wireless device giving the hint (used only for reporting + * conflicts) + * @country_ie: pointer to the country IE + * @country_ie_len: length of the country IE + * + * We will intersect the rd with the what CRDA tells us should apply + * for the alpha2 this country IE belongs to, this prevents APs from + * sending us incorrect or outdated information against a country. + */ +extern void regulatory_hint_11d(struct wiphy *wiphy, + u8 *country_ie, + u8 country_ie_len); +/** + * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain + * @wiphy: the wireless device we want to process the regulatory domain on + * @regd: the custom regulatory domain to use for this wiphy + * + * Drivers can sometimes have custom regulatory domains which do not apply + * to a specific country. Drivers can use this to apply such custom regulatory + * domains. This routine must be called prior to wiphy registration. The + * custom regulatory domain will be trusted completely and as such previous + * default channel settings will be disregarded. If no rule is found for a + * channel on the regulatory domain the channel will be disabled. + */ +extern void wiphy_apply_custom_regulatory( + struct wiphy *wiphy, + const struct ieee80211_regdomain *regd); + +/** + * freq_reg_info - get regulatory information for the given frequency + * @wiphy: the wiphy for which we want to process this rule for + * @center_freq: Frequency in KHz for which we want regulatory information for + * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one + * you can set this to 0. If this frequency is allowed we then set + * 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 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. + */ +extern int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth, + const struct ieee80211_reg_rule **reg_rule); + +/* + * Temporary wext handlers & helper functions + * + * In the future cfg80211 will simply assign the entire wext handler + * structure to netdevs it manages, but we're not there yet. + */ int cfg80211_wext_giwname(struct net_device *dev, struct iw_request_info *info, char *name, char *extra); @@ -892,10 +1342,14 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra); -/* wext helper for now (to be removed) */ struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); +/* + * callbacks for asynchronous cfg80211 methods, notification + * functions and BSS handling helpers + */ + /** * cfg80211_scan_done - notify that scan finished * @@ -949,6 +1403,7 @@ struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy, const u8 *meshid, size_t meshidlen, const u8 *meshcfg); void cfg80211_put_bss(struct cfg80211_bss *bss); + /** * cfg80211_unlink_bss - unlink BSS from internal data structures * @wiphy: the wiphy diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 52808bdcc6ca..d9686917252b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -19,7 +19,6 @@ #include #include #include -#include #include /** diff --git a/include/net/regulatory.h b/include/net/regulatory.h new file mode 100644 index 000000000000..47995b81c5d7 --- /dev/null +++ b/include/net/regulatory.h @@ -0,0 +1,101 @@ +#ifndef __NET_REGULATORY_H +#define __NET_REGULATORY_H +/* + * regulatory support structures + * + * Copyright 2008-2009 Luis R. Rodriguez + * + * 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. + */ + + +/** + * enum environment_cap - Environment parsed from country IE + * @ENVIRON_ANY: indicates country IE applies to both indoor and + * outdoor operation. + * @ENVIRON_INDOOR: indicates country IE applies only to indoor operation + * @ENVIRON_OUTDOOR: indicates country IE applies only to outdoor operation + */ +enum environment_cap { + ENVIRON_ANY, + ENVIRON_INDOOR, + ENVIRON_OUTDOOR, +}; + +/** + * struct regulatory_request - used to keep track of regulatory requests + * + * @wiphy_idx: this is set if this request's initiator is + * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This + * can be used by the wireless core to deal with conflicts + * and potentially inform users of which devices specifically + * cased the conflicts. + * @initiator: indicates who sent this request, could be any of + * of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*) + * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested + * regulatory domain. We have a few special codes: + * 00 - World regulatory domain + * 99 - built by driver but a specific alpha2 cannot be determined + * 98 - result of an intersection between two regulatory domains + * @intersect: indicates whether the wireless core should intersect + * the requested regulatory domain with the presently set regulatory + * domain. + * @country_ie_checksum: checksum of the last processed and accepted + * country IE + * @country_ie_env: lets us know if the AP is telling us we are outdoor, + * indoor, or if it doesn't matter + * @list: used to insert into the reg_requests_list linked list + */ +struct regulatory_request { + int wiphy_idx; + enum nl80211_reg_initiator initiator; + char alpha2[2]; + bool intersect; + u32 country_ie_checksum; + enum environment_cap country_ie_env; + struct list_head list; +}; + +struct ieee80211_freq_range { + u32 start_freq_khz; + u32 end_freq_khz; + u32 max_bandwidth_khz; +}; + +struct ieee80211_power_rule { + u32 max_antenna_gain; + u32 max_eirp; +}; + +struct ieee80211_reg_rule { + struct ieee80211_freq_range freq_range; + struct ieee80211_power_rule power_rule; + u32 flags; +}; + +struct ieee80211_regdomain { + u32 n_reg_rules; + char alpha2[2]; + struct ieee80211_reg_rule reg_rules[]; +}; + +#define MHZ_TO_KHZ(freq) ((freq) * 1000) +#define KHZ_TO_MHZ(freq) ((freq) / 1000) +#define DBI_TO_MBI(gain) ((gain) * 100) +#define MBI_TO_DBI(gain) ((gain) / 100) +#define DBM_TO_MBM(gain) ((gain) * 100) +#define MBM_TO_DBM(gain) ((gain) / 100) + +#define REG_RULE(start, end, bw, gain, eirp, reg_flags) \ +{ \ + .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \ + .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \ + .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \ + .power_rule.max_antenna_gain = DBI_TO_MBI(gain),\ + .power_rule.max_eirp = DBM_TO_MBM(eirp), \ + .flags = reg_flags, \ +} + +#endif diff --git a/include/net/wireless.h b/include/net/wireless.h deleted file mode 100644 index abd27b033331..000000000000 --- a/include/net/wireless.h +++ /dev/null @@ -1,492 +0,0 @@ -#ifndef __NET_WIRELESS_H -#define __NET_WIRELESS_H - -/* - * 802.11 device management - * - * Copyright 2007 Johannes Berg - */ - -#include -#include -#include -#include -#include - -/** - * enum ieee80211_band - supported frequency bands - * - * The bands are assigned this way because the supported - * bitrates differ in these bands. - * - * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band - * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7) - */ -enum ieee80211_band { - IEEE80211_BAND_2GHZ, - IEEE80211_BAND_5GHZ, - - /* keep last */ - IEEE80211_NUM_BANDS -}; - -/** - * enum ieee80211_channel_flags - channel flags - * - * Channel flags set by the regulatory control code. - * - * @IEEE80211_CHAN_DISABLED: This channel is disabled. - * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted - * on this channel. - * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. - * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. - * @IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel - * is not permitted. - * @IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel - * is not permitted. - */ -enum ieee80211_channel_flags { - IEEE80211_CHAN_DISABLED = 1<<0, - IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, - IEEE80211_CHAN_NO_IBSS = 1<<2, - IEEE80211_CHAN_RADAR = 1<<3, - IEEE80211_CHAN_NO_FAT_ABOVE = 1<<4, - IEEE80211_CHAN_NO_FAT_BELOW = 1<<5, -}; - -/** - * struct ieee80211_channel - channel definition - * - * This structure describes a single channel for use - * with cfg80211. - * - * @center_freq: center frequency in MHz - * @max_bandwidth: maximum allowed bandwidth for this channel, in MHz - * @hw_value: hardware-specific value for the channel - * @flags: channel flags from &enum ieee80211_channel_flags. - * @orig_flags: channel flags at registration time, used by regulatory - * code to support devices with additional restrictions - * @band: band this channel belongs to. - * @max_antenna_gain: maximum antenna gain in dBi - * @max_power: maximum transmission power (in dBm) - * @beacon_found: helper to regulatory code to indicate when a beacon - * has been found on this channel. Use regulatory_hint_found_beacon() - * to enable this, this is is useful only on 5 GHz band. - * @orig_mag: internal use - * @orig_mpwr: internal use - */ -struct ieee80211_channel { - enum ieee80211_band band; - u16 center_freq; - u8 max_bandwidth; - u16 hw_value; - u32 flags; - int max_antenna_gain; - int max_power; - bool beacon_found; - u32 orig_flags; - int orig_mag, orig_mpwr; -}; - -/** - * enum ieee80211_rate_flags - rate flags - * - * Hardware/specification flags for rates. These are structured - * in a way that allows using the same bitrate structure for - * different bands/PHY modes. - * - * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short - * preamble on this bitrate; only relevant in 2.4GHz band and - * with CCK rates. - * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate - * when used with 802.11a (on the 5 GHz band); filled by the - * core code when registering the wiphy. - * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate - * when used with 802.11b (on the 2.4 GHz band); filled by the - * core code when registering the wiphy. - * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate - * when used with 802.11g (on the 2.4 GHz band); filled by the - * core code when registering the wiphy. - * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. - */ -enum ieee80211_rate_flags { - IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, - IEEE80211_RATE_MANDATORY_A = 1<<1, - IEEE80211_RATE_MANDATORY_B = 1<<2, - IEEE80211_RATE_MANDATORY_G = 1<<3, - IEEE80211_RATE_ERP_G = 1<<4, -}; - -/** - * struct ieee80211_rate - bitrate definition - * - * This structure describes a bitrate that an 802.11 PHY can - * operate with. The two values @hw_value and @hw_value_short - * are only for driver use when pointers to this structure are - * passed around. - * - * @flags: rate-specific flags - * @bitrate: bitrate in units of 100 Kbps - * @hw_value: driver/hardware value for this rate - * @hw_value_short: driver/hardware value for this rate when - * short preamble is used - */ -struct ieee80211_rate { - u32 flags; - u16 bitrate; - u16 hw_value, hw_value_short; -}; - -/** - * struct ieee80211_sta_ht_cap - STA's HT capabilities - * - * This structure describes most essential parameters needed - * to describe 802.11n HT capabilities for an STA. - * - * @ht_supported: is HT supported by the STA - * @cap: HT capabilities map as described in 802.11n spec - * @ampdu_factor: Maximum A-MPDU length factor - * @ampdu_density: Minimum A-MPDU spacing - * @mcs: Supported MCS rates - */ -struct ieee80211_sta_ht_cap { - u16 cap; /* use IEEE80211_HT_CAP_ */ - bool ht_supported; - u8 ampdu_factor; - u8 ampdu_density; - struct ieee80211_mcs_info mcs; -}; - -/** - * struct ieee80211_supported_band - frequency band definition - * - * This structure describes a frequency band a wiphy - * is able to operate in. - * - * @channels: Array of channels the hardware can operate in - * in this band. - * @band: the band this structure represents - * @n_channels: Number of channels in @channels - * @bitrates: Array of bitrates the hardware can operate with - * in this band. Must be sorted to give a valid "supported - * rates" IE, i.e. CCK rates first, then OFDM. - * @n_bitrates: Number of bitrates in @bitrates - */ -struct ieee80211_supported_band { - struct ieee80211_channel *channels; - struct ieee80211_rate *bitrates; - enum ieee80211_band band; - int n_channels; - int n_bitrates; - struct ieee80211_sta_ht_cap ht_cap; -}; - -/** - * struct wiphy - wireless hardware description - * @idx: the wiphy index assigned to this item - * @class_dev: the class device representing /sys/class/ieee80211/ - * @custom_regulatory: tells us the driver for this device - * has its own custom regulatory domain and cannot identify the - * ISO / IEC 3166 alpha2 it belongs to. When this is enabled - * we will disregard the first regulatory hint (when the - * initiator is %REGDOM_SET_BY_CORE). - * @strict_regulatory: tells us the driver for this device will ignore - * regulatory domain settings until it gets its own regulatory domain - * via its regulatory_hint(). After its gets its own regulatory domain - * it will only allow further regulatory domain settings to further - * enhance compliance. For example if channel 13 and 14 are disabled - * by this regulatory domain no user regulatory domain can enable these - * channels at a later time. This can be used for devices which do not - * have calibration information gauranteed for frequencies or settings - * outside of its regulatory domain. - * @reg_notifier: the driver's regulatory notification callback - * @regd: the driver's regulatory domain, if one was requested via - * the regulatory_hint() API. This can be used by the driver - * on the reg_notifier() if it chooses to ignore future - * regulatory domain changes caused by other drivers. - * @signal_type: signal type reported in &struct cfg80211_bss. - * @cipher_suites: supported cipher suites - * @n_cipher_suites: number of supported cipher suites - */ -struct wiphy { - /* assign these fields before you register the wiphy */ - - /* permanent MAC address */ - u8 perm_addr[ETH_ALEN]; - - /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ - u16 interface_modes; - - bool custom_regulatory; - bool strict_regulatory; - - enum cfg80211_signal_type signal_type; - - int bss_priv_size; - u8 max_scan_ssids; - u16 max_scan_ie_len; - - int n_cipher_suites; - const u32 *cipher_suites; - - /* If multiple wiphys are registered and you're handed e.g. - * a regular netdev with assigned ieee80211_ptr, you won't - * know whether it points to a wiphy your driver has registered - * or not. Assign this to something global to your driver to - * help determine whether you own this wiphy or not. */ - void *privid; - - struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; - - /* Lets us get back the wiphy on the callback */ - int (*reg_notifier)(struct wiphy *wiphy, - struct regulatory_request *request); - - /* fields below are read-only, assigned by cfg80211 */ - - const struct ieee80211_regdomain *regd; - - /* the item in /sys/class/ieee80211/ points to this, - * you need use set_wiphy_dev() (see below) */ - struct device dev; - - /* dir in debugfs: ieee80211/ */ - struct dentry *debugfsdir; - - char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); -}; - -/** struct wireless_dev - wireless per-netdev state - * - * This structure must be allocated by the driver/stack - * that uses the ieee80211_ptr field in struct net_device - * (this is intentional so it can be allocated along with - * the netdev.) - * - * @wiphy: pointer to hardware description - * @iftype: interface type - * @list: (private) - * @netdev (private) - */ -struct wireless_dev { - struct wiphy *wiphy; - enum nl80211_iftype iftype; - - /* private to the generic wireless code */ - struct list_head list; - struct net_device *netdev; - - /* currently used for IBSS - might be rearranged in the future */ - struct cfg80211_bss *current_bss; - u8 bssid[ETH_ALEN]; - u8 ssid[IEEE80211_MAX_SSID_LEN]; - u8 ssid_len; - -#ifdef CONFIG_WIRELESS_EXT - /* wext data */ - struct cfg80211_ibss_params wext; - u8 wext_bssid[ETH_ALEN]; -#endif -}; - -/** - * wiphy_priv - return priv from wiphy - */ -static inline void *wiphy_priv(struct wiphy *wiphy) -{ - BUG_ON(!wiphy); - return &wiphy->priv; -} - -/** - * set_wiphy_dev - set device pointer for wiphy - */ -static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev) -{ - wiphy->dev.parent = dev; -} - -/** - * wiphy_dev - get wiphy dev pointer - */ -static inline struct device *wiphy_dev(struct wiphy *wiphy) -{ - return wiphy->dev.parent; -} - -/** - * wiphy_name - get wiphy name - */ -static inline const char *wiphy_name(struct wiphy *wiphy) -{ - return dev_name(&wiphy->dev); -} - -/** - * wdev_priv - return wiphy priv from wireless_dev - */ -static inline void *wdev_priv(struct wireless_dev *wdev) -{ - BUG_ON(!wdev); - return wiphy_priv(wdev->wiphy); -} - -/** - * wiphy_new - create a new wiphy for use with cfg80211 - * - * create a new wiphy and associate the given operations with it. - * @sizeof_priv bytes are allocated for private use. - * - * the returned pointer must be assigned to each netdev's - * ieee80211_ptr for proper operation. - */ -struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv); - -/** - * wiphy_register - register a wiphy with cfg80211 - * - * register the given wiphy - * - * Returns a non-negative wiphy index or a negative error code. - */ -extern int wiphy_register(struct wiphy *wiphy); - -/** - * wiphy_unregister - deregister a wiphy from cfg80211 - * - * unregister a device with the given priv pointer. - * After this call, no more requests can be made with this priv - * pointer, but the call may sleep to wait for an outstanding - * request that is being handled. - */ -extern void wiphy_unregister(struct wiphy *wiphy); - -/** - * wiphy_free - free wiphy - */ -extern void wiphy_free(struct wiphy *wiphy); - -/** - * ieee80211_channel_to_frequency - convert channel number to frequency - */ -extern int ieee80211_channel_to_frequency(int chan); - -/** - * ieee80211_frequency_to_channel - convert frequency to channel number - */ -extern int ieee80211_frequency_to_channel(int freq); - -/* - * Name indirection necessary because the ieee80211 code also has - * a function named "ieee80211_get_channel", so if you include - * cfg80211's header file you get cfg80211's version, if you try - * to include both header files you'll (rightfully!) get a symbol - * clash. - */ -extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy, - int freq); -/** - * ieee80211_get_channel - get channel struct from wiphy for specified frequency - */ -static inline struct ieee80211_channel * -ieee80211_get_channel(struct wiphy *wiphy, int freq) -{ - return __ieee80211_get_channel(wiphy, freq); -} - -/** - * ieee80211_get_response_rate - get basic rate for a given rate - * - * @sband: the band to look for rates in - * @basic_rates: bitmap of basic rates - * @bitrate: the bitrate for which to find the basic rate - * - * This function returns the basic rate corresponding to a given - * bitrate, that is the next lower bitrate contained in the basic - * rate map, which is, for this function, given as a bitmap of - * indices of rates in the band's bitrate table. - */ -struct ieee80211_rate * -ieee80211_get_response_rate(struct ieee80211_supported_band *sband, - u32 basic_rates, int bitrate); - -/** - * regulatory_hint - driver hint to the wireless core a regulatory domain - * @wiphy: the wireless device giving the hint (used only for reporting - * conflicts) - * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain - * should be in. If @rd is set this should be NULL. Note that if you - * set this to NULL you should still set rd->alpha2 to some accepted - * alpha2. - * - * Wireless drivers can use this function to hint to the wireless core - * what it believes should be the current regulatory domain by - * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory - * domain should be in or by providing a completely build regulatory domain. - * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried - * for a regulatory domain structure for the respective country. - * - * The wiphy must have been registered to cfg80211 prior to this call. - * For cfg80211 drivers this means you must first use wiphy_register(), - * for mac80211 drivers you must first use ieee80211_register_hw(). - * - * Drivers should check the return value, its possible you can get - * an -ENOMEM. - */ -extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2); - -/** - * regulatory_hint_11d - hints a country IE as a regulatory domain - * @wiphy: the wireless device giving the hint (used only for reporting - * conflicts) - * @country_ie: pointer to the country IE - * @country_ie_len: length of the country IE - * - * We will intersect the rd with the what CRDA tells us should apply - * for the alpha2 this country IE belongs to, this prevents APs from - * sending us incorrect or outdated information against a country. - */ -extern void regulatory_hint_11d(struct wiphy *wiphy, - u8 *country_ie, - u8 country_ie_len); -/** - * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain - * @wiphy: the wireless device we want to process the regulatory domain on - * @regd: the custom regulatory domain to use for this wiphy - * - * Drivers can sometimes have custom regulatory domains which do not apply - * to a specific country. Drivers can use this to apply such custom regulatory - * domains. This routine must be called prior to wiphy registration. The - * custom regulatory domain will be trusted completely and as such previous - * default channel settings will be disregarded. If no rule is found for a - * channel on the regulatory domain the channel will be disabled. - */ -extern void wiphy_apply_custom_regulatory( - struct wiphy *wiphy, - const struct ieee80211_regdomain *regd); - -/** - * freq_reg_info - get regulatory information for the given frequency - * @wiphy: the wiphy for which we want to process this rule for - * @center_freq: Frequency in KHz for which we want regulatory information for - * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one - * you can set this to 0. If this frequency is allowed we then set - * 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 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. - */ -extern int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth, - const struct ieee80211_reg_rule **reg_rule); - -#endif /* __NET_WIRELESS_H */ diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 73bd427750ef..0891bfb06996 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -14,7 +14,6 @@ */ #include -#include #include #include "ieee80211_i.h" #include "rate.h" diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e770c1e8e08c..92a573bf1035 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include "key.h" diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c index 5f7a2624ed74..48bf78e7fa7a 100644 --- a/net/mac80211/spectmgmt.c +++ b/net/mac80211/spectmgmt.c @@ -15,7 +15,7 @@ */ #include -#include +#include #include #include "ieee80211_i.h" #include "sta_info.h" diff --git a/net/wireless/core.c b/net/wireless/core.c index de1ac51ae4e5..827a56263551 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "nl80211.h" #include "core.h" #include "sysfs.h" diff --git a/net/wireless/core.h b/net/wireless/core.h index 2ef3595fd6e0..89a8159ef0b1 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "reg.h" diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 2bf42fdef3a1..4e1fcb0c9e4c 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -7,7 +7,6 @@ #include #include #include -#include #include "nl80211.h" diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 574e217bcc86..f38cc39fa79e 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include "core.h" #include "reg.h" diff --git a/net/wireless/util.c b/net/wireless/util.c index 487cdd9bcffc..5f7e997195c7 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1,10 +1,10 @@ /* * Wireless utility functions * - * Copyright 2007 Johannes Berg + * Copyright 2007-2009 Johannes Berg */ -#include -#include +#include +#include #include "core.h" struct ieee80211_rate * diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 57eaea26b67a..4e054ea9c0a0 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "core.h" -- GitLab From 314bd7503b1e96841931311f28a8925dab66ed83 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Apr 2009 15:17:01 +0200 Subject: [PATCH 0644/6080] rndis_wlan: remove nickname support Supporting wireless extension nickname is pointless and no other modern driver supports this, so remove it. Signed-off-by: Johannes Berg Acked-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 38 ------------------------------- 1 file changed, 38 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 43e0ba61df24..109e60343363 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -372,9 +372,6 @@ struct rndis_wext_private { struct iw_statistics iwstats; struct iw_statistics privstats; - int nick_len; - char nick[32]; - int caps; int multicast_size; @@ -1798,39 +1795,6 @@ static int rndis_iw_get_frag(struct net_device *dev, } -static int rndis_iw_set_nick(struct net_device *dev, - struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ - struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); - - devdbg(usbdev, "SIOCSIWNICK"); - - priv->nick_len = wrqu->data.length; - if (priv->nick_len > 32) - priv->nick_len = 32; - - memcpy(priv->nick, extra, priv->nick_len); - return 0; -} - - -static int rndis_iw_get_nick(struct net_device *dev, - struct iw_request_info *info, union iwreq_data *wrqu, char *extra) -{ - struct usbnet *usbdev = netdev_priv(dev); - struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); - - wrqu->data.flags = 1; - wrqu->data.length = priv->nick_len; - memcpy(extra, priv->nick, priv->nick_len); - - devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick); - - return 0; -} - - static int rndis_iw_set_freq(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { @@ -2039,8 +2003,6 @@ static const iw_handler rndis_iw_handler[] = IW_IOCTL(SIOCGIWSCAN) = (iw_handler) cfg80211_wext_giwscan, IW_IOCTL(SIOCSIWESSID) = rndis_iw_set_essid, IW_IOCTL(SIOCGIWESSID) = rndis_iw_get_essid, - IW_IOCTL(SIOCSIWNICKN) = rndis_iw_set_nick, - IW_IOCTL(SIOCGIWNICKN) = rndis_iw_get_nick, IW_IOCTL(SIOCGIWRATE) = rndis_iw_get_rate, IW_IOCTL(SIOCSIWRTS) = rndis_iw_set_rts, IW_IOCTL(SIOCGIWRTS) = rndis_iw_get_rts, -- GitLab From 9e52b0623c6eb49c3f23a326c1fb97bdecc49ba1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Apr 2009 18:27:04 +0200 Subject: [PATCH 0645/6080] ar9170: support HT receive and channel config This patch adds support for configuring HT40 channels and receiving HT40 to ar9170. Receiving aggregation doesn't seem to work right now, so it's not enabled. Same goes for TX aggregation, but that probably needs even more work. With this, I can receive roughly 33 Mbits/sec. The HT capabilities are a little odd, I tried following otus here -- in particular having SGI_40 but not SGI_20 is a little weird but afaict that's what otus does. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/ar9170.h | 15 +++++++ drivers/net/wireless/ath/ar9170/main.c | 54 ++++++++++++++++++++---- 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index 2522a190fdfb..b6a1bff67cab 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h @@ -60,6 +60,21 @@ enum ar9170_bw { __AR9170_NUM_BW, }; +static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type) +{ + switch (type) { + case NL80211_CHAN_NO_HT: + case NL80211_CHAN_HT20: + return AR9170_BW_20; + case NL80211_CHAN_HT40MINUS: + return AR9170_BW_40_BELOW; + case NL80211_CHAN_HT40PLUS: + return AR9170_BW_40_ABOVE; + default: + BUG(); + } +} + enum ar9170_rf_init_mode { AR9170_RFI_NONE, AR9170_RFI_WARM, diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 857416c80199..4682fe2f3f3c 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -142,11 +142,36 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = { }; #undef CHAN +#define AR9170_HT_CAP \ +{ \ + .ht_supported = true, \ + .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ + IEEE80211_HT_CAP_SM_PS | \ + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ + IEEE80211_HT_CAP_SGI_40 | \ + IEEE80211_HT_CAP_DSSSCCK40 | \ + IEEE80211_HT_CAP_SM_PS, \ + .ampdu_factor = 3, /* ?? */ \ + .ampdu_density = 7, /* ?? */ \ + .mcs = { \ + .rx_mask = { 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, }, \ + }, \ +} + static struct ieee80211_supported_band ar9170_band_2GHz = { .channels = ar9170_2ghz_chantable, .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable), .bitrates = ar9170_g_ratetable, .n_bitrates = ar9170_g_ratetable_size, + .ht_cap = AR9170_HT_CAP, +}; + +static struct ieee80211_supported_band ar9170_band_5GHz = { + .channels = ar9170_5ghz_chantable, + .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable), + .bitrates = ar9170_a_ratetable, + .n_bitrates = ar9170_a_ratetable_size, + .ht_cap = AR9170_HT_CAP, }; #ifdef AR9170_QUEUE_DEBUG @@ -190,13 +215,6 @@ static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar, } #endif /* AR9170_QUEUE_DEBUG */ -static struct ieee80211_supported_band ar9170_band_5GHz = { - .channels = ar9170_5ghz_chantable, - .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable), - .bitrates = ar9170_a_ratetable, - .n_bitrates = ar9170_a_ratetable_size, -}; - void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, bool valid_status, u16 tx_status) { @@ -1077,7 +1095,8 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { err = ar9170_set_channel(ar, hw->conf.channel, - AR9170_RFI_NONE, AR9170_BW_20); + AR9170_RFI_NONE, + nl80211_to_ar9170(hw->conf.channel_type)); if (err) goto out; /* adjust slot time for 5 GHz */ @@ -1499,6 +1518,24 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, return ret; } +static int ar9170_ampdu_action(struct ieee80211_hw *hw, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, u16 tid, u16 *ssn) +{ + switch (action) { + case IEEE80211_AMPDU_RX_START: + case IEEE80211_AMPDU_RX_STOP: + /* + * Something goes wrong -- RX locks up + * after a while of receiving aggregated + * frames -- not enabling for now. + */ + return -EOPNOTSUPP; + default: + return -EOPNOTSUPP; + } +} + static const struct ieee80211_ops ar9170_ops = { .start = ar9170_op_start, .stop = ar9170_op_stop, @@ -1515,6 +1552,7 @@ static const struct ieee80211_ops ar9170_ops = { .sta_notify = ar9170_sta_notify, .get_stats = ar9170_get_stats, .get_tx_stats = ar9170_get_tx_stats, + .ampdu_action = ar9170_ampdu_action, }; void *ar9170_alloc(size_t priv_size) -- GitLab From b9a5f8cab751d362f7c2d94899ca788c22fcd1ef Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 20 Apr 2009 18:39:05 +0200 Subject: [PATCH 0646/6080] nl80211: Add set/get for frag/rts threshold and retry limits Add new nl80211 attributes that can be used with NL80211_CMD_SET_WIPHY and NL80211_CMD_GET_WIPHY to manage fragmentation/RTS threshold and retry limits. Since these values are stored in struct wiphy, remove the local copy from mac80211 where feasible (frag & rts threshold). The retry limits are currently needed in struct ieee80211_conf, but these could be eventually removed since the driver should have access to the values in struct wiphy. Signed-off-by: Jouni Malinen Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 24 +++++- include/net/cfg80211.h | 50 ++++++++++++ net/mac80211/cfg.c | 27 +++++++ net/mac80211/debugfs.c | 8 +- net/mac80211/ieee80211_i.h | 3 - net/mac80211/main.c | 6 +- net/mac80211/tx.c | 9 +-- net/mac80211/util.c | 2 +- net/mac80211/wext.c | 138 ++------------------------------- net/wireless/core.c | 10 +++ net/wireless/nl80211.c | 95 +++++++++++++++++++++++ net/wireless/wext-compat.c | 151 +++++++++++++++++++++++++++++++++++++ 12 files changed, 372 insertions(+), 151 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 25ce3e42bd10..dc9d9ec5d1ae 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -46,8 +46,10 @@ * to get a list of all present wiphys. * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, - * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, and/or - * %NL80211_ATTR_WIPHY_CHANNEL_TYPE. + * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, + * %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT, + * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, + * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD. * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request * or rename notification. Has attributes %NL80211_ATTR_WIPHY and * %NL80211_ATTR_WIPHY_NAME. @@ -337,6 +339,18 @@ enum nl80211_commands { * NL80211_CHAN_HT20 = HT20 only * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel + * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is + * less than or equal to the RTS threshold; allowed range: 1..255; + * dot11ShortRetryLimit; u8 + * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is + * greater than the RTS threshold; allowed range: 1..255; + * dot11ShortLongLimit; u8 + * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum + * length in octets for frames; allowed range: 256..8000, disable + * fragmentation with (u32)-1; dot11FragmentationThreshold; u32 + * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length + * larger than or equal to this use RTS/CTS handshake); allowed range: + * 0..65536, disable with (u32)-1; dot11RTSThreshold; u32 * * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on * @NL80211_ATTR_IFNAME: network interface name @@ -565,6 +579,12 @@ enum nl80211_attrs { NL80211_ATTR_FREQ_FIXED, + + NL80211_ATTR_WIPHY_RETRY_SHORT, + NL80211_ATTR_WIPHY_RETRY_LONG, + NL80211_ATTR_WIPHY_FRAG_THRESHOLD, + NL80211_ATTR_WIPHY_RTS_THRESHOLD, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 601eac64b02d..54bc69c83691 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -743,6 +743,20 @@ struct cfg80211_ibss_params { bool channel_fixed; }; +/** + * enum wiphy_params_flags - set_wiphy_params bitfield values + * WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed + * WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed + * WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed + * WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed + */ +enum wiphy_params_flags { + WIPHY_PARAM_RETRY_SHORT = 1 << 0, + WIPHY_PARAM_RETRY_LONG = 1 << 1, + WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2, + WIPHY_PARAM_RTS_THRESHOLD = 1 << 3, +}; + /** * struct cfg80211_ops - backend description for wireless configuration * @@ -823,6 +837,11 @@ struct cfg80211_ibss_params { * cfg80211_ibss_joined(), also call that function when changing BSSID due * to a merge. * @leave_ibss: Leave the IBSS. + * + * @set_wiphy_params: Notify that wiphy parameters have changed; + * @changed bitfield (see &enum wiphy_params_flags) describes which values + * have changed. The actual parameter values are available in + * struct wiphy. If returning an error, no value should be changed. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy); @@ -912,6 +931,8 @@ struct cfg80211_ops { int (*join_ibss)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params); int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); + + int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); }; /* @@ -945,6 +966,11 @@ struct cfg80211_ops { * @signal_type: signal type reported in &struct cfg80211_bss. * @cipher_suites: supported cipher suites * @n_cipher_suites: number of supported cipher suites + * @retry_short: Retry limit for short frames (dot11ShortRetryLimit) + * @retry_long: Retry limit for long frames (dot11LongRetryLimit) + * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold); + * -1 = fragmentation disabled, only odd values >= 256 used + * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -967,6 +993,11 @@ struct wiphy { int n_cipher_suites; const u32 *cipher_suites; + u8 retry_short; + u8 retry_long; + u32 frag_threshold; + u32 rts_threshold; + /* If multiple wiphys are registered and you're handed e.g. * a regular netdev with assigned ieee80211_ptr, you won't * know whether it points to a wiphy your driver has registered @@ -1345,6 +1376,25 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev, struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); +int cfg80211_wext_siwrts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra); +int cfg80211_wext_giwrts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra); +int cfg80211_wext_siwfrag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra); +int cfg80211_wext_giwfrag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra); +int cfg80211_wext_siwretry(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *retry, char *extra); +int cfg80211_wext_giwretry(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *retry, char *extra); + /* * callbacks for asynchronous cfg80211 methods, notification * functions and BSS handling helpers diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 14013dc64474..5e1c230744b5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1298,6 +1298,32 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return ieee80211_ibss_leave(sdata); } +static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) +{ + struct ieee80211_local *local = wiphy_priv(wiphy); + + if (changed & WIPHY_PARAM_RTS_THRESHOLD) { + int err; + + if (local->ops->set_rts_threshold) { + err = local->ops->set_rts_threshold( + local_to_hw(local), wiphy->rts_threshold); + if (err) + return err; + } + } + + if (changed & WIPHY_PARAM_RETRY_SHORT) + local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; + if (changed & WIPHY_PARAM_RETRY_LONG) + local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; + if (changed & + (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG)) + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); + + return 0; +} + struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -1336,4 +1362,5 @@ struct cfg80211_ops mac80211_config_ops = { .disassoc = ieee80211_disassoc, .join_ibss = ieee80211_join_ibss, .leave_ibss = ieee80211_leave_ibss, + .set_wiphy_params = ieee80211_set_wiphy_params, }; diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 210b9b6fecd2..5001328be46b 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -52,13 +52,13 @@ static const struct file_operations name## _ops = { \ DEBUGFS_READONLY_FILE(frequency, 20, "%d", local->hw.conf.channel->center_freq); DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d", - local->rts_threshold); + local->hw.wiphy->rts_threshold); DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d", - local->fragmentation_threshold); + local->hw.wiphy->frag_threshold); DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d", - local->hw.conf.short_frame_max_tx_count); + local->hw.wiphy->retry_short); DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", - local->hw.conf.long_frame_max_tx_count); + local->hw.wiphy->retry_long); DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", local->total_ps_buffered); DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x", diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 92a573bf1035..dba78d89a10c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -643,9 +643,6 @@ struct ieee80211_local { struct rate_control_ref *rate_ctrl; - int rts_threshold; - int fragmentation_threshold; - struct crypto_blkcipher *wep_tx_tfm; struct crypto_blkcipher *wep_rx_tfm; u32 wep_iv; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index d26fc399285e..5320e08434ac 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -776,10 +776,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, /* set up some defaults */ local->hw.queues = 1; local->hw.max_rates = 1; - local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; - local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; - local->hw.conf.long_frame_max_tx_count = 4; - local->hw.conf.short_frame_max_tx_count = 7; + local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; + local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; local->hw.conf.radio_enabled = true; INIT_LIST_HEAD(&local->interfaces); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c53d77db3e4f..9ab49826c15a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -516,7 +516,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) sband = tx->local->hw.wiphy->bands[tx->channel->band]; len = min_t(int, tx->skb->len + FCS_LEN, - tx->local->fragmentation_threshold); + tx->local->hw.wiphy->frag_threshold); /* set up the tx rate control struct we give the RC algo */ txrc.hw = local_to_hw(tx->local); @@ -527,8 +527,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; /* set up RTS protection if desired */ - if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD && - len > tx->local->rts_threshold) { + if (len > tx->local->hw.wiphy->rts_threshold) { txrc.rts = rts = true; } @@ -770,7 +769,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) struct sk_buff *skb = tx->skb; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (void *)skb->data; - int frag_threshold = tx->local->fragmentation_threshold; + int frag_threshold = tx->local->hw.wiphy->frag_threshold; int hdrlen; int fragnum; @@ -1088,7 +1087,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, if (tx->flags & IEEE80211_TX_FRAGMENTED) { if ((tx->flags & IEEE80211_TX_UNICAST) && - skb->len + FCS_LEN > local->fragmentation_threshold && + skb->len + FCS_LEN > local->hw.wiphy->frag_threshold && !(info->flags & IEEE80211_TX_CTL_AMPDU)) tx->flags |= IEEE80211_TX_FRAGMENTED; else diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 3dd490fa4b68..11244212f41d 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1044,7 +1044,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) /* setup RTS threshold */ if (local->ops->set_rts_threshold) - local->ops->set_rts_threshold(hw, local->rts_threshold); + local->ops->set_rts_threshold(hw, hw->wiphy->rts_threshold); /* reconfigure hardware */ ieee80211_hw_config(local, ~0); diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index eb63fc148019..1eb6d8642a77 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -472,132 +472,6 @@ static int ieee80211_ioctl_giwtxpower(struct net_device *dev, return 0; } -static int ieee80211_ioctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - - if (rts->disabled) - local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; - else if (!rts->fixed) - /* if the rts value is not fixed, then take default */ - local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; - else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) - return -EINVAL; - else - local->rts_threshold = rts->value; - - /* If the wlan card performs RTS/CTS in hardware/firmware, - * configure it here */ - - if (local->ops->set_rts_threshold) - local->ops->set_rts_threshold(local_to_hw(local), - local->rts_threshold); - - return 0; -} - -static int ieee80211_ioctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - - rts->value = local->rts_threshold; - rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD); - rts->fixed = 1; - - return 0; -} - - -static int ieee80211_ioctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - - if (frag->disabled) - local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; - else if (!frag->fixed) - local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; - else if (frag->value < 256 || - frag->value > IEEE80211_MAX_FRAG_THRESHOLD) - return -EINVAL; - else { - /* Fragment length must be even, so strip LSB. */ - local->fragmentation_threshold = frag->value & ~0x1; - } - - return 0; -} - -static int ieee80211_ioctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - - frag->value = local->fragmentation_threshold; - frag->disabled = (frag->value >= IEEE80211_MAX_FRAG_THRESHOLD); - frag->fixed = 1; - - return 0; -} - - -static int ieee80211_ioctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *retry, char *extra) -{ - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - - if (retry->disabled || - (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) - return -EINVAL; - - if (retry->flags & IW_RETRY_MAX) { - local->hw.conf.long_frame_max_tx_count = retry->value; - } else if (retry->flags & IW_RETRY_MIN) { - local->hw.conf.short_frame_max_tx_count = retry->value; - } else { - local->hw.conf.long_frame_max_tx_count = retry->value; - local->hw.conf.short_frame_max_tx_count = retry->value; - } - - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS); - - return 0; -} - - -static int ieee80211_ioctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *retry, char *extra) -{ - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - - retry->disabled = 0; - if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) { - /* first return min value, iwconfig will ask max value - * later if needed */ - retry->flags |= IW_RETRY_LIMIT; - retry->value = local->hw.conf.short_frame_max_tx_count; - if (local->hw.conf.long_frame_max_tx_count != - local->hw.conf.short_frame_max_tx_count) - retry->flags |= IW_RETRY_MIN; - return 0; - } - if (retry->flags & IW_RETRY_MAX) { - retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - retry->value = local->hw.conf.long_frame_max_tx_count; - } - - return 0; -} - - static int ieee80211_ioctl_siwencode(struct net_device *dev, struct iw_request_info *info, struct iw_point *erq, char *keybuf) @@ -1050,14 +924,14 @@ static const iw_handler ieee80211_handler[] = (iw_handler) NULL, /* -- hole -- */ (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */ (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */ - (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */ - (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */ - (iw_handler) ieee80211_ioctl_siwfrag, /* SIOCSIWFRAG */ - (iw_handler) ieee80211_ioctl_giwfrag, /* SIOCGIWFRAG */ + (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */ + (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ + (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ + (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */ (iw_handler) ieee80211_ioctl_siwtxpower, /* SIOCSIWTXPOW */ (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ - (iw_handler) ieee80211_ioctl_siwretry, /* SIOCSIWRETRY */ - (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */ + (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */ + (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ diff --git a/net/wireless/core.c b/net/wireless/core.c index 827a56263551..f256b4f7e833 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -273,6 +273,16 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv) drv->wiphy.dev.class = &ieee80211_class; drv->wiphy.dev.platform_data = drv; + /* + * Initialize wiphy parameters to IEEE 802.11 MIB default values. + * Fragmentation and RTS threshold are disabled by default with the + * special -1 value. + */ + drv->wiphy.retry_short = 7; + drv->wiphy.retry_long = 4; + drv->wiphy.frag_threshold = (u32) -1; + drv->wiphy.rts_threshold = (u32) -1; + return &drv->wiphy; } EXPORT_SYMBOL(wiphy_new); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 16f86356ac97..5a9a5c6c71db 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -61,6 +61,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, + [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 }, + [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 }, + [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, + [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, @@ -204,6 +208,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx); NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); + + NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, + dev->wiphy.retry_short); + NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG, + dev->wiphy.retry_long); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, + dev->wiphy.frag_threshold); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, + dev->wiphy.rts_threshold); + NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, dev->wiphy.max_scan_ssids); NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, @@ -416,6 +430,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) struct cfg80211_registered_device *rdev; int result = 0, rem_txq_params = 0; struct nlattr *nl_txq_params; + u32 changed; + u8 retry_short = 0, retry_long = 0; + u32 frag_threshold = 0, rts_threshold = 0; rtnl_lock(); @@ -530,6 +547,84 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) goto bad_res; } + changed = 0; + + if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) { + retry_short = nla_get_u8( + info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]); + if (retry_short == 0) { + result = -EINVAL; + goto bad_res; + } + changed |= WIPHY_PARAM_RETRY_SHORT; + } + + if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) { + retry_long = nla_get_u8( + info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]); + if (retry_long == 0) { + result = -EINVAL; + goto bad_res; + } + changed |= WIPHY_PARAM_RETRY_LONG; + } + + if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) { + frag_threshold = nla_get_u32( + info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]); + if (frag_threshold < 256) { + result = -EINVAL; + goto bad_res; + } + if (frag_threshold != (u32) -1) { + /* + * Fragments (apart from the last one) are required to + * have even length. Make the fragmentation code + * simpler by stripping LSB should someone try to use + * odd threshold value. + */ + frag_threshold &= ~0x1; + } + changed |= WIPHY_PARAM_FRAG_THRESHOLD; + } + + if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) { + rts_threshold = nla_get_u32( + info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]); + changed |= WIPHY_PARAM_RTS_THRESHOLD; + } + + if (changed) { + u8 old_retry_short, old_retry_long; + u32 old_frag_threshold, old_rts_threshold; + + if (!rdev->ops->set_wiphy_params) { + result = -EOPNOTSUPP; + goto bad_res; + } + + old_retry_short = rdev->wiphy.retry_short; + old_retry_long = rdev->wiphy.retry_long; + old_frag_threshold = rdev->wiphy.frag_threshold; + old_rts_threshold = rdev->wiphy.rts_threshold; + + if (changed & WIPHY_PARAM_RETRY_SHORT) + rdev->wiphy.retry_short = retry_short; + if (changed & WIPHY_PARAM_RETRY_LONG) + rdev->wiphy.retry_long = retry_long; + if (changed & WIPHY_PARAM_FRAG_THRESHOLD) + rdev->wiphy.frag_threshold = frag_threshold; + if (changed & WIPHY_PARAM_RTS_THRESHOLD) + rdev->wiphy.rts_threshold = rts_threshold; + + result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed); + if (result) { + rdev->wiphy.retry_short = old_retry_short; + rdev->wiphy.retry_long = old_retry_long; + rdev->wiphy.frag_threshold = old_frag_threshold; + rdev->wiphy.rts_threshold = old_rts_threshold; + } + } bad_res: mutex_unlock(&rdev->mtx); diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 4e054ea9c0a0..3279e7f038dc 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -314,3 +314,154 @@ struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, } EXPORT_SYMBOL(cfg80211_wext_freq); + +int cfg80211_wext_siwrts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); + u32 orts = wdev->wiphy->rts_threshold; + int err; + + if (rts->disabled || !rts->fixed) + wdev->wiphy->rts_threshold = (u32) -1; + else if (rts->value < 0) + return -EINVAL; + else + wdev->wiphy->rts_threshold = rts->value; + + err = rdev->ops->set_wiphy_params(wdev->wiphy, + WIPHY_PARAM_RTS_THRESHOLD); + if (err) + wdev->wiphy->rts_threshold = orts; + + return err; +} +EXPORT_SYMBOL(cfg80211_wext_siwrts); + +int cfg80211_wext_giwrts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + rts->value = wdev->wiphy->rts_threshold; + rts->disabled = rts->value == (u32) -1; + rts->fixed = 1; + + return 0; +} +EXPORT_SYMBOL(cfg80211_wext_giwrts); + +int cfg80211_wext_siwfrag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); + u32 ofrag = wdev->wiphy->frag_threshold; + int err; + + if (frag->disabled || !frag->fixed) + wdev->wiphy->frag_threshold = (u32) -1; + else if (frag->value < 256) + return -EINVAL; + else { + /* Fragment length must be even, so strip LSB. */ + wdev->wiphy->frag_threshold = frag->value & ~0x1; + } + + err = rdev->ops->set_wiphy_params(wdev->wiphy, + WIPHY_PARAM_FRAG_THRESHOLD); + if (err) + wdev->wiphy->frag_threshold = ofrag; + + return err; +} +EXPORT_SYMBOL(cfg80211_wext_siwfrag); + +int cfg80211_wext_giwfrag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + frag->value = wdev->wiphy->frag_threshold; + frag->disabled = frag->value == (u32) -1; + frag->fixed = 1; + + return 0; +} +EXPORT_SYMBOL(cfg80211_wext_giwfrag); + +int cfg80211_wext_siwretry(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *retry, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); + u32 changed = 0; + u8 olong = wdev->wiphy->retry_long; + u8 oshort = wdev->wiphy->retry_short; + int err; + + if (retry->disabled || + (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) + return -EINVAL; + + if (retry->flags & IW_RETRY_LONG) { + wdev->wiphy->retry_long = retry->value; + changed |= WIPHY_PARAM_RETRY_LONG; + } else if (retry->flags & IW_RETRY_SHORT) { + wdev->wiphy->retry_short = retry->value; + changed |= WIPHY_PARAM_RETRY_SHORT; + } else { + wdev->wiphy->retry_short = retry->value; + wdev->wiphy->retry_long = retry->value; + changed |= WIPHY_PARAM_RETRY_LONG; + changed |= WIPHY_PARAM_RETRY_SHORT; + } + + if (!changed) + return 0; + + err = rdev->ops->set_wiphy_params(wdev->wiphy, changed); + if (err) { + wdev->wiphy->retry_short = oshort; + wdev->wiphy->retry_long = olong; + } + + return err; +} +EXPORT_SYMBOL(cfg80211_wext_siwretry); + +int cfg80211_wext_giwretry(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *retry, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + retry->disabled = 0; + + if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) { + /* + * First return short value, iwconfig will ask long value + * later if needed + */ + retry->flags |= IW_RETRY_LIMIT; + retry->value = wdev->wiphy->retry_short; + if (wdev->wiphy->retry_long != wdev->wiphy->retry_short) + retry->flags |= IW_RETRY_LONG; + + return 0; + } + + if (retry->flags & IW_RETRY_LONG) { + retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; + retry->value = wdev->wiphy->retry_long; + } + + return 0; +} +EXPORT_SYMBOL(cfg80211_wext_giwretry); -- GitLab From 9d308429a9fd0fa644f0b748f6241631f74a6cda Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Apr 2009 18:43:46 +0200 Subject: [PATCH 0647/6080] cfg80211: clear WEXT SSID when clearing IBSS When we leave an IBSS, we should clear the SSID and not just the BSSID, but since WEXT allows configuring while the interface is down we must not clear it when leaving due to taking the iface down, so some complications are needed. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/core.c | 2 +- net/wireless/core.h | 4 ++-- net/wireless/ibss.c | 21 ++++++++++++++------- net/wireless/nl80211.c | 4 ++-- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index f256b4f7e833..2006a4ee60eb 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -464,7 +464,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, break; if (!dev->ieee80211_ptr->ssid_len) break; - cfg80211_leave_ibss(rdev, dev); + cfg80211_leave_ibss(rdev, dev, true); break; case NETDEV_UP: #ifdef CONFIG_WIRELESS_EXT diff --git a/net/wireless/core.h b/net/wireless/core.h index 89a8159ef0b1..3e49d3399311 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -147,8 +147,8 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev, int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, struct net_device *dev, struct cfg80211_ibss_params *params); -void cfg80211_clear_ibss(struct net_device *dev); +void cfg80211_clear_ibss(struct net_device *dev, bool nowext); int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, - struct net_device *dev); + struct net_device *dev, bool nowext); #endif /* __NET_WIRELESS_CORE_H */ diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 4e1fcb0c9e4c..b5c601e1b1b7 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -76,7 +76,7 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, return 0; } -void cfg80211_clear_ibss(struct net_device *dev) +void cfg80211_clear_ibss(struct net_device *dev, bool nowext) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -88,10 +88,14 @@ void cfg80211_clear_ibss(struct net_device *dev) wdev->current_bss = NULL; wdev->ssid_len = 0; memset(wdev->bssid, 0, ETH_ALEN); +#ifdef CONFIG_WIRELESS_EXT + if (!nowext) + wdev->wext.ssid_len = 0; +#endif } int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, - struct net_device *dev) + struct net_device *dev, bool nowext) { int err; @@ -100,7 +104,7 @@ int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, if (err) return err; - cfg80211_clear_ibss(dev); + cfg80211_clear_ibss(dev, nowext); return 0; } @@ -179,7 +183,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, return 0; if (wdev->ssid_len) { - err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev); + err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), + dev, true); if (err) return err; } @@ -241,7 +246,8 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, return -EOPNOTSUPP; if (wdev->ssid_len) { - err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev); + err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), + dev, true); if (err) return err; } @@ -275,7 +281,7 @@ int cfg80211_ibss_wext_giwessid(struct net_device *dev, data->flags = 1; data->length = wdev->ssid_len; memcpy(ssid, wdev->ssid, data->length); - } else if (wdev->wext.ssid) { + } else if (wdev->wext.ssid && wdev->wext.ssid_len) { data->flags = 1; data->length = wdev->wext.ssid_len; memcpy(ssid, wdev->wext.ssid, data->length); @@ -318,7 +324,8 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, return 0; if (wdev->ssid_len) { - err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), dev); + err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy), + dev, true); if (err) return err; } diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 5a9a5c6c71db..97bb5c80125d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -833,7 +833,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) if (dev && !err && (ntype != otype)) { if (otype == NL80211_IFTYPE_ADHOC) - cfg80211_clear_ibss(dev); + cfg80211_clear_ibss(dev, false); } unlock: @@ -3249,7 +3249,7 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) goto out; } - err = cfg80211_leave_ibss(drv, dev); + err = cfg80211_leave_ibss(drv, dev, false); out: cfg80211_put_dev(drv); -- GitLab From ba44cb7226afd4e19308c1d8a90e8b7c566c0d8b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Apr 2009 18:49:39 +0200 Subject: [PATCH 0648/6080] cfg80211: mark all WEXT handlers _GPL The fact that these are exported is a technical detail of the conversion period -- we don't want anybody to start relying on these. Ultimately we want things to use cfg80211 only, and once everything that is in wext is converted to cfg80211 drivers will not need to touch wext _at all_. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/scan.c | 4 ++-- net/wireless/wext-compat.c | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 1396248dc5cc..723aeb3d9462 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -653,7 +653,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, cfg80211_put_dev(rdev); return err; } -EXPORT_SYMBOL(cfg80211_wext_siwscan); +EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); static void ieee80211_scan_add_ies(struct iw_request_info *info, struct cfg80211_bss *bss, @@ -962,5 +962,5 @@ int cfg80211_wext_giwscan(struct net_device *dev, cfg80211_put_dev(rdev); return res; } -EXPORT_SYMBOL(cfg80211_wext_giwscan); +EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan); #endif diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 3279e7f038dc..5ef82f2ca88f 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -57,7 +57,7 @@ int cfg80211_wext_giwname(struct net_device *dev, return 0; } -EXPORT_SYMBOL(cfg80211_wext_giwname); +EXPORT_SYMBOL_GPL(cfg80211_wext_giwname); int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, u32 *mode, char *extra) @@ -108,7 +108,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info, return ret; } -EXPORT_SYMBOL(cfg80211_wext_siwmode); +EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode); int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, u32 *mode, char *extra) @@ -143,7 +143,7 @@ int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info, } return 0; } -EXPORT_SYMBOL(cfg80211_wext_giwmode); +EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode); int cfg80211_wext_giwrange(struct net_device *dev, @@ -239,7 +239,7 @@ int cfg80211_wext_giwrange(struct net_device *dev, return 0; } -EXPORT_SYMBOL(cfg80211_wext_giwrange); +EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange); int cfg80211_wext_siwmlme(struct net_device *dev, struct iw_request_info *info, @@ -283,7 +283,7 @@ int cfg80211_wext_siwmlme(struct net_device *dev, return -EOPNOTSUPP; } } -EXPORT_SYMBOL(cfg80211_wext_siwmlme); +EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme); /** @@ -313,7 +313,7 @@ struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, } } -EXPORT_SYMBOL(cfg80211_wext_freq); +EXPORT_SYMBOL_GPL(cfg80211_wext_freq); int cfg80211_wext_siwrts(struct net_device *dev, struct iw_request_info *info, @@ -338,7 +338,7 @@ int cfg80211_wext_siwrts(struct net_device *dev, return err; } -EXPORT_SYMBOL(cfg80211_wext_siwrts); +EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts); int cfg80211_wext_giwrts(struct net_device *dev, struct iw_request_info *info, @@ -352,7 +352,7 @@ int cfg80211_wext_giwrts(struct net_device *dev, return 0; } -EXPORT_SYMBOL(cfg80211_wext_giwrts); +EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts); int cfg80211_wext_siwfrag(struct net_device *dev, struct iw_request_info *info, @@ -379,7 +379,7 @@ int cfg80211_wext_siwfrag(struct net_device *dev, return err; } -EXPORT_SYMBOL(cfg80211_wext_siwfrag); +EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag); int cfg80211_wext_giwfrag(struct net_device *dev, struct iw_request_info *info, @@ -393,7 +393,7 @@ int cfg80211_wext_giwfrag(struct net_device *dev, return 0; } -EXPORT_SYMBOL(cfg80211_wext_giwfrag); +EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag); int cfg80211_wext_siwretry(struct net_device *dev, struct iw_request_info *info, @@ -434,7 +434,7 @@ int cfg80211_wext_siwretry(struct net_device *dev, return err; } -EXPORT_SYMBOL(cfg80211_wext_siwretry); +EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry); int cfg80211_wext_giwretry(struct net_device *dev, struct iw_request_info *info, @@ -464,4 +464,4 @@ int cfg80211_wext_giwretry(struct net_device *dev, return 0; } -EXPORT_SYMBOL(cfg80211_wext_giwretry); +EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry); -- GitLab From e7ec86f54e519e8e86f1cf328db13263f3ef8bd4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 18 Apr 2009 17:33:24 +0200 Subject: [PATCH 0649/6080] mac80211: validate TIM IE length (redux) The TIM IE must not be shorter than 4 bytes, so verify that when parsing it and use the proper type. To ease that adjust struct ieee80211_tim_ie to have a virtual bitmap of size at least 1. Also check that the TIM IE is actually present before trying to parse it! Because other people may need the function, make it a static inline in ieee80211.h. (The original "mac80211: validate TIM IE length" was a minimal fix for 2.6.30. This purports to be the full, correct fix. -- JWL) Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 32 +++++++++++++++++++++++++++++++- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/mlme.c | 27 ++------------------------- net/mac80211/util.c | 6 ++++-- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 53563d53b5ad..c52e7fba4e40 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -540,7 +540,7 @@ struct ieee80211_tim_ie { u8 dtim_period; u8 bitmap_ctrl; /* variable size: 1 - 251 bytes */ - u8 virtual_map[0]; + u8 virtual_map[1]; } __attribute__ ((packed)); #define WLAN_SA_QUERY_TR_ID_LEN 16 @@ -1392,4 +1392,34 @@ static inline unsigned long ieee80211_tu_to_usec(unsigned long tu) return 1024 * tu; } +/** + * ieee80211_check_tim - check if AID bit is set in TIM + * @tim: the TIM IE + * @tim_len: length of the TIM IE + * @aid: the AID to look for + */ +static inline bool ieee80211_check_tim(struct ieee80211_tim_ie *tim, + u8 tim_len, u16 aid) +{ + u8 mask; + u8 index, indexn1, indexn2; + + if (unlikely(!tim || tim_len < sizeof(*tim))) + return false; + + aid &= 0x3fff; + index = aid / 8; + mask = 1 << (aid & 7); + + indexn1 = tim->bitmap_ctrl & 0xfe; + indexn2 = tim_len + indexn1 - 4; + + if (index < indexn1 || index > indexn2) + return false; + + index -= indexn1; + + return !!(tim->virtual_map[index] & mask); +} + #endif /* LINUX_IEEE80211_H */ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index dba78d89a10c..1579bc92c88d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -832,7 +832,7 @@ struct ieee802_11_elems { u8 *fh_params; u8 *ds_params; u8 *cf_params; - u8 *tim; + struct ieee80211_tim_ie *tim; u8 *ibss_params; u8 *challenge; u8 *wpa; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 428742d7f440..1b0b7aa387ee 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -675,30 +675,6 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, } } -static bool ieee80211_check_tim(struct ieee802_11_elems *elems, u16 aid) -{ - u8 mask; - u8 index, indexn1, indexn2; - struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim; - - if (unlikely(!tim || elems->tim_len < 4)) - return false; - - aid &= 0x3fff; - index = aid / 8; - mask = 1 << (aid & 7); - - indexn1 = tim->bitmap_ctrl & 0xfe; - indexn2 = elems->tim_len + indexn1 - 4; - - if (index < indexn1 || index > indexn2) - return false; - - index -= indexn1; - - return !!(tim->virtual_map[index] & mask); -} - static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, u16 capab, bool erp_valid, u8 erp) { @@ -1806,7 +1782,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, care_about_ies, ncrc); if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) - directed_tim = ieee80211_check_tim(&elems, ifmgd->aid); + directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, + ifmgd->aid); ncrc = crc32_be(ncrc, (void *)&directed_tim, sizeof(directed_tim)); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 11244212f41d..61876eb50b49 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -588,8 +588,10 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, elems->cf_params_len = elen; break; case WLAN_EID_TIM: - elems->tim = pos; - elems->tim_len = elen; + if (elen >= sizeof(struct ieee80211_tim_ie)) { + elems->tim = (void *)pos; + elems->tim_len = elen; + } break; case WLAN_EID_IBSS_PARAMS: elems->ibss_params = pos; -- GitLab From cca84799dfe9f5201ae9c69eb8ed15fd26b72b37 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 19 Apr 2009 01:28:12 +0200 Subject: [PATCH 0650/6080] ar9170: rework rxstream code With this patch ar9170 is capable of receiving aggregated 802.11n frames and sniffing on most networks without having a "debug message overhead". (Includes phy initialization requested by Johannes Berg -- JWL) Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ar9170/ar9170.h | 12 + drivers/net/wireless/ath/ar9170/hw.h | 15 +- drivers/net/wireless/ath/ar9170/main.c | 532 +++++++++++++++++------ 3 files changed, 421 insertions(+), 138 deletions(-) diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index b6a1bff67cab..17bd3eaf3e03 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h @@ -104,10 +104,16 @@ enum ar9170_device_state { AR9170_ASSOCIATED, }; +struct ar9170_rxstream_mpdu_merge { + struct ar9170_rx_head plcp; + bool has_plcp; +}; + struct ar9170 { struct ieee80211_hw *hw; struct mutex mutex; enum ar9170_device_state state; + unsigned long bad_hw_nagger; int (*open)(struct ar9170 *); void (*stop)(struct ar9170 *); @@ -135,6 +141,7 @@ struct ar9170 { u64 cur_mc_hash, want_mc_hash; u32 cur_filter, want_filter; unsigned int filter_changed; + unsigned int filter_state; bool sniffer_enabled; /* PHY */ @@ -174,6 +181,11 @@ struct ar9170 { struct sk_buff_head global_tx_status; struct sk_buff_head global_tx_status_waste; struct delayed_work tx_status_janitor; + + /* rxstream mpdu merge */ + struct ar9170_rxstream_mpdu_merge rx_mpdu; + struct sk_buff *rx_failover; + int rx_failover_missing; }; struct ar9170_sta_info { diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h index 53e250a4278f..95bf812d6fcc 100644 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ b/drivers/net/wireless/ath/ar9170/hw.h @@ -312,7 +312,7 @@ struct ar9170_rx_head { u8 plcp[12]; } __packed; -struct ar9170_rx_tail { +struct ar9170_rx_phystatus { union { struct { u8 rssi_ant0, rssi_ant1, rssi_ant2, @@ -324,6 +324,9 @@ struct ar9170_rx_tail { u8 evm_stream0[6], evm_stream1[6]; u8 phy_err; +} __packed; + +struct ar9170_rx_macstatus { u8 SAidx, DAidx; u8 error; u8 status; @@ -339,7 +342,7 @@ struct ar9170_rx_tail { #define AR9170_RX_ENC_SOFTWARE 0x8 -static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t) +static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) { return (t->SAidx & 0xc0) >> 4 | (t->DAidx & 0xc0) >> 6; @@ -357,10 +360,9 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t) #define AR9170_RX_STATUS_MPDU_MASK 0x30 #define AR9170_RX_STATUS_MPDU_SINGLE 0x00 -#define AR9170_RX_STATUS_MPDU_FIRST 0x10 -#define AR9170_RX_STATUS_MPDU_MIDDLE 0x20 -#define AR9170_RX_STATUS_MPDU_LAST 0x30 - +#define AR9170_RX_STATUS_MPDU_FIRST 0x20 +#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 +#define AR9170_RX_STATUS_MPDU_LAST 0x10 #define AR9170_RX_ERROR_RXTO 0x01 #define AR9170_RX_ERROR_OVERRUN 0x02 @@ -369,6 +371,7 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t) #define AR9170_RX_ERROR_WRONG_RA 0x10 #define AR9170_RX_ERROR_PLCP 0x20 #define AR9170_RX_ERROR_MMIC 0x40 +#define AR9170_RX_ERROR_FATAL 0x80 struct ar9170_cmd_tx_status { __le16 unkn; diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 4682fe2f3f3c..1b60906b80c9 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -454,214 +454,430 @@ static void ar9170_handle_command_response(struct ar9170 *ar, } } -/* - * If the frame alignment is right (or the kernel has - * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there - * is only a single MPDU in the USB frame, then we can - * submit to mac80211 the SKB directly. However, since - * there may be multiple packets in one SKB in stream - * mode, and we need to observe the proper ordering, - * this is non-trivial. - */ -static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) +static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar) { - struct sk_buff *skb; - struct ar9170_rx_head *head = (void *)buf; - struct ar9170_rx_tail *tail; - struct ieee80211_rx_status status; - int mpdu_len, i; - u8 error, antennas = 0, decrypt; - __le16 fc; - int reserved; + memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head)); + ar->rx_mpdu.has_plcp = false; +} - if (unlikely(!IS_STARTED(ar))) - return ; +static int ar9170_nag_limiter(struct ar9170 *ar) +{ + bool print_message; + + /* + * we expect all sorts of errors in promiscuous mode. + * don't bother with it, it's OK! + */ + if (ar->sniffer_enabled) + return false; + + /* + * only go for frequent errors! The hardware tends to + * do some stupid thing once in a while under load, in + * noisy environments or just for fun! + */ + if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit()) + print_message = true; + else + print_message = false; + + /* reset threshold for "once in a while" */ + ar->bad_hw_nagger = jiffies + HZ / 4; + return print_message; +} + +static int ar9170_rx_mac_status(struct ar9170 *ar, + struct ar9170_rx_head *head, + struct ar9170_rx_macstatus *mac, + struct ieee80211_rx_status *status) +{ + u8 error, decrypt; - /* Received MPDU */ - mpdu_len = len; - mpdu_len -= sizeof(struct ar9170_rx_head); - mpdu_len -= sizeof(struct ar9170_rx_tail); BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12); - BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24); + BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4); - if (mpdu_len <= FCS_LEN) - return; + error = mac->error; + if (error & AR9170_RX_ERROR_MMIC) { + status->flag |= RX_FLAG_MMIC_ERROR; + error &= ~AR9170_RX_ERROR_MMIC; + } - tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len); + if (error & AR9170_RX_ERROR_PLCP) { + status->flag |= RX_FLAG_FAILED_PLCP_CRC; + error &= ~AR9170_RX_ERROR_PLCP; - for (i = 0; i < 3; i++) - if (tail->rssi[i] != 0x80) - antennas |= BIT(i); + if (!(ar->filter_state & FIF_PLCPFAIL)) + return -EINVAL; + } - /* post-process RSSI */ - for (i = 0; i < 7; i++) - if (tail->rssi[i] & 0x80) - tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f; + if (error & AR9170_RX_ERROR_FCS) { + status->flag |= RX_FLAG_FAILED_FCS_CRC; + error &= ~AR9170_RX_ERROR_FCS; - memset(&status, 0, sizeof(status)); + if (!(ar->filter_state & FIF_FCSFAIL)) + return -EINVAL; + } + + decrypt = ar9170_get_decrypt_type(mac); + if (!(decrypt & AR9170_RX_ENC_SOFTWARE) && + decrypt != AR9170_ENC_ALG_NONE) + status->flag |= RX_FLAG_DECRYPTED; - status.band = ar->channel->band; - status.freq = ar->channel->center_freq; - status.signal = ar->noise[0] + tail->rssi_combined; - status.noise = ar->noise[0]; - status.antenna = antennas; + /* ignore wrong RA errors */ + error &= ~AR9170_RX_ERROR_WRONG_RA; - switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) { + if (error & AR9170_RX_ERROR_DECRYPT) { + error &= ~AR9170_RX_ERROR_DECRYPT; + /* + * Rx decryption is done in place, + * the original data is lost anyway. + */ + + return -EINVAL; + } + + /* drop any other error frames */ + if (unlikely(error)) { + /* TODO: update netdevice's RX dropped/errors statistics */ + + if (ar9170_nag_limiter(ar)) + printk(KERN_DEBUG "%s: received frame with " + "suspicious error code (%#x).\n", + wiphy_name(ar->hw->wiphy), error); + + return -EINVAL; + } + + status->band = ar->channel->band; + status->freq = ar->channel->center_freq; + + switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) { case AR9170_RX_STATUS_MODULATION_CCK: - if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE) - status.flag |= RX_FLAG_SHORTPRE; + if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE) + status->flag |= RX_FLAG_SHORTPRE; switch (head->plcp[0]) { case 0x0a: - status.rate_idx = 0; + status->rate_idx = 0; break; case 0x14: - status.rate_idx = 1; + status->rate_idx = 1; break; case 0x37: - status.rate_idx = 2; + status->rate_idx = 2; break; case 0x6e: - status.rate_idx = 3; + status->rate_idx = 3; break; default: - if ((!ar->sniffer_enabled) && (net_ratelimit())) + if (ar9170_nag_limiter(ar)) printk(KERN_ERR "%s: invalid plcp cck rate " "(%x).\n", wiphy_name(ar->hw->wiphy), head->plcp[0]); - return; + return -EINVAL; } break; + case AR9170_RX_STATUS_MODULATION_OFDM: - switch (head->plcp[0] & 0xF) { - case 0xB: - status.rate_idx = 0; + switch (head->plcp[0] & 0xf) { + case 0xb: + status->rate_idx = 0; break; - case 0xF: - status.rate_idx = 1; + case 0xf: + status->rate_idx = 1; break; - case 0xA: - status.rate_idx = 2; + case 0xa: + status->rate_idx = 2; break; - case 0xE: - status.rate_idx = 3; + case 0xe: + status->rate_idx = 3; break; case 0x9: - status.rate_idx = 4; + status->rate_idx = 4; break; - case 0xD: - status.rate_idx = 5; + case 0xd: + status->rate_idx = 5; break; case 0x8: - status.rate_idx = 6; + status->rate_idx = 6; break; - case 0xC: - status.rate_idx = 7; + case 0xc: + status->rate_idx = 7; break; default: - if ((!ar->sniffer_enabled) && (net_ratelimit())) + if (ar9170_nag_limiter(ar)) printk(KERN_ERR "%s: invalid plcp ofdm rate " "(%x).\n", wiphy_name(ar->hw->wiphy), head->plcp[0]); - return; + return -EINVAL; } - if (status.band == IEEE80211_BAND_2GHZ) - status.rate_idx += 4; + if (status->band == IEEE80211_BAND_2GHZ) + status->rate_idx += 4; break; + case AR9170_RX_STATUS_MODULATION_HT: + if (head->plcp[3] & 0x80) + status->flag |= RX_FLAG_40MHZ; + if (head->plcp[6] & 0x80) + status->flag |= RX_FLAG_SHORT_GI; + + status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f); + status->flag |= RX_FLAG_HT; + break; + case AR9170_RX_STATUS_MODULATION_DUPOFDM: /* XXX */ - - if (net_ratelimit()) + if (ar9170_nag_limiter(ar)) printk(KERN_ERR "%s: invalid modulation\n", wiphy_name(ar->hw->wiphy)); - return; + return -EINVAL; } - error = tail->error; + return 0; +} - if (error & AR9170_RX_ERROR_MMIC) { - status.flag |= RX_FLAG_MMIC_ERROR; - error &= ~AR9170_RX_ERROR_MMIC; - } +static void ar9170_rx_phy_status(struct ar9170 *ar, + struct ar9170_rx_phystatus *phy, + struct ieee80211_rx_status *status) +{ + int i; - if (error & AR9170_RX_ERROR_PLCP) { - status.flag |= RX_FLAG_FAILED_PLCP_CRC; - error &= ~AR9170_RX_ERROR_PLCP; + BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20); + + for (i = 0; i < 3; i++) + if (phy->rssi[i] != 0x80) + status->antenna |= BIT(i); + + /* post-process RSSI */ + for (i = 0; i < 7; i++) + if (phy->rssi[i] & 0x80) + phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f; + + /* TODO: we could do something with phy_errors */ + status->signal = ar->noise[0] + phy->rssi_combined; + status->noise = ar->noise[0]; +} + +static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) +{ + struct sk_buff *skb; + int reserved = 0; + struct ieee80211_hdr *hdr = (void *) buf; + + if (ieee80211_is_data_qos(hdr->frame_control)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + reserved += NET_IP_ALIGN; + + if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) + reserved += NET_IP_ALIGN; } - if (error & AR9170_RX_ERROR_FCS) { - status.flag |= RX_FLAG_FAILED_FCS_CRC; - error &= ~AR9170_RX_ERROR_FCS; + if (ieee80211_has_a4(hdr->frame_control)) + reserved += NET_IP_ALIGN; + + reserved = 32 + (reserved & NET_IP_ALIGN); + + skb = dev_alloc_skb(len + reserved); + if (likely(skb)) { + skb_reserve(skb, reserved); + memcpy(skb_put(skb, len), buf, len); } - decrypt = ar9170_get_decrypt_type(tail); - if (!(decrypt & AR9170_RX_ENC_SOFTWARE) && - decrypt != AR9170_ENC_ALG_NONE) - status.flag |= RX_FLAG_DECRYPTED; + return skb; +} - /* ignore wrong RA errors */ - error &= ~AR9170_RX_ERROR_WRONG_RA; +/* + * If the frame alignment is right (or the kernel has + * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there + * is only a single MPDU in the USB frame, then we could + * submit to mac80211 the SKB directly. However, since + * there may be multiple packets in one SKB in stream + * mode, and we need to observe the proper ordering, + * this is non-trivial. + */ - if (error & AR9170_RX_ERROR_DECRYPT) { - error &= ~AR9170_RX_ERROR_DECRYPT; +static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) +{ + struct ar9170_rx_head *head; + struct ar9170_rx_macstatus *mac; + struct ar9170_rx_phystatus *phy = NULL; + struct ieee80211_rx_status status; + struct sk_buff *skb; + int mpdu_len; + + if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac)))) + return ; + + /* Received MPDU */ + mpdu_len = len - sizeof(*mac); + + mac = (void *)(buf + mpdu_len); + if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) { + /* this frame is too damaged and can't be used - drop it */ - /* - * Rx decryption is done in place, - * the original data is lost anyway. - */ return ; } - /* drop any other error frames */ - if ((error) && (net_ratelimit())) { - printk(KERN_DEBUG "%s: errors: %#x\n", - wiphy_name(ar->hw->wiphy), error); - return; + switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) { + case AR9170_RX_STATUS_MPDU_FIRST: + /* first mpdu packet has the plcp header */ + if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { + head = (void *) buf; + memcpy(&ar->rx_mpdu.plcp, (void *) buf, + sizeof(struct ar9170_rx_head)); + + mpdu_len -= sizeof(struct ar9170_rx_head); + buf += sizeof(struct ar9170_rx_head); + ar->rx_mpdu.has_plcp = true; + } else { + if (ar9170_nag_limiter(ar)) + printk(KERN_ERR "%s: plcp info is clipped.\n", + wiphy_name(ar->hw->wiphy)); + return ; + } + break; + + case AR9170_RX_STATUS_MPDU_LAST: + /* last mpdu has a extra tail with phy status information */ + + if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) { + mpdu_len -= sizeof(struct ar9170_rx_phystatus); + phy = (void *)(buf + mpdu_len); + } else { + if (ar9170_nag_limiter(ar)) + printk(KERN_ERR "%s: frame tail is clipped.\n", + wiphy_name(ar->hw->wiphy)); + return ; + } + + case AR9170_RX_STATUS_MPDU_MIDDLE: + /* middle mpdus are just data */ + if (unlikely(!ar->rx_mpdu.has_plcp)) { + if (!ar9170_nag_limiter(ar)) + return ; + + printk(KERN_ERR "%s: rx stream did not start " + "with a first_mpdu frame tag.\n", + wiphy_name(ar->hw->wiphy)); + + return ; + } + + head = &ar->rx_mpdu.plcp; + break; + + case AR9170_RX_STATUS_MPDU_SINGLE: + /* single mpdu - has plcp (head) and phy status (tail) */ + head = (void *) buf; + + mpdu_len -= sizeof(struct ar9170_rx_head); + mpdu_len -= sizeof(struct ar9170_rx_phystatus); + + buf += sizeof(struct ar9170_rx_head); + phy = (void *)(buf + mpdu_len); + break; + + default: + BUG_ON(1); + break; } - buf += sizeof(struct ar9170_rx_head); - fc = *(__le16 *)buf; + if (unlikely(mpdu_len < FCS_LEN)) + return ; - if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc)) - reserved = 32 + 2; - else - reserved = 32; + memset(&status, 0, sizeof(status)); + if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status))) + return ; - skb = dev_alloc_skb(mpdu_len + reserved); - if (!skb) - return; + if (phy) + ar9170_rx_phy_status(ar, phy, &status); - skb_reserve(skb, reserved); - memcpy(skb_put(skb, mpdu_len), buf, mpdu_len); - ieee80211_rx_irqsafe(ar->hw, skb, &status); + skb = ar9170_rx_copy_data(buf, mpdu_len); + if (likely(skb)) + ieee80211_rx_irqsafe(ar->hw, skb, &status); } void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) { - unsigned int i, tlen, resplen; + unsigned int i, tlen, resplen, wlen = 0, clen = 0; u8 *tbuf, *respbuf; tbuf = skb->data; tlen = skb->len; while (tlen >= 4) { - int clen = tbuf[1] << 8 | tbuf[0]; - int wlen = (clen + 3) & ~3; + clen = tbuf[1] << 8 | tbuf[0]; + wlen = ALIGN(clen, 4); - /* - * parse stream (if any) - */ + /* check if this is stream has a valid tag.*/ if (tbuf[2] != 0 || tbuf[3] != 0x4e) { - printk(KERN_ERR "%s: missing tag!\n", - wiphy_name(ar->hw->wiphy)); + /* + * TODO: handle the highly unlikely event that the + * corrupted stream has the TAG at the right position. + */ + + /* check if the frame can be repaired. */ + if (!ar->rx_failover_missing) { + /* this is no "short read". */ + if (ar9170_nag_limiter(ar)) { + printk(KERN_ERR "%s: missing tag!\n", + wiphy_name(ar->hw->wiphy)); + goto err_telluser; + } else + goto err_silent; + } + + if (ar->rx_failover_missing > tlen) { + if (ar9170_nag_limiter(ar)) { + printk(KERN_ERR "%s: possible multi " + "stream corruption!\n", + wiphy_name(ar->hw->wiphy)); + goto err_telluser; + } else + goto err_silent; + } + + memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); + ar->rx_failover_missing -= tlen; + + if (ar->rx_failover_missing <= 0) { + /* + * nested ar9170_rx call! + * termination is guranteed, even when the + * combined frame also have a element with + * a bad tag. + */ + + ar->rx_failover_missing = 0; + ar9170_rx(ar, ar->rx_failover); + + skb_reset_tail_pointer(ar->rx_failover); + skb_trim(ar->rx_failover, 0); + } + return ; } + + /* check if stream is clipped */ if (wlen > tlen - 4) { - printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n", - wiphy_name(ar->hw->wiphy), clen, wlen, tlen); - print_hex_dump(KERN_DEBUG, "data: ", - DUMP_PREFIX_OFFSET, - 16, 1, tbuf, tlen, true); + if (ar->rx_failover_missing) { + /* TODO: handle double stream corruption. */ + if (ar9170_nag_limiter(ar)) { + printk(KERN_ERR "%s: double rx stream " + "corruption!\n", + wiphy_name(ar->hw->wiphy)); + goto err_telluser; + } else + goto err_silent; + } + + /* + * save incomplete data set. + * the firmware will resend the missing bits when + * the rx - descriptor comes round again. + */ + + memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); + ar->rx_failover_missing = clen - tlen; return ; } resplen = clen; @@ -686,12 +902,44 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb) if (i == 12) ar9170_handle_command_response(ar, respbuf, resplen); else - ar9170_handle_mpdu(ar, respbuf, resplen); + ar9170_handle_mpdu(ar, respbuf, clen); } - if (tlen) - printk(KERN_ERR "%s: buffer remains!\n", - wiphy_name(ar->hw->wiphy)); + if (tlen) { + if (net_ratelimit()) + printk(KERN_ERR "%s: %d bytes of unprocessed " + "data left in rx stream!\n", + wiphy_name(ar->hw->wiphy), tlen); + + goto err_telluser; + } + + return ; + +err_telluser: + printk(KERN_ERR "%s: damaged RX stream data [want:%d, " + "data:%d, rx:%d, pending:%d ]\n", + wiphy_name(ar->hw->wiphy), clen, wlen, tlen, + ar->rx_failover_missing); + + if (ar->rx_failover_missing) + print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, + ar->rx_failover->data, + ar->rx_failover->len); + + print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, + skb->data, skb->len); + + printk(KERN_ERR "%s: please check your hardware and cables, if " + "you see this message frequently.\n", + wiphy_name(ar->hw->wiphy)); + +err_silent: + if (ar->rx_failover_missing) { + skb_reset_tail_pointer(ar->rx_failover); + skb_trim(ar->rx_failover, 0); + ar->rx_failover_missing = 0; + } } #define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \ @@ -721,6 +969,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw) AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */ AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */ + ar->bad_hw_nagger = jiffies; + err = ar->open(ar); if (err) goto out; @@ -1175,8 +1425,8 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, /* mask supported flags */ *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC | - FIF_PROMISC_IN_BSS; - + FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL; + ar->filter_state = *new_flags; /* * We can support more by setting the sniffer bit and * then checking the error flags, later. @@ -1559,20 +1809,33 @@ void *ar9170_alloc(size_t priv_size) { struct ieee80211_hw *hw; struct ar9170 *ar; + struct sk_buff *skb; int i; + /* + * this buffer is used for rx stream reconstruction. + * Under heavy load this device (or the transport layer?) + * tends to split the streams into seperate rx descriptors. + */ + + skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); + if (!skb) + goto err_nomem; + hw = ieee80211_alloc_hw(priv_size, &ar9170_ops); if (!hw) - return ERR_PTR(-ENOMEM); + goto err_nomem; ar = hw->priv; ar->hw = hw; + ar->rx_failover = skb; mutex_init(&ar->mutex); spin_lock_init(&ar->cmdlock); spin_lock_init(&ar->tx_stats_lock); skb_queue_head_init(&ar->global_tx_status); skb_queue_head_init(&ar->global_tx_status_waste); + ar9170_rx_reset_rx_mpdu(ar); INIT_WORK(&ar->filter_config_work, ar9170_set_filters); INIT_WORK(&ar->beacon_work, ar9170_new_beacon); INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor); @@ -1600,6 +1863,10 @@ void *ar9170_alloc(size_t priv_size) ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ return ar; + +err_nomem: + kfree_skb(skb); + return ERR_PTR(-ENOMEM); } static int ar9170_read_eeprom(struct ar9170 *ar) @@ -1725,6 +1992,7 @@ void ar9170_unregister(struct ar9170 *ar) ar9170_unregister_leds(ar); #endif /* CONFIG_AR9170_LEDS */ + kfree_skb(ar->rx_failover); ieee80211_unregister_hw(ar->hw); mutex_destroy(&ar->mutex); } -- GitLab From 9b3bf06abad70db820c74c90118ea49358549d22 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Apr 2009 14:36:55 -0700 Subject: [PATCH 0651/6080] iwlwifi: rename PROBE_OPTION_MAX_API1 to PROBE_OPTION_MAX_3945 This limit applies to current (APIv1 and APIv2) 3945 firmware only, not supported firmware of any of the other cards. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 29d40746da6a..411a5d2d9148 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2469,8 +2469,8 @@ struct iwl_ssid_ie { u8 ssid[32]; } __attribute__ ((packed)); -#define PROBE_OPTION_MAX_API1 0x4 -#define PROBE_OPTION_MAX 0x14 +#define PROBE_OPTION_MAX_3945 4 +#define PROBE_OPTION_MAX 20 #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) #define IWL_GOOD_CRC_TH cpu_to_le16(1) #define IWL_MAX_SCAN_SIZE 1024 @@ -2552,7 +2552,7 @@ struct iwl3945_scan_cmd { struct iwl3945_tx_cmd tx_cmd; /* For directed active scans (set to all-0s otherwise) */ - struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_API1]; + struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945]; /* * Probe request frame, followed by channel list. -- GitLab From 1ecf9fc1317f8df91eb1d74360f408558d657478 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Apr 2009 14:36:56 -0700 Subject: [PATCH 0652/6080] iwlwifi: improve scan support This modifies iwlwifi to * no longer build its own probe request, but use mac80211's * therefore, support arbitrary scan IEs (up to the max len) * support multiple scan SSIDs * support passive scanning Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 6 +- drivers/net/wireless/iwlwifi/iwl-core.h | 4 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 187 ++++---------------- drivers/net/wireless/iwlwifi/iwl3945-base.c | 48 +++-- 6 files changed, 73 insertions(+), 177 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 411a5d2d9148..7b84d5246b36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2474,6 +2474,7 @@ struct iwl_ssid_ie { #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF) #define IWL_GOOD_CRC_TH cpu_to_le16(1) #define IWL_MAX_SCAN_SIZE 1024 +#define IWL_MAX_PROBE_REQUEST 200 /* * REPLY_SCAN_CMD = 0x80 (command) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f23175240289..c43c57d7a4cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1309,8 +1309,10 @@ int iwl_setup_mac(struct iwl_priv *priv) BIT(NL80211_IFTYPE_ADHOC); hw->wiphy->custom_regulatory = true; - hw->wiphy->max_scan_ssids = 1; - hw->wiphy->max_scan_ie_len = 0; /* XXX for now */ + + hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; + /* we create the 802.11 header and a zero-length SSID element */ + hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; /* Default value; 4 EDCA QOS priorities */ hw->queues = 4; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 8773d733a54e..8ab60df48d56 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -396,8 +396,8 @@ int iwl_scan_cancel(struct iwl_priv *priv); int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); int iwl_scan_initiate(struct iwl_priv *priv); int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); -u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band, - struct ieee80211_mgmt *frame, int left); +u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, + const u8 *ie, int ie_len, int left); void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); u16 iwl_get_active_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 0922e33a7d42..e363d9b05eeb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -889,9 +889,7 @@ struct iwl_priv { unsigned long scan_start_tsf; void *scan; int scan_bands; - int one_direct_scan; - u8 direct_ssid_len; - u8 direct_ssid[IW_ESSID_MAX_SIZE]; + struct cfg80211_scan_request *scan_request; u8 scan_tx_ant[IEEE80211_NUM_BANDS]; u8 mgmt_tx_ant; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 23644cf884f1..9edcf8c76b20 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -448,13 +448,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, unsigned long flags; struct iwl_priv *priv = hw->priv; int ret; - u8 *ssid = NULL; - size_t ssid_len = 0; - - if (req->n_ssids) { - ssid = req->ssids[0].ssid; - ssid_len = req->ssids[0].ssid_len; - } IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -488,13 +481,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, goto out_unlock; } - if (ssid_len) { - priv->one_direct_scan = 1; - priv->direct_ssid_len = ssid_len; - memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len); - } else { - priv->one_direct_scan = 0; - } + priv->scan_request = req; ret = iwl_scan_initiate(priv); @@ -532,74 +519,15 @@ void iwl_bg_scan_check(struct work_struct *data) } EXPORT_SYMBOL(iwl_bg_scan_check); -/** - * iwl_supported_rate_to_ie - fill in the supported rate in IE field - * - * return : set the bit for each supported rate insert in ie - */ -static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, - u16 basic_rate, int *left) -{ - u16 ret_rates = 0, bit; - int i; - u8 *cnt = ie; - u8 *rates = ie + 1; - - for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { - if (bit & supported_rate) { - ret_rates |= bit; - rates[*cnt] = iwl_rates[i].ieee | - ((bit & basic_rate) ? 0x80 : 0x00); - (*cnt)++; - (*left)--; - if ((*left <= 0) || - (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) - break; - } - } - - return ret_rates; -} - - -static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, - u8 *pos, int *left) -{ - struct ieee80211_ht_cap *ht_cap; - - if (!sband || !sband->ht_cap.ht_supported) - return; - - if (*left < sizeof(struct ieee80211_ht_cap)) - return; - - *pos++ = sizeof(struct ieee80211_ht_cap); - ht_cap = (struct ieee80211_ht_cap *) pos; - - ht_cap->cap_info = cpu_to_le16(sband->ht_cap.cap); - memcpy(&ht_cap->mcs, &sband->ht_cap.mcs, 16); - ht_cap->ampdu_params_info = - (sband->ht_cap.ampdu_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) | - ((sband->ht_cap.ampdu_density << 2) & - IEEE80211_HT_AMPDU_PARM_DENSITY); - *left -= sizeof(struct ieee80211_ht_cap); -} - /** * iwl_fill_probe_req - fill in all required fields and IE for probe request */ -u16 iwl_fill_probe_req(struct iwl_priv *priv, - enum ieee80211_band band, - struct ieee80211_mgmt *frame, - int left) +u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, + const u8 *ies, int ie_len, int left) { int len = 0; u8 *pos = NULL; - u16 active_rates, ret_rates, cck_rates, active_rate_basic; - const struct ieee80211_supported_band *sband = - iwl_get_hw_mode(priv, band); - /* Make sure there is enough space for the probe request, * two mandatory IEs and the data */ @@ -627,62 +555,12 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, len += 2; - /* fill in supported rate */ - left -= 2; - if (left < 0) - return 0; - - *pos++ = WLAN_EID_SUPP_RATES; - *pos = 0; - - /* exclude 60M rate */ - active_rates = priv->rates_mask; - active_rates &= ~IWL_RATE_60M_MASK; - - active_rate_basic = active_rates & IWL_BASIC_RATES_MASK; - - cck_rates = IWL_CCK_RATES_MASK & active_rates; - ret_rates = iwl_supported_rate_to_ie(pos, cck_rates, - active_rate_basic, &left); - active_rates &= ~ret_rates; - - ret_rates = iwl_supported_rate_to_ie(pos, active_rates, - active_rate_basic, &left); - active_rates &= ~ret_rates; + if (WARN_ON(left < ie_len)) + return len; - len += 2 + *pos; - pos += (*pos) + 1; - - if (active_rates == 0) - goto fill_end; - - /* fill in supported extended rate */ - /* ...next IE... */ - left -= 2; - if (left < 0) - return 0; - /* ... fill it in... */ - *pos++ = WLAN_EID_EXT_SUPP_RATES; - *pos = 0; - iwl_supported_rate_to_ie(pos, active_rates, active_rate_basic, &left); - if (*pos > 0) { - len += 2 + *pos; - pos += (*pos) + 1; - } else { - pos--; - } - - fill_end: - - left -= 2; - if (left < 0) - return 0; - - *pos++ = WLAN_EID_HT_CAPABILITY; - *pos = 0; - iwl_ht_cap_to_ie(sband, pos, &left); - if (*pos > 0) - len += 2 + *pos; + memcpy(pos, ies, ie_len); + len += ie_len; + left -= ie_len; return (u16)len; } @@ -703,10 +581,10 @@ static void iwl_bg_request_scan(struct work_struct *data) u32 rate_flags = 0; u16 cmd_len; enum ieee80211_band band; - u8 n_probes = 2; + u8 n_probes = 0; u8 rx_chain = priv->hw_params.valid_rx_ant; u8 rate; - DECLARE_SSID_BUF(ssid); + bool is_active = false; conf = ieee80211_get_hw_conf(priv->hw); @@ -796,19 +674,25 @@ static void iwl_bg_request_scan(struct work_struct *data) scan_suspend_time, interval); } - /* We should add the ability for user to lock to PASSIVE ONLY */ - if (priv->one_direct_scan) { - IWL_DEBUG_SCAN(priv, "Start direct scan for '%s'\n", - print_ssid(ssid, priv->direct_ssid, - priv->direct_ssid_len)); - scan->direct_scan[0].id = WLAN_EID_SSID; - scan->direct_scan[0].len = priv->direct_ssid_len; - memcpy(scan->direct_scan[0].ssid, - priv->direct_ssid, priv->direct_ssid_len); - n_probes++; - } else { - IWL_DEBUG_SCAN(priv, "Start indirect scan.\n"); - } + if (priv->scan_request->n_ssids) { + int i, p = 0; + IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; + scan->direct_scan[p].id = WLAN_EID_SSID; + scan->direct_scan[p].len = + priv->scan_request->ssids[i].ssid_len; + memcpy(scan->direct_scan[p].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + n_probes++; + p++; + } + is_active = true; + } else + IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; @@ -850,10 +734,11 @@ static void iwl_bg_request_scan(struct work_struct *data) cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) | (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); - - cmd_len = iwl_fill_probe_req(priv, band, - (struct ieee80211_mgmt *)scan->data, - IWL_MAX_SCAN_SIZE - sizeof(*scan)); + cmd_len = iwl_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + priv->scan_request->ie, + priv->scan_request->ie_len, + IWL_MAX_SCAN_SIZE - sizeof(*scan)); scan->tx_cmd.len = cpu_to_le16(cmd_len); @@ -864,8 +749,7 @@ static void iwl_bg_request_scan(struct work_struct *data) RXON_FILTER_BCON_AWARE_MSK); scan->channel_count = - iwl_get_channels_for_scan(priv, band, 1, /* active */ - n_probes, + iwl_get_channels_for_scan(priv, band, is_active, n_probes, (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); if (scan->channel_count == 0) { @@ -928,6 +812,7 @@ void iwl_bg_scan_completed(struct work_struct *work) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; + priv->scan_request = NULL; ieee80211_scan_completed(priv->hw, false); /* Since setting the TXPOWER may have been deferred while diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index ed497551a860..4df9b4b5072a 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2942,9 +2942,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data) int rc = 0; struct iwl3945_scan_cmd *scan; struct ieee80211_conf *conf = NULL; - u8 n_probes = 2; + u8 n_probes = 0; enum ieee80211_band band; - DECLARE_SSID_BUF(ssid); + bool is_active = false; conf = ieee80211_get_hw_conf(priv->hw); @@ -3043,18 +3043,25 @@ static void iwl3945_bg_request_scan(struct work_struct *data) scan_suspend_time, interval); } - /* We should add the ability for user to lock to PASSIVE ONLY */ - if (priv->one_direct_scan) { - IWL_DEBUG_SCAN(priv, "Kicking off one direct scan for '%s'\n", - print_ssid(ssid, priv->direct_ssid, - priv->direct_ssid_len)); - scan->direct_scan[0].id = WLAN_EID_SSID; - scan->direct_scan[0].len = priv->direct_ssid_len; - memcpy(scan->direct_scan[0].ssid, - priv->direct_ssid, priv->direct_ssid_len); - n_probes++; + if (priv->scan_request->n_ssids) { + int i, p = 0; + IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); + for (i = 0; i < priv->scan_request->n_ssids; i++) { + /* always does wildcard anyway */ + if (!priv->scan_request->ssids[i].ssid_len) + continue; + scan->direct_scan[p].id = WLAN_EID_SSID; + scan->direct_scan[p].len = + priv->scan_request->ssids[i].ssid_len; + memcpy(scan->direct_scan[p].ssid, + priv->scan_request->ssids[i].ssid, + priv->scan_request->ssids[i].ssid_len); + n_probes++; + p++; + } + is_active = true; } else - IWL_DEBUG_SCAN(priv, "Kicking off one indirect scan.\n"); + IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n"); /* We don't build a direct scan probe request; the uCode will do * that based on the direct_mask added to each channel entry */ @@ -3079,9 +3086,11 @@ static void iwl3945_bg_request_scan(struct work_struct *data) } scan->tx_cmd.len = cpu_to_le16( - iwl_fill_probe_req(priv, band, - (struct ieee80211_mgmt *)scan->data, - IWL_MAX_SCAN_SIZE - sizeof(*scan))); + iwl_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + priv->scan_request->ie, + priv->scan_request->ie_len, + IWL_MAX_SCAN_SIZE - sizeof(*scan))); /* select Rx antennas */ scan->flags |= iwl3945_get_antenna_flags(priv); @@ -3090,8 +3099,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) scan->filter_flags = RXON_FILTER_PROMISC_MSK; scan->channel_count = - iwl3945_get_channels_for_scan(priv, band, 1, /* active */ - n_probes, + iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); if (scan->channel_count == 0) { @@ -4119,7 +4127,9 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) hw->wiphy->custom_regulatory = true; - hw->wiphy->max_scan_ssids = 1; /* WILL FIX */ + hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; + /* we create the 802.11 header and a zero-length SSID element */ + hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; /* Default value; 4 EDCA QOS priorities */ hw->queues = 4; -- GitLab From b097ad29752f909ec1121ac3dc57d348f08dd8d7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Apr 2009 14:36:57 -0700 Subject: [PATCH 0653/6080] iwlwifi: support truly passive scanning If passive scanning is requested we should not ask the microcode to do active scanning after detecting traffic on a channel -- that should only be used when an active scan is requested but some channels are marked passive. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 7 ++++++- drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 9edcf8c76b20..25311e1ceed7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -712,7 +712,12 @@ static void iwl_bg_request_scan(struct work_struct *data) } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { band = IEEE80211_BAND_5GHZ; rate = IWL_RATE_6M_PLCP; - scan->good_CRC_th = IWL_GOOD_CRC_TH; + /* + * If active scaning is requested but a certain channel + * is marked passive, we can do active scanning if we + * detect transmissions. + */ + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; /* Force use of chains B and C (0x6) for scan Rx for 4965 * Avoid A (0x1) because of its off-channel reception on A-band. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4df9b4b5072a..c15d0cfb93bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3078,7 +3078,12 @@ static void iwl3945_bg_request_scan(struct work_struct *data) band = IEEE80211_BAND_2GHZ; } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { scan->tx_cmd.rate = IWL_RATE_6M_PLCP; - scan->good_CRC_th = IWL_GOOD_CRC_TH; + /* + * If active scaning is requested but a certain channel + * is marked passive, we can do active scanning if we + * detect transmissions. + */ + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; band = IEEE80211_BAND_5GHZ; } else { IWL_WARN(priv, "Invalid scan band count\n"); -- GitLab From a75fbe8d68ceace836b27c216a5eda1c4687be4b Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Mon, 20 Apr 2009 14:36:58 -0700 Subject: [PATCH 0654/6080] iwl3945: add debugfs to 3945 Patch adds debugfs to 3945. Also fix debugfs registration in iwlagn to return error code if it fails. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 12de63e9c720..2751736b0b64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2829,7 +2829,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = iwl_dbgfs_register(priv, DRV_NAME); if (err) - IWL_ERR(priv, "failed to create debugfs files\n"); + IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); /* If platform's RF_KILL switch is NOT set to KILL */ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index c15d0cfb93bc..bcfe199567e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4346,6 +4346,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e if (err) goto out_remove_sysfs; + err = iwl_dbgfs_register(priv, DRV_NAME); + if (err) + IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + err = iwl_rfkill_init(priv); if (err) IWL_ERR(priv, "Unable to initialize RFKILL system. " @@ -4396,6 +4400,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); + iwl_dbgfs_unregister(priv); + set_bit(STATUS_EXIT_PENDING, &priv->status); if (priv->mac80211_registered) { -- GitLab From 86ddbf62c2daefebba13e3c79f88cbdfde766176 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Mon, 20 Apr 2009 14:36:59 -0700 Subject: [PATCH 0655/6080] iwl3945: calculate debugfs isr statistics This patch calculates interrupt statistics for debugfs. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index bcfe199567e6..562dd76226cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1543,6 +1543,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) "r = %d, i = %d, %s, 0x%02x\n", r, i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); + priv->isr_stats.rx_handlers[pkt->hdr.cmd]++; } else { /* No handling needed */ IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR, @@ -1845,6 +1846,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) /* Tell the device to stop sending interrupts */ iwl_disable_interrupts(priv); + priv->isr_stats.hw++; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_HW_ERR; @@ -1857,13 +1859,17 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) #ifdef CONFIG_IWLWIFI_DEBUG if (priv->debug_level & (IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ - if (inta & CSR_INT_BIT_SCD) + if (inta & CSR_INT_BIT_SCD) { IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " "the frame/frames.\n"); + priv->isr_stats.sch++; + } /* Alive notification via Rx interrupt will do the real work */ - if (inta & CSR_INT_BIT_ALIVE) + if (inta & CSR_INT_BIT_ALIVE) { IWL_DEBUG_ISR(priv, "Alive interrupt\n"); + priv->isr_stats.alive++; + } } #endif /* Safely ignore these bits for debug checks below */ @@ -1873,6 +1879,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) if (inta & CSR_INT_BIT_SW_ERR) { IWL_ERR(priv, "Microcode SW error detected. " "Restarting 0x%X.\n", inta); + priv->isr_stats.sw++; + priv->isr_stats.sw_err = inta; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } @@ -1888,6 +1896,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) iwl_txq_update_write_ptr(priv, &priv->txq[4]); iwl_txq_update_write_ptr(priv, &priv->txq[5]); + priv->isr_stats.wakeup++; handled |= CSR_INT_BIT_WAKEUP; } @@ -1896,11 +1905,13 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) * notifications from uCode come through here*/ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { iwl3945_rx_handle(priv); + priv->isr_stats.rx++; handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); } if (inta & CSR_INT_BIT_FH_TX) { IWL_DEBUG_ISR(priv, "Tx interrupt\n"); + priv->isr_stats.tx++; iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); if (!iwl_grab_nic_access(priv)) { @@ -1911,8 +1922,10 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) handled |= CSR_INT_BIT_FH_TX; } - if (inta & ~handled) + if (inta & ~handled) { IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); + priv->isr_stats.unhandled++; + } if (inta & ~CSR_INI_SET_MASK) { IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", -- GitLab From 279b05d4362472ae9269f982f00e644265bdbf94 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 20 Apr 2009 14:37:00 -0700 Subject: [PATCH 0656/6080] iwlwifi: clean up unused NL80211_IFTYPE_MONITOR for Monitor mode This patch clean up the code for NL80211_IFTYPE_MONITOR mode, priv->iw_mode is set in add_interface, but add_interface is never called for monitor mode. The only way mac80211 informs us about monitor mode is through configuring filter; since iw_mode will never set to NL80211_IFTYPE_MONITOR, modify and remove all the code refer to NL80211_IFTYPE_MONITOR and replace with iwl_is_monitor_mode() function call. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 -- drivers/net/wireless/iwlwifi/iwl-core.c | 8 ++------ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-rx.c | 7 ------- drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++-- 8 files changed, 7 insertions(+), 24 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 2751736b0b64..fc52d3229d66 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2001,8 +2001,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw) out: priv->is_open = 1; - /* default to MONITOR mode */ - priv->iw_mode = NL80211_IFTYPE_MONITOR; IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c43c57d7a4cb..bf7ad515e6a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -904,10 +904,11 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap) * never called for monitor mode. The only way mac80211 informs us about * monitor mode is through configuring filters (call to configure_filter). */ -static bool iwl_is_monitor_mode(struct iwl_priv *priv) +bool iwl_is_monitor_mode(struct iwl_priv *priv) { return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK); } +EXPORT_SYMBOL(iwl_is_monitor_mode); /** * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image @@ -1071,11 +1072,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode) RXON_FILTER_ACCEPT_GRP_MSK; break; - case NL80211_IFTYPE_MONITOR: - priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER; - priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK | - RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; - break; default: IWL_ERR(priv, "Unsupported interface type %d\n", mode); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 8ab60df48d56..3bc2f6c3e8b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -267,6 +267,7 @@ int iwl_setup_mac(struct iwl_priv *priv); int iwl_set_hw_params(struct iwl_priv *priv); int iwl_init_drv(struct iwl_priv *priv); void iwl_uninit_drv(struct iwl_priv *priv); +bool iwl_is_monitor_mode(struct iwl_priv *priv); void iwl_post_associate(struct iwl_priv *priv); void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 8f65908f66f1..fae84262efb6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -1102,13 +1102,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, if (rx_start->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) rx_status.flag |= RX_FLAG_SHORTPRE; - /* Take shortcut when only in monitor mode */ - if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { - iwl_pass_packet_to_mac80211(priv, include_phy, - rxb, &rx_status); - return; - } - network_packet = iwl_is_network_packet(priv, header); if (network_packet) { priv->last_rx_rssi = rx_status.signal; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 25311e1ceed7..799f5eb61ece 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -747,7 +747,7 @@ static void iwl_bg_request_scan(struct work_struct *data) scan->tx_cmd.len = cpu_to_le16(cmd_len); - if (priv->iw_mode == NL80211_IFTYPE_MONITOR) + if (iwl_is_monitor_mode(priv)) scan->filter_flags = RXON_FILTER_PROMISC_MSK; scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index b8f18c697888..17a4dd2be1f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1078,11 +1078,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); return priv->hw_params.bcast_sta_id; - /* If we are in monitor mode, use BCAST. This is required for - * packet injection. */ - case NL80211_IFTYPE_MONITOR: - return priv->hw_params.bcast_sta_id; - default: IWL_WARN(priv, "Unknown mode of operation: %d\n", priv->iw_mode); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index c734c5f7e976..58cdd3294216 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -728,7 +728,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* drop all data frame if we are not associated */ if (ieee80211_is_data(fc) && - (priv->iw_mode != NL80211_IFTYPE_MONITOR || + (!iwl_is_monitor_mode(priv) || !(info->flags & IEEE80211_TX_CTL_INJECTED)) && /* packet injection */ (!iwl_is_associated(priv) || ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) || diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 562dd76226cc..c9fde0e0c982 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -729,7 +729,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* drop all data frame if we are not associated */ if (ieee80211_is_data(fc) && - (priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */ + (!iwl_is_monitor_mode(priv)) && /* packet injection */ (!iwl_is_associated(priv) || ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) { IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n"); @@ -3113,7 +3113,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) /* select Rx antennas */ scan->flags |= iwl3945_get_antenna_flags(priv); - if (priv->iw_mode == NL80211_IFTYPE_MONITOR) + if (iwl_is_monitor_mode(priv)) scan->filter_flags = RXON_FILTER_PROMISC_MSK; scan->channel_count = -- GitLab From 447fee700f6cb7ada906c5db61c6c045741893e8 Mon Sep 17 00:00:00 2001 From: Mohamed Abbas Date: Mon, 20 Apr 2009 14:37:02 -0700 Subject: [PATCH 0657/6080] iwlcore: Fix stay in table function. Function rs_stay_in_table was flushing the rate scale table way to early. time_after macro in expecting long value and was failing because we passing u32 value. Signed-off-by: Mohamed Abbas Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 26 +++++++++-------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 98b6b37951b3..3504279c7586 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -52,7 +52,7 @@ /* max allowed rate miss before sync LQ cmd */ #define IWL_MISSED_RATE_MAX 15 /* max time to accum history 2 seconds */ -#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ) +#define IWL_RATE_SCALE_FLUSH_INTVL (3*HZ) static u8 rs_ht_to_legacy[] = { IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX, @@ -135,7 +135,7 @@ struct iwl_lq_sta { u32 table_count; u32 total_failed; /* total failed frames, any/all rates */ u32 total_success; /* total successful frames, any/all rates */ - u32 flush_timer; /* time staying in mode before new search */ + u64 flush_timer; /* time staying in mode before new search */ u8 action_counter; /* # mode-switch actions tried */ u8 is_green; @@ -1025,6 +1025,7 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy, lq_sta->table_count = 0; lq_sta->total_failed = 0; lq_sta->total_success = 0; + lq_sta->flush_timer = jiffies; } /* @@ -1914,8 +1915,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) /* Elapsed time using current modulation mode */ if (lq_sta->flush_timer) flush_interval_passed = - time_after(jiffies, - (unsigned long)(lq_sta->flush_timer + + time_after(jiffies, + (unsigned long)(lq_sta->flush_timer + IWL_RATE_SCALE_FLUSH_INTVL)); /* @@ -2249,6 +2250,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, update_lq = 1; index = low; } + break; case 1: /* Increase starting rate, update uCode's rate table */ @@ -2314,8 +2316,11 @@ lq_update: tbl->current_rate, index); rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); - } + } else + done_search = 1; + } + if (done_search && !lq_sta->stay_in_tbl) { /* If the "active" (non-search) mode was legacy, * and we've tried switching antennas, * but we haven't been able to try HT modes (not available), @@ -2350,17 +2355,6 @@ lq_update: lq_sta->action_counter = 0; rs_set_stay_in_table(priv, 0, lq_sta); } - - /* - * Else, don't search for a new modulation mode. - * Put new timestamp in stay-in-modulation-mode flush timer if: - * 1) Not changing rates right now - * 2) Not just finishing up a search - * 3) flush timer is empty - */ - } else { - if ((!update_lq) && (!done_search) && (!lq_sta->flush_timer)) - lq_sta->flush_timer = jiffies; } out: -- GitLab From 09f9bf79b7870ac017a94f7f9b603c2e28ac73f7 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Mon, 20 Apr 2009 14:37:03 -0700 Subject: [PATCH 0658/6080] iwlwifi: remove radio disable parameter. Patch removes the "manual radio disable" parameter as there is no usage scenario of disabling radio using this module parameter. User can use iwconfig's txpower to enable and disable radio. This module parameter also does not work as expected. During module load the status of radio is set, the radio is not actually disabled. Even so, the moment mac80211 requests the interface to be up the radio will be enabled again. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 3 --- drivers/net/wireless/iwlwifi/iwl-agn.c | 14 ++------------ drivers/net/wireless/iwlwifi/iwl-core.h | 1 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 18 ++---------------- 5 files changed, 4 insertions(+), 34 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index e4762e530345..a98ff4ead720 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2361,8 +2361,6 @@ MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX)); module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); -module_param_named(disable, iwl4965_mod_params.disable, int, 0444); -MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444); MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); module_param_named(debug, iwl4965_mod_params.debug, uint, 0444); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 5bbb4f953364..d731a836e6c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1655,9 +1655,6 @@ struct iwl_cfg iwl5150_agn_cfg = { MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); -module_param_named(disable50, iwl50_mod_params.disable, int, 0444); -MODULE_PARM_DESC(disable50, - "manually disable the 50XX radio (default 0 [radio on])"); module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444); MODULE_PARM_DESC(swcrypto50, "using software crypto engine (default 0 [hardware])\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index fc52d3229d66..9e41e1bb7c79 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2774,18 +2774,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_free_eeprom; /* At this point both hw and priv are initialized. */ - /********************************** - * 7. Initialize module parameters - **********************************/ - - /* Disable radio (SW RF KILL) via parameter when loading driver */ - if (priv->cfg->mod_params->disable) { - set_bit(STATUS_RF_KILL_SW, &priv->status); - IWL_DEBUG_INFO(priv, "Radio disabled.\n"); - } - /******************** - * 8. Setup services + * 7. Setup services ********************/ spin_lock_irqsave(&priv->lock, flags); iwl_disable_interrupts(priv); @@ -2809,7 +2799,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_setup_rx_handlers(priv); /********************************** - * 9. Setup and register mac80211 + * 8. Setup and register mac80211 **********************************/ /* enable interrupts if needed: hw bug w/a */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3bc2f6c3e8b9..d4c60afa2891 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -176,7 +176,6 @@ struct iwl_ops { }; struct iwl_mod_params { - int disable; /* def: 0 = enable radio */ int sw_crypto; /* def: 0 = using hardware encryption */ u32 debug; /* def: 0 = minimal debug log messages */ int disable_hw_scan; /* def: 0 = use h/w scan */ diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index c9fde0e0c982..a5efb3b28c74 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -4309,20 +4309,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n", priv->cfg->name); - /*********************************** - * 7. Initialize Module Parameters - * **********************************/ - - /* Initialize module parameter values here */ - /* Disable radio (SW RF KILL) via parameter when loading driver */ - if (iwl3945_mod_params.disable) { - set_bit(STATUS_RF_KILL_SW, &priv->status); - IWL_DEBUG_INFO(priv, "Radio disabled.\n"); - } - - /*********************** - * 8. Setup Services + * 7. Setup Services * ********************/ spin_lock_irqsave(&priv->lock, flags); @@ -4350,7 +4338,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e iwl3945_setup_rx_handlers(priv); /********************************* - * 9. Setup and Register mac80211 + * 8. Setup and Register mac80211 * *******************************/ iwl_enable_interrupts(priv); @@ -4528,8 +4516,6 @@ MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX)); module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444); MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); -module_param_named(disable, iwl3945_mod_params.disable, int, 0444); -MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444); MODULE_PARM_DESC(swcrypto, "using software crypto (default 1 [software])\n"); -- GitLab From 0cf4c01ebe2ccf4487fe9301bab905365dca06c3 Mon Sep 17 00:00:00 2001 From: Mohamed Abbas Date: Mon, 20 Apr 2009 14:37:04 -0700 Subject: [PATCH 0659/6080] iwlwifi: allow config if device not ready Allow user to config the device all the time but only allow commiting these changes to card if the card is up and running. Signed-off-by: Mohamed Abbas Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index bf7ad515e6a0..3dec2d25fa3d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2474,12 +2474,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&priv->mutex); - if (!iwl_is_ready(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - ret = -EIO; - goto out; - } - IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", conf->channel->hw_value, changed); @@ -2574,6 +2568,11 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) goto out; } + if (!iwl_is_ready(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); + goto out; + } + if (scan_active) goto out; -- GitLab From 29b4a4f7c7b588b5568edd0da42f38623b81fc66 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 21 Apr 2009 00:30:49 +0200 Subject: [PATCH 0660/6080] mac80211: fix IBSS code to not sleep while atomic With the RCU locking here we sleep while in an atomic context, since we can sleep just use mutex locking for the interface list instead of RCU. Sorry, seems I didn't get that in my UML test. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/ibss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 4f7a54518be4..6030e003180c 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -784,14 +784,14 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { + mutex_lock(&local->iflist_mtx); + list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type != NL80211_IFTYPE_ADHOC) continue; sdata->u.ibss.last_scan_completed = jiffies; ieee80211_sta_find_ibss(sdata); } - rcu_read_unlock(); + mutex_unlock(&local->iflist_mtx); } ieee80211_rx_result -- GitLab From caa6dfadebee2098e9c5ece1d5efae96a6926d0f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 21 Apr 2009 10:55:10 +0200 Subject: [PATCH 0661/6080] rndis_wlan: make some symbols static sparse complains, correctly, about these: drivers/net/wireless/rndis_wlan.c:418:21: warning: symbol 'rndis_config_ops' was not declared. Should it be static? drivers/net/wireless/rndis_wlan.c:423:6: warning: symbol 'rndis_wiphy_privid' was not declared. Should it be static? Fix that. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 109e60343363..4b11ceae5b64 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -415,12 +415,12 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex, static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request); -struct cfg80211_ops rndis_config_ops = { +static struct cfg80211_ops rndis_config_ops = { .change_virtual_intf = rndis_change_virtual_intf, .scan = rndis_scan, }; -void *rndis_wiphy_privid = &rndis_wiphy_privid; +static void *rndis_wiphy_privid = &rndis_wiphy_privid; static const int bcm4320_power_output[4] = { 25, 50, 75, 100 }; -- GitLab From 8d4d99ae89a8845a1d63b0529dd98da28dc0ff65 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 21 Apr 2009 19:48:07 +0300 Subject: [PATCH 0662/6080] rndis_wlan: fix initialization order for workqueue&workers rndis_wext_link_change() might be called from rndis_command() at initialization stage and priv->workqueue/priv->work have not been initialized yet. This causes invalid opcode at rndis_wext_bind on some brands of bcm4320. Fix by initializing workqueue/workers in rndis_wext_bind() before rndis_command is used. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 4b11ceae5b64..9ef547d6724e 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2384,6 +2384,12 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) mutex_init(&priv->command_lock); spin_lock_init(&priv->stats_lock); + /* because rndis_command() sleeps we need to use workqueue */ + priv->workqueue = create_singlethread_workqueue("rndis_wlan"); + INIT_WORK(&priv->work, rndis_wext_worker); + INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); + INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); + /* try bind rndis_host */ retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS); if (retval < 0) @@ -2454,17 +2460,18 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) disassociate(usbdev, 1); netif_carrier_off(usbdev->net); - /* because rndis_command() sleeps we need to use workqueue */ - priv->workqueue = create_singlethread_workqueue("rndis_wlan"); - INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); queue_delayed_work(priv->workqueue, &priv->stats_work, round_jiffies_relative(STATS_UPDATE_JIFFIES)); - INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); - INIT_WORK(&priv->work, rndis_wext_worker); return 0; fail: + cancel_delayed_work_sync(&priv->stats_work); + cancel_delayed_work_sync(&priv->scan_work); + cancel_work_sync(&priv->work); + flush_workqueue(priv->workqueue); + destroy_workqueue(priv->workqueue); + kfree(priv); return retval; } -- GitLab From eb1a685e07310b5137c561e25ab738292db2c8a5 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 21 Apr 2009 19:48:15 +0300 Subject: [PATCH 0663/6080] rndis_wlan: free priv correctly when rndis_wext_bind fails Private structure is allocated by wiphy_new now, so use wiphy_free instead of kfree. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville --- drivers/net/wireless/rndis_wlan.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 9ef547d6724e..52fc647e6cb6 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2449,8 +2449,8 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) set_wiphy_dev(wiphy, &usbdev->udev->dev); if (wiphy_register(wiphy)) { - wiphy_free(wiphy); - return -ENODEV; + retval = -ENODEV; + goto fail; } set_default_iw_params(usbdev); @@ -2472,7 +2472,7 @@ fail: flush_workqueue(priv->workqueue); destroy_workqueue(priv->workqueue); - kfree(priv); + wiphy_free(wiphy); return retval; } -- GitLab From 1d4df3a50f40a731fc03c86a76535ed141b0e4bc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Apr 2009 11:25:43 +0200 Subject: [PATCH 0664/6080] mac80211: fix variable truncation on 32-bit Stephen Rothwell reported these warnings from a 32-bit build: net/mac80211/mlme.c:1771: warning: left shift count >= width of type net/mac80211/mlme.c:1772: warning: left shift count >= width of type net/mac80211/mlme.c:1773: warning: left shift count >= width of type net/mac80211/mlme.c:1774: warning: left shift count >= width of type net/mac80211/mlme.c:1775: warning: left shift count >= width of type This shows a bug in my code -- BIT(X) uses just "1 << X" which means a 32-bit integer on 32-bit platforms, but the code here needs a u64 on all platforms. Fix this by using "1ULL << X" instead of BIT(X). Thanks Stephen! Reported-by: Stephen Rothwell Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 1b0b7aa387ee..e819c02d13f0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1743,12 +1743,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, * look out for other vendor IEs. */ static const u64 care_about_ies = - BIT(WLAN_EID_COUNTRY) | - BIT(WLAN_EID_ERP_INFO) | - BIT(WLAN_EID_CHANNEL_SWITCH) | - BIT(WLAN_EID_PWR_CONSTRAINT) | - BIT(WLAN_EID_HT_CAPABILITY) | - BIT(WLAN_EID_HT_INFORMATION); + (1ULL << WLAN_EID_COUNTRY) | + (1ULL << WLAN_EID_ERP_INFO) | + (1ULL << WLAN_EID_CHANNEL_SWITCH) | + (1ULL << WLAN_EID_PWR_CONSTRAINT) | + (1ULL << WLAN_EID_HT_CAPABILITY) | + (1ULL << WLAN_EID_HT_INFORMATION); static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, -- GitLab From e255d5eb2b478eec1416b46aea03798b64355402 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Apr 2009 12:40:07 +0200 Subject: [PATCH 0665/6080] mac80211: remove IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT Just setting IEEE80211_CONF_CHANGE_PS should be sufficient for changes in the power saving things. The driver already tells us whether it wants notification of dynps via the "have dynps support" hw flag. Signed-off-by: Johannes Berg Reviewed-by: Kalle Valo Signed-off-by: John W. Linville --- include/net/mac80211.h | 10 ++++------ net/mac80211/wext.c | 3 +-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d9686917252b..183956e4930a 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -532,8 +532,7 @@ enum ieee80211_conf_flags { * @IEEE80211_CONF_CHANGE_BEACON_INTERVAL: the beacon interval changed * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed - * @IEEE80211_CONF_CHANGE_PS: the PS flag changed - * @IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT: the dynamic PS timeout changed + * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed * @IEEE80211_CONF_CHANGE_POWER: the TX power changed * @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed @@ -544,10 +543,9 @@ enum ieee80211_conf_changed { IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2), IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3), IEEE80211_CONF_CHANGE_PS = BIT(4), - IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT = BIT(5), - IEEE80211_CONF_CHANGE_POWER = BIT(6), - IEEE80211_CONF_CHANGE_CHANNEL = BIT(7), - IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(8), + IEEE80211_CONF_CHANGE_POWER = BIT(5), + IEEE80211_CONF_CHANGE_CHANNEL = BIT(6), + IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(7), }; /** diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 1eb6d8642a77..1a649da42c41 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -622,8 +622,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev, conf->dynamic_ps_timeout = timeout; if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) - ieee80211_hw_config(local, - IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT); + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); ieee80211_recalc_ps(local, -1); -- GitLab From 8e30bc55de98c000b0b836cb42525c82f605f191 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Apr 2009 17:45:38 +0200 Subject: [PATCH 0666/6080] nl80211: allow configuring IBSS beacon interval Make the JOIN_IBSS command look at the beacon interval attribute to see if the user requested a specific beacon interval, if not default to 100 TU (wext too). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 4 +++- include/net/cfg80211.h | 2 ++ net/wireless/ibss.c | 3 +++ net/wireless/nl80211.c | 12 +++++++++++- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index dc9d9ec5d1ae..b6a48dd502ce 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -230,7 +230,9 @@ * and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those * should be fixed rather than automatically determined. Can only be * executed on a network interface that is UP, and fixed BSSID/FREQ - * may be rejected. + * may be rejected. Another optional parameter is the beacon interval, + * given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not + * given defaults to 100 TU (102.4ms). * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is * determined by the network interface. * diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 54bc69c83691..7f7b53b69cb2 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -733,6 +733,7 @@ struct cfg80211_disassoc_request { * IBSSs to join on other channels. * @ie: information element(s) to include in the beacon * @ie_len: length of that + * @beacon_interval: beacon interval to use */ struct cfg80211_ibss_params { u8 *ssid; @@ -740,6 +741,7 @@ struct cfg80211_ibss_params { struct ieee80211_channel *channel; u8 *ie; u8 ssid_len, ie_len; + u16 beacon_interval; bool channel_fixed; }; diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index b5c601e1b1b7..3c38afaed28a 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -116,6 +116,9 @@ static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, enum ieee80211_band band; int i; + if (!wdev->wext.beacon_interval) + wdev->wext.beacon_interval = 100; + /* try to find an IBSS channel if none requested ... */ if (!wdev->wext.channel) { for (band = 0; band < IEEE80211_NUM_BANDS; band++) { diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 97bb5c80125d..3b21b3e89e96 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3159,6 +3159,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) struct wiphy *wiphy; int err; + memset(&ibss, 0, sizeof(ibss)); + if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) return -EINVAL; @@ -3167,6 +3169,15 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) !nla_len(info->attrs[NL80211_ATTR_SSID])) return -EINVAL; + ibss.beacon_interval = 100; + + if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { + ibss.beacon_interval = + nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); + if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000) + return -EINVAL; + } + rtnl_lock(); err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); @@ -3189,7 +3200,6 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) } wiphy = &drv->wiphy; - memset(&ibss, 0, sizeof(ibss)); if (info->attrs[NL80211_ATTR_MAC]) ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); -- GitLab From 04fe20372e70685d9f15966216cdffd3795fe590 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Apr 2009 18:44:37 +0200 Subject: [PATCH 0667/6080] mac80211: calculate maximum sleep interval The maximum sleep interval, for powersave purposes, is determined by the DTIM period (it may not be larger) and the required networking latency (it must be small enough to fulfil those constraints). This makes mac80211 calculate the maximum sleep interval based on those constraints, and pass it to the driver. Then the driver should instruct the device to sleep at most that long. Note that the device is responsible for aligning the maximum sleep interval between DTIMs, we make sure it's not longer but it needs to make sure it's between them. Also, group some powersave documentation together and make it more explicit that we support managed mode only, and no IBSS powersaving (yet). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/mac80211.h | 19 ++++++++++++++++--- net/mac80211/mlme.c | 20 ++++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 183956e4930a..446dbf75a1c5 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -517,7 +517,7 @@ struct ieee80211_rx_status { * Flags to define PHY configuration options * * @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported) - * @IEEE80211_CONF_PS: Enable 802.11 power save mode + * @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only) */ enum ieee80211_conf_flags { IEEE80211_CONF_RADIOTAP = (1<<0), @@ -553,14 +553,26 @@ enum ieee80211_conf_changed { * * This struct indicates how the driver shall configure the hardware. * + * @flags: configuration flags defined above + * * @radio_enabled: when zero, driver is required to switch off the radio. * @beacon_int: beacon interval (TODO make interface config) + * * @listen_interval: listen interval in units of beacon interval - * @flags: configuration flags defined above + * @max_sleep_interval: the maximum number of beacon intervals to sleep for + * before checking the beacon for a TIM bit (managed mode only); this + * value will be only achievable between DTIM frames, the hardware + * needs to check for the multicast traffic bit in DTIM beacons. + * This variable is valid only when the CONF_PS flag is set. + * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the + * powersave documentation below. This variable is valid only when + * the CONF_PS flag is set. + * * @power_level: requested transmit power (in dBm) - * @dynamic_ps_timeout: dynamic powersave timeout (in ms) + * * @channel: the channel to tune to * @channel_type: the channel (HT) type + * * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame * (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11, * but actually means the number of transmissions not the number of retries @@ -572,6 +584,7 @@ struct ieee80211_conf { int beacon_int; u32 flags; int power_level, dynamic_ps_timeout; + int max_sleep_interval; u16 listen_interval; bool radio_enabled; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e819c02d13f0..df27c68620c9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -545,10 +545,19 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) beaconint_us = ieee80211_tu_to_usec( found->vif.bss_conf.beacon_int); - if (beaconint_us > latency) + if (beaconint_us > latency) { local->ps_sdata = NULL; - else + } else { + u8 dtimper = found->vif.bss_conf.dtim_period; + int maxslp = 1; + + if (dtimper > 1) + maxslp = min_t(int, dtimper, + latency / beaconint_us); + + local->hw.conf.max_sleep_interval = maxslp; local->ps_sdata = found; + } } else { local->ps_sdata = NULL; } @@ -851,8 +860,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ieee80211_bss_info_change_notify(sdata, bss_info_changed); /* will be same as sdata */ - if (local->ps_sdata) - ieee80211_enable_ps(local, sdata); + if (local->ps_sdata) { + mutex_lock(&local->iflist_mtx); + ieee80211_recalc_ps(local, -1); + mutex_unlock(&local->iflist_mtx); + } netif_tx_start_all_queues(sdata->dev); netif_carrier_on(sdata->dev); -- GitLab From ff2ba188fc5eaae529cb2ef9b127c3ca2a7df4b9 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 22 Apr 2009 13:27:08 -0400 Subject: [PATCH 0668/6080] rndis_wlan: select CFG80211 in Kconfig Signed-off-by: John W. Linville --- drivers/net/wireless/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 11c248180982..2d8434f409b6 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -337,6 +337,7 @@ config USB_NET_RNDIS_WLAN select USB_NET_CDCETHER select USB_NET_RNDIS_HOST select WIRELESS_EXT + select CFG80211 ---help--- This is a driver for wireless RNDIS devices. These are USB based adapters found in devices such as: -- GitLab From 1965c85331ed29dc4fd32479ff31663e3e9a518f Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 22 Apr 2009 21:38:25 +0300 Subject: [PATCH 0669/6080] nl80211: Add event for authentication/association timeout SME needs to be notified when the authentication or association attempt times out and MLME has stopped processing in order to allow the SME to decide what to do next. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- include/linux/nl80211.h | 13 +++++++++-- include/net/cfg80211.h | 22 ++++++++++++++++-- net/mac80211/mlme.c | 4 ++-- net/wireless/mlme.c | 27 +++++++++++++++++++++++ net/wireless/nl80211.c | 49 +++++++++++++++++++++++++++++++++++++++++ net/wireless/nl80211.h | 6 +++++ 6 files changed, 115 insertions(+), 6 deletions(-) diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index b6a48dd502ce..e9fd13aa79f0 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -203,8 +203,12 @@ * frame, i.e., it was for the local STA and was received in correct * state. This is similar to MLME-AUTHENTICATE.confirm primitive in the * MLME SAP interface (kernel providing MLME, userspace SME). The - * included NL80211_ATTR_FRAME attribute contains the management frame - * (including both the header and frame body, but not FCS). + * included %NL80211_ATTR_FRAME attribute contains the management frame + * (including both the header and frame body, but not FCS). This event is + * also used to indicate if the authentication attempt timed out. In that + * case the %NL80211_ATTR_FRAME attribute is replaced with a + * %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which + * pending authentication timed out). * @NL80211_CMD_ASSOCIATE: association request and notification; like * NL80211_CMD_AUTHENTICATE but for Association and Reassociation * (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request, @@ -487,6 +491,9 @@ enum nl80211_commands { * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look * for other networks on different channels * + * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this + * is used, e.g., with %NL80211_CMD_AUTHENTICATE event + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -587,6 +594,8 @@ enum nl80211_attrs { NL80211_ATTR_WIPHY_FRAG_THRESHOLD, NL80211_ATTR_WIPHY_RTS_THRESHOLD, + NL80211_ATTR_TIMED_OUT, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 7f7b53b69cb2..b8a76764e1c5 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1475,10 +1475,19 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss); * @len: length of the frame data * * This function is called whenever an authentication has been processed in - * station mode. + * station mode. The driver is required to call either this function or + * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth() + * call. */ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); +/** + * cfg80211_send_auth_timeout - notification of timed out authentication + * @dev: network device + * @addr: The MAC address of the device with which the authentication timed out + */ +void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr); + /** * cfg80211_send_rx_assoc - notification of processed association * @dev: network device @@ -1486,10 +1495,19 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); * @len: length of the frame data * * This function is called whenever a (re)association response has been - * processed in station mode. + * processed in station mode. The driver is required to call either this + * function or cfg80211_send_assoc_timeout() to indicate the result of + * cfg80211_ops::assoc() call. */ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len); +/** + * cfg80211_send_assoc_timeout - notification of timed out association + * @dev: network device + * @addr: The MAC address of the device with which the association timed out + */ +void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr); + /** * cfg80211_send_deauth - notification of processed deauthentication * @dev: network device diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index df27c68620c9..3610c11286bc 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -932,7 +932,7 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata) " timed out\n", sdata->dev->name, ifmgd->bssid); ifmgd->state = IEEE80211_STA_MLME_DISABLED; - ieee80211_sta_send_apinfo(sdata); + cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid); ieee80211_rx_bss_remove(sdata, ifmgd->bssid, sdata->local->hw.conf.channel->center_freq, ifmgd->ssid, ifmgd->ssid_len); @@ -1115,7 +1115,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata) " timed out\n", sdata->dev->name, ifmgd->bssid); ifmgd->state = IEEE80211_STA_MLME_DISABLED; - ieee80211_sta_send_apinfo(sdata); + cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid); ieee80211_rx_bss_remove(sdata, ifmgd->bssid, sdata->local->hw.conf.channel->center_freq, ifmgd->ssid, ifmgd->ssid_len); diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 1407244a647e..42184361a109 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -44,6 +44,33 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len) } EXPORT_SYMBOL(cfg80211_send_disassoc); +static void cfg80211_wext_disconnected(struct net_device *dev) +{ +#ifdef CONFIG_WIRELESS_EXT + union iwreq_data wrqu; + memset(&wrqu, 0, sizeof(wrqu)); + wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); +#endif +} + +void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) +{ + struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + nl80211_send_auth_timeout(rdev, dev, addr); + cfg80211_wext_disconnected(dev); +} +EXPORT_SYMBOL(cfg80211_send_auth_timeout); + +void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr) +{ + struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + nl80211_send_assoc_timeout(rdev, dev, addr); + cfg80211_wext_disconnected(dev); +} +EXPORT_SYMBOL(cfg80211_send_assoc_timeout); + void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, enum nl80211_key_type key_type, int key_id, const u8 *tsc) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 3b21b3e89e96..b1fc98225fd1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -121,6 +121,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 }, [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG }, + [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG }, }; /* IE validation */ @@ -3695,6 +3696,54 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, NL80211_CMD_DISASSOCIATE); } +void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, + struct net_device *netdev, int cmd, + const u8 *addr) +{ + struct sk_buff *msg; + void *hdr; + + msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); + if (!msg) + return; + + hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); + if (!hdr) { + nlmsg_free(msg); + return; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex); + NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT); + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); + + if (genlmsg_end(msg, hdr) < 0) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC); + return; + + nla_put_failure: + genlmsg_cancel(msg, hdr); + nlmsg_free(msg); +} + +void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *addr) +{ + nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE, + addr); +} + +void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev, + struct net_device *netdev, const u8 *addr) +{ + nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, addr); +} + void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *bssid, gfp_t gfp) diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 17d2d8bfaf75..5c12ad13499b 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -23,6 +23,12 @@ extern void nl80211_send_deauth(struct cfg80211_registered_device *rdev, extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *buf, size_t len); +extern void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *addr); +extern void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev, + struct net_device *netdev, + const u8 *addr); extern void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, struct net_device *netdev, const u8 *addr, -- GitLab From 1a787e7ad242312af0afb2156596d42ee5e0c6bc Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Wed, 22 Apr 2009 13:13:34 +0900 Subject: [PATCH 0670/6080] ASoC: TWL4030: Add VDL path support Add DAPMs for VDL(Voice Down Link) path. To support VDL path, we have to change DAPMs of outputs(Earpiece, PreDrive Left/Right, Headset Left/Right, Carkit Left/Right) from mux to mixer. Signed-off-by: Joonyoung Shim Acked-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 256 ++++++++++++++++++------------------- 1 file changed, 126 insertions(+), 130 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index cc2968cf6409..fdf88dfbcff9 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -321,104 +321,60 @@ static void twl4030_power_down(struct snd_soc_codec *codec) } /* Earpiece */ -static const char *twl4030_earpiece_texts[] = - {"Off", "DACL1", "DACL2", "DACR1"}; - -static const unsigned int twl4030_earpiece_values[] = - {0x0, 0x1, 0x2, 0x4}; - -static const struct soc_enum twl4030_earpiece_enum = - SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7, - ARRAY_SIZE(twl4030_earpiece_texts), - twl4030_earpiece_texts, - twl4030_earpiece_values); - -static const struct snd_kcontrol_new twl4030_dapm_earpiece_control = -SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum); +static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0), + SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0), +}; /* PreDrive Left */ -static const char *twl4030_predrivel_texts[] = - {"Off", "DACL1", "DACL2", "DACR2"}; - -static const unsigned int twl4030_predrivel_values[] = - {0x0, 0x1, 0x2, 0x4}; - -static const struct soc_enum twl4030_predrivel_enum = - SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7, - ARRAY_SIZE(twl4030_predrivel_texts), - twl4030_predrivel_texts, - twl4030_predrivel_values); - -static const struct snd_kcontrol_new twl4030_dapm_predrivel_control = -SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum); +static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0), + SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0), +}; /* PreDrive Right */ -static const char *twl4030_predriver_texts[] = - {"Off", "DACR1", "DACR2", "DACL2"}; - -static const unsigned int twl4030_predriver_values[] = - {0x0, 0x1, 0x2, 0x4}; - -static const struct soc_enum twl4030_predriver_enum = - SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7, - ARRAY_SIZE(twl4030_predriver_texts), - twl4030_predriver_texts, - twl4030_predriver_values); - -static const struct snd_kcontrol_new twl4030_dapm_predriver_control = -SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum); +static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0), +}; /* Headset Left */ -static const char *twl4030_hsol_texts[] = - {"Off", "DACL1", "DACL2"}; - -static const struct soc_enum twl4030_hsol_enum = - SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1, - ARRAY_SIZE(twl4030_hsol_texts), - twl4030_hsol_texts); - -static const struct snd_kcontrol_new twl4030_dapm_hsol_control = -SOC_DAPM_ENUM("Route", twl4030_hsol_enum); +static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0), +}; /* Headset Right */ -static const char *twl4030_hsor_texts[] = - {"Off", "DACR1", "DACR2"}; - -static const struct soc_enum twl4030_hsor_enum = - SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4, - ARRAY_SIZE(twl4030_hsor_texts), - twl4030_hsor_texts); - -static const struct snd_kcontrol_new twl4030_dapm_hsor_control = -SOC_DAPM_ENUM("Route", twl4030_hsor_enum); +static const struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0), + SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0), + SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0), +}; /* Carkit Left */ -static const char *twl4030_carkitl_texts[] = - {"Off", "DACL1", "DACL2"}; - -static const struct soc_enum twl4030_carkitl_enum = - SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1, - ARRAY_SIZE(twl4030_carkitl_texts), - twl4030_carkitl_texts); - -static const struct snd_kcontrol_new twl4030_dapm_carkitl_control = -SOC_DAPM_ENUM("Route", twl4030_carkitl_enum); +static const struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0), +}; /* Carkit Right */ -static const char *twl4030_carkitr_texts[] = - {"Off", "DACR1", "DACR2"}; - -static const struct soc_enum twl4030_carkitr_enum = - SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1, - ARRAY_SIZE(twl4030_carkitr_texts), - twl4030_carkitr_texts); - -static const struct snd_kcontrol_new twl4030_dapm_carkitr_control = -SOC_DAPM_ENUM("Route", twl4030_carkitr_enum); +static const struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = { + SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0), + SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0), + SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0), +}; /* Handsfree Left */ static const char *twl4030_handsfreel_texts[] = - {"Voice", "DACL1", "DACL2", "DACR2"}; + {"Voice", "AudioL1", "AudioL2", "AudioR2"}; static const struct soc_enum twl4030_handsfreel_enum = SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0, @@ -430,7 +386,7 @@ SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum); /* Handsfree Right */ static const char *twl4030_handsfreer_texts[] = - {"Voice", "DACR1", "DACR2", "DACL2"}; + {"Voice", "AudioR1", "AudioR2", "AudioL2"}; static const struct soc_enum twl4030_handsfreer_enum = SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0, @@ -828,6 +784,12 @@ static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1); */ static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0); +/* + * Voice Downlink GAIN volume control: + * from -37 to 12 dB in 1 dB steps (mute instead of -37 dB) + */ +static DECLARE_TLV_DB_SCALE(digital_voice_downlink_tlv, -3700, 100, 1); + /* * Analog playback gain * -24 dB to 12 dB in 2 dB steps @@ -892,6 +854,16 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL, 1, 1, 0), + /* Common voice downlink gain controls */ + SOC_SINGLE_TLV("DAC Voice Digital Downlink Volume", + TWL4030_REG_VRXPGA, 0, 0x31, 0, digital_voice_downlink_tlv), + + SOC_SINGLE_TLV("DAC Voice Analog Downlink Volume", + TWL4030_REG_VDL_APGA_CTL, 3, 0x12, 1, analog_tlv), + + SOC_SINGLE("DAC Voice Analog Downlink Switch", + TWL4030_REG_VDL_APGA_CTL, 1, 1, 0), + /* Separate output gain controls */ SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume", TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL, @@ -956,6 +928,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback", SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback", + TWL4030_REG_AVDAC_CTL, 4, 0), /* Analog PGAs */ SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL, @@ -966,6 +940,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { 0, 0, NULL, 0), SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("VDL_APGA", TWL4030_REG_VDL_APGA_CTL, + 0, 0, NULL, 0), /* Analog bypasses */ SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, @@ -998,26 +974,35 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL, 3, 0, NULL, 0), - /* Output MUX controls */ + /* Output MIXER controls */ /* Earpiece */ - SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_earpiece_control), + SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_earpiece_controls[0], + ARRAY_SIZE(twl4030_dapm_earpiece_controls)), /* PreDrivL/R */ - SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_predrivel_control), - SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_predriver_control), + SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_predrivel_controls[0], + ARRAY_SIZE(twl4030_dapm_predrivel_controls)), + SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_predriver_controls[0], + ARRAY_SIZE(twl4030_dapm_predriver_controls)), /* HeadsetL/R */ - SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_hsol_control, headsetl_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_hsor_control), + SND_SOC_DAPM_MIXER_E("HeadsetL Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_hsol_controls[0], + ARRAY_SIZE(twl4030_dapm_hsol_controls), headsetl_event, + SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_hsor_controls[0], + ARRAY_SIZE(twl4030_dapm_hsor_controls)), /* CarkitL/R */ - SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_carkitl_control), - SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_carkitr_control), + SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_carkitl_controls[0], + ARRAY_SIZE(twl4030_dapm_carkitl_controls)), + SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_carkitr_controls[0], + ARRAY_SIZE(twl4030_dapm_carkitr_controls)), + + /* Output MUX controls */ /* HandsfreeL/R */ SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0, &twl4030_dapm_handsfreel_control, handsfree_event, @@ -1082,50 +1067,61 @@ static const struct snd_soc_dapm_route intercon[] = { {"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"}, {"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"}, + {"VDL_APGA", NULL, "DAC Voice"}, + /* Internal playback routings */ /* Earpiece */ - {"Earpiece Mux", "DACL1", "ARXL1_APGA"}, - {"Earpiece Mux", "DACL2", "ARXL2_APGA"}, - {"Earpiece Mux", "DACR1", "ARXR1_APGA"}, + {"Earpiece Mixer", "Voice", "VDL_APGA"}, + {"Earpiece Mixer", "AudioL1", "ARXL1_APGA"}, + {"Earpiece Mixer", "AudioL2", "ARXL2_APGA"}, + {"Earpiece Mixer", "AudioR1", "ARXR1_APGA"}, /* PreDrivL */ - {"PredriveL Mux", "DACL1", "ARXL1_APGA"}, - {"PredriveL Mux", "DACL2", "ARXL2_APGA"}, - {"PredriveL Mux", "DACR2", "ARXR2_APGA"}, + {"PredriveL Mixer", "Voice", "VDL_APGA"}, + {"PredriveL Mixer", "AudioL1", "ARXL1_APGA"}, + {"PredriveL Mixer", "AudioL2", "ARXL2_APGA"}, + {"PredriveL Mixer", "AudioR2", "ARXR2_APGA"}, /* PreDrivR */ - {"PredriveR Mux", "DACR1", "ARXR1_APGA"}, - {"PredriveR Mux", "DACR2", "ARXR2_APGA"}, - {"PredriveR Mux", "DACL2", "ARXL2_APGA"}, + {"PredriveR Mixer", "Voice", "VDL_APGA"}, + {"PredriveR Mixer", "AudioR1", "ARXR1_APGA"}, + {"PredriveR Mixer", "AudioR2", "ARXR2_APGA"}, + {"PredriveR Mixer", "AudioL2", "ARXL2_APGA"}, /* HeadsetL */ - {"HeadsetL Mux", "DACL1", "ARXL1_APGA"}, - {"HeadsetL Mux", "DACL2", "ARXL2_APGA"}, + {"HeadsetL Mixer", "Voice", "VDL_APGA"}, + {"HeadsetL Mixer", "AudioL1", "ARXL1_APGA"}, + {"HeadsetL Mixer", "AudioL2", "ARXL2_APGA"}, /* HeadsetR */ - {"HeadsetR Mux", "DACR1", "ARXR1_APGA"}, - {"HeadsetR Mux", "DACR2", "ARXR2_APGA"}, + {"HeadsetR Mixer", "Voice", "VDL_APGA"}, + {"HeadsetR Mixer", "AudioR1", "ARXR1_APGA"}, + {"HeadsetR Mixer", "AudioR2", "ARXR2_APGA"}, /* CarkitL */ - {"CarkitL Mux", "DACL1", "ARXL1_APGA"}, - {"CarkitL Mux", "DACL2", "ARXL2_APGA"}, + {"CarkitL Mixer", "Voice", "VDL_APGA"}, + {"CarkitL Mixer", "AudioL1", "ARXL1_APGA"}, + {"CarkitL Mixer", "AudioL2", "ARXL2_APGA"}, /* CarkitR */ - {"CarkitR Mux", "DACR1", "ARXR1_APGA"}, - {"CarkitR Mux", "DACR2", "ARXR2_APGA"}, + {"CarkitR Mixer", "Voice", "VDL_APGA"}, + {"CarkitR Mixer", "AudioR1", "ARXR1_APGA"}, + {"CarkitR Mixer", "AudioR2", "ARXR2_APGA"}, /* HandsfreeL */ - {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"}, - {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"}, - {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"}, + {"HandsfreeL Mux", "Voice", "VDL_APGA"}, + {"HandsfreeL Mux", "AudioL1", "ARXL1_APGA"}, + {"HandsfreeL Mux", "AudioL2", "ARXL2_APGA"}, + {"HandsfreeL Mux", "AudioR2", "ARXR2_APGA"}, /* HandsfreeR */ - {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"}, - {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"}, - {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"}, + {"HandsfreeR Mux", "Voice", "VDL_APGA"}, + {"HandsfreeR Mux", "AudioR1", "ARXR1_APGA"}, + {"HandsfreeR Mux", "AudioR2", "ARXR2_APGA"}, + {"HandsfreeR Mux", "AudioL2", "ARXL2_APGA"}, /* outputs */ {"OUTL", NULL, "ARXL2_APGA"}, {"OUTR", NULL, "ARXR2_APGA"}, - {"EARPIECE", NULL, "Earpiece Mux"}, - {"PREDRIVEL", NULL, "PredriveL Mux"}, - {"PREDRIVER", NULL, "PredriveR Mux"}, - {"HSOL", NULL, "HeadsetL Mux"}, - {"HSOR", NULL, "HeadsetR Mux"}, - {"CARKITL", NULL, "CarkitL Mux"}, - {"CARKITR", NULL, "CarkitR Mux"}, + {"EARPIECE", NULL, "Earpiece Mixer"}, + {"PREDRIVEL", NULL, "PredriveL Mixer"}, + {"PREDRIVER", NULL, "PredriveR Mixer"}, + {"HSOL", NULL, "HeadsetL Mixer"}, + {"HSOR", NULL, "HeadsetR Mixer"}, + {"CARKITL", NULL, "CarkitL Mixer"}, + {"CARKITR", NULL, "CarkitR Mixer"}, {"HFL", NULL, "HandsfreeL Mux"}, {"HFR", NULL, "HandsfreeR Mux"}, -- GitLab From 2d7e71fa231035d69faffbfe506ef23638385994 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Thu, 23 Apr 2009 17:05:38 +0800 Subject: [PATCH 0671/6080] ASoC: simplify the SSP DMA parameters settings by run-time generation The SSP DMA parameters can actually be easily generated at run-time since they are almost similar except for the FIFO width and direction. Another benefit is the re-use of information from 'struct ssp_device', like SSDR physical FIFO address and DRCMR register index for both directions. Signed-off-by: Eric Miao Signed-off-by: Mark Brown Reviewed-by: pHilipp Zabel --- sound/soc/pxa/pxa-ssp.c | 203 +++++++++------------------------------- 1 file changed, 43 insertions(+), 160 deletions(-) diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index b9b61ddca6ba..fb8cacca3416 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -50,139 +50,6 @@ struct ssp_priv { #endif }; -#define PXA2xx_SSP1_BASE 0x41000000 -#define PXA27x_SSP2_BASE 0x41700000 -#define PXA27x_SSP3_BASE 0x41900000 -#define PXA3xx_SSP4_BASE 0x41a00000 - -static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_out = { - .name = "SSP1 PCM Mono out", - .dev_addr = PXA2xx_SSP1_BASE + SSDR, - .drcmr = &DRCMR(14), - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_in = { - .name = "SSP1 PCM Mono in", - .dev_addr = PXA2xx_SSP1_BASE + SSDR, - .drcmr = &DRCMR(13), - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_out = { - .name = "SSP1 PCM Stereo out", - .dev_addr = PXA2xx_SSP1_BASE + SSDR, - .drcmr = &DRCMR(14), - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST16 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_in = { - .name = "SSP1 PCM Stereo in", - .dev_addr = PXA2xx_SSP1_BASE + SSDR, - .drcmr = &DRCMR(13), - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_out = { - .name = "SSP2 PCM Mono out", - .dev_addr = PXA27x_SSP2_BASE + SSDR, - .drcmr = &DRCMR(16), - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_in = { - .name = "SSP2 PCM Mono in", - .dev_addr = PXA27x_SSP2_BASE + SSDR, - .drcmr = &DRCMR(15), - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_out = { - .name = "SSP2 PCM Stereo out", - .dev_addr = PXA27x_SSP2_BASE + SSDR, - .drcmr = &DRCMR(16), - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST16 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_in = { - .name = "SSP2 PCM Stereo in", - .dev_addr = PXA27x_SSP2_BASE + SSDR, - .drcmr = &DRCMR(15), - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_out = { - .name = "SSP3 PCM Mono out", - .dev_addr = PXA27x_SSP3_BASE + SSDR, - .drcmr = &DRCMR(67), - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_in = { - .name = "SSP3 PCM Mono in", - .dev_addr = PXA27x_SSP3_BASE + SSDR, - .drcmr = &DRCMR(66), - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_out = { - .name = "SSP3 PCM Stereo out", - .dev_addr = PXA27x_SSP3_BASE + SSDR, - .drcmr = &DRCMR(67), - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST16 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_in = { - .name = "SSP3 PCM Stereo in", - .dev_addr = PXA27x_SSP3_BASE + SSDR, - .drcmr = &DRCMR(66), - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_out = { - .name = "SSP4 PCM Mono out", - .dev_addr = PXA3xx_SSP4_BASE + SSDR, - .drcmr = &DRCMR(67), - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_in = { - .name = "SSP4 PCM Mono in", - .dev_addr = PXA3xx_SSP4_BASE + SSDR, - .drcmr = &DRCMR(66), - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH2, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_out = { - .name = "SSP4 PCM Stereo out", - .dev_addr = PXA3xx_SSP4_BASE + SSDR, - .drcmr = &DRCMR(67), - .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | - DCMD_BURST16 | DCMD_WIDTH4, -}; - -static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_in = { - .name = "SSP4 PCM Stereo in", - .dev_addr = PXA3xx_SSP4_BASE + SSDR, - .drcmr = &DRCMR(66), - .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | - DCMD_BURST16 | DCMD_WIDTH4, -}; - static void dump_registers(struct ssp_device *ssp) { dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n", @@ -194,25 +61,33 @@ static void dump_registers(struct ssp_device *ssp) ssp_read_reg(ssp, SSACD)); } -static struct pxa2xx_pcm_dma_params *ssp_dma_params[4][4] = { - { - &pxa_ssp1_pcm_mono_out, &pxa_ssp1_pcm_mono_in, - &pxa_ssp1_pcm_stereo_out, &pxa_ssp1_pcm_stereo_in, - }, - { - &pxa_ssp2_pcm_mono_out, &pxa_ssp2_pcm_mono_in, - &pxa_ssp2_pcm_stereo_out, &pxa_ssp2_pcm_stereo_in, - }, - { - &pxa_ssp3_pcm_mono_out, &pxa_ssp3_pcm_mono_in, - &pxa_ssp3_pcm_stereo_out, &pxa_ssp3_pcm_stereo_in, - }, - { - &pxa_ssp4_pcm_mono_out, &pxa_ssp4_pcm_mono_in, - &pxa_ssp4_pcm_stereo_out, &pxa_ssp4_pcm_stereo_in, - }, +struct pxa2xx_pcm_dma_data { + struct pxa2xx_pcm_dma_params params; + char name[20]; }; +static struct pxa2xx_pcm_dma_params * +ssp_get_dma_params(struct ssp_device *ssp, int stereo, int out) +{ + struct pxa2xx_pcm_dma_data *dma; + + dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL); + if (dma == NULL) + return NULL; + + snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id, + stereo ? "Stereo" : "Mono", out ? "out" : "in"); + + dma->params.name = dma->name; + dma->params.drcmr = &DRCMR(out ? ssp->drcmr_tx : ssp->drcmr_rx); + dma->params.dcmd = (out ? (DCMD_INCSRCADDR | DCMD_FLOWTRG) : + (DCMD_INCTRGADDR | DCMD_FLOWSRC)) | + (stereo ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16; + dma->params.dev_addr = ssp->phys_base + SSDR; + + return &dma->params; +} + static int pxa_ssp_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -227,6 +102,11 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, clk_enable(priv->dev.ssp->clk); ssp_disable(&priv->dev); } + + if (cpu_dai->dma_data) { + kfree(cpu_dai->dma_data); + cpu_dai->dma_data = NULL; + } return ret; } @@ -241,6 +121,11 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, ssp_disable(&priv->dev); clk_disable(priv->dev.ssp->clk); } + + if (cpu_dai->dma_data) { + kfree(cpu_dai->dma_data); + cpu_dai->dma_data = NULL; + } } #ifdef CONFIG_PM @@ -653,25 +538,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct ssp_priv *priv = cpu_dai->private_data; struct ssp_device *ssp = priv->dev.ssp; - int dma = 0, chn = params_channels(params); + int chn = params_channels(params); u32 sscr0; u32 sspsp; int width = snd_pcm_format_physical_width(params_format(params)); int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; - /* select correct DMA params */ - if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) - dma = 1; /* capture DMA offset is 1,3 */ + /* generate correct DMA params */ + if (cpu_dai->dma_data) + kfree(cpu_dai->dma_data); + /* Network mode with one active slot (ttsa == 1) can be used * to force 16-bit frame width on the wire (for S16_LE), even * with two channels. Use 16-bit DMA transfers for this case. */ - if (((chn == 2) && (ttsa != 1)) || (width == 32)) - dma += 2; /* 32-bit DMA offset is 2, 16-bit is 0 */ - - cpu_dai->dma_data = ssp_dma_params[cpu_dai->id][dma]; - - dev_dbg(&ssp->pdev->dev, "pxa_ssp_hw_params: dma %d\n", dma); + cpu_dai->dma_data = ssp_get_dma_params(ssp, + ((chn == 2) && (ttsa != 1)) || (width == 32), + substream->stream == SNDRV_PCM_STREAM_PLAYBACK); /* we can only change the settings if the port is not in use */ if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) -- GitLab From 8eb9feabe566d8272510d5fb33f55a72e3ab3ce4 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Thu, 23 Apr 2009 17:57:46 +0800 Subject: [PATCH 0672/6080] ASoC: change stereo/mono to 32-bit/16-bit for pxa-ssp The original idea came from pHilipp, and this makes the code looks more consistent. Signed-off-by: Eric Miao Signed-off-by: Mark Brown --- sound/soc/pxa/pxa-ssp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index fb8cacca3416..6fc787610ad7 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -67,7 +67,7 @@ struct pxa2xx_pcm_dma_data { }; static struct pxa2xx_pcm_dma_params * -ssp_get_dma_params(struct ssp_device *ssp, int stereo, int out) +ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) { struct pxa2xx_pcm_dma_data *dma; @@ -76,13 +76,13 @@ ssp_get_dma_params(struct ssp_device *ssp, int stereo, int out) return NULL; snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id, - stereo ? "Stereo" : "Mono", out ? "out" : "in"); + width4 ? "32-bit" : "16-bit", out ? "out" : "in"); dma->params.name = dma->name; dma->params.drcmr = &DRCMR(out ? ssp->drcmr_tx : ssp->drcmr_rx); dma->params.dcmd = (out ? (DCMD_INCSRCADDR | DCMD_FLOWTRG) : (DCMD_INCTRGADDR | DCMD_FLOWSRC)) | - (stereo ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16; + (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16; dma->params.dev_addr = ssp->phys_base + SSDR; return &dma->params; -- GitLab From 42e1b4c2c6c823ae26e64c557addf5329a7735b7 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Tue, 21 Apr 2009 23:26:20 +0000 Subject: [PATCH 0673/6080] iucv: provide second per-cpu IUCV command parameter block Some of the IUCV commands can be invoked in interrupt context. Those commands need a different per-cpu IUCV command parameter block, otherwise they might overwrite an IUCV command parameter of a not yet finished IUCV command invocation in process context. Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- net/iucv/iucv.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index a35240f61ec3..fcf404065f12 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -280,6 +280,7 @@ union iucv_param { * Anchor for per-cpu IUCV command parameter block. */ static union iucv_param *iucv_param[NR_CPUS]; +static union iucv_param *iucv_param_irq[NR_CPUS]; /** * iucv_call_b2f0 @@ -358,7 +359,7 @@ static void iucv_allow_cpu(void *data) * 0x10 - Flag to allow priority message completion interrupts * 0x08 - Flag to allow IUCV control interrupts */ - parm = iucv_param[cpu]; + parm = iucv_param_irq[cpu]; memset(parm, 0, sizeof(union iucv_param)); parm->set_mask.ipmask = 0xf8; iucv_call_b2f0(IUCV_SETMASK, parm); @@ -379,7 +380,7 @@ static void iucv_block_cpu(void *data) union iucv_param *parm; /* Disable all iucv interrupts. */ - parm = iucv_param[cpu]; + parm = iucv_param_irq[cpu]; memset(parm, 0, sizeof(union iucv_param)); iucv_call_b2f0(IUCV_SETMASK, parm); @@ -403,7 +404,7 @@ static void iucv_declare_cpu(void *data) return; /* Declare interrupt buffer. */ - parm = iucv_param[cpu]; + parm = iucv_param_irq[cpu]; memset(parm, 0, sizeof(union iucv_param)); parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]); rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm); @@ -460,7 +461,7 @@ static void iucv_retrieve_cpu(void *data) iucv_block_cpu(NULL); /* Retrieve interrupt buffer. */ - parm = iucv_param[cpu]; + parm = iucv_param_irq[cpu]; iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm); /* Clear indication that an iucv buffer exists for this cpu. */ @@ -574,11 +575,22 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, iucv_irq_data[cpu] = NULL; return NOTIFY_BAD; } + iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param), + GFP_KERNEL|GFP_DMA, cpu_to_node(cpu)); + if (!iucv_param_irq[cpu]) { + kfree(iucv_param[cpu]); + iucv_param[cpu] = NULL; + kfree(iucv_irq_data[cpu]); + iucv_irq_data[cpu] = NULL; + return NOTIFY_BAD; + } break; case CPU_UP_CANCELED: case CPU_UP_CANCELED_FROZEN: case CPU_DEAD: case CPU_DEAD_FROZEN: + kfree(iucv_param_irq[cpu]); + iucv_param_irq[cpu] = NULL; kfree(iucv_param[cpu]); iucv_param[cpu] = NULL; kfree(iucv_irq_data[cpu]); @@ -625,7 +637,7 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16]) { union iucv_param *parm; - parm = iucv_param[smp_processor_id()]; + parm = iucv_param_irq[smp_processor_id()]; memset(parm, 0, sizeof(union iucv_param)); if (userdata) memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser)); @@ -918,10 +930,8 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16]) if (iucv_active_cpu != smp_processor_id()) spin_lock_bh(&iucv_table_lock); rc = iucv_sever_pathid(path->pathid, userdata); - if (!rc) { - iucv_path_table[path->pathid] = NULL; - list_del_init(&path->list); - } + iucv_path_table[path->pathid] = NULL; + list_del_init(&path->list); if (iucv_active_cpu != smp_processor_id()) spin_unlock_bh(&iucv_table_lock); preempt_enable(); @@ -1413,7 +1423,7 @@ static void iucv_path_severed(struct iucv_irq_data *data) else { iucv_sever_pathid(path->pathid, NULL); iucv_path_table[path->pathid] = NULL; - list_del_init(&path->list); + list_del(&path->list); iucv_path_free(path); } } @@ -1717,6 +1727,13 @@ static int __init iucv_init(void) rc = -ENOMEM; goto out_free; } + iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param), + GFP_KERNEL|GFP_DMA, cpu_to_node(cpu)); + if (!iucv_param_irq[cpu]) { + rc = -ENOMEM; + goto out_free; + } + } rc = register_hotcpu_notifier(&iucv_cpu_notifier); if (rc) @@ -1734,6 +1751,8 @@ out_cpu: unregister_hotcpu_notifier(&iucv_cpu_notifier); out_free: for_each_possible_cpu(cpu) { + kfree(iucv_param_irq[cpu]); + iucv_param_irq[cpu] = NULL; kfree(iucv_param[cpu]); iucv_param[cpu] = NULL; kfree(iucv_irq_data[cpu]); @@ -1764,6 +1783,8 @@ static void __exit iucv_exit(void) spin_unlock_irq(&iucv_queue_lock); unregister_hotcpu_notifier(&iucv_cpu_notifier); for_each_possible_cpu(cpu) { + kfree(iucv_param_irq[cpu]); + iucv_param_irq[cpu] = NULL; kfree(iucv_param[cpu]); iucv_param[cpu] = NULL; kfree(iucv_irq_data[cpu]); -- GitLab From af88b52def76679c8c5bcdbed199fbe62b6a16d4 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 21 Apr 2009 23:26:21 +0000 Subject: [PATCH 0674/6080] af_iucv: sync sk shutdown flag if iucv path is quiesced If the af_iucv communication partner quiesces the path to shutdown its receive direction, provide a quiesce callback implementation to shutdown the (local) send direction. This ensures that both sides are synchronized. Signed-off-by: Hendrik Brueckner Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- net/iucv/af_iucv.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 49e786535dc8..6cf02b41ef95 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -54,6 +54,7 @@ static void iucv_callback_connack(struct iucv_path *, u8 ipuser[16]); static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); static void iucv_callback_connrej(struct iucv_path *, u8 ipuser[16]); +static void iucv_callback_shutdown(struct iucv_path *, u8 ipuser[16]); static struct iucv_sock_list iucv_sk_list = { .lock = __RW_LOCK_UNLOCKED(iucv_sk_list.lock), @@ -65,7 +66,8 @@ static struct iucv_handler af_iucv_handler = { .path_complete = iucv_callback_connack, .path_severed = iucv_callback_connrej, .message_pending = iucv_callback_rx, - .message_complete = iucv_callback_txdone + .message_complete = iucv_callback_txdone, + .path_quiesced = iucv_callback_shutdown, }; static inline void high_nmcpy(unsigned char *dst, char *src) @@ -1196,6 +1198,21 @@ static void iucv_callback_connrej(struct iucv_path *path, u8 ipuser[16]) sk->sk_state_change(sk); } +/* called if the other communication side shuts down its RECV direction; + * in turn, the callback sets SEND_SHUTDOWN to disable sending of data. + */ +static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16]) +{ + struct sock *sk = path->private; + + bh_lock_sock(sk); + if (sk->sk_state != IUCV_CLOSED) { + sk->sk_shutdown |= SEND_SHUTDOWN; + sk->sk_state_change(sk); + } + bh_unlock_sock(sk); +} + static struct proto_ops iucv_sock_ops = { .family = PF_IUCV, .owner = THIS_MODULE, -- GitLab From 9d5c5d8f4105dc56ec10864b195dd1714f282c22 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 21 Apr 2009 23:26:22 +0000 Subject: [PATCH 0675/6080] af_iucv: add sockopt() to enable/disable use of IPRM_DATA msgs Provide the socket operations getsocktopt() and setsockopt() to enable/disable sending of data in the parameter list of IUCV messages. The patch sets respective flag only. Signed-off-by: Hendrik Brueckner Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- include/linux/socket.h | 1 + include/net/iucv/af_iucv.h | 4 ++ net/iucv/af_iucv.c | 79 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 42a0396f2c59..d2310cb45d2f 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -303,6 +303,7 @@ struct ucred { #define SOL_BLUETOOTH 274 #define SOL_PNPIPE 275 #define SOL_RDS 276 +#define SOL_IUCV 277 /* IPX options */ #define IPX_TYPE 1 diff --git a/include/net/iucv/af_iucv.h b/include/net/iucv/af_iucv.h index 85f80eadfa35..78a72764aeff 100644 --- a/include/net/iucv/af_iucv.h +++ b/include/net/iucv/af_iucv.h @@ -73,8 +73,12 @@ struct iucv_sock { struct sk_buff_head backlog_skb_q; struct sock_msg_q message_q; unsigned int send_tag; + u8 flags; }; +/* iucv socket options (SOL_IUCV) */ +#define SO_IPRMDATA_MSG 0x0080 /* send/recv IPRM_DATA msgs */ + struct iucv_sock_list { struct hlist_head head; rwlock_t lock; diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 6cf02b41ef95..b7c40c979921 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -32,7 +32,7 @@ #define CONFIG_IUCV_SOCK_DEBUG 1 #define IPRMDATA 0x80 -#define VERSION "1.0" +#define VERSION "1.1" static char iucv_userid[80]; @@ -226,6 +226,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio) spin_lock_init(&iucv_sk(sk)->message_q.lock); skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); iucv_sk(sk)->send_tag = 0; + iucv_sk(sk)->flags = 0; sk->sk_destruct = iucv_sock_destruct; sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; @@ -1003,6 +1004,78 @@ static int iucv_sock_release(struct socket *sock) return err; } +/* getsockopt and setsockopt */ +static int iucv_sock_setsockopt(struct socket *sock, int level, int optname, + char __user *optval, int optlen) +{ + struct sock *sk = sock->sk; + struct iucv_sock *iucv = iucv_sk(sk); + int val; + int rc; + + if (level != SOL_IUCV) + return -ENOPROTOOPT; + + if (optlen < sizeof(int)) + return -EINVAL; + + if (get_user(val, (int __user *) optval)) + return -EFAULT; + + rc = 0; + + lock_sock(sk); + switch (optname) { + case SO_IPRMDATA_MSG: + if (val) + iucv->flags |= IUCV_IPRMDATA; + else + iucv->flags &= ~IUCV_IPRMDATA; + break; + default: + rc = -ENOPROTOOPT; + break; + } + release_sock(sk); + + return rc; +} + +static int iucv_sock_getsockopt(struct socket *sock, int level, int optname, + char __user *optval, int __user *optlen) +{ + struct sock *sk = sock->sk; + struct iucv_sock *iucv = iucv_sk(sk); + int val, len; + + if (level != SOL_IUCV) + return -ENOPROTOOPT; + + if (get_user(len, optlen)) + return -EFAULT; + + if (len < 0) + return -EINVAL; + + len = min_t(unsigned int, len, sizeof(int)); + + switch (optname) { + case SO_IPRMDATA_MSG: + val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0; + break; + default: + return -ENOPROTOOPT; + } + + if (put_user(len, optlen)) + return -EFAULT; + if (copy_to_user(optval, &val, len)) + return -EFAULT; + + return 0; +} + + /* Callback wrappers - called from iucv base support */ static int iucv_callback_connreq(struct iucv_path *path, u8 ipvmid[8], u8 ipuser[16]) @@ -1229,8 +1302,8 @@ static struct proto_ops iucv_sock_ops = { .mmap = sock_no_mmap, .socketpair = sock_no_socketpair, .shutdown = iucv_sock_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt + .setsockopt = iucv_sock_setsockopt, + .getsockopt = iucv_sock_getsockopt, }; static struct net_proto_family iucv_sock_family_ops = { -- GitLab From b8942e3b6c4b35dda5e8ca75aec5e2f027fe39a9 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 21 Apr 2009 23:26:23 +0000 Subject: [PATCH 0676/6080] af_iucv: Support data in IUCV msg parameter lists (IPRMDATA) The patch allows to send and receive data in the parameter list of an iucv message. The parameter list is an arry of 8 bytes that are used by af_iucv as follows: 0..6 7 bytes for socket data and 7 1 byte to store the data length. Instead of storing the data length directly, the difference between 0xFF and the data length is used. This convention does not interfere with the existing use of PRM messages for shutting down the send direction of an AF_IUCV socket (shutdown() operation). Data lenghts greater than 7 (or PRM message byte 8 is less than 0xF8) denotes to special messages. Currently, the special SEND_SHUTDOWN message is supported only. To use IPRM messages, both communicators must set the IUCV_IPRMDATA flag during path negotiation, i.e. in iucv_connect() and path_pending(). To be compatible to older af_iucv implementations, sending PRM messages is controlled by the socket option SO_IPRMDATA_MSG. Receiving PRM messages does not depend on the socket option (but requires the IUCV_IPRMDATA path flag to be set). Sending/Receiving data in the parameter list improves performance for small amounts of data by reducing message_completion() interrupts and memory copy operations. Signed-off-by: Hendrik Brueckner Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- net/iucv/af_iucv.c | 121 +++++++++++++++++++++++++++++++++++++-------- net/iucv/iucv.c | 2 + 2 files changed, 103 insertions(+), 20 deletions(-) diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index b7c40c979921..5fc077ee5831 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -29,9 +29,6 @@ #include #include -#define CONFIG_IUCV_SOCK_DEBUG 1 - -#define IPRMDATA 0x80 #define VERSION "1.1" static char iucv_userid[80]; @@ -44,6 +41,10 @@ static struct proto iucv_proto = { .obj_size = sizeof(struct iucv_sock), }; +/* special AF_IUCV IPRM messages */ +static const u8 iprm_shutdown[8] = + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; + static void iucv_sock_kill(struct sock *sk); static void iucv_sock_close(struct sock *sk); @@ -80,6 +81,37 @@ static inline void low_nmcpy(unsigned char *dst, char *src) memcpy(&dst[8], src, 8); } +/** + * iucv_msg_length() - Returns the length of an iucv message. + * @msg: Pointer to struct iucv_message, MUST NOT be NULL + * + * The function returns the length of the specified iucv message @msg of data + * stored in a buffer and of data stored in the parameter list (PRMDATA). + * + * For IUCV_IPRMDATA, AF_IUCV uses the following convention to transport socket + * data: + * PRMDATA[0..6] socket data (max 7 bytes); + * PRMDATA[7] socket data length value (len is 0xff - PRMDATA[7]) + * + * The socket data length is computed by substracting the socket data length + * value from 0xFF. + * If the socket data len is greater 7, then PRMDATA can be used for special + * notifications (see iucv_sock_shutdown); and further, + * if the socket data len is > 7, the function returns 8. + * + * Use this function to allocate socket buffers to store iucv message data. + */ +static inline size_t iucv_msg_length(struct iucv_message *msg) +{ + size_t datalen; + + if (msg->flags & IUCV_IPRMDATA) { + datalen = 0xff - msg->rmmsg[7]; + return (datalen < 8) ? datalen : 8; + } + return msg->length; +} + /* Timers */ static void iucv_sock_timeout(unsigned long arg) { @@ -487,7 +519,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr, iucv = iucv_sk(sk); /* Create path. */ iucv->path = iucv_path_alloc(IUCV_QUEUELEN_DEFAULT, - IPRMDATA, GFP_KERNEL); + IUCV_IPRMDATA, GFP_KERNEL); if (!iucv->path) { err = -ENOMEM; goto done; @@ -521,8 +553,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr, } if (sk->sk_state == IUCV_DISCONN) { - release_sock(sk); - return -ECONNREFUSED; + err = -ECONNREFUSED; } if (err) { @@ -636,6 +667,30 @@ static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr, return 0; } +/** + * iucv_send_iprm() - Send socket data in parameter list of an iucv message. + * @path: IUCV path + * @msg: Pointer to a struct iucv_message + * @skb: The socket data to send, skb->len MUST BE <= 7 + * + * Send the socket data in the parameter list in the iucv message + * (IUCV_IPRMDATA). The socket data is stored at index 0 to 6 in the parameter + * list and the socket data len at index 7 (last byte). + * See also iucv_msg_length(). + * + * Returns the error code from the iucv_message_send() call. + */ +static int iucv_send_iprm(struct iucv_path *path, struct iucv_message *msg, + struct sk_buff *skb) +{ + u8 prmdata[8]; + + memcpy(prmdata, (void *) skb->data, skb->len); + prmdata[7] = 0xff - (u8) skb->len; + return iucv_message_send(path, msg, IUCV_IPRMDATA, 0, + (void *) prmdata, 8); +} + static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) { @@ -677,8 +732,29 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, txmsg.tag = iucv->send_tag++; memcpy(skb->cb, &txmsg.tag, 4); skb_queue_tail(&iucv->send_skb_q, skb); - err = iucv_message_send(iucv->path, &txmsg, 0, 0, - (void *) skb->data, skb->len); + + if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags) + && skb->len <= 7) { + err = iucv_send_iprm(iucv->path, &txmsg, skb); + + /* on success: there is no message_complete callback + * for an IPRMDATA msg; remove skb from send queue */ + if (err == 0) { + skb_unlink(skb, &iucv->send_skb_q); + kfree_skb(skb); + } + + /* this error should never happen since the + * IUCV_IPRMDATA path flag is set... sever path */ + if (err == 0x15) { + iucv_path_sever(iucv->path, NULL); + skb_unlink(skb, &iucv->send_skb_q); + err = -EPIPE; + goto fail; + } + } else + err = iucv_message_send(iucv->path, &txmsg, 0, 0, + (void *) skb->data, skb->len); if (err) { if (err == 3) { user_id[8] = 0; @@ -744,19 +820,25 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, struct iucv_message *msg) { int rc; + unsigned int len; + + len = iucv_msg_length(msg); - if (msg->flags & IPRMDATA) { - skb->data = NULL; - skb->len = 0; + /* check for special IPRM messages (e.g. iucv_sock_shutdown) */ + if ((msg->flags & IUCV_IPRMDATA) && len > 7) { + if (memcmp(msg->rmmsg, iprm_shutdown, 8) == 0) { + skb->data = NULL; + skb->len = 0; + } } else { - rc = iucv_message_receive(path, msg, 0, skb->data, - msg->length, NULL); + rc = iucv_message_receive(path, msg, msg->flags & IUCV_IPRMDATA, + skb->data, len, NULL); if (rc) { kfree_skb(skb); return; } if (skb->truesize >= sk->sk_rcvbuf / 4) { - rc = iucv_fragment_skb(sk, skb, msg->length); + rc = iucv_fragment_skb(sk, skb, len); kfree_skb(skb); skb = NULL; if (rc) { @@ -767,7 +849,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, } else { skb_reset_transport_header(skb); skb_reset_network_header(skb); - skb->len = msg->length; + skb->len = len; } } @@ -782,7 +864,7 @@ static void iucv_process_message_q(struct sock *sk) struct sock_msg_q *p, *n; list_for_each_entry_safe(p, n, &iucv->message_q.list, list) { - skb = alloc_skb(p->msg.length, GFP_ATOMIC | GFP_DMA); + skb = alloc_skb(iucv_msg_length(&p->msg), GFP_ATOMIC | GFP_DMA); if (!skb) break; iucv_process_message(sk, skb, p->path, &p->msg); @@ -928,7 +1010,6 @@ static int iucv_sock_shutdown(struct socket *sock, int how) struct iucv_sock *iucv = iucv_sk(sk); struct iucv_message txmsg; int err = 0; - u8 prmmsg[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; how++; @@ -950,7 +1031,7 @@ static int iucv_sock_shutdown(struct socket *sock, int how) txmsg.class = 0; txmsg.tag = 0; err = iucv_message_send(iucv->path, &txmsg, IUCV_IPRMDATA, 0, - (void *) prmmsg, 8); + (void *) iprm_shutdown, 8); if (err) { switch (err) { case 1: @@ -1196,11 +1277,11 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) goto save_message; len = atomic_read(&sk->sk_rmem_alloc); - len += msg->length + sizeof(struct sk_buff); + len += iucv_msg_length(msg) + sizeof(struct sk_buff); if (len > sk->sk_rcvbuf) goto save_message; - skb = alloc_skb(msg->length, GFP_ATOMIC | GFP_DMA); + skb = alloc_skb(iucv_msg_length(msg), GFP_ATOMIC | GFP_DMA); if (!skb) goto save_message; diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index fcf404065f12..61e8038a55ee 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -1388,6 +1388,8 @@ static void iucv_path_complete(struct iucv_irq_data *data) struct iucv_path_complete *ipc = (void *) data; struct iucv_path *path = iucv_path_table[ipc->ippathid]; + if (path) + path->flags = ipc->ipflags1; if (path && path->handler && path->handler->path_complete) path->handler->path_complete(path, ipc->ipuser); } -- GitLab From 44b1e6b5f9a93cc2ba024e09cf137d5f1b5f8426 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 21 Apr 2009 23:26:24 +0000 Subject: [PATCH 0677/6080] af_iucv: Modify iucv msg target class using control msghdr Allow 'classification' of socket data that is sent or received over an af_iucv socket. For classification of data, the target class of an (native) iucv message is used. This patch provides the cmsg interface for iucv_sock_recvmsg() and iucv_sock_sendmsg(). Applications can use the msg_control field of struct msghdr to set or get the target class as a "socket control message" (SCM/CMSG). Signed-off-by: Hendrik Brueckner Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- include/net/iucv/af_iucv.h | 3 ++ net/iucv/af_iucv.c | 79 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/include/net/iucv/af_iucv.h b/include/net/iucv/af_iucv.h index 78a72764aeff..b57739e49dc1 100644 --- a/include/net/iucv/af_iucv.h +++ b/include/net/iucv/af_iucv.h @@ -79,6 +79,9 @@ struct iucv_sock { /* iucv socket options (SOL_IUCV) */ #define SO_IPRMDATA_MSG 0x0080 /* send/recv IPRM_DATA msgs */ +/* iucv related control messages (scm) */ +#define SCM_IUCV_TRGCLS 0x0001 /* target class control message */ + struct iucv_sock_list { struct hlist_head head; rwlock_t lock; diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 5fc077ee5831..47c5c8d3703f 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -45,6 +45,15 @@ static struct proto iucv_proto = { static const u8 iprm_shutdown[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; +#define TRGCLS_SIZE (sizeof(((struct iucv_message *)0)->class)) + +/* macros to set/get socket control buffer at correct offset */ +#define CB_TAG(skb) ((skb)->cb) /* iucv message tag */ +#define CB_TAG_LEN (sizeof(((struct iucv_message *) 0)->tag)) +#define CB_TRGCLS(skb) ((skb)->cb + CB_TAG_LEN) /* iucv msg target class */ +#define CB_TRGCLS_LEN (TRGCLS_SIZE) + + static void iucv_sock_kill(struct sock *sk); static void iucv_sock_close(struct sock *sk); @@ -698,6 +707,8 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct iucv_sock *iucv = iucv_sk(sk); struct sk_buff *skb; struct iucv_message txmsg; + struct cmsghdr *cmsg; + int cmsg_done; char user_id[9]; char appl_id[9]; int err; @@ -717,6 +728,48 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, } if (sk->sk_state == IUCV_CONNECTED) { + /* initialize defaults */ + cmsg_done = 0; /* check for duplicate headers */ + txmsg.class = 0; + + /* iterate over control messages */ + for (cmsg = CMSG_FIRSTHDR(msg); cmsg; + cmsg = CMSG_NXTHDR(msg, cmsg)) { + + if (!CMSG_OK(msg, cmsg)) { + err = -EINVAL; + goto out; + } + + if (cmsg->cmsg_level != SOL_IUCV) + continue; + + if (cmsg->cmsg_type & cmsg_done) { + err = -EINVAL; + goto out; + } + cmsg_done |= cmsg->cmsg_type; + + switch (cmsg->cmsg_type) { + case SCM_IUCV_TRGCLS: + if (cmsg->cmsg_len != CMSG_LEN(TRGCLS_SIZE)) { + err = -EINVAL; + goto out; + } + + /* set iucv message target class */ + memcpy(&txmsg.class, + (void *) CMSG_DATA(cmsg), TRGCLS_SIZE); + + break; + + default: + err = -EINVAL; + goto out; + break; + } + } + if (!(skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT, &err))) @@ -727,10 +780,9 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, goto fail; } - txmsg.class = 0; - memcpy(&txmsg.class, skb->data, skb->len >= 4 ? 4 : skb->len); + /* increment and save iucv message tag for msg_completion cbk */ txmsg.tag = iucv->send_tag++; - memcpy(skb->cb, &txmsg.tag, 4); + memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN); skb_queue_tail(&iucv->send_skb_q, skb); if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags) @@ -801,6 +853,10 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len) if (!nskb) return -ENOMEM; + /* copy target class to control buffer of new skb */ + memcpy(CB_TRGCLS(nskb), CB_TRGCLS(skb), CB_TRGCLS_LEN); + + /* copy data fragment */ memcpy(nskb->data, skb->data + copied, size); copied += size; dataleft -= size; @@ -824,6 +880,10 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, len = iucv_msg_length(msg); + /* store msg target class in the second 4 bytes of skb ctrl buffer */ + /* Note: the first 4 bytes are reserved for msg tag */ + memcpy(CB_TRGCLS(skb), &msg->class, CB_TRGCLS_LEN); + /* check for special IPRM messages (e.g. iucv_sock_shutdown) */ if ((msg->flags & IUCV_IPRMDATA) && len > 7) { if (memcmp(msg->rmmsg, iprm_shutdown, 8) == 0) { @@ -915,6 +975,17 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, len -= copied; + /* create control message to store iucv msg target class: + * get the trgcls from the control buffer of the skb due to + * fragmentation of original iucv message. */ + err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS, + CB_TRGCLS_LEN, CB_TRGCLS(skb)); + if (err) { + if (!(flags & MSG_PEEK)) + skb_queue_head(&sk->sk_receive_queue, skb); + return err; + } + /* Mark read part of skb as used */ if (!(flags & MSG_PEEK)) { skb_pull(skb, copied); @@ -1316,7 +1387,7 @@ static void iucv_callback_txdone(struct iucv_path *path, spin_lock_irqsave(&list->lock, flags); while (list_skb != (struct sk_buff *)list) { - if (!memcmp(&msg->tag, list_skb->cb, 4)) { + if (!memcmp(&msg->tag, CB_TAG(list_skb), CB_TAG_LEN)) { this = list_skb; break; } -- GitLab From aa8e71f58ab8e01d63c33df40ff1bcb997c9df92 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 21 Apr 2009 23:26:25 +0000 Subject: [PATCH 0678/6080] af_iucv: Provide new socket type SOCK_SEQPACKET This patch provides the socket type SOCK_SEQPACKET in addition to SOCK_STREAM. AF_IUCV sockets of type SOCK_SEQPACKET supports an 1:1 mapping of socket read or write operations to complete IUCV messages. Socket data or IUCV message data is not fragmented as this is the case for SOCK_STREAM sockets. The intention is to help application developers who write applications or device drivers using native IUCV interfaces (Linux kernel or z/VM IUCV interfaces). Signed-off-by: Hendrik Brueckner Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- net/iucv/af_iucv.c | 73 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 47c5c8d3703f..95e38d3d2d74 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -289,11 +289,22 @@ static int iucv_sock_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; - if (sock->type != SOCK_STREAM) - return -ESOCKTNOSUPPORT; + if (protocol && protocol != PF_IUCV) + return -EPROTONOSUPPORT; sock->state = SS_UNCONNECTED; - sock->ops = &iucv_sock_ops; + + switch (sock->type) { + case SOCK_STREAM: + sock->ops = &iucv_sock_ops; + break; + case SOCK_SEQPACKET: + /* currently, proto ops can handle both sk types */ + sock->ops = &iucv_sock_ops; + break; + default: + return -ESOCKTNOSUPPORT; + } sk = iucv_sock_alloc(sock, protocol, GFP_KERNEL); if (!sk) @@ -504,11 +515,9 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr, if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND) return -EBADFD; - if (sk->sk_type != SOCK_STREAM) + if (sk->sk_type != SOCK_STREAM && sk->sk_type != SOCK_SEQPACKET) return -EINVAL; - iucv = iucv_sk(sk); - if (sk->sk_state == IUCV_OPEN) { err = iucv_sock_autobind(sk); if (unlikely(err)) @@ -585,7 +594,10 @@ static int iucv_sock_listen(struct socket *sock, int backlog) lock_sock(sk); err = -EINVAL; - if (sk->sk_state != IUCV_BOUND || sock->type != SOCK_STREAM) + if (sk->sk_state != IUCV_BOUND) + goto done; + + if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET) goto done; sk->sk_max_ack_backlog = backlog; @@ -720,6 +732,10 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP; + /* SOCK_SEQPACKET: we do not support segmented records */ + if (sk->sk_type == SOCK_SEQPACKET && !(msg->msg_flags & MSG_EOR)) + return -EOPNOTSUPP; + lock_sock(sk); if (sk->sk_shutdown & SEND_SHUTDOWN) { @@ -770,6 +786,10 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, } } + /* allocate one skb for each iucv message: + * this is fine for SOCK_SEQPACKET (unless we want to support + * segmented records using the MSG_EOR flag), but + * for SOCK_STREAM we might want to improve it in future */ if (!(skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT, &err))) @@ -897,7 +917,11 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, kfree_skb(skb); return; } - if (skb->truesize >= sk->sk_rcvbuf / 4) { + /* we need to fragment iucv messages for SOCK_STREAM only; + * for SOCK_SEQPACKET, it is only relevant if we support + * record segmentation using MSG_EOR (see also recvmsg()) */ + if (sk->sk_type == SOCK_STREAM && + skb->truesize >= sk->sk_rcvbuf / 4) { rc = iucv_fragment_skb(sk, skb, len); kfree_skb(skb); skb = NULL; @@ -941,7 +965,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, int noblock = flags & MSG_DONTWAIT; struct sock *sk = sock->sk; struct iucv_sock *iucv = iucv_sk(sk); - int target, copied = 0; + int target; + unsigned int copied, rlen; struct sk_buff *skb, *rskb, *cskb; int err = 0; @@ -963,7 +988,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, return err; } - copied = min_t(unsigned int, skb->len, len); + rlen = skb->len; /* real length of skb */ + copied = min_t(unsigned int, rlen, len); cskb = skb; if (memcpy_toiovec(msg->msg_iov, cskb->data, copied)) { @@ -973,7 +999,13 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, goto done; } - len -= copied; + /* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */ + if (sk->sk_type == SOCK_SEQPACKET) { + if (copied < rlen) + msg->msg_flags |= MSG_TRUNC; + /* each iucv message contains a complete record */ + msg->msg_flags |= MSG_EOR; + } /* create control message to store iucv msg target class: * get the trgcls from the control buffer of the skb due to @@ -988,11 +1020,14 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, /* Mark read part of skb as used */ if (!(flags & MSG_PEEK)) { - skb_pull(skb, copied); - if (skb->len) { - skb_queue_head(&sk->sk_receive_queue, skb); - goto done; + /* SOCK_STREAM: re-queue skb if it contains unreceived data */ + if (sk->sk_type == SOCK_STREAM) { + skb_pull(skb, copied); + if (skb->len) { + skb_queue_head(&sk->sk_receive_queue, skb); + goto done; + } } kfree_skb(skb); @@ -1019,7 +1054,11 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, skb_queue_head(&sk->sk_receive_queue, skb); done: - return err ? : copied; + /* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */ + if (sk->sk_type == SOCK_SEQPACKET && (flags & MSG_TRUNC)) + copied = rlen; + + return copied; } static inline unsigned int iucv_accept_poll(struct sock *parent) @@ -1281,7 +1320,7 @@ static int iucv_callback_connreq(struct iucv_path *path, } /* Create the new socket */ - nsk = iucv_sock_alloc(NULL, SOCK_STREAM, GFP_ATOMIC); + nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC); if (!nsk) { err = iucv_path_sever(path, user_data); iucv_path_free(path); -- GitLab From 802788bf90f78e7f248e78d4d0510bb00e976db8 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 21 Apr 2009 23:26:26 +0000 Subject: [PATCH 0679/6080] af_iucv: cleanup and refactor recvmsg() EFAULT handling If the skb cannot be copied to user iovec, always return -EFAULT. The skb is enqueued again, except MSG_PEEK flag is set, to allow user space applications to correct its iovec pointer. Signed-off-by: Hendrik Brueckner Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- net/iucv/af_iucv.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 95e38d3d2d74..f0dea1b8ed4b 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -965,7 +965,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, int noblock = flags & MSG_DONTWAIT; struct sock *sk = sock->sk; struct iucv_sock *iucv = iucv_sk(sk); - int target; unsigned int copied, rlen; struct sk_buff *skb, *rskb, *cskb; int err = 0; @@ -979,8 +978,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & (MSG_OOB)) return -EOPNOTSUPP; - target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); - skb = skb_recv_datagram(sk, flags, noblock, &err); if (!skb) { if (sk->sk_shutdown & RCV_SHUTDOWN) @@ -993,10 +990,9 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, cskb = skb; if (memcpy_toiovec(msg->msg_iov, cskb->data, copied)) { - skb_queue_head(&sk->sk_receive_queue, skb); - if (copied == 0) - return -EFAULT; - goto done; + if (!(flags & MSG_PEEK)) + skb_queue_head(&sk->sk_receive_queue, skb); + return -EFAULT; } /* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */ -- GitLab From 09488e2e0fab14ebe41135f0d066cfe2c56ba9e5 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 21 Apr 2009 23:26:27 +0000 Subject: [PATCH 0680/6080] af_iucv: New socket option for setting IUCV MSGLIMITs The SO_MSGLIMIT socket option modifies the message limit for new IUCV communication paths. The message limit specifies the maximum number of outstanding messages that are allowed for connections. This setting can be lowered by z/VM when an IUCV connection is established. Expects an integer value in the range of 1 to 65535. The default value is 65535. The message limit must be set before calling connect() or listen() for sockets. If sockets are already connected or in state listen, changing the message limit is not supported. For reading the message limit value, unconnected sockets return the limit that has been set or the default limit. For connected sockets, the actual message limit is returned. The actual message limit is assigned by z/VM for each connection and it depends on IUCV MSGLIMIT authorizations specified for the z/VM guest virtual machine. Signed-off-by: Hendrik Brueckner Signed-off-by: Ursula Braun Signed-off-by: David S. Miller --- include/net/iucv/af_iucv.h | 2 ++ net/iucv/af_iucv.c | 27 +++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/include/net/iucv/af_iucv.h b/include/net/iucv/af_iucv.h index b57739e49dc1..21ee49ffcbaf 100644 --- a/include/net/iucv/af_iucv.h +++ b/include/net/iucv/af_iucv.h @@ -74,10 +74,12 @@ struct iucv_sock { struct sock_msg_q message_q; unsigned int send_tag; u8 flags; + u16 msglimit; }; /* iucv socket options (SOL_IUCV) */ #define SO_IPRMDATA_MSG 0x0080 /* send/recv IPRM_DATA msgs */ +#define SO_MSGLIMIT 0x1000 /* get/set IUCV MSGLIMIT */ /* iucv related control messages (scm) */ #define SCM_IUCV_TRGCLS 0x0001 /* target class control message */ diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index f0dea1b8ed4b..264c6b36931c 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -268,6 +268,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio) skb_queue_head_init(&iucv_sk(sk)->backlog_skb_q); iucv_sk(sk)->send_tag = 0; iucv_sk(sk)->flags = 0; + iucv_sk(sk)->msglimit = IUCV_QUEUELEN_DEFAULT; sk->sk_destruct = iucv_sock_destruct; sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; @@ -536,7 +537,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr, iucv = iucv_sk(sk); /* Create path. */ - iucv->path = iucv_path_alloc(IUCV_QUEUELEN_DEFAULT, + iucv->path = iucv_path_alloc(iucv->msglimit, IUCV_IPRMDATA, GFP_KERNEL); if (!iucv->path) { err = -ENOMEM; @@ -1219,6 +1220,20 @@ static int iucv_sock_setsockopt(struct socket *sock, int level, int optname, else iucv->flags &= ~IUCV_IPRMDATA; break; + case SO_MSGLIMIT: + switch (sk->sk_state) { + case IUCV_OPEN: + case IUCV_BOUND: + if (val < 1 || val > (u16)(~0)) + rc = -EINVAL; + else + iucv->msglimit = val; + break; + default: + rc = -EINVAL; + break; + } + break; default: rc = -ENOPROTOOPT; break; @@ -1250,6 +1265,12 @@ static int iucv_sock_getsockopt(struct socket *sock, int level, int optname, case SO_IPRMDATA_MSG: val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0; break; + case SO_MSGLIMIT: + lock_sock(sk); + val = (iucv->path != NULL) ? iucv->path->msglim /* connected */ + : iucv->msglimit; /* default */ + release_sock(sk); + break; default: return -ENOPROTOOPT; } @@ -1339,7 +1360,9 @@ static int iucv_callback_connreq(struct iucv_path *path, memcpy(nuser_data + 8, niucv->src_name, 8); ASCEBC(nuser_data + 8, 8); - path->msglim = IUCV_QUEUELEN_DEFAULT; + /* set message limit for path based on msglimit of accepting socket */ + niucv->msglimit = iucv->msglimit; + path->msglim = iucv->msglimit; err = iucv_path_accept(path, &af_iucv_handler, nuser_data, nsk); if (err) { err = iucv_path_sever(path, user_data); -- GitLab From d93fe1a144c1a4312972bedbefc2213aa8b88612 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Thu, 23 Apr 2009 06:37:16 -0700 Subject: [PATCH 0681/6080] af_iucv: Fix merge. From: Ursula Braun net/iucv/af_iucv.c in net-next-2.6 is almost correct. 4 lines should still be deleted. These are the remaining changes: Signed-off-by: David S. Miller --- net/iucv/af_iucv.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 0fc00087ea8b..a9b3a6f9ea95 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -982,8 +982,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & (MSG_OOB)) return -EOPNOTSUPP; - target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); - /* receive/dequeue next skb: * the function understands MSG_PEEK and, thus, does not dequeue skb */ skb = skb_recv_datagram(sk, flags, noblock, &err); @@ -1429,8 +1427,6 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) iucv_process_message(sk, skb, path, msg); goto out_unlock; - return; - save_message: save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA); if (!save_msg) -- GitLab From 31a00c6b7c0c4f01be49f02660de920c8b82b613 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 23 Apr 2009 14:36:48 +0300 Subject: [PATCH 0682/6080] ASoC: OMAP: Add 4 channel support to mcbsp Add 4 channel support to omap-mcbsp. This mode is going to be used by the twl4030 codec, when it is configured in Option1 mode. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 495192af8c2e..a5d46a7b196a 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -259,6 +259,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, regs->xcr2 |= XFRLEN2(wpf - 1); } case 1: + case 4: /* Set word per (McBSP) frame for phase1 */ regs->rcr1 |= RFRLEN1(wpf - 1); regs->xcr1 |= XFRLEN1(wpf - 1); @@ -506,13 +507,13 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = { .id = (link_id), \ .playback = { \ .channels_min = 1, \ - .channels_max = 2, \ + .channels_max = 4, \ .rates = OMAP_MCBSP_RATES, \ .formats = SNDRV_PCM_FMTBIT_S16_LE, \ }, \ .capture = { \ .channels_min = 1, \ - .channels_max = 2, \ + .channels_max = 4, \ .rates = OMAP_MCBSP_RATES, \ .formats = SNDRV_PCM_FMTBIT_S16_LE, \ }, \ -- GitLab From 8a1f936acdfd53cb0a981f3f80483863dcd84fa9 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 23 Apr 2009 14:36:49 +0300 Subject: [PATCH 0683/6080] ASoC: TWL4030: Add 4 channel TDM support Support for 4 channel TDM (SND_SOC_DAIFMT_DSP_A) for twl4030 codec. The channel allocations are: Playback: TDM i2s TWL RX Channel 1 Left SDRL2 Channel 3 Right SDRR2 Channel 2 -- SDRL1 Channel 4 -- SDRR1 Capture: TDM i2s TWL TX Channel 1 Left TXL1 Channel 3 Right TXR1 Channel 2 -- TXL2 Channel 4 -- TXR2 Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/codecs/twl4030.c | 52 ++++++++++++++++++++++++++++++++++++-- sound/soc/codecs/twl4030.h | 11 ++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index fdf88dfbcff9..e23c20c42f19 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -1251,6 +1251,28 @@ static void twl4030_constraints(struct twl4030_priv *twl4030, twl4030->channels); } +/* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for + * capture has to be enabled/disabled. */ +static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction, + int enable) +{ + u8 reg, mask; + + reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); + + if (direction == SNDRV_PCM_STREAM_PLAYBACK) + mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN; + else + mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN; + + if (enable) + reg |= mask; + else + reg &= ~mask; + + twl4030_write(codec, TWL4030_REG_OPTION, reg); +} + static int twl4030_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -1267,6 +1289,15 @@ static int twl4030_startup(struct snd_pcm_substream *substream, if (twl4030->configured) twl4030_constraints(twl4030, twl4030->master_substream); } else { + if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) & + TWL4030_OPTION_1)) { + /* In option2 4 channel is not supported, set the + * constraint for the first stream for channels, the + * second stream will 'inherit' this cosntraint */ + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_CHANNELS, + 2, 2); + } twl4030->master_substream = substream; } @@ -1292,6 +1323,10 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream, twl4030->configured = 0; else if (!twl4030->master_substream->runtime->channels) twl4030->configured = 0; + + /* If the closing substream had 4 channel, do the necessary cleanup */ + if (substream->runtime->channels == 4) + twl4030_tdm_enable(codec, substream->stream, 0); } static int twl4030_hw_params(struct snd_pcm_substream *substream, @@ -1304,6 +1339,16 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, struct twl4030_priv *twl4030 = codec->private_data; u8 mode, old_mode, format, old_format; + /* If the substream has 4 channel, do the necessary setup */ + if (params_channels(params) == 4) { + /* Safety check: are we in the correct operating mode? */ + if ((twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) & + TWL4030_OPTION_1)) + twl4030_tdm_enable(codec, substream->stream, 1); + else + return -EINVAL; + } + if (twl4030->configured) /* Ignoring hw_params for already configured DAI */ return 0; @@ -1461,6 +1506,9 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, case SND_SOC_DAIFMT_I2S: format |= TWL4030_AIF_FORMAT_CODEC; break; + case SND_SOC_DAIFMT_DSP_A: + format |= TWL4030_AIF_FORMAT_TDM; + break; default: return -EINVAL; } @@ -1642,13 +1690,13 @@ struct snd_soc_dai twl4030_dai[] = { .playback = { .stream_name = "Playback", .channels_min = 2, - .channels_max = 2, + .channels_max = 4, .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000, .formats = TWL4030_FORMATS,}, .capture = { .stream_name = "Capture", .channels_min = 2, - .channels_max = 2, + .channels_max = 4, .rates = TWL4030_RATES, .formats = TWL4030_FORMATS,}, .ops = &twl4030_dai_ops, diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h index 981ec609495b..3441115136f6 100644 --- a/sound/soc/codecs/twl4030.h +++ b/sound/soc/codecs/twl4030.h @@ -116,6 +116,17 @@ #define TWL4030_OPTION_1 (1 << 0) #define TWL4030_OPTION_2 (0 << 0) +/* TWL4030_OPTION (0x02) Fields */ + +#define TWL4030_ATXL1_EN (1 << 0) +#define TWL4030_ATXR1_EN (1 << 1) +#define TWL4030_ATXL2_VTXL_EN (1 << 2) +#define TWL4030_ATXR2_VTXR_EN (1 << 3) +#define TWL4030_ARXL1_VRX_EN (1 << 4) +#define TWL4030_ARXR1_EN (1 << 5) +#define TWL4030_ARXL2_EN (1 << 6) +#define TWL4030_ARXR2_EN (1 << 7) + /* TWL4030_REG_MICBIAS_CTL (0x04) Fields */ #define TWL4030_MICBIAS2_CTL 0x40 -- GitLab From 0cfcdedaddf2468cb53e3cff9c3abfef14b4d784 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Thu, 23 Apr 2009 21:46:19 +0200 Subject: [PATCH 0684/6080] ALSA: sc6000: fix older card initialization The last patch to handle newer cards like SC7000 broke initialization of the SC6000. Fix this. Signed-off-by: Krzysztof Helt Signed-off-by: Takashi Iwai --- sound/isa/sc6000.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index 983ab7e3b5b4..c803b2e30df9 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c @@ -391,7 +391,6 @@ static int __devinit sc6000_init_board(char __iomem *vport, int config = mss_config | sc6000_mpu_irq_to_softcfg(mpu_irq[dev]); int err; - int cfg[2]; int old = 0; err = sc6000_dsp_reset(vport); @@ -421,11 +420,18 @@ static int __devinit sc6000_init_board(char __iomem *vport, answer, version[0], version[1]); /* set configuration */ - sc6000_hw_cfg_encode(vport, &cfg[0], port[dev], mpu_port[dev], - mss_port[dev]); - if (sc6000_hw_cfg_write(vport, cfg) < 0) { - snd_printk(KERN_ERR "sc6000_hw_cfg_write: failed!\n"); - return -EIO; + sc6000_write(vport, COMMAND_5C); + if (sc6000_read(vport) < 0) + old = 1; + + if (!old) { + int cfg[2]; + sc6000_hw_cfg_encode(vport, &cfg[0], port[dev], mpu_port[dev], + mss_port[dev]); + if (sc6000_hw_cfg_write(vport, cfg) < 0) { + snd_printk(KERN_ERR "sc6000_hw_cfg_write: failed!\n"); + return -EIO; + } } err = sc6000_setup_board(vport, config); if (err < 0) { @@ -434,10 +440,6 @@ static int __devinit sc6000_init_board(char __iomem *vport, } sc6000_dsp_reset(vport); - sc6000_write(vport, COMMAND_5C); - if (sc6000_read(vport) < 0) - old = 1; - sc6000_dsp_reset(vport); if (!old) { sc6000_write(vport, COMMAND_60); -- GitLab From 3e98f9f15e916c48dfc5231d7e6a59be7f122764 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Apr 2009 15:39:39 +0900 Subject: [PATCH 0685/6080] sh: pci: Fix up the build for CONFIG_PCI=n. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pci.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index f910121559b0..5b2e0fcdfc22 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -88,6 +88,7 @@ static inline void pcibios_penalize_isa_irq(int irq, int active) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) #endif +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -95,6 +96,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif #ifdef CONFIG_SUPERH32 /* -- GitLab From ad8affd972a705a38e769859c50ee8e749b631da Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Fri, 24 Apr 2009 04:45:33 -0700 Subject: [PATCH 0686/6080] 8390p: fix build breakage Fix this build error caused by 362b76edb789 "8390p: Get rid of init_module/cleanup_module" drivers/net/8390p.c:94:19: error: invalid suffix "p_init_module" on integer constant drivers/net/8390p.c:94: error: expected identifier or '(' before numeric constant drivers/net/8390p.c:99:20: error: invalid suffix "p_cleanup_module" on integer constant Signed-off-by: Alexander Beregalov Signed-off-by: David S. Miller --- drivers/net/8390p.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c index cacdd86a27d0..d225c291fd93 100644 --- a/drivers/net/8390p.c +++ b/drivers/net/8390p.c @@ -91,15 +91,15 @@ void NS8390p_init(struct net_device *dev, int startp) } EXPORT_SYMBOL(NS8390p_init); -static int __init 8390p_init_module(void) +static int __init NS8390p_init_module(void) { return 0; } -static void __exit 8390p_cleanup_module(void) +static void __exit NS8390p_cleanup_module(void) { } -module_init(8390p_init_module); -module_exit(8390p_cleanup_module); +module_init(NS8390p_init_module); +module_exit(NS8390p_cleanup_module); MODULE_LICENSE("GPL"); -- GitLab From a8353a57299f965ca8747b1b062490aef2c9ca50 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 24 Apr 2009 11:03:21 +0300 Subject: [PATCH 0687/6080] ASoC: Beagle: Add support for 4 channel This patch adds support for the four channel TDM mode on Beagle board. Depending on the channel count, the interface needs to be configured differently (I2S for stereo DSP_A for four channels) Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap3beagle.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c index 6aa428e07d86..b0cff9f33b7e 100644 --- a/sound/soc/omap/omap3beagle.c +++ b/sound/soc/omap/omap3beagle.c @@ -41,23 +41,33 @@ static int omap3beagle_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + unsigned int fmt; int ret; + switch (params_channels(params)) { + case 2: /* Stereo I2S mode */ + fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM; + break; + case 4: /* Four channel TDM mode */ + fmt = SND_SOC_DAIFMT_DSP_A | + SND_SOC_DAIFMT_IB_NF | + SND_SOC_DAIFMT_CBM_CFM; + break; + default: + return -EINVAL; + } + /* Set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); + ret = snd_soc_dai_set_fmt(codec_dai, fmt); if (ret < 0) { printk(KERN_ERR "can't set codec DAI configuration\n"); return ret; } /* Set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, - SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); if (ret < 0) { printk(KERN_ERR "can't set cpu DAI configuration\n"); return ret; -- GitLab From 7629ad24f2b3df95c8b4cd8869e3c04e1df6c442 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 24 Apr 2009 16:37:44 +0200 Subject: [PATCH 0688/6080] ASoC: add SOC_DOUBLE_EXT macro Add a macro for double controls with special callback functions. Signed-off-by: Daniel Mack Signed-off-by: Mark Brown --- include/sound/soc.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index b1f2f8819fea..6ab80bf7abd2 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -118,6 +118,14 @@ .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } +#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\ + xhandler_get, xhandler_put) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ + .info = snd_soc_info_volsw, \ + .get = xhandler_get, .put = xhandler_put, \ + .private_value = (unsigned long)&(struct soc_mixer_control) \ + {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ + .max = xmax, .invert = xinvert} } #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ xhandler_get, xhandler_put, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ -- GitLab From 172fd9e26200668ebaf3e1d6d09b36d5d531bfa6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 24 Apr 2009 16:33:10 +0100 Subject: [PATCH 0689/6080] ASoC: Fix S3C64xx IIS device registration and support both ports The S3C64xx IIS code had a number of problems with device registration. The hardware has two IIS ports of which the driver supported only one at once via a single exported DAI, attempting to identify the DAI to use based on the dev->id of the ASoC platform device. As well as limiting the driver to only supporting one IIS port at once this also meant that the ID of the soc-audio device (or in future the card device) had to match the IIS ID. Fix both problems by converting the driver to register the DAIs based on probing of platform devices registered by the arch/arm code, using those platform devices to interact with the clock API. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c64xx-i2s.c | 146 +++++++++++++++++++++----------- sound/soc/s3c24xx/s3c64xx-i2s.h | 2 +- 2 files changed, 98 insertions(+), 50 deletions(-) diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 33c5de7e255f..a84c4bec56b9 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -120,36 +120,8 @@ EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); static int s3c64xx_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) { - struct device *dev = &pdev->dev; - struct s3c_i2sv2_info *i2s; - int ret; - - dev_dbg(dev, "%s: probing dai %d\n", __func__, pdev->id); - - if (pdev->id < 0 || pdev->id > ARRAY_SIZE(s3c64xx_i2s)) { - dev_err(dev, "id %d out of range\n", pdev->id); - return -EINVAL; - } - - i2s = &s3c64xx_i2s[pdev->id]; - - ret = s3c_i2sv2_probe(pdev, dai, i2s, - pdev->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0); - if (ret) - return ret; - - i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; - i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; - - i2s->iis_cclk = clk_get(dev, "audio-bus"); - if (IS_ERR(i2s->iis_cclk)) { - dev_err(dev, "failed to get audio-bus"); - iounmap(i2s->regs); - return -ENODEV; - } - /* configure GPIO for i2s port */ - switch (pdev->id) { + switch (dai->id) { case 0: s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); @@ -181,35 +153,114 @@ static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { .set_sysclk = s3c64xx_i2s_set_sysclk, }; -struct snd_soc_dai s3c64xx_i2s_dai = { - .name = "s3c64xx-i2s", - .id = 0, - .probe = s3c64xx_i2s_probe, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, +struct snd_soc_dai s3c64xx_i2s_dai[] = { + { + .name = "s3c64xx-i2s", + .id = 0, + .probe = s3c64xx_i2s_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS, + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS, + }, + .ops = &s3c64xx_i2s_dai_ops, }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, + { + .name = "s3c64xx-i2s", + .id = 1, + .probe = s3c64xx_i2s_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS, + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS, + }, + .ops = &s3c64xx_i2s_dai_ops, }, - .ops = &s3c64xx_i2s_dai_ops, }; EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); +static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) +{ + struct s3c_i2sv2_info *i2s; + struct snd_soc_dai *dai; + int ret; + + if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) { + dev_err(&pdev->dev, "id %d out of range\n", pdev->id); + return -EINVAL; + } + + i2s = &s3c64xx_i2s[pdev->id]; + dai = &s3c64xx_i2s_dai[pdev->id]; + dai->dev = &pdev->dev; + + i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; + i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; + + i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); + if (IS_ERR(i2s->iis_cclk)) { + dev_err(&pdev->dev, "failed to get audio-bus"); + ret = PTR_ERR(i2s->iis_cclk); + goto err; + } + + ret = s3c_i2sv2_probe(pdev, dai, i2s, + dai->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0); + if (ret) + goto err_clk; + + ret = snd_soc_register_dai(dai); + if (ret != 0) + goto err_i2sv2; + + return 0; + +err_i2sv2: + /* Not implemented for I2Sv2 core yet */ +err_clk: + clk_put(i2s->iis_cclk); +err: + return ret; +} + +static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev) +{ + dev_err(&pdev->dev, "Device removal not yet supported\n"); + return 0; +} + +static struct platform_driver s3c64xx_iis_driver = { + .probe = s3c64xx_iis_dev_probe, + .remove = s3c64xx_iis_dev_remove, + .driver = { + .name = "s3c64xx-iis", + .owner = THIS_MODULE, + }, +}; + static int __init s3c64xx_i2s_init(void) { - return s3c_i2sv2_register_dai(&s3c64xx_i2s_dai); + return platform_driver_register(&s3c64xx_iis_driver); } module_init(s3c64xx_i2s_init); static void __exit s3c64xx_i2s_exit(void) { - snd_soc_unregister_dai(&s3c64xx_i2s_dai); + platform_driver_unregister(&s3c64xx_iis_driver); } module_exit(s3c64xx_i2s_exit); @@ -217,6 +268,3 @@ module_exit(s3c64xx_i2s_exit); MODULE_AUTHOR("Ben Dooks, "); MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); MODULE_LICENSE("GPL"); - - - diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h index b7ffe3c38b66..597822a4658f 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.h +++ b/sound/soc/s3c24xx/s3c64xx-i2s.h @@ -24,7 +24,7 @@ #define S3C64XX_CLKSRC_PCLK (0) #define S3C64XX_CLKSRC_MUX (1) -extern struct snd_soc_dai s3c64xx_i2s_dai; +extern struct snd_soc_dai s3c64xx_i2s_dai[]; extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); -- GitLab From 008bec397cdabd22a6f4e4c16a746a86a046f8af Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 24 Apr 2009 16:27:09 +0100 Subject: [PATCH 0690/6080] ASoC: S3C2412: Failing to get the I2S clock is an error Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c2412-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c index b7e0b3f0bfc8..168a088ba761 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/sound/soc/s3c24xx/s3c2412-i2s.c @@ -120,7 +120,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev, s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk"); if (s3c2412_i2s.iis_cclk == NULL) { - pr_debug("failed to get i2sclk clock\n"); + pr_err("failed to get i2sclk clock\n"); iounmap(s3c2412_i2s.regs); return -ENODEV; } -- GitLab From 9b171ffe1b3004587f4a90ef293531a4a262e538 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 24 Apr 2009 15:30:28 -0400 Subject: [PATCH 0691/6080] libertas: fix format warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/libertas/if_spi.c: In function ‘if_spi_c2h_data’: drivers/net/wireless/libertas/if_spi.c:733: warning: format ‘%u’ expects type ‘unsigned int’, but argument 4 has type ‘long unsigned int’ Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 97493e2f4109..dccd01fd1f10 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -731,7 +731,7 @@ static int if_spi_c2h_data(struct if_spi_card *card) goto out; } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) { lbs_pr_err("%s: error: card has %d bytes of data, but " - "our maximum skb size is %u\n", + "our maximum skb size is %lu\n", __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE); err = -EINVAL; goto out; -- GitLab From d3feaf5ad12259927039a675cfb25dc342b403ab Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 24 Apr 2009 15:35:42 -0400 Subject: [PATCH 0692/6080] wireless: remove some (bogus?) 'may be used uninitialized' warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit net/mac80211/tx.c: In function ‘ieee80211_tx_h_select_key’: net/mac80211/tx.c:448: warning: ‘key’ may be used uninitialized in this function drivers/net/wireless/ath/ath9k/rc.c: In function ‘ath_rc_rate_getidx’: drivers/net/wireless/ath/ath9k/rc.c:815: warning: ‘nextindex’ may be used uninitialized in this function drivers/net/wireless/hostap/hostap_plx.c: In function ‘prism2_plx_probe’: drivers/net/wireless/hostap/hostap_plx.c:438: warning: ‘cor_index’ may be used uninitialized in this function drivers/net/wireless/hostap/hostap_plx.c:438: warning: ‘cor_offset’ may be used uninitialized in this function Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 2 +- drivers/net/wireless/hostap/hostap_plx.c | 2 +- net/mac80211/tx.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index a13668b9b6dc..8f3cf10f65c4 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -812,7 +812,7 @@ static u8 ath_rc_rate_getidx(struct ath_softc *sc, u16 min_rate) { u32 j; - u8 nextindex; + u8 nextindex = 0; if (min_rate) { for (j = RATE_TABLE_SIZE; j > 0; j--) { diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index cbf15d703201..0e5d51086a44 100644 --- a/drivers/net/wireless/hostap/hostap_plx.c +++ b/drivers/net/wireless/hostap/hostap_plx.c @@ -435,7 +435,7 @@ static int prism2_plx_probe(struct pci_dev *pdev, unsigned long pccard_attr_mem; unsigned int pccard_attr_len; void __iomem *attr_mem = NULL; - unsigned int cor_offset, cor_index; + unsigned int cor_offset = 0, cor_index = 0; u32 reg; local_info_t *local = NULL; struct net_device *dev = NULL; diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 9ab49826c15a..1865622003c9 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -445,7 +445,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) static ieee80211_tx_result debug_noinline ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) { - struct ieee80211_key *key; + struct ieee80211_key *key = NULL; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; -- GitLab From 79ffab34391933ee3b95dac7f25c0478fa2f8f1e Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 13 May 2009 15:13:42 -0400 Subject: [PATCH 0693/6080] ext4: Properly initialize the buffer_head state These struct buffer_heads are allocated on the stack (and hence are initialized with stack garbage). They are only used to call a get_blocks() function, so that's mostly OK, but b_state must be initialized to be 0 so we don't have any unexpected BH_* flags set by accident, such as BH_Unwritten or BH_Delay. Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 1 + fs/ext4/inode.c | 15 ++++++++++++++- fs/mpage.c | 6 ++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e3a55eb8b26a..a953214f2829 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3150,6 +3150,7 @@ retry: ret = PTR_ERR(handle); break; } + map_bh.b_state = 0; ret = ext4_get_blocks_wrap(handle, inode, block, max_blocks, &map_bh, EXT4_CREATE_UNINITIALIZED_EXT, 0, 0); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 2a9ffd528dd1..d7ad0bb73cd5 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2055,7 +2055,20 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd) if ((mpd->b_state & (1 << BH_Mapped)) && !(mpd->b_state & (1 << BH_Delay))) return 0; - new.b_state = mpd->b_state; + /* + * We need to make sure the BH_Delay flag is passed down to + * ext4_da_get_block_write(), since it calls + * ext4_get_blocks_wrap() with the EXT4_DELALLOC_RSVED flag. + * This flag causes ext4_get_blocks_wrap() to call + * ext4_da_update_reserve_space() if the passed buffer head + * has the BH_Delay flag set. In the future, once we clean up + * the interfaces to ext4_get_blocks_wrap(), we should pass in + * a separate flag which requests that the delayed allocation + * statistics should be updated, instead of depending on the + * state information getting passed down via the map_bh's + * state bitmasks plus the magic EXT4_DELALLOC_RSVED flag. + */ + new.b_state = mpd->b_state & (1 << BH_Delay); new.b_blocknr = 0; new.b_size = mpd->b_size; next = mpd->b_blocknr; diff --git a/fs/mpage.c b/fs/mpage.c index 680ba60863ff..42381bd6543b 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -379,7 +379,8 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages, struct buffer_head map_bh; unsigned long first_logical_block = 0; - clear_buffer_mapped(&map_bh); + map_bh.b_state = 0; + map_bh.b_size = 0; for (page_idx = 0; page_idx < nr_pages; page_idx++) { struct page *page = list_entry(pages->prev, struct page, lru); @@ -412,7 +413,8 @@ int mpage_readpage(struct page *page, get_block_t get_block) struct buffer_head map_bh; unsigned long first_logical_block = 0; - clear_buffer_mapped(&map_bh); + map_bh.b_state = 0; + map_bh.b_size = 0; bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio, &map_bh, &first_logical_block, get_block); if (bio) -- GitLab From 8fb0e342481c4d80040670fec915f0b9c7c6499a Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 12 May 2009 16:22:37 -0400 Subject: [PATCH 0694/6080] vfs: Add BUG_ON for delayed and unwritten flags in submit_bh() The BH_Delay and BH_Unwritten flags should never leak out to submit_bh(). So add some BUG_ON() checks to submit_bh so we can get a stack trace and determine how and why this might have happened. (Note that only XFS and ext4 use these buffer head flags, and XFS does not use submit_bh(). So this patch should only modify behavior for ext4.) Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" Cc: linux-fsdevel@vger.kernel.org --- fs/buffer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/buffer.c b/fs/buffer.c index aed297739eb0..ad0112900222 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2933,6 +2933,8 @@ int submit_bh(int rw, struct buffer_head * bh) BUG_ON(!buffer_locked(bh)); BUG_ON(!buffer_mapped(bh)); BUG_ON(!bh->b_end_io); + BUG_ON(buffer_delay(bh)); + BUG_ON(buffer_unwritten(bh)); /* * Mask in barrier bit for a write (could be either a WRITE or a -- GitLab From 29fa89d088941d79765d60f22d5ccdd6b8696e11 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 12 May 2009 16:30:27 -0400 Subject: [PATCH 0695/6080] ext4: Mark the unwritten buffer_head as mapped during write_begin Setting BH_Unwritten buffer_heads as BH_Mapped avoids multiple (unnecessary) calls to get_block() during the call to the write(2) system call. Setting BH_Unwritten buffer heads as BH_Mapped requires that the writepages() functions can handle BH_Unwritten buffer_heads. After this commit, things work as follows: ext4_ext_get_block() returns unmapped, unwritten, buffer head when called with create = 0 for prealloc space. This makes sure we handle the read path and non-delayed allocation case correctly. Even though the buffer head is marked unmapped we have valid b_blocknr and b_bdev values in the buffer_head. ext4_da_get_block_prep() called for block resrevation will now return mapped, unwritten, new buffer_head for prealloc space. This avoids multiple calls to get_block() for write to same offset. By making such buffers as BH_New, we also assure that sub-block zeroing of buffered writes happens correctly. Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 4 +-- fs/ext4/inode.c | 82 ++++++++++++++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 32 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index a953214f2829..ea5c47608cea 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2872,6 +2872,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, if (create == EXT4_CREATE_UNINITIALIZED_EXT) goto out; if (!create) { + if (allocated > max_blocks) + allocated = max_blocks; /* * We have blocks reserved already. We * return allocated blocks so that delalloc @@ -2879,8 +2881,6 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, * the buffer head will be unmapped so that * a read from the block returns 0s. */ - if (allocated > max_blocks) - allocated = max_blocks; set_buffer_unwritten(bh_result); bh_result->b_bdev = inode->i_sb->s_bdev; bh_result->b_blocknr = newblock; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d7ad0bb73cd5..96f3366f59f6 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1852,7 +1852,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd) * @logical - first logical block to start assignment with * * the function goes through all passed space and put actual disk - * block numbers into buffer heads, dropping BH_Delay + * block numbers into buffer heads, dropping BH_Delay and BH_Unwritten */ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical, struct buffer_head *exbh) @@ -1902,16 +1902,24 @@ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical, do { if (cur_logical >= logical + blocks) break; - if (buffer_delay(bh)) { - bh->b_blocknr = pblock; - clear_buffer_delay(bh); - bh->b_bdev = inode->i_sb->s_bdev; - } else if (buffer_unwritten(bh)) { - bh->b_blocknr = pblock; - clear_buffer_unwritten(bh); - set_buffer_mapped(bh); - set_buffer_new(bh); - bh->b_bdev = inode->i_sb->s_bdev; + + if (buffer_delay(bh) || + buffer_unwritten(bh)) { + + BUG_ON(bh->b_bdev != inode->i_sb->s_bdev); + + if (buffer_delay(bh)) { + clear_buffer_delay(bh); + bh->b_blocknr = pblock; + } else { + /* + * unwritten already should have + * blocknr assigned. Verify that + */ + clear_buffer_unwritten(bh); + BUG_ON(bh->b_blocknr != pblock); + } + } else if (buffer_mapped(bh)) BUG_ON(bh->b_blocknr != pblock); @@ -2053,7 +2061,8 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd) * We consider only non-mapped and non-allocated blocks */ if ((mpd->b_state & (1 << BH_Mapped)) && - !(mpd->b_state & (1 << BH_Delay))) + !(mpd->b_state & (1 << BH_Delay)) && + !(mpd->b_state & (1 << BH_Unwritten))) return 0; /* * We need to make sure the BH_Delay flag is passed down to @@ -2205,6 +2214,17 @@ flush_it: return; } +static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) +{ + /* + * unmapped buffer is possible for holes. + * delay buffer is possible with delayed allocation. + * We also need to consider unwritten buffer as unmapped. + */ + return (!buffer_mapped(bh) || buffer_delay(bh) || + buffer_unwritten(bh)) && buffer_dirty(bh); +} + /* * __mpage_da_writepage - finds extent of pages and blocks * @@ -2289,8 +2309,7 @@ static int __mpage_da_writepage(struct page *page, * Otherwise we won't make progress * with the page in ext4_da_writepage */ - if (buffer_dirty(bh) && - (!buffer_mapped(bh) || buffer_delay(bh))) { + if (ext4_bh_unmapped_or_delay(NULL, bh)) { mpage_add_bh_to_extent(mpd, logical, bh->b_size, bh->b_state); @@ -2318,6 +2337,14 @@ static int __mpage_da_writepage(struct page *page, /* * this is a special callback for ->write_begin() only * it's intention is to return mapped block or reserve space + * + * For delayed buffer_head we have BH_Mapped, BH_New, BH_Delay set. + * We also have b_blocknr = -1 and b_bdev initialized properly + * + * For unwritten buffer_head we have BH_Mapped, BH_New, BH_Unwritten set. + * We also have b_blocknr = physicalblock mapping unwritten extent and b_bdev + * initialized properly. + * */ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) @@ -2353,28 +2380,23 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, set_buffer_delay(bh_result); } else if (ret > 0) { bh_result->b_size = (ret << inode->i_blkbits); - /* - * With sub-block writes into unwritten extents - * we also need to mark the buffer as new so that - * the unwritten parts of the buffer gets correctly zeroed. - */ - if (buffer_unwritten(bh_result)) + if (buffer_unwritten(bh_result)) { + /* A delayed write to unwritten bh should + * be marked new and mapped. Mapped ensures + * that we don't do get_block multiple times + * when we write to the same offset and new + * ensures that we do proper zero out for + * partial write. + */ set_buffer_new(bh_result); + set_buffer_mapped(bh_result); + } ret = 0; } return ret; } -static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) -{ - /* - * unmapped buffer is possible for holes. - * delay buffer is possible with delayed allocation - */ - return ((!buffer_mapped(bh) || buffer_delay(bh)) && buffer_dirty(bh)); -} - static int ext4_normal_get_block_write(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { @@ -2828,7 +2850,7 @@ static int ext4_da_should_update_i_disksize(struct page *page, for (i = 0; i < idx; i++) bh = bh->b_this_page; - if (!buffer_mapped(bh) || (buffer_delay(bh))) + if (!buffer_mapped(bh) || (buffer_delay(bh)) || buffer_unwritten(bh)) return 0; return 1; } -- GitLab From c5ca7c7636fa689a9746b6032f83aa7fffec31c6 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 27 Apr 2009 22:48:48 -0400 Subject: [PATCH 0696/6080] ext4: Fallback to vmalloc if kmalloc can't allocate s_flex_groups array For very large filesystems, the s_flex_groups array can get quite big. For example, a filesystem that can be resized up to 16TB will have 8192 flex groups (assuming the default flex_bg size of 16), so the array is 96k, which is *very* marginal for kmalloc(). On the other hand, a 160GB filesystem without the resize_inode feature will only require 960 bytes. So we try to allocate the array first using kmalloc(), and if that fails, we'll try to use vmalloc() instead. Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2958f4e6f222..3f4475daa66d 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -586,7 +587,10 @@ static void ext4_put_super(struct super_block *sb) for (i = 0; i < sbi->s_gdb_count; i++) brelse(sbi->s_group_desc[i]); kfree(sbi->s_group_desc); - kfree(sbi->s_flex_groups); + if (is_vmalloc_addr(sbi->s_flex_groups)) + vfree(sbi->s_flex_groups); + else + kfree(sbi->s_flex_groups); percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); @@ -1620,6 +1624,7 @@ static int ext4_fill_flex_info(struct super_block *sb) ext4_group_t flex_group_count; ext4_group_t flex_group; int groups_per_flex = 0; + size_t size; int i; if (!sbi->s_es->s_log_groups_per_flex) { @@ -1634,8 +1639,13 @@ static int ext4_fill_flex_info(struct super_block *sb) flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex; - sbi->s_flex_groups = kzalloc(flex_group_count * - sizeof(struct flex_groups), GFP_KERNEL); + size = flex_group_count * sizeof(struct flex_groups); + sbi->s_flex_groups = kzalloc(size, GFP_KERNEL); + if (sbi->s_flex_groups == NULL) { + sbi->s_flex_groups = vmalloc(size); + if (sbi->s_flex_groups) + memset(sbi->s_flex_groups, 0, size); + } if (sbi->s_flex_groups == NULL) { printk(KERN_ERR "EXT4-fs: not enough memory for " "%u flex groups\n", flex_group_count); @@ -2842,6 +2852,12 @@ failed_mount4: sbi->s_journal = NULL; } failed_mount3: + if (sbi->s_flex_groups) { + if (is_vmalloc_addr(sbi->s_flex_groups)) + vfree(sbi->s_flex_groups); + else + kfree(sbi->s_flex_groups); + } percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); -- GitLab From f7c439504ccba0cca43271e651013ab97a221c62 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 24 Apr 2009 23:31:59 -0400 Subject: [PATCH 0697/6080] ext4: Use is_power_of_2() for clarity Signed-off-by: Robert P. J. Day Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3f4475daa66d..3e509bc647e3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1483,7 +1483,7 @@ set_qf_format: return 0; if (option < 0 || option > (1 << 30)) return 0; - if (option & (option - 1)) { + if (!is_power_of_2(option)) { printk(KERN_ERR "EXT4-fs: inode_readahead_blks" " must be a power of 2\n"); return 0; @@ -2101,8 +2101,7 @@ static ssize_t inode_readahead_blks_store(struct ext4_attr *a, if (parse_strtoul(buf, 0x40000000, &t)) return -EINVAL; - /* inode_readahead_blks must be a power of 2 */ - if (t & (t-1)) + if (!is_power_of_2(t)) return -EINVAL; sbi->s_inode_readahead_blks = t; -- GitLab From e2d670523c6c4ccb0fca9f3ab1b8f066d9aa57d6 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 1 May 2009 00:33:44 -0400 Subject: [PATCH 0698/6080] ext4: Simplify ext4_commit_super()'s function signature The ext4_commit_super() function took both a struct super_block * and a struct ext4_super_block *, but the struct ext4_super_block can be derived from the struct super_block. Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3e509bc647e3..ad4c9be4abdc 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -54,8 +54,7 @@ static struct kset *ext4_kset; static int ext4_load_journal(struct super_block *, struct ext4_super_block *, unsigned long journal_devnum); -static int ext4_commit_super(struct super_block *sb, - struct ext4_super_block *es, int sync); +static int ext4_commit_super(struct super_block *sb, int sync); static void ext4_mark_recovery_complete(struct super_block *sb, struct ext4_super_block *es); static void ext4_clear_journal_err(struct super_block *sb, @@ -306,7 +305,7 @@ static void ext4_handle_error(struct super_block *sb) printk(KERN_CRIT "Remounting filesystem read-only\n"); sb->s_flags |= MS_RDONLY; } - ext4_commit_super(sb, es, 1); + ext4_commit_super(sb, 1); if (test_opt(sb, ERRORS_PANIC)) panic("EXT4-fs (device %s): panic forced after error\n", sb->s_id); @@ -448,7 +447,7 @@ __acquires(bitlock) if (test_opt(sb, ERRORS_CONT)) { EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; es->s_state |= cpu_to_le16(EXT4_ERROR_FS); - ext4_commit_super(sb, es, 0); + ext4_commit_super(sb, 0); return; } ext4_unlock_group(sb, grp); @@ -577,7 +576,7 @@ static void ext4_put_super(struct super_block *sb) if (!(sb->s_flags & MS_RDONLY)) { EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); es->s_state = cpu_to_le16(sbi->s_mount_state); - ext4_commit_super(sb, es, 1); + ext4_commit_super(sb, 1); } if (sbi->s_proc) { remove_proc_entry(sb->s_id, ext4_proc_root); @@ -1596,7 +1595,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, if (sbi->s_journal) EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - ext4_commit_super(sb, es, 1); + ext4_commit_super(sb, 1); if (test_opt(sb, DEBUG)) printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%u, " "bpg=%lu, ipg=%lu, mo=%04lx]\n", @@ -2655,7 +2654,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) if (test_opt(sb, ERRORS_PANIC)) { EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; es->s_state |= cpu_to_le16(EXT4_ERROR_FS); - ext4_commit_super(sb, es, 1); + ext4_commit_super(sb, 1); goto failed_mount4; } } @@ -3132,15 +3131,15 @@ static int ext4_load_journal(struct super_block *sb, sb->s_dirt = 1; /* Make sure we flush the recovery flag to disk. */ - ext4_commit_super(sb, es, 1); + ext4_commit_super(sb, 1); } return 0; } -static int ext4_commit_super(struct super_block *sb, - struct ext4_super_block *es, int sync) +static int ext4_commit_super(struct super_block *sb, int sync) { + struct ext4_super_block *es = EXT4_SB(sb)->s_es; struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; int error = 0; @@ -3212,7 +3211,7 @@ static void ext4_mark_recovery_complete(struct super_block *sb, sb->s_flags & MS_RDONLY) { EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); sb->s_dirt = 0; - ext4_commit_super(sb, es, 1); + ext4_commit_super(sb, 1); } unlock_super(sb); @@ -3253,7 +3252,7 @@ static void ext4_clear_journal_err(struct super_block *sb, EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; es->s_state |= cpu_to_le16(EXT4_ERROR_FS); - ext4_commit_super(sb, es, 1); + ext4_commit_super(sb, 1); jbd2_journal_clear_err(journal); } @@ -3293,7 +3292,7 @@ static void ext4_write_super(struct super_block *sb) BUG(); sb->s_dirt = 0; } else { - ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); + ext4_commit_super(sb, 1); } } @@ -3312,7 +3311,7 @@ static int ext4_sync_fs(struct super_block *sb, int wait) target); } } else { - ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait); + ext4_commit_super(sb, wait); } return ret; } @@ -3345,7 +3344,7 @@ 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); - error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); + error = ext4_commit_super(sb, 1); if (error) goto out; } @@ -3365,7 +3364,7 @@ static int ext4_unfreeze(struct super_block *sb) lock_super(sb); /* Reser the needs_recovery flag before the fs is unlocked. */ EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); + ext4_commit_super(sb, 1); unlock_super(sb); jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); } @@ -3520,7 +3519,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) } } if (sbi->s_journal == NULL) - ext4_commit_super(sb, es, 1); + ext4_commit_super(sb, 1); #ifdef CONFIG_QUOTA /* Release old quota file names */ -- GitLab From 7234ab2a55e77784b44cf2d862136d9e41b8d98a Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 30 Apr 2009 21:24:04 -0400 Subject: [PATCH 0699/6080] ext4: Fix and simplify s_dirt handling The s_dirt flag wasn't completely handled correctly, but it didn't really matter when journalling was enabled. It turns out that when ext4 runs without a journal, we don't clear s_dirt in places where we should have, with the result that the high-level write_super() function was writing the superblock when it wasn't necessary. So we fix this by making ext4_commit_super() clear the s_dirt flag, and removing many of the other places where s_dirt is manipulated. When journalling is enabled, the s_dirt flag might be left set more often, but s_dirt really doesn't matter when journalling is enabled. Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ad4c9be4abdc..7c7a08af1200 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3128,7 +3128,6 @@ static int ext4_load_journal(struct super_block *sb, if (journal_devnum && journal_devnum != le32_to_cpu(es->s_journal_dev)) { es->s_journal_dev = cpu_to_le32(journal_devnum); - sb->s_dirt = 1; /* Make sure we flush the recovery flag to disk. */ ext4_commit_super(sb, 1); @@ -3168,7 +3167,7 @@ static int ext4_commit_super(struct super_block *sb, int sync) &EXT4_SB(sb)->s_freeblocks_counter)); es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive( &EXT4_SB(sb)->s_freeinodes_counter)); - + sb->s_dirt = 0; BUFFER_TRACE(sbh, "marking dirty"); mark_buffer_dirty(sbh); if (sync) { @@ -3210,7 +3209,6 @@ static void ext4_mark_recovery_complete(struct super_block *sb, if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && sb->s_flags & MS_RDONLY) { EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - sb->s_dirt = 0; ext4_commit_super(sb, 1); } unlock_super(sb); @@ -3271,10 +3269,8 @@ int ext4_force_commit(struct super_block *sb) return 0; journal = EXT4_SB(sb)->s_journal; - if (journal) { - sb->s_dirt = 0; + if (journal) ret = ext4_journal_force_commit(journal); - } return ret; } @@ -3282,15 +3278,13 @@ int ext4_force_commit(struct super_block *sb) /* * Ext4 always journals updates to the superblock itself, so we don't * have to propagate any other updates to the superblock on disk at this - * point. (We can probably nuke this function altogether, and remove - * any mention to sb->s_dirt in all of fs/ext4; eventual cleanup...) + * point if the journalling is enabled. */ static void ext4_write_super(struct super_block *sb) { if (EXT4_SB(sb)->s_journal) { if (mutex_trylock(&sb->s_lock) != 0) BUG(); - sb->s_dirt = 0; } else { ext4_commit_super(sb, 1); } @@ -3302,7 +3296,6 @@ static int ext4_sync_fs(struct super_block *sb, int wait) tid_t target; trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); - sb->s_dirt = 0; if (EXT4_SB(sb)->s_journal) { if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { @@ -3324,7 +3317,6 @@ static int ext4_freeze(struct super_block *sb) { int error = 0; journal_t *journal; - sb->s_dirt = 0; if (!(sb->s_flags & MS_RDONLY)) { journal = EXT4_SB(sb)->s_journal; -- GitLab From 9ca92389c5312a51e819c15c762f0abdc7f3129b Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 1 May 2009 12:52:25 -0400 Subject: [PATCH 0700/6080] ext4: Use separate super_operations structure for no_journal filesystems By using a separate super_operations structure for filesystems that have and don't have journals, we can simply ext4_write_super() --- which is only needed when no journal is present --- and ext4_freeze(), ext4_unfreeze(), and ext4_sync_fs(), which are only needed when the journal is present. Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 108 +++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 51 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7c7a08af1200..68c3a44c4a97 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -995,7 +995,6 @@ static const struct super_operations ext4_sops = { .dirty_inode = ext4_dirty_inode, .delete_inode = ext4_delete_inode, .put_super = ext4_put_super, - .write_super = ext4_write_super, .sync_fs = ext4_sync_fs, .freeze_fs = ext4_freeze, .unfreeze_fs = ext4_unfreeze, @@ -1010,6 +1009,25 @@ static const struct super_operations ext4_sops = { .bdev_try_to_free_page = bdev_try_to_free_page, }; +static const struct super_operations ext4_nojournal_sops = { + .alloc_inode = ext4_alloc_inode, + .destroy_inode = ext4_destroy_inode, + .write_inode = ext4_write_inode, + .dirty_inode = ext4_dirty_inode, + .delete_inode = ext4_delete_inode, + .write_super = ext4_write_super, + .put_super = ext4_put_super, + .statfs = ext4_statfs, + .remount_fs = ext4_remount, + .clear_inode = ext4_clear_inode, + .show_options = ext4_show_options, +#ifdef CONFIG_QUOTA + .quota_read = ext4_quota_read, + .quota_write = ext4_quota_write, +#endif + .bdev_try_to_free_page = bdev_try_to_free_page, +}; + static const struct export_operations ext4_export_ops = { .fh_to_dentry = ext4_fh_to_dentry, .fh_to_parent = ext4_fh_to_parent, @@ -2615,7 +2633,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) /* * set up enough so that it can read an inode */ - sb->s_op = &ext4_sops; + if (!test_opt(sb, NOLOAD) && + EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) + sb->s_op = &ext4_sops; + else + sb->s_op = &ext4_nojournal_sops; sb->s_export_op = &ext4_export_ops; sb->s_xattr = ext4_xattr_handlers; #ifdef CONFIG_QUOTA @@ -3275,19 +3297,9 @@ int ext4_force_commit(struct super_block *sb) return ret; } -/* - * Ext4 always journals updates to the superblock itself, so we don't - * have to propagate any other updates to the superblock on disk at this - * point if the journalling is enabled. - */ static void ext4_write_super(struct super_block *sb) { - if (EXT4_SB(sb)->s_journal) { - if (mutex_trylock(&sb->s_lock) != 0) - BUG(); - } else { - ext4_commit_super(sb, 1); - } + ext4_commit_super(sb, 1); } static int ext4_sync_fs(struct super_block *sb, int wait) @@ -3296,15 +3308,9 @@ static int ext4_sync_fs(struct super_block *sb, int wait) tid_t target; trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); - if (EXT4_SB(sb)->s_journal) { - if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, - &target)) { - if (wait) - jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, - target); - } - } else { - ext4_commit_super(sb, wait); + if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { + if (wait) + jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target); } return ret; } @@ -3318,32 +3324,31 @@ static int ext4_freeze(struct super_block *sb) int error = 0; journal_t *journal; - if (!(sb->s_flags & MS_RDONLY)) { - journal = EXT4_SB(sb)->s_journal; + if (sb->s_flags & MS_RDONLY) + return 0; - if (journal) { - /* Now we set up the journal barrier. */ - jbd2_journal_lock_updates(journal); + journal = EXT4_SB(sb)->s_journal; - /* - * We don't want to clear needs_recovery flag when we - * failed to flush the journal. - */ - error = jbd2_journal_flush(journal); - if (error < 0) - goto out; - } + /* Now we set up the journal barrier. */ + jbd2_journal_lock_updates(journal); - /* Journal blocked and flushed, clear needs_recovery flag. */ - EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - error = ext4_commit_super(sb, 1); - if (error) - goto out; + /* + * Don't clear the needs_recovery flag if we failed to flush + * the journal. + */ + error = jbd2_journal_flush(journal); + if (error < 0) { + out: + jbd2_journal_unlock_updates(journal); + return error; } + + /* Journal blocked and flushed, clear needs_recovery flag. */ + EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); + error = ext4_commit_super(sb, 1); + if (error) + goto out; return 0; -out: - jbd2_journal_unlock_updates(journal); - return error; } /* @@ -3352,14 +3357,15 @@ out: */ static int ext4_unfreeze(struct super_block *sb) { - if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) { - lock_super(sb); - /* Reser the needs_recovery flag before the fs is unlocked. */ - EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); - ext4_commit_super(sb, 1); - unlock_super(sb); - jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); - } + if (sb->s_flags & MS_RDONLY) + return 0; + + lock_super(sb); + /* Reset the needs_recovery flag before the fs is unlocked. */ + EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); + ext4_commit_super(sb, 1); + unlock_super(sb); + jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); return 0; } -- GitLab From 8df9675f8b498d0bfa1f0b5b06f56bf1ff366dd5 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 1 May 2009 08:50:38 -0400 Subject: [PATCH 0701/6080] ext4: Avoid races caused by on-line resizing and SMP memory reordering Ext4's on-line resizing adds a new block group and then, only at the last step adjusts s_groups_count. However, it's possible on SMP systems that another CPU could see the updated the s_group_count and not see the newly initialized data structures for the just-added block group. For this reason, it's important to insert a SMP read barrier after reading s_groups_count and before reading any (for example) the new block group descriptors allowed by the increased value of s_groups_count. Unfortunately, we rather blatently violate this locking protocol documented in fs/ext4/resize.c. Fortunately, (1) on-line resizes happen relatively rarely, and (2) it seems rare that the filesystem code will immediately try to use just-added block group before any memory ordering issues resolve themselves. So apparently problems here are relatively hard to hit, since ext3 has been vulnerable to the same issue for years with no one apparently complaining. Signed-off-by: "Theodore Ts'o" --- fs/ext4/balloc.c | 15 +++++++-------- fs/ext4/ext4.h | 12 ++++++++++++ fs/ext4/ialloc.c | 40 +++++++++++++++++++--------------------- fs/ext4/inode.c | 7 ++++--- fs/ext4/mballoc.c | 45 ++++++++++++++++++++++++--------------------- fs/ext4/super.c | 3 +-- 6 files changed, 67 insertions(+), 55 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 53c72ad85877..a5ba039850c5 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -88,6 +88,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, ext4_group_t block_group, struct ext4_group_desc *gdp) { int bit, bit_max; + ext4_group_t ngroups = ext4_get_groups_count(sb); unsigned free_blocks, group_blocks; struct ext4_sb_info *sbi = EXT4_SB(sb); @@ -123,7 +124,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, bit_max += ext4_bg_num_gdb(sb, block_group); } - if (block_group == sbi->s_groups_count - 1) { + if (block_group == ngroups - 1) { /* * Even though mke2fs always initialize first and last group * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need @@ -131,7 +132,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, */ group_blocks = ext4_blocks_count(sbi->s_es) - le32_to_cpu(sbi->s_es->s_first_data_block) - - (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count - 1)); + (EXT4_BLOCKS_PER_GROUP(sb) * (ngroups - 1)); } else { group_blocks = EXT4_BLOCKS_PER_GROUP(sb); } @@ -205,18 +206,18 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, { unsigned int group_desc; unsigned int offset; + ext4_group_t ngroups = ext4_get_groups_count(sb); struct ext4_group_desc *desc; struct ext4_sb_info *sbi = EXT4_SB(sb); - if (block_group >= sbi->s_groups_count) { + if (block_group >= ngroups) { ext4_error(sb, "ext4_get_group_desc", "block_group >= groups_count - " "block_group = %u, groups_count = %u", - block_group, sbi->s_groups_count); + block_group, ngroups); return NULL; } - smp_rmb(); group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); @@ -665,7 +666,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) ext4_fsblk_t desc_count; struct ext4_group_desc *gdp; ext4_group_t i; - ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; + ext4_group_t ngroups = ext4_get_groups_count(sb); #ifdef EXT4FS_DEBUG struct ext4_super_block *es; ext4_fsblk_t bitmap_count; @@ -677,7 +678,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) bitmap_count = 0; gdp = NULL; - smp_rmb(); for (i = 0; i < ngroups; i++) { gdp = ext4_get_group_desc(sb, i, NULL); if (!gdp) @@ -700,7 +700,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) return bitmap_count; #else desc_count = 0; - smp_rmb(); for (i = 0; i < ngroups; i++) { gdp = ext4_get_group_desc(sb, i, NULL); if (!gdp) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index d0f15ef56de1..02ec44bf38e6 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1228,6 +1228,18 @@ struct ext4_group_info *ext4_get_group_info(struct super_block *sb, return grp_info[indexv][indexh]; } +/* + * Reading s_groups_count requires using smp_rmb() afterwards. See + * the locking protocol documented in the comments of ext4_group_add() + * in resize.c + */ +static inline ext4_group_t ext4_get_groups_count(struct super_block *sb) +{ + ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; + + smp_rmb(); + return ngroups; +} static inline ext4_group_t ext4_flex_group(struct ext4_sb_info *sbi, ext4_group_t block_group) diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index f18e0a08a6b5..55ba419ca00b 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -316,7 +316,7 @@ error_return: static int find_group_dir(struct super_block *sb, struct inode *parent, ext4_group_t *best_group) { - ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; + ext4_group_t ngroups = ext4_get_groups_count(sb); unsigned int freei, avefreei; struct ext4_group_desc *desc, *best_desc = NULL; ext4_group_t group; @@ -353,7 +353,7 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, struct flex_groups *flex_group = sbi->s_flex_groups; ext4_group_t parent_group = EXT4_I(parent)->i_block_group; ext4_group_t parent_fbg_group = ext4_flex_group(sbi, parent_group); - ext4_group_t ngroups = sbi->s_groups_count; + ext4_group_t ngroups = ext4_get_groups_count(sb); int flex_size = ext4_flex_bg_size(sbi); ext4_group_t best_flex = parent_fbg_group; int blocks_per_flex = sbi->s_blocks_per_group * flex_size; @@ -362,7 +362,7 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, ext4_group_t n_fbg_groups; ext4_group_t i; - n_fbg_groups = (sbi->s_groups_count + flex_size - 1) >> + n_fbg_groups = (ngroups + flex_size - 1) >> sbi->s_log_groups_per_flex; find_close_to_parent: @@ -478,20 +478,21 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, { ext4_group_t parent_group = EXT4_I(parent)->i_block_group; struct ext4_sb_info *sbi = EXT4_SB(sb); - ext4_group_t ngroups = sbi->s_groups_count; + ext4_group_t real_ngroups = ext4_get_groups_count(sb); int inodes_per_group = EXT4_INODES_PER_GROUP(sb); unsigned int freei, avefreei; ext4_fsblk_t freeb, avefreeb; unsigned int ndirs; int max_dirs, min_inodes; ext4_grpblk_t min_blocks; - ext4_group_t i, grp, g; + ext4_group_t i, grp, g, ngroups; struct ext4_group_desc *desc; struct orlov_stats stats; int flex_size = ext4_flex_bg_size(sbi); + ngroups = real_ngroups; if (flex_size > 1) { - ngroups = (ngroups + flex_size - 1) >> + ngroups = (real_ngroups + flex_size - 1) >> sbi->s_log_groups_per_flex; parent_group >>= sbi->s_log_groups_per_flex; } @@ -543,7 +544,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, */ grp *= flex_size; for (i = 0; i < flex_size; i++) { - if (grp+i >= sbi->s_groups_count) + if (grp+i >= real_ngroups) break; desc = ext4_get_group_desc(sb, grp+i, NULL); if (desc && ext4_free_inodes_count(sb, desc)) { @@ -583,7 +584,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, } fallback: - ngroups = sbi->s_groups_count; + ngroups = real_ngroups; avefreei = freei / ngroups; fallback_retry: parent_group = EXT4_I(parent)->i_block_group; @@ -613,9 +614,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent, ext4_group_t *group, int mode) { ext4_group_t parent_group = EXT4_I(parent)->i_block_group; - ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; + ext4_group_t i, last, ngroups = ext4_get_groups_count(sb); struct ext4_group_desc *desc; - ext4_group_t i, last; int flex_size = ext4_flex_bg_size(EXT4_SB(sb)); /* @@ -799,11 +799,10 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) struct super_block *sb; struct buffer_head *inode_bitmap_bh = NULL; struct buffer_head *group_desc_bh; - ext4_group_t group = 0; + ext4_group_t ngroups, group = 0; unsigned long ino = 0; struct inode *inode; struct ext4_group_desc *gdp = NULL; - struct ext4_super_block *es; struct ext4_inode_info *ei; struct ext4_sb_info *sbi; int ret2, err = 0; @@ -818,15 +817,14 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) return ERR_PTR(-EPERM); sb = dir->i_sb; + ngroups = ext4_get_groups_count(sb); trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id, dir->i_ino, mode); inode = new_inode(sb); if (!inode) return ERR_PTR(-ENOMEM); ei = EXT4_I(inode); - sbi = EXT4_SB(sb); - es = sbi->s_es; if (sbi->s_log_groups_per_flex && test_opt(sb, OLDALLOC)) { ret2 = find_group_flex(sb, dir, &group); @@ -856,7 +854,7 @@ got_group: if (ret2 == -1) goto out; - for (i = 0; i < sbi->s_groups_count; i++) { + for (i = 0; i < ngroups; i++) { err = -EIO; gdp = ext4_get_group_desc(sb, group, &group_desc_bh); @@ -917,7 +915,7 @@ repeat_in_this_group: * group descriptor metadata has not yet been updated. * So we just go onto the next blockgroup. */ - if (++group == sbi->s_groups_count) + if (++group == ngroups) group = 0; } err = -ENOSPC; @@ -1158,7 +1156,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) { unsigned long desc_count; struct ext4_group_desc *gdp; - ext4_group_t i; + ext4_group_t i, ngroups = ext4_get_groups_count(sb); #ifdef EXT4FS_DEBUG struct ext4_super_block *es; unsigned long bitmap_count, x; @@ -1168,7 +1166,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) desc_count = 0; bitmap_count = 0; gdp = NULL; - for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { + for (i = 0; i < ngroups; i++) { gdp = ext4_get_group_desc(sb, i, NULL); if (!gdp) continue; @@ -1190,7 +1188,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) return desc_count; #else desc_count = 0; - for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { + for (i = 0; i < ngroups; i++) { gdp = ext4_get_group_desc(sb, i, NULL); if (!gdp) continue; @@ -1205,9 +1203,9 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) unsigned long ext4_count_dirs(struct super_block * sb) { unsigned long count = 0; - ext4_group_t i; + ext4_group_t i, ngroups = ext4_get_groups_count(sb); - for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { + for (i = 0; i < ngroups; i++) { struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); if (!gdp) continue; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 96f3366f59f6..4e7f363e3030 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4965,7 +4965,8 @@ static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) */ int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) { - int groups, gdpblocks; + ext4_group_t groups, ngroups = ext4_get_groups_count(inode->i_sb); + int gdpblocks; int idxblocks; int ret = 0; @@ -4992,8 +4993,8 @@ int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) groups += nrblocks; gdpblocks = groups; - if (groups > EXT4_SB(inode->i_sb)->s_groups_count) - groups = EXT4_SB(inode->i_sb)->s_groups_count; + if (groups > ngroups) + groups = ngroups; if (groups > EXT4_SB(inode->i_sb)->s_gdb_count) gdpblocks = EXT4_SB(inode->i_sb)->s_gdb_count; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index f871677a7984..c3af9e6b6668 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -739,6 +739,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb, static int ext4_mb_init_cache(struct page *page, char *incore) { + ext4_group_t ngroups; int blocksize; int blocks_per_page; int groups_per_page; @@ -757,6 +758,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) inode = page->mapping->host; sb = inode->i_sb; + ngroups = ext4_get_groups_count(sb); blocksize = 1 << inode->i_blkbits; blocks_per_page = PAGE_CACHE_SIZE / blocksize; @@ -780,7 +782,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) for (i = 0; i < groups_per_page; i++) { struct ext4_group_desc *desc; - if (first_group + i >= EXT4_SB(sb)->s_groups_count) + if (first_group + i >= ngroups) break; err = -EIO; @@ -852,7 +854,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) struct ext4_group_info *grinfo; group = (first_block + i) >> 1; - if (group >= EXT4_SB(sb)->s_groups_count) + if (group >= ngroups) break; /* @@ -1788,6 +1790,7 @@ int ext4_mb_get_buddy_cache_lock(struct super_block *sb, ext4_group_t group) int block, pnum; int blocks_per_page; int groups_per_page; + ext4_group_t ngroups = ext4_get_groups_count(sb); ext4_group_t first_group; struct ext4_group_info *grp; @@ -1807,7 +1810,7 @@ int ext4_mb_get_buddy_cache_lock(struct super_block *sb, ext4_group_t group) /* read all groups the page covers into the cache */ for (i = 0; i < groups_per_page; i++) { - if ((first_group + i) >= EXT4_SB(sb)->s_groups_count) + if ((first_group + i) >= ngroups) break; grp = ext4_get_group_info(sb, first_group + i); /* take all groups write allocation @@ -1945,8 +1948,7 @@ err: static noinline_for_stack int ext4_mb_regular_allocator(struct ext4_allocation_context *ac) { - ext4_group_t group; - ext4_group_t i; + ext4_group_t ngroups, group, i; int cr; int err = 0; int bsbits; @@ -1957,6 +1959,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) sb = ac->ac_sb; sbi = EXT4_SB(sb); + ngroups = ext4_get_groups_count(sb); BUG_ON(ac->ac_status == AC_STATUS_FOUND); /* first, try the goal */ @@ -2017,11 +2020,11 @@ repeat: */ group = ac->ac_g_ex.fe_group; - for (i = 0; i < EXT4_SB(sb)->s_groups_count; group++, i++) { + for (i = 0; i < ngroups; group++, i++) { struct ext4_group_info *grp; struct ext4_group_desc *desc; - if (group == EXT4_SB(sb)->s_groups_count) + if (group == ngroups) group = 0; /* quick check to skip empty groups */ @@ -2315,12 +2318,10 @@ static struct file_operations ext4_mb_seq_history_fops = { static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) { struct super_block *sb = seq->private; - struct ext4_sb_info *sbi = EXT4_SB(sb); ext4_group_t group; - if (*pos < 0 || *pos >= sbi->s_groups_count) + if (*pos < 0 || *pos >= ext4_get_groups_count(sb)) return NULL; - group = *pos + 1; return (void *) ((unsigned long) group); } @@ -2328,11 +2329,10 @@ static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) static void *ext4_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t *pos) { struct super_block *sb = seq->private; - struct ext4_sb_info *sbi = EXT4_SB(sb); ext4_group_t group; ++*pos; - if (*pos < 0 || *pos >= sbi->s_groups_count) + if (*pos < 0 || *pos >= ext4_get_groups_count(sb)) return NULL; group = *pos + 1; return (void *) ((unsigned long) group); @@ -2587,6 +2587,7 @@ void ext4_mb_update_group_info(struct ext4_group_info *grp, ext4_grpblk_t add) static int ext4_mb_init_backend(struct super_block *sb) { + ext4_group_t ngroups = ext4_get_groups_count(sb); ext4_group_t i; int metalen; struct ext4_sb_info *sbi = EXT4_SB(sb); @@ -2598,7 +2599,7 @@ static int ext4_mb_init_backend(struct super_block *sb) struct ext4_group_desc *desc; /* This is the number of blocks used by GDT */ - num_meta_group_infos = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - + num_meta_group_infos = (ngroups + EXT4_DESC_PER_BLOCK(sb) - 1) >> EXT4_DESC_PER_BLOCK_BITS(sb); /* @@ -2644,7 +2645,7 @@ static int ext4_mb_init_backend(struct super_block *sb) for (i = 0; i < num_meta_group_infos; i++) { if ((i + 1) == num_meta_group_infos) metalen = sizeof(*meta_group_info) * - (sbi->s_groups_count - + (ngroups - (i << EXT4_DESC_PER_BLOCK_BITS(sb))); meta_group_info = kmalloc(metalen, GFP_KERNEL); if (meta_group_info == NULL) { @@ -2655,7 +2656,7 @@ static int ext4_mb_init_backend(struct super_block *sb) sbi->s_group_info[i] = meta_group_info; } - for (i = 0; i < sbi->s_groups_count; i++) { + for (i = 0; i < ngroups; i++) { desc = ext4_get_group_desc(sb, i, NULL); if (desc == NULL) { printk(KERN_ERR @@ -2781,13 +2782,14 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp) int ext4_mb_release(struct super_block *sb) { + ext4_group_t ngroups = ext4_get_groups_count(sb); ext4_group_t i; int num_meta_group_infos; struct ext4_group_info *grinfo; struct ext4_sb_info *sbi = EXT4_SB(sb); if (sbi->s_group_info) { - for (i = 0; i < sbi->s_groups_count; i++) { + for (i = 0; i < ngroups; i++) { grinfo = ext4_get_group_info(sb, i); #ifdef DOUBLE_CHECK kfree(grinfo->bb_bitmap); @@ -2797,7 +2799,7 @@ int ext4_mb_release(struct super_block *sb) ext4_unlock_group(sb, i); kfree(grinfo); } - num_meta_group_infos = (sbi->s_groups_count + + num_meta_group_infos = (ngroups + EXT4_DESC_PER_BLOCK(sb) - 1) >> EXT4_DESC_PER_BLOCK_BITS(sb); for (i = 0; i < num_meta_group_infos; i++) @@ -4121,7 +4123,7 @@ static void ext4_mb_return_to_preallocation(struct inode *inode, static void ext4_mb_show_ac(struct ext4_allocation_context *ac) { struct super_block *sb = ac->ac_sb; - ext4_group_t i; + ext4_group_t ngroups, i; printk(KERN_ERR "EXT4-fs: Can't allocate:" " Allocation context details:\n"); @@ -4145,7 +4147,8 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac) printk(KERN_ERR "EXT4-fs: %lu scanned, %d found\n", ac->ac_ex_scanned, ac->ac_found); printk(KERN_ERR "EXT4-fs: groups: \n"); - for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { + ngroups = ext4_get_groups_count(sb); + for (i = 0; i < ngroups; i++) { struct ext4_group_info *grp = ext4_get_group_info(sb, i); struct ext4_prealloc_space *pa; ext4_grpblk_t start; @@ -4469,13 +4472,13 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac) static int ext4_mb_discard_preallocations(struct super_block *sb, int needed) { - ext4_group_t i; + ext4_group_t i, ngroups = ext4_get_groups_count(sb); int ret; int freed = 0; trace_mark(ext4_mb_discard_preallocations, "dev %s needed %d", sb->s_id, needed); - for (i = 0; i < EXT4_SB(sb)->s_groups_count && needed > 0; i++) { + for (i = 0; i < ngroups && needed > 0; i++) { ret = ext4_mb_discard_group_preallocations(sb, i, needed); freed += ret; needed -= ret; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 68c3a44c4a97..fcd7b24c6df3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3557,9 +3557,8 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) if (test_opt(sb, MINIX_DF)) { sbi->s_overhead_last = 0; } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { - ext4_group_t ngroups = sbi->s_groups_count, i; + ext4_group_t i, ngroups = ext4_get_groups_count(sb); ext4_fsblk_t overhead = 0; - smp_rmb(); /* * Compute the overhead (FS structures). This is constant -- GitLab From 114e9fc90703bd6aac0229fb559e97caa6c49770 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 25 Apr 2009 15:48:07 -0400 Subject: [PATCH 0702/6080] ext4: Remove outdated comment about lock_super() ext4_fill_super() is no longer called by read_super(), and it is no longer called with the superblock locked. The unlock_super()/lock_super() is no longer present, so this comment is entirely superfluous. Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index fcd7b24c6df3..e3b35f26d5fe 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2828,14 +2828,6 @@ no_journal: goto failed_mount4; }; - /* - * akpm: core read_super() calls in here with the superblock locked. - * That deadlocks, because orphan cleanup needs to lock the superblock - * in numerous places. Here we just pop the lock - it's relatively - * harmless, because we are now ready to accept write_super() requests, - * and aviro says that's the only reason for hanging onto the - * superblock lock. - */ EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; ext4_orphan_cleanup(sb, es); EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; -- GitLab From a63c9eb2ce6f5028da90f282798232c4f398ceb8 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 1 May 2009 01:59:42 -0400 Subject: [PATCH 0703/6080] ext4: ext4_mark_recovery_complete() doesn't need to use lock_super The function ext4_mark_recovery_complete() is called from two call paths: either (a) while mounting the filesystem, in which case there's no danger of any other CPU calling write_super() until the mount is completed, and (b) while remounting the filesystem read-write, in which case the fs core has already locked the superblock. This also allows us to take out a very vile unlock_super()/lock_super() pair in ext4_remount(). Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e3b35f26d5fe..45d0ada9bfce 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3219,13 +3219,11 @@ static void ext4_mark_recovery_complete(struct super_block *sb, if (jbd2_journal_flush(journal) < 0) goto out; - lock_super(sb); if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && sb->s_flags & MS_RDONLY) { EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); ext4_commit_super(sb, 1); } - unlock_super(sb); out: jbd2_journal_unlock_updates(journal); @@ -3436,15 +3434,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) (sbi->s_mount_state & EXT4_VALID_FS)) es->s_state = cpu_to_le16(sbi->s_mount_state); - /* - * We have to unlock super so that we can wait for - * transactions. - */ - if (sbi->s_journal) { - unlock_super(sb); + if (sbi->s_journal) ext4_mark_recovery_complete(sb, es); - lock_super(sb); - } } else { int ret; if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, -- GitLab From 3b9d4ed26680771295d904a6b83e88e620780893 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 25 Apr 2009 22:54:04 -0400 Subject: [PATCH 0704/6080] ext4: Replace lock/unlock_super() with an explicit lock for the orphan list Use a separate lock to protect the orphan list, so we can stop overloading the use of lock_super(). Signed-off-by: "Theodore Ts'o" --- fs/ext4/ext4_sb.h | 1 + fs/ext4/namei.c | 20 +++++++++++--------- fs/ext4/super.c | 1 + 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h index 57b71fefbccf..4bda2f75d426 100644 --- a/fs/ext4/ext4_sb.h +++ b/fs/ext4/ext4_sb.h @@ -71,6 +71,7 @@ struct ext4_sb_info { struct inode *s_journal_inode; struct journal_s *s_journal; struct list_head s_orphan; + struct mutex s_orphan_lock; unsigned long s_commit_interval; u32 s_max_batch_time; u32 s_min_batch_time; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 22098e1cd085..8018e49a7287 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1997,7 +1997,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) if (!ext4_handle_valid(handle)) return 0; - lock_super(sb); + mutex_lock(&EXT4_SB(sb)->s_orphan_lock); if (!list_empty(&EXT4_I(inode)->i_orphan)) goto out_unlock; @@ -2006,9 +2006,13 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) /* @@@ FIXME: Observation from aviro: * I think I can trigger J_ASSERT in ext4_orphan_add(). We block - * here (on lock_super()), so race with ext4_link() which might bump + * here (on s_orphan_lock), so race with ext4_link() which might bump * ->i_nlink. For, say it, character device. Not a regular file, * not a directory, not a symlink and ->i_nlink > 0. + * + * tytso, 4/25/2009: I'm not sure how that could happen; + * shouldn't the fs core protect us from these sort of + * unlink()/link() races? */ J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); @@ -2045,7 +2049,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) jbd_debug(4, "orphan inode %lu will point to %d\n", inode->i_ino, NEXT_ORPHAN(inode)); out_unlock: - unlock_super(sb); + mutex_unlock(&EXT4_SB(sb)->s_orphan_lock); ext4_std_error(inode->i_sb, err); return err; } @@ -2066,11 +2070,9 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) if (!ext4_handle_valid(handle)) return 0; - lock_super(inode->i_sb); - if (list_empty(&ei->i_orphan)) { - unlock_super(inode->i_sb); - return 0; - } + mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); + if (list_empty(&ei->i_orphan)) + goto out; ino_next = NEXT_ORPHAN(inode); prev = ei->i_orphan.prev; @@ -2120,7 +2122,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) out_err: ext4_std_error(inode->i_sb, err); out: - unlock_super(inode->i_sb); + mutex_unlock(&EXT4_SB(inode->i_sb)->s_orphan_lock); return err; out_brelse: diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 45d0ada9bfce..7f43fde9554b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2645,6 +2645,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sb->dq_op = &ext4_quota_operations; #endif INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ + mutex_init(&sbi->s_orphan_lock); sb->s_root = NULL; -- GitLab From 32ed5058ce90024efcd811254b4b1de0468099df Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 25 Apr 2009 22:53:39 -0400 Subject: [PATCH 0705/6080] ext4: Replace lock/unlock_super() with an explicit lock for resizing Use a separate lock to protect s_groups_count and the other block group descriptors which get changed via an on-line resize operation, so we can stop overloading the use of lock_super(). Signed-off-by: "Theodore Ts'o" --- fs/ext4/ext4_sb.h | 1 + fs/ext4/resize.c | 35 ++++++++++++++++++----------------- fs/ext4/super.c | 1 + 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h index 4bda2f75d426..2d36223d5f57 100644 --- a/fs/ext4/ext4_sb.h +++ b/fs/ext4/ext4_sb.h @@ -72,6 +72,7 @@ struct ext4_sb_info { struct journal_s *s_journal; struct list_head s_orphan; struct mutex s_orphan_lock; + struct mutex s_resize_lock; unsigned long s_commit_interval; u32 s_max_batch_time; u32 s_min_batch_time; diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 546c7dd869e1..e8ded13b5cb1 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -193,7 +193,7 @@ static int setup_new_group_blocks(struct super_block *sb, if (IS_ERR(handle)) return PTR_ERR(handle); - lock_super(sb); + mutex_lock(&sbi->s_resize_lock); if (input->group != sbi->s_groups_count) { err = -EBUSY; goto exit_journal; @@ -302,7 +302,7 @@ exit_bh: brelse(bh); exit_journal: - unlock_super(sb); + mutex_unlock(&sbi->s_resize_lock); if ((err2 = ext4_journal_stop(handle)) && !err) err = err2; @@ -643,11 +643,12 @@ exit_free: * important part is that the new block and inode counts are in the backup * superblocks, and the location of the new group metadata in the GDT backups. * - * We do not need lock_super() for this, because these blocks are not - * otherwise touched by the filesystem code when it is mounted. We don't - * need to worry about last changing from sbi->s_groups_count, because the - * worst that can happen is that we do not copy the full number of backups - * at this time. The resize which changed s_groups_count will backup again. + * We do not need take the s_resize_lock for this, because these + * blocks are not otherwise touched by the filesystem code when it is + * mounted. We don't need to worry about last changing from + * sbi->s_groups_count, because the worst that can happen is that we + * do not copy the full number of backups at this time. The resize + * which changed s_groups_count will backup again. */ static void update_backups(struct super_block *sb, int blk_off, char *data, int size) @@ -809,7 +810,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) goto exit_put; } - lock_super(sb); + mutex_lock(&sbi->s_resize_lock); if (input->group != sbi->s_groups_count) { ext4_warning(sb, __func__, "multiple resizers run on filesystem!"); @@ -840,7 +841,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) /* * OK, now we've set up the new group. Time to make it active. * - * Current kernels don't lock all allocations via lock_super(), + * We do not lock all allocations via s_resize_lock * so we have to be safe wrt. concurrent accesses the group * data. So we need to be careful to set all of the relevant * group descriptor data etc. *before* we enable the group. @@ -900,12 +901,12 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) * * The precise rules we use are: * - * * Writers of s_groups_count *must* hold lock_super + * * Writers of s_groups_count *must* hold s_resize_lock * AND * * Writers must perform a smp_wmb() after updating all dependent * data and before modifying the groups count * - * * Readers must hold lock_super() over the access + * * Readers must hold s_resize_lock over the access * OR * * Readers must perform an smp_rmb() after reading the groups count * and before reading any dependent data. @@ -948,7 +949,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) sb->s_dirt = 1; exit_journal: - unlock_super(sb); + mutex_unlock(&sbi->s_resize_lock); if ((err2 = ext4_journal_stop(handle)) && !err) err = err2; if (!err) { @@ -986,7 +987,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, /* We don't need to worry about locking wrt other resizers just * yet: we're going to revalidate es->s_blocks_count after - * taking lock_super() below. */ + * taking the s_resize_lock below. */ o_blocks_count = ext4_blocks_count(es); o_groups_count = EXT4_SB(sb)->s_groups_count; @@ -1056,11 +1057,11 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, goto exit_put; } - lock_super(sb); + mutex_lock(&EXT4_SB(sb)->s_resize_lock); if (o_blocks_count != ext4_blocks_count(es)) { ext4_warning(sb, __func__, "multiple resizers run on filesystem!"); - unlock_super(sb); + mutex_unlock(&EXT4_SB(sb)->s_resize_lock); ext4_journal_stop(handle); err = -EBUSY; goto exit_put; @@ -1070,14 +1071,14 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, EXT4_SB(sb)->s_sbh))) { ext4_warning(sb, __func__, "error %d on journal write access", err); - unlock_super(sb); + mutex_unlock(&EXT4_SB(sb)->s_resize_lock); ext4_journal_stop(handle); goto exit_put; } ext4_blocks_count_set(es, o_blocks_count + add); ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh); sb->s_dirt = 1; - unlock_super(sb); + mutex_unlock(&EXT4_SB(sb)->s_resize_lock); ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, o_blocks_count + add); /* We add the blocks to the bitmap and set the group need init bit */ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7f43fde9554b..1fbf0906ae2e 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2646,6 +2646,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) #endif INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ mutex_init(&sbi->s_orphan_lock); + mutex_init(&sbi->s_resize_lock); sb->s_root = NULL; -- GitLab From 924a158a12c7e732179dd85ddd20848039e7bd71 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 26 Apr 2009 13:14:52 +0100 Subject: [PATCH 0706/6080] [ARM] Convert pmd_page() to be highmem safe In the long run, we may want to place page tables in highmem. However, pmd_page() has traditionally been coded to convert the physical address to a virtual one, which won't work with highmem pages. Instead, translate the physical address to a PFN, and then convert the PFN to a struct page instead. Signed-off-by: Russell King --- arch/arm/include/asm/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 110295c5461d..1cd2d6416bda 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -342,7 +342,7 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) return __va(ptr); } -#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) +#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd))) /* * Conversion functions: convert a page and protection to a page entry, -- GitLab From 38f7b009a6ae1708fcf0f208aba9a9a4364bcfcf Mon Sep 17 00:00:00 2001 From: Hartley Sweeten Date: Wed, 15 Apr 2009 23:18:26 +0100 Subject: [PATCH 0707/6080] [ARM] 5452/1: ep93x: rtc: use ioremap'ed addresses Update the rtc-ep93xx driver to use ioremap'ed addresses. This removes the dependency on and properly reports the memory addresses used by the driver in /proc/iomem. In addition, ep93xx_rtc_init() is updated to use platform_driver_probe() instead of platform_driver_register(). Also, the device_create_file() calls are now properly checked for error conditions. The created sysfs files are also now removed when the driver is removed. The version number for the driver has been bumped at the request of Alessandro Zummo. Signed-off-by: H Hartley Sweeten Acked-by: Alessandro Zummo Signed-off-by: Russell King --- arch/arm/mach-ep93xx/core.c | 15 +- .../mach-ep93xx/include/mach/ep93xx-regs.h | 1 + drivers/rtc/rtc-ep93xx.c | 149 +++++++++++++----- 3 files changed, 125 insertions(+), 40 deletions(-) diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index ae24486f858a..c535e8805a3b 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -450,10 +450,19 @@ static struct amba_device uart3_device = { }; +static struct resource ep93xx_rtc_resource[] = { + { + .start = EP93XX_RTC_PHYS_BASE, + .end = EP93XX_RTC_PHYS_BASE + 0x10c - 1, + .flags = IORESOURCE_MEM, + }, +}; + static struct platform_device ep93xx_rtc_device = { - .name = "ep93xx-rtc", - .id = -1, - .num_resources = 0, + .name = "ep93xx-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(ep93xx_rtc_resource), + .resource = ep93xx_rtc_resource, }; diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index f66be12b856e..78ac1bddc8bc 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -147,6 +147,7 @@ #define EP93XX_PWM_BASE (EP93XX_APB_VIRT_BASE + 0x00110000) #define EP93XX_RTC_BASE (EP93XX_APB_VIRT_BASE + 0x00120000) +#define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000) #define EP93XX_SYSCON_BASE (EP93XX_APB_VIRT_BASE + 0x00130000) #define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x)) diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index f7a3283dd029..551332e4ed02 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c @@ -12,32 +12,56 @@ #include #include #include -#include +#include + +#define EP93XX_RTC_DATA 0x000 +#define EP93XX_RTC_MATCH 0x004 +#define EP93XX_RTC_STATUS 0x008 +#define EP93XX_RTC_STATUS_INTR (1<<0) +#define EP93XX_RTC_LOAD 0x00C +#define EP93XX_RTC_CONTROL 0x010 +#define EP93XX_RTC_CONTROL_MIE (1<<0) +#define EP93XX_RTC_SWCOMP 0x108 +#define EP93XX_RTC_SWCOMP_DEL_MASK 0x001f0000 +#define EP93XX_RTC_SWCOMP_DEL_SHIFT 16 +#define EP93XX_RTC_SWCOMP_INT_MASK 0x0000ffff +#define EP93XX_RTC_SWCOMP_INT_SHIFT 0 + +#define DRV_VERSION "0.3" -#define EP93XX_RTC_REG(x) (EP93XX_RTC_BASE + (x)) -#define EP93XX_RTC_DATA EP93XX_RTC_REG(0x0000) -#define EP93XX_RTC_LOAD EP93XX_RTC_REG(0x000C) -#define EP93XX_RTC_SWCOMP EP93XX_RTC_REG(0x0108) - -#define DRV_VERSION "0.2" +/* + * struct device dev.platform_data is used to store our private data + * because struct rtc_device does not have a variable to hold it. + */ +struct ep93xx_rtc { + void __iomem *mmio_base; +}; -static int ep93xx_get_swcomp(struct device *dev, unsigned short *preload, +static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload, unsigned short *delete) { - unsigned short comp = __raw_readl(EP93XX_RTC_SWCOMP); + struct ep93xx_rtc *ep93xx_rtc = dev->platform_data; + unsigned long comp; + + comp = __raw_readl(ep93xx_rtc->mmio_base + EP93XX_RTC_SWCOMP); if (preload) - *preload = comp & 0xffff; + *preload = (comp & EP93XX_RTC_SWCOMP_INT_MASK) + >> EP93XX_RTC_SWCOMP_INT_SHIFT; if (delete) - *delete = (comp >> 16) & 0x1f; + *delete = (comp & EP93XX_RTC_SWCOMP_DEL_MASK) + >> EP93XX_RTC_SWCOMP_DEL_SHIFT; return 0; } static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) { - unsigned long time = __raw_readl(EP93XX_RTC_DATA); + struct ep93xx_rtc *ep93xx_rtc = dev->platform_data; + unsigned long time; + + time = __raw_readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA); rtc_time_to_tm(time, tm); return 0; @@ -45,7 +69,9 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs) { - __raw_writel(secs + 1, EP93XX_RTC_LOAD); + struct ep93xx_rtc *ep93xx_rtc = dev->platform_data; + + __raw_writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD); return 0; } @@ -53,7 +79,7 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) { unsigned short preload, delete; - ep93xx_get_swcomp(dev, &preload, &delete); + ep93xx_rtc_get_swcomp(dev, &preload, &delete); seq_printf(seq, "preload\t\t: %d\n", preload); seq_printf(seq, "delete\t\t: %d\n", delete); @@ -67,54 +93,104 @@ static const struct rtc_class_ops ep93xx_rtc_ops = { .proc = ep93xx_rtc_proc, }; -static ssize_t ep93xx_sysfs_show_comp_preload(struct device *dev, +static ssize_t ep93xx_rtc_show_comp_preload(struct device *dev, struct device_attribute *attr, char *buf) { unsigned short preload; - ep93xx_get_swcomp(dev, &preload, NULL); + ep93xx_rtc_get_swcomp(dev, &preload, NULL); return sprintf(buf, "%d\n", preload); } -static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_sysfs_show_comp_preload, NULL); +static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_rtc_show_comp_preload, NULL); -static ssize_t ep93xx_sysfs_show_comp_delete(struct device *dev, +static ssize_t ep93xx_rtc_show_comp_delete(struct device *dev, struct device_attribute *attr, char *buf) { unsigned short delete; - ep93xx_get_swcomp(dev, NULL, &delete); + ep93xx_rtc_get_swcomp(dev, NULL, &delete); return sprintf(buf, "%d\n", delete); } -static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_sysfs_show_comp_delete, NULL); +static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL); -static int __devinit ep93xx_rtc_probe(struct platform_device *dev) +static int __init ep93xx_rtc_probe(struct platform_device *pdev) { - struct rtc_device *rtc = rtc_device_register("ep93xx", - &dev->dev, &ep93xx_rtc_ops, THIS_MODULE); + struct ep93xx_rtc *ep93xx_rtc; + struct resource *res; + struct rtc_device *rtc; + int err; + + ep93xx_rtc = kzalloc(sizeof(struct ep93xx_rtc), GFP_KERNEL); + if (ep93xx_rtc == NULL) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) + return -ENXIO; + + res = request_mem_region(res->start, resource_size(res), pdev->name); + if (res == NULL) + return -EBUSY; + + ep93xx_rtc->mmio_base = ioremap(res->start, resource_size(res)); + if (ep93xx_rtc->mmio_base == NULL) { + err = -ENXIO; + goto fail; + } + pdev->dev.platform_data = ep93xx_rtc; + + rtc = rtc_device_register(pdev->name, + &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { - return PTR_ERR(rtc); + err = PTR_ERR(rtc); + goto fail; } - platform_set_drvdata(dev, rtc); + platform_set_drvdata(pdev, rtc); - device_create_file(&dev->dev, &dev_attr_comp_preload); - device_create_file(&dev->dev, &dev_attr_comp_delete); + err = device_create_file(&pdev->dev, &dev_attr_comp_preload); + if (err) + goto fail; + err = device_create_file(&pdev->dev, &dev_attr_comp_delete); + if (err) { + device_remove_file(&pdev->dev, &dev_attr_comp_preload); + goto fail; + } return 0; + +fail: + if (ep93xx_rtc->mmio_base) { + iounmap(ep93xx_rtc->mmio_base); + pdev->dev.platform_data = NULL; + } + release_mem_region(res->start, resource_size(res)); + return err; } -static int __devexit ep93xx_rtc_remove(struct platform_device *dev) +static int __exit ep93xx_rtc_remove(struct platform_device *pdev) { - struct rtc_device *rtc = platform_get_drvdata(dev); + struct rtc_device *rtc = platform_get_drvdata(pdev); + struct ep93xx_rtc *ep93xx_rtc = pdev->dev.platform_data; + struct resource *res; + + /* cleanup sysfs */ + device_remove_file(&pdev->dev, &dev_attr_comp_delete); + device_remove_file(&pdev->dev, &dev_attr_comp_preload); + + rtc_device_unregister(rtc); + + iounmap(ep93xx_rtc->mmio_base); + pdev->dev.platform_data = NULL; - if (rtc) - rtc_device_unregister(rtc); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); - platform_set_drvdata(dev, NULL); + platform_set_drvdata(pdev, NULL); return 0; } @@ -122,23 +198,22 @@ static int __devexit ep93xx_rtc_remove(struct platform_device *dev) /* work with hotplug and coldplug */ MODULE_ALIAS("platform:ep93xx-rtc"); -static struct platform_driver ep93xx_rtc_platform_driver = { +static struct platform_driver ep93xx_rtc_driver = { .driver = { .name = "ep93xx-rtc", .owner = THIS_MODULE, }, - .probe = ep93xx_rtc_probe, - .remove = __devexit_p(ep93xx_rtc_remove), + .remove = __exit_p(ep93xx_rtc_remove), }; static int __init ep93xx_rtc_init(void) { - return platform_driver_register(&ep93xx_rtc_platform_driver); + return platform_driver_probe(&ep93xx_rtc_driver, ep93xx_rtc_probe); } static void __exit ep93xx_rtc_exit(void) { - platform_driver_unregister(&ep93xx_rtc_platform_driver); + platform_driver_unregister(&ep93xx_rtc_driver); } MODULE_AUTHOR("Alessandro Zummo "); -- GitLab From fc4967b8c6a1540ebce9ac48e44b8d44e7fac971 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 27 Apr 2009 14:06:26 +0900 Subject: [PATCH 0708/6080] sh: update defconfigs for PCI changes. Signed-off-by: Paul Mundt --- arch/sh/configs/ap325rxa_defconfig | 37 ++++++++++-- arch/sh/configs/cayman_defconfig | 71 ++++++++++------------- arch/sh/configs/dreamcast_defconfig | 39 ++++++++++--- arch/sh/configs/edosk7705_defconfig | 29 +++++++-- arch/sh/configs/edosk7760_defconfig | 32 ++++++++-- arch/sh/configs/espt_defconfig | 39 +++++++++++-- arch/sh/configs/hp6xx_defconfig | 35 +++++++++-- arch/sh/configs/landisk_defconfig | 48 ++++++++++++--- arch/sh/configs/lboxre2_defconfig | 44 +++++++++++--- arch/sh/configs/magicpanelr2_defconfig | 30 ++++++++-- arch/sh/configs/microdev_defconfig | 36 ++++++++++-- arch/sh/configs/migor_defconfig | 36 +++++++++--- arch/sh/configs/polaris_defconfig | 30 ++++++++-- arch/sh/configs/r7780mp_defconfig | 36 +++++++++--- arch/sh/configs/r7785rp_defconfig | 36 +++++++++--- arch/sh/configs/rsk7201_defconfig | 37 ++++++++++-- arch/sh/configs/rsk7203_defconfig | 40 ++++++++++--- arch/sh/configs/rts7751r2d1_defconfig | 43 +++++++++++--- arch/sh/configs/rts7751r2dplus_defconfig | 43 +++++++++++--- arch/sh/configs/sdk7780_defconfig | 38 +++++++++--- arch/sh/configs/se7206_defconfig | 35 +++++++++-- arch/sh/configs/se7343_defconfig | 42 ++++++++++++-- arch/sh/configs/se7619_defconfig | 35 +++++++++-- arch/sh/configs/se7705_defconfig | 34 +++++++++-- arch/sh/configs/se7712_defconfig | 30 ++++++++-- arch/sh/configs/se7721_defconfig | 33 +++++++++-- arch/sh/configs/se7722_defconfig | 38 +++++++++--- arch/sh/configs/se7750_defconfig | 34 +++++++++-- arch/sh/configs/se7751_defconfig | 34 +++++++++-- arch/sh/configs/se7780_defconfig | 38 +++++++++--- arch/sh/configs/sh03_defconfig | 43 +++++++++++--- arch/sh/configs/sh7710voipgw_defconfig | 35 +++++++++-- arch/sh/configs/sh7724_generic_defconfig | 4 +- arch/sh/configs/sh7763rdp_defconfig | 35 +++++++++-- arch/sh/configs/sh7785lcr_32bit_defconfig | 37 +++++++++--- arch/sh/configs/sh7785lcr_defconfig | 6 +- arch/sh/configs/shmin_defconfig | 31 ++++++++-- arch/sh/configs/shx3_defconfig | 32 ++++++++-- arch/sh/configs/snapgear_defconfig | 40 ++++++++++--- arch/sh/configs/systemh_defconfig | 39 +++++++++++-- arch/sh/configs/titan_defconfig | 40 ++++++++++--- arch/sh/configs/ul2_defconfig | 37 ++++++++++-- arch/sh/configs/urquell_defconfig | 39 +++++++++++-- 43 files changed, 1247 insertions(+), 303 deletions(-) diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig index c8d982a8a2e6..022f70e0ea03 100644 --- a/arch/sh/configs/ap325rxa_defconfig +++ b/arch/sh/configs/ap325rxa_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 17:46:53 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:42:06 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -74,6 +75,7 @@ CONFIG_EMBEDDED=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y # CONFIG_KALLSYMS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -92,12 +94,15 @@ 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_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -110,7 +115,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -159,6 +163,7 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set CONFIG_CPU_SUBTYPE_SH7723=y +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -168,8 +173,6 @@ CONFIG_CPU_SUBTYPE_SH7723=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -573,6 +576,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -695,6 +699,7 @@ CONFIG_DEVKMEM=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=6 CONFIG_SERIAL_SH_SCI_CONSOLE=y @@ -1030,6 +1035,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y @@ -1051,6 +1057,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1100,6 +1111,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1191,10 +1203,24 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1303,6 +1329,7 @@ CONFIG_CRYPTO_CBC=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig index fa5fc1e1e980..40301f86a45c 100644 --- a/arch/sh/configs/cayman_defconfig +++ b/arch/sh/configs/cayman_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 17:49:14 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:42:53 2009 # CONFIG_SUPERH=y # CONFIG_SUPERH32 is not set @@ -40,6 +40,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y # CONFIG_SYSVIPC is not set CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set @@ -70,6 +71,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -89,10 +91,13 @@ 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_HAVE_IOREMAP_PROT=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -105,7 +110,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -127,39 +131,6 @@ CONFIG_DEFAULT_IOSCHED="cfq" # System type # CONFIG_CPU_SH5=y -# CONFIG_CPU_SUBTYPE_SH7619 is not set -# CONFIG_CPU_SUBTYPE_SH7201 is not set -# CONFIG_CPU_SUBTYPE_SH7203 is not set -# CONFIG_CPU_SUBTYPE_SH7206 is not set -# CONFIG_CPU_SUBTYPE_SH7263 is not set -# CONFIG_CPU_SUBTYPE_MXG is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set -# CONFIG_CPU_SUBTYPE_SH7712 is not set -# CONFIG_CPU_SUBTYPE_SH7720 is not set -# CONFIG_CPU_SUBTYPE_SH7721 is not set -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set -# CONFIG_CPU_SUBTYPE_SH7723 is not set -# CONFIG_CPU_SUBTYPE_SH7763 is not set -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set -# CONFIG_CPU_SUBTYPE_SH7785 is not set -# CONFIG_CPU_SUBTYPE_SH7786 is not set -# CONFIG_CPU_SUBTYPE_SHX3 is not set -# CONFIG_CPU_SUBTYPE_SH7343 is not set -# CONFIG_CPU_SUBTYPE_SH7722 is not set -# CONFIG_CPU_SUBTYPE_SH7366 is not set CONFIG_CPU_SUBTYPE_SH5_101=y # CONFIG_CPU_SUBTYPE_SH5_103 is not set @@ -279,8 +250,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -492,6 +461,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -568,6 +538,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -591,6 +562,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -779,6 +751,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -1042,7 +1015,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1082,6 +1054,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -1104,6 +1077,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1146,8 +1124,13 @@ CONFIG_MINIX_FS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1208,6 +1191,9 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y # CONFIG_TIMER_STATS is not set @@ -1241,15 +1227,21 @@ CONFIG_FRAME_POINTER=y # CONFIG_LATENCYTOP is not set # CONFIG_SYSCTL_SYSCALL_CHECK is not set # CONFIG_PAGE_POISONING is not set +CONFIG_TRACING_SUPPORT=y # # Tracers # # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set # CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_DEBUG_BOOTMEM is not set @@ -1354,6 +1346,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig index 5c1123640142..1f3cc98330bf 100644 --- a/arch/sh/configs/dreamcast_defconfig +++ b/arch/sh/configs/dreamcast_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 17:51:48 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:44:27 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -71,6 +72,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -90,6 +92,7 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y +# CONFIG_MARKERS is not set # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -98,6 +101,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -110,7 +115,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -156,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7091=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -165,8 +170,6 @@ CONFIG_CPU_SUBTYPE_SH7091=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -271,7 +274,7 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_SH_DMA_API=y CONFIG_SH_DMA=y CONFIG_SH_DMA_IRQ_MULTI=y -CONFIG_NR_ONCHIP_DMA_CHANNELS=6 +CONFIG_NR_ONCHIP_DMA_CHANNELS=4 CONFIG_NR_DMA_CHANNELS_BOOL=y CONFIG_NR_DMA_CHANNELS=9 # CONFIG_PVR2_DMA is not set @@ -320,7 +323,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 panic=3" CONFIG_MAPLE=y CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -602,6 +604,7 @@ CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_BCM5974 is not set # CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MOUSE_MAPLE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set @@ -812,7 +815,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -866,6 +868,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -910,6 +917,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -947,10 +955,24 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1051,6 +1073,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig index f4c34b039312..d7092457ddc7 100644 --- a/arch/sh/configs/edosk7705_defconfig +++ b/arch/sh/configs/edosk7705_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 17:54:02 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:45:04 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -56,6 +57,7 @@ CONFIG_EMBEDDED=y # CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set # CONFIG_KALLSYMS is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_HOTPLUG is not set # CONFIG_PRINTK is not set # CONFIG_BUG is not set @@ -74,12 +76,15 @@ CONFIG_SHMEM=y CONFIG_SLUB=y # CONFIG_SLOB is not set # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_BASE_SMALL=1 # CONFIG_MODULES is not set @@ -114,6 +119,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -123,8 +129,6 @@ CONFIG_CPU_SUBTYPE_SH7705=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -381,6 +385,10 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# + # # Pseudo filesystems # @@ -409,10 +417,22 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -426,6 +446,7 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig index 7825c2699f18..a822b1d8c116 100644 --- a/arch/sh/configs/edosk7760_defconfig +++ b/arch/sh/configs/edosk7760_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 17:54:57 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:45:25 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -40,6 +41,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set @@ -67,7 +69,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -77,6 +78,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -96,6 +98,7 @@ CONFIG_COMPAT_BRK=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_IOREMAP_PROT=y @@ -103,6 +106,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -115,7 +120,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -161,6 +165,7 @@ CONFIG_CPU_SH4=y CONFIG_CPU_SUBTYPE_SH7760=y # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -170,8 +175,6 @@ CONFIG_CPU_SUBTYPE_SH7760=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -815,6 +818,7 @@ CONFIG_EXT2_FS_XATTR=y # CONFIG_EXT2_FS_SECURITY is not set CONFIG_EXT2_FS_XIP=y CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -838,6 +842,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_FUSE_FS is not set CONFIG_GENERIC_ACL=y +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -883,6 +892,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -964,6 +974,9 @@ CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 # CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set CONFIG_TIMER_STATS=y @@ -1001,6 +1014,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1010,9 +1024,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1126,6 +1145,7 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig index ebb4c37abaa6..c5b50077913d 100644 --- a/arch/sh/configs/espt_defconfig +++ b/arch/sh/configs/espt_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 17:58:18 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:46:26 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -78,6 +79,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -106,6 +108,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -117,7 +121,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -164,6 +167,7 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set CONFIG_CPU_SUBTYPE_SH7763=y # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -173,8 +177,6 @@ CONFIG_CPU_SUBTYPE_SH7763=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -548,6 +550,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -919,6 +922,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -942,6 +946,11 @@ CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set CONFIG_GENERIC_ACL=y +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -985,8 +994,13 @@ CONFIG_CRAMFS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -1075,11 +1089,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1179,6 +1207,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig index 82b113af08d3..8e13027eecc3 100644 --- a/arch/sh/configs/hp6xx_defconfig +++ b/arch/sh/configs/hp6xx_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:01:05 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:47:15 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -67,6 +68,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -85,12 +87,15 @@ 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_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -98,7 +103,6 @@ CONFIG_BASE_SMALL=0 # CONFIG_MODULES is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -144,6 +148,7 @@ CONFIG_CPU_SUBTYPE_SH7709=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -153,8 +158,6 @@ CONFIG_CPU_SUBTYPE_SH7709=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -385,6 +388,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set # CONFIG_SCSI_DH is not set @@ -431,6 +435,7 @@ CONFIG_KEYBOARD_HP6XX=y # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TABLET is not set CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_AD7879 is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELO is not set @@ -673,6 +678,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -719,6 +729,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set # # Partition Types @@ -786,10 +797,23 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -898,6 +922,7 @@ CONFIG_CRYPTO_MD5=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index b6fa4a7599d0..7f549aef0dfd 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:02:54 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:47:48 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -69,6 +70,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_EXTRA_PASS=y +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -88,6 +90,7 @@ 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_IOREMAP_PROT=y @@ -95,6 +98,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -107,7 +112,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -153,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -162,8 +167,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -292,8 +295,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -602,6 +603,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -706,6 +708,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -729,6 +732,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -922,6 +926,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y # CONFIG_SOC_CAMERA is not set CONFIG_V4L_USB_DRIVERS=y # CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y # CONFIG_USB_GSPCA is not set # CONFIG_VIDEO_HDPVR is not set CONFIG_VIDEO_USBVIDEO=m @@ -994,15 +999,17 @@ CONFIG_USB_HID=m # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_HID_A4TECH=m CONFIG_HID_APPLE=m CONFIG_HID_BELKIN=m CONFIG_HID_CHERRY=m CONFIG_HID_CHICONY=m CONFIG_HID_CYPRESS=m +# CONFIG_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=m +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=m +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=m # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -1197,6 +1204,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -1221,6 +1229,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1270,10 +1283,15 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set CONFIG_UFS_FS=m # CONFIG_UFS_FS_WRITE is not set # CONFIG_UFS_DEBUG is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m CONFIG_NFS_V3=y @@ -1364,10 +1382,23 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y @@ -1469,6 +1500,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig index 92c515c4199f..a7db539f2800 100644 --- a/arch/sh/configs/lboxre2_defconfig +++ b/arch/sh/configs/lboxre2_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:06:51 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:48:54 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -69,6 +70,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_EXTRA_PASS=y +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -88,6 +90,7 @@ 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_IOREMAP_PROT=y @@ -95,6 +98,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -107,7 +112,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -153,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -162,8 +167,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -293,8 +296,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1" # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -542,6 +543,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -702,6 +704,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -725,6 +728,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -931,7 +935,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1007,6 +1010,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -1028,6 +1032,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1073,8 +1082,13 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -1151,10 +1165,23 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y @@ -1256,6 +1283,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig index 26586c2d64ca..58bec61506fa 100644 --- a/arch/sh/configs/magicpanelr2_defconfig +++ b/arch/sh/configs/magicpanelr2_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:07:39 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:49:32 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -39,6 +40,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y # CONFIG_TASKSTATS is not set @@ -66,7 +68,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -76,6 +77,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -94,6 +96,7 @@ 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_IOREMAP_PROT=y @@ -101,6 +104,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -113,7 +118,6 @@ CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -159,6 +163,7 @@ CONFIG_CPU_SUBTYPE_SH7720=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -168,8 +173,6 @@ CONFIG_CPU_SUBTYPE_SH7720=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -813,6 +816,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set # CONFIG_EXT4_FS is not set CONFIG_JBD=y @@ -830,6 +834,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -884,6 +893,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -965,6 +975,7 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set # CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DETECT_HUNG_TASK is not set # CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1000,6 +1011,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1008,9 +1020,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1035,6 +1052,7 @@ CONFIG_DUMP_CODE=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig index 75178355d69a..2886fc84bc1c 100644 --- a/arch/sh/configs/microdev_defconfig +++ b/arch/sh/configs/microdev_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:11:13 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:50:51 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -65,7 +66,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -74,6 +74,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -92,12 +93,15 @@ 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_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -105,7 +109,6 @@ CONFIG_BASE_SMALL=0 # CONFIG_MODULES is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -151,6 +154,7 @@ CONFIG_CPU_SH4=y # CONFIG_CPU_SUBTYPE_SH7760 is not set CONFIG_CPU_SUBTYPE_SH4_202=y # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -160,8 +164,6 @@ CONFIG_CPU_SUBTYPE_SH4_202=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -647,6 +649,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -668,6 +671,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -715,6 +723,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -802,10 +811,24 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -914,6 +937,7 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig index a8720f9c6047..8ecceb4bf27e 100644 --- a/arch/sh/configs/migor_defconfig +++ b/arch/sh/configs/migor_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:14:03 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:51:34 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -67,7 +68,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -76,6 +76,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -104,6 +105,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -115,7 +118,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -165,6 +167,7 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -174,8 +177,6 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_CPU_SUBTYPE_SH7343 is not set CONFIG_CPU_SUBTYPE_SH7722=y # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -577,6 +578,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -873,7 +875,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -1011,6 +1012,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1056,6 +1062,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -1105,11 +1112,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1218,6 +1239,7 @@ CONFIG_CRYPTO_WORKQUEUE=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig index df2d177d5346..2b9507286182 100644 --- a/arch/sh/configs/polaris_defconfig +++ b/arch/sh/configs/polaris_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:16:48 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:52:19 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -40,6 +41,7 @@ CONFIG_LOCALVERSION="" CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y # CONFIG_TASKSTATS is not set @@ -76,6 +78,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -94,6 +97,7 @@ 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_IOREMAP_PROT=y @@ -101,6 +105,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -113,7 +119,6 @@ CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -159,6 +164,7 @@ CONFIG_CPU_SUBTYPE_SH7709=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -168,8 +174,6 @@ CONFIG_CPU_SUBTYPE_SH7709=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -777,6 +781,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -831,6 +840,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -874,6 +884,9 @@ CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 # CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -914,6 +927,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -923,9 +937,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -950,6 +969,7 @@ CONFIG_DUMP_CODE=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig index 7def4df46ddb..68e5eff5d7fe 100644 --- a/arch/sh/configs/r7780mp_defconfig +++ b/arch/sh/configs/r7780mp_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:20:17 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:53:28 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -78,6 +79,7 @@ CONFIG_UID16=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -107,6 +109,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_BASE_SMALL=0 @@ -118,7 +122,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -165,6 +168,7 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set CONFIG_CPU_SUBTYPE_SH7780=y @@ -174,8 +178,6 @@ CONFIG_CPU_SUBTYPE_SH7780=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -313,8 +315,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -536,6 +536,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -696,6 +697,7 @@ CONFIG_E1000=m # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -719,6 +721,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -920,6 +923,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -1027,7 +1031,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1120,6 +1123,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -1142,6 +1146,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1191,6 +1200,7 @@ CONFIG_MINIX_FS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1279,6 +1289,9 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1316,6 +1329,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1325,11 +1339,16 @@ CONFIG_TRACING=y # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1449,6 +1468,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig index cb134ffc2118..890fe3cc9142 100644 --- a/arch/sh/configs/r7785rp_defconfig +++ b/arch/sh/configs/r7785rp_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:24:35 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:55:10 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -43,6 +44,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set @@ -78,6 +80,7 @@ CONFIG_UID16=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -108,6 +111,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -120,7 +125,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -168,6 +172,7 @@ CONFIG_CPU_SHX2=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -177,8 +182,6 @@ CONFIG_CPU_SUBTYPE_SH7785=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -337,8 +340,6 @@ CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCI_LEGACY is not set @@ -561,6 +562,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -698,6 +700,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -721,6 +724,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -948,6 +952,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set @@ -970,6 +975,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_SMSC47M1 is not set @@ -1109,7 +1115,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1202,6 +1207,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -1224,6 +1230,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1273,6 +1284,7 @@ CONFIG_MINIX_FS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1359,6 +1371,7 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set # CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DETECT_HUNG_TASK is not set CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1401,6 +1414,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1410,11 +1424,16 @@ CONFIG_TRACING=y # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1534,6 +1553,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig index a037c744b798..fa4395768d19 100644 --- a/arch/sh/configs/rsk7201_defconfig +++ b/arch/sh/configs/rsk7201_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:29:08 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:56:29 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -65,7 +66,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -74,6 +74,7 @@ CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -100,6 +101,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 @@ -110,7 +113,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -157,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7201=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -166,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7201=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -602,6 +603,11 @@ CONFIG_EXT2_FS=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -651,8 +657,13 @@ CONFIG_JFFS2_RTIME=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set # # Partition Types @@ -686,11 +697,24 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -705,6 +729,7 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig index 9ae28e88426c..e3a65f819f0a 100644 --- a/arch/sh/configs/rsk7203_defconfig +++ b/arch/sh/configs/rsk7203_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:30:34 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:57:06 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -39,6 +40,7 @@ CONFIG_LOCALVERSION="" CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set @@ -70,7 +72,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -80,6 +81,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -106,6 +108,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 @@ -116,7 +120,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -163,6 +166,7 @@ CONFIG_CPU_SUBTYPE_SH7203=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -172,8 +176,6 @@ CONFIG_CPU_SUBTYPE_SH7203=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -750,15 +752,17 @@ CONFIG_USB_HID=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_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -874,6 +878,7 @@ CONFIG_LEDS_CLASS=y # LED drivers # CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y # # LED Triggers @@ -882,6 +887,7 @@ CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_BACKLIGHT=y +# CONFIG_LEDS_TRIGGER_GPIO is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # @@ -950,6 +956,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -989,8 +1000,13 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -1033,6 +1049,9 @@ CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1076,6 +1095,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1083,11 +1103,16 @@ CONFIG_TRACING=y # CONFIG_FUNCTION_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1111,6 +1136,7 @@ CONFIG_DUMP_CODE=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig index c0f741af6da8..a4a59f6205ab 100644 --- a/arch/sh/configs/rts7751r2d1_defconfig +++ b/arch/sh/configs/rts7751r2d1_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:33:25 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:58:13 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -70,6 +71,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -99,6 +101,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -110,7 +114,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -156,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -165,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -302,8 +304,6 @@ CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=se # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -513,6 +513,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -672,6 +673,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -695,6 +697,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -793,6 +796,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=1 CONFIG_SERIAL_SH_SCI_CONSOLE=y @@ -1079,15 +1083,17 @@ CONFIG_USB_HID=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_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -1290,6 +1296,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1337,6 +1348,7 @@ CONFIG_MINIX_FS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -1417,11 +1429,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1524,6 +1550,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig index 8feef629e49c..2bc1c97d346a 100644 --- a/arch/sh/configs/rts7751r2dplus_defconfig +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:34:12 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:59:01 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -70,6 +71,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -99,6 +101,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -110,7 +114,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -156,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -165,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -302,8 +304,6 @@ CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=se # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -513,6 +513,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -672,6 +673,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -695,6 +697,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -793,6 +796,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=1 CONFIG_SERIAL_SH_SCI_CONSOLE=y @@ -1079,15 +1083,17 @@ CONFIG_USB_HID=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_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -1290,6 +1296,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1337,6 +1348,7 @@ CONFIG_MINIX_FS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -1417,11 +1429,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1524,6 +1550,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig index 739e2299ae80..a629b79a1844 100644 --- a/arch/sh/configs/sdk7780_defconfig +++ b/arch/sh/configs/sdk7780_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:34:43 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 12:59:32 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -41,6 +42,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set @@ -73,6 +75,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -93,6 +96,7 @@ CONFIG_COMPAT_BRK=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_IOREMAP_PROT=y @@ -100,6 +104,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -112,7 +118,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -159,6 +164,7 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set CONFIG_CPU_SUBTYPE_SH7780=y @@ -168,8 +174,6 @@ CONFIG_CPU_SUBTYPE_SH7780=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -310,8 +314,6 @@ CONFIG_CMDLINE="mem=128M console=tty0 console=ttySC0,115200 ip=bootp root=/dev/n # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCI_LEGACY is not set @@ -646,6 +648,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -1091,15 +1094,17 @@ CONFIG_USB_HID=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_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -1257,6 +1262,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y # CONFIG_EXT2_FS_SECURITY is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y # CONFIG_EXT3_FS_SECURITY is not set @@ -1280,6 +1286,11 @@ CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set CONFIG_GENERIC_ACL=y +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1331,6 +1342,7 @@ CONFIG_MINIX_FS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1418,6 +1430,9 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 # CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set CONFIG_TIMER_STATS=y @@ -1455,6 +1470,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1464,9 +1480,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1580,6 +1601,7 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index d30e0a7ad9f1..5caf85a3312d 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:39:37 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:01:02 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -40,6 +41,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set @@ -63,6 +65,7 @@ CONFIG_CGROUP_DEBUG=y CONFIG_CGROUP_NS=y # CONFIG_CGROUP_FREEZER is not set CONFIG_CGROUP_DEVICE=y +# CONFIG_CPUSETS is not set CONFIG_CGROUP_CPUACCT=y CONFIG_RESOURCE_COUNTERS=y CONFIG_CGROUP_MEM_RES_CTLR=y @@ -80,7 +83,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -90,6 +92,7 @@ CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -116,6 +119,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 @@ -127,7 +132,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -174,6 +178,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -183,8 +188,6 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -745,6 +748,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -785,8 +793,13 @@ CONFIG_CRAMFS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -831,6 +844,9 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -869,6 +885,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -876,11 +893,16 @@ CONFIG_TRACING=y # CONFIG_FUNCTION_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -991,6 +1013,7 @@ CONFIG_CRYPTO_LZO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig index fbb72d029e68..004d531716dc 100644 --- a/arch/sh/configs/se7343_defconfig +++ b/arch/sh/configs/se7343_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:42:00 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:01:44 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -40,6 +41,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set @@ -73,6 +75,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -91,6 +94,7 @@ 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_IOREMAP_PROT=y @@ -98,6 +102,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_BASE_SMALL=0 @@ -109,7 +115,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -158,6 +163,7 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -167,8 +173,6 @@ CONFIG_ARCH_SHMOBILE=y CONFIG_CPU_SUBTYPE_SH7343=y # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -769,6 +773,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y # CONFIG_SOC_CAMERA is not set CONFIG_V4L_USB_DRIVERS=y # CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y CONFIG_USB_GSPCA=m # CONFIG_USB_M5602 is not set # CONFIG_USB_STV06XX is not set @@ -800,6 +805,7 @@ CONFIG_USB_GSPCA=m # CONFIG_VIDEO_PVRUSB2 is not set # CONFIG_VIDEO_HDPVR is not set # CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set # CONFIG_VIDEO_USBVISION is not set # CONFIG_USB_VICAM is not set # CONFIG_USB_IBMCAM is not set @@ -813,6 +819,7 @@ CONFIG_USB_GSPCA=m # CONFIG_USB_STV680 is not set # CONFIG_USB_ZC0301 is not set # CONFIG_USB_PWC is not set +CONFIG_USB_PWC_INPUT_EVDEV=y # CONFIG_USB_ZR364XX is not set # CONFIG_USB_STKWEBCAM is not set # CONFIG_USB_S2255 is not set @@ -914,15 +921,17 @@ CONFIG_USB_HID=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_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -1050,6 +1059,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -1070,6 +1080,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1125,6 +1140,7 @@ CONFIG_CRAMFS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1174,10 +1190,23 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1279,6 +1308,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig index 125304e80f57..edbece52afc1 100644 --- a/arch/sh/configs/se7619_defconfig +++ b/arch/sh/configs/se7619_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:44:53 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:02:32 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -61,6 +62,7 @@ CONFIG_EMBEDDED=y # CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set # CONFIG_KALLSYMS is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y @@ -78,11 +80,14 @@ 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_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_BASE_SMALL=1 @@ -134,6 +139,7 @@ CONFIG_CPU_SUBTYPE_SH7619=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -143,8 +149,6 @@ CONFIG_CPU_SUBTYPE_SH7619=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -513,7 +517,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -563,6 +566,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -601,8 +609,13 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set # # Partition Types @@ -630,10 +643,21 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -647,6 +671,7 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig index 0308abf52384..bae161c66835 100644 --- a/arch/sh/configs/se7705_defconfig +++ b/arch/sh/configs/se7705_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:45:56 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:02:52 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -62,7 +63,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -70,6 +70,7 @@ CONFIG_EMBEDDED=y CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set # CONFIG_KALLSYMS is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y @@ -88,12 +89,15 @@ 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_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -150,6 +154,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -159,8 +164,6 @@ CONFIG_CPU_SUBTYPE_SH7705=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -698,7 +701,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -751,6 +753,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -804,6 +811,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -847,10 +855,23 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -949,6 +970,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig index a8c24b703489..330043f3c316 100644 --- a/arch/sh/configs/se7712_defconfig +++ b/arch/sh/configs/se7712_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:48:18 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:03:27 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -38,6 +39,7 @@ CONFIG_LOCALVERSION="" CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set @@ -69,6 +71,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y # CONFIG_BUG is not set @@ -87,6 +90,7 @@ 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_IOREMAP_PROT=y @@ -94,6 +98,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -105,7 +111,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -151,6 +156,7 @@ CONFIG_CPU_SUBTYPE_SH7712=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -160,8 +166,6 @@ CONFIG_CPU_SUBTYPE_SH7712=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -585,6 +589,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -812,6 +817,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -832,6 +838,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -887,6 +898,7 @@ CONFIG_CRAMFS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -927,6 +939,7 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set # CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DETECT_HUNG_TASK is not set CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -961,6 +974,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -969,9 +983,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1090,6 +1109,7 @@ CONFIG_CRYPTO_DEFLATE=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig index 4b79c2567dc8..56478918440d 100644 --- a/arch/sh/configs/se7721_defconfig +++ b/arch/sh/configs/se7721_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:51:44 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:04:19 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -38,6 +39,7 @@ CONFIG_LOCALVERSION="" CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set @@ -73,6 +75,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y # CONFIG_BUG is not set @@ -91,6 +94,7 @@ 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_IOREMAP_PROT=y @@ -98,6 +102,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -109,7 +115,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7721=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -164,8 +170,6 @@ CONFIG_CPU_SUBTYPE_SH7721=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -776,15 +780,17 @@ CONFIG_USB_HID=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_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -943,6 +949,7 @@ CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -963,6 +970,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1021,6 +1033,7 @@ CONFIG_CRAMFS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set # CONFIG_NETWORK_FILESYSTEMS is not set # @@ -1085,6 +1098,7 @@ CONFIG_FRAME_WARN=1024 CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set # CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DETECT_HUNG_TASK is not set CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1119,6 +1133,7 @@ CONFIG_FRAME_POINTER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1127,9 +1142,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1248,6 +1268,7 @@ CONFIG_CRYPTO_DEFLATE=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig index 82bdaac45fb5..726fdbdb2807 100644 --- a/arch/sh/configs/se7722_defconfig +++ b/arch/sh/configs/se7722_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:55:10 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:05:29 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -69,7 +70,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -78,6 +78,7 @@ CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -97,6 +98,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y +# CONFIG_MARKERS is not set # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -105,6 +107,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -117,7 +121,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -167,6 +170,7 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -176,8 +180,6 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_CPU_SUBTYPE_SH7343 is not set CONFIG_CPU_SUBTYPE_SH7722=y # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -486,6 +488,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -692,7 +695,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -766,6 +768,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -788,6 +791,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -832,6 +840,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -872,11 +881,25 @@ CONFIG_DEBUG_FS=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y @@ -977,6 +1000,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig index ceef6d9138ee..ed1a1230f636 100644 --- a/arch/sh/configs/se7750_defconfig +++ b/arch/sh/configs/se7750_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:57:31 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:06:02 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -70,6 +71,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y @@ -88,6 +90,7 @@ 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_IOREMAP_PROT=y @@ -95,6 +98,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -106,7 +111,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -152,6 +156,7 @@ CONFIG_CPU_SUBTYPE_SH7750=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -161,8 +166,6 @@ CONFIG_CPU_SUBTYPE_SH7750=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -553,6 +556,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -774,6 +778,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -829,6 +838,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -886,10 +896,23 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -989,6 +1012,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig index 67fc26b3a7d0..55f3b788e0cb 100644 --- a/arch/sh/configs/se7751_defconfig +++ b/arch/sh/configs/se7751_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 18:59:59 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:06:44 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -65,7 +66,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -74,6 +74,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y @@ -92,6 +93,7 @@ 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_IOREMAP_PROT=y @@ -99,6 +101,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -110,7 +114,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -156,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -165,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7751=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -741,6 +743,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -796,6 +803,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -833,10 +841,23 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -936,6 +957,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig index ebce23cc2ad8..c4f0af32efa9 100644 --- a/arch/sh/configs/se7780_defconfig +++ b/arch/sh/configs/se7780_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:02:05 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:07:14 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -67,6 +68,7 @@ CONFIG_EMBEDDED=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y # CONFIG_KALLSYMS is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y @@ -86,12 +88,15 @@ 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_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -103,7 +108,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_INTEGRITY is not set # @@ -149,6 +153,7 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set CONFIG_CPU_SUBTYPE_SH7780=y @@ -158,8 +163,6 @@ CONFIG_CPU_SUBTYPE_SH7780=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -285,8 +288,6 @@ CONFIG_CMDLINE="console=ttySC0.115200 root=/dev/sda1" # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -558,6 +559,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -957,15 +959,17 @@ CONFIG_USB_HID=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_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -1121,6 +1125,10 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# + # # CD-ROM/DVD Filesystems # @@ -1245,11 +1253,24 @@ CONFIG_DEBUG_FS=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1345,6 +1366,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig index 6fcdb090cf32..f9c6e51dc0b0 100644 --- a/arch/sh/configs/sh03_defconfig +++ b/arch/sh/configs/sh03_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:04:59 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:07:56 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -41,6 +42,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set @@ -67,7 +69,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -76,6 +77,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -105,6 +107,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -117,7 +121,6 @@ CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -163,6 +166,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -172,8 +176,6 @@ CONFIG_CPU_SUBTYPE_SH7751=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -300,8 +302,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 mem=64M root=/dev/nfs" # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -562,6 +562,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -656,6 +657,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -679,6 +681,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -887,7 +890,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -929,6 +931,7 @@ CONFIG_EXT2_FS_XATTR=y # CONFIG_EXT2_FS_SECURITY is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y # CONFIG_EXT3_FS_SECURITY is not set @@ -951,6 +954,11 @@ CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1001,6 +1009,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1112,11 +1121,26 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y @@ -1228,6 +1252,7 @@ CONFIG_CRYPTO_DEFLATE=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig index 1ab37c01da6e..48b58098cf84 100644 --- a/arch/sh/configs/sh7710voipgw_defconfig +++ b/arch/sh/configs/sh7710voipgw_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:09:01 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:09:16 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -39,6 +40,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set @@ -72,6 +74,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -90,6 +93,7 @@ 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_IOREMAP_PROT=y @@ -97,6 +101,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_BASE_SMALL=0 @@ -108,7 +114,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -154,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7710=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -163,8 +169,6 @@ CONFIG_CPU_SUBTYPE_SH7710=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -728,7 +732,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y # CONFIG_USB_ARCH_HAS_OHCI is not set @@ -779,6 +782,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -834,6 +842,7 @@ CONFIG_JFFS2_RTIME=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -871,11 +880,24 @@ CONFIG_DEBUG_FS=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -975,6 +997,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/sh7724_generic_defconfig b/arch/sh/configs/sh7724_generic_defconfig index 268d04ed8cdd..ec8f18c7684c 100644 --- a/arch/sh/configs/sh7724_generic_defconfig +++ b/arch/sh/configs/sh7724_generic_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.30-rc2 -# Thu Apr 16 15:42:20 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:09:47 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig index c79bb84ec305..f77bc7998d2f 100644 --- a/arch/sh/configs/sh7763rdp_defconfig +++ b/arch/sh/configs/sh7763rdp_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:10:57 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:10:12 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -78,6 +79,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -106,6 +108,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -117,7 +121,6 @@ CONFIG_MODULES=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -164,6 +167,7 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set CONFIG_CPU_SUBTYPE_SH7763=y # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -173,8 +177,6 @@ CONFIG_CPU_SUBTYPE_SH7763=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -555,6 +557,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -941,6 +944,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -964,6 +968,11 @@ CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set CONFIG_GENERIC_ACL=y +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1012,6 +1021,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -1100,11 +1110,25 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1204,6 +1228,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig index a6cf4505741c..1c55b800d124 100644 --- a/arch/sh/configs/sh7785lcr_32bit_defconfig +++ b/arch/sh/configs/sh7785lcr_32bit_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:12:18 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:10:53 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -79,6 +80,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -98,6 +100,7 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y +# CONFIG_MARKERS is not set # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -106,6 +109,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -118,7 +123,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -166,6 +170,7 @@ CONFIG_CPU_SHX2=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -175,8 +180,6 @@ CONFIG_CPU_SUBTYPE_SH7785=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -310,8 +313,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -672,6 +673,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -1009,15 +1011,17 @@ CONFIG_USB_HID=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_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -1218,6 +1222,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -1239,6 +1244,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1289,6 +1299,7 @@ CONFIG_MINIX_FS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1377,6 +1388,9 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1413,6 +1427,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1422,9 +1437,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1542,6 +1562,7 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig index e4fac2efc055..4385fe97a780 100644 --- a/arch/sh/configs/sh7785lcr_defconfig +++ b/arch/sh/configs/sh7785lcr_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.30-rc2 -# Wed Apr 22 19:17:56 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:11:48 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y @@ -307,8 +307,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig index d695e9061874..4e120256ec63 100644 --- a/arch/sh/configs/shmin_defconfig +++ b/arch/sh/configs/shmin_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:19:03 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:12:41 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -63,6 +64,7 @@ CONFIG_EMBEDDED=y # CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set # CONFIG_KALLSYMS is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y # CONFIG_BUG is not set @@ -81,12 +83,15 @@ CONFIG_COMPAT_BRK=y # CONFIG_SLUB is not set CONFIG_SLOB=y # CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_BASE_SMALL=1 # CONFIG_MODULES is not set @@ -137,6 +142,7 @@ CONFIG_CPU_SUBTYPE_SH7706=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -146,8 +152,6 @@ CONFIG_CPU_SUBTYPE_SH7706=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -674,6 +678,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -718,6 +727,7 @@ CONFIG_CRAMFS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -762,10 +772,22 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_SH_STANDARD_BIOS=y @@ -864,6 +886,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index e3651f574399..c088144925fa 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:20:54 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:13:12 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -42,6 +43,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set @@ -96,6 +98,7 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -126,6 +129,8 @@ CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_USE_GENERIC_SMP_HELPERS=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 @@ -138,7 +143,6 @@ CONFIG_MODULE_UNLOAD=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -186,6 +190,7 @@ CONFIG_CPU_SHX3=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -195,8 +200,6 @@ CONFIG_CPU_SUBTYPE_SHX3=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -553,6 +556,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -646,6 +650,7 @@ CONFIG_DEVKMEM=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MAX3100 is not set CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=2 CONFIG_SERIAL_SH_SCI_CONSOLE=y @@ -985,6 +990,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -1007,6 +1013,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1051,6 +1062,7 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -1085,6 +1097,9 @@ CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1124,6 +1139,7 @@ CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_RING_BUFFER=y CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1133,11 +1149,16 @@ CONFIG_TRACING=y # CONFIG_PREEMPT_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1245,6 +1266,7 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y # # Library routines diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig index 6960f60bf52e..54a7a3c41f34 100644 --- a/arch/sh/configs/snapgear_defconfig +++ b/arch/sh/configs/snapgear_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:21:39 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:14:00 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -64,7 +65,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -73,6 +73,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y @@ -92,12 +93,15 @@ 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_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -105,7 +109,6 @@ CONFIG_BASE_SMALL=0 # CONFIG_MODULES is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -151,6 +154,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -160,8 +164,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -295,8 +297,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -762,6 +762,11 @@ CONFIG_FILE_LOCKING=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -805,8 +810,13 @@ CONFIG_CRAMFS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set @@ -844,10 +854,23 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -862,6 +885,7 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig index 7ea639bc5936..dbe7e546f0bb 100644 --- a/arch/sh/configs/systemh_defconfig +++ b/arch/sh/configs/systemh_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:23:31 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:14:33 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -61,7 +62,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -70,6 +70,7 @@ CONFIG_UID16=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y @@ -88,6 +89,7 @@ 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_IOREMAP_PROT=y @@ -95,6 +97,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -107,7 +111,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -153,6 +156,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -162,8 +166,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -505,6 +507,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -547,8 +554,13 @@ CONFIG_CRAMFS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set # # Partition Types @@ -577,10 +589,24 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -595,6 +621,7 @@ CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig index bbeb4c6ebb95..8ca94ef74278 100644 --- a/arch/sh/configs/titan_defconfig +++ b/arch/sh/configs/titan_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:24:55 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:14:55 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -40,6 +41,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set @@ -66,7 +68,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -76,6 +77,7 @@ CONFIG_UID16=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -95,6 +97,7 @@ 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_IOREMAP_PROT=y @@ -102,6 +105,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -114,7 +119,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -160,6 +164,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -169,8 +174,6 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -305,8 +308,6 @@ CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw" # CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # CONFIG_PCIEPORTBUS is not set # CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_PCI_LEGACY=y @@ -789,6 +790,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -906,6 +908,7 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set +# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -929,6 +932,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_IXGBE is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set +# CONFIG_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -1182,7 +1186,6 @@ CONFIG_HID=y # # Special HID drivers # -CONFIG_HID_COMPAT=y CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -1393,6 +1396,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set # CONFIG_EXT4_FS is not set CONFIG_JBD=y @@ -1418,6 +1422,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1467,8 +1476,13 @@ CONFIG_MISC_FILESYSTEMS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set CONFIG_ROMFS_FS=y +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1576,6 +1590,7 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set # CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_DETECT_HUNG_TASK is not set CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set @@ -1610,6 +1625,7 @@ CONFIG_SCHED_DEBUG=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers @@ -1618,9 +1634,14 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set # CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -1741,6 +1762,7 @@ CONFIG_CRYPTO_DEFLATE=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig index 34f5192a3241..bfb4d9806892 100644 --- a/arch/sh/configs/ul2_defconfig +++ b/arch/sh/configs/ul2_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:30:27 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 13:17:05 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -69,7 +70,6 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y # CONFIG_RD_BZIP2 is not set # CONFIG_RD_LZMA is not set -CONFIG_INITRAMFS_COMPRESSION_NONE=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_ANON_INODES=y @@ -78,6 +78,7 @@ CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -97,6 +98,7 @@ CONFIG_COMPAT_BRK=y CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y +# CONFIG_MARKERS is not set # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -105,6 +107,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -117,7 +121,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -167,6 +170,7 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -176,8 +180,6 @@ CONFIG_ARCH_SHMOBILE=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set CONFIG_CPU_SUBTYPE_SH7366=y -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -584,6 +586,7 @@ CONFIG_SCSI_WAIT_SCAN=m CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set @@ -936,6 +939,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -957,6 +961,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1005,6 +1014,7 @@ CONFIG_CRAMFS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set @@ -1095,10 +1105,24 @@ CONFIG_FRAME_WARN=1024 CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1208,6 +1232,7 @@ CONFIG_CRYPTO_ARC4=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y +# CONFIG_BINARY_PRINTF is not set # # Library routines diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index d174b1a4d802..512664fed66c 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig @@ -1,10 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.29 -# Thu Apr 2 19:33:39 2009 +# Linux kernel version: 2.6.30-rc3 +# Mon Apr 27 14:02:55 2009 # CONFIG_SUPERH=y CONFIG_SUPERH32=y +# CONFIG_SUPERH64 is not set CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig" CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y @@ -76,6 +77,7 @@ CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y @@ -94,6 +96,7 @@ CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y +# CONFIG_MARKERS is not set # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set @@ -102,6 +105,8 @@ CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +# CONFIG_SLOW_WORK is not set CONFIG_HAVE_GENERIC_DMA_COHERENT=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -114,7 +119,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_INTEGRITY is not set @@ -162,6 +166,7 @@ CONFIG_CPU_SHX3=y # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set # CONFIG_CPU_SUBTYPE_SH7723 is not set +# CONFIG_CPU_SUBTYPE_SH7724 is not set # CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set @@ -171,8 +176,6 @@ CONFIG_CPU_SUBTYPE_SH7786=y # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set # CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -900,15 +903,17 @@ CONFIG_USB_HID=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_DRAGONRISE_FF is not set CONFIG_HID_EZKEY=y +# CONFIG_HID_KYE is not set CONFIG_HID_GYRATION=y +# CONFIG_HID_KENSINGTON is not set CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set @@ -1046,6 +1051,7 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y +# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set @@ -1067,6 +1073,11 @@ CONFIG_INOTIFY_USER=y # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set +# +# Caches +# +# CONFIG_FSCACHE is not set + # # CD-ROM/DVD Filesystems # @@ -1117,6 +1128,7 @@ CONFIG_MINIX_FS=y # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set +# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1209,10 +1221,24 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_TRACING_SUPPORT=y # # Tracers # +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_EVENT_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_DMA_API_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_SH_STANDARD_BIOS is not set @@ -1322,6 +1348,7 @@ CONFIG_CRYPTO_DES=y # # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +# CONFIG_BINARY_PRINTF is not set # # Library routines -- GitLab From 5be7c0a4d3dfe25091f2e4e524103e81d9e7e180 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 27 Apr 2009 14:40:47 +0900 Subject: [PATCH 0709/6080] sh: select GENERIC_TIME for new CMT driver. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 4c68fdedfa10..164748945f95 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -476,10 +476,11 @@ config SH_TIMER_CMT bool "CMT clockevents driver" depends on SYS_SUPPORTS_CMT && !SH_CMT select GENERIC_CLOCKEVENTS + select GENERIC_TIME config SH_MTU2 bool "MTU2 timer support" - depends on CPU_SH2A + depends on CPU_SH2A && !GENERIC_TIME default y help This enables the use of the MTU2 as the system timer. -- GitLab From 148be2c15d4a866fbc7a8f55342e4fd4de73be61 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 27 Apr 2009 08:02:14 +0200 Subject: [PATCH 0710/6080] perf_counter tools: move helper library to util/* Clean up the top level directory a bit by moving all the helper libraries to util/*.[ch]. Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 60 ++++++++++--------- Documentation/perf_counter/builtin-help.c | 10 ++-- Documentation/perf_counter/builtin-stat.c | 2 +- Documentation/perf_counter/builtin-top.c | 2 +- Documentation/perf_counter/builtin.h | 4 +- Documentation/perf_counter/perf.c | 8 +-- .../perf_counter/{ => util}/PERF-VERSION-GEN | 0 .../perf_counter/{ => util}/abspath.c | 0 Documentation/perf_counter/{ => util}/alias.c | 0 Documentation/perf_counter/{ => util}/cache.h | 0 .../perf_counter/{ => util}/config.c | 0 Documentation/perf_counter/{ => util}/ctype.c | 0 .../perf_counter/{ => util}/exec_cmd.c | 0 .../perf_counter/{ => util}/exec_cmd.h | 0 .../{ => util}/generate-cmdlist.sh | 0 Documentation/perf_counter/{ => util}/help.c | 2 +- Documentation/perf_counter/{ => util}/help.h | 0 .../perf_counter/{ => util}/levenshtein.c | 0 .../perf_counter/{ => util}/levenshtein.h | 0 .../perf_counter/{ => util}/parse-options.c | 3 - .../perf_counter/{ => util}/parse-options.h | 0 Documentation/perf_counter/{ => util}/path.c | 0 Documentation/perf_counter/{ => util}/quote.c | 0 Documentation/perf_counter/{ => util}/quote.h | 2 +- .../perf_counter/{ => util}/run-command.c | 0 .../perf_counter/{ => util}/run-command.h | 0 .../perf_counter/{ => util}/strbuf.c | 0 .../perf_counter/{ => util}/strbuf.h | 0 Documentation/perf_counter/{ => util}/usage.c | 0 Documentation/perf_counter/{ => util}/util.h | 0 .../perf_counter/{ => util}/wrapper.c | 0 31 files changed, 46 insertions(+), 47 deletions(-) rename Documentation/perf_counter/{ => util}/PERF-VERSION-GEN (100%) rename Documentation/perf_counter/{ => util}/abspath.c (100%) rename Documentation/perf_counter/{ => util}/alias.c (100%) rename Documentation/perf_counter/{ => util}/cache.h (100%) rename Documentation/perf_counter/{ => util}/config.c (100%) rename Documentation/perf_counter/{ => util}/ctype.c (100%) rename Documentation/perf_counter/{ => util}/exec_cmd.c (100%) rename Documentation/perf_counter/{ => util}/exec_cmd.h (100%) rename Documentation/perf_counter/{ => util}/generate-cmdlist.sh (100%) rename Documentation/perf_counter/{ => util}/help.c (99%) rename Documentation/perf_counter/{ => util}/help.h (100%) rename Documentation/perf_counter/{ => util}/levenshtein.c (100%) rename Documentation/perf_counter/{ => util}/levenshtein.h (100%) rename Documentation/perf_counter/{ => util}/parse-options.c (99%) rename Documentation/perf_counter/{ => util}/parse-options.h (100%) rename Documentation/perf_counter/{ => util}/path.c (100%) rename Documentation/perf_counter/{ => util}/quote.c (100%) rename Documentation/perf_counter/{ => util}/quote.h (97%) rename Documentation/perf_counter/{ => util}/run-command.c (100%) rename Documentation/perf_counter/{ => util}/run-command.h (100%) rename Documentation/perf_counter/{ => util}/strbuf.c (100%) rename Documentation/perf_counter/{ => util}/strbuf.h (100%) rename Documentation/perf_counter/{ => util}/usage.c (100%) rename Documentation/perf_counter/{ => util}/util.h (100%) rename Documentation/perf_counter/{ => util}/wrapper.c (100%) diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index 690045e49692..543ccf28ac4a 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -147,7 +147,7 @@ all:: # broken, or spawning external process is slower than built-in grep perf has). PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE - @$(SHELL_PATH) ./PERF-VERSION-GEN + @$(SHELL_PATH) util/PERF-VERSION-GEN -include PERF-VERSION-FILE uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') @@ -287,26 +287,28 @@ export PERL_PATH LIB_FILE=libperf.a LIB_H += ../../include/linux/perf_counter.h -LIB_H += levenshtein.h -LIB_H += parse-options.h -LIB_H += quote.h -LIB_H += strbuf.h -LIB_H += run-command.h - -LIB_OBJS += abspath.o -LIB_OBJS += alias.o -LIB_OBJS += config.o -LIB_OBJS += ctype.o -LIB_OBJS += exec_cmd.o -LIB_OBJS += help.o -LIB_OBJS += levenshtein.o -LIB_OBJS += parse-options.o -LIB_OBJS += path.o -LIB_OBJS += run-command.o -LIB_OBJS += quote.o -LIB_OBJS += strbuf.o -LIB_OBJS += usage.o -LIB_OBJS += wrapper.o +LIB_H += util/levenshtein.h +LIB_H += util/parse-options.h +LIB_H += util/quote.h +LIB_H += util/util.h +LIB_H += util/help.h +LIB_H += util/strbuf.h +LIB_H += util/run-command.h + +LIB_OBJS += util/abspath.o +LIB_OBJS += util/alias.o +LIB_OBJS += util/config.o +LIB_OBJS += util/ctype.o +LIB_OBJS += util/exec_cmd.o +LIB_OBJS += util/help.o +LIB_OBJS += util/levenshtein.o +LIB_OBJS += util/parse-options.o +LIB_OBJS += util/path.o +LIB_OBJS += util/run-command.o +LIB_OBJS += util/quote.o +LIB_OBJS += util/strbuf.o +LIB_OBJS += util/usage.o +LIB_OBJS += util/wrapper.o BUILTIN_OBJS += builtin-help.o BUILTIN_OBJS += builtin-record.o @@ -620,10 +622,10 @@ $(BUILT_INS): perf$X ln -s perf$X $@ 2>/dev/null || \ cp perf$X $@ -common-cmds.h: ./generate-cmdlist.sh command-list.txt +common-cmds.h: util/generate-cmdlist.sh command-list.txt common-cmds.h: $(wildcard Documentation/perf-*.txt) - $(QUIET_GEN)./generate-cmdlist.sh > $@+ && mv $@+ $@ + $(QUIET_GEN)util/generate-cmdlist.sh > $@+ && mv $@+ $@ $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh $(QUIET_GEN)$(RM) $@ $@+ && \ @@ -656,7 +658,7 @@ perf.o perf.spec \ %.o: %.S $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< -exec_cmd.o: exec_cmd.c PERF-CFLAGS +util/exec_cmd.o: util/exec_cmd.c PERF-CFLAGS $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \ '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \ '-DBINDIR="$(bindir_relative_SQ)"' \ @@ -666,7 +668,7 @@ exec_cmd.o: exec_cmd.c PERF-CFLAGS builtin-init-db.o: builtin-init-db.c PERF-CFLAGS $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_PERF_TEMPLATE_DIR='"$(template_dir_SQ)"' $< -config.o: config.c PERF-CFLAGS +util/config.o: util/config.c PERF-CFLAGS $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< perf-%$X: %.o $(PERFLIBS) @@ -729,7 +731,7 @@ export NO_SVN_TESTS check: common-cmds.h if sparse; \ then \ - for i in *.c; \ + for i in *.c */*.c; \ do \ sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \ done; \ @@ -795,7 +797,7 @@ distclean: clean $(RM) configure clean: - $(RM) *.o $(LIB_FILE) + $(RM) *.o */*.o $(LIB_FILE) $(RM) $(ALL_PROGRAMS) $(BUILT_INS) perf$X $(RM) $(TEST_PROGRAMS) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags cscope* @@ -836,7 +838,7 @@ coverage-build: coverage-clean -j1 test coverage-report: - gcov -b *.c - grep '^function.*called 0 ' *.c.gcov \ + gcov -b *.c */*.c + grep '^function.*called 0 ' *.c.gcov */*.c.gcov \ | sed -e 's/\([^:]*\)\.gcov: *function \([^ ]*\) called.*/\1: \2/' \ | tee coverage-untested-functions diff --git a/Documentation/perf_counter/builtin-help.c b/Documentation/perf_counter/builtin-help.c index a136d619db37..6616de0ef053 100644 --- a/Documentation/perf_counter/builtin-help.c +++ b/Documentation/perf_counter/builtin-help.c @@ -3,13 +3,13 @@ * * Builtin help command */ -#include "cache.h" +#include "util/cache.h" #include "builtin.h" -#include "exec_cmd.h" +#include "util/exec_cmd.h" #include "common-cmds.h" -#include "parse-options.h" -#include "run-command.h" -#include "help.h" +#include "util/parse-options.h" +#include "util/run-command.h" +#include "util/help.h" static struct man_viewer_list { struct man_viewer_list *next; diff --git a/Documentation/perf_counter/builtin-stat.c b/Documentation/perf_counter/builtin-stat.c index 169a2d1783fc..d7ace631fc4f 100644 --- a/Documentation/perf_counter/builtin-stat.c +++ b/Documentation/perf_counter/builtin-stat.c @@ -61,7 +61,7 @@ * Released under the GPL v2. (and only v2, not any later version) */ -#include "util.h" +#include "util/util.h" #include #include diff --git a/Documentation/perf_counter/builtin-top.c b/Documentation/perf_counter/builtin-top.c index 98e8690b6bcb..dea016fa41e8 100644 --- a/Documentation/perf_counter/builtin-top.c +++ b/Documentation/perf_counter/builtin-top.c @@ -42,7 +42,7 @@ * Released under the GPL v2. (and only v2, not any later version) */ -#include "util.h" +#include "util/util.h" #include #include diff --git a/Documentation/perf_counter/builtin.h b/Documentation/perf_counter/builtin.h index 800f86c1d445..d32318aed8cf 100644 --- a/Documentation/perf_counter/builtin.h +++ b/Documentation/perf_counter/builtin.h @@ -1,8 +1,8 @@ #ifndef BUILTIN_H #define BUILTIN_H -#include "util.h" -#include "strbuf.h" +#include "util/util.h" +#include "util/strbuf.h" extern const char perf_version_string[]; extern const char perf_usage_string[]; diff --git a/Documentation/perf_counter/perf.c b/Documentation/perf_counter/perf.c index 8d6faecdc15d..594d270be390 100644 --- a/Documentation/perf_counter/perf.c +++ b/Documentation/perf_counter/perf.c @@ -1,8 +1,8 @@ #include "builtin.h" -#include "exec_cmd.h" -#include "cache.h" -#include "quote.h" -#include "run-command.h" +#include "util/exec_cmd.h" +#include "util/cache.h" +#include "util/quote.h" +#include "util/run-command.h" const char perf_usage_string[] = "perf [--version] [--help] COMMAND [ARGS]"; diff --git a/Documentation/perf_counter/PERF-VERSION-GEN b/Documentation/perf_counter/util/PERF-VERSION-GEN similarity index 100% rename from Documentation/perf_counter/PERF-VERSION-GEN rename to Documentation/perf_counter/util/PERF-VERSION-GEN diff --git a/Documentation/perf_counter/abspath.c b/Documentation/perf_counter/util/abspath.c similarity index 100% rename from Documentation/perf_counter/abspath.c rename to Documentation/perf_counter/util/abspath.c diff --git a/Documentation/perf_counter/alias.c b/Documentation/perf_counter/util/alias.c similarity index 100% rename from Documentation/perf_counter/alias.c rename to Documentation/perf_counter/util/alias.c diff --git a/Documentation/perf_counter/cache.h b/Documentation/perf_counter/util/cache.h similarity index 100% rename from Documentation/perf_counter/cache.h rename to Documentation/perf_counter/util/cache.h diff --git a/Documentation/perf_counter/config.c b/Documentation/perf_counter/util/config.c similarity index 100% rename from Documentation/perf_counter/config.c rename to Documentation/perf_counter/util/config.c diff --git a/Documentation/perf_counter/ctype.c b/Documentation/perf_counter/util/ctype.c similarity index 100% rename from Documentation/perf_counter/ctype.c rename to Documentation/perf_counter/util/ctype.c diff --git a/Documentation/perf_counter/exec_cmd.c b/Documentation/perf_counter/util/exec_cmd.c similarity index 100% rename from Documentation/perf_counter/exec_cmd.c rename to Documentation/perf_counter/util/exec_cmd.c diff --git a/Documentation/perf_counter/exec_cmd.h b/Documentation/perf_counter/util/exec_cmd.h similarity index 100% rename from Documentation/perf_counter/exec_cmd.h rename to Documentation/perf_counter/util/exec_cmd.h diff --git a/Documentation/perf_counter/generate-cmdlist.sh b/Documentation/perf_counter/util/generate-cmdlist.sh similarity index 100% rename from Documentation/perf_counter/generate-cmdlist.sh rename to Documentation/perf_counter/util/generate-cmdlist.sh diff --git a/Documentation/perf_counter/help.c b/Documentation/perf_counter/util/help.c similarity index 99% rename from Documentation/perf_counter/help.c rename to Documentation/perf_counter/util/help.c index ec0116721660..edde541d238d 100644 --- a/Documentation/perf_counter/help.c +++ b/Documentation/perf_counter/util/help.c @@ -1,5 +1,5 @@ #include "cache.h" -#include "builtin.h" +#include "../builtin.h" #include "exec_cmd.h" #include "levenshtein.h" #include "help.h" diff --git a/Documentation/perf_counter/help.h b/Documentation/perf_counter/util/help.h similarity index 100% rename from Documentation/perf_counter/help.h rename to Documentation/perf_counter/util/help.h diff --git a/Documentation/perf_counter/levenshtein.c b/Documentation/perf_counter/util/levenshtein.c similarity index 100% rename from Documentation/perf_counter/levenshtein.c rename to Documentation/perf_counter/util/levenshtein.c diff --git a/Documentation/perf_counter/levenshtein.h b/Documentation/perf_counter/util/levenshtein.h similarity index 100% rename from Documentation/perf_counter/levenshtein.h rename to Documentation/perf_counter/util/levenshtein.h diff --git a/Documentation/perf_counter/parse-options.c b/Documentation/perf_counter/util/parse-options.c similarity index 99% rename from Documentation/perf_counter/parse-options.c rename to Documentation/perf_counter/util/parse-options.c index 7464f34e5407..28b34c1c29cf 100644 --- a/Documentation/perf_counter/parse-options.c +++ b/Documentation/perf_counter/util/parse-options.c @@ -469,9 +469,6 @@ int parse_options_usage(const char * const *usagestr, } -/*----- some often used options -----*/ -#include "cache.h" - int parse_opt_verbosity_cb(const struct option *opt, const char *arg, int unset) { diff --git a/Documentation/perf_counter/parse-options.h b/Documentation/perf_counter/util/parse-options.h similarity index 100% rename from Documentation/perf_counter/parse-options.h rename to Documentation/perf_counter/util/parse-options.h diff --git a/Documentation/perf_counter/path.c b/Documentation/perf_counter/util/path.c similarity index 100% rename from Documentation/perf_counter/path.c rename to Documentation/perf_counter/util/path.c diff --git a/Documentation/perf_counter/quote.c b/Documentation/perf_counter/util/quote.c similarity index 100% rename from Documentation/perf_counter/quote.c rename to Documentation/perf_counter/util/quote.c diff --git a/Documentation/perf_counter/quote.h b/Documentation/perf_counter/util/quote.h similarity index 97% rename from Documentation/perf_counter/quote.h rename to Documentation/perf_counter/util/quote.h index 66730f2bff3c..5dfad89816db 100644 --- a/Documentation/perf_counter/quote.h +++ b/Documentation/perf_counter/util/quote.h @@ -18,7 +18,7 @@ * run the command on the other side: * * sprintf(cmd, "git-diff-tree %s %s", sq_quote(arg0), sq_quote(arg1)); - * sprintf(rcmd, "ssh %s %s", sq_quote(host), sq_quote(cmd)); + * sprintf(rcmd, "ssh %s %s", sq_util/quote.host), sq_quote(cmd)); * * Note that the above examples leak memory! Remember to free result from * sq_quote() in a real application. diff --git a/Documentation/perf_counter/run-command.c b/Documentation/perf_counter/util/run-command.c similarity index 100% rename from Documentation/perf_counter/run-command.c rename to Documentation/perf_counter/util/run-command.c diff --git a/Documentation/perf_counter/run-command.h b/Documentation/perf_counter/util/run-command.h similarity index 100% rename from Documentation/perf_counter/run-command.h rename to Documentation/perf_counter/util/run-command.h diff --git a/Documentation/perf_counter/strbuf.c b/Documentation/perf_counter/util/strbuf.c similarity index 100% rename from Documentation/perf_counter/strbuf.c rename to Documentation/perf_counter/util/strbuf.c diff --git a/Documentation/perf_counter/strbuf.h b/Documentation/perf_counter/util/strbuf.h similarity index 100% rename from Documentation/perf_counter/strbuf.h rename to Documentation/perf_counter/util/strbuf.h diff --git a/Documentation/perf_counter/usage.c b/Documentation/perf_counter/util/usage.c similarity index 100% rename from Documentation/perf_counter/usage.c rename to Documentation/perf_counter/util/usage.c diff --git a/Documentation/perf_counter/util.h b/Documentation/perf_counter/util/util.h similarity index 100% rename from Documentation/perf_counter/util.h rename to Documentation/perf_counter/util/util.h diff --git a/Documentation/perf_counter/wrapper.c b/Documentation/perf_counter/util/wrapper.c similarity index 100% rename from Documentation/perf_counter/wrapper.c rename to Documentation/perf_counter/util/wrapper.c -- GitLab From 47c8a08bbe77ad3c06f63919a14b0f0b0cd54390 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 27 Apr 2009 17:34:39 +0900 Subject: [PATCH 0711/6080] sh: rtc-generic support. This adds rtc-generic support for SUPERH32. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 1 + arch/sh/include/asm/rtc.h | 11 +++++++++++ arch/sh/kernel/time_32.c | 23 +++++++++++++++++++++++ drivers/rtc/Kconfig | 2 +- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 164748945f95..9db02ced57a5 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -30,6 +30,7 @@ config SUPERH32 select HAVE_DYNAMIC_FTRACE select HAVE_ARCH_KGDB select ARCH_HIBERNATION_POSSIBLE if MMU + select RTC_LIB config SUPERH64 def_bool ARCH = "sh64" diff --git a/arch/sh/include/asm/rtc.h b/arch/sh/include/asm/rtc.h index f7b010d48af7..52b0c2dba979 100644 --- a/arch/sh/include/asm/rtc.h +++ b/arch/sh/include/asm/rtc.h @@ -6,6 +6,17 @@ extern void (*board_time_init)(void); extern void (*rtc_sh_get_time)(struct timespec *); extern int (*rtc_sh_set_time)(const time_t); +/* 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 */ + +struct rtc_time; +unsigned int get_rtc_time(struct rtc_time *); +int set_rtc_time(struct rtc_time *); + #define RTC_CAP_4_DIGIT_YEAR (1 << 0) struct sh_rtc_platform_info { diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c index c770413c3213..109409f5ca53 100644 --- a/arch/sh/kernel/time_32.c +++ b/arch/sh/kernel/time_32.c @@ -19,6 +19,7 @@ #include /* for rtc_lock */ #include #include +#include #include #include #include @@ -45,6 +46,28 @@ static int null_rtc_set_time(const time_t secs) void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; +unsigned int get_rtc_time(struct rtc_time *tm) +{ + if (rtc_sh_get_time != null_rtc_get_time) { + struct timespec tv; + + rtc_sh_get_time(&tv); + rtc_time_to_tm(tv.tv_sec, tm); + } + + return RTC_24H; +} +EXPORT_SYMBOL(get_rtc_time); + +int set_rtc_time(struct rtc_time *tm) +{ + unsigned long secs; + + rtc_tm_to_time(tm, &secs); + return rtc_sh_set_time(secs); +} +EXPORT_SYMBOL(set_rtc_time); + #ifndef CONFIG_GENERIC_TIME void do_gettimeofday(struct timeval *tv) { diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 4e9851fc1746..277d35d232fa 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -692,7 +692,7 @@ config RTC_DRV_GENERIC tristate "Generic RTC support" # Please consider writing a new RTC driver instead of using the generic # RTC abstraction - depends on PARISC || M68K || PPC + depends on PARISC || M68K || PPC || SUPERH32 help Say Y or M here to enable RTC support on systems using the generic RTC abstraction. If you do not know what you are doing, you should -- GitLab From c2e0090c668fc99f5be65fd9907da781cb6a2ef5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 27 Apr 2009 17:54:41 +0900 Subject: [PATCH 0712/6080] sh: mach-r2d: add physmap-flash support for R2D+ boards. The RTS7751R2D_1 boards only support 1MB of socket-mounted MBM29F040 flash, which we just leave alone as it's not terribly interesting. This adds support for the s29gl256p on the r2d+ boards that makes a bit more sense to expose to the user. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Paul Mundt --- arch/sh/boards/mach-r2d/setup.c | 50 ++++++++++++++ arch/sh/configs/rts7751r2dplus_defconfig | 87 +++++++++++++++++++++++- 2 files changed, 136 insertions(+), 1 deletion(-) diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c index c585be00956e..a625ecb93e47 100644 --- a/arch/sh/boards/mach-r2d/setup.c +++ b/arch/sh/boards/mach-r2d/setup.c @@ -10,6 +10,9 @@ */ #include #include +#include +#include +#include #include #include #include @@ -181,6 +184,50 @@ static struct platform_device sm501_device = { .resource = sm501_resources, }; +static struct mtd_partition r2d_partitions[] = { + { + .name = "U-Boot", + .offset = 0x00000000, + .size = 0x00040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "Environment", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x00040000, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "Kernel", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x001c0000, + }, { + .name = "Flash_FS", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct physmap_flash_data flash_data = { + .width = 2, + .nr_parts = ARRAY_SIZE(r2d_partitions), + .parts = r2d_partitions, +}; + +static struct resource flash_resource = { + .start = 0x00000000, + .end = 0x02000000, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device flash_device = { + .name = "physmap-flash", + .id = -1, + .resource = &flash_resource, + .num_resources = 1, + .dev = { + .platform_data = &flash_data, + }, +}; + static struct platform_device *rts7751r2d_devices[] __initdata = { &sm501_device, &heartbeat_device, @@ -203,6 +250,9 @@ static int __init rts7751r2d_devices_setup(void) if (register_trapped_io(&cf_trapped_io) == 0) platform_device_register(&cf_ide_device); + if (mach_is_r2d_plus()) + platform_device_register(&flash_device); + spi_register_board_info(spi_bus, ARRAY_SIZE(spi_bus)); return platform_add_devices(rts7751r2d_devices, diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig index 2bc1c97d346a..a860435b8847 100644 --- a/arch/sh/configs/rts7751r2dplus_defconfig +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -424,7 +424,92 @@ CONFIG_FIRMWARE_IN_KERNEL=y CONFIG_EXTRA_FIRMWARE="" # CONFIG_SYS_HYPERVISOR is not set # CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLKDEVS is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_CPQ_CISS_DA is not set -- GitLab From 788c9700e7855f8a8cc8875e30d2518b57385c20 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 26 Apr 2009 14:21:59 +0100 Subject: [PATCH 0713/6080] [ARM] Kconfig: sort ARM machine class support choice list by option name Signed-off-by: Russell King --- arch/arm/Kconfig | 136 +++++++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e02b893fb909..a930e5c5672c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -253,6 +253,14 @@ config ARCH_CLPS711X help Support for Cirrus Logic 711x/721x based boards. +config ARCH_GEMINI + bool "Cortina Systems Gemini" + select CPU_FA526 + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB + help + Support for the Cortina Systems Gemini family SoCs + config ARCH_EBSA110 bool "EBSA-110" select CPU_SA110 @@ -276,14 +284,6 @@ config ARCH_EP93XX help This enables support for the Cirrus EP93xx series of CPUs. -config ARCH_GEMINI - bool "Cortina Systems Gemini" - select CPU_FA526 - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Support for the Cortina Systems Gemini family SoCs - config ARCH_FOOTBRIDGE bool "FootBridge" select CPU_SA110 @@ -292,6 +292,16 @@ config ARCH_FOOTBRIDGE Support for systems based on the DC21285 companion chip ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder. +config ARCH_MXC + bool "Freescale MXC/iMX-based" + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select ARCH_MTD_XIP + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB + help + Support for Freescale MXC/iMX-based family of processors + config ARCH_NETX bool "Hilscher NetX based" select CPU_ARM926T @@ -404,28 +414,6 @@ config ARCH_KIRKWOOD Support for the following Marvell Kirkwood series SoCs: 88F6180, 88F6192 and 88F6281. -config ARCH_KS8695 - bool "Micrel/Kendin KS8695" - select CPU_ARM922T - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based - System-on-Chip devices. - -config ARCH_NS9XXX - bool "NetSilicon NS9xxx" - select CPU_ARM926T - select GENERIC_GPIO - select GENERIC_TIME - select GENERIC_CLOCKEVENTS - select HAVE_CLK - help - Say Y here if you intend to run this kernel on a NetSilicon NS9xxx - System. - - - config ARCH_LOKI bool "Marvell Loki (88RC8480)" select CPU_FEROCEON @@ -447,16 +435,6 @@ config ARCH_MV78XX0 Support for the following Marvell MV78xx0 series SoCs: MV781x0, MV782x0. -config ARCH_MXC - bool "Freescale MXC/iMX-based" - select GENERIC_TIME - select GENERIC_CLOCKEVENTS - select ARCH_MTD_XIP - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - help - Support for Freescale MXC/iMX-based family of processors - config ARCH_ORION5X bool "Marvell Orion" depends on MMU @@ -471,6 +449,49 @@ config ARCH_ORION5X Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182), Orion-2 (5281), Orion-1-90 (6183). +config ARCH_MMP + bool "Marvell PXA168/910" + depends on MMU + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB + select HAVE_CLK + select COMMON_CLKDEV + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select TICK_ONESHOT + select PLAT_PXA + help + Support for Marvell's PXA168/910 processor line. + +config ARCH_KS8695 + bool "Micrel/Kendin KS8695" + select CPU_ARM922T + select GENERIC_GPIO + select ARCH_REQUIRE_GPIOLIB + help + Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based + System-on-Chip devices. + +config ARCH_NS9XXX + bool "NetSilicon NS9xxx" + select CPU_ARM926T + select GENERIC_GPIO + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select HAVE_CLK + help + Say Y here if you intend to run this kernel on a NetSilicon NS9xxx + System. + + + +config ARCH_W90X900 + bool "Nuvoton W90X900 CPU" + select CPU_ARM926T + help + Support for Nuvoton (Winbond logic dept.) ARM9 processor,You + can login www.mcuos.com or www.nuvoton.com to know more. + config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" select CPU_ARM926T @@ -495,19 +516,16 @@ config ARCH_PXA help Support for Intel/Marvell's PXA2xx/PXA3xx processor line. -config ARCH_MMP - bool "Marvell PXA168/910" - depends on MMU - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB - select HAVE_CLK - select COMMON_CLKDEV +config ARCH_MSM + bool "Qualcomm MSM" + select CPU_V6 select GENERIC_TIME select GENERIC_CLOCKEVENTS - select TICK_ONESHOT - select PLAT_PXA help - Support for Marvell's PXA168/910 processor line. + Support for Qualcomm MSM7K based systems. This runs on the ARM11 + apps processor of the MSM7K and depends on a shared memory + interface to the ARM9 modem processor which runs the baseband stack + and controls some vital subsystems (clock and power control, etc). config ARCH_RPC bool "RiscPC" @@ -598,24 +616,6 @@ config ARCH_OMAP help Support for TI's OMAP platform (OMAP1 and OMAP2). -config ARCH_MSM - bool "Qualcomm MSM" - select CPU_V6 - select GENERIC_TIME - select GENERIC_CLOCKEVENTS - help - Support for Qualcomm MSM7K based systems. This runs on the ARM11 - apps processor of the MSM7K and depends on a shared memory - interface to the ARM9 modem processor which runs the baseband stack - and controls some vital subsystems (clock and power control, etc). - -config ARCH_W90X900 - bool "Nuvoton W90X900 CPU" - select CPU_ARM926T - help - Support for Nuvoton (Winbond logic dept.) ARM9 processor,You - can login www.mcuos.com or www.nuvoton.com to know more. - endchoice source "arch/arm/mach-clps711x/Kconfig" -- GitLab From 9bef5de1e0f8915547124082e5c27c63cfa5c2fd Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Wed, 22 Apr 2009 23:51:15 +0100 Subject: [PATCH 0714/6080] [ARM] 5461/1: Freescale STMP platform support Header files for STMP37xx boards Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- .../mach-stmp37xx/include/mach/entry-macro.S | 37 +++++ arch/arm/mach-stmp37xx/include/mach/irqs.h | 99 ++++++++++++ arch/arm/mach-stmp37xx/include/mach/pins.h | 147 ++++++++++++++++++ 3 files changed, 283 insertions(+) create mode 100644 arch/arm/mach-stmp37xx/include/mach/entry-macro.S create mode 100644 arch/arm/mach-stmp37xx/include/mach/irqs.h create mode 100644 arch/arm/mach-stmp37xx/include/mach/pins.h diff --git a/arch/arm/mach-stmp37xx/include/mach/entry-macro.S b/arch/arm/mach-stmp37xx/include/mach/entry-macro.S new file mode 100644 index 000000000000..fed2787b6c34 --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/entry-macro.S @@ -0,0 +1,37 @@ +/* + * Low-level IRQ helper macros for Freescale STMP37XX + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + mov \base, #0xf0000000 @ vm address of IRQ controller + ldr \irqnr, [\base, #0x30] @ HW_ICOLL_STAT + cmp \irqnr, #0x3f + movne \irqstat, #0 @ Ack this IRQ + strne \irqstat, [\base, #0x00]@ HW_ICOLL_VECTOR + moveqs \irqnr, #0 @ Zero flag set for no IRQ + + .endm + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm diff --git a/arch/arm/mach-stmp37xx/include/mach/irqs.h b/arch/arm/mach-stmp37xx/include/mach/irqs.h new file mode 100644 index 000000000000..98f12938550d --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/irqs.h @@ -0,0 +1,99 @@ +/* + * Freescale STMP37XX interrupts + * + * Copyright (C) 2005 Sigmatel Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef _ASM_ARCH_IRQS_H +#define _ASM_ARCH_IRQS_H + +#define IRQ_DEBUG_UART 0 +#define IRQ_COMMS_RX 1 +#define IRQ_COMMS_TX 1 +#define IRQ_SSP2_ERROR 2 +#define IRQ_VDD5V 3 +#define IRQ_HEADPHONE_SHORT 4 +#define IRQ_DAC_DMA 5 +#define IRQ_DAC_ERROR 6 +#define IRQ_ADC_DMA 7 +#define IRQ_ADC_ERROR 8 +#define IRQ_SPDIF_DMA 9 +#define IRQ_SAIF2_DMA 9 +#define IRQ_SPDIF_ERROR 10 +#define IRQ_SAIF1_IRQ 10 +#define IRQ_SAIF2_IRQ 10 +#define IRQ_USB_CTRL 11 +#define IRQ_USB_WAKEUP 12 +#define IRQ_GPMI_DMA 13 +#define IRQ_SSP1_DMA 14 +#define IRQ_SSP_ERROR 15 +#define IRQ_GPIO0 16 +#define IRQ_GPIO1 17 +#define IRQ_GPIO2 18 +#define IRQ_SAIF1_DMA 19 +#define IRQ_SSP2_DMA 20 +#define IRQ_ECC8_IRQ 21 +#define IRQ_RTC_ALARM 22 +#define IRQ_UARTAPP_TX_DMA 23 +#define IRQ_UARTAPP_INTERNAL 24 +#define IRQ_UARTAPP_RX_DMA 25 +#define IRQ_I2C_DMA 26 +#define IRQ_I2C_ERROR 27 +#define IRQ_TIMER0 28 +#define IRQ_TIMER1 29 +#define IRQ_TIMER2 30 +#define IRQ_TIMER3 31 +#define IRQ_BATT_BRNOUT 32 +#define IRQ_VDDD_BRNOUT 33 +#define IRQ_VDDIO_BRNOUT 34 +#define IRQ_VDD18_BRNOUT 35 +#define IRQ_TOUCH_DETECT 36 +#define IRQ_LRADC_CH0 37 +#define IRQ_LRADC_CH1 38 +#define IRQ_LRADC_CH2 39 +#define IRQ_LRADC_CH3 40 +#define IRQ_LRADC_CH4 41 +#define IRQ_LRADC_CH5 42 +#define IRQ_LRADC_CH6 43 +#define IRQ_LRADC_CH7 44 +#define IRQ_LCDIF_DMA 45 +#define IRQ_LCDIF_ERROR 46 +#define IRQ_DIGCTL_DEBUG_TRAP 47 +#define IRQ_RTC_1MSEC 48 +#define IRQ_DRI_DMA 49 +#define IRQ_DRI_ATTENTION 50 +#define IRQ_GPMI_ATTENTION 51 +#define IRQ_IR 52 +#define IRQ_DCP_VMI 53 +#define IRQ_DCP 54 +#define IRQ_RESERVED_55 55 +#define IRQ_RESERVED_56 56 +#define IRQ_RESERVED_57 57 +#define IRQ_RESERVED_58 58 +#define IRQ_RESERVED_59 59 +#define SW_IRQ_60 60 +#define SW_IRQ_61 61 +#define SW_IRQ_62 62 +#define SW_IRQ_63 63 + +#define NR_REAL_IRQS 64 +#define NR_IRQS (NR_REAL_IRQS + 32 * 3) + +/* TIMER and BRNOUT are FIQ capable */ +#define FIQ_START IRQ_TIMER0 + +/* Hard disk IRQ is a GPMI attention IRQ */ +#define IRQ_HARDDISK IRQ_GPMI_ATTENTION + +#endif /* _ASM_ARCH_IRQS_H */ diff --git a/arch/arm/mach-stmp37xx/include/mach/pins.h b/arch/arm/mach-stmp37xx/include/mach/pins.h new file mode 100644 index 000000000000..d56de0c471d8 --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/pins.h @@ -0,0 +1,147 @@ +/* + * Freescale STMP37XX SoC pin multiplexing + * + * Author: Vladislav Buzov + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_ARCH_PINS_H +#define __ASM_ARCH_PINS_H + +/* + * Define all STMP37XX pins, a pin name corresponds to a STMP37xx hardware + * interface this pin belongs to. + */ + +/* Bank 0 */ +#define PINID_GPMI_D00 STMP3XXX_PINID(0, 0) +#define PINID_GPMI_D01 STMP3XXX_PINID(0, 1) +#define PINID_GPMI_D02 STMP3XXX_PINID(0, 2) +#define PINID_GPMI_D03 STMP3XXX_PINID(0, 3) +#define PINID_GPMI_D04 STMP3XXX_PINID(0, 4) +#define PINID_GPMI_D05 STMP3XXX_PINID(0, 5) +#define PINID_GPMI_D06 STMP3XXX_PINID(0, 6) +#define PINID_GPMI_D07 STMP3XXX_PINID(0, 7) +#define PINID_GPMI_D08 STMP3XXX_PINID(0, 8) +#define PINID_GPMI_D09 STMP3XXX_PINID(0, 9) +#define PINID_GPMI_D10 STMP3XXX_PINID(0, 10) +#define PINID_GPMI_D11 STMP3XXX_PINID(0, 11) +#define PINID_GPMI_D12 STMP3XXX_PINID(0, 12) +#define PINID_GPMI_D13 STMP3XXX_PINID(0, 13) +#define PINID_GPMI_D14 STMP3XXX_PINID(0, 14) +#define PINID_GPMI_D15 STMP3XXX_PINID(0, 15) +#define PINID_GPMI_A0 STMP3XXX_PINID(0, 16) +#define PINID_GPMI_A1 STMP3XXX_PINID(0, 17) +#define PINID_GPMI_A2 STMP3XXX_PINID(0, 18) +#define PINID_GPMI_RDY0 STMP3XXX_PINID(0, 19) +#define PINID_GPMI_RDY2 STMP3XXX_PINID(0, 20) +#define PINID_GPMI_RDY3 STMP3XXX_PINID(0, 21) +#define PINID_GPMI_RESETN STMP3XXX_PINID(0, 22) +#define PINID_GPMI_IRQ STMP3XXX_PINID(0, 23) +#define PINID_GPMI_WRN STMP3XXX_PINID(0, 24) +#define PINID_GPMI_RDN STMP3XXX_PINID(0, 25) +#define PINID_UART2_CTS STMP3XXX_PINID(0, 26) +#define PINID_UART2_RTS STMP3XXX_PINID(0, 27) +#define PINID_UART2_RX STMP3XXX_PINID(0, 28) +#define PINID_UART2_TX STMP3XXX_PINID(0, 29) + +/* Bank 1 */ +#define PINID_LCD_D00 STMP3XXX_PINID(1, 0) +#define PINID_LCD_D01 STMP3XXX_PINID(1, 1) +#define PINID_LCD_D02 STMP3XXX_PINID(1, 2) +#define PINID_LCD_D03 STMP3XXX_PINID(1, 3) +#define PINID_LCD_D04 STMP3XXX_PINID(1, 4) +#define PINID_LCD_D05 STMP3XXX_PINID(1, 5) +#define PINID_LCD_D06 STMP3XXX_PINID(1, 6) +#define PINID_LCD_D07 STMP3XXX_PINID(1, 7) +#define PINID_LCD_D08 STMP3XXX_PINID(1, 8) +#define PINID_LCD_D09 STMP3XXX_PINID(1, 9) +#define PINID_LCD_D10 STMP3XXX_PINID(1, 10) +#define PINID_LCD_D11 STMP3XXX_PINID(1, 11) +#define PINID_LCD_D12 STMP3XXX_PINID(1, 12) +#define PINID_LCD_D13 STMP3XXX_PINID(1, 13) +#define PINID_LCD_D14 STMP3XXX_PINID(1, 14) +#define PINID_LCD_D15 STMP3XXX_PINID(1, 15) +#define PINID_LCD_RESET STMP3XXX_PINID(1, 16) +#define PINID_LCD_RS STMP3XXX_PINID(1, 17) +#define PINID_LCD_WR_RWN STMP3XXX_PINID(1, 18) +#define PINID_LCD_RD_E STMP3XXX_PINID(1, 19) +#define PINID_LCD_CS STMP3XXX_PINID(1, 20) +#define PINID_LCD_BUSY STMP3XXX_PINID(1, 21) +#define PINID_SSP1_CMD STMP3XXX_PINID(1, 22) +#define PINID_SSP1_SCK STMP3XXX_PINID(1, 23) +#define PINID_SSP1_DATA0 STMP3XXX_PINID(1, 24) +#define PINID_SSP1_DATA1 STMP3XXX_PINID(1, 25) +#define PINID_SSP1_DATA2 STMP3XXX_PINID(1, 26) +#define PINID_SSP1_DATA3 STMP3XXX_PINID(1, 27) +#define PINID_SSP1_DETECT STMP3XXX_PINID(1, 28) + +/* Bank 2 */ +#define PINID_PWM0 STMP3XXX_PINID(2, 0) +#define PINID_PWM1 STMP3XXX_PINID(2, 1) +#define PINID_PWM2 STMP3XXX_PINID(2, 2) +#define PINID_PWM3 STMP3XXX_PINID(2, 3) +#define PINID_PWM4 STMP3XXX_PINID(2, 4) +#define PINID_I2C_SCL STMP3XXX_PINID(2, 5) +#define PINID_I2C_SDA STMP3XXX_PINID(2, 6) +#define PINID_ROTTARYA STMP3XXX_PINID(2, 7) +#define PINID_ROTTARYB STMP3XXX_PINID(2, 8) +#define PINID_EMI_CKE STMP3XXX_PINID(2, 9) +#define PINID_EMI_RASN STMP3XXX_PINID(2, 10) +#define PINID_EMI_CASN STMP3XXX_PINID(2, 11) +#define PINID_EMI_CE0N STMP3XXX_PINID(2, 12) +#define PINID_EMI_CE1N STMP3XXX_PINID(2, 13) +#define PINID_EMI_CE2N STMP3XXX_PINID(2, 14) +#define PINID_EMI_CE3N STMP3XXX_PINID(2, 15) +#define PINID_EMI_A00 STMP3XXX_PINID(2, 16) +#define PINID_EMI_A01 STMP3XXX_PINID(2, 17) +#define PINID_EMI_A02 STMP3XXX_PINID(2, 18) +#define PINID_EMI_A03 STMP3XXX_PINID(2, 19) +#define PINID_EMI_A04 STMP3XXX_PINID(2, 20) +#define PINID_EMI_A05 STMP3XXX_PINID(2, 21) +#define PINID_EMI_A06 STMP3XXX_PINID(2, 22) +#define PINID_EMI_A07 STMP3XXX_PINID(2, 23) +#define PINID_EMI_A08 STMP3XXX_PINID(2, 24) +#define PINID_EMI_A09 STMP3XXX_PINID(2, 25) +#define PINID_EMI_A10 STMP3XXX_PINID(2, 26) +#define PINID_EMI_A11 STMP3XXX_PINID(2, 27) +#define PINID_EMI_A12 STMP3XXX_PINID(2, 28) +#define PINID_EMI_A13 STMP3XXX_PINID(2, 29) +#define PINID_EMI_A14 STMP3XXX_PINID(2, 30) +#define PINID_EMI_WEN STMP3XXX_PINID(2, 31) + +/* Bank 3 */ +#define PINID_EMI_D00 STMP3XXX_PINID(3, 0) +#define PINID_EMI_D01 STMP3XXX_PINID(3, 1) +#define PINID_EMI_D02 STMP3XXX_PINID(3, 2) +#define PINID_EMI_D03 STMP3XXX_PINID(3, 3) +#define PINID_EMI_D04 STMP3XXX_PINID(3, 4) +#define PINID_EMI_D05 STMP3XXX_PINID(3, 5) +#define PINID_EMI_D06 STMP3XXX_PINID(3, 6) +#define PINID_EMI_D07 STMP3XXX_PINID(3, 7) +#define PINID_EMI_D08 STMP3XXX_PINID(3, 8) +#define PINID_EMI_D09 STMP3XXX_PINID(3, 9) +#define PINID_EMI_D10 STMP3XXX_PINID(3, 10) +#define PINID_EMI_D11 STMP3XXX_PINID(3, 11) +#define PINID_EMI_D12 STMP3XXX_PINID(3, 12) +#define PINID_EMI_D13 STMP3XXX_PINID(3, 13) +#define PINID_EMI_D14 STMP3XXX_PINID(3, 14) +#define PINID_EMI_D15 STMP3XXX_PINID(3, 15) +#define PINID_EMI_DQS0 STMP3XXX_PINID(3, 16) +#define PINID_EMI_DQS1 STMP3XXX_PINID(3, 17) +#define PINID_EMI_DQM0 STMP3XXX_PINID(3, 18) +#define PINID_EMI_DQM1 STMP3XXX_PINID(3, 19) +#define PINID_EMI_CLK STMP3XXX_PINID(3, 20) +#define PINID_EMI_CLKN STMP3XXX_PINID(3, 21) + +#endif /* __ASM_ARCH_PINS_H */ -- GitLab From b4175b89921fefb2f352472fa6dccb0fc4fb37d9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 26 Apr 2009 14:22:29 +0100 Subject: [PATCH 0715/6080] [ARM] sort machine- and plat- by CONFIG* name Signed-off-by: Russell King --- arch/arm/Makefile | 117 ++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e84729bf13d4..885a83724b9c 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -99,64 +99,69 @@ CHECKFLAGS += -D__arm__ #Default value head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o textofs-y := 0x00008000 - - machine-$(CONFIG_ARCH_RPC) := rpc - machine-$(CONFIG_ARCH_EBSA110) := ebsa110 - machine-$(CONFIG_FOOTBRIDGE) := footbridge - machine-$(CONFIG_ARCH_SHARK) := shark - machine-$(CONFIG_ARCH_SA1100) := sa1100 -ifeq ($(CONFIG_ARCH_SA1100),y) +textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory - textofs-$(CONFIG_SA1111) := 0x00208000 +ifeq ($(CONFIG_ARCH_SA1100),y) +textofs-$(CONFIG_SA1111) := 0x00208000 endif - machine-$(CONFIG_ARCH_PXA) := pxa - machine-$(CONFIG_ARCH_MMP) := mmp - plat-$(CONFIG_PLAT_PXA) := pxa - machine-$(CONFIG_ARCH_L7200) := l7200 - machine-$(CONFIG_ARCH_INTEGRATOR) := integrator - machine-$(CONFIG_ARCH_GEMINI) := gemini - textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 - machine-$(CONFIG_ARCH_CLPS711X) := clps711x - machine-$(CONFIG_ARCH_IOP32X) := iop32x - machine-$(CONFIG_ARCH_IOP33X) := iop33x - machine-$(CONFIG_ARCH_IOP13XX) := iop13xx - plat-$(CONFIG_PLAT_IOP) := iop - machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx - machine-$(CONFIG_ARCH_IXP2000) := ixp2000 - machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx - machine-$(CONFIG_ARCH_OMAP1) := omap1 - machine-$(CONFIG_ARCH_OMAP2) := omap2 - machine-$(CONFIG_ARCH_OMAP3) := omap2 - plat-$(CONFIG_ARCH_OMAP) := omap - machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443 - machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 - plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c - machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 - plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c - machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x - machine-$(CONFIG_ARCH_VERSATILE) := versatile - machine-$(CONFIG_ARCH_IMX) := imx - machine-$(CONFIG_ARCH_H720X) := h720x - machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 - machine-$(CONFIG_ARCH_REALVIEW) := realview - machine-$(CONFIG_ARCH_AT91) := at91 - machine-$(CONFIG_ARCH_EP93XX) := ep93xx - machine-$(CONFIG_ARCH_PNX4008) := pnx4008 - machine-$(CONFIG_ARCH_NETX) := netx - machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx - machine-$(CONFIG_ARCH_DAVINCI) := davinci - machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood - machine-$(CONFIG_ARCH_KS8695) := ks8695 - plat-$(CONFIG_ARCH_MXC) := mxc - machine-$(CONFIG_ARCH_MX2) := mx2 - machine-$(CONFIG_ARCH_MX3) := mx3 - machine-$(CONFIG_ARCH_MX1) := mx1 - machine-$(CONFIG_ARCH_ORION5X) := orion5x - plat-$(CONFIG_PLAT_ORION) := orion - machine-$(CONFIG_ARCH_MSM) := msm - machine-$(CONFIG_ARCH_LOKI) := loki - machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 - machine-$(CONFIG_ARCH_W90X900) := w90x900 + +# Machine directory name. This list is sorted alphanumerically +# by CONFIG_* macro name. +machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 +machine-$(CONFIG_ARCH_AT91) := at91 +machine-$(CONFIG_ARCH_CLPS711X) := clps711x +machine-$(CONFIG_ARCH_DAVINCI) := davinci +machine-$(CONFIG_ARCH_EBSA110) := ebsa110 +machine-$(CONFIG_ARCH_EP93XX) := ep93xx +machine-$(CONFIG_ARCH_GEMINI) := gemini +machine-$(CONFIG_ARCH_H720X) := h720x +machine-$(CONFIG_ARCH_IMX) := imx +machine-$(CONFIG_ARCH_INTEGRATOR) := integrator +machine-$(CONFIG_ARCH_IOP13XX) := iop13xx +machine-$(CONFIG_ARCH_IOP32X) := iop32x +machine-$(CONFIG_ARCH_IOP33X) := iop33x +machine-$(CONFIG_ARCH_IXP2000) := ixp2000 +machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx +machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx +machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood +machine-$(CONFIG_ARCH_KS8695) := ks8695 +machine-$(CONFIG_ARCH_L7200) := l7200 +machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x +machine-$(CONFIG_ARCH_LOKI) := loki +machine-$(CONFIG_ARCH_MMP) := mmp +machine-$(CONFIG_ARCH_MSM) := msm +machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 +machine-$(CONFIG_ARCH_MX1) := mx1 +machine-$(CONFIG_ARCH_MX2) := mx2 +machine-$(CONFIG_ARCH_MX3) := mx3 +machine-$(CONFIG_ARCH_NETX) := netx +machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx +machine-$(CONFIG_ARCH_OMAP1) := omap1 +machine-$(CONFIG_ARCH_OMAP2) := omap2 +machine-$(CONFIG_ARCH_OMAP3) := omap2 +machine-$(CONFIG_ARCH_ORION5X) := orion5x +machine-$(CONFIG_ARCH_PNX4008) := pnx4008 +machine-$(CONFIG_ARCH_PXA) := pxa +machine-$(CONFIG_ARCH_REALVIEW) := realview +machine-$(CONFIG_ARCH_RPC) := rpc +machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443 +machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 +machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 +machine-$(CONFIG_ARCH_SA1100) := sa1100 +machine-$(CONFIG_ARCH_SHARK) := shark +machine-$(CONFIG_ARCH_VERSATILE) := versatile +machine-$(CONFIG_ARCH_W90X900) := w90x900 +machine-$(CONFIG_FOOTBRIDGE) := footbridge + +# Platform directory name. This list is sorted alphanumerically +# by CONFIG_* macro name. +plat-$(CONFIG_ARCH_MXC) := mxc +plat-$(CONFIG_ARCH_OMAP) := omap +plat-$(CONFIG_PLAT_IOP) := iop +plat-$(CONFIG_PLAT_ORION) := orion +plat-$(CONFIG_PLAT_PXA) := pxa +plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c +plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. -- GitLab From 1e3dd535d641a856e913dd8a17a75bd3c36c49e0 Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Wed, 22 Apr 2009 23:52:45 +0100 Subject: [PATCH 0716/6080] [ARM] 5469/1: Freescale STMP platform support [2/10] Headers for STMP378x boards Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- .../mach-stmp378x/include/mach/entry-macro.S | 35 ++++ arch/arm/mach-stmp378x/include/mach/irqs.h | 95 +++++++++++ arch/arm/mach-stmp378x/include/mach/pins.h | 151 ++++++++++++++++++ 3 files changed, 281 insertions(+) create mode 100644 arch/arm/mach-stmp378x/include/mach/entry-macro.S create mode 100644 arch/arm/mach-stmp378x/include/mach/irqs.h create mode 100644 arch/arm/mach-stmp378x/include/mach/pins.h diff --git a/arch/arm/mach-stmp378x/include/mach/entry-macro.S b/arch/arm/mach-stmp378x/include/mach/entry-macro.S new file mode 100644 index 000000000000..731a92286da2 --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/entry-macro.S @@ -0,0 +1,35 @@ +/* + * Low-level IRQ helper macros for Freescale STMP378X + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + + .macro disable_fiq + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + mov \base, #0xf0000000 @ vm address of IRQ controller + ldr \irqnr, [\base, #0x70] @ HW_ICOLL_STAT + cmp \irqnr, #0x7f + moveqs \irqnr, #0 @ Zero flag set for no IRQ + + .endm + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm diff --git a/arch/arm/mach-stmp378x/include/mach/irqs.h b/arch/arm/mach-stmp378x/include/mach/irqs.h new file mode 100644 index 000000000000..cc59673becdd --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/irqs.h @@ -0,0 +1,95 @@ +/* + * Freescale STMP378X interrupts + * + * Copyright (C) 2005 Sigmatel Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#define IRQ_DEBUG_UART 0 +#define IRQ_COMMS_RX 1 +#define IRQ_COMMS_TX 1 +#define IRQ_SSP2_ERROR 2 +#define IRQ_VDD5V 3 +#define IRQ_HEADPHONE_SHORT 4 +#define IRQ_DAC_DMA 5 +#define IRQ_DAC_ERROR 6 +#define IRQ_ADC_DMA 7 +#define IRQ_ADC_ERROR 8 +#define IRQ_SPDIF_DMA 9 +#define IRQ_SAIF2_DMA 9 +#define IRQ_SPDIF_ERROR 10 +#define IRQ_SAIF1_IRQ 10 +#define IRQ_SAIF2_IRQ 10 +#define IRQ_USB_CTRL 11 +#define IRQ_USB_WAKEUP 12 +#define IRQ_GPMI_DMA 13 +#define IRQ_SSP1_DMA 14 +#define IRQ_SSP_ERROR 15 +#define IRQ_GPIO0 16 +#define IRQ_GPIO1 17 +#define IRQ_GPIO2 18 +#define IRQ_SAIF1_DMA 19 +#define IRQ_SSP2_DMA 20 +#define IRQ_ECC8_IRQ 21 +#define IRQ_RTC_ALARM 22 +#define IRQ_UARTAPP_TX_DMA 23 +#define IRQ_UARTAPP_INTERNAL 24 +#define IRQ_UARTAPP_RX_DMA 25 +#define IRQ_I2C_DMA 26 +#define IRQ_I2C_ERROR 27 +#define IRQ_TIMER0 28 +#define IRQ_TIMER1 29 +#define IRQ_TIMER2 30 +#define IRQ_TIMER3 31 +#define IRQ_BATT_BRNOUT 32 +#define IRQ_VDDD_BRNOUT 33 +#define IRQ_VDDIO_BRNOUT 34 +#define IRQ_VDD18_BRNOUT 35 +#define IRQ_TOUCH_DETECT 36 +#define IRQ_LRADC_CH0 37 +#define IRQ_LRADC_CH1 38 +#define IRQ_LRADC_CH2 39 +#define IRQ_LRADC_CH3 40 +#define IRQ_LRADC_CH4 41 +#define IRQ_LRADC_CH5 42 +#define IRQ_LRADC_CH6 43 +#define IRQ_LRADC_CH7 44 +#define IRQ_LCDIF_DMA 45 +#define IRQ_LCDIF_ERROR 46 +#define IRQ_DIGCTL_DEBUG_TRAP 47 +#define IRQ_RTC_1MSEC 48 +#define IRQ_DRI_DMA 49 +#define IRQ_DRI_ATTENTION 50 +#define IRQ_GPMI_ATTENTION 51 +#define IRQ_IR 52 +#define IRQ_DCP_VMI 53 +#define IRQ_DCP 54 +#define IRQ_BCH 56 +#define IRQ_PXP 57 +#define IRQ_UARTAPP2_TX_DMA 58 +#define IRQ_UARTAPP2_INTERNAL 59 +#define IRQ_UARTAPP2_RX_DMA 60 +#define IRQ_VDAC_DETECT 61 +#define IRQ_VDD5V_DROOP 64 +#define IRQ_DCDC4P2_BO 65 + + +#define NR_REAL_IRQS 128 +#define NR_IRQS (NR_REAL_IRQS + 32 * 3) + +/* All interrupts are FIQ capable */ +#define FIQ_START IRQ_DEBUG_UART + +/* Hard disk IRQ is a GPMI attention IRQ */ +#define IRQ_HARDDISK IRQ_GPMI_ATTENTION diff --git a/arch/arm/mach-stmp378x/include/mach/pins.h b/arch/arm/mach-stmp378x/include/mach/pins.h new file mode 100644 index 000000000000..93f952d35969 --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/pins.h @@ -0,0 +1,151 @@ +/* + * Freescale STMP378X SoC pin multiplexing + * + * Author: Vladislav Buzov + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_ARCH_PINS_H +#define __ASM_ARCH_PINS_H + +/* + * Define all STMP378x pins, a pin name corresponds to a STMP378x hardware + * interface this pin belongs to. + */ + +/* Bank 0 */ +#define PINID_GPMI_D00 STMP3XXX_PINID(0, 0) +#define PINID_GPMI_D01 STMP3XXX_PINID(0, 1) +#define PINID_GPMI_D02 STMP3XXX_PINID(0, 2) +#define PINID_GPMI_D03 STMP3XXX_PINID(0, 3) +#define PINID_GPMI_D04 STMP3XXX_PINID(0, 4) +#define PINID_GPMI_D05 STMP3XXX_PINID(0, 5) +#define PINID_GPMI_D06 STMP3XXX_PINID(0, 6) +#define PINID_GPMI_D07 STMP3XXX_PINID(0, 7) +#define PINID_GPMI_D08 STMP3XXX_PINID(0, 8) +#define PINID_GPMI_D09 STMP3XXX_PINID(0, 9) +#define PINID_GPMI_D10 STMP3XXX_PINID(0, 10) +#define PINID_GPMI_D11 STMP3XXX_PINID(0, 11) +#define PINID_GPMI_D12 STMP3XXX_PINID(0, 12) +#define PINID_GPMI_D13 STMP3XXX_PINID(0, 13) +#define PINID_GPMI_D14 STMP3XXX_PINID(0, 14) +#define PINID_GPMI_D15 STMP3XXX_PINID(0, 15) +#define PINID_GPMI_CLE STMP3XXX_PINID(0, 16) +#define PINID_GPMI_ALE STMP3XXX_PINID(0, 17) +#define PINID_GMPI_CE2N STMP3XXX_PINID(0, 18) +#define PINID_GPMI_RDY0 STMP3XXX_PINID(0, 19) +#define PINID_GPMI_RDY1 STMP3XXX_PINID(0, 20) +#define PINID_GPMI_RDY2 STMP3XXX_PINID(0, 21) +#define PINID_GPMI_RDY3 STMP3XXX_PINID(0, 22) +#define PINID_GPMI_WPN STMP3XXX_PINID(0, 23) +#define PINID_GPMI_WRN STMP3XXX_PINID(0, 24) +#define PINID_GPMI_RDN STMP3XXX_PINID(0, 25) +#define PINID_AUART1_CTS STMP3XXX_PINID(0, 26) +#define PINID_AUART1_RTS STMP3XXX_PINID(0, 27) +#define PINID_AUART1_RX STMP3XXX_PINID(0, 28) +#define PINID_AUART1_TX STMP3XXX_PINID(0, 29) +#define PINID_I2C_SCL STMP3XXX_PINID(0, 30) +#define PINID_I2C_SDA STMP3XXX_PINID(0, 31) + +/* Bank 1 */ +#define PINID_LCD_D00 STMP3XXX_PINID(1, 0) +#define PINID_LCD_D01 STMP3XXX_PINID(1, 1) +#define PINID_LCD_D02 STMP3XXX_PINID(1, 2) +#define PINID_LCD_D03 STMP3XXX_PINID(1, 3) +#define PINID_LCD_D04 STMP3XXX_PINID(1, 4) +#define PINID_LCD_D05 STMP3XXX_PINID(1, 5) +#define PINID_LCD_D06 STMP3XXX_PINID(1, 6) +#define PINID_LCD_D07 STMP3XXX_PINID(1, 7) +#define PINID_LCD_D08 STMP3XXX_PINID(1, 8) +#define PINID_LCD_D09 STMP3XXX_PINID(1, 9) +#define PINID_LCD_D10 STMP3XXX_PINID(1, 10) +#define PINID_LCD_D11 STMP3XXX_PINID(1, 11) +#define PINID_LCD_D12 STMP3XXX_PINID(1, 12) +#define PINID_LCD_D13 STMP3XXX_PINID(1, 13) +#define PINID_LCD_D14 STMP3XXX_PINID(1, 14) +#define PINID_LCD_D15 STMP3XXX_PINID(1, 15) +#define PINID_LCD_D16 STMP3XXX_PINID(1, 16) +#define PINID_LCD_D17 STMP3XXX_PINID(1, 17) +#define PINID_LCD_RESET STMP3XXX_PINID(1, 18) +#define PINID_LCD_RS STMP3XXX_PINID(1, 19) +#define PINID_LCD_WR STMP3XXX_PINID(1, 20) +#define PINID_LCD_CS STMP3XXX_PINID(1, 21) +#define PINID_LCD_DOTCK STMP3XXX_PINID(1, 22) +#define PINID_LCD_ENABLE STMP3XXX_PINID(1, 23) +#define PINID_LCD_HSYNC STMP3XXX_PINID(1, 24) +#define PINID_LCD_VSYNC STMP3XXX_PINID(1, 25) +#define PINID_PWM0 STMP3XXX_PINID(1, 26) +#define PINID_PWM1 STMP3XXX_PINID(1, 27) +#define PINID_PWM2 STMP3XXX_PINID(1, 28) +#define PINID_PWM3 STMP3XXX_PINID(1, 29) +#define PINID_PWM4 STMP3XXX_PINID(1, 30) + +/* Bank 2 */ +#define PINID_SSP1_CMD STMP3XXX_PINID(2, 0) +#define PINID_SSP1_DETECT STMP3XXX_PINID(2, 1) +#define PINID_SSP1_DATA0 STMP3XXX_PINID(2, 2) +#define PINID_SSP1_DATA1 STMP3XXX_PINID(2, 3) +#define PINID_SSP1_DATA2 STMP3XXX_PINID(2, 4) +#define PINID_SSP1_DATA3 STMP3XXX_PINID(2, 5) +#define PINID_SSP1_SCK STMP3XXX_PINID(2, 6) +#define PINID_ROTARYA STMP3XXX_PINID(2, 7) +#define PINID_ROTARYB STMP3XXX_PINID(2, 8) +#define PINID_EMI_A00 STMP3XXX_PINID(2, 9) +#define PINID_EMI_A01 STMP3XXX_PINID(2, 10) +#define PINID_EMI_A02 STMP3XXX_PINID(2, 11) +#define PINID_EMI_A03 STMP3XXX_PINID(2, 12) +#define PINID_EMI_A04 STMP3XXX_PINID(2, 13) +#define PINID_EMI_A05 STMP3XXX_PINID(2, 14) +#define PINID_EMI_A06 STMP3XXX_PINID(2, 15) +#define PINID_EMI_A07 STMP3XXX_PINID(2, 16) +#define PINID_EMI_A08 STMP3XXX_PINID(2, 17) +#define PINID_EMI_A09 STMP3XXX_PINID(2, 18) +#define PINID_EMI_A10 STMP3XXX_PINID(2, 19) +#define PINID_EMI_A11 STMP3XXX_PINID(2, 20) +#define PINID_EMI_A12 STMP3XXX_PINID(2, 21) +#define PINID_EMI_BA0 STMP3XXX_PINID(2, 22) +#define PINID_EMI_BA1 STMP3XXX_PINID(2, 23) +#define PINID_EMI_CASN STMP3XXX_PINID(2, 24) +#define PINID_EMI_CE0N STMP3XXX_PINID(2, 25) +#define PINID_EMI_CE1N STMP3XXX_PINID(2, 26) +#define PINID_GPMI_CE1N STMP3XXX_PINID(2, 27) +#define PINID_GPMI_CE0N STMP3XXX_PINID(2, 28) +#define PINID_EMI_CKE STMP3XXX_PINID(2, 29) +#define PINID_EMI_RASN STMP3XXX_PINID(2, 30) +#define PINID_EMI_WEN STMP3XXX_PINID(2, 31) + +/* Bank 3 */ +#define PINID_EMI_D00 STMP3XXX_PINID(3, 0) +#define PINID_EMI_D01 STMP3XXX_PINID(3, 1) +#define PINID_EMI_D02 STMP3XXX_PINID(3, 2) +#define PINID_EMI_D03 STMP3XXX_PINID(3, 3) +#define PINID_EMI_D04 STMP3XXX_PINID(3, 4) +#define PINID_EMI_D05 STMP3XXX_PINID(3, 5) +#define PINID_EMI_D06 STMP3XXX_PINID(3, 6) +#define PINID_EMI_D07 STMP3XXX_PINID(3, 7) +#define PINID_EMI_D08 STMP3XXX_PINID(3, 8) +#define PINID_EMI_D09 STMP3XXX_PINID(3, 9) +#define PINID_EMI_D10 STMP3XXX_PINID(3, 10) +#define PINID_EMI_D11 STMP3XXX_PINID(3, 11) +#define PINID_EMI_D12 STMP3XXX_PINID(3, 12) +#define PINID_EMI_D13 STMP3XXX_PINID(3, 13) +#define PINID_EMI_D14 STMP3XXX_PINID(3, 14) +#define PINID_EMI_D15 STMP3XXX_PINID(3, 15) +#define PINID_EMI_DQM0 STMP3XXX_PINID(3, 16) +#define PINID_EMI_DQM1 STMP3XXX_PINID(3, 17) +#define PINID_EMI_DQS0 STMP3XXX_PINID(3, 18) +#define PINID_EMI_DQS1 STMP3XXX_PINID(3, 19) +#define PINID_EMI_CLK STMP3XXX_PINID(3, 20) +#define PINID_EMI_CLKN STMP3XXX_PINID(3, 21) + +#endif /* __ASM_ARCH_PINS_H */ -- GitLab From 34acb09025a132943555d0f0ffca6cb05c698cd4 Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Wed, 22 Apr 2009 23:54:05 +0100 Subject: [PATCH 0717/6080] [ARM] 5468/1: Freescale STMP platform support [3/10] Minimal definition of register set for 37xx boards Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- .../mach-stmp37xx/include/mach/regs-apbh.h | 102 +++++++++++ .../mach-stmp37xx/include/mach/regs-apbx.h | 109 ++++++++++++ .../mach-stmp37xx/include/mach/regs-clkctrl.h | 85 ++++++++++ .../mach-stmp37xx/include/mach/regs-icoll.h | 36 ++++ .../mach-stmp37xx/include/mach/regs-pinctrl.h | 159 ++++++++++++++++++ .../mach-stmp37xx/include/mach/regs-power.h | 31 ++++ .../mach-stmp37xx/include/mach/regs-timrot.h | 52 ++++++ 7 files changed, 574 insertions(+) create mode 100644 arch/arm/mach-stmp37xx/include/mach/regs-apbh.h create mode 100644 arch/arm/mach-stmp37xx/include/mach/regs-apbx.h create mode 100644 arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h create mode 100644 arch/arm/mach-stmp37xx/include/mach/regs-icoll.h create mode 100644 arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h create mode 100644 arch/arm/mach-stmp37xx/include/mach/regs-power.h create mode 100644 arch/arm/mach-stmp37xx/include/mach/regs-timrot.h diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h b/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h new file mode 100644 index 000000000000..3044c20ad90c --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h @@ -0,0 +1,102 @@ +/* + * STMP APBH Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * Copyright 2008 Embedded Alley Solutions, 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 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 _INCLUDE_ASM_ARCH_REGS_APBH_H +#define _INCLUDE_ASM_ARCH_REGS_APBH_H + +#include + +#ifndef REGS_APBH_BASE +#define REGS_APBH_BASE (REGS_BASE + 0x00004000) +#endif + +HW_REGISTER(HW_APBH_CTRL0, REGS_APBH_BASE, 0x00) +#define BP_APBH_CTRL0_SFTRST 31 +#define BM_APBH_CTRL0_SFTRST 0x80000000 +#define BP_APBH_CTRL0_CLKGATE 30 +#define BM_APBH_CTRL0_CLKGATE 0x40000000 +#define BP_APBH_CTRL0_RESET_CHANNEL 16 +#define BM_APBH_CTRL0_RESET_CHANNEL 0x00FF0000 +#define BF_APBH_CTRL0_RESET_CHANNEL(v) \ + (((v) << BP_APBH_CTRL0_RESET_CHANNEL) & BM_APBH_CTRL0_RESET_CHANNEL) +HW_REGISTER(HW_APBH_CTRL1, REGS_APBH_BASE, 0x10) +#define BP_APBH_CTRL1_CH1_CMDCMPLT_IRQ_EN 9 +#define BM_APBH_CTRL1_CH1_CMDCMPLT_IRQ_EN 0x00000200 +#define BP_APBH_CTRL1_CH0_CMDCMPLT_IRQ_EN 8 +#define BM_APBH_CTRL1_CH0_CMDCMPLT_IRQ_EN 0x00000100 +#define BP_APBH_CTRL1_CH7_CMDCMPLT_IRQ 7 +#define BM_APBH_CTRL1_CH7_CMDCMPLT_IRQ 0x00000080 +#define BP_APBH_CTRL1_CH1_CMDCMPLT_IRQ 1 +#define BM_APBH_CTRL1_CH1_CMDCMPLT_IRQ 0x00000002 +#define BP_APBH_CTRL1_CH0_CMDCMPLT_IRQ 0 +#define BM_APBH_CTRL1_CH0_CMDCMPLT_IRQ 0x00000001 +#define BP_APBH_CTRL1_CH1_ERR_IRQ 17 +#define BM_APBH_CTRL1_CH1_ERR_IRQ 0x00020000 +HW_REGISTER_0(HW_APBH_DEVSEL, REGS_APBH_BASE, 0x20) +HW_REGISTER_RO_INDEXED(HW_APBH_CHn_CURCMDAR, REGS_APBH_BASE, 0x40, 0x70) +HW_REGISTER_0_INDEXED(HW_APBH_CHn_NXTCMDAR, REGS_APBH_BASE, 0x50, 0x70) +#define BP_APBH_CHn_NXTCMDAR_CMD_ADDR 0 +#define BM_APBH_CHn_NXTCMDAR_CMD_ADDR 0xFFFFFFFF +#define BF_APBH_CHn_NXTCMDAR_CMD_ADDR(v) ((u32) v) +HW_REGISTER_RO_INDEXED(HW_APBH_CHn_CMD, REGS_APBH_BASE, 0x60, 0x70) +#define BM_APBH_CHn_CMD_XFER_COUNT 0xFFFF0000 +#define BP_APBH_CHn_CMD_XFER_COUNT 16 +#define BF_APBH_CHn_CMD_XFER_COUNT(v) \ + (((v) << BP_APBH_CHn_CMD_XFER_COUNT) & BM_APBH_CHn_CMD_XFER_COUNT) +#define BM_APBH_CHn_CMD_CMDWORDS 0x0000F000 +#define BP_APBH_CHn_CMD_CMDWORDS 12 +#define BF_APBH_CHn_CMD_CMDWORDS(v) \ + (((v) << BP_APBH_CHn_CMD_CMDWORDS) & BM_APBH_CHn_CMD_CMDWORDS) +#define BM_APBH_CHn_CMD_WAIT4ENDCMD 0x00000080 +#define BM_APBH_CHn_CMD_SEMAPHORE 0x00000040 +#define BP_APBH_CHn_CMD_SEMAPHORE 6 +#define BF_APBH_CHn_CMD_SEMAPHORE(v) \ + (((v) << BP_APBH_CHn_CMD_SEMAPHORE) & BM_APBH_CHn_CMD_SEMAPHORE) +#define BM_APBH_CHn_CMD_NANDWAIT4READY 0x00000020 +#define BP_APBH_CHn_CMD_NANDLOCK 4 +#define BM_APBH_CHn_CMD_NANDLOCK 0x00000010 +#define BF_APBH_CHn_CMD_NANDLOCK(v) \ + (((v) << BP_APBH_CHn_CMD_NANDLOCK) & BM_APBH_CHn_CMD_NANDLOCK) +#define BM_APBH_CHn_CMD_IRQONCMPLT 0x00000008 +#define BM_APBH_CHn_CMD_CHAIN 0x00000004 +#define BM_APBH_CHn_CMD_DMA_READ 0x00000003 +#define BP_APBH_CHn_CMD_DMA_READ 0 +#define BF_APBH_CHn_CMD_DMA_READ(v) \ + (((v) << BP_APBH_CHn_CMD_DMA_READ) & BM_APBH_CHn_CMD_DMA_READ) +#define BF_APBH_CHn_CMD_COMMAND(v) \ + (((v) << BP_APBH_CHn_CMD_DMA_READ) & BM_APBH_CHn_CMD_DMA_READ) +#define BV_APBH_CHn_CMD_COMMAND__NO_DMA_XFER 0x0 +#define BV_APBH_CHn_CMD_COMMAND__DMA_WRITE 0x1 +#define BV_APBH_CHn_CMD_COMMAND__DMA_READ 0x2 +#define BV_APBH_CHn_CMD_COMMAND__DMA_SENSE 0x3 +HW_REGISTER_INDEXED(HW_APBH_CHn_BAR, REGS_APBH_BASE, 0x70, 0x70) +HW_REGISTER_0_INDEXED(HW_APBH_CHn_SEMA, REGS_APBH_BASE, 0x80, 0x70) +#define BP_APBH_CHn_SEMA_INCREMENT_SEMA 0 +#define BM_APBH_CHn_SEMA_INCREMENT_SEMA 0x000000FF +#define BF_APBH_CHn_SEMA_INCREMENT_SEMA(v) \ + (((v) << BP_APBH_CHn_SEMA_INCREMENT_SEMA) & \ + BM_APBH_CHn_SEMA_INCREMENT_SEMA) +#define BP_APBH_CHn_SEMA_PHORE 16 +#define BM_APBH_CHn_SEMA_PHORE 0x00FF0000 +HW_REGISTER_RO_INDEXED(HW_APBH_CHn_DEBUG1, REGS_APBH_BASE, 0x90, 0x70) +HW_REGISTER_RO_INDEXED(HW_APBH_CHn_DEBUG2, REGS_APBH_BASE, 0xA0, 0x70) +HW_REGISTER_RO(HW_APBH_VERSION, REGS_APBH_BASE, 0x3F0) + +#endif /* _INCLUDE_ASM_ARCH_REGS_APBH_H */ diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h b/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h new file mode 100644 index 000000000000..a14ddb97639a --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h @@ -0,0 +1,109 @@ +/* + * STMP APBX Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * Copyright 2008 Embedded Alley Solutions, 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 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 _INCLUDE_ASM_ARCH_REGS_APBX_H +#define _INCLUDE_ASM_ARCH_REGS_APBX_H + +#include + +#ifndef REGS_APBX_BASE +#define REGS_APBX_BASE (REGS_BASE + 0x00024000) +#endif + +HW_REGISTER(HW_APBX_CTRL0, REGS_APBX_BASE, 0x00) +#define BP_APBX_CTRL0_SFTRST 31 +#define BM_APBX_CTRL0_SFTRST 0x80000000 +#define BP_APBX_CTRL0_CLKGATE 30 +#define BM_APBX_CTRL0_CLKGATE 0x40000000 +#define BP_APBX_CTRL0_RESET_CHANNEL 16 +#define BM_APBX_CTRL0_RESET_CHANNEL 0x00FF0000 +#define BF_APBX_CTRL0_RESET_CHANNEL(v) \ + (((v) << BP_APBX_CTRL0_RESET_CHANNEL) & BM_APBX_CTRL0_RESET_CHANNEL) +HW_REGISTER(HW_APBX_CTRL1, REGS_APBX_BASE, 0x10) +HW_REGISTER_0(HW_APBX_DEVSEL, REGS_APBX_BASE, 0x20) +#define BP_APBX_DEVSEL_CH7 28 +#define BM_APBX_DEVSEL_CH7 0xF0000000 +#define BF_APBX_DEVSEL_CH7(v) \ + (((v) << BP_APBX_DEVSEL_CH7) & BM_APBX_DEVSEL_CH7) +#define BV_APBX_DEVSEL_CH7__USE_UART 0x0 +#define BV_APBX_DEVSEL_CH7__USE_IRDA 0x1 +#define BP_APBX_DEVSEL_CH6 24 +#define BM_APBX_DEVSEL_CH6 0x0F000000 +#define BF_APBX_DEVSEL_CH6(v) \ + (((v) << BP_APBX_DEVSEL_CH6) & BM_APBX_DEVSEL_CH6) +#define BV_APBX_DEVSEL_CH6__USE_UART 0x0 +#define BV_APBX_DEVSEL_CH6__USE_IRDA 0x1 +#define BP_APBX_CTRL1_CH7_AHB_ERROR_IRQ 23 +#define BM_APBX_CTRL1_CH7_AHB_ERROR_IRQ 0x00800000 +#define BP_APBX_CTRL1_CH6_AHB_ERROR_IRQ 22 +#define BM_APBX_CTRL1_CH6_AHB_ERROR_IRQ 0x00400000 +#define BP_APBX_CTRL1_CH7_CMDCMPLT_IRQ_EN 15 +#define BM_APBX_CTRL1_CH7_CMDCMPLT_IRQ_EN 0x00008000 +#define BP_APBX_CTRL1_CH6_CMDCMPLT_IRQ_EN 14 +#define BM_APBX_CTRL1_CH6_CMDCMPLT_IRQ_EN 0x00004000 + +HW_REGISTER_RO_INDEXED(HW_APBX_CHn_CURCMDAR, REGS_APBX_BASE, 0x40, 0x70) +HW_REGISTER_0_INDEXED(HW_APBX_CHn_NXTCMDAR, REGS_APBX_BASE, 0x50, 0x70) +#define BP_APBX_CHn_NXTCMDAR_CMD_ADDR 0 +#define BM_APBX_CHn_NXTCMDAR_CMD_ADDR 0xFFFFFFFF +#define BF_APBX_CHn_NXTCMDAR_CMD_ADDR(v) ((u32) v) +HW_REGISTER_RO_INDEXED(HW_APBX_CHn_CMD, REGS_APBX_BASE, 0x60, 0x70) +#define BP_APBX_CHn_CMD_XFER_COUNT 16 +#define BM_APBX_CHn_CMD_XFER_COUNT 0xFFFF0000 +#define BF_APBX_CHn_CMD_XFER_COUNT(v) \ + (((v) << BP_APBX_CHn_CMD_XFER_COUNT) & BM_APBX_CHn_CMD_XFER_COUNT) +#define BP_APBX_CHn_CMD_CMDWORDS 12 +#define BM_APBX_CHn_CMD_CMDWORDS 0x0000F000 +#define BF_APBX_CHn_CMD_CMDWORDS(v) \ + (((v) << BP_APBX_CHn_CMD_CMDWORDS) & BM_APBX_CHn_CMD_CMDWORDS) +#define BP_APBX_CHn_CMD_WAIT4ENDCMD 7 +#define BM_APBX_CHn_CMD_WAIT4ENDCMD 0x00000080 +#define BP_APBX_CHn_CMD_SEMAPHORE 6 +#define BM_APBX_CHn_CMD_SEMAPHORE 0x00000040 +#define BP_APBX_CHn_CMD_IRQONCMPLT 3 +#define BM_APBX_CHn_CMD_IRQONCMPLT 0x00000008 +#define BP_APBX_CHn_CMD_CHAIN 2 +#define BM_APBX_CHn_CMD_CHAIN 0x00000004 +#define BM_APBX_CHn_CMD_DMA_READ 0x00000003 +#define BP_APBX_CHn_CMD_DMA_READ 0 +#define BF_APBX_CHn_CMD_DMA_READ(v) \ + (((v) << BP_APBX_CHn_CMD_DMA_READ) & BM_APBX_CHn_CMD_DMA_READ) +#define BP_APBX_CHn_CMD_COMMAND 0 +#define BM_APBX_CHn_CMD_COMMAND 0x00000003 +#define BF_APBX_CHn_CMD_COMMAND(v) \ + (((v) << BP_APBX_CHn_CMD_COMMAND) & BM_APBX_CHn_CMD_COMMAND) +#define BV_APBX_CHn_CMD_COMMAND__NO_DMA_XFER 0x0 +#define BV_APBX_CHn_CMD_COMMAND__DMA_WRITE 0x1 +#define BV_APBX_CHn_CMD_COMMAND__DMA_READ 0x2 + +HW_REGISTER_RO_INDEXED(HW_APBX_CHn_BAR, REGS_APBX_BASE, 0x70, 0x70) +HW_REGISTER_0_INDEXED(HW_APBX_CHn_SEMA, REGS_APBX_BASE, 0x80, 0x70) +#define BP_APBX_CHn_SEMA_INCREMENT_SEMA 0 +#define BM_APBX_CHn_SEMA_INCREMENT_SEMA 0x000000FF +#define BF_APBX_CHn_SEMA_INCREMENT_SEMA(v) \ + (((v) << BP_APBX_CHn_SEMA_INCREMENT_SEMA) & \ + BM_APBX_CHn_SEMA_INCREMENT_SEMA) +#define BP_APBX_CHn_SEMA_PHORE 16 +#define BM_APBX_CHn_SEMA_PHORE 0x00FF0000 +HW_REGISTER_RO_INDEXED(HW_APBX_CHn_DEBUG1, REGS_APBX_BASE, 0x90, 0x70) +HW_REGISTER_RO_INDEXED(HW_APBX_CHn_DEBUG2, REGS_APBX_BASE, 0xA0, 0x70) +HW_REGISTER_RO(HW_APBX_VERSION, REGS_APBX_BASE, 0x3F0) + +#endif /* _INCLUDE_ASM_ARCH_REGS_APBX_H */ diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h b/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h new file mode 100644 index 000000000000..229ee75f90d9 --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h @@ -0,0 +1,85 @@ +#ifndef _INCLUDE_ASM_ARCH_REGS_CLKCTRL_H +#define _INCLUDE_ASM_ARCH_REGS_CLKCTRL_H + +#include + +#define REGS_CLKCTRL_BASE (REGS_BASE + 0x00040000) + +#define HW_CLKCTRL_PLLCTRL0_ADDR (REGS_CLKCTRL_BASE + 0x00) +HW_REGISTER(HW_CLKCTRL_PLLCTRL0, REGS_CLKCTRL_BASE, 0x00) +#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000 +#define HW_CLKCTRL_PLLCTRL1_ADDR (REGS_CLKCTRL_BASE + 0x10) +HW_REGISTER(HW_CLKCTRL_PLLCTRL1, REGS_CLKCTRL_BASE, 0x10) + +#define HW_CLKCTRL_CPU_ADDR (REGS_CLKCTRL_BASE + 0x20) +HW_REGISTER(HW_CLKCTRL_CPU, REGS_CLKCTRL_BASE, 0x20) +#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F +#define BF_CLKCTRL_CPU_DIV_CPU(v) \ + (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU) + +#define HW_CLKCTRL_HBUS_ADDR (REGS_CLKCTRL_BASE + 0x30) +HW_REGISTER(HW_CLKCTRL_HBUS, REGS_CLKCTRL_BASE, 0x30) +#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0 /* for compatitibility */ +#define BM_CLKCTRL_HBUS_DIV 0x0000001F +#define BF_CLKCTRL_HBUS_DIV(v) \ + (((v) << 0) & BM_CLKCTRL_HBUS_DIV) +#define HW_CLKCTRL_XBUS_ADDR (REGS_CLKCTRL_BASE + 0x40) +HW_REGISTER(HW_CLKCTRL_XBUS, REGS_CLKCTRL_BASE, 0x40) +#define HW_CLKCTRL_XTAL_ADDR (REGS_CLKCTRL_BASE + 0x50) +HW_REGISTER(HW_CLKCTRL_XTAL, REGS_CLKCTRL_BASE, 0x50) +#define HW_CLKCTRL_PIX_ADDR (REGS_CLKCTRL_BASE + 0x60) +HW_REGISTER(HW_CLKCTRL_PIX, REGS_CLKCTRL_BASE, 0x60) +#define BM_CLKCTRL_PIX_CLKGATE 0x80000000 +#define BM_CLKCTRL_PIX_BUSY 0x20000000 +#define BM_CLKCTRL_PIX_DIV 0x00007FFF +#define BP_CLKCTRL_PIX_DIV 0 +#define BF_CLKCTRL_PIX_DIV(v) \ + (((v) << BP_CLKCTRL_PIX_DIV) & BM_CLKCTRL_PIX_DIV) +#define HW_CLKCTRL_SSP_ADDR (REGS_CLKCTRL_BASE + 0x70) +HW_REGISTER(HW_CLKCTRL_SSP, REGS_CLKCTRL_BASE, 0x70) +#define HW_CLKCTRL_GPMI_ADDR (REGS_CLKCTRL_BASE + 0x80) +HW_REGISTER(HW_CLKCTRL_GPMI, REGS_CLKCTRL_BASE, 0x80) +#define HW_CLKCTRL_SPDIF_ADDR (REGS_CLKCTRL_BASE + 0x90) +HW_REGISTER(HW_CLKCTRL_SPDIF, REGS_CLKCTRL_BASE, 0x90) +#define HW_CLKCTRL_EMI_ADDR (REGS_CLKCTRL_BASE + 0xA0) +HW_REGISTER(HW_CLKCTRL_EMI, REGS_CLKCTRL_BASE, 0xA0) +#define HW_CLKCTRL_IR_ADDR (REGS_CLKCTRL_BASE + 0xB0) +HW_REGISTER(HW_CLKCTRL_IR, REGS_CLKCTRL_BASE, 0xB0) +#define HW_CLKCTRL_SAIF_ADDR (REGS_CLKCTRL_BASE + 0xC0) +HW_REGISTER(HW_CLKCTRL_SAIF, REGS_CLKCTRL_BASE, 0xC0) +#define HW_CLKCTRL_FRAC_ADDR (REGS_CLKCTRL_BASE + 0xD0) +HW_REGISTER(HW_CLKCTRL_FRAC, REGS_CLKCTRL_BASE, 0xD0) +#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000 +#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000 +#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000 +#define BP_CLKCTRL_FRAC_IOFRAC 24 +#define BF_CLKCTRL_FRAC_IOFRAC(v) \ + (((v) << BP_CLKCTRL_FRAC_IOFRAC) & BM_CLKCTRL_FRAC_IOFRAC) +#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000 +#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000 +#define BP_CLKCTRL_FRAC_PIXFRAC 16 +#define BF_CLKCTRL_FRAC_PIXFRAC(v) \ + (((v) << BP_CLKCTRL_FRAC_PIXFRAC) & BM_CLKCTRL_FRAC_PIXFRAC) +#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000 +#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00 +#define BP_CLKCTRL_FRAC_EMIFRAC 8 +#define BF_CLKCTRL_FRAC_EMIFRAC(v) \ + (((v) << BP_CLKCTRL_FRAC_EMIFRAC) & BM_CLKCTRL_FRAC_EMIFRAC) +#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080 +#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F +#define BP_CLKCTRL_FRAC_CPUFRAC 0 +#define BF_CLKCTRL_FRAC_CPUFRAC(v) \ + (((v) << BP_CLKCTRL_FRAC_CPUFRAC) & BM_CLKCTRL_FRAC_CPUFRAC) +#define HW_CLKCTRL_CLKSEQ_ADDR (REGS_CLKCTRL_BASE + 0xE0) +HW_REGISTER(HW_CLKCTRL_CLKSEQ, REGS_CLKCTRL_BASE, 0xE0) +#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080 +#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040 +#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020 +#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010 +#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008 +#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002 +#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001 +HW_REGISTER_WO(HW_CLKCTRL_RESET, REGS_CLKCTRL_BASE, 0xF0) +#define BM_CLKCTRL_RESET_CHIP 0x00000002 +#define BM_CLKCTRL_RESET_DIG 0x00000001 +#endif /* _INCLUDE_ASM_ARCH_REGS_CLKCTRL_H */ diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h b/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h new file mode 100644 index 000000000000..8a92f923f6bd --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h @@ -0,0 +1,36 @@ +/* + * Freescale STMP378X: clock registers definitions + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#ifndef _INCLUDE_ASM_ARCH_REGS_ICOLL_H +#define _INCLUDE_ASM_ARCH_REGS_ICOLL_H + + +#include + +#define REGS_ICOLL_BASE (REGS_BASE + 0x00000000) + +HW_REGISTER(HW_ICOLL_VECTOR, REGS_ICOLL_BASE, 0x00) +HW_REGISTER_WO(HW_ICOLL_LEVELACK, REGS_ICOLL_BASE, 0x10) +HW_REGISTER(HW_ICOLL_CTRL, REGS_ICOLL_BASE, 0x20) +#define BM_ICOLL_CTRL_CLKGATE 0x40000000 +#define BM_ICOLL_CTRL_SFTRST 0x80000000 +HW_REGISTER_RO(HW_ICOLL_STAT, REGS_ICOLL_BASE, 0x30) + +HW_REGISTER_INDEXED(HW_ICOLL_PRIORITYn, REGS_ICOLL_BASE, 0x60, 0x10) + +#endif /* _INCLUDE_ASM_ARCH_REGS_CLKCTRL_H */ diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h b/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h new file mode 100644 index 000000000000..b114ecd9a5eb --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h @@ -0,0 +1,159 @@ +/* + * STMP pinmux register definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * + * 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 _INCLUDE_ASM_ARCH_REGS_PINCTRL_H +#define _INCLUDE_ASM_ARCH_REGS_PINCTRL_H + +#include + +#ifndef REGS_PINCTRL_BASE +#define REGS_PINCTRL_BASE (REGS_BASE + 0x00018000) +#endif /* REGS_PINCTRL_BASE */ + +HW_REGISTER(HW_PINCTRL_CTRL, REGS_PINCTRL_BASE, 0) + +#define HW_PINCTRL_MUXSEL0_ADDR (REGS_PINCTRL_BASE + 0x100) +HW_REGISTER(HW_PINCTRL_MUXSEL0, REGS_PINCTRL_BASE, 0x100) +#define HW_PINCTRL_MUXSEL1_ADDR (REGS_PINCTRL_BASE + 0x110) +HW_REGISTER(HW_PINCTRL_MUXSEL1, REGS_PINCTRL_BASE, 0x110) +#define HW_PINCTRL_MUXSEL2_ADDR (REGS_PINCTRL_BASE + 0x120) +HW_REGISTER(HW_PINCTRL_MUXSEL2, REGS_PINCTRL_BASE, 0x120) +#define HW_PINCTRL_MUXSEL3_ADDR (REGS_PINCTRL_BASE + 0x130) +HW_REGISTER(HW_PINCTRL_MUXSEL3, REGS_PINCTRL_BASE, 0x130) +#define BM_PINCTRL_MUXSEL3_BANK1_PIN28 0x03000000 +#define HW_PINCTRL_MUXSEL4_ADDR (REGS_PINCTRL_BASE + 0x140) +HW_REGISTER(HW_PINCTRL_MUXSEL4, REGS_PINCTRL_BASE, 0x140) +#define BM_PINCTRL_MUXSEL4_BANK2_PIN03 0x000000C0 +#define BM_PINCTRL_MUXSEL4_BANK2_PIN04 0x00000300 +#define HW_PINCTRL_MUXSEL5_ADDR (REGS_PINCTRL_BASE + 0x150) +HW_REGISTER(HW_PINCTRL_MUXSEL5, REGS_PINCTRL_BASE, 0x150) +#define HW_PINCTRL_MUXSEL6_ADDR (REGS_PINCTRL_BASE + 0x160) +HW_REGISTER(HW_PINCTRL_MUXSEL6, REGS_PINCTRL_BASE, 0x160) +#define HW_PINCTRL_MUXSEL7_ADDR (REGS_PINCTRL_BASE + 0x170) +HW_REGISTER(HW_PINCTRL_MUXSEL7, REGS_PINCTRL_BASE, 0x170) + +HW_REGISTER(HW_PINCTRL_DRIVE0, REGS_PINCTRL_BASE, 0x200) +#define HW_PINCTRL_DRIVE0_ADDR (REGS_PINCTRL_BASE + 0x200) +HW_REGISTER(HW_PINCTRL_DRIVE1, REGS_PINCTRL_BASE, 0x210) +#define HW_PINCTRL_DRIVE1_ADDR (REGS_PINCTRL_BASE + 0x210) +HW_REGISTER(HW_PINCTRL_DRIVE2, REGS_PINCTRL_BASE, 0x220) +#define HW_PINCTRL_DRIVE2_ADDR (REGS_PINCTRL_BASE + 0x220) +HW_REGISTER(HW_PINCTRL_DRIVE3, REGS_PINCTRL_BASE, 0x230) +#define HW_PINCTRL_DRIVE3_ADDR (REGS_PINCTRL_BASE + 0x230) +HW_REGISTER(HW_PINCTRL_DRIVE4, REGS_PINCTRL_BASE, 0x240) +#define HW_PINCTRL_DRIVE4_ADDR (REGS_PINCTRL_BASE + 0x240) +HW_REGISTER(HW_PINCTRL_DRIVE5, REGS_PINCTRL_BASE, 0x250) +#define HW_PINCTRL_DRIVE5_ADDR (REGS_PINCTRL_BASE + 0x250) +HW_REGISTER(HW_PINCTRL_DRIVE6, REGS_PINCTRL_BASE, 0x260) +#define HW_PINCTRL_DRIVE6_ADDR (REGS_PINCTRL_BASE + 0x260) +HW_REGISTER(HW_PINCTRL_DRIVE7, REGS_PINCTRL_BASE, 0x270) +#define HW_PINCTRL_DRIVE7_ADDR (REGS_PINCTRL_BASE + 0x270) +HW_REGISTER(HW_PINCTRL_DRIVE8, REGS_PINCTRL_BASE, 0x280) +#define HW_PINCTRL_DRIVE8_ADDR (REGS_PINCTRL_BASE + 0x280) +HW_REGISTER(HW_PINCTRL_DRIVE9, REGS_PINCTRL_BASE, 0x290) +#define HW_PINCTRL_DRIVE9_ADDR (REGS_PINCTRL_BASE + 0x290) +HW_REGISTER(HW_PINCTRL_DRIVE10, REGS_PINCTRL_BASE, 0x2a0) +#define HW_PINCTRL_DRIVE10_ADDR (REGS_PINCTRL_BASE + 0x2a0) +HW_REGISTER(HW_PINCTRL_DRIVE11, REGS_PINCTRL_BASE, 0x2b0) +#define HW_PINCTRL_DRIVE11_ADDR (REGS_PINCTRL_BASE + 0x2b0) +HW_REGISTER(HW_PINCTRL_DRIVE12, REGS_PINCTRL_BASE, 0x2c0) +#define HW_PINCTRL_DRIVE12_ADDR (REGS_PINCTRL_BASE + 0x2c0) +HW_REGISTER(HW_PINCTRL_DRIVE13, REGS_PINCTRL_BASE, 0x2d0) +#define HW_PINCTRL_DRIVE13_ADDR (REGS_PINCTRL_BASE + 0x2d0) +HW_REGISTER(HW_PINCTRL_DRIVE14, REGS_PINCTRL_BASE, 0x2e0) +#define HW_PINCTRL_DRIVE14_ADDR (REGS_PINCTRL_BASE + 0x2e0) + + +HW_REGISTER(HW_PINCTRL_PULL0, REGS_PINCTRL_BASE, 0x300) +#define HW_PINCTRL_PULL0_ADDR (REGS_PINCTRL_BASE + 0x300) +#define BM_PINCTRL_PULL0_BANK0_PIN01 0x00000002 +#define BM_PINCTRL_PULL0_BANK0_PIN02 0x00000004 +#define BM_PINCTRL_PULL0_BANK0_PIN03 0x00000008 +#define BM_PINCTRL_PULL0_BANK0_PIN04 0x00000010 +#define BM_PINCTRL_PULL0_BANK0_PIN20 0x00100000 +HW_REGISTER(HW_PINCTRL_PULL1, REGS_PINCTRL_BASE, 0x310) +#define HW_PINCTRL_PULL1_ADDR (REGS_PINCTRL_BASE + 0x310) +#define BM_PINCTRL_PULL1_BANK1_PIN22 0x00400000 +#define BM_PINCTRL_PULL1_BANK1_PIN24 0x01000000 +#define BM_PINCTRL_PULL1_BANK1_PIN25 0x02000000 +#define BM_PINCTRL_PULL1_BANK1_PIN26 0x04000000 +#define BM_PINCTRL_PULL1_BANK1_PIN27 0x08000000 +HW_REGISTER(HW_PINCTRL_PULL2, REGS_PINCTRL_BASE, 0x320) +#define HW_PINCTRL_PULL2_ADDR (REGS_PINCTRL_BASE + 0x320) +HW_REGISTER(HW_PINCTRL_PULL3, REGS_PINCTRL_BASE, 0x330) +#define HW_PINCTRL_PULL3_ADDR (REGS_PINCTRL_BASE + 0x330) + +#define HW_PINCTRL_DOUT0_ADDR (REGS_PINCTRL_BASE + 0x400) +HW_REGISTER(HW_PINCTRL_DOUT0, REGS_PINCTRL_BASE, 0x400) +#define HW_PINCTRL_DOUT1_ADDR (REGS_PINCTRL_BASE + 0x410) +HW_REGISTER(HW_PINCTRL_DOUT1, REGS_PINCTRL_BASE, 0x410) +#define HW_PINCTRL_DOUT2_ADDR (REGS_PINCTRL_BASE + 0x420) +HW_REGISTER(HW_PINCTRL_DOUT2, REGS_PINCTRL_BASE, 0x420) + +#define HW_PINCTRL_DIN0_ADDR (REGS_PINCTRL_BASE + 0x500) +HW_REGISTER_RO(HW_PINCTRL_DIN0, REGS_PINCTRL_BASE, 0x500) +#define HW_PINCTRL_DIN1_ADDR (REGS_PINCTRL_BASE + 0x510) +HW_REGISTER_RO(HW_PINCTRL_DIN1, REGS_PINCTRL_BASE, 0x510) +#define HW_PINCTRL_DIN2_ADDR (REGS_PINCTRL_BASE + 0x520) +HW_REGISTER_RO(HW_PINCTRL_DIN2, REGS_PINCTRL_BASE, 0x520) + +#define HW_PINCTRL_DOE0_ADDR (REGS_PINCTRL_BASE + 0x600) +HW_REGISTER(HW_PINCTRL_DOE0, REGS_PINCTRL_BASE, 0x600) +#define HW_PINCTRL_DOE1_ADDR (REGS_PINCTRL_BASE + 0x610) +HW_REGISTER(HW_PINCTRL_DOE1, REGS_PINCTRL_BASE, 0x610) +#define HW_PINCTRL_DOE2_ADDR (REGS_PINCTRL_BASE + 0x620) +HW_REGISTER(HW_PINCTRL_DOE2, REGS_PINCTRL_BASE, 0x620) + +HW_REGISTER(HW_PINCTRL_PIN2IRQ0, REGS_PINCTRL_BASE, 0x700) +#define HW_PINCTRL_PIN2IRQ0_ADDR (REGS_PINCTRL_BASE + 0x700) +HW_REGISTER(HW_PINCTRL_PIN2IRQ1, REGS_PINCTRL_BASE, 0x710) +#define HW_PINCTRL_PIN2IRQ1_ADDR (REGS_PINCTRL_BASE + 0x710) +HW_REGISTER(HW_PINCTRL_PIN2IRQ2, REGS_PINCTRL_BASE, 0x720) +#define HW_PINCTRL_PIN2IRQ2_ADDR (REGS_PINCTRL_BASE + 0x720) + +HW_REGISTER(HW_PINCTRL_IRQEN0, REGS_PINCTRL_BASE, 0x800) +#define HW_PINCTRL_IRQEN0_ADDR (REGS_PINCTRL_BASE + 0x800) +HW_REGISTER(HW_PINCTRL_IRQEN1, REGS_PINCTRL_BASE, 0x810) +#define HW_PINCTRL_IRQEN1_ADDR (REGS_PINCTRL_BASE + 0x810) +HW_REGISTER(HW_PINCTRL_IRQEN2, REGS_PINCTRL_BASE, 0x820) +#define HW_PINCTRL_IRQEN2_ADDR (REGS_PINCTRL_BASE + 0x820) + +HW_REGISTER(HW_PINCTRL_IRQLEVEL0, REGS_PINCTRL_BASE, 0x900) +#define HW_PINCTRL_IRQLEVEL0_ADDR (REGS_PINCTRL_BASE + 0x900) +HW_REGISTER(HW_PINCTRL_IRQLEVEL1, REGS_PINCTRL_BASE, 0x910) +#define HW_PINCTRL_IRQLEVEL1_ADDR (REGS_PINCTRL_BASE + 0x910) +HW_REGISTER(HW_PINCTRL_IRQLEVEL2, REGS_PINCTRL_BASE, 0x920) +#define HW_PINCTRL_IRQLEVEL2_ADDR (REGS_PINCTRL_BASE + 0x920) + +HW_REGISTER(HW_PINCTRL_IRQPOL0, REGS_PINCTRL_BASE, 0xA00) +#define HW_PINCTRL_IRQPOL0_ADDR (REGS_PINCTRL_BASE + 0xa00) +HW_REGISTER(HW_PINCTRL_IRQPOL1, REGS_PINCTRL_BASE, 0xA10) +#define HW_PINCTRL_IRQPOL1_ADDR (REGS_PINCTRL_BASE + 0xa10) +HW_REGISTER(HW_PINCTRL_IRQPOL2, REGS_PINCTRL_BASE, 0xA20) +#define HW_PINCTRL_IRQPOL2_ADDR (REGS_PINCTRL_BASE + 0xa20) + +HW_REGISTER(HW_PINCTRL_IRQSTAT0, REGS_PINCTRL_BASE, 0xB00) +#define HW_PINCTRL_IRQSTAT0_ADDR (REGS_PINCTRL_BASE + 0xb00) +HW_REGISTER(HW_PINCTRL_IRQSTAT1, REGS_PINCTRL_BASE, 0xB10) +#define HW_PINCTRL_IRQSTAT1_ADDR (REGS_PINCTRL_BASE + 0xb10) +HW_REGISTER(HW_PINCTRL_IRQSTAT2, REGS_PINCTRL_BASE, 0xB20) +#define HW_PINCTRL_IRQSTAT2_ADDR (REGS_PINCTRL_BASE + 0xb20) + +#endif /* _INCLUDE_ASM_ARCH_REGS_PINCTRL_H */ + diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-power.h b/arch/arm/mach-stmp37xx/include/mach/regs-power.h new file mode 100644 index 000000000000..d15cd6601e7f --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/regs-power.h @@ -0,0 +1,31 @@ +/* + * STMP POWER Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * + * 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 __ARCH_ARM___POWER_H +#define __ARCH_ARM___POWER_H 1 + +#include + +#define REGS_POWER_BASE (void __iomem *)(REGS_BASE + 0x44000) +#define REGS_POWER_BASE_PHYS (0x80044000) +#define REGS_POWER_SIZE 0x00002000 +HW_REGISTER(HW_POWER_MINPWR, REGS_POWER_BASE, 0x00000020) +HW_REGISTER(HW_POWER_CHARGE, REGS_POWER_BASE, 0x00000030) +#endif /* __ARCH_ARM___POWER_H */ diff --git a/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h b/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h new file mode 100644 index 000000000000..7f000306e890 --- /dev/null +++ b/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h @@ -0,0 +1,52 @@ +/* + * include/asm-arm/arch-stmp3xxx/regstimer.h + * + * Copyright (c) 2008 SigmaTel Inc + * Copyright (c) 2008 Embedded Alley Solutions, Inc + * + * 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 __ARCH_ARM_REGS_TIMROT_H +#define __ARCH_ARM_REGS_TIMROT_H + +#include + +#define REGS_TIMROT_BASE (REGS_BASE + 0x00068000) + +HW_REGISTER(HW_TIMROT_ROTCTRL, REGS_TIMROT_BASE, 0) +#define BM_TIMROT_ROTCTRL_SFTRST 0x80000000 +#define BM_TIMROT_ROTCTRL_CLKGATE 0x40000000 + +HW_REGISTER_INDEXED(HW_TIMROT_TIMCTRLn, REGS_TIMROT_BASE, 0x20, 0x20) +#define BM_TIMROT_TIMCTRLn_SELECT 0x0000000F +#define BF_TIMROT_TIMCTRLn_SELECT(v) (((v) << 0) & BM_TIMROT_TIMCTRLn_SELECT) +#define BM_TIMROT_TIMCTRLn_PRESCALE 0x00000030 +#define BF_TIMROT_TIMCTRLn_PRESCALE(v) \ + (((v) << 4) & BM_TIMROT_TIMCTRLn_PRESCALE) +#define BM_TIMROT_TIMCTRLn_RELOAD 0x00000040 +#define BF_TIMROT_TIMCTRLn_RELOAD(v) (((v) << 6) & BM_TIMROT_TIMCTRLn_RELOAD) +#define BM_TIMROT_TIMCTRLn_UPDATE 0x00000080 +#define BF_TIMROT_TIMCTRLn_UPDATE(v) (((v) << 7) & BM_TIMROT_TIMCTRLn_UPDATE) +#define BM_TIMROT_TIMCTRLn_POLARITY 0x00000100 +#define BF_TIMROT_TIMCTRLn_POLARITY(v) \ + (((v) << 8) & BM_TIMROT_TIMCTRLn_POLARITY) +#define BM_TIMROT_TIMCTRLn_IRQ_EN 0x00004000 +#define BF_TIMROT_TIMCTRLn_IRQ_EN(v) \ + (((v) << 14) & BM_TIMROT_TIMCTRLn_IRQ_EN) +#define BM_TIMROT_TIMCTRLn_IRQ 0x00008000 +#define BF_TIMROT_TIMCTRLn_IRQ(v) (((v) << 15) & BM_TIMROT_TIMCTRLn_IRQ) +HW_REGISTER_0_INDEXED(HW_TIMROT_TIMCOUNTn, REGS_TIMROT_BASE, 0x30, 0x20) + +#endif /* __ARCH_ARM_REGSTIMER_H */ -- GitLab From 07d9714365bcab286389d679f73512e35796847c Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Wed, 22 Apr 2009 23:54:42 +0100 Subject: [PATCH 0718/6080] [ARM] 5467/1: Freescale STMP platform support [4/10] Minimal definition of register set for 378x boards Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- .../mach-stmp378x/include/mach/regs-apbh.h | 88 ++++++ .../mach-stmp378x/include/mach/regs-apbx.h | 79 +++++ .../mach-stmp378x/include/mach/regs-clkctrl.h | 276 ++++++++++++++++++ .../mach-stmp378x/include/mach/regs-icoll.h | 213 ++++++++++++++ .../mach-stmp378x/include/mach/regs-pinctrl.h | 143 +++++++++ .../mach-stmp378x/include/mach/regs-power.h | 32 ++ .../mach-stmp378x/include/mach/regs-timrot.h | 216 ++++++++++++++ 7 files changed, 1047 insertions(+) create mode 100644 arch/arm/mach-stmp378x/include/mach/regs-apbh.h create mode 100644 arch/arm/mach-stmp378x/include/mach/regs-apbx.h create mode 100644 arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h create mode 100644 arch/arm/mach-stmp378x/include/mach/regs-icoll.h create mode 100644 arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h create mode 100644 arch/arm/mach-stmp378x/include/mach/regs-power.h create mode 100644 arch/arm/mach-stmp378x/include/mach/regs-timrot.h diff --git a/arch/arm/mach-stmp378x/include/mach/regs-apbh.h b/arch/arm/mach-stmp378x/include/mach/regs-apbh.h new file mode 100644 index 000000000000..db63b041e4f0 --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/regs-apbh.h @@ -0,0 +1,88 @@ +/* + * STMP APBH Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * Copyright 2008 Embedded Alley Solutions, 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 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 __ARCH_ARM___APBH_H +#define __ARCH_ARM___APBH_H 1 + +#include + +#define REGS_APBH_BASE (REGS_BASE + 0x4000) +#define REGS_APBH_BASE_PHYS (0x80004000) +#define REGS_APBH_SIZE 0x00002000 +HW_REGISTER(HW_APBH_CTRL0, REGS_APBH_BASE, 0x00000000) +#define HW_APBH_CTRL0_ADDR (REGS_APBH_BASE + 0x00000000) +#define BM_APBH_CTRL0_SFTRST 0x80000000 +#define BM_APBH_CTRL0_CLKGATE 0x40000000 +#define BM_APBH_CTRL0_AHB_BURST8_EN 0x20000000 +#define BM_APBH_CTRL0_APB_BURST4_EN 0x10000000 +#define BP_APBH_CTRL0_RESET_CHANNEL 16 +#define BM_APBH_CTRL0_RESET_CHANNEL 0x00FF0000 +#define BF_APBH_CTRL0_RESET_CHANNEL(v) \ + (((v) << 16) & BM_APBH_CTRL0_RESET_CHANNEL) +HW_REGISTER(HW_APBH_CTRL1, REGS_APBH_BASE, 0x00000010) +#define HW_APBH_CTRL1_ADDR (REGS_APBH_BASE + 0x00000010) +HW_REGISTER(HW_APBH_CTRL2, REGS_APBH_BASE, 0x00000020) +HW_REGISTER_0(HW_APBH_DEVSEL, REGS_APBH_BASE, 0x00000030) +HW_REGISTER_0_INDEXED(HW_APBH_CHn_CURCMDAR, REGS_APBH_BASE, 0x00000040, 0x70) +#define BP_APBH_CHn_CURCMDAR_CMD_ADDR 0 +#define BM_APBH_CHn_CURCMDAR_CMD_ADDR 0xFFFFFFFF +#define BF_APBH_CHn_CURCMDAR_CMD_ADDR(v) (v) +HW_REGISTER_0_INDEXED(HW_APBH_CHn_NXTCMDAR, REGS_APBH_BASE, 0x00000050, 0x70) +HW_REGISTER_0_INDEXED(HW_APBH_CHn_CMD, REGS_APBH_BASE, 0x00000060, 0x70) +#define BP_APBH_CHn_CMD_XFER_COUNT 16 +#define BM_APBH_CHn_CMD_XFER_COUNT 0xFFFF0000 +#define BF_APBH_CHn_CMD_XFER_COUNT(v) \ + (((v) << 16) & BM_APBH_CHn_CMD_XFER_COUNT) +#define BP_APBH_CHn_CMD_CMDWORDS 12 +#define BM_APBH_CHn_CMD_CMDWORDS 0x0000F000 +#define BF_APBH_CHn_CMD_CMDWORDS(v) \ + (((v) << 12) & BM_APBH_CHn_CMD_CMDWORDS) +#define BM_APBH_CHn_CMD_HALTONTERMINATE 0x00000100 +#define BM_APBH_CHn_CMD_WAIT4ENDCMD 0x00000080 +#define BM_APBH_CHn_CMD_SEMAPHORE 0x00000040 +#define BM_APBH_CHn_CMD_NANDWAIT4READY 0x00000020 +#define BM_APBH_CHn_CMD_NANDLOCK 0x00000010 +#define BM_APBH_CHn_CMD_IRQONCMPLT 0x00000008 +#define BM_APBH_CHn_CMD_CHAIN 0x00000004 +#define BP_APBH_CHn_CMD_COMMAND 0 +#define BM_APBH_CHn_CMD_COMMAND 0x00000003 +#define BF_APBH_CHn_CMD_COMMAND(v) \ + (((v) << 0) & BM_APBH_CHn_CMD_COMMAND) +#define BV_APBH_CHn_CMD_COMMAND__NO_DMA_XFER 0x0 +#define BV_APBH_CHn_CMD_COMMAND__DMA_WRITE 0x1 +#define BV_APBH_CHn_CMD_COMMAND__DMA_READ 0x2 +#define BV_APBH_CHn_CMD_COMMAND__DMA_SENSE 0x3 +HW_REGISTER_0_INDEXED(HW_APBH_CHn_BAR, REGS_APBH_BASE, 0x00000070, 0x70) +HW_REGISTER_0_INDEXED(HW_APBH_CHn_SEMA, REGS_APBH_BASE, 0x00000080, 0x70) +#define BP_APBH_CHn_SEMA_PHORE 16 +#define BM_APBH_CHn_SEMA_PHORE 0x00FF0000 +#define BF_APBH_CHn_SEMA_PHORE(v) \ + (((v) << 16) & BM_APBH_CHn_SEMA_PHORE) +#define BP_APBH_CHn_SEMA_INCREMENT_SEMA 0 +#define BM_APBH_CHn_SEMA_INCREMENT_SEMA 0x000000FF +#define BF_APBH_CHn_SEMA_INCREMENT_SEMA(v) \ + (((v) << 0) & BM_APBH_CHn_SEMA_INCREMENT_SEMA) +HW_REGISTER_0_INDEXED(HW_APBH_CHn_DEBUG1, REGS_APBH_BASE, 0x00000090, 0x70) +HW_REGISTER_0_INDEXED(HW_APBH_CHn_DEBUG2, REGS_APBH_BASE, 0x000000a0, 0x70) +HW_REGISTER_0(HW_APBH_VERSION, REGS_APBH_BASE, 0x000003f0) +#endif /* __ARCH_ARM___APBH_H */ diff --git a/arch/arm/mach-stmp378x/include/mach/regs-apbx.h b/arch/arm/mach-stmp378x/include/mach/regs-apbx.h new file mode 100644 index 000000000000..d0e8e9fe1cce --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/regs-apbx.h @@ -0,0 +1,79 @@ +/* + * STMP APBX Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * Copyright 2008 Embedded Alley Solutions, 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 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 __ARCH_ARM___APBX_H +#define __ARCH_ARM___APBX_H 1 + +#include + +#define REGS_APBX_BASE (REGS_BASE + 0x24000) +#define REGS_APBX_BASE_PHYS (0x80024000) +#define REGS_APBX_SIZE 0x00002000 +HW_REGISTER(HW_APBX_CTRL0, REGS_APBX_BASE, 0x00000000) +#define HW_APBX_CTRL0_ADDR (REGS_APBX_BASE + 0x00000000) +#define BM_APBX_CTRL0_SFTRST 0x80000000 +#define BM_APBX_CTRL0_CLKGATE 0x40000000 +HW_REGISTER(HW_APBX_CTRL1, REGS_APBX_BASE, 0x00000010) +HW_REGISTER(HW_APBX_CTRL2, REGS_APBX_BASE, 0x00000020) +HW_REGISTER(HW_APBX_CHANNEL_CTRL, REGS_APBX_BASE, 0x00000030) +#define BP_APBX_CHANNEL_CTRL_RESET_CHANNEL 16 +#define BM_APBX_CHANNEL_CTRL_RESET_CHANNEL 0xFFFF0000 +#define BF_APBX_CHANNEL_CTRL_RESET_CHANNEL(v) \ + (((v) << BP_APBX_CHANNEL_CTRL_RESET_CHANNEL) & \ + BM_APBX_CHANNEL_CTRL_RESET_CHANNEL) +HW_REGISTER_0(HW_APBX_DEVSEL, REGS_APBX_BASE, 0x00000040) +HW_REGISTER_0_INDEXED(HW_APBX_CHn_CURCMDAR, REGS_APBX_BASE, 0x00000100, 0x70) +HW_REGISTER_0_INDEXED(HW_APBX_CHn_NXTCMDAR, REGS_APBX_BASE, 0x00000110, 0x70) +HW_REGISTER_0_INDEXED(HW_APBX_CHn_CMD, REGS_APBX_BASE, 0x00000120, 0x70) +#define BP_APBX_CHn_CMD_XFER_COUNT 16 +#define BM_APBX_CHn_CMD_XFER_COUNT 0xFFFF0000 +#define BF_APBX_CHn_CMD_XFER_COUNT(v) \ + (((v) << 16) & BM_APBX_CHn_CMD_XFER_COUNT) +#define BP_APBX_CHn_CMD_CMDWORDS 12 +#define BM_APBX_CHn_CMD_CMDWORDS 0x0000F000 +#define BF_APBX_CHn_CMD_CMDWORDS(v) \ + (((v) << 12) & BM_APBX_CHn_CMD_CMDWORDS) +#define BM_APBX_CHn_CMD_HALTONTERMINATE 0x00000100 +#define BM_APBX_CHn_CMD_WAIT4ENDCMD 0x00000080 +#define BM_APBX_CHn_CMD_SEMAPHORE 0x00000040 +#define BM_APBX_CHn_CMD_IRQONCMPLT 0x00000008 +#define BM_APBX_CHn_CMD_CHAIN 0x00000004 +#define BP_APBX_CHn_CMD_COMMAND 0 +#define BM_APBX_CHn_CMD_COMMAND 0x00000003 +#define BF_APBX_CHn_CMD_COMMAND(v) \ + (((v) << 0) & BM_APBX_CHn_CMD_COMMAND) +#define BV_APBX_CHn_CMD_COMMAND__NO_DMA_XFER 0x0 +#define BV_APBX_CHn_CMD_COMMAND__DMA_WRITE 0x1 +#define BV_APBX_CHn_CMD_COMMAND__DMA_READ 0x2 +HW_REGISTER_0_INDEXED(HW_APBX_CHn_BAR, REGS_APBX_BASE, 0x00000130, 0x70) +HW_REGISTER_0_INDEXED(HW_APBX_CHn_SEMA, REGS_APBX_BASE, 0x00000140, 0x70) +#define BP_APBX_CHn_SEMA_PHORE 16 +#define BM_APBX_CHn_SEMA_PHORE 0x00FF0000 +#define BF_APBX_CHn_SEMA_PHORE(v) \ + (((v) << 16) & BM_APBX_CHn_SEMA_PHORE) +#define BP_APBX_CHn_SEMA_INCREMENT_SEMA 0 +#define BM_APBX_CHn_SEMA_INCREMENT_SEMA 0x000000FF +#define BF_APBX_CHn_SEMA_INCREMENT_SEMA(v) \ + (((v) << 0) & BM_APBX_CHn_SEMA_INCREMENT_SEMA) +HW_REGISTER_0_INDEXED(HW_APBX_CHn_DEBUG1, REGS_APBX_BASE, 0x00000150, 0x70) +HW_REGISTER_0_INDEXED(HW_APBX_CHn_DEBUG2, REGS_APBX_BASE, 0x00000160, 0x70) +HW_REGISTER_0(HW_APBX_VERSION, REGS_APBX_BASE, 0x00000800) +#endif /* __ARCH_ARM___APBX_H */ diff --git a/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h b/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h new file mode 100644 index 000000000000..a421d9e0cbff --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h @@ -0,0 +1,276 @@ +/* + * STMP CLKCTRL Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * Copyright 2008 Embedded Alley Solutions, 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 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 __ARCH_ARM___CLKCTRL_H +#define __ARCH_ARM___CLKCTRL_H 1 + +#include + +#define REGS_CLKCTRL_BASE (REGS_BASE + 0x40000) +#define REGS_CLKCTRL_BASE_PHYS (0x80040000) +#define REGS_CLKCTRL_SIZE 0x00002000 +HW_REGISTER(HW_CLKCTRL_PLLCTRL0, REGS_CLKCTRL_BASE, 0x00000000) +#define HW_CLKCTRL_PLLCTRL0_ADDR (REGS_CLKCTRL_BASE + 0x00000000) +#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28 +#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000 +#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \ + (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL) +#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0 +#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1 +#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2 +#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3 +#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24 +#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000 +#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \ + (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL) +#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0 +#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1 +#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2 +#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3 +#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20 +#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000 +#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \ + (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL) +#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0 +#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1 +#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2 +#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3 +#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000 +#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000 +HW_REGISTER_0(HW_CLKCTRL_PLLCTRL1, REGS_CLKCTRL_BASE, 0x00000010) +#define HW_CLKCTRL_PLLCTRL1_ADDR (REGS_CLKCTRL_BASE + 0x00000010) +#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000 +#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000 +#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0 +#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF +#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \ + (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT) +HW_REGISTER(HW_CLKCTRL_CPU, REGS_CLKCTRL_BASE, 0x00000020) +#define HW_CLKCTRL_CPU_ADDR (REGS_CLKCTRL_BASE + 0x00000020) +#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000 +#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000 +#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000 +#define BP_CLKCTRL_CPU_DIV_XTAL 16 +#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000 +#define BF_CLKCTRL_CPU_DIV_XTAL(v) \ + (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL) +#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000 +#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400 +#define BP_CLKCTRL_CPU_DIV_CPU 0 +#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F +#define BF_CLKCTRL_CPU_DIV_CPU(v) \ + (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU) +HW_REGISTER(HW_CLKCTRL_HBUS, REGS_CLKCTRL_BASE, 0x00000030) +#define HW_CLKCTRL_HBUS_ADDR (REGS_CLKCTRL_BASE + 0x00000030) +#define BM_CLKCTRL_HBUS_BUSY 0x20000000 +#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000 +#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x08000000 +#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000 +#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000 +#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000 +#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000 +#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000 +#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000 +#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE 0x00100000 +#define BP_CLKCTRL_HBUS_SLOW_DIV 16 +#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000 +#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \ + (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV) +#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0 +#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1 +#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2 +#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3 +#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4 +#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5 +#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020 +#define BP_CLKCTRL_HBUS_DIV 0 +#define BM_CLKCTRL_HBUS_DIV 0x0000001F +#define BF_CLKCTRL_HBUS_DIV(v) \ + (((v) << 0) & BM_CLKCTRL_HBUS_DIV) +HW_REGISTER_0(HW_CLKCTRL_XBUS, REGS_CLKCTRL_BASE, 0x00000040) +#define HW_CLKCTRL_XBUS_ADDR (REGS_CLKCTRL_BASE + 0x00000040) +#define BM_CLKCTRL_XBUS_BUSY 0x80000000 +#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400 +#define BP_CLKCTRL_XBUS_DIV 0 +#define BM_CLKCTRL_XBUS_DIV 0x000003FF +#define BF_CLKCTRL_XBUS_DIV(v) \ + (((v) << 0) & BM_CLKCTRL_XBUS_DIV) +HW_REGISTER(HW_CLKCTRL_XTAL, REGS_CLKCTRL_BASE, 0x00000050) +#define HW_CLKCTRL_XTAL_ADDR (REGS_CLKCTRL_BASE + 0x00000050) +#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000 +#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000 +#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000 +#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000 +#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000 +#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000 +#define BP_CLKCTRL_XTAL_DIV_UART 0 +#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003 +#define BF_CLKCTRL_XTAL_DIV_UART(v) \ + (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART) +HW_REGISTER_0(HW_CLKCTRL_PIX, REGS_CLKCTRL_BASE, 0x00000060) +#define HW_CLKCTRL_PIX_ADDR (REGS_CLKCTRL_BASE + 0x00000060) +#define BM_CLKCTRL_PIX_CLKGATE 0x80000000 +#define BM_CLKCTRL_PIX_BUSY 0x20000000 +#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000 +#define BP_CLKCTRL_PIX_DIV 0 +#define BM_CLKCTRL_PIX_DIV 0x00000FFF +#define BF_CLKCTRL_PIX_DIV(v) \ + (((v) << 0) & BM_CLKCTRL_PIX_DIV) +HW_REGISTER_0(HW_CLKCTRL_SSP, REGS_CLKCTRL_BASE, 0x00000070) +#define HW_CLKCTRL_SSP_ADDR (REGS_CLKCTRL_BASE + 0x00000070) +#define BM_CLKCTRL_SSP_CLKGATE 0x80000000 +#define BM_CLKCTRL_SSP_BUSY 0x20000000 +#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200 +#define BP_CLKCTRL_SSP_DIV 0 +#define BM_CLKCTRL_SSP_DIV 0x000001FF +#define BF_CLKCTRL_SSP_DIV(v) \ + (((v) << 0) & BM_CLKCTRL_SSP_DIV) +HW_REGISTER_0(HW_CLKCTRL_GPMI, REGS_CLKCTRL_BASE, 0x00000080) +#define HW_CLKCTRL_GPMI_ADDR (REGS_CLKCTRL_BASE + 0x00000080) +#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000 +#define BM_CLKCTRL_GPMI_BUSY 0x20000000 +#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400 +#define BP_CLKCTRL_GPMI_DIV 0 +#define BM_CLKCTRL_GPMI_DIV 0x000003FF +#define BF_CLKCTRL_GPMI_DIV(v) \ + (((v) << 0) & BM_CLKCTRL_GPMI_DIV) +HW_REGISTER_0(HW_CLKCTRL_SPDIF, REGS_CLKCTRL_BASE, 0x00000090) +#define HW_CLKCTRL_SPDIF_ADDR (REGS_CLKCTRL_BASE + 0x00000090) +#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000 +HW_REGISTER_0(HW_CLKCTRL_EMI, REGS_CLKCTRL_BASE, 0x000000a0) +#define HW_CLKCTRL_EMI_ADDR (REGS_CLKCTRL_BASE + 0x000000a0) +#define BM_CLKCTRL_EMI_CLKGATE 0x80000000 +#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000 +#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000 +#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000 +#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000 +#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000 +#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000 +#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000 +#define BP_CLKCTRL_EMI_DIV_XTAL 8 +#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00 +#define BF_CLKCTRL_EMI_DIV_XTAL(v) \ + (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL) +#define BP_CLKCTRL_EMI_DIV_EMI 0 +#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F +#define BF_CLKCTRL_EMI_DIV_EMI(v) \ + (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI) +HW_REGISTER_0(HW_CLKCTRL_IR, REGS_CLKCTRL_BASE, 0x000000b0) +#define HW_CLKCTRL_IR_ADDR (REGS_CLKCTRL_BASE + 0x000000b0) +#define BM_CLKCTRL_IR_CLKGATE 0x80000000 +#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000 +#define BM_CLKCTRL_IR_IR_BUSY 0x10000000 +#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000 +#define BP_CLKCTRL_IR_IROV_DIV 16 +#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000 +#define BF_CLKCTRL_IR_IROV_DIV(v) \ + (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV) +#define BP_CLKCTRL_IR_IR_DIV 0 +#define BM_CLKCTRL_IR_IR_DIV 0x000003FF +#define BF_CLKCTRL_IR_IR_DIV(v) \ + (((v) << 0) & BM_CLKCTRL_IR_IR_DIV) +HW_REGISTER_0(HW_CLKCTRL_SAIF, REGS_CLKCTRL_BASE, 0x000000c0) +#define HW_CLKCTRL_SAIF_ADDR (REGS_CLKCTRL_BASE + 0x000000c0) +#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000 +#define BM_CLKCTRL_SAIF_BUSY 0x20000000 +#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000 +#define BP_CLKCTRL_SAIF_DIV 0 +#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF +#define BF_CLKCTRL_SAIF_DIV(v) \ + (((v) << 0) & BM_CLKCTRL_SAIF_DIV) +HW_REGISTER_0(HW_CLKCTRL_TV, REGS_CLKCTRL_BASE, 0x000000d0) +#define HW_CLKCTRL_TV_ADDR (REGS_CLKCTRL_BASE + 0x000000d0) +#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000 +#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000 +HW_REGISTER_0(HW_CLKCTRL_ETM, REGS_CLKCTRL_BASE, 0x000000e0) +#define HW_CLKCTRL_ETM_ADDR (REGS_CLKCTRL_BASE + 0x000000e0) +#define BM_CLKCTRL_ETM_CLKGATE 0x80000000 +#define BM_CLKCTRL_ETM_BUSY 0x20000000 +#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040 +#define BP_CLKCTRL_ETM_DIV 0 +#define BM_CLKCTRL_ETM_DIV 0x0000003F +#define BF_CLKCTRL_ETM_DIV(v) \ + (((v) << 0) & BM_CLKCTRL_ETM_DIV) +HW_REGISTER(HW_CLKCTRL_FRAC, REGS_CLKCTRL_BASE, 0x000000f0) +#define HW_CLKCTRL_FRAC_ADDR (REGS_CLKCTRL_BASE + 0x000000f0) +#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000 +#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000 +#define BP_CLKCTRL_FRAC_IOFRAC 24 +#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000 +#define BF_CLKCTRL_FRAC_IOFRAC(v) \ + (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC) +#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000 +#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000 +#define BP_CLKCTRL_FRAC_PIXFRAC 16 +#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000 +#define BF_CLKCTRL_FRAC_PIXFRAC(v) \ + (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC) +#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000 +#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000 +#define BP_CLKCTRL_FRAC_EMIFRAC 8 +#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00 +#define BF_CLKCTRL_FRAC_EMIFRAC(v) \ + (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC) +#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080 +#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040 +#define BP_CLKCTRL_FRAC_CPUFRAC 0 +#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F +#define BF_CLKCTRL_FRAC_CPUFRAC(v) \ + (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC) +HW_REGISTER(HW_CLKCTRL_FRAC1, REGS_CLKCTRL_BASE, 0x00000100) +#define HW_CLKCTRL_FRAC1_ADDR (REGS_CLKCTRL_BASE + 0x00000100) +#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000 +#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000 +HW_REGISTER(HW_CLKCTRL_CLKSEQ, REGS_CLKCTRL_BASE, 0x00000110) +#define HW_CLKCTRL_CLKSEQ_ADDR (REGS_CLKCTRL_BASE + 0x00000110) +#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100 +#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080 +#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040 +#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020 +#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010 +#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008 +#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002 +#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001 +HW_REGISTER_0(HW_CLKCTRL_RESET, REGS_CLKCTRL_BASE, 0x00000120) +#define HW_CLKCTRL_RESET_ADDR (REGS_CLKCTRL_BASE + 0x00000120) +#define BM_CLKCTRL_RESET_CHIP 0x00000002 +#define BM_CLKCTRL_RESET_DIG 0x00000001 +HW_REGISTER_0(HW_CLKCTRL_STATUS, REGS_CLKCTRL_BASE, 0x00000130) +#define HW_CLKCTRL_STATUS_ADDR (REGS_CLKCTRL_BASE + 0x00000130) +#define BP_CLKCTRL_STATUS_CPU_LIMIT 30 +#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000 +#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \ + (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT) +HW_REGISTER_0(HW_CLKCTRL_VERSION, REGS_CLKCTRL_BASE, 0x00000140) +#define HW_CLKCTRL_VERSION_ADDR (REGS_CLKCTRL_BASE + 0x00000140) +#define BP_CLKCTRL_VERSION_MAJOR 24 +#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000 +#define BF_CLKCTRL_VERSION_MAJOR(v) \ + (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR) +#define BP_CLKCTRL_VERSION_MINOR 16 +#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000 +#define BF_CLKCTRL_VERSION_MINOR(v) \ + (((v) << 16) & BM_CLKCTRL_VERSION_MINOR) +#define BP_CLKCTRL_VERSION_STEP 0 +#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF +#define BF_CLKCTRL_VERSION_STEP(v) \ + (((v) << 0) & BM_CLKCTRL_VERSION_STEP) +#endif /* __ARCH_ARM___CLKCTRL_H */ diff --git a/arch/arm/mach-stmp378x/include/mach/regs-icoll.h b/arch/arm/mach-stmp378x/include/mach/regs-icoll.h new file mode 100644 index 000000000000..a5a530c6440d --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/regs-icoll.h @@ -0,0 +1,213 @@ +/* + * STMP ICOLL Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * Copyright 2008 Embedded Alley Solutions, 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 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 __ARCH_ARM___ICOLL_H +#define __ARCH_ARM___ICOLL_H 1 + +#include + +#define REGS_ICOLL_BASE (REGS_BASE + 0x0) +#define REGS_ICOLL_BASE_PHYS (0x80000000) +#define REGS_ICOLL_SIZE 0x00002000 +HW_REGISTER(HW_ICOLL_VECTOR, REGS_ICOLL_BASE, 0x00000000) +#define HW_ICOLL_VECTOR_ADDR (REGS_ICOLL_BASE + 0x00000000) +#define BP_ICOLL_VECTOR_IRQVECTOR 2 +#define BM_ICOLL_VECTOR_IRQVECTOR 0xFFFFFFFC +#define BF_ICOLL_VECTOR_IRQVECTOR(v) \ + (((v) << 2) & BM_ICOLL_VECTOR_IRQVECTOR) +HW_REGISTER_0(HW_ICOLL_LEVELACK, REGS_ICOLL_BASE, 0x00000010) +#define HW_ICOLL_LEVELACK_ADDR (REGS_ICOLL_BASE + 0x00000010) +#define BP_ICOLL_LEVELACK_IRQLEVELACK 0 +#define BM_ICOLL_LEVELACK_IRQLEVELACK 0x0000000F +#define BF_ICOLL_LEVELACK_IRQLEVELACK(v) \ + (((v) << 0) & BM_ICOLL_LEVELACK_IRQLEVELACK) +#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1 +#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL1 0x2 +#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL2 0x4 +#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL3 0x8 +HW_REGISTER(HW_ICOLL_CTRL, REGS_ICOLL_BASE, 0x00000020) +#define HW_ICOLL_CTRL_ADDR (REGS_ICOLL_BASE + 0x00000020) +#define BM_ICOLL_CTRL_SFTRST 0x80000000 +#define BV_ICOLL_CTRL_SFTRST__RUN 0x0 +#define BV_ICOLL_CTRL_SFTRST__IN_RESET 0x1 +#define BM_ICOLL_CTRL_CLKGATE 0x40000000 +#define BV_ICOLL_CTRL_CLKGATE__RUN 0x0 +#define BV_ICOLL_CTRL_CLKGATE__NO_CLOCKS 0x1 +#define BP_ICOLL_CTRL_VECTOR_PITCH 21 +#define BM_ICOLL_CTRL_VECTOR_PITCH 0x00E00000 +#define BF_ICOLL_CTRL_VECTOR_PITCH(v) \ + (((v) << 21) & BM_ICOLL_CTRL_VECTOR_PITCH) +#define BV_ICOLL_CTRL_VECTOR_PITCH__DEFAULT_BY4 0x0 +#define BV_ICOLL_CTRL_VECTOR_PITCH__BY4 0x1 +#define BV_ICOLL_CTRL_VECTOR_PITCH__BY8 0x2 +#define BV_ICOLL_CTRL_VECTOR_PITCH__BY12 0x3 +#define BV_ICOLL_CTRL_VECTOR_PITCH__BY16 0x4 +#define BV_ICOLL_CTRL_VECTOR_PITCH__BY20 0x5 +#define BV_ICOLL_CTRL_VECTOR_PITCH__BY24 0x6 +#define BV_ICOLL_CTRL_VECTOR_PITCH__BY28 0x7 +#define BM_ICOLL_CTRL_BYPASS_FSM 0x00100000 +#define BV_ICOLL_CTRL_BYPASS_FSM__NORMAL 0x0 +#define BV_ICOLL_CTRL_BYPASS_FSM__BYPASS 0x1 +#define BM_ICOLL_CTRL_NO_NESTING 0x00080000 +#define BV_ICOLL_CTRL_NO_NESTING__NORMAL 0x0 +#define BV_ICOLL_CTRL_NO_NESTING__NO_NEST 0x1 +#define BM_ICOLL_CTRL_ARM_RSE_MODE 0x00040000 +#define BM_ICOLL_CTRL_FIQ_FINAL_ENABLE 0x00020000 +#define BV_ICOLL_CTRL_FIQ_FINAL_ENABLE__DISABLE 0x0 +#define BV_ICOLL_CTRL_FIQ_FINAL_ENABLE__ENABLE 0x1 +#define BM_ICOLL_CTRL_IRQ_FINAL_ENABLE 0x00010000 +#define BV_ICOLL_CTRL_IRQ_FINAL_ENABLE__DISABLE 0x0 +#define BV_ICOLL_CTRL_IRQ_FINAL_ENABLE__ENABLE 0x1 +HW_REGISTER(HW_ICOLL_VBASE, REGS_ICOLL_BASE, 0x00000040) +#define HW_ICOLL_VBASE_ADDR (REGS_ICOLL_BASE + 0x00000040) +#define BP_ICOLL_VBASE_TABLE_ADDRESS 2 +#define BM_ICOLL_VBASE_TABLE_ADDRESS 0xFFFFFFFC +#define BF_ICOLL_VBASE_TABLE_ADDRESS(v) \ + (((v) << 2) & BM_ICOLL_VBASE_TABLE_ADDRESS) +HW_REGISTER_0(HW_ICOLL_STAT, REGS_ICOLL_BASE, 0x00000070) +#define HW_ICOLL_STAT_ADDR (REGS_ICOLL_BASE + 0x00000070) +#define BP_ICOLL_STAT_VECTOR_NUMBER 0 +#define BM_ICOLL_STAT_VECTOR_NUMBER 0x0000007F +#define BF_ICOLL_STAT_VECTOR_NUMBER(v) \ + (((v) << 0) & BM_ICOLL_STAT_VECTOR_NUMBER) +/* + * multi-register-define name HW_ICOLL_RAWn + * base 0x000000A0 + * count 4 + * offset 0x10 + */ +HW_REGISTER_0_INDEXED(HW_ICOLL_RAWn, REGS_ICOLL_BASE, 0x000000a0, 0x10) +#define BP_ICOLL_RAWn_RAW_IRQS 0 +#define BM_ICOLL_RAWn_RAW_IRQS 0xFFFFFFFF +#define BF_ICOLL_RAWn_RAW_IRQS(v) (v) +/* + * multi-register-define name HW_ICOLL_INTERRUPTn + * base 0x00000120 + * count 128 + * offset 0x10 + */ +HW_REGISTER_INDEXED(HW_ICOLL_INTERRUPTn, REGS_ICOLL_BASE, 0x00000120, 0x10) +#define BM_ICOLL_INTERRUPTn_ENFIQ 0x00000010 +#define BV_ICOLL_INTERRUPTn_ENFIQ__DISABLE 0x0 +#define BV_ICOLL_INTERRUPTn_ENFIQ__ENABLE 0x1 +#define BM_ICOLL_INTERRUPTn_SOFTIRQ 0x00000008 +#define BV_ICOLL_INTERRUPTn_SOFTIRQ__NO_INTERRUPT 0x0 +#define BV_ICOLL_INTERRUPTn_SOFTIRQ__FORCE_INTERRUPT 0x1 +#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004 +#define BV_ICOLL_INTERRUPTn_ENABLE__DISABLE 0x0 +#define BV_ICOLL_INTERRUPTn_ENABLE__ENABLE 0x1 +#define BP_ICOLL_INTERRUPTn_PRIORITY 0 +#define BM_ICOLL_INTERRUPTn_PRIORITY 0x00000003 +#define BF_ICOLL_INTERRUPTn_PRIORITY(v) \ + (((v) << 0) & BM_ICOLL_INTERRUPTn_PRIORITY) +#define BV_ICOLL_INTERRUPTn_PRIORITY__LEVEL0 0x0 +#define BV_ICOLL_INTERRUPTn_PRIORITY__LEVEL1 0x1 +#define BV_ICOLL_INTERRUPTn_PRIORITY__LEVEL2 0x2 +#define BV_ICOLL_INTERRUPTn_PRIORITY__LEVEL3 0x3 +HW_REGISTER(HW_ICOLL_DEBUG, REGS_ICOLL_BASE, 0x00001120) +#define HW_ICOLL_DEBUG_ADDR (REGS_ICOLL_BASE + 0x00001120) +#define BP_ICOLL_DEBUG_INSERVICE 28 +#define BM_ICOLL_DEBUG_INSERVICE 0xF0000000 +#define BF_ICOLL_DEBUG_INSERVICE(v) \ + (((v) << 28) & BM_ICOLL_DEBUG_INSERVICE) +#define BV_ICOLL_DEBUG_INSERVICE__LEVEL0 0x1 +#define BV_ICOLL_DEBUG_INSERVICE__LEVEL1 0x2 +#define BV_ICOLL_DEBUG_INSERVICE__LEVEL2 0x4 +#define BV_ICOLL_DEBUG_INSERVICE__LEVEL3 0x8 +#define BP_ICOLL_DEBUG_LEVEL_REQUESTS 24 +#define BM_ICOLL_DEBUG_LEVEL_REQUESTS 0x0F000000 +#define BF_ICOLL_DEBUG_LEVEL_REQUESTS(v) \ + (((v) << 24) & BM_ICOLL_DEBUG_LEVEL_REQUESTS) +#define BV_ICOLL_DEBUG_LEVEL_REQUESTS__LEVEL0 0x1 +#define BV_ICOLL_DEBUG_LEVEL_REQUESTS__LEVEL1 0x2 +#define BV_ICOLL_DEBUG_LEVEL_REQUESTS__LEVEL2 0x4 +#define BV_ICOLL_DEBUG_LEVEL_REQUESTS__LEVEL3 0x8 +#define BP_ICOLL_DEBUG_REQUESTS_BY_LEVEL 20 +#define BM_ICOLL_DEBUG_REQUESTS_BY_LEVEL 0x00F00000 +#define BF_ICOLL_DEBUG_REQUESTS_BY_LEVEL(v) \ + (((v) << 20) & BM_ICOLL_DEBUG_REQUESTS_BY_LEVEL) +#define BV_ICOLL_DEBUG_REQUESTS_BY_LEVEL__LEVEL0 0x1 +#define BV_ICOLL_DEBUG_REQUESTS_BY_LEVEL__LEVEL1 0x2 +#define BV_ICOLL_DEBUG_REQUESTS_BY_LEVEL__LEVEL2 0x4 +#define BV_ICOLL_DEBUG_REQUESTS_BY_LEVEL__LEVEL3 0x8 +#define BM_ICOLL_DEBUG_FIQ 0x00020000 +#define BV_ICOLL_DEBUG_FIQ__NO_FIQ_REQUESTED 0x0 +#define BV_ICOLL_DEBUG_FIQ__FIQ_REQUESTED 0x1 +#define BM_ICOLL_DEBUG_IRQ 0x00010000 +#define BV_ICOLL_DEBUG_IRQ__NO_IRQ_REQUESTED 0x0 +#define BV_ICOLL_DEBUG_IRQ__IRQ_REQUESTED 0x1 +#define BP_ICOLL_DEBUG_VECTOR_FSM 0 +#define BM_ICOLL_DEBUG_VECTOR_FSM 0x000003FF +#define BF_ICOLL_DEBUG_VECTOR_FSM(v) \ + (((v) << 0) & BM_ICOLL_DEBUG_VECTOR_FSM) +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_IDLE 0x000 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE1 0x001 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE2 0x002 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_PENDING 0x004 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE3 0x008 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE4 0x010 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_ISR_RUNNING1 0x020 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_ISR_RUNNING2 0x040 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_ISR_RUNNING3 0x080 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE5 0x100 +#define BV_ICOLL_DEBUG_VECTOR_FSM__FSM_MULTICYCLE6 0x200 +HW_REGISTER(HW_ICOLL_DBGREAD0, REGS_ICOLL_BASE, 0x00001130) +#define HW_ICOLL_DBGREAD0_ADDR (REGS_ICOLL_BASE + 0x00001130) +#define BP_ICOLL_DBGREAD0_VALUE 0 +#define BM_ICOLL_DBGREAD0_VALUE 0xFFFFFFFF +#define BF_ICOLL_DBGREAD0_VALUE(v) (v) +HW_REGISTER(HW_ICOLL_DBGREAD1, REGS_ICOLL_BASE, 0x00001140) +#define HW_ICOLL_DBGREAD1_ADDR (REGS_ICOLL_BASE + 0x00001140) +#define BP_ICOLL_DBGREAD1_VALUE 0 +#define BM_ICOLL_DBGREAD1_VALUE 0xFFFFFFFF +#define BF_ICOLL_DBGREAD1_VALUE(v) (v) +HW_REGISTER(HW_ICOLL_DBGFLAG, REGS_ICOLL_BASE, 0x00001150) +#define HW_ICOLL_DBGFLAG_ADDR (REGS_ICOLL_BASE + 0x00001150) +#define BP_ICOLL_DBGFLAG_FLAG 0 +#define BM_ICOLL_DBGFLAG_FLAG 0x0000FFFF +#define BF_ICOLL_DBGFLAG_FLAG(v) \ + (((v) << 0) & BM_ICOLL_DBGFLAG_FLAG) +/* + * multi-register-define name HW_ICOLL_DBGREQUESTn + * base 0x00001160 + * count 4 + * offset 0x10 + */ +HW_REGISTER_0_INDEXED(HW_ICOLL_DBGREQUESTn, REGS_ICOLL_BASE, 0x00001160, + 0x10) +#define BP_ICOLL_DBGREQUESTn_BITS 0 +#define BM_ICOLL_DBGREQUESTn_BITS 0xFFFFFFFF +#define BF_ICOLL_DBGREQUESTn_BITS(v) (v) +HW_REGISTER_0(HW_ICOLL_VERSION, REGS_ICOLL_BASE, 0x000011e0) +#define HW_ICOLL_VERSION_ADDR (REGS_ICOLL_BASE + 0x000011e0) +#define BP_ICOLL_VERSION_MAJOR 24 +#define BM_ICOLL_VERSION_MAJOR 0xFF000000 +#define BF_ICOLL_VERSION_MAJOR(v) \ + (((v) << 24) & BM_ICOLL_VERSION_MAJOR) +#define BP_ICOLL_VERSION_MINOR 16 +#define BM_ICOLL_VERSION_MINOR 0x00FF0000 +#define BF_ICOLL_VERSION_MINOR(v) \ + (((v) << 16) & BM_ICOLL_VERSION_MINOR) +#define BP_ICOLL_VERSION_STEP 0 +#define BM_ICOLL_VERSION_STEP 0x0000FFFF +#define BF_ICOLL_VERSION_STEP(v) \ + (((v) << 0) & BM_ICOLL_VERSION_STEP) +#endif /* __ARCH_ARM___ICOLL_H */ diff --git a/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h b/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h new file mode 100644 index 000000000000..6c42d2a47c19 --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h @@ -0,0 +1,143 @@ +/* + * STMP PINCTRL Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * Copyright 2008 Embedded Alley Solutions, 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 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 __ARCH_ARM___PINCTRL_H +#define __ARCH_ARM___PINCTRL_H 1 + +#include + +#define REGS_PINCTRL_BASE (REGS_BASE + 0x18000) +#define REGS_PINCTRL_BASE_PHYS (0x80018000) +#define REGS_PINCTRL_SIZE 0x00002000 +HW_REGISTER(HW_PINCTRL_CTRL, REGS_PINCTRL_BASE, 0x00000000) +#define HW_PINCTRL_CTRL_ADDR (REGS_PINCTRL_BASE + 0x00000000) +#define BM_PINCTRL_CTRL_SFTRST 0x80000000 +#define BM_PINCTRL_CTRL_CLKGATE 0x40000000 +#define BM_PINCTRL_CTRL_PRESENT3 0x08000000 +#define BM_PINCTRL_CTRL_PRESENT2 0x04000000 +#define BM_PINCTRL_CTRL_PRESENT1 0x02000000 +#define BM_PINCTRL_CTRL_PRESENT0 0x01000000 +#define BM_PINCTRL_CTRL_IRQOUT2 0x00000004 +#define BM_PINCTRL_CTRL_IRQOUT1 0x00000002 +#define BM_PINCTRL_CTRL_IRQOUT0 0x00000001 +HW_REGISTER(HW_PINCTRL_MUXSEL0, REGS_PINCTRL_BASE, 0x00000100) +#define HW_PINCTRL_MUXSEL0_ADDR (REGS_PINCTRL_BASE + 0x00000100) +HW_REGISTER(HW_PINCTRL_MUXSEL1, REGS_PINCTRL_BASE, 0x00000110) +#define HW_PINCTRL_MUXSEL1_ADDR (REGS_PINCTRL_BASE + 0x00000110) +HW_REGISTER(HW_PINCTRL_MUXSEL2, REGS_PINCTRL_BASE, 0x00000120) +#define HW_PINCTRL_MUXSEL2_ADDR (REGS_PINCTRL_BASE + 0x00000120) +HW_REGISTER(HW_PINCTRL_MUXSEL3, REGS_PINCTRL_BASE, 0x00000130) +#define HW_PINCTRL_MUXSEL3_ADDR (REGS_PINCTRL_BASE + 0x00000130) +HW_REGISTER(HW_PINCTRL_MUXSEL4, REGS_PINCTRL_BASE, 0x00000140) +#define HW_PINCTRL_MUXSEL4_ADDR (REGS_PINCTRL_BASE + 0x00000140) +HW_REGISTER(HW_PINCTRL_MUXSEL5, REGS_PINCTRL_BASE, 0x00000150) +#define HW_PINCTRL_MUXSEL5_ADDR (REGS_PINCTRL_BASE + 0x00000150) +HW_REGISTER(HW_PINCTRL_MUXSEL6, REGS_PINCTRL_BASE, 0x00000160) +#define HW_PINCTRL_MUXSEL6_ADDR (REGS_PINCTRL_BASE + 0x00000160) +HW_REGISTER(HW_PINCTRL_MUXSEL7, REGS_PINCTRL_BASE, 0x00000170) +#define HW_PINCTRL_MUXSEL7_ADDR (REGS_PINCTRL_BASE + 0x00000170) +HW_REGISTER(HW_PINCTRL_DRIVE0, REGS_PINCTRL_BASE, 0x00000200) +#define HW_PINCTRL_DRIVE0_ADDR (REGS_PINCTRL_BASE + 0x00000200) +HW_REGISTER(HW_PINCTRL_DRIVE1, REGS_PINCTRL_BASE, 0x00000210) +#define HW_PINCTRL_DRIVE1_ADDR (REGS_PINCTRL_BASE + 0x00000210) +HW_REGISTER(HW_PINCTRL_DRIVE2, REGS_PINCTRL_BASE, 0x00000220) +#define HW_PINCTRL_DRIVE2_ADDR (REGS_PINCTRL_BASE + 0x00000220) +HW_REGISTER(HW_PINCTRL_DRIVE3, REGS_PINCTRL_BASE, 0x00000230) +#define HW_PINCTRL_DRIVE3_ADDR (REGS_PINCTRL_BASE + 0x00000230) +HW_REGISTER(HW_PINCTRL_DRIVE4, REGS_PINCTRL_BASE, 0x00000240) +#define HW_PINCTRL_DRIVE4_ADDR (REGS_PINCTRL_BASE + 0x00000240) +HW_REGISTER(HW_PINCTRL_DRIVE5, REGS_PINCTRL_BASE, 0x00000250) +#define HW_PINCTRL_DRIVE5_ADDR (REGS_PINCTRL_BASE + 0x00000250) +HW_REGISTER(HW_PINCTRL_DRIVE6, REGS_PINCTRL_BASE, 0x00000260) +#define HW_PINCTRL_DRIVE6_ADDR (REGS_PINCTRL_BASE + 0x00000260) +HW_REGISTER(HW_PINCTRL_DRIVE7, REGS_PINCTRL_BASE, 0x00000270) +#define HW_PINCTRL_DRIVE7_ADDR (REGS_PINCTRL_BASE + 0x00000270) +HW_REGISTER(HW_PINCTRL_DRIVE8, REGS_PINCTRL_BASE, 0x00000280) +#define HW_PINCTRL_DRIVE8_ADDR (REGS_PINCTRL_BASE + 0x00000280) +HW_REGISTER(HW_PINCTRL_DRIVE9, REGS_PINCTRL_BASE, 0x00000290) +#define HW_PINCTRL_DRIVE9_ADDR (REGS_PINCTRL_BASE + 0x00000290) +HW_REGISTER(HW_PINCTRL_DRIVE10, REGS_PINCTRL_BASE, 0x000002a0) +#define HW_PINCTRL_DRIVE10_ADDR (REGS_PINCTRL_BASE + 0x000002a0) +HW_REGISTER(HW_PINCTRL_DRIVE11, REGS_PINCTRL_BASE, 0x000002b0) +#define HW_PINCTRL_DRIVE11_ADDR (REGS_PINCTRL_BASE + 0x000002b0) +HW_REGISTER(HW_PINCTRL_DRIVE12, REGS_PINCTRL_BASE, 0x000002c0) +#define HW_PINCTRL_DRIVE12_ADDR (REGS_PINCTRL_BASE + 0x000002c0) +HW_REGISTER(HW_PINCTRL_DRIVE13, REGS_PINCTRL_BASE, 0x000002d0) +#define HW_PINCTRL_DRIVE13_ADDR (REGS_PINCTRL_BASE + 0x000002d0) +HW_REGISTER(HW_PINCTRL_DRIVE14, REGS_PINCTRL_BASE, 0x000002e0) +#define HW_PINCTRL_DRIVE14_ADDR (REGS_PINCTRL_BASE + 0x000002e0) +HW_REGISTER(HW_PINCTRL_PULL0, REGS_PINCTRL_BASE, 0x00000400) +#define HW_PINCTRL_PULL0_ADDR (REGS_PINCTRL_BASE + 0x00000400) +HW_REGISTER(HW_PINCTRL_PULL1, REGS_PINCTRL_BASE, 0x00000410) +#define HW_PINCTRL_PULL1_ADDR (REGS_PINCTRL_BASE + 0x00000410) +HW_REGISTER(HW_PINCTRL_PULL2, REGS_PINCTRL_BASE, 0x00000420) +#define HW_PINCTRL_PULL2_ADDR (REGS_PINCTRL_BASE + 0x00000420) +HW_REGISTER(HW_PINCTRL_PULL3, REGS_PINCTRL_BASE, 0x00000430) +#define HW_PINCTRL_PULL3_ADDR (REGS_PINCTRL_BASE + 0x00000430) +HW_REGISTER(HW_PINCTRL_DOUT0, REGS_PINCTRL_BASE, 0x00000500) +#define HW_PINCTRL_DOUT0_ADDR (REGS_PINCTRL_BASE + 0x00000500) +HW_REGISTER(HW_PINCTRL_DOUT1, REGS_PINCTRL_BASE, 0x00000510) +#define HW_PINCTRL_DOUT1_ADDR (REGS_PINCTRL_BASE + 0x00000510) +HW_REGISTER(HW_PINCTRL_DOUT2, REGS_PINCTRL_BASE, 0x00000520) +#define HW_PINCTRL_DOUT2_ADDR (REGS_PINCTRL_BASE + 0x00000520) +HW_REGISTER(HW_PINCTRL_DIN0, REGS_PINCTRL_BASE, 0x00000600) +#define HW_PINCTRL_DIN0_ADDR (REGS_PINCTRL_BASE + 0x00000600) +HW_REGISTER(HW_PINCTRL_DIN1, REGS_PINCTRL_BASE, 0x00000610) +#define HW_PINCTRL_DIN1_ADDR (REGS_PINCTRL_BASE + 0x00000610) +HW_REGISTER(HW_PINCTRL_DIN2, REGS_PINCTRL_BASE, 0x00000620) +#define HW_PINCTRL_DIN2_ADDR (REGS_PINCTRL_BASE + 0x00000620) +HW_REGISTER(HW_PINCTRL_DOE0, REGS_PINCTRL_BASE, 0x00000700) +#define HW_PINCTRL_DOE0_ADDR (REGS_PINCTRL_BASE + 0x00000700) +HW_REGISTER(HW_PINCTRL_DOE1, REGS_PINCTRL_BASE, 0x00000710) +#define HW_PINCTRL_DOE1_ADDR (REGS_PINCTRL_BASE + 0x00000710) +HW_REGISTER(HW_PINCTRL_DOE2, REGS_PINCTRL_BASE, 0x00000720) +#define HW_PINCTRL_DOE2_ADDR (REGS_PINCTRL_BASE + 0x00000720) +HW_REGISTER(HW_PINCTRL_PIN2IRQ0, REGS_PINCTRL_BASE, 0x00000800) +#define HW_PINCTRL_PIN2IRQ0_ADDR (REGS_PINCTRL_BASE + 0x00000800) +HW_REGISTER(HW_PINCTRL_PIN2IRQ1, REGS_PINCTRL_BASE, 0x00000810) +#define HW_PINCTRL_PIN2IRQ1_ADDR (REGS_PINCTRL_BASE + 0x00000810) +HW_REGISTER(HW_PINCTRL_PIN2IRQ2, REGS_PINCTRL_BASE, 0x00000820) +#define HW_PINCTRL_PIN2IRQ2_ADDR (REGS_PINCTRL_BASE + 0x00000820) +HW_REGISTER(HW_PINCTRL_IRQEN0, REGS_PINCTRL_BASE, 0x00000900) +#define HW_PINCTRL_IRQEN0_ADDR (REGS_PINCTRL_BASE + 0x00000900) +HW_REGISTER(HW_PINCTRL_IRQEN1, REGS_PINCTRL_BASE, 0x00000910) +#define HW_PINCTRL_IRQEN1_ADDR (REGS_PINCTRL_BASE + 0x00000910) +HW_REGISTER(HW_PINCTRL_IRQEN2, REGS_PINCTRL_BASE, 0x00000920) +#define HW_PINCTRL_IRQEN2_ADDR (REGS_PINCTRL_BASE + 0x00000920) +HW_REGISTER(HW_PINCTRL_IRQLEVEL0, REGS_PINCTRL_BASE, 0x00000a00) +#define HW_PINCTRL_IRQLEVEL0_ADDR (REGS_PINCTRL_BASE + 0x00000a00) +HW_REGISTER(HW_PINCTRL_IRQLEVEL1, REGS_PINCTRL_BASE, 0x00000a10) +#define HW_PINCTRL_IRQLEVEL1_ADDR (REGS_PINCTRL_BASE + 0x00000a10) +HW_REGISTER(HW_PINCTRL_IRQLEVEL2, REGS_PINCTRL_BASE, 0x00000a20) +#define HW_PINCTRL_IRQLEVEL2_ADDR (REGS_PINCTRL_BASE + 0x00000a20) +HW_REGISTER(HW_PINCTRL_IRQPOL0, REGS_PINCTRL_BASE, 0x00000b00) +#define HW_PINCTRL_IRQPOL0_ADDR (REGS_PINCTRL_BASE + 0x00000b00) +HW_REGISTER(HW_PINCTRL_IRQPOL1, REGS_PINCTRL_BASE, 0x00000b10) +#define HW_PINCTRL_IRQPOL1_ADDR (REGS_PINCTRL_BASE + 0x00000b10) +HW_REGISTER(HW_PINCTRL_IRQPOL2, REGS_PINCTRL_BASE, 0x00000b20) +#define HW_PINCTRL_IRQPOL2_ADDR (REGS_PINCTRL_BASE + 0x00000b20) +HW_REGISTER(HW_PINCTRL_IRQSTAT0, REGS_PINCTRL_BASE, 0x00000c00) +#define HW_PINCTRL_IRQSTAT0_ADDR (REGS_PINCTRL_BASE + 0x00000c00) +HW_REGISTER(HW_PINCTRL_IRQSTAT1, REGS_PINCTRL_BASE, 0x00000c10) +#define HW_PINCTRL_IRQSTAT1_ADDR (REGS_PINCTRL_BASE + 0x00000c10) +HW_REGISTER(HW_PINCTRL_IRQSTAT2, REGS_PINCTRL_BASE, 0x00000c20) +#define HW_PINCTRL_IRQSTAT2_ADDR (REGS_PINCTRL_BASE + 0x00000c20) +#endif /* __ARCH_ARM___PINCTRL_H */ diff --git a/arch/arm/mach-stmp378x/include/mach/regs-power.h b/arch/arm/mach-stmp378x/include/mach/regs-power.h new file mode 100644 index 000000000000..1c81afeed531 --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/regs-power.h @@ -0,0 +1,32 @@ +/* + * STMP POWER Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * Copyright 2008 Embedded Alley Solutions, 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 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 __ARCH_ARM___POWER_H +#define __ARCH_ARM___POWER_H 1 + +#include + +#define REGS_POWER_BASE (void __iomem *)(REGS_BASE + 0x44000) +#define REGS_POWER_BASE_PHYS (0x80044000) +#define REGS_POWER_SIZE 0x00002000 +HW_REGISTER(HW_POWER_MINPWR, REGS_POWER_BASE, 0x00000020) +HW_REGISTER(HW_POWER_CHARGE, REGS_POWER_BASE, 0x00000030) +#endif /* __ARCH_ARM___POWER_H */ diff --git a/arch/arm/mach-stmp378x/include/mach/regs-timrot.h b/arch/arm/mach-stmp378x/include/mach/regs-timrot.h new file mode 100644 index 000000000000..bb6355acdfd1 --- /dev/null +++ b/arch/arm/mach-stmp378x/include/mach/regs-timrot.h @@ -0,0 +1,216 @@ +/* + * STMP TIMROT Register Definitions + * + * Copyright (c) 2008 Freescale Semiconductor + * Copyright 2008 Embedded Alley Solutions, 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 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 __ARCH_ARM___TIMROT_H +#define __ARCH_ARM___TIMROT_H 1 + +#include + +#define REGS_TIMROT_BASE (REGS_BASE + 0x68000) +#define REGS_TIMROT_BASE_PHYS (0x80068000) +#define REGS_TIMROT_SIZE 0x00002000 +HW_REGISTER(HW_TIMROT_ROTCTRL, REGS_TIMROT_BASE, 0x00000000) +#define HW_TIMROT_ROTCTRL_ADDR (REGS_TIMROT_BASE + 0x00000000) +#define BM_TIMROT_ROTCTRL_SFTRST 0x80000000 +#define BM_TIMROT_ROTCTRL_CLKGATE 0x40000000 +#define BM_TIMROT_ROTCTRL_ROTARY_PRESENT 0x20000000 +#define BM_TIMROT_ROTCTRL_TIM3_PRESENT 0x10000000 +#define BM_TIMROT_ROTCTRL_TIM2_PRESENT 0x08000000 +#define BM_TIMROT_ROTCTRL_TIM1_PRESENT 0x04000000 +#define BM_TIMROT_ROTCTRL_TIM0_PRESENT 0x02000000 +#define BP_TIMROT_ROTCTRL_STATE 22 +#define BM_TIMROT_ROTCTRL_STATE 0x01C00000 +#define BF_TIMROT_ROTCTRL_STATE(v) \ + (((v) << 22) & BM_TIMROT_ROTCTRL_STATE) +#define BP_TIMROT_ROTCTRL_DIVIDER 16 +#define BM_TIMROT_ROTCTRL_DIVIDER 0x003F0000 +#define BF_TIMROT_ROTCTRL_DIVIDER(v) \ + (((v) << 16) & BM_TIMROT_ROTCTRL_DIVIDER) +#define BM_TIMROT_ROTCTRL_RELATIVE 0x00001000 +#define BP_TIMROT_ROTCTRL_OVERSAMPLE 10 +#define BM_TIMROT_ROTCTRL_OVERSAMPLE 0x00000C00 +#define BF_TIMROT_ROTCTRL_OVERSAMPLE(v) \ + (((v) << 10) & BM_TIMROT_ROTCTRL_OVERSAMPLE) +#define BV_TIMROT_ROTCTRL_OVERSAMPLE__8X 0x0 +#define BV_TIMROT_ROTCTRL_OVERSAMPLE__4X 0x1 +#define BV_TIMROT_ROTCTRL_OVERSAMPLE__2X 0x2 +#define BV_TIMROT_ROTCTRL_OVERSAMPLE__1X 0x3 +#define BM_TIMROT_ROTCTRL_POLARITY_B 0x00000200 +#define BM_TIMROT_ROTCTRL_POLARITY_A 0x00000100 +#define BP_TIMROT_ROTCTRL_SELECT_B 4 +#define BM_TIMROT_ROTCTRL_SELECT_B 0x00000070 +#define BF_TIMROT_ROTCTRL_SELECT_B(v) \ + (((v) << 4) & BM_TIMROT_ROTCTRL_SELECT_B) +#define BV_TIMROT_ROTCTRL_SELECT_B__NEVER_TICK 0x0 +#define BV_TIMROT_ROTCTRL_SELECT_B__PWM0 0x1 +#define BV_TIMROT_ROTCTRL_SELECT_B__PWM1 0x2 +#define BV_TIMROT_ROTCTRL_SELECT_B__PWM2 0x3 +#define BV_TIMROT_ROTCTRL_SELECT_B__PWM3 0x4 +#define BV_TIMROT_ROTCTRL_SELECT_B__PWM4 0x5 +#define BV_TIMROT_ROTCTRL_SELECT_B__ROTARYA 0x6 +#define BV_TIMROT_ROTCTRL_SELECT_B__ROTARYB 0x7 +#define BP_TIMROT_ROTCTRL_SELECT_A 0 +#define BM_TIMROT_ROTCTRL_SELECT_A 0x00000007 +#define BF_TIMROT_ROTCTRL_SELECT_A(v) \ + (((v) << 0) & BM_TIMROT_ROTCTRL_SELECT_A) +#define BV_TIMROT_ROTCTRL_SELECT_A__NEVER_TICK 0x0 +#define BV_TIMROT_ROTCTRL_SELECT_A__PWM0 0x1 +#define BV_TIMROT_ROTCTRL_SELECT_A__PWM1 0x2 +#define BV_TIMROT_ROTCTRL_SELECT_A__PWM2 0x3 +#define BV_TIMROT_ROTCTRL_SELECT_A__PWM3 0x4 +#define BV_TIMROT_ROTCTRL_SELECT_A__PWM4 0x5 +#define BV_TIMROT_ROTCTRL_SELECT_A__ROTARYA 0x6 +#define BV_TIMROT_ROTCTRL_SELECT_A__ROTARYB 0x7 +HW_REGISTER_0(HW_TIMROT_ROTCOUNT, REGS_TIMROT_BASE, 0x00000010) +#define HW_TIMROT_ROTCOUNT_ADDR (REGS_TIMROT_BASE + 0x00000010) +#define BP_TIMROT_ROTCOUNT_UPDOWN 0 +#define BM_TIMROT_ROTCOUNT_UPDOWN 0x0000FFFF +#define BF_TIMROT_ROTCOUNT_UPDOWN(v) \ + (((v) << 0) & BM_TIMROT_ROTCOUNT_UPDOWN) +/* + * multi-register-define name HW_TIMROT_TIMCTRLn + * base 0x00000020 + * count 3 + * offset 0x20 + */ +HW_REGISTER_INDEXED(HW_TIMROT_TIMCTRLn, REGS_TIMROT_BASE, 0x00000020, 0x20) +#define BM_TIMROT_TIMCTRLn_IRQ 0x00008000 +#define BM_TIMROT_TIMCTRLn_IRQ_EN 0x00004000 +#define BM_TIMROT_TIMCTRLn_POLARITY 0x00000100 +#define BM_TIMROT_TIMCTRLn_UPDATE 0x00000080 +#define BM_TIMROT_TIMCTRLn_RELOAD 0x00000040 +#define BP_TIMROT_TIMCTRLn_PRESCALE 4 +#define BM_TIMROT_TIMCTRLn_PRESCALE 0x00000030 +#define BF_TIMROT_TIMCTRLn_PRESCALE(v) \ + (((v) << 4) & BM_TIMROT_TIMCTRLn_PRESCALE) +#define BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_1 0x0 +#define BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_2 0x1 +#define BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_4 0x2 +#define BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_8 0x3 +#define BP_TIMROT_TIMCTRLn_SELECT 0 +#define BM_TIMROT_TIMCTRLn_SELECT 0x0000000F +#define BF_TIMROT_TIMCTRLn_SELECT(v) \ + (((v) << 0) & BM_TIMROT_TIMCTRLn_SELECT) +#define BV_TIMROT_TIMCTRLn_SELECT__NEVER_TICK 0x0 +#define BV_TIMROT_TIMCTRLn_SELECT__PWM0 0x1 +#define BV_TIMROT_TIMCTRLn_SELECT__PWM1 0x2 +#define BV_TIMROT_TIMCTRLn_SELECT__PWM2 0x3 +#define BV_TIMROT_TIMCTRLn_SELECT__PWM3 0x4 +#define BV_TIMROT_TIMCTRLn_SELECT__PWM4 0x5 +#define BV_TIMROT_TIMCTRLn_SELECT__ROTARYA 0x6 +#define BV_TIMROT_TIMCTRLn_SELECT__ROTARYB 0x7 +#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL 0x8 +#define BV_TIMROT_TIMCTRLn_SELECT__8KHZ_XTAL 0x9 +#define BV_TIMROT_TIMCTRLn_SELECT__4KHZ_XTAL 0xA +#define BV_TIMROT_TIMCTRLn_SELECT__1KHZ_XTAL 0xB +#define BV_TIMROT_TIMCTRLn_SELECT__TICK_ALWAYS 0xC +/* + * multi-register-define name HW_TIMROT_TIMCOUNTn + * base 0x00000030 + * count 3 + * offset 0x20 + */ +HW_REGISTER_0_INDEXED(HW_TIMROT_TIMCOUNTn, REGS_TIMROT_BASE, 0x00000030, + 0x20) +#define BP_TIMROT_TIMCOUNTn_RUNNING_COUNT 16 +#define BM_TIMROT_TIMCOUNTn_RUNNING_COUNT 0xFFFF0000 +#define BF_TIMROT_TIMCOUNTn_RUNNING_COUNT(v) \ + (((v) << 16) & BM_TIMROT_TIMCOUNTn_RUNNING_COUNT) +#define BP_TIMROT_TIMCOUNTn_FIXED_COUNT 0 +#define BM_TIMROT_TIMCOUNTn_FIXED_COUNT 0x0000FFFF +#define BF_TIMROT_TIMCOUNTn_FIXED_COUNT(v) \ + (((v) << 0) & BM_TIMROT_TIMCOUNTn_FIXED_COUNT) +HW_REGISTER(HW_TIMROT_TIMCTRL3, REGS_TIMROT_BASE, 0x00000080) +#define HW_TIMROT_TIMCTRL3_ADDR (REGS_TIMROT_BASE + 0x00000080) +#define BP_TIMROT_TIMCTRL3_TEST_SIGNAL 16 +#define BM_TIMROT_TIMCTRL3_TEST_SIGNAL 0x000F0000 +#define BF_TIMROT_TIMCTRL3_TEST_SIGNAL(v) \ + (((v) << 16) & BM_TIMROT_TIMCTRL3_TEST_SIGNAL) +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__NEVER_TICK 0x0 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM0 0x1 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM1 0x2 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM2 0x3 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM3 0x4 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__PWM4 0x5 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__ROTARYA 0x6 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__ROTARYB 0x7 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__32KHZ_XTAL 0x8 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__8KHZ_XTAL 0x9 +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__4KHZ_XTAL 0xA +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__1KHZ_XTAL 0xB +#define BV_TIMROT_TIMCTRL3_TEST_SIGNAL__TICK_ALWAYS 0xC +#define BM_TIMROT_TIMCTRL3_IRQ 0x00008000 +#define BM_TIMROT_TIMCTRL3_IRQ_EN 0x00004000 +#define BM_TIMROT_TIMCTRL3_DUTY_VALID 0x00000400 +#define BM_TIMROT_TIMCTRL3_DUTY_CYCLE 0x00000200 +#define BM_TIMROT_TIMCTRL3_POLARITY 0x00000100 +#define BM_TIMROT_TIMCTRL3_UPDATE 0x00000080 +#define BM_TIMROT_TIMCTRL3_RELOAD 0x00000040 +#define BP_TIMROT_TIMCTRL3_PRESCALE 4 +#define BM_TIMROT_TIMCTRL3_PRESCALE 0x00000030 +#define BF_TIMROT_TIMCTRL3_PRESCALE(v) \ + (((v) << 4) & BM_TIMROT_TIMCTRL3_PRESCALE) +#define BV_TIMROT_TIMCTRL3_PRESCALE__DIV_BY_1 0x0 +#define BV_TIMROT_TIMCTRL3_PRESCALE__DIV_BY_2 0x1 +#define BV_TIMROT_TIMCTRL3_PRESCALE__DIV_BY_4 0x2 +#define BV_TIMROT_TIMCTRL3_PRESCALE__DIV_BY_8 0x3 +#define BP_TIMROT_TIMCTRL3_SELECT 0 +#define BM_TIMROT_TIMCTRL3_SELECT 0x0000000F +#define BF_TIMROT_TIMCTRL3_SELECT(v) \ + (((v) << 0) & BM_TIMROT_TIMCTRL3_SELECT) +#define BV_TIMROT_TIMCTRL3_SELECT__NEVER_TICK 0x0 +#define BV_TIMROT_TIMCTRL3_SELECT__PWM0 0x1 +#define BV_TIMROT_TIMCTRL3_SELECT__PWM1 0x2 +#define BV_TIMROT_TIMCTRL3_SELECT__PWM2 0x3 +#define BV_TIMROT_TIMCTRL3_SELECT__PWM3 0x4 +#define BV_TIMROT_TIMCTRL3_SELECT__PWM4 0x5 +#define BV_TIMROT_TIMCTRL3_SELECT__ROTARYA 0x6 +#define BV_TIMROT_TIMCTRL3_SELECT__ROTARYB 0x7 +#define BV_TIMROT_TIMCTRL3_SELECT__32KHZ_XTAL 0x8 +#define BV_TIMROT_TIMCTRL3_SELECT__8KHZ_XTAL 0x9 +#define BV_TIMROT_TIMCTRL3_SELECT__4KHZ_XTAL 0xA +#define BV_TIMROT_TIMCTRL3_SELECT__1KHZ_XTAL 0xB +#define BV_TIMROT_TIMCTRL3_SELECT__TICK_ALWAYS 0xC +HW_REGISTER_0(HW_TIMROT_TIMCOUNT3, REGS_TIMROT_BASE, 0x00000090) +#define HW_TIMROT_TIMCOUNT3_ADDR (REGS_TIMROT_BASE + 0x00000090) +#define BP_TIMROT_TIMCOUNT3_LOW_RUNNING_COUNT 16 +#define BM_TIMROT_TIMCOUNT3_LOW_RUNNING_COUNT 0xFFFF0000 +#define BF_TIMROT_TIMCOUNT3_LOW_RUNNING_COUNT(v) \ + (((v) << 16) & BM_TIMROT_TIMCOUNT3_LOW_RUNNING_COUNT) +#define BP_TIMROT_TIMCOUNT3_HIGH_FIXED_COUNT 0 +#define BM_TIMROT_TIMCOUNT3_HIGH_FIXED_COUNT 0x0000FFFF +#define BF_TIMROT_TIMCOUNT3_HIGH_FIXED_COUNT(v) \ + (((v) << 0) & BM_TIMROT_TIMCOUNT3_HIGH_FIXED_COUNT) +HW_REGISTER_0(HW_TIMROT_VERSION, REGS_TIMROT_BASE, 0x000000a0) +#define HW_TIMROT_VERSION_ADDR (REGS_TIMROT_BASE + 0x000000a0) +#define BP_TIMROT_VERSION_MAJOR 24 +#define BM_TIMROT_VERSION_MAJOR 0xFF000000 +#define BF_TIMROT_VERSION_MAJOR(v) \ + (((v) << 24) & BM_TIMROT_VERSION_MAJOR) +#define BP_TIMROT_VERSION_MINOR 16 +#define BM_TIMROT_VERSION_MINOR 0x00FF0000 +#define BF_TIMROT_VERSION_MINOR(v) \ + (((v) << 16) & BM_TIMROT_VERSION_MINOR) +#define BP_TIMROT_VERSION_STEP 0 +#define BM_TIMROT_VERSION_STEP 0x0000FFFF +#define BF_TIMROT_VERSION_STEP(v) \ + (((v) << 0) & BM_TIMROT_VERSION_STEP) +#endif /* __ARCH_ARM___TIMROT_H */ -- GitLab From e317872ac532fd845c597e55ceb5a9bceee878c1 Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Wed, 22 Apr 2009 23:55:23 +0100 Subject: [PATCH 0719/6080] [ARM] 5466/1: Freescale STMP platform support [5/10] Shared (platform) headers Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- arch/arm/plat-stmp3xxx/include/mach/clkdev.h | 18 ++ arch/arm/plat-stmp3xxx/include/mach/cputype.h | 33 +++ .../plat-stmp3xxx/include/mach/debug-macro.S | 42 ++++ arch/arm/plat-stmp3xxx/include/mach/dma.h | 155 ++++++++++++++ arch/arm/plat-stmp3xxx/include/mach/gpio.h | 28 +++ .../arm/plat-stmp3xxx/include/mach/hardware.h | 32 +++ arch/arm/plat-stmp3xxx/include/mach/io.h | 25 +++ arch/arm/plat-stmp3xxx/include/mach/memory.h | 22 ++ arch/arm/plat-stmp3xxx/include/mach/pinmux.h | 158 ++++++++++++++ arch/arm/plat-stmp3xxx/include/mach/pins.h | 30 +++ .../arm/plat-stmp3xxx/include/mach/platform.h | 47 +++++ .../arm/plat-stmp3xxx/include/mach/stmp3xxx.h | 34 +++ .../include/mach/stmp3xxx_regs.h | 195 ++++++++++++++++++ arch/arm/plat-stmp3xxx/include/mach/system.h | 47 +++++ arch/arm/plat-stmp3xxx/include/mach/timex.h | 20 ++ .../plat-stmp3xxx/include/mach/uncompress.h | 53 +++++ arch/arm/plat-stmp3xxx/include/mach/vmalloc.h | 12 ++ 17 files changed, 951 insertions(+) create mode 100644 arch/arm/plat-stmp3xxx/include/mach/clkdev.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/cputype.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/debug-macro.S create mode 100644 arch/arm/plat-stmp3xxx/include/mach/dma.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/gpio.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/hardware.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/io.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/memory.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/pinmux.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/pins.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/platform.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/stmp3xxx_regs.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/system.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/timex.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/uncompress.h create mode 100644 arch/arm/plat-stmp3xxx/include/mach/vmalloc.h diff --git a/arch/arm/plat-stmp3xxx/include/mach/clkdev.h b/arch/arm/plat-stmp3xxx/include/mach/clkdev.h new file mode 100644 index 000000000000..f9c39772d7c5 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/clkdev.h @@ -0,0 +1,18 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_MACH_CLKDEV_H +#define __ASM_MACH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/plat-stmp3xxx/include/mach/cputype.h b/arch/arm/plat-stmp3xxx/include/mach/cputype.h new file mode 100644 index 000000000000..b4e205b95f2c --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/cputype.h @@ -0,0 +1,33 @@ +/* + * Freescale STMP37XX/STMP378X CPU type detection + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_PLAT_CPU_H +#define __ASM_PLAT_CPU_H + +#ifdef CONFIG_ARCH_STMP37XX +#define cpu_is_stmp37xx() (1) +#else +#define cpu_is_stmp37xx() (0) +#endif + +#ifdef CONFIG_ARCH_STMP378X +#define cpu_is_stmp378x() (1) +#else +#define cpu_is_stmp378x() (0) +#endif + +#endif /* __ASM_PLAT_CPU_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S b/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S new file mode 100644 index 000000000000..fb3b969bf0a2 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S @@ -0,0 +1,42 @@ +/* + * Debugging macro include header + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0x80000000 @ physical base address + addeq \rx, \rx, #0x00070000 + movne \rx, #0xf0000000 @ virtual base + addne \rx, \rx, #0x00070000 + .endm + + .macro senduart,rd,rx + strb \rd, [\rx, #0] @ data register at 0 + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #0x18] @ UARTFLG + tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full + bne 1001b + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, #0x18] @ UARTFLG + tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy + bne 1001b + .endm diff --git a/arch/arm/plat-stmp3xxx/include/mach/dma.h b/arch/arm/plat-stmp3xxx/include/mach/dma.h new file mode 100644 index 000000000000..1e305b2bfe73 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/dma.h @@ -0,0 +1,155 @@ +/* + * Freescale STMP37XX/STMP378X DMA helper interface + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_PLAT_STMP3XXX_DMA_H +#define __ASM_PLAT_STMP3XXX_DMA_H + +#include +#include + +#if !defined(MAX_PIO_WORDS) +#define MAX_PIO_WORDS (15) +#endif + +#define STMP3XXX_BUS_APBH 0 +#define STMP3XXX_BUS_APBX 1 +#define STMP3XXX_DMA_MAX_CHANNEL 16 + + +#define STMP3xxx_DMA(channel, bus) ((bus) * 16 + (channel)) + +#define MAX_DMA_ADDRESS 0xffffffff + +#define MAX_DMA_CHANNELS 32 + +struct stmp3xxx_dma_command { + u32 next; + u32 cmd; + union { + u32 buf_ptr; + u32 alternate; + }; + u32 pio_words[MAX_PIO_WORDS]; +}; + +struct stmp3xxx_dma_descriptor { + struct stmp3xxx_dma_command *command; + dma_addr_t handle; + + /* The virtual address of the buffer pointer */ + void *virtual_buf_ptr; + /* The next descriptor in a the DMA chain (optional) */ + struct stmp3xxx_dma_descriptor *next_descr; +}; + +struct stmp37xx_circ_dma_chain { + unsigned total_count; + struct stmp3xxx_dma_descriptor *chain; + + unsigned free_index; + unsigned free_count; + unsigned active_index; + unsigned active_count; + unsigned cooked_index; + unsigned cooked_count; + + int bus; + unsigned channel; +}; + +static inline struct stmp3xxx_dma_descriptor + *stmp3xxx_dma_circ_get_free_head(struct stmp37xx_circ_dma_chain *chain) +{ + return &(chain->chain[chain->free_index]); +} + +static inline struct stmp3xxx_dma_descriptor + *stmp3xxx_dma_circ_get_cooked_head(struct stmp37xx_circ_dma_chain *chain) +{ + return &(chain->chain[chain->cooked_index]); +} + +int stmp3xxx_dma_request(int ch, struct device *dev, const char *name); +int stmp3xxx_dma_release(int ch); +int stmp3xxx_dma_allocate_command(int ch, + struct stmp3xxx_dma_descriptor *descriptor); +int stmp3xxx_dma_free_command(int ch, + struct stmp3xxx_dma_descriptor *descriptor); +void stmp3xxx_dma_continue(int channel, u32 semaphore); +void stmp3xxx_dma_go(int ch, struct stmp3xxx_dma_descriptor *head, + u32 semaphore); +int stmp3xxx_dma_running(int ch); +int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain, + struct stmp3xxx_dma_descriptor descriptors[], + unsigned items); +void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain); +void stmp37xx_circ_clear_chain(struct stmp37xx_circ_dma_chain *chain); +void stmp37xx_circ_advance_free(struct stmp37xx_circ_dma_chain *chain, + unsigned count); +void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain, + unsigned count); +unsigned stmp37xx_circ_advance_cooked(struct stmp37xx_circ_dma_chain *chain); +int stmp3xxx_dma_read_semaphore(int ch); +void stmp3xxx_dma_init(void); +void stmp3xxx_dma_set_alt_target(int ch, int target); +void stmp3xxx_dma_suspend(void); +void stmp3xxx_dma_resume(void); + +/* + * STMP37xx and STMP378x have different DMA control + * registers layout + */ + +void stmp3xxx_arch_dma_freeze(int ch); +void stmp3xxx_arch_dma_unfreeze(int ch); +void stmp3xxx_arch_dma_reset_channel(int ch); +void stmp3xxx_arch_dma_enable_interrupt(int ch); +void stmp3xxx_arch_dma_clear_interrupt(int ch); +int stmp3xxx_arch_dma_is_interrupt(int ch); + +static inline void stmp3xxx_dma_reset_channel(int ch) +{ + stmp3xxx_arch_dma_reset_channel(ch); +} + + +static inline void stmp3xxx_dma_freeze(int ch) +{ + stmp3xxx_arch_dma_freeze(ch); +} + +static inline void stmp3xxx_dma_unfreeze(int ch) +{ + stmp3xxx_arch_dma_unfreeze(ch); +} + +static inline void stmp3xxx_dma_enable_interrupt(int ch) +{ + stmp3xxx_arch_dma_enable_interrupt(ch); +} + +static inline void stmp3xxx_dma_clear_interrupt(int ch) +{ + stmp3xxx_arch_dma_clear_interrupt(ch); +} + +static inline int stmp3xxx_dma_is_interrupt(int ch) +{ + return stmp3xxx_arch_dma_is_interrupt(ch); +} + +#endif /* __ASM_PLAT_STMP3XXX_DMA_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/gpio.h b/arch/arm/plat-stmp3xxx/include/mach/gpio.h new file mode 100644 index 000000000000..a8b579256170 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/gpio.h @@ -0,0 +1,28 @@ +/* + * Freescale STMP37XX/STMP378X GPIO interface + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_PLAT_GPIO_H +#define __ASM_PLAT_GPIO_H + +#define ARCH_NR_GPIOS (32 * 3) +#define gpio_to_irq(gpio) __gpio_to_irq(gpio) +#define gpio_get_value(gpio) __gpio_get_value(gpio) +#define gpio_set_value(gpio, value) __gpio_set_value(gpio, value) + +#include + +#endif /* __ASM_PLAT_GPIO_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/hardware.h b/arch/arm/plat-stmp3xxx/include/mach/hardware.h new file mode 100644 index 000000000000..47b8978405bc --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/hardware.h @@ -0,0 +1,32 @@ +/* + * This file contains the hardware definitions of the Freescale STMP3XXX + * + * Copyright (C) 2005 Sigmatel Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +/* + * Where in virtual memory the IO devices (timers, system controllers + * and so on) + */ +#define IO_BASE 0xF0000000 /* VA of IO */ +#define IO_SIZE 0x00100000 /* How much? */ +#define IO_START 0x80000000 /* PA of IO */ + +/* macro to get at IO space when running virtually */ +#define IO_ADDRESS(x) (((x) & 0x000fffff) | IO_BASE) + +#endif diff --git a/arch/arm/plat-stmp3xxx/include/mach/io.h b/arch/arm/plat-stmp3xxx/include/mach/io.h new file mode 100644 index 000000000000..d08b1b7f3d1c --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/io.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2005 Sigmatel Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) +#define __mem_isa(a) (a) + +#endif diff --git a/arch/arm/plat-stmp3xxx/include/mach/memory.h b/arch/arm/plat-stmp3xxx/include/mach/memory.h new file mode 100644 index 000000000000..7b875a07a1a7 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/memory.h @@ -0,0 +1,22 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +/* + * Physical DRAM offset. + */ +#define PHYS_OFFSET UL(0x40000000) + +#endif diff --git a/arch/arm/plat-stmp3xxx/include/mach/pinmux.h b/arch/arm/plat-stmp3xxx/include/mach/pinmux.h new file mode 100644 index 000000000000..526c068d7c44 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/pinmux.h @@ -0,0 +1,158 @@ +/* + * Freescale STMP37XX/STMP378X Pin Multiplexing + * + * Author: Vladislav Buzov + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __PINMUX_H +#define __PINMUX_H + +#include +#include +#include +#include + +/* Pin definitions */ +#include "pins.h" +#include + +/* + * Each pin may be routed up to four different HW interfaces + * including GPIO + */ +enum pin_fun { + PIN_FUN1 = 0, + PIN_FUN2, + PIN_FUN3, + PIN_GPIO, +}; + +/* + * Each pin may have different output drive strength in range from + * 4mA to 20mA. The most common case is 4, 8 and 12 mA strengths. + */ +enum pin_strength { + PIN_4MA = 0, + PIN_8MA, + PIN_12MA, + PIN_16MA, + PIN_20MA, +}; + +/* + * Each pin can be programmed for 1.8V or 3.3V + */ +enum pin_voltage { + PIN_1_8V = 0, + PIN_3_3V, +}; + +/* + * Structure to define a group of pins and their parameters + */ +struct pin_desc { + unsigned id; + enum pin_fun fun; + enum pin_strength strength; + enum pin_voltage voltage; + unsigned pullup:1; +}; + +struct pin_group { + struct pin_desc *pins; + int nr_pins; +}; + +/* Set pin drive strength */ +void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength, + const char *label); + +/* Set pin voltage */ +void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage, + const char *label); + +/* Enable pull-up resistor for a pin */ +void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label); + +/* + * Request a pin ownership, only one module (identified by @label) + * may own a pin. + */ +int stmp3xxx_request_pin(unsigned id, enum pin_fun fun, const char *label); + +/* Release pin */ +void stmp3xxx_release_pin(unsigned id, const char *label); + +void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun); + +/* + * Each bank is associated with a number of registers to control + * pin function, drive strength, voltage and pull-up reigster. The + * number of registers of a given type depends on the number of bits + * describin particular pin. + */ +#define HW_MUXSEL_NUM 2 /* registers per bank */ +#define HW_MUXSEL_PIN_LEN 2 /* bits per pin */ +#define HW_MUXSEL_PIN_NUM 16 /* pins per register */ +#define HW_MUXSEL_PINFUN_MASK 0x3 /* pin function mask */ +#define HW_MUXSEL_PINFUN_NUM 4 /* four options for a pin */ + +#define HW_DRIVE_NUM 4 /* registers per bank */ +#define HW_DRIVE_PIN_LEN 4 /* bits per pin */ +#define HW_DRIVE_PIN_NUM 8 /* pins per register */ +#define HW_DRIVE_PINDRV_MASK 0x3 /* pin strength mask - 2 bits */ +#define HW_DRIVE_PINDRV_NUM 5 /* five possible strength values */ +#define HW_DRIVE_PINV_MASK 0x4 /* pin voltage mask - 1 bit */ + + +struct stmp3xxx_pinmux_bank { + struct gpio_chip chip; + + /* Pins allocation map */ + unsigned long pin_map; + + /* Pin owner names */ + const char *pin_labels[32]; + + /* Bank registers */ + void __iomem *hw_muxsel[HW_MUXSEL_NUM]; + void __iomem *hw_drive[HW_DRIVE_NUM]; + void __iomem *hw_pull; + + void __iomem *pin2irq, + *irqlevel, + *irqpolarity, + *irqen, + *irqstat; + + /* HW MUXSEL register function bit values */ + u8 functions[HW_MUXSEL_PINFUN_NUM]; + + /* + * HW DRIVE register strength bit values: + * 0xff - requested strength is not supported for this bank + */ + u8 strengths[HW_DRIVE_PINDRV_NUM]; + + /* GPIO things */ + void __iomem *hw_gpio_read, + *hw_gpio_set, + *hw_gpio_clr, + *hw_gpio_doe; + int irq, virq; +}; + +int __init stmp3xxx_pinmux_init(int virtual_irq_start); + +#endif /* __PINMUX_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/pins.h b/arch/arm/plat-stmp3xxx/include/mach/pins.h new file mode 100644 index 000000000000..c573318e1caa --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/pins.h @@ -0,0 +1,30 @@ +/* + * Freescale STMP37XX/STMP378X Pin multiplexing interface definitions + * + * Author: Vladislav Buzov + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_PLAT_PINS_H +#define __ASM_PLAT_PINS_H + +#define STMP3XXX_PINID(bank, pin) (bank * 32 + pin) +#define STMP3XXX_PINID_TO_BANK(pinid) (pinid / 32) +#define STMP3XXX_PINID_TO_PINNUM(pinid) (pinid % 32) + +/* + * Special invalid pin identificator to show a pin doesn't exist + */ +#define PINID_NO_PIN STMP3XXX_PINID(0xFF, 0xFF) + +#endif /* __ASM_PLAT_PINS_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/platform.h b/arch/arm/plat-stmp3xxx/include/mach/platform.h new file mode 100644 index 000000000000..525c41379bbe --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/platform.h @@ -0,0 +1,47 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_PLAT_PLATFORM_H +#define __ASM_PLAT_PLATFORM_H + +#include + +/* Virtual address where registers are mapped */ +#define STMP3XXX_REGS_PHBASE 0x80000000 +#ifdef __ASSEMBLER__ +#define STMP3XXX_REGS_BASE 0xF0000000 +#else +#define STMP3XXX_REGS_BASE (void __iomem *)0xF0000000 +#endif +#define STMP3XXX_REGS_SIZE SZ_1M + +/* Virtual address where OCRAM is mapped */ +#define STMP3XXX_OCRAM_PHBASE 0x00000000 +#ifdef __ASSEMBLER__ +#define STMP3XXX_OCRAM_BASE 0xf1000000 +#else +#define STMP3XXX_OCRAM_BASE (void __iomem *)0xf1000000 +#endif +#define STMP3XXX_OCRAM_SIZE (32 * SZ_1K) + +#ifdef CONFIG_ARCH_STMP37XX +#define IRQ_PRIORITY_REG_RD HW_ICOLL_PRIORITYn_RD +#define IRQ_PRIORITY_REG_WR HW_ICOLL_PRIORITYn_WR +#endif + +#ifdef CONFIG_ARCH_STMP378X +#define IRQ_PRIORITY_REG_RD HW_ICOLL_INTERRUPTn_RD +#define IRQ_PRIORITY_REG_WR HW_ICOLL_INTERRUPTn_WR +#endif + +#endif /* __ASM_ARCH_PLATFORM_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h b/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h new file mode 100644 index 000000000000..78cf1be75519 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h @@ -0,0 +1,34 @@ +/* + * Freescale STMP37XX/STMP378X core structure and function declarations + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_PLAT_STMP3XXX_H +#define __ASM_PLAT_STMP3XXX_H + +#include + +extern struct sys_timer stmp3xxx_timer; + +void stmp3xxx_init_irq(struct irq_chip *chip); +void stmp3xxx_init(void); +int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable); +extern struct platform_device stmp3xxx_dbguart; + +struct pin_group; +void stmp3xxx_release_pin_group(struct pin_group *pin_group, const char *label); +int stmp3xxx_request_pin_group(struct pin_group *pin_group, const char *label); + +#endif /* __ASM_PLAT_STMP3XXX_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx_regs.h b/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx_regs.h new file mode 100644 index 000000000000..47797b2b36af --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx_regs.h @@ -0,0 +1,195 @@ +/* + * Freescale STMP37XX/STMP378X SoC register access interfaces + * + * The SoC registers may be accessed via: + * + * - single 32 bit address, or + * - four 32 bit addresses - general purpose, set, clear and toggle bits + * + * Multiple IP blocks (e.g. SSP, UART) provide identical register sets per + * each module + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_PLAT_STMP3XXX_REGS_H +#define __ASM_PLAT_STMP3XXX_REGS_H + +#ifndef __ASSEMBLER__ +#include +#endif + +#include "platform.h" + +#define REGS_BASE STMP3XXX_REGS_BASE + +#define HW_STMP3xxx_SET 0x04 +#define HW_STMP3xxx_CLR 0x08 +#define HW_STMP3xxx_TOG 0x0c + +#ifndef __ASSEMBLER__ +#define HW_REGISTER_FUNCS(id, base, offset, regset, rd, wr) \ + static const u32 id##_OFFSET = offset; \ + static inline u32 id##_RD_NB(const void __iomem *regbase) { \ + if (!rd) \ + printk(KERN_ERR"%s: cannot READ at %p+%x\n", \ + #id, regbase, offset); \ + return __raw_readl(regbase + offset); \ + } \ + static inline void id##_WR_NB(void __iomem *regbase, u32 v) { \ + if (!wr) \ + printk(KERN_ERR"%s: cannot WRITE at %p+%x\n", \ + #id, regbase, offset); \ + __raw_writel(v, regbase + offset); \ + } \ + static inline void id##_SET_NB(void __iomem *regbase, u32 v) { \ + if (!wr) \ + printk(KERN_ERR"%s: cannot SET at %p+%x\n", \ + #id, regbase, offset); \ + if (regset) \ + __raw_writel(v, regbase + \ + offset + HW_STMP3xxx_SET); \ + else \ + __raw_writel(v | __raw_readl(regbase + offset), \ + regbase + offset); \ + } \ + static inline void id##_CLR_NB(void __iomem *regbase, u32 v) { \ + if (!wr) \ + printk(KERN_ERR"%s: cannot CLR at %p+%x\n", \ + #id, regbase, offset); \ + if (regset) \ + __raw_writel(v, regbase + \ + offset + HW_STMP3xxx_CLR); \ + else \ + __raw_writel( \ + ~v & __raw_readl(regbase + offset), \ + regbase + offset); \ + } \ + static inline void id##_TOG_NB(void __iomem *regbase, u32 v) { \ + if (!wr) \ + printk(KERN_ERR"%s: cannot TOG at %p+%x\n", \ + #id, regbase, offset); \ + if (regset) \ + __raw_writel(v, regbase + \ + offset + HW_STMP3xxx_TOG); \ + else \ + __raw_writel(v ^ __raw_readl(regbase + offset), \ + regbase + offset); \ + } \ + static inline u32 id##_RD(void) { return id##_RD_NB(base); } \ + static inline void id##_WR(u32 v) { id##_WR_NB(base, v); } \ + static inline void id##_SET(u32 v) { id##_SET_NB(base, v); } \ + static inline void id##_CLR(u32 v) { id##_CLR_NB(base, v); } \ + static inline void id##_TOG(u32 v) { id##_TOG_NB(base, v); } + +#define HW_REGISTER_FUNCS_INDEXED(id, base, offset, regset, rd, wr, step)\ + static inline u32 id##_OFFSET(int i) { \ + return offset + i * step; \ + } \ + static inline u32 id##_RD_NB(const void __iomem *regbase, int i) {\ + if (!rd) \ + printk(KERN_ERR"%s(%d): can't READ at %p+%x\n", \ + #id, i, regbase, offset + i * step); \ + return __raw_readl(regbase + offset + i * step); \ + } \ + static inline void id##_WR_NB(void __iomem *regbase, int i, u32 v) {\ + if (!wr) \ + printk(KERN_ERR"%s(%d): can't WRITE at %p+%x\n",\ + #id, i, regbase, offset + i * step); \ + __raw_writel(v, regbase + offset + i * step); \ + } \ + static inline void id##_SET_NB(void __iomem *regbase, int i, u32 v) {\ + if (!wr) \ + printk(KERN_ERR"%s(%d): can't SET at %p+%x\n", \ + #id, i, regbase, offset + i * step); \ + if (regset) \ + __raw_writel(v, regbase + offset + \ + i * step + HW_STMP3xxx_SET); \ + else \ + __raw_writel(v | __raw_readl(regbase + \ + offset + i * step), \ + regbase + offset + i * step); \ + } \ + static inline void id##_CLR_NB(void __iomem *regbase, int i, u32 v) {\ + if (!wr) \ + printk(KERN_ERR"%s(%d): cannot CLR at %p+%x\n", \ + #id, i, regbase, offset + i * step); \ + if (regset) \ + __raw_writel(v, regbase + offset + \ + i * step + HW_STMP3xxx_CLR); \ + else \ + __raw_writel(~v & __raw_readl(regbase + \ + offset + i * step), \ + regbase + offset + i * step); \ + } \ + static inline void id##_TOG_NB(void __iomem *regbase, int i, u32 v) {\ + if (!wr) \ + printk(KERN_ERR"%s(%d): cannot TOG at %p+%x\n", \ + #id, i, regbase, offset + i * step); \ + if (regset) \ + __raw_writel(v, regbase + offset + \ + i * step + HW_STMP3xxx_TOG); \ + else \ + __raw_writel(v ^ __raw_readl(regbase + offset \ + + i * step), \ + regbase + offset + i * step); \ + } \ + static inline u32 id##_RD(int i) \ + { \ + return id##_RD_NB(base, i); \ + } \ + static inline void id##_WR(int i, u32 v) \ + { \ + id##_WR_NB(base, i, v); \ + } \ + static inline void id##_SET(int i, u32 v) \ + { \ + id##_SET_NB(base, i, v); \ + } \ + static inline void id##_CLR(int i, u32 v) \ + { \ + id##_CLR_NB(base, i, v); \ + } \ + static inline void id##_TOG(int i, u32 v) \ + { \ + id##_TOG_NB(base, i, v); \ + } + +#define HW_REGISTER_WO(id, base, offset)\ + HW_REGISTER_FUNCS(id, base, offset, 1, 0, 1) +#define HW_REGISTER_RO(id, base, offset)\ + HW_REGISTER_FUNCS(id, base, offset, 1, 1, 0) +#define HW_REGISTER(id, base, offset) \ + HW_REGISTER_FUNCS(id, base, offset, 1, 1, 1) +#define HW_REGISTER_0(id, base, offset) \ + HW_REGISTER_FUNCS(id, base, offset, 0, 1, 1) +#define HW_REGISTER_INDEXED(id, base, offset, step) \ + HW_REGISTER_FUNCS_INDEXED(id, base, offset, 1, 1, 1, step) +#define HW_REGISTER_RO_INDEXED(id, base, offset, step) \ + HW_REGISTER_FUNCS_INDEXED(id, base, offset, 1, 1, 0, step) +#define HW_REGISTER_0_INDEXED(id, base, offset, step) \ + HW_REGISTER_FUNCS_INDEXED(id, base, offset, 0, 1, 1, step) +#else /* __ASSEMBLER__ */ +#define HW_REGISTER_FUNCS(id, base, offset, regset, rd, wr) +#define HW_REGISTER_FUNCS_INDEXED(id, base, offset, regset, rd, wr, step) +#define HW_REGISTER_WO(id, base, offset) +#define HW_REGISTER_RO(id, base, offset) +#define HW_REGISTER(id, base, offset) +#define HW_REGISTER_0(id, base, offset) +#define HW_REGISTER_INDEXED(id, base, offset, step) +#define HW_REGISTER_RO_INDEXED(id, base, offset, step) +#define HW_REGISTER_0_INDEXED(id, base, offset, step) +#endif /* __ASSEMBLER__ */ + +#endif /* __ASM_PLAT_STMP3XXX_REGS_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/system.h b/arch/arm/plat-stmp3xxx/include/mach/system.h new file mode 100644 index 000000000000..dac48d267148 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/system.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2005 Sigmatel Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +#include +#include +#include + +static inline void arch_idle(void) +{ + /* + * This should do all the clock switching + * and wait for interrupt tricks + */ + + cpu_do_idle(); +} + +static inline void arch_reset(char mode, const char *cmd) +{ + /* Set BATTCHRG to default value */ + HW_POWER_CHARGE_WR(0x00010000); + + /* Set MINPWR to default value */ + HW_POWER_MINPWR_WR(0); + + /* Reset digital side of chip (but not power or RTC) */ + HW_CLKCTRL_RESET_WR(BM_CLKCTRL_RESET_DIG); + + /* Should not return */ +} + +#endif diff --git a/arch/arm/plat-stmp3xxx/include/mach/timex.h b/arch/arm/plat-stmp3xxx/include/mach/timex.h new file mode 100644 index 000000000000..3373985d7a8e --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/timex.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 1999 ARM Limited + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/* + * System time clock is sourced from the 32k clock + */ +#define CLOCK_TICK_RATE (32768) diff --git a/arch/arm/plat-stmp3xxx/include/mach/uncompress.h b/arch/arm/plat-stmp3xxx/include/mach/uncompress.h new file mode 100644 index 000000000000..f79f5ee56cd4 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/uncompress.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ASM_PLAT_UNCOMPRESS_H +#define __ASM_PLAT_UNCOMPRESS_H + +/* + * Register includes are for when the MMU enabled; we need to define our + * own stuff here for pre-MMU use + */ +#define UARTDBG_BASE 0x80070000 +#define UART(c) (((volatile unsigned *)UARTDBG_BASE)[c]) + +/* + * This does not append a newline + */ +static void putc(char c) +{ + /* Wait for TX fifo empty */ + while ((UART(6) & (1<<7)) == 0) + continue; + + /* Write byte */ + UART(0) = c; + + /* Wait for last bit to exit the UART */ + while (UART(6) & (1<<3)) + continue; +} + +static void flush(void) +{ +} + +/* + * nothing to do + */ +#define arch_decomp_setup() + +#define arch_decomp_wdog() + +#endif /* __ASM_PLAT_UNCOMPRESS_H */ diff --git a/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h b/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h new file mode 100644 index 000000000000..541b880c1863 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h @@ -0,0 +1,12 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#define VMALLOC_END (0xF0000000) -- GitLab From 5cccd37ea15970846a93b4b01fafd6e043bafe8e Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Thu, 23 Apr 2009 12:24:13 +0100 Subject: [PATCH 0720/6080] [ARM] 5477/1: Freescale STMP platform support [6/10] Sources: common STMP3xxx platform support Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- arch/arm/plat-stmp3xxx/Kconfig | 37 + arch/arm/plat-stmp3xxx/Makefile | 5 + arch/arm/plat-stmp3xxx/clock.c | 1112 +++++++++++++++++++++++++++++++ arch/arm/plat-stmp3xxx/clock.h | 61 ++ arch/arm/plat-stmp3xxx/core.c | 127 ++++ arch/arm/plat-stmp3xxx/dma.c | 462 +++++++++++++ arch/arm/plat-stmp3xxx/irq.c | 59 ++ arch/arm/plat-stmp3xxx/pinmux.c | 545 +++++++++++++++ arch/arm/plat-stmp3xxx/timer.c | 172 +++++ 9 files changed, 2580 insertions(+) create mode 100644 arch/arm/plat-stmp3xxx/Kconfig create mode 100644 arch/arm/plat-stmp3xxx/Makefile create mode 100644 arch/arm/plat-stmp3xxx/clock.c create mode 100644 arch/arm/plat-stmp3xxx/clock.h create mode 100644 arch/arm/plat-stmp3xxx/core.c create mode 100644 arch/arm/plat-stmp3xxx/dma.c create mode 100644 arch/arm/plat-stmp3xxx/irq.c create mode 100644 arch/arm/plat-stmp3xxx/pinmux.c create mode 100644 arch/arm/plat-stmp3xxx/timer.c diff --git a/arch/arm/plat-stmp3xxx/Kconfig b/arch/arm/plat-stmp3xxx/Kconfig new file mode 100644 index 000000000000..2cf37c35951b --- /dev/null +++ b/arch/arm/plat-stmp3xxx/Kconfig @@ -0,0 +1,37 @@ +if ARCH_STMP3XXX + +menu "Freescale STMP3xxx implementations" + +choice + prompt "Select STMP3xxx chip family" + +config ARCH_STMP37XX + bool "Freescale SMTP37xx" + select CPU_ARM926T + ---help--- + STMP37xx refers to 3700 through 3769 chips + +config ARCH_STMP378X + bool "Freescale STMP378x" + select CPU_ARM926T + ---help--- + STMP378x refers to 3780 through 3789 chips + +endchoice + +choice + prompt "Select STMP3xxx board type" + +config MACH_STMP37XX + depends on ARCH_STMP37XX + bool "Freescale STMP37xx development board" + +config MACH_STMP378X + depends on ARCH_STMP378X + bool "Freescale STMP378x development board" + +endchoice + +endmenu + +endif diff --git a/arch/arm/plat-stmp3xxx/Makefile b/arch/arm/plat-stmp3xxx/Makefile new file mode 100644 index 000000000000..b63480066d6b --- /dev/null +++ b/arch/arm/plat-stmp3xxx/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the linux kernel. +# +# Object file lists. +obj-y += core.o timer.o irq.o dma.o clock.o pinmux.o diff --git a/arch/arm/plat-stmp3xxx/clock.c b/arch/arm/plat-stmp3xxx/clock.c new file mode 100644 index 000000000000..9a1d46b470cd --- /dev/null +++ b/arch/arm/plat-stmp3xxx/clock.c @@ -0,0 +1,1112 @@ +/* + * Clock manipulation routines for Freescale STMP37XX/STMP378X + * + * Author: Vitaly Wool + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "clock.h" + +static DEFINE_SPINLOCK(clocks_lock); + +static struct clk osc_24M; +static struct clk pll_clk; +static struct clk cpu_clk; +static struct clk hclk; + +static int propagate_rate(struct clk *); + +static inline int clk_is_busy(struct clk *clk) +{ + return __raw_readl(clk->busy_reg) & (1 << clk->busy_bit); +} + +static inline int clk_good(struct clk *clk) +{ + return clk && !IS_ERR(clk) && clk->ops; +} + +static int std_clk_enable(struct clk *clk) +{ + if (clk->enable_reg) { + u32 clk_reg = __raw_readl(clk->enable_reg); + if (clk->enable_negate) + clk_reg &= ~(1 << clk->enable_shift); + else + clk_reg |= (1 << clk->enable_shift); + __raw_writel(clk_reg, clk->enable_reg); + if (clk->enable_wait) + udelay(clk->enable_wait); + return 0; + } else + return -EINVAL; +} + +static int std_clk_disable(struct clk *clk) +{ + if (clk->enable_reg) { + u32 clk_reg = __raw_readl(clk->enable_reg); + if (clk->enable_negate) + clk_reg |= (1 << clk->enable_shift); + else + clk_reg &= ~(1 << clk->enable_shift); + __raw_writel(clk_reg, clk->enable_reg); + return 0; + } else + return -EINVAL; +} + +static int io_set_rate(struct clk *clk, u32 rate) +{ + u32 reg_frac, clkctrl_frac; + int i, ret = 0, mask = 0x1f; + + clkctrl_frac = (clk->parent->rate * 18 + rate - 1) / rate; + + if (clkctrl_frac < 18 || clkctrl_frac > 35) { + ret = -EINVAL; + goto out; + } + + reg_frac = __raw_readl(clk->scale_reg); + reg_frac &= ~(mask << clk->scale_shift); + __raw_writel(reg_frac | (clkctrl_frac << clk->scale_shift), + clk->scale_reg); + if (clk->busy_reg) { + for (i = 10000; i; i--) + if (!clk_is_busy(clk)) + break; + if (!i) + ret = -ETIMEDOUT; + else + ret = 0; + } +out: + return ret; +} + +static long io_get_rate(struct clk *clk) +{ + long rate = clk->parent->rate * 18; + int mask = 0x1f; + + rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask; + clk->rate = rate; + + return rate; +} + +static long per_get_rate(struct clk *clk) +{ + long rate = clk->parent->rate; + long div; + const int mask = 0xff; + + if (clk->enable_reg && + !(__raw_readl(clk->enable_reg) & clk->enable_shift)) + clk->rate = 0; + else { + div = (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask; + if (div) + rate /= div; + clk->rate = rate; + } + + return clk->rate; +} + +static int per_set_rate(struct clk *clk, u32 rate) +{ + int ret = -EINVAL; + int div = (clk->parent->rate + rate - 1) / rate; + u32 reg_frac; + const int mask = 0xff; + int try = 10; + int i = -1; + + if (div == 0 || div > mask) + goto out; + + reg_frac = __raw_readl(clk->scale_reg); + reg_frac &= ~(mask << clk->scale_shift); + + while (try--) { + __raw_writel(reg_frac | (div << clk->scale_shift), + clk->scale_reg); + + if (clk->busy_reg) { + for (i = 10000; i; i--) + if (!clk_is_busy(clk)) + break; + } + if (i) + break; + } + + if (!i) + ret = -ETIMEDOUT; + else + ret = 0; + +out: + if (ret != 0) + printk(KERN_ERR "%s: error %d\n", __func__, ret); + return ret; +} + +static long lcdif_get_rate(struct clk *clk) +{ + long rate = clk->parent->rate; + long div; + const int mask = 0xff; + + div = (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask; + if (div) { + rate /= div; + div = (HW_CLKCTRL_FRAC_RD() & BM_CLKCTRL_FRAC_PIXFRAC) >> + BP_CLKCTRL_FRAC_PIXFRAC; + rate /= div; + } + clk->rate = rate; + + return rate; +} + +static int lcdif_set_rate(struct clk *clk, u32 rate) +{ + int ret = 0; + /* + * On 3700, we can get most timings exact by modifying ref_pix + * and the divider, but keeping the phase timings at 1 (2 + * phases per cycle). + * + * ref_pix can be between 480e6*18/35=246.9MHz and 480e6*18/18=480MHz, + * which is between 18/(18*480e6)=2.084ns and 35/(18*480e6)=4.050ns. + * + * ns_cycle >= 2*18e3/(18*480) = 25/6 + * ns_cycle <= 2*35e3/(18*480) = 875/108 + * + * Multiply the ns_cycle by 'div' to lengthen it until it fits the + * bounds. This is the divider we'll use after ref_pix. + * + * 6 * ns_cycle >= 25 * div + * 108 * ns_cycle <= 875 * div + */ + u32 ns_cycle = 1000000 / rate; + u32 div, reg_val; + u32 lowest_result = (u32) -1; + u32 lowest_div = 0, lowest_fracdiv = 0; + + for (div = 1; div < 256; ++div) { + u32 fracdiv; + u32 ps_result; + int lower_bound = 6 * ns_cycle >= 25 * div; + int upper_bound = 108 * ns_cycle <= 875 * div; + if (!lower_bound) + break; + if (!upper_bound) + continue; + /* + * Found a matching div. Calculate fractional divider needed, + * rounded up. + */ + fracdiv = ((clk->parent->rate / 1000 * 18 / 2) * + ns_cycle + 1000 * div - 1) / + (1000 * div); + if (fracdiv < 18 || fracdiv > 35) { + ret = -EINVAL; + goto out; + } + /* Calculate the actual cycle time this results in */ + ps_result = 6250 * div * fracdiv / 27; + + /* Use the fastest result that doesn't break ns_cycle */ + if (ps_result <= lowest_result) { + lowest_result = ps_result; + lowest_div = div; + lowest_fracdiv = fracdiv; + } + } + + if (div >= 256 || lowest_result == (u32) -1) { + ret = -EINVAL; + goto out; + } + pr_debug("Programming PFD=%u,DIV=%u ref_pix=%uMHz " + "PIXCLK=%uMHz cycle=%u.%03uns\n", + lowest_fracdiv, lowest_div, + 480*18/lowest_fracdiv, 480*18/lowest_fracdiv/lowest_div, + lowest_result / 1000, lowest_result % 1000); + + /* Program ref_pix phase fractional divider */ + HW_CLKCTRL_FRAC_WR((HW_CLKCTRL_FRAC_RD() & ~BM_CLKCTRL_FRAC_PIXFRAC) | + BF_CLKCTRL_FRAC_PIXFRAC(lowest_fracdiv)); + /* Ungate PFD */ + HW_CLKCTRL_FRAC_CLR(BM_CLKCTRL_FRAC_CLKGATEPIX); + + /* Program pix divider */ + reg_val = __raw_readl(clk->scale_reg); + reg_val &= ~(BM_CLKCTRL_PIX_DIV | BM_CLKCTRL_PIX_CLKGATE); + reg_val |= BF_CLKCTRL_PIX_DIV(lowest_div); + __raw_writel(reg_val, clk->scale_reg); + + /* Wait for divider update */ + if (clk->busy_reg) { + int i; + for (i = 10000; i; i--) + if (!clk_is_busy(clk)) + break; + if (!i) { + ret = -ETIMEDOUT; + goto out; + } + } + + /* Switch to ref_pix source */ + HW_CLKCTRL_CLKSEQ_CLR(BM_CLKCTRL_CLKSEQ_BYPASS_PIX); + +out: + return ret; +} + + +static int cpu_set_rate(struct clk *clk, u32 rate) +{ + if (rate < 24000) + return -EINVAL; + else if (rate == 24000) { + /* switch to the 24M source */ + clk_set_parent(clk, &osc_24M); + } else { + int i; + u32 clkctrl_cpu = 1; + u32 c = clkctrl_cpu; + u32 clkctrl_frac = 1; + u32 val; + for ( ; c < 0x40; c++) { + u32 f = (pll_clk.rate*18/c + rate/2) / rate; + int s1, s2; + + if (f < 18 || f > 35) + continue; + s1 = pll_clk.rate*18/clkctrl_frac/clkctrl_cpu - rate; + s2 = pll_clk.rate*18/c/f - rate; + pr_debug("%s: s1 %d, s2 %d\n", __func__, s1, s2); + if (abs(s1) > abs(s2)) { + clkctrl_cpu = c; + clkctrl_frac = f; + } + if (s2 == 0) + break; + }; + pr_debug("%s: clkctrl_cpu %d, clkctrl_frac %d\n", __func__, + clkctrl_cpu, clkctrl_frac); + if (c == 0x40) { + int d = pll_clk.rate*18/clkctrl_frac/clkctrl_cpu - + rate; + if (abs(d) > 100 || + clkctrl_frac < 18 || clkctrl_frac > 35) + return -EINVAL; + } + + /* 4.6.2 */ + val = __raw_readl(clk->scale_reg); + val &= ~(0x3f << clk->scale_shift); + val |= clkctrl_frac; + clk_set_parent(clk, &osc_24M); + udelay(10); + __raw_writel(val, clk->scale_reg); + /* ungate */ + __raw_writel(1<<7, clk->scale_reg + 8); + /* write clkctrl_cpu */ + clk->saved_div = clkctrl_cpu; + HW_CLKCTRL_CPU_WR((HW_CLKCTRL_CPU_RD() & ~0x3f) | clkctrl_cpu); + for (i = 10000; i; i--) + if (!clk_is_busy(clk)) + break; + if (!i) { + printk(KERN_ERR "couldn't set up CPU divisor\n"); + return -ETIMEDOUT; + } + clk_set_parent(clk, &pll_clk); + clk->saved_div = 0; + udelay(10); + } + return 0; +} + +static long cpu_get_rate(struct clk *clk) +{ + long rate = clk->parent->rate * 18; + + rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & 0x3f; + rate /= HW_CLKCTRL_CPU_RD() & 0x3f; + rate = ((rate + 9) / 10) * 10; + clk->rate = rate; + + return rate; +} + +static long cpu_round_rate(struct clk *clk, u32 rate) +{ + unsigned long r = 0; + + if (rate <= 24000) + r = 24000; + else { + u32 clkctrl_cpu = 1; + u32 clkctrl_frac; + do { + clkctrl_frac = + (pll_clk.rate*18 / clkctrl_cpu + rate/2) / rate; + if (clkctrl_frac > 35) + continue; + if (pll_clk.rate*18 / clkctrl_frac / clkctrl_cpu/10 == + rate / 10) + break; + } while (pll_clk.rate / 2 >= clkctrl_cpu++ * rate); + if (pll_clk.rate / 2 < (clkctrl_cpu - 1) * rate) + clkctrl_cpu--; + pr_debug("%s: clkctrl_cpu %d, clkctrl_frac %d\n", __func__, + clkctrl_cpu, clkctrl_frac); + if (clkctrl_frac < 18) + clkctrl_frac = 18; + if (clkctrl_frac > 35) + clkctrl_frac = 35; + + r = pll_clk.rate * 18; + r /= clkctrl_frac; + r /= clkctrl_cpu; + r = 10 * ((r + 9) / 10); + } + return r; +} + +static long emi_get_rate(struct clk *clk) +{ + long rate = clk->parent->rate * 18; + + rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & 0x3f; + rate /= HW_CLKCTRL_EMI_RD() & 0x3f; + clk->rate = rate; + + return rate; +} + +static int clkseq_set_parent(struct clk *clk, struct clk *parent) +{ + int ret = -EINVAL; + int shift = 8; + + /* bypass? */ + if (parent == &osc_24M) + shift = 4; + + if (clk->bypass_reg) { + u32 hbus_mask = BM_CLKCTRL_HBUS_DIV_FRAC_EN | + BM_CLKCTRL_HBUS_DIV; + + if (clk == &cpu_clk && shift == 4) { + u32 hbus_val = HW_CLKCTRL_HBUS_RD(); + u32 cpu_val = HW_CLKCTRL_CPU_RD(); + hbus_val &= ~hbus_mask; + hbus_val |= 1; + clk->saved_div = cpu_val & BM_CLKCTRL_CPU_DIV_CPU; + cpu_val &= ~BM_CLKCTRL_CPU_DIV_CPU; + cpu_val |= 1; + __raw_writel(1 << clk->bypass_shift, + clk->bypass_reg + shift); + if (machine_is_stmp378x()) { + HW_CLKCTRL_HBUS_WR(hbus_val); + HW_CLKCTRL_CPU_WR(cpu_val); + hclk.rate = 0; + } + } else if (clk == &cpu_clk && shift == 8) { + u32 hbus_val = HW_CLKCTRL_HBUS_RD(); + u32 cpu_val = HW_CLKCTRL_CPU_RD(); + hbus_val &= ~hbus_mask; + hbus_val |= 2; + cpu_val &= ~BM_CLKCTRL_CPU_DIV_CPU; + if (clk->saved_div) + cpu_val |= clk->saved_div; + else + cpu_val |= 2; + if (machine_is_stmp378x()) { + HW_CLKCTRL_HBUS_WR(hbus_val); + HW_CLKCTRL_CPU_WR(cpu_val); + hclk.rate = 0; + } + __raw_writel(1 << clk->bypass_shift, + clk->bypass_reg + shift); + } else + __raw_writel(1 << clk->bypass_shift, + clk->bypass_reg + shift); + + ret = 0; + } + + return ret; +} + +static int hbus_set_rate(struct clk *clk, u32 rate) +{ + u8 div = 0; + int is_frac = 0; + u32 clkctrl_hbus; + struct clk *parent = clk->parent; + + pr_debug("%s: rate %d, parent rate %d\n", __func__, rate, + parent->rate); + + if (rate > parent->rate) + return -EINVAL; + + if (((parent->rate + rate/2) / rate) * rate != parent->rate && + parent->rate / rate < 32) { + pr_debug("%s: switching to fractional mode\n", __func__); + is_frac = 1; + } + + if (is_frac) + div = (32 * rate + parent->rate / 2) / parent->rate; + else + div = (parent->rate + rate - 1) / rate; + pr_debug("%s: div calculated is %d\n", __func__, div); + if (!div || div > 0x1f) + return -EINVAL; + + clk_set_parent(&cpu_clk, &osc_24M); + udelay(10); + clkctrl_hbus = __raw_readl(clk->scale_reg); + clkctrl_hbus &= ~0x3f; + clkctrl_hbus |= div; + clkctrl_hbus |= (is_frac << 5); + + __raw_writel(clkctrl_hbus, clk->scale_reg); + if (clk->busy_reg) { + int i; + for (i = 10000; i; i--) + if (!clk_is_busy(clk)) + break; + if (!i) { + printk(KERN_ERR "couldn't set up CPU divisor\n"); + return -ETIMEDOUT; + } + } + clk_set_parent(&cpu_clk, &pll_clk); + __raw_writel(clkctrl_hbus, clk->scale_reg); + udelay(10); + return 0; +} + +static long hbus_get_rate(struct clk *clk) +{ + long rate = clk->parent->rate; + + if (__raw_readl(clk->scale_reg) & 0x20) { + rate *= __raw_readl(clk->scale_reg) & 0x1f; + rate /= 32; + } else + rate /= __raw_readl(clk->scale_reg) & 0x1f; + clk->rate = rate; + + return rate; +} + +static int xbus_set_rate(struct clk *clk, u32 rate) +{ + u16 div = 0; + u32 clkctrl_xbus; + + pr_debug("%s: rate %d, parent rate %d\n", __func__, rate, + clk->parent->rate); + + div = (clk->parent->rate + rate - 1) / rate; + pr_debug("%s: div calculated is %d\n", __func__, div); + if (!div || div > 0x3ff) + return -EINVAL; + + clkctrl_xbus = __raw_readl(clk->scale_reg); + clkctrl_xbus &= ~0x3ff; + clkctrl_xbus |= div; + __raw_writel(clkctrl_xbus, clk->scale_reg); + if (clk->busy_reg) { + int i; + for (i = 10000; i; i--) + if (!clk_is_busy(clk)) + break; + if (!i) { + printk(KERN_ERR "couldn't set up xbus divisor\n"); + return -ETIMEDOUT; + } + } + return 0; +} + +static long xbus_get_rate(struct clk *clk) +{ + long rate = clk->parent->rate; + + rate /= __raw_readl(clk->scale_reg) & 0x3ff; + clk->rate = rate; + + return rate; +} + + +/* Clock ops */ + +static struct clk_ops std_ops = { + .enable = std_clk_enable, + .disable = std_clk_disable, + .get_rate = per_get_rate, + .set_rate = per_set_rate, + .set_parent = clkseq_set_parent, +}; + +static struct clk_ops min_ops = { + .enable = std_clk_enable, + .disable = std_clk_disable, +}; + +static struct clk_ops cpu_ops = { + .enable = std_clk_enable, + .disable = std_clk_disable, + .get_rate = cpu_get_rate, + .set_rate = cpu_set_rate, + .round_rate = cpu_round_rate, + .set_parent = clkseq_set_parent, +}; + +static struct clk_ops io_ops = { + .enable = std_clk_enable, + .disable = std_clk_disable, + .get_rate = io_get_rate, + .set_rate = io_set_rate, +}; + +static struct clk_ops hbus_ops = { + .get_rate = hbus_get_rate, + .set_rate = hbus_set_rate, +}; + +static struct clk_ops xbus_ops = { + .get_rate = xbus_get_rate, + .set_rate = xbus_set_rate, +}; + +static struct clk_ops lcdif_ops = { + .enable = std_clk_enable, + .disable = std_clk_disable, + .get_rate = lcdif_get_rate, + .set_rate = lcdif_set_rate, + .set_parent = clkseq_set_parent, +}; + +static struct clk_ops emi_ops = { + .get_rate = emi_get_rate, +}; + +/* List of on-chip clocks */ + +static struct clk osc_24M = { + .flags = FIXED_RATE | ENABLED, + .rate = 24000, +}; + +static struct clk pll_clk = { + .parent = &osc_24M, + .enable_reg = HW_CLKCTRL_PLLCTRL0_ADDR, + .enable_shift = 16, + .enable_wait = 10, + .flags = FIXED_RATE | ENABLED, + .rate = 480000, + .ops = &min_ops, +}; + +static struct clk cpu_clk = { + .parent = &pll_clk, + .scale_reg = HW_CLKCTRL_FRAC_ADDR, + .scale_shift = 0, + .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR, + .bypass_shift = 7, + .busy_reg = HW_CLKCTRL_CPU_ADDR, + .busy_bit = 28, + .flags = RATE_PROPAGATES | ENABLED, + .ops = &cpu_ops, +}; + +static struct clk io_clk = { + .parent = &pll_clk, + .enable_reg = HW_CLKCTRL_FRAC_ADDR, + .enable_shift = 31, + .enable_negate = 1, + .scale_reg = HW_CLKCTRL_FRAC_ADDR, + .scale_shift = 24, + .flags = RATE_PROPAGATES | ENABLED, + .ops = &io_ops, +}; + +static struct clk hclk = { + .parent = &cpu_clk, + .scale_reg = HW_CLKCTRL_HBUS_ADDR, + .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR, + .bypass_shift = 7, + .busy_reg = HW_CLKCTRL_HBUS_ADDR, + .busy_bit = 29, + .flags = RATE_PROPAGATES | ENABLED, + .ops = &hbus_ops, +}; + +static struct clk xclk = { + .parent = &osc_24M, + .scale_reg = HW_CLKCTRL_XBUS_ADDR, + .busy_reg = HW_CLKCTRL_XBUS_ADDR, + .busy_bit = 31, + .flags = RATE_PROPAGATES | ENABLED, + .ops = &xbus_ops, +}; + +static struct clk uart_clk = { + .parent = &xclk, + .enable_reg = HW_CLKCTRL_XTAL_ADDR, + .enable_shift = 31, + .enable_negate = 1, + .flags = ENABLED, + .ops = &min_ops, +}; + +static struct clk audio_clk = { + .parent = &xclk, + .enable_reg = HW_CLKCTRL_XTAL_ADDR, + .enable_shift = 30, + .enable_negate = 1, + .ops = &min_ops, +}; + +static struct clk pwm_clk = { + .parent = &xclk, + .enable_reg = HW_CLKCTRL_XTAL_ADDR, + .enable_shift = 29, + .enable_negate = 1, + .ops = &min_ops, +}; + +static struct clk dri_clk = { + .parent = &xclk, + .enable_reg = HW_CLKCTRL_XTAL_ADDR, + .enable_shift = 28, + .enable_negate = 1, + .ops = &min_ops, +}; + +static struct clk digctl_clk = { + .parent = &xclk, + .enable_reg = HW_CLKCTRL_XTAL_ADDR, + .enable_shift = 27, + .enable_negate = 1, + .ops = &min_ops, +}; + +static struct clk timer_clk = { + .parent = &xclk, + .enable_reg = HW_CLKCTRL_XTAL_ADDR, + .enable_shift = 26, + .enable_negate = 1, + .flags = ENABLED, + .ops = &min_ops, +}; + +static struct clk lcdif_clk = { + .parent = &pll_clk, + .scale_reg = HW_CLKCTRL_PIX_ADDR, + .busy_reg = HW_CLKCTRL_PIX_ADDR, + .busy_bit = 29, + .enable_reg = HW_CLKCTRL_PIX_ADDR, + .enable_shift = 31, + .enable_negate = 1, + .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR, + .bypass_shift = 1, + .flags = NEEDS_SET_PARENT, + .ops = &lcdif_ops, +}; + +static struct clk ssp_clk = { + .parent = &io_clk, + .scale_reg = HW_CLKCTRL_SSP_ADDR, + .busy_reg = HW_CLKCTRL_SSP_ADDR, + .busy_bit = 29, + .enable_reg = HW_CLKCTRL_SSP_ADDR, + .enable_shift = 31, + .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR, + .bypass_shift = 5, + .enable_negate = 1, + .flags = NEEDS_SET_PARENT, + .ops = &std_ops, +}; + +static struct clk gpmi_clk = { + .parent = &io_clk, + .scale_reg = HW_CLKCTRL_GPMI_ADDR, + .busy_reg = HW_CLKCTRL_GPMI_ADDR, + .busy_bit = 29, + .enable_reg = HW_CLKCTRL_GPMI_ADDR, + .enable_shift = 31, + .enable_negate = 1, + .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR, + .bypass_shift = 4, + .flags = NEEDS_SET_PARENT, + .ops = &std_ops, +}; + +static struct clk spdif_clk = { + .parent = &pll_clk, + .enable_reg = HW_CLKCTRL_SPDIF_ADDR, + .enable_shift = 31, + .enable_negate = 1, + .ops = &min_ops, +}; + +static struct clk emi_clk = { + .parent = &pll_clk, + .enable_reg = HW_CLKCTRL_EMI_ADDR, + .enable_shift = 31, + .enable_negate = 1, + .scale_reg = HW_CLKCTRL_FRAC_ADDR, + .scale_shift = 8, + .busy_reg = HW_CLKCTRL_EMI_ADDR, + .busy_bit = 28, + .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR, + .bypass_shift = 6, + .flags = ENABLED, + .ops = &emi_ops, +}; + +static struct clk ir_clk = { + .parent = &io_clk, + .enable_reg = HW_CLKCTRL_IR_ADDR, + .enable_shift = 31, + .enable_negate = 1, + .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR, + .bypass_shift = 3, + .ops = &min_ops, +}; + +static struct clk saif_clk = { + .parent = &pll_clk, + .scale_reg = HW_CLKCTRL_SAIF_ADDR, + .busy_reg = HW_CLKCTRL_SAIF_ADDR, + .busy_bit = 29, + .enable_reg = HW_CLKCTRL_SAIF_ADDR, + .enable_shift = 31, + .enable_negate = 1, + .bypass_reg = HW_CLKCTRL_CLKSEQ_ADDR, + .bypass_shift = 0, + .ops = &std_ops, +}; + +static struct clk usb_clk = { + .parent = &pll_clk, + .enable_reg = HW_CLKCTRL_PLLCTRL0_ADDR, + .enable_shift = 18, + .enable_negate = 1, + .ops = &min_ops, +}; + +/* list of all the clocks */ +static __initdata struct clk_lookup onchip_clks[] = { + { + .con_id = "osc_24M", + .clk = &osc_24M, + }, { + .con_id = "pll", + .clk = &pll_clk, + }, { + .con_id = "cpu", + .clk = &cpu_clk, + }, { + .con_id = "hclk", + .clk = &hclk, + }, { + .con_id = "xclk", + .clk = &xclk, + }, { + .con_id = "io", + .clk = &io_clk, + }, { + .con_id = "uart", + .clk = &uart_clk, + }, { + .con_id = "audio", + .clk = &audio_clk, + }, { + .con_id = "pwm", + .clk = &pwm_clk, + }, { + .con_id = "dri", + .clk = &dri_clk, + }, { + .con_id = "digctl", + .clk = &digctl_clk, + }, { + .con_id = "timer", + .clk = &timer_clk, + }, { + .con_id = "lcdif", + .clk = &lcdif_clk, + }, { + .con_id = "ssp", + .clk = &ssp_clk, + }, { + .con_id = "gpmi", + .clk = &gpmi_clk, + }, { + .con_id = "spdif", + .clk = &spdif_clk, + }, { + .con_id = "emi", + .clk = &emi_clk, + }, { + .con_id = "ir", + .clk = &ir_clk, + }, { + .con_id = "saif", + .clk = &saif_clk, + }, { + .con_id = "usb", + .clk = &usb_clk, + }, +}; + +static int __init propagate_rate(struct clk *clk) +{ + struct clk_lookup *cl; + + for (cl = onchip_clks; cl < onchip_clks + ARRAY_SIZE(onchip_clks); + cl++) { + if (unlikely(!clk_good(cl->clk))) + continue; + if (cl->clk->parent == clk && cl->clk->ops->get_rate) { + cl->clk->ops->get_rate(cl->clk); + if (cl->clk->flags & RATE_PROPAGATES) + propagate_rate(cl->clk); + } + } + + return 0; +} + +/* Exported API */ +unsigned long clk_get_rate(struct clk *clk) +{ + if (unlikely(!clk_good(clk))) + return 0; + + if (clk->rate != 0) + return clk->rate; + + if (clk->ops->get_rate != NULL) + return clk->ops->get_rate(clk); + + return clk_get_rate(clk->parent); +} +EXPORT_SYMBOL(clk_get_rate); + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + if (unlikely(!clk_good(clk))) + return 0; + + if (clk->ops->round_rate) + return clk->ops->round_rate(clk, rate); + + return 0; +} +EXPORT_SYMBOL(clk_round_rate); + +static inline int close_enough(long rate1, long rate2) +{ + return rate1 && !((rate2 - rate1) * 1000 / rate1); +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = -EINVAL; + + if (unlikely(!clk_good(clk))) + goto out; + + if (clk->flags & FIXED_RATE || !clk->ops->set_rate) + goto out; + + else if (!close_enough(clk->rate, rate)) { + ret = clk->ops->set_rate(clk, rate); + if (ret < 0) + goto out; + clk->rate = rate; + if (clk->flags & RATE_PROPAGATES) + propagate_rate(clk); + } else + ret = 0; + +out: + return ret; +} +EXPORT_SYMBOL(clk_set_rate); + +int clk_enable(struct clk *clk) +{ + unsigned long clocks_flags; + + if (unlikely(!clk_good(clk))) + return -EINVAL; + + if (clk->parent) + clk_enable(clk->parent); + + spin_lock_irqsave(&clocks_lock, clocks_flags); + + clk->usage++; + if (clk->ops && clk->ops->enable) + clk->ops->enable(clk); + + spin_unlock_irqrestore(&clocks_lock, clocks_flags); + return 0; +} +EXPORT_SYMBOL(clk_enable); + +static void local_clk_disable(struct clk *clk) +{ + if (unlikely(!clk_good(clk))) + return; + + if (clk->usage == 0 && clk->ops->disable) + clk->ops->disable(clk); + + if (clk->parent) + local_clk_disable(clk->parent); +} + +void clk_disable(struct clk *clk) +{ + unsigned long clocks_flags; + + if (unlikely(!clk_good(clk))) + return; + + spin_lock_irqsave(&clocks_lock, clocks_flags); + + if ((--clk->usage) == 0 && clk->ops->disable) + clk->ops->disable(clk); + + spin_unlock_irqrestore(&clocks_lock, clocks_flags); + if (clk->parent) + clk_disable(clk->parent); +} +EXPORT_SYMBOL(clk_disable); + +/* Some additional API */ +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + int ret = -ENODEV; + unsigned long clocks_flags; + + if (unlikely(!clk_good(clk))) + goto out; + + if (!clk->ops->set_parent) + goto out; + + spin_lock_irqsave(&clocks_lock, clocks_flags); + + ret = clk->ops->set_parent(clk, parent); + if (!ret) { + /* disable if usage count is 0 */ + local_clk_disable(parent); + + parent->usage += clk->usage; + clk->parent->usage -= clk->usage; + + /* disable if new usage count is 0 */ + local_clk_disable(clk->parent); + + clk->parent = parent; + } + spin_unlock_irqrestore(&clocks_lock, clocks_flags); + +out: + return ret; +} +EXPORT_SYMBOL(clk_set_parent); + +struct clk *clk_get_parent(struct clk *clk) +{ + if (unlikely(!clk_good(clk))) + return NULL; + return clk->parent; +} +EXPORT_SYMBOL(clk_get_parent); + +static int __init clk_init(void) +{ + struct clk_lookup *cl; + struct clk_ops *ops; + + spin_lock_init(&clocks_lock); + + for (cl = onchip_clks; cl < onchip_clks + ARRAY_SIZE(onchip_clks); + cl++) { + if (cl->clk->flags & ENABLED) + clk_enable(cl->clk); + else + local_clk_disable(cl->clk); + + ops = cl->clk->ops; + + if ((cl->clk->flags & NEEDS_INITIALIZATION) && + ops && ops->set_rate) + ops->set_rate(cl->clk, cl->clk->rate); + + if (cl->clk->flags & FIXED_RATE) { + if (cl->clk->flags & RATE_PROPAGATES) + propagate_rate(cl->clk); + } else { + if (ops && ops->get_rate) + ops->get_rate(cl->clk); + } + + if (cl->clk->flags & NEEDS_SET_PARENT) { + if (ops && ops->set_parent) + ops->set_parent(cl->clk, cl->clk->parent); + } + + clkdev_add(cl); + } + return 0; +} + +arch_initcall(clk_init); diff --git a/arch/arm/plat-stmp3xxx/clock.h b/arch/arm/plat-stmp3xxx/clock.h new file mode 100644 index 000000000000..a6611e1a3510 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/clock.h @@ -0,0 +1,61 @@ +/* + * Clock control driver for Freescale STMP37XX/STMP378X - internal header file + * + * Author: Vitaly Wool + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __ARCH_ARM_STMX3XXX_CLOCK_H__ +#define __ARCH_ARM_STMX3XXX_CLOCK_H__ + +#ifndef __ASSEMBLER__ + +struct clk_ops { + int (*enable) (struct clk *); + int (*disable) (struct clk *); + long (*get_rate) (struct clk *); + long (*round_rate) (struct clk *, u32); + int (*set_rate) (struct clk *, u32); + int (*set_parent) (struct clk *, struct clk *); +}; + +struct clk { + struct clk *parent; + u32 rate; + u32 flags; + u8 scale_shift; + u8 enable_shift; + u8 bypass_shift; + u8 busy_bit; + s8 usage; + int enable_wait; + int enable_negate; + u32 saved_div; + void __iomem *enable_reg; + void __iomem *scale_reg; + void __iomem *bypass_reg; + void __iomem *busy_reg; + struct clk_ops *ops; +}; + +#endif /* __ASSEMBLER__ */ + +/* Flags */ +#define RATE_PROPAGATES (1<<0) +#define NEEDS_INITIALIZATION (1<<1) +#define PARENT_SET_RATE (1<<2) +#define FIXED_RATE (1<<3) +#define ENABLED (1<<4) +#define NEEDS_SET_PARENT (1<<5) + +#endif diff --git a/arch/arm/plat-stmp3xxx/core.c b/arch/arm/plat-stmp3xxx/core.c new file mode 100644 index 000000000000..6e2fef1639b0 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/core.c @@ -0,0 +1,127 @@ +/* + * Freescale STMP37XX/STMP378X core routines + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include + +#include +#include +#include + +static int __stmp3xxx_reset_block(void __iomem *hwreg, int just_enable) +{ + u32 c; + int timeout; + + /* the process of software reset of IP block is done + in several steps: + + - clear SFTRST and wait for block is enabled; + - clear clock gating (CLKGATE bit); + - set the SFTRST again and wait for block is in reset; + - clear SFTRST and wait for reset completion. + */ + c = __raw_readl(hwreg); + c &= ~(1<<31); /* clear SFTRST */ + __raw_writel(c, hwreg); + for (timeout = 1000000; timeout > 0; timeout--) + /* still in SFTRST state ? */ + if ((__raw_readl(hwreg) & (1<<31)) == 0) + break; + if (timeout <= 0) { + printk(KERN_ERR"%s(%p): timeout when enabling\n", + __func__, hwreg); + return -ETIME; + } + + c = __raw_readl(hwreg); + c &= ~(1<<30); /* clear CLKGATE */ + __raw_writel(c, hwreg); + + if (!just_enable) { + c = __raw_readl(hwreg); + c |= (1<<31); /* now again set SFTRST */ + __raw_writel(c, hwreg); + for (timeout = 1000000; timeout > 0; timeout--) + /* poll until CLKGATE set */ + if (__raw_readl(hwreg) & (1<<30)) + break; + if (timeout <= 0) { + printk(KERN_ERR"%s(%p): timeout when resetting\n", + __func__, hwreg); + return -ETIME; + } + + c = __raw_readl(hwreg); + c &= ~(1<<31); /* clear SFTRST */ + __raw_writel(c, hwreg); + for (timeout = 1000000; timeout > 0; timeout--) + /* still in SFTRST state ? */ + if ((__raw_readl(hwreg) & (1<<31)) == 0) + break; + if (timeout <= 0) { + printk(KERN_ERR"%s(%p): timeout when enabling " + "after reset\n", __func__, hwreg); + return -ETIME; + } + + c = __raw_readl(hwreg); + c &= ~(1<<30); /* clear CLKGATE */ + __raw_writel(c, hwreg); + } + for (timeout = 1000000; timeout > 0; timeout--) + /* still in SFTRST state ? */ + if ((__raw_readl(hwreg) & (1<<30)) == 0) + break; + + if (timeout <= 0) { + printk(KERN_ERR"%s(%p): timeout when unclockgating\n", + __func__, hwreg); + return -ETIME; + } + + return 0; +} + +int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable) +{ + int try = 10; + int r; + + while (try--) { + r = __stmp3xxx_reset_block(hwreg, just_enable); + if (!r) + break; + pr_debug("%s: try %d failed\n", __func__, 10 - try); + } + return r; +} +EXPORT_SYMBOL(stmp3xxx_reset_block); + +struct platform_device stmp3xxx_dbguart = { + .name = "stmp3xxx-dbguart", + .id = -1, +}; + +void __init stmp3xxx_init(void) +{ + /* Turn off auto-slow and other tricks */ + HW_CLKCTRL_HBUS_CLR(0x07f00000U); + + stmp3xxx_dma_init(); +} diff --git a/arch/arm/plat-stmp3xxx/dma.c b/arch/arm/plat-stmp3xxx/dma.c new file mode 100644 index 000000000000..cf42de05e568 --- /dev/null +++ b/arch/arm/plat-stmp3xxx/dma.c @@ -0,0 +1,462 @@ +/* + * DMA helper routines for Freescale STMP37XX/STMP378X + * + * Author: dmitry pervushin + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +static const size_t pool_item_size = sizeof(struct stmp3xxx_dma_command); +static const size_t pool_alignment = 8; +static struct stmp3xxx_dma_user { + void *pool; + int inuse; + const char *name; +} channels[MAX_DMA_CHANNELS]; + +static inline int dmach(int ch) +{ + return ch % 16; +} + +static inline int dmabus(int ch) +{ + return ch / 16; +} + +#define IS_VALID_CHANNEL(ch) ((ch) >= 0 && (ch) < MAX_DMA_CHANNELS) +#define IS_USED(ch) (channels[ch].inuse) + +int stmp3xxx_dma_request(int ch, struct device *dev, const char *name) +{ + struct stmp3xxx_dma_user *user; + int err = 0; + + user = channels + ch; + if (!IS_VALID_CHANNEL(ch)) { + err = -ENODEV; + goto out; + } + if (IS_USED(ch)) { + err = -EBUSY; + goto out; + } + /* Create a pool to allocate dma commands from */ + user->pool = dma_pool_create(name, dev, pool_item_size, + pool_alignment, PAGE_SIZE); + if (user->pool == NULL) { + err = -ENOMEM; + goto out; + } + user->name = name; + user->inuse++; +out: + return err; +} +EXPORT_SYMBOL(stmp3xxx_dma_request); + +int stmp3xxx_dma_release(int ch) +{ + struct stmp3xxx_dma_user *user = channels + ch; + int err = 0; + + if (!IS_VALID_CHANNEL(ch)) { + err = -ENODEV; + goto out; + } + if (!IS_USED(ch)) { + err = -EBUSY; + goto out; + } + BUG_ON(user->pool == NULL); + dma_pool_destroy(user->pool); + user->inuse--; +out: + return err; +} +EXPORT_SYMBOL(stmp3xxx_dma_release); + +int stmp3xxx_dma_read_semaphore(int channel) +{ + int sem = -1; + + switch (dmabus(channel)) { + case STMP3XXX_BUS_APBH: + sem = + (HW_APBH_CHn_SEMA_RD(dmach(channel)) & + BM_APBH_CHn_SEMA_PHORE) >> BP_APBH_CHn_SEMA_PHORE; + break; + + case STMP3XXX_BUS_APBX: + sem = + (HW_APBX_CHn_SEMA_RD(dmach(channel)) & + BM_APBX_CHn_SEMA_PHORE) >> BP_APBX_CHn_SEMA_PHORE; + break; + default: + BUG(); + } + return sem; +} +EXPORT_SYMBOL(stmp3xxx_dma_read_semaphore); + +int stmp3xxx_dma_allocate_command(int channel, + struct stmp3xxx_dma_descriptor *descriptor) +{ + struct stmp3xxx_dma_user *user = channels + channel; + int err = 0; + + if (!IS_VALID_CHANNEL(channel)) { + err = -ENODEV; + goto out; + } + if (!IS_USED(channel)) { + err = -EBUSY; + goto out; + } + if (descriptor == NULL) { + err = -EINVAL; + goto out; + } + + /* Allocate memory for a command from the buffer */ + descriptor->command = + dma_pool_alloc(user->pool, GFP_KERNEL, &descriptor->handle); + + /* Check it worked */ + if (!descriptor->command) { + err = -ENOMEM; + goto out; + } + + memset(descriptor->command, 0, pool_item_size); +out: + WARN_ON(err); + return err; +} +EXPORT_SYMBOL(stmp3xxx_dma_allocate_command); + +int stmp3xxx_dma_free_command(int channel, + struct stmp3xxx_dma_descriptor *descriptor) +{ + int err = 0; + + if (!IS_VALID_CHANNEL(channel)) { + err = -ENODEV; + goto out; + } + if (!IS_USED(channel)) { + err = -EBUSY; + goto out; + } + + /* Return the command memory to the pool */ + dma_pool_free(channels[channel].pool, descriptor->command, + descriptor->handle); + + /* Initialise descriptor so we're not tempted to use it */ + descriptor->command = NULL; + descriptor->handle = 0; + descriptor->virtual_buf_ptr = NULL; + descriptor->next_descr = NULL; + + WARN_ON(err); +out: + return err; +} +EXPORT_SYMBOL(stmp3xxx_dma_free_command); + +void stmp3xxx_dma_go(int channel, + struct stmp3xxx_dma_descriptor *head, u32 semaphore) +{ + int ch = dmach(channel); + + switch (dmabus(channel)) { + case STMP3XXX_BUS_APBH: + /* Set next command */ + HW_APBH_CHn_NXTCMDAR_WR(ch, head->handle); + /* Set counting semaphore (kicks off transfer). Assumes + peripheral has been set up correctly */ + HW_APBH_CHn_SEMA_WR(ch, semaphore); + break; + + case STMP3XXX_BUS_APBX: + /* Set next command */ + HW_APBX_CHn_NXTCMDAR_WR(ch, head->handle); + /* Set counting semaphore (kicks off transfer). Assumes + peripheral has been set up correctly */ + HW_APBX_CHn_SEMA_WR(ch, semaphore); + break; + } +} +EXPORT_SYMBOL(stmp3xxx_dma_go); + +int stmp3xxx_dma_running(int channel) +{ + switch (dmabus(channel)) { + case STMP3XXX_BUS_APBH: + return HW_APBH_CHn_SEMA_RD(dmach(channel)) & + BM_APBH_CHn_SEMA_PHORE; + + case STMP3XXX_BUS_APBX: + return HW_APBX_CHn_SEMA_RD(dmach(channel)) & + BM_APBX_CHn_SEMA_PHORE; + + default: + BUG(); + return 0; + } +} +EXPORT_SYMBOL(stmp3xxx_dma_running); + +/* + * Circular dma chain management + */ +void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain) +{ + int i; + + for (i = 0; i < chain->total_count; i++) + stmp3xxx_dma_free_command( + STMP3xxx_DMA(chain->channel, chain->bus), + &chain->chain[i]); +} +EXPORT_SYMBOL(stmp3xxx_dma_free_chain); + +int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain, + struct stmp3xxx_dma_descriptor descriptors[], + unsigned items) +{ + int i; + int err = 0; + + if (items == 0) + return err; + + for (i = 0; i < items; i++) { + err = stmp3xxx_dma_allocate_command(ch, &descriptors[i]); + if (err) { + WARN_ON(err); + /* + * Couldn't allocate the whole chain. + * deallocate what has been allocated + */ + if (i) { + do { + stmp3xxx_dma_free_command(ch, + &descriptors + [i]); + } while (i-- >= 0); + } + return err; + } + + /* link them! */ + if (i > 0) { + descriptors[i - 1].next_descr = &descriptors[i]; + descriptors[i - 1].command->next = + descriptors[i].handle; + } + } + + /* make list circular */ + descriptors[items - 1].next_descr = &descriptors[0]; + descriptors[items - 1].command->next = descriptors[0].handle; + + chain->total_count = items; + chain->chain = descriptors; + chain->free_index = 0; + chain->active_index = 0; + chain->cooked_index = 0; + chain->free_count = items; + chain->active_count = 0; + chain->cooked_count = 0; + chain->bus = dmabus(ch); + chain->channel = dmach(ch); + return err; +} +EXPORT_SYMBOL(stmp3xxx_dma_make_chain); + +void stmp37xx_circ_clear_chain(struct stmp37xx_circ_dma_chain *chain) +{ + BUG_ON(stmp3xxx_dma_running(STMP3xxx_DMA(chain->channel, chain->bus)) > + 0); + chain->free_index = 0; + chain->active_index = 0; + chain->cooked_index = 0; + chain->free_count = chain->total_count; + chain->active_count = 0; + chain->cooked_count = 0; +} +EXPORT_SYMBOL(stmp37xx_circ_clear_chain); + +void stmp37xx_circ_advance_free(struct stmp37xx_circ_dma_chain *chain, + unsigned count) +{ + BUG_ON(chain->cooked_count < count); + + chain->cooked_count -= count; + chain->cooked_index += count; + chain->cooked_index %= chain->total_count; + chain->free_count += count; +} +EXPORT_SYMBOL(stmp37xx_circ_advance_free); + +void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain, + unsigned count) +{ + BUG_ON(chain->free_count < count); + + chain->free_count -= count; + chain->free_index += count; + chain->free_index %= chain->total_count; + chain->active_count += count; + + switch (chain->bus) { + case STMP3XXX_BUS_APBH: + /* Set counting semaphore (kicks off transfer). Assumes + peripheral has been set up correctly */ + HW_APBH_CHn_SEMA_CLR(chain->channel, + BM_APBH_CHn_SEMA_INCREMENT_SEMA); + HW_APBH_CHn_SEMA_SET(chain->channel, + BF_APBH_CHn_SEMA_INCREMENT_SEMA(count)); + break; + + case STMP3XXX_BUS_APBX: + /* Set counting semaphore (kicks off transfer). Assumes + peripheral has been set up correctly */ + HW_APBX_CHn_SEMA_CLR(chain->channel, + BM_APBX_CHn_SEMA_INCREMENT_SEMA); + HW_APBX_CHn_SEMA_SET(chain->channel, + BF_APBX_CHn_SEMA_INCREMENT_SEMA(count)); + break; + + default: + BUG(); + } +} +EXPORT_SYMBOL(stmp37xx_circ_advance_active); + +unsigned stmp37xx_circ_advance_cooked(struct stmp37xx_circ_dma_chain *chain) +{ + unsigned cooked; + + cooked = chain->active_count - + stmp3xxx_dma_read_semaphore(STMP3xxx_DMA(chain->channel, chain->bus)); + + chain->active_count -= cooked; + chain->active_index += cooked; + chain->active_index %= chain->total_count; + + chain->cooked_count += cooked; + + return cooked; +} +EXPORT_SYMBOL(stmp37xx_circ_advance_cooked); + +void stmp3xxx_dma_set_alt_target(int channel, int function) +{ +#if defined(CONFIG_ARCH_STMP37XX) + unsigned bits = 4; +#elif defined(CONFIG_ARCH_STMP378X) + unsigned bits = 2; +#else +#error wrong arch +#endif + int shift = dmach(channel) * bits; + unsigned mask = (1<= (1< + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include + +#include +#include + +void __init stmp3xxx_init_irq(struct irq_chip *chip) +{ + unsigned int i; + + /* Reset the interrupt controller */ + HW_ICOLL_CTRL_CLR(BM_ICOLL_CTRL_CLKGATE); + udelay(10); + HW_ICOLL_CTRL_CLR(BM_ICOLL_CTRL_SFTRST); + udelay(10); + HW_ICOLL_CTRL_SET(BM_ICOLL_CTRL_SFTRST); + while (!(HW_ICOLL_CTRL_RD() & BM_ICOLL_CTRL_CLKGATE)) + continue; + HW_ICOLL_CTRL_CLR(BM_ICOLL_CTRL_SFTRST | BM_ICOLL_CTRL_CLKGATE); + + /* Disable all interrupts initially */ + for (i = 0; i < NR_REAL_IRQS; i++) { + chip->mask(i); + set_irq_chip(i, chip); + set_irq_handler(i, handle_level_irq); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + + /* Ensure vector is cleared */ + HW_ICOLL_LEVELACK_WR(1); + HW_ICOLL_LEVELACK_WR(2); + HW_ICOLL_LEVELACK_WR(4); + HW_ICOLL_LEVELACK_WR(8); + + HW_ICOLL_VECTOR_WR(0); + /* Barrier */ + (void) HW_ICOLL_STAT_RD(); +} + diff --git a/arch/arm/plat-stmp3xxx/pinmux.c b/arch/arm/plat-stmp3xxx/pinmux.c new file mode 100644 index 000000000000..9b28cc83f31c --- /dev/null +++ b/arch/arm/plat-stmp3xxx/pinmux.c @@ -0,0 +1,545 @@ +/* + * Freescale STMP378X/STMP378X Pin Multiplexing + * + * Author: Vladislav Buzov + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define NR_BANKS ARRAY_SIZE(pinmux_banks) +static struct stmp3xxx_pinmux_bank pinmux_banks[] = { + [0] = { + .hw_muxsel = { + HW_PINCTRL_MUXSEL0_ADDR, + HW_PINCTRL_MUXSEL1_ADDR + }, + .hw_drive = { + HW_PINCTRL_DRIVE0_ADDR, + HW_PINCTRL_DRIVE1_ADDR, + HW_PINCTRL_DRIVE2_ADDR, + HW_PINCTRL_DRIVE3_ADDR + }, + .hw_pull = HW_PINCTRL_PULL0_ADDR, + .functions = { 0x0, 0x1, 0x2, 0x3 }, + .strengths = { 0x0, 0x1, 0x2, 0x3, 0xff }, + + .hw_gpio_read = HW_PINCTRL_DIN0_ADDR, + .hw_gpio_set = HW_PINCTRL_DOUT0_ADDR + HW_STMP3xxx_SET, + .hw_gpio_clr = HW_PINCTRL_DOUT0_ADDR + HW_STMP3xxx_CLR, + .hw_gpio_doe = HW_PINCTRL_DOE0_ADDR, + .irq = IRQ_GPIO0, + + .pin2irq = HW_PINCTRL_PIN2IRQ0_ADDR, + .irqstat = HW_PINCTRL_IRQSTAT0_ADDR, + .irqlevel = HW_PINCTRL_IRQLEVEL0_ADDR, + .irqpolarity = HW_PINCTRL_IRQPOL0_ADDR, + .irqen = HW_PINCTRL_IRQEN0_ADDR, + }, + [1] = { + .hw_muxsel = { + HW_PINCTRL_MUXSEL2_ADDR, + HW_PINCTRL_MUXSEL3_ADDR + }, + .hw_drive = { + HW_PINCTRL_DRIVE4_ADDR, + HW_PINCTRL_DRIVE5_ADDR, + HW_PINCTRL_DRIVE6_ADDR, + HW_PINCTRL_DRIVE7_ADDR + }, + .hw_pull = HW_PINCTRL_PULL1_ADDR, + .functions = { 0x0, 0x1, 0x2, 0x3 }, + .strengths = { 0x0, 0x1, 0x2, 0x3, 0xff }, + + .hw_gpio_read = HW_PINCTRL_DIN1_ADDR, + .hw_gpio_set = HW_PINCTRL_DOUT1_ADDR + HW_STMP3xxx_SET, + .hw_gpio_clr = HW_PINCTRL_DOUT1_ADDR + HW_STMP3xxx_CLR, + .hw_gpio_doe = HW_PINCTRL_DOE1_ADDR, + .irq = IRQ_GPIO1, + + .pin2irq = HW_PINCTRL_PIN2IRQ1_ADDR, + .irqstat = HW_PINCTRL_IRQSTAT1_ADDR, + .irqlevel = HW_PINCTRL_IRQLEVEL1_ADDR, + .irqpolarity = HW_PINCTRL_IRQPOL1_ADDR, + .irqen = HW_PINCTRL_IRQEN1_ADDR, + }, + [2] = { + .hw_muxsel = { + HW_PINCTRL_MUXSEL4_ADDR, + HW_PINCTRL_MUXSEL5_ADDR, + }, + .hw_drive = { + HW_PINCTRL_DRIVE8_ADDR, + HW_PINCTRL_DRIVE9_ADDR, + HW_PINCTRL_DRIVE10_ADDR, + HW_PINCTRL_DRIVE11_ADDR, + }, + .hw_pull = HW_PINCTRL_PULL2_ADDR, + .functions = { 0x0, 0x1, 0x2, 0x3 }, + .strengths = { 0x0, 0x1, 0x2, 0x1, 0x2 }, + + .hw_gpio_read = HW_PINCTRL_DIN2_ADDR, + .hw_gpio_set = HW_PINCTRL_DOUT2_ADDR + HW_STMP3xxx_SET, + .hw_gpio_clr = HW_PINCTRL_DOUT2_ADDR + HW_STMP3xxx_CLR, + .hw_gpio_doe = HW_PINCTRL_DOE2_ADDR, + .irq = IRQ_GPIO2, + + .pin2irq = HW_PINCTRL_PIN2IRQ2_ADDR, + .irqstat = HW_PINCTRL_IRQSTAT2_ADDR, + .irqlevel = HW_PINCTRL_IRQLEVEL2_ADDR, + .irqpolarity = HW_PINCTRL_IRQPOL2_ADDR, + .irqen = HW_PINCTRL_IRQEN2_ADDR, + }, + [3] = { + .hw_muxsel = { + HW_PINCTRL_MUXSEL6_ADDR, + HW_PINCTRL_MUXSEL7_ADDR, + }, + .hw_drive = { + HW_PINCTRL_DRIVE12_ADDR, + HW_PINCTRL_DRIVE13_ADDR, + HW_PINCTRL_DRIVE14_ADDR, + NULL, + }, + .hw_pull = HW_PINCTRL_PULL3_ADDR, + .functions = {0x0, 0x1, 0x2, 0x3}, + .strengths = {0x0, 0x1, 0x2, 0x3, 0xff}, + }, +}; + +static inline struct stmp3xxx_pinmux_bank * +stmp3xxx_pinmux_bank(unsigned id, unsigned *bank, unsigned *pin) +{ + unsigned b, p; + + b = STMP3XXX_PINID_TO_BANK(id); + p = STMP3XXX_PINID_TO_PINNUM(id); + BUG_ON(b >= NR_BANKS); + if (bank) + *bank = b; + if (pin) + *pin = p; + return &pinmux_banks[b]; +} + +/* Check if requested pin is owned by caller */ +static int stmp3xxx_check_pin(unsigned id, const char *label) +{ + unsigned pin; + struct stmp3xxx_pinmux_bank *pm = stmp3xxx_pinmux_bank(id, NULL, &pin); + + if (!test_bit(pin, &pm->pin_map)) { + printk(KERN_WARNING + "%s: Accessing free pin %x, caller %s\n", + __func__, id, label); + + return -EINVAL; + } + + if (label && pm->pin_labels[pin] && + strcmp(label, pm->pin_labels[pin])) { + printk(KERN_WARNING + "%s: Wrong pin owner %x, caller %s owner %s\n", + __func__, id, label, pm->pin_labels[pin]); + + return -EINVAL; + } + return 0; +} + +void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength, + const char *label) +{ + struct stmp3xxx_pinmux_bank *pbank; + void __iomem *hwdrive; + u32 shift, val; + u32 bank, pin; + + pbank = stmp3xxx_pinmux_bank(id, &bank, &pin); + pr_debug("%s: label %s bank %d pin %d strength %d\n", __func__, label, + bank, pin, strength); + + hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM]; + shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN; + val = pbank->strengths[strength]; + if (val == 0xff) { + printk(KERN_WARNING + "%s: strength is not supported for bank %d, caller %s", + __func__, bank, label); + return; + } + + if (stmp3xxx_check_pin(id, label)) + return; + + pr_debug("%s: writing 0x%x to 0x%p register\n", __func__, + val << shift, hwdrive); + __raw_writel(HW_DRIVE_PINDRV_MASK << shift, hwdrive + HW_STMP3xxx_CLR); + __raw_writel(val << shift, hwdrive + HW_STMP3xxx_SET); +} + +void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage, + const char *label) +{ + struct stmp3xxx_pinmux_bank *pbank; + void __iomem *hwdrive; + u32 shift; + u32 bank, pin; + + pbank = stmp3xxx_pinmux_bank(id, &bank, &pin); + pr_debug("%s: label %s bank %d pin %d voltage %d\n", __func__, label, + bank, pin, voltage); + + hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM]; + shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN; + + if (stmp3xxx_check_pin(id, label)) + return; + + pr_debug("%s: changing 0x%x bit in 0x%p register\n", + __func__, HW_DRIVE_PINV_MASK << shift, hwdrive); + if (voltage == PIN_1_8V) + __raw_writel(HW_DRIVE_PINV_MASK << shift, + hwdrive + HW_STMP3xxx_CLR); + else + __raw_writel(HW_DRIVE_PINV_MASK << shift, + hwdrive + HW_STMP3xxx_SET); +} + +void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label) +{ + struct stmp3xxx_pinmux_bank *pbank; + void __iomem *hwpull; + u32 bank, pin; + + pbank = stmp3xxx_pinmux_bank(id, &bank, &pin); + pr_debug("%s: label %s bank %d pin %d enable %d\n", __func__, label, + bank, pin, enable); + + hwpull = pbank->hw_pull; + + if (stmp3xxx_check_pin(id, label)) + return; + + pr_debug("%s: changing 0x%x bit in 0x%p register\n", + __func__, 1 << pin, hwpull); + __raw_writel(1 << pin, + hwpull + (enable ? HW_STMP3xxx_SET : HW_STMP3xxx_CLR)); +} + +int stmp3xxx_request_pin(unsigned id, enum pin_fun fun, const char *label) +{ + struct stmp3xxx_pinmux_bank *pbank; + u32 bank, pin; + int ret = 0; + + pbank = stmp3xxx_pinmux_bank(id, &bank, &pin); + pr_debug("%s: label %s bank %d pin %d fun %d\n", __func__, label, + bank, pin, fun); + + if (test_bit(pin, &pbank->pin_map)) { + printk(KERN_WARNING + "%s: CONFLICT DETECTED pin %d:%d caller %s owner %s\n", + __func__, bank, pin, label, pbank->pin_labels[pin]); + return -EBUSY; + } + + set_bit(pin, &pbank->pin_map); + pbank->pin_labels[pin] = label; + + stmp3xxx_set_pin_type(id, fun); + + return ret; +} + +void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun) +{ + struct stmp3xxx_pinmux_bank *pbank; + void __iomem *hwmux; + u32 shift, val; + u32 bank, pin; + + pbank = stmp3xxx_pinmux_bank(id, &bank, &pin); + + hwmux = pbank->hw_muxsel[pin / HW_MUXSEL_PIN_NUM]; + shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN; + + val = pbank->functions[fun]; + shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN; + pr_debug("%s: writing 0x%x to 0x%p register\n", + __func__, val << shift, hwmux); + __raw_writel(HW_MUXSEL_PINFUN_MASK << shift, hwmux + HW_STMP3xxx_CLR); + __raw_writel(val << shift, hwmux + HW_STMP3xxx_SET); +} + +void stmp3xxx_release_pin(unsigned id, const char *label) +{ + struct stmp3xxx_pinmux_bank *pbank; + u32 bank, pin; + + pbank = stmp3xxx_pinmux_bank(id, &bank, &pin); + pr_debug("%s: label %s bank %d pin %d\n", __func__, label, bank, pin); + + if (stmp3xxx_check_pin(id, label)) + return; + + clear_bit(pin, &pbank->pin_map); + pbank->pin_labels[pin] = NULL; +} + +int stmp3xxx_request_pin_group(struct pin_group *pin_group, const char *label) +{ + struct pin_desc *pin; + int p; + int err = 0; + + /* Allocate and configure pins */ + for (p = 0; p < pin_group->nr_pins; p++) { + pr_debug("%s: #%d\n", __func__, p); + pin = &pin_group->pins[p]; + + err = stmp3xxx_request_pin(pin->id, pin->fun, label); + if (err) + goto out_err; + + stmp3xxx_pin_strength(pin->id, pin->strength, label); + stmp3xxx_pin_voltage(pin->id, pin->voltage, label); + stmp3xxx_pin_pullup(pin->id, pin->pullup, label); + } + + return 0; + +out_err: + /* Release allocated pins in case of error */ + while (--p >= 0) { + pr_debug("%s: releasing #%d\n", __func__, p); + stmp3xxx_release_pin(pin_group->pins[p].id, label); + } + return err; +} +EXPORT_SYMBOL(stmp3xxx_request_pin_group); + +void stmp3xxx_release_pin_group(struct pin_group *pin_group, const char *label) +{ + struct pin_desc *pin; + int p; + + for (p = 0; p < pin_group->nr_pins; p++) { + pin = &pin_group->pins[p]; + stmp3xxx_release_pin(pin->id, label); + } +} +EXPORT_SYMBOL(stmp3xxx_release_pin_group); + +static int stmp3xxx_irq_to_gpio(int irq, + struct stmp3xxx_pinmux_bank **bank, unsigned *gpio) +{ + struct stmp3xxx_pinmux_bank *pm; + + for (pm = pinmux_banks; pm < pinmux_banks + NR_BANKS; pm++) + if (pm->virq <= irq && irq < pm->virq + 32) { + *bank = pm; + *gpio = irq - pm->virq; + return 0; + } + return -ENOENT; +} + +static int stmp3xxx_set_irqtype(unsigned irq, unsigned type) +{ + struct stmp3xxx_pinmux_bank *pm; + unsigned gpio; + int l, p; + + stmp3xxx_irq_to_gpio(irq, &pm, &gpio); + switch (type) { + case IRQ_TYPE_EDGE_RISING: + l = 0; p = 1; break; + case IRQ_TYPE_EDGE_FALLING: + l = 0; p = 0; break; + case IRQ_TYPE_LEVEL_HIGH: + l = 1; p = 1; break; + case IRQ_TYPE_LEVEL_LOW: + l = 1; p = 0; break; + default: + pr_debug("%s: Incorrect GPIO interrupt type 0x%x\n", + __func__, type); + return -ENXIO; + } + __raw_writel(1 << gpio, + pm->irqlevel + (l ? HW_STMP3xxx_SET : HW_STMP3xxx_CLR)); + __raw_writel(1 << gpio, + pm->irqpolarity + (p ? HW_STMP3xxx_SET : HW_STMP3xxx_CLR)); + return 0; +} + +static void stmp3xxx_pin_ack_irq(unsigned irq) +{ + u32 stat; + struct stmp3xxx_pinmux_bank *pm; + unsigned gpio; + + stmp3xxx_irq_to_gpio(irq, &pm, &gpio); + stat = __raw_readl(pm->irqstat) & (1<irqstat + HW_STMP3xxx_CLR); +} + +static void stmp3xxx_pin_mask_irq(unsigned irq) +{ + struct stmp3xxx_pinmux_bank *pm; + unsigned gpio; + + stmp3xxx_irq_to_gpio(irq, &pm, &gpio); + __raw_writel(1 << gpio, pm->irqen + HW_STMP3xxx_CLR); + __raw_writel(1 << gpio, pm->pin2irq + HW_STMP3xxx_CLR); +} + +static void stmp3xxx_pin_unmask_irq(unsigned irq) +{ + struct stmp3xxx_pinmux_bank *pm; + unsigned gpio; + + stmp3xxx_irq_to_gpio(irq, &pm, &gpio); + __raw_writel(1 << gpio, pm->irqen + HW_STMP3xxx_SET); + __raw_writel(1 << gpio, pm->pin2irq + HW_STMP3xxx_SET); +} + +static inline +struct stmp3xxx_pinmux_bank *to_pinmux_bank(struct gpio_chip *chip) +{ + return container_of(chip, struct stmp3xxx_pinmux_bank, chip); +} + +static int stmp3xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip); + return pm->virq + offset; +} + +static int stmp3xxx_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip); + unsigned v; + + v = __raw_readl(pm->hw_gpio_read) & (1 << offset); + return v ? 1 : 0; +} + +static void stmp3xxx_gpio_set(struct gpio_chip *chip, unsigned offset, int v) +{ + struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip); + + __raw_writel(1 << offset, v ? pm->hw_gpio_set : pm->hw_gpio_clr); +} + +static int stmp3xxx_gpio_output(struct gpio_chip *chip, unsigned offset, int v) +{ + struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip); + + __raw_writel(1 << offset, pm->hw_gpio_doe + HW_STMP3xxx_SET); + stmp3xxx_gpio_set(chip, offset, v); + return 0; +} + +static int stmp3xxx_gpio_input(struct gpio_chip *chip, unsigned offset) +{ + struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip); + + __raw_writel(1 << offset, pm->hw_gpio_doe + HW_STMP3xxx_CLR); + return 0; +} + +static int stmp3xxx_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + return stmp3xxx_request_pin(chip->base + offset, PIN_GPIO, "gpio"); +} + +static void stmp3xxx_gpio_free(struct gpio_chip *chip, unsigned offset) +{ + stmp3xxx_release_pin(chip->base + offset, "gpio"); +} + +static void stmp3xxx_gpio_irq(u32 irq, struct irq_desc *desc) +{ + struct stmp3xxx_pinmux_bank *pm = get_irq_data(irq); + int gpio_irq = pm->virq; + u32 stat = __raw_readl(pm->irqstat); + + while (stat) { + if (stat & 1) + irq_desc[gpio_irq].handle_irq(gpio_irq, + &irq_desc[gpio_irq]); + gpio_irq++; + stat >>= 1; + } +} + +static struct irq_chip gpio_irq_chip = { + .ack = stmp3xxx_pin_ack_irq, + .mask = stmp3xxx_pin_mask_irq, + .unmask = stmp3xxx_pin_unmask_irq, + .set_type = stmp3xxx_set_irqtype, +}; + +int __init stmp3xxx_pinmux_init(int virtual_irq_start) +{ + int b, r = 0; + struct stmp3xxx_pinmux_bank *pm; + int virq; + + for (b = 0; b < 3; b++) { + /* only banks 0,1,2 are allowed to GPIO */ + pm = pinmux_banks + b; + pm->chip.base = 32 * b; + pm->chip.ngpio = 32; + pm->chip.owner = THIS_MODULE; + pm->chip.can_sleep = 1; + pm->chip.exported = 1; + pm->chip.to_irq = stmp3xxx_gpio_to_irq; + pm->chip.direction_input = stmp3xxx_gpio_input; + pm->chip.direction_output = stmp3xxx_gpio_output; + pm->chip.get = stmp3xxx_gpio_get; + pm->chip.set = stmp3xxx_gpio_set; + pm->chip.request = stmp3xxx_gpio_request; + pm->chip.free = stmp3xxx_gpio_free; + pm->virq = virtual_irq_start + b * 32; + + for (virq = pm->virq; virq < pm->virq; virq++) { + gpio_irq_chip.mask(virq); + set_irq_chip(virq, &gpio_irq_chip); + set_irq_handler(virq, handle_level_irq); + set_irq_flags(virq, IRQF_VALID); + } + r = gpiochip_add(&pm->chip); + if (r < 0) + break; + set_irq_chained_handler(pm->irq, stmp3xxx_gpio_irq); + set_irq_data(pm->irq, pm); + } + return r; +} + +MODULE_AUTHOR("Vladislav Buzov"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/plat-stmp3xxx/timer.c b/arch/arm/plat-stmp3xxx/timer.c new file mode 100644 index 000000000000..c916068f0cab --- /dev/null +++ b/arch/arm/plat-stmp3xxx/timer.c @@ -0,0 +1,172 @@ +/* + * System timer for Freescale STMP37XX/STMP378X + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static irqreturn_t +stmp3xxx_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *c = dev_id; + + if (HW_TIMROT_TIMCTRLn_RD(0) & (1<<15)) { + HW_TIMROT_TIMCTRLn_CLR(0, (1<<15)); + c->event_handler(c); + } else if (HW_TIMROT_TIMCTRLn_RD(1) & (1<<15)) { + HW_TIMROT_TIMCTRLn_CLR(1, (1<<15)); + HW_TIMROT_TIMCTRLn_CLR(1, BM_TIMROT_TIMCTRLn_IRQ_EN); + HW_TIMROT_TIMCOUNTn_WR(1, 0xFFFF); + } + + return IRQ_HANDLED; +} + +static cycle_t stmp3xxx_clock_read(void) +{ + return ~((HW_TIMROT_TIMCOUNTn_RD(1) & 0xFFFF0000) >> 16); +} + +static int +stmp3xxx_timrot_set_next_event(unsigned long delta, + struct clock_event_device *dev) +{ + HW_TIMROT_TIMCOUNTn_WR(0, delta); /* reload */ + return 0; +} + +static void +stmp3xxx_timrot_set_mode(enum clock_event_mode mode, + struct clock_event_device *dev) +{ +} + +static struct clock_event_device ckevt_timrot = { + .name = "timrot", + .features = CLOCK_EVT_FEAT_ONESHOT, + .shift = 32, + .set_next_event = stmp3xxx_timrot_set_next_event, + .set_mode = stmp3xxx_timrot_set_mode, +}; + +static struct clocksource cksrc_stmp3xxx = { + .name = "cksrc_stmp3xxx", + .rating = 250, + .read = stmp3xxx_clock_read, + .mask = CLOCKSOURCE_MASK(16), + .shift = 10, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static struct irqaction stmp3xxx_timer_irq = { + .name = "stmp3xxx_timer", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = stmp3xxx_timer_interrupt, + .dev_id = &ckevt_timrot, +}; + + +/* + * Set up timer interrupt, and return the current time in seconds. + */ +static void __init stmp3xxx_init_timer(void) +{ + cksrc_stmp3xxx.mult = clocksource_hz2mult(CLOCK_TICK_RATE, + cksrc_stmp3xxx.shift); + ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, + ckevt_timrot.shift); + ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot); + ckevt_timrot.max_delta_ns = clockevent_delta2ns(0xFFF, &ckevt_timrot); + ckevt_timrot.cpumask = cpumask_of(0); + + HW_TIMROT_ROTCTRL_CLR(BM_TIMROT_ROTCTRL_SFTRST | + BM_TIMROT_ROTCTRL_CLKGATE); + HW_TIMROT_TIMCOUNTn_WR(0, 0); + HW_TIMROT_TIMCOUNTn_WR(1, 0); + + HW_TIMROT_TIMCTRLn_WR(0, + (BF_TIMROT_TIMCTRLn_SELECT(8) | /* 32 kHz */ + BF_TIMROT_TIMCTRLn_PRESCALE(0) | + BM_TIMROT_TIMCTRLn_RELOAD | + BM_TIMROT_TIMCTRLn_UPDATE | + BM_TIMROT_TIMCTRLn_IRQ_EN)); + HW_TIMROT_TIMCTRLn_WR(1, + (BF_TIMROT_TIMCTRLn_SELECT(8) | /* 32 kHz */ + BF_TIMROT_TIMCTRLn_PRESCALE(0) | + BM_TIMROT_TIMCTRLn_RELOAD | + BM_TIMROT_TIMCTRLn_UPDATE)); + + HW_TIMROT_TIMCOUNTn_WR(0, CLOCK_TICK_RATE / HZ - 1); + HW_TIMROT_TIMCOUNTn_WR(1, 0xFFFF); /* reload */ + + setup_irq(IRQ_TIMER0, &stmp3xxx_timer_irq); + + clocksource_register(&cksrc_stmp3xxx); + clockevents_register_device(&ckevt_timrot); +} + +#ifdef CONFIG_PM + +void stmp3xxx_suspend_timer(void) +{ + HW_TIMROT_TIMCTRLn_CLR(0, BM_TIMROT_TIMCTRLn_IRQ_EN); + HW_TIMROT_TIMCTRLn_CLR(0, (1<<15)); + HW_TIMROT_ROTCTRL_SET(BM_TIMROT_ROTCTRL_CLKGATE); +} + +void stmp3xxx_resume_timer(void) +{ + HW_TIMROT_ROTCTRL_CLR(BM_TIMROT_ROTCTRL_SFTRST | + BM_TIMROT_ROTCTRL_CLKGATE); + + + HW_TIMROT_TIMCTRLn_WR(0, + (BF_TIMROT_TIMCTRLn_SELECT(8) | /* 32 kHz */ + BF_TIMROT_TIMCTRLn_PRESCALE(0) | + BM_TIMROT_TIMCTRLn_UPDATE | + BM_TIMROT_TIMCTRLn_IRQ_EN)); + HW_TIMROT_TIMCTRLn_WR(1, + (BF_TIMROT_TIMCTRLn_SELECT(8) | /* 32 kHz */ + BF_TIMROT_TIMCTRLn_PRESCALE(0) | + BM_TIMROT_TIMCTRLn_RELOAD | + BM_TIMROT_TIMCTRLn_UPDATE)); + + HW_TIMROT_TIMCOUNTn_WR(0, CLOCK_TICK_RATE / HZ - 1); + HW_TIMROT_TIMCOUNTn_WR(1, 0xFFFF); /* reload */ +} + +#else + +#define stmp3xxx_suspend_timer NULL +#define stmp3xxx_resume_timer NULL + +#endif /* CONFIG_PM */ + +struct sys_timer stmp3xxx_timer = { + .init = stmp3xxx_init_timer, + .suspend = stmp3xxx_suspend_timer, + .resume = stmp3xxx_resume_timer, +}; -- GitLab From 45d9108011b9dfb4fccd6c258290d2185145709b Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Wed, 22 Apr 2009 23:57:05 +0100 Subject: [PATCH 0721/6080] [ARM] 5465/1: Freescale STMP platform support [7/10] Sources: support for 37xx boards Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- arch/arm/mach-stmp37xx/Makefile | 2 + arch/arm/mach-stmp37xx/Makefile.boot | 3 + arch/arm/mach-stmp37xx/stmp37xx.c | 217 +++++++++++++++++++++++++ arch/arm/mach-stmp37xx/stmp37xx.h | 24 +++ arch/arm/mach-stmp37xx/stmp37xx_devb.c | 83 ++++++++++ 5 files changed, 329 insertions(+) create mode 100644 arch/arm/mach-stmp37xx/Makefile create mode 100644 arch/arm/mach-stmp37xx/Makefile.boot create mode 100644 arch/arm/mach-stmp37xx/stmp37xx.c create mode 100644 arch/arm/mach-stmp37xx/stmp37xx.h create mode 100644 arch/arm/mach-stmp37xx/stmp37xx_devb.c diff --git a/arch/arm/mach-stmp37xx/Makefile b/arch/arm/mach-stmp37xx/Makefile new file mode 100644 index 000000000000..57deffd09fbf --- /dev/null +++ b/arch/arm/mach-stmp37xx/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_ARCH_STMP37XX) += stmp37xx.o +obj-$(CONFIG_MACH_STMP37XX) += stmp37xx_devb.o diff --git a/arch/arm/mach-stmp37xx/Makefile.boot b/arch/arm/mach-stmp37xx/Makefile.boot new file mode 100644 index 000000000000..1568ad404d59 --- /dev/null +++ b/arch/arm/mach-stmp37xx/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x40008000 +params_phys-y := 0x40000100 +initrd_phys-y := 0x40800000 diff --git a/arch/arm/mach-stmp37xx/stmp37xx.c b/arch/arm/mach-stmp37xx/stmp37xx.c new file mode 100644 index 000000000000..83a41c90c252 --- /dev/null +++ b/arch/arm/mach-stmp37xx/stmp37xx.c @@ -0,0 +1,217 @@ +/* + * Freescale STMP37XX platform support + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include "stmp37xx.h" + +/* + * IRQ handling + */ +static void stmp37xx_ack_irq(unsigned int irq) +{ + /* Disable IRQ */ + HW_ICOLL_PRIORITYn_CLR(irq / 4, 0x04 << ((irq % 4) * 8)); + + /* ACK current interrupt */ + HW_ICOLL_LEVELACK_WR(1); + + /* Barrier */ + (void) HW_ICOLL_STAT_RD(); +} + +static void stmp37xx_mask_irq(unsigned int irq) +{ + /* IRQ disable */ + HW_ICOLL_PRIORITYn_CLR(irq / 4, 0x04 << ((irq % 4) * 8)); +} + +static void stmp37xx_unmask_irq(unsigned int irq) +{ + /* IRQ enable */ + HW_ICOLL_PRIORITYn_SET(irq / 4, 0x04 << ((irq % 4) * 8)); +} + +static struct irq_chip stmp37xx_chip = { + .ack = stmp37xx_ack_irq, + .mask = stmp37xx_mask_irq, + .unmask = stmp37xx_unmask_irq, +}; + +void __init stmp37xx_init_irq(void) +{ + stmp3xxx_init_irq(&stmp37xx_chip); +} + +/* + * DMA interrupt handling + */ +void stmp3xxx_arch_dma_enable_interrupt(int channel) +{ + int dmabus = channel / 16; + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + HW_APBH_CTRL1_SET(1 << (8 + (channel % 16))); + break; + + case STMP3XXX_BUS_APBX: + HW_APBX_CTRL1_SET(1 << (8 + (channel % 16))); + break; + } +} +EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt); + +void stmp3xxx_arch_dma_clear_interrupt(int channel) +{ + int dmabus = channel / 16; + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + HW_APBH_CTRL1_CLR(1 << (channel % 16)); + break; + + case STMP3XXX_BUS_APBX: + HW_APBX_CTRL1_CLR(1 << (channel % 16)); + break; + } +} +EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt); + +int stmp3xxx_arch_dma_is_interrupt(int channel) +{ + int r = 0; + + int dmabus = channel / 16; + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + r = HW_APBH_CTRL1_RD() & (1 << (channel % 16)); + break; + + case STMP3XXX_BUS_APBX: + r = HW_APBX_CTRL1_RD() & (1 << (channel % 16)); + break; + } + return r; +} +EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt); + +void stmp3xxx_arch_dma_reset_channel(int channel) +{ + int dmabus = channel / 16; + unsigned chbit = 1 << (channel % 16); + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + /* Reset channel and wait for it to complete */ + HW_APBH_CTRL0_SET(chbit << BP_APBH_CTRL0_RESET_CHANNEL); + while (HW_APBH_CTRL0_RD() & + (chbit << BP_APBH_CTRL0_RESET_CHANNEL)) + continue; + break; + + case STMP3XXX_BUS_APBX: + /* Reset channel and wait for it to complete */ + HW_APBX_CTRL0_SET(chbit << BP_APBX_CTRL0_RESET_CHANNEL); + while (HW_APBX_CTRL0_RD() & + (chbit << BP_APBX_CTRL0_RESET_CHANNEL)) + continue; + break; + } +} +EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel); + +void stmp3xxx_arch_dma_freeze(int channel) +{ + int dmabus = channel / 16; + unsigned chbit = 1 << (channel % 16); + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + HW_APBH_CTRL0_SET(1< + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __MACH_STMP37XX_H +#define __MACH_STMP37XX_H + +void stmp37xx_map_io(void); +void stmp37xx_init_irq(void); + +#endif /* __MACH_STMP37XX_H */ diff --git a/arch/arm/mach-stmp37xx/stmp37xx_devb.c b/arch/arm/mach-stmp37xx/stmp37xx_devb.c new file mode 100644 index 000000000000..adfbdc7f8e27 --- /dev/null +++ b/arch/arm/mach-stmp37xx/stmp37xx_devb.c @@ -0,0 +1,83 @@ +/* + * Freescale STMP37XX development board support + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "stmp37xx.h" + +/* + * List of STMP37xx development board specific devices + */ +static struct platform_device *stmp37xx_devb_devices[] = { + &stmp3xxx_dbguart, +}; + +static struct pin_desc dbguart_pins_0[] = { + { PINID_PWM0, PIN_FUN3, }, + { PINID_PWM1, PIN_FUN3, }, +}; + +static struct pin_group dbguart_pins[] = { + [0] = { + .pins = dbguart_pins_0, + .nr_pins = ARRAY_SIZE(dbguart_pins_0), + }, +}; + +static int dbguart_pins_control(int id, int request) +{ + int r = 0; + + if (request) + r = stmp3xxx_request_pin_group(&dbguart_pins[id], "debug uart"); + else + stmp3xxx_release_pin_group(&dbguart_pins[id], "debug uart"); + return r; +} + + +static void __init stmp37xx_devb_init(void) +{ + stmp3xxx_pinmux_init(NR_REAL_IRQS); + + /* Init STMP3xxx platform */ + stmp3xxx_init(); + + stmp3xxx_dbguart.dev.platform_data = dbguart_pins_control; + /* Add STMP37xx development board devices */ + platform_add_devices(stmp37xx_devb_devices, + ARRAY_SIZE(stmp37xx_devb_devices)); +} + +MACHINE_START(STMP37XX, "STMP37XX") + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0x40000100, + .map_io = stmp37xx_map_io, + .init_irq = stmp37xx_init_irq, + .timer = &stmp3xxx_timer, + .init_machine = stmp37xx_devb_init, +MACHINE_END -- GitLab From bc19d892a14cbb31d838813b2225e262a6c01341 Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Wed, 22 Apr 2009 23:57:28 +0100 Subject: [PATCH 0722/6080] [ARM] 5464/1: Freescale STMP platform support [7/10] Sources: support for 378x boards Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- arch/arm/mach-stmp378x/Makefile | 2 + arch/arm/mach-stmp378x/Makefile.boot | 3 + arch/arm/mach-stmp378x/stmp378x.c | 225 +++++++++++++++++++++++++ arch/arm/mach-stmp378x/stmp378x.h | 24 +++ arch/arm/mach-stmp378x/stmp378x_devb.c | 80 +++++++++ 5 files changed, 334 insertions(+) create mode 100644 arch/arm/mach-stmp378x/Makefile create mode 100644 arch/arm/mach-stmp378x/Makefile.boot create mode 100644 arch/arm/mach-stmp378x/stmp378x.c create mode 100644 arch/arm/mach-stmp378x/stmp378x.h create mode 100644 arch/arm/mach-stmp378x/stmp378x_devb.c diff --git a/arch/arm/mach-stmp378x/Makefile b/arch/arm/mach-stmp378x/Makefile new file mode 100644 index 000000000000..d156f76b379f --- /dev/null +++ b/arch/arm/mach-stmp378x/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_ARCH_STMP378X) += stmp378x.o +obj-$(CONFIG_MACH_STMP378X) += stmp378x_devb.o diff --git a/arch/arm/mach-stmp378x/Makefile.boot b/arch/arm/mach-stmp378x/Makefile.boot new file mode 100644 index 000000000000..1568ad404d59 --- /dev/null +++ b/arch/arm/mach-stmp378x/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x40008000 +params_phys-y := 0x40000100 +initrd_phys-y := 0x40800000 diff --git a/arch/arm/mach-stmp378x/stmp378x.c b/arch/arm/mach-stmp378x/stmp378x.c new file mode 100644 index 000000000000..f156ec7306c0 --- /dev/null +++ b/arch/arm/mach-stmp378x/stmp378x.c @@ -0,0 +1,225 @@ +/* + * Freescale STMP378X platform support + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stmp378x.h" +/* + * IRQ handling + */ +static void stmp378x_ack_irq(unsigned int irq) +{ + /* Tell ICOLL to release IRQ line */ + HW_ICOLL_VECTOR_WR(0x0); + + /* ACK current interrupt */ + HW_ICOLL_LEVELACK_WR(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0); + + /* Barrier */ + (void) HW_ICOLL_STAT_RD(); +} + +static void stmp378x_mask_irq(unsigned int irq) +{ + /* IRQ disable */ + HW_ICOLL_INTERRUPTn_CLR(irq, BM_ICOLL_INTERRUPTn_ENABLE); +} + +static void stmp378x_unmask_irq(unsigned int irq) +{ + /* IRQ enable */ + HW_ICOLL_INTERRUPTn_SET(irq, BM_ICOLL_INTERRUPTn_ENABLE); +} + +static struct irq_chip stmp378x_chip = { + .ack = stmp378x_ack_irq, + .mask = stmp378x_mask_irq, + .unmask = stmp378x_unmask_irq, +}; + +void __init stmp378x_init_irq(void) +{ + stmp3xxx_init_irq(&stmp378x_chip); +} + +/* + * DMA interrupt handling + */ +void stmp3xxx_arch_dma_enable_interrupt(int channel) +{ + int dmabus = channel / 16; + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + HW_APBH_CTRL1_SET(1 << (16 + (channel % 16))); + HW_APBH_CTRL2_SET(1 << (16 + (channel % 16))); + break; + + case STMP3XXX_BUS_APBX: + HW_APBX_CTRL1_SET(1 << (16 + (channel % 16))); + HW_APBX_CTRL2_SET(1 << (16 + (channel % 16))); + break; + } +} +EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt); + +void stmp3xxx_arch_dma_clear_interrupt(int channel) +{ + int dmabus = channel / 16; + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + HW_APBH_CTRL1_CLR(1 << (channel % 16)); + HW_APBH_CTRL2_CLR(1 << (channel % 16)); + break; + + case STMP3XXX_BUS_APBX: + HW_APBX_CTRL1_CLR(1 << (channel % 16)); + HW_APBX_CTRL2_CLR(1 << (channel % 16)); + break; + } +} +EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt); + +int stmp3xxx_arch_dma_is_interrupt(int channel) +{ + int dmabus = channel / 16; + int r = 0; + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + r = HW_APBH_CTRL1_RD() & (1 << (channel % 16)); + break; + + case STMP3XXX_BUS_APBX: + r = HW_APBX_CTRL1_RD() & (1 << (channel % 16)); + break; + } + return r; +} +EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt); + +void stmp3xxx_arch_dma_reset_channel(int channel) +{ + int dmabus = channel / 16; + unsigned chbit = 1 << (channel % 16); + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + /* Reset channel and wait for it to complete */ + HW_APBH_CTRL0_SET(chbit << + BP_APBH_CTRL0_RESET_CHANNEL); + while (HW_APBH_CTRL0_RD() & + (chbit << BP_APBH_CTRL0_RESET_CHANNEL)) + continue; + break; + + case STMP3XXX_BUS_APBX: + /* Reset channel and wait for it to complete */ + HW_APBX_CHANNEL_CTRL_SET( + BF_APBX_CHANNEL_CTRL_RESET_CHANNEL(chbit)); + while (HW_APBX_CHANNEL_CTRL_RD() & + BF_APBX_CHANNEL_CTRL_RESET_CHANNEL(chbit)) + continue; + break; + } +} +EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel); + +void stmp3xxx_arch_dma_freeze(int channel) +{ + int dmabus = channel / 16; + unsigned chbit = 1 << (channel % 16); + + switch (dmabus) { + case STMP3XXX_BUS_APBH: + HW_APBH_CTRL0_SET(1< + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#ifndef __MACH_STMP378X_H +#define __MACH_STMP378X_H + +void stmp378x_map_io(void); +void stmp378x_init_irq(void); + +#endif /* __MACH_STMP378X_COMMON_H */ diff --git a/arch/arm/mach-stmp378x/stmp378x_devb.c b/arch/arm/mach-stmp378x/stmp378x_devb.c new file mode 100644 index 000000000000..bc643f686b11 --- /dev/null +++ b/arch/arm/mach-stmp378x/stmp378x_devb.c @@ -0,0 +1,80 @@ +/* + * Freescale STMP378X development board support + * + * Embedded Alley Solutions, Inc + * + * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "stmp378x.h" + +static struct platform_device *devices[] = { + &stmp3xxx_dbguart, +}; + +static struct pin_desc dbguart_pins_0[] = { + { PINID_PWM0, PIN_FUN3, }, + { PINID_PWM1, PIN_FUN3, }, +}; + +static struct pin_group dbguart_pins[] = { + [0] = { + .pins = dbguart_pins_0, + .nr_pins = ARRAY_SIZE(dbguart_pins_0), + }, +}; + +static int dbguart_pins_control(int id, int request) +{ + int r = 0; + + if (request) + r = stmp3xxx_request_pin_group(&dbguart_pins[id], "debug uart"); + else + stmp3xxx_release_pin_group(&dbguart_pins[id], "debug uart"); + return r; +} + +static void __init stmp378x_devb_init(void) +{ + stmp3xxx_pinmux_init(NR_REAL_IRQS); + + /* init stmp3xxx platform */ + stmp3xxx_init(); + + stmp3xxx_dbguart.dev.platform_data = dbguart_pins_control; + + /* add board's devices */ + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +MACHINE_START(STMP378X, "STMP378X") + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0x40000100, + .map_io = stmp378x_map_io, + .init_irq = stmp378x_init_irq, + .timer = &stmp3xxx_timer, + .init_machine = stmp378x_devb_init, +MACHINE_END -- GitLab From bf155f8defdb5be5da0653279327bbd3801a3ca9 Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Thu, 23 Apr 2009 00:00:01 +0100 Subject: [PATCH 0723/6080] [ARM] 5463/1: Freescale STMP platform support [10/10] Default configs for STMP3xxx boards Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- arch/arm/configs/stmp378x_defconfig | 1141 +++++++++++++++++++++++++++ arch/arm/configs/stmp37xx_defconfig | 1002 +++++++++++++++++++++++ 2 files changed, 2143 insertions(+) create mode 100644 arch/arm/configs/stmp378x_defconfig create mode 100644 arch/arm/configs/stmp37xx_defconfig diff --git a/arch/arm/configs/stmp378x_defconfig b/arch/arm/configs/stmp378x_defconfig new file mode 100644 index 000000000000..44461f197a17 --- /dev/null +++ b/arch/arm/configs/stmp378x_defconfig @@ -0,0 +1,1141 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.30-rc2 +# Thu Apr 23 02:44:13 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="-default" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +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_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_RELAY=y +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_INITRAMFS_COMPRESSION_NONE is not set +CONFIG_INITRAMFS_COMPRESSION_GZIP=y +# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set +# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_STRIP_ASM_SYMS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=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_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y +# CONFIG_SLOW_WORK is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +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=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLOCK=y +CONFIG_LBD=y +# 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 is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_FREEZER is not set + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_W90X900 is not set +CONFIG_ARCH_STMP3XXX=y + +# +# Freescale STMP3xxx implementations +# +# CONFIG_ARCH_STMP37XX is not set +CONFIG_ARCH_STMP378X=y +# CONFIG_MACH_STMP37XX is not set +CONFIG_MACH_STMP378X=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HIGHMEM=y +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_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_HAVE_MLOCK=y +CONFIG_HAVE_MLOCKED_PAGE_BIT=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttySDBG0,115200 mem=32M" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +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=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +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_NETLABEL 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_PHONET is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +# 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 +# CONFIG_NET_SCH_TBF is not set +# 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 + +# +# Classification +# +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_DROP_MONITOR 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_FIB_RULES=y +# 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 is not set +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=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set +# CONFIG_MTD_TESTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLKDEVS is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + +# +# UBI - Unsorted block images +# +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_RESERVE=1 +CONFIG_MTD_UBI_GLUEBI=y + +# +# UBI debugging options +# +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=4 +CONFIG_BLK_DEV_RAM_SIZE=6144 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# 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 is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# 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 is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_NETDEVICES is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_POLLDEV=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# 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_KEYBOARD_GPIO is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_AD7879 is not set +# 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_TOUCHIT213 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT 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=y +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +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 +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# 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 is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_VIDEO_ALLOW_V4L1 is not set +# CONFIG_VIDEO_V4L1_COMPAT is not set +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# + +# +# RDS decoders +# + +# +# Video decoders +# + +# +# Video and audio decoders +# + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_VIVI is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +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 is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_PLATFORM is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_REGULATOR is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# 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 is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +# CONFIG_MISC_FILESYSTEMS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_SHIRQ=y +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_DETECT_HUNG_TASK=y +# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +CONFIG_DEBUG_OBJECTS=y +CONFIG_DEBUG_OBJECTS_SELFTEST=y +CONFIG_DEBUG_OBJECTS_FREE=y +CONFIG_DEBUG_OBJECTS_TIMERS=y +CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 +CONFIG_DEBUG_SLAB=y +CONFIG_DEBUG_SLAB_LEAK=y +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_PI_LIST=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_LOCK_ALLOC=y +CONFIG_PROVE_LOCKING=y +CONFIG_LOCKDEP=y +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_LOCKDEP is not set +CONFIG_TRACE_IRQFLAGS=y +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +CONFIG_DEBUG_KOBJECT=y +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# 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_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_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_PAGE_POISONING is not set +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y + +# +# Tracers +# +CONFIG_FUNCTION_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_EVENT_TRACER is not set +CONFIG_BOOT_TRACER=y +# CONFIG_TRACE_BRANCH_PROFILING is not set +CONFIG_STACK_TRACER=y +# CONFIG_KMEMTRACE is not set +# CONFIG_WORKQUEUE_TRACER is not set +CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +CONFIG_ARM_UNWIND=y +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_LL is not set + +# +# Security options +# +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +# CONFIG_SECURITY_TOMOYO 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=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_TEST=m + +# +# 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=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# 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=m +# 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=m +# 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=y +# 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=y +# CONFIG_CRYPTO_ZLIB is not set +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_DECOMPRESS_GZIP=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_NLATTR=y diff --git a/arch/arm/configs/stmp37xx_defconfig b/arch/arm/configs/stmp37xx_defconfig new file mode 100644 index 000000000000..401279d531d5 --- /dev/null +++ b/arch/arm/configs/stmp37xx_defconfig @@ -0,0 +1,1002 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.29.1 +# Mon Apr 20 04:41:26 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_MMU=y +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="-default" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +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_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_RELAY=y +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=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_COMPAT_BRK=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +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=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLOCK=y +CONFIG_LBD=y +CONFIG_BLK_DEV_IO_TRACE=y +# 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 is not set +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_FREEZER is not set + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_W90X900 is not set +CONFIG_ARCH_STMP3XXX=y + +# +# Freescale STMP3xxx implementations +# +CONFIG_ARCH_STMP37XX=y +# CONFIG_ARCH_STMP378X is not set +CONFIG_MACH_STMP37XX=y +# CONFIG_MACH_STMP378X is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +# CONFIG_OUTER_CACHE is not set +CONFIG_COMMON_CLKDEV=y + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PREEMPT=y +CONFIG_HZ=100 +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL 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_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="console=ttySDBG0,115200 mem=32M lcd_panel=lms350 rdinit=/bin/sh ignore_loglevel" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Power Management +# +# CONFIG_CPU_IDLE is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options +# +# CONFIG_PM is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_COMPAT_NET_DEV_OPS=y +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +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=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +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_NETLABEL 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=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +# 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 +# CONFIG_NET_SCH_TBF is not set +# 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 + +# +# Classification +# +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_SCH_FIFO=y +# 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_FIB_RULES=y +# 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 is not set +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_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_CRYPTOLOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=4 +CONFIG_BLK_DEV_RAM_SIZE=6144 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# 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 is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# 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 is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_DH is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_NETDEVICES is not set +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_POLLDEV=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=320 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# 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_KEYBOARD_GPIO is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +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_TOUCHIT213 is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_UINPUT is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT 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=y +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_STMP_DBG 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 +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO expanders: +# + +# +# I2C GPIO expanders: +# + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# 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 is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_VIDEO_ALLOW_V4L1 is not set +# CONFIG_VIDEO_V4L1_COMPAT is not set +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# + +# +# Video decoders +# + +# +# Video and audio decoders +# + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# + +# +# Video improvement chips +# +# CONFIG_VIDEO_VIVI is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +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 is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX 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=y +# CONFIG_LCD_ILI9320 is not set +# CONFIG_LCD_PLATFORM is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_GENERIC=y + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_REGULATOR is not set +# CONFIG_UIO is not set +# CONFIG_STAGING is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# 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 is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +# CONFIG_MISC_FILESYSTEMS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_FRAME_WARN=1024 +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_SECTION_MISMATCH=y +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_DEBUG_SLAB is not set +CONFIG_DEBUG_PREEMPT=y +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_BUGVERBOSE 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 is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +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_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_RING_BUFFER=y +CONFIG_TRACING=y + +# +# Tracers +# +CONFIG_FUNCTION_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_BOOT_TRACER=y +# CONFIG_TRACE_BRANCH_PROFILING is not set +CONFIG_STACK_TRACER=y +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_ERRORS is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +CONFIG_SECURITY=y +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_NETWORK is not set +# CONFIG_SECURITY_PATH is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +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=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 +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_TEST=m + +# +# 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=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# 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=m +# 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=m +# 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=y +# 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=y +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_HW=y + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_GENERIC_FIND_LAST_BIT=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y -- GitLab From 92ae3efa53b481ad669d8b85c6cfa37d774bb21e Mon Sep 17 00:00:00 2001 From: Rami Rosen Date: Mon, 27 Apr 2009 02:35:32 -0700 Subject: [PATCH 0724/6080] ipv4: remove unused member in fib_table. This patch removes an unused parameter (tb_stamp) from fib_table structure in include/net/ip_fib.h. Signed-off-by: Rami Rosen Signed-off-by: David S. Miller --- include/net/ip_fib.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 8b12667f7a2b..34855eede5fe 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -145,7 +145,6 @@ struct fib_result_nl { struct fib_table { struct hlist_node tb_hlist; u32 tb_id; - unsigned tb_stamp; int tb_default; int (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res); int (*tb_insert)(struct fib_table *, struct fib_config *); -- GitLab From 06bd12c3b861f8ca9e1215428b19dc0026c6268f Mon Sep 17 00:00:00 2001 From: John Dykstra Date: Mon, 27 Apr 2009 02:42:20 -0700 Subject: [PATCH 0725/6080] pcnet32: Remove redundant set of skb->dev Remove redundant set of skb->dev (now handled for ethernet drivers by eth_type_trans()). Signed-off-by: John Dykstra Signed-off-by: David S. Miller --- drivers/net/pcnet32.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 80124fac65fa..e5e8c59243b6 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1227,7 +1227,6 @@ static void pcnet32_rx_entry(struct net_device *dev, dev->stats.rx_dropped++; return; } - skb->dev = dev; if (!rx_in_place) { skb_reserve(skb, NET_IP_ALIGN); skb_put(skb, pkt_len); /* Make room */ -- GitLab From edf391ff17232f097d72441c9ad467bcb3b5db18 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 27 Apr 2009 02:45:02 -0700 Subject: [PATCH 0726/6080] snmp: add missing counters for RFC 4293 The IP MIB (RFC 4293) defines stats for InOctets, OutOctets, InMcastOctets and OutMcastOctets: http://tools.ietf.org/html/rfc4293 But it seems we don't track those in any way that easy to separate from other protocols. This patch adds those missing counters to the stats file. Tested successfully by me With help from Eric Dumazet. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- include/linux/snmp.h | 10 ++++++++-- include/net/ip.h | 3 +++ include/net/ipv6.h | 15 ++++++++++++++- include/net/snmp.h | 19 ++++++++++++++++++- net/ipv4/ip_input.c | 13 ++++++++----- net/ipv4/ip_output.c | 12 ++++++------ net/ipv4/proc.c | 10 ++++++++-- net/ipv6/ip6_input.c | 7 ++++--- net/ipv6/ip6_output.c | 9 +++++---- net/ipv6/mcast.c | 19 ++++++++++++------- net/ipv6/ndisc.c | 4 ++-- net/ipv6/proc.c | 10 ++++++++-- net/ipv6/raw.c | 2 +- 13 files changed, 97 insertions(+), 36 deletions(-) diff --git a/include/linux/snmp.h b/include/linux/snmp.h index aee3f1e1d1ce..0f953fe40413 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h @@ -18,7 +18,7 @@ enum { IPSTATS_MIB_NUM = 0, - IPSTATS_MIB_INRECEIVES, /* InReceives */ + IPSTATS_MIB_INPKTS, /* InReceives */ IPSTATS_MIB_INHDRERRORS, /* InHdrErrors */ IPSTATS_MIB_INTOOBIGERRORS, /* InTooBigErrors */ IPSTATS_MIB_INNOROUTES, /* InNoRoutes */ @@ -28,7 +28,7 @@ enum IPSTATS_MIB_INDISCARDS, /* InDiscards */ IPSTATS_MIB_INDELIVERS, /* InDelivers */ IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */ - IPSTATS_MIB_OUTREQUESTS, /* OutRequests */ + IPSTATS_MIB_OUTPKTS, /* OutRequests */ IPSTATS_MIB_OUTDISCARDS, /* OutDiscards */ IPSTATS_MIB_OUTNOROUTES, /* OutNoRoutes */ IPSTATS_MIB_REASMTIMEOUT, /* ReasmTimeout */ @@ -42,6 +42,12 @@ enum IPSTATS_MIB_OUTMCASTPKTS, /* OutMcastPkts */ IPSTATS_MIB_INBCASTPKTS, /* InBcastPkts */ IPSTATS_MIB_OUTBCASTPKTS, /* OutBcastPkts */ + IPSTATS_MIB_INOCTETS, /* InOctets */ + IPSTATS_MIB_OUTOCTETS, /* OutOctets */ + IPSTATS_MIB_INMCASTOCTETS, /* InMcastOctets */ + IPSTATS_MIB_OUTMCASTOCTETS, /* OutMcastOctets */ + IPSTATS_MIB_INBCASTOCTETS, /* InBcastOctets */ + IPSTATS_MIB_OUTBCASTOCTETS, /* OutBcastOctets */ __IPSTATS_MIB_MAX }; diff --git a/include/net/ip.h b/include/net/ip.h index 4ac7577f98d0..72c36926c26d 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -168,7 +168,10 @@ struct ipv4_config extern struct ipv4_config ipv4_config; #define IP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.ip_statistics, field) #define IP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.ip_statistics, field) +#define IP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.ip_statistics, field, val) #define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS_BH((net)->mib.ip_statistics, field, val) +#define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS((net)->mib.ip_statistics, field, val) +#define IP_UPD_PO_STATS_BH(net, field, val) SNMP_UPD_PO_STATS_BH((net)->mib.ip_statistics, field, val) #define NET_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.net_statistics, field) #define NET_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.net_statistics, field) #define NET_INC_STATS_USER(net, field) SNMP_INC_STATS_USER((net)->mib.net_statistics, field) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index c1f16fc49ade..f27fd83d67d8 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -126,15 +126,28 @@ extern struct ctl_path net_ipv6_ctl_path[]; SNMP_ADD_STATS##modifier((net)->mib.statname##_statistics, (field), (val));\ }) +#define _DEVUPD(net, statname, modifier, idev, field, val) \ +({ \ + struct inet6_dev *_idev = (idev); \ + if (likely(_idev != NULL)) \ + SNMP_UPD_PO_STATS##modifier((_idev)->stats.statname, field, (val)); \ + SNMP_UPD_PO_STATS##modifier((net)->mib.statname##_statistics, field, (val));\ +}) + /* MIBs */ #define IP6_INC_STATS(net, idev,field) \ _DEVINC(net, ipv6, , idev, field) #define IP6_INC_STATS_BH(net, idev,field) \ _DEVINC(net, ipv6, _BH, idev, field) +#define IP6_ADD_STATS(net, idev,field,val) \ + _DEVADD(net, ipv6, , idev, field, val) #define IP6_ADD_STATS_BH(net, idev,field,val) \ _DEVADD(net, ipv6, _BH, idev, field, val) - +#define IP6_UPD_PO_STATS(net, idev,field,val) \ + _DEVUPD(net, ipv6, , idev, field, val) +#define IP6_UPD_PO_STATS_BH(net, idev,field,val) \ + _DEVUPD(net, ipv6, _BH, idev, field, val) #define ICMP6_INC_STATS(net, idev, field) \ _DEVINC(net, icmpv6, , idev, field) #define ICMP6_INC_STATS_BH(net, idev, field) \ diff --git a/include/net/snmp.h b/include/net/snmp.h index 57c93628695f..8c842e06bec8 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -153,6 +153,11 @@ struct linux_xfrm_mib { per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \ put_cpu(); \ } while (0) +#define SNMP_ADD_STATS(mib, field, addend) \ + do { \ + per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field] += addend; \ + put_cpu(); \ + } while (0) #define SNMP_ADD_STATS_BH(mib, field, addend) \ (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend) #define SNMP_ADD_STATS_USER(mib, field, addend) \ @@ -160,5 +165,17 @@ struct linux_xfrm_mib { per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \ put_cpu(); \ } while (0) - +#define SNMP_UPD_PO_STATS(mib, basefield, addend) \ + do { \ + __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], get_cpu());\ + ptr->mibs[basefield##PKTS]++; \ + ptr->mibs[basefield##OCTETS] += addend;\ + put_cpu(); \ + } while (0) +#define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \ + do { \ + __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id());\ + ptr->mibs[basefield##PKTS]++; \ + ptr->mibs[basefield##OCTETS] += addend;\ + } while (0) #endif diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 1a58a6fa1dc0..40f6206b2aa9 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -358,10 +358,12 @@ static int ip_rcv_finish(struct sk_buff *skb) goto drop; rt = skb->rtable; - if (rt->rt_type == RTN_MULTICAST) - IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCASTPKTS); - else if (rt->rt_type == RTN_BROADCAST) - IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCASTPKTS); + if (rt->rt_type == RTN_MULTICAST) { + IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCAST, + skb->len); + } else if (rt->rt_type == RTN_BROADCAST) + IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCAST, + skb->len); return dst_input(skb); @@ -384,7 +386,8 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, if (skb->pkt_type == PACKET_OTHERHOST) goto drop; - IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INRECEIVES); + + IP_UPD_PO_STATS_BH(dev_net(dev), IPSTATS_MIB_IN, skb->len); if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 3e7e910c7c0f..ea19c37ccc0c 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -181,10 +181,10 @@ static inline int ip_finish_output2(struct sk_buff *skb) struct net_device *dev = dst->dev; unsigned int hh_len = LL_RESERVED_SPACE(dev); - if (rt->rt_type == RTN_MULTICAST) - IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTMCASTPKTS); - else if (rt->rt_type == RTN_BROADCAST) - IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTBCASTPKTS); + if (rt->rt_type == RTN_MULTICAST) { + IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len); + } else if (rt->rt_type == RTN_BROADCAST) + IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTBCAST, skb->len); /* Be paranoid, rather than too clever. */ if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { @@ -244,7 +244,7 @@ int ip_mc_output(struct sk_buff *skb) /* * If the indicated interface is up and running, send the packet. */ - IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); + IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len); skb->dev = dev; skb->protocol = htons(ETH_P_IP); @@ -298,7 +298,7 @@ int ip_output(struct sk_buff *skb) { struct net_device *dev = skb->dst->dev; - IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); + IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len); skb->dev = dev; skb->protocol = htons(ETH_P_IP); diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index cf0cdeeb1db0..f25542c48b7d 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -90,14 +90,14 @@ static const struct file_operations sockstat_seq_fops = { /* snmp items */ static const struct snmp_mib snmp4_ipstats_list[] = { - SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES), + SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INPKTS), SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS), SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS), SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS), SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS), SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS), SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS), - SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTREQUESTS), + SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTPKTS), SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS), SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES), SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT), @@ -118,6 +118,12 @@ static const struct snmp_mib snmp4_ipextstats_list[] = { SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS), SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS), + SNMP_MIB_ITEM("InOctets", IPSTATS_MIB_INOCTETS), + SNMP_MIB_ITEM("OutOctets", IPSTATS_MIB_OUTOCTETS), + SNMP_MIB_ITEM("InMcastOctets", IPSTATS_MIB_INMCASTOCTETS), + SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS), + SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS), + SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), SNMP_MIB_SENTINEL }; diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 8f04bd9da274..bc1a920c34a1 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -70,7 +70,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt idev = __in6_dev_get(skb->dev); - IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INRECEIVES); + IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_IN, skb->len); if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL || !idev || unlikely(idev->cnf.disable_ipv6)) { @@ -242,8 +242,9 @@ int ip6_mc_input(struct sk_buff *skb) struct ipv6hdr *hdr; int deliver; - IP6_INC_STATS_BH(dev_net(skb->dst->dev), - ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); + IP6_UPD_PO_STATS_BH(dev_net(skb->dst->dev), + ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCAST, + skb->len); hdr = ipv6_hdr(skb); deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 9fb49c3b518a..735a2bf4b5f1 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -159,7 +159,8 @@ static int ip6_output2(struct sk_buff *skb) } } - IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS); + IP6_UPD_PO_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCAST, + skb->len); } return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, @@ -275,8 +276,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, mtu = dst_mtu(dst); if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { - IP6_INC_STATS(net, ip6_dst_idev(skb->dst), - IPSTATS_MIB_OUTREQUESTS); + IP6_UPD_PO_STATS(net, ip6_dst_idev(skb->dst), + IPSTATS_MIB_OUT, skb->len); return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, dst_output); } @@ -1516,7 +1517,7 @@ int ip6_push_pending_frames(struct sock *sk) skb->mark = sk->sk_mark; skb->dst = dst_clone(&rt->u.dst); - IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); + IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len); if (proto == IPPROTO_ICMPV6) { struct inet6_dev *idev = ip6_dst_idev(skb->dst); diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index a51fb33e6864..4b48819a5b8d 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1449,7 +1449,8 @@ static void mld_sendpack(struct sk_buff *skb) int err; struct flowi fl; - IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); + IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); + payload_len = (skb->tail - skb->network_header) - sizeof(*pip6); mldlen = skb->tail - skb->transport_header; pip6->payload_len = htons(payload_len); @@ -1473,13 +1474,15 @@ static void mld_sendpack(struct sk_buff *skb) if (err) goto err_out; + payload_len = skb->len; + err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, dst_output); out: if (!err) { ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT); ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); - IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTMCASTPKTS); + IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len); } else IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS); @@ -1773,10 +1776,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) IPV6_TLV_PADN, 0 }; struct flowi fl; - rcu_read_lock(); - IP6_INC_STATS(net, __in6_dev_get(dev), - IPSTATS_MIB_OUTREQUESTS); - rcu_read_unlock(); if (type == ICMPV6_MGM_REDUCTION) snd_addr = &in6addr_linklocal_allrouters; else @@ -1786,6 +1785,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) payload_len = len + sizeof(ra); full_len = sizeof(struct ipv6hdr) + payload_len; + rcu_read_lock(); + IP6_UPD_PO_STATS(net, __in6_dev_get(dev), + IPSTATS_MIB_OUT, full_len); + rcu_read_unlock(); + skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err); if (skb == NULL) { @@ -1838,13 +1842,14 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) if (err) goto err_out; + err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, dst_output); out: if (!err) { ICMP6MSGOUT_INC_STATS(net, idev, type); ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); - IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTMCASTPKTS); + IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len); } else IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 9f061d1adbc2..ab65cc51b00e 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -533,7 +533,7 @@ void ndisc_send_skb(struct sk_buff *skb, skb->dst = dst; idev = in6_dev_get(dst->dev); - IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); + IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, dst_output); @@ -1613,7 +1613,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, buff->dst = dst; idev = in6_dev_get(dst->dev); - IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); + IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, dst_output); if (!err) { diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 97c17fdd6f75..590ddefb7ffc 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -61,7 +61,7 @@ static const struct file_operations sockstat6_seq_fops = { static struct snmp_mib snmp6_ipstats_list[] = { /* ipv6 mib according to RFC 2465 */ - SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES), + SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INPKTS), SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS), SNMP_MIB_ITEM("Ip6InTooBigErrors", IPSTATS_MIB_INTOOBIGERRORS), SNMP_MIB_ITEM("Ip6InNoRoutes", IPSTATS_MIB_INNOROUTES), @@ -71,7 +71,7 @@ static struct snmp_mib snmp6_ipstats_list[] = { SNMP_MIB_ITEM("Ip6InDiscards", IPSTATS_MIB_INDISCARDS), SNMP_MIB_ITEM("Ip6InDelivers", IPSTATS_MIB_INDELIVERS), SNMP_MIB_ITEM("Ip6OutForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS), - SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTREQUESTS), + SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTPKTS), SNMP_MIB_ITEM("Ip6OutDiscards", IPSTATS_MIB_OUTDISCARDS), SNMP_MIB_ITEM("Ip6OutNoRoutes", IPSTATS_MIB_OUTNOROUTES), SNMP_MIB_ITEM("Ip6ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT), @@ -83,6 +83,12 @@ static struct snmp_mib snmp6_ipstats_list[] = { SNMP_MIB_ITEM("Ip6FragCreates", IPSTATS_MIB_FRAGCREATES), SNMP_MIB_ITEM("Ip6InMcastPkts", IPSTATS_MIB_INMCASTPKTS), SNMP_MIB_ITEM("Ip6OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), + SNMP_MIB_ITEM("Ip6InOctets", IPSTATS_MIB_INOCTETS), + SNMP_MIB_ITEM("Ip6OutOctets", IPSTATS_MIB_OUTOCTETS), + SNMP_MIB_ITEM("Ip6InMcastOctets", IPSTATS_MIB_INMCASTOCTETS), + SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS), + SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS), + SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), SNMP_MIB_SENTINEL }; diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 61f6827e5906..e99307fba0b1 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -638,7 +638,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, if (err) goto error_fault; - IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); + IP6_UPD_PO_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len); err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output); if (err > 0) -- GitLab From 739649c53d7f78f5bf41bdfd1a858ee90c7a687a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:52:40 +0000 Subject: [PATCH 0727/6080] of: add of_parse_phandle() helper for parsing phandle properties of_parse_phandle() is a helper function to read and parse a phandle property and return a pointer to the resulting device_node. Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/of/base.c | 24 ++++++++++++++++++++++++ include/linux/of.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index 41c5dfd85358..ddf224d456b2 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -494,6 +494,30 @@ int of_modalias_node(struct device_node *node, char *modalias, int len) } EXPORT_SYMBOL_GPL(of_modalias_node); +/** + * of_parse_phandle - Resolve a phandle property to a device_node pointer + * @np: Pointer to device node holding phandle property + * @phandle_name: Name of property holding a phandle value + * @index: For properties holding a table of phandles, this is the index into + * the table + * + * Returns the device_node pointer with refcount incremented. Use + * of_node_put() on it when done. + */ +struct device_node * +of_parse_phandle(struct device_node *np, const char *phandle_name, int index) +{ + const phandle *phandle; + int size; + + phandle = of_get_property(np, phandle_name, &size); + if ((!phandle) || (size < sizeof(*phandle) * (index + 1))) + return NULL; + + return of_find_node_by_phandle(phandle[index]); +} +EXPORT_SYMBOL(of_parse_phandle); + /** * of_parse_phandles_with_args - Find a node pointed by phandle in a list * @np: pointer to a device tree node containing a list diff --git a/include/linux/of.h b/include/linux/of.h index 6a7efa242f5e..7be2d1043c16 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -77,6 +77,9 @@ extern int of_n_size_cells(struct device_node *np); extern const struct of_device_id *of_match_node( const struct of_device_id *matches, const struct device_node *node); extern int of_modalias_node(struct device_node *node, char *modalias, int len); +extern struct device_node *of_parse_phandle(struct device_node *np, + const char *phandle_name, + int index); extern int of_parse_phandles_with_args(struct device_node *np, const char *list_name, const char *cells_name, int index, struct device_node **out_node, const void **out_args); -- GitLab From 4dea547fef1ba23f9d23f5e7f5218187a7dcf1b3 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:52:46 +0000 Subject: [PATCH 0728/6080] phylib: rework to prepare for OF registration of PHYs This patch makes changes in preparation for supporting open firmware device tree descriptions of MDIO busses. Changes include: - Cleanup handling of phy_map[] entries; they are already NULLed when registering and so don't need to be re-cleared, and it is good practice to clear them out when unregistering. - Split phy_device registration out into a new function so that the OF helpers can do two stage registration (separate allocation and registration steps). Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/phy/mdio_bus.c | 29 +++-------------------- drivers/net/phy/phy_device.c | 45 ++++++++++++++++++++++++++++++++---- include/linux/phy.h | 1 + 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index b754020cbe75..bd4e8d72dc08 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -113,7 +113,6 @@ int mdiobus_register(struct mii_bus *bus) bus->reset(bus); for (i = 0; i < PHY_MAX_ADDR; i++) { - bus->phy_map[i] = NULL; if ((bus->phy_mask & (1 << i)) == 0) { struct phy_device *phydev; @@ -150,6 +149,7 @@ void mdiobus_unregister(struct mii_bus *bus) for (i = 0; i < PHY_MAX_ADDR; i++) { if (bus->phy_map[i]) device_unregister(&bus->phy_map[i]->dev); + bus->phy_map[i] = NULL; } } EXPORT_SYMBOL(mdiobus_unregister); @@ -188,35 +188,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) if (IS_ERR(phydev) || phydev == NULL) return phydev; - /* There's a PHY at this address - * We need to set: - * 1) IRQ - * 2) bus_id - * 3) parent - * 4) bus - * 5) mii_bus - * And, we need to register it */ - - phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL; - - phydev->dev.parent = bus->parent; - phydev->dev.bus = &mdio_bus_type; - dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr); - - phydev->bus = bus; - - /* Run all of the fixups for this PHY */ - phy_scan_fixups(phydev); - - err = device_register(&phydev->dev); + err = phy_device_register(phydev); if (err) { - printk(KERN_ERR "phy %d failed to register\n", addr); phy_device_free(phydev); - phydev = NULL; + return NULL; } - bus->phy_map[addr] = phydev; - return phydev; } EXPORT_SYMBOL(mdiobus_scan); diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 0a06e4fd37d9..9352ca8fa2cc 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -39,20 +39,21 @@ MODULE_DESCRIPTION("PHY library"); MODULE_AUTHOR("Andy Fleming"); MODULE_LICENSE("GPL"); -static struct phy_driver genphy_driver; -extern int mdio_bus_init(void); -extern void mdio_bus_exit(void); - void phy_device_free(struct phy_device *phydev) { kfree(phydev); } +EXPORT_SYMBOL(phy_device_free); static void phy_device_release(struct device *dev) { phy_device_free(to_phy_device(dev)); } +static struct phy_driver genphy_driver; +extern int mdio_bus_init(void); +extern void mdio_bus_exit(void); + static LIST_HEAD(phy_fixup_list); static DEFINE_MUTEX(phy_fixup_lock); @@ -166,6 +167,10 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id) dev->addr = addr; dev->phy_id = phy_id; dev->bus = bus; + dev->dev.parent = bus->parent; + dev->dev.bus = &mdio_bus_type; + dev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL; + dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr); dev->state = PHY_DOWN; @@ -235,6 +240,38 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr) return dev; } +EXPORT_SYMBOL(get_phy_device); + +/** + * phy_device_register - Register the phy device on the MDIO bus + * @phy_device: phy_device structure to be added to the MDIO bus + */ +int phy_device_register(struct phy_device *phydev) +{ + int err; + + /* Don't register a phy if one is already registered at this + * address */ + if (phydev->bus->phy_map[phydev->addr]) + return -EINVAL; + phydev->bus->phy_map[phydev->addr] = phydev; + + /* Run all of the fixups for this PHY */ + phy_scan_fixups(phydev); + + err = device_register(&phydev->dev); + if (err) { + pr_err("phy %d failed to register\n", phydev->addr); + goto out; + } + + return 0; + + out: + phydev->bus->phy_map[phydev->addr] = NULL; + return err; +} +EXPORT_SYMBOL(phy_device_register); /** * phy_prepare_link - prepares the PHY layer to monitor link status diff --git a/include/linux/phy.h b/include/linux/phy.h index 97e40cb6b588..bf0b5f112dc7 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -444,6 +444,7 @@ static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val) int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id); struct phy_device* get_phy_device(struct mii_bus *bus, int addr); +int phy_device_register(struct phy_device *phy); int phy_clear_interrupt(struct phy_device *phydev); int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); struct phy_device * phy_attach(struct net_device *dev, -- GitLab From fa94f6d93c5382810ff41f010f12ca8698fc775e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:52:51 +0000 Subject: [PATCH 0729/6080] phylib: add *_direct() variants of phy_connect and phy_attach functions Add phy_connect_direct() and phy_attach_direct() functions so that drivers can use a pointer to the phy_device instead of trying to determine the phy's bus_id string. This patch is useful for OF device tree descriptions of phy devices where the driver doesn't need or know what the bus_id value in order to get a phy_device pointer. Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/phy/phy_device.c | 118 +++++++++++++++++++++++++---------- include/linux/phy.h | 5 ++ 2 files changed, 90 insertions(+), 33 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 9352ca8fa2cc..a2ece89622d6 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -291,6 +291,33 @@ void phy_prepare_link(struct phy_device *phydev, phydev->adjust_link = handler; } +/** + * phy_connect_direct - connect an ethernet device to a specific phy_device + * @dev: the network device to connect + * @phydev: the pointer to the phy device + * @handler: callback function for state change notifications + * @flags: PHY device's dev_flags + * @interface: PHY device's interface + */ +int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, + void (*handler)(struct net_device *), u32 flags, + phy_interface_t interface) +{ + int rc; + + rc = phy_attach_direct(dev, phydev, flags, interface); + if (rc) + return rc; + + phy_prepare_link(phydev, handler); + phy_start_machine(phydev, NULL); + if (phydev->irq > 0) + phy_start_interrupts(phydev); + + return 0; +} +EXPORT_SYMBOL(phy_connect_direct); + /** * phy_connect - connect an ethernet device to a PHY device * @dev: the network device to connect @@ -312,18 +339,21 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, phy_interface_t interface) { struct phy_device *phydev; + struct device *d; + int rc; - phydev = phy_attach(dev, bus_id, flags, interface); - - if (IS_ERR(phydev)) - return phydev; - - phy_prepare_link(phydev, handler); - - phy_start_machine(phydev, NULL); + /* Search the list of PHY devices on the mdio bus for the + * PHY with the requested name */ + d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id); + if (!d) { + pr_err("PHY %s not found\n", bus_id); + return ERR_PTR(-ENODEV); + } + phydev = to_phy_device(d); - if (phydev->irq > 0) - phy_start_interrupts(phydev); + rc = phy_connect_direct(dev, phydev, handler, flags, interface); + if (rc) + return ERR_PTR(rc); return phydev; } @@ -347,9 +377,9 @@ void phy_disconnect(struct phy_device *phydev) EXPORT_SYMBOL(phy_disconnect); /** - * phy_attach - attach a network device to a particular PHY device + * phy_attach_direct - attach a network device to a given PHY device pointer * @dev: network device to attach - * @bus_id: PHY device to attach + * @phydev: Pointer to phy_device to attach * @flags: PHY device's dev_flags * @interface: PHY device's interface * @@ -360,22 +390,10 @@ EXPORT_SYMBOL(phy_disconnect); * the attaching device, and given a callback for link status * change. The phy_device is returned to the attaching driver. */ -struct phy_device *phy_attach(struct net_device *dev, - const char *bus_id, u32 flags, phy_interface_t interface) +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + u32 flags, phy_interface_t interface) { - struct bus_type *bus = &mdio_bus_type; - struct phy_device *phydev; - struct device *d; - - /* Search the list of PHY devices on the mdio bus for the - * PHY with the requested name */ - d = bus_find_device_by_name(bus, NULL, bus_id); - if (d) { - phydev = to_phy_device(d); - } else { - printk(KERN_ERR "%s not found\n", bus_id); - return ERR_PTR(-ENODEV); - } + struct device *d = &phydev->dev; /* Assume that if there is no driver, that it doesn't * exist, and we should use the genphy driver. */ @@ -388,13 +406,12 @@ struct phy_device *phy_attach(struct net_device *dev, err = device_bind_driver(d); if (err) - return ERR_PTR(err); + return err; } if (phydev->attached_dev) { - printk(KERN_ERR "%s: %s already attached\n", - dev->name, bus_id); - return ERR_PTR(-EBUSY); + dev_err(&dev->dev, "PHY already attached\n"); + return -EBUSY; } phydev->attached_dev = dev; @@ -412,13 +429,48 @@ struct phy_device *phy_attach(struct net_device *dev, err = phy_scan_fixups(phydev); if (err < 0) - return ERR_PTR(err); + return err; err = phydev->drv->config_init(phydev); if (err < 0) - return ERR_PTR(err); + return err; + } + + return 0; +} +EXPORT_SYMBOL(phy_attach_direct); + +/** + * phy_attach - attach a network device to a particular PHY device + * @dev: network device to attach + * @bus_id: Bus ID of PHY device to attach + * @flags: PHY device's dev_flags + * @interface: PHY device's interface + * + * Description: Same as phy_attach_direct() except that a PHY bus_id + * string is passed instead of a pointer to a struct phy_device. + */ +struct phy_device *phy_attach(struct net_device *dev, + const char *bus_id, u32 flags, phy_interface_t interface) +{ + struct bus_type *bus = &mdio_bus_type; + struct phy_device *phydev; + struct device *d; + int rc; + + /* Search the list of PHY devices on the mdio bus for the + * PHY with the requested name */ + d = bus_find_device_by_name(bus, NULL, bus_id); + if (!d) { + pr_err("PHY %s not found\n", bus_id); + return ERR_PTR(-ENODEV); } + phydev = to_phy_device(d); + + rc = phy_attach_direct(dev, phydev, flags, interface); + if (rc) + return ERR_PTR(rc); return phydev; } diff --git a/include/linux/phy.h b/include/linux/phy.h index bf0b5f112dc7..c216e4e503b3 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -447,8 +447,13 @@ struct phy_device* get_phy_device(struct mii_bus *bus, int addr); int phy_device_register(struct phy_device *phy); int phy_clear_interrupt(struct phy_device *phydev); int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); +int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, + u32 flags, phy_interface_t interface); struct phy_device * phy_attach(struct net_device *dev, const char *bus_id, u32 flags, phy_interface_t interface); +int phy_connect_direct(struct net_device *dev, struct phy_device *phydev, + void (*handler)(struct net_device *), u32 flags, + phy_interface_t interface); struct phy_device * phy_connect(struct net_device *dev, const char *bus_id, void (*handler)(struct net_device *), u32 flags, phy_interface_t interface); -- GitLab From 8bc487d150b939e69830c39322df4ee486efe381 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:52:56 +0000 Subject: [PATCH 0730/6080] openfirmware: Add OF phylib support code Add support for parsing the device tree for PHY devices on an MDIO bus. Currently many of the PowerPC ethernet drivers are open coding a solution for reading data out of the device tree to find the correct PHY device. This patch implements a set of common routines to: a) let MDIO bus drivers register phy_devices described in the tree, and b) let MAC drivers find the correct phy_device via the tree. Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/of/Kconfig | 6 ++ drivers/of/Makefile | 1 + drivers/of/of_mdio.c | 139 ++++++++++++++++++++++++++++++++++++++++ include/linux/of_mdio.h | 22 +++++++ 4 files changed, 168 insertions(+) create mode 100644 drivers/of/of_mdio.c create mode 100644 include/linux/of_mdio.h diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index f821dbc952a4..6fe043bd3770 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -19,3 +19,9 @@ config OF_SPI depends on OF && PPC_OF && SPI help OpenFirmware SPI accessors + +config OF_MDIO + def_tristate PHYLIB + depends on OF && PHYLIB + help + OpenFirmware MDIO bus (Ethernet PHY) accessors diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 4c3c6f8e36f5..bdfb5f5d4b06 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_GPIO) += gpio.o obj-$(CONFIG_OF_I2C) += of_i2c.o obj-$(CONFIG_OF_SPI) += of_spi.o +obj-$(CONFIG_OF_MDIO) += of_mdio.o diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c new file mode 100644 index 000000000000..aee967d7f760 --- /dev/null +++ b/drivers/of/of_mdio.c @@ -0,0 +1,139 @@ +/* + * OF helpers for the MDIO (Ethernet PHY) API + * + * Copyright (c) 2009 Secret Lab Technologies, Ltd. + * + * This file is released under the GPLv2 + * + * This file provides helper functions for extracting PHY device information + * out of the OpenFirmware device tree and using it to populate an mii_bus. + */ + +#include +#include +#include +#include + +MODULE_AUTHOR("Grant Likely "); +MODULE_LICENSE("GPL"); + +/** + * of_mdiobus_register - Register mii_bus and create PHYs from the device tree + * @mdio: pointer to mii_bus structure + * @np: pointer to device_node of MDIO bus. + * + * This function registers the mii_bus structure and registers a phy_device + * for each child node of @np. + */ +int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) +{ + struct phy_device *phy; + struct device_node *child; + int rc, i; + + /* Mask out all PHYs from auto probing. Instead the PHYs listed in + * the device tree are populated after the bus has been registered */ + mdio->phy_mask = ~0; + + /* Clear all the IRQ properties */ + if (mdio->irq) + for (i=0; iirq[i] = PHY_POLL; + + /* Register the MDIO bus */ + rc = mdiobus_register(mdio); + if (rc) + return rc; + + /* Loop over the child nodes and register a phy_device for each one */ + for_each_child_of_node(np, child) { + const u32 *addr; + int len; + + /* A PHY must have a reg property in the range [0-31] */ + addr = of_get_property(child, "reg", &len); + if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) { + dev_err(&mdio->dev, "%s has invalid PHY address\n", + child->full_name); + continue; + } + + if (mdio->irq) { + mdio->irq[*addr] = irq_of_parse_and_map(child, 0); + if (!mdio->irq[*addr]) + mdio->irq[*addr] = PHY_POLL; + } + + phy = get_phy_device(mdio, *addr); + if (!phy) { + dev_err(&mdio->dev, "error probing PHY at address %i\n", + *addr); + continue; + } + phy_scan_fixups(phy); + + /* Associate the OF node with the device structure so it + * can be looked up later */ + of_node_get(child); + dev_archdata_set_node(&phy->dev.archdata, child); + + /* All data is now stored in the phy struct; register it */ + rc = phy_device_register(phy); + if (rc) { + phy_device_free(phy); + of_node_put(child); + continue; + } + + dev_dbg(&mdio->dev, "registered phy %s at address %i\n", + child->name, *addr); + } + + return 0; +} +EXPORT_SYMBOL(of_mdiobus_register); + +/** + * of_phy_find_device - Give a PHY node, find the phy_device + * @phy_np: Pointer to the phy's device tree node + * + * Returns a pointer to the phy_device. + */ +struct phy_device *of_phy_find_device(struct device_node *phy_np) +{ + struct device *d; + int match(struct device *dev, void *phy_np) + { + return dev_archdata_get_node(&dev->archdata) == phy_np; + } + + if (!phy_np) + return NULL; + + d = bus_find_device(&mdio_bus_type, NULL, phy_np, match); + return d ? to_phy_device(d) : NULL; +} +EXPORT_SYMBOL(of_phy_find_device); + +/** + * of_phy_connect - Connect to the phy described in the device tree + * @dev: pointer to net_device claiming the phy + * @phy_np: Pointer to device tree node for the PHY + * @hndlr: Link state callback for the network device + * @iface: PHY data interface type + * + * Returns a pointer to the phy_device if successfull. NULL otherwise + */ +struct phy_device *of_phy_connect(struct net_device *dev, + struct device_node *phy_np, + void (*hndlr)(struct net_device *), u32 flags, + phy_interface_t iface) +{ + struct phy_device *phy = of_phy_find_device(phy_np); + + if (!phy) + return NULL; + + return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy; +} +EXPORT_SYMBOL(of_phy_connect); diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h new file mode 100644 index 000000000000..c9663c690303 --- /dev/null +++ b/include/linux/of_mdio.h @@ -0,0 +1,22 @@ +/* + * OF helpers for the MDIO (Ethernet PHY) API + * + * Copyright (c) 2009 Secret Lab Technologies, Ltd. + * + * This file is released under the GPLv2 + */ + +#ifndef __LINUX_OF_MDIO_H +#define __LINUX_OF_MDIO_H + +#include +#include + +extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np); +extern struct phy_device *of_phy_find_device(struct device_node *phy_np); +extern struct phy_device *of_phy_connect(struct net_device *dev, + struct device_node *phy_np, + void (*hndlr)(struct net_device *), + u32 flags, phy_interface_t iface); + +#endif /* __LINUX_OF_MDIO_H */ -- GitLab From ca816d98170942371535b3e862813b0aba9b7d90 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:53:02 +0000 Subject: [PATCH 0731/6080] net: Rework mpc5200 fec driver to use of_mdio infrastructure. The patch reworks the MPC5200 Fast Ethernet Controller (FEC) driver to use the of_mdio infrastructure for registering PHY devices from data out openfirmware device tree, and eliminates the assumption that the PHY for the FEC is always attached to the FEC's own MDIO bus. With this patch, the FEC can use a PHY attached to any MDIO bus if it is described in the device tree. Tested on Freescale Lite5200b eval board Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/fec_mpc52xx.c | 180 ++++++++++------------------------ drivers/net/fec_mpc52xx_phy.c | 26 ++--- 2 files changed, 59 insertions(+), 147 deletions(-) diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 8bbe7f617994..7d443405bbe2 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -43,11 +44,9 @@ #define DRIVER_NAME "mpc52xx-fec" -#define FEC5200_PHYADDR_NONE (-1) -#define FEC5200_PHYADDR_7WIRE (-2) - /* Private driver data structure */ struct mpc52xx_fec_priv { + struct net_device *ndev; int duplex; int speed; int r_irq; @@ -59,10 +58,11 @@ struct mpc52xx_fec_priv { int msg_enable; /* MDIO link details */ - int phy_addr; - unsigned int phy_speed; + unsigned int mdio_speed; + struct device_node *phy_node; struct phy_device *phydev; enum phy_state link; + int seven_wire_mode; }; @@ -211,85 +211,25 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev) phy_print_status(phydev); } -static int mpc52xx_fec_init_phy(struct net_device *dev) -{ - struct mpc52xx_fec_priv *priv = netdev_priv(dev); - struct phy_device *phydev; - char phy_id[BUS_ID_SIZE]; - - snprintf(phy_id, sizeof(phy_id), "%x:%02x", - (unsigned int)dev->base_addr, priv->phy_addr); - - priv->link = PHY_DOWN; - priv->speed = 0; - priv->duplex = -1; - - phydev = phy_connect(dev, phy_id, &mpc52xx_fec_adjust_link, 0, PHY_INTERFACE_MODE_MII); - if (IS_ERR(phydev)) { - dev_err(&dev->dev, "phy_connect failed\n"); - return PTR_ERR(phydev); - } - dev_info(&dev->dev, "attached phy %i to driver %s\n", - phydev->addr, phydev->drv->name); - - priv->phydev = phydev; - - return 0; -} - -static int mpc52xx_fec_phy_start(struct net_device *dev) -{ - struct mpc52xx_fec_priv *priv = netdev_priv(dev); - int err; - - if (priv->phy_addr < 0) - return 0; - - err = mpc52xx_fec_init_phy(dev); - if (err) { - dev_err(&dev->dev, "mpc52xx_fec_init_phy failed\n"); - return err; - } - - /* reset phy - this also wakes it from PDOWN */ - phy_write(priv->phydev, MII_BMCR, BMCR_RESET); - phy_start(priv->phydev); - - return 0; -} - -static void mpc52xx_fec_phy_stop(struct net_device *dev) -{ - struct mpc52xx_fec_priv *priv = netdev_priv(dev); - - if (!priv->phydev) - return; - - phy_disconnect(priv->phydev); - /* power down phy */ - phy_stop(priv->phydev); - phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN); -} - -static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv) -{ - struct mpc52xx_fec __iomem *fec = priv->fec; - - if (priv->phydev) - return; - - out_be32(&fec->mii_speed, priv->phy_speed); -} - static int mpc52xx_fec_open(struct net_device *dev) { struct mpc52xx_fec_priv *priv = netdev_priv(dev); int err = -EBUSY; + if (priv->phy_node) { + priv->phydev = of_phy_connect(priv->ndev, priv->phy_node, + mpc52xx_fec_adjust_link, 0, 0); + if (!priv->phydev) { + dev_err(&dev->dev, "of_phy_connect failed\n"); + return -ENODEV; + } + phy_start(priv->phydev); + } + if (request_irq(dev->irq, &mpc52xx_fec_interrupt, IRQF_SHARED, DRIVER_NAME "_ctrl", dev)) { dev_err(&dev->dev, "ctrl interrupt request failed\n"); - goto out; + goto free_phy; } if (request_irq(priv->r_irq, &mpc52xx_fec_rx_interrupt, 0, DRIVER_NAME "_rx", dev)) { @@ -311,10 +251,6 @@ static int mpc52xx_fec_open(struct net_device *dev) goto free_irqs; } - err = mpc52xx_fec_phy_start(dev); - if (err) - goto free_skbs; - bcom_enable(priv->rx_dmatsk); bcom_enable(priv->tx_dmatsk); @@ -324,16 +260,18 @@ static int mpc52xx_fec_open(struct net_device *dev) return 0; - free_skbs: - mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk); - free_irqs: free_irq(priv->t_irq, dev); free_2irqs: free_irq(priv->r_irq, dev); free_ctrl_irq: free_irq(dev->irq, dev); - out: + free_phy: + if (priv->phydev) { + phy_stop(priv->phydev); + phy_disconnect(priv->phydev); + priv->phydev = NULL; + } return err; } @@ -352,7 +290,12 @@ static int mpc52xx_fec_close(struct net_device *dev) free_irq(priv->r_irq, dev); free_irq(priv->t_irq, dev); - mpc52xx_fec_phy_stop(dev); + if (priv->phydev) { + /* power down phy */ + phy_stop(priv->phydev); + phy_disconnect(priv->phydev); + priv->phydev = NULL; + } return 0; } @@ -696,7 +639,7 @@ static void mpc52xx_fec_hw_init(struct net_device *dev) /* set phy speed. * this can't be done in phy driver, since it needs to be called * before fec stuff (even on resume) */ - mpc52xx_fec_phy_hw_init(priv); + out_be32(&fec->mii_speed, priv->mdio_speed); } /** @@ -732,7 +675,7 @@ static void mpc52xx_fec_start(struct net_device *dev) rcntrl = FEC_RX_BUFFER_SIZE << 16; /* max frame length */ rcntrl |= FEC_RCNTRL_FCE; - if (priv->phy_addr != FEC5200_PHYADDR_7WIRE) + if (!priv->seven_wire_mode) rcntrl |= FEC_RCNTRL_MII_MODE; if (priv->duplex == DUPLEX_FULL) @@ -798,8 +741,6 @@ static void mpc52xx_fec_stop(struct net_device *dev) /* Stop FEC */ out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~FEC_ECNTRL_ETHER_EN); - - return; } /* reset fec and bestcomm tasks */ @@ -817,9 +758,11 @@ static void mpc52xx_fec_reset(struct net_device *dev) mpc52xx_fec_hw_init(dev); - phy_stop(priv->phydev); - phy_write(priv->phydev, MII_BMCR, BMCR_RESET); - phy_start(priv->phydev); + if (priv->phydev) { + phy_stop(priv->phydev); + phy_write(priv->phydev, MII_BMCR, BMCR_RESET); + phy_start(priv->phydev); + } bcom_fec_rx_reset(priv->rx_dmatsk); bcom_fec_tx_reset(priv->tx_dmatsk); @@ -919,8 +862,6 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) struct net_device *ndev; struct mpc52xx_fec_priv *priv = NULL; struct resource mem; - struct device_node *phy_node; - const phandle *phy_handle; const u32 *prop; int prop_size; @@ -933,6 +874,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) return -ENOMEM; priv = netdev_priv(ndev); + priv->ndev = ndev; /* Reserve FEC control zone */ rv = of_address_to_resource(op->node, 0, &mem); @@ -956,6 +898,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) ndev->ethtool_ops = &mpc52xx_fec_ethtool_ops; ndev->watchdog_timeo = FEC_WATCHDOG_TIMEOUT; ndev->base_addr = mem.start; + SET_NETDEV_DEV(ndev, &op->dev); spin_lock_init(&priv->lock); @@ -1003,14 +946,9 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) */ /* Start with safe defaults for link connection */ - priv->phy_addr = FEC5200_PHYADDR_NONE; priv->speed = 100; priv->duplex = DUPLEX_HALF; - priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; - - /* the 7-wire property means don't use MII mode */ - if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) - priv->phy_addr = FEC5200_PHYADDR_7WIRE; + priv->mdio_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; /* The current speed preconfigures the speed of the MII link */ prop = of_get_property(op->node, "current-speed", &prop_size); @@ -1019,43 +957,23 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF; } - /* If there is a phy handle, setup link to that phy */ - phy_handle = of_get_property(op->node, "phy-handle", &prop_size); - if (phy_handle && (prop_size >= sizeof(phandle))) { - phy_node = of_find_node_by_phandle(*phy_handle); - prop = of_get_property(phy_node, "reg", &prop_size); - if (prop && (prop_size >= sizeof(u32))) - if ((*prop >= 0) && (*prop < PHY_MAX_ADDR)) - priv->phy_addr = *prop; - of_node_put(phy_node); + /* If there is a phy handle, then get the PHY node */ + priv->phy_node = of_parse_phandle(op->node, "phy-handle", 0); + + /* the 7-wire property means don't use MII mode */ + if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) { + priv->seven_wire_mode = 1; + dev_info(&ndev->dev, "using 7-wire PHY mode\n"); } /* Hardware init */ mpc52xx_fec_hw_init(ndev); - mpc52xx_fec_reset_stats(ndev); - SET_NETDEV_DEV(ndev, &op->dev); - - /* Register the new network device */ rv = register_netdev(ndev); if (rv < 0) goto probe_error; - /* Now report the link setup */ - switch (priv->phy_addr) { - case FEC5200_PHYADDR_NONE: - dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n", - priv->speed, priv->duplex ? 'F' : 'H'); - break; - case FEC5200_PHYADDR_7WIRE: - dev_info(&ndev->dev, "using 7-wire PHY mode\n"); - break; - default: - dev_info(&ndev->dev, "Using PHY at MDIO address %i\n", - priv->phy_addr); - } - /* We're done ! */ dev_set_drvdata(&op->dev, ndev); @@ -1065,6 +983,10 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) /* Error handling - free everything that might be allocated */ probe_error: + if (priv->phy_node) + of_node_put(priv->phy_node); + priv->phy_node = NULL; + irq_dispose_mapping(ndev->irq); if (priv->rx_dmatsk) @@ -1093,6 +1015,10 @@ mpc52xx_fec_remove(struct of_device *op) unregister_netdev(ndev); + if (priv->phy_node) + of_node_put(priv->phy_node); + priv->phy_node = NULL; + irq_dispose_mapping(ndev->irq); bcom_fec_rx_release(priv->rx_dmatsk); diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index dd9bfa42ac34..fec9f245116b 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -14,12 +14,14 @@ #include #include #include +#include #include #include #include "fec_mpc52xx.h" struct mpc52xx_fec_mdio_priv { struct mpc52xx_fec __iomem *regs; + int mdio_irqs[PHY_MAX_ADDR]; }; static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id, @@ -27,7 +29,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id, { struct mpc52xx_fec_mdio_priv *priv = bus->priv; struct mpc52xx_fec __iomem *fec; - int tries = 100; + int tries = 3; value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK; value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK; @@ -38,7 +40,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id, /* wait for it to finish, this takes about 23 us on lite5200b */ while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries) - udelay(5); + msleep(1); if (!tries) return -ETIMEDOUT; @@ -64,7 +66,6 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, { struct device *dev = &of->dev; struct device_node *np = of->node; - struct device_node *child = NULL; struct mii_bus *bus; struct mpc52xx_fec_mdio_priv *priv; struct resource res = {}; @@ -85,22 +86,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, bus->write = mpc52xx_fec_mdio_write; /* setup irqs */ - bus->irq = kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GFP_KERNEL); - if (bus->irq == NULL) { - err = -ENOMEM; - goto out_free; - } - for (i=0; iirq[i] = PHY_POLL; - - while ((child = of_get_next_child(np, child)) != NULL) { - int irq = irq_of_parse_and_map(child, 0); - if (irq != NO_IRQ) { - const u32 *id = of_get_property(child, "reg", NULL); - if (id) - bus->irq[*id] = irq; - } - } + bus->irq = priv->mdio_irqs; /* setup registers */ err = of_address_to_resource(np, 0, &res); @@ -122,7 +108,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, out_be32(&priv->regs->mii_speed, ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1); - err = mdiobus_register(bus); + err = of_mdiobus_register(bus, np); if (err) goto out_unmap; -- GitLab From 324931ba21858c34787dee7d222388ef3fb41ee0 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:53:07 +0000 Subject: [PATCH 0732/6080] net: rework fsl_pq_mdio driver to use of_mdio infrastructure This patch simplifies the driver by making use of more common code. Tested on Freescale MPC8349emitxgp eval board Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/fsl_pq_mdio.c | 51 +++------------------------------------ 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index aa1eb88c21fc..b01daa1e3adf 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -154,44 +155,6 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus) return 0; } -/* Allocate an array which provides irq #s for each PHY on the given bus */ -static int *create_irq_map(struct device_node *np) -{ - int *irqs; - int i; - struct device_node *child = NULL; - - irqs = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); - - if (!irqs) - return NULL; - - for (i = 0; i < PHY_MAX_ADDR; i++) - irqs[i] = PHY_POLL; - - while ((child = of_get_next_child(np, child)) != NULL) { - int irq = irq_of_parse_and_map(child, 0); - const u32 *id; - - if (irq == NO_IRQ) - continue; - - id = of_get_property(child, "reg", NULL); - - if (!id) - continue; - - if (*id < PHY_MAX_ADDR && *id >= 0) - irqs[*id] = irq; - else - printk(KERN_WARNING "%s: " - "%d is not a valid PHY address\n", - np->full_name, *id); - } - - return irqs; -} - void fsl_pq_mdio_bus_name(char *name, struct device_node *np) { const u32 *addr; @@ -315,7 +278,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, new_bus->priv = (void __force *)regs; - new_bus->irq = create_irq_map(np); + new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL); if (NULL == new_bus->irq) { err = -ENOMEM; @@ -384,15 +347,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, out_be32(tbipa, tbiaddr); - /* - * The TBIPHY-only buses will find PHYs at every address, - * so we mask them all but the TBI - */ - if (of_device_is_compatible(np, "fsl,gianfar-tbi")) - new_bus->phy_mask = ~(1 << tbiaddr); - - err = mdiobus_register(new_bus); - + err = of_mdiobus_register(new_bus, np); if (err) { printk (KERN_ERR "%s: Cannot register as MDIO bus\n", new_bus->name); -- GitLab From fe192a49118f5b1272317d60c7930ece4e13ae49 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:53:12 +0000 Subject: [PATCH 0733/6080] net: Rework gianfar driver to use of_mdio infrastructure. This patch simplifies the driver by making use of more common code. Tested on Freescale MPC8349emitxgp eval board Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 109 ++++++++++++++---------------------------- drivers/net/gianfar.h | 4 +- 2 files changed, 39 insertions(+), 74 deletions(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index b2c49679bba7..dae14373296a 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -168,17 +169,13 @@ static inline int gfar_uses_fcb(struct gfar_private *priv) static int gfar_of_init(struct net_device *dev) { - struct device_node *phy, *mdio; - const unsigned int *id; const char *model; const char *ctype; const void *mac_addr; - const phandle *ph; u64 addr, size; int err = 0; struct gfar_private *priv = netdev_priv(dev); struct device_node *np = priv->node; - char bus_name[MII_BUS_ID_SIZE]; const u32 *stash; const u32 *stash_len; const u32 *stash_idx; @@ -264,8 +261,8 @@ static int gfar_of_init(struct net_device *dev) if (of_get_property(np, "fsl,magic-packet", NULL)) priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET; - ph = of_get_property(np, "phy-handle", NULL); - if (ph == NULL) { + priv->phy_node = of_parse_phandle(np, "phy-handle", 0); + if (!priv->phy_node) { u32 *fixed_link; fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL); @@ -273,57 +270,10 @@ static int gfar_of_init(struct net_device *dev) err = -ENODEV; goto err_out; } - - snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), - PHY_ID_FMT, "0", fixed_link[0]); - } else { - phy = of_find_node_by_phandle(*ph); - - if (phy == NULL) { - err = -ENODEV; - goto err_out; - } - - mdio = of_get_parent(phy); - - id = of_get_property(phy, "reg", NULL); - - of_node_put(phy); - - fsl_pq_mdio_bus_name(bus_name, mdio); - of_node_put(mdio); - snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x", - bus_name, *id); } /* Find the TBI PHY. If it's not there, we don't support SGMII */ - ph = of_get_property(np, "tbi-handle", NULL); - if (ph) { - struct device_node *tbi = of_find_node_by_phandle(*ph); - struct of_device *ofdev; - struct mii_bus *bus; - - if (!tbi) - return 0; - - mdio = of_get_parent(tbi); - if (!mdio) - return 0; - - ofdev = of_find_device_by_node(mdio); - - of_node_put(mdio); - - id = of_get_property(tbi, "reg", NULL); - if (!id) - return 0; - - of_node_put(tbi); - - bus = dev_get_drvdata(&ofdev->dev); - - priv->tbiphy = bus->phy_map[*id]; - } + priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0); return 0; @@ -529,6 +479,10 @@ static int gfar_probe(struct of_device *ofdev, register_fail: iounmap(priv->regs); regs_fail: + if (priv->phy_node) + of_node_put(priv->phy_node); + if (priv->tbi_node) + of_node_put(priv->tbi_node); free_netdev(dev); return err; } @@ -537,6 +491,11 @@ static int gfar_remove(struct of_device *ofdev) { struct gfar_private *priv = dev_get_drvdata(&ofdev->dev); + if (priv->phy_node) + of_node_put(priv->phy_node); + if (priv->tbi_node) + of_node_put(priv->tbi_node); + dev_set_drvdata(&ofdev->dev, NULL); iounmap(priv->regs); @@ -690,7 +649,6 @@ static int init_phy(struct net_device *dev) uint gigabit_support = priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ? SUPPORTED_1000baseT_Full : 0; - struct phy_device *phydev; phy_interface_t interface; priv->oldlink = 0; @@ -699,21 +657,21 @@ static int init_phy(struct net_device *dev) interface = gfar_get_interface(dev); - phydev = phy_connect(dev, priv->phy_bus_id, &adjust_link, 0, interface); + if (priv->phy_node) { + priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, + 0, interface); + if (!priv->phydev) { + dev_err(&dev->dev, "error: Could not attach to PHY\n"); + return -ENODEV; + } + } if (interface == PHY_INTERFACE_MODE_SGMII) gfar_configure_serdes(dev); - if (IS_ERR(phydev)) { - printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(phydev); - } - /* Remove any features not supported by the controller */ - phydev->supported &= (GFAR_SUPPORTED | gigabit_support); - phydev->advertising = phydev->supported; - - priv->phydev = phydev; + priv->phydev->supported &= (GFAR_SUPPORTED | gigabit_support); + priv->phydev->advertising = priv->phydev->supported; return 0; } @@ -730,10 +688,17 @@ static int init_phy(struct net_device *dev) static void gfar_configure_serdes(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); + struct phy_device *tbiphy; + + if (!priv->tbi_node) { + dev_warn(&dev->dev, "error: SGMII mode requires that the " + "device tree specify a tbi-handle\n"); + return; + } - if (!priv->tbiphy) { - printk(KERN_WARNING "SGMII mode requires that the device " - "tree specify a tbi-handle\n"); + tbiphy = of_phy_find_device(priv->tbi_node); + if (!tbiphy) { + dev_err(&dev->dev, "error: Could not get TBI device\n"); return; } @@ -743,17 +708,17 @@ static void gfar_configure_serdes(struct net_device *dev) * everything for us? Resetting it takes the link down and requires * several seconds for it to come back. */ - if (phy_read(priv->tbiphy, MII_BMSR) & BMSR_LSTATUS) + if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS) return; /* Single clk mode, mii mode off(for serdes communication) */ - phy_write(priv->tbiphy, MII_TBICON, TBICON_CLK_SELECT); + phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT); - phy_write(priv->tbiphy, MII_ADVERTISE, + phy_write(tbiphy, MII_ADVERTISE, ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM); - phy_write(priv->tbiphy, MII_BMCR, BMCR_ANENABLE | + phy_write(tbiphy, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); } diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 0642d52aef5c..91317bc11154 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -779,7 +779,8 @@ struct gfar_private { spinlock_t bflock; phy_interface_t interface; - char phy_bus_id[BUS_ID_SIZE]; + struct device_node *phy_node; + struct device_node *tbi_node; u32 device_flags; unsigned char rx_csum_enable:1, extended_hash:1, @@ -793,7 +794,6 @@ struct gfar_private { /* PHY stuff */ struct phy_device *phydev; - struct phy_device *tbiphy; struct mii_bus *mii_bus; int oldspeed; int oldduplex; -- GitLab From 1dd2d06c0459a2f1bffc56765e3cc57427818867 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:53:17 +0000 Subject: [PATCH 0734/6080] net: Rework pasemi_mac driver to use of_mdio infrastructure This patch simplifies the driver by making use of more common code. Signed-off-by: Grant Likely Tested-by: Olof Johansson Acked-by: Olof Johansson Acked-by: Andy Fleming Signed-off-by: David S. Miller --- arch/powerpc/platforms/pasemi/gpio_mdio.c | 32 ++++------------------- drivers/net/pasemi_mac.c | 28 +++----------------- drivers/net/pasemi_mac.h | 1 - 3 files changed, 9 insertions(+), 52 deletions(-) diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index 75cc165d5bee..3bf546797cbb 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #define DELAY 1 @@ -39,6 +39,7 @@ static void __iomem *gpio_regs; struct gpio_priv { int mdc_pin; int mdio_pin; + int mdio_irqs[PHY_MAX_ADDR]; }; #define MDC_PIN(bus) (((struct gpio_priv *)bus->priv)->mdc_pin) @@ -218,12 +219,11 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; - struct device_node *phy_dn, *np = ofdev->node; + struct device_node *np = ofdev->node; struct mii_bus *new_bus; struct gpio_priv *priv; const unsigned int *prop; int err; - int i; err = -ENOMEM; priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL); @@ -244,27 +244,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop); new_bus->priv = priv; - new_bus->phy_mask = 0; - - new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); - - if (!new_bus->irq) - goto out_free_bus; - - for (i = 0; i < PHY_MAX_ADDR; i++) - new_bus->irq[i] = NO_IRQ; - - for (phy_dn = of_get_next_child(np, NULL); - phy_dn != NULL; - phy_dn = of_get_next_child(np, phy_dn)) { - const unsigned int *ip, *regp; - - ip = of_get_property(phy_dn, "interrupts", NULL); - regp = of_get_property(phy_dn, "reg", NULL); - if (!ip || !regp || *regp >= PHY_MAX_ADDR) - continue; - new_bus->irq[*regp] = irq_create_mapping(NULL, *ip); - } + new_bus->irq = priv->mdio_irqs; prop = of_get_property(np, "mdc-pin", NULL); priv->mdc_pin = *prop; @@ -275,7 +255,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, new_bus->parent = dev; dev_set_drvdata(dev, new_bus); - err = mdiobus_register(new_bus); + err = of_mdiobus_register(new_bus, np); if (err != 0) { printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n", @@ -286,8 +266,6 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev, return 0; out_free_irq: - kfree(new_bus->irq); -out_free_bus: kfree(new_bus); out_free_priv: kfree(priv); diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 067caba43656..6ea4539085d5 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1086,34 +1087,17 @@ static int pasemi_mac_phy_init(struct net_device *dev) struct pasemi_mac *mac = netdev_priv(dev); struct device_node *dn, *phy_dn; struct phy_device *phydev; - unsigned int phy_id; - const phandle *ph; - const unsigned int *prop; - struct resource r; - int ret; dn = pci_device_to_OF_node(mac->pdev); - ph = of_get_property(dn, "phy-handle", NULL); - if (!ph) - return -ENODEV; - phy_dn = of_find_node_by_phandle(*ph); - - prop = of_get_property(phy_dn, "reg", NULL); - ret = of_address_to_resource(phy_dn->parent, 0, &r); - if (ret) - goto err; - - phy_id = *prop; - snprintf(mac->phy_id, sizeof(mac->phy_id), "%x:%02x", - (int)r.start, phy_id); - + phy_dn = of_parse_phandle(dn, "phy-handle", 0); of_node_put(phy_dn); mac->link = 0; mac->speed = 0; mac->duplex = -1; - phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII); + phydev = of_phy_connect(dev, phy_dn, &pasemi_adjust_link, 0, + PHY_INTERFACE_MODE_SGMII); if (IS_ERR(phydev)) { printk(KERN_ERR "%s: Could not attach to phy\n", dev->name); @@ -1123,10 +1107,6 @@ static int pasemi_mac_phy_init(struct net_device *dev) mac->phydev = phydev; return 0; - -err: - of_node_put(phy_dn); - return -ENODEV; } diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index 1a115ec60b53..e2f4efa8ad46 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h @@ -100,7 +100,6 @@ struct pasemi_mac { int duplex; unsigned int msg_enable; - char phy_id[BUS_ID_SIZE]; }; /* Software status descriptor (ring_info) */ -- GitLab From 0b9da337dca972e7a4144e298ec3adb8f244d4a4 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:53:23 +0000 Subject: [PATCH 0735/6080] net: Rework ucc_geth driver to use of_mdio infrastructure This patch simplifies the driver by making use of more common code. Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/ucc_geth.c | 47 +++++++++++------------------------------- drivers/net/ucc_geth.h | 2 +- 2 files changed, 13 insertions(+), 36 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 811f97cb0a29..a53628466637 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1543,12 +1544,14 @@ static int init_phy(struct net_device *dev) priv->oldspeed = 0; priv->oldduplex = -1; - phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0, - priv->phy_interface); + if (!ug_info->phy_node) + return 0; - if (IS_ERR(phydev)) { + phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0, + priv->phy_interface); + if (!phydev) { printk("%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(phydev); + return -ENODEV; } phydev->supported &= (ADVERTISED_10baseT_Half | @@ -3511,14 +3514,12 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma { struct device *device = &ofdev->dev; struct device_node *np = ofdev->node; - struct device_node *mdio; struct net_device *dev = NULL; struct ucc_geth_private *ugeth = NULL; struct ucc_geth_info *ug_info; struct resource res; struct device_node *phy; int err, ucc_num, max_speed = 0; - const phandle *ph; const u32 *fixed_link; const unsigned int *prop; const char *sprop; @@ -3618,45 +3619,21 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); fixed_link = of_get_property(np, "fixed-link", NULL); if (fixed_link) { - snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id), - PHY_ID_FMT, "0", fixed_link[0]); phy = NULL; } else { - char bus_name[MII_BUS_ID_SIZE]; - - ph = of_get_property(np, "phy-handle", NULL); - phy = of_find_node_by_phandle(*ph); - + phy = of_parse_phandle(np, "phy-handle", 0); if (phy == NULL) return -ENODEV; - - /* set the PHY address */ - prop = of_get_property(phy, "reg", NULL); - if (prop == NULL) - return -1; - - /* Set the bus id */ - mdio = of_get_parent(phy); - - if (mdio == NULL) - return -ENODEV; - - err = of_address_to_resource(mdio, 0, &res); - - if (err) { - of_node_put(mdio); - return err; - } - fsl_pq_mdio_bus_name(bus_name, mdio); - of_node_put(mdio); - snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id), - "%s:%02x", bus_name, *prop); } + ug_info->phy_node = phy; /* get the phy interface type, or default to MII */ prop = of_get_property(np, "phy-connection-type", NULL); if (!prop) { /* handle interface property present in old trees */ + if (!phy) + return -ENODEV; + prop = of_get_property(phy, "interface", NULL); if (prop != NULL) { phy_interface = enet_to_phy_interface[*prop]; diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 602764799df0..dca628a922ba 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -1099,7 +1099,7 @@ struct ucc_geth_info { u32 eventRegMask; u16 pausePeriod; u16 extensionField; - char phy_bus_id[BUS_ID_SIZE]; + struct device_node *phy_node; u8 weightfactor[NUM_TX_QUEUES]; u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES]; u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX]; -- GitLab From fd84f0ee50d3abedd11454b016823aa3ffcdc919 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:53:28 +0000 Subject: [PATCH 0736/6080] powerpc/82xx: Rework Embedded Planet ep8248e platform to use of_mdio This patch modifies the bitbanged MDIO driver in the ep8248e platform code to use the common of_mdio infrastructure. Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- arch/powerpc/platforms/82xx/ep8248e.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/platforms/82xx/ep8248e.c b/arch/powerpc/platforms/82xx/ep8248e.c index 0eb6d7f62241..51fcae41f08a 100644 --- a/arch/powerpc/platforms/82xx/ep8248e.c +++ b/arch/powerpc/platforms/82xx/ep8248e.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -115,7 +116,7 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, struct mii_bus *bus; struct resource res; struct device_node *node; - int ret, i; + int ret; node = of_get_parent(ofdev->node); of_node_put(node); @@ -130,17 +131,13 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, if (!bus) return -ENOMEM; - bus->phy_mask = 0; bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - for (i = 0; i < PHY_MAX_ADDR; i++) - bus->irq[i] = -1; - bus->name = "ep8248e-mdio-bitbang"; bus->parent = &ofdev->dev; snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); - return mdiobus_register(bus); + return of_mdiobus_register(bus, ofdev->node); } static int ep8248e_mdio_remove(struct of_device *ofdev) -- GitLab From aa73832c5a80d6c52c69b18af858d88fa595dd3c Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:53:33 +0000 Subject: [PATCH 0737/6080] net: Rework fs_enet driver to use of_mdio infrastructure This patch simplifies the driver by making use of more common code. Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/fs_enet/fs_enet-main.c | 69 +++++------------------------- drivers/net/fs_enet/mii-bitbang.c | 29 +------------ drivers/net/fs_enet/mii-fec.c | 26 +---------- include/linux/fs_enet_pd.h | 6 +-- 4 files changed, 16 insertions(+), 114 deletions(-) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index a9cbc3191a2a..9604aaed61d6 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include @@ -752,9 +754,10 @@ static int fs_init_phy(struct net_device *dev) fep->oldlink = 0; fep->oldspeed = 0; fep->oldduplex = -1; - if(fep->fpi->bus_id) - phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0, - PHY_INTERFACE_MODE_MII); + if(fep->fpi->phy_node) + phydev = of_phy_connect(dev, fep->fpi->phy_node, + &fs_adjust_link, 0, + PHY_INTERFACE_MODE_MII); else { printk("No phy bus ID specified in BSP code\n"); return -EINVAL; @@ -962,57 +965,6 @@ static void cleanup_immap(void) /**************************************************************************************/ -static int __devinit find_phy(struct device_node *np, - struct fs_platform_info *fpi) -{ - struct device_node *phynode, *mdionode; - int ret = 0, len, bus_id; - const u32 *data; - - data = of_get_property(np, "fixed-link", NULL); - if (data) { - snprintf(fpi->bus_id, 16, "%x:%02x", 0, *data); - return 0; - } - - data = of_get_property(np, "phy-handle", &len); - if (!data || len != 4) - return -EINVAL; - - phynode = of_find_node_by_phandle(*data); - if (!phynode) - return -EINVAL; - - data = of_get_property(phynode, "reg", &len); - if (!data || len != 4) { - ret = -EINVAL; - goto out_put_phy; - } - - mdionode = of_get_parent(phynode); - if (!mdionode) { - ret = -EINVAL; - goto out_put_phy; - } - - bus_id = of_get_gpio(mdionode, 0); - if (bus_id < 0) { - struct resource res; - ret = of_address_to_resource(mdionode, 0, &res); - if (ret) - goto out_put_mdio; - bus_id = res.start; - } - - snprintf(fpi->bus_id, 16, "%x:%02x", bus_id, *data); - -out_put_mdio: - of_node_put(mdionode); -out_put_phy: - of_node_put(phynode); - return ret; -} - #ifdef CONFIG_FS_ENET_HAS_FEC #define IS_FEC(match) ((match)->data == &fs_fec_ops) #else @@ -1062,9 +1014,9 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, fpi->rx_copybreak = 240; fpi->use_napi = 1; fpi->napi_weight = 17; - - ret = find_phy(ofdev->node, fpi); - if (ret) + fpi->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0); + if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fixed-link", + NULL))) goto out_free_fpi; privsize = sizeof(*fep) + @@ -1136,6 +1088,7 @@ out_cleanup_data: out_free_dev: free_netdev(ndev); dev_set_drvdata(&ofdev->dev, NULL); + of_node_put(fpi->phy_node); out_free_fpi: kfree(fpi); return ret; @@ -1151,7 +1104,7 @@ static int fs_enet_remove(struct of_device *ofdev) fep->ops->free_bd(ndev); fep->ops->cleanup_data(ndev); dev_set_drvdata(fep->dev, NULL); - + of_node_put(fep->fpi->phy_node); free_netdev(ndev); return 0; } diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index 49b6645d7e0c..93b481b0e3c7 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "fs_enet.h" @@ -149,31 +150,12 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus, return 0; } -static void __devinit add_phy(struct mii_bus *bus, struct device_node *np) -{ - const u32 *data; - int len, id, irq; - - data = of_get_property(np, "reg", &len); - if (!data || len != 4) - return; - - id = *data; - bus->phy_mask &= ~(1 << id); - - irq = of_irq_to_resource(np, 0, NULL); - if (irq != NO_IRQ) - bus->irq[id] = irq; -} - static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { - struct device_node *np = NULL; struct mii_bus *new_bus; struct bb_info *bitbang; int ret = -ENOMEM; - int i; bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL); if (!bitbang) @@ -196,17 +178,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, if (!new_bus->irq) goto out_unmap_regs; - for (i = 0; i < PHY_MAX_ADDR; i++) - new_bus->irq[i] = -1; - - while ((np = of_get_next_child(ofdev->node, np))) - if (!strcmp(np->type, "ethernet-phy")) - add_phy(new_bus, np); - new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); - ret = mdiobus_register(new_bus); + ret = of_mdiobus_register(new_bus, ofdev->node); if (ret) goto out_free_irqs; diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 61aaae444b40..75a09994d665 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -100,23 +100,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus) return 0; } -static void __devinit add_phy(struct mii_bus *bus, struct device_node *np) -{ - const u32 *data; - int len, id, irq; - - data = of_get_property(np, "reg", &len); - if (!data || len != 4) - return; - - id = *data; - bus->phy_mask &= ~(1 << id); - - irq = of_irq_to_resource(np, 0, NULL); - if (irq != NO_IRQ) - bus->irq[id] = irq; -} - static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { @@ -163,17 +146,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, if (!new_bus->irq) goto out_unmap_regs; - for (i = 0; i < PHY_MAX_ADDR; i++) - new_bus->irq[i] = -1; - - while ((np = of_get_next_child(ofdev->node, np))) - if (!strcmp(np->type, "ethernet-phy")) - add_phy(new_bus, np); - new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); - ret = mdiobus_register(new_bus); + ret = of_mdiobus_register(new_bus, ofdev->node); if (ret) goto out_free_irqs; diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h index 8300cab30f9a..51b793466ff3 100644 --- a/include/linux/fs_enet_pd.h +++ b/include/linux/fs_enet_pd.h @@ -17,6 +17,7 @@ #define FS_ENET_PD_H #include +#include #include #define FS_ENET_NAME "fs_enet" @@ -130,10 +131,7 @@ struct fs_platform_info { u32 device_flags; - int phy_addr; /* the phy address (-1 no phy) */ - char bus_id[16]; - int phy_irq; /* the phy irq (if it exists) */ - + struct device_node *phy_node; const struct fs_mii_bus_info *bus_info; int rx_ring, tx_ring; /* number of buffers on rx */ -- GitLab From 92744989533cbe85e8057935d230e128810168ce Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:53:39 +0000 Subject: [PATCH 0738/6080] net: add Xilinx ll_temac device driver This patch adds support for the Xilinx ll_temac 10/100/1000 Ethernet device. The ll_temac ipcore is typically used on Xilinx Virtex and Spartan designs attached to either a PowerPC 4xx or Microblaze processor. At the present moment, this driver only works with Virtex5 PowerPC designs because it assumes DCR is used to access the DMA registers. However, the low level access to DMA registers is abstracted and it should be easy to adapt for the other implementations. I'm posting this driver now as an RFC. There are still some things that need to be tightened up, but it does appear to be stable. Derived from driver code written by Yoshio Kashiwagi and David H. Lynch Jr. Tested on Xilinx ML507 eval board with Base System Builder generated FPGA design. Signed-off-by: Grant Likely Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/Kconfig | 8 + drivers/net/Makefile | 2 + drivers/net/ll_temac.h | 374 ++++++++++++++ drivers/net/ll_temac_main.c | 969 ++++++++++++++++++++++++++++++++++++ drivers/net/ll_temac_mdio.c | 120 +++++ 5 files changed, 1473 insertions(+) create mode 100644 drivers/net/ll_temac.h create mode 100644 drivers/net/ll_temac_main.c create mode 100644 drivers/net/ll_temac_mdio.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 214a92d1ef75..3320e7761576 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2362,6 +2362,14 @@ config MV643XX_ETH Some boards that use the Discovery chipset are the Momenco Ocelot C and Jaguar ATX and Pegasos II. +config XILINX_LL_TEMAC + tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" + select PHYLIB + depends on PPC_DCR_NATIVE + help + This driver supports the Xilinx 10/100/1000 LocalLink TEMAC + core used in Xilinx Spartan and Virtex FPGAs + config QLA3XXX tristate "QLogic QLA3XXX Network Driver Support" depends on PCI diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 1fc4602a6ff2..80420f6d0795 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -134,6 +134,8 @@ obj-$(CONFIG_AX88796) += ax88796.o obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o +ll_temac-objs := ll_temac_main.o ll_temac_mdio.o +obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o obj-$(CONFIG_QLA3XXX) += qla3xxx.o obj-$(CONFIG_QLGE) += qlge/ diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h new file mode 100644 index 000000000000..1af66a1e6911 --- /dev/null +++ b/drivers/net/ll_temac.h @@ -0,0 +1,374 @@ + +#ifndef XILINX_LL_TEMAC_H +#define XILINX_LL_TEMAC_H + +#include +#include +#include +#include +#include + +/* packet size info */ +#define XTE_HDR_SIZE 14 /* size of Ethernet header */ +#define XTE_TRL_SIZE 4 /* size of Ethernet trailer (FCS) */ +#define XTE_JUMBO_MTU 9000 +#define XTE_MAX_JUMBO_FRAME_SIZE (XTE_JUMBO_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE) + +/* Configuration options */ + +/* Accept all incoming packets. + * This option defaults to disabled (cleared) */ +#define XTE_OPTION_PROMISC (1 << 0) +/* Jumbo frame support for Tx & Rx. + * This option defaults to disabled (cleared) */ +#define XTE_OPTION_JUMBO (1 << 1) +/* VLAN Rx & Tx frame support. + * This option defaults to disabled (cleared) */ +#define XTE_OPTION_VLAN (1 << 2) +/* Enable recognition of flow control frames on Rx + * This option defaults to enabled (set) */ +#define XTE_OPTION_FLOW_CONTROL (1 << 4) +/* Strip FCS and PAD from incoming frames. + * Note: PAD from VLAN frames is not stripped. + * This option defaults to disabled (set) */ +#define XTE_OPTION_FCS_STRIP (1 << 5) +/* Generate FCS field and add PAD automatically for outgoing frames. + * This option defaults to enabled (set) */ +#define XTE_OPTION_FCS_INSERT (1 << 6) +/* Enable Length/Type error checking for incoming frames. When this option is +set, the MAC will filter frames that have a mismatched type/length field +and if XTE_OPTION_REPORT_RXERR is set, the user is notified when these +types of frames are encountered. When this option is cleared, the MAC will +allow these types of frames to be received. +This option defaults to enabled (set) */ +#define XTE_OPTION_LENTYPE_ERR (1 << 7) +/* Enable the transmitter. + * This option defaults to enabled (set) */ +#define XTE_OPTION_TXEN (1 << 11) +/* Enable the receiver +* This option defaults to enabled (set) */ +#define XTE_OPTION_RXEN (1 << 12) + +/* Default options set when device is initialized or reset */ +#define XTE_OPTION_DEFAULTS \ + (XTE_OPTION_TXEN | \ + XTE_OPTION_FLOW_CONTROL | \ + XTE_OPTION_RXEN) + +/* XPS_LL_TEMAC SDMA registers definition */ + +#define TX_NXTDESC_PTR 0x00 /* r */ +#define TX_CURBUF_ADDR 0x01 /* r */ +#define TX_CURBUF_LENGTH 0x02 /* r */ +#define TX_CURDESC_PTR 0x03 /* rw */ +#define TX_TAILDESC_PTR 0x04 /* rw */ +#define TX_CHNL_CTRL 0x05 /* rw */ +/* + 0:7 24:31 IRQTimeout + 8:15 16:23 IRQCount + 16:20 11:15 Reserved + 21 10 0 + 22 9 UseIntOnEnd + 23 8 LdIRQCnt + 24 7 IRQEn + 25:28 3:6 Reserved + 29 2 IrqErrEn + 30 1 IrqDlyEn + 31 0 IrqCoalEn +*/ +#define CHNL_CTRL_IRQ_IOE (1 << 9) +#define CHNL_CTRL_IRQ_EN (1 << 7) +#define CHNL_CTRL_IRQ_ERR_EN (1 << 2) +#define CHNL_CTRL_IRQ_DLY_EN (1 << 1) +#define CHNL_CTRL_IRQ_COAL_EN (1 << 0) +#define TX_IRQ_REG 0x06 /* rw */ +/* + 0:7 24:31 DltTmrValue + 8:15 16:23 ClscCntrValue + 16:17 14:15 Reserved + 18:21 10:13 ClscCnt + 22:23 8:9 DlyCnt + 24:28 3::7 Reserved + 29 2 ErrIrq + 30 1 DlyIrq + 31 0 CoalIrq + */ +#define TX_CHNL_STS 0x07 /* r */ +/* + 0:9 22:31 Reserved + 10 21 TailPErr + 11 20 CmpErr + 12 19 AddrErr + 13 18 NxtPErr + 14 17 CurPErr + 15 16 BsyWr + 16:23 8:15 Reserved + 24 7 Error + 25 6 IOE + 26 5 SOE + 27 4 Cmplt + 28 3 SOP + 29 2 EOP + 30 1 EngBusy + 31 0 Reserved +*/ + +#define RX_NXTDESC_PTR 0x08 /* r */ +#define RX_CURBUF_ADDR 0x09 /* r */ +#define RX_CURBUF_LENGTH 0x0a /* r */ +#define RX_CURDESC_PTR 0x0b /* rw */ +#define RX_TAILDESC_PTR 0x0c /* rw */ +#define RX_CHNL_CTRL 0x0d /* rw */ +/* + 0:7 24:31 IRQTimeout + 8:15 16:23 IRQCount + 16:20 11:15 Reserved + 21 10 0 + 22 9 UseIntOnEnd + 23 8 LdIRQCnt + 24 7 IRQEn + 25:28 3:6 Reserved + 29 2 IrqErrEn + 30 1 IrqDlyEn + 31 0 IrqCoalEn + */ +#define RX_IRQ_REG 0x0e /* rw */ +#define IRQ_COAL (1 << 0) +#define IRQ_DLY (1 << 1) +#define IRQ_ERR (1 << 2) +#define IRQ_DMAERR (1 << 7) /* this is not documented ??? */ +/* + 0:7 24:31 DltTmrValue + 8:15 16:23 ClscCntrValue + 16:17 14:15 Reserved + 18:21 10:13 ClscCnt + 22:23 8:9 DlyCnt + 24:28 3::7 Reserved +*/ +#define RX_CHNL_STS 0x0f /* r */ +#define CHNL_STS_ENGBUSY (1 << 1) +#define CHNL_STS_EOP (1 << 2) +#define CHNL_STS_SOP (1 << 3) +#define CHNL_STS_CMPLT (1 << 4) +#define CHNL_STS_SOE (1 << 5) +#define CHNL_STS_IOE (1 << 6) +#define CHNL_STS_ERR (1 << 7) + +#define CHNL_STS_BSYWR (1 << 16) +#define CHNL_STS_CURPERR (1 << 17) +#define CHNL_STS_NXTPERR (1 << 18) +#define CHNL_STS_ADDRERR (1 << 19) +#define CHNL_STS_CMPERR (1 << 20) +#define CHNL_STS_TAILERR (1 << 21) +/* + 0:9 22:31 Reserved + 10 21 TailPErr + 11 20 CmpErr + 12 19 AddrErr + 13 18 NxtPErr + 14 17 CurPErr + 15 16 BsyWr + 16:23 8:15 Reserved + 24 7 Error + 25 6 IOE + 26 5 SOE + 27 4 Cmplt + 28 3 SOP + 29 2 EOP + 30 1 EngBusy + 31 0 Reserved +*/ + +#define DMA_CONTROL_REG 0x10 /* rw */ +#define DMA_CONTROL_RST (1 << 0) +#define DMA_TAIL_ENABLE (1 << 2) + +/* XPS_LL_TEMAC direct registers definition */ + +#define XTE_RAF0_OFFSET 0x00 +#define RAF0_RST (1 << 0) +#define RAF0_MCSTREJ (1 << 1) +#define RAF0_BCSTREJ (1 << 2) +#define XTE_TPF0_OFFSET 0x04 +#define XTE_IFGP0_OFFSET 0x08 +#define XTE_ISR0_OFFSET 0x0c +#define ISR0_HARDACSCMPLT (1 << 0) +#define ISR0_AUTONEG (1 << 1) +#define ISR0_RXCMPLT (1 << 2) +#define ISR0_RXREJ (1 << 3) +#define ISR0_RXFIFOOVR (1 << 4) +#define ISR0_TXCMPLT (1 << 5) +#define ISR0_RXDCMLCK (1 << 6) + +#define XTE_IPR0_OFFSET 0x10 +#define XTE_IER0_OFFSET 0x14 + +#define XTE_MSW0_OFFSET 0x20 +#define XTE_LSW0_OFFSET 0x24 +#define XTE_CTL0_OFFSET 0x28 +#define XTE_RDY0_OFFSET 0x2c + +#define XTE_RSE_MIIM_RR_MASK 0x0002 +#define XTE_RSE_MIIM_WR_MASK 0x0004 +#define XTE_RSE_CFG_RR_MASK 0x0020 +#define XTE_RSE_CFG_WR_MASK 0x0040 +#define XTE_RDY0_HARD_ACS_RDY_MASK (0x10000) + +/* XPS_LL_TEMAC indirect registers offset definition */ + +#define XTE_RXC0_OFFSET 0x00000200 /* Rx configuration word 0 */ +#define XTE_RXC1_OFFSET 0x00000240 /* Rx configuration word 1 */ +#define XTE_RXC1_RXRST_MASK (1 << 31) /* Receiver reset */ +#define XTE_RXC1_RXJMBO_MASK (1 << 30) /* Jumbo frame enable */ +#define XTE_RXC1_RXFCS_MASK (1 << 29) /* FCS not stripped */ +#define XTE_RXC1_RXEN_MASK (1 << 28) /* Receiver enable */ +#define XTE_RXC1_RXVLAN_MASK (1 << 27) /* VLAN enable */ +#define XTE_RXC1_RXHD_MASK (1 << 26) /* Half duplex */ +#define XTE_RXC1_RXLT_MASK (1 << 25) /* Length/type check disable */ + +#define XTE_TXC_OFFSET 0x00000280 /* Tx configuration */ +#define XTE_TXC_TXRST_MASK (1 << 31) /* Transmitter reset */ +#define XTE_TXC_TXJMBO_MASK (1 << 30) /* Jumbo frame enable */ +#define XTE_TXC_TXFCS_MASK (1 << 29) /* Generate FCS */ +#define XTE_TXC_TXEN_MASK (1 << 28) /* Transmitter enable */ +#define XTE_TXC_TXVLAN_MASK (1 << 27) /* VLAN enable */ +#define XTE_TXC_TXHD_MASK (1 << 26) /* Half duplex */ + +#define XTE_FCC_OFFSET 0x000002C0 /* Flow control config */ +#define XTE_FCC_RXFLO_MASK (1 << 29) /* Rx flow control enable */ +#define XTE_FCC_TXFLO_MASK (1 << 30) /* Tx flow control enable */ + +#define XTE_EMCFG_OFFSET 0x00000300 /* EMAC configuration */ +#define XTE_EMCFG_LINKSPD_MASK 0xC0000000 /* Link speed */ +#define XTE_EMCFG_HOSTEN_MASK (1 << 26) /* Host interface enable */ +#define XTE_EMCFG_LINKSPD_10 0x00000000 /* 10 Mbit LINKSPD_MASK */ +#define XTE_EMCFG_LINKSPD_100 (1 << 30) /* 100 Mbit LINKSPD_MASK */ +#define XTE_EMCFG_LINKSPD_1000 (1 << 31) /* 1000 Mbit LINKSPD_MASK */ + +#define XTE_GMIC_OFFSET 0x00000320 /* RGMII/SGMII config */ +#define XTE_MC_OFFSET 0x00000340 /* MDIO configuration */ +#define XTE_UAW0_OFFSET 0x00000380 /* Unicast address word 0 */ +#define XTE_UAW1_OFFSET 0x00000384 /* Unicast address word 1 */ + +#define XTE_MAW0_OFFSET 0x00000388 /* Multicast addr word 0 */ +#define XTE_MAW1_OFFSET 0x0000038C /* Multicast addr word 1 */ +#define XTE_AFM_OFFSET 0x00000390 /* Promiscuous mode */ +#define XTE_AFM_EPPRM_MASK (1 << 31) /* Promiscuous mode enable */ + +/* Interrupt Request status */ +#define XTE_TIS_OFFSET 0x000003A0 +#define TIS_FRIS (1 << 0) +#define TIS_MRIS (1 << 1) +#define TIS_MWIS (1 << 2) +#define TIS_ARIS (1 << 3) +#define TIS_AWIS (1 << 4) +#define TIS_CRIS (1 << 5) +#define TIS_CWIS (1 << 6) + +#define XTE_TIE_OFFSET 0x000003A4 /* Interrupt enable */ + +/** MII Mamagement Control register (MGTCR) */ +#define XTE_MGTDR_OFFSET 0x000003B0 /* MII data */ +#define XTE_MIIMAI_OFFSET 0x000003B4 /* MII control */ + +#define CNTLREG_WRITE_ENABLE_MASK 0x8000 +#define CNTLREG_EMAC1SEL_MASK 0x0400 +#define CNTLREG_ADDRESSCODE_MASK 0x03ff + +/* CDMAC descriptor status bit definitions */ + +#define STS_CTRL_APP0_ERR (1 << 31) +#define STS_CTRL_APP0_IRQONEND (1 << 30) +/* undoccumented */ +#define STS_CTRL_APP0_STOPONEND (1 << 29) +#define STS_CTRL_APP0_CMPLT (1 << 28) +#define STS_CTRL_APP0_SOP (1 << 27) +#define STS_CTRL_APP0_EOP (1 << 26) +#define STS_CTRL_APP0_ENGBUSY (1 << 25) +/* undocumented */ +#define STS_CTRL_APP0_ENGRST (1 << 24) + +#define TX_CONTROL_CALC_CSUM_MASK 1 + +#define XTE_ALIGN 32 +#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN) + +#define MULTICAST_CAM_TABLE_NUM 4 + +/* TX/RX CURDESC_PTR points to first descriptor */ +/* TX/RX TAILDESC_PTR points to last descriptor in linked list */ + +/** + * struct cdmac_bd - LocalLink buffer descriptor format + * + * app0 bits: + * 0 Error + * 1 IrqOnEnd generate an interrupt at completion of DMA op + * 2 reserved + * 3 completed Current descriptor completed + * 4 SOP TX - marks first desc/ RX marks first desct + * 5 EOP TX marks last desc/RX marks last desc + * 6 EngBusy DMA is processing + * 7 reserved + * 8:31 application specific + */ +struct cdmac_bd { + u32 next; /* Physical address of next buffer descriptor */ + u32 phys; + u32 len; + u32 app0; + u32 app1; /* TX start << 16 | insert */ + u32 app2; /* TX csum */ + u32 app3; + u32 app4; /* skb for TX length for RX */ +}; + +struct temac_local { + struct net_device *ndev; + struct device *dev; + + /* Connection to PHY device */ + struct phy_device *phy_dev; /* Pointer to PHY device */ + struct device_node *phy_node; + + /* MDIO bus data */ + struct mii_bus *mii_bus; /* MII bus reference */ + int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */ + + /* IO registers and IRQs */ + void __iomem *regs; + dcr_host_t sdma_dcrs; + int tx_irq; + int rx_irq; + int emac_num; + + struct sk_buff **rx_skb; + spinlock_t rx_lock; + struct mutex indirect_mutex; + u32 options; /* Current options word */ + int last_link; + + /* Buffer descriptors */ + struct cdmac_bd *tx_bd_v; + dma_addr_t tx_bd_p; + struct cdmac_bd *rx_bd_v; + dma_addr_t rx_bd_p; + int tx_bd_ci; + int tx_bd_next; + int tx_bd_tail; + int rx_bd_ci; +}; + +/* xilinx_temac.c */ +u32 temac_ior(struct temac_local *lp, int offset); +void temac_iow(struct temac_local *lp, int offset, u32 value); +int temac_indirect_busywait(struct temac_local *lp); +u32 temac_indirect_in32(struct temac_local *lp, int reg); +void temac_indirect_out32(struct temac_local *lp, int reg, u32 value); + + +/* xilinx_temac_mdio.c */ +int temac_mdio_setup(struct temac_local *lp, struct device_node *np); +void temac_mdio_teardown(struct temac_local *lp); + +#endif /* XILINX_LL_TEMAC_H */ diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c new file mode 100644 index 000000000000..96e7248876c1 --- /dev/null +++ b/drivers/net/ll_temac_main.c @@ -0,0 +1,969 @@ +/* + * Driver for Xilinx TEMAC Ethernet device + * + * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi + * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. + * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. + * + * This is a driver for the Xilinx ll_temac ipcore which is often used + * in the Virtex and Spartan series of chips. + * + * Notes: + * - The ll_temac hardware uses indirect access for many of the TEMAC + * registers, include the MDIO bus. However, indirect access to MDIO + * registers take considerably more clock cycles than to TEMAC registers. + * MDIO accesses are long, so threads doing them should probably sleep + * rather than busywait. However, since only one indirect access can be + * in progress at any given time, that means that *all* indirect accesses + * could end up sleeping (to wait for an MDIO access to complete). + * Fortunately none of the indirect accesses are on the 'hot' path for tx + * or rx, so this should be okay. + * + * TODO: + * - Fix driver to work on more than just Virtex5. Right now the driver + * assumes that the locallink DMA registers are accessed via DCR + * instructions. + * - Factor out locallink DMA code into separate driver + * - Fix multicast assignment. + * - Fix support for hardware checksumming. + * - Testing. Lots and lots of testing. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* needed for sizeof(tcphdr) */ +#include /* needed for sizeof(udphdr) */ +#include +#include +#include +#include + +#include "ll_temac.h" + +#define TX_BD_NUM 64 +#define RX_BD_NUM 128 + +/* --------------------------------------------------------------------- + * Low level register access functions + */ + +u32 temac_ior(struct temac_local *lp, int offset) +{ + return in_be32((u32 *)(lp->regs + offset)); +} + +void temac_iow(struct temac_local *lp, int offset, u32 value) +{ + out_be32((u32 *) (lp->regs + offset), value); +} + +int temac_indirect_busywait(struct temac_local *lp) +{ + long end = jiffies + 2; + + while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) { + if (end - jiffies <= 0) { + WARN_ON(1); + return -ETIMEDOUT; + } + msleep(1); + } + return 0; +} + +/** + * temac_indirect_in32 + * + * lp->indirect_mutex must be held when calling this function + */ +u32 temac_indirect_in32(struct temac_local *lp, int reg) +{ + u32 val; + + if (temac_indirect_busywait(lp)) + return -ETIMEDOUT; + temac_iow(lp, XTE_CTL0_OFFSET, reg); + if (temac_indirect_busywait(lp)) + return -ETIMEDOUT; + val = temac_ior(lp, XTE_LSW0_OFFSET); + + return val; +} + +/** + * temac_indirect_out32 + * + * lp->indirect_mutex must be held when calling this function + */ +void temac_indirect_out32(struct temac_local *lp, int reg, u32 value) +{ + if (temac_indirect_busywait(lp)) + return; + temac_iow(lp, XTE_LSW0_OFFSET, value); + temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg); +} + +static u32 temac_dma_in32(struct temac_local *lp, int reg) +{ + return dcr_read(lp->sdma_dcrs, reg); +} + +static void temac_dma_out32(struct temac_local *lp, int reg, u32 value) +{ + dcr_write(lp->sdma_dcrs, reg, value); +} + +/** + * temac_dma_bd_init - Setup buffer descriptor rings + */ +static int temac_dma_bd_init(struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + struct sk_buff *skb; + int i; + + lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL); + /* allocate the tx and rx ring buffer descriptors. */ + /* returns a virtual addres and a physical address. */ + lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, + sizeof(*lp->tx_bd_v) * TX_BD_NUM, + &lp->tx_bd_p, GFP_KERNEL); + lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, + sizeof(*lp->rx_bd_v) * RX_BD_NUM, + &lp->rx_bd_p, GFP_KERNEL); + + memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM); + for (i = 0; i < TX_BD_NUM; i++) { + lp->tx_bd_v[i].next = lp->tx_bd_p + + sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM); + } + + memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM); + for (i = 0; i < RX_BD_NUM; i++) { + lp->rx_bd_v[i].next = lp->rx_bd_p + + sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM); + + skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + + XTE_ALIGN, GFP_ATOMIC); + if (skb == 0) { + dev_err(&ndev->dev, "alloc_skb error %d\n", i); + return -1; + } + lp->rx_skb[i] = skb; + skb_reserve(skb, BUFFER_ALIGN(skb->data)); + /* returns physical address of skb->data */ + lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, + skb->data, + XTE_MAX_JUMBO_FRAME_SIZE, + DMA_FROM_DEVICE); + lp->rx_bd_v[i].len = XTE_MAX_JUMBO_FRAME_SIZE; + lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND; + } + + temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 | + CHNL_CTRL_IRQ_EN | + CHNL_CTRL_IRQ_DLY_EN | + CHNL_CTRL_IRQ_COAL_EN); + /* 0x10220483 */ + /* 0x00100483 */ + temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 | + CHNL_CTRL_IRQ_EN | + CHNL_CTRL_IRQ_DLY_EN | + CHNL_CTRL_IRQ_COAL_EN | + CHNL_CTRL_IRQ_IOE); + /* 0xff010283 */ + + temac_dma_out32(lp, RX_CURDESC_PTR, lp->rx_bd_p); + temac_dma_out32(lp, RX_TAILDESC_PTR, + lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p); + + return 0; +} + +/* --------------------------------------------------------------------- + * net_device_ops + */ + +static int temac_set_mac_address(struct net_device *ndev, void *address) +{ + struct temac_local *lp = netdev_priv(ndev); + + if (address) + memcpy(ndev->dev_addr, address, ETH_ALEN); + + if (!is_valid_ether_addr(ndev->dev_addr)) + random_ether_addr(ndev->dev_addr); + + /* set up unicast MAC address filter set its mac address */ + mutex_lock(&lp->indirect_mutex); + temac_indirect_out32(lp, XTE_UAW0_OFFSET, + (ndev->dev_addr[0]) | + (ndev->dev_addr[1] << 8) | + (ndev->dev_addr[2] << 16) | + (ndev->dev_addr[3] << 24)); + /* There are reserved bits in EUAW1 + * so don't affect them Set MAC bits [47:32] in EUAW1 */ + temac_indirect_out32(lp, XTE_UAW1_OFFSET, + (ndev->dev_addr[4] & 0x000000ff) | + (ndev->dev_addr[5] << 8)); + mutex_unlock(&lp->indirect_mutex); + + return 0; +} + +static void temac_set_multicast_list(struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + u32 multi_addr_msw, multi_addr_lsw, val; + int i; + + mutex_lock(&lp->indirect_mutex); + if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) + || ndev->mc_count > MULTICAST_CAM_TABLE_NUM) { + /* + * We must make the kernel realise we had to move + * into promisc mode or we start all out war on + * the cable. If it was a promisc request the + * flag is already set. If not we assert it. + */ + ndev->flags |= IFF_PROMISC; + temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK); + dev_info(&ndev->dev, "Promiscuous mode enabled.\n"); + } else if (ndev->mc_count) { + struct dev_mc_list *mclist = ndev->mc_list; + for (i = 0; mclist && i < ndev->mc_count; i++) { + + if (i >= MULTICAST_CAM_TABLE_NUM) + break; + multi_addr_msw = ((mclist->dmi_addr[3] << 24) | + (mclist->dmi_addr[2] << 16) | + (mclist->dmi_addr[1] << 8) | + (mclist->dmi_addr[0])); + temac_indirect_out32(lp, XTE_MAW0_OFFSET, + multi_addr_msw); + multi_addr_lsw = ((mclist->dmi_addr[5] << 8) | + (mclist->dmi_addr[4]) | (i << 16)); + temac_indirect_out32(lp, XTE_MAW1_OFFSET, + multi_addr_lsw); + mclist = mclist->next; + } + } else { + val = temac_indirect_in32(lp, XTE_AFM_OFFSET); + temac_indirect_out32(lp, XTE_AFM_OFFSET, + val & ~XTE_AFM_EPPRM_MASK); + temac_indirect_out32(lp, XTE_MAW0_OFFSET, 0); + temac_indirect_out32(lp, XTE_MAW1_OFFSET, 0); + dev_info(&ndev->dev, "Promiscuous mode disabled.\n"); + } + mutex_unlock(&lp->indirect_mutex); +} + +struct temac_option { + int flg; + u32 opt; + u32 reg; + u32 m_or; + u32 m_and; +} temac_options[] = { + /* Turn on jumbo packet support for both Rx and Tx */ + { + .opt = XTE_OPTION_JUMBO, + .reg = XTE_TXC_OFFSET, + .m_or = XTE_TXC_TXJMBO_MASK, + }, + { + .opt = XTE_OPTION_JUMBO, + .reg = XTE_RXC1_OFFSET, + .m_or =XTE_RXC1_RXJMBO_MASK, + }, + /* Turn on VLAN packet support for both Rx and Tx */ + { + .opt = XTE_OPTION_VLAN, + .reg = XTE_TXC_OFFSET, + .m_or =XTE_TXC_TXVLAN_MASK, + }, + { + .opt = XTE_OPTION_VLAN, + .reg = XTE_RXC1_OFFSET, + .m_or =XTE_RXC1_RXVLAN_MASK, + }, + /* Turn on FCS stripping on receive packets */ + { + .opt = XTE_OPTION_FCS_STRIP, + .reg = XTE_RXC1_OFFSET, + .m_or =XTE_RXC1_RXFCS_MASK, + }, + /* Turn on FCS insertion on transmit packets */ + { + .opt = XTE_OPTION_FCS_INSERT, + .reg = XTE_TXC_OFFSET, + .m_or =XTE_TXC_TXFCS_MASK, + }, + /* Turn on length/type field checking on receive packets */ + { + .opt = XTE_OPTION_LENTYPE_ERR, + .reg = XTE_RXC1_OFFSET, + .m_or =XTE_RXC1_RXLT_MASK, + }, + /* Turn on flow control */ + { + .opt = XTE_OPTION_FLOW_CONTROL, + .reg = XTE_FCC_OFFSET, + .m_or =XTE_FCC_RXFLO_MASK, + }, + /* Turn on flow control */ + { + .opt = XTE_OPTION_FLOW_CONTROL, + .reg = XTE_FCC_OFFSET, + .m_or =XTE_FCC_TXFLO_MASK, + }, + /* Turn on promiscuous frame filtering (all frames are received ) */ + { + .opt = XTE_OPTION_PROMISC, + .reg = XTE_AFM_OFFSET, + .m_or =XTE_AFM_EPPRM_MASK, + }, + /* Enable transmitter if not already enabled */ + { + .opt = XTE_OPTION_TXEN, + .reg = XTE_TXC_OFFSET, + .m_or =XTE_TXC_TXEN_MASK, + }, + /* Enable receiver? */ + { + .opt = XTE_OPTION_RXEN, + .reg = XTE_RXC1_OFFSET, + .m_or =XTE_RXC1_RXEN_MASK, + }, + {} +}; + +/** + * temac_setoptions + */ +static u32 temac_setoptions(struct net_device *ndev, u32 options) +{ + struct temac_local *lp = netdev_priv(ndev); + struct temac_option *tp = &temac_options[0]; + int reg; + + mutex_lock(&lp->indirect_mutex); + while (tp->opt) { + reg = temac_indirect_in32(lp, tp->reg) & ~tp->m_or; + if (options & tp->opt) + reg |= tp->m_or; + temac_indirect_out32(lp, tp->reg, reg); + tp++; + } + lp->options |= options; + mutex_unlock(&lp->indirect_mutex); + + return (0); +} + +/* Initilize temac */ +static void temac_device_reset(struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + u32 timeout; + u32 val; + + /* Perform a software reset */ + + /* 0x300 host enable bit ? */ + /* reset PHY through control register ?:1 */ + + dev_dbg(&ndev->dev, "%s()\n", __func__); + + mutex_lock(&lp->indirect_mutex); + /* Reset the receiver and wait for it to finish reset */ + temac_indirect_out32(lp, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK); + timeout = 1000; + while (temac_indirect_in32(lp, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) { + udelay(1); + if (--timeout == 0) { + dev_err(&ndev->dev, + "temac_device_reset RX reset timeout!!\n"); + break; + } + } + + /* Reset the transmitter and wait for it to finish reset */ + temac_indirect_out32(lp, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK); + timeout = 1000; + while (temac_indirect_in32(lp, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) { + udelay(1); + if (--timeout == 0) { + dev_err(&ndev->dev, + "temac_device_reset TX reset timeout!!\n"); + break; + } + } + + /* Disable the receiver */ + val = temac_indirect_in32(lp, XTE_RXC1_OFFSET); + temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK); + + /* Reset Local Link (DMA) */ + temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST); + timeout = 1000; + while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) { + udelay(1); + if (--timeout == 0) { + dev_err(&ndev->dev, + "temac_device_reset DMA reset timeout!!\n"); + break; + } + } + temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE); + + temac_dma_bd_init(ndev); + + temac_indirect_out32(lp, XTE_RXC0_OFFSET, 0); + temac_indirect_out32(lp, XTE_RXC1_OFFSET, 0); + temac_indirect_out32(lp, XTE_TXC_OFFSET, 0); + temac_indirect_out32(lp, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK); + + mutex_unlock(&lp->indirect_mutex); + + /* Sync default options with HW + * but leave receiver and transmitter disabled. */ + temac_setoptions(ndev, + lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN)); + + temac_set_mac_address(ndev, NULL); + + /* Set address filter table */ + temac_set_multicast_list(ndev); + if (temac_setoptions(ndev, lp->options)) + dev_err(&ndev->dev, "Error setting TEMAC options\n"); + + /* Init Driver variable */ + ndev->trans_start = 0; +} + +void temac_adjust_link(struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + struct phy_device *phy = lp->phy_dev; + u32 mii_speed; + int link_state; + + /* hash together the state values to decide if something has changed */ + link_state = phy->speed | (phy->duplex << 1) | phy->link; + + mutex_lock(&lp->indirect_mutex); + if (lp->last_link != link_state) { + mii_speed = temac_indirect_in32(lp, XTE_EMCFG_OFFSET); + mii_speed &= ~XTE_EMCFG_LINKSPD_MASK; + + switch (phy->speed) { + case SPEED_1000: mii_speed |= XTE_EMCFG_LINKSPD_1000; break; + case SPEED_100: mii_speed |= XTE_EMCFG_LINKSPD_100; break; + case SPEED_10: mii_speed |= XTE_EMCFG_LINKSPD_10; break; + } + + /* Write new speed setting out to TEMAC */ + temac_indirect_out32(lp, XTE_EMCFG_OFFSET, mii_speed); + lp->last_link = link_state; + phy_print_status(phy); + } + mutex_unlock(&lp->indirect_mutex); +} + +static void temac_start_xmit_done(struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + struct cdmac_bd *cur_p; + unsigned int stat = 0; + + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; + stat = cur_p->app0; + + while (stat & STS_CTRL_APP0_CMPLT) { + dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len, + DMA_TO_DEVICE); + if (cur_p->app4) + dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); + cur_p->app0 = 0; + + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += cur_p->len; + + lp->tx_bd_ci++; + if (lp->tx_bd_ci >= TX_BD_NUM) + lp->tx_bd_ci = 0; + + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; + stat = cur_p->app0; + } + + netif_wake_queue(ndev); +} + +static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + struct cdmac_bd *cur_p; + dma_addr_t start_p, tail_p; + int ii; + unsigned long num_frag; + skb_frag_t *frag; + + num_frag = skb_shinfo(skb)->nr_frags; + frag = &skb_shinfo(skb)->frags[0]; + start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + + if (cur_p->app0 & STS_CTRL_APP0_CMPLT) { + if (!netif_queue_stopped(ndev)) { + netif_stop_queue(ndev); + return NETDEV_TX_BUSY; + } + return NETDEV_TX_BUSY; + } + + cur_p->app0 = 0; + if (skb->ip_summed == CHECKSUM_PARTIAL) { + const struct iphdr *ip = ip_hdr(skb); + int length = 0, start = 0, insert = 0; + + switch (ip->protocol) { + case IPPROTO_TCP: + start = sizeof(struct iphdr) + ETH_HLEN; + insert = sizeof(struct iphdr) + ETH_HLEN + 16; + length = ip->tot_len - sizeof(struct iphdr); + break; + case IPPROTO_UDP: + start = sizeof(struct iphdr) + ETH_HLEN; + insert = sizeof(struct iphdr) + ETH_HLEN + 6; + length = ip->tot_len - sizeof(struct iphdr); + break; + default: + break; + } + cur_p->app1 = ((start << 16) | insert); + cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr, + length, ip->protocol, 0); + skb->data[insert] = 0; + skb->data[insert + 1] = 0; + } + cur_p->app0 |= STS_CTRL_APP0_SOP; + cur_p->len = skb_headlen(skb); + cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len, + DMA_TO_DEVICE); + cur_p->app4 = (unsigned long)skb; + + for (ii = 0; ii < num_frag; ii++) { + lp->tx_bd_tail++; + if (lp->tx_bd_tail >= TX_BD_NUM) + lp->tx_bd_tail = 0; + + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + cur_p->phys = dma_map_single(ndev->dev.parent, + (void *)page_address(frag->page) + + frag->page_offset, + frag->size, DMA_TO_DEVICE); + cur_p->len = frag->size; + cur_p->app0 = 0; + frag++; + } + cur_p->app0 |= STS_CTRL_APP0_EOP; + + tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; + lp->tx_bd_tail++; + if (lp->tx_bd_tail >= TX_BD_NUM) + lp->tx_bd_tail = 0; + + /* Kick off the transfer */ + temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ + + return 0; +} + + +static void ll_temac_recv(struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + struct sk_buff *skb, *new_skb; + unsigned int bdstat; + struct cdmac_bd *cur_p; + dma_addr_t tail_p; + int length; + unsigned long skb_vaddr; + unsigned long flags; + + spin_lock_irqsave(&lp->rx_lock, flags); + + tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; + cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; + + bdstat = cur_p->app0; + while ((bdstat & STS_CTRL_APP0_CMPLT)) { + + skb = lp->rx_skb[lp->rx_bd_ci]; + length = cur_p->app4; + + skb_vaddr = virt_to_bus(skb->data); + dma_unmap_single(ndev->dev.parent, skb_vaddr, length, + DMA_FROM_DEVICE); + + skb_put(skb, length); + skb->dev = ndev; + skb->protocol = eth_type_trans(skb, ndev); + skb->ip_summed = CHECKSUM_NONE; + + netif_rx(skb); + + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += length; + + new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN, + GFP_ATOMIC); + if (new_skb == 0) { + dev_err(&ndev->dev, "no memory for new sk_buff\n"); + spin_unlock_irqrestore(&lp->rx_lock, flags); + return; + } + + skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data)); + + cur_p->app0 = STS_CTRL_APP0_IRQONEND; + cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, + XTE_MAX_JUMBO_FRAME_SIZE, + DMA_FROM_DEVICE); + cur_p->len = XTE_MAX_JUMBO_FRAME_SIZE; + lp->rx_skb[lp->rx_bd_ci] = new_skb; + + lp->rx_bd_ci++; + if (lp->rx_bd_ci >= RX_BD_NUM) + lp->rx_bd_ci = 0; + + cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; + bdstat = cur_p->app0; + } + temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p); + + spin_unlock_irqrestore(&lp->rx_lock, flags); +} + +static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) +{ + struct net_device *ndev = _ndev; + struct temac_local *lp = netdev_priv(ndev); + unsigned int status; + + status = temac_dma_in32(lp, TX_IRQ_REG); + temac_dma_out32(lp, TX_IRQ_REG, status); + + if (status & (IRQ_COAL | IRQ_DLY)) + temac_start_xmit_done(lp->ndev); + if (status & 0x080) + dev_err(&ndev->dev, "DMA error 0x%x\n", status); + + return IRQ_HANDLED; +} + +static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev) +{ + struct net_device *ndev = _ndev; + struct temac_local *lp = netdev_priv(ndev); + unsigned int status; + + /* Read and clear the status registers */ + status = temac_dma_in32(lp, RX_IRQ_REG); + temac_dma_out32(lp, RX_IRQ_REG, status); + + if (status & (IRQ_COAL | IRQ_DLY)) + ll_temac_recv(lp->ndev); + + return IRQ_HANDLED; +} + +static int temac_open(struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + int rc; + + dev_dbg(&ndev->dev, "temac_open()\n"); + + if (lp->phy_node) { + lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, + temac_adjust_link, 0, 0); + if (!lp->phy_dev) { + dev_err(lp->dev, "of_phy_connect() failed\n"); + return -ENODEV; + } + + phy_start(lp->phy_dev); + } + + rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev); + if (rc) + goto err_tx_irq; + rc = request_irq(lp->rx_irq, ll_temac_rx_irq, 0, ndev->name, ndev); + if (rc) + goto err_rx_irq; + + temac_device_reset(ndev); + return 0; + + err_rx_irq: + free_irq(lp->tx_irq, ndev); + err_tx_irq: + if (lp->phy_dev) + phy_disconnect(lp->phy_dev); + lp->phy_dev = NULL; + dev_err(lp->dev, "request_irq() failed\n"); + return rc; +} + +static int temac_stop(struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + + dev_dbg(&ndev->dev, "temac_close()\n"); + + free_irq(lp->tx_irq, ndev); + free_irq(lp->rx_irq, ndev); + + if (lp->phy_dev) + phy_disconnect(lp->phy_dev); + lp->phy_dev = NULL; + + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void +temac_poll_controller(struct net_device *ndev) +{ + struct temac_local *lp = netdev_priv(ndev); + + disable_irq(lp->tx_irq); + disable_irq(lp->rx_irq); + + ll_temac_rx_irq(lp->tx_irq, lp); + ll_temac_tx_irq(lp->rx_irq, lp); + + enable_irq(lp->tx_irq); + enable_irq(lp->rx_irq); +} +#endif + +static const struct net_device_ops temac_netdev_ops = { + .ndo_open = temac_open, + .ndo_stop = temac_stop, + .ndo_start_xmit = temac_start_xmit, + .ndo_set_mac_address = temac_set_mac_address, + //.ndo_set_multicast_list = temac_set_multicast_list, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = temac_poll_controller, +#endif +}; + +/* --------------------------------------------------------------------- + * SYSFS device attributes + */ +static ssize_t temac_show_llink_regs(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct temac_local *lp = netdev_priv(ndev); + int i, len = 0; + + for (i = 0; i < 0x11; i++) + len += sprintf(buf + len, "%.8x%s", temac_dma_in32(lp, i), + (i % 8) == 7 ? "\n" : " "); + len += sprintf(buf + len, "\n"); + + return len; +} + +static DEVICE_ATTR(llink_regs, 0440, temac_show_llink_regs, NULL); + +static struct attribute *temac_device_attrs[] = { + &dev_attr_llink_regs.attr, + NULL, +}; + +static const struct attribute_group temac_attr_group = { + .attrs = temac_device_attrs, +}; + +static int __init +temac_of_probe(struct of_device *op, const struct of_device_id *match) +{ + struct device_node *np; + struct temac_local *lp; + struct net_device *ndev; + const void *addr; + int size, rc = 0; + unsigned int dcrs; + + /* Init network device structure */ + ndev = alloc_etherdev(sizeof(*lp)); + if (!ndev) { + dev_err(&op->dev, "could not allocate device.\n"); + return -ENOMEM; + } + ether_setup(ndev); + dev_set_drvdata(&op->dev, ndev); + SET_NETDEV_DEV(ndev, &op->dev); + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ + ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; + ndev->netdev_ops = &temac_netdev_ops; +#if 0 + ndev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4. */ + ndev->features |= NETIF_F_HW_CSUM; /* Can checksum all the packets. */ + ndev->features |= NETIF_F_IPV6_CSUM; /* Can checksum IPV6 TCP/UDP */ + ndev->features |= NETIF_F_HIGHDMA; /* Can DMA to high memory. */ + ndev->features |= NETIF_F_HW_VLAN_TX; /* Transmit VLAN hw accel */ + ndev->features |= NETIF_F_HW_VLAN_RX; /* Receive VLAN hw acceleration */ + ndev->features |= NETIF_F_HW_VLAN_FILTER; /* Receive VLAN filtering */ + ndev->features |= NETIF_F_VLAN_CHALLENGED; /* cannot handle VLAN pkts */ + ndev->features |= NETIF_F_GSO; /* Enable software GSO. */ + ndev->features |= NETIF_F_MULTI_QUEUE; /* Has multiple TX/RX queues */ + ndev->features |= NETIF_F_LRO; /* large receive offload */ +#endif + + /* setup temac private info structure */ + lp = netdev_priv(ndev); + lp->ndev = ndev; + lp->dev = &op->dev; + lp->options = XTE_OPTION_DEFAULTS; + spin_lock_init(&lp->rx_lock); + mutex_init(&lp->indirect_mutex); + + /* map device registers */ + lp->regs = of_iomap(op->node, 0); + if (!lp->regs) { + dev_err(&op->dev, "could not map temac regs.\n"); + goto nodev; + } + + /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ + np = of_parse_phandle(op->node, "llink-connected", 0); + if (!np) { + dev_err(&op->dev, "could not find DMA node\n"); + goto nodev; + } + + dcrs = dcr_resource_start(np, 0); + if (dcrs == 0) { + dev_err(&op->dev, "could not get DMA register address\n"); + goto nodev;; + } + lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); + dev_dbg(&op->dev, "DCR base: %x\n", dcrs); + + lp->rx_irq = irq_of_parse_and_map(np, 0); + lp->tx_irq = irq_of_parse_and_map(np, 1); + if (!lp->rx_irq || !lp->tx_irq) { + dev_err(&op->dev, "could not determine irqs\n"); + rc = -ENOMEM; + goto nodev; + } + + of_node_put(np); /* Finished with the DMA node; drop the reference */ + + /* Retrieve the MAC address */ + addr = of_get_property(op->node, "local-mac-address", &size); + if ((!addr) || (size != 6)) { + dev_err(&op->dev, "could not find MAC address\n"); + rc = -ENODEV; + goto nodev; + } + temac_set_mac_address(ndev, (void *)addr); + + rc = temac_mdio_setup(lp, op->node); + if (rc) + dev_warn(&op->dev, "error registering MDIO bus\n"); + + lp->phy_node = of_parse_phandle(op->node, "phy-handle", 0); + if (lp->phy_node) + dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np); + + /* Add the device attributes */ + rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group); + if (rc) { + dev_err(lp->dev, "Error creating sysfs files\n"); + goto nodev; + } + + rc = register_netdev(lp->ndev); + if (rc) { + dev_err(lp->dev, "register_netdev() error (%i)\n", rc); + goto err_register_ndev; + } + + return 0; + + err_register_ndev: + sysfs_remove_group(&lp->dev->kobj, &temac_attr_group); + nodev: + free_netdev(ndev); + ndev = NULL; + return rc; +} + +static int __devexit temac_of_remove(struct of_device *op) +{ + struct net_device *ndev = dev_get_drvdata(&op->dev); + struct temac_local *lp = netdev_priv(ndev); + + temac_mdio_teardown(lp); + unregister_netdev(ndev); + sysfs_remove_group(&lp->dev->kobj, &temac_attr_group); + if (lp->phy_node) + of_node_put(lp->phy_node); + lp->phy_node = NULL; + dev_set_drvdata(&op->dev, NULL); + free_netdev(ndev); + return 0; +} + +static struct of_device_id temac_of_match[] __devinitdata = { + { .compatible = "xlnx,xps-ll-temac-1.01.b", }, + {}, +}; +MODULE_DEVICE_TABLE(of, temac_of_match); + +static struct of_platform_driver temac_of_driver = { + .match_table = temac_of_match, + .probe = temac_of_probe, + .remove = __devexit_p(temac_of_remove), + .driver = { + .owner = THIS_MODULE, + .name = "xilinx_temac", + }, +}; + +static int __init temac_init(void) +{ + return of_register_platform_driver(&temac_of_driver); +} +module_init(temac_init); + +static void __exit temac_exit(void) +{ + of_unregister_platform_driver(&temac_of_driver); +} +module_exit(temac_exit); + +MODULE_DESCRIPTION("Xilinx LL_TEMAC Ethernet driver"); +MODULE_AUTHOR("Yoshio Kashiwagi"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/ll_temac_mdio.c b/drivers/net/ll_temac_mdio.c new file mode 100644 index 000000000000..da0e462308d5 --- /dev/null +++ b/drivers/net/ll_temac_mdio.c @@ -0,0 +1,120 @@ +/* + * MDIO bus driver for the Xilinx TEMAC device + * + * Copyright (c) 2009 Secret Lab Technologies, Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ll_temac.h" + +/* --------------------------------------------------------------------- + * MDIO Bus functions + */ +static int temac_mdio_read(struct mii_bus *bus, int phy_id, int reg) +{ + struct temac_local *lp = bus->priv; + u32 rc; + + /* Write the PHY address to the MIIM Access Initiator register. + * When the transfer completes, the PHY register value will appear + * in the LSW0 register */ + mutex_lock(&lp->indirect_mutex); + temac_iow(lp, XTE_LSW0_OFFSET, (phy_id << 5) | reg); + rc = temac_indirect_in32(lp, XTE_MIIMAI_OFFSET); + mutex_unlock(&lp->indirect_mutex); + + dev_dbg(lp->dev, "temac_mdio_read(phy_id=%i, reg=%x) == %x\n", + phy_id, reg, rc); + + return rc; +} + +static int temac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val) +{ + struct temac_local *lp = bus->priv; + + dev_dbg(lp->dev, "temac_mdio_write(phy_id=%i, reg=%x, val=%x)\n", + phy_id, reg, val); + + /* First write the desired value into the write data register + * and then write the address into the access initiator register + */ + mutex_lock(&lp->indirect_mutex); + temac_indirect_out32(lp, XTE_MGTDR_OFFSET, val); + temac_indirect_out32(lp, XTE_MIIMAI_OFFSET, (phy_id << 5) | reg); + mutex_unlock(&lp->indirect_mutex); + + return 0; +} + +int temac_mdio_setup(struct temac_local *lp, struct device_node *np) +{ + struct mii_bus *bus; + const u32 *bus_hz; + int clk_div; + int rc, size; + struct resource res; + + /* Calculate a reasonable divisor for the clock rate */ + clk_div = 0x3f; /* worst-case default setting */ + bus_hz = of_get_property(np, "clock-frequency", &size); + if (bus_hz && size >= sizeof(*bus_hz)) { + clk_div = (*bus_hz) / (2500 * 1000 * 2) - 1; + if (clk_div < 1) + clk_div = 1; + if (clk_div > 0x3f) + clk_div = 0x3f; + } + + /* Enable the MDIO bus by asserting the enable bit and writing + * in the clock config */ + mutex_lock(&lp->indirect_mutex); + temac_indirect_out32(lp, XTE_MC_OFFSET, 1 << 6 | clk_div); + mutex_unlock(&lp->indirect_mutex); + + bus = mdiobus_alloc(); + if (!bus) + return -ENOMEM; + + of_address_to_resource(np, 0, &res); + snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", + (unsigned long long)res.start); + bus->priv = lp; + bus->name = "Xilinx TEMAC MDIO"; + bus->read = temac_mdio_read; + bus->write = temac_mdio_write; + bus->parent = lp->dev; + bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ + + lp->mii_bus = bus; + + rc = of_mdiobus_register(bus, np); + if (rc) + goto err_register; + + mutex_lock(&lp->indirect_mutex); + dev_dbg(lp->dev, "MDIO bus registered; MC:%x\n", + temac_indirect_in32(lp, XTE_MC_OFFSET)); + mutex_unlock(&lp->indirect_mutex); + return 0; + + err_register: + mdiobus_free(bus); + return rc; +} + +void temac_mdio_teardown(struct temac_local *lp) +{ + mdiobus_unregister(lp->mii_bus); + kfree(lp->mii_bus->irq); + mdiobus_free(lp->mii_bus); + lp->mii_bus = NULL; +} + -- GitLab From 434e7b0d12f4e2de6686841a42bd344325b4d756 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 25 Apr 2009 12:53:44 +0000 Subject: [PATCH 0739/6080] net: fix fsl_pq_mdio driver to use module_init() Modules are not supposed to use any of the *_initcall*() hooks as the entry point. fsl_pq_mdio.c was using subsys_initcall_sync() instead of module_init() to guarantee that the MDIO bus was initialized before the Ethernet driver goes looking for the phy. However, the recent OF helpers rework happens to also make sure PHY connection is deferred to .open time, so using an initcall is no longer necessary. This patch replaces the initcall with a more traditional an accepted module_init() call. Tested on Freescale MPC8349emitxgp eval board. Signed-off-by: Grant Likely Signed-off-by: David S. Miller --- drivers/net/fsl_pq_mdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index b01daa1e3adf..d12e0e0336f4 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -415,10 +415,10 @@ int __init fsl_pq_mdio_init(void) { return of_register_platform_driver(&fsl_pq_mdio_driver); } +module_init(fsl_pq_mdio_init); void fsl_pq_mdio_exit(void) { of_unregister_platform_driver(&fsl_pq_mdio_driver); } -subsys_initcall_sync(fsl_pq_mdio_init); module_exit(fsl_pq_mdio_exit); -- GitLab From 29112f4e248ca6941f2233f6ed96a7283a67cced Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 24 Apr 2009 01:58:23 +0000 Subject: [PATCH 0740/6080] bonding: use ethtool for link checking first This patch only changes the order of interfaces to use for checking slave link status in bond_check_dev_link() to priorize ethtool interface. Should safe some troubles as ethtool seems to be more supported. Jirka Signed-off-by: Jiri Pirko drivers/net/bonding/bond_main.c | 26 ++++++++++++-------------- 1 files changed, 12 insertions(+), 14 deletions(-) Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 63369b6b14d4..e4166ee9091d 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -695,6 +695,18 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de if (bond->params.use_carrier) return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0; + /* Try to get link status using Ethtool first. */ + if (slave_dev->ethtool_ops) { + if (slave_dev->ethtool_ops->get_link) { + u32 link; + + link = slave_dev->ethtool_ops->get_link(slave_dev); + + return link ? BMSR_LSTATUS : 0; + } + } + + /* Ethtool can't be used, fallback to MII ioclts. */ ioctl = slave_ops->ndo_do_ioctl; if (ioctl) { /* TODO: set pointer to correct ioctl on a per team member */ @@ -720,20 +732,6 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de } } - /* - * Some drivers cache ETHTOOL_GLINK for a period of time so we only - * attempt to get link status from it if the above MII ioctls fail. - */ - if (slave_dev->ethtool_ops) { - if (slave_dev->ethtool_ops->get_link) { - u32 link; - - link = slave_dev->ethtool_ops->get_link(slave_dev); - - return link ? BMSR_LSTATUS : 0; - } - } - /* * If reporting, report that either there's no dev->do_ioctl, * or both SIOCGMIIREG and get_link failed (meaning that we -- GitLab From 41f8910040639eb106b1a5b5301aab79ecde4940 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 24 Apr 2009 03:57:29 +0000 Subject: [PATCH 0741/6080] bonding: ignore updelay param when there is no active slave Pointed out by Sean E. Millichamp. Quote from Documentation/networking/bonding.txt: "Note that when a bonding interface has no active links, the driver will immediately reuse the first link that goes up, even if the updelay parameter has been specified (the updelay is ignored in this case). If there are slave interfaces waiting for the updelay timeout to expire, the interface that first went into that state will be immediately reused. This reduces down time of the network if the value of updelay has been overestimated, and since this occurs only in cases with no connectivity, there is no additional penalty for ignoring the updelay." This patch actually changes the behaviour in this way. Signed-off-by: Jiri Pirko drivers/net/bonding/bond_main.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e4166ee9091d..fd738367d740 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2247,6 +2247,9 @@ static int bond_miimon_inspect(struct bonding *bond) { struct slave *slave; int i, link_state, commit = 0; + bool ignore_updelay; + + ignore_updelay = !bond->curr_active_slave ? true : false; bond_for_each_slave(bond, slave, i) { slave->new_link = BOND_LINK_NOCHANGE; @@ -2311,6 +2314,7 @@ static int bond_miimon_inspect(struct bonding *bond) ": %s: link status up for " "interface %s, enabling it in %d ms.\n", bond->dev->name, slave->dev->name, + ignore_updelay ? 0 : bond->params.updelay * bond->params.miimon); } @@ -2329,9 +2333,13 @@ static int bond_miimon_inspect(struct bonding *bond) continue; } + if (ignore_updelay) + slave->delay = 0; + if (slave->delay <= 0) { slave->new_link = BOND_LINK_UP; commit++; + ignore_updelay = false; continue; } -- GitLab From 4e204c1000561ddb1a62a9df857cb0457dd868a7 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 23 Apr 2009 15:31:38 +0000 Subject: [PATCH 0742/6080] vxge: fix possible NULL dereference in vxge-traffic.c If vpath is NULL then hldev is NULL also. Signed-off-by: Alexander Beregalov Acked-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-traffic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index 7be0ae10d69b..506625b180ac 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -1923,7 +1923,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( if (vpath == NULL) { alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN, alarm_event); - goto out; + goto out2; } hldev = vpath->hldev; @@ -2161,7 +2161,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( } out: hldev->stats.sw_dev_err_stats.vpath_alarms++; - +out2: if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) || (alarm_event == VXGE_HW_EVENT_UNKNOWN)) return VXGE_HW_OK; -- GitLab From 011983048a120e520147361be1067dd82343038e Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 23 Apr 2009 15:53:21 +0000 Subject: [PATCH 0743/6080] vxge: use max() instead of VXGE_HW_SET_LEVEL Signed-off-by: Alexander Beregalov Acked-by: Ram Vepa Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-traffic.c | 55 ++++++++++++++------------------- drivers/net/vxge/vxge-traffic.h | 2 -- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index 506625b180ac..cf4ebb55273d 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -505,7 +505,7 @@ enum vxge_hw_status vxge_hw_device_begin_irq(struct __vxge_hw_device *hldev, ret = __vxge_hw_vpath_alarm_process( &hldev->virtual_paths[i], skip_alarms); - error_level = VXGE_HW_SET_LEVEL(ret, error_level); + error_level = max(ret, error_level); if (unlikely((ret == VXGE_HW_ERR_CRITICAL) || (ret == VXGE_HW_ERR_SLOT_FREEZE))) @@ -1921,7 +1921,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( struct vxge_hw_vpath_reg __iomem *vp_reg; if (vpath == NULL) { - alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN, + alarm_event = max(VXGE_HW_EVENT_UNKNOWN, alarm_event); goto out2; } @@ -1931,7 +1931,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( alarm_status = readq(&vp_reg->vpath_general_int_status); if (alarm_status == VXGE_HW_ALL_FOXES) { - alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_SLOT_FREEZE, + alarm_event = max(VXGE_HW_EVENT_SLOT_FREEZE, alarm_event); goto out; } @@ -1945,7 +1945,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT)) { sw_stats->error_stats.unknown_alarms++; - alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN, + alarm_event = max(VXGE_HW_EVENT_UNKNOWN, alarm_event); goto out; } @@ -1975,8 +1975,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( &vp_reg->asic_ntwk_vp_err_mask); __vxge_hw_device_handle_link_down_ind(hldev); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_LINK_DOWN, alarm_event); + alarm_event = max(VXGE_HW_EVENT_LINK_DOWN, + alarm_event); } if (((val64 & @@ -1996,15 +1996,15 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( &vp_reg->asic_ntwk_vp_err_mask); __vxge_hw_device_handle_link_up_ind(hldev); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_LINK_UP, alarm_event); + alarm_event = max(VXGE_HW_EVENT_LINK_UP, + alarm_event); } writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->asic_ntwk_vp_err_reg); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); + alarm_event = max(VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event); if (skip_alarms) return VXGE_HW_OK; @@ -2026,8 +2026,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.ini_serr_det++; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_SERR, alarm_event); + alarm_event = max(VXGE_HW_EVENT_SERR, + alarm_event); } if ((val64 & @@ -2035,8 +2035,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.dblgen_fifo0_overflow++; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_FIFO_ERR, alarm_event); + alarm_event = max(VXGE_HW_EVENT_FIFO_ERR, + alarm_event); } if ((val64 & @@ -2057,8 +2057,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( if (!skip_alarms) { writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->general_errors_reg); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event = max(VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); } } @@ -2074,8 +2073,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.kdfcctl_fifo0_overwrite++; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_FIFO_ERR, + alarm_event = max(VXGE_HW_EVENT_FIFO_ERR, alarm_event); } @@ -2084,8 +2082,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.kdfcctl_fifo0_poison++; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_FIFO_ERR, + alarm_event = max(VXGE_HW_EVENT_FIFO_ERR, alarm_event); } @@ -2094,16 +2091,14 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.kdfcctl_fifo0_dma_error++; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_FIFO_ERR, + alarm_event = max(VXGE_HW_EVENT_FIFO_ERR, alarm_event); } if (!skip_alarms) { writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->kdfcctl_errors_reg); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event = max(VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); } } @@ -2127,8 +2122,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.prc_rxdcm_sc_err++; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_VPATH_ERR, + alarm_event = max(VXGE_HW_EVENT_VPATH_ERR, alarm_event); } @@ -2136,8 +2130,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( & ~mask64) { sw_stats->error_stats.prc_rxdcm_sc_abort++; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_VPATH_ERR, + alarm_event = max(VXGE_HW_EVENT_VPATH_ERR, alarm_event); } @@ -2145,16 +2138,14 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( & ~mask64) { sw_stats->error_stats.prc_quanta_size_err++; - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_VPATH_ERR, + alarm_event = max(VXGE_HW_EVENT_VPATH_ERR, alarm_event); } if (!skip_alarms) { writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->prc_alarm_reg); - alarm_event = VXGE_HW_SET_LEVEL( - VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event = max(VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); } } diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h index 7567a1140d07..d03f3d3805c9 100644 --- a/drivers/net/vxge/vxge-traffic.h +++ b/drivers/net/vxge/vxge-traffic.h @@ -110,8 +110,6 @@ enum vxge_hw_event { VXGE_HW_EVENT_SLOT_FREEZE = VXGE_HW_EVENT_BASE + 14, }; -#define VXGE_HW_SET_LEVEL(a, b) (((a) > (b)) ? (a) : (b)) - /* * struct vxge_hw_mempool_dma - Represents DMA objects passed to the caller. -- GitLab From 78b1f6070fa16cb442a7c48e8f5364cd84a88b90 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 23 Apr 2009 11:20:29 +0000 Subject: [PATCH 0744/6080] igb: always use adapter->itr as EITR value The igb driver was switching between adapter->itr containing the EITR value and the number of interrupts per second. This resulted in high latencies being seen after brining the interface down and then back up. To resolve the issue the itr value will now only contain the value that should be programmed into EITR. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 183235d46aee..ab846ec65204 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2898,13 +2898,13 @@ static void igb_set_itr(struct igb_adapter *adapter) switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ case lowest_latency: - new_itr = 70000; + new_itr = 56; /* aka 70,000 ints/sec */ break; case low_latency: - new_itr = 20000; /* aka hwitr = ~200 */ + new_itr = 196; /* aka 20,000 ints/sec */ break; case bulk_latency: - new_itr = 4000; + new_itr = 980; /* aka 4,000 ints/sec */ break; default: break; @@ -2923,7 +2923,8 @@ set_itr_now: * by adding intermediate steps when interrupt rate is * increasing */ new_itr = new_itr > adapter->itr ? - min(adapter->itr + (new_itr >> 2), new_itr) : + max((new_itr * adapter->itr) / + (new_itr + (adapter->itr >> 2)), new_itr) : new_itr; /* Don't write the value here; it resets the adapter's * internal timer, and causes us to delay far longer than @@ -2932,7 +2933,7 @@ set_itr_now: * ends up being correct. */ adapter->itr = new_itr; - adapter->rx_ring->itr_val = 1000000000 / (new_itr * 256); + adapter->rx_ring->itr_val = new_itr; adapter->rx_ring->set_itr = 1; } -- GitLab From fa466e91bdf214e6e136e9da9a46a52775a1e884 Mon Sep 17 00:00:00 2001 From: "Waskiewicz Jr, Peter P" Date: Thu, 23 Apr 2009 11:31:37 +0000 Subject: [PATCH 0745/6080] ixgbe: Disallow SFP 1G modules in the SFP+ cages for 82598 and 82599 82598 and 82599 do not support SFP 1G modules. Instead of allowing the driver to load, but never get link, rejecting the module and displaying a useful message is more preferrable. The framework for displaying the failure message already exists, now we just need to detect and reject the SFP modules. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_phy.c | 22 +++++++++++++++++----- drivers/net/ixgbe/ixgbe_type.h | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index f3258ec901fe..2543c32ca84a 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -673,11 +673,22 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) break; } } - if (hw->mac.type == ixgbe_mac_82598EB || - (hw->phy.sfp_type != ixgbe_sfp_type_sr && - hw->phy.sfp_type != ixgbe_sfp_type_lr && - hw->phy.sfp_type != ixgbe_sfp_type_srlr_core0 && - hw->phy.sfp_type != ixgbe_sfp_type_srlr_core1)) { + + /* All DA cables are supported */ + if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE) { + status = 0; + goto out; + } + + /* 1G SFP modules are not supported */ + if (comp_codes_10g == 0) { + hw->phy.type = ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + goto out; + } + + /* Anything else 82598-based is supported */ + if (hw->mac.type == ixgbe_mac_82598EB) { status = 0; goto out; } @@ -690,6 +701,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) status = 0; } else { hw_dbg(hw, "SFP+ module not supported\n"); + hw->phy.type = ixgbe_phy_sfp_unsupported; status = IXGBE_ERR_SFP_NOT_SUPPORTED; } } else { diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index a3317d8fbf6a..375f0d4ad965 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1904,6 +1904,7 @@ enum ixgbe_phy_type { ixgbe_phy_sfp_ftl, ixgbe_phy_sfp_unknown, ixgbe_phy_sfp_intel, + ixgbe_phy_sfp_unsupported, ixgbe_phy_generic }; -- GitLab From 683703a26e4677db437a1480682851e27c7a154f Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 27 Apr 2009 03:17:31 -0700 Subject: [PATCH 0746/6080] drop_monitor: Update netlink protocol to include netlink attribute header in alert message When I initially implemented this protocol, I disregarded the use of netlink attribute headers, thinking for my purposes they weren't needed. I've come to find out that, as I'm starting to work with sending down messages with associated data (like config messages), the kernel code spits out warnings about trailing data in a netlink skb that doesn't have an associated header on it. As such, I'm going to start including attribute headers in my netlink transaction, and so for completeness, I should likely include them on messages bound from the kernel to user space. This patch adds that header to the kernel, and bumps the protocol version accordingly Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- net/core/drop_monitor.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 9fd0dc3cca99..2797b711a978 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -51,7 +51,7 @@ static struct genl_family net_drop_monitor_family = { .id = GENL_ID_GENERATE, .hdrsize = 0, .name = "NET_DM", - .version = 1, + .version = 2, .maxattr = NET_DM_CMD_MAX, }; @@ -65,13 +65,17 @@ static void reset_per_cpu_data(struct per_cpu_dm_data *data) { size_t al; struct net_dm_alert_msg *msg; + struct nlattr *nla; al = sizeof(struct net_dm_alert_msg); al += dm_hit_limit * sizeof(struct net_dm_drop_point); + al += sizeof(struct nlattr); + data->skb = genlmsg_new(al, GFP_KERNEL); genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family, 0, NET_DM_CMD_ALERT); - msg = __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_alert_msg)); + nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg)); + msg = nla_data(nla); memset(msg, 0, al); atomic_set(&data->dm_hit_count, dm_hit_limit); } @@ -115,6 +119,7 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location) { struct net_dm_alert_msg *msg; struct nlmsghdr *nlh; + struct nlattr *nla; int i; struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); @@ -127,7 +132,8 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location) } nlh = (struct nlmsghdr *)data->skb->data; - msg = genlmsg_data(nlmsg_data(nlh)); + nla = genlmsg_data(nlmsg_data(nlh)); + msg = nla_data(nla); for (i = 0; i < msg->entries; i++) { if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { msg->points[i].count++; @@ -139,6 +145,7 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location) * We need to create a new entry */ __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point)); + nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point)); memcpy(msg->points[msg->entries].pc, &location, sizeof(void *)); msg->points[msg->entries].count = 1; msg->entries++; -- GitLab From 15b8e19131486856373592e45793a79aefb6fbe7 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Thu, 23 Apr 2009 08:53:20 +0000 Subject: [PATCH 0747/6080] pasemi_mac: mac_to_intf() error not noticed mac_to_intf() can return -1 when no device or function is found, but when mac->dma_if is unsigned. The error wasn't noticed. Signed-off-by: Roel Kluin Acked-by: Olof Johansson Signed-off-by: David S. Miller --- drivers/net/pasemi_mac.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 6ea4539085d5..c254a7f5b9f5 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -1733,7 +1733,7 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *dev; struct pasemi_mac *mac; - int err; + int err, ret; err = pci_enable_device(pdev); if (err) @@ -1791,12 +1791,13 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr)); - mac->dma_if = mac_to_intf(mac); - if (mac->dma_if < 0) { + ret = mac_to_intf(mac); + if (ret < 0) { dev_err(&mac->pdev->dev, "Can't map DMA interface\n"); err = -ENODEV; goto out; } + mac->dma_if = ret; switch (pdev->device) { case 0xa005: -- GitLab From 0456b4f8b742006c2b79fcbe6b0736aa1ad39180 Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Mon, 27 Apr 2009 03:22:15 -0700 Subject: [PATCH 0748/6080] cxacru: Fix negative dB output Values of dB between -0.99 and -0.01 will be output with the wrong sign. This converts the negative value to positive and outputs it with a "-" prefix. Signed-off-by: Simon Arlott Signed-off-by: David S. Miller --- drivers/usb/atm/cxacru.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 6789089e2461..56802d2e994b 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -227,8 +227,14 @@ static ssize_t cxacru_sysfs_showattr_s8(s8 value, char *buf) static ssize_t cxacru_sysfs_showattr_dB(s16 value, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d.%02u\n", - value / 100, abs(value) % 100); + if (likely(value >= 0)) { + return snprintf(buf, PAGE_SIZE, "%u.%02u\n", + value / 100, value % 100); + } else { + value = -value; + return snprintf(buf, PAGE_SIZE, "-%u.%02u\n", + value / 100, value % 100); + } } static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf) -- GitLab From f85ba78068ac137fe9c1f50d25405d2783d75c77 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 27 Apr 2009 03:23:54 -0700 Subject: [PATCH 0749/6080] tun: add IFF_TUN_EXCL flag to avoid opening a persistent device. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When creating a certain types of VPN, NetworkManager will first attempt to find an available tun device by iterating through 'vpn%d' until it finds one that isn't already busy. Then it'll set that to be persistent and owned by the otherwise unprivileged user that the VPN dæmon itself runs as. There's a race condition here -- during the period where the vpn%d device is created and we're waiting for the VPN dæmon to actually connect and use it, if we try to create _another_ device we could end up re-using the same one -- because trying to open it again doesn't get -EBUSY as it would while it's _actually_ busy. So solve this, we add an IFF_TUN_EXCL flag which causes tun_set_iff() to fail if it would be opening an existing persistent tundevice -- so that we can make sure we're getting an entirely _new_ device. Signed-off-by: David Woodhouse Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 ++ include/linux/if_tun.h | 1 + 2 files changed, 3 insertions(+) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 589f0ca668d6..94622e5fb936 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -874,6 +874,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) dev = __dev_get_by_name(net, ifr->ifr_name); if (dev) { + if (ifr->ifr_flags & IFF_TUN_EXCL) + return -EBUSY; if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops) tun = netdev_priv(dev); else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops) diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index 049d6c9428db..915ba5789f0e 100644 --- a/include/linux/if_tun.h +++ b/include/linux/if_tun.h @@ -55,6 +55,7 @@ #define IFF_NO_PI 0x1000 #define IFF_ONE_QUEUE 0x2000 #define IFF_VNET_HDR 0x4000 +#define IFF_TUN_EXCL 0x8000 /* Features for GSO (TUNSETOFFLOAD). */ #define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */ -- GitLab From ec9323f417e803f07a99a15a9cfb207662ad2c55 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 27 Apr 2009 03:26:13 -0700 Subject: [PATCH 0750/6080] bnx2x: FW 4.8.53.0 Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- firmware/bnx2x-e1-4.8.53.0.fw.ihex | 10364 ++++++++++++++++++++++ firmware/bnx2x-e1h-4.8.53.0.fw.ihex | 12028 ++++++++++++++++++++++++++ 2 files changed, 22392 insertions(+) create mode 100644 firmware/bnx2x-e1-4.8.53.0.fw.ihex create mode 100644 firmware/bnx2x-e1h-4.8.53.0.fw.ihex diff --git a/firmware/bnx2x-e1-4.8.53.0.fw.ihex b/firmware/bnx2x-e1-4.8.53.0.fw.ihex new file mode 100644 index 000000000000..f1edb1e7ad1b --- /dev/null +++ b/firmware/bnx2x-e1-4.8.53.0.fw.ihex @@ -0,0 +1,10364 @@ +:10000000000028600000006000000630000028C8E2 +:100010000000160800002F000000009400004510AA +:10002000000073C8000045A8000000C40000B978B3 +:100030000000A4680000BA400000007400015EB037 +:100040000000559000015F28000000B80001B4C016 +:100050000000D1F80001B580000000040002878094 +:10006000020400480000000F020400540000004594 +:1000700002040058000000840204005C0000000636 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000060400CC0000000418 +:10010000020400DC00100000020400E012140000F1 +:10011000020400E422140000020400E8321400008B +:10012000060400EC000000040104012400000000AB +:1001300001040128000000000104012C000000005F +:10014000010401300000000002040004000000FF70 +:1001500002040008000000FF0204000C000000FF81 +:1001600002040010000000FF02040014000000FF61 +:1001700002040018000000FF0204001C000000FF41 +:1001800002040020000000FF020400240000003EE2 +:1001900002040028000000000204002C0000003FC0 +:1001A000020400300000003F020400340000003F61 +:1001B00002040038000000000204003C0000003F80 +:1001C000020400400000003F020400440000003F21 +:1001D00002042008000004110204200C00000400A6 +:1001E000020420100000040402042014000004197A +:1001F0000204201C0000FFFF020420200000FFFF7B +:10020000020420240000FFFF020420280000FFFF5A +:1002100006042038000000020204204000000034E0 +:100220000204204400000035060420480000007C41 +:100230000204223807FFFFFF0204223C0000003FB7 +:100240000204224007FFFFFF020422440000000FC7 +:1002500001042248000000000104224C00000000BC +:10026000010422500000000001042254000000009C +:1002700001042258000000000104225C000000007C +:10028000010422600000000001042264000000005C +:1002900001042268000000000104226C000000003C +:1002A000010422700000000001042274000000001C +:1002B00001042278000000000104227C00000000FC +:1002C000020424BC000000010C042000000003E82C +:1002D0000A042000000000010B0420000000000AB6 +:1002E0000205004400000020020500480000003222 +:1002F000020500900215002002050094021500205E +:1003000002050098000000300205009C0810000063 +:10031000020500A000000033020500A40000003028 +:10032000020500A800000031020500AC0000000238 +:10033000020500B000000005020500B40000000640 +:10034000020500B800000002020500BC0000000227 +:10035000020500C000000000020500C40000000506 +:10036000020500C800000002020500CC00000002E7 +:10037000020500D000000002020500D400000001C8 +:1003800002050114000000010205011C000000012B +:100390000205012000000002020502040000000125 +:1003A0000205020C0000004002050210000000409F +:1003B0000205021C000000200205022000000013BC +:1003C0000205022400000020060502400000000A89 +:1003D0000405028000200000020500500000000714 +:1003E0000205005400000007020500580000000844 +:1003F0000205005C00000008060500600000000423 +:10040000020500D800000006020500E00000000D13 +:10041000020500E40000002D020500E800000007CE +:10042000020500EC00000027020500F000000007B4 +:10043000020500F400000027020500F80000000794 +:10044000020500FC00000027020500040000000176 +:1004500002050008000000010205000C0000000178 +:100460000205001000000001020500140000000158 +:1004700002050018000000010205001C0000000138 +:100480000205002000000001020500240000000118 +:1004900002050028000000010205002C00000001F8 +:1004A00002050030000000010205003400000001D8 +:1004B00002050038000000010205003C00000001B8 +:1004C00002050040000000010406100002000020A8 +:1004D000020600DC00000001010600D80000000058 +:1004E0000406020000030220020600DC00000000F7 +:1004F00002060068000000B802060078000001143F +:10050000010600B800000000010600C8000000005D +:100510000206006C000000B80206007C0000011416 +:10052000010600BC00000000010600CC0000000035 +:100530000718040000930000081807600014022345 +:10054000071C0000324F0000071C800033250C946C +:10055000071D00000E4D195E081D1E005C4002259F +:100560000118000000000000011800040000000055 +:1005700001180008000000000118000C0000000035 +:100580000118001000000000011800140000000015 +:1005900002180020000000010218002400000002E0 +:1005A00002180028000000030218002C00000000C0 +:1005B000021800300000000402180034000000019E +:1005C00002180038000000000218003C0000000182 +:1005D000021800400000000402180044000000005F +:1005E00002180048000000010218004C000000033F +:1005F0000218005000000000021800540000000122 +:1006000002180058000000040218005C00000000FE +:1006100002180060000000010218006400000003DE +:1006200002180068000000000218006C00000001C1 +:10063000021800700000000402180074000000009E +:1006400002180078000000040218007C000000037B +:100650000618008000000002021800A400003FFFFE +:10066000021800A8000003FF021802240000000086 +:1006700002180234000000000218024C00000000C2 +:10068000021802E4000000FF061810000000040039 +:10069000021B8BC000000001021B80000000003420 +:1006A000021B804000000018021B80800000000C2C +:1006B000021B80C0000000200C1B83000007A1204B +:1006C0000A1B8300000001380B1B83000000138805 +:1006D000021B83C0000001F4061A2000000000B2D3 +:1006E000061A23C8000000C1041A26CC0001022704 +:1006F000061A1020000000C8061A100000000002B0 +:10070000061A1C1800000004061A1C100000000243 +:10071000061A080000000002061A0808000000027D +:10072000061A081000000004041A1FB00004022872 +:10073000041A4CB00008022C061A22C8000000203F +:10074000061A40000000016C021A4B600000000015 +:10075000061A14000000000A061A145000000006D1 +:10076000061A150000000002041A150800050234DC +:10077000061A151C00000007061A1570000000126A +:10078000061A09C00000004C061A0800000000020A +:10079000061A08200000000E041A1FB000020239D9 +:1007A000061A290800000002061A2348000000204B +:1007B000061A45B00000016C021A4B6400000000EC +:1007C000061A14280000000A061A14680000000621 +:1007D000061A153800000002041A15400005023BF5 +:1007E000061A155400000007061A15B8000000127A +:1007F000061A0AF00000004C061A08080000000261 +:10080000061A08580000000E041A1FB80002024021 +:10081000061A2910000000020200A2800000000158 +:100820000200A294071D29110200A29800000000F6 +:100830000200A29C009C04240200A2A00000000070 +:100840000200A2A4000002090200A4FCFF000000B4 +:10085000020100B400000001020100B80000000124 +:10086000020100DC000000010201010000000001A3 +:1008700002010104000000010201007C00300000C0 +:1008800002010084000000280201008C000000002A +:1008900002010130000000040201025C00000001BE +:1008A000020103280000000002010554000000308E +:1008B000020100C400000001020100CC00000001A0 +:1008C000020100F800000001020100F00000000138 +:1008D00002010080003000000201008800000028B2 +:1008E0000201009000000000020101340000000439 +:1008F000020102DC000000010201032C00000000E4 +:100900000201056400000030020100C8000000017F +:10091000020100D000000001020100FC0000000103 +:10092000020100F400000001020C10000000002091 +:10093000020C200800000A11020C200C00000A0022 +:10094000020C201000000A04020C201C0000FFFF13 +:10095000020C20200000FFFF020C20240000FFFFFB +:10096000020C20280000FFFF020C2038000000C607 +:10097000020C203C00000000020C2040000000346B +:10098000020C204400000035060C20480000001C2A +:10099000020C20B800000001060C20BC0000005F23 +:1009A000020C223807FFFFFF020C223C0000003F30 +:1009B000020C224007FFFFFF020C22440000000F40 +:1009C000010C224800000000010C224C0000000035 +:1009D000010C225000000000010C22540000000015 +:1009E000010C225800000000010C225C00000000F5 +:1009F000010C226000000000010C226400000000D5 +:100A0000010C226800000000010C226C00000000B4 +:100A1000010C227000000000010C22740000000094 +:100A2000010C227800000000010C227C0000000074 +:100A3000020C24BC000000010C0C2000000003E8A4 +:100A40000A0C2000000000010B0C20000000000A2E +:100A5000020C400800000A11020C400C00000A00C1 +:100A6000020C401000000A04020C401400000A218D +:100A7000020C401C0000FFFF020C40200000FFFFA2 +:100A8000020C40240000FFFF020C40280000FFFF82 +:100A9000020C403800000046020C403C00000005FB +:100AA000020C404000000034020C404400000035BD +:100AB000060C40480000005C020C41B80000000138 +:100AC000060C41BC0000001F020C423807FFFFFF6C +:100AD000020C423C0000003F020C424007FFFFFFB7 +:100AE000020C42440000000F010C424800000000CC +:100AF000010C424C00000000010C425000000000BC +:100B0000010C425400000000010C4258000000009B +:100B1000010C425C00000000010C4260000000007B +:100B2000010C426400000000010C4268000000005B +:100B3000010C426C00000000010C4270000000003B +:100B4000010C427400000000010C4278000000001B +:100B5000010C427C00000000010C428000000000FB +:100B6000020C44C0000000010C0C4000000003E82F +:100B70000A0C4000000000010B0C40000000000ABD +:100B8000020D004400000032020D008C021500200E +:100B9000020D009002150020020D009408100000C4 +:100BA000020D009800000033020D009C00000002BE +:100BB000020D00A000000000020D00A400000005CE +:100BC000020D00A800000005060D00AC00000002A8 +:100BD000020D00B400000002020D00B80000000386 +:100BE000020D00BC00000002020D00C00000000168 +:100BF000020D00C800000002020D00CC000000023F +:100C0000020D010800000001020D015C000000015E +:100C1000020D016400000001020D016800000002E5 +:100C2000020D020400000001020D020C0000002071 +:100C3000020D021000000040020D021400000040EE +:100C4000020D022000000003020D02240000001823 +:100C5000060D028000000012040D03000024024271 +:100C6000020D004C00000001020D005000000002C7 +:100C7000020D005400000008020D0058000000089A +:100C8000060D005C00000004020D00C4000000041A +:100C9000020D011400000009020D011800000029D6 +:100CA000020D011C0000000A020D01200000002AB4 +:100CB000020D012400000007020D0128000000279A +:100CC000020D012C00000007020D0130000000277A +:100CD000020D01340000000C020D01380000002C50 +:100CE000020D013C0000000C020D01400000002C30 +:100CF000020D01440000000C020D01480000002C10 +:100D0000020D000400000001020D000800000001B7 +:100D1000020D000C00000001020D00100000000197 +:100D2000020D001400000001020D00180000000177 +:100D3000020D001C00000001020D00200000000157 +:100D4000020D002400000001020D00280000000137 +:100D5000020D002C00000001020D00300000000117 +:100D6000020D003400000001020D003800000001F7 +:100D7000020D003C00000001020E004C0000003299 +:100D8000020E009402150020020E009802150020A9 +:100D9000020E009C00000030020E00A008100000AF +:100DA000020E00A400000033020E00A80000003074 +:100DB000020E00AC00000031020E00B00000000284 +:100DC000020E00B400000004020E00B80000000093 +:100DD000020E00BC00000002020E00C00000000273 +:100DE000020E00C400000000020E00C80000000255 +:100DF000020E00CC00000007020E00D0000000022E +:100E0000020E00D400000002020E00D80000000113 +:100E1000020E00E400000001020E01440000000187 +:100E2000020E014C00000001020E01500000000201 +:100E3000020E020400000001020E020C000000403D +:100E4000020E021000000040020E021C000000040E +:100E5000020E022000000020020E02240000000EFC +:100E6000020E02280000001B060E03000000001204 +:100E7000040E0280001B0266020E005400000010E7 +:100E8000020E005800000007020E005C0000000F78 +:100E9000020E006000000010060E00640000000456 +:100EA000020E00DC00000003020E01100000000F23 +:100EB000020E01140000002F020E01180000000EA7 +:100EC000020E011C0000002E020E000400000001B2 +:100ED000020E000800000001020E000C00000001DC +:100EE000020E001000000001020E001400000001BC +:100EF000020E001800000001020E001C000000019C +:100F0000020E002000000001020E0024000000017B +:100F1000020E002800000001020E002C000000015B +:100F2000020E003000000001020E0034000000013B +:100F3000020E003800000001020E003C000000011B +:100F4000020E004000000001020E004400000001FB +:100F50000730040000C30000083007680013028156 +:100F600007340000314C00000734800035EF0C548A +:100F700007350000361319D00735800007112755B3 +:100F800008358EE04E24028301300000000000008E +:100F900001300004000000000130000800000000E3 +:100FA0000130000C000000000130001000000000C3 +:100FB0000130001400000000023000200000000199 +:100FC000023000240000000202300028000000036C +:100FD0000230002C0000000002300030000000044D +:100FE0000230003400000001023000380000000030 +:100FF0000230003C0000000102300040000000040C +:1010000002300044000000000230004800000001EF +:101010000230004C000000030230005000000000CD +:1010200002300054000000010230005800000004AB +:101030000230005C0000000002300060000000018F +:10104000023000640000000302300068000000006D +:101050000230006C0000000102300070000000044B +:10106000023000740000000002300078000000042C +:101070000230007C00000003063000800000000207 +:10108000023000A400003FFF023000A8000003FF70 +:101090000230022400000000023002340000000090 +:1010A0000230024C00000000023002E40000FFFFAA +:1010B000063020000000080002338BC00000000151 +:1010C000023380000000001A023380400000004E0E +:1010D0000233808000000010023380C00000002036 +:1010E0000C3383000007A1200A338300000001387D +:1010F0000B33830000001388023383C0000001F427 +:101100000C3383801DCD65000A3383800004C4B492 +:101110000B338380004C4B4006325000000000C26D +:1011200006321020000000C8063210000000000245 +:101130000632464000000040063257F0000000042E +:10114000063257D800000005043257EC0001028532 +:1011500006321C60000000200432283000020286A3 +:10116000023308000100000004330C000010028864 +:10117000023308000000000004330C400010029805 +:1011800006321400000000A0063219000000001012 +:10119000063219800000003006324740000000B4DB +:1011A00002321D900000000006321B4000000004C7 +:1011B00006321B6000000020063253180000009821 +:1011C00006321680000000A0063219400000001010 +:1011D00006321A400000003006324A10000000B407 +:1011E00002321D940000000006321B500000000473 +:1011F00006321BE0000000200632557800000098FF +:10120000072004000071000008200780001002A8D9 +:1012100007240000322900000724800023630C8B80 +:101220000824C930654002AA012000000000000027 +:101230000120000400000000012000080000000060 +:101240000120000C00000000012000100000000040 +:101250000120001400000000022000200000000116 +:1012600002200024000000020220002800000003E9 +:101270000220002C000000000220003000000004CA +:1012800002200034000000010220003800000000AD +:101290000220003C00000001022000400000000489 +:1012A000022000440000000002200048000000016D +:1012B0000220004C0000000302200050000000004B +:1012C0000220005400000001022000580000000429 +:1012D0000220005C0000000002200060000000010D +:1012E00002200064000000030220006800000000EB +:1012F0000220006C000000010220007000000004C9 +:1013000002200074000000000220007800000004A9 +:101310000220007C00000003062000800000000284 +:10132000022000A400003FFF022000A8000003FFED +:10133000022002240000000002200234000000000D +:101340000220024C00000000022002E40000FFFF27 +:10135000062020000000080002238BC000000001CE +:1013600002238000000000100223804000000012D1 +:101370000223808000000030022380C00000000EA5 +:10138000022383C0000001F4062250000000004246 +:1013900006221020000000C80622100000000002F3 +:1013A00006222000000000C00622307000000080ED +:1013B0000622428000000004062225C000000240F0 +:1013C00004222EC8000802AC02230800013FFFFFE0 +:1013D00004230C00001002B40223080000000000E7 +:1013E00004230C40001002C406221400000000A0D8 +:1013F00006221900000000100622198000000030AB +:101400000222511800000000062223000000000EF6 +:1014100006223040000000060622241000000030A2 +:1014200006221680000000A00622194000000010CD +:1014300006221A40000000300222511C0000000069 +:10144000062223380000000E062230580000000655 +:10145000062224D0000000300216100000000020F8 +:1014600002170008000000020217002C0000000311 +:101470000217003C000000040217004400000008AE +:1014800002170048000000020217004C0000009004 +:1014900002170050000000900217005400800090D6 +:1014A0000217005808140000021700600000008AAC +:1014B000021700640000008002170068000000901E +:1014C0000217006C00000080021700700000000688 +:1014D00002170078000007D00217007C0000076C9C +:1014E00002170038007C1004021700040000000FEF +:1014F0000616402400000002021640700000001C86 +:10150000021642080000000102164210000000010D +:1015100002164220000000010216422800000001CD +:10152000021642300000000102164238000000019D +:1015300002164260000000010C16401C0003D0900F +:101540000A16401C0000009C0B16401C000009C439 +:101550000216403000000008021640340000000C63 +:10156000021640380000001002164044000000201F +:101570000216400000000001021640D800000001E1 +:1015800002164008000000010216400C0000000195 +:101590000216401000000001021642400000000048 +:1015A00002164248000000000616427000000002C9 +:1015B00002164250000000000216425800000000CF +:1015C00006164280000000020216600800000614A1 +:1015D0000216600C000006000216601000000604EF +:1015E0000216601C0000FFFF021660200000FFFFD3 +:1015F000021660240000FFFF021660280000FFFFB3 +:1016000002166038000000200216603C0000002036 +:1016100002166040000000340216604400000035ED +:1016200002166048000000230216604C00000024EF +:1016300002166050000000250216605400000026CB +:1016400002166058000000270216605C00000029A6 +:10165000021660600000002A021660640000002B81 +:10166000021660680000002C0216606C0000002D5D +:101670000616607000000052021661B800000001FA +:10168000061661BC0000001F0216623807FFFFFF4C +:101690000216623C0000003F0216624007FFFFFF97 +:1016A000021662440000000F0116624800000000AC +:1016B0000116624C0000000001166250000000009C +:1016C000011662540000000001166258000000007C +:1016D0000116625C0000000001166260000000005C +:1016E000011662640000000001166268000000003C +:1016F0000116626C0000000001166270000000001C +:1017000001166274000000000116627800000000FB +:101710000116627C00000000021664BC000000019B +:101720000C166000000003E80A16600000000001CB +:101730000B1660000000000A021680400000000640 +:101740000216804400000005021680480000000ACE +:101750000216804C000000050216805400000002B2 +:10176000021680CC00000004021680D000000004A5 +:10177000021680D400000004021680D80000000485 +:10178000021680DC00000004021680E00000000465 +:10179000021680E400000004021680E80000000445 +:1017A0000216880400000004021680300000007C4D +:1017B000021680340000003D021680380000003F11 +:1017C0000216803C0000009C021680F0000000071A +:1017D000061680F4000000050216880C01010101C4 +:1017E00002168108000000000216810C00000004AF +:1017F000021681100000000402168114000000028D +:101800000216881008012004021681180000000545 +:101810000216811C00000005021681200000000550 +:1018200002168124000000050216882C20081001F1 +:1018300002168128000000080216812C0000000614 +:1018400002168130000000070216813400000000FB +:1018500002168830010101200616813800000004BC +:1018600002168834010101010616814800000004B7 +:101870000216883801010101061681580000000493 +:101880000216883C01010101061681680000000370 +:101890000216817400000001021688400101010156 +:1018A00002168178000000010216817C0000000110 +:1018B00002168180000000010216818400000001F0 +:1018C000021688440101010102168188000000010E +:1018D0000216818C000000040216819000000004B2 +:1018E00002168194000000020216884808012004B4 +:1018F00002168198000000050216819C0000000578 +:10190000021681A000000005021681A40000000557 +:101910000216881420081001021681A80000000891 +:10192000021681AC00000006021681B0000000071C +:10193000021681B40000000102168818010101207E +:10194000021681B800000001021681BC00000001EF +:10195000021681C000000001021681C400000001CF +:101960000216881C01010101021681C80000000155 +:10197000021681CC00000001021681D00000000197 +:10198000021681D400000001021688200101010125 +:10199000021681D800000001021681DC000000015F +:1019A000021681E000000001021681E4000000013F +:1019B0000216882401010101021681E800000001DD +:1019C000021681EC00000001021681F00000000107 +:1019D000021688280101010102168240FFFF003F24 +:1019E00006168244000000020216824CFFFF003FF0 +:1019F000021682500000010002168254000001000D +:101A0000061682580000000202168260000000C024 +:101A100002168264000000C00216826800001E00E8 +:101A20000216826C00001E00021682700000400048 +:101A300002168274000040000216827800008000C6 +:101A40000216827C000080000216828000002000C6 +:101A5000021682840000200006168288000000071B +:101A6000021682A400000001061682A80000000AE7 +:101A7000021681F400000C08021681F800000040F4 +:101A8000021681FC00000100021682000000002006 +:101A9000021682040000001702168208000000806F +:101AA0000216820C000002000216821000000000E4 +:101AB00002168218FFFF01FF02168214FFFF01FFCA +:101AC0000216823C00000013021680900000013FC5 +:101AD0000216806000000140021680640000014090 +:101AE000061680680000000202168070000000C028 +:101AF00006168074000000070216809C0000004853 +:101B0000021680A000000048061680A40000000213 +:101B1000021680AC00000048061680B000000007E6 +:101B2000021682380000800002168234000025E48C +:101B30000216809400007FFF02168220000000073A +:101B40000216821C00000007021682280000000016 +:101B500002168224FFFFFFFF021682300000000001 +:101B60000216822CFFFFFFFF021680EC000000FF30 +:101B700002140000000000010214000C000000012B +:101B800002140040000000010214004400007FFF26 +:101B90000214000C0000000002140000000000000D +:101BA0000214006C00000000021400040000000198 +:101BB00002140030000000010214000400000000C4 +:101BC0000214005C00000000021400080000000184 +:101BD000021400340000000102140008000000009C +:101BE00002140060000000000202005800000032F1 +:101BF000020200A003150020020200A40315002029 +:101C0000020200A801000030020200AC081000002F +:101C1000020200B000000033020200B400000030F5 +:101C2000020200B800000031020200BC0000000304 +:101C3000020200C000000006020200C4000000030F +:101C4000020200C800000003020200CC00000002F3 +:101C5000020200D000000000020200D400000002D6 +:101C6000020200DC00000000020200E000000006AA +:101C7000020200E400000004020200E8000000028A +:101C8000020200EC00000002020200F0000000016D +:101C9000020200FC00000006020201200000000019 +:101CA0000202013400000002020201B00000000143 +:101CB0000202020C000000010202021400000001F6 +:101CC00002020218000000020202040400000001E7 +:101CD0000202040C00000040020204100000004058 +:101CE0000202041C00000004020204200000002084 +:101CF0000202042400000002020204280000001F67 +:101D0000060205000000001204020480001F02D435 +:101D1000020200600000000F0202006400000007E1 +:101D2000020200680000000B0202006C0000000EBE +:101D30000602007000000004020200F4000000042B +:101D4000020200040000000102020008000000017D +:101D50000202000C0000000102020010000000015D +:101D6000020200140000000102020018000000013D +:101D70000202001C0000000102020020000000011D +:101D800002020024000000010202002800000001FD +:101D90000202002C000000010202003000000001DD +:101DA00002020034000000010202003800000001BD +:101DB0000202003C0000000102020040000000019D +:101DC000020200440000000102020048000000017D +:101DD0000202004C0000000102020050000000015D +:101DE00002020108000000C80202011800000002FF +:101DF000020201C400000000020201CC0000000049 +:101E0000020201D400000002020201DC0000000214 +:101E1000020201E4000000FF020201EC000000FFEA +:101E20000202010C000000C80202011C00000002B6 +:101E3000020201C800000000020201D00000000000 +:101E4000020201D800000002020201E000000002CC +:101E5000020201E8000000FF020201F0000000FFA2 +:101E60000728040000B5000008280768001302F3E3 +:101E7000072C000033660000072C800038B30CDA12 +:101E8000072D00003BB11B07072D80002A2629F4EF +:101E9000082DD6C0452802F50128000000000000EA +:101EA00001280004000000000128000800000000D4 +:101EB0000128000C000000000128001000000000B4 +:101EC000012800140000000002280020000000018A +:101ED000022800240000000202280028000000035D +:101EE0000228002C0000000002280030000000043E +:101EF0000228003400000001022800380000000021 +:101F00000228003C000000010228004000000004FC +:101F100002280044000000000228004800000001E0 +:101F20000228004C000000030228005000000000BE +:101F3000022800540000000102280058000000049C +:101F40000228005C00000000022800600000000180 +:101F5000022800640000000302280068000000005E +:101F60000228006C0000000102280070000000043C +:101F7000022800740000000002280078000000041D +:101F80000228007C000000030628008000000002F8 +:101F9000022800A400003FFF022800A8000003FF61 +:101FA0000228022400000000022802340000000081 +:101FB0000228024C00000000022802E40000FFFF9B +:101FC0000628200000000800022B8BC00000000142 +:101FD000022B800000000000022B8040000000184F +:101FE000022B80800000000C022B80C000000066E5 +:101FF0000C2B83000007A1200A2B8300000001386E +:102000000B2B830000001388022B83C0000001F417 +:102010000C2B8340000001F40A2B834000000000D9 +:102020000B2B8340000000050A2B83800004C4B4FE +:102030000C2B83801DCD65000B2B8380004C4B4007 +:10204000062A3D6000000004042A3D70000202F7E9 +:10205000062A300000000048062A1020000000C8B0 +:10206000062A100000000002062A31280000008E17 +:10207000022A336800000000042A3370000202F9CB +:10208000042A3B90000402FB042A3E20000202FFC7 +:10209000022A151800000001022A18300000000072 +:1020A000022A183800000000042A18200002030148 +:1020B000062A4AC000000002062A4B000000000465 +:1020C000042A1F4800020303022B0800000000003E +:1020D000042B0C0000100305022B08000100000077 +:1020E000042B0C4000080315022B0800020000001E +:1020F000042B0C600008031D062A3BA000000014FE +:10210000062A3C4000000024062A14000000000AB1 +:10211000062A145000000006062A3378000000FC4E +:10212000022A3B5800000000042A3D7800020325E3 +:10213000042A3D8800100327022A15000000000031 +:10214000022A150800000001062A502000000002A3 +:10215000062A503000000002062A5000000000024B +:10216000062A501000000002022A50400000000021 +:10217000062A50480000000E022A50B80000000154 +:10218000042A4AC800020337062A4B100000004206 +:10219000062A4D2000000004062A3BF0000000142F +:1021A000062A3CD000000024062A14280000000A59 +:1021B000062A146800000006062A3768000000FCA2 +:1021C000022A3B5C00000000042A3D800002033923 +:1021D000042A3DC80010033B022A15040000000039 +:1021E000022A150C00000001062A502800000002F7 +:1021F000062A503800000002062A5008000000029B +:10220000062A501800000002022A50440000000074 +:10221000062A50800000000E022A50BC0000000177 +:10222000042A4AD00002034B062A4C180000004240 +:10223000062A4D30000000040210100800000001C2 +:10224000021010000003D000021010040000003D36 +:10225000091018000200034D091011000020054D5F +:102260000610118000000002091011880006056D9B +:10227000061011A00000001806102400000000E065 +:102280000210201C000000000210202000000001AD +:10229000021020C000000001021020040000000114 +:1022A000021020080000000109103C000005057321 +:1022B00009103C2000050578091038000005057D4F +:1022C00002104028000000100210404400003FFFB0 +:1022D0000210405800280000021040840084924AF6 +:1022E0000210405800000000061080680000000442 +:1022F00002108000000010800610802800000002FC +:102300000210803800000010021080400000FFFF23 +:10231000021080440000FFFF021080500000000007 +:102320000210810000000000061081200000000261 +:1023300002108008000002B50210801000000000AA +:10234000061082000000004A021081080001FFFF11 +:1023500006108140000000020210800000001A8078 +:102360000610900000000024061091200000004A92 +:10237000061093700000004A061095C00000004A45 +:10238000021080040000108006108030000000025F +:102390000210803C00000010021080480000FFFF87 +:1023A0000210804C0000FFFF02108054000000006B +:1023B00002108104000000000610812800000002C5 +:1023C0000210800C000002B5021080140000000012 +:1023D000061084000000004A0210810C0001FFFF7B +:1023E00006108148000000020210800400001A80DC +:1023F0000610909000000024061092480000004A49 +:10240000061094980000004A061096E80000004A62 +:102410000212049000E383400212051400003C10F5 +:1024200002120494FFFFFFFF02120498FFFFFFFF58 +:102430000212049CFFFFFFFF021204A0FFFFFFFF38 +:10244000021204A4FFFFFFFF021204A8FFFFFFFF18 +:10245000021204ACFFFFFFFF021204B0FFFFFFFFF8 +:10246000021204B8FFFFFFFF021204BCFFFFFFFFD0 +:10247000021204C0FFFFFFFF021204C4FFFFFFFFB0 +:10248000021204C8FFFFFFFF021204CCFFFFFFFF90 +:10249000021204D0FFFFFFFF021204DCFFFFFFFF68 +:1024A000021204E0FFFFFFFF021204E4FFFFFFFF40 +:1024B000021204E8FFFFFFFF021204ECFFFFFFFF20 +:1024C000021204F0FFFFFFFF021204F4FFFFFFFF00 +:1024D000021204F8FFFFFFFF021204FCFFFFFFFFE0 +:1024E00002120500FFFFFFFF02120504FFFFFFFFBE +:1024F00002120508FFFFFFFF0212050CFFFFFFFF9E +:1025000002120510FFFFFFFF021204D4FFFF333059 +:10251000021204D8FFFF3340021204B4F00030006E +:1025200002120390000000080212039C0000000841 +:10253000021203A000000008021203A4000000021F +:10254000021203BC00000004021203C000000005D8 +:10255000021203C400000004021203D000000000B5 +:102560000212036C00000001021203680000003F29 +:10257000021201BC00000040021201C00000180855 +:10258000021201C400000803021201C8000008037F +:10259000021201CC00000040021201D00000000332 +:1025A000021201D400000803021201D8000008033F +:1025B000021201DC00000803021201E00001000326 +:1025C000021201E400000803021201E800000803FF +:1025D000021201EC00000003021201F000000003EF +:1025E000021201F400000003021201F800000003CF +:1025F000021201FC000000030212020000000003AE +:10260000021202040000000302120208000000038C +:102610000212020C0000000302120210000000036C +:10262000021202140000000302120218000000034C +:102630000212021C0000000302120220000000032C +:1026400002120224000000030212022800002403E8 +:102650000212022C0000002F0212023000000009BA +:102660000212023400000019021202380000018434 +:102670000212023C00000183021202400000030625 +:102680000212024400000019021202480000000673 +:102690000212024C00000306021202500000030660 +:1026A00002120254000003060212025800000C86B7 +:1026B0000212025C00000306021202600000030620 +:1026C0000212026400000006021202680000000606 +:1026D0000212026C000000060212027000000006E6 +:1026E00002120274000000060212027800000006C6 +:1026F0000212027C000000060212028000000006A6 +:102700000212028400000006021202880000000685 +:102710000212028C00000006021202900000000665 +:102720000212029400000006021202980000000645 +:102730000212029C00000006021202A00000030622 +:10274000021202A400000013021202A800000006F8 +:10275000021202B000001004021202B400001004C1 +:102760000212032400106440021203280010644087 +:10277000021201B0000000010600A00000000016D7 +:102780000200A06CBF5C00000200A070FFF51FEF0C +:102790000200A0740000FFFF0200A078500003E0D8 +:1027A0000200A07C000000000200A0800000A00049 +:1027B0000600A084000000050200A0980FE00000C1 +:1027C0000600A09C000000140200A0EC555400007C +:1027D0000200A0F0555555550200A0F400005555D3 +:1027E0000200A0F8000000000200A0FC5554000008 +:1027F0000200A100555555550200A1040000555591 +:102800000200A108000000000200A22C000000004D +:102810000600A230000000030200A06000000007D4 +:102820000200A10CBF5C00000200A110FFF51FEF29 +:102830000200A1140000FFFF0200A118500003E0F5 +:102840000200A11C000000000200A1200000A00066 +:102850000600A124000000050200A1380FE00000DE +:102860000600A13C000000140200A18C5554000099 +:102870000200A190555555550200A19400005555F0 +:102880000200A198000000000200A19C5554000025 +:102890000200A1A0555555550200A1A400005555B0 +:1028A0000200A1A8000000000200A23C00000000FD +:1028B0000600A240000000030200A0640000000720 +:1028C00000000000000000000000002E00000000DA +:1028D00000000000000000000000000000000000F8 +:1028E00000000000000000000000000000000000E8 +:1028F00000000000000000000000000000000000D8 +:1029000000000000000000000000000000000000C7 +:1029100000000000000000000000000000000000B7 +:10292000002E005000000000000000000000000029 +:102930000000000000000000000000000000000097 +:102940000000000000000000000000000050008DAA +:102950000000000000000000000000000000000077 +:102960000000000000000000000000000000000067 +:102970000000000000000000008D00920092009610 +:102980000096009A00000000000000000000000017 +:102990000000000000000000000000000000000037 +:1029A00000000000009A00DB00DB00E900E900F70E +:1029B0000000000000000000000000000000000017 +:1029C0000000000000000000000000000000000007 +:1029D00000000000000000000000000000000000F7 +:1029E00000000000000000000000000000000000E7 +:1029F00000000000000000000000000000000000D7 +:102A000000000000000000000000000000000000C6 +:102A100000000000000000000000000000000000B6 +:102A200000000000000000000000000000000000A6 +:102A30000000000000000000000000000000000096 +:102A40000000000000000000000000000000000086 +:102A50000000000000000000000000000000000076 +:102A60000000000000000000000000000000000066 +:102A70000000000000000000000000000000000056 +:102A800000F700FE00000000000000000000000051 +:102A90000000000000000000000000000000000036 +:102AA0000000000000000000000000000000000026 +:102AB0000000000000000000000000000000000016 +:102AC0000000000000000000000000000000000006 +:102AD000000000000000000000FE01030103010EE1 +:102AE000010E0119000000000000000000000000BD +:102AF00000000000000000000000000000000000D6 +:102B000000000000000000000000000000000000C5 +:102B100000000000000000000000000000000000B5 +:102B200000000000000000000000000000000000A5 +:102B30000119011A00000000000000000000000060 +:102B40000000000000000000000000000000000085 +:102B5000000000000000000000000000011A013E1B +:102B60000000000000000000000000000000000065 +:102B70000000000000000000000000000000000055 +:102B80000000000000000000013E016400000000A1 +:102B90000000000000000000000000000000000035 +:102BA0000000000000000000000000000000000025 +:102BB00000000000016401A300000000000000000C +:102BC0000000000000000000000000000000000005 +:102BD00000000000000000000000000000000000F5 +:102BE00001A301DE00000000000000000000000062 +:102BF00000000000000000000000000000000000D5 +:102C000000000000000000000000000001DE0224BF +:102C10000224022C022C02340000000000000000FC +:102C200000000000000000000000000000000000A4 +:102C300000000000000000000234027102710278FE +:102C40000278027F00000000000000000000000089 +:102C50000000000000000000000000000000000074 +:102C600000000000027F0280000000000000000061 +:102C70000000000000000000000000000000000054 +:102C80000000000000000000000000000000000044 +:102C9000028002920000000000000000000000001E +:102CA0000000000000000000000000000000000024 +:102CB000000000000000000000000000029202A7D7 +:102CC00002A702AA02AA02AD000000000000000054 +:102CD00000000000000000000000000000000000F4 +:102CE000000000000000000002AD02DB0000000058 +:102CF00000000000000000000000000000000000D4 +:102D000000000000000000000000000000000000C3 +:102D10000000000002DB0362000000000000000071 +:102D200000000000000000000000000000000000A3 +:102D30000000000000000000000000000000000093 +:102D4000036203690369036D036D037100000000F2 +:102D50000000000000000000000000000000000073 +:102D6000000000000000000000000000037103B03C +:102D700003B003B803B803C0000000000000000067 +:102D80000000000000000000000000000000000043 +:102D9000000000000000000003C004130413042717 +:102DA0000427043B000000000000000000000000B9 +:102DB0000000000000000000000000000000000013 +:102DC00000000000043B044300000000000000007D +:102DD00000000000000000000000000000000000F3 +:102DE00000000000000000000000000000000000E3 +:102DF000044304490000000000000000000000003F +:102E000000000000000000000000000000000000C2 +:102E10000000000000000000000000000449044C15 +:102E200000000000000000000000000000000000A2 +:102E30000000000000000000000000000000000092 +:102E40000000000000000000044C045100000000DD +:102E50000000000000000000000000000000000072 +:102E60000000000000000000000000000000000062 +:102E70000000000004510452045204640464047607 +:102E80000000000000000000000000000000000042 +:102E90000000000000000000000000000000000032 +:102EA000047604E3000000000000000000000000C1 +:102EB0000000000000000000000000000000000012 +:102EC00000000000000000000000000004E304E433 +:102ED00004E404F804F8050C000000000000000001 +:102EE00000000000000000000000000000000000E2 +:102EF00000000000000000000000000000000000D2 +:102F000000010000000204C00003098000040E401C +:102F100000051300000617C000071C8000082140B0 +:102F200000092600000A2AC0000B2F80000C344044 +:102F3000000D3900000E3DC0000F428000104740D8 +:102F400000114C00001250C00013558000145A406C +:102F500000155F00001663C00017688000186D4000 +:102F600000197200001A76C0001B7B80001C804094 +:102F7000001D8500001E89C0001F8E800020934028 +:102F80000000200000004000000060000000800001 +:102F90000000A0000000C0000000E00000010000F0 +:102FA00000012000000140000001600000018000DD +:102FB0000001A0000001C0000001E00000020000CC +:102FC00000022000000240000002600000028000B9 +:102FD0000002A0000002C0000002E00000030000A8 +:102FE0000003200000034000000360000003800095 +:102FF0000003A0000003C0000003E0000004000084 +:103000000004200000044000000460000004800070 +:103010000004A0000004C0000004E000000500005F +:10302000000520000005400000056000000580004C +:103030000005A0000005C0000005E000000600003B +:103040000006200000064000000660000006800028 +:103050000006A0000006C0000006E0000007000017 +:103060000007200000074000000760000007800004 +:103070000007A0000007C0000007E00000080000F3 +:1030800000082000000840000008600000088000E0 +:103090000008A0000008C0000008E00000090000CF +:1030A00000092000000940000009600000098000BC +:1030B0000009A0000009C0000009E000000A0000AB +:1030C000000A2000000A4000000A6000000A800098 +:1030D000000AA000000AC000000AE000000B000087 +:1030E000000B2000000B4000000B6000000B800074 +:1030F000000BA000000BC000000BE000000C000063 +:10310000000C2000000C4000000C6000000C80004F +:10311000000CA000000CC000000CE000000D00003E +:10312000000D2000000D4000000D6000000D80002B +:10313000000DA000000DC000000DE000000E00001A +:10314000000E2000000E4000000E6000000E800007 +:10315000000EA000000EC000000EE000000F0000F6 +:10316000000F2000000F4000000F6000000F8000E3 +:10317000000FA000000FC000000FE00000100000D2 +:1031800000102000001040000010600000108000BF +:103190000010A0000010C0000010E00000110000AE +:1031A000001120000011400000116000001180009B +:1031B0000011A0000011C0000011E000001200008A +:1031C0000012200000124000001260000012800077 +:1031D0000012A0000012C0000012E0000013000066 +:1031E0000013200000134000001360000013800053 +:1031F0000013A0000013C0000013E0000014000042 +:10320000001420000014400000146000001480002E +:103210000014A0000014C0000014E000001500001D +:10322000001520000015400000156000001580000A +:103230000015A0000015C0000015E00000160000F9 +:1032400000162000001640000016600000168000E6 +:103250000016A0000016C0000016E00000170000D5 +:1032600000172000001740000017600000178000C2 +:103270000017A0000017C0000017E00000180000B1 +:10328000001820000018400000186000001880009E +:103290000018A0000018C0000018E000001900008D +:1032A000001920000019400000196000001980007A +:1032B0000019A0000019C0000019E000001A000069 +:1032C000001A2000001A4000001A6000001A800056 +:1032D000001AA000001AC000001AE000001B000045 +:1032E000001B2000001B4000001B6000001B800032 +:1032F000001BA000001BC000001BE000001C000021 +:10330000001C2000001C4000001C6000001C80000D +:10331000001CA000001CC000001CE000001D0000FC +:10332000001D2000001D4000001D6000001D8000E9 +:10333000001DA000001DC000001DE000001E0000D8 +:10334000001E2000001E4000001E6000001E8000C5 +:10335000001EA000001EC000001EE000001F0000B4 +:10336000001F2000001F4000001F6000001F8000A1 +:10337000001FA000001FC000001FE0000020000090 +:10338000002020000020400000206000002080007D +:103390000020A0000020C0000020E000002100006C +:1033A0000021200000214000002160000021800059 +:1033B0000021A0000021C0000021E0000022000048 +:1033C0000022200000224000002260000022800035 +:1033D0000022A0000022C0000022E0000023000024 +:1033E0000023200000234000002360000023800011 +:1033F0000023A0000023C0000023E0000024000000 +:1034000000242000002440000024600000248000EC +:103410000024A0000024C0000024E00000250000DB +:1034200000252000002540000025600000258000C8 +:103430000025A0000025C0000025E00000260000B7 +:1034400000262000002640000026600000268000A4 +:103450000026A0000026C0000026E0000027000093 +:103460000027200000274000002760000027800080 +:103470000027A0000027C0000027E000002800006F +:10348000002820000028400000286000002880005C +:103490000028A0000028C0000028E000002900004B +:1034A0000029200000294000002960000029800038 +:1034B0000029A0000029C0000029E000002A000027 +:1034C000002A2000002A4000002A6000002A800014 +:1034D000002AA000002AC000002AE000002B000003 +:1034E000002B2000002B4000002B6000002B8000F0 +:1034F000002BA000002BC000002BE000002C0000DF +:10350000002C2000002C4000002C6000002C8000CB +:10351000002CA000002CC000002CE000002D0000BA +:10352000002D2000002D4000002D6000002D8000A7 +:10353000002DA000002DC000002DE000002E000096 +:10354000002E2000002E4000002E6000002E800083 +:10355000002EA000002EC000002EE000002F000072 +:10356000002F2000002F4000002F6000002F80005F +:10357000002FA000002FC000002FE000003000004E +:10358000003020000030400000306000003080003B +:103590000030A0000030C0000030E000003100002A +:1035A0000031200000314000003160000031800017 +:1035B0000031A0000031C0000031E0000032000006 +:1035C00000322000003240000032600000328000F3 +:1035D0000032A0000032C0000032E00000330000E2 +:1035E00000332000003340000033600000338000CF +:1035F0000033A0000033C0000033E00000340000BE +:1036000000342000003440000034600000348000AA +:103610000034A0000034C0000034E0000035000099 +:103620000035200000354000003560000035800086 +:103630000035A0000035C0000035E0000036000075 +:103640000036200000364000003660000036800062 +:103650000036A0000036C0000036E0000037000051 +:10366000003720000037400000376000003780003E +:103670000037A0000037C0000037E000003800002D +:10368000003820000038400000386000003880001A +:103690000038A0000038C0000038E0000039000009 +:1036A00000392000003940000039600000398000F6 +:1036B0000039A0000039C0000039E000003A0000E5 +:1036C000003A2000003A4000003A6000003A8000D2 +:1036D000003AA000003AC000003AE000003B0000C1 +:1036E000003B2000003B4000003B6000003B8000AE +:1036F000003BA000003BC000003BE000003C00009D +:10370000003C2000003C4000003C6000003C800089 +:10371000003CA000003CC000003CE000003D000078 +:10372000003D2000003D4000003D6000003D800065 +:10373000003DA000003DC000003DE000003E000054 +:10374000003E2000003E4000003E6000003E800041 +:10375000003EA000003EC000003EE000003F000030 +:10376000003F2000003F4000003F6000003F80001D +:10377000003FA000003FC000003FE000003FE0012C +:1037800000000000000001FF0000020000007FF8C0 +:1037900000007FF8000002920000350000000001E8 +:1037A0000000000300BEBC200000000300BEBC20DF +:1037B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19 +:1037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09 +:1037D000FFFFFFFF00000000FFFFFFFF00000000F1 +:1037E000FFFFFFFF0000000300BEBC20FFFFFFFF44 +:1037F00000000000FFFFFFFF00000000FFFFFFFFD1 +:103800000000000300BEBC2000002000000040C0FB +:1038100000006180000082400000A3000000C3C0DF +:103820000000E4800001054000012600000146C0C0 +:1038300000016780000188400001A9000001C9C0A3 +:103840000001EA8000020B4000022C0000024CC084 +:1038500000026D8000028E400002AF000002CFC067 +:103860000002F0800003114000033200000352C048 +:1038700000037380000394400003B5000003D5C02B +:103880000003F6800004174000043800000458C00C +:103890000004798000049A40000080000001038049 +:1038A0000001870000020A8000028E0000031180E0 +:1038B000000395000004188000049C0000051F8090 +:1038C0000005A300000626800006AA0000072D8040 +:1038D0000007B100000834800008B80000093B80F0 +:1038E0000009BF00000A4280000AC600000B4980A0 +:1038F000000BCD00000C5080000CD400000D578050 +:10390000000DDB0000007FF800007FF8000003E5F9 +:10391000000015000000190000000000FFFFFFFF7D +:103920004000000040000000400000004000000097 +:103930004000000040000000400000004000000087 +:103940004000000040000000400000004000000077 +:103950004000000040000000400000004000000067 +:103960004000000040000000400000004000000057 +:103970004000000040000000400000004000000047 +:103980004000000040000000400000004000000037 +:103990004000000040000000400000004000000027 +:1039A00000007FF800007FF8000003C80000150049 +:1039B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:1039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:1039D00040000000400000004000000040000000E7 +:1039E00040000000400000004000000040000000D7 +:1039F00040000000400000004000000040000000C7 +:103A000040000000400000004000000040000000B6 +:103A100040000000400000004000000040000000A6 +:103A20004000000040000000400000004000000096 +:103A30004000000040000000400000004000000086 +:103A40004000000040000000400000004000000076 +:103A500000001000000020800000310000004180C4 +:103A600000005200000062800000730000008380AC +:103A7000000094000000A4800000B5000000C58094 +:103A80000000D6000000E6800000F700000107807B +:103A90000001180000012880000139000001498060 +:103AA00000015A0000016A8000017B0000018B8048 +:103AB00000019C000001AC800001BD000001CD8030 +:103AC0000001DE000001EE800001FF0000007FF831 +:103AD00000007FF800000207000035001000000021 +:103AE000000028AD000000000001000100350804BE +:103AF000CCCCCCC1FFFFFFFFFFFFFFFF7058103C95 +:103B000000000000CCCC0201CCCCCCCC00000000EA +:103B1000FFFFFFFF400000004000000040000000E9 +:103B20004000000040000000400000004000000095 +:103B30004000000040000000400000004000000085 +:103B40004000000040000000400000004000000075 +:103B50004000000040000000400000004000000065 +:103B60004000000040000000400000004000000055 +:103B70004000000040000000400000004000000045 +:103B80004000000040000000400000004000000035 +:103B900040000000000E01B7011600D60000FFFF34 +:103BA000000000000000FFFF000000000000FFFF19 +:103BB000000000000000FFFF000000000000FFFF09 +:103BC000000000000000FFFF000000000000FFFFF9 +:103BD000000000000000FFFF0000000000100000D7 +:103BE00000000000007201BB012300F30000FFFF92 +:103BF000000000000000FFFF000000000000FFFFC9 +:103C0000000000000000FFFF000000000000FFFFB8 +:103C1000000000000000FFFF000000000000FFFFA8 +:103C2000000000000000FFFF000000000010000086 +:103C300000000000FFFFFFF3320FFFFF0C30C30C4A +:103C4000C30C30C3CF3CF300F3CF3CF30000CF3CB8 +:103C5000CDCDCDCDFFFFFFF130EFFFFF0C30C30C1A +:103C6000C30C30C3CF3CF300F3CF3CF30001CF3C97 +:103C7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C85 +:103C8000C30C30C3CF3CF300F3CF3CF30002CF3C76 +:103C9000CDCDCDCDFFFFF4061CBFFFFF0C30C3051B +:103CA000C30C30C3CF300014F3CF3CF30004CF3C3F +:103CB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C59 +:103CC000C30C30C3CF3CF300F3CF3CF30008CF3C30 +:103CD000CDCDCDCDFFFFFFFA302FFFFF0C30C30C51 +:103CE000C30C30C3CF3CF300F3CF3CF30010CF3C08 +:103CF000CDCDCDCDFFFFFFF731EFFFFF0C30C30C73 +:103D0000C30C30C3CF3CF300F3CF3CF30020CF3CD7 +:103D1000CDCDCDCDFFFFFFF5302FFFFF0C30C30C15 +:103D2000C30C30C3CF3CF300F3CF3CF30040CF3C97 +:103D3000CDCDCDCDFFFFFFF3310FFFFF0C30C30C16 +:103D4000C30C30C3CF3CF300F3CF3CF30000CF3CB7 +:103D5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF8 +:103D6000C30C30C3CF3CF300F3CF3CF30001CF3C96 +:103D7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C84 +:103D8000C30C30C3CF3CF300F3CF3CF30002CF3C75 +:103D9000CDCDCDCDFFFFF4061CBFFFFF0C30C3051A +:103DA000C30C30C3CF300014F3CF3CF30004CF3C3E +:103DB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C58 +:103DC000C30C30C3CF3CF300F3CF3CF30008CF3C2F +:103DD000CDCDCDCDFFFFFFFA302FFFFF0C30C30C50 +:103DE000C30C30C3CF3CF300F3CF3CF30010CF3C07 +:103DF000CDCDCDCDFFFFFFF730EFFFFF0C30C30C73 +:103E0000C30C30C3CF3CF300F3CF3CF30020CF3CD6 +:103E1000CDCDCDCDFFFFFFF5304FFFFF0C30C30CF4 +:103E2000C30C30C3CF3CF300F3CF3CF30040CF3C96 +:103E3000CDCDCDCDFFFFFFF331EFFFFF0C30C30C35 +:103E4000C30C30C3CF3CF300F3CF3CF30000CF3CB6 +:103E5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF7 +:103E6000C30C30C3CF3CF300F3CF3CF30001CF3C95 +:103E7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C83 +:103E8000C30C30C3CF3CF300F3CF3CF30002CF3C74 +:103E9000CDCDCDCDFFFFF4061CBFFFFF0C30C30519 +:103EA000C30C30C3CF300014F3CF3CF30004CF3C3D +:103EB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C57 +:103EC000C30C30C3CF3CF300F3CF3CF30008CF3C2E +:103ED000CDCDCDCDFFFFFFFA302FFFFF0C30C30C4F +:103EE000C30C30C3CF3CF300F3CF3CF30010CF3C06 +:103EF000CDCDCDCDFFFFFF97056FFFFF0C30C30C7D +:103F0000C30C30C3CF3CC000F3CF3CF30020CF3C08 +:103F1000CDCDCDCDFFFFFFF5310FFFFF0C30C30C32 +:103F2000C30C30C3CF3CF300F3CF3CF30040CF3C95 +:103F3000CDCDCDCDFFFFFFF3320FFFFF0C30C30C13 +:103F4000C30C30C3CF3CF300F3CF3CF30000CF3CB5 +:103F5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF6 +:103F6000C30C30C3CF3CF300F3CF3CF30001CF3C94 +:103F7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C82 +:103F8000C30C30C3CF3CF300F3CF3CF30002CF3C73 +:103F9000CDCDCDCDFFFFF4061CBFFFFF0C30C30518 +:103FA000C30C30C3CF300014F3CF3CF30004CF3C3C +:103FB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C56 +:103FC000C30C30C3CF3CF300F3CF3CF30008CF3C2D +:103FD000CDCDCDCDFFFFFF8A042FFFFF0C30C30CEA +:103FE000C30C30C3CF3CC000F3CF3CF30010CF3C38 +:103FF000CDCDCDCDFFFFFF9705CFFFFF0C30C30C1C +:10400000C30C30C3CF3CC000F3CF3CF30020CF3C07 +:10401000CDCDCDCDFFFFFFF5310FFFFF0C30C30C31 +:10402000C30C30C3CF3CF300F3CF3CF30040CF3C94 +:10403000CDCDCDCDFFFFFFF3300FFFFF0C30C30C14 +:10404000C30C30C3CF3CF300F3CF3CF30000CF3CB4 +:10405000CDCDCDCDFFFFFFF1300FFFFF0C30C30CF6 +:10406000C30C30C3CF3CF300F3CF3CF30001CF3C93 +:10407000CDCDCDCDFFFFFFF6305FFFFF0C30C30C81 +:10408000C30C30C3CF3CF300F3CF3CF30002CF3C72 +:10409000CDCDCDCDFFFFF4061CBFFFFF0C30C30517 +:1040A000C30C30C3CF300014F3CF3CF30004CF3C3B +:1040B000CDCDCDCDFFFFFFF2304FFFFF0C30C30C55 +:1040C000C30C30C3CF3CF300F3CF3CF30008CF3C2C +:1040D000CDCDCDCDFFFFFFFA302FFFFF0C30C30C4D +:1040E000C30C30C3CF3CF300F3CF3CF30010CF3C04 +:1040F000CDCDCDCDFFFFFF97040FFFFF0C30C30CDC +:10410000C30C30C3CF3CC000F3CF3CF30020CF3C06 +:10411000CDCDCDCDFFFFFFF5300FFFFF0C30C30C31 +:10412000C30C30C3CF3CF300F3CF3CF30040CF3C93 +:10413000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C47 +:10414000C30C30C3CF3CF3CCF3CF3CF30000CF3CE7 +:10415000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C27 +:10416000C30C30C3CF3CF3CCF3CF3CF30001CF3CC6 +:10417000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C07 +:10418000C30C30C3CF3CF3CCF3CF3CF30002CF3CA5 +:10419000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE7 +:1041A000C30C30C3CF3CF3CCF3CF3CF30004CF3C83 +:1041B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC7 +:1041C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5F +:1041D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA7 +:1041E000C30C30C3CF3CF3CCF3CF3CF30010CF3C37 +:1041F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C87 +:10420000C30C30C3CF3CF3CCF3CF3CF30020CF3C06 +:10421000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C66 +:10422000C30C30C3CF3CF3CCF3CF3CF30040CF3CC6 +:10423000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C46 +:10424000C30C30C3CF3CF3CCF3CF3CF30000CF3CE6 +:10425000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C26 +:10426000C30C30C3CF3CF3CCF3CF3CF30001CF3CC5 +:10427000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C06 +:10428000C30C30C3CF3CF3CCF3CF3CF30002CF3CA4 +:10429000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE6 +:1042A000C30C30C3CF3CF3CCF3CF3CF30004CF3C82 +:1042B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC6 +:1042C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5E +:1042D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA6 +:1042E000C30C30C3CF3CF3CCF3CF3CF30010CF3C36 +:1042F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C86 +:10430000C30C30C3CF3CF3CCF3CF3CF30020CF3C05 +:10431000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C65 +:10432000C30C30C3CF3CF3CCF3CF3CF30040CF3CC5 +:10433000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C45 +:10434000C30C30C3CF3CF3CCF3CF3CF30000CF3CE5 +:10435000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C25 +:10436000C30C30C3CF3CF3CCF3CF3CF30001CF3CC4 +:10437000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C05 +:10438000C30C30C3CF3CF3CCF3CF3CF30002CF3CA3 +:10439000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE5 +:1043A000C30C30C3CF3CF3CCF3CF3CF30004CF3C81 +:1043B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC5 +:1043C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5D +:1043D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA5 +:1043E000C30C30C3CF3CF3CCF3CF3CF30010CF3C35 +:1043F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C85 +:10440000C30C30C3CF3CF3CCF3CF3CF30020CF3C04 +:10441000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C64 +:10442000C30C30C3CF3CF3CCF3CF3CF30040CF3CC4 +:10443000CDCDCDCD0010000000070100000281703D +:10444000000B81980002025000010270000F0280F0 +:1044500000010370000800000008008000028100D5 +:10446000000B8128000201E0000102000007021099 +:1044700000020280000F0000000800F000028170BE +:10448000000B81980002025000010270000B828034 +:1044900000080338001000000008010000028180BD +:1044A000000B81A80002026000018280000E829849 +:1044B0000008038000028000000B8028000200E05A +:1044C000000101000000811000000118CCCCCCCC10 +:1044D000CCCCCCCCCCCCCCCCCCCCCCCC000020002C +:1044E000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0C +:1044F00000002000CCCCCCCCCCCCCCCCCCCCCCCC0C +:10450000CCCCCCCC0000200000000000000000005B +:104510001F8B08000000000000FFFB51CFC0F0031C +:104520008A45D91918FC3811FCA18059981918D856 +:10453000809803883D80B8819181A1919178FDDABE +:10454000620876BF3003C36E20E611029A23821000 +:104550009F0254F306C85F0F15B312656038263A00 +:10456000F07EA706DE2A8D29364512C1DE86451E5D +:10457000196F4793FF2289CADF4140FF40632965D5 +:1045800054BE9D22845EA604A1A5D1E4EDA1F2D77C +:10459000A1FE9251C66EEE0DA83C00F85C49656024 +:1045A00003000000000000001F8B08000000000056 +:1045B00000FFED7D0B7854D5B5F03E73CE9C994944 +:1045C000CE4C4E4212F2224C1288A0210CAF808AAF +:1045D0007F270122F539202858D40142087983D455 +:1045E0004BAFEDCD8424101135F447058B76885000 +:1045F000D1A20D34D260C10E20147B6D6FF0FAC0D1 +:10460000EAF50B4841312FB1207EC5CBBFD6DAE7A2 +:1046100064E64C2680D8DBAFFFFFFDB4B8D9E7ECE9 +:10462000B3F7DAEBB5D75A7BED3D92750293BFC76E +:10463000D845FC03E54F4D8CB109C1F26766F680A1 +:104640002787B1C9BDFE3A473C63556D193BA29D12 +:104650008C25EC9921142850FED5232C5082DFBFE5 +:1046600065C397F0FFB619423E7C97D0E911E6C3C7 +:10467000FBE4D5026B873A939C310CEA8CB9194B59 +:10468000642C6B12A33F224B8D82FFE07325398F80 +:10469000B134FC2774754661AEC078C6321E535CD7 +:1046A000D4D0A93815783F847FC6D2BC25B731074E +:1046B00063CF03BCC971F0BC5A3ADE61E5EF2EC28C +:1046C000DFA1F33A6ACD58AE303E7732A789654113 +:1046D000BF3EE3F3AC46633D9BD9E34F46C33FEC9B +:1046E000CC7E518C308F13B18C013CCB540E2F6398 +:1046F000BDB26754101F9B6A58A2322C580F2F85E9 +:1047000065873356035E97ED165C16F8FE396C2FFD +:1047100031E6D7BE6BD6EA153E5962A3A10404B5B3 +:10472000E4F4EF6711CBBF11F1FE302BA0B24AEADF +:10473000955580AFAA5A76FB95FEED673389E8540C +:1047400029B9F65B61FCDE5AE66A86F19799D502D3 +:10475000AC2FFB91D3E5837A6663472183FAD03689 +:10476000818919C1EFAF009EDB917F001E2A2BA526 +:10477000DE420674ECDD2BB0E60C1C87F7BB6C77D1 +:1047800006F3650C0CE758662638E732413A89741F +:10479000713007D2C1BC24F38942A8CE54DCF3B0F7 +:1047A0007F9FE29D87EDF4E7490BE638BD0057F2A5 +:1047B0005066A057B1B53A9D653256EA692944BEA4 +:1047C00038B5EC8D5558029E1324C0F77C8BA70892 +:1047D000FBA998579DCD80A7E659188D3FB42DFFB2 +:1047E0003309F80CBAF3C5C4213F31763C844FF04D +:1047F000CFF1115A5D1C98DE972B8BB01F09F10584 +:104800007217011F3F42A026E0284D543A57FC2959 +:104810006BD8A0D0FA5B59C3C66900E511BC0C3F48 +:1048200061AC4308E54BBD1CBA3BFFB0943B303C48 +:10483000FFD3F30474127EAB00B7C81F1576D9BF3F +:1048400012F861CAABE6C0F7803F2A360B7E0BD464 +:104850004DAFDBE87DF7265E0FD86537F24FD716F0 +:10486000A80BF0BDA5FDF11B91BF5E155933763B3A +:1048700022CA84FAE5A4063B1B0F75C047B18D57C9 +:104880002B36EFBB1FBF2F69B3301BF457B17BF141 +:104890001D37427DF16133C326155B6BE514A82FEC +:1048A000F10B2D58EF29E0F0F97689FEADD0BEC7A7 +:1048B000D19E381BE873BAC6CA9C326375F6F6C43B +:1048C00059C067A5FE1D85F85DE976C185689FF230 +:1048D000EAD643C938AF17B97C976D8B664E1D7FFA +:1048E000F0F764AB18F81EBC5F06F364D0EF62D635 +:1048F00054887AB062EB3AD9690FE2EB748D4AE3DF +:10490000F4C9DF8B300E7C57F98AE0C229569A9899 +:1049100017E5B07BB76DCEF30ACEAF56CEB6E3BC8B +:1049200056CBD86EB17FFE2E54CDA5FECD7221BCE4 +:104930002FDDB4592E0E91DBB26D838C706DC81AC9 +:10494000EC8D20D7417880D7B283F552D403A80FDD +:1049500025BF3C2384CF2A8558E2CBB26D22731A3F +:10496000F888D3DDF72EFC13F0E5DB6B27BCEA7487 +:10497000EBD3A71ADDCEA81A1DA5DEBC1911F8F8D5 +:1049800071A403C0D384788272AD069F6332CB9743 +:10499000A07F879BA902BB3C5F3699D97C0663F553 +:1049A000B007DDD2F55097D952E682F550FAB17BC7 +:1049B0002AD49304EF67389F7AC15BC2D7AB9624A1 +:1049C0000FE07995C0E6E0FC8F21D030AF55C9C02B +:1049D0009F80F7A66979CF8B82067B3CD68B7FB10F +:1049E0002683FA3943FD98A19FACCBF7A3164E322C +:1049F000F4A31696E8FDFC8DFAB15D593F4D85375D +:104A000018E1292CD5FB910468576FBFB279A937FB +:104A10004F36C2737339F5133BD5C5BC0AAEE71ADE +:104A20003FB076B708EF95EDB163D7B050BE2850D0 +:104A30000580DB0E5212CA173193A20C7C18EB8E44 +:104A400033D4A127F5E47541FD138895697C394578 +:104A500026BD909F62A5FA43290AE985876EF05E1C +:104A600083EB208ECD92A12E7B47AB11F81AE01478 +:104A7000581296601724F57FBFDACCF150907A2156 +:104A8000FB187C5F65EACD8E85FA35A6FC6B116F4D +:104A90002E81EBE528915563BB280B23FDB43A2307 +:104AA000EF795F089E1A8700FD8560BF8D666F12E3 +:104AB000F2D7F8DA677C12C0B76A08CC2705BA12B9 +:104AC0009E09F8603D5A3DA43809F1699141BE4301 +:104AD000C79761FC1C1AFF06C4A31BC74FE83FBE63 +:104AE000257392617C6B7A89617CAB0CE303BF4FC9 +:104AF000AD6DD6C607FCDDC0D834A199C6B7A49762 +:104B0000D0F8AB655662183FAA6FFC5B70FE9E81C1 +:104B1000E69F798371FEE9A5C6F9CB7CFEB36A5F97 +:104B2000D2C68FA2F9CF165EE2F34F2FE5F3B7F0AE +:104B30007EFBC677F4E1FF5E9CBF7780F12D599331 +:104B40008DF31F5A6E9CBF858F5F54BB531B5FA1B3 +:104B5000F117093BF9FC8796D3F8B2C5EB423E92B8 +:104B600053A3AAFD684FA481400C261DE5A672043C +:104B70001805A01F860A9904C743519CEFCE450132 +:104B8000BF29417DC7FC2051A0CF2A359E2FDB9E37 +:104B90002FA39EA5F7896837F13F456D22AD376C8D +:104BA000BDC53F1CE0ED6E137D582F5A7F935FA467 +:104BB000F58EDBE560C605F0F95F9E1CD51C3AAFAB +:104BC000F0725193F96487418E383CBE0236A21AC6 +:104BD000E06B47269810AC9F043D0AC62F3B0E7A27 +:104BE00014CB53666E8F9C003DCBE450B9A9E5F61B +:104BF000888FBD9303F3BA5B83FFA4C4F17D72B9C0 +:104C0000E047FC9F5BB75446FDB4A8098CE91079D6 +:104C1000AFD2E8D4BBDBE26F16089F4EC4CF3D2471 +:104C20008A8CFD9766D72FDE30C8F0DD3CE66F48F2 +:104C300082F60BD7CE1FA2C2FC7F30C73216ED53CF +:104C400090845413C9314B35816F31A7759D391547 +:104C50002AF7CC311BECFAB95E63FD0725C67AB79B +:104C6000D96F36A1BDB144609BA1DFFBAA8DEFF5E2 +:104C7000713609719CAEDA7877277278EFC3722C9F +:104C80003E5689AEF7ABFC5B1D9EAA87CD2C40EB50 +:104C9000654702433AFA12C85EF3AA7CDEE1F0DE11 +:104CA0006FB6BA3D00CFFD3F12099FE1F077BC1E01 +:104CB000ED36811DD7B1E14B33DAB7E1F30987FF58 +:104CC0008115E1F35165D4F7F37DE1CF399F84F38A +:104CD00053555BFEA01321ED2A5ABE3FE844087FDE +:104CE000956D9B61A82FF1CF35B45FBC61BEE1FD2E +:104CF000A2A62586F70B1B971AEAF37D3F32B47FF5 +:104D00006045ADE1FD7DD58F18DEFFA0649DA13E1D +:104D1000D7BBD1D0FE9E399B0DEF4DAF8FBC13E5B5 +:104D2000A8EE5D91E1BA715639F938DA836715C991 +:104D300085F4F8B42689E4E0748D93CAEEB6715612 +:104D40002FD783C50C4C9C5EE19CAF7132EA65465F +:104D5000FAF3AFC2059F0FEA7F139C843F7183CCA7 +:104D600002C0C2028BEBE3E35E31E47DC765DE6F18 +:104D700000411FD7FFBDD811F97955F3FCA16A0492 +:104D8000FF2128B72C15D7B91E6D7D0F7F5F2E3000 +:104D90004FE873C656929CD769EB4CB9CCF541F9F4 +:104DA000CEE402F4BFCBE54076F5A5C66B01A4A224 +:104DB0009E44EB3C01F901A4C0C02F5906F9EEDC7A +:104DC00027125C95A81340AFAE639EC126D43381F1 +:104DD00003E9778D4238DC49546F4BA075BDB3664B +:104DE000FAA01312D2C743E5A73573A83C59E3A52F +:104DF000F2444D0995C76BAAA9ECA85941E5C735FE +:104E00003E2A3FAA69A4F2CF354D541EADD940E5E4 +:104E10007B357E2ABB6BDC54F6F92BBAFE8DD7ECC2 +:104E200055CDAF809587EA67B4B9D443DB769273EA +:104E30005712CAF919E55C36DAE3678E8263993155 +:104E400030BEC2F96D603ABAC95E29F603FDC7F5F6 +:104E50007F6F8BE274B299D87470A6D923C37FE1B7 +:104E60005A9043750959061624D70C7B847E61ED50 +:104E7000437A5D8E4ECCDD9B3B13E871F299BFE522 +:104E800061BF75DAFA177540A47598059E7721BD44 +:104E900042F046EB5AEFAB9ABEBF0CFEBAFAF0D71F +:104EA0009E8EFEFB4141A5FECFB45A988478DC1358 +:104EB000ED07E667670E3FEF40795C9664524F441A +:104EC000C0835E56B464A84AE8FAD366AC9F691200 +:104ED000A6B7D07AEC8C99350AF94A554F0C43FAAB +:104EE0002751A9F7B32C49564F80BC9EDE9615C3B7 +:104EF000D76F3F5F07B7C712BF825F48EDFFDEF095 +:104F00000CD48F0E0F63ADEC132BEA037897F5EDFD +:104F1000FD7226FD95E2576C8FF91CDA0B16F87BB3 +:104F200091E20712D5F57EAB5A449F65343EDF6EA1 +:104F3000180FBE73EA3EF7C5CC4BF1ADC44E86C424 +:104F400011D669F1C6B26D36D5B8AEC41AEA556D40 +:104F5000C9AA619DC17F80FCB36A4142BE29D7B80E +:104F6000A847521A0580AFDCE4A47EAB04DEAEC2D3 +:104F7000DA217BE151572BA7DB40F09DAE39EC9451 +:104F800040DE4BACE001027C252D23A7A29EEB6AFC +:104F9000AD4B447BB04C3CF39027C2F73B4D028DA8 +:104FA000B7C46FEE35AEA31A7F30E8577F4E7E163A +:104FB000534E86D43B4DDCCE0EEFF780D6EFE5F0B6 +:104FC00053B9FD48E18DCEFE78AA6CFB42F6921CE7 +:104FD000C1FFF28278D2F1576EF21C407D5ABAEDD1 +:104FE00018D9A39F9A7DD90F5F423FF59F9F9244A6 +:104FF00071527D5E3E3029619C055A7C17F8F79E00 +:105000000F613DFDECDFCD6C0DC0C72E402B786FDE +:10501000D65F331333417DA1565BD05A4671DDCF45 +:105020004CDC8E2A621E07D18135E5A11DD9C54C05 +:10503000D3114F5DEC6DC7B8103A9C32C9A4671606 +:10504000361AED18B07F0DF5C51B8CF5623633119D +:10505000F549F17A33F30B343FC3FBF74D2AE17F77 +:1050600031AB5E85EBAAA4F9230B5426A5027C156F +:10507000BF79366F3EC65F4CDC0FD1E3234BE2387D +:10508000FCA5F17ED90DEF3F691D77F78D48068BA2 +:105090007F15C689580C736D65FDF1FB6DE10F87B7 +:1050A000575FAFFBC5693438C46D82DB1F817F2F2A +:1050B000687CA6EBEB5B44D5E017DC8DF510BF21D7 +:1050C00046D4E2B2221391EE5DAAD5678AA1F71405 +:1050D000B7F7EDB4B8EA80DE3F3779068913C84EDA +:1050E000C86521ED7E6EF2D2F34EE1AD62B45B99FC +:1050F00014C8453B14D618E25359E30731CA918BC3 +:10510000F1663B837514E86F41F8A09F55F692DB7A +:10511000582EC6BB41DEA1BFC71C858705A8DB94FE +:105120005686FD59928CF17C9BD358AFC27F201DCF +:1051300046308A3F458F90C2F01860A80FED2EE3ED +:10514000F351E88491DD1F203E76108B43695502B0 +:10515000228CCF26499D7DFE5626FA7B1C7E8A2F07 +:1051600040FBE52A6F5FA9C5CF977F503038EE121C +:10517000FAA8EA3C68904121753DBE7F5E62FE71EF +:10518000DF416F3A61550DD19B734DDE69480FD4F5 +:1051900093089F00E3780D76609A1A2AE70BC2F80D +:1051A000E3AAE1886706FD5D6EF2DE2D26F487E353 +:1051B000AAFB4FEAD7FF8248F3BCEAFE87F5EBBFB4 +:1051C0003252FF15BF7979970FF8A9F4574F3A80FB +:1051D00099D9675253A20BE85EBEB5C18172F9A995 +:1051E000E473205D3FF38BD323C9E71651974FB784 +:1051F00022E411FF101F9D7EE9D13BD0AE3AB7D516 +:10520000AC527C609B256001A6AC6C5DC2E5639BE3 +:10521000E518AFAFFE02F9B3AACDA82F4A5F7832E6 +:1052200011E3CD4049CD7F0E907F50B9E52F8568C1 +:105230007755B15ED27BE1DFE1F8E7E3C81E982F36 +:10524000C7F47FAFEFF3556978A96A7DF40B9184B9 +:10525000A583FCCDF0F6259ABDFFA4688FA738DFA3 +:10526000443611F94CC707F3737BBFEEC5A7738FA4 +:10527000013C9D5BFEDD21E484F227D77B675A1653 +:10528000FEFC35E7C0F2D40D7A31D4AED6D76767CD +:105290009BE6A7ECE165B939E0403FB07CB3D9E5C6 +:1052A00043BABEFCFC2F9EC1B8CC0716D770E8BF2E +:1052B000ECE583EFDD00F5B21DE6F8DBF8341421F0 +:1052C0003148972AF8BB626C900EA5BF3E283B4739 +:1052D000F1E73F8E0BD2A36CC73E998DEA8F8F29E1 +:1052E0002DFBE40E25025D5A8E15A23F51F7E257C1 +:1052F00032EAAFCF5E17D8E08C08F8DC7C90EC6225 +:10530000C413D151A3531FDDC2DA57015D50BFEA68 +:10531000740A7FFF2F9AFEC7FE9C39C4CFAFBC86AC +:10532000FB287FB6B870FE25AF3CE8C0799C92AAF6 +:10533000395F3FDB90E886714BCCBE44954AFEBC9A +:10534000E4B91F12BF2D3EF2C3448A7F3077B28981 +:105350006C055F32CE6FD1A6D934BF62E625BE2B75 +:105360007956F4E0FEE059894DDF11412E5224AE0A +:105370008F4F355B704D65A770E1C07D85B745FFE8 +:10538000568AFF2DA5F8CA0FF5FD20B68CEA67AD49 +:105390009C4E5F88FABE1AAC3CA1FCBA65753BD244 +:1053A000E7F410F7608C1B5731C9A7E143B808FD3B +:1053B0008A47A60DE6F4614E294FFB0EF4FD147CDE +:1053C0008EEDDBCD6E5BAEE13B76312338FE726D48 +:1053D0007C803B0AEDD5538960FF45985FA1A4AF5F +:1053E00037605785F057887C7379DFF208976F5DD7 +:1053F000DEFD33A6E3FBBFBEC3E507BF437B05E08D +:105400000A0CA6F7FB6609A40F2C2C1049AEB7981E +:1054100035B936BED7F904E09670DDEDE317EC3F01 +:105420008EF04F766CF17AF82E445F56E1788EFE5E +:10543000FDE972BB5893FF04C928FF6C1397FB81E9 +:10544000FD091F8F4B98FDBF7806E515E413F7AFF4 +:10545000CB5F367B70DE9F6F3FF0DEBD20A79FB72E +:10546000E8726AD49FE1725AB273028B24A79F63D9 +:105470001A42243985E711E554E9203EFE47E94FF9 +:105480001D7F3785E14FD78703E1315C1FFE5974DB +:1054900046D487F0E71D96D79FFF74BED3F9ADF4CD +:1054A000971543293EA6F3A5CE777D7CA9F35DBF72 +:1054B00078A3017FE1EF2D188301B83CBBCD1447E1 +:1054C00028DFC3F77FE1BB43A9E3094F6E5AC658F3 +:1054D000D3A1D4F8D0BA3FACDE12D6DE1D56F78485 +:1054E000B5F786D5AB0DEDCBDB0EC83CAF256068BC +:1054F00027AE78867D322812BFFAB95FDAFA85ECDA +:1055000043BE507AE97BF34AE6B3633C7CAF48F193 +:10551000911EC0F12A18A7677B861FF3241A6C3CE2 +:10552000EED4A3F63AD05E6C88E5F5DE047915EA90 +:105530003DFD79AF8DC7F57A3CBD8ED810FBEDD817 +:105540001E91F476879F4D8FE467C28A4272D4C160 +:10555000067ACFE3FDD344257D05C65F9A441786BE +:10556000748A6AEF71609E41CF9EAC3BE7C0F34501 +:105570006F8AB48DD883767B0C92C72D2587F877F8 +:105580009F32DF5393317EBF87FB79456BC3EC11AC +:10559000B696F8A958592EA33E05BFECB871FF8204 +:1055A000CB45A9D65FC926E37BFD7BDCC145FBBDAE +:1055B000748BF1BD578B0734EB7232868DD1FC7141 +:1055C0001E8FD2F4F23431E7CE39408F9EC322C30E +:1055D000FDFB337B44A2C799ED7CBF9EE2F6D72347 +:1055E0007FF7923ED4F1D489F2240FACAF3A5FFD3D +:1055F000AFBC87916F767D98FB33283B777D90FD1C +:105600005BACFFE6FDF40F59FFF6535EB7D13E49A0 +:10561000CFEB76E2F79EBD7F4C7F18EBBB2D149F3E +:10562000EE79FDAB5CE49F9E959612D4773D438066 +:10563000FE681FECFD2AB783D6D77AA2DB1F259917 +:10564000DB477BFEF6B1108F25CC0AED86D7A34948 +:105650009EAA5EB3513CAD67EF5779A176FF779D67 +:105660004FA5B67FD963677376227CB17CDFA7EA4A +:10567000B7D73F5F8BF917ADFBE485F07ECAEFBE6D +:10568000C9453DDAB393DB43DDE68EE7707FEE6814 +:10569000FDDC9566C073370A550AAC9B0DCF14A08C +:1056A000DCF4C7CB371427BC527CF4FC5F830FC1FA +:1056B000CDF59DDD6F1570DE5F7FFC21EA85D72D6E +:1056C000C497FA7C3F6FA9257BE572F37698799CA5 +:1056D000E4FF9D790B812B99F728F33F37BD7F2D90 +:1056E00039892EE172D09FCFF73E44F597ED2E8297 +:1056F000F70AF9FDF67FF2F97F6BBAEF04BA3B2E99 +:105700003FEFF27FF2790F4CF737EFD7E8AE627ECA +:105710004BD5EFBE21F8BEAD9E5BFB4F2EEF03CD08 +:105720005FB7EBD7985C4D99189F43AF01D669C519 +:105730003EB311C3856B46CC54D1CE14C3F62BF5C2 +:1057400072AF99FB4D22EE5B629C6F088FF331CDF7 +:105750008FA22D3D185A528AC98E959455DCBE965B +:105760005CED6EC0CB9A6B17B82877888D3DEAC583 +:105770007ADA6417C5AFC3FCC97A81B905B06FA5E1 +:105780006B6F398CFE8D79842960C9A5F21896ABB0 +:10579000B5B8A459950D7E8F9263ACDB9CC6BA4513 +:1057A000EBCFCA38FCD624E6C7F8B43872BF8A7982 +:1057B0006DE218890950B7B1261FFA179624E3F74E +:1057C0001B31C01E12CFBD5A3CF6F6E1716CBB1BFB +:1057D000F138D244716B4A2E25BCB8FC6B789E8D93 +:1057E000D588D755ED884F09FD5F6E7F91DFCC34AA +:1057F0007F59D2BA904698DC36633BCD4FBE2C9D84 +:10580000385DD2CB353A2D33D045A74304FA18E89A +:10581000A2E3F9DBD2279C2EE1F8DF6F7612FE07B8 +:10582000A2974E9734C5CD505ECD9ABF3015FD4935 +:10583000ACA77918ED336BFE8214EF663EA493EAB1 +:1058400062482FF4DB02E0B7FD7EFBF31427EA7A0F +:10585000E9D81D084FD96F456605FC756FB7B300D1 +:105860007E2FF965F4434B5B458AFB3329907757CC +:10587000C8BEAF6EF797FDCA4EF329DD69F1DF06AA +:10588000DF97EEFA2497ECB095BDE4D7F85E1238B6 +:10589000DD7D1DB9B8AF5B2A71FF239C5F62659EF9 +:1058A00027D0B93B7A0EC66D846D3CDFB6B4E51ED9 +:1058B000B3C5907F66D6DB915EF0BD2850BE13C2A3 +:1058C000179AE7A9FB1D9D2F0A1CBE36B31FF3765E +:1058D0004BB7EDE8C6F853E9518B0BC3D255DBBE8D +:1058E000A0FD8D29BF7AD9D141FEB668883FF4F377 +:1058F000FBB789C41F95AD15E487409DF8A2B2257A +:1059000072FCEB72FE69D9AFF6EEF2010ACB7EFDB6 +:105910008203E35BA7DBB73AC8FFDF76E9B85B3FFA +:105920003FBFE5914BFAF9A7F11FE0BFDC2087C527 +:1059300049B60D227F04E0CB8B94EFADF35BD9CB5E +:10594000679FC33874E7CECF9F4378CBFFFBCBE78D +:10595000D09F60AFDBD4AD889797DEA5389EFEDD83 +:105960002C99C79DBB5F7C81E29FDD1F80DF017F9B +:10597000BAF79E4A477FB27BC7D789182F59BE779F +:10598000DA609CEFF257A70C6611F4885E22DFFA0A +:10599000AF20FE1A4EAF03AD07C8EFE9027AA3DFCE +:1059A000D917B769A9E07130A716AFD91E39CEDD76 +:1059B0002F3ED37AD79D378DC7D2EC72B22B88D3C6 +:1059C000BC03741C7D05F4DBFE88E67F46A65F17EA +:1059D000FE03E8B42C8C7E675B17FDFC197CD73A7C +:1059E00068C0384DE00AF0A6C7D1BF27BB7F22A30D +:1059F0007CEDFC25C5C5906EB7C144BB5F3E9B8E58 +:105A0000FB0F9F9A7BEFE7E7322C2AC61B4AF7BEB3 +:105A10004FF2D3FDEA118A53332D9EDDCDFAFEF00D +:105A2000F8A3965359B5C5CEE33B1AFE31FEE37495 +:105A3000D0732DCEC3F9588FFF0C14F7699579DE1A +:105A4000881EDFAFD8F2A1164F09D24B9884743A62 +:105A500076C9FD081D0F2AE26162681C33727CADB5 +:105A60002FDEADD10BE987F1CBBE3825D4D3306E14 +:105A7000E517DE6711F441F7661EFFEC3647CEA34B +:105A8000D2E39ABF0A9753FF95C5332F07FFB7C5D7 +:105A90008F5F7652BFE178EABC10598FBF2DF37546 +:105AA000FFAAF7C5CA0543BE41B9C97B04F9B1A233 +:105AB000F598CCCFA5F0F352FA7C3BB5BCD1CE978C +:105AC000448A77AD6A39407A3C5C5FE8FBA6E1F036 +:105AD0009ED0E0AD6CE3EB44E74EBB5F817E3AF7CE +:105AE000EF267EAEDC7E8CE26D87B6FD5AEE08595D +:105AF00057719DF087C0DFF9CABE5C1EB7E579EC2F +:105B0000E1E39CD1F461D59EC8E3546DFFC2304EF1 +:105B100099AF45E6EBFDA5C73B2DB9EFC1FE4EB7EA +:105B20009B19E6799E6E11A7473A17F5AEB66EEA55 +:105B3000E77E70BDA47CFD23FC5CCCF8B7A3281FD6 +:105B40007EF991E91FC6C463098487FE5A6B399FA9 +:105B5000B6FEC49D8AF46E3D72AF88EBD42EC46F3E +:105B6000889D9FF74EF5143BE885BC8F3CE3915D23 +:105B7000C3F5CDC4A32603FC30CE605C07EAA11FA9 +:105B80003CA782F96E088FE8289C8EF088AA49B558 +:105B900009FDE761563C745E40EFD7AC1ACF03B005 +:105BA0000BE39CD84FD24C1E474CBE8B973EFD3C1E +:105BB0004E7194BF0EE659A078D32CF07D927D7D76 +:105BC000C64186E7BF2651DE7696C5786EAC4B554A +:105BD0007C26D0DFCFE46C5937D949F907D7584232 +:105BE000F30F582017F9516FD7EF7D587E421A7E78 +:105BF00002FD881A7C595A7EC210D621A07DBDC9EB +:105C0000CECF270E55E24DF8FDF39ABDA99F3FEC8C +:105C1000775E31EC9CE2E5CE27C64FC95F3AD405EA +:105C2000FCB47ACF14CC5F8FBF277F47AA8A791242 +:105C30007F9E82E757E25FC81F930CF513AB1F9C52 +:105C40004AF5FFC81F930EF56F1AFF8DD7CB04CA14 +:105C5000572D583D7A2AF2EB55CBF92CC08851CEFE +:105C6000EF40BC75793EBA7B9113F31F7A658E5F66 +:105C7000E6C176432671BCA5291FED403C0D357564 +:105C8000D4227FFE7CEF57B1A8179C4C25FCA8AC12 +:105C90005E45FAC1A349172F9147179E4FA6EB9374 +:105CA000CD8AF70184E391F923E85CE0332533AD35 +:105CB0003C5FCF98C7C0D478A26791464F84D31A6F +:105CC000928FBF58F4C9FC5C4C93A6AFA6AA389E2D +:105CD000E02B172F5EF7EDE17A50E74BED5C69C8DA +:105CE00079C687105E9FE27DC892D0FF3CE31D1607 +:105CF000CF0A7C9F5C7C3E1DF95B3F9F187ECE9156 +:105D000049BDA648F65FB376CE7120783D56EF2A9E +:105D10001C37F377CE9D8741BE4617C92E4CCD1C4C +:105D2000BD627C82C4CF15529E439546BF24139713 +:105D300043F610A37DD61E8BE046BFB9E74195F42C +:105D4000775AD16DE457F54467B4603E50CFC3FC39 +:105D50005C29664CA31C0DD9131340BF0FE4E05C13 +:105D6000981C9C33AE73C6717B2E3ADB3AA83F5524 +:105D7000EB0F0CB0C4E0B9E01E91EBE59E1A27C111 +:105D80003184F9F6E1FA7EA5E36DB518CFFD02DEA8 +:105D90005F40BCE878FFE5C0F47B45A3DF2B91E8CA +:105DA000177EFE74BEC5FB6B6C7FAAF8D02A7415F3 +:105DB000C3CF9D86D3B54A6ADA88AE78E29E2F6853 +:105DC0009DD1E9367A852B411A64A0E3EBD8EFE840 +:105DD0003D5F98105E9D7E4F0F90EFFD070B5FCFEC +:105DE000C2C74B9CD391E28DB4FE60102E2158CFD8 +:105DF000B5E6D1F8834D3CDED3BFBD10713ED07FF8 +:105E0000E6A5F2307355DE2FE0FFFD50BEFF10F126 +:105E10003F2222FE3F46BC03FE3FC6F65780FF4F9F +:105E20002E857FDDAE2FD3F44219EE2B01FFFCC58A +:105E300039333113C62D1415E2FF255B456D1FD292 +:105E40007D5B7262508F2CB9BE7A9F19F870C9B30E +:105E500002F16991765EFD73ED5C4B785E5FF11C3B +:105E60001FE9C9CBE7F7F9490F956D333EBF10E441 +:105E7000DB74CAC7F5F1F393A22617E1F83FA368D4 +:105E8000FAA228D6D02E9C0E43AA4D863CF0E429D7 +:105E90007DFD909F976472BE4FF1B53F9819C6077C +:105EA000DC52FCF800E263BC3015FBCDD7E456EFC2 +:105EB0006FE80AE33A9FE1339EFBCB6A349EFB1BFB +:105EC000DE9462687FCD864CC3FB91FE6B0DEFAF15 +:105ED000DB36D6501FD57283A1FDE8B602437D4C58 +:105EE000E01643FB7187671AEA13DAEF35B49F783F +:105EF0007481E1FDF51DA586F7377EBACC50BFA9A8 +:105F0000F75F0DED038BB85EDC5F939486E70A7450 +:105F1000BCEC5F2A9B547CBE34DBA4E6863E4F7407 +:105F20003B73B1CC73A37F3590BC4CB126A785AE33 +:105F3000CFF9CC6CD06B53ACC67A8155E39774E043 +:105F40001720FECD56A35CA556CF6B02B39BA52CA4 +:105F50001946F9D2205FB758B97EBBC57A65FAED0C +:105F60004E6C7FAA3240E7ECC3E54B44F9CAA2D29B +:105F700047FBA9CC45F9961B6D463E4D1A40AFCC68 +:105F8000B31ACFC38BEA619B649013FDF9F9A8D0D3 +:105F9000E7C2E2DB286F67A07EE5A405B76E017D4E +:105FA00029277BA9D49FAF9A638A9897F790F53BEE +:105FB000FA491BFAD94F0F217EBB92DE7E0AF3CC41 +:105FC0002AE7F592BF946C31E22558770DE67954B3 +:105FD0004E7E8E50E5FFDC54D3782BAEF7FA3C179B +:105FE0007D303311F303D206F09F5ED5E6F15C4DB0 +:105FF000C9AD45C3B03FD5147ABF457AA0AA10FDFC +:1060000098A15A1EF453A6C8F94A3FD5FA198C0A2A +:1060100014ED035521FBA0ABF8238704F3F8779325 +:10602000F7A7C8170B46B7E7F173CB6ED74CB2ABE7 +:1060300054825FD743E98AE729D42BE94912736672 +:10604000F48767F03C6F6306BCAF8F33B914AAF7CF +:106050000A389EE5C78C0D82F1EAFF5B24F8EAF767 +:106060005F4FF93C16A59AE2A7FA3C99B6DFAFC795 +:106070008BCF26CD8A413CD65FDB776E8761FDAC46 +:10608000E26DC77ECFAE37D3B8F50582E1BD3E6F76 +:1060900069C31D741E2B5DE1F32E867923DC9634D3 +:1060A0000E57FD73024B23B8FEF7D243E8BFEC8ACC +:1060B0007661BC0DF0B189E8EDCE3867D2270FF3D9 +:1060C000AA18A434AF21FB25B21FFA9695AFDB4C7A +:1060D0009D9588F654F23546B8C5F566F20717C5A2 +:1060E0002A94AFE0AF59A1D1D538EF554933EF9C91 +:1060F0000BF0D4BD23324CFD7176342D3D04DF15F9 +:10610000B746BBFCCEFE78EF72723801EEB7106E68 +:10611000714321CD9BDA21DC3F17D83319C877DED4 +:10612000E944FF1413C37D9770F8FFD3CAE3C4EFAB +:1061300058559A879C547CEB9641581691DC1DB5B6 +:106140000EB8CE7F68E5EBFC87D608EBFCE5EEFDEC +:10615000289FD37E084BD16DD2ECDAEAEC507B1944 +:10616000F4D649EC57AF8B313FCEC57E07B6CB3C5A +:106170004DD91997B7CBD01E43FED3EDB1BF5A8D81 +:106180007664889EFD4AD3B35F5DA19EBD80ED4ECF +:10619000DD1B8868C724C891F5DC381BC77F952AAA +:1061A00033CAE31B209E9F6D8B6C1F0EB40E5DCE19 +:1061B000CFC88CD6F954D7EFDCDF60C532ED2F9C09 +:1061C000D9E07F241BF729E38751DEED40FDA4AE23 +:1061D000F8830DF1ABE36D88CD884FC0A3D3C6F92A +:1061E000C4698B640F96031E4D063C0EC7F603D997 +:1061F0008357ADDF4B8CE76EBA357C839E9771BCBD +:10620000AEBB3ECEC3B845E5EC73A4E7AF7A9C398C +:10621000C67544F7BF611C01E7DF7DD77F6B71B79F +:106220000E8A17D5BD7A4D0CC6A72A0AFAF48695B0 +:10623000DB8599A407BB7659DC0867571CCFE7ECD0 +:10624000DA35F110C6393EAF399C2985D82D5DAFBE +:106250001CC933437F5D3B8FE4499420E7277ED1FF +:10626000DF575CFCCF3C8F123C27D0C76F56BE0E69 +:10627000ADB7F1F8C9D398C7369AB1F7A363F9FA65 +:1062800091687A1C9F47BFE3F3A17E7F5470E5C7F6 +:10629000002B26DD554C66ABE58DA600968F0A6E69 +:1062A00011E355BE91FC3C4D52161B9101FD284750 +:1062B000DB03088EA3A3D78DDB29EAA7EA3E2C0BCC +:1062C00014EF02C47B5CAF2B097DFC37878DB3A133 +:1062D0005F214DE17AB7777E941FEF294A34B98F59 +:1062E00080AA67670E2F8CC5F77F8BE6F2F258D233 +:1062F00089265C8E7039A038D49B665ADF960D7162 +:10630000272F82EF974D88E77EE905987DC839965B +:10631000C7E367091407B9007881E714FA023EB5AC +:106320004BCC173316F4B089B955F00BEC9342EE11 +:10633000D9C1FF6876FC604DFFF6384D3E33E0452D +:106340007619DBD509EE0C5C4F7781FC0D03FAB4AE +:10635000D558A97CAD464D1806F2B8A72689EAAFF4 +:10636000D738A90CD48CA0E7FB6B5C548F36B5A74B +:10637000D37A2C55AF9B87FEF5FD120BBDB723BC1E +:10638000C47B568E87C8F9972EE69300AE2F353D15 +:1063900052FBD638E2AFA7C600D431FDBFFFD98A81 +:1063A0003F644D053D98FAA3C35953418E9F12781F +:1063B000FE021E188E742E552F9F32B7C4A2A9F06C +:1063C0006B1BF34D4DC2BCC8DE3F158E61CCF6E8A9 +:1063D0009FA64E1D09F3C7FDFE14C6F6DADEABC755 +:1063E00073D8A9FB3FAB8B81F9C86DFC3E9F8982B6 +:1063F000A756407D339BF30B933CB598CFD97337A9 +:1064000073E2FEBE3ECE5E1BB71376DBB89D3951FC +:10641000E0FCC1E6CA5A1E416F6EE8BA11DE3EEFDB +:10642000C0D7748F0F8CB72FD5305E2FC51107FAE8 +:106430002E75FFD7B48E5CE9773D1F49FC7C84C480 +:10644000F32BBAE6266EA6FD78681FBA8FDA2347CB +:10645000B6D7DED2D68106EDBEB79F65F07283A6B1 +:106460005724C6F5FF6BD105BF47B961DE38DA5F47 +:10647000AAD3E209933A7AE5F9767E2F5C3ED413EB +:106480004E78043C0FD7A5D13355601ECCFF486031 +:1064900033840228DD36CFDBD84FD2C24DBE97D130 +:1064A0005ED86571A2D9A3E3ABEE03D98AFA216164 +:1064B000CF31DA8FAA133A64A4F7978F7C4D71CB52 +:1064C0003A737532D56D171BB0FEB4BD7A23D699D9 +:1064D000EFEBA96F003F0CD6CEE1E313D463BB9082 +:1064E000E829583B57EF067ED865E6F52F1F394B54 +:1064F000FCB1CB5C3D9F8DE1F57A98EFAE586FAA69 +:1065000009549052FB65FDE19BB0AEB7FF92DA777C +:10651000DB546E3F2ADE0CA47F5F5D85BA3DA42E5E +:10652000F13AB3F2529F5FC581AF297FB8720FE78E +:1065300047C41BCE13EFCDC375E98C7AD451EBA4BD +:10654000B87336D7D701039FE9E753B798BC2C2A15 +:1065500044CF5E085BFF42CED9B1A88490FEB43828 +:10656000763A03BB342B186FCD642E2A87310F95F2 +:10657000D9DB96EE47B42DBBAFD5897A2B3ED7FA3F +:106580008097E868F41F9ED0F4E2FAE8FC1BA301B0 +:106590009EF582778D887AF165B34AE72F3A24B267 +:1065A000373BB5358CAD3053BD5C3BF76D5EE95D77 +:1065B0003312F5EE2293AB19D7B30C4FBE19BE2F91 +:1065C000DB9DE1AA65C1BCE7B2D896C4B14A30EF01 +:1065D00059AF3FAAF1D946B5C986F7D2E8FB439532 +:1065E0006DEBD2717FFBB37D1F903CBD1F95417C4D +:1065F0005CD17A44F6DA69BF4CC6F3299FD9FAD642 +:106600003F5AF7BE6C19740BEAF52FEB4D74B8794D +:10661000203DF406E83F3738C8876AAC54FEC25DB7 +:106620007D2D9ADE055129D36C60B4BF90E9569157 +:106630008FE6ADB9A6C10A7CF482AC8E443E9B17AE +:10664000954B7C5B162B72BE64B907DD92B6CF0DFD +:10665000F5D43565D3BE533CBEC8686F546D5288BF +:106660000FC00EC8473EA8DC60F2E17EA2C9DA4E38 +:10667000E77DE74531CD8F369E4F5CAFE93BDF6C60 +:106680001EDFBDDC39C592F351741E51AFBF1FE54B +:1066900024BE28917CB4FF5572DE41E718BFFB3859 +:1066A00056C379C8FEE32804873E4E79701CD25742 +:1066B000E51FEC273FF88D6B757BD64D71ACE53B44 +:1066C000B4FC059B7B30F6F3B4A62718FAB18077AB +:1066D00029A3AFEE9340CF1CECD333F90D53D390E5 +:1066E000BEC1F76C92410FB925A0D3C128ADEEFB16 +:1066F0007EE4F65161ED33F5FACC86A993FBC3F342 +:10670000B42D58B7427BE91B4B5F1DE1A373F5A184 +:10671000FDC5E9E3DF4BFDE9FC971AB5F0A00FF8E2 +:10672000EF60AC271FF37C7A673327CAE166498D97 +:106730007285D021358AAF3725E7AF35E03F88F73E +:106740005C03FD4FD5380DFB8A8B8B96D17998541D +:106750009D5ECCC7CF776DCA32EC27FE7F38AE1670 +:106760000EF700704CFD07C331C2305E108E1C0363 +:106770007C570B87183B6B7A06DA6B8F98280F28AB +:10678000D1E4B366A25DF66F268AA70C673C0F883A +:1067900029E30DFBB4997B2CF331FE9E29B1C3D2C2 +:1067A000589427B7B316D7A99F48645FC173AB3914 +:1067B0000E876E72E3FD4F2095D45F66B9B7821FD6 +:1067C000F2E6FB82FA3ED37095E5E3BDA09BA3E71A +:1067D000DF188DFB66731EAAC23C98E795F12F3532 +:1067E0003083BC921DD2202C253BE3ABA8871B70C5 +:1067F000BF767014B75B04F670C3E1E448EFB9BC30 +:106800009E5BF3F0348C1B34AF745E8BFE53B3CDC0 +:10681000DFB21FF3761E53E8DED6AC47FD8D9950EC +:1068200017D79968BD1463FDDB9A71DFFDC96C173A +:10683000DA11CD68BF60FB4714F26B56D538D3F040 +:106840007E923A6D1DD8B276B28A79C1F58A1487E4 +:10685000EBDD2A73F55C3C7731EED18D0DD6EB5133 +:106860008FB91A07A9BC9E948CEB9A33D33A467B16 +:106870000FC868AE75A6A8B1C1FAF06FC0FA203D86 +:10688000B3B1C19D86FD2E2BD5FA3B88718A17E2E4 +:1068900034BC68EF33FBF4D2C606CCCB126B83F565 +:1068A000A930DFADCF723D3518FA47FB0BE6E3C3E5 +:1068B0007B057B874B744ECA06633B607EB691991D +:1068C000B4DFD70C7A11EF2BEE1DC9DFEBFB34F2EE +:1068D0007013EDD3607B5C6F6CC9BCBD3C83DF572C +:1068E00020DB158A37C07A3015F39E14A6FF71F3AA +:1068F000B8A4B68F1185F70184F0A375ED323AF78D +:10690000691D66DC9F97D38C75897916A0BF27AA6D +:10691000C6E737466BF94183580ADA6DC34D3E131B +:10692000B61BC9FC545EC702648F8D621D541F8D57 +:106930005E63161E5B72D241AB71CC2DF238AA4752 +:10694000443B3171AE1E47F24E41BE74476B7661D7 +:106950000AEF3F7EC62CCAF7F569EFCD33863D318D +:106960000DE6B57EC6DDCE50FB4E5F2F75FBAD4804 +:1069700083F9CB6821A2BDA0DB7545365E4F98E553 +:106980007E7A14C611DBCD26BC9FAD588B63166F83 +:10699000C84F44BBAC68DF5CB287D74473BB6CD1D3 +:1069A000FA19B277149EF79A4F767FFEBA0931181A +:1069B000A76FB0B962AE47FEFD23BFDFF54AEDB168 +:1069C000E6C46B0A501E9BC1AFC6FB8F0E9ADDCA90 +:1069D00018E48B75C3C8CE6C8EF2D6C742BFCDFF0C +:1069E000EA74D541FD6736F7F823384E43147F8F9C +:1069F000F726216FF6EDF73F2F5C8C1E78FCF0FD3B +:106A0000FE83B191EFF1BD43C35FD0FEF090DDD9BD +:106A100060F6C4DC87F0BDCBE779D6EA89512F1147 +:106A200067FBB486E70376D6B85840E6F7D162BD77 +:106A3000A4683FDDAF5CD22250DC7C096B223D3A7A +:106A40004C89D5EEA731E6C59616BD4DED4B5B7969 +:106A5000FB32D642ED757AE1BDB501831D3ACEF029 +:106A6000FD1DD1DC6FDDAC781F43FBFF9119D9C44C +:106A70004FC06711F32DE207D877B9319AAF1F37AE +:106A800062DBC8F628F163B87DB85CE0E7B307C203 +:106A900053D57993613D0ADE9F21D37AD4ADF9496C +:106AA00087937CEB6F84F97F9FF54A24A7DABD2397 +:106AB00075825F42F9FABE33ECDE1B2D0F68BAA671 +:106AC00025FE43CBEFF93E6B79C30DFDDCCE02F41E +:106AD000DD61ED9E1214A4487919D0AF411FDC3A54 +:106AE000C258BFDD65ACDF3929F23D7D6B6BD4B494 +:106AF000D07BAAD60E708EF32D8D5E577FDF120BE2 +:106B0000CFEB7B0BE95E81F994B47FC1F3FA141BE0 +:106B1000F3A01ED9BFCF46FB21558ABC1943165599 +:106B2000E0EFE2BDF08A9D9F3740FF17E3058A99A9 +:106B3000B70FDE97C4F751123C495A3CC3953463F2 +:106B4000D4B7871BFD2ACA0B96D846DC770DE627FB +:106B50001AEFEDE88AFE380FFD6398CF6C8C4FE892 +:106B6000715A7D3EFF287F2C5ABBCF399C6E6B3407 +:106B7000F9A80BA3733DD23907DF73B9F952BB876C +:106B8000FF29C143796889261E17ACB3B98E529C80 +:106B900044F30FEAB4B806F37D5DEF56C2EC9510EE +:106BA000FF227DEDD7F5F539E477F338882D6A15A6 +:106BB000AEC30D36BD6EA6FAD3E6A600F9FDAF5AF8 +:106BC0009C181F83EFDD1867F3CD1D417E5D5D06C8 +:106BD0004BC17B0EDEB0CBB4FED6BD6A69C6F5D81C +:106BE0006DF376DB42F249BAECEFD1F9A608FDF974 +:106BF0000CFD0DF976FDC1F8AD8877FDFD1BF6A7FC +:106C00000222FFCE49F91B69ED1F7BA19EB8CB4242 +:106C1000714FFDF70FCACFE7D1FD8C7A7F13144E69 +:106C200087CE1AD5908F5D8E7A3707E5A09DF467E1 +:106C300045CB2083DED4F569C5F91B68BF2C4857C6 +:106C40002D2E21B5935EAA38FFBF68BC3B909E34C1 +:106C50004E12E9F781C74935E8E3E038930C70F745 +:106C60001F6732C1A18FC3DAA20CE79FEBCC3CAE09 +:106C7000726698332636821ED14B7183C970FF60CD +:106C80009DE4B262FF75CA4E35347F287C5F00EF09 +:106C9000C56421F0D5C17A86C1720BF3525E403DC6 +:106CA000F6132207A2D9A562BF62C2F8E9F92EC67F +:106CB000FE45B9BD107D7233F22DD88B3F583B7E17 +:106CC000950FEC49C9EC6947BA4A769313F3686BA0 +:106CD0001513C545EB92AC64FFAD12CA559473BD54 +:106CE0005FA9432238F47D8F81E6299F77D03CC38A +:106CF000EF3BFB9F1B4FA176FDEE573B30D7930F29 +:106D0000FD5B54930B455D4E53D82721F40FEF479D +:106D1000DA2045EC27BC9D8EFF01E96CEE70203D2A +:106D2000BAE3A58879101B95EF9807312F4C1F27E0 +:106D30001CCD0EE0F74287232383F4E54605F5A535 +:106D4000FDCC9FDC4ED2CBB4EFADAF7FE684A9562D +:106D50009E4F6CBC576F20FED3F1627DF341C6F3AA +:106D600053BD947F72393C4882CB43FB007629E2C5 +:106D7000BE36584286FC384931E64F35481EE2633C +:106D8000F34DD556DA27495B69C57D92D592330616 +:106D9000FDD8DE37C1FE83F9353A79BE6A78FF6BDC +:106DA000F01E66B4731553C4FB79A306B0AFBA34B2 +:106DB000FAACD97769FE01F5E1C175372A4E5271F7 +:106DC000DD359B39BC03AD4B7ABF03E1EBD17DFCD4 +:106DD000F71B2C39563FAEFFE1E3354A1E4F3EBC50 +:106DE0006F047870DFAC31CD4DF86D542515FDD5AD +:106DF000E81151CC1AEA6F65CCA2F767E2E3F1CC57 +:106E0000226B8C8F9C97A3E369B7F21DED1D6F1861 +:106E10005F0E7F8FE2E8217CD9A94CE8CF97BB9128 +:106E2000171338FCA1F7A65A338645BC7FB21F7FE3 +:106E300086F14DDE6446E7F70643B919FA6ED5EEE2 +:106E400043AAC0B50BFCF4F27B14A6C2FAE677E4C1 +:106E50005F4039C96BDFCFCFD1B426F07B1EB5EFD1 +:106E6000C3C75D62E7FEC812BB4A65CC51F72FF17C +:106E7000F7375ADBA39C785EB1352EB21F9363D7E8 +:106E8000F3689AB473081DB44FA1B7CF9BC7DCCD8C +:106E90000AC53D1BADE07F25F4B5FFA9B63F0282D0 +:106EA0000BE3DCF9DBEB9AF9F9513E7F8CAB62FB2B +:106EB000C4C48E5C41FC0E74DBC60CF7DB55583B3A +:106EC000B251CEE79ABC997618A7EA684722D65BFA +:106ED000DF3E9D4E7E6F1DB7377B774753DCA03F6B +:106EE0007D6AF979F2F329CC37A83FDDCAA500AD58 +:106EF000ABE5E7D3996F1CCDDB678D0BBEBFD3C26B +:106F0000D8A4B1C8001C4F889F48F430DB4D067AE6 +:106F1000803C5E67D7E88178EAA3B776EF4BA77627 +:106F2000BFE071CD5F612AF7D7F5FBA58E67F7E566 +:106F30005BD07D5BE536F713784F0B3B2252BEE604 +:106F4000C229FCFEC48516770CDA570BFF53146A6E +:106F5000697F93F3FD220D7F9DCC45F70EF8D6DABD +:106F6000F8BE4E987F96F154FEB83FC2F78BDA44D4 +:106F7000CA1B5F3045F161BF79ED05BFC4FDF9E281 +:106F8000C6683A77BEF07BAE9368D72D7CC2E6C464 +:106F9000DF7B59FE41667E32F4BBFCC90CD507DFAE +:106FA00045AFF024595DA0271FDB53887E45833011 +:106FB0007FBE3006FCCAC70EACC2B898F4CD94CFE1 +:106FC0006D507FF4B1775661BCE9B718E7263BF600 +:106FD000DD42B4635F42D0F4FD3FC0C14B874D5AE0 +:106FE000FDC4AAA9A0F2AF4D6835292AFA65275633 +:106FF000E139D9C438F718138CF78EFDB342EC6F22 +:10700000C113A3CE6D80F7E7ED17C8BE003A69DF64 +:107010000B374F01BBBB78B25E972D588F8F6686BA +:1070200038BE3933383EDAD9AD7A7C8B45DD8C7188 +:10703000F7E305D55324E83FC3A1AECE19C9D8C4A0 +:10704000F5F9AA1BC6CF76C4DD8CF198D6BE7D8338 +:10705000F8D5181F6B65DE0366787FD3E3436EB601 +:107060000262E30779C6A830FF41D629ABA7DFF457 +:107070001DE46344BFF3590DF60492934388D2F4A0 +:1070800015FCDEC23EF94EE37CDB571FD1C1CFC3F6 +:10709000E8F5245E6F5D19595FDC12C3F9BA352A31 +:1070A000F2FB664D3F00BE03147F6D8BF60FCF08D9 +:1070B000EA0F901FEB2492A7755C7F801CCDB493E0 +:1070C000DC46ECEFDBCA6BAB76AF79ABE48EC6F88F +:1070D00082AEC7308286E3CCB53B0DFA39AF7D0175 +:1070E000E9D751312A87C7C9F19330C5A84798B568 +:1070F0003D3B74DFFE77DA3C33AED3E33F013974B6 +:10710000DF69F98EFC4B9E9F2DC7387F88BD1D9C83 +:10711000C7548A67F4EB17FA736AFDBB72AE045F5B +:10712000EA65F0154FF8BADC3C83FD19E32FFDFB4F +:1071300093B57DC126E33A224786F3A4CE27807F0C +:107140005388FE2CD6F4A99E07D1BD6B24E54F06CB +:10715000C7E5E73181BEBFC4DF5DF2813E453D96A4 +:1071600027B96FC5F679ED712ADAEFC06FF51ABF4E +:1071700049C86F3A9D5BE3AAF369BEEB04B24BFAD0 +:10718000D941DA3A9AD724D0EF990D9EE715E787CF +:10719000C0A7EB7BE8BF55EB7F3CE7E767FBF8F95F +:1071A0003E941FCD9F67AE0EBA5F3D1CFE852873CF +:1071B0000921EBD5AB368AEBEB78BB5AFED7ED85D0 +:1071C000F201D725077D37F868C0E184768B511E20 +:1071D000505FB57C42F764B6B6890C7FB200E78D8C +:1071E0007A234FD793BE95870A24B25B827AD94916 +:1071F000F68BAE3703566BB0FDB9B52B0BEB51AF29 +:107200006AF7ECC78BA0C5C706E1487370BB7792DD +:107210009745FCDDB81CBB5DD723348F8D2B0AE866 +:107220005E852A6D3D9DD4E1A3785334E27142100E +:107230001FFA7A7DA7A5E315EDBC97811FF53AD813 +:107240002595A6AC60FFF87E6608DFE739381F8415 +:10725000D3E7BBEA27C0830FF1F0430DEF0950C716 +:107260007B2D9804EB17E6FDCC505C6B3242E05668 +:10727000B83E4E104D5C8F5D462EE20731EDF7585B +:10728000EC24CF417C70BBE5018716E7D5EE293FA2 +:10729000680239A17D363ECFEE5DC9D4EF6CADDD1D +:1072A000DF4B2F6FD6F296747BB1E2B5D4CD46F8A2 +:1072B000797FBB1C1C2F7947DD63D08E19EE515CA2 +:1072C000E81FE4B5CFDC8FF924D97BF00704827C7A +:1072D0009EDDC2E514B84BC3CB9BDB43FBAD74D83A +:1072E0007539FBBBCC23FB28E757A4CB7D21725A11 +:1072F000E35038BE607E16C4A764D4A37AF9F7833E +:10730000C3B31FCF2595033E506DEB786B6D99BFCE +:10731000D286727C94B9508EBB5BE69B46215D3170 +:1073200011CC19A21FD6F379E87628F0650BF2E5A7 +:107330003AC7101A6FF85177740EBC1F8E7613C6B9 +:107340007D5BEC7EF423FC0EEF2E07E27356EF1408 +:10735000DC4FAD8CAEAEB5853CEF6BDF06ED898FB3 +:10736000BD22EE1F953FC0F8BDF1DA7CA0A9CF0287 +:10737000E355C820A759540F20DE5A65DEBEF73EFC +:10738000FAA5115629F27BF960FDBE95F8F36D530D +:107390001CD217FD24B493CB454F1AEE7BB2C11615 +:1073A00017AE03E07710BF1FB431C906FDFF1E4AB8 +:1073B000D4D3D3C4A5748E6B5A9640FB44BA7F8F46 +:1073C0007A0BFDA43BBF174DFCC82E3C380CE3D311 +:1073D00009D19C4ED08F55EBC76A1D1B94BFFF4847 +:1073E0001F49FE8EBEBE1D1404EAE7E04DD735D717 +:1073F00085F841D81FEAFF83C28CB4A5C8FF9A1F45 +:1074000047F6617C70DD457B65AC21CEE6D3E0EBD1 +:1074100048473E0AB547D13EEDB3677DF357DF0CD1 +:107420007A76E2F496005E715FCB8A6EFE17E86FA3 +:107430001AD8B336C0C33E8D2F0E66F844DC4F3DDC +:10744000385CA0FBDC0F457973AA95E038895A5C5B +:107450002051CB334F8CE2E50F62B81EFC3C86AF67 +:10746000D737A8BC9EE8881C4798ADBDFFA989EB1B +:10747000F735F991F3D14F68FAF5AAEDDE1C21FC3E +:10748000BEEE138E09DA7DDD946FC7E3FD0B34FE8B +:10749000063B87E814B4ABF87E9D6E879E6D9F4DCA +:1074A000F51382F7BD7B042C3D4F909FF4AE48F15D +:1074B000A1E2586F22E6A55544458ECB0CD2F0F4DC +:1074C000590DA338EF29DCCFCBE6BFB785F5251BD7 +:1074D0009EA47B1D4A999FE2BD451B1A68BFAEC89A +:1074E0002F30A780FE9987C781353A946E110D71B0 +:1074F000E7C552B51C9B13E45BFC1DAED0F7259B82 +:10750000C619EA576F971618F23B827AA790ECBF1C +:10751000F07E753E0FB74F8FD7380DF1EE051B8605 +:1075200017F2CD78DE7E2173D17C17366619EF1104 +:107530006E4CB8B27B82C11EF545845326FDA83F30 +:107540003F0EF8F785C4F7177C3A8CE0F88BC37BC5 +:107550005D8C018E68E633C4CF26F3DF29B4F1F8E1 +:1075600023F08FEF5276407ECC77F507AE1DC01F1B +:10757000C8FD87FA037993B9FE654D02E5E04C9C9E +:107580006AB4CF66C7F0756E764CB4C13E2B9A676D +:107590006C37576B37576B77B9384AA85D2664A1AB +:1075A0003EE3FDE9BF1F9571FA6DCAFFDC10C3ED24 +:1075B000D79FAA6E6F0CF4BB563B77D06FDEDAEF25 +:1075C0004AAD35F7E585525EE0E66F1EACC3DF09D4 +:1075D000E9DD01F63FE8C1FC67DFA07BBAF4EF6E9E +:1075E0005FD132B408F054A9C973B98BCFAFDC15A1 +:1075F0009087413F29E51CAEB4967D8214F25D5A16 +:10760000096FB722C66CF02F7FA2D5FF35C649653A +:107610005A49401806ED52366D1124EC0F7F570B76 +:10762000E049A966FED0DF934A19CFED9ADBC76F18 +:107630001616E604F1D0689A91A3625C3531DA85BA +:10764000EBCC47AAB70EF150FE5180CE494CFCA8B6 +:107650005D42BBBD5B75D7237FEB78708A6A0AAE4B +:10766000A3D11F71389BFAFC62BEBE30F6A86647F4 +:1076700037EB76E961C6ED425AA712578E30FC3ED1 +:1076800061629CB64E2432EF4E85DA3732A227A3D0 +:10769000F924AECC6EE6762CA7F7B42CCF167C3E40 +:1076A0006DF0C8B178DF47D6DA8084BF3BFEDA26BA +:1076B00053C4FB519A35FCC33C9EC5F9E9F3B89C11 +:1076C0005ED0DB9907884FE8F2103D3DB2DFC1D8AC +:1076D000E3F43EFFD9F87BE9FECA7A997E4F4EC7A4 +:1076E0007FB7EA6941BCA6B46C160837DA787ADC51 +:1076F0000E9FA35C1E978DE73A0794FB153B8716F8 +:1077000085CA7DBD4CF4D91C96E7AFDBF77F88E1D5 +:10771000EBEA9058CF3EC44B65DB3A8AEF2CD9C2D6 +:107720007FF76740FC5C21FE8412EE0794CFE1FBFB +:107730005EF9CF4A44FFB27AFEFBACE5DB77F0B8E6 +:10774000CE8F990BF54379CB0EA128077F0773875E +:10775000B028049FA9E57ECA83BFC6AECB1FD75B06 +:10776000E1FC8E7162B4530ED9B87EE8CC577CB878 +:107770001FDC69F69663BBCEE46817E677E9F8FF8D +:10778000FD8E9BE9DCB57DA7258065A3A939C98A53 +:10779000FB0ED7CA2EE4AB6ED57B12E91327795ABC +:1077A000F1FBD878BBAB16BE755AD85855B9723CA8 +:1077B0004C0CE38F893FE67293A43AF4BC86B12463 +:1077C00037AA9DEB2D13D76787CC7C1E3B1987F713 +:1077D0000731EEB3248787E368DC94F2009D1FCA6B +:1077E00038BDD370CE30C85FEEBF7D1B7EFF3F2C0F +:1077F000A14B2800800000001F8B08000000000043 +:1078000000FFD57D7B7C54C5F5F8DCBDFB0AD90DA6 +:107810009BF73BDC100C28246C9E0401D924848740 +:10782000206E0228C86B7947926C02D2FED0FA6DA6 +:10783000168331E56B6BD41645A92E8896B65A830C +:10784000A2060DB82822D64723A58A2DDAA5202224 +:1078500084641BFBC056CB6FCE9999ECDE9B0D0F59 +:107860006BFBF97CE18FC9DC799F73E69C33E79C65 +:10787000991D33B5CDA88C22A4A69A38BC342DFD11 +:10788000E90EE98485900BF06F2221836C3221F19F +:1078900084A43CBD4D522C58BE7F5A1CD6272605C9 +:1078A000BE4BD8AE8696AFA0A95B22848C25E4A0FF +:1078B0008178CC3184B4E82A47D968FD9684487B26 +:1078C000132D3B667345DB687F96639D07ACB4EA76 +:1078D00098633EA38BF64BDAE9C76442DE3012129E +:1078E00041DB1D8C60EDD36D74902242261B89070D +:1078F000BF1B3D2314DADFC1A183B0BF97B7EAA64F +:107900007A697BC320B2D81932EF749B0EDBA56C69 +:10791000DD21E9E8F7B8485A1E323F51EF015B59C3 +:1079200026CC67CCD44E8443DD563DAEA7C2E81CBE +:10793000B66654B0DE68E88FD67BEDE64F8C7EFAF3 +:10794000FDC72FBD6F2450BF5572B4C1FC5BDF373C +:10795000CEC9A1A9E7E7324920643A61FF36BFF0FA +:10796000BE51A1DFA7EFA670A2F5EA76EFD22FA352 +:107970006957A9C5238D2624F3CC6B8B4821FDDEE6 +:10798000662211746EDD3657918DCEFBCD5D530EA0 +:10799000495184589F33F92015F021C49FE1B40662 +:1079A000E725523A30CE2F722AFDB310B246EF557A +:1079B00099F0DD955945EBB7C630F8CC1FCCE042C5 +:1079C0002CEC7B155F97800B1D7F0A8C5F91E5DCAB +:1079D00001FD542446D89B32619EF9AF9929DCEB16 +:1079E000EC923D82568D2B67F00C9D57654EB87911 +:1079F0006DC0F1E263D9F844EFCF807109F1B2EFC5 +:107A0000326921F9C1F67338BEE9771FFB4E863A19 +:107A10007382F3D7E26F834DC2FA61E86C11ACA3B5 +:107A2000F698CFC7E8AC530F749679E630E243D0AE +:107A3000CDCFB6EA3115FDD5D98CD85F9D4D8F706D +:107A4000D90C781A4C53032C9AA61BCC5E0F85C711 +:107A50009BF3261F9272297E6E31FA207D43B7B4C4 +:107A600016CADF4861E3B7E8746B21DF729785348B +:107A7000215E1D6E98CF6B3747217E6AE71ABD26BF +:107A8000DACF8F9F9758DE63F112FA67AD6BF6720B +:107A90006847E222EC4F02FE5C078C73ACFDE94ABA +:107AA000796EBF51A1DFA7B7B1FD27F050DBC6E863 +:107AB0004BEC0701D7203CBDAAFD24F0317FB08DEF +:107AC000D105A5178077CDCE08DB49331BEB02012A +:107AD000FA8C56E5EBDB936D274704F335F007D0BE +:107AE000C10E628179D6F279CED3B9EE83FD5567A6 +:107AF000F61F3450D4161F0DE07E1F887E6BD6FF14 +:107B00003AFB640121AB930E612AF6AD61A87A7F3E +:107B10006FE5786F8294B67B82D34D4D611BEECBBF +:107B20009A930DB89F2D53195FB31C238E503C13AD +:107B3000F243BEDE7BB17D4564DB6499C2BDE27178 +:107B4000C9D644FACF4FA4AB24E26CA3FD7DB6F5B1 +:107B5000F5A82500DFAF2EC8A498AE3782AD7737E1 +:107B6000E73B5D3B29C091DE1B8C24CC7A2FB73FCD +:107B7000E23B22013C6B38ECBB9E2E1FFB29A51774 +:107B8000CFCEC1F6ABE892CF3E3DEBF64FE9BCBBA2 +:107B9000764CB4CB40364D4EA49F407C847D3BA5B3 +:107BA0009F38994C9528DE37B4BD1E358EB6FBFC48 +:107BB00097A3F3816FBFCDF7FD99E7E5F50097BB7C +:107BC0007EF6EC75505EE395624D30CECEC7FF95E4 +:107BD00042FBA9DE510F10264DBF7CD5E8A7F574F6 +:107BE000DE6DECFBCEC136A8F7F913F75F07F06E38 +:107BF0006A6BC2F2334F6CC3FC6B3F7B76DF3F682E +:107C0000BD5A67941DEA9D797E3FE2A5D6A577C04F +:107C10007A07A2EBCDBBF6337ED926E17E2373191A +:107C20001F13742DE8F7F39F2D1E1B2A37C4F71678 +:107C300023973B83981C39CBF76F4D99A505D2B399 +:107C4000CF44CC85F5BA8DFEEC6898CF2846171F37 +:107C50007178D4B6AD31B82DD81EFBF980EE7B48D3 +:107C600073287D9EA2F44E6BEDB85000E3FD0AEB45 +:107C7000D37A251114BE372F382EC17C22473518F0 +:107C80006A709EBF64E574D5A1E5C5EB183D6AE94D +:107C9000E00B9B05EB8B7D90B2BB324D413E60B259 +:107CA000333ECED69752ED6AB2D2EFD7AF73D965D5 +:107CB0008AC7974F1F9E9C4AF33F1B211520FE65E4 +:107CC00089C9398F05C7A95B5F464ED0F9EAA2D9A9 +:107CD0007E49B011FDB5C807B631BAD713BD05F25C +:107CE000FA00F289BA162E0777B0791273206396DC +:107CF00015DB59AE8D09CE83B6B358301FC8B829ED +:107D000007E48E672ECA1DC588F33D23F801F1E410 +:107D10002ECC09EEB7041D7101FE138C34B5307EF4 +:107D20005349FB4F8F2E4D8A2E0AA6098358B91648 +:107D30004EB7F0F21F453B92A2015E3B6355F260E5 +:107D400020BEF2DACDDD4C6EBF721CE9D00D740896 +:107D5000E3BB4EAAE4F67264AE940EF71C473A5C9D +:107D6000DECEF8ABBBBDD4B88CA69B253217E6EFB0 +:107D7000E6F4047464A7F99BA2A3717DEEEBFCD931 +:107D8000C0A7BA39DD75EF61F4F6864EE701F8BC9D +:107D9000B17DE43690075AF928553B11DF6E8A6FA2 +:107DA00093047AD6BAC3A067D555133BEC57F76E48 +:107DB000BE1F1A08EE07777BE572E82F356E9A5DD5 +:107DC00096502F999C4AF3EE5A5204FB2D656BD9BD +:107DD0001EA00BD22E91AB205FEDDC0DEDAF8FAB73 +:107DE000B3CB9920F7B6279969FDEB471463FBCD18 +:107DF000E94A29F4E7A920B627216F70A13CDB9C52 +:107E00003CD20EF2CEEDDA887A175106D9A19CB891 +:107E1000F46BA1BEDBB3806C92C2ECE33D9203CB6A +:107E2000BD91DE08DA7E7A3BD37FDCED6C1F9F13B9 +:107E3000F011A9A173118CD7FD828978A4209DBD72 +:107E4000B9670A93B32F9A50CE9E6D749013543431 +:107E50008F8C5610AF028E35AD993AA05B42669971 +:107E6000601ECBF83C5A0D4C6E44733990752F9BB5 +:107E7000C772BE1F9647EB786AE4FBAF95C9059BB6 +:107E80002717E4E0393E1E924502977374E8BAE57D +:107E90003EDC27B54FB3FEE24C8EBCDB42E855E832 +:107EA000475A7A6CE2E3A66C3D20013349D95AA5C2 +:107EB000DAE7D757135F3D5DE7F55B75BE89B9A873 +:107EC00037DD82FC7C83916C97FAF7774F34E35B64 +:107ED00015B1CE3C09E4D7CD16D43FFAF6E9208798 +:107EE0002E02F4B87CC9DE84AB7016EA68BDD309F3 +:107EF000563BE0ED471C8E5A7DABAFBD460F9CD183 +:107F0000EAC9254369E9864173019E545FB798A188 +:107F10009D8DB6A7F512B68F7B6213F2AB26ECF7F8 +:107F2000F6681BEB27D659D8002C2ECBB98EC92763 +:107F3000AB3DDC7AD2A3859EBD284F07F433DB82AC +:107F4000FBE1C7AF484B19BD514128013DB2FD418E +:107F5000E8FE7852417A443DCADDE0F486A747B690 +:107F60005FDC54AF023D9BD2E35AA6275B08DB4F90 +:107F70008C2E23A73279007C2B549F15FB54BBEF2A +:107F800005FDF6EDFBCBDCEFDD06B61FBB291C8043 +:107F9000DEFBE8FC6546E79B36D0FD48CB37D1FDDC +:107FA000D814C2FFB5E71F98279C0704BF3D66732E +:107FB00076005F746F7FAB19C996F347F7CB3FC864 +:107FC000BE98DE6586CAB45F33DDAFA1F463A6E078 +:107FD000B6E663EA013911B95EAD4789F4836826D4 +:107FE000BFBEB1DE3842D2A3DEC3F155AB737D0014 +:107FF0007C1EF4464A1124633DD31B1340E600DE89 +:10800000B6477A413F4E4820AEE7C2CC673FDF67B4 +:10801000029FE2FC9010C5EAF7F27DFF29AFF74F0F +:108020009E869C4B703F283AD771220F2C8F443B81 +:108030003A2F2C17F3E93BD798D97C13EECADEBE52 +:1080400029048FC17D75753EE037EB5E9F7EA925C3 +:10805000388E908B5ABA81F983FC81F5548E1AB808 +:108060005EEB7E7E3ED3D07104DF5F7BA8B882B426 +:10807000D5E0FB2BEEC7355602FA222507472C9D8B +:1080800057FDBEE16C1F8D086443FBEA58D74D31A4 +:10809000B4DF3193F8FEA0DFABE09CA0271E530CA9 +:1080A000E0DDE0F587E0F9D318D67F8FD5EC91E9D4 +:1080B000FEB823D6150DED3D65C4EE03397307E513 +:1080C00027B06F89AF08F84D3DF147019CC7585D57 +:1080D000F13140BF726736C9A2FC57F2E7C2F763BD +:1080E0001151B984F6F371FB6F9F7985B65AF8CABE +:1080F000B985DF03FA7A312203E8E218D5973B51BC +:10810000DF560683BEDD4B94C1B630FC57A40BCCC2 +:108110003AB3BE20983F66559F2F447A4D0CC36FEB +:10812000FDF914E28985FE099EBF7B6214F65D1F8E +:108130003082EA567F3E8378687F1FEB48755B98F4 +:108140007137C5307ADB4DC8D470E5F7F171760F21 +:1081500065FB30B04DF2027FAC5EBFE1CF32E50788 +:10816000D5EBAC3E4C6931E86FD5368F4F47F3C73E +:108170000C8C1FD17FB3CDC541B947EBE9C7030EC6 +:108180003CF4204BF9E0522EB79635BCF925D813B4 +:10819000AAF5C43C9EF6B3DCEC3C984A8B3EB32C6B +:1081A0008F02B6BFF23BB725805C4A5CD0CAEC3286 +:1081B00064920DF45EC93143BE1079313D4B8FFAA4 +:1081C00031E29FE2EB8B18E74CC0F782C104F580E7 +:1081D00005B7457A3D217CD0CCE1A1A59B4FB87E67 +:1081E000A5ED7F766C1981FE3AA29C73813E16DC68 +:1081F000764EC5CFBA25FF538F025DADB1DA9F64CD +:10820000DD653843E8FE3B62BCF33AC4534F5E671A +:10821000F6FA4CA0DF40C68760CFEA30D93C0A941A +:108220001B11CFA2DD9F1A29E3CB0EE6979E1E36C7 +:1082300019E86B19B13703DE97B544124F083F03B5 +:108240000518E8C37D9E603F4B3BDE3C0AFCDCAD7D +:10825000F7239D2C355B108FEEF37A9C0769317400 +:10826000F9457B8AFB23518EDB607D9E7BC6479F51 +:108270001A493F26D2EFB87ED7EDF0FDA1C828E21B +:1082800000FA784BF60EA7F3EF352B836328BCEA90 +:108290008D940E4663374E7388FE43D2AC6AFC77EA +:1082A000BCF525CC67B9D9650439BEC241CFA73228 +:1082B000E0C957641B158AEFF1F28591978FEF455E +:1082C0007CBF7F6CA4F41F661FDDC7E1DF23EAA536 +:1082D000B07DF27106A97E0ED26B684ADB7D3C94BC +:1082E000E7F3793E9BD74B60F91D7C9F7C9CCBEAE2 +:1082F00069C7F1C530FE363BD6B115E045DBF98CD8 +:108300004017FB22BCA8B716527E07FC6D6D3AEAF7 +:10831000AD94AFEDC07AD9C4178DF54C28574803FA +:10832000E57BB0CF8B1484CFA6524A27B43CB0D79C +:1083300064DBAE04F12AF0A9C5637B8CF4EFC9C3FA +:1083400051923ED48E42E5617B0CB3A318617FD27B +:108350009918999E360CF18574225F3EBE6E8C6032 +:1083600078A0FBF4B518D47B7D39A1FBE504C79751 +:10837000E0671F0F52E3B58AE3E16D5E6F518C8DAC +:10838000C94F7B00F7DDC731AC7E5C169343420FCB +:10839000FF0387CB4D9A54C8953153D5FAC54D1C70 +:1083A0009F37C54409BC7E08F315F288F2175F3485 +:1083B000DD0F0B5E35217F211B03D9B0FF68BD6344 +:1083C000586E0A2C8AA572E426AADF18F3B1DD22C2 +:1083D00068DFEF3C3F4AD08595809C3E25D65318F8 +:1083E000407E4FE51DAE6B29A17C43BA34FE37D0E9 +:1083F0003AC994D6870C56D8F94EA60302ED8F20C1 +:108400000AF447E1FEE750B86BC73BC6E9E09F318D +:10841000921EF19647F2709FBDFF857521EDF29C8B +:10842000CDECD151BEFFB8CE7501FAE9BAFD2DD41D +:10843000CB8F197DD9AD9630E546DF630F49C1F288 +:10844000C53F973D46CA2F767776FDE466BAEEA51E +:108450009DB21D865C7AE75FDF1D037A75A7C10EAA +:10846000E7462ADFEFD5C3BC1B981E794CA7A6832D +:10847000B3DF559F73D26219BEA8DE83FA9CE03B3E +:10848000427EDF4A7C57815C5F461C4648FFB466EB +:10849000D50C42E1B7C2B20EF9D1E76BA7A11EBC61 +:1084A0009278B07C598BE14FA1F26145AB3ABFEABB +:1084B0006175FE56AF3ADF677F2E0F2FDFA7C732F9 +:1084C0003A3E4BD93EE03FB0C1E4053D485BAF9832 +:1084D000D7CBA43CB113F82495FB60475817E1486B +:1084E00004BEBE6E6F69E2C5EC7CF5E7AF21DE101D +:1084F0007D23A837E4126F6CFF7ECB63158423F4D1 +:10850000ABF071E0BC71B62CFC3A26C60A3D651092 +:10851000F627BE8B7E82E345E13CEACF9B07988F2E +:1085200005DB9F5D197E9C1BFAC6B1A9E464B07D92 +:108530001C936BFC1C2DE8A3FE7C127E1779A1070F +:1085400007DBA531FD8AA4D94E4506F994B0638BAB +:10855000FD704222E664B43BDDCFCFEBF65CB05F4A +:108560009F003D08F6E314659F9F4E71D9F7C666DC +:10857000EB8706F78B761D94AECEF843F8EEB25833 +:108580006B1C8E6B27761857D0FBA2DB2B06BBE843 +:108590007CFF786779A26B54283FF530BF8951E89A +:1085A0005F16959C251A39BCACFD2DD4BBA8BE9591 +:1085B0000D4CE7D3BDB723BDAF24CE04A0F39EBDC1 +:1085C000C3335CFF86FC15F399E559622098A79B9D +:1085D00098EEBF2A3E9F591D4CEFD3991D061CC72C +:1085E00041145B021EA5D97C29F3D4D3FC84BEF9C7 +:1085F00083918E90F17CFE12B4A7F09DC053B2D44B +:108600009504F336C1B874BC08E24D82B469AC5D20 +:108610008174A2E4D4B379303C4F260D69505F6772 +:10862000F6CB6C9D740609D0BE0F5E98B7F2FCC6FF +:10863000D9BD8B56C0778B15F98891CF63472CE550 +:108640008766E42F6658B7C9E2FB1CFD643CF594CD +:1086500029B88F3D4309DA3B06913602E35A2CE7ED +:108660003CB0581BB149908FB0F5FAE0FC70CE6673 +:10867000F1E846239FDC190B7C527A6725E085F2EE +:108680006566FF19A85CEFC373B7E073317C7E4D5C +:108690009CCF2513068758E2C0F11EB0AE9C414026 +:1086A0008459D649D07E4BD454F4EF2500E0697943 +:1086B000EC54BD8A6FC53BD5F9C4B9EA7CB24B9D79 +:1086C00037D3933FE88B92CF99742116CF5923C0AB +:1086D000DE62E0FCA299CFEB08A4743DEF713EFD91 +:1086E0008DF513BBFABCEE8E3112B4E32598CDD0D4 +:1086F0003FD557DE8B65FACA271E289703C8CFF3EC +:1087000026B6F9C0AED37C8364BF8B7E6FB62A1BBE +:10871000F494543DD32466C7D1DB4AF5B47C5B8620 +:10872000CDBE89E6EBC17E1D0BF3B7D53C8DF64976 +:1087300013AB4702CDE08FDCB6C966837A71E58161 +:10874000C946D08B5710DB761286BEBFA2FB86CE01 +:10875000F709C853BC489C5E220F29F3710DBC7CFD +:1087600007FC9DC5F2138BE15CCAFE6575E4753AA2 +:10877000C0EEE090512ED677E4BD6EA1E365CDCE7C +:10878000433BBCB39CF97309DFF76334FB6A5C902D +:10879000CEB13C8FE7877570BB6E9C89F96B6D74A9 +:1087A00088626636C0FA718CFEED44FC63FBF25AB7 +:1087B00012FC07FD9507FB473E3429581CDC677403 +:1087C000A87CB3BDA996D61BA3F7ED877D3C8EA7E9 +:1087D000793C7DA3F40694BF9D3A8B62D4B17D6D44 +:1087E000CE0213865306B814DB7ED004FD4C907C79 +:1087F00098664CBDBF09A65FC5ED47D14946EF0657 +:10880000BA8EA6128A67B477FCF920D8A5E5074985 +:1088100001E0E98841C839079ED3157A1CFB1A3A52 +:10882000986C40FDFC2F932AF03B01D58CCEBBD237 +:10883000C61621BE0F2C5F75283F6AE364E437B388 +:10884000A632BF6AFD5CB3579240CE10E677D2BB2A +:10885000326F0AB197083FC4FB0632775798F3444A +:108860006D1CD34FAB66303B6FFD46A3CA7F531DD3 +:10887000C7EC5E33E3268F8C4379C4FCA779715C27 +:108880006F1B4146009F0AE1234550AFABF4ED81D9 +:10889000F88CBA9CF399398E0203EAFD9CDF08BE7E +:1088A000EE1CC4F6F33C42D281AE679306E4FF8728 +:1088B0004B6F457E7313F118006F1F95B17802312D +:1088C000EF5953D57AD21CA73A7FF35CAD1EC5F0A1 +:1088D00021C69DE7529757093D78AA5A0F5EF0FFCF +:1088E000BE8A46B99AF854DD8521E0E760F600C0FB +:1088F0000BF373E8916EDC1B993FBCBE3DEF8D38E6 +:10890000D8677712BECF7649CBD1FFB24B5A1182CE +:10891000FFD45AAF047264B855D87D98DEE4347938 +:10892000F783DFC359831291BCCEE3490E403C4923 +:108930007E90BEAD65561657411CB5309F345BA482 +:108940001DF4FE165D3EDA655BA2AC2A3BFAA60D6D +:108950004A05D413F658C544F26D9C6EC29D77D774 +:10896000C531FEBA59627671CF3C339E2BE3B39C7E +:108970002A3F41BC4C8E829D70649C22EAA3FD6319 +:10898000B3C1955C4053AF44971117D25E261BD1FB +:10899000AEA8E14FF1B176B4EBC70FCE413BFD9CE1 +:1089A0008E3CB42F124B84FD2A29D8FF9CD9DBF4CE +:1089B00010A753DFB14DBFDC12A4BB7BE2B85C8DC6 +:1089C000249140AF7D76BAE74C68A77B5CE7FC5FFB +:1089D000A0CB5AA30FED7121F48ADF07928BAB383D +:1089E000BD18CA9CF356D0F9F5BC6BB4C3F9191D78 +:1089F0006DB4FFE7F744A39D515F45503E6D2C6574 +:108A00007CA407EC5F741D9F4557E3F960A3D48AEB +:108A1000F2A33B6632D2F16ACB013C07576FA574D3 +:108A200018229F56EF50E76B48279EDF6B9FEE475B +:108A3000CFC817051F76EF56B723C3D47C378FCB2B +:108A40008B7CA77D56054C7DAE3D8B9DC3E9418651 +:108A5000AEA3E81D23B7EF2EB09D8A0056FB947499 +:108A600031FDADC77A5A66FB9FC983223E8E566E92 +:108A70001571BDED3ACABFE0FC2AF4B022C2F2077C +:108A8000741D72922E38DF42DE4EE87F424E087C23 +:108A90009596105242F743A7E04F43C950C037EDB7 +:108AA0001FF78904914331D8BF07CE7DE3F878944E +:108AB0001E3C20B73D3AB317E8AB596A4039690606 +:108AC0003D9FA69B2417CA8397AA3D32C07B2C6981 +:108AD000983583D61B6FEE8C0438513A39124A3FD1 +:108AE0004DC497B14B52D111967745BF1D968E84D8 +:108AF0003CF37DC4F498E974C5D04F05387E687A9C +:108B00004062E7C829961FEBA1FDDBBA69482753ED +:108B100089570FF3ABB0A9F13F25499D9FA6F4A358 +:108B20000F8CC37070784E1FA12E77087E47D4FC3F +:108B30002E937C857A18F9C1C1EF805D21723D19B1 +:108B400001FA0DD544711F6AE9E0EBB86FDD6FF2F1 +:108B5000755C18BF490FB7135F4BFC2B9F96FAD378 +:108B600059F71BEBE5A4107A14FBE265038B7F90A9 +:108B70005E65FEA9123319E503FA2A647645B13F12 +:108B8000AE05FA8C09D25D31FF9E11CFE96C081950 +:108B9000027436A13DC22753BCE4F1FEAE05BACB48 +:108BA0000FEA23E25CD154D28FBE32A52CD45F7081 +:108BB000DF097DA4406A6BD267021FB9A709E61BD3 +:108BC000424F43E38B802F517AC27DDA4FCEAACB3E +:108BD00035F426F02EF4E552D28074365BA760EAB5 +:108BE000AB5C85F2B5DC325B0FEDDFAC62F43609CD +:108BF000E8310BEAABE9A5DCACCE6BE9918EA80BB2 +:108C00001D574B9F03D1DB10A037215F632F4D6FA2 +:108C1000D3E3BF757A9B1E7F117AD3D299E05FBBF5 +:108C2000226CE5A03FD7574B280F0ADE1DD604F96A +:108C3000E17599A84FEF8AB6A37E5DDFC0CA0B3BF2 +:108C40001D32C4BD64ADE3E599CE72C8D7AFA7E5C8 +:108C5000B4EBA2232C2E66D89DAC3CEFAE86D7ADEC +:108C6000A0677858FB973F6F96A368B9B799B72F5D +:108C70006D2D877C7D0B6BFF19F8A946437C9AB755 +:108C800009BE5F7D6FA69D1DAB99FE3E91AF7797A4 +:108C9000F4DCEBD8AE95B55B75D03C88E0F99FE984 +:108CA000E5D7F1754EDCCAD61977E2FAA90AA58B89 +:108CB00015010FEA6FA774B5C5C8DF06383F974A9C +:108CC000AD69904EA1EC175287D9DE220F657ECC9C +:108CD000ED74887BE299FD45F8FF20CEA032449FD9 +:108CE000B8279ED96345BD84188A01A08747ACA8E0 +:108CF0005F0BFFA4EF212281BC8735723D24ACBFFE +:108D0000724A5603EA115386083FA55FBF948E9BB3 +:108D100077E18BC9E1EC433FE2E39EE671137D7A94 +:108D2000B237530774B10B88240580F4DEAF417F5E +:108D3000DB057E4826A43CA404F0CAF25BE37FBDB9 +:108D4000A9653C85AFAE41EF01A1962161DCC9CC9C +:108D50004EE21B1CD57FFE53F4C467C4382636FF91 +:108D6000954D541E23D1317E3687E38F8CBF0AE99F +:108D70007736C7D3CF057F2A2005C09FE670BCDDBC +:108D800064A67A34F2C35683866F3C130F726ACBA3 +:108D900080FABBBA5CC357AAF9B82BB9DE7E2B099F +:108DA000A07E724AF2627A7A0BD3DB6B2C4750BFFB +:108DB000E97984E9EDB5C48FFA8FD6BE59B3539DD6 +:108DC000AF6B53E7EBDBD5F99E1C0F8ED3B3A5AE8B +:108DD00018EC8AD50FBF8B76EC6AC15FBC6AFE4285 +:108DE0001571C65F1EBA06ED51DF986F3C4D4F6F8F +:108DF000C5AAB8D0DF029CFAEC352FB2F81437615F +:108E000076821EEB88F9704E251A79A4E527799CA5 +:108E10009F08FB86E02F7984C9237A8E7DD7418213 +:108E20007C5CABD7F5C473BD979FD384FE9307FAE0 +:108E30000FD0D3350D48644139647FDB2487C89F48 +:108E4000798566C073BE99EE6780976CC971595475 +:108E5000F4F005CA9981CF7BEA720DBD88F3D62D57 +:108E60009C5E668127858EFF7BC981E7BAC3B732D6 +:108E70007A99635987F4FAD16A462FE2DC77E5E7FD +:108E80003C87FC4DCE797D741241F55E9A1E4917E0 +:108E9000E77CE68FAF97181DD4557DF818E8CF8290 +:108EA0002F1C6E24F1FA103ED134CD64063B4A9358 +:108EB000819D83AAA67F5CBC3484CF38224A1313D9 +:108EC0004059EE8847FB6C5DA47A9C66A9F3BB7F92 +:108ED00080F3D24F23D14ED4FB304195A477EB7071 +:108EE0008CDB3E6B607E52319F550777EEF3C37E7D +:108EF0005CFFEB083D959F3592F7C55A5AB6C4E41E +:108F0000CA86716A743E23B36376A25F578C3BB006 +:108F10005DD683F2D5F81A93C3016910C6E1D2EF8A +:108F2000D9A1FEB5D1898C4FDF11EB2A48880FCA31 +:108F30004B613FA45296A4C604FD26C1F8066637CD +:108F4000F90B715C32BE6163887D9EB60F1B8F5634 +:108F500096C0F8F5F729CE61DE07A31DE5309FD353 +:108F6000DC8F7B9AFBFD4E47313FE0CCBEFA2C757F +:108F7000F1F434F7139E8E51FB8744BDA509CC8EC6 +:108F800072B2D16CDEA807BF3A316F1C4649EC21A2 +:108F90005303C6932C6078EAD913BD6D5388FFA59F +:108FA0002EA1F4FB309F7FD89C3743BABCF5B83173 +:108FB000D40EDF23B1F3770FA7979E08968A71EB43 +:108FC000122ABF0F78EC99E7473CF6E5C78ABC1335 +:108FD000FBEF99C0F86B5FFE3B2C4FB8DD43D8F533 +:108FE00007F2F769FD7B54D0B0734004B3CF6BFD3B +:108FF000F30B053FE3FEF9059C1F2DEC607E8245D7 +:1090000066D29C4ACB177724B2736E94275BE59F98 +:10901000F7445E513C86A0CB9EF4CE3E7FF62321E2 +:10902000FEEC3AEECFAC13EBDBAD5EDF0309DFBA4B +:109030003FFB818430FE6C6DDCC38BA0470C0BE2E0 +:1090400061AD8DC1AD42AE2D077B6FEF728271E8CD +:109050006BDF5AD604F6E0B53F000B2AF231D4A7F5 +:10906000EB389C075A57BC534714959D7D105142CD +:10907000E69FEC8A51E551430F89034DAD4E51B542 +:109080004F6F18AAAA3F64FD35AAF24C4FBE2A9F23 +:10909000D572ADAAFE55AD65AAFCF087AF57D5CF06 +:1090A000234307A3FDEC900CB62172B5B74A553E99 +:1090B00072E72DAAF69F9186CDE369BDDD42FE7968 +:1090C0001C9DA38A8371CE396D4B55ED9BA4B6626E +:1090D0001FF0469FE49368BD151C5FCB3B99FF6270 +:1090E00074FB6A55FF67A3D83D18AD5F96762EA333 +:1090F0001ED62E9147A4FE7EDAEA8EFB9B21EEA8B7 +:10910000BFBF96F24DDA6E353DBF80FEA6D56F8E9D +:1091100026703F5D0A496174ADA50B0BEA7FBD5B0C +:1091200065B427E691EC87C623BC0CC4ABF4C75FDB +:109130002F6176AEDEA7AD7688FF59F5D632A4470B +:1091400053929A2E2214355D448E50D385D5AEA607 +:1091500083C1256A3AD0C23DDAA1A60BE2A7FF433C +:10916000E02DE02AE01E3B554D375A78E79300DAB0 +:10917000D9DD5EC9EE2361FCE2EDDB705D97D21FA5 +:10918000F5896AF8161C703459106E2CBE4CE861D3 +:1091900026AEFF68FD1342AF894BE47A15EF47F81E +:1091A000179A250FEA517DFEC2125F862F13F4A78E +:1091B00006C2EC44CEA4C4F07646FC3E909D51C05D +:1091C00075F620262F6B8803EDE12B880BF9DDC99E +:1091D000CA5BD13EB4CAF263F4BB9EAD627A52352B +:1091E000F1229FBFE2B802AA879210FBAB168E5203 +:1091F00087E4B302BFE1F22085740879E0C27813F6 +:109200004A86E662951F47ADE782DF30847F09BD5D +:10921000578C27E029F89A18CF441AE424D8171A53 +:109220003E474668FD486A3B8DB0F3E06021FE2270 +:10923000AD5D26440F6E91E938F290CC2642F1578D +:109240006073A0DDAF8874CE87EF25E6B626BDC279 +:10925000ED1357933EFBC480F2EA12FEE8591EC993 +:10926000FF68667F3FB4F06BD3E59FF8036D3C5E0B +:109270005210EF552F0F8F077AEA6FA7B41F7D8525 +:10928000F623EB02B1A1F6C3BEFB06921FD7731300 +:1092900071DC4D42F41037699B3C3F13ECC4544ED3 +:1092A0004641CAEC58A45DAB07EBD18EACA32B01B1 +:1092B000BAAF21217EDACC6039E6E5FE7911377448 +:1092C000297DE242A28DC73FB07827C2F9A0385F5E +:1092D0000E749E13711470CF16FC21224EA8399182 +:1092E0009F8373492EF44FF7DBA644B41FD0FD29AA +:1092F00085EEC7BEB8222CEFB71F35EB177114B23D +:10930000B510ED42CB42D77B19F0107ACB6FA83E57 +:1093100080F7341215A6D70D3AF681038A0B3B5518 +:10932000719EF5467A80017BC18B3C8EAF4DADAF0F +:109330003F9BC8E393F839E752F01A181F3CEE4EF2 +:10934000E0E332F530117727E0F8427FB8EF51C102 +:10935000B5EFBCD807F73DE1E02EE072AEA8F329E7 +:10936000C0976C3D9200F0EE8872EE83FAE947FDFB +:10937000A7245D705E157217C6CBF6B6CB783FCFCB +:109380003D81C55BB9F7C8C81ABA3B4CE837AD6E2A +:109390007F1DF5C2AE46CA68A91E76A6910EA9BF6A +:1093A00088BD4003EF81CE47623D1F68D62FE2752E +:1093B000E83A7F7F0938FC3E1C1C2AE45183E19E79 +:1093C000575F9C913E905115421FDA756CE6F4B0E0 +:1093D00056EF3C01FD1DEF4CDB0CFD55C81D07533E +:1093E000003EEB24BC7F35D1C4EECB26F3FB7425C5 +:1093F000FE063BDC374E4AB3E0FDA9E1DF919DE07C +:1094000017FE78DD6D31704F4CF43F5CD2E1FD4EBC +:10941000429EFBE48E42F0572EB06FA2B98526160D +:109420009791F9DD485F16E523AF1A8919F6A36114 +:109430006803DE6B0944CB68B78C93C924A03B3129 +:109440006F711F567C87FBFA70EF527C9FD81428EF +:10945000584BD30E4E0F62DD13CB03050D9620FC47 +:10946000455CA6163E5B383CDCF1C666D017BBCD2A +:10947000E2FCC95262D3239F596766FBE6D855E2E6 +:10948000FCEDB3C2B9D41DE1183C06F6DFFB32791E +:1094900092267FB1390647E3FA15D4C7D7D958BB0E +:1094A0006E1E07BFEEA3B244885F8E6F0A1F6FA6C1 +:1094B00024B1735C2DF7EF8BEFB57A1FC68DD542C3 +:1094C000BC7641F0FB95C66B8B78FC01E110AD27B3 +:1094D000FAD178EFDC79B17AAFFC4B0E7BBEBE3EA1 +:1094E0004927E20FD1EF4DCF5B61E30B4B93D8F9E6 +:1094F0002A1807E8C77BC37DF1857B4A13C945CE8F +:10950000FBEEF30E55DC9F8837779F9F84717EFDBD +:10951000FAA5FD2996605CE140F0DF92C8E6E58699 +:1095200078BF82D0EF0AFBDE374E1C8FDFF347C1D6 +:109530003EFD45BB8CF7EA7F714837757B9879D73C +:109540002731B85D13AFC77D33D2471CDBC28C2FE8 +:10955000EA89FB35E29EAA767EBBCBFC8B60FE10CF +:10956000471C6EBCA59C8EC4BC77C7307CB8F799ED +:10957000F09E05ED17E3BD77C7F857E2BEB0A9F13D +:109580007C3BB7D7ECBEDE9F81F7BCA6313BC34026 +:10959000F4E08D72FD04F5D89B69654A3FC5FA0673 +:1095A000C916B2FF2E450F41B8EB5478ED0F772363 +:1095B000E257F4FBF961BE4F89C302E7B7255CBEF1 +:1095C0002DD95183FAAF381F7DFEB08CF1179F1350 +:1095D000E627F9BC55C2F3CF521721EB291F5AF9E0 +:1095E00064413388B92549845C17C3BEDF09E94665 +:1095F000B59F7CF9BDFDEC872454AEAE200D2857F5 +:1096000056FE58DDAE9ADCFB67D09FB4FEFBE1DC72 +:109610002E27D6B139899E4740EF2926C5201FD66F +:109620003EF985314A19781F9CA67C77981EF8AFC1 +:1096300019D3AE461BA6BF48723C9644F1B727C962 +:10964000B50DD29EF759FFBDB5BD4C7E6C8D43B9AB +:10965000D564FD2EF2757908E3EBF7C03B09141EC3 +:109660002613D39712740D7214EA2D5EA487E3F1CA +:109670006BAA6662DE9E04741FF7CB295331CEEFCE +:1096800097910E80F7A652471ED8253655B27B9982 +:109690006613F3B37B7F31F63570830C6BBBBF0C65 +:1096A000CEC1B68EFD3EB0F7B4E8FE7C10E2575A4C +:1096B000AE63F18B093AFFFED490F1E223BD49E09D +:1096C000878F1F69C4388F38B934AF21245ECACD63 +:1096D00071D1DB9E8576C21E83B01BB645E0BDA866 +:1096E000DAA183818F5C43189E45DC1BCC2154DFBB +:1096F000EDA27084A04B91BFA64DF219A2F0FD120D +:10970000F4E3D4DEE54B980F72EAE77AF48389F943 +:10971000C5BD9A5C06FE2E219FE64B366647E3FAEE +:10972000FC3C22FE317FD95C4E27F3B81E3F3F92AE +:10973000C17B29B16740BB5BCC244A47B7D4FCF25C +:10974000B6225C678D211AF405E1F71958CF086F2E +:10975000FF723F6565F78DA54036747286C2E76279 +:10976000FB30C0F9B23B9BDDBB23C38803FC8CEE0E +:109770007DC3B7817DC23488F9AF297F3297E4A3D6 +:109780005E6D8673D4ADAF44F0F8222FBF4FECC8A6 +:1097900083F89CFAAAB47C8C13391AC07737BA0DB7 +:1097A000FE0CDCC794EF4854360EDAF2FD197AB895 +:1097B000AF9942F5359A2FD9722FCB0FF5AFD4D18F +:1097C000FC922D4FCDD0D3FDE1BEC67F0AF2355BB2 +:1097D00076B17CBE7FA54CF3CD5B5E65F5E160495B +:1097E00009ECC12D07677868FF67A2B9BCB7FBF128 +:1097F0009EB5FBE5E1BA503B6B6332E35B67B89D16 +:10980000F84C26595C05F01E11BEFEB2641D0F5ABD +:1098100069C554AC57B42749E1DB25F3716EE5F710 +:10982000A32746929608E6B7F344513C1CE8188EED +:109830007EC7AF9362989E6EF3E3FB38A21F014F81 +:10984000D19F187735C867E0CB9A78ACEC64863F37 +:109850003ACE461C679883DD2BAE4ACB03FC51BC45 +:10986000E939DEF4ECFCBB8DCD8FF61B9D8B72A02D +:1098700000ECF807BEA2F53383F3D6D24941329308 +:109880002FB736317F6B203A0BE96962247F67A5D9 +:1098900050BD8E660E87C6E4687E6F46C02B51C2EF +:1098A000719A381CD3FC78CFF24AD75DF11F5A77F2 +:1098B00008BE1CF05ECA81F6ABB7B3F5C4F07BCD31 +:1098C000FE8C18D4F7EE57F5776683A67D09C1B8EC +:1098D00036774C16B6BF278298F13BD9DED72E33A8 +:1098E00097E9ADA0CF8A772C88E73A12EA47EC7B5C +:1098F000AFA28DC56706D739A390AFD3C6D769632A +:10990000EBF4AAE8951C0964CCB6F6A7E33EF8F799 +:10991000F5372A9FF7A7DAE7E1FA837D3D105ED697 +:10992000733AF9D6F022E6A981671F9C35F313F04C +:1099300084FD8DED46A9E952CCB326599C9335FBA5 +:109940003BF31B8E57CADAD5DDCEE2B989A2A6EB6E +:10995000BADD993A882B10ED6AC127101FB4FF3D7C +:109960009ACCED8969246D80F8C4C7938BC2DA0D57 +:10997000F1BBF69CD813CDE2D5B5F68A9E787B274D +:10998000DCAFF49C63EF0A8CD3D86FC0CFF49C2576 +:10999000D82E285FD4F9739C3FF6B73F0532607E1E +:1099A00085A6B2E7153BD547B61C437E5D38B8ECBB +:1099B000B64C9A7F35F98FC8CF0B53CBBEC8A4FCE9 +:1099C0007C7FB29FE547967D3114F25BFCACFE4490 +:1099D000C7F3C0EF89C73F63527250AF782D59412A +:1099E000B8C9E53A027464022586AEC7F4AA09E351 +:1099F000F6045C074A0B4DBA8670F76FDFEEA307DB +:109A0000E65729813F15B0F3713B805FAFB203F495 +:109A100044B17BDF3D7BFF8EF75D3E487675021ECD +:109A2000EA23BB1665D2FC5D919FA01F4F72D03D0B +:109A300001F615C54616D0F94A5D9B9CA03F91D50D +:109A400076B31EE1CAED5E748D1728FC5ED9F7F37C +:109A5000EFA5B2619C308FB19C0FD4EFFBF26FE0A9 +:109A6000F7AD3F63B183F97A6CC796DB40FF1ADB31 +:109A7000F1F6974C0EB3FB3962DE63C1AE49BF9776 +:109A8000B49B70FE633BAE5E01F5C7FDB6230BE8E9 +:109A900064C2315F13B0859EBD2FA5AAEEE590CFBD +:109AA0002E1AD739A0DF4DC0E353AA540D4678F4DF +:109AB00032787C85F167DDF1879BFD68FC54DF7FA0 +:109AC000A2FA3AFA917BC9203BF833C47D7AADBD46 +:109AD000F468255D1FFD3E21406710A24F4F3C6F8B +:109AE000A68C24982F25D1AA7CB9395955BFC29686 +:109AF000A92A9F9274B5AA7C9A92A7CA4F1F315681 +:109B000055FF067BA92A7F63C93455FD4A47A52A1C +:109B10009FE76B53D52F38D4AE2E3F4264C043FE2F +:109B200051FBEB90169D74A0D9B5F874C3EB908EE1 +:109B3000FD0B0387D65E7CEDF9B6D7E1BBB0176BA2 +:109B4000EF3309FBF1CDB2C56B0C6F274ED2670521 +:109B5000DF1F9075EC3ED318ABEBEA94A2E07DA634 +:109B600089602FA648A8587CEE47E3004F0B983D2C +:109B7000ED282006E3BEAD68873C6A6878E60F2CC6 +:109B80000E201DF8DE84C05CD5BA279E77A9D65D6D +:109B90004A6ED5E0698D2A5F61BB5D557F4AD2066A +:109BA00055F934E5071A3CDDAFCADF60DFA2C1D347 +:109BB000360D9E7EAE2A17F4DDC1ED5AFBC01E4560 +:109BC000D3F1FECE72C0C375A703888F92CED67232 +:109BD000C0D3B547DB105F853E6739B0CBE2430D9C +:109BE000AF43EAA3E73168F75A6312A6071A15B420 +:109BF0006B1D6C1C81E9A1463B7EFF756309A6EFD6 +:109C0000343A307DAF712AA69D8D4E4CDB1ADBB005 +:109C1000FE738DEDCC2E16DBF7DE453AD807BA750C +:109C20007E377882173F927703F0CBEE41FE6EC805 +:109C3000DF45EC374CA2F925C044E8BEFC294F377C +:109C4000A43A028057371CCA8A82F1186D3A471E1F +:109C5000E8E177A44CF8A13E9D90BB3738936CD1D6 +:109C60002C6FA6794436C6B34DF8A18312D73320A2 +:109C70004AD0A933E106C8F744B07277CA841B40C2 +:109C80000FFFC6FE73473FFFF91D2961FCE7CF9C1C +:109C900056AC60D739FCD5702BC0E330B76F39486C +:109CA0009E61094D4BF5790690B34707B8B7F08030 +:109CB000AEB409E0D0A6B3CFC178EFEB0D04E8B79E +:109CC0004A62E75F51CF95CAE441CF0D263C4F1D54 +:109CD000D13956605C9914780CE0BC3DA512E1DEE8 +:109CE000630D6400FCBC294E968F0F3C26D943F2CD +:109CF00006069F07526EFCB6E1F35838F83C9162B5 +:109D000063FAB6CF910E7A80C81FA974D4C17E3E83 +:109D100052EAB80AEFCF384D6CFF3AADDEABD03E19 +:109D2000E4289A1362E719926A60F7D1E16222D8B7 +:109D30003B6F91719F6BE1392195E97B482770CE8C +:109D40009C1789E782233AF69E81B6FE020ED7B3AE +:109D500083C2DBE316A632BDA26C56DD332FD0FEE4 +:109D60007AD64560D73DCEE1A88FF53450E82A3445 +:109D70003DDD708E959BEC1C24E8BF9D0F7FD1F2DA +:109D8000673A6EFBEBEF68FD4FD645DA5186D8AEE9 +:109D900041F8DDC22B2F8C35A3FEB4B02ABD0CE4F4 +:109DA000E27CEE075C64D527A03B501F6D8427172B +:109DB000975BF29A2904C9CAB84A233C25559DB637 +:109DC000A619D2D5C3EE37C21329B5A37635831AA7 +:109DD0005B47B77011F23FFFBB8D745E8BD7CB0A28 +:109DE0003BCF89FBAE355714CF22E8F7088F3BA253 +:109DF00040C0F3EA220E6FD16E1187D78914AE3FAF +:109E0000E6909C0B6A3FD66740EF5D0BDFCD1EC02E +:109E1000CFA02EE7FAE3074636AEF6FD1231EEE2AA +:109E20005476FE3A62A49409FAE42D4C0EE4CEFD79 +:109E3000E2AE22BAFEDC0E9B0EE31516D7BD00780B +:109E4000E86DE778349076D84FB33C4B3EF91D224D +:109E5000264E758FF752F2D2DE692B0F9597857ECD +:109E60006779A8BC2C09B496835C14F251F84F7D35 +:109E70008DD59C2F37203F3DD0B81EF3071B3D9852 +:109E80001E6A6CE17CB915CBDF697C98F3652FE71E +:109E9000CB3BF17B47E35C4CF735BA583ECA19958A +:109EA0000AFBC4ECC2F8C437B69808F8E77A3B4C12 +:109EB000189F4177C4638FC641FC9109EF716AE333 +:109EC00090B47CBE8F1E76F77B372505C6E98B1FC5 +:109ED000027D71C8C0F474982856E04BF98FFEE4F7 +:109EE00006D0AF0F2B8A15F4E982D4CD2CEF50ACFD +:109EF000069A2F7C94E75D8AD504AC22F521E45BB9 +:109F0000873D8A3582E68B1F7D88957B093AF3C7AA +:109F10003DBAF5060FF059221D80FD516ECE9C44CE +:109F2000C50595D7A507605F4C495A3209F6C5CEDD +:109F30001405E9639AB2E100E4A78FD8A687ABFACB +:109F40000E4BDE4668571657A9877693D2D66C8497 +:109F5000769387DDAF0F6D3775D4AE8D909F61DF3F +:109F6000A607FD7427F0B1F8603F222FCA059F169F +:109F70007172A33B9C280F72DB9D280F045CCA669C +:109F800057DE0DF6CFFA76C926C13C664B7D410AF5 +:109F90001093E886F74929BFBE3EF597D60DB45D0C +:109FA0003DE4AFC5FC0F377CBBFCFBA6D430FCFB0B +:109FB00043BEDF41DE43DCFB8746F60ECC331C2E6E +:109FC000F51D4BACF88E2A715941CF7A9ECBF39791 +:109FD00020A5E59FF1B48B7F7F40E770C138AB527D +:109FE000B91FB23F7FA84965FB5F738F648072CE53 +:109FF0001FEA526DAAF73CEA08BBBF76A9383B6D51 +:10A000009CB836EE6435693BE8C8EC1F6F520BF71D +:10A01000DCB2FAC77F8B786A6D1C78DFB96A10E30F +:10A02000A77381D750BA6E491D904FDE7B0938DC8B +:10A030001B0E0EFDD643589C7BBF38241EEFAE5D31 +:10A040001771C5B3778D79FCBB767D822EFAAFAFE1 +:10A0500095C15FCFE04FF5BBC7607E158BAD04ECBB +:10A0600056A1FCE77717E13F5A7EF66DF1C99B17C1 +:10A07000D7E1BB6561F8D8F3E1F898B8CFAF4D856B +:10A080009E0AF7F3201E12DE3982737E65A26B1FD3 +:10A09000F4D35316F89B0ECEA171ECDDF083D1AE54 +:10A0A000FDF05D32B2B80611977C5AE7F915E86DFC +:10A0B000EF3DFA19F2B36E1016748FBC41F3A097FE +:10A0C000FDC3E67C13E04746F88DA1EF8F0F147FA8 +:10A0D000FB1B2EFFFAA76CDF8938D49E6D5F66A04C +:10A0E000FDEE12FB62207854C8E3FD703FA4B72454 +:10A0F00012E56797447CF0DE71576902EA2D5DE94D +:10A10000463DA4DFF6B9B82B3D1BFBD79E8FBB9213 +:10A110004BCC6CDCC953217D2FF95421C8BDDFF035 +:10A12000F8CB76A3A7E03DB00F8F8D40FFFE8D9258 +:10A13000BF10E0A03D5777BDB5A04CC9ED7FBEA6CE +:10A14000EB9B04EBAB3DAEBB1BBE5DE979BB76FD83 +:10A15000DF08C4B98F5BFF1581F7EFAEFCFCDD199A +:10A1600093AB805EE16A021219D345F5099ABF5498 +:10A17000FCD639899ED33343CEE5256FB3382E9E66 +:10A180006ACFE7FDDE095CED51C70D96FA8A305EB5 +:10A1900045F647E1BD601D7B6F43C473BDC9CFF376 +:10A1A000F4BC3E240DED709D19AAF3FA1D1F2DFA83 +:10A1B0001EF281088CEF78A6FD443CCCF58F9DF112 +:10A1C0003F794509D277BDED6F24F49DC0DAF5BD26 +:10A1D000AA7CD786E0FB56701FABF65F32CA252AF1 +:10A1E000C75A104FE435E3DA10F94ADAFEDC07EF1C +:10A1F000D194DF5502C050BE36CF74D07695FC3C6A +:10A200004448E48D0EDAAE929F1F8967252B8FE7B5 +:10A21000F53D9FB07CBA28FFE34CAC7F95E86F1CFE +:10A220002B4F1679DEDFD5229F782396678AF62595 +:10A230002C9F23C6AF64EDADACFEE4ADFF9C097A64 +:10A240008DE0F733D2B89CE0EF5251FEEF4C2BBAC1 +:10A2500068BC8EBA9CCB07F10E55C51DD322DF8595 +:10A260007DDC2661EC61ED9D06B4E79F8D69CB0D29 +:10A27000BD2F2FE27A9CE5568CF3AA7B71F8769974 +:10A28000C73B811EB39CFBE92B640BFA617AEF6537 +:10A290007C7E203D70E5FA9755F8EC57CEDFD3462B +:10A2A00047251DEFDC0F13F17E0219D689F102EE6E +:10A2B0003449C427E0BD6A11571797451C707E8E3C +:10A2C0007B2982BDA77AB213F9EFCA97987DBB6E3E +:10A2D000CBEB28EF96CA0ADA97BE1EEA5A07F0E9D6 +:10A2E000B6B2772F57AEDF87FBF431C5C6FD60816C +:10A2F00051A1F0BCB33FFC3D69F11785BFBAFC3FEB +:10A300000C7FAD5D5DDCD75F7D85F17FDD56E607B7 +:10A31000B6733CFD49A71473783D02F03AB7A233F7 +:10A320003B5A8620EE4E8C77AB90DF2982F3566F36 +:10A33000839500DEBBA5CEDC0FC3E05F7BAE389F0C +:10A34000415471693BFBC3F7E94BD0F7D3FF4DFA9A +:10A350004ED4FB8D76F01B1F65EFE51577FEC9180F +:10A360001A1FF44E1A3B070F6E677E311117172C18 +:10A37000B7323C71FF535DD53BE3C1FF24F6C3C444 +:10A3800048D206FE044AD7764ED776A06B41BF412D +:10A390003F146D1706BE41FA252C2E91C3E9B7FD77 +:10A3A000E1FAE125E0FAE17F13AEBBA93E8CFEDBCA +:10A3B0001722D04EA385F33F385C05BC23D32F0E64 +:10A3C000E7C8F4FF0C9C23D315959D43C07B20F96F +:10A3D000A4C58F9877987D5AF44DF6E923199C4FC0 +:10A3E000E9FD188FABC57B4C7A3FBC27A45F1CEFFF +:10A3F000EAF2FF30DEB570D3A6B5DC9FABFD5E9808 +:10A400003E20BFFB56E0F87FCD4FB0B061BFAA7CC5 +:10A41000F1FAB754E54B3CEF5F965F41D8FBFF5B29 +:10A42000FE05E15798F9FC2A1DF81FB5F24137C423 +:10A43000F923A0C71B5FFE7AD48730F9EA6C8CB78A +:10A44000BA8DAFE58BF17FFFE47B94BEBE6860F60A +:10A45000D663FB3F372839FDE965E1791D7184D06A +:10A46000D9C2F5EF1B40CF5A48D8FB54DAFA0FA6F1 +:10A47000337B30C64951BE30D74C0C71941FCC9DF4 +:10A48000CBEE4BCF0507630CA63E172D9FA9273EA9 +:10A49000788FBBD2A2F799D0EFA9BEFF6EE2EF751D +:10A4A00093B858D53D78D921639CDF9C12E62FBD27 +:10A4B000C5D286F787E71DBAEBDCF7602F6FF4147F +:10A4C000B1B87771FFF0F7BA2BF1833E087A2A9C76 +:10A4D000FB24EE5F5F6340FFBAB6DD2ABE9F66CA0B +:10A4E000128BA3D9C3E233C5FEA4EB3B64CA67F762 +:10A4F00060E0F7482A1B0CBEE1B9A067EF473DBBFF +:10A50000BE64432EE0AF7E9274DC941B3CEFD4AF6C +:10A51000FF0BB6D7F2676D7AB9F6D54F1A0F21BD8A +:10A520008873D1B1461FE6B5F6D60513FF17FD9324 +:10A5300063FFE26D8274DC578E0FC7D075FB1B3B47 +:10A54000FF2D7B82B02308BB82D64E21F88878BFCE +:10A55000D2976EE3EFB296A2DF83E8592AF8EDC1F5 +:10A56000FEFCF9D7E917D727D5E5FF61FE7CB9F4E2 +:10A570005F9BC4E4AA96EE8F56FD0CEDCF82BEB56C +:10A58000F4BF006252E8F80BEA25BC273E7755ABD2 +:10A59000619CF4CDE97DB5E56406839B462E5CB1F4 +:10A5A0003C50783C878CE70B93BCC60E760F8187B6 +:10A5B000AFD3D5EF0353BC48191797ABEAF2FFFAB4 +:10A5C00039E0E4A26F2617894A9F48CBE8B76EE5C9 +:10A5D00012EB56FE9BEB0EB9A7B448D605EFE3404D +:10A5E000FC35C481F678D9FDD4EACC56FCDD0352A3 +:10A5F0001288027E77EB5E99FD9E8EDEA14F0E796A +:10A600003FAD8BF83E007A5C359EBD3BA48D9B76BA +:10A61000F378EAD596DD78BF51FB0E9A88CB76F3B6 +:10A62000FEB4EFA189F6E29D03ED7B685332781CFE +:10A63000763EC967712917E7A3DD20CF43FC35DDDE +:10A640005F35A25DE1C6C74AEEF3A405F13227A348 +:10A650001FDF99977171BEA32EFF2FD3AF6CDD81E1 +:10A66000F7D8AE947E47643ADC407F822FF7F19BA7 +:10A67000574CC86FC43BF33D6B9EC1F7877ABE242D +:10A68000E897BDD43BE313BBD835C40927BD4D566D +:10A690008AD771C73C68AF1B7BC485F776C7BCE31C +:10A6A00080887F9277C029C3BC853E23F49B20FF1E +:10A6B000E2F7D9789CD5E5F2B92BF537FEA7FC8CEB +:10A6C000E25E5DB7C15704BFE7E0D91381BF03A1C4 +:10A6D0009DFF9319BA8BBE93DC11E57A12F0348B8F +:10A6E000CB09F15E7285CCDE49EFED94D15EB8EE18 +:10A6F0007F7EFBAB47954BDB15EA6DBD61CF6522D5 +:10A70000ADD7B17B2DF9E50AC649C2790DEC87C2F8 +:10A710009EA8AD7F4A297B2903ED5BE3F13DDADE9C +:10A7200087D97C06C257FDFA008E3F60391FBF7E75 +:10A730006F912DF49D95F3197DE743DB297310DFAD +:10A74000974B17FFD7CE2D3365E291A87CCD91BCF6 +:10A750004CEF254CFF5D403A315D440298BA08BB8E +:10A76000CFB094D8315D4E9C98AE555C5D191837CA +:10A770001448C0F8D317FF390AE8E6DC75E35A211C +:10A7800046F1DBF22369F5BE9E3C85BD97F4C23FDE +:10A790007F07F4D9F33F86CBE21B47A21C6448181D +:10A7A0003FD37BA532BBD754F25DDC17E2FD5D32AF +:10A7B00089F9E1962766E2FE09F2CDC46D826F82C7 +:10A7C0003F39E7B88EC5C3DC2AE17BC6ED7E1D6E3E +:10A7D000B19C15995EF8DDB9F6DDAC3CA72EDA2BFD +:10A7E000D17CCED80856BE26DA0BF74F16123FEEB4 +:10A7F000CBC570FB4486FB4B8C2F8ADF0BA02782D6 +:10A80000A1126DBFA2C3CCEE5110FF30E0FFB970B2 +:10A810007E0A174F3384F1F1D14319BF1F5DA6B6ED +:10A82000870CE5E5F72965DF0778B40C71640D81C5 +:10A83000FA319D9B1E2C043B908E809FE6B3B1B7EE +:10A84000A35F53B47B51291B01F59F9558BCBF678B +:10A850002FBF6F4C0209A1FEB1B54A792ED42B1A35 +:10A86000C2F8D3407085DF517486392F8AF8D1D170 +:10A87000706643BB3CC177D29E95587EF2E35B6F16 +:10A88000DC68415F8207F4E31715D744186FB49171 +:10A89000100BCCFFA7FC7E1B69C800BBE8AAC74C05 +:10A8A0003AD02F3EA2E218EEF7FC819EB721FD9828 +:10A8B0009E9B21FD233D37437A9C9E9B213D41CFAA +:10A8C000CD90AE386F87C7CCC989218EB9D0BFF083 +:10A8D000F769E75B3984F1D7BEF1F71A71FCFB1415 +:10A8E00017C2B70FDF7B08FEDEEDB3D18194988BE2 +:10A8F000D05BCFDEBFA39F7420B808FFA3B67C0A4D +:10A90000C76BEE6E3DCAFFDC767FD4CA907A2B8788 +:10A9100018B17DCE0B27A3A0FF6E5B1F7C1D125DBF +:10A92000F24C1DCBAF7CFCB91B378E82F93BBE0FBE +:10A930007441F7F96A4873DB7FFB00FC5E2AED1F68 +:10A94000E3247AA4C0663C2F68D6A1858358D7B388 +:10A95000D19D9BA0FDB32F0C859550BE43D8BE0161 +:10A960003A92C2AD7703AEE74653A010EE0BDD7806 +:10A97000410E1BA77D9F528A704E067A43FEDDCAA8 +:10A9800053465F026FDF747F6BFB23E2FD15E0A58A +:10A990000AC8A5AFA2402FACE4F104EDBB87FD06C9 +:10A9A000D6E9392413F8BDDAD131EAFDB78BE34992 +:10A9B000A4397B8D4EC0D7B37B4F0D83F789297E99 +:10A9C00086C17BC5DB865C45427FEF3167EC978FA4 +:10A9D0003C1887F5F1F769E7916D15103733DFBC47 +:10A9E000FF0D58D242DBF10A889B599C241D8474C8 +:10A9F00089923919E265C47D8365234A0FC2969A0C +:10AA000061AF447DAE14984C887C283747F247D814 +:10AA1000853C8A55E5A724A5AAEA4F53B254E5D34D +:10AA2000478C54958B7167D80B54F546C70486C282 +:10AA3000798EAE83BD03FFA48CF186392F1CB97EBD +:10AA400024CDCF7C6A0EBE43F92C2F9FF95CB91739 +:10AA5000F0D143E169A40AD5E9921F6C7E103AD384 +:10AA60009C176AF73E71D0A15CC679E112E7848138 +:10AA7000DE4F16EDB5E704CA371F00BE39FAC5D957 +:10AA800036F0DB3E3BF6CB148847FDCD10FEAE0C16 +:10AA90003F3F0C44377DFB435218DDBC259327C351 +:10AAA000D00D44F2323A64E9CCC3EC7EDE95F2B5C7 +:10AAB0004F81AFA1BDC043427F7F576BDF1B6DB499 +:10AAC000FFE636B047BD2BC30DA5BE7B932BE16FD0 +:10AAD0003948EF64F9B6BB93E3F0BB07F46137B7CD +:10AAE000F70D52B83E55BBFFEEE4C2603959775CB2 +:10AAF000559FDC2935ABF21B33D5F97B4B9B43DBF0 +:10AB00000FA48FAD7C7889D19503F76EA5B0BF37C0 +:10AB10002CE6F3FF010980D5200080000000000032 +:10AB20001F8B08000000000000FFB5190B5454658E +:10AB3000FABBF7CE0B1960782810427798440A8444 +:10AB4000895728B08DA01ED7DA1A4C8F545693E53A +:10AB500003794DE0B6F4D8E318AD8FB6076D5B69A5 +:10AB60006B355696E7E439B144462536AE5B49EB82 +:10AB7000D654A266E499D8424C70267A6D9D5AF755 +:10AB8000FBFEFF5E672E605B9DD64EE79FEFFFFFEB +:10AB9000FB7FEF279014CA70CE0008F6ACCC7099FA +:10ABA0000106F7D61AE41880D3F4EFE2F0DAB8F928 +:10ABB0007A8303CF5700383ACCE3CF01D601140390 +:10ABC0005C29817BA2F3145960E760FF65F1BD2F1A +:10ABD000010849009E178DDEED5684E35C06676E22 +:10ABE000F89E8DF04E0618D972FFEFBF2AC2F525E8 +:10ABF000B0E30E8CC4430DBD9BD7755C1471CD9F23 +:10AC000004D7D17779968098806B7055B407E200AD +:10AC10009A6A633C623E9E67860E992E04C8F1A62E +:10AC2000B59B52018E8A22C039440778A014EFE305 +:10AC30001B045F24A739EFA4DFB9C867CC2FC7E78F +:10AC40004532B035BF3294E9C67BD77E87E71CBF5B +:10AC500003A291CE3F804A8F034C5C2E04BBBD19EA +:10AC6000FE3F233F4DBD1218909F61F01DBA5A6000 +:10AC7000D7CCA925002BE9A74CFB1D0690D86F194E +:10AC8000707F95B2BFB27CE5A5108BF056FD4020D9 +:10AC90009BBD0FA7F1FFD57F6F3798F17CF553DA95 +:10ACA0007D420F53902FE5FB3AF0B377EB77E23D0F +:10ACB00053F85E23DCFD9984EF367669BF5F24C7C5 +:10ACC000240DE6E08F0228382DB16D91DE6B36F150 +:10ACD000F7E64ADFBD7B09EAB1E925C96EC4ADD10B +:10ACE000DDD3E200F98339A8E4D4F1F26BDA8C7A8F +:10ACF0002A0CC3A7764BF3BD745F17CAA89E315EBA +:10AD0000CE60C9E2F82C1C5F73C5D70B01F135F793 +:10AD1000E8D0D07E00CF4611E4083CCFED31AEF252 +:10AD20009AC3F4072D9CC7FC9E2F1366E7F2751D8E +:10AD3000D101ED1C2F70BF9821803E09F141B56013 +:10AD4000DF8E4B5F4F7225C9BF4F009F5CC09E587E +:10AD50006442FD5CC19FA37D3324E08F946C1DE1B0 +:10AD600059A8C8FD8AD27F7C23E0778B7B164F439E +:10AD70000AE050D7B23ED40C6C906D0CDF12F0E8B4 +:10AD8000492F7DF1CEF416A4F3324960F6DF171F88 +:10AD90001A16107F5F45B4D026B0F7EFA4F755BE62 +:10ADA000FAF4CE7437E36B8E6510F526382E904E8C +:10ADB000478F974758AE3A1854F52B7177217F9CEF +:10ADC0002BDD3EFB12F4DBD1A5603122BD974B6831 +:10ADD0003808C3ABDC8FAB49D63351AE823F81E834 +:10ADE0006C96176E91F1BBE4D67B41971821371D05 +:10ADF000F733552FAA1CC7D3A1E22DF73B90BFD143 +:10AE00001D02B39F46BBCCECB3B1FCE4834B107F77 +:10AE1000A35FB20B48CFB2EEBD47487E1D6B3B40EF +:10AE2000771E40E7DA6EB62E33997D521EE38BD93A +:10AE3000AD8846417CAD5660C6A7357C1EE67B0CCE +:10AE4000BC513F7C06CE043818EB7C9EF85BF3FBCC +:10AE5000CFFB9610B51BCAE3991F90AD9D1BA63F73 +:10AE6000DF006046FA43DBA3BD4F303C68AF25618D +:10AE70007B3DB127EB700B9E9F7853CFCC755FC5A0 +:10AE8000C3A76E4178CDF66826E71309E049A5F31C +:10AE900027A67B3D7861A518EA6F21B977C6D8B798 +:10AEA000E3F9F147A73FBB13E1DA67A7D9894CF271 +:10AEB0001F19E57D3C1D01DA7F3E957D07291CEFBA +:10AEC0000AC52FA56766DC574EE7CF24DA098FAA9B +:10AED000BFA147A31C80F2FA127C791634BD93827D +:10AEE0006750C487EBC49DC704B4CBDB0CAE83C4EE +:10AEF000F7EA47FE7AA80CF9A97AE6370FCF44FAA9 +:10AF00006ADF9B0CF44E58AFE3E2406C2097FCDF05 +:10AF1000C6FD5F914FDD8E28CBC71171A6A1235EC0 +:10AF2000033775A75A3E8E883775C0650CF5828E3B +:10AF3000F8A957FCAA5E741D25BA1A20C0E3228422 +:10AF40000C64570592E0A07810BAC7C8E43FD6CE8B +:10AF5000466591D1512F828BE27941229852C86F78 +:10AF60005D5C7EC17BA63F7117CA66923541F5FBD9 +:10AF7000AC853322EDB3BFF115B2CFCD46669FC38A +:10AF8000513C2F8DC5F31F399E7DBFC2F405F38759 +:10AF900033F9A4F5DF5A38171C14EF0ADAE4C29B20 +:10AFA000706D51F4722CC5295849EE1DF7EF3AC067 +:10AFB000E4B9F5E6A38477BF99E90F0E70B90705E8 +:10AFC0009E27D5F7569842A02B247AB7317AD5FD23 +:10AFD000C12D87F35CF8FEE00B397980F6BC4CF2AA +:10AFE0000FFE05E5732AC67FEC365C3BF7BF3B8559 +:10AFF000F2E0587AEB5B47D97B2A3C2CF038544F6F +:10B000007CE0FEF799CE64A213C3088B0F0377CDC3 +:10B0100060F29B2BE5C691FE8327B4F48DA5537D8A +:10B020005FA54F7D5FBD37CD2A32398E18FC7994EC +:10B03000F75FCC90357C8DC4FAF3E2CDB46FE17547 +:10B040004402C211F656433F51BF35268CDB485FA0 +:10B050004D8D606F03B6EFA1B889ABCF85E7F529B9 +:10B060002F2B7203A709ED78B162679094C8EC6E3C +:10B070001170BB5EACC4EDABA0430FE82F47C475A5 +:10B08000BF35A0FD0D773CA07745C65DCF51F1746B +:10B09000CE4F8FBB9E4AC8A6F83D6231B3BA669EBA +:10B0A00055D0B17BE9904EF7F0DCEE433BF0741ADB +:10B0B000ED6D48CFE3A2738115E5536FF0E5911F65 +:10B0C000A8DF3D2EBAD8FEB0706005E91B74BE3C07 +:10B0D00056EFC41B40C03A2338D9EE77505DF625B1 +:10B0E000B0B812D4434D27E22DAA12DD9DE6703C84 +:10B0F00054E367510EEEA35C2B685FF557B49BA237 +:10B100007CEDFD303F5AF8B895FB5D51A2E8EE9812 +:10B11000C05F6E57F4DC061D12F7679E47CB14B96B +:10B1200063DD2245D62D8D4A9C0FC69A3C12F25300 +:10B13000B61BF5827099CEB797568C02D08AFA9DCD +:10B14000053EFE5EB7369E530E59CAF2720ECBCB49 +:10B15000B31475AF17DC407A3551FEC2F52EC12FFE +:10B16000D1FA2B08B1D501161DADA806B6CE012720 +:10B170005BE7819BADF3A19DAD0BA083AD97829F53 +:10B18000AD7081AF0D583EB8DD3288F9187EBD52E2 +:10B19000A4BC5CB464E27AFC71455E67970746F92B +:10B1A000929F2F8F79E04A61749D4D2E53B399DDA4 +:10B1B000AB7231927DE27751E04DA1B50202EC9D78 +:10B1C0008BC990F19DD920EB08AE020783E7FE48BA +:10B1D0007994065C3A57EE0472A99AD84E7628768E +:10B1E000524C365D1CD6D787561E1754BD01D24926 +:10B1F000F960BC3E2183E82C8AAEFC5CC690F1DA93 +:10B20000B6F79D3A8CA34585952D36840F593FE5B9 +:10B210007059E5F399081FD976D2A99B49765E59F2 +:10B22000A8B76315BA6ED83907CF4D18FCA3504E96 +:10B23000924D82525C5D51B179807E6794ACEB7423 +:10B24000E857C6DB80C5195714809FD5B36865E4FD +:10B250002735BC7E5D63E17ADB6B70BD4A7EDA60C8 +:10B26000F2C5CAC8D39A757393295F6E30F0F73F61 +:10B270009A2CE7BC827232223E5341984F3CF744ED +:10B28000211C10E496566B18FF8FC0F7CF1FC277B2 +:10B290006B8AEB5D16CF4D5940FA4F53F2796767D1 +:10B2A000598A5D24FC16863F1093D5D28A470752EF +:10B2B0009C1FD27BC1186E771F5AB95ECEB69A32E8 +:10B2C0001D1F5827D80FAEFB7A978FE2D02748086A +:10B2D000BEF399D53540743489818C42D4D71DD1C1 +:10B2E000C70C6427AA1D0BA8BCA5C87F9B03BC067E +:10B2F000E61FE59633F5982DEC07C1E5F81ECAA5C3 +:10B30000C8E9ACD2E371498D7B1FADA5AEF62A3CEE +:10B31000213C41A2A7490AAD20BB3815FF9EE1138D +:10B32000E6A753B93D2AF1AB674FEF6D691C744234 +:10B33000841F36EDF9E6AB0F50DF4DA3663B5D0F82 +:10B34000FBDF9616EA0BB01AD4C417D52F67751B0E +:10B350007DD45F95ED3E7F39DDAB78AFDF4671FA86 +:10B36000E2FE401B95CBC19EC369DC2FD43AFE6B35 +:10B37000E1E7E493B9120575ACCB5E90BC46E4AB53 +:10B3800099EA0B05F6207CDC84761347F779BFA990 +:10B39000F6950DBDAF19A82FC1673CC46FAD42FF34 +:10B3A000AAAD375C4AF562AD57DB2FD6F57BD713D4 +:10B3B000DD753BB4FB6ABFD9A47C5F4FF59A8DEA7B +:10B3C0003EEDBD26EA37F3A8FED3EE67662AFDA65A +:10B3D00092FF40A933572A77883F33EBFF0C5E2357 +:10B3E000F2D6FC688BDD4270BAD9CEE26DFD0666FE +:10B3F000C7EA7DD89AC86C44F5DBDA8DC0EA675598 +:10B400008EF94F1B1DA48FFCA793595D8CF53CABA7 +:10B4100047309EF0FE1E6522A0DD3D171FCA1411A5 +:10B42000CF733DD976AAB75F5EEB807F9D17A64F9D +:10B43000ADF7E74A3BAB0CD447DD887D146E35F79A +:10B440003ED96642B87913D00D242D3B8EEAA6E290 +:10B45000FD1278E91DF03E508E6B971A4F52B0BE28 +:10B460008F9047943C09E409FA79A3A2B7E8EC0469 +:10B47000CD798CFD1CCDF771A599DAEF3D0E7F6E6D +:10B4800009C573FE7DBCE302CDFD36C16DF791CDDC +:10B4900004F03FBC57AE88B1C2BF82CD1D12E71782 +:10B4A00068EE6F889DB79FECBBFC0BDD183B704BC3 +:10B4B000647765018047502FB386B5E7C507DB2168 +:10B4C00016F1471DD48D99577880EA16A3ACDD5F3D +:10B4D000AEDAC55498AA99439C913BB7FBD1219110 +:10B4E000D945099CF7707911C9590F5E79BCDC46C2 +:10B4F00069A5FB6603F38B59BD2D768A47939D5A48 +:10B50000F927D768E59FEAD2CA3B6D9556DEE96E0A +:10B51000ADBCCF6DD5CAD7EAD1CACFB67196E6FE1B +:10B52000B4F64A0D3C7DF302CDFDF3BD0B3570CE74 +:10B530008EAB34F767742CD39CE777AFD69CAB7691 +:10B5400036D60E2EF4358FB13311C408FDAB7A56C2 +:10B55000EDA070FFAD1A3CFF6FFD6F1FA3FFA7C8E2 +:10B56000D731DEBD153B7437B9EB65D13CAE9D9943 +:10B570002794EB59BFF6B69C5815437795FCE654D3 +:10B58000F21B94FF91C3160EDBFDF67D14CF0A8EDD +:10B5900038AB88AEA2807B1F85F392A1F6AA38BA99 +:10B5A000EF00D932858F9CE8FEE5A502E8347E8560 +:10B5B000F094B03CAFF0AC93E2F072D977DE36167F +:10B5C0006EC9E94BC2F320A194E7856A4714E822CB +:10B5D000E452A1EC0325E92961F9ABF323EC07C0A0 +:10B5E00040FD8068F2B65927AA77EC9B25568FB9A3 +:10B5F000587DF686E06273A545267F06C5F7DF25F0 +:10B60000BBDECEC4B8764AB4CBAC9E13026DC45434 +:10B610009018A3A4E5A9AF76501F87ED2CCD2BFF82 +:10B6200074476DB52797916F0994F0B699FEF56749 +:10B63000BA8E64A2FC0704CBFA42FCF6AD5927335C +:10B64000287F1925944401CD4F1C47E9FCCCDC240C +:10B6500019F9C3781B10650F89C273ABC0FA9093B8 +:10B66000F4D8CC08FFDDA867790B94BEEC1A455ED0 +:10B670006A5FB654C13F804FACC2787E4DF71B4C19 +:10B680002E7529C3CA1CCA6DB7E0FB374C3517505D +:10B690005F0A8E423BEFE7D53E2D4DFA297955EDF5 +:10B6A0006BCF76BF2E6548D32FC3CEC409E7916315 +:10B6B000E75E61BEF9FB039BA2591E1AD894CEE641 +:10B6C0008BE1F74FB1F7AF71BFA3B193EB5ADFD75F +:10B6D000D8DFF59E8F34E781A4903E0DF90FEC4A38 +:10B6E0009D7735CA6FE4056309F5ABA8B7385B7180 +:10B6F000F8FDC03DD3E710BEFFCDE7A74CBEFD6B04 +:10B70000FD6CEEA6F2796CED110607D606D83A96D6 +:10B710004FB5BF5557C3DF209BEAE59030C93ED1F6 +:10B72000BCE6311BEF83FA674FA9A47CDC9F6ED087 +:10B73000F1358BC3A9A5260ECF9B4F6B506FDE480A +:10B74000FD6DBF000E01ED61A9E07CEC7AE4BB3A2F +:10B75000D9956BA37A7275284F87FED0941FB8567F +:10B76000407DBE1EEFCA27FE052C065313189D59B7 +:10B77000D4370C899E3C0163C14D4F765753FD3F32 +:10B7800034C9738A3276ADADAB9AFA832103F78F51 +:10B790005B9E7C84F9C3B716D74C7AE71341F2312C +:10B7A0007B7E49F06E67F616302C8CF8BB823AAF80 +:10B7B000A17E9BFA9B60145F67DBF8DF5F2AC7AC52 +:10B7C0004B6D3CAEDD426B31E9E5EE2CFA7BCAE80D +:10B7D0006623905F203E8748F87AF85C760AF2404C +:10B7E000750D566FAC5F2878D5E8A3F8A1CE751615 +:10B7F000DBACECBD241B9FD724DD67F4B6B1FCEEB7 +:10B80000CFA8463ADBF558EF50DF7010D81C6D8496 +:10B81000E661117A596CE3FD17DC08C0CF93B7D10C +:10B820007943EFC0318A27DF67BAAE24390C8872BA +:10B8300009C59386D8BDACDE6BB6C9EC3BA497F1C5 +:10B840008F71E14ED2CF2F380F5C45FA6D300578FD +:10B85000DDAACC03CF26B791E5FE8772D9FCCB9E3B +:10B8600041F4A9F422FDCDB688B99D4A7FF89D1F09 +:10B87000F60B75AEA5C2835B3664919FA15EF8BCE2 +:10B880005112AE5B38C1F70F2AFA3E96E2F410FE71 +:10B89000D56E3EF70BDB4DFBCD4749CFBD66162776 +:10B8A000CFF6FD583E1BF6F43279209FD7127F1158 +:10B8B0007CDE1BC9E748CFE18772E59FCF5F309DF3 +:10B8C000FF1D29B8ED9B0C19BF6FD8FDC611B2BB87 +:10B8D00006751EDFA59D33182761FF9A30D11C1D08 +:10B8E000B34F445D6654BF9FAAD37E8F0539CDA95F +:10B8F000BBC9DFA97E71F0BF8BA9F9B84BE96B8496 +:10B90000C0EB2C1F103EF287F58287E545758ED17E +:10B910002660DE23DDBA5A589E90CE35DBC99EBB29 +:10B92000D006FDE4073A47349B5F8FE9A3BF35B8E3 +:10B930007691FCD6BC53994C7D76E79B0B947E8D1B +:10B94000E7A962C52E8B093FD19F1BC7ECB548A163 +:10B95000AFC484F55026857C8FC4E715CAFC63D339 +:10B96000EB9A3EEFBF32596853001E000000000002 +:10B9700000000000000000001F8B08000000000015 +:10B9800000FFFB51CFC0F0038AC515191844D41924 +:10B99000184C341818566820C46989B5B829D39F43 +:10B9A000C9C2C0900DC4B9409C0FC47C4C0C0CFCA7 +:10B9B0004CC4EB171445B0F50419188480FC6F02D1 +:10B9C0000C0CD7851818BE8B30300803F92E40F1C7 +:10B9D0000420CE01626FA0580B905E04C4DD402CA1 +:10B9E000228ADF7C5102F26B8551F937D1F87B84D2 +:10B9F000F0EB5710C12FAF47401E1B16D1223F3E20 +:10BA00002229D03B10585F01955F26C7C0D0270F71 +:10BA10008C7FA8B80192FC4B20BB5C0EC2F69660EE +:10BA2000602806F20D15B09BEB03942F01CA7D85AB +:10BA3000CA0300CCCCBA8C680300000000000000F0 +:10BA40001F8B08000000000000FFE57D0B78144507 +:10BA5000B670F574F7CC2499994C12F2E03D490088 +:10BA600011030E2144C0709924C0A2460D021A147D +:10BA7000750292849097887EECAEFE330189A0A86F +:10BA8000F1B9AC17DD416137B2E8060C1835E0605A +:10BA900000B32EBAC145C0E72680BC362443F0B9B6 +:10BAA000CB5E6F9D53D533DD9D09C4C7DE7FEFFFAD +:10BAB0008F9F5FA5BAAAEB71DEE7D4E942328F27E8 +:10BAC000640A21DFC18F969F8B8490F850596F20B4 +:10BAD0002E924188D766F46D4CA6CF88237AE6680B +:10BAE0005A981DD1375843EFE9CBD59EA434691835 +:10BAF000210F791C5812E223844EB55A2005F51601 +:10BB0000A83B93E07D3A3E21FDE8F80F46E2F8308D +:10BB10002D99181A671031E07B53ADF989B01E4298 +:10BB20006A47E6C3FC163B21FD7B9F9F8E88EBA7EF +:10BB3000EF0DC1F724FA9EB5EFEF2965570EFD13FF +:10BB4000F6DF6DF66D1408F1EFFCC77158EF9986BA +:10BB5000390E135D6F76B7D93F05EABE6C9F89B683 +:10BB6000E76EFBC026D1FEE5DB4409DA0D3B23F08E +:10BB7000FDCE75820FEA95A6D647AEA4F5C03691E4 +:10BB80003C0FD3F82D069240C87133613F8715EB07 +:10BB90004511AC5ABE7ED76D305F49A38944D0F7BA +:10BBA0008F37882EA82FD928F8089DAFFCB5078CB1 +:10BBB00003E878C53EA13EC241EB1B1F333AE83E85 +:10BBC00097EFFCD8D646E17CDA63260E23EEA3A4D9 +:10BBD0003E8D9052DF96E903E8FBA59B052780BECA +:10BBE00074DDD94E585F69833C5CA4E32DAE8B2293 +:10BBF0008E916CEEEF08CCD77C14E7DB260F83F92F +:10BC00004ACEDF650424E56E93912ECAE93A60DFDF +:10BC1000CABCA73D6B713E059EE52FD2F968BF8A6D +:10BC20009705276CB1C240DCB08ECED7220A5EB039 +:10BC3000C0FEAA8D23ACEA7D146E877D94FAD61BD4 +:10BC4000A75B607DEB8D4569A1F116D7FDA7767DD9 +:10BC50006B5313DD69BDE3F3B487827444A85E4A75 +:10BC6000880BE94FF219818E95E7E78518C4F7E252 +:10BC70003A9138CCA1F1153AF07EC0E9748795F17C +:10BC800001C7DB123BE02C84B76E3BC7A314C8543A +:10BC90008FAF948F003EE87A6A3D762C1FF72461BF +:10BCA000F9A4C781707BDA3312CBB51E273E7FC65D +:10BCB0003301CB751E1796CF796660E9F3E463BF55 +:10BCC000E73D05586EF0B8F1F96F3D2558D679AAD1 +:10BCD000F0F926CF322C377BBCF8FC65CF2A2CEB51 +:10BCE0003DB5586E057CD1B2C1E3C37EDB3D7558CE +:10BCF000367AEAF1F9EB9E462CD77038DAB248B6BC +:10BD000044E16073113B453B89CD7365CBB41E9B09 +:10BD1000CFEA09F3BCD9465A4F70D33A85CB80326B +:10BD20007FB689D60754B1F621F7921C33AD0FF1D7 +:10BD3000B2F69435AE9C085A4FA965ED23D67973B7 +:10BD400022697D848FB58FDAECCF89A2F551F5ACED +:10BD50007D4C13C9B5D0FA183FABA7EF73E55A690C +:10BD60003DBD95D5333FF1E6DA683DB38DBD3FA9C2 +:10BD7000C3273A2C3DF1B055762C2014574DDEB92F +:10BD80002E89CA9BAD46C75DC449C87BDEF92E89A2 +:10BD9000CA8706D985ED6DDEC5AC6E74617BB77759 +:10BDA00029F6DF2EBBB15DAABE0FDBB71BDDD89E27 +:10BDB000505D83ED8DB217DB47563F8AED8D462FE0 +:10BDC000B64FAA5E8BF5D7651FB6E755AFC7FEAF76 +:10BDD0001B7DD8FEF8FD9B5C5369FD05C1BD1DE4CC +:10BDE000DE0AC15D4252819EEA9340EED570F9F9B8 +:10BDF0001C101D6DAFE96F443EDCFA6EE60BC0BF50 +:10BE0000F8EB07F5A2DF3E988CE3BC89E3C8741C0D +:10BE1000F1E2E3A4BF3741334EFA7B25CA382D380F +:10BE20004E44DFC6D9FADE24ED7ADE2B55C6D90F93 +:10BE3000FCB4C2DAB77DA5FF394BBB9E3F9729E31F +:10BE40007C84EB89E9DB7A1A3ED0C2A7E183207CAF +:10BE50008EE238F17D5B4FC6412D7C320E06E1D378 +:10BE600081E3F4EFDB380D07B5F069381884CF971C +:10BE7000089FC17DDB57C6212D7C320E05E1F35FA3 +:10BE8000B89EE4BE8DB3FD532D7CB67F1A848F49D6 +:10BE900080F50CEFDBBE323FD3C227F3B3207CEC3E +:10BEA00038CEA57D1B67FB675AF86CFF2C089FFEF8 +:10BEB00038CEE8BEED2BF3AF5AF864FE35089F1478 +:10BEC00001E033B66FEB69FC5C0B9FC6CF83F0B922 +:10BED0000CC719DFB7F54C38AE85CF84E341F86461 +:10BEE000E0BE26F66D9CC6E35AF8341E0FC26732D8 +:10BEF0008E33B96FFB9A70420B9F092782F0998E9F +:10BF0000E364BBEB985146C7B1F63ECEEB67B4F0A5 +:10BF100079FD4C103ED7E338D3E838A9171F675294 +:10BF2000A7163E933A83F029C071AEEADB38AF77AB +:10BF30006AE1F37A67103E8538CEB57DDBD7A42E53 +:10BF40002D7C267531F88C3B50956BA3ED54173A38 +:10BF500045FACA951D2E9740EBA29DD545BB93800F +:10BF60005D222AF606697589F47DCBE698F4078987 +:10BF7000DAEEC8B913E8C74AAD31B5DD113D21523B +:10BF800063E7C4B86235F5B8190334FDE3F35334FD +:10BF9000ED8905A334EDFDDDE99AFAC092499AFED8 +:10BFA00083AB7234F5A1CBAED6F44FF6DEA0A9A7D1 +:10BFB000AEBA59D37F78ED7C4DFB256B4B35ED97B1 +:10BFC000FA9668EA97D5FD42D37F74FD724DFBE582 +:10BFD0008D0F6ADAC7FA1FD7D4C7B53CA3E93FBEB5 +:10BFE000F5794DFB15873769DA27B66DD5D4AF3CA7 +:10BFF000F9BACECEB3D88F5FC6EB22D03D61767F43 +:10C000007FE6F7F8AD46AC1B0758D08EDF652D7282 +:10C010001CA3F835BEB5C0D18FE217700A7E45F675 +:10C0200080924BDAE8F37B26B92FB1D3E7F718DD1E +:10C0300097DBC3D8A7941E049204A5C300A5BEFD38 +:10C040000199D163CEC0F323DAE9FB9586C0881845 +:10C050005ACF12B31B817E770ACC2F8A144915F46C +:10C060008B3411F40B1E48CE7CC1ABA2D75583296B +:10C070001F0AA17157C9EE24B033DEAA6EF7821DE4 +:10C08000523398EE6B0021CD42BBDF4BFDB4070667 +:10C090001725B9E9782623B5D3D5F31BE9FC693810 +:10C0A0007F0BD0EB7B307F7CCFF94D291334F39B92 +:10C0B000879468E6371BE9FC7642DEAF3EC5E7A70A +:10C0C000489844C85F845338BF694809CEFF8091BF +:10C0D000FA2BEAF92383F31F86FD7FD6DBFE532676 +:10C0E00069F73FA454BB7F23DBFF91EAB37CFE4892 +:10C0F000DCFF51E12CDBFF9052B67F131B3738BFBA +:10C100002D08FF93307F672FF39B52B3B4FB1F5A68 +:10C11000A6DDBF89CDDF5DFD2D9FDF82F39F13BEBE +:10C1200065FB1F5A86F31B4D6E27D08F7160649597 +:10C130008FCE4F1D6107490472A1F340393216FDBD +:10C14000E49784145CC73D918CDEBE8AA4F486F229 +:10C15000C6CBFC581F956C99D4EFE2B4BE7873B689 +:10C1600011E412B6537F65215FEA1D8D22D2377923 +:10C17000D2E41B4ED7DBD9287AA17EC793937D20CA +:10C18000FF2A4DE4F67C784F227E78FEF953A39F78 +:10C1900057EF4B5F2EAC958FB7A9F82DE847E59088 +:10C1A00091551698D7AEA91FA17E10A1FEC527D420 +:10C1B000CF2094248FCA6CBECFA8BF04F536EA2FD7 +:10C1C000413B21D5B85FE2757D308CAE3F9F283F63 +:10C1D00017EEF32664293A9EC4F8F7C81AC107F887 +:10C1E000B87D5914057E683D85DE384D9DEE0FFB08 +:10C1F00007AE127CCF0B38861BE033938F4760BDB0 +:10C20000B45E6067EF1CA2E8EF4F51B060D5408A82 +:10C210008BD038B3884B4EA4EFCF595A2843E8A2AD +:10C220005510062F01FA5920539711E0E78D276921 +:10C230009C38E87A6FB6B3F167BAE4636DAAF51477 +:10C24000C866573E5D4F41A188EB9F3543DBFED169 +:10C25000CE2897610C2D573D81F3CCC9D7B6DF545A +:10C26000A0ADCF756BEB54EFC9A0F76E29D13FA7F6 +:10C2700060A1FB9C17842B5D285DE7AD1C0EB756B3 +:10C28000C95E0D5EC16D55DA21A0E026B82F7C5F36 +:10C29000ECD9FFF665DA7AA1575B5FB04A373EA763 +:10C2A0009BE31CFF47803E687902E883C2F318A72E +:10C2B0008F905CD5D2C78DC16D30FA50F6715C623B +:10C2C0002838BE8ED1C7C2DAA8F0F45018A4079758 +:10C2D0009ABE147AB88DD3C3A79C1E8AD76AE96A1E +:10C2E0002EF1AD4CA2EFDFB26617E2E9A050C8E82C +:10C2F000E1970A3DB469E8C1CDE9418FBFDB383D24 +:10C30000DCF673460F7A7CB6717A685B7B4E262921 +:10C310003DF14AF1A0A9533CE8F06E37023D507C54 +:10C3200084A587F9C17DD38DD3FA02DED6035F9C45 +:10C330001EB03D05C04E104EF87E6ACFFE544E68CA +:10C34000EAC56BC3E3BFB2313BEE986A5DE5F557D2 +:10C35000C51D53F55B5C3753535FE49BABE95FBC92 +:10C36000B650D3BEB07691A67DC1AA3B35F542EF5B +:10C37000CF35FD6F5F56AD69BFB56AB5A6FD969224 +:10C38000C734F5B9EE5F6BFADF54B05ED33E27FFDA +:10C39000454DFBAC195B34F599AED734FD0D3B2F01 +:10C3A000BD1EE831EBA048C0FE38E67120DD1FF766 +:10C3B0008CC4F2A4C7897C71DA3301CB7D8DCD4F5B +:10C3C0005C49BB7C192888264C7F16911842F62CB4 +:10C3D0007757AFCA027D4E50EFFE717951B5771095 +:10C3E00095530607C2396FAD91F8C711228052E20A +:10C3F000F307C4507B561B6D8FEBBD3D6FAD14B67C +:10C400003DAB4D0A3B6EE5E38543ED61E233217EB2 +:10C410002603C13EEAE2F6B9BEBD4C20F9EAE78444 +:10C420002C47FE8F3130FD5C666472A26C6BFF1C82 +:10C430006283BA7F44D585E6ABA7CC9508F491AA70 +:10C44000E1E3E2B59769E43C81E86D3CD0D938CDB1 +:10C45000F3C575576ADEEBD825E2BA2B4086507DCE +:10C460003D8CE4070CA097FDCD43668D8675BACE52 +:10C470001A405E35C6A3FDD8E19911774C023CE61F +:10C480006379D25380E5718F1BCB639E122C8F781A +:10C49000AAB06CF32CC3F2338F17CB4F3CABB0FC7C +:10C4A000C8538BE561CF5A2C0F7A7C581EF0D461AB +:10C4B000F9BEA71ECB564F23969D1E17960ABF297D +:10C4C000F0D0D3DD49AEA74F03FD5D80CEE2C407B7 +:10C4D000AA570D0AD159E28A87ABBD59A171F3D68B +:10C4E0009A389D2468E86108F864E3815E4C9C5E9C +:10C4F000C2B7E7AD952FD89ED526871DBFF2F97F2D +:10C500000DBDCDF991F416A2A7813A7A4ABD183D26 +:10C510004D12C787E8698EC1CEF41FA7A787601F99 +:10C5200061FC8F6230EAC6ABEC3A57148B67F37349 +:10C53000076AD1B278369F7B051DAE15ED3FDF4807 +:10C54000C073F7C8BF8F80787DF761AA28937BDF1F +:10C550009F9E5E7A87BB0BFDA0221F55A2E37AB691 +:10C56000474432B84618C80C924EC8EAE1BF75CEAF +:10C570004FC3BA4462E17D9F736698F32802674F08 +:10C58000891787EB0AEB576360BCE3CFFC2313CA20 +:10C59000398614E6DF348B68DF13FF0B4E806F5053 +:10C5A0001F999C4910070F0C37DAD13EF059B4F0AF +:10C5B000F3D27A66087EAB298C5A51DFD72621FC4C +:10C5C000867D35A27F1FE07731397F3178CEF70D38 +:10C5D000F897C0F362F2F1627291B81C2F37D2FD66 +:10C5E00077ED1C9DFEA003E4E085E1AD9C5FE9D7FB +:10C5F000F3BC287D2F3AEE4A50E8B87508A1F388BD +:10C60000A21DC7EF6EB884C92FC5EEDB66F2F50533 +:10C61000AF6792B5E33DC5F94F19AFBBE5051BF810 +:10C620005B4B920CF66361F0A094E5F5C9768BDA6A +:10C63000FE6CD4D6BB6B8519F568273AA2678F06C6 +:10C640003D61B71F1B06723B094B659C254946FBA4 +:10C65000312AF74ED7A546333FCFC7E4C1E6189439 +:10C6600017A73D66ECFF53AFA7B77194F510D24002 +:10C670008E9A411ED3B6D4DEFBF74ACFD217463C82 +:10C68000F76D92BF02FBD04CFFFF0EFC0D22615DE7 +:10C6900019B7B25EF49A2E87E79B35F3D1F71CCA1F +:10C6A00019EB772917E21B891C57E896EA8B635C24 +:10C6B0009F2CAE8BB06BEDCF184DBDB2B1BF5D639B +:10C6C0008FC21F54FE922A4102FA29E3E4D325596E +:10C6D0005609747D6F429010E85660FDCACD6D46D4 +:10C6E000B703CE9519DE7A5B1FC5DF4C89927C8932 +:10C6F000B916CF614BEA2F9D0A7AE64CC38A0488AB +:10C700001B2C16BBEFC90FF3BE2C3179BFC827070E +:10C71000B4F63DA70F42C7559E635C94588EABEAB2 +:10C720001D06168FD18F9B00E3C65F1C3E159BF73D +:10C730004F073B410FA78AC6B34637CA45FA5F6623 +:10C74000084E0AFCDE14F313243A7E695D3BC62DC5 +:10C750004ECADE11BFBC80BCECB93F4BD2F128D52C +:10C76000BEBCA415E6993F814F441C377D4CE5F8CB +:10C77000A93FC904E410394F7B65624886FB3B063C +:10C7800062C80CF93BF31B16E701BC4F81BF47E5BC +:10C79000E61D24DF867820B599E0DF9C218619000C +:10C7A000A733E47DDB38151E7225238733958294E9 +:10C7B0001E4CC1F1DDFDC1EF3215D4B48A63E0B97E +:10C7C000A4F83FC2771847720B98B750C09E7B8978 +:10C7D000B91AE897FA511A3F8DFA519A3AF5A334EB +:10C7E000F522724302E425143D29139F8070D2B4D0 +:10C7F0008F92EC88C762525503F6D1AF79FC6DBEBB +:10C800009D4803E93ECB5F7D36B390EEE76A89C56C +:10C81000FD9473F545B10C0EA5253EA3CBD2737FD5 +:10C82000471BC6DD48253F8CC7CECF6F36621E053D +:10C83000B44A99DCF449E97DFF890DA22BC206FDBB +:10C84000E87365BDC9DF7FFFFAFD12F238EEA3B4CD +:10C850006E2601FAEB9127C0F723D7092E5F187EC9 +:10C860002AE474AFE8A73B017EE343F1ACFB74F527 +:10C87000D51CBE4AFD295DFB0F962FFD8846BEBC28 +:10C8800029BAEF93C6337902F017A400F2D70F1E2E +:10C890003FA9C7F8AB811F7FB2F10769F99E8EFFF0 +:10C8A000D44FBAFE613DD6BF3EDCFACB5F7D69BB9B +:10C8B00097EA97D23F3C652394DF4E49B5094E8AEB +:10C8C000F7B28D2B6D2E903B92D7067C71CA27CE86 +:10C8D00008470F87B87CA506884580782BFC49C798 +:10C8E0003FBDE9A1EBC09EF86AA36CC7386A9DC939 +:10C8F0006FA2F45CD1B0288F8CC17A3BAB3F70162D +:10C90000E8BFB2513EA2A6D3D2DF3D95007935945F +:10C9100052061A92A0F4A37F52B1E1F3E9606F547A +:10C920009200F2ABFE3D98FF9B58D48785C6E89EE7 +:10C93000ED18984980F7D9AFB2E1A1B3A20DFE6A14 +:10C94000C33890BE7F09F7375A246B3F3C27B98222 +:10C950005C01F2548107F1317F63C58BBF1AD34E5E +:10C96000D7D3B1E14F36410527C54FEAAE5FF09B03 +:10C97000D71DBDCBEF4ECA876ABB56D14F8E46EE50 +:10C980002735B1B24CF6DBAEA4F2A46CBDECF4D208 +:10C99000C7652FBDF0DB67207EFDA1C9399C8EBF26 +:10C9A000F8A53D0727D1FAE22D72BF3CB60D8B905A +:10C9B00010C24B25FD7F597A080FA5AFEC313A46DE +:10C9C000B3E7F7C686F0B178CB2E2319DD131EB975 +:10C9D000F5BB8C6D963078A96F9F0E76DF8A17BFF6 +:10C9E0003682BC3BB5532089C961E0B97E0FDA8538 +:10C9F0000027C423C753106FBAFE95142FA05F14ED +:10CA00003CE9DB37717902E339D2909E5F7E9DCE9F +:10CA10005FF291C909FB2F79F92E1BECE38454C511 +:10CA2000E8FAD9950920DF4A646F821D4BF6BCE411 +:10CA3000B9BB91DE8AF7DF9DC0E292AEFE06D495C7 +:10CA4000DEFEB0BF85EBE6E0FE8A881BE9AEE45966 +:10CA500031DF47CB2F2532634B18BEB8566672F2D2 +:10CA6000C4F35423D0FD9D50F4C0FB22D70377625A +:10CA7000DCF36EBE176A3162FD4B33C3D330D9C0CD +:10CA8000E52CD32B417ADDF000EA8BD3835D8970EE +:10CA9000BE5619D20FA837C4FDD312197E989EC175 +:10CAA000F7A89EC985E7D0BF5576458CD1BC877A5B +:10CAB00045997F299F9FAE3B12ECB51309E1FD8F8D +:10CAC0009FCB0ADF53BB42455F2AFE66FCBE613541 +:10CAD000E36F85DF7D336740FB170718FFC07BA03E +:10CAE00067E9BAFC89D8BE6BB680F2C044FCE1F8B5 +:10CAF0007A83CCF95ADBAED0095DB72444ABE805A4 +:10CB0000C68F45F8A35E2F7A92BEA7929795309F65 +:10CB1000ADE7780ADF1673FE9F216BF99FAC8BEFB0 +:10CB2000533E6599ECFBED33C0AF943FBD0EE0572B +:10CB3000391FF6FDB7CDCD076FA67CFAB77A854FC2 +:10CB4000B5F253CFA7255BEF26409F7A3EFDDBA0D1 +:10CB50002A12964FE9F3B07C3AA8ED7F547E2AF072 +:10CB6000AB02F84585E0A7C8C3DEE0A8978756D991 +:10CB700011561ED2DF0192D993FE14BA53E8ADF4D8 +:10CB8000F7E54341EE04E952A1BB205D2A74A7DF1B +:10CB9000AF167EFAF64932C175E5BF26A3FF5CD613 +:10CBA000C4F242E97B7B0766209C5CA8C648EDDEA8 +:10CBB00081FDD4759FAE5EAFEBEFD2D5F375FDDD91 +:10CBC000BA7A95A67F5963B39120FEFD9A7EE2B2B0 +:10CBD00067C8D1B870F4EA637E59C359A317E8C295 +:10CBE00012C0F7E5E5C40B7986811D22C605BA2877 +:10CBF0008C6B207EB139D9E7A5726365048B3F74D5 +:10CC0000D903B6585AAE8C61F540BCB106E49EF229 +:10CC10003C10C1E28A5DF9015B8CCA9F6A6F1251B8 +:10CC20006EB7F9C88C707E16D528C8476DA4B77644 +:10CC300076EE354DB40C590671A55AD10936F81D5A +:10CC4000D537D9E0DCA9AB29F5FA02FA7CE11F451A +:10CC50004C7BE98AB48D817511AF4BEAAFF26F4E10 +:10CC600012EFD359747F0B9A989F73C71A9D3D4258 +:10CC7000D6203D1559961A419E527FE288F6BC8611 +:10CC8000F145291FAF649DB65D799FD201FAF3A5E6 +:10CC90001BB4ED6EEE0F7FA0F0C9583296FBA32CAB +:10CCA0000EC3E5F23431EDFA028A8FAE1691986820 +:10CCB000BDBB49447C746F167C104F23DE78E4B70B +:10CCC0000A124079A8C0A903F8C9D8BBBCEAD8F6B3 +:10CCD00069E62F816EB67F3CE63F69D9B1FDC3118D +:10CCE0006F40FDD543433E263DFBE7EE8CC073FF0E +:10CCF000AE9D56A4F7AE1DEF0EF925D45F33396112 +:10CD00009D5D3BBF1E03F4D3B5DC5402F2AE6B3025 +:10CD10008BC7AED8F1F59836D4AFF733FD6164FE1A +:10CD20006177D33F3E13FA4149770576C3CE28E4B5 +:10CD3000A7CAD72330DFBB6BC7D7996ECB4FB79F3E +:10CD40000A9EE7D16525055B617D312C8FA1F28DAF +:10CD5000892F54D3F9CB1B761917D0F6DC37FF395E +:10CD600006E468D756660F75CA6DCF411E4394F12D +:10CD7000DC7299E2AB13988A3ACDBF3366E402DFE6 +:10CD8000F484CB3F313ED65778A4FCAF8187E06274 +:10CD9000F2CEEA330BB0EF6F3FFB18E39A26A44BB9 +:10CDA00065BF7FABAF467BE562FBCEFE7F6EDF8269 +:10CDB000BF2FFB76FF9BEFFB38D7BB7A3EE849E7F6 +:10CDC0003BEEC1FA4B5627AEB78FF4EE85FDC7FF99 +:10CDD000FBEEFF7BE37D2BC5BBEDE2FBFECDFF5AF7 +:10CDE000BCFFF1368E773B7ED7F3E63F717DDF5790 +:10CDF000CEBDF96F8EF7DEF6AFD8F5AD862A7B068D +:10CE00005D5F01A9B582613137BEDB92E1806CD7ED +:10CE100073FD308F0ECE4BC3F84D0123F30B4D90B5 +:10CE200047077EFB1C41890BA21F751DB71FAE1B58 +:10CE3000548276C875AE8799DD2055B566D3FEADB0 +:10CE4000390B9C987349D20FBBA13E7B32AF6BFD6F +:10CE5000C9F704E212A81D7F5DCE352D60D75EEFC5 +:10CE600012D1EEA525DABB1F0C99CE9E4FD0FA3D0C +:10CE700073DDDAFA4D05DAFA1C3EDE8D84ADFFC6AD +:10CE80007CC107715553F613F11067352D948990C5 +:10CE90000CF942552BC1BF9893AF7D7F1FF8C1E3BA +:10CEA0007F3C1C534D0A1C97205C48B6E8DC48FACE +:10CEB0000047BEEED6D9637D90CF4C242783E38D07 +:10CEC000E54E8C83737F5BE6EFCB9655ADC0CFB25A +:10CED000CECF56FCE5DEE04DB8FF8DE3A484E02F15 +:10CEE000BB44F4BF659DFFADE0E5FBE243C1E38FCA +:10CEF000C5CB973ABC0CB2B808F0ABCCFD85A916EF +:10CF000027AB0FCA2778DEC8FD05A99F8B78D342CF +:10CF100079DF8BCCE66C385F338F1430DE71FD1A0D +:10CF200011F583394DC075E54F90318FF873437E0D +:10CF300026E03B6FDC1515BF60CB70023C1771B863 +:10CF400017912AB45FC9F9EFBECBCA84730682F683 +:10CF5000EF221721D752BFAD284BF0475278154B1F +:10CF6000C41B9D0E716F811CD1C4BDB575F8FD4702 +:10CF700042689C8BF5EF4DBEFCD4E55FA93C3B328B +:10CF80008CFA411E9EBB4958DC56F1AF6F6F627040 +:10CF9000AC2C137C2948777E395F75EEF81CE7834B +:10CFA000BFDE3B0EE564F6A3A3A3D1EF7739D06FC4 +:10CFB000A8E47E43B7D7110D71AEEEA6547E3E9B1A +:10CFC0006B53CB55A5DCCFFDEEBF407E212DBBA61C +:10CFD0000AB522F8712480F15CEFD408B2314CFE1E +:10CFE000EBFF311938FD54611C007E6226E091FD93 +:10CFF0008AE9ABD1B12ABCADB9F69434A6271EE0BC +:10D000007744750EF963E10B7E3EC0757F44DBF417 +:10D01000FC30FBAD35B13856DE5BDFE2779C373450 +:10D0200025CB00971BA68A9A73FB5526EE978D2376 +:10D03000E3605D796F5D659B087869119DF0DD6641 +:10D0400065D359A33BCC79B01E9E303EC4D58FCA60 +:10D05000CE2280E7D1872308F8D1EFF273C634F8E7 +:10D060006E220D433A2E882BFE9AC3B5D364C77245 +:10D07000565EB61C4FE74D6BB08F85A3D401BC7FC5 +:10D08000271821E3218987BDA7F41B50C6FAB51BD9 +:10D09000ED15E1F63F3C82EDBF9838EF9920FCFB9F +:10D0A000E12DFB51AB3F07EC83A93CAED283AE0927 +:10D0B000F247F70CC107FA1BFC61ACE7B1EF84DF64 +:10D0C00055BEB3BE81E95985EEF570DECBE1ACCC3F +:10D0D0007FDCC4E2AF7FE2FCA5C05981AF7EBD4AD0 +:10D0E0007F2AAFA6A8E351D7378E7D19EC9B8A26FD +:10D0F000C16EA04355486D46E0C3CAC6C764386FC9 +:10D1000099EB60E312297F8C3A9FA0D3C4F23B9A3B +:10D11000D3AFBC0DE8E4DC1A13E842E2BAE3AC0D8D +:10D12000E4F0BB06E79FE17B6AEF7B22D9780179C7 +:10D13000F5B1A7CE3555528F9B8CEB9C55962D4360 +:10D14000F8EC96B25D72A28A9E3A4DB1D8AE3C1F01 +:10D1500050E64887E7743E5C87F7111381EF42D2AF +:10D16000EA5BF1FBD45BAA62181D96D4EF32623DF4 +:10D1700019FB2BF329F3E8F969769E36EF78416EB7 +:10D18000DB20804B9EC9BFD419864E1F332BE78E00 +:10D19000DF534FB828DD8EF9FF484F2C55F4441B60 +:10D1A000E6B92BEFCF35333E57E989C4707A62492F +:10D1B000B52311F0B064476A2230C9923F4E4B0844 +:10D1C000A7273EF0B073E343FCBBEEAED9544F5CEF +:10D1D000AED213B323904EF4EFE59A95738D8BE89E +:10D1E00009056FFFC3F2E603D01361F8FB46B3569F +:10D1F0004FDCD854887AE2C6D9A2E6FBAA6BCD17D9 +:10D20000D313D90973B12E3BA3C2D0CF07DCBF39EA +:10D21000C4F3FB611ED0176BCC76849B5E6FF42643 +:10D22000D7C7F655AEFF5F82B322D797CC61F743DD +:10D23000F4A44382F4BC642E95EB02D02393EB4B11 +:10D240006EE5714E9D9CCD07399BA196B3ECFD0A0E +:10D2500037D30B958DC9BF9A47DB6FAE959D66DAC4 +:10D26000FFE690DCCD54CBDD356609E1DC43EE967C +:10D2700030B97BAE691CDA4FBDEDEF532E6FA93C80 +:10D280001BE60C431F05F3A234DFDF1D1DFB76DA1E +:10D290002BC02FEF8A787EFB39B703F68D7D3B03D9 +:10D2A000ECE9537C3DDBB8FCEBF4F85C53A91CC8FB +:10D2B000BD83D9D3E59B45845F4503E3FF8A619134 +:10D2C0003E07AD4F4FFF16CF6117EF60E7B0740711 +:10D2D00079D92AFC2F7EB7AD06CE0516AF17F01C04 +:10D2E00019BE5F0078167378163917E3394AF1DAF8 +:10D2F000F0E73FE5BCDFA2A6F5180F5FE4D3F62BFD +:10D300001F76F529F047F24C0C0F79AF08BEF5C92E +:10D3100090CFA0EBE75C8DE747E5F5DAE707F97E0C +:10D32000178AFEB457E8FBE4CFCCBFD3C3FBA01EE3 +:10D330002E253F122EFB295C32FEF570E90D0ED42E +:10D34000BEC7F3013D3C0E2B72259D64001F7E6E0F +:10D3500070A15CF1BE43E142E7BBE3B1E19AFB405F +:10D360008E73B8BC6B70D7F4877E1502F62B5EB750 +:10D37000654F02ADCFAB2763E178A178AD560F07BB +:10D38000F57E8303F5FABCAA2D02E4C72EE4DFFB89 +:10D3900095F81EC37B546E5D46F53CEDBF20DDE481 +:10D3A0008673F0FD1101949B0ADDC64730FB258E84 +:10D3B000CBA1A3030253513F350A76E4477F04D340 +:10D3C00057144F70BF4BF3C4AFA773BCB0B8522310 +:10D3D000C36325C51BF0F3F4265EAF6376E02D4AE8 +:10D3E000BD5EF0390490ABBB64765F8C40E2048E86 +:10D3F00004957E84F3D5EC04159E77B433FADF28C8 +:10D4000038F1818FFEF743F0DC2BDD333BA6AFF420 +:10D41000AEC0293E428BE7FD11AD79E3FAC1F99B1D +:10D42000E0C47B739A62F09CE8582DBBFF2595BF42 +:10D43000A7E70BF03BD4F7D1CC8485437EF38C086F +:10D44000CC0FC57953985DA6964FFA7B80BE6FFED0 +:10D45000512569457B2C94C7E87EDE04E3CD10346A +:10D46000F94E1009033AFF09C6BFD57C81F14992F4 +:10D470001DF396EFB22BCFEDECBB2C5E6F1E9C79AB +:10D48000681E85EFB955A2135CA89B0C8E835920AA +:10D490006F1E9409F0CBB97DB28BE98128D43B850E +:10D4A000EF1EC5EFD90A590E1A29BC8FE997A37C44 +:10D4B0003D1F51BDED82580AA91F0FF7E0CC76EE53 +:10D4C0009AE680784BC6FE9570CE392BD77EF02039 +:10D4D000E07335BB07E9C8AA5CF4D3EEBA53407ECB +:10D4E0003B4CF106EFCF999D7CF0209DF7D655F18E +:10D4F000786E39CF157F239C63CEDB273A1DB4DFCE +:10D5000082EBAD1638C7BC66A448DC2AF8DC4A5A60 +:10D5100031BE33AFEACE39B0EE12AA0FC56428F798 +:10D520004F4B84FA3A01DFAFF4BA8DF0BD66EBDA07 +:10D53000B3C60C3A7F11ED0760AF5CC7FA556E10A9 +:10D540009C90FA5DD4F418CACBA20D025E34D34A83 +:10D55000ED5F331BD767A6E3B6AEA3EFD37A31BC3A +:10D560000FE36E88B911CE272BE93AF1FD09D57882 +:10D570002E5D44DFA3CDA475C39D38DEA275028164 +:10D58000EF034B26243F3201C6DB273BA1FDD0AE83 +:10D590005F1B61DDB7D1F9FAD3F117886DD3A03FD6 +:10D5A000F9A560C7FB87EA4660DCAD0B360C2F544B +:10D5B0000DC73AE6133B100C923A1F654704FB4E29 +:10D5C000B86859750DECABCD1B9F6C40BA3A6B0433 +:10D5D0003D7E8CC2DB4D873C6A64792ECDDEA3C6CE +:10D5E00036951CFD282215DFBFA3311BF3261692AA +:10D5F0007CCC9B7057337BA47D65840FE26AEDB2CF +:10D600007D083C6F5E69C2E79D2F31FDD339B80DAF +:10D61000E3DB27D6C904BE5F5CB12EF569C0E389A0 +:10D62000CD32D29BF82CCB1B287E89C5C99AD7B1A5 +:10D63000714F2C35B27BB5A09DD68B5F54F20AB4E6 +:10D6400072ACC8518A724A2F97F4726BD193D54647 +:10D6500020D91EF26AE9749457A554EF00A1F59001 +:10D6600057836A306EAA975795C4A2C8A974885F79 +:10D6700016960FBE6D2DD0F1ADEC838156FF6B5F1A +:10D680003E057AB7CC4AE04985647F5A6074418090 +:10D690005FE6356DF912F8A0645E04DEC7751CF014 +:10D6A000007CB3260ECFAF8B7C85086F252FB77813 +:10D6B000AD96CE95F8E35CB7485C6AFD5512455CC3 +:10D6C000AA7E87EEA3F44AE7B9BD51F081A83C7465 +:10D6D0005FFBDEBB33B06EC7752DE3F6C11A2BD2EC +:10D6E000F3A19F9F5D09F47ADBBD02017B9D78DD8C +:10D6F00035A00F2BD60A0E880F17DFCBDE2FA6EF33 +:10D70000C3BA0FFD9AD115A56F07D07FC5BAC7F66A +:10D7100062FF0D8203C63FB4BE10ED8912AF48B060 +:10D720007D433BFA0F544F619E59B3574C00FAAFFB +:10D73000B8DF64075349A123852EDBF97D08C4ECCB +:10D740001C338BBEB70A1615DF931EC50221A84FE6 +:10D75000814E2ABD8CCEDA5F929D403617A74BF6DC +:10D760001DFC09AE5FC567E74C87EF748AA97E048C +:10D770003A6D5E976B043BE2844FC0FC8A9E74490D +:10D780002C6A3B4AA1CB670526AF7BD0A38E0E7BCC +:10D79000D01DA74B85FE2851A35F59B64F26F0FD3B +:10D7A000BD9E1EDD72FD8D90FF51F832DD0F5D6F65 +:10D7B0006ECDCFD15E57E048EB09502F9258DE8FE7 +:10D7C000C20FE512CB0FFBDEEBD3CDBF2982E7877B +:10D7D000013F882C7FC94FE77D7BF30B982F79663B +:10D7E00053FB7568DFBC41E900E0BFD94AFCE87F24 +:10D7F000F8500E953688986F4D247FE62C95DFAE55 +:10D80000E4BF2CFE8315E15DBAD5E4CBA3EF976EA0 +:10D810003F3A06F311960730BFC7BB4960E71FDEEA +:10D82000B631F0FD50A9C4F270F476C1F04816E7A5 +:10D83000EA782DAA00EC36A18EDDB3575A7F936C9F +:10D8400052C5750745CA382FED87E7635E8A67B80A +:10D850001F01D6A7BEDF4DC9BFE97891D15F69A38B +:10D860008CF65C69DD964EC8C32C3D6C423FB7B266 +:10D87000EEAC11FCD8DC3FBC84F7F355368A9A3CF9 +:10D88000BC1EF96F75A2DF04F95B0DE5787E43EBF2 +:10D89000ED58AF0F9F077AB13CADC57FD8B1DD4BD6 +:10D8A00041B8F895DFD9F0BEBED68D36FCEEA9EEB4 +:10D8B000C2F9A73DF2DDEA575F30DFED34FC4109E4 +:10D8C000EBBA485DBE601D936B747D99F961E2C44B +:10D8D000417BEBA52F9F837CEC8EAD7F7B0ED65BCF +:10D8E000F65FE79E83BC1AB233C20EF648E5A60F78 +:10D8F000309F5579AF2492D97F9D2FFE0EF3803B48 +:10D900003F343961B4CE1D278680BDD1B9E5DB0433 +:10D91000C8EF5DBA631AC673966ECB4D2461E205FB +:10D920004A0974EBEB431EB21E5FCD0DCD98FF7319 +:10D9300086E21BE443307FB1BE9CE5833A78DEE2A9 +:10D94000E6F0F9DE3DF2141B665D3F19E46203B3B5 +:10D950000B2E9AAF7880E2F1F23EE06FF36A2E4F21 +:10D96000C2E3EF0CFC41F15413A9CD57FCB261E1C5 +:10D970006F9E81B686B85EF315FD7D809B924F3E0B +:10D980002BD2F55824F0CDD6DF637E28E02DCF01D1 +:10D99000F2F9CB2110173E290730FE10D861C2EFF3 +:10D9A0002C4B771C42FEE9DCB61FF3B509CFEBEE3A +:10D9B00024C11FCBC3E5B19ECA0D5696E7C8E10F3F +:10D9C00079900E1B3EE7F98E8C8E953CC8DEF21FD7 +:10D9D0005B2253F87D2A2C4FB37CC3C73CAF308405 +:10D9E0002F6102E0A9FD8279A50A1CEC00872BD4E7 +:10D9F000F9BCE1F34C8379DF1C5F803F90D3C17C9D +:10DA00005D5A1F04F99B3EE11009230F3AD7B33C3E +:10DA1000E04E39FCF7CC4A7E6FB39E4F7D7DCBEB59 +:10DA2000BDD8FABF2F7C1A221D38AE1E4E1DE7C38B +:10DA3000CBF1E39CEF7FF0F7216582FEFB93CF8172 +:10DA40001ECB1BDA8D789F89E23FF1FD76F0785A84 +:10DA5000C72611F33E6BEA9B518EEBE545053F2748 +:10DA6000D1AFF71BBEDE8A46A6273AB65A7D163AD4 +:10DA70004EC75BAF213D576C6EC7BCD3BD75AF18A9 +:10DA8000DB54E7CBA0277CAAF577BCBC6B0CCA6D36 +:10DA90007EBF987E1E63149BA7B229FC3C959BCF4A +:10DAA0006AE659ECAD37DA2D179FEFB4E4BA09C630 +:10DAB0003BDDCAECA5D3F5E20C5F98F94F71BD4987 +:10DAC000482D3B0FA5FA12EF59B3B27BD5445B2426 +:10DAD000DA5F4BAD130E47F783D288792F2BAA79E3 +:10DAE0009ECC7DCE24C0F70AEBD504D6BB12E0ABAA +:10DAF000F2E365BB9B80DD2627E567A8CF5994F547 +:10DB00001BFB19884F85FFA5D61989E07F12C93BF9 +:10DB100008D6715DCAD712E8BF560F8BDF93F34763 +:10DB200087C1F356C9BE278E8EDB3A557042E8B5E1 +:10DB300027DDFB347186992EED7DB1F80D1CDD5F7C +:10DB4000B7D380F6A0D5E0B7D32EC41AD19A840EED +:10DB5000AC8338A404FC1402F3211EF49867C1FDC1 +:10DB6000C83642CD53E8E79434F79F444F9074F79A +:10DB7000A19003C328BD5A38BD2A71392BFB9B8E57 +:10DB8000DB86F7ACC4A4916A20DF355637DA0D4F37 +:10DB9000F0FB69E86F24E441C49248A7FAFE263AF4 +:10DBA000AFE6FB383AAFA61EE3D2D6E36648C7C25B +:10DBB000E99738BE8EE9A205E11033CDA0F86B7964 +:10DBC000C31342EB8E89274E3FB45F6BC1EF012830 +:10DBD0007B79D5FBB058B4EBA6EBD3C889E8B43653 +:10DBE000AF81AD53F3DC4E1C02EEDFA57D4ED7AB0B +:10DBF000A917467179271109E49DC5DC4A38FCBB99 +:10DC000035F0BE5FDA373801F043B85FED2590CFCD +:10DC100012CDF741E7D7F4B7437480CDAF1D870C21 +:10DC2000B2ABBF43BD9CEBBF5196FC2551949E32D5 +:10DC30008756616276561249C3EFA59BFAA17C4ACA +:10DC40005996837927422DA3AB616B08F2CDB000C2 +:10DC5000CF9BBA3F12ED5193997823D2E17B36E204 +:10DC600095D361161FCF43702C37D0A1A45594D6FD +:10DC7000E87B4D811CC3428A847A68A2E35746B987 +:10DC8000AAA3289FD6CC742719C6C2F6DE5EB93B7C +:10DC90000BB9F65288081AAAF7EE69198C2204EF1C +:10DCA000F120DEBD7B80C66B953A15ECF09D7F6D53 +:10DCB00064B0EE3253795F9BC2EA8F3EB47725DCC5 +:10DCC00037936ECF7F14F649CCF65178DEE58FD5C9 +:10DCD000DCF3DD9B7E51D63972833F17EE05BE3AE9 +:10DCE000C0EEF51D6E0D7E778F7A78A345A9FBD126 +:10DCF0008FC86FD88F72ADBC7E3FB61BA04ECBA134 +:10DD000071FEDC81749F2F471D9A9674291DAFA167 +:10DD100030093ED97F35EAD01EF8EE3004878F57A0 +:10DD2000EE1E148283B4FCC33D2D93D570F8700FA2 +:10DD3000D8217D85C3AB0F7D8870E8EBBE295D6C73 +:10DD400007BC5C936DC0FBD6AE386CC1F80AFD45CC +:10DD5000A03EE2E3ACEFE5BB6CC51FA1E3EC54D3FE +:10DD600097F29E4257BDD14D2AB18F62F76C6AE996 +:10DD7000A72BCAF536ACAB25CA758F351EF78FF7C2 +:10DD8000005CE3763BA78E0BD135B1B8C7C1FDEE81 +:10DD9000A32CF35BA354F2F29AEC25620AC4C98166 +:10DDA00017E243FB895FE68D1841F719EF3260DE19 +:10DDB000FC288BFB20CC632B08F82177EC0AE21EB1 +:10DDC000278821BE50E6ABD9C1FCF59A42836F3952 +:10DDD0003BEF1560BC107DB4E9E823C0E8A3B11D9A +:10DDE000E9A3A2A99DD14763754E64063B37033F63 +:10DDF000BF9604C602DE3BA2BE9A2651FA1F1A1530 +:10DE0000A801BA91BDE7A6E55D8A703D1D163F7C6D +:10DE10007DCABE7AC36F6D4BCA4369E04FEE33E0F3 +:10DE200079970237A55F8C85E5C5B658DD5F03FCA1 +:10DE30002A27B4ED85ED6F6D791FF3366CFB6ED834 +:10DE400005EFDB66530C3942F3D6EE5B8EF767D7EE +:10DE500006D87DD8D124E005BDDE3B3C18FF04E1A7 +:10DE600001764F1AC0A31DF96513FF5E2CAB5170EC +:10DE7000819E1F1AC5EE0D89B4B0F3EB211611D7A0 +:10DE800039C4C2CE59E2F7BD2582BF9575BF01FBEB +:10DE9000C74399A6DEFFFDBCBFA489AF2BF854E8A9 +:10DEA000894AD228B87FE44C8C3BD1A2A19FD8A844 +:10DEB00014D578CA7B8F7888F30EAA47AFD83DFF78 +:10DEC0002ED0AB947EBE00FC04FB8D9623006E4AE0 +:10DED0007FA0CF70F8A1EF0D87F9601EB017B6ECE8 +:10DEE0005E22E23D1A7DC46B26DC1B49FB6746912E +:10DEF000AAADF4FDCC685A423D8ED713797D202B14 +:10DF0000533F711A04FA7C3D8FBB4EB6F0FC31C909 +:10DF10003EEA86D15067765C565224EA05856FE169 +:10DF20000E0838B796F8F9754A20C5007853F858A6 +:10DF30000A18FC56AAB452248701F218DEF1D07DEB +:10DF40004BBDCB9DAB2F65DF71EA9FCFE4EBF9C1F1 +:10DF5000F6F5173DBEEF9E09F02D37B73D7203ADC4 +:10DF6000575C7A0ECF079747555C79A17B2FF4EB6E +:10DF70007FE7FCDB5140874DDF98C27E0F55C3E140 +:10DF8000D6E229C0F732F9BD2E2451C93356E5B186 +:10DF9000421BB7CB109529F81CEDACFF401108F8D7 +:10DFA000F44AB1F07E54329E1F4ED1E5ADFE879FFC +:10DFB000C5F932C130002571C92836CF37CC4E3271 +:10DFC000D3FFE09C691A3F177B4772AFB0D2F1DEF6 +:10DFD00021EC7C3533AEAA19EAC4C4C6CF26DAFBDD +:10DFE0000A32136BA7C6C2B8D1C918DFCA35EBDA3B +:10DFF00053BD12C869929A8C7989D388CA3E637AD4 +:10E0000003EDEE08BA2E90E3D78C2C744EE5EDE7C5 +:10E01000E8FF434DE4F6992A7FE32AC75CE7548D75 +:10E02000FD528BF701FDE99FE2EDE1F22C3EE3FCAE +:10E03000DFE2C977C2F9B31E9E390EE17EABA3279A +:10E04000DCF570D4C35D81AB1E8ED99F38A7C68620 +:10E0500081931E2ED348ED48D0630ADCF57079C752 +:10E06000CCE8E29D3413DEABF88EC4E0F80E352325 +:10E07000A11EA49B6811EF01CE8CE2F53747B0BA20 +:10E0800082EFA864C4B71EAE7A3866C6F1F7E358CB +:10E09000FFBD002F09E502E247A19BCCD4AADD31E8 +:10E0A0002A7A50ECEB691C2ED4BE46FB3937DE8A47 +:10E0B0007126B0AFA72584E0965BCED6953BDCF207 +:10E0C0003CF8A9F475BCBF720AE13FFF143C2FCAAB +:10E0D000E45505CE53BED1DAC9D39AA69F8238C380 +:10E0E0005093FB7EA0CF801083E77514EE477470C9 +:10E0F000D7BE67D7D6F570F803FC31B127BC143A08 +:10E10000FBC0C2E34E03C820B097C7BC96110DF206 +:10E110009B34C5868D4B5C71383F380EA757A4637E +:10E1200081B883CFEDA93F428EEDA35A5225C73661 +:10E130008BEED396F89E724CC1D3648E87C9C4BB54 +:10E140000BE24B9389F445D01F480EEDBF5BD9E736 +:10E15000403210F67983C5C1E43FDF6770DFD4BC7D +:10E1600084F9B3F8FC59660B7E5F4302524710CE28 +:10E170002978DF91D7181B5A8792BF4F86541166B2 +:10E18000CFCDC37BAE295CC87751A17598AC828492 +:10E19000F7FDF0759CA9337B218FAD5B7447819DA2 +:10E1A000D721EC1B83FB93FC2340FFE9DBCF35EE4B +:10E1B000AE8076DAAF08FBF1F52F1659FC21B0C31B +:10E1C000E47B3EB9773B95B235EA09857EB3E0FB47 +:10E1D000D4CB81DEFD0361DD5340D5D172E759F622 +:10E1E0001D437663BA04F3ECE96679FF39C42581EF +:10E1F0007DABA7DFEF4BA7A178456008F8298A5DC2 +:10E2000036D5EA1E69A5CF57F3EF669BCE8E18056B +:10E2100078F9C1F474404B4F0A1D51BA1A0FF0EC53 +:10E22000CAF8FC6930C7DFCD3897007A51B1DF43B7 +:10E23000768A6B02ACA7373B7E89D53DC57A013B18 +:10E240005EB1672EE68790DDD441A674741BC7CB00 +:10E250003C73ABCCEECD0F60FEFDEA48E55E3B477C +:10E2600024D891B7AD4ED95407E786D52CFE7E6BE6 +:10E2700095ACF183DD90DD86EFB3FB666F5FA66D35 +:10E28000FF4C60FE7EA157FB9C581234F7EDF69CC4 +:10E29000D7E035C0BCC323313F413FAF7E7FFA7921 +:10E2A000F5F3ADE67ED56A63ED48A7CA2E596065E1 +:10E2B000F650F7AAC7EBE0CABADEE0E7360F48939C +:10E2C00054F7ABB5AD8E2C08776F8C329E02EF7988 +:10E2D000C4CFE20055F2DFC3DD839BE566F181DE4A +:10E2E000E61D16988A76A0E149BF08F6FCB0004109 +:10E2F000FB3B2BE0322CD0F801CC4FEEE107C0BD48 +:10E3000026B45ED6B08BF901F5D5E84F94517F0263 +:10E31000F4CC7A389B1EC0179486FE41D0DF85FC72 +:10E32000A92CB8CF92FBC312A597D45AD67FA3F5D8 +:10E330005DE36A09FC5577924C2963E3C3EFD798F4 +:10E34000A95F55934C2208F5AB5E78F8FDE96BC0E8 +:10E350005F8E7509707F28ADD758FAF7DDBFDEF8FC +:10E36000F0FE1AB86F94FA65EBAC2A7FB737FE78E7 +:10E37000048C910BF047BA3D7F23F0A112AF688A5D +:10E38000E07C1F11A4BB6880974227572F9B8F7E8C +:10E3900045C425E787409E5816C7FF162B8FC346F6 +:10E3A000B1F79F12DD5B90BFDF3A3F02E2CBEF8C0B +:10E3B0003C8AFE5C9395C5E7F7794AD07E52F0B966 +:10E3C000CB2A703FC93F10F8EDDAF1CD71E09764C8 +:10E3D000C902DE43DA24FB9E4CCF007934DBBE82D7 +:10E3E0006E296BA211BF136B8AF00FBC5B65A7355A +:10E3F000F1FB4C9BCEEE1DA8CE631E66CDDD6545C0 +:10E40000FAF38B307E56C6EEC3A0EF7BD32F21FDEF +:10E41000E112407F90F3FB13F0FCA8618F0DE24204 +:10E420001DFC7E82330DCD09F36959BEE52F36F010 +:10E43000D7DEE7703823B5E23D4A65DB44BCFF8395 +:10E44000CE9B700BC4A71B1664B2EFF7D877678A10 +:10E45000FE4CFF67F3C07C1634C4EFC8147B72B265 +:10E46000D9EB83F535558B182F9EACBB376C0ABFA3 +:10E47000374C6F5F9EB42A71E904CC875A6A67F300 +:10E48000F4C64F59DFC4129F8ADFB224BF08EBCF16 +:10E49000FA2681C01597675A529EC8033F9EC8CE80 +:10E4A000E130AC4476A3FDCACF9FE86F37DC43BEB2 +:10E4B0009357DE6C3837EB4A2466FBFD970960778B +:10E4C000B9FBB1E022D3078A7D37E51B6D7C556F20 +:10E4D000E7E6348DBD7F204178B37FA722C0EE559B +:10E4E000EB61FF06A687B57B09790CE190BE2DF59F +:10E4F0001AB84729FD8F063BCCDB027C110FF83C94 +:10E5000087F7FC5410FF8DD05ED120DAFDB07E92EB +:10E510007119F09562372870693CDF6C1E43D79102 +:10E5200075D6605F4E877833F005FACFE3FEBC2FD7 +:10E530000EF4575340C27382ACB3BBA316A8E46079 +:10E54000D379033E7FF3FC5BDAE781D8CBE0BD2DC6 +:10E5500006E617EFDEFBF728904B6F9EEFC6F182C1 +:10E5600076434FBB18E1916B15837167B55D4CC461 +:10E57000AC0390B7352D9AAA31A177BB37FB137244 +:10E58000BF95F4B41F72C01E11C3D8111CCE743EC7 +:10E5900009F8486F575C6EE3F1E6C1241DEEA36CE9 +:10E5A0003C1FB718BF1F6E8AB22F477DCCECA5AEBB +:10E5B000DDA71FBF069EEF13D9FD11E745E4A7B7FE +:10E5C000762E1EDAA6E25B2A39114F5FF53FDBF9A2 +:10E5D00006EDFFD59E481647979C97A9BF7708F58B +:10E5E000F77178F907B0F338EF00B8D7E907DB2FF8 +:10E5F0001D3DFCFA3C1BDAC381E9A01E46AC6B371B +:10E6000002FE5BACF9D7D990DFEAA3002E5E92330D +:10E61000904C80F37A92037415A82676F027B6B54D +:10E62000180C80978C8DC998A7B3899F572EAAAFD5 +:10E630003526ABE862113FEF3A297B87C4AA9E1FBB +:10E64000B031F972724FE96F304FE34313191EC6B0 +:10E65000DE6CB0317DFB8AD17BCD66E877C480DF8C +:10E660000DEDDEFBFA5EB8CF78D161C75888FF3D6B +:10E67000627360BFC67D9B6A20CFB7F113D052543E +:10E68000AF6C28140D74DE378883C5EF0E18D01FC9 +:10E690000FC63D892B0EF6F9105FCF1B2D06CDF965 +:10E6A000D81BFCDEDD7B6D32B62FB18988C7AD2D5E +:10E6B0003971A0375AACEEBB6DA02F8EB5D5C01204 +:10E6C00094789F62AF4D3CB0F59AD1F4CF891D0686 +:10E6D0003BA0DB71E07911F6EB3849488C407AD8E1 +:10E6E0006F743C8F7ABC373AD878741D6F01BF2A9B +:10E6F000F0A79AFFA1345A7FA3558A85FC2E05FE08 +:10E70000CA3E94F91DF5C4B5DE82ACE4DA7A81B86C +:10E71000B3925F3ACE4E947F2F01E9D268733D6A7F +:10E7200063F60EDAD727F730BBE815AE474952E15A +:10E7300050809F82A77A1B8B332AEBE96DFEDFDBCB +:10E74000989E54CAEF4BD79B648717E9661BCB0F83 +:10E750007778FDE654C8236B4CC57FCF499567FB9E +:10E760007BA4E793DA7B051BDB0C06F80EAC628713 +:10E770001083E66D1FEDEB209D49F5487F8D8709DD +:10E78000F27169DD9D2CEE48E50DBF7F0DCFD18183 +:10E790007FF8797A7F8196139BD6AF1888F0F5DBE6 +:10E7A00080AF4270A27C036555AD11E875D1525619 +:10E7B00016F373E9456BDDC89F45EB587EE11E5BA0 +:10E7C00032AEE70CA75762881C00F9272E0E7F6532 +:10E7D000DD799C6E4F353CD10CF352FAFA13E0739D +:10E7E00052E3634FC372157A3DB541C6714A22B5F3 +:10E7F000E7F6AD7CBC6D0718BD4FDC20E7C0FD5FC0 +:10E8000013BDC40E71EC37366C14417EBF01F49C0D +:10E81000CCF81CF4EDC93D0F46FD02F45CBB814011 +:10E82000BCFC152329D9A2E28BDDEB5FD5F06F6923 +:10E830005DF53518976F8B1540CE2B7CABC0FD1561 +:10E84000A3F32AE4FFEB74FC3F95BD2F473BB0DFF9 +:10E85000139CFF9F9841F99F3E8AD91023C038AF7F +:10E8600018C3DF07F7F50FA4BFA05C6DEB2157BFFE +:10E870006672B5CD964AE7AFB8B61BE30CC1F57129 +:10E88000BA7962AA4237C902C0BF96627018C08BBB +:10E89000C215E899DACDB7DF90865CD922E1390F4D +:10E8A0003F47E2F91FCA77020ABF86E499C2B76EF2 +:10E8B0007334D8D553AB56805D1F97E745FA3C2596 +:10E8C000B887C6527D760AF8388C3C38C1E5C75700 +:10E8D000B2FB62F7EE0F007A2EA11E22EC87AC137A +:10E8E000EC8017A5DDB18EDDC33A3C5AD09CBF2B1E +:10E8F000F51F0CEF408FFB418747637C3A60843CF7 +:10E90000D5113EA6C7889083FC400C570F003E5B94 +:10E9100044F5D7CD2AFD754AAE453A55E0707934B5 +:10E92000935F5FC5B07DFF95D38515E285AA732FF0 +:10E93000EA904802E36751607C2EC2F8A7F64CBA11 +:10E940000AE9FDDAF0F46E07FF2A16FE3DA7F54846 +:10E950009F3133ECF81DCB1392332246631FF9B07D +:10E96000DCBDF157E8D701FD02BFF746FF2540FFA8 +:10E97000240CDDFB28DDABF0A7D001A58B6BA255E5 +:10E98000F2414F17CA79A302975774E7954F47335F +:10E9900079B080978E5EF26694FDFC603C9FEC81BE +:10E9A000E7F90CCF21BE027C2BF2E16717E1AF3D06 +:10E9B000D1766CAFF97401E6A9D4F273AB7A3E9FBD +:10E9C000B2EEA5D182E67C4B7FEE34CAE2BE2B5A72 +:10E9D000773EEA480BD1C7346ECF2ED968C273FF99 +:10E9E0002DD00278DBCDFEBD6CE53DBB440D4F0A5A +:10E9F000EA15D14C8E2BF4E1586624C3A8FFF255DA +:10EA000072E16EC8FFF959AB376F34DDC716A377D3 +:10EA1000F6B5E80738AF82F1AFCA33D8211F24C654 +:10EA2000651720DE81240A7CB88FCD332ED5791965 +:10EA3000FAC90EE73890070F737C29F855E0D09B90 +:10EA40009EEB0DAF7B387CE279BB5E8E1473FE9E2D +:10EA5000C2FB5D5C8E7845E0271B712F1761FD5965 +:10EA60004CFE05E54816C173C9977572E4E59F5ED3 +:10EA70008EBCAC912313DAC2CA11FA0BCBFFF11B87 +:10EA800016A21D4B0E87B7637746333D1C0FFA93D2 +:10EA9000F68BF7B2F3DE8739DD528AC4BCC9DA0DD2 +:10EAA00026CC1357E4906D36C9817FAFD906FA168C +:10EAB0007ACD761F9E0CE7C54946079C5F9F92035F +:10EAC00088F753D401AF45FAC8C7FBC7C3C82302B0 +:10EAD000F112EF4783D0EF9C2636219F2C994650A8 +:10EAE0007FEEDE7805D255495E8A00745B5A1723A3 +:10EAF000407BEC54BB01E494B28F2B9619C8B071E3 +:10EB0000C80707D472E40A6F15FEBBCD43E3DC49A6 +:10EB1000720C21471F3DFB3375BCA88DD6D5F12261 +:10EB20005A7FE0FBC48B8E46071E8078D13F6CAEC7 +:10EB30007698779425FF28EAB7C42A91A8E4D6C529 +:10EB4000ECB71F4A2F953C2E455AA9344ED0C481AC +:10EB50006FAB73601CF82B584FC580E34FC37078C0 +:10EB6000AF46587B9BADA31F970BE41382F8E89741 +:10EB70005F2542FC45913B067BACE22F0B9097A1B1 +:10EB8000F0DB7F031C7DB5D7008000000000000093 +:10EB90001F8B08000000000000FFCD7D097894D590 +:10EBA000D5F07DE79D2DCB2493C9427626ECBB039F +:10EBB00009ABB14E086090040710448D380990B03D +:10EBC000640391D2D6968120068A182BB554B10ED3 +:10EBD00014FA51451BB61ADBA013401A143456AD73 +:10EBE000D8AFA561911D8980FDD38AE53BE7DC7B29 +:10EBF00033F34E26026A9FE70F0FCFCD5DDE7BCF4A +:10EC00003DFB3D77492D63793B22199B90B350ED35 +:10EC100006A9C9CC3C161B831F2F6343793E7A0893 +:10EC2000E659986B20636BF27579DE018C5DC79FA6 +:10EC30003BFD69A2153E8E676CFED630EB4933B5BD +:10EC400067D7E17F795D8C265F599F643DD9C79F67 +:10EC50009F8FBF24C1FF334CCF12182B63E2A7E173 +:10EC6000CBDFFF7018B4C7DF55C6DE54DD89568090 +:10EC7000A7DCDC12D5DDCED833F9C713DC91D45232 +:10EC800087DF3D22C67871B9E3BDDE718C79DE5530 +:10EC9000D916C80F36193D4A34FCE264766B82E817 +:10ECA0000F7E9406C5671904F97F43552C6397FEC0 +:10ECB000ADA3F4C59FB8F232E0FB8A7A9D6339B404 +:10ECC000AB685018CB62CCD19579CD198CD58547DE +:10ECD0000D62D05FCEBE48A701CA2F2966AF298337 +:10ECE000D100088741C23FA2357D1BD4573798D841 +:10ECF0006AC85ECA61AC19E1D53BA2D9003F7E0764 +:10ED00001D7EA60FCC00CA6B1D2E0B639BC278FF25 +:10ED10009BC2647B7B3483B4DB92D1EC04C0A7D765 +:10ED200033160DF481C48369F6926E03F499301F93 +:10ED30003DF318804ED9AD3E15F1D2ADD5AE6391FD +:10ED4000FE71F4AD8CE6DB4D6FD73960FC3A81F78C +:10ED50009D4D3B543DE073D898DA6A15D2D228F71E +:10ED600058C4F3A8ECAA6A2C8FCDF7A86E689FA5AB +:10ED700054EDB3005ED878E6D802E5CC07838F84E3 +:10ED8000FA16D61805D998232DCE28281F75C6D96E +:10ED90003800E61DED620AF6C7D8321ABF5FA4CB71 +:10EDA00085FDB238A75200FD0CFB0723BCC87E7658 +:10EDB000368D56EC006F5CF318C51EC05F304DE217 +:10EDC000ABF5CCFE53ECD77348E740BADAEB987357 +:10EDD00023B4EFFA72BF312CCADFBED2AAD078B703 +:10EDE000BBDDB94646F379D80ADF8F9CEEDD6700BC +:10EDF0007886CFF1EC33DA03E63397517F292D1E65 +:10EE00009A47D211770EA68B2D31D4CFA833BEC628 +:10EE100001D0AE4B15CC07CAD39A3F5410AF6955F9 +:10EE2000CD0AD27167D35E8237B5793F4F8111EA3F +:10EE300020DD01725517308FC5161DCD63B145A178 +:10EE400074E5C599892EA87FC4EA5E6C19EA9FC74C +:10EE5000CA1C776215F4BFBEA95BFB7C7B02BCB702 +:10EE6000C1678827D9DF72AB91FA69B2B87F84F3A2 +:10EE7000AB9CDE7200796F47D39FA3482E1AE288BD +:10EE8000BE09878E133D129600CEA078FDA1850A9B +:10EE900083AAF5854033A5239E27B8DD8E31998856 +:10EEA0006F809FF8C71A3109F8F2628CBB06C791D0 +:10EEB000ED2714D922505FB4E7C577CF2E658E5960 +:10EEC0003D00CFFB8B77B26E4877F712A47B7BBBFC +:10EED000818F87213F318BB316FBBBA4B0E938CEBD +:10EEE0004B9842F94B069E97F8FAAB95E3EB11EB82 +:10EEF000A4C596788E272BF0F14B61BC5DB01E7ACD +:10EF0000D7CABFB30B7E61CD9C5F701EA8BF64BB28 +:10EF1000DDA2DFDB9DEE5C3DE793CD08E7C811DEA7 +:10EF20007DC8B7C3F33CFB90FFD398E0933CCE275A +:10EF3000C1FCBECF6AA37E469D696588F72C85B962 +:10EF400002E92ED3D710AEA1C8DFA3897F401EB639 +:10EF5000E378C352AA54038012C7AC135877C6DEB5 +:10EF6000B6DAA95DE608E73EE437ABD345F27C208C +:10EF7000C24AE52B33387FC0F77F40FC05CBD32E48 +:10EF800094A3017E398A437E8CECC88FBF13F0BCFA +:10EF90002DE4A563FFEE3F61FF71CD3AA7029D0C02 +:10EFA0003F12E965D074F8A22A15E18F63C0FF0013 +:10EFB000A06D8E3507E52CA5CCA1205D9B225C873A +:10EFC000ADD40F23BDB93247E7AD86EFE6463B89A6 +:10EFD0007EDFD83EEC676636CC6F1FC01EFC15E1A5 +:10EFE000037BB0B608F5F46FFF69443D6A97F2D72A +:10EFF0003424A238803FAE48BDE0A7F771D20B4160 +:10F00000F40ED673C1F4F6EB05AD9E037C5DE0F41F +:10F010007067229FC5352F52B97ED0EAB5CEE8D1B0 +:10F02000413F083A5C8A707E81F85C0C3288E37A52 +:10F0300046B33E58DE991D0E8B89A476FF453B1CD6 +:10F040001613DFD10EEBCCAD0715C04779836A5795 +:10F05000610AD58FD99C48FF17EB148709E5A441B5 +:10F06000257E78716538D94B09EF67BBA307B1DB03 +:10F070002015F2CFDCDDC98E56C688F1ED9087F100 +:10F080002F5979D6687527C504E893171BBE084326 +:10F090003CF74F64034EC6620BA7D60E830829F0D7 +:10F0A000BD097F5310AF836B5414AC69EE9D269558 +:10F0B000E8D61DFB1BCE5AFE9C0D70BDBC6DB4CEB8 +:10F0C0001DC837F55767EC05F82B23B85DBEB4F7BC +:10F0D0005A2FE433597FF79262D27B3F072B1913E3 +:10F0E000A01FDFEE7382EB6156683DD51F87762A3D +:10F0F000D723008551E63E7AF427D47087AAF527F6 +:10F100008839AA7B027E107F8DE184BFEA9E20773A +:10F110001904E748EC7FBFC5C892A0FC0AC823B613 +:10F1200093707F03784707E2D10F6FAAF55484E00C +:10F130000BD50F5F3B5D900ED0BF6AD1D33C2EB193 +:10F140007007D2B3CEE864487FCF51E11F08BA55AB +:10F15000089EBBD430F4881BE6F7E29154077E7F0B +:10F16000A9FE4A982E12FD46F7149C979AD61A8546 +:10F17000F6705FC395BE2D0348BF4DC5F22B874E79 +:10F18000D8DC03BED1FC6684A687767E95FAC89A41 +:10F1900040FF50617C7EC17CA43434FE4B1944F2A4 +:10F1A000C7501F7AD299B71AE6BD72A0E0A77B9923 +:10F1B0001DE53E98DE46ABAB2226406EFF15EDAA5C +:10F1C00042B8709C942134CF85981F747866A6410C +:10F1D00087F31BC3D06E4A7F0FFDEFB0217EFF4E39 +:10F1E000CEAF7DFE3DAF0D3AC468BE3FC67100F89C +:10F1F000E53A80AF128CC1EA8CC079FB881EE562CB +:10F200007EE5E6489F0AF361BB0C175AA41EE8D6B8 +:10F21000117EA04F0DC2E719ED38E246FAFE35D255 +:10F22000518DF8D1375BD15F85F9ACC67A36A2280B +:10F2300011E7DF2FD2B905F5FC4BCB18F1F3A55739 +:10F240009877134C76FB7E1DF1CB46D68FF8BE9F88 +:10F25000EEF20C5724C9F33A843BABB956877AB720 +:10F26000A7D7AE437DDAB7B94EA7233E70FF2286FB +:10F27000FCE49957F4005FFF6D55EA37E4076F68C7 +:10F280007EEF40AFCD81F49278CB167C908D7843A1 +:10F2900083D0AABFD062F6E30DE8C3526C1DFB63B6 +:10F2A000AC251DF1D4F8FAE95E2DD05FC51BA76728 +:10F2B000205E2AFE60222618F387BED1C8EF9FE5A4 +:10F2C00084F6672E2CAD72E8C19F7A25A61BD985DE +:10F2D00032D66C443FA1BC6E81431FA0CFA5FF7600 +:10F2E000C8D09C8FFD1F1AAAB26580E72B8EE15D06 +:10F2F00058083BD1EE2FA1BF06B02F47D811CFAF92 +:10F30000674573FFD146F620B8FDA1A5731C637A4B +:10F3100074DEDFA1C161D3BDF07D7E901F743486A1 +:10F32000DBB5B6186E8741213B11CE8BBFB7783D58 +:10F33000507471C847510CFDCC5D1F647A808F2ECC +:10F34000B2E647FE8872763592D671F9833FCA5C81 +:10F3500066F1CBE51D23F8DCEF78ED70941DDAE75C +:10F360006FDF17E709C0DF1D4C7FB59DAF33705CC1 +:10F3700046E3337D4B2FA407FBE3D9043BA4F9AF4D +:10F38000BF15C7F9204187745E24F4DBEFB028C0B5 +:10F39000DFCE5F52417C24F3E56D66E68D0DC8EB50 +:10F3A0009B8DB8042E6F8B645E68B737C612477AA0 +:10F3B000269925A39EE9145F3789CFE07289CF4350 +:10F3C00083CFA6A35FF15927FE706F1B6FD7CEF7CF +:10F3D0004BC14FD7FBF3EF7CA53EEC0AF15D848D6A +:10F3E000D3E98A636417F4F7F28DBE1ED610EDE4FC +:10F3F000FA32184F6F5F2B8DC07E7FDF66CA0B0518 +:10F4000097DEA6FB767ECA21802AC01FDCA6BA53EF +:10F410006DC21F9C0CF98ABE57C6D1BA5AF28BD066 +:10F420007B77304F23CA6F307F487AF7B001DDFA1F +:10F43000A372662948B78B3176CE37421EA47C046E +:10F44000E331389D6064EE50EB80AF62245EC39878 +:10F4500007F4E1231B0D64DF0F5FFBF8DE4CE0F7E0 +:10F46000D31B0CD6E530E49C17F6A53E03F57306D6 +:10F470009BAC0AE44FDB7D3D50EE4B5F505DC80F07 +:10F48000A7373C923013D2F320BF650047E946030B +:10F4900095CFD9F828959F15725DFA427C7FD49755 +:10F4A00087F7AF4E403ACEF9EA89694897ED466B47 +:10F4B000FFC190966D531C6302F03D6F739826BF99 +:10F4C0005DC7E6E03C245D99E26EAF47133FD5A6E9 +:10F4D000FB76711F9FD6DF04FF72AAA0E3C4293018 +:10F4E000EF8AA157C8AFDF77209CECC99B912AF91E +:10F4F0008FBEC1FFEF9DDB209FFB95DE41BE9DA02F +:10F50000F3584167B05CA4B74BCC3C9FFBBA9EFC60 +:10F51000CF5C8B4AF886F69163A1FE7BA2BD0FF407 +:10F520002CCA2153B3D78D847663A30D0CEDD0F78D +:10F530007CF3F219D8C93BDBF4C75B02E6339AD5FA +:10F54000F6417F38871982CA9D7A2CCF356BCBC79D +:10F55000F6B8FB2CFA0F63ADDA72C9778FD8B4FA1C +:10F5600062DF81733F9B00F32B39A492FF7C237DE4 +:10F57000FC2EC2AF473ABF5DB80DBE3B2CB072F84F +:10F58000DAE91549C857231486F1ACD3D742CBE347 +:10F590001FA45E6640DF3E7EFA1638E6B6E751DC11 +:10F5A000EF19B1A03D8FF0DFBC1EFB7A3D759B8D3E +:10F5B000C73382ED46B0DCFCB7EC46FEE0B7D23D87 +:10F5C000164A7F83E985ED5CEF06EB89603B21E11C +:10F5D0000A86B7BC4DA7B10F5FA11E191A68278C08 +:10F5E0006427BEC3F570836D68C7F530F831842F8A +:10F5F000CF303DADC3C1DF6AC4760322EDB139001F +:10F60000D20A6BB708B27F16F77E5B401CAAFFB622 +:10F610005A1DEA8DF6F88C411BA791EBD577849D96 +:10F62000A813FA1CD6ABB4CEDF18EE4ED4E3B8C99B +:10F6300046C7968C8EF8F948B4EFCCCF957EACBE19 +:10F6400086FBB18F585D9A3819EB93A889FBA25FAE +:10F650008EF2EDD91B4EF3FC54710D4239D433E7D1 +:10F66000DF6D01F4A93670F883E1898FE576923178 +:10F6700017F907B27CF6E8D07A5C89D553FB9C6712 +:10F68000EF4F47FFEDD3C607D251BF7E1A14E7ED07 +:10F690004C1E9E16F2FAA4B02331222EF014CA1189 +:10F6A000E441DA9DDBE1FB554B5D24573F5D3A9D1C +:10F6B000D267962EA1FA13B60C1ADF9AF367577722 +:10F6C000C0D3C9352AD989D94657AF18F8EEA459FD +:10F6D00047F18513559179BB22B19CD17A72F6B36B +:10F6E00013B67802E27E276C7AA24367F38C8FFD13 +:10F6F00066FABD9CB544A1BD6AE7D7231DECB52DC4 +:10F7000016E37FAC2501DB552ACDBDB6291DC7B751 +:10F7100032677C2CF29791F547B9A90BE7F628B828 +:10F720005D4A2CE7C3BFA11F0BFD7E8A762B849E0A +:10F73000B10B3A2FB438EDB1A4EF22C95F27B881DD +:10F740005FBE8C727647B8605DD613D3615D787CFE +:10F750006EB1C52AF8C3A9F0758EAB5F6C88F85BF3 +:10F7600067F19E6038DE11780D8E03C954C681861C +:10F77000C6F2F9BC6DB36AE24218FF0E15FFF979C3 +:10F780002CD7A31BC35B3C2ACAC3037C3DDE25DB0D +:10F79000A3607C2B25BF3607E35F77C5F2B8A52DA4 +:10F7A000CF9D88EBF6E444A303E336372B8F03EABF +:10F7B0009C7C5FC0AD2338D6377BC27A015C09CD13 +:10F7C000EE1C23A45371310DF8EDC2AA9621DDA0E1 +:10F7D0001D21236B7FB857918B6C689229F42840C8 +:10F7E0001A8672678C724F45BA0C9B55558D71FA0B +:10F7F0009432BEFF70567177B5019F9C7D2B3CA45F +:10F800003F5C22E8CF94D1C968FAB3361B08AEAC8E +:10F81000CD3F9F817C9FB5F92EBD12A08796C71A58 +:10F8200068FE67DF9AD795E2169F9858CF107AEA5C +:10F8300087825F1E1074D8690CCD7F8B45BB6FAC7F +:10F84000CF5B405569F5F9E2D880385B45F965D260 +:10F85000E79363ED34CEF3FABA03C980CFE767319B +:10F8600087078AE66DDD48F1D79DC6BAF1B8EFE4A7 +:10F87000A9D031A4FBFE037F38908C7EE42CFB6082 +:10F88000F423DABF3FF4D24A2C7F7E0E1B8CF84F54 +:10F89000F23EAD603CE69F61B584AF7F6E31B165ED +:10F8A00018B77DBF6EFC0F21BFBE4CC750BF04CF41 +:10F8B0001B4632E81231F519742338FD510F4ABA4C +:10F8C000030319911E926E88BFED90EEDFF21AC10C +:10F8D0002FE19A2AE2DEF3B66E1F8F7C925C6653AC +:10F8E000304E20E1BA913D7931F6DBD993EFD00E5D +:10F8F000BF121B222E1DC20EEF880D618783ED2FD4 +:10F90000B3387763BB1BD9E1E182FF36C606ED7FD2 +:10F91000E07E5908BA0D8DED100FDF1F1B62FFE36B +:10F9200046F1F0DEB172FF431B0F7FC9C8F56FAD22 +:10F930008D3D3C2984BC7413E3EBD6B51AD17EC649 +:10F94000352821F5D9628B51EE1F7E1C1BB05F124A +:10F95000AC8F43E0F728B6EFBBCDB7175B0D89E955 +:10F960001181EE5BBFEBB0DE0D31CE29813FFB2272 +:10F9700046FBA6F62A46FA0AF25E1E14F42914374C +:10F98000B0384F93DDBAC1BED59DD61CF283E43E9C +:10F99000D554ABD64F8C8B93ED9C9F239C699DD8FF +:10F9A000897F093CC1FCDB70DCB8454CB31F23F7F1 +:10F9B00061E2AA3C8A310BCD11A3F86AD758F7321D +:10F9C00003B46B1DC91C9B201F5D68CD417D6A9BE4 +:10F9D000E368C4FD9A9517793C7EE502E65D4EFD2D +:10F9E000F0F93277372FCA17D22D302E1011C7E118 +:10F9F0008888E3720676D21CC7E10A8F0BB0939217 +:10FA00001EBA753E95E8DA1ADA4E05D0D546DF778C +:10FA100042D7EF502EED7137E71FF78CBB05BE19AB +:10FA20001877737CF3144C4BECDF048F9789F30F3A +:10FA30001E0FF82C2BEE26F8ECEA2DEE8F1E8850C8 +:10FA4000BE5DDCA5235E27C485D0776BF2757D484B +:10FA50005FB3704728BB3A232EF2BF7D5E6486A059 +:10FA6000F72D9D1779F1272D46A4B3DCF790F0060A +:10FA70009F1391E5150D4A26AE3F73F65DA375C041 +:10FA8000A5C67FD33AA0E3790F3EEE42E403806738 +:10FA9000AC3AA0CE07F277799B9156EA2AB3FF22BF +:10FAA0001BE3F64D06E6B5537B33B6EFC778FB7E16 +:10FAB000DB563663DCAA1FD37BC47A54B9CEFDA8CB +:10FAC0006894E37E4D2A5B8DF9ADBCBE8A9997613F +:10FAD0005C3A7A848ED903F019E30C67F6007CC691 +:10FAE000E6D93479B94E9E2FC68D77256BBEEF329D +:10FAF000BD9BA67D92BB9FA63E65CE104D3EAD6AD6 +:10FB000094A67D57B0CF81F90CCFDD9AF6DD6B2638 +:10FB10006BF23D6B1FD0B43FCDAA9ECDC6797A9CC7 +:10FB2000CD3D00CE5902CEDEEB8B35DFF5D7D50DBE +:10FB3000F3A120F9141FEEFFCD166C324BC473FAFB +:10FB40007AE769FA3DFF6A5E9302F89D5D6B3819AA +:10FB5000189F217C007E4BEA15F61C8C5BBA5E5B1D +:10FB60003FA7E1E9952990CEF56ACBE7E1BE9C82FB +:10FB7000FCAD2DDFAD733D82EB9DED7122CE28E211 +:10FB80003DAC037F44D2B89737F07897EAE91DC4BB +:10FB90001F5A3AB16FC92F76C12FA6442DBF84D901 +:10FBA000B5FC527A70E7301FEB88FF883E417CE459 +:10FBB000817F017897F895F8B738B47CF55DE19DC1 +:10FBC00031AF91DB0D6DF93FE2B4F1B57E91EEE31B +:10FBD000A8B7AED42F5271BF8DE5F17DFB2BF55741 +:10FBE000071DB26BF6D73ADB4F3A1717185717FBBA +:10FBF0004997703FF1367613FB89FBFE85F800D9F3 +:10FC0000771B801FD80887B97DFF30CCBF7F14AC2D +:10FC100037650A76E3CB38B227FE7DD76AF87A5883 +:10FC2000F45F5C08AFDC8793E772E4F92116C9E75B +:10FC300029FB013CA8F143F1FC9F2D02D7ADDBF776 +:10FC40002FA4F5963C3FC4C4B9BF107E3FE9EF3AFC +:10FC5000FC3589FC81F0786ECF23316DF707C4F94C +:10FC60002E69CF3BEB47EEB775962A7B55DA3F6C92 +:10FC700055C21D9B42D8935EF1DF72FD75A6431CF1 +:10FC8000BA577CE0FAEBD12B07D0AE00DEFB62B9AD +:10FC9000C502F65AF1DBEB5F444411BFB61E54BDFA +:10FCA000BDA1E0B2D91E6D033C368469ED884CAB32 +:10FCB000CCC903F4B158AF3DE727F71183DB676385 +:10FCC000FB80FD27F84EE38FAC1CC2FDB5EC786ECF +:10FCD000DFBF88E4FEC11491AF0C5A1755D670BF30 +:10FCE0006C23F8E90D01FD4C89B750FBA511395380 +:10FCF000E2298EC0D7BB2B3314F227562A0AF921EA +:10FD000067A24753FDB5B89CC9C43F629C29E8BBB4 +:10FD1000C1FFDA6E1C1EBB388F23FB37C7F3F6E634 +:10FD2000F8D1944E89B78AB8B3B51FF2476584936A +:10FD3000FA35AAA1F7A5A6C7F379ADB530E9276AC8 +:10FD4000E2FEE384DEC438BF89FBA3F96313FC71D0 +:10FD50007EA6667F688C13F17D853E77A29EBA539E +:10FD6000D0BDB378BFB38F753F6E27758CF7FB128C +:10FD700043C6FB1DE328DE0F5FEA715EC1717FA4FD +:10FD80004384CD2F3F8FC4B7DB8354D44FF54677E0 +:10FD900035AEBB5A7783FF0EC57DBC2DB41F30F046 +:10FDA000507707AEAF5666B0BD16E4B7658CA17F3D +:10FDB0005FDFA25B1E06F56B3CCC8AF52337F0753E +:10FDC0005BE97ABB03A7698075B065885F1FAC8B60 +:10FDD0008F21BCD7B74C6EC4FD8135F7321B9AA179 +:10FDE0005A569B1B85FED0061672DDF89490B30917 +:10FDF000397B55D417F1E8DF87A0D353824EA00F8B +:10FE0000D6229D87B7BAAFF0FD38AE4F4825E2FA4B +:10FE100074BFCE1B6A3D3F373A771DF2C1406FE891 +:10FE2000F5C35A0BE7B77511AEE7A8DD2E7EEEB528 +:10FE300054EADF593AA607BA4F11749DB2819FDF89 +:10FE400060D7AE5F57A59FC8A87F867AA5F45E8B62 +:10FE500017E343A50D191E82CBA5387AA2BE687898 +:10FE6000DF85F9D2AC2C2BC6239C7F65CAA93EE462 +:10FE70006232AEBFF4EC94D42764C7E368DF69B2A2 +:10FE8000E0B7B5163B3F470D288E00FC976E58B67D +:10FE900017CFEF7CF46B46FB4B47D4D661D8D954CF +:10FEA00040CE922198EA5921C52BF8FED5BDA21F5C +:10FEB000CFBF615CB37FDCA90D07693E470CCC6303 +:10FEC000063EBAB4E73E3BFADB2BE3CD14C793FB07 +:10FED000B24755F7E36484F4AD1508DAFD0D115609 +:10FEE0008C7FFC43F05D46827B1FD2C7BD7C7C05C6 +:10FEF000DAC19665A674C4A37B79921A0770BAD743 +:10FF00002A34EFD1CB938C787E61E68AC1E3504FDF +:10FF10000D61CE9518DF7928968594D3F3F17C9DF9 +:10FF2000585C6560C6689A8411E32F176B148ABF0A +:10FF3000E0FE5B01D0678E985FF9AAF7A3883FECDB +:10FF4000F06F181ECBE53F73AA4A491EC1CE6BE481 +:10FF5000A78CD51993A09F796B6039DB8DECFDF1EF +:10FF60000EFE43C079EFF23A6D7D255BF3399D7F3C +:10FF700061E0EF5BD02E68EB3F95F2E8600EA4AB3A +:10FF80007BB1C58CE784460BBC14AD51ACA85F6651 +:10FF9000AE688CBF0FF2339B5407F2B4C40BEBE88E +:10FFA000EFD3398FCB4D3D693D70D96EEF82EDDCDB +:10FFB000515CFF2B7AF7702C7F28D63D1CD7F1AD12 +:10FFC0009F58189E9B39D606FE18C61ECD6C10C5CC +:10FFD0001FAC6CD0A4003B5A64B02660BCDFC316D3 +:10FFE0002632BEB7650E9C77A5790DF98195E80795 +:10FFF000F2F9911FF8502C67D5D6D7153A9FC3EA6E +:020000021000EC +:100000000DE4079A851F78D65E9B00AE17733D6E90 +:1000100020392DDE16437E68F18A5C23F26FF1AE43 +:1000200018D243E0077ED863989F8EC756641E4857 +:10003000847E8BEB321CAA967E5AFFB8E698A45BAE +:1000400047BF4F4BB793A1E806F4D294A72408FF0B +:100050004ED08B3D164B7E47E182B77A9A019ECBFC +:10006000556174EEA833FF83A5C6D1BE9E5C17E62A +:1000700025B7AFDF68DFFCCA9AA144B7607AE5FD17 +:1000800067E670B427ECAF16867AECA1EEECE1C916 +:1000900050FEB0C2E5EBA1EAF17928A759095C6FDF +:1000A000BEB714666864ECFDA566E6ECC5D8074BE0 +:1000B000AD94FF686922E53F5E6AA7F493A57D28A9 +:1000C0003D29E26852CE8001885F472570F91A9574 +:1000D00020E2DE6C5122AA8CBCFF7C305467C5A1A3 +:1000E000D2278C4D63EC1E272023C0DF997E6F043E +:1000F00012B93DDF62B08E4B44FF719542FABED813 +:1001000075BBA63DF825463CFFCDFA64FACBE99CC9 +:1001100098DD3819F8F0FEFC584DFB6935299AFC3A +:10012000E4043BCD7B525E774DF90385FD35F9A2A2 +:100130003640029E2F30DBF8FEAAD8B767CCC6D770 +:10014000EB56DEF66AD5F02EDF0778AF1E32507D13 +:10015000303D245D67ADD731378036733DCC0DFA25 +:100160003D593B93E4EAFC110BD9FD95DB32DF1DD1 +:1001700001F963DB0CB4BF7E6C45EC5ADC3F3EB644 +:100180002D3E8A41EA5EA9321FFAC17AAB9105E899 +:10019000B7DC15CBE8FC5691D7E440F92FDAEFF93C +:1001A00095CCDBD11F4420513E3E54BD3E85E8E74F +:1001B00024FCBE14E6DD02F933A0AFF1C8F8CC167A +:1001C0000ED71985ADC0FCD9B0BFF5FA3EC071B1EC +:1001D000A0B64487EB01F5503CE9CB1D2A43BE2D68 +:1001E0005C60A0FDBBB91FA91B31CF9421299CDE07 +:1001F0002A9D47642F99A87FD60A1C02ED16FDD6CA +:10020000B489D6774CE4770FF4AE16FC897C74265B +:10021000863963085885E03DF77EFC46ACF7E3D3AA +:100220003B08E7FDA5DEB53201F8EB5C897710E904 +:10023000B5C7E249AE82F17ED2C8F59607E540F136 +:10024000EB4BBF9C2D273E9D69702438485F652588 +:10025000A1BE3AB9C640E79899DE193589D63F3B29 +:10026000888FE53827F5F67108DFC99A0C86FB966A +:10027000C56B54F20790FF787B2FE7FFA755371B1C +:100280000EFDD6286ED6A523DF3CB260389D639A5A +:1002900021D641C17AE0339055772F7F7EDE1E7ED6 +:1002A000CE8665B5E8EF1D18388F157CBC44DEBFDF +:1002B0003C0750D6ED4F47D1E5BEDCD43D1AEDF0FA +:1002C000D90F55E2B3B3DD6A8725023D2FE8F60E5C +:1002D000FB3EE4CF17784EE921FF54B87B6702AEAE +:1002E00057746BD2956E783EF6C4DADBE1BB73AF20 +:1002F000181C24E64BE2497FCC7B696ED7C0F38E95 +:100300001DF5972F99EFBF389314C0E77C7BDD383C +:10031000EB005C77BB841DE2F8B1E3E62AE0C5BAE6 +:100320004EC143C3ECC450CB6A3C773D13C4243068 +:100330004E7842EC8F1F107A45FA09115D787EA63F +:100340008EF3377B5521BF0D7E34FABF529C4F94FC +:100350007A5FEAEB32564BFBC14712F839C6B98ACD +:1003600097DA55E0CE2EA8A8122B0F42976D35795B +:10037000BD19D49735D00F48EE62E7FB43C6579EB0 +:1003800045B62D65CD7C7E41EDCE19BC25CD191D20 +:10039000ED4D8975E30A1BF56F7060FCA454C869C4 +:1003A00079ADE2F5F17990DD94F18AD9C26E06DB80 +:1003B000A70EF628C80ECD0EB2B3AC566B5701DEB1 +:1003C000481C47C21B0CA72BC24278980770A1BDDE +:1003D0002D717B0F4C24B8150750B2033CA5CC35CA +:1003E0002606E701F53E7B47F882E7D5015E31CF6F +:1003F00060B84B1C9FFB70FF18CF8751BC29681E4B +:10040000921EC1FE9AA44B8987E3B7A441217A7E4C +:10041000DAEE07328A1B497E8105509DF67BD74470 +:10042000D467A5EB40FF66F8F947F2D33C56178531 +:10043000FC52C17C2B9350BE7C75D346A2DFBEE13B +:100440007D23CA49A1CDD7531783285CFBD3BCB405 +:1004500080F544109E6F44D76F8A379C955EC6BD69 +:10046000004FB337ABCEB0419A76E21C9187E4607F +:100470008EC763C4F8C61CB1EEBF119C957A7E6E20 +:10048000FC86F076E2277D5BB8F3BA68FD62BF9F19 +:10049000D5333A949E6AF7AF82ECFADF0C3C7E21AA +:1004A000F5F155BD93E225502EFCAE2A2B8F9B070C +:1004B000E9F1B42CD2E325C2AECB714EADDF49F1E8 +:1004C000B7D968F703CA3F5DB793E2FEC6576647E0 +:1004D000A1FF7D6AFDCCB578BEEBD4B69964E74B3D +:1004E0009F9376DE6D0CF41F72D717BDF863E4DFBF +:1004F000AD61149F2FD9EF16EB1ED0ABD0CEBE9EB0 +:10050000EB51B68EEBD552B48703C81EF6C6768B78 +:100510004BDCBD510E02CAC94E2E9EE9FEDD1EE81F +:1005200077F1CB110E0FA1C2EAD391DF6EF5A13D99 +:100530002C5FF8F1513CE70EF6FFA31F48FB0FD9E3 +:100540008D7AF7922E286FC2EE97AB1BD3ADE827BA +:10055000083BF15FC0BF3934FE8710FE8B11FF01ED +:10056000FB20C76B389E6706E1FFC41A4E9795DBE8 +:10057000BA47E1FAF1784D77F2B38E6FEB49F89F05 +:10058000B51AF0CFE35F5A3FAB06F08FEB08C43FDC +:10059000C05BBCDF2EF0EFE0F8AFE178676B783A34 +:1005A000AB039E3D748E61F1AF4D0EF41BCE84F90A +:1005B000C89F3AB35D65D5017E98F483BE60B5BF30 +:1005C000427F4DE27F6EAFE641A87F0A9FFE531443 +:1005D000D261EE761EA4EF807FE6EC82FEB87FFC4F +:1005E00076BFE9952EF1017ED34DD2A982B918D9F3 +:1005F000C5863F1DC17583E2844F6D788F46DCD779 +:10060000A8D7DED7C0331985368C2F38CC6684271F +:1006100035F81E8A9B611CF99F3D3F9FB190E4BC59 +:100620005573BE6D22F319BAA0FF58A7D0FDC6F2CC +:10063000453951390CE3D45504C7E92E8AE6FC78D4 +:10064000B9AA23FFB1CCC8FD48B93FF9AEF00FDE1F +:10065000EDC2D725EF75B1D27797C218D9814B1665 +:10066000A317EF23C07A2A11C7F7EC3111DD8E22D0 +:100670004C807FD528E2366002914F1F649C4F1F4B +:100680008C6CA23839AC545E40BBF8D0129383FC1A +:10069000DAB8688AD73E20F4DD83912B5D681F1E8F +:1006A0008A343A31857E3D7888CE301A8687F10DBE +:1006B000C946BAAF53686E790597BE0F279E78D4A6 +:1006C0000CA0DE06EE37C655E0D75DD7633BD2C53A +:1006D0004F1F6D9CA7323C74DCA355E04B713A2947 +:1006E0009E6382BEC3018E2B682FB1DC6EE5F19D47 +:1006F0000D40278B9FBEC1E5CCC3F703CAF05CE376 +:1007000028C6196404E15F932F33F2FAF0C4AF26D0 +:10071000ACCB66ECCFCC3E10E956863A04D7F74511 +:10072000D15E8C97DF83F1251BA67AE297C97AE622 +:10073000D1F1B42612CFCC8978D34481CFA92398A4 +:100740002F1AF0EE3BA88D77DDE7D3F97A037EEF21 +:10075000D1FB1A913F7566BBC10AE3B8F29421B888 +:100760002E295B7E73F0A6259AF3D7A5425EC7CFEC +:1007700085B5FE80C7211E046145BCCDD0B3FDEA1E +:1007800010CE0788974A9BDD43ED1628140F95710C +:100790003649FFC1D07D201D1F14F0413F3551F86F +:1007A000BD3134BDFA26CAF5731DADABE70BB99B5D +:1007B0002FE56D9B56DEC627DAA9BD827E30E0EDBF +:1007C0004191762617E344FFE312B95C64DDE278D9 +:1007D0002CB2359DCEB708792937F1FEE5F8F788B8 +:1007E000744CA28DFA95F000BF1EC77E74A00190D4 +:1007F0005F4FD656937F348705C4B533FCED245F35 +:1008000077CCB7EB11DD754C8DADB310F5CAF7C2DF +:100810001CA8471F34D6F5AC8AECD84EEEDB14B2D8 +:100820006603233D29E261C2FE8C5523E97C40A189 +:10083000C2EF0F5ECAB17874D118A73110690B638B +:10084000143A3FF137B17FF250F4E28928D785514D +:10085000463DA633582BF5FB776BB7E8FB18DE3324 +:100860005631760E038FC877C2B8D5A877787E8DBB +:10087000339BA24A227FC72127E0E1DE6B407FCA7B +:100880007F2FDF09FD5F7A4BD4B33BE9FB4B8F0B26 +:100890003EF6E4F2FCCF657D1ECFAF92F5F93CFF4A +:1008A000A4EC5FE49F0EAA5F1654FF4B9E5FBC3E14 +:1008B0003FDF837EEB68CED285A314D2537B84BE08 +:1008C000285CEE23FC16EAF6F27434F3E9B26EDC2F +:1008D0006E53A26B0FDA1FD572D282F6F7D564275A +:1008E000E59F4F702F4BC475D424C563447DFBA195 +:1008F00097ECC1C44ECE1FEDE9C2E3F89B92A0BFB6 +:10090000A17EFB05FDAC4E8CBFF57E1C491CAE8064 +:100910007E9EF926F0FCA7233C1BBE493FB392B54F +:10092000FD487F484975BE86F36327E334E745E613 +:10093000FFC4118DF12786E74500F5F397D7A5672A +:1009400042FFF35F7D3DBD04FD2561E72BDA74CCEA +:1009500089F734DB18A5E71B3F31E27DB38A5D8D53 +:10096000C671D0AE12D2DC00B8CA049C60E7F49322 +:1009700003EC7383D01B8C3DCDF7375F3DAB477ADB +:10098000CED7D59D7A0EEDF62825E43ECD66F1DD75 +:10099000D14ECE17EF157AE86A9AB311E7F96B8C4E +:1009A00021403EB7BA93FB60491C5F85C2EECD1C67 +:1009B0006631DB01CF433FE4FB54251B3286603CAC +:1009C000F8CD84D1EF247E6D3CB595C7531B783CA0 +:1009D000B5D0D6BC089437332695AD31DFC1D88465 +:1009E0005F48390391856FF34C325F9D3F269BC76B +:1009F000BB307F76FD636B506E9AC2B91FFBD0F09F +:100A000081E1A8175A3222745690E737E38B8C495C +:100A100043B1FC8E71589E63B2F42A22FC32E28B01 +:100A200037E35DC7905FB03DC641DC465FFC7D307B +:100A30000FF7DB2A9DA7750F8A7087DA77FA87C0D0 +:100A4000AB31C94A69139019FD1709871C1FFCF9BE +:100A500045CDD0DFC9E5498357DB719F25C7903469 +:100A6000D43F7E4682FB72E0F82775AC172E296EC4 +:100A7000168E4B020E03EE5D03BE5DD92A7306ACE3 +:100A8000F3268F89D0E4EFCD8F65CEC038EDBD2938 +:100A90009AFCF4C2EE9AF60FCCEAAFA92F30356774 +:100AA0005505F8B19DFB491E82A7D26209477FEE2A +:100AB000EF0D5FFCE541F4FF36AB0EF455E7EED9E0 +:100AC000F297DBA1D5653C4E45F1473BC5CBCEC97E +:100AD000F3287AA73E705FE8226BA6F33E9DED03F4 +:100AE000C975EE7CEB7E3A77F65DEF03F54A12EBC3 +:100AF000DD216C08DAC3CB551F51BCAE2292CFEF7B +:100B0000E2EBC78CB80F8AFB8AD781DFEFC20FD127 +:100B10003F6CF3503C3BB7FE18ED9B1D48E47ABA9E +:100B20002275811EEF1D55428A76681CE8AB68E08D +:100B300097E646367017EEBB6658B81FDE3699B199 +:100B400058E42B1EDF694A88A17BD7F36BF2A8BC5F +:100B5000A22D9CFA7F4F6D1E47E7095F5368FFA1E6 +:100B600020E5A1E5787EB829DC33E01118B7E077FD +:100B700077E521DE2A76F1F3B505EA9FB316405AF0 +:100B8000569B47DF17A8AC49017F61422EB7BF05CE +:100B900068F321AF0EB3AC46BBAB1A7DBD9E473D9B +:100BA00063B4909E896E7B80C6AF6C33D3F7F72415 +:100BB000717FD7D0C2E11ADBE6A272C90F5393BA94 +:100BC00069D60F86F8CD7A7C97C3D0C2A8FDDD6DBB +:100BD000FD2895F37DBBCFAFE93EAE21FEEAB81408 +:100BE00098F7DB718A95DC90203D7CA56A78340B00 +:100BF000A1A7DAC769E3E7F44C6DFCDC5E618A7398 +:100C00007E12C031F1B1163DEE07B148B315F13592 +:100C100071C4607B49807CA97BEF37227D0CEBDEC1 +:100C200037A29D36419A1B505F2ECE3304EBE90567 +:100C300049524F2FA354DA1D767506F9A933AC82B9 +:100C40000185FCCC10FA547EDF4C6B1AA0E36E1EBB +:100C5000C77F34C5BD02F545730E9BBE83F4667332 +:100C60003AEEC37C57F0039DCD0AF9892D741E75A9 +:100C7000E208BB0EE3FFAB045C528E6F348FC5A25B +:100C8000FD7B2A5B82FDBE77E79DCD4EE8AFF14745 +:100C90009999680FE4B8CF25F17B29CCDA7A0DD782 +:100CA00083956F44D851DE0B703186FB9D7B4CB42D +:100CB0004E8172DACFA87CC3B409EF895446C17A59 +:100CC00015C6CF7D33CC877CDCF866981EED46EFE9 +:100CD00074F77348CFDC377B8FC1F5A1B3C1A4672C +:100CE000E4F7389F273DDB09BC37D25BC17C26E5A2 +:100CF000D35DC3E5A548F069B1903FB790A32B55EC +:100D00005D480EAF3C0640E33EE963CAC05DE8279C +:100D1000D82DF47E9394CB025C0F417941FF183AB1 +:100D2000FF2BFD8D60392C6BB352BFE56D7621EF43 +:100D300036CA4BB92B167263127EC62CC1E7BB5361 +:100D4000DCEF205E0AAA41EEA3681F3F0BE5C9CF86 +:100D500037462BF217F04D624980FC5437DECFD076 +:100D60003F31C5B9886F66411AE89FCC6EF74FAC2A +:100D7000E31200FE892B327478DFA99D7FDBF9E650 +:100D8000E6F87F8F9097E2485F4FF4670D55610E4C +:100D90003C877E398EEFF72C5CC5F1B8D0E0CA45B0 +:100DA000FF62E12F158A97A1DF817A69D8912A63C2 +:100DB000601CE5FEB641CC0E7898D2D683D23713AC +:100DC000DC47110F456DD304BE067DA3FDC5A14EC2 +:100DD0001E4732784D8E8D19184772AB48E733693C +:100DE000CCFA4CE07EDE7A1DC5C3E4BEA38C2B9901 +:100DF000F0BC7C801DFD425F9B4EEF3704C79972AB +:100E0000B8DDBFB0D94076BFACF1CFC374507F2EF0 +:100E1000C3D905EDC9977A771BF2F5BCC9DE570D2A +:100E2000909FFFE4CEA891763F3EEBF4BE9E6847CC +:100E3000EB008F18EFAA5BA3E679B9BF13C1F7C91E +:100E4000387F4B7E0EE6F3796DDD889FAE5499C8EE +:100E50000E5D01BE65017648DA1DA9E7A5FD917C0E +:100E60005DAEE7FAAB3C32DAEBC908B43B935C39D0 +:100E7000C8777DF8791ABFDDD9B47614CAC1A53810 +:100E80003AB728ED46B01CBCB6141CD35E1DED8EDF +:100E9000D4EB52CF4BBB35FAE52F77FE15CD558AF3 +:100EA0007B4032E0EB6E3DB75F77EB2DC43F63E3F1 +:100EB00026E9916F6E5E8F1E137AF498468F5674F2 +:100EC00062070627DF9A1C7415EDF34CDC7F443D66 +:100ED0001FD8DFA329A3C7E03CC627733BFB5DC136 +:100EE000DD99FE1F9F7C6BFA7F58B288F7DD40FFCB +:100EF000172673FD1FACEF9995BFA773694F5F2F3E +:100F0000DA83A30CEC03DAC18608FB16610FC85E16 +:100F100084477BBFCE1E5C4D9B5988780A610F1EAB +:100F20004AFE16F640F2A1941B2927522E82E5486C +:100F3000CAC5849FC23A11E9F41EBF5750AEF76C80 +:100F4000A3FD467BC46094CF763F6E9742F2D6C134 +:100F50004E08F9F1CB8BD66E48B990F222E5A75C2A +:100F6000C8C5EC20B9D8A7D63D330AF7CB92DD6BC4 +:100F700093E3FD7252B623D83E74CA57185964B32E +:100F8000E3AA18F25539A4817C65EA441E9E49BE45 +:100F900035BF68D94DF2D36FFEFBFCF49B4EF8E9E8 +:100FA0007FBE0D3F75F4633FCEB2033C57B240DFC6 +:100FB00066F8F96DC23B8CFB0FDDF97A00D6970419 +:100FC0007793318DE23E13AEB32A8A2F0ABE947412 +:100FD00096FEC06C11773893E27A07E1C5F5C082BE +:100FE0009BD37B4467535CB311D727B3210DF40324 +:100FF0003AF37F9B6F51EFBD7193743E96FC9DFB5E +:101000008DC79243FB8DC7B1FC9BD2B5209789F861 +:10101000DE8F0B30DE38E1299167CB0A108FD34683 +:10102000C8FA9F3CE9EC81FA81C9B838C539DE536A +:1010300045DEB3F4F018683FE119E68F9B43FDD815 +:10104000ECE8F6B888C2FCED95E71F3BBC86E8519A +:10105000CBE5CCDDA2E7FB3F229F05794B407E44E8 +:10106000507E036F1FA56F6181E745909F94219C7F +:10107000CEAE00FF0186DF7F05ED85556118D7A84C +:101080008CDBF8D615D46BF50AED45B5E381D514A4 +:101090003853C5FBB9945F73D8093EC203BB78BE11 +:1010A0004F4AED931EBDE837E0DCBDA14E71D2B9C9 +:1010B00083118AB75B46477CF749D1DA27FCD16BAD +:1010C000BF67781EEF56BE6FBFCFD68DBEF7996E45 +:1010D00061FCFBB2439F7FFE5E0AE7EF3159D121ED +:1010E000EBC7A5A8BC1F1137A0F1A1684A5DE87B3A +:1010F000B013C5B8CDB85F42F8DCF624E2B7D92802 +:10110000F1FDF293C8776319D3C4CF607CCADF9F27 +:10111000F272418D9E4FD71984AFAF9BEF8014A917 +:10112000BFFDF8F204D1CBF435F87684C0B75DFB8F +:10113000BDEFEBE835ACC3F7826FE7483E766AF85F +:101140003D5AEF22FE8C8E53ACE84757B8C2D6E02A +:101150007AC12F9FBF27BE6C96FB031DE4EFB5023B +:1011600094BF0A8947CFEB4FA2FCBA74EDEDB93CAE +:10117000B6F33573F601BC52C80FBE7FE4F9FA2707 +:10118000312E097C41F594D707C01D2C8F7541F98C +:10119000EC20F915F247FA03ED01E0A927EAB7B808 +:1011A00063467B009FFC4CD0E9A2B827DA3C9AFB4F +:1011B00093CDDD78BA2385FB8FCF097C6E12ED9B32 +:1011C000C303F090AAE11F1FAE5B02E64D78BA3F61 +:1011D0004ECEFB93827CD063CD365EBF2DE5A32738 +:1011E0003DD9FE7C707FAFA67C528078F1F7FFF18D +:1011F00061F423EE1778DB9172E4B02752D039C145 +:10120000FF4E21F007BD63518EFCA174E48F1F7661 +:10121000E44F4FD0F7F44E7767DF7B3A7EEF0CFA5E +:101220009EE13DEA9BFF5ED02D3F88AE7941741D63 +:1012300013942F9479AF46FF4ABD5C5CFFF4E30939 +:101240007118DF54E838BF9F9F4F93BD996F95FC8D +:101250007BE630F2AB9F9FCF129E27D709BA79CE9B +:101260003D897A7812EAE151FEFC14D443943F5F41 +:1012700080FB617E7B7581EAEFAB91ED2F92FD7A69 +:101280006085ECEF33CA4B3A32CF25B277F70BBD0E +:10129000C33CADA4F7E735F0EF3F7DFEF3C35F2B12 +:1012A0000FB54178D91094F704B55F7703FBB622E8 +:1012B000E8FBC782EAD704E5D707E56BB4DF17CDB3 +:1012C00052480E8B46F0FDC960B90CE68F2F52DAFA +:1012D000E363EDF65C8924FF4E235713AA79FEFAE7 +:1012E000F3FF29A8890CC8A7B0891EB2EF305AC0F5 +:1012F000FD41D0B91E15F8C1D089DEBCD899DEEC0D +:10130000136CEF79FD3FF0D724DA2FD2F825FB5488 +:101310006DBE51957047BDBB2832605F955926E27E +:10132000BABAF3FD9B8889635203FC224FF84467E5 +:10133000C03C65FB715F5D5771BCF8D4F0899B714F +:101340007F68B4D8D7B4F114ECA58AF6BA52C46F4A +:10135000C6E1395D6C17EEEBB930D00F6275BD7028 +:101360009E8D3F52F9BB50D5401FC05311B3D37966 +:10137000D39978EABE3BD447472FF90D7CB7EF47A6 +:10138000EA12B4D34797C4D239A645A9DCEFDC17DB +:10139000DD356136E41B231E267DDBF8C4584AF791 +:1013A000AACE95AD56E83A357962645FAC8F263C9B +:1013B0003936C44F5C06FC9D996A2738DC366B428F +:1013C0003DFADBAB0DB45F082D7E45FCF3A469301C +:1013D000AEB78B96F5A7FDB0E29F4F1A87F7B08A9C +:1013E0001F37D03E498BCE4A7122F7EAB1742E6A7C +:1013F000D60A917AEEA2F4CDFFFCBA1AEF69B5BE17 +:10140000A0D0FB0E775CAD7B67109E9BACE94EF7DE +:101410002EDE8075009EFB3EBEBEB717CF219F0813 +:10142000ABA273A4D09EEE8B955EB3BF3B310BDBBA +:10143000ABD6E5D0FE1494A3FF7C6A95BA09EF41C0 +:10144000154559C2F1FCF6A9AF18C5754E3D6EA2FF +:1014500077228E47BA67AC8FA3FBB8E8E9B3538A0B +:101460003D4A013C4CDAD067626212969B047DFBD8 +:101470004415011E8A74EDFC43F6A42486E727A5D3 +:10148000F699B805E671EA97BDE97CD8C154E7E45E +:1014900054C0D72FD29C5352E3115E6EB7DEFC0FBF +:1014A000DF8FFCE385E204E4AF8752395FBFD1569A +:1014B0009C10F8BE77C9453DF1C19B46FB227A27B7 +:1014C000303C4DC17536F0412CC6CD6789750BF0A7 +:1014D000F3929D21FCABE1A92AD1ABF1A7F1D94848 +:1014E0005F3F5F0F7F17F519AD37205FB121732D77 +:1014F000DAB993A625EC440FD67EFE91ED0B233C82 +:1015000019B68579C332307EEA1C87FCCD12EB7A9E +:101510004DB604C8A168FF770F3FE7FB77688FEBF4 +:10152000BEBF7BFED712B89F21DB9746593CE85CD3 +:101530009CB658F4488FA3FAA5A7F03C5AC90B06ED +:10154000B203252FC43FD68AFA07F806E36BC1F32E +:10155000FA63AA81C7313A934BCF18AD5CB231130D +:1015600071BE9DC965CD86DC899B233B97CB522BF1 +:10157000D74FE35EE0EF51960EB5E8717F73F40B41 +:101580006F6DA17B740BC286E0BD89D2174C44AF4E +:10159000168BC563BD0DEF1358F431903E9BCAED19 +:1015A00069BD909F5C95E9CD4328A57B1272DFF061 +:1015B000EC92679EC5E397E79877DA70C0DF6527FE +:1015C000E7D3CBBB548A3F06EF23961FDC69CC617F +:1015D00037B18F7883FDC332D622DEDF0DFD7DF07B +:1015E000FEE1ABA9C1FB8706BA4F5E2AF60F73373F +:1015F000280477E9127ECF3F3796C78D4F2E05FA24 +:101600001B69DE1EEB103C0FCDED4E2953BC66F876 +:10161000F5AE0D0B288ED913F184716EF16EE2894F +:1016200030473AAEF34B5E0823FC96FE6AEE5F7ECF +:101630009985F7FA0AE202D7D5FB912F387E19DE99 +:101640001F94FD9C5EF6637AA731F745581FC37C53 +:101650004A63D8ABF76720BD92D2719F53B62B5D1A +:10166000FEA35EBC1DACAF611D5DB44AE5EFC7ECE7 +:1016700036911D04594F6401F72C67AD38683472F8 +:101680003BC6128709FFDAEEBF9F761CEAF1EA6ECD +:10169000A5B88726F127EF5115E9F8FB74853A853F +:1016A000EE578126A37B499753B95F7B3A959F6795 +:1016B000284A77D0FD9CF2B526C7F20CDE4FFB7DA1 +:1016C0004F58DF95EB9A4B683FF3F7268AAB54AE41 +:1016D00008738645F1F3173B06D0F96ABD11F05146 +:1016E00066E7FAE2B2986FA57DD25D749F41CF8E16 +:1016F000E8A1BEDCC2F563790CE03D92338A6E1836 +:10170000BE67C7E8DC24F69B3428607C4594433FE1 +:10171000F6287FBF4D3A5683711B6CDF7710E2319C +:1017200076DA7484EF1595E41990B47604FA7DAFF7 +:10173000A899B8DE2E5AB56F1CEADFF9DB07E38DF6 +:101740000956F4EA07643FE60BFAB7887367C59059 +:10175000C777B622D2B83CB9551E2F8A485334EF0A +:1017600010C9FAF255061EBF073D8F8AA57CD9C75E +:10177000D46FB9A53901F56FF96EC330D4D351696F +:101780005C2E8B97A5651F01BE2A3644D3BB8365AB +:101790009E0223E6CB6A15CAFBBF8B4F473E3DBF77 +:1017A000E2B528E49F1361BE9E68975A178439E812 +:1017B000DEA195C7EBCEAFE849F79566599B2DF8AA +:1017C0009EC1AC45DD6DA8BF8F5A7D46AC3F5A9790 +:1017D000A1C3BCD36ACDC6BC537F1BE5CF8BF32D11 +:1017E000F4837CA5703A976DDB67C4BF4F3244CC5D +:1017F000F7E22B1FF4C2F84F797A732FB42BC0078E +:10180000BD5210CF2F2964972BB6F1F3EE920F2A19 +:10181000900F40EEE6093EA8D8F5DAF7511E2A905F +:10182000FE433AF211F0F37E2ADFB1711CE3DFEFE1 +:10183000473E91760CF22B0C368CDFF17C661AA7B2 +:101840003F948FE1E59E01FC1C5DFB39048D1C7407 +:10185000465F571AB787C5CB4CA46F5D695C1E5AAB +:1018600056ED8E42FA5D7C65DF01DC6729DF0156AB +:10187000DA1E421E043E2A71FE51043FF9179538C4 +:10188000DF28FFFCDBF95EC86125E3F393F3ADD4F9 +:101890008BF9CB7AF1FD24C12F654CE06B576F2E8D +:1018A0007742CE508EE9BD0E313FB74DFB0EE5F7C6 +:1018B000C5FCDC2265D6BA28C40FD217F50F3E103E +:1018C0006994FA049A5CDCBE91CEF14B7A49F857E0 +:1018D000093840DF39636C7E3AB674F24E6495E0A5 +:1018E0009B638F7749AF07FC9DDF4ACF6C11BFEA3E +:1018F00003C6937C23C7CB7D79D2DD386FE8DF87C1 +:10190000FDCB718F7A22F4D8CF51C6E543C22FE5C3 +:1019100032B7FAA1BB074761BB8B96EE0370DE9C22 +:101920008EABD2ACF4BD13FD05F8DE59AF50DCFA36 +:101930009858E71F7BFCB5A8E2017E7E7F427C279A +:10194000F90C7F303E26E16DB2F1387030DC520F79 +:1019500049B8739FB8EF6E2C97F0E3BE51209F4AB1 +:101960003C4A7E95F7F582F996784EDA4FB573FECC +:10197000AE4C3D46E7773A9407F727FCA213E25CAA +:10198000796B3CE371FF1589FB35F78A188B0CB432 +:101990003FD28EC0CF1A7D80FD69BFA716E73C8B72 +:1019A00074BB90D68DFA3FC7EA8C39D06FD999E6CF +:1019B00071F8CE9DF443EFB8EA53A3315EB58B9F27 +:1019C0007793FC5276613FC941B9B8FF54B4EA83BA +:1019D00082E1C8EFBF35D0BE4ED1E3638DE8DFCFE3 +:1019E000DD327318A201EF41A05E3FBB796826BFCC +:1019F00059604D9886F721363F33ED01289F55AF4A +:101A0000D2BB0DD80FCA6FD1A399145F3D11D65226 +:101A1000300AFDF81FA856F4E36FDF32F4316C7F13 +:101A2000BBA56B0C3DB6B13996F24E7D34D907E9B2 +:101A3000F7CA7380D5E2DEC75F84DE3FDC9E2AE210 +:101A4000FC5F752FDC8F6FDD1846EFAC141AED7557 +:101A50003E1C6F4F175A67541AF1EA23DD5B25BF0E +:101A60006C8E9199938650B93909CA0F1A9A1F45FD +:101A70003B72F051CB607C3F92A9D78615737F9A59 +:101A8000EF3BC66ADF2D91707C24C60FEE4F7EDFE0 +:101A900084EB081BDD4FA4EFCFAEF8ED34B48367C1 +:101AA000B7F6B4E1BC4FEF09A3FB03A70DDA77CF7C +:101AB0006EF5DE57F07D29796FF5749AD68F93FC19 +:101AC0007EC37B377FD39E83BCD1B9A50B4B19DD79 +:101AD000FB7E398DD1F76322BEDA89E7084B6A4D68 +:101AE00056BC077312F91EF7B376ABFCFEA599CB73 +:101AF000C1C9DD9974BFB7E46F3C5F52A778F13E6E +:101B0000F2FEA79FA0F30AB3C1CFC4AB09EDFEF369 +:101B1000BAA7A7A1385C76B857E27DFECB5BF9F98E +:101B20008A0EEF321CDC7920C9DEB9DFFC5DFBCB0D +:101B3000320E119FAEBDCF2FF12CD74F6F023F8CCD +:101B400018E2C7DB674BE790BF7C61A99BD24BCA09 +:101B5000B1B5B7231F5BA2E9BEC01FEB9F51F1BD1A +:101B6000A8F25D83AFE13A78546434BD93F2D9D2E0 +:101B700025B48F7A616915A592DE320E77C7AE461D +:101B8000FAEEB3FACC06BC9FFB4664B4B003B69041 +:101B900074EDECDEB19CD7B91F70FA4AB8CF6D9DD9 +:101BA0001985F36A7C3EB66124D23522DA8A7E5FDB +:101BB000A93847726A3DF7ABCF98A37F930FF43DE6 +:101BC000B3614A02BE3737BBF1DE69585EB247B136 +:101BD000E27AC0B1675214AEDB3ED5B744E1FDA84E +:101BE0004FD7CB7B555EFA3B54A3F2D8146C3FCA57 +:101BF000A767F60CBE758D7C32F2829EEEBF9E8783 +:101C0000728A935C0BA73809FCC4E2B991D9AFF38F +:101C1000F84AFB3A57ACF36E17F37E34DD26F73102 +:101C2000A83C77042F3FBD61E744ECEFEC668315D9 +:101C3000E1FE6CB381FA9F07EB331DC07B662B5F1F +:101C4000F7601ED7CB67B7F2F5CDBC3ABEBE295FB1 +:101C50006070F2FBA25A7ECC0D6847EFFB74F25E17 +:101C6000C83C279FDF3CB09738DF60BE8D6175743C +:101C70008FEC9B9E170DE6DBF9925F857E68E7D7B8 +:101C8000CEF844E013E51DF955F2C3BCF57CDFDE68 +:101C900056373807F94EF247F03B59D546C6DF575D +:101CA000D485D37BB89322ED06B40F53E25AC620F5 +:101CB0005A3E4EE77E809AAB73E2BD37566D0AF905 +:101CC000CECE8A74EE57457465C4EFDE742B3FCFD9 +:101CD00029EE7FC914269286767B5284ED0B3B3425 +:101CE000793AFDAE7BF4C0CF936EB73DDADDC1D853 +:101CF0002FD30BEED1C37C2665DA767783FCF3BF56 +:101D00009AC0F3B7D9861A20BF4C9978CF18C8D794 +:101D1000A73B9F4A0F18E7EC962E69383F28FF191A +:101D200096D7C5BB7F8E69A5B80F7649691DB424C7 +:101D3000C3DFFEFD3D96A37FB4FBF32D0696EE18A0 +:101D40008079097FE8B425DDF9ABF4F88EE5C58C20 +:101D50003D4EE7F53CFC1E0EFCB8CC09784F8AF3EB +:101D60005BB1BC975313742FC7C1EF9FC9FB52F2ED +:101D70003E545FFF7DB20DB7729FEC9281FF1D2A2A +:101D8000C5A9BD0FA634FC89DEF9A9F6B09630A22C +:101D900083F69E4D39BE53771BDD0BA2FB874C6F3C +:101DA000277D3357FA3B68AC87F9DF296089FCFC53 +:101DB000C1A3821F4F2F653D7A80E89F7FB739CA44 +:101DC0000E705C98E8EB85FA2032DCFD27C4D7E979 +:101DD0000DD5A90BE3F01EAAC9910FEDCF78F97DBF +:101DE000CE32E1B7B2CDF1422FA8BE3BA15D534642 +:101DF000DF4D6887DE177C7521C397FE23D42B192E +:101E00007C9D04EDE83C5DDEF2BBE2B1DD85ED4F8B +:101E1000F4980D709B0006BCA7351EFA1C61A3F751 +:101E2000AA984AFBCF5EFE7E929E79A26CF8EED510 +:101E300033E9E23E11DD13947492F8EF4017181A5B +:101E4000FD599D991910EEBE6C03FDFD2F491FF938 +:101E5000CEE2C2DD3CFE427724451EE348A7CDE238 +:101E6000EF9F75B08B6F91BF0A62E9D1E89F0D3388 +:101E700043DBC9111B8DD8F5776D2FFF9D2EFC928A +:101E8000C16C70E03B92A5A2CD58B5D08EEF5B2D12 +:101E90008C37D37B250B5FE84EFCC196FC9005B6D2 +:101EA000631B62895F5666A884FFB9F58CDE1D2A24 +:101EB000A84FA6F394F9F5364AA3DA12A9FCEC6F01 +:101EC000DEC9E27A89D3A7E07FBA8CA6734BFFD331 +:101ED0009B52D6D97BA79166BACFBBF020B76B0BCC +:101EE000A7CABFC7C2EFAFBB0438AEC81A8A0BB9C6 +:101EF0003ADC53E7EF57BAF0BE007EE734507D6717 +:101F0000EF574AFC9A04DD82DFB39C7A303391DECE +:101F10007F14EF594E17ED9AC5BDB3CEDEB5BC4F59 +:101F2000B47B226A5C13F2DD746769C8772DF59E75 +:101F30003007FACF86D4487A47E13E37F8979AF5CA +:101F40004C8B1EF1302D9BBF733975BAB6DE90FDF8 +:101F500039E97343768777920CA88F4D2E6DFBEC91 +:101F6000AEC20EF5657DBFF65DD15423D94F3DBE9F +:101F70003B0BF969E25D51F40FD1FFBFECB410FFE8 +:101F80009BC43BB8CD2C2B11F5C2ADBE27FBFFDBAC +:101F9000FBB1C1EFC406BF03DB7FEB424D7E60DDCA +:101FA0000F35ED6FAB5FAEA91FEC5BADA9CF6CFA3F +:101FB00099263FB4F9394DFBE1473669EA47B6BC8B +:101FC000A4A9BFFDCC0E4DFE8ED63F68DADFD9B690 +:101FD0005793CF61EF68DAE79A3FD0E4C75AFF57CB +:101FE000D3FEAEC4139AFAF1F6F39AFA097DAE68FD +:101FF000F2058E2F35ED3F37BA577745BF22EA0CF1 +:10200000F1AD3A4361F844F9E5A62966D4076BBA05 +:102010000A7D24F86FB9B0D3AC07A37BAC63D56C51 +:102020001FF15F3DFFBBA0C1764F7FDEE5C4F81F07 +:102030007B8DDF6B8B067F521F307E8CD3CC02FFF3 +:10204000EE5D6C9E55938F77256ADA77996ED7D4BB +:1020500027B9FB68EA53E63834F9B4AA119AF65D59 +:10206000973835F90C4F9EA67DF71A9726DFB37681 +:10207000BAA67DEFF56E4D7D5FEF1C4D7DFFAD5532 +:102080009AFCC0BA259AF6B7D57B34F5837D359A8C +:10209000FACCA65A4D7E68F37A4DFBE147BC9AFA1A +:1020A000912D5B35F5B79FA9D3E4EF68ADD7B4BFE9 +:1020B000B3CDA7C9E7B0839AF6B9E6F735F9B1D63B +:1020C0004F34EDEF4A3CA6A91F6F3FABA9977ECED8 +:1020D000843E9F6BCB85DF53E0F897E6FBF6F76E07 +:1020E0007728741FEA5CD76EF27DC5963015FD2403 +:1020F00017C5996C781011F515DE27B7F1F33985FE +:1021000014AF8A237F884C941DCF0B81DF1085ABE1 +:10211000B68C0CF4AB23FCFE5BEAF5CC9BF7DFDA64 +:1021200084FFDCD5EEBE88F231AF6EFB387A9F9823 +:102130007956221CF2FDBF7783DE6D95E978F3199D +:10214000A60FF0170F86D5A60EF99A38C178F305B9 +:1021500086EFC1B6F72BE222F8C7BD1706F4BF160B +:10216000D617F8F7236B979AE96FC7FF6CA995F21A +:10217000EB962652FEFF003A29BF47008000000080 +:102180001F8B08000000000000FFED7D0B78544518 +:102190009670DDEEDB8F249DD07975779EDC3C490F +:1021A00048089DF0D8003E3A216040C0E635044919 +:1021B000A4C1A84143BA81F84F7475BB311002B273 +:1021C000B391D11095C1860164199D092EA3D1093F +:1021D0009AF09AE03A4C601CC5D91937A0A3E28E58 +:1021E000101EE3CFEE8FC37FCEA97B93BE9D0E382A +:1021F000FE3AFFF73FFAFBB4385575AB4E559D7369 +:10220000EA3CAA2AAD5E898922636DDE1C4A9FF3EF +:10221000DA9998C9D8366F31C1DBBD0E82FDDE7206 +:102220004A777A9D94BFCB5B41F01EAF8BD2BDDE67 +:102230001A4AF7793D54FE92B781E09F7A7D94B6B1 +:102240007B9B29FF156F0BC107BC6D04BFEAF553DB +:10225000DAE1DD4BE91BDE762AEFF47610FCA6B757 +:102260008BE02E6F0FC187BCBD041FF19E26F8982E +:10227000B78FD21EEF6794BEEDEDA7F277BC57097A +:10228000BE8EBFDB19FC2ACD9FE431263097E67A5B +:102290001EC2CCC92632F600FE4B82FFE24688CC35 +:1022A000C2D8FD8CFF3ED7B09A76139477FEF23FEA +:1022B0008502C674A58C8D1F0F6962F6CEC634C622 +:1022C00026B075E64F7218D34057D76307FB094E07 +:1022D000191319D6C3DF752DFEDFC7583CFCBF9418 +:1022E000E5784C836953091442FBBE55827F771A07 +:1022F00055D7203EAB8D1CBF695A1395573E2CF81D +:102300000D02635522F3E98B18FB7D5854011BC164 +:10231000D8258F2E47C47221DC0E8304F88F3A44EF +:102320000E7E5D2C8EB1A59D861D9BD206F1AA84E2 +:10233000EF35F0FD2B561A0CAB643D3AC403F21D89 +:10234000DA18C69EB7B8A64B90FF608AC6A787F674 +:1023500099C99FED8C64EC2D8B6B06E65FF2DC7700 +:102360000C1B7FC06CCFC67E661BBAE21741FFFD17 +:10237000C7B5F69DD2F0F3E16E29676CDC0DCADFBC +:102380003C97EC023CCAFFA275E1FC9FD04556F891 +:10239000F3012F49E0784A1A553ADBEA5A82F87C71 +:1023A00019E9B9470353F8E56DABF6AC812155AE99 +:1023B000CA1AE182EFEE822563198CCD65928E41B7 +:1023C000F97CE6389A064D2D642E8217311FA56FD1 +:1023D000C5BBAAB19DC5CC4FB06BB22135D4B88274 +:1023E000F172CB78B9657C94F471ABAB8EE3E520E8 +:1023F000BC4E4CBA231BC7A5E0F59655A27A73587C +:10240000FF76C4EFCB83173F113286D2C7774017D0 +:1024100026681EEB313DAC73A38ED1F78D8F087EFD +:10242000A46B852E2A9991B7FB18E40B817402F4F2 +:102430005184FCD29F3A3792E8E449091A7C7092A1 +:10244000D6A71F0BE3D4F8B3052DD1875E00FC1E81 +:102450008803FA481F9E0EEA9A210DE01FA0AF677D +:10246000B0BDF3AFFF5D0ECE97FBCD4912CE57A3A3 +:1024700006D601E8D8F7B6D6BE5B92991460ED9403 +:10248000317EA46B26DAED73C7E07AB1A54EA8DFE2 +:10249000AD650DFBF387F6FB2AAE17B47FC2A62B02 +:1024A000F753BB9CCF95F29FE2FAC563CAEBAD5ED2 +:1024B000F569AD16F03F71E89C5E1A13621C0D6F52 +:1024C000E76606E0EFEE3833DD6142E4FAF2E74515 +:1024D0000EE69F94E944A11FAD3ED2B5C314881700 +:1024E000EF17E8F9E74437D140CF1944CF9FF8E020 +:1024F000D3390669C42248FB606ABA2075BD60D62C +:1025000023DD2C67764AAB9993D20760F9917E9DC3 +:10251000BEA7F438EF0FB276CAAF2BBED782F47CD9 +:10252000BFC6958A702DEBA57C37EB2FB3C1FC2D70 +:102530006C5E7BD40658CF6F796A5A02CCEF3CFFB1 +:10254000B2A398CEDD257CE293883F7A10AF3EC1DE +:10255000B33E11FABFFBA592F549903F47CBD78513 +:10256000FD2B5F17457E048F1BF8A1978FCB41E3AE +:10257000D24695ABF8A1F209E610A09DFE8306FFB6 +:10258000CEB400FE287EE8DF93508E89FDF7E07A16 +:10259000BBDF34C4E07A3F08E21BC72938186B80E0 +:1025A000FE90D62A63882A88DE1F62E176ACF7B9EE +:1025B0004CDF9FA730A2EFCF05E66040BF1774A69F +:1025C0006601E55AAACB5604F8AC60BE2606E56E55 +:1025D000CD4B05384F2325D7A744D71FB53715A6B0 +:1025E000A1FCF7A70A28FFF719EC8D69AAFD845D05 +:1025F0008F4021E361389F3FC076C70EC54B283E10 +:10260000F69F421463063DF3198B88BFD944E4EB6F +:10261000443DF157234E6D06F6E3943CA6A1ED9F91 +:1026200090F1EDF94A4B74EF83F1EC1642F5C3F7E4 +:102630002B43F8603F243F2C8CFAD1A7713E56FA09 +:1026400063A6BE6427D0756A844B978682C116C77D +:10265000E58B99CB979EB44F33717DE64CDEA8C8CD +:10266000656A8FDDC6E5D1099DE443F844499A1DAA +:1026700024D7809CBDABF897A7118FBB8CA62E2DBD +:10268000A4EC16DD9FFA947D307D70FFBD4BD97FA1 +:102690006FE1FBEF1C99B5EF12BBBAF17BC6EC3AC8 +:1026A000C42F97FD5E998F6DB8DF2AF271C87E0B3B +:1026B00003EBC5F913252B8374B5C0C7BF3A25DCDE +:1026C0008F7CC436E7D2F8F4B2FC0CFEDE5AC15857 +:1026D000A651C613FE4B70195966CE209C54635602 +:1026E000C1291E9BAAFEC80649559EE6CB51956797 +:1026F00034DB5570564BB1AAFEA836870ACEF59743 +:10270000ABEAE7ED75AAE031ED15AAFA633B5CAAE6 +:10271000F2C2AE1A55F9B81E8F0A9ED0DBA0AAFFEE +:1027200077A77DAAF2497DCDAAF2299FB5A8E05BE3 +:10273000FBDB54F56FBFEA579597B07F56954F3541 +:10274000EE57C1D3CCAFABEABF80FB16F0CF1DB6BE +:102750006E55FE0CE9B8EABB3B734EAAE017E47570 +:10276000F62D0E27BE682DE7FBD16CFB07AA765825 +:10277000E768BEFE613C6F7BCF1F0B514E6ED7F4F6 +:10278000A721DD4A5A7322F27166F1DC4340662CC0 +:10279000DBB1AA14C55B4EF95387301DEDDC5F8AAF +:1027A0006C925F71F210A605AE8BA5D01CB3D74416 +:1027B0001FC6B4C85338D58AA834CC3D8CE944DF51 +:1027C000AAA928575F785C3F1AF9282A46A14F0723 +:1027D000D1677D8286F8B97EB1C98FF2C732C52430 +:1027E000329013961F5AD6B1024C8B9A316DF61A5D +:1027F000995F0FFA809751BAC96B66FE6C2067AF7C +:102800008DE0FA93F795A7433B23AB4433AA99E6AF +:10281000518F2548D0BEF5E5969C5D76C6D6EDB0C5 +:10282000CFD7E542FF199EC53BA2014E638E05300E +:102830007F1698233699B1253BDF76FAF287C29747 +:10284000339D4D2417C4F65CD4FF947637967E6E84 +:10285000D79821DFF74BE71198F7ADF1E1F41DC2EE +:1028600025995FA75D470BB60BF99EF6107CFC4CD3 +:102870001ADF7F97A4737D0A8784EB66E5CBC6AC2D +:10288000A0A78C80B9DC3AA9E10CEAF0A2D927A074 +:102890007C62D7E07B902B89582983E0DBC3014E13 +:1028A0004058626C7F96EBC7D8AFD5C5D8D900FA2F +:1028B00049A851C35B619ECF660EE2A35BAAF18972 +:1028C0003006DD8F9D763BF4B3AD0AC60BF0563D66 +:1028D000D737947AA3348CF6F72FD3F87ECEAECDCB +:1028E000B7A39EF4A53C9EE7BCFD8B3ECE447BEB9C +:1028F0002AA589351EC105F2CD5AE9B4FBA09EAECA +:1029000011E62384DEF28B3491BED71D7E4490A065 +:10291000DEA76912C189957E1A77520DB41B80BF5C +:102920004DF40966C8B73DE613103F9BD96967F0BF +:102930001D335A88FED7C83C616BF8CBA28F410F7C +:10294000D3799D76ACA7BB13E8331F27D46366B851 +:102950004EC9E347B010EBA3A4863E0D73DC409F45 +:102960008F4A7DD443FBC5DD26290BE8FB85C5A630 +:102970008A1D21DAFB549E9F0D31EAFE2D5A3E1F1F +:102980008ADCBE6CE6EBA8F0F19A68A692E36B5283 +:10299000C65B6F84AFB5CDC85C01F86E857ECCD0C8 +:1029A000BEE1AB55661C3FE8D04EEA4FE4F264C787 +:1029B0008F72C86E0A5EC721F408943FA208E9A38B +:1029C000CFDF087C68A8D2DB516FB2FE4393807BD7 +:1029D00073226B1150BE5853CA7A44DCD74457AEA9 +:1029E00033843E7933BA54D64FD99F83D74B773D42 +:1029F000E3FD129CEF7FD531D4C7561F8F8F710531 +:102A0000D0534C3AA7CB62D6A245FE98CCDA29BD6A +:102A100085F5527A1BEBA7D4C1CC22A6A5CC4E6972 +:102A20001973523A9D79282D672D94CE64ED94CE7A +:102A300062BD94823D43A99399C9EE9A07FB37A6DC +:102A40000B9893D2EF310FA599E99C7E2B580BC1BF +:102A500077B3764A3B80EF243DFA018C9476829CD2 +:102A6000C3F44D9073987679252665A31F2087D2ED +:102A7000235E3BA5C7BCC594F6781D54EF6D6F3936 +:102A8000A5EF789D949EF05650DAEB7551BD53DE5C +:102A90001A4ADFF57A287DCFDB40E969AF8FD2DFB4 +:102AA000799B291DA5077EC6F9CDE92B447D3EF50E +:102AB00023BD4302F9EC91E5D26187E699DCF1B8D8 +:102AC0006E1A66403A285B2320FD5973340E3FA4EA +:102AD0009B72560BF742BAE104D7DF0CD648D20FEF +:102AE000AD6DF58204ED76087DDA0858CBE9E9A9E9 +:102AF000738D209F4B3AD9BA083BC2194F1981EE0A +:102B000076E83CFD3BA0BC64A734D7087BD6E4C87C +:102B100053FFB18FC3543EE9086B34033C2B3DFB9C +:102B2000A93881E381C2EF7B3B73E6AECD443C25FF +:102B3000C2F3C534302C51BF7EC444FA7561DBD971 +:102B4000420DC0931A4C45681706D4EB42BA1FAE2B +:102B50005E70B9F2DDB65596469C870D9F805A0E81 +:102B600059A9197D85ABF3D5ED6ABE5EFF4C7B8319 +:102B7000FE03EB0937686F7F96A3327DC2FF7E3A72 +:102B80000FA66FDDF58FF66BC80F648EC1FD74570D +:102B9000349733FDA09FEE04BC77C5C8F0C64C1A2D +:102BA00017CA435CB70D9BD2FD3E80778539571F0E +:102BB000C7F27FD4D87742D1AE70D7A65C8233C932 +:102BC0003FB121C69313938FFA3CDF975A931F0DA1 +:102BD0009302F8BF399DCBAFADB75CE9DD81764498 +:102BE000B38665C1773B9B976FCC81767EBC19F429 +:102BF000078047DC5ABD310BCAD3376A266A65198C +:102C00008778FC7873F59E4DA85F258F8EC98676F0 +:102C1000336479991ADB57B806E8BC55AFB6A79567 +:102C2000F49F647EA98666CE826C4D95EDF41D3AC4 +:102C30005611B8DFFD4CC6EF57593CD5DDCEFD57D8 +:102C40008691E1FE2760FC2523B9BFC3B2CE48FEC2 +:102C50000E4BF27F9DBC03CA2DDB347654E9446BE6 +:102C6000ED5A1DEAFB8B593BF2E30E817FEF4BE1FE +:102C70007A21280AE97303ECF2ADDED38B3203FC30 +:102C800084B60A9F80F67BC9C85AA10FF79FE40754 +:102C900005B4FB2D152EC11589F68187CACF65B9FC +:102CA0007E920EF8D92AE1FB40FD92B912705DA127 +:102CB000DF8A76D2F35851607FA7B3F83CAC073B6C +:102CC00099F4D5757AC22B78BE4E65971EC0F695DD +:102CD000750C2EFF7E06B7AB773D015D201F4CE2E1 +:102CE00076F389DD89A43FCE690D77A0FD74E2A952 +:102CF000D165046F99EC403DF2C4EEC9D3319DB368 +:102D00006526D53B21B01EB487E76CB95BC4FCD403 +:102D10000CC00BDB3BA3277A9CB3E541F9FB47CB07 +:102D2000B0BC58E3FB09DA91C58DFB22D04E9E1C46 +:102D3000F94A12A627347DF5DDD0FF5D66F62BDC5F +:102D40009E9D1BE3FEB11CFE31F7A9741DEAD7BF9F +:102D50004B4FA7F59CCF1CC4075083ECBA5BF6F62B +:102D60001E064D8ADDD6DE3F15CC5CE6E8301FC17D +:102D7000B4B4CB5E86D357D6E33C82E9F45E4F19F8 +:102D8000AA2FE5A75B8E60BA24D7F53B9C9F17FF5F +:102D9000E17BAFBC08F0C8C7EBCDA807653ED137D3 +:102DA0006327F9EB740CF9216B92A7458B046C74C3 +:102DB000C6A07C78F6695183FBB921AD250C61C3AF +:102DC0007DE91AB40B7745B7D4D0B8B3C219CEE3B6 +:102DD000DBB00F215D64453B63909F802F691D3EF2 +:102DE00093E9D310ED3147637E18CF1FA817CEE1CA +:102DF000F303F55AC204EA274620FB13D406DCBFCE +:102E00006DF2FEDDC63C09381FD648CF0EF4EB64E8 +:102E10009570FE67919C2EB07AD344FA849CCD962F +:102E200016CF9DB80E5697E8EB0BA43BD80607F4D7 +:102E300091748219DAD75B050E839C21BCF0877EE2 +:102E40000C8BC9427A8D82BFB502DA0BD033701C6D +:102E5000F34C83DF2974179BC1C73542A6BFAC650D +:102E6000BC3D05DFB80C2E9F016F4983F868657C77 +:102E7000601C9A007C02EAD1F806F066761BD20547 +:102E8000487A81A74C1203C75FAD7184A15D647A53 +:102E9000F5FBE84F8942390278FE53F72423F269A3 +:102EA000F0387232D208DF46D087516F9FE9E2FCDA +:102EB000DB58E911C83E4218C79F2C3AD01F68352D +:102EC000AD167401E3B526F37D7A66A5A71BE5CAA6 +:102ED000CCE2083BD2F79DAC7D9D99F3F7914CC0B5 +:102EE0006F141BF899D8C441BDF0474FBF7B1297B0 +:102EF0003499B597E4E2FEF9F8FDB370FDB63E3AB9 +:102F0000B307F14FCC79AA3B061A745E94D77D19AA +:102F1000F7EBA46C133F0E1C479207E040BF448DB3 +:102F2000BA1CE841052B7465131AA271BFD144E4A1 +:102F3000CF9C817A4A9486E43BC829614148FD339D +:102F400088AEE4F957D6E7AE8C4C5A37AB89AF035D +:102F5000EBB71B1746CA8355D609FA6D04361F0115 +:102F600074DF58A6F50B68D762FD28ACCFE29D91BF +:102F700043D769874E9A3903E5F4C31AF36E367462 +:102F80005E81DC7E4B7AEDC371540EF9A291FC7D1B +:102F900001F86A43C1EAF5B859FD6DAC6BEE8CB42B +:102FA000A1F989C90B66E23E9B58CB68FD83CB47EC +:102FB0003DA65E57B237C7A3FF88F9BBBEC17ACE24 +:102FC0004CDE5586FA7CF0BA2A74971A1B7A5F1089 +:102FD00033395FA646D84F95935E21929EE04C11FF +:102FE000E303EDA20D197C1FBAFD3513ED43EC236D +:102FF000A31FB75C7B57EF93B9B00EA5573468AEEB +:10300000B0A3EF1CFAE14C48A7FDEADDD5FF0AF5B5 +:10301000A67D651A87F96FB0BE19E810F1F5809D9D +:1030200001F0DA2FF6B4A0A3A4B192D971DF55FA5A +:10303000D923F7F30B9DDF49F23557643B490E82E4 +:10304000651E402F0069897E78197356B690DD6839 +:10305000CDCC07598D6EBDF625B45FFE49CFD0EFBC +:1030600038AF42D295C0F8E7554ABA65E8C7175954 +:1030700039EA11F32BEC943FBFD2CEF38D3C7F4164 +:103080008583F217543A78BE09F2613E1656F87BF2 +:10309000BDD0EE42538CA4413F78A593975F355045 +:1030A000F93B600F6402C98787F949DEB77CA6E166 +:1030B000F1124FB85F005C0D91453D12CEDF7D1AD5 +:1030C0007B162486149199017EB6C2E9D742F9F3A2 +:1030D000CC9F8013F946F56A6736E4BF912C9A714C +:1030E0007C6F38C06EC6F9AB1569DEE907F01B3599 +:1030F000C914CFD821FBAD7D2B8CE467055D87FC1F +:10310000AC6C45A2ACC7F0F26DCBCD7ED4C7400EFF +:10311000D23AF6DF27921E00F2F0ED1CD48B5ECA85 +:10312000B4874948B76A7EB3542F2FA1F62A99195C +:10313000EDF25995BCBDC697347E0DEA55A679339C +:10314000910E1AF7323BDAAFCF569F2A8B45789B08 +:10315000DDCEE5875A2E34566F392EE1783C1A734E +:1031600016D5E77EAD464FE92EAD30C8CFB4DED2DE +:10317000A0FC182A6FEC3DD84E4255A97D13D4B35C +:10318000C038D18FBD4DCFF37DF7881467B0548B15 +:103190005DE68241FE4E91A7D0827C1845F245C57E +:1031A0005FA35F52C33F92F914F85DC471F97631A1 +:1031B0003BC9955DEA7A20273528AF52DAD4F96702 +:1031C000B204C52FA59A87E079B67AB8DC0B1EE762 +:1031D000E0B8BAC246D1B8347C5C28D7203FD77457 +:1031E00088F2732B45BB24A1BC6B3F85E31FF5928E +:1031F000C8BA009E555D3413E969D6660DB94366B9 +:10320000B35E920B371BB7E2DF081E67F0F8366437 +:103210006869DF1CD007D71B491F6C7DC4A4C1B8E7 +:1032200022E85BE1E8573897551A9E09F33022539C +:10323000D6D7AF6BB93C6934119DEAAC8FE504FA7F +:103240001F84D1A523B0BEEE7AECBC728A1BE9685C +:10325000DCC172AC58966393FA607C2AFF73389392 +:1032600002E6F7D6FE18157CFBD54455FD12102E4C +:1032700081E5538D79AAF269E6712AF80EDB1455BF +:10328000FD19D254157C67CE9DAAFAB3EDF355F023 +:103290005DC54B54F5E73AEE5595CF2F7F4855BEA7 +:1032A000D0B946052FAAF87B55FDC5AE4655F99213 +:1032B0009A2755E5C1F693929666723FCF569BE7E3 +:1032C000A483E48B4B70460EAD67A914FB03D73D76 +:1032D0002A82EB53C1F51AE5F57841E0FDB1FE48CD +:1032E0000DF29DE27F63ED912AFF5CD7E4C9C63EF3 +:1032F00013FA72ECEF23DDB213DC1FC5FCFC3BC5F7 +:103300007FD5FD04D483F65647A65B71BF43BFABA0 +:103310004B0FFDF935E4BFB736D70BB40F6EAEE7F0 +:103320007E95AB7AE68A0DC08385F37EE5788E8242 +:1033300027734470FF6018CFDF26FB959E43BF5272 +:1033400036633FB0287E7817B59B50ACF7A17F4617 +:10335000A8F6087A945B2E66364828079753FF979D +:103360002BEC2358887956D256AF8D39A07D5BBDA2 +:103370006FAD1EC656973969CBB3D0BCCDC3C81F3D +:10338000F368E6942D6B81E7FF2153A2754910F98C +:103390003C3F5FF7C6B93DD05F6B95A508E56A7005 +:1033A0007992BBF3E2B11B943FBFF2D50FEEBFD1D0 +:1033B000F7751D679A02CA87F58B56243247001DA0 +:1033C0004886D07EF91FC874E59EAC273FD6335A95 +:1033D000D793C8CF1726FFD7C4BDF0DD79E9CA3D22 +:1033E000A8A743FE0F301FEAD1BC9ECFBC44E729FB +:1033F00052F340BF47FD3B2C34DD1E94DB17AD95E7 +:10340000FDE8075A1DA997D0CE4F327E467EEA0EC0 +:103410001DB7AB83EDF7E707ECED76B2BFF7CBED69 +:10342000EC9653AD997FCF8C3E265AE4F84088F94C +:10343000D046B50928AF12ABC54F02F9A23B524F97 +:103440007E048B49F63B986A547E01C56FD01D7986 +:10345000BF80746FE95A417E7AF417607B07E57587 +:1034600009F6172419FFB4E8E3D81BB5CF06F223F9 +:103470008410FD04E1A1F82782FBF1A33E81FBCC7F +:10348000CA70D22782C77D39B3E450663CF248FF48 +:10349000C93B507E9FD2D17E381CBD8449E1CC1FF0 +:1034A000D07E6F26B7EF23726254F991F644E60F8F +:1034B000F45FB364F32711320C5BCC487DDFC65157 +:1034C000D8DFDBBCBF133ABB8DF441D8F6D0FE7B0E +:1034D0004FE6E7EE5C4669AB6C97B7011F63FA9C59 +:1034E000D74CFAD936E03F84B77B254AFDDE1C4A2B +:1034F000777AED54BECB5B4CF01EAF83E0BDDE723D +:103500004AF7799D94FF92B782E09F7A5D94B67BEB +:103510006B28FF15AF87E003DE06825F457D5044D0 +:103520003F7533A56F785BA8BCD3DB46F09B5E3F4D +:10353000A55DDEBD947FC8DB4EF0116F07C1C7BC2F +:103540005D04F7787B287DDBDB4BF9EF784F13DCEC +:103550002B8F93B1E65E2FFA2B5CA284FADDB3AE1B +:103560006A33EAD7B6651A338AF336976605FA39AD +:10357000B655F2789F6D9586FC40A087FA519FB3AF +:103580002D7BFAF8342A5F40E55BB149304AACAB99 +:10359000B8FECA56EAA99E150F02C177DB6A2BFD59 +:1035A0005A805BB2C3A9DCBA4A24BBED798D273AB5 +:1035B0009BEB5D24BFAD3AAE3F28741021FBE9229E +:1035C000B2444A976573FCA33242EF2319594AFC6F +:1035D000A4B907C767AB82F121BE55F5468C5F5A87 +:1035E000EF83F149A43FAE3A047824C378117FC039 +:1035F00087FCC26C19D797AD55EB08AFE465F3941F +:10360000786734DAE96D9EFAB9846FA5487ECD36C5 +:10361000D7A1E8FB504ECAE77CACF1E14E7FFE50EB +:103620007C3282F0DFC6B8DD900CFAD2FE10E300E7 +:103630008B47A9C7FD788F1943FAF126CB7A62B27E +:10364000C0F98F3D2C12FF6D67A0F7C177CF817E47 +:10365000E7433950BA6F15FAAB1ECD724DCC023C20 +:103660007E248D3F24021C53CEDB4FAF17F7A01EE4 +:103670000DEB7DAE09F2373EB8D989B671EC6669BB +:103680002DB25BDBB25713D0FF952CA8D74749CB9F +:10369000653CB63B787BCFD58BE44FB6AE3A90769F +:1036A00084F75B86FD268EFA7D18BA613216481AB9 +:1036B0001419C955E245EC2FECA1CDE5D85FFC66A5 +:1036C00087D25F21F6F775E769E4E365565708BCD2 +:1036D0008693273793238BB322E3488E24B1249417 +:1036E00023CFEBB8DCF29DE4FA241D869934B41F95 +:1036F000257EAEC4D383E3E835323D241942C76149 +:10370000570DE8FD3EAAB7DDB1C949E74B303E0B86 +:1037100045AB756C05AEF3EA9270F3DA10F4A0A431 +:103720005B508E01DFDF8B4623B5B3B99CB7A3E1B5 +:10373000EDDCCA56115C6232FB42C86B257D5A6EC5 +:10374000E7812C4EB7490FBEB4F118AEEFDB3A3A21 +:1037500013F49CC6BF11ED04DF092DC9D7446DFBDE +:103760008E3D017835CBE3794EEFCFB523FF407B1B +:10377000F92857915FF2C97FC16605CCBBF2DD5ACB +:10378000D98FFDA36B1BA229BE5CB52E0CF5A33609 +:1037900066247AB0EA3CD18501F46045BA0C411F39 +:1037A000FBB2F44A3CD5543211E3327C5F9E8A72FC +:1037B00009F03E581D45FBE1D465EFDE3916E05BAC +:1037C000AE8876D4CB9EABE5E71327FD5143E726C1 +:1037D000DE7C9CDB7DB7FDB7B21EF47B27C8E9B366 +:1037E00068E7417A4B33B377C1BADC526D22FFCD23 +:1037F000AD57C5B381761AB9A4C7A37DC1FD3553B2 +:10380000FAA13C80FE267DA6AE0F33AA453D23A13A +:103810004F9D6FAB3A70661AF4D356CB3F6EBBF632 +:10382000FE71847DF51AF29300F529F49340FE4D64 +:10383000D19780E716371A19C973EB32A319E541FE +:10384000B7259CE45FDB6213E9A11B325787A19E79 +:103850006CA8AA8FC674A4DEB7037DA7DDBBFF7D6D +:103860009E2D81E42D3F7F8184590CFAC0BD7AAE34 +:10387000E4F8FAB64CCB4479A9A1F2C3BBFF7D8B27 +:103880000F7D07AC85F090342C910F7E00BE9BE23B +:10389000D402DF2F40674E44F874AEAB07E54342D5 +:1038A0009CAF1B8BB69ACE56D2F9E2CA38E2335D92 +:1038B000B587E931BFB2C818C8E70A9FFCB5FCFF5D +:1038C000B41CE7BB991CB859BB37E3F79FA573BE7F +:1038D00019CE9E360C234F15FB18CF9A638A6C4B7A +:1038E000FBEA597D48FDEAF66CCE67C57A7E3E64F8 +:1038F0004EC5F4728AC3F8FA443CC79693CDF9A931 +:10390000CD124971E2B674D6857103DF720DF7F7F7 +:10391000C4F1FFDA2AD3C93FD42A78A27D19783EB0 +:10392000C29586EBD706731409FDB7A672B9CEFC13 +:103930001E33C6ABA19D9A40FCC1DEF3A9E9989164 +:103940003E4CFE0B2DF19EA40FF0B7A35F1CFD179C +:10395000C1DFDDDAAF866FBFAA864B984E054F35C3 +:10396000AAE16966356CC9E67AFA1D3675FE0C491E +:103970000D27A71C09D3F073EDA6017FB344F0BB5C +:1039800099017EA00D9A7601E725A5AF96FCB2AD10 +:10399000A9DCDF935CAFF67324B296B53102F96D02 +:1039A00054F9B6FC5502FA736CD5EA7C9807158C6D +:1039B000CB8AF4BF24D7959F8D71E9027EEE3A4BF6 +:1039C000EBE9CDC575688B233E4A93CF050DDD1F0E +:1039D000B7D0B89576900F7C01E345FA0F842FE6B7 +:1039E000BA2667C7733EF005EE97F97D3AE403A562 +:1039F000BFE1F841E1C762396EA29CABB922B7A51D +:103A00009CABA997CFC775049DC7B9925C46E78167 +:103A1000AEF4AE090FC577C867BE6CCE77986E94CA +:103A2000CFD720DFF9F49CEF30DFF0D52A6728FDEF +:103A3000F0BCBCAF3CB437CCFC71C0F856B647AB59 +:103A40006077478239F0BCD343F80F74BA37333A02 +:103A5000475A2B0FE78B33BFDBD308E95B5A970B31 +:103A6000D76765D6593D8F33F5EB51FE9E97F7DF4B +:103A70000D82DD385AC094DBA58D66BB11FDBDCC2F +:103A80009FA1F257287E87D52BD2AC3180FF8801C9 +:103A90003F82D34CE74DE333C98F1135D571372BB6 +:103AA000043CF7CC986F04A2DC854E5590C78F6517 +:103AB00097FDD0973C385E03FAAB02CE2319440F32 +:103AC00023B97335954901E7CA5B65FFC5001F9BA4 +:103AD0009697607F3FCC96783C8679D672FF9FDAC6 +:103AE0005F66B86A53B533D87EB2AADF56D92F7253 +:103AF000F3F6D5FE37C3D5F461DACF0E6ADF1CB218 +:103B0000FDC176D57EBCAF111F6F433E18CEFFB509 +:103B10005F96A71B6C9E5EF47FE918D89514070684 +:103B2000FA98886A23FF69C3F979535DB2DA0FA660 +:103B3000637E921FCF47D690FC48603E8ADF59983B +:103B400087F2D7474DE7F1BB60B9711379C1988708 +:103B5000A1DE00FDA9F2573FC2F7D346C1EE423CB9 +:103B600083C7F3FF8ADDAB891CDF4BFA734AB86465 +:103B7000B881DEDBEA7525E3F71BC23D3518EBFEA5 +:103B80003CBB2E763DE83D1B30C6087C7635BB71CC +:103B9000BECF84FB24A78FF5711AA227CBDD961D1B +:103BA000DA007AB2E85D69A8F75A34F2392FFCA13D +:103BB000BF6CBD65E7A610FD2BFA9B025B2B008F47 +:103BC00000BA6D95F5E681FE9624EED006B4633119 +:103BD000B80AA93FE55CA3D25FD337EB6FABECF734 +:103BE00052FAB3DEA31E9F55EFA1F159E5FD47E957 +:103BF0006F2B8E2F045FDDB43FD98E1EE86FA97A3C +:103C00007C568387C667D572FFE1407F4DDFACBF2E +:103C100036F91E934DE6D3E1CEFD370E9CAB761AF6 +:103C200051AEB429FE40797FBB14B4BFAD96F737CF +:103C3000E5FB4B71E9E4DFBDD433DF186A5FC3FDF8 +:103C40008CC97A2493F54826EB9108CF997AA63E41 +:103C50001EE8B0F0C5B6F922ECE3731E3A333E1508 +:103C6000E0192FF6CF17615F9AF3E2990349F0C983 +:103C7000CB2FBECCCB7F78E64A32949B7CEFCD2F06 +:103C800003382A96EFC70ADE4ABFB78DE27AA3BB94 +:103C9000E173EEBF04F98AFB5663AA87A17FF14264 +:103CA000727FD432A8EF4EE9B72C0F312F4AEA6E5B +:103CB000384F7E46147928FFE6E1BF40B4CF53EE7B +:103CC0006794ABEF6744456D22FD2F8CF9CD28EF4B +:103CD000228C0EBA4FF8D628BE1F2C64F60A6E3717 +:103CE0004859F2390DBACF31BF586ED77CCBCFB11E +:103CF0007CA1C6B11EEDD9DF4EAA8A47F558391707 +:103D00009737787F72D7F51B9C1F0EBE3F39E7238C +:103D100081EBC223B8BFA53B57E2F7B902FC86A8E6 +:103D2000F70E379FB5A3B87D3F389F0E3E9F310EEB +:103D30003E9FE6FEA8B5B0FEEEE87ECB13C49F5DC5 +:103D400021E76BC8BC06CD5FFD28A6D8795AA4B779 +:103D50009BCDB732AFCAF9C14641CAA2FDEA4F793D +:103D60002AFD8331BB142A8E83F419B8BFEA6D4E45 +:103D700086FE195D9C3D07CF9537FE451BF25CDE44 +:103D80006E793ED64685D3B9CEC6283DD9DBDD5106 +:103D90003319FA9745D3749A97B2A8723A6FA98DDE +:103DA00065ED688F069F23D78EB89BCE0169AD68FD +:103DB00041403A702ED961A4F889B9E886E7C8C5B0 +:103DC0009B9D238F99C9CF9147E9257459B445EA42 +:103DD000439E237F6C14DFF7BB713C71883F8C27B7 +:103DE0006D701CA299C7D1313F02F2F56617237F8F +:103DF000BA3CDEC7E47550EA1BCC1E86F240ABB776 +:103E00004BA8A768C3F93E61B069584E08BFC8F710 +:103E100047E9E8FB4F72CD34AF1A23D7CBE7FC5A02 +:103E200008E94F7A7594E24F0A4D67C3D1C93C0D3A +:103E30003F47A7F0E102939ECEF72D30D94AD10F2C +:103E4000B20008EFB39880FAB72DE2F78145BB0DB9 +:103E5000E9E737536EFFF96F18BAF9B97C3E35437D +:103E600047F7E34E09CC618F197A7ED5E98C9E869F +:103E70006E9ABB669D5987ECF7E2F2EF15617B867F +:103E8000E353751689EC9F7746A15CA84E5B1F0F24 +:103E9000F0A2CA421DDDDF94E344EE082EC79FD195 +:103EA000BA4E8EA278D1E751A54847627F2AE2A395 +:103EB000C48902EABD372A9EEACDE1D7C5A0DE1843 +:103EC00094D3677FEF62B41EB6507A12DA4F2C306B +:103ED0006E23CB07B4A302F3D17E6201EB272C2F14 +:103EE000B6F68590174A9A60DB92520D7C9E90D070 +:103EF00042A992FFAC435BEE0FB1AE57E575FDC62C +:103F0000764C1B603B71D08E01FBE52ACEDB17D5CA +:103F1000A72CE36148756517C98EB1E9153E9388F2 +:103F2000BF06611EAF04FB4575DEB0D5EB4BA1FBB0 +:103F3000FEF2386D2BD646A31D03551C489FDBBCF3 +:103F40006D29659983E3C8CE91E9138DB689A817C9 +:103F5000F35F725CCB0CF497249B34743E012653C0 +:103F6000752F616E59F4B4383445DDCC6E92D02E85 +:103F7000EF253D3FE1BA96F820E1F0628671ABA4EF +:103F8000B87601EF030DF423DF6FAE97E3B9575C0A +:103F900065348E04EBC0FECEC80E8DF3CD4579742A +:103FA000E5698E51C28FD5E5C971FCDCC2FDD5E152 +:103FB0007E09E83AA9B6574038010C38F4C5275CA9 +:103FC0006F4C6B4279F25A04F98BB56D99CC07F2BC +:103FD00027557445E5E03CFBA5FFA6C990070BDF1C +:103FE000AD7C209CF4B336A16506D925F769582825 +:103FF0003FCF981CEEC728C8E1FC9F606B4DA91EFF +:1040000087E9D344375F97CF6790B31DF4D9119FE9 +:104010002DFA581CD47B9A75A1E9739BDCEFC07E06 +:1040200021CF5F187319917FB582933B39F7EEDB8F +:10403000B7CF82CE1346E75536C97A8DD24E444E5D +:104040003B1546D81D0CCF450A6607DF07CC3E9BC3 +:104050000FD6ABF92B6D487BEBC11C791F496BB2B6 +:1040600061FDB24CBB0DFD94C1F7551AD326DA7031 +:104070007D1A670CD0A931705FE84ECB7E1FCF53FD +:10408000997A742CF01C5970AAC77321B1372897FC +:10409000CF97371DE2E7429B4C45BD780EA1C9146E +:1040A0005744C7FE4CFC9CA952DF643A46F2DE64DA +:1040B000E7F15613EE0F02A2C7E7A13BED18CD833F +:1040C000526F5A0E97AB267B17C3FB5BE1763FD549 +:1040D0000B139D3E0DE01F16C7E8FE4F9891F35558 +:1040E00004AC8F3180EF957E6FCBD1D1BC352517D5 +:1040F000F596107E22DE04674DB6221BEDDB38DF1D +:10410000D06F63B442DF9CAF1F97E75B69A7513E56 +:10411000FF7A4F43CEFCB258F41339D7E460BBA604 +:10412000E546B483B491E36FD8DE8661DB6B5E282D +:10413000B7F738F28536B2C88CEDE9505E84A0C37B +:1041400067E476FE57E3ED30B374DF97605A309F33 +:104150002D94DEA3A4468CA38F1BFADD3796BFEB0C +:10416000D47E2490BF7B71FC2B93CF1E2BA11CEE21 +:104170003FDA2EDB278A9D6191DBDE2EF07BE83E65 +:1041800021DC4EEF36C87687254C3D0F83F741F989 +:104190003A5CAEE0E7E62EC7318A6B04F3F3E577CD +:1041A0003E8A0EB44F50EF736473BB0453B44B1C80 +:1041B000B29F0D61F41BA09DA2F0FD805FB742FA93 +:1041C000A75B003F03C86F0DB42B247B88BE0DC9CD +:1041D0007D69C8E7A9F23B0543F6D75C2EA7854762 +:1041E0003F4B43FE2E8BEB4FC0EF82F9FC8547AE71 +:1041F00026E0785E983170CE86E243AB17A7F37B5A +:10420000D9C7FF1CED0AD1FECDEE7F459DDDB486FA +:10421000F4C0E55C0FFC5BDF07DBBE8CEB9D1D8211 +:10422000DAEFA4CDE57AE75FE47DCC7A55A4F72DEB +:10423000CE65B92E201FB60AE6E5287F531FE1E7B9 +:10424000E6563F5EFFD90321F84118EDFA734E8020 +:104250003D5CDCAC273F5AA3297DC48DE21CC3AF73 +:10426000B387CB71797D4B1E35F2F3242EAE175BED +:104270005CF7D33995E0F323C3D53B24CB3DA5BEF2 +:1042800001DB4779629A47FE804B6823A0BF4D96B9 +:104290007BC17876E264C8F36304B9127568451887 +:1042A000B6AB93EDB1ED8A3FA3A2C8E808F85EB7BC +:1042B000B8C8581A402F8D8C9FDF0D6EFFCEDC01E1 +:1042C0007D5AA5AFE8709F45DF509CF8A7013943A0 +:1042D0008A65B8CA8E51FA0F3E3F16705E2C8CF379 +:1042E00029B7675AF1DC18E8B76B2B968FC4F96DC4 +:1042F000155D2F58611EFA3F30D039E70F65BEECCF +:1043000093F972B8F5F3B143A08C31F6043B829770 +:10431000D6804EC68F40FE68CCD494FB438CB35CF1 +:104320001E6708FDFAD6DCAFA75F97E686D0AF51CF +:104330007F7604C51F0261D49B1D21F4EB1382EC30 +:104340000F90CFED9CD0491D7D300F276E1D616F02 +:1043500094E89E91C35E04F6C38B6732516F9F232E +:104360000CBCC723DB318C60B02316225E739967C7 +:10437000DF0302C5515AEE48A3EE045C8F9BADA744 +:1043800024FB1137C23A61DCA1F5DAB219A1E20CC3 +:10439000FF38402728BA02EF07C02A04C49586C414 +:1043A000CB82E263184E1938FFAB1D5AFFAE62751F +:1043B000FC6AE335EEBF30AC60FE27043C1FAA2E3A +:1043C0009F5FAE0B8ECFA9E25A0B9DBA607C7C88B2 +:1043D0006FB28C6FCAB607290E3E2D45E4FDAC6462 +:1043E00064CF07C7BD0C85BD0E2DEAC3158CF4F74D +:1043F000603F369E1725FF5E0563CF0974DE5A7D48 +:10440000DFE4E959E7F8FB1C2DE5D88F2D53C350A5 +:104410003F0EBEAFA0C49BF0984CE07D69E5DD2265 +:10442000CB620DE1C77CB753B9E29787FAA6124B6E +:10443000C0B9EE556CA03EDDA3F2851EF7D6D65965 +:1044400014EF4F1CEF29EC82A2243BA37948AA6603 +:104450006407C03CA8E2FA86945D34CE4B358CC527 +:10446000F238A0AA3C017670A44F18BF2ACE0FE301 +:1044700054C1C176E7CDEC4D434AE60DE5F9CDFCDC +:104480008D06395EF8466E641CE93B63D818D47714 +:104490002C8B9FA6F5B804EB817E59348442C5036A +:1044A0003743FB6807BA905FE2D1DFC454EFCA30EC +:1044B0008748F7C984628EB310EBE4F1E17C46FCD7 +:1044C0006D0807950BF859986C70E0BC1B0C00C385 +:1044D00090053D332640BE56F637AF1598883033E9 +:1044E000DB8DDC4FA8BC6BE3A7776D86EB0774FF11 +:1044F000BE30ECCFC7BF53FA19F28EDB0DBE27FBDF +:10450000CD1CFC7D19F91D95FE879BFFE1DE6DFB3F +:10451000C3D4772770BF6732D16BE520BD12BC4C86 +:10452000A647FC1EE5C2BD4AB1AD770CDE373CFBA9 +:1045300070841DFDE003E3F0DDA9E5EFD1FD75ED2D +:104540000DE0619348BE0F8C4B6EEFAF1D17FD025F +:10455000E4DA06BC3484E74F2A199D27B0B84ACF65 +:1045600089740E00C6A0921301EF13407B1B0EF15D +:1045700073AF5BF19D0B71B05FD42BD06EB0554221 +:104580007E083B4849AB19BF1FACE0D5A8073D1AD0 +:10459000E952C3F5E8D9A63E11CF35E9E2FA45E480 +:1045A0001FE7682EC707E8379ED1F90B6D927CCEC6 +:1045B00071A4C4DF4DCBE4FB9BD2CF84D11A59FE4A +:1045C000F7D2FB47B3234ED54B76C6F2F6C52F4440 +:1045D000FFFCEC11A7EAD3002ED867E170D2A92B1B +:1045E0006966C6ECFBAC0BD19F3F3BEFD495748062 +:1045F0008BF6D978F9144646CEF87D090BD19F3158 +:1046000061B459D5FE5B38D7F1DF3CD51A3421CFE0 +:1046100063DF365A394FC9E83EADB3F397A7312E61 +:10462000E954F647872E48DF81220BDE23937F7102 +:1046300051140F9D29D3D99DF8EE5214FA2DBB6861 +:104640007E470DFAE99FFE6BFCF482437997CACC52 +:104650002A81FF1B1B982B2C2380EE9943739D9F6F +:1046600003A6B881828FD2FF10BC6069C59840BC98 +:10467000B6513B0A5E170A0DA48705C7872E08FDB1 +:10468000DBF19C54C4CFD62FC275BA10D99F2A0033 +:104690001C9EB79ED6ED427CFF76C11E00EBF83A19 +:1046A00056EF2BA275FCA3D6513D7A02BEDBC5DFC7 +:1046B0006F6896E3504FC6BB7C689F01DDD1B9326D +:1046C0005F8A9EFC4865E30547A03FB06E34F7CB98 +:1046D0005C92D3698616CF49A04BF70181AD85FA6C +:1046E000EE6B97F5A89FCCEE3CA3473DBAEEC01900 +:1046F0003DDE4BAD4318DAA9DBA67784D2FFFE324C +:104700005AABF2972976D7D194ECF5E877ABAB1694 +:10471000E81EDEEAD7B91F6EF5321C256377DFB2DB +:104720009FFCB855CEEEF5982E657D47F1DD88C526 +:104730002EADEADCC0929A08553CBECA13AB8297F4 +:10474000B6C0EAC03EBBB42149F51DC35DCF82EFC0 +:10475000280EFED0FEAF90D771B16D732FFABB1645 +:10476000BBD47ACCECCEB5620CE2ED11EC1ACEFEE5 +:10477000127EB7848F10D200BD0AE67D5A07D7A3F8 +:10478000EA2A8C649F54220CF35A59ABF5E39373D5 +:104790004753F454EEEE10A8DC2D97BB6B046E5714 +:1047A000CBF275A98CE3928327A7D175529FA337CB +:1047B0003300DFA515E5E7881E657D43195785C4DD +:1047C000F58D0D29EFE9B0DDA5DF17586C1A8D4B7B +:1047D000A5472DA951C3551E5D909ED5A743F9BD90 +:1047E000B4419DFFF3D1F2BE9EC7F2909FDE182D1B +:1047F000889F1807E13FA5BC7702EF815DD23A0F91 +:10480000227DD6EABB0A70DFBBA47511AC94437E4F +:104810001DDFAFB8BEA201CEC3EF1B750E33DEA7FE +:10482000F5AD14886E97B000BD276DB03EC1DAA11A +:1048300070BF2277C39CF5E40F3D2898516F281371 +:104840001D22DE836F1CC68F7E51E68313AC2F1FA3 +:10485000F1CA46228575CA9E3F82F699ECB796F951 +:10486000308E943D4E20BFC49D80714311A622C955 +:104870009139B03784419AAD6DAF20F93E566FE65D +:10488000EF62DA58A0BC70FC331370BE1075B20B27 +:10489000937BE8FDBD396D9B2FA25CCCCC70143DA1 +:1048A00005F83D19C6FB7FF275C1BF16DAA9CB3FEB +:1048B00046F2D30AE481FDD6D96439DAA1F6CF5A9B +:1048C00051AE21C1CCCAA77E1394F832D015EDC3E6 +:1048D0005DA5A49F58E57E9F2D94B8DDFCA07C2E9D +:1048E0008DF9D6E2F9FABED18CF295F41BFBABCA76 +:1048F0000431285E50371AE679A5AD4F75DEE95BC5 +:104900006CBF01E92CB87D18BE2A5E394D7B2D8A1B +:10491000EE771DCCB0DEE8FE94D6A83EB7A4338770 +:1049200007DDBB53CB9FD9F6A4A07B771941F7EEE7 +:10493000F282EEDDA9EFF92D744E09BA77A7BEE732 +:1049400067B0CD54D50F93E6A9E0889CBB55F523FD +:10495000EDCBD5E7AE8EFFBC4248C777067D7D2EF6 +:10496000988766E08DE298C17D242F0A2A431A3E7B +:104970002ECC846973A1A10BE9A43991DBE786E30E +:104980000FDBBAA01DE388978CE86FFC89E02F4508 +:10499000FBC4289F5319FD1853ED33AF1570BE5259 +:1049A000D2DBF25CB3F3617DF2F74A49FC1DE0DE35 +:1049B000D1B83E467C6C03F9E6557EAF78AC6C47C7 +:1049C00028ED3C5F5832350FBECF7FCC3183E2EC0F +:1049D0001DFC7EF04E3D8FA7F85EE5E75BF33BFAEA +:1049E000348E00FE3E99C7F590679CA5141FA9EB75 +:1049F000845D16F9A9EDAC1EEF65D4757647E17EAE +:104A000056E03CAB47BFC960BEBCCF89FDE168AF93 +:104A1000FFAC3D743C6D6D9E9EF8E3982CD7AB1EA9 +:104A2000D672BB913966E1B971455E57EDE7E3ABEC +:104A30005AA8E7E760311A1D426E839C3EAB96C3CD +:104A40000EF57E708B7F3DCA0E90DFAA7A4B174C15 +:104A500027BBB712E436F231C87375797213C917E0 +:104A600090E7AA7C77DE803CCFBF0EDF9D766A425E +:104A70008EF3708148F378DA3595E6FF199847F49C +:104A8000A73D3364DEF87CDE6CBE5EC6B50F58B75A +:104A9000E07ABF2EE0EBF6F230F2FA7D795D770A2C +:104AA000BD45284CDDCE70A2DB254663099E7B38D0 +:104AB00096F26513C6E1AA7E2ED03DFD7FEB3E6ED9 +:104AC00041FD5FBFFFA805FD61EEF6A316B04D598D +:104AD000AD4E5A8B7A3CD0851DF59EBA8E2EC27F84 +:104AE00065FBB86ECC5FD921D0FB3DEE0317A7D391 +:104AF00038595F13C60B770E83D78FF2B8FEBE37D7 +:104B00004FE27E3017F489FBFD0183DF2F201D80EB +:104B10005C42BC5E17F0E535B673A3B122941EF576 +:104B20006FF27C1FD9A867E8AFAF85EF711CC75241 +:104B30008EE98D4847FB05B2B5DDED27174660FBD2 +:104B4000F53A86FA8582DF1729BD1FE2F83FA8D61D +:104B5000A1A78035566B69BE3FA8D7523BDAFB74DC +:104B6000042F5EC1CF551CAEFEA82909DAFDA05660 +:104B7000A07B0C53EFFBF3318417AFE0FA5A303DC2 +:104B80002BF41A4C9FC1F43B844E6BBE199D1EC979 +:104B900093EFD5E4B102DCE761DDA759917E1EE118 +:104BA000F7E32BAE1DD6A17F33BDC96C7F02E03188 +:104BB0005AFF7A0BCA89C3BCBCB07687C0E58D7436 +:104BC00037F26152B39EA1BDFB7E1E974BEFE37A95 +:104BD000C5E3D0FA058CAF31B1371DE5529A1C4FB1 +:104BE0007A45C72AF6535C90CB9B31AFD954EF96E8 +:104BF00037E571BD43918340E6AEFDE4976D4FC448 +:104C00007B142FCBE74153E5F6B232FAA7CF85F4F8 +:104C1000AA4C2F67643C14F8B24CFF6CDBCF681FC2 +:104C20009F2DC759663674D179CC3C83EB5394875A +:104C3000B352DFABC57DAE39FDED7C3A678D3725CC +:104C400026E2FBC9FC7778D2A7DBD660DC2F379C45 +:104C5000D631ECE053741E382C6BBC35549C434960 +:104C6000DD57257A8FB0EE6A3AA50A3CF7D0397D38 +:104C70001FD90117A7139F5CB5A9DE2DFC54C67B75 +:104C80008CF23E5D27F7F3809C168B8B06EB29F3A5 +:104C9000809E651C6F58D62E5AAF35AB5821A9752A +:104CA000EC29FECE66ED4901DFBD58A473E84C3017 +:104CB000DFEF8D60251F8BFC1D245736C64D8C748D +:104CC0002FFB84D74C70AFD746F029AF44E9AD61D4 +:104CD000CE887C6867E1114F16CEDBE1945627DE63 +:104CE00057BCF08E4EA66B33BF2F2ED3DAE54E2D78 +:104CF00033629CEB00E8E3C220FEF75C4DA4FBDDD1 +:104D0000BFC3FEA09F950DBF217967AFB9381DEDD8 +:104D1000A2C2DA334D08BB1BFE3C1DF5890F61FFB3 +:104D200020BD1EF47B9B8072E424BDD35D79358663 +:104D3000DA7959D33F1DF9CBF7A640F76F3EECB8AF +:104D4000A8B7F2FD89DC73782F1CFDF2B3F2A3B98A +:104D50001CE92CD4D0FA3A24D53BEBDDA3FF2B0A77 +:104D6000D7C3D820FD7A0A7EDFA365C8BF9B4AFB64 +:104D7000A3CC21E4EF69F4DF65F371B0ECA1E51594 +:104D80007A5F169E93AC90E938B8BC3C7FC03FA1D7 +:104D900073CAEFEB0801FEA12AC6DF3F05BBA72BB4 +:104DA0001CF8B8AA732AF967AA3CC20DFD33C3D117 +:104DB000E1D74DEB18F7CF2830DA8D817E4DB41B4B +:104DC00099AA7F1F7F072B25F386F774DC7D891452 +:104DD000CFAF6B6614EF5A797534A5E75FDF2021FA +:104DE000FF18C3FB5BE97E6BB686EC8C953EB5FE87 +:104DF00033A580CB8529057CDE5CF9602FE5B00109 +:104E00007B09ECA27BF3B95D147588A9ECA5E07C65 +:104E1000B2978CF23D1D1013AE5742E07D474169B9 +:104E20000D7E97CA5A88CED93BFCFE72F038D7E483 +:104E3000733E55F87A31F235D26F07E7EBE076E74B +:104E40001594AC413EDA384C7CAB5CE6FB956D8C3E +:104E5000E6CBDD1643F3F4056B7396025D7E0178B5 +:104E6000E03DD20B4E6744347C7FC1E58CC0F33DFE +:104E70008A1CA86B0BA7EF3666CE8BC573A3CD48F3 +:104E8000F7D0DEF98EA9469CE77BDA38FF29FD7D55 +:104E9000D8B53816F96982AE5F6F87F2E4CE335128 +:104EA000A8F74D787D7E2CF2E17078FEFD1819CFC1 +:104EB00086C4121E9787BD70A26C4F007EEE27BA83 +:104EC000E89DFA871A18D16FF7ABFF56877C7CBE36 +:104ED00033C28CFBE6170723E8BDCA0B6F1AE83D07 +:104EE0009A5AF97DD52F747D7348BF7C5D4BF722AC +:104EF000DD6FFE472BF2A3FB55039D3B7CA873C3DC +:104F000045DCF76A3B679CC377566B5FFADBF2C3FD +:104F1000CA8654D28B14F83FBC4627BEF37B5EE4AE +:104F200072E2A18E7F217DF7A16B970BF07CCA17EF +:104F300007FFC744946BEEB72E4F4479E6FEC5E5F4 +:104F40008958EE7E2DC2134A5FB95EC0FD3ECA7E0F +:104F500099F6AEA8F20FAD90E9236D5D0BBD073D4C +:104F6000E1E4027BE0BB0F13B2344EAC3FE1B76526 +:104F7000B1F7057CB7AE57A438E3F8936511D501B6 +:104F800074794F814EF12F7E23BF0E93DFC719F046 +:104F9000E3F4F2777F36F68AFC7DA31A81EEA183D3 +:104FA000FE32E45E1AADFF8A587ADF8889CE3BC7AD +:104FB0008C47388BDE05623EE3D1CC003D6971AF92 +:104FC000A6CB007454D169E822FDBE573C43B0AC77 +:104FD0003FDD73F1D3C83421847F26E7D43494E3D2 +:104FE000C17E1AF84522DE8ABE55E971A520FEC1B0 +:104FF000FE9BA51577907F28D87F93D62B6A668F66 +:10500000C7F7DFE93A2F8CF76923F28BA287E2FA20 +:105010001D08C1FF6BC67039A6F0D5BA5E1EFF5DD4 +:10502000D75B6ACC84B456E6AB03B09DFAA0FD759D +:105030009DF377A31F61DDB545116360BED6BD3B0F +:105040008F3D81FC6F2E3566E177D7EE302ECC1F79 +:10505000A497E0FEA68CE1F272404F1866DFCB9772 +:10506000F1FA5BED7F3963E4F36CFF87EF7F6087D4 +:105070008F1DC3EDF025DC4FC2EDF0E07D4391C7FD +:105080004ABB2E799D87CA63FE7748C05E2679ECBD +:105090001A2351BDE4CEB9B16447BFBB2056320DCF +:1050A0006D3F43B46B62F287B6AFE8716E9FE3A8C1 +:1050B00011ED1C8796FB491708F4BE99A2F7B99D1C +:1050C00002E9E3EE4A9D1FEB2978F52EE07ED585B7 +:1050D0000E9D3F4C18D40F15FD71A0DC2E50B9A2C7 +:1050E0004F2A7A63AF93FB71178CE7E5B786B91641 +:1050F000E17C7DD81546F91326F17CC69C479300C8 +:105100005EF43D8111FFCBFAA442A7C1FAE6A5CE19 +:105110008C1BBED7B34DA64F85CF5283F843D9BF62 +:105120009AF339DDD7E1FE1D8BFBF77FAAF4F2E09D +:105130007661FF7E08F16F461D12BE1FFF5BD1191D +:10514000CA3EFF4AD60BFE5E59BFDE232588AF72EA +:105150004E76B87DB54ED66F862B6FCEFF7AFCBCEF +:10516000471EDFDF8A9F778EF9BF439F1DD00BF567 +:10517000A1C7794741C94FC6C0BC866B3D749E73B9 +:10518000B8F7CD1E95F555B07355747C3445AF41D5 +:10519000BBC85DC3FD03CDD1D2AFC97E39AEA5F783 +:1051A000571E92EF733E78D54C692DEAC9902ED9DF +:1051B0007B92DED95D52A3C6BF197DB7F8FDAA3434 +:1051C0008AEB57B132F22B5575469BF1BC7F737C4D +:1051D000FB31E42BDF6EADB43BB0FEC6D1727D2354 +:1051E000F7B7D544D3DF8F61417A40952758DF5711 +:1051F000EB0553643FD170FAC12FBAC3B85CE9D153 +:10520000129FD739F9DF55D07772B9E06E0823BF06 +:1052100009DA6B88D7670D821FDF3D5F29D7FB4C0A +:10522000EC25FF13C5D3A0CAB9CEA72C0EB2DFD48C +:10523000F1A395BB7E4B7233388E1473408E0B0DE9 +:10524000C48D26D2799095604FE29FBC724BD25D9F +:1052500038FF801FF393DC71A8FC30977A3E22FB65 +:1052600073C9EB3CFE33247ED43C93C78FF0DD95AD +:10527000107EC8A5238F1DC5BFA374B3B8515DC7E9 +:1052800049BA473244FF08D23BAE8D51FB19478AD9 +:10529000DC8F3BB25330A37F6AA43C8F7FB7319C35 +:1052A000F4EAE97FA88E4579A0ACD3F9B97C5ECF4A +:1052B0007F70A504BF9BF807D11C06E3FAC507F56C +:1052C000BF49E2B06494F0BBFA08B463CEFF6175E5 +:1052D00004CEEB2F20C5BF2FF1DA6931A43FD22BCA +:1052E000CB2DD80FA30BC8BF2CFBA545D80F230788 +:1052F000FD39C1DF6D97BF6B063385FC98AFF3F8BE +:105300007E73826B26C1CFA633FE1EA683FCCEFF22 +:1053100002748DFEA23C182CC69F7F1ACED661BCAB +:10532000A839DEF536F1D1B31A09F908BEA73893CA +:105330006FBF44FB234E19C6730AF4FC5D46EA0CAA +:10534000D66BB4BC8E0960C7623C09B05980F1E6E7 +:105350003C39AE5310CE446CFF499D6B13BE97F998 +:1053600064B7685F4B4C608FC577BF83E34B828324 +:10537000C7C5953893121F1F2ECE24603F059CEEA3 +:10538000F8B91587807173259EC4BEE7A4205763C2 +:10539000B187CEF73F53C848AE7F8B719E25F92168 +:1053A000E24835C86324CFD571C54D39AF109DFE95 +:1053B000B5F1C43D63D8B71CFFE2F3138CF7F8E8EE +:1053C0004B16B2B7BEFAEF51B4CF765EA6FDF042EF +:1053D000BF41BE8FD0C7FDEC9D3AF22F5C00BB2DC4 +:1053E0003E609F3D9ACFDB3DD43995E8FF406F5931 +:1053F00004D63F2FE76F7C77C1FCD94897BD22BD0B +:10540000078BE7E3D00E3BD02B4E40BDE55B5C97AE +:10541000EF8F09B12EC6F0D0EF4CE4CB7C945FC087 +:10542000E963EA07DCFE72D7F3388A59960BEE720D +:105430003DC9C163291641F19F5B43C5595EEFA782 +:105440007DA36A8540F71CBE719CA5A35BDEB78275 +:10545000FCD3E5D3496E0EE7B70E889BABCAB715F0 +:105460000C9C8723FF75548199C61DE3292CC1B379 +:1054700087CAF8BFC575B8736C083AFB16DB5F695D +:10548000FF6EDB9F92F7DDB6BFE63B6E7F6DDE778A +:105490001BE7DEF11DE37FF53B6EFFCC773C3FAFB2 +:1054A000E5FFFF73000370709C3FF85C4070BCDF49 +:1054B00070FC3E1F966D1036F777416A8C7AB542C4 +:1054C00000512D46EFA27708664DE271B08D65461A +:1054D000FF0E61F07C80325F4B0BB91D61CEBFE8DF +:1054E0008B85794E75F496C5A29F6C127F87FD82DD +:1054F000FCCE2A13CDF4CE18D44CC0FBF1CD61A163 +:10550000E3AA61727BC3ED23CF1796DC31369EFE92 +:105510006C43C8FB1D2FC8FE47730723BF2413A588 +:105520008479D4AF9480FAD088233C3FAA8B397613 +:10553000105E52DA3CB207A534C46F8B1CEF8D9914 +:10554000999D86FEE818D00B311EF814C605298EE9 +:1055500065A67A4A7F1F8CE5FD6DD13181EE5BE552 +:10556000F2F34CACF9A02A9EF78EAEEBE36502C5D0 +:10557000F39623FEBFD274E5EF4C938918E637FF0C +:105580008099E28C2726BD487F775689EFAD31F3AD +:105590002A87D16E063CD61C1C47F4BBE4D0A4F786 +:1055A000F1E93377A6680F754F51F1179C96FD1DF1 +:1055B0008ABF40896BFD5EF6937C88FE17BA1F2276 +:1055C00051EA1DABF9B6F727EFD810FCBF45E0FE56 +:1055D00021DFAFB87F689CDE9E11786E72B33CAF5E +:1055E000CBBA78DC42F1F7EC93C733EE116D97013B +:1055F000F6D2714D63F4B8CF8F6B4A09C7B4C0E1DE +:10560000D7E07DF0C5D5FB35CAFA85A2A3D6B1B2E5 +:105610001FA3A79FE27AFF1214E7FF602C3FBF3061 +:10562000AF90E3F101D82408AFC9121B517D1C7162 +:105630008B591B2A9E54057631E2B9AC99E3ADCC67 +:105640007755973415FB3973B4BF09D3A29AB4A91F +:10565000E46FAFBDD884FA9BFBDAE563B793BF4C28 +:105660002FA13D714F9FDAEFB60AA3A5F18427FD64 +:105670009D5ADF0C91ECE3713344A29F98AA30B29B +:105680005F63744C6B42782ED78B8ACAE3A622CC18 +:105690001644933E58D42345DF973FE8078B995132 +:1056A0001F8FF374B3F8AAE24FBB35CCF11AAEE703 +:1056B0005F1B5F5DF9CEBB74AE541997322F4A9CC5 +:1056C00074B8F8AA72CEC15D7E45752EC32DF64F13 +:1056D00047FFE3B88367F4F2394B33FE1D6125FEC3 +:1056E0003AEEF58B147755E2AC6ECF45D2ABE13B89 +:1056F0003D7E3F0E963F2106DF17E2F1D757F19E20 +:10570000941EEFFF99E9BED41BF2FDC54E183FE68B +:10571000BFE9CDA1B4CB6BA7F490B7985277E7451A +:105720008AD77E38561DEF53E27997B4CE3363D5CE +:10573000E723090E8EF769C3B9BFC6DDA3A3BF97E0 +:10574000E17EC748F2BBA47319DDEBFAF2A46B2427 +:10575000E25D87F1B600BA38EFB087E13B61E79DC3 +:10576000F6308CB38DEB3EA7C7F32F7562AF1EFDED +:10577000618071121E4D741FB8C8CFF77696D0DFC6 +:10578000E3BA695CACE36F1317FB9FE541012100AD +:10579000800000001F8B08000000000000FFB5170C +:1057A0005D4C5367F47CB7B7E596DF0B2A3F227256 +:1057B000C16298A2DCC240A7311674AC135C8A4A5D +:1057C0000201B5662E92092DD9CCC2CBD23A8901FD +:1057D000DDC3B2B864F3A92683E8B687FA93AD6E49 +:1057E000550B0B84252EE2C39C71C9520D3333BA7D +:1057F0008162DCD85CD839DFBDB5BDD8BD2CDAA458 +:10580000393D3FDF39DFF9FF0A003007DAE756B9E3 +:1058100006E74CF8A5CFC6FF0F3DA44F8CE3DDBDD6 +:105820004BEB2617C4F1BB3EC9356903F85D9CCE2E +:10583000942B00F687CE5A1C041FCFAC7621FCEDCA +:10584000C2DFB54A3A80F7D24C2D20EEFD66A6960F +:10585000F8DEAFD27A02E94FDB7BD78E975E047019 +:1058600096416B10F9552EC17182E0B8C3FA4645D6 +:105870005C6EC02538E9FC80AD349BE8C75CA5D9D7 +:105880007B13F4F539456700E939AFDAAC89F409DF +:10589000BB19A006E90C5CC124F66B5581DBDF7FE8 +:1058A000D22A4F4A7A1CF1DB1DCC36E0DE50813C17 +:1058B000591EC7F7D38F02FC6E6622D40274E9B971 +:1058C000B86472D7AAA8AF3B3F6A8152A24C5B5C16 +:1058D000AB305EDF4BFDAC1260F8FCBEE268051732 +:1058E000952017A04D3F37E0DC5B9CB110C07F3D99 +:1058F00005CA98461391DF4A3F148E2A22DA69A717 +:105900005F78E5B6FCF7274CAB11BACDFE68C2BD97 +:10591000DA9D82C39AC9ED2E6DCE207931CE2F212A +:10592000A5D34BB7AD22CC5128E413F417C25A02C9 +:10593000D2A8AD366EEF06047EB0A17C9B5388A43E +:10594000A09DD6704A04506F955304DF8B087BCD21 +:105950008112467CF126E72B6F3611BF4FAE2A0429 +:10596000F4E3E7CB16794109BFDF6434218EAAF353 +:10597000D3FE523CAF763195DC6AEF34F2F19341BD +:105980007EEED6E3B23334FC7221F75F36019ECB54 +:105990001D03388E7677F618CFED6E75DE61743F95 +:1059A000F8A07F33CA814D900789DE6B94A33A3B00 +:1059B0008DF11F007026D64337D5410D41C6E1E772 +:1059C000E813D54515062A58113F37BF7E4674F9AE +:1059D000F9FA62F00CF117517D560DD828BF4D022F +:1059E0009401E1F5922D419F5F15B99E0F6501FC71 +:1059F00028D717DE3EC8307E7D8F5F915A506E4AA1 +:105A0000AE97CAD2E3B8F732D6531640F5F06C031E +:105A1000C5FB589881154D79F3F1BE28577DB16EBD +:105A20009CAD4EBCA7E6DF31CCF9443AD5819A0D46 +:105A30009A5F2061BCFC17586010ED55353D1C493C +:105A4000A3F8B9B2D53285ECD80EA523EE6D126B52 +:105A500018E12E3C40F80E1690F0E7F62B9D5B0007 +:105A6000ED54B7D8AF52DC5B3ACCAA1588DEDA40E9 +:105A7000F46B5950372912FFC47BA9C42F67AA556C +:105A800021BEB39EF88D5F4444AAE7AD14A56578A6 +:105A9000B7CB288D7DB3C1EA0E501F5537A311F443 +:105AA0006F47873540FEB5849BCD90CEEB41A0BEBD +:105AB0007B5BCFEDB7458F32A3489F095767915F56 +:105AC0000BCCD316156135EA2EC84178E1BE05B07E +:105AD0001FBCE2B44546B9733E4CAC05E04B9FC4D5 +:105AE00061C827836339C0D7BE7C0EC33E85D32FE0 +:105AF000FACA398CF8540E477C6B35A8CA3C9E957F +:105B0000E1FB02DD27A75970259B6F7EBD3E62F940 +:105B1000AA0BEF29A67B3EBAEA2E9693C8C7205A55 +:105B20002C14D66AFDC930675EE7C306B2E381E88C +:105B3000613AA760BE610D46218430EFBFEB6FAACA +:105B4000529B6FD902B893F167F4FA048722D03CD4 +:105B50007A4BD2FA7F78C55F3C9E5248B9B21EF3A9 +:105B6000E61937410AD28FD46B737FBE9EEB184F74 +:105B7000C0B8DDC078129CCF6FB5F8CB281FAD74CC +:105B80008F24E7A7F4FAC40A30BB32B49C32BC4F6E +:105B9000476C0E6020B2308F1D211649C53EDF19BB +:105BA000DE744724D8C3E096717E3CD77DD8E646A4 +:105BB000A589F3B6338D26F9135C4AD5E22C593406 +:105BC000D86FD5F65A935D8B730C6EB56B75719467 +:105BD0009A05EBFBE879163888FDE7A918BB4E73E8 +:105BE0002CCF01D08BC3C7939F1E31D13C0F99EFAF +:105BF0003D99E3D81F798A0C1D3994370C26F6415C +:105C0000817E0724C06D9463911C616E25CA2D1995 +:105C10009F257D9FD8156E2F77579001BA5004FEAF +:105C200083345F462D50771AED779D637090FA3B71 +:105C3000E00205F7FDE8F11B874F21DD738EC9B443 +:105C40008EBA8357F99EEF162778FF78C2772DBC5E +:105C50001E8337357A88390249F23A40FB1DED6ED2 +:105C6000467F686E741F300552D06EC339ADAFBD2C +:105C70000E4B40417CACE81D91F09DE719E4D11C2E +:105C8000532616A511FF80190225DCAFA6BA84FDA4 +:105C9000845F85FC8EEDCFD8FEF1C0F45821D56B22 +:105CA0002753230ADF3FB78CFB052F921BDF2FED15 +:105CB000A16133CD1BDC4306B9DD8E863B343F71D9 +:105CC000CF18E94B0EDFE7F98028AF53DC2F067EB3 +:105CD0008D3D63E16D2C095809157338CF3655CACF +:105CE0003CDFAD6EC6DC181F497075919F7091C97D +:105CF000346FE7C7ABD1AEF541A39F412FE677C81C +:105D0000A2D5C7D03A16F0A37C23A294F7A18B7B2F +:105D1000FC0CFD1CAA62AA40F120218CC7163D3E56 +:105D20002F801F6E4BFCA9706CAE1AE035AC612B56 +:105D3000D653A35E0F00016EA7F9E3D408BD238EEE +:105D40009A83F92A7F97F8F97D6755E0FCD414E827 +:105D500049D6AF6BEC75B36A0DC93DF3F7D32E7B13 +:105D600092F7D347F876223B7BED4C24BF30BE2B15 +:105D7000A9BFEF155DCB1C41F481C9B58FCE755914 +:105D800022ABA9BE1F98DC1C8FF191EEA1FD828B86 +:105D9000EF16F591008CCF8723E567CC949776A218 +:105DA000C7EE5B1297E3B8E969FCA10ACFDAEFA16D +:105DB000CA9AA7FD7E86FA17ABCF577F6EB2BC1D7D +:105DC000A2F997A47E7ED2E71FC01299F7CB933831 +:105DD00083B68764E0753CAAEFF57EA6FC487BC8D5 +:105DE000FF9D190695F85CEDCFD0F47FA6EB8BC133 +:105DF000511DF69B35B9F9F627F439FC8BC9718A28 +:105E0000EEBDF2A4004A82DFAB82A9A024F85D199E +:105E1000CA31E0F6C862837CF578A9815F33B1C2EC +:105E2000C05F73BDCA80BF145D67905FFF6BBD012B +:105E3000DF30BDC520BFF1CF6D063CD6BF7558B968 +:105E400089E73649AF1BE40A3B8D7E15F518FD2A1C +:105E5000EE35FA15D35BE237FAB7ACDFE85F4EF602 +:105E6000835C85DEA1FFFC9149FB60203CC3F334D9 +:105E7000359D02133447C4A8B61FC266BE17A6F0EC +:105E8000FFE2A2843C2CA7D73FDA19092FB3D2B97D +:105E90000F9D362BBDDB2E510D603EFE05D7762EB5 +:105EA00017E00E00000000000000000000000000ED +:105EB0001F8B08000000000000FFE3E36660F8515C +:105EC0000FC1D3B81818367221F84301B7334368AD +:105ED0003E16060601207EC7C8C0F09E91043338E6 +:105EE00010EC7E20BB0A88277150CF7D43112FE52F +:105EF000A19F5D5FA0763D1518787F83B083100366 +:105F0000839B300383B40884BF5F0455DE5108C10E +:105F10007E2E41995D9F81FA018DEBBB318003009C +:105F200000000000000000001F8B080000000000BF +:105F300000FFE57D0B7C54D5B5F73E731E33939976 +:105F40004C260F4242004F08202A842140088838FE +:105F50000990068D9A080888CA000142483211A9A2 +:105F6000975E6D672214D16A1B2D6DA397DA0141EC +:105F7000A3450D18E840031D4C41BC5A8D0A4A5BED +:105F8000B541313C0A4978E8C5D65BEF5E6BEF332B +:105F900099736642A2B6DFFDBEDF177FFE36FBECCB +:105FA00073F65E7BADFF5A7BEDB51F2359C613D345 +:105FB00015847C057FD71372482484F4EB4E3B0B89 +:105FC000683A8E107F8E39B0552024B4EFEFED245F +:105FD0008590B34DB355732621FBC79843D7D3F2B1 +:105FE000B381FC8099964FDD79C421D17CD54E5187 +:105FF0008272D33E2B7EDFB1510840DE6B6EFDF125 +:10600000B534DFB553249B69D5246437915442DA03 +:106010002D84FDA9F1985F6A65D9AA4DFBEF82F640 +:10602000CA836662A5DFB737896EC8AFDC2A040869 +:106030006DAF6AF783CA005ADFB280D06855697EB7 +:10604000EB638A1A4FC803FBFEEC68B31372DA677E +:1060500021AA82FD286F1C494845607BE100FA7D3A +:10606000C536C165A2F5576C3CD701F45534C9C398 +:10607000445ADF8A061B5147B0B6BF22D05ECB0719 +:10608000D8DE4E7928B457FEE53D0A11A19FB21B18 +:10609000BEABA27440BFB5764FFBEAB13D8D9F55B4 +:1060A000CFD1F6E87BD52F0A2EE862B58978808EAD +:1060B0008EDDD6B94FDBA17FB5CAF0F8C87E2CDCE7 +:1060C00005FDA8086C520AED40DF2665E9C8EEFA26 +:1060D0005634FC879EBEFAACFE9E8872637ADA471D +:1060E000593ABC3B5F4188BB91D64BA480523AAA37 +:1060F000FBF907422221E3A17E91A896EEFAA9E4DA +:106100001107FE23F49F940FFEBDF181AD99DD725E +:106110005BE9049975CBEDBC93CB51EACA8DAC5FBA +:106120004B7F0CF2A0F4D4F99C983EEE4BC37483E1 +:106130004F45BEFDDC3702D37A9F0B9F3FE9CBC3AF +:1061400074A3CF8DE953BE224C03BE127C6FB36F94 +:106150002EA65B7C1E7CFE8CAF1CD3065F0D3E7FA3 +:10616000DEB71AD36D3E3F3E7FD1B71ED3465F1DCB +:10617000A63B405E346DF205F0BD5DBE064C83BEAD +:10618000467CBEC717C4F411CE47C764922F513E58 +:1061900038DCC449C54E928ADDF932CD2795B07CF2 +:1061A000EA1DFE7C85E6533D344FF932A032946FF0 +:1061B000A6F90135AC7CF0FDA4C042F383FDAC7CB4 +:1061C000C823EE022BCD0FA963E5C337FA0BE268B3 +:1061D0007E7880955FBD2D5460A3F9AB1B5979760D +:1061E00033996AA7F9EC10CBE7BCE19E1A4FF3395B +:1061F000AD2C9FFB817FAA83E673DBD8F793CE0497 +:1062000044D51E2D871DB2BA9850596DF4CF704BEE +:1062100013695E51EF212ECA1FFFAD6E299DF24317 +:10622000766379C83F1FCB9B143796BFE32FC3FC1F +:106230002ED983E5C7FD552CAF78B0FC73FFBD9810 +:106240000FCA7E2CB7D4FA585EF163F980DAF5589C +:10625000FF1E3980E5236B1FC3F23D4A00CB1F5F51 +:10626000FBA47B1ACDAF113C3F073CD2B49C640128 +:106270009E1AD34A289ED609642EE0F707003A8A70 +:10628000CB75E90AEAE18E3FE43E0DFA8B7F299057 +:106290005FFACCC399F8FDAFB01E99D623F65E4FD6 +:1062A000CE9B79BA7A72DE2CD7EA6980F7D658FB92 +:1062B00056CF8E3727E9E979B342AB673BD213DF7C +:1062C000B77EE5BC35594FCF5B955A3D7B909EC458 +:1062D000BED1D37444CF9FA62361FEB4203DFDFA06 +:1062E00046CFB8F7F4FC19F75E983F6F603DE97D43 +:1062F000ABA7E93D3D7F9ADE0BF3E708F66B50DF75 +:10630000FA35EE7D3D7FC6BD1FE6CF47484F66DFBD +:10631000EAD9F5A19E3FBB3E0CF3E704D633AC6F40 +:10632000FDCAFD48CF9FDC8FC2FCE9C27AAEEA5BB2 +:106330003DBB3ED2F367D74761FE7C81F58CEA5BBB +:10634000BF72FFA2E74FEE5FC2FC310950CF98BE8B +:10635000D113FC54CF9FE0A761FED8B09EF17DA37E +:1063600027AF5DCF9FBCF6307F520490FBC4BED5F3 +:10637000136CD7F327D81EE6CF20ACE7BABEF52BB7 +:10638000EF849E3F7927C2FC198EFDCAA77A0FF4CD +:10639000105A4F7CCFF5EC39ABE7CF9EB361FE8C42 +:1063A000C67AA6D37AB27AAF6752879E3F933AC233 +:1063B000FCC9C37A66F4AD9E3D1D7AFEECE908F394 +:1063C000271FF97353DFFA35A953CF9F499D8C3F9F +:1063D000630FD74C75D0723A16BA44FAC9B567DC68 +:1063E0006E81E64527CB8B4E1701BF44D4FC0DD2FE +:1063F000EA16E9F7F66D89390F9348BFA3A014FA9E +:10640000154FBDB148BF23212F4EE7E724BA93743F +:10641000F9E4A201BAF7FB950CD195F79F7BB5AED5 +:106420003CDD93A3CB67944FD2BD3FA8A64097BF56 +:1064300062F50DBAF733FDB7EAF259EB6FD7BD3FFE +:10644000AC6E91AEFCCAFA0A5DF9558195BAFC357D +:106450000DFFAE7B7F54E303BAF2D1C18775E563CC +:10646000428FEBF2630F3DA97B7F7CEB665DF98485 +:10647000A3CFEBCA27B6EDD0E5AF3DB9C7E0E7D96A +:106480009DEDD7F0BC08B827CCEF4F57D0DF0BC538 +:106490002B985706D8D18FDF1FBF543D4EE5ABBCBC +:1064A000B2584DA1F20599123AAEE70F28BFB28D4E +:1064B0003EBF7792E74A277D7EAFE219ED8CE19FE0 +:1064C000523C08240D52D504A9B1FC4199E1B120F8 +:1064D000E3CBE1C7E8F75E53D7F0449AEF2FE6D756 +:1064E000035E9E124C88D33891D4C07B716682F3D0 +:1064F000820733739FF647E075FD20AA874277BD78 +:10650000EB654F1AF8199B6BDFF6831FB26E10ED27 +:10651000D700429E16DE0EF987D2EF072D4DF3D03D +:10652000FACC0AF5D323DB5768FB23B1FD0668FFDD +:10653000C51EDA370FC9D3B56F195CAE6BDFA2D0B9 +:10654000F69DD41FA8FD236F9F0A6112212F0B7F98 +:10655000C4F6CD83CBB1FD07153A5F896C3F2EDCC5 +:106560007E10F4771FB43F3E46FF874CD2F77F7012 +:1065700085BEFF0AEBFF2BB5C778FB71D8FF16E18C +:1065800018EBFFE00AD67F33AB37DCBE23CCFF43EA +:10659000D0FF377BEA7FD6647DFFAFA8D4F7DFCC8E +:1065A000DA7FA7F6146FDF8EEDBF2B9C62FDBFA2D2 +:1065B00012DB57CC1E17E047C988AB09D0F6C9409B +:1065C0006A98FA035C683B908E48A2A026E4516169 +:1065D00008D2716F1CC3DBE771146F686FFCF89C05 +:1065E00004A865CBA5F32E8EF515DBF215B04B583C +:1065F0004EE72B4B38A9654111F14D369803C3285E +:10660000BD1D41D10FF9B20DD705C0FE79CD644152 +:10661000097C2791103CFFF467A33647F6CB982EF0 +:10662000A993DBDB22F42D3C8F2A20236A287DD31B +:106630000104E3BBF31FD37910A1F38B0FE83C8374 +:1066400050487E22B3F63EA2F325C8B7D1F9129482 +:1066500013528BDFD1EA0EA751FA4B38FD1F4B4C7A +:106660005F3FBE4308F8A97E7EFEBD31384F5DB066 +:10667000DA4699DE4DC7427FB22E4FFBE5073975EA +:10668000ED3607360BC85F15F8558AAA49C8E2F5FA +:106690001994D7DDEFBF4FC59E4E597F1B71CBFDBF +:1066A000E9FB77AE12063969BBB3DDE61C364EB89E +:1066B000334CA8D724C39447C8AD4D63645A03290B +:1066C00075CB1FB745B43BB3489F9F5DA2CF77C83A +:1066D0006ED944E9EA2815C8265AEF9CB9FA72AD7A +:1066E0001DBB2989C999B75792CAE89B03690E3C1B +:1066F00076A29CE73AD9B71A3DDEC5329DC2823CEC +:10670000FDFD08C8D59F82EFDDEE64FD36D23B5714 +:10671000B6B84B683FE72E1403806F23FD7FDA671E +:10672000739BB269BAFEA7323145F7C748FF3C8F69 +:10673000B13F8D328CC3F3CB8DCF196EDAB9FC3FEC +:10674000067CD0F404E083D27F9CE3A3DBAE327CF2 +:1067500078CD9E9B010F5D4F8804E5CAF1721BC77F +:10676000CB923A3D2E08F1C820C76573859C8723DC +:10677000703087E36059BD1E377712BF9C1E432ED1 +:10678000F3366CFA619A1ADDBF0F396EE63FB21F1D +:10679000F913DD4F26A7BBB89CEEACD197DFC6E559 +:1067A0007A2797EBDCFAC70E50F3416E570332E8B5 +:1067B000BBF73E4D9E6D3A797AB83C8D74DEC5E5E7 +:1067C00079D7F7983C8DF4B67179B6D55F90C990BA +:1067D000687A8DF42D581DD51F05E4B9D01F5B9E36 +:1067E000DE607EF2F188E7558D33928F47E8D98AD3 +:1067F00086525D7E79609EEEFD65F50B75E54BEA90 +:1068000096EBCA17AFBF5B975FE8FF9EEEFD05AB47 +:106810006B75E577D63CA42B9F5FFE982E3FCFF398 +:1068200084EEFD397337E9CA67973CA72B9F59B4AB +:106830005D972F75EFD6BD6FDA77D52D80CF378E68 +:106840008804FC89CF5C27302EF8994B76C13BC772 +:106850007D2AE2BADD3702D3933E17E2FEB42F0F52 +:10686000D38E608B1DC6093A2E2E2589D4CC9B6E03 +:10687000AE5D3F10C66982E3E916D3AC5AFF6442AD +:106880007E6D5291DFC5F50A098D254480C186D3FE +:10689000D1254694B7F5525E4F0D7F727479715BC6 +:1068A000ECE7DEC7175EE18C1177E9D65392017EE3 +:1068B0004F27F7BB8DE5950229897C4EC803A8D7E1 +:1068C000E7F8B85BA930FDAFDC915E401C900F0D7E +:1068D000AFB95C7B8D14E4FD0127593A3D5E567FCC +:1068E0008DCEBE1388CAF603BC8DD53D5FD170AD89 +:1068F000EEBB33FB45A4BB1A6CC54418164B5E3780 +:10690000811D0EB50C9E390AE874BF6182712AD8C8 +:106910000FFDC233BEA2E4E312C8AF04D393BEB9E5 +:1069200098B6FB3C981EF79563FAB1AF06D336DFF5 +:106930006A4C3FF2F931FDC0B71ED33FF9EA303D52 +:10694000EAABC7F43D5F00D3C3BE064CDFF135624E +:10695000DAEA0B62DAE17363AAE95D6FB83BC9C793 +:10696000E1D380BF1838EB786055EDFAC9DD383BCC +:106970006FBAAFD63FB09BCFC5F5668E87541D1E4C +:10698000BE806033E2AC97F27A99E3B0A7EF6397E9 +:106990007B37FF6BF036DEC4FCCC6F8AB76E3C658C +:1069A00018F094D51B9EFA89E3BBF134DEE4647ED3 +:1069B0000FC7D38FA01F31E61505E084F48BF0D705 +:1069C000DC3616A7E6EB09D45365716ADEF61AFACF +:1069D0006E2BFA758111306E9C1FF1B7E110873F65 +:1069E0007FD44C277D3DF7CF88939EF9EEC6F9CD35 +:1069F000D2001DBCC646975BE3185FAD265244E843 +:106A0000B8F6D0B0675C8B46625E2249F07DC05517 +:106A10001A1FA35EEA2B037F7BE3EB9AF8CFB3A1A7 +:106A2000BEF627FF9E0BE97813F397E35A44F4DB95 +:106A300049E86917F0373C2E995D6910DFEE1AA618 +:106A400038D16F08D8F5FCF3D37C6E37FF1EA23C1B +:106A50006AC571B72E0DF937F4F3E1E97DE05F6F98 +:106A6000F6BD377E2E0A0CF897F0B337FBD89B5D46 +:106A7000246EF5C520ED7FE7BE51390FAB60078767 +:106A8000B0795A0FFCD6D6A58CF47CFF6BE2B833F4 +:106A900055C371EB6042DBF988EBCBF9A62B1340B1 +:106AA0002EB41E9C1F74EDE47E7E2F723D9BA9AF19 +:106AB000CF6BAC2F4121C268DA6EBCA29004426A4F +:106AC00044CFA322CE6F5C6D7E881BECB3B9D6A8F1 +:106AD000306F3CFD6648851AF5F185F3879E76C0D8 +:106AE0003C6C659AC9793C861CB5B4AA31D3698FD0 +:106AF0009CAF04F5F9F375425123CEE7D48459A332 +:106B0000609C713A8F0F05BB9F86A956CFCA34C5CA +:106B1000799CDADDD30D59096CFE1760F6645B22AF +:106B2000DA9BD33E0BBEFFCFA6A7A77A347A0869BB +:106B3000229F58C09ED3B2AC9EDFEF511FA48B0A98 +:106B4000C43749B3FC39CC37ADF4FFAF8640BD1232 +:106B5000E6B57ABD8DA2DF3C1A9E6FD3B547BF5311 +:106B6000B5B557F8AE67BD9348BB867B2ABF57F9CA +:106B7000FAF08A06AB53EFC726EAF2DE60BA53E7B3 +:106B8000D7C23FC071AF1124C05F25875FA7645F84 +:106B90000F78DA0CC14398BF08ECBD2A4B9BE25139 +:106BA000515D5A019F8BF234FCAB73FE4CEDD4A9BE +:106BB000D765027A46BEA454E5F2A920E2CD444C42 +:106BC00034BF98BFBDA86945318C5BA74C6CFE50A3 +:106BD000464A1C303F2E2775B9104F3D4B4C45A0FF +:106BE0009F67C93B8EB111FA784E54B0D2C5EBF510 +:106BF0007E3C9DDFEBF2CBEAF5F9A5E4D6545807CD +:106C00005FBA41260101EC86BEFC98E8C47A9791F0 +:106C10009A75306EFF9CC7BB1639899441E9ABFA6F +:106C2000CD2F7317523A2E896CFCD5D67197273128 +:106C3000FA2B660514377DFF93A6B1B7510B44BFFD +:106C40000FAC83756D7F29716D25D1F2FBBAF41BF2 +:106C5000E9D5FC81A8F5644E474A83E00EC4B063D1 +:106C60008A24303DE3F6EE6AC9A98B83E4423E22D2 +:106C70000EF28DF194427478DA2C7A064BE3197E89 +:106C8000000F82D4A578BE4DFD6951F55F2DF5FB4F +:106C900027D63F90D69FABAB3FF79F4AFFD028FA4D +:106CA0000B62D55FF59B1776F9A93DA978E9670EC8 +:106CB00042C7C953525DAA8BCAB572EB0F1D6E9ABB +:106CC0009E94FC0EC0EBA98058144BDEABC3F27649 +:106CD000DB0588BBC13F69FDA79FFF11C6233EDFCF +:106CE0002A3B319ED6600E99A93E56372D2F26D9C4 +:106CF000983FC6F20F9E13211FD4E3AFE2D99FA5A0 +:106D0000C2FE0A8A141E5F0AA13F5BBDE5D3421C86 +:106D10009F4817EA91F13B68FF5212DABF854A4259 +:106D20007439A513E3045ECE176FD38FCE890EF8A6 +:106D3000571BCEDF8DEF9773FF74B9149FD26EA3EC +:106D4000FF9E4026803DD4F84102CC3F5DF3DC2F0E +:106D5000B28F517ACE6C79DD2144F049D3A3F38D03 +:106D60008B7FB547EDD9DE76503D8BF483B4F14A85 +:106D70000D72BFBA99A59572C8712DD5FBCA4DB2D7 +:106D8000CB4F1F57BEF0F4334F421CF38F66D73002 +:106D90005AFF8A170EBC3789E6576C97538A5937C2 +:106DA000EC426AB75CBCF4FFD539DD72A878F98093 +:106DB000A28E62CFEF4FEA96C78AEDFB15322A9A70 +:106DC0001F531BF72B6DF61872693C56087EC29A4A +:106DD000E7FE4B81F8E2A97D02E99F19839F9B0E94 +:106DE000A01F007C4239723985E56678DF4BE502E9 +:106DF000F65A9393B1FC466E4FA03E7524E2F9C556 +:106E00003DB4FDF23F995DD0FFF217EF71403F4E68 +:106E100048350CD7BFFC612AD8AF72D99FEAC49419 +:106E20003D2F7FEABB88B7656F7F3715E349C49D67 +:106E30006EC2B1C79F0EFD5BB27136F66F29F120AD +:106E4000EECA7F29960468FA99448AB6C7D08B0E99 +:106E5000AE17273653478CF6EF04CC1FC15EBF2315 +:106E6000E2BE2A42EE26A0FFDFE57DA11E02E63F3C +:106E7000B330391D904C5CAFA8B71989D72D0FB628 +:106E8000827C4E0F72F78775162F91FC9C1FC2579C +:106E9000B45EF1EDE9FD997C882AE5F2EFE8383F30 +:106EA000159EC3FBADB2DB9AADFB8E7C95D9DDFEA2 +:106EB0002ADE3EA53B0EC6E713A9B1FDD501B2A659 +:106EC000F7749C8EC057847E337DDFF210D36F4DF4 +:106ED000DF03A545507EF130D31FF80EC63F4A5759 +:106EE000A83F96EF9F25A03DA0F3E6587ABD45E662 +:106EF0007AAD2FD77042E996848408BC40FD49C81A +:106F00007F5C5F59BA817E17612FBDD09E23BA3E48 +:106F10004D6F9771FD3F05FA7F4DB7FE938D4CEF96 +:106F20007BF69FFC2C6E23079E7912F495EAA75FEF +:106F3000057D954BA0DF7FDDD6F2DEED544FFFDA05 +:106F4000A8E9A9DE7E1AF5B47CC778124B4FFF6A18 +:106F50007791987A4A9FC7D4537B1BE2F8FF94FD40 +:106F6000D4F89728EBF9A7D9C39EF868B4872F4ABD +:106F70002AF2D3680FE9DF61921B8D3F0D771ADE8D +:106F80002A7E5D7505D89D302E35DC8571A9E12EF0 +:106F90002A7EABE39FB1FCCF106BA274CDB7D44F68 +:106FA000817984A58BE0BC2B7F9688EBA6968B0419 +:106FB000F5BE80C8B86FF07D53CD78F043A7FCFDD7 +:106FC000B6B3F7527AE713BFCCD6E5EB64F4EBBF68 +:106FD000FCEAABC9B43FB773FECEA7ECBE89CA6367 +:106FE000AE2484E2289DF324E24F4882F8AC403E70 +:106FF0008EA0637EB93E0F7F5352BBEBE9EDFDAF30 +:107000003B0FF9A6E9DB3EB676F52EA443B179290C +:10701000124FA52057CA3FEF38213004ED529B5440 +:107020001231AF7A9CDB9DB7A7CD1C0FFE4BFE9CA7 +:1070300051090CE783717EEBE5F6EBBC5F4D00BBBD +:107040007EBE390BE7AFE70F2D8E8FB56FB285E3AC +:10705000EC005F57E9B40B7522C57D27E942FFC5F7 +:107060006FB792AD31D6FDBE2F9BF8E483CB8DFE7A +:1070700089546E73390EE7D14F137222E436EBA6B2 +:107080005392235A0EF0F771C43CEBDBF217700DEC +:10709000FC6DB1B61596C488D7FD84F36FCA2B5F1B +:1070A000E0FED569CDF912F0719A5DD4C5391ED4D0 +:1070B000F475241909744D7965F9A3E3298EBD8708 +:1070C0004417EC57F5369F533C31E6BB467E42FDF4 +:1070D000E0471E909DC8AF2372C912E0EB91D956CC +:1070E00002EB96EF2AAEAA58744E37B378C83C52DA +:1070F000F2D938E1FF3EFEE6CF890F15507E9CB7EE +:10710000B3FDC0D1F8637A7FDE29046A05C0A1C847 +:10711000F2294200E26485C4F3E86401F5FDFA480F +:10712000FB951F2C7D01F6D554370B4E132DAF96D2 +:10713000DA14C0B137B85D02FFFC4695B831DE20E5 +:10714000D58C9A1511D73A204BC8AF96BFDD7E2754 +:10715000F0F7C22C3301BADC23CF3960DCBFD03C5E +:1071600016F5A0A77EFDC147A64C93A01E82F8305D +:10717000E2A130C5A6CBCF9E4A06BAA8DCA698DB12 +:10718000EE71C590DF3285E1ACCFF6CDF2FF997D8F +:107190009B4CED1BC3B51C69DF462B51F6AD7F2C14 +:1071A000FBB6B256ED0FB858B937AB3FC875E56BB3 +:1071B0004BFAC5B26FAFFAD8FCFD35BE0FBB7320DA +:1071C000B56FA323ECDB406ADF62C46DD315CDFF3E +:1071D000ECC5BE59FE77F4EF55B06F31FA3B52D192 +:1071E000DBB7A2E65AB46F450345DD7EA82C85CFF8 +:1071F000E77AB46F0B7F361BF3B2CB16033FC05751 +:10720000B06FAF713B07ED809D5BA438B1FDBEDA76 +:10721000B9D2BEDAB9FF253E6B766EE520769E23A5 +:107220001A87CCCEADCC64766EE55E66E7560E630B +:1072300076CE68DF0AA2EC1BFBBE7A04FD1EE78B4C +:1072400099BFB8839617CF955D16FA7EB1AA9D5F58 +:10725000A8191F69EF162912F239CADEB9CEE13931 +:1072600090DEECDD5B60EF86A21D1B0A7A64C4C76A +:107270000D436DBAFD7247BE68FFF54BA02F7F101E +:10728000719EFDBE89CD8BF67DD13E16F46E37A77B +:10729000E75185C9B3C3E7477B3A7524D3F7AA43BF +:1072A00071384E543709ACBFF70B0115C681BF5D6D +:1072B000C2F9F29D7BD97C798E99F183FC9BC8CE73 +:1072C0005D50162C8CC0C3DC4B1518D79C2B110BB2 +:1072D000F8AF0B0EDD700AFCD60597D6A3BFBB0036 +:1072E0009EC3BE89ED6DEB3268BB772E1770DEA1B1 +:1072F000EDEF9817B6977A3F767E73EC7D1A533888 +:107300003D53EE1302B02FA7B77D102F72FD9B23C4 +:10731000B621BFC85B62CCF8A4F65E984F2EC69724 +:10732000AA55CC6F0EF389F24D15A2F944255DBC28 +:1073300030B59B2F77EEA4FD4DE9B9BF1ADFA2F758 +:10734000E1B8713EB380BFD7131F343E47F59FF3BA +:107350009DFAA9B89FC7C88F46CDCE5C4346815ED3 +:10736000BE6FF23C3A1E70F49F942F94CEDBE60D74 +:10737000D39DE7D9C5F97293E7D8B45415F8486A94 +:107380000067B7976F3F904AFB778B3B330742E626 +:10739000B3FFA67820FED062ED423BA8E130CDCC11 +:1073A00070F8578EC323039CD370BC090A4ED4AF28 +:1073B00090C1CEF17D645ECA67D05F6F908F4F142D +:1073C0009FA09F85DA780572A1FFBCA999C9C55B0A +:1073D00023A05C6E265D0781EFD529822B44AB2A62 +:1073E0000C6EFF21ECB77AD54A9F839E970BAECDEA +:1073F0008C1DF6F4D498389662E1183709468C9BB8 +:107400000BE0BD24D8B768C6F6EFFC1EB347463F75 +:10741000658AB9F508D033E5DF64B2091E06E87F56 +:10742000113830FA31517AF035F7FDA472FBFD2A9C +:10743000C8C10EFCEE52C01FF286D8F8A3957B257A +:10744000751AF24D9343908E2FE3981C60A9DFC804 +:10745000E75BB43CE01FDE6F1664F87E06954F32A2 +:107460002D9A6AFAE2A08677B31ACD2F8827A4470F +:10747000D80DB06F91EB96D5C1B7914F37ACA2EE56 +:10748000991ACD274D3E60072FC7AF28FD09EE8F13 +:10749000B97FEA9BEA4F9A59AF3FFBAC5DAF8F864D +:1074A00038DA5E01ED0A694ED4C50FF2CC6C5ED6B7 +:1074B00062F520CEBB5E935D9BD568FB7315970B81 +:1074C000CC5722CFEF4D850EC1BAB1D34A3ED1FA87 +:1074D0003D84E12C723C78D5EA41F9F554FF045E15 +:1074E0007F4FFE9896FF0EB407FB16557D7BC6F1C5 +:1074F000488B27F5D6AF6966663FBE69BFB476BED6 +:10750000EEBA8397B462FC4D5B7FD82C7A7E2EC393 +:10751000FCB848D0AD7350CA71FDF29F50FF58E5DA +:1075200032F543FC2844F9FCEAB6A7315E7DF6F952 +:10753000633783FEACF8AD482C549F3AB6C5931020 +:10754000DB07A2809F50D124E27A169142B93323FF +:10755000FC0C42D6307EBC148F76A7628739504C23 +:10756000BFAFD8F54936C4DD3A1E60F6CFFF3CC741 +:10757000A3BF2D1BD6FB2B24B68E6F94CFBD1C9FB3 +:107580006776DBE682FD161AD879D78AC639B23912 +:1075900022CE506596595C7BB70DF759FB9F13704F +:1075A0009F32D01779CE52DBFF79E63966972B826E +:1075B0007200CECD56346CEF803878C55133FAAFB7 +:1075C000DE86730AF8A7535F7A01FD236F50D4C596 +:1075D00041A3E28F0D62C80CF1B3A62AB403347F35 +:1075E0000CF38DB1E3F0BDC5C956BCB477979FB21B +:1075F00070C5CBCF3AF0DC6CEB5607C6211B2E1FB3 +:10760000FF8F8A37363E74D978E3698E8F5F99F59C +:10761000EB35A42119E39094BEDC9218718B30EE07 +:107620005FF8EC29580F3BB3E3AF4F01BD95FFB8AE +:10763000F0D47DE08FEDB33A61BCF63E7F04D71302 +:10764000B4EF76733DEF78EE595C87E9F8A3D9057E +:10765000B575EC3D3118D6233AB67F910A71DB55EA +:107660007BA7E33C6DD5CEA9FD498C798096026E4F +:10767000037D580732CAABA5A96530D07996CA1BDD +:107680005CB670FCB8B18AC5E3551E37DE167BBD0B +:107690002D2A4EDC34F396EB60FC6E925D2AE943B2 +:1076A000BCF83095E3E83EC86FDB439ABD8F29BF35 +:1076B000B3F00F2AA7F70DF2FBAC69C9AF9E84B2F5 +:1076C000A6E41EE3C5A13EF04D5BCFDB62767F6C86 +:1076D00006BDD9F16B8CCF83DCE85C8374BCF0D938 +:1076E0006088B39C94BBEEC2FD337BCDB82FAA62F9 +:1076F000EFFBA83F1D3BDFC6F532C2D7D53A48F8AD +:107700008FAD83F0399C774B3C8B3373FE431C5A0F +:1077100075E0731E6F6638D6E2D03DC59FD32D6CE1 +:107720003F91B6CE58B5E5CF0A31C4F5853C90D32C +:10773000B1CBAE8B6A7C70021F2644AEA7C48EF319 +:1077400087D7DDB8BC407EE07F85D74B687E20C4FC +:10775000CF03C2FB24863DE8D8C4D6613AE4D8FB07 +:107760000FB5F595148B414F037D5B57E98DFEAF47 +:10777000CB1F19269BE3A3F974E6CBD8767C824510 +:10778000F876FB612A85A8F57F0BACCF371D5360D7 +:10779000FEA18D635A7FCFF079F299E7453CEFB1B6 +:1077A000AEB105EDB8D15E5413161F34D23B83D36E +:1077B0005B1D64E3C4991DF1013BADE7CC2BBB110C +:1077C000CFD5DB8E297E5ADFC1869795B688FD52CC +:1077D000304E0422E83FF3E2FE6CB67EC4E6E5C616 +:1077E00076E6F076BCCDB1DBF16E3BA76B6785BF6B +:1077F0005161E7772EDFDE69C93D07EA3BDD2A13D9 +:10780000D8BF7FBA512C0AC4687F9245D6E2F24CA9 +:107810006FE87889E71DE3D9F946314941FF7A5588 +:107820007CDED18414481515E2146B6AD9FED2357A +:10783000DF77A581BCD724DE86EB6D7506FE3A5353 +:107840009CF910BF704E2B19077035DA9B44B7496D +:1078500047FFAAF8A2FE701E7F2DF7C788E4C2F387 +:1078600097A2A3B008FA233A4D4E6B8CF505D95E6A +:10787000423C117C919DFAF392E4CBB12AD4A3ED62 +:10788000A3A9B4B41EC442A71BB70A4B79ECDDFC14 +:10789000594EEC77E7363E4F7013D599CAF683C13F +:1078A000B8D1B923219B8CC60F899BE2D1C69F0B0F +:1078B000DBF6EF077BB4D641DC8954CF285755312E +:1078C0000BCE8D8EB1085980D3736FFE96D66B6D3B +:1078D0001671FED069D7F685BA1341CF6CE411DC7E +:1078E000FF0750FE2AB99B4EE3BE4002AFA476DFED +:1078F0002B315DB4E3BCE7FC46160710C9D5BF9831 +:10790000CCE2702400F4F3F16405A7F33CA4F07E0C +:107910009982E73A96BDF6726E88303944F22BB9F7 +:10792000487FBEB4DEEAC8867579E277B7C2399976 +:10793000325E5FBF12FDB953AA7E7ED0D3255C4F65 +:10794000FFBAB4F010D8BF32CF52B4EBFDE7EACFA4 +:10795000A51AF75921BDB02F8CEADD9342F4BEABD6 +:10796000F2E6C7D6C17C397AFF151901FBC92A484E +:107970009C0BCEE7AC68D097EF03BB7915B093D8DA +:107980002F17EFEB95BF6DC37F3179DC65F9EB0AFB +:10799000C1FBDBE231AEB2ECB5C5689FCC697AFEC3 +:1079A0005A553D7F6D238C7CD4F339DEA5E79B3699 +:1079B000FFEC89CF0979FAF3BE463E4B84C71B0220 +:1079C0002C0E11B5BF2DB809E936F2D9C8D7760B00 +:1079D0005FF7E27CA57F25965466B281EE74298418 +:1079E0007A61D4A30C7B48807F0F4A09D4E257AE5A +:1079F00078B4EF69BC3F4219FBCE067A2402BD2E53 +:107A0000D42338D10776DE463E70B65B41589F904E +:107A1000AFAEE9599EF794FEFED822FAD546C0EFE4 +:107A200068D42B766E378904D664829EBA9C306EF9 +:107A300037FA2C6A9904F79F10B56C28DC7BE2C4F6 +:107A4000F4C77C1F4AE74882FB821B431753C13EA1 +:107A5000FD38A7EB66B07BDE25A404ECE0CD716CAD +:107A60009EB298A77FB72ADCAE4E7BED7AF8BE595E +:107A700056E15C7867F356CB30C80745BC7FC49BA2 +:107A8000587715B4DFD12C33BACA2C816110BFD816 +:107A90002B63BB1D6593F17C65D86F6B66FB403A29 +:107AA0009B3F712C8EB0E71DC19F5E05F1AC274C4A +:107AB000B1F79F0CB79AF8FD35DF70FC6D8CDA7F5B +:107AC00037DCCAF6C7FD7808ED4775E9793E0E3315 +:107AD0007DB896CBF9F74B6FC0FEEF6C1654184784 +:107AE0000AC53B6E1C45FB39F188C4E3302C2E39A6 +:107AF0008EBFBF9BB8D2801F13AF2302E8F3C43FF1 +:107B000012DCB735AE6629CEAB7EEBA038CF8675DA +:107B1000528A5BB07367ECE8BF8F6F9574B84C9C6A +:107B2000E6698179E684A304EDED84A3FAF23C12C0 +:107B300010B19D36FDF36B4FEAF305568E6F074982 +:107B4000057C6FF85244BA3ABB88EB015A6F67D98B +:107B500000BCEFA6F3229CDAA5E9976251AC717ED6 +:107B600026E081F2EB0985E0F8F2C4523BC6EF5FF4 +:107B7000595A71058CEB9F7FCF7345AC73E011763A +:107B80002981EDAF722750E229AED70A8CDF75E963 +:107B90002531F6EB6B38D670ADE1397D699C27D67F +:107BA000BEC40FADCC0F29583A4250605EB64F208C +:107BB000C0D78E073C973D37E3270F64003DDEE0DA +:107BC00005F4B32DCD823B969FB1CAEA60F3BE07A0 +:107BD000FCB5B01FEF5EAA94601F7BAE7703CEABFF +:107BE0006E87A02B7C67A95B88E7709758C866886A +:107BF000674B75E9B7C603EEA7CE5847E97DB2C417 +:107C000084727E427621FDFE2A4230BEC0E3B50377 +:107C10006F269B22CF23FFC09AFFB095D6FBB0D52D +:107C2000897249F6B804A0DFF5DFFFE500BDEEBCC0 +:107C30006446390EE0F31FEDBBAD9C4FA3E3DC6B54 +:107C400001FFA43C05F5C3E571A865C9702F01E5E6 +:107C50007B8C7554CD2F4DF250DB46E949B29BF039 +:107C60007E2EE276AB4E6DDF19E1EF45E8030909A0 +:107C700004F6A569F654681642F114FFE32CF610D9 +:107C8000CC3392CA69BF2909566261F5B54A67C209 +:107C9000E7AA719F3BC5652E1C6E22B8AF0D36D288 +:107CA00042FD9A9DD5ECF3DA4482F666ED635260AC +:107CB0000DAD67A3D46685F849A65B2D80AD444918 +:107CC000928AE7BD0795337DB465FD3231ECAF5044 +:107CD000651FF30F7141ACF5BA8FC3FCF2BC00FC19 +:107CE000CA3ED4F50AB8352E2B6BCF75C082FE790B +:107CF000D86E703FAC908FBB133F35B1FD02A1EB46 +:107D000071BF9DB68E66B41B540FDE1541AF3E9514 +:107D1000089ECF75D3FF72B52D7711F6838F93B977 +:107D2000C19A16F4DDC4912D80C76B5FC7BB38A222 +:107D3000ECC884373C6B80DE6F6A3F8C781813A2E6 +:107D4000FAC8E53352857B2A9CE13C94B75AF9FC8A +:107D50008EDB9B94D271FDD1AFE53833F257D36BF4 +:107D6000A3BEE7AC76B598B1D60032C1D80E11BA31 +:107D7000E950B3C01EBD21827FDF994FF142E9BABD +:107D800017F40EFCF38B8119809B0DCDDFB1827E41 +:107D90007CE3F1A3997E1DB1BFFA27A2A7C3CAF65F +:107DA000873B800FD5FB2FF2F12384720ECB95EA2F +:107DB00047643C44C3BD11E79A5EAC810B33B2F01B +:107DC0007C1C01F98842230AD64C363A81AF9A7F4F +:107DD000BD26ECCF26E2B99E554ED6DE1A59F3CB1E +:107DE0005D16E8EFAAF882FE975B17F55EA2F3979F +:107DF00088F3305EA90BE767DE4B0A09247F0B7E10 +:107E00000569EBB93A7EA5C4C5E05707E8D1F8FF8C +:107E100027FB936DECCF836A777FAE259EDFB6514B +:107E2000BB907B4F7D3AC305399C16890BBE5ED94A +:107E3000937EE751FD06D72D4A9F0D7A3CB199EA12 +:107E4000B1295A8F5D7209DE5BE7DA6B437B67D439 +:107E5000EB8BBC5F5E1BE37B8DE8991107F37153DD +:107E6000D760C05DB64A928B29B1D94191ADAFB60A +:107E700026EBC691E8F1DD8F7652F32F35BFD2F8AD +:107E80005ED8AFE4E38616CF148214FFB4DFF7C7E1 +:107E900079E6015FD738D9FC130E9A82BFFC03AB99 +:107EA000E70EA0CF46FB1007EB1A2342992C5E1277 +:107EB000D2E95B4FFA6533E84F6348C271CC4FC7D4 +:107EC000B16142CFF4F48B4B64F452AB027ECAC072 +:107ED0005CC21AAB26B8AF7B6036BB4766600EBB90 +:107EE000F7F1DFE3D87ACC7D716CDCD0D21F584B30 +:107EF000EE817EC912F19B73BE39DD402AC40FEFBB +:107F00008F73DF0DFCB014B9B11F194EE21228DED9 +:107F100032A44601F6372455AA028B1B1236EE40D6 +:107F20004AEBCB2856F361DCCAA0B616E22019CD85 +:107F3000B1CFF56C8893BF5DBCAB29EA3CCA8638EB +:107F4000E66F1F54687F938BD9799470DC86920F0B +:107F5000FCED88BF0D3BDBF1195B0FF527323E1BB3 +:107F6000E75F2030E897C4F33F5488644DC2F9912D +:107F7000DF04DF992C383FB2115723D8CF97E2584E +:107F80005C759DE05A0FF99F485D16B86F47C3FFB7 +:107F90008F27DFEA92E82B8EEBCE67C39C95EAC36E +:107FA000F320AF8EC9E787AFC51E740D6678738B5B +:107FB000BAFDEF9ADC82B24E6E56888744DAEB78CF +:107FC00005E7F71D429C0BE6431DCB0546A760E184 +:107FD000E703247D9C86DB436D1C78272E13E9B7CD +:107FE00011FF18BC1FCCE2B2003D1AFDE173A4865C +:107FF000739EC673A06959E1B84D3AEE932D51E0D6 +:108000008E2F72BED986FE97D7C1F4DF8887FE60B7 +:108010003C2E736E92F2AB15E4DB5FAE49047BDB62 +:10802000FFCEE30E90AF910F9D827FCC4158DFFAD7 +:10803000831C739F8896A6A50D28057F342D3D0DC2 +:1080400053ED79BD5D8A19073CCDF5EE1BE3B59E76 +:10805000580CF3C3D3D09FB39E77DE73A3BA776176 +:108060007CBC3E8EF1BB5ED1F8A826809E75E75D94 +:1080700009EC7E924476FF9093C97383CF522A49CC +:1080800091EFB9D11FE947DC33E68111D82093ADD8 +:10809000886B16BFD1CE655043C7E497C8E8FAB9DC +:1080A0006F4C29EC9F916DCC2E5DDC301DDB4B2598 +:1080B0000F588753BE2E2D31B920AE7376D19F1C39 +:1080C00070147C51466B2EE0FD88E8916DE331D44D +:1080D0008DF3B76573954088422AA59E1A2426978A +:1080E00019B8EEB8D01473FFB3DDC6E6DFCD714E1C +:1080F0004CD3D20697968D8DCC0F44396978A47AEB +:10810000985E36AEFB9C30C5470AB46FD4A74E9933 +:108110000461DD40B387299CFF9A3DD6F42105F424 +:108120000CD6014BA87DD4E43984BF9A8AF14AFC6D +:10813000139A5FFD02E6038EEB0AD0DE51FD5F8FDE +:10814000FA3282D96F2BD8D3883865E7DEF707C1BA +:10815000FADF87DFBF100FEB407F91BAE2C17E9E4E +:10816000BCFFDD783837F4E1FD2C5E7197611E3578 +:10817000C1C6ECFAA3B6926CE8D702DF7FE77A2299 +:10818000704956B3758DE501D1709E5C7F2F4F55B8 +:1081900063B2E19E1E3FD65BC5EFE732CAA192CB28 +:1081A00061F9B64D4A860AED7BDCB67E706E8FA013 +:1081B000BD3CD9148FF3118D9E45DBC6283077FA6C +:1081C0004BB399AF7FB7CA6C5C7017C37A9687F3CD +:1081D000CD48E7C17D36AC6FC9CFD8FE9485B4AD2C +:1081E000D5D4BE7A9AD9790B633F967CA816F6A7A8 +:1081F000C25BF29080F36278FF7E3A4E79563F88F8 +:10820000EB5EC67E1AEFCD319E5FD5E653CBB8FC50 +:10821000CB8807F52FEA5C6B335B9F36C6FFCE1F1A +:10822000CAB261FF6D3CFE914B26C079E81D87867E +:10823000245CEE3EE533FC1E26B8571AD2933E82EC +:1082400069B64D65F76434BF7D2FE0AA3AB81DEFDB +:1082500019FBBAF6A6AAF99403F6306B7687FA9161 +:10826000AB013FA44CD0F997D59B2E286CBECBF820 +:1082700070077F7E07F4371BF659AB3F9A4CE57CBD +:1082800047A57C31F21E32BF4D7FEEA6AFFDD5FA79 +:10829000A9F55B2BAFE2FBD18CDF69F8CFE6782C38 +:1082A000DB52BA6E0065D19ABD2706F3F368784EAB +:1082B00047C397113FCB484961BA108193E647B154 +:1082C0005F9A3CCBEA16F2FEFBD3F8BA5E1AC48F73 +:1082D0007AC38D111F1D72DB60D067233E3A7AB8D6 +:1082E0005FE42736E62794A9EE4288675137769DEA +:1082F00033C24F3929D51DBC0FF46C0BC379C4F8B8 +:10830000CB9CB9D7651CCF57C6ABFDE13E3D94DB96 +:1083100044D81760F6C37B5A3BED3EB76BA8047C8C +:108320002FC2F4B4AFC435746877F9D2272E38C0A1 +:108330008FEE1C41308ED311AFA7F7773611E9F9D4 +:108340001D9743A5D4FA8F3F838DDAD28AFB1DDABD +:10835000BFE471A02FCD45B1FAF927FE1DE1F786E4 +:10836000DDC5F54C9B972CE072BBAB99AD672FDA5E +:10837000588AF230EED77A43701666D0AA3C8D63E5 +:108380001490BF513E4B5CDFC17D605172228FF073 +:108390007D011EDCA753562F62DCC328BF7CBB9334 +:1083A0009DA3576B701EB7428ABD0E79A5DDF4B54B +:1083B000FA63ECC7C22601EDA491FE655B6AD70D96 +:1083C00020D07FD6BFE87E8406A25DE2FDD4FA55B8 +:1083D000465C78FF40D4FA50DBF524723FF5F2E6B4 +:1083E000C5B82FBF9AF69FB03812C68534FA357AD1 +:1083F0008DFD2814CFC81688E3AE165C609FA3EFEE +:108400002773EBEE3F5CD8B07F20C8AF5D62FB66A0 +:10841000DBFD02CE0B3B3F206C7D60BD80EB693DF8 +:10842000CAAF99ED07EA598E350ADCE757B651888D +:1084300029C765F5F9AEA111766A7960866BA88EB9 +:10844000DE46DC1FB2A2A154F77C809DC793B8FD25 +:10845000EE4DDF484D62CC3893A65F9ABE69FA971D +:108460006F57D93C470A1CCCC804BBFE18CE4BA89A +:108470005DBEDACED707E6D157AA9FB8A05B1F58DA +:1084800092C7E4B3442CC6E73DD957CA079D7D1E69 +:1084900067D7EF7FF8B6FDD1FAA1E985D63FA35E95 +:1084A00018F9AFC5D58C7230F21FE882F9C11B7B79 +:1084B0006D810704D07746A77FAF15E9EC482B7094 +:1084C000C139C83FC00794CEEAF4DB315F239694EC +:1084D000DA715EC7E74DE3FA163FC8E17ED64EABD0 +:1084E0007B2C3B4754920CB89852DB36D3E2A4F86D +:1084F0007C647421DC2B3AE5B1B69910FA5EF2C8BF +:108500009842B85F7ECAD6B6772D2EEAD7D58E2D83 +:1085100084FBE55780DD80F60796DB10573DE58943 +:10852000E7F27995BD3FCE5C329FDDCBCCCA2B29DB +:108530008F2D743CAB3C3CFCF7A09F95ADC545101E +:10854000B7A98488371DCFAADC8E902D9B8DE79329 +:10855000E87BDB6C9E5576F0EB2EADC5F1ADF2B04D +:1085600084FA440EB1B8A844FB6AA5DFAD8DA37EA2 +:108570002FE5EFDA248B0BE6AFF4B91FE6B56B936A +:10858000DCAA1AF15C931F7C0774AC35B175FBFD56 +:10859000AF0D4F68BBCC78BFDF4726C33CA4C5678F +:1085A000C1D4589EAF38F17C44BE89C5358CE5BF37 +:1085B000D2EC2C51330017D5871416AFA67FE04FAD +:1085C0005611A617D5849DEBAA3A4CF01C4BF5A189 +:1085D000423CC702FBFC3FD6E1F05F738EA51B5700 +:1085E0008C4F059230598AC0F534BB559717FB9BC9 +:1085F00046407F8818E78273186286A96607EDBF38 +:1086000078054D293F24A74B84FB5AEAA64E11E179 +:10861000BEA93532DF3F6262E7CCB5F69A387FB447 +:10862000F4B4BD6407C8FDEC5BADB936B67E81F32A +:1086300061ADBF6B04371160DE7580E0F9809C147A +:10864000D202FCB311771EE0ED3D7B12E7375B37BA +:10865000A67F1990BACCA697558AF7571F5984FA66 +:10866000E04A30DD9349F36FD997B17C86E9422621 +:1086700085F0DBF67296BFC6746108CDBF6B5FCE26 +:10868000F2B0C04907B623F68A42FF486887E37D07 +:108690009BFB1AC0B76462F117E91505D753B47D87 +:1086A000216BE9440BF0F81ED84D88A7D416FCDAEC +:1086B00006F1EA02B70AFB3D36F37B83BE69AAF1F5 +:1086C00055B49970FE0329F0FF43CE4F4D2EA4C937 +:1086D0007D0DEC8B258DEE6B601DEDB4DDD306F6C4 +:1086E00066EC1BAD53C07E37BDF3A75CBC9FFC0A94 +:1086F00056CFD837E89C90F6E7EC6F066D8A5C8F12 +:108700003E6DCFFF14BEA36240FF54509DE40EAAFD +:10871000876BDC4455B260BEAC9F2F3611669FB6A6 +:10872000D94ACE825CC9C0108E5B45F6924EC86BAA +:10873000F69CB426F5695F9B92BD5A847139292352 +:10874000787411D8FFDFB17B3D04B71BF773BE14FB +:10875000BED78CED0FB1C1FE10D07F1749F3A7F241 +:10876000F8178B2F9394DC887930EF07FD7E1AEC95 +:10877000379F6063FB0768BF44B0AB63888AE958E2 +:1087800088676581283D98DF431A8FDE47EB7FDCE1 +:10879000CAE2499606A28B0F66C7B338CB4C078B4B +:1087A0000FC6C98DB782FF10778E38C17FE8FCA550 +:1087B00022E1FE22C97923AE8F1D3411A0F7593969 +:1087C000E084F599AEAB247533E9AEAF93CB5BABE8 +:1087D000F77145BD0AE272731DCC3F7D369FE07E86 +:1087E000E8AE534A00D64D93322C3591F19F2BF9C8 +:1087F000770F390B32E321FEBC378E40FB13F6C5F1 +:1088000099400EBFDE9663053CBC043CA27C483216 +:108810003BEF86FA922E507A33F139DB272FA9638A +:1088200012287F27DD6057E1BEA967AD8D37E07E56 +:10883000D0174C78BFEE4B8AAB14F22F9D579D603A +:108840007F9FCD6C8CC3FEBC60C2FEBC14D775F597 +:108850004A4AF7C323587C4AB21109ECB2642A5041 +:10886000EFA6CF73E3D93C49B3D3CBE399FE3C2EBB +:10887000103C0F2099F2517FB4FD3A9D5D04F7EB57 +:10888000F49BD52A028EE34AB5B851488478CFE4E8 +:1088900012827EDB64BB8CE772607F309C1B9BC2C4 +:1088A000EDEF940F2A713D814AE030DC7FD962E719 +:1088B000F768F175C5EB394EAE236D22F891D75D9F +:1088C000222E88075D7F498AE9474EE7F53E23104F +:1088D0002981BE977F51950077F944EFE74DAF2F7F +:1088E0003C05E3E0548BE139F889488F1BCFF74F03 +:1088F000771AEE4F8EE7F3D6C16470E43E316D1DFA +:1089000068BA38F209F4538B1417F065BBDDFD3EED +:10891000AC7BFA5B6572B938E2333EB69F6FC4A593 +:10892000385CFFA1F8B4032EAEAEAFF35B69BFAF06 +:108930001ECAEA071C825DB9F29729C960E7CDF12A +:10894000CCDE68A9863BC0973381E1CB39BA5B3F67 +:1089500057C567E27B9ABE01EEA09E3D72607EAC79 +:1089600075658AD75580D7ED7682F3B31FA55BE690 +:10897000829E69EDEC8967F837A6EB6A57EE87753A +:108980001DFF676CBC9836E0921239DE7FE86438D0 +:10899000F3AA75336FA6FDF3DA655CBF49E5E78B93 +:1089A00022F1921E81170D771D7616EFD1F03375E7 +:1089B000F7BB223C9FFA1921CE4C129E8768F8998A +:1089C000E267389C72888D13BDE1C7DDE59C06E641 +:1089D000310A3787186E0A283EF0F7B77AC08F1130 +:1089E000374FF58A9B2FF13CFCAABD532FBB6E1865 +:1089F000F4E9F77D1AD389B6D8FB828F727EEF56E1 +:108A0000EA6ECC067B7193899D7F9348C6AD14E7CF +:108A1000BBE3B47BE56BB220BF5D62F6677BB31945 +:108A2000EDCF76BBC78371D7340B9ECB2692A70DB3 +:108A3000F6F5BB0658D4C8DFD1F82EC761A31C9A3F +:108A40007802FCEFD798FCF36ECA811BEC487A19C8 +:108A500093C3B893CA2611E2428EFCFD80AF4FE06B +:108A60004E2DC0C37105EF25AA3EAEA05DFCCDBE64 +:108A7000B70B21BEA9ED1F9EB0E7EDC28291F03E7B +:108A8000C3D96BDCAE6A793C4A0176D2702FFDC443 +:108A9000F07926FDBDF225809FECEE72E37DEB734D +:108AA000E084171D776E6D734D07B360BC6F7D4E0C +:108AB000889D1F9B7DD43D1D4C65D47DEB1C0FB75D +:108AC00091D65D7162F4FDDF747C3E160FF1FBD729 +:108AD000430AC4C11B959A6BD87CA2260BEC8FA6C7 +:108AE00077F847F9D6F8E108DD7DFFC3F8F8F38899 +:108AF0004B62F738B529B84EF82861DF35F271EBD3 +:108B00002BAEF739AB5E9C0FF6706CB91BD76D5767 +:108B100039457CFE1312B26481BC5C12AE7734CA54 +:108B2000EAD41342F77B442A1961A7E57BFAC58D85 +:108B300085F6EF70784C0EF02BA4AE43F0DD84493F +:108B40003963C16EDBC7AC4D86714CA39BD255B463 +:108B5000D5DE4D87465727C7C91D8E8526C778F6AF +:108B60001DD8A1E0B1760B7CAFE1A071EF3926FFF3 +:108B7000083C80FCBBF1202C80BCC6071B4FB5FC19 +:108B80003F1F0FA181209F1EF1007108C7B7C2438C +:108B900016F055C303F5D7AE02FE68FE5AA3C2F61F +:108BA0001D6A790D0745F67C7CCFA510DC3F44F6A5 +:108BB00059D9396D4F22AE57BCEC646D747ED83EE6 +:108BC00098BA9864B283F9EBDAEF898C0909E8570F +:108BD0008EA106E10EF4E306A23D74717E9176410A +:108BE000807B37716F7906F897A164D08B31E6E20C +:108BF00010E07F876D4A06F88739B6C95980AF5DA6 +:108C00002356BD0E43D6AE01E52F6F51BBFD27CDD8 +:108C1000EEB5F06AB5F66F7430FB74BD9B9D0F0224 +:108C2000BB1D498766FF412C4087109A63FACA86AC +:108C3000F6BAB90DEC39D041F9BA5F204DE01FE426 +:108C40009BDC2953C1CFEB179280CECEBD5F0C8643 +:108C5000386571F3AB4781DE626D3DD4A55F0F359A +:108C6000FAD19ABFA3CD2B347F489BCF82DF04E596 +:108C7000D9FCB9D3CCD6AD26872C786EF9F1F3EABE +:108C8000556EAEBF12ED4731EFC72DA415E9D2EEF8 +:108C90001DB999F3A3F8109D876643392137513EDA +:108CA000DCC4EF1DB9C9A5BF57E196BCD8F78E68E3 +:108CB000F5F4F6BE717CB8D6B06EF46DD3433E7653 +:108CC000CFC87FFAD83C77D210D12FC1809A97CEE7 +:108CD000EE6970323E1C52628F57FBB9FE4E32B5C0 +:108CE00065C3B9E5FD7BFE8EE3E32B7BFEFE1EF83C +:108CF00089134F4904F6B54E3A352E01D7E7F3D222 +:108D0000703D59ABD7FB69938DB0E7881FED77575E +:108D10000E527ADC0AD067C1F4B7671EFF29D477F8 +:108D2000F1B84422CF4D142A9EA110C72DE4BFBF35 +:108D3000735060FE92567E90FFEEC5F31CB7B021D3 +:108D400042BB8FC41C21E79BF83D199A5C6F3A59CE +:108D5000744ACA8E960FFCFD33E20B5A5CA199F35C +:108D60008FB4FC11CFB77CA7E96E09FCF3EFA4899F +:108D7000C41DD1EE0C95CEE023E21C2F3B0C7E4AA5 +:108D8000CB733FBD998E2BDE3744DC4AE86DDEFEA7 +:108D90007A36E45BC598F78F18F9FB9DE6BBF1FEC8 +:108DA0009121092AD2D35BFB93AEA638190D722705 +:108DB000CCCFCB65F77718E5FBCA9EFF486E1BD971 +:108DC00033BF7B92BF510EBF3D5380EB4EBDC9C335 +:108DD00088DB7DB49F7EDABF10EDA79FFA63AFF802 +:108DE0009C98FFBD2F0DF31A5EBD7B9F4E067F4EF4 +:108DF000C3E9F464869B89BB7F9A4CECDDF232F2C6 +:108E0000ED7307F36BE610D7EC9BE93F770AAE787A +:108E1000B4177ED20AFBB34A388D730E17A2FF41F6 +:108E2000F87910E33836471C89E7DE7BFDDD9BA12E +:108E3000F932985BE37805BFC702B8368E53456FA9 +:108E4000D449E0B2154AAB981DE37EBA469751CE9D +:108E5000474809F6A3273A8D3830D2ABF9E7DAEF65 +:108E6000C0507E4C4FA2F5DDAAE663FFA2C661CEDC +:108E7000979EC6DF9EFA959CC0E3DE1CFF174E4E00 +:108E80007B0BD8DB93BE19E5662CD7EC47213490D9 +:108E900083A91FFC912109A9A80F859714E2A6E3D5 +:108EA0000C19A83FFF4E8AAF40BCDDE364CF7AC205 +:108EB0005BF52513F12477E34E0E3E6603DCED9659 +:108EC000EA6C101FBDCE5EBA06546FDAA705B3F088 +:108ED0009E8736138190D9F4E6732D1047F01E2536 +:108EE000783EA0A079FF54C0E9EFA5569C47755E77 +:108EF00024E4B1083F33D8BCC6067E5830859D6F48 +:108F00003B984874FB90F72730BC068F9FBFD91D54 +:108F1000A3FC122F9F49DC29D9382EC763FCA3700C +:108F2000BD09FB3F4D701D4801BF659E80F385CE96 +:108F3000BD130EA4507A3BEE4C443B333DF8E0DDCC +:108F40004E2A88C6FF1E8BCFBB160A78CF40A1EAF7 +:108F5000C27C615926EEDF98F08FE499C5503E43FC +:108F6000C6F9CD74B1528278D4D9342107E68B7B0F +:108F700084B65AF81D5C7F296B8738FDC930FF7CA9 +:108F8000A738790CFE769CAAE587E1EF0312C33C73 +:108F90006DD5CE0BFBCDB47CD56C01F7EF4E77666B +:108FA000107F047E0AD753798EA5B86CEE5F00B8A7 +:108FB0009E59A43F3738BBC4460291EB168213EF8B +:108FC000213BC8F7697709FC5E7CAEE73770BCCF00 +:108FD000999BACFBAE94303FD3BB5364F771E4B3C1 +:108FE000DFA1D6F4EB46AE8737F0F9F13C4F868E21 +:108FF0008E6288D288403F5B47BEE5621B0ECFA5DC +:10900000E20787E7D3F66E1C6198D78A956B111734 +:10901000696C1D6F36EC8213C16EEADFBB254F9F72 +:109020008FA1C797B5139A3D98BD57C475C3D9F999 +:1090300094CF0289F2D3BFAEBD9860721D8078D004 +:10904000AD97DC788F4E94BDF8A0E81BD98BDF502C +:109050001DCCA37AFD64021F370791416037A68BB0 +:10906000DB7E0A38EAA4E3A639068EB471479BEF8B +:1090700017523D06DC90336C9D65FAA534DCEFA4F5 +:10908000CDF7C37684FA25AE18FED26F12B274F70C +:109090007A84ED4A845F22E77E7BBF643AF5479588 +:1090A0001CA06F20F18F457B8671C942D81805F14D +:1090B000C1B47318E7F14A74FE8AE3F3D3882FB082 +:1090C0007F4252B77E18FD152DCE3CD6A9F9537AB2 +:1090D0009C84E38DB3D87DA51A4E0A819FA0FFB36F +:1090E000448CEBF4861BADFDDEF012A2F6084C5664 +:1090F0008F78E1FAF775F1F2176D7C194A86F6055B +:10910000271A3E34BC18C79BFF34C4837A1A6FBA3F +:109110007A196F0E8C90D1AEF7E6D77CEAE4F3EAC9 +:109120000427A6375C351B7F97682CD811F037F9D8 +:10913000B8158E6BD5339C1C685B24C1FA9117EC73 +:109140004766B71CB478F0FF00C6C481D500800024 +:10915000000000001F8B08000000000000FFBD7C25 +:109160000B7C54D5B9EFB767EF7924334966924940 +:10917000323C841D082121090E21BC1137490811F8 +:10918000A20CA8888FD6011F6020094DADD5536F62 +:10919000332181526C3D58BDD67BF4F43758ED41F4 +:1091A0000D75080183277026A098F0D020F8C07AAA +:1091B000DA6829451B92185A0F6ACFF57CDFB7F69B +:1091C0004E662683A5F7DE73879F2ED65E6BAFF5BE +:1091D000ADEFF95FDF5A9B4AC09F0A50B315209844 +:1091E0000650F9E1864A4806E83B20011403D4966C +:1091F000C9411BFEB5B4FDB1C745DD0C5689DF5131 +:109200006126C0F5207E0B950EC5E60658E695BC96 +:10921000721680D62EDEBFE19225A862FD7AAFF9E4 +:10922000E31E9BE8FB35FF5F03C800B8517F7F1941 +:10923000FD0FFB2FD3A460185F5D363BBAFF8D97FF +:10924000CA3F91A6022CD7629EC34F3E93A7F2223B +:10925000CCBE24AC5744B78F7326B9CFD9F12FE3D6 +:1092600061FCD732C0C5F3656F51F7AFE977EDC840 +:10927000F2483D526601E8ACB77119DB5E6E017FC2 +:10928000C881254D50C4650052010A9DB8981958EF +:10929000BF64010DF9086313E0F7B93A1D1386DFC7 +:1092A0003F88E30770DC308E1FC8013854EFE4FAC2 +:1092B0006BF51EAE5F93822FA4E37F87BFB0A8B883 +:1092C0009EC5EDDF51FC38DFE24B0A8F3B9BD69306 +:1092D0004F0B8371B49E3FF716FDE30D30DCBFB634 +:1092E000FD338BBFF0F2EBF95BF3E7A7A83C3FCD72 +:1092F000AB150CCFBB44011883EB5C9A1BCD5F63AD +:109300009E58F9C6CA6FB9FE7EACFC56C4ACC79075 +:109310000FF4A2328D8AC3FF4B26D0A65F5E7E4338 +:10932000F2B1F8B3BD0523DB017EC9721A1E4F9757 +:1093300017742BBE42419719F5BA52B70BD4EF40C0 +:109340000ACAB9B213C28948D8F5E72B3E51A8F42E +:109350004AF071943E037C6CC85B1E1E7FD125E4ED +:109360006BDAF0BC8B146477113D1F0B8138EBA8CE +:10937000A17114EA1F60396CD9615A15C2755C631A +:10938000813B7D54268A32E094B87D93D3C4E3F6C2 +:10939000FFC56682AB015E3E985902489FD7EA3C02 +:1093A0000613014266E0F7BF4E52B9DFE6240824F7 +:1093B000E0FCA074DBC85E9412805CB43B65B4250D +:1093C000D88843362B611FD961BF578106B4DB2F84 +:1093D0008DF70E056E0714C9E68F734C8D59F47E18 +:1093E000B87B1EF69B55A4A8DBB08BCBAA7E87DA90 +:1093F000FB0E589DF45EFFFEEF7798699CBF8017C7 +:109400002984D70E5881DAE73BCC41F21F8BE4E385 +:10941000B209EBFD030056EC3F7F55B814506ED7F0 +:109420004077A313CBB924C738F27B8DD69BCEFEF1 +:10943000C3310AE5B44097D302DD6F951E90D98FF2 +:109440009426C941C81AF653D7EA325A806C253A95 +:1094500016B4E17AB1FDDA4B4A5CBFB4481F77E13C +:109460009F4121935C08D17ABBA84DF8A312D01478 +:10947000C0294B6D31EDE497909E45CEE8E773C966 +:1094800077A25EEF8EF14BF833D1BCF73BC5BC8BB6 +:10949000E4BF26F7E0FA5FB668EFCD437A074E9A4D +:1094A000E1597C0EE7B13267245FDAD0AE83399799 +:1094B000B78BFD07133515E97999F4C741F5D19AB2 +:1094C0003AF5F2FDA7F60C94607778B97985021326 +:1094D000581D4F7B3286F93D82AF3AFF63F9D9229E +:1094E00041931DF9BCB0DD5B46AE65041F3B918F17 +:1094F000F85EC980C6F35C291F0DFB78F95CA246B3 +:10950000FAFEF2B9D11ACDFF2AE96BFAB0FEEF3FAD +:109510003B9848FE13F9A82AA817032E9BF759D6A3 +:109520005FA1F7A15139C16D586FD1F5FCE5C48138 +:10953000A3F9C4EFEB4DDE67691A65E3C41585E452 +:1095400037B7969CC577240DA407D17E24D509771B +:10955000601940FB217D0BA402EB93194240F336C6 +:109560006AF034950BE6AB29C4EF411CB3DB41E351 +:10957000A929A4E7F0D78B337D8523F9DE528F0A22 +:1095800085F3B4D6DB34251B605FBD93EB6DF51E10 +:109590002E5FAD57B9DC742CF9C1208E53AB593412 +:1095A000256DF87D57AAB08F05E86788AE052005C0 +:1095B00003A8730B1ED6F55E91829B249213AE27EF +:1095C000829F2897C19EDC08FE36294D9366B235EE +:1095D000B0BC8BF24DFC3E06FFE0F35923FBA3DC4D +:1095E000A3EAAA4B627EE6BAB42417963F74F852F7 +:1095F000A86C916E397C01B8EE12F55BE50B38FE74 +:10960000F4F0427810E3C374140CF1157FB713FD26 +:10961000333A2C40F2C180CA7659A4D3A37D2E4997 +:10962000E7703E329DAFC7E07BD6CA30E9D13EE855 +:109630004923BE17DB7C76B428A443C855936EF645 +:109640004838DE9C748B5726D226FAA66F44FE75E6 +:10965000A4E384D8BFA32363AC8AF6A6296FBC4FCA +:1096600076ADD91C61812BCCBD3D11713C139E712F +:1096700052BC229FF635F2BDF377C901F66B8873B1 +:10968000C88F759E4AF686719E6B2ED9BC56D27FC6 +:109690007A11EDF56062F254F2CFD05DC6EBB8D628 +:1096A00026D6916FF617BBD89F850F9FC0F7FE6D2A +:1096B0001080FCE935DD1FCA80F4949AF2327B9069 +:1096C000CEC3D2E4142A9FFC5D720197A7927B89D6 +:1096D0003F074D7695E67DA75E2DCE467DD1DE72A5 +:1096E00098001DD682B71C0A9527EAA1381BF5E51C +:1096F000AD7A1B9727EB9D5C9EAAF7707918DB4922 +:109700009F5EC776D2B737B09DEA5DD84EE5311C73 +:1097100097CAA2DB9378BC96DB922CB48E83C9D017 +:109720006CCC4FFA144E0CB78217E03F1EFB6AABAD +:10973000ED2A8C97567FA1340DF9F4B3AF2A14ACFF +:109740001F5B3CEEA1BF60BBF967A61FDB90DE9BF1 +:109750004E395A8F63DD9EAAFCD841FA792C119DAF +:109760002399B5B94B433AA6936F1CCD6CD760369D +:10977000D6D3F47AC07C5DD97C8095A53DF9E042D2 +:10978000257159AFB3217F57DAFDDFA3BA25B0ABFE +:10979000A2EC2AAA6388247B97CC41B6F7B1927BCE +:1097A00005C6BB950EFF7F12BF0D7BD1A43FA491D0 +:1097B0007F98A949E072B3BC8393A4E1E746BF95C3 +:1097C0008E45FF49FABADE25B37DCD982F6941C792 +:1097D00048FB35FACD38AB9691FC669E2F6FA2728E +:1097E00059858BEBBE55B39AC8FECB1C977BBF94B3 +:1097F000DF7FD06566BD2D51B05F9C3868F49B8ECD +:109800004A46B87BA02B31F82CE9F5697F6312D664 +:109810001779B28A64DD3703D75D3BB6517BE5EB40 +:10982000AD6C57DE242FE1F299A89069D8BED02103 +:1098300079C3642AF33F6A4AA376A7E425B62DD4F8 +:10984000A69D28A6F66CD9BB90EAA7D5320A51A7E7 +:109850009485F32E60BFC5B9295E1BBE772AFCD064 +:1098600045D2DF85B949DE04F2F34AF0E91AAA7B52 +:10987000ADDE0695D6F15869328DA34A5E13D65BEC +:109880006E28FD1F4447892F052489DA5D0AE1D738 +:10989000277FF7C33227F66B192701D9CFA970DECE +:1098A0009F88FE859D896A02F9698BB38CDE6BB156 +:1098B00048CE4D5CF79552FF408E597D1EC73D7EC8 +:1098C0009B9DE341E55B058C838EDF3686E342E5B5 +:1098D0005BF34BA83C6E1278BDF2ADCA0A6E3741FD +:1098E000989C4AE5EDDFE2F7B697FEB0CC8DE31F1A +:1098F0001BEF62DF82722A5622FC24F60789DEBF44 +:10990000BD9AFB7748990F9DC5FE170B528AAC385C +:109910007FB93B21AA7FC55857547D49F6A86225D7 +:10992000C24F56166445D56F28968AB323FAFBE6D4 +:109930002744D55794B98AB323FADF54392AAABEEB +:10994000F2A6ACA8FA42D31CE13FEA617E99B0F3DB +:10995000F965D9208C89FCA953F47D03DBEF263B04 +:10996000EF12F8A9C885F809E552D655CC71B9D8D7 +:10997000AEFBAF00747B6692FF17BF2E1C8FDE8399 +:1099800020FE99497848FC1676231E207CA460DCD2 +:109990008EA0A7CC111DC72B40CD27FF5BD1B9846A +:1099A000F154B96779199A31F231FABD0AF9618136 +:1099B0004362E82EEA32C7A5B7626CF4FB06AEAB91 +:1099C000D0E96B31F99B52098B05B46EC235C67A6A +:1099D0000C3A2EB79E0AF98E3214FFDF5C572CFD2D +:1099E000001B797F114BD7A04BC78188A71807763A +:1099F000A6323EC49F3B1E3E30704F25FA3757A417 +:109A00007F7348EEE58597F76FC6B897C37BC6B8F6 +:109A1000C6FBD02CF3FCC6FB43CF5529FEF39DD8E3 +:109A20003F29CE73B714FFF973D1FD17286AA3033A +:109A3000EDF82848DE00F1FBB8AA10242B3DAD3527 +:109A400051B9E843BF427874F1D9401395F37A8352 +:109A5000C7ADB8FEEB726595F20D061E8A5DD78C18 +:109A600054B14F3A7A49B5ABD8DE1250EDB4BF6865 +:109A70007958B5D33EAA45830ADA2F6A134D1B697C +:109A8000BFA1E56389F59C54E1E7F352058E31CA25 +:109A900067657F5E2A96D5B69E47098BD47C316078 +:109AA00021307094705EC1489C7754093A68BEA317 +:109AB0000F071DBE083F7EA5386F14295B3AE9A742 +:109AC000A445FA91525B8216E93716395D51F5AF1C +:109AD0009CAAD8C77B4645BD779D9A15D50FF16BDB +:109AE0002EE1A0460BE42AE4474D895EC277B17CA3 +:109AF000FC177DFD5E8793E01398DDAAEC8F13972A +:109B0000BCA5827FB1CF57A48A7DEA6F683D586EAD +:109B10004F15F435C93E01E21037933EC4D6714F5C +:109B2000BA8AC6C3913DA4775EBBE922426FF84E64 +:109B3000EAD5D729A8CFDEE9A6EF4EC4FA23A98B30 +:109B4000447D9E69CF04ACFF34B55CD4AF364D374D +:109B50007B017E058BAF2BC37ABADBE74FC579FB60 +:109B6000CD8EAD12E219C52441917B78FFFB8805AB +:109B7000E3290A16954C7321AD76ABD82FD724A0D4 +:109B8000FFA3FE259A4AFCAA4930E4DC9341711DEB +:109B9000EECE3491BF30F66F760BBE87EFE7D8FC80 +:109BA000B5425FC2C92AFAA5FBF72FCA24BDD89EC9 +:109BB000EAE4F5E7EF99E7217F85747D97FAFD7F69 +:109BC000A46B533CBA9ACC629EDE96FC528ABBF9D7 +:109BD000E3511CD2B0BC70BBCFCF1342A82B8CCBAF +:109BE000358F84F54697C54B387DFB907CAFAC6CC8 +:109BF000D4F313B25DE88D9C62DAB81BCB9FEBFA0D +:109C0000F214CD3B83E61918B71CF5019C03E3560B +:109C1000148A3AE9832C170D10DE1EF8569297F736 +:109C2000C763077EFB03ACBF7747BE9770F4078915 +:109C3000823FAB82131A7BB03ECD1ABC2A8C743E95 +:109C400094E67F96F4E0366B7012EB9B6363128DA3 +:109C50002F69C0FB10637F87FB38D5327124EE1F5C +:109C6000392FD888CFB7CC117C36E6459EDA28EE5E +:109C7000BC375B3C37E8C0F95B88FF063D4374C0E6 +:109C80005827C7031079A445B243E461FF60E2BCE2 +:109C9000492D191FD6F79C35F1BEAECFD85780E6B7 +:109CA000583D939B789E392736C94C6C00FFCCD425 +:109CB0005948AFB6ADE77DFA8CEEE87DFAAC4E7F41 +:109CC000A903DF9BF57EFC7CC83C7DDCD910942980 +:109CD0005ECFE989EE374FDFA7CF3B1FFDFCCD54A8 +:109CE0003DBE8D86D191798E3A7DFF33787C420AD4 +:109CF000E929F93A19F96E5165989D3AEC375AEB12 +:109D0000B15F0EF9471B9785A79D7711FD6DF5A8EB +:109D1000D016F2931E2E0D7B2A3C0D77C2D4887983 +:109D200074BD37F838F8BEE0E3B49EDC9FCFC7BA05 +:109D3000B9D30C4175789D73753E0D82E0F3A0D3C5 +:109D4000C27C9ED9F5CBE9617C64F598408D585F63 +:109D5000829A086A843FB5E7A646D565433E3ACE67 +:109D600098AE8F9FE41D1D358E81370CF9BD9A5A30 +:109D7000DE493864BA631DE38E94D913A2C62D3E22 +:109D80001E2B27641CE17624F29F08D79F56A270F1 +:109D9000C62C77803800B33F546270C97699EC685E +:109DA000EED9E8E7E6B4CBC8ED72FC84A93F9FEF9B +:109DB000FEFBF9E9D2A2F9995611CDCF745F343F79 +:109DC000335745F36D943F9A2F63D64D896ABF6A26 +:109DD0006351547DFC8373A3FA6761008CAC4FDC44 +:109DE000BA24AAFFA4ED2BA2EA939FBA2DAA7F5E04 +:109DF000704D547BFECEAA2B927F61A82EAA1FB174 +:109E0000D7F40DF2BFBAED1FA2E6F9EF96FFA23428 +:109E10003D2FAFCB7F998E435C1AFAC7A2E138453C +:109E2000E915F293AEF637BEA0FC4BA044E5BC5357 +:109E30006009781BB1ED09D927915F1B83AC36A16E +:109E4000DF6832C13AF2F78F9A4C9C8734ECBC2A17 +:109E50004DE08BAA34E1F79F469BA6F866F0CFEC65 +:109E6000DE9E4478433699A09BE29AE265BF71C6B4 +:109E700001E16B713E7934705EAB3479F6B299A82A +:109E800087F29B32EF1FE5D17E50717D8DC71F3F5A +:109E900041F99F8B0E9B4AFA2AA7FA0314B7707DEB +:109EA000A1E761245E79AF3E3C89F649467D95671E +:109EB000E366EABFEA8E859368FF3AF4FC8E8E492A +:109EC000651172885CDF8A38F8E87B69223F67C4D5 +:109ED00087DBAC6A630FCA6B9A2CFC3FC685EFA583 +:109EE000E1FA3F901E360B9C1530D3BA314E72DE2C +:109EF000DF8580BA0ECB94E178A47E8D4AF5C184CB +:109F000068DCF9261144FB085B2AC7FF5B0D7FBBA9 +:109F10002E8FF936E888EE3F78F744C1CF6F23D70C +:109F200090DF672C621D06DDE7753FFCA9EE877B9D +:109F3000C9FF46E49BD7ED783C89F0F5995C81A791 +:109F40008DE7CFE8727D264DE0E9F53B139C9179D2 +:109F5000C7EA902BAA5EDB36CA7936420FD71BEBD5 +:109F6000F04B0AAD63836E3FD59D3DC9B701E3F168 +:109F7000A7D370DC9A1D17BFBD8FDE370D648838FC +:109F80001AE0F96E790F18D7DFF21544E1D297D2B3 +:109F9000447EE525A20BCB95583851DF56626C778D +:109FA00051F9C6FC72B23B7C1E96B0BEAC13CC8499 +:109FB000D396FBB3CCC4F453E07D672F2E6D5F9A2C +:109FC000CAF3DC043E33C5C577BF5D9D44FD86C63C +:109FD00033C61943B959D42B57C09C41F99A6B2405 +:109FE000C60D389F8D9EFBEE18B399E2AF31DFBBF3 +:109FF000E0BFF00EEAC50AF0F2B8C6F800A9517E3B +:10A00000F803CB901CED24BFBA2E5398F239756734 +:10A01000AC7CFED1DF30F0EB0790CEDF557DB15741 +:10A0200042BA7FBB7AE057FBF0F9AD4FA1DFC5B56F +:10A0300066DBFD87D322CEC3CEDC7D91ED0CF1C86B +:10A04000F34F92337AC9EA25FBF8A0EAA59C48BCF5 +:10A050007F226D6127BD07B3D3E29E47C4EE2BABD1 +:10A06000483FD96E55C699865EDEA7EB65DD0B933A +:10A07000F9795DD2D07A44FD7999F3577507ACBC74 +:10A08000BF7F47D787AA17BF9819999F6B41BD54C7 +:10A0900073A8747249E79C2AF266CFF1C1A9D46F04 +:10A0A000A3ECEF213D3978E9E364AAEF79F34B5E45 +:10A0B0000FDC7465F4F723F322F95C9B34F02EF97E +:10A0C00093EA7D5695F250A5FBF28EDD8EF59A4E01 +:10A0D000F43BB89E0BAE9E234FD37E6ABF04949789 +:10A0E000AA0927B073AF69958294C7AA6ADBBD65D8 +:10A0F0000CD6AB9A971793BAD6260B3F56D32205A8 +:10A10000693CF0A7317F8A74DB287D35EF1F0BB0E7 +:10A11000BDEFA818FF5C7D78EA59F44F7D2D9F9D17 +:10A12000233A36B459393F762E296C1983F35ED819 +:10A130002D8502EAB0DDF6B9C43E6A5DE8310BCD8B +:10A14000BBEEB9E5D9040FFBF69DB4907F5CD7FA5E +:10A1500058B9FEBC5884FB20DBC5FA9D1D9322F341 +:10A1600049F721FC83C8F881F40508F78290E309D8 +:10A170005D3EABDA273612BBD0AFED7D5A62BFE64B +:10A180007493DF3BB8EBDFFF95E6DDFF2F9398FF7D +:10A19000C557C67FF005184FD4E8F3C0F95316DA57 +:10A1A0001FD6B49ACFC53B17FABEDB77957BC6F0B6 +:10A1B000FE3616576FB18038B79900C1E7291E38AF +:10A1C000062CAB919E1F5107A447710E58D660DD37 +:10A1D00046764671C2E308C6DB17D7B9159E0FF75E +:10A1E000081BE39D57D6EAEDA56A8F85F270359E70 +:10A1F0005E0BE9754DF813715EDFF651B91667BF56 +:10A200005CED167ED3D003C3DEEBD2A7B05D98879A +:10A21000E260C8C6765FB86680E253DD7ED40EDAAF +:10A2200017B8FC034477606F824AEB2BDDF7C9CC8B +:10A230009E8879FEA4DB8751AF79F9A3A966E2E78E +:10A240009E8FA62A49C3CFFB321CEBE2E555AADD5F +:10A25000224E6F4EF69D8FB683046F18E7AD69B737 +:10A26000F3F907DAC1968EE2483BB875DD0ED2F3FA +:10A2700076D98B1601356DCBFD0DDC3FC94BE291D4 +:10A28000DB1606480F65A78FF513FE8AF3CDD4CFF2 +:10A290007D2652AEDB7F1BE991E2084F8ACC6BD45E +:10A2A000987A7ED121915CB76B269AAF08D86FC996 +:10A2B0000E5F0FEF9F8A3354DAC71E9E510EC4A75C +:10A2C0009F1E90385F6B4EF56FCD22F91E95B9BF7A +:10A2D000E5F00B013A97EE9B06C5449FB1DE9F4E19 +:10A2E0000B838CE36C2E042F4DBB79FF2D1ED2DF28 +:10A2F0009FA61F617C61F78680FC4A23E206CAE7BD +:10A30000D80B42611A2721D7572CE33C796E27F3EB +:10A31000CB62F57B291F944D755C874DF1AD23FA17 +:10A320006CEE44B19F1E7B6579BA3EB27F85CE1B31 +:10A33000FD9C2FE9330B3DEDBB0A185FF31D9D39E2 +:10A34000D4A409BEC1762E6BDB3AA646C6DB44F028 +:10A35000DBE879DFFE5BBC44BF3951D7F78C44B6EC +:10A360008BD8F9FF99F499E46E5AB3358BF84C7C8D +:10A370005347F67B5AEF67F003147F2ED92B92AA2E +:10A38000C5CB0F8D77973C4E72DD9CEACB7515F0EF +:10A39000F1AC00C39EC4B87687FDFF5764FF1FE988 +:10A3A000FCDCA2F86DC4DF4D7ADD6CF1A94EB67FFE +:10A3B0009F4AF30FAD6F74FCF5B5E9F6BA6582FFFD +:10A3C0001BD7B74F5F9F3915F58DC64B06EE674E0D +:10A3D0000E0648FF9A92A078133E3EEC2AF790DDD5 +:10A3E0006D39F4C538B2F7A624AF0728AF7560D62B +:10A3F0002AB2FB2DA36F63FDFFF485BC2239629E58 +:10A40000136925ADE4BF7E69ACCBE2CFA575FC42F4 +:10A41000D723635DE96EDFABEE88BC118C755F916D +:10A42000FE80BE9FF3EAF117F7739CFFEB87442F82 +:10A430009D27EED671B7023ED61B3B7855C6551AFE +:10A440001CA37B1F8D1D26D846CBA6E454C4395DC2 +:10A45000B26C32367D9A0DB7E6746C4CED6FBAEB88 +:10A46000963421BDFB21200B7C169DAF004DD2A45C +:10A47000C83CC56B55F1F314CFF81BC92EFF569E8F +:10A48000624ED8B4DA92F2F7E72BCEBAA3F73D9F2B +:10A49000BA55262A942BF431144E0C8ABC174CA7BB +:10A4A0007D5333F112FF7B06D7CAF62DF5E5DA5C52 +:10A4B000684FEEFBB76D1D8B76972DD64FF546FA9C +:10A4C0007BA7C03D43F98FD7A630EE463F27F3FE6A +:10A4D000DFA9D31223B762C46BC0F78852A3F22757 +:10A4E000E1235F26937EED4A55DF22B90C74C97CC7 +:10A4F0004F2441E9B1B8E2D8D93EC203E8F78BD383 +:10A50000C53EC4D626CE176DAAC67E31C1E99C26AB +:10A5100047D8C579B7C89F571FF9609C0531DC053E +:10A52000D3F1E4021C7FC3DE96644AC3AD3FF3F669 +:10A530004CBA9253A2F81DE9B8FE4FA51D3936C298 +:10A54000A95B8353893FA1F08414F293850A049494 +:10A55000A238F1F1A922DE14D73CC587FF50D83EBE +:10A560007D2DE1E5DAB0582FCD61C6A6BC36E07A84 +:10A570005F5B632A8D57FB6F074693BF7A295DE0C7 +:10A580009A172F4D11EF2BA050FFAC7497AEE741F7 +:10A5900013E50B5FD2F38C7D974CDCCF98BFB06D89 +:10A5A000A1EC443D28086F3FC479CD76AB4AF24D0B +:10A5B000780E043FDA131877D61E5C0C14E7FA5DA8 +:10A5C000E095B07D57E2C06F491F060E58553A77A7 +:10A5D0004D706E87541C7F977E4F2B0F15B2C5317F +:10A5E000FCDC982FA1FDE7941324BDE0F3DF0465A4 +:10A5F0003B5CE388E47712D35DA2EBD5AEC4B089AF +:10A60000CE450626E15E87E91AA613785E83CE3C26 +:10A61000F6FBBB2C03E77EE066BA9CA4077920E832 +:10A6200084F6C92AF9D104A7C6EB4870AADE8034A3 +:10A6300092AEDAA908FCD06E1E25E73577D8AE6B4E +:10A640001387EB36B4855D13403F8FFFD5363A8FC5 +:10A650001FAA9383993DFCFE2DE92F6C6B1ACBF951 +:10A66000BD808CA2B66399944AEB54797DE845B5D8 +:10A67000F422C107BAAF67B789F6A1FEA8E70EAA10 +:10A680003B443FAFD5695F92C5F64287D74378F028 +:10A690007E297CEE5AB4D7DEC77C2905B8AE5ED3DE +:10A6A000A1079AB1DF9F568772E83EE97356FF1AF9 +:10A6B000D2CF573E5CF34821F9DB5D666F25F99DEB +:10A6C0009EC0CF1887BF6856B745D81D8C1DC8E0FF +:10A6D000FB8031F3D49ED9F433C2D7FDFB2595CE50 +:10A6E000BDFBCD03E388EE9AF63F5AE8BE64EDFE6B +:10A6F0008F184F4B19FE1A9A6F765B03DF6B9B0323 +:10A70000DBF95E1BFA43BE9F18F2087F32783AE706 +:10A71000D98608393C912EEC0D06FCE3295EB5EB99 +:10A72000F67A90F6DD58EEEDB875228DBF57CF075B +:10A7300018EF35C0A131C4F74DF01A97C6F3FEA04B +:10A7400052417A96FFAEED4E2DA2FFA3E902BF3D26 +:10A750009A2E70667686BF89E85DDFF1B12599D6BD +:10A760007936348EF6B921454D71C6F12343F61B77 +:10A77000634FB5CA8085FAD79E07F62B28EFA6143B +:10A7800094DF4BEFB64D598DCFF7A24C5228AEE275 +:10A79000FE94E2EF5EB36F0CF56F78E7F3A9E4C7C0 +:10A7A0001E484FE7F57F7E60FD78E21BEA7F492275 +:10A7B000D9D96E60BF66D86901D929BE5F40FA5FFA +:10A7C0004CF53CF6CBBB2CDD4BD82EF79A80EC1227 +:10A7D000F59FED01F5DF49F8AEC089F6C0EF4F6691 +:10A7E0003BDFD56DD21827A35F9FC4F5921BA9BE8E +:10A7F000ABBBCCC9764EF7058AC85EC387789C1080 +:10A80000C024129D04BEA8FC883B99E936FCE5E70C +:10A810006ED0E3869AE2C575D86539CA3E22E2A4B5 +:10A82000A81B71F4C933DB9E407B81EED428DC0F7A +:10A83000EF0BBFFF5D3D56D5BD3E775933AEB3EE4E +:10A8400084CCED07F57D5E58D793437A7E86E28609 +:10A850003A5DDCEFA5E733B04EF75D676A1B4B0945 +:10A8600063CDAED87E98CAB9BE502941C8F9ABBAFB +:10A870000F9B8599E793FEB51EBA2E9FEECDF59FEF +:10A88000B1420292D8FAE5C06F5FC4B53D7010F9CD +:10A890001F274EE17258FF106F8D01CFC8F67EC999 +:10A8A000F023BD4B481FFB5AE5E13A1252838A4D13 +:10A8B000F577D23FDD16C0BA3F437B9F54E2C7997C +:10A8C000FEF7493FFB4F7E994166B9F7B4D8C7B749 +:10A8D0005AB47CD29FD609B8B58DA3A7AFA58B3C3F +:10A8E0004FB115E29E4B7EA5C7C19C003C22F1FEF4 +:10A8F0005C760651EE175A65CD82F8E73C0456CED9 +:10A90000237FA3E76FEF01FDA7E11F94CFBD7AF589 +:10A910001EC22B18B7EE7D62C4B9BF89F4696DBB46 +:10A9200004FF846B5FF74CFC7B09465EEBBEB61DF3 +:10A9300047C6A03CAB9E8BEEB761E89E7B88F7BD17 +:10A940001B9AA3EF1B7C95AEE396893091700BEABE +:10A9500013FB07B3029D56D4DF5732FD9F105E7E76 +:10A96000C924F8847E95EDF213B71E674A843F1A16 +:10A97000B8007C8F286F67E830DDD799DB9CE5A5B0 +:10A9800039E62AA27D6E5B16C719508232DD3798F0 +:10A99000ADF9CB195F07B4D3742F649DEE27C1893D +:10A9A0007F28BFA3AF6B9D8EE7EE0B46D33D07829A +:10A9B0008D34CFDA9DE2FED1FA9DF1BF13A8D5C741 +:10A9C000D9F0D4C923940EAC0E45F7ABD5F953DBBF +:10A9D00016FDBC057812189F117DCFFC4AEF43FC91 +:10A9E000C92CF0C5DBFA3846FBB519C27FD62079F1 +:10A9F00024DF0D4139487AB34E0A240B7C0B8ED5E7 +:10AA000048F75D86BEE8F765EFD6F97397AE2FBCC1 +:10AA10002E7CBFFA192948E78077FF249AFE7B42F3 +:10AA2000ABCB491F62F56A5DB399F16D156CB4103B +:10AA3000BE8DD5ABAA217DD96EA13816AB4F357E20 +:10AA4000E932740B5CFE7F4BF77A7398F34CEBFFA3 +:10AA5000A7E4A53CD4BDADDFB1505E74A47D08F978 +:10AA600056197AA2AFEBEF5DCFED867CA7C01496A6 +:10AA70006F45DA15EE83A2F1F46ECB509E92F37C13 +:10AA8000839D13383F6EE851EC38E53A2E5FFC1495 +:10AA90007079A1ADD44EF8A2FFB8C92BA99C7F4C08 +:10AAA0002E443E4C3F2003E18DFEF6898F0790FE39 +:10AAB000A213C53752BE7CFA098C3FD8BEA7B3F8A3 +:10AAC00057E45F11E1A4917D2FECCA4EFBBD83C713 +:10AAD000E1F8DD7FBCE8F14AF2C3C7CB8A695C09C3 +:10AAE000DBE97E78911E871A8E17D97B22E2D1FD91 +:10AAF0001922DFBEC5F3FB47695FB078B7D94BF9C0 +:10AB00008EC566FFA604A4AFE805C9DB80B31DE9C6 +:10AB10003EF4248D8BF6A452BE66F1EEEF1DA2F634 +:10AB2000DA5D12D3DFDFBE287F17C5C7A0ECA5B85A +:10AB3000D7DF7E57C1BD84730EDC537057C47C478A +:10AB400052855F597C9599E371EF68FB2F2B29CFD4 +:10AB5000A9ED60FFD0FBEA1E0B7F57B04B020FAE92 +:10AB6000F388E7F0AF890FBDFB4E5A08E497B69E15 +:10AB7000B4F4C4F1CF467901B77161CEBF6EB7F0BE +:10AB80003DCABD7FB0D07A6B9EFB88F369556D12CC +:10AB9000FBA7AA67E4A04A799E03AF58483F6B9A87 +:10ABA00025C8CC8A6C37733BF951AAFFB159F865B7 +:10ABB00043EFD7E87A6EE8BD61076B74FF75D7D6AF +:10ABC000683DBF17B42DA3F1FD7B9A57F33DA07BE1 +:10ABD000B6C7F75F861F5C4BFB528C2B6B9F8AEED0 +:10ABE00077DF907E07D8BFC7FAC95732F4F3D83C55 +:10ABF000C823FD1E0CAF19AFA03D7D7EB26A3CC4D8 +:10AC0000C93B1ED7F180118F07C3268E67B1FDFAAD +:10AC1000DA2E5A288ED676FE99F16B79FB672C874F +:10AC2000CAF60EBEAF7A3DF837101FAF6FB73B09BB +:10AC30004757F608BB5FD26E0D06256A0F35917C2B +:10AC4000FB0F8AEF3B02AF4A8CA340F77F6B757E08 +:10AC5000AED5F9B716F76763E8DE8ABEFFBE2F7779 +:10AC6000C711BAE251A33FDFD0753899F8B8048410 +:10AC70007F5A1212FEC99087115F46C6D1816F9329 +:10AC80003CD7B75BF9BEF852DD3F2D6D16DF93C59B +:10AC9000FA8BFE517691FFDD2BE88D8DA735ADD176 +:10ACA000FDBB32D2D9DF0FEA78F813C3DFE8F2A890 +:10ACB0001C003BE5E797A8B237C86F752B347FE7D8 +:10ACC0005489CF633BD58929F1EE4B19E59B3ACEE8 +:10ACD00037EACB284F86FD43CEED8EC87DFC8D999B +:10ACE00002AF54CD910324CF887DCFB2A2ACB8FB84 +:10ACF0001EC844BADF187BD74FA645EE7BB41D397A +:10AD0000A4673FF23C5E49F78C6A9B857FE89B8D88 +:10AD1000E3A6108E07C6C5B5CDD620ED4F6A514FBC +:10AD2000F87B30D20FB2BF766911E907EE1B1C9990 +:10AD300048CF723AAAC4F52F6FC3388EC32F2FFBAA +:10AD40008CF5AA2B5BAC1BF996196F1F61EC1F6A7F +:10AD50002E099C6A3CAF517A781F51D32EEE49B729 +:10AD60001EFA625C16D2DB7FE03FC6ADC67241A61A +:10AD700088BFAD25A18FE9BECFE7BB6C71F1E8902C +:10AD8000BF979AD80E6ACC3D198C57F6232E9C8516 +:10AD90007EF3ED4F79DFD17A28E14ECAC7F5ADF1E8 +:10ADA0008F777E839C1A6013E3DA4DD0C425E19E31 +:10ADB000481CB8D629EE0FDDABC749AA3F8C7A7D77 +:10ADC0002FF65D5014CFEE035BE64923EDDDF01B5B +:10ADD000D5BABEAF2FD8B1858EE063F151B56E47BD +:10ADE00088FC392EC6E2A21B33A3F5B4E1ED44C6BC +:10ADF000B9FD5DB29372C4C8D75F8C26DC87F87E3C +:10AE0000429C3CEBA7BA5EF6EAE7BE0DB365E69B53 +:10AE1000698E280D1C85FC637DE93FE908521CCB37 +:10AE20003FF8CA0492FFFA9DD1E745243F3FDFDF98 +:10AE30000AB2FCAA43763E4332DA5F3AF8CA14D229 +:10AE4000B386B7BFCC1172F922C7E2BE3C7D46295A +:10AE50004962FF6B92C4FE77AFD2934CFBAEDAFD32 +:10AE6000B22FF2FEBC21E7BB75FD0145ECF3D765BF +:10AE7000AA5C6F68177A613A204A9C7FA5C8F3984C +:10AE800079FE11ED25A82FDF10B780E842D9D79AB7 +:10AE90000758EF6A4F9A989EDA938319D911EF05F4 +:10AEA00068DC4CF27B0D1B80FD881DC8BF2EA5EF12 +:10AEB0000FB1BEF4FD04C65947263C5229CEAD64FD +:10AEC00020BFF5C0DB559323FDFF053DEE03F1C127 +:10AED0004328E70931BFCE874DB042CF13083DAEBE +:10AEE000D2712CEEAF9AC88E63F757578A931B0E18 +:10AEF0005881F2C7B51F58F93ED0E707D6F2FE1DBC +:10AF00002EF927939F01BFFF6A2A1F38B876323D7A +:10AF1000FFFCE07D5773DE53DA1495AF08107D1EF9 +:10AF2000C2517F79F776C2975D0AE390A2AED3EF64 +:10AF3000D2F9EA9E56337F9B59BD77C6E38124C27E +:10AF40004F454BE9BB9D3D9D0AEB1FE22A0347D9C4 +:10AF500019479D28661C85E3F8825C161FABA47117 +:10AF60004F9414533709DBC99F4D271CE518C6556C +:10AF7000063DFF9C29F8D9DF91C0F9130926083D49 +:10AF800083EC28BA37B4BECE3864439B1CF5BD862B +:10AF9000F1DEEE4C71AEB0D7D0B390A4B11EED1679 +:10AFA000E586B63D19B48EF5E610EB4943B359B4C6 +:10AFB000EF1225D0F9CD0CFED83840FC39468F5021 +:10AFC0002E4B2CC1B184DB770F9D07EAF73982E263 +:10AFD0005E5D63E744FE6E68B0738F3B5EFC394E86 +:10AFE000E73348DAD12CB1CF896DAFF3887CC6D175 +:10AFF00033C22F1E5DE89F1CCF3F06A044ECFB250B +:10B000005D7EADE68A78E7861B3D22DFB4736CE097 +:10B0100028E971EFEE043E37EC7589FC6C694B97BB +:10B0200042DF9FAC6F9566503C5A9FFB1E7F9F820C +:10B03000F562F683E1FD7C6E5ADDBCBB5C8B43C7D9 +:10B04000B51E111F97E8DF018FD057BDFD1478D3CF +:10B05000F57DDA23745E73AAD2EC14DF9989EF4A86 +:10B060006FD0FDF98DD79B19379D02D52CCE3FC4EB +:10B0700039C532DD2FDFA0FBF911DF3B3F039BE930 +:10B080009C22F67B67C3AFDFAC8FBF02341E37F65E +:10B09000BBF59B753C78B32FFAF9A54C1D07E6402C +:10B0A0000EF9F310C617BE1F9197C0717A69E1A41B +:10B0B000B83883BE0357F5EFC0A934E4DE90F71E1D +:10B0C000C7BFA31D677ECDDF139C49800971CEC524 +:10B0D00086E39FE13F6E12F2D6CF2DAA9D824643B2 +:10B0E000EE17700716991F33E43E46E7FFFFF13D68 +:10B0F000A05C5022F325CFCAFE311E3A9FB0F53234 +:10B10000FEC615701CC4758DD3D735CE1A11DF2E2F +:10B110008C5A1D577F87D7971A1071C4CD65479EEB +:10B120009571627548E2EFFBAAC3625F5B5D26F62C +:10B13000B539AD02A7AEBC490A6A12BBC3D3449F5E +:10B14000A13FCB6C020F187A32C42F5D7FA89DF00F +:10B15000C10D3A3E88D5A3C9D05D4EF9E65B34C92E +:10B160004BF72A477C3FBF6ADAEBE4EE2FA73FA8F4 +:10B170006FFCEF22C4EAD1F73DFE120FE5D3BA0708 +:10B180005716E2B847F3FE388EF4A6E63276F32D72 +:10B190008F88133B1D81A37CDFA4453FEF6FC96BF4 +:10B1A000EB217E7402E3C75E57F7963A81ABF9BC98 +:10B1B000BF3A9CC0DF4356B7DBF9BBB0EAD686C4C2 +:10B1C00029E47FDB65AF1DEB95AD27CB889F95C547 +:10B1D000E23E4AAD5DDC8BB3B9FDB7107DD77B3B5A +:10B1E000A2CFF92D3DBFA8FB063D8FF56B1B09A330 +:10B1F000A5FFF7F99B8D3A5FEABA2E664CC1A9FE0E +:10B2000090E6AF267DEC7FFD450B1DD7D54E79A589 +:10B210009CAE886DF4A8DCEFFAE68E264AF31AF4A9 +:10B2200077643AF9F95173702CE3D2822BBB0FD3B8 +:10B23000B0FF8DA914A7FA3ABAA65A22F4BBB70EEA +:10B24000FD731CF9358049B75B854B495AA1E3254D +:10B2500061C7B5070E67503EA297ECB780CA7792D8 +:10B26000B3B1ACDE7D2A7912E196BDA21CC219ED04 +:10B2700032F703A527E7E6A448FA36337D17426282 +:10B280001C809E9C1B0B23DB1BFF5FDBFFD3A427D3 +:10B29000D5B69E28FB37F884BB7CFE3E3770D0CAFB +:10B2A000F708E8BCC61521C757747F340B374B64C9 +:10B2B000A773E87C7A22413B05EEA0BA026125958E +:10B2C000CE8BC3B2B87F3796FDF74C7DFE594AB896 +:10B2D00083EEE9CED1CF37E74237F75B00035C6AF4 +:10B2E000E0E4EF8B4BC0CBE56C5B7829C1F1825079 +:10B2F00088BF9F096728AE7336FD3BE638F21EE62D +:10B300009B02E70C7EC8740E26EE1BC5AEA75BD76A +:10B31000C7599AF03B041DE87EEE6C08F1B9FB3585 +:10B32000D0A39FBFC75FC73CDCF7D1B9DB35683B13 +:10B3300089CC8F20F79F4FEB91E3ADA767298B193D +:10B34000CA9C449F14CE307D6DBFF275F4D36D4D11 +:10B35000CA57DF35D0F783E2E1734B6FFB1BEFD3A6 +:10B360007D6249D3F8BEB197BEC7A67D4E58E91D90 +:10B37000F2631300FEDDB3E637646FC6F71AE00729 +:10B38000BEE711FBBD062DF77CC6F03D35E3FEEDB3 +:10B39000CEE00A95EE6FAC72DBF8DFAD29B28D9B83 +:10B3A0004E79CA87D2FCBF21BDFA406A9EC4832869 +:10B3B000C1198C6375BDB283369BD62F69C6F7223F +:10B3C000C0FA32F4EF0164007FB763B78AEF691EF9 +:10B3D000413DB4A5B2F6AB740F1A1E2E55092F6F5E +:10B3E00071D9BCF45DAE95E8B50FD3DB6813F72FC8 +:10B3F0008CFB6BB17C6CB419794AAF8D7176CC77CC +:10B400003E77DAFCFF9BE8BF3FA924937060FECB38 +:10B41000F33D7C3F29C15877898DEBC3F71A193763 +:10B4200036D17D6AA4AB311DF81EE2E1A49C14BAAA +:10B430001FD5D825EE5337A607D87F9BFD12FBF307 +:10B44000C6CED24E8A07830E0BDFAB6E74F934AAD8 +:10B4500007D22144FE9FF83EDFE0BB6998EF21FD53 +:10B460005E5091EDD75751DE7F9A1B4AE9BD696165 +:10B470006D12F1C0F81E06E5E019954ECFA3EF7BE3 +:10B4800081E2E4FB17861C503158999DBA7C0DB9B6 +:10B49000388DEFF83525EA3B7E435E8F240AB99854 +:10B4A000E926CC447E57A57163E561F0FDBF008FAE +:10B4B00040AEB13049000000000000000000000074 +:10B4C0001F8B08000000000000FF3B24C3C0F0A356 +:10B4D0001E81EF4A313030F1A28AD112EFE364606D +:10B4E00010E062603005E2FB3C0C0C3380F44C2031 +:10B4F00016E566601003E21A20DE0DC47B80F819A1 +:10B5000050FC3910EF00E21B3C10FDBE4C0C0CFE51 +:10B51000401C08C4C140FC958181E11B03F1F67316 +:10B520000A33304C1547F02F03D99F24E9E7FFC1B8 +:10B5300086430CE96BDF71A07DF3AC107C46207B69 +:10B54000BE15AA9A0556F8CD588826BF088DBF1893 +:10B550008FFE720354FE5A4D34B3B581E90949CDCB +:10B560003A4DFC6E41C7AA40FFA9013100ADF15F21 +:10B57000CA68030000000000000000000000000096 +:10B580001F8B08000000000000FFE57D097894D5BE +:10B59000D5F07DE75D66269999BC816CAC4ED844A8 +:10B5A0000B7442421A10DB618B6811834B051798AC +:10B5B00008644F2620F5C7DAEFCF40005151438B86 +:10B5C000355AB40304051B34D88041020EE0822DA5 +:10B5D000D5D86A5DDAD2A0C81A93801BFE5DFCCE76 +:10B5E00039F7BEC9FB4E2682B5FFFFF5FBFEF8F822 +:10B5F0005CEE7BF7B3DD73CE3DF78EE218C7948B1C +:10B6000018FB12FFBEC798DDC6181BD79D32562304 +:10B61000D24A2DCFCD58D003FFCC62ACDCAD85979C +:10B62000A7333665871AF95E12E43748613BE46D4B +:10B630007B9D54DEBE9EE7236ECDCFA0FCA33AC80F +:10B640004BD0DEDEF2C06550DEB943661BB1DB9144 +:10B65000713696C2D83107E37F5990CF66ACC0C926 +:10B66000B3E51BF6CDC5F6454D76E684FECA7715E3 +:10B67000CEBC0CF28507558655CA372FD3FA43BE88 +:10B68000382C3560BE63329F5F68A71CDE0CF53B2B +:10B690003C2D2937B8183B55E5605E8DB16A774B74 +:10B6A000CAF5A3182B096FCFC57625F5920F973AE7 +:10B6B00065C7E697FBE1BAB64A3EBB97B1D22DF11A +:10B6C000CC3B92CFE14BF8FF58A31CF91E942F8678 +:10B6D0007532E8B790D5E43219C75FAB79DDDDF09C +:10B6E0003B55A5D33846BE7C2B8C03ED2A9E967C19 +:10B6F000B8C40A1B0B34C0F8EDBB9CB337B9707DDE +:10B70000CBB4116E5CD7DD1AD62B0CE7EF747A71CF +:10B710007E1BB45C282F59BF412B18D5DD5FE996FD +:10B72000BED679D50E4D0D98CAA3D353558C794703 +:10B7300074E74B18F33740BF4C096BB346777FFF74 +:10B74000802532968CFDCBCCEBE8EE1F2049DF4301 +:10B750006FC13F015EA13D6E82AB81B7C53AFCDB94 +:10B76000DB8DB7B3BAC0A3D2996DEEDF481F403C62 +:10B77000C07C6A104E90AE11F3F34C649314E8DF72 +:10B78000E367BAC47A5F8F91D6A82C9FC1580B4249 +:10B79000A3FDCA78C86B6C11F331F69315D9FEA9D5 +:10B7A00090BF9F05E6E2BC57488122C413630D6930 +:10B7B00048BFAB24361BD7FF039C3494AFEA07F491 +:10B7C0000970AF9996BD4996C4DC93305FF0C4BD53 +:10B7D000E9D44F21F5A3423F43CFDF8F9E9B63E91E +:10B7E00047CF2D32FAA9A47E9C17D64F4DEE04EB1D +:10B7F0007C724B8C7EEEA47EDC17B62EFD8A89D639 +:10B80000F95C5146FD244EF5B100D4970D7A602DB8 +:10B810007E19CA5DF58963EF6566BA98BC12F9DFD7 +:10B820000D5C62A68B849C380B1D26FAFB58F2D067 +:10B83000937EEC5B220F834412351A5FEBAF915C71 +:10B8400098D4DF41F93BFABB482EDC312170B10EB0 +:10B85000F3C0B1593FC86B816FEB31E81AE629B1EB +:10B86000344CBD364CA3CBEF56391C260FF8DB8881 +:10B8700023D03E68EB1C9108F9F5D2A45F205C361A +:10B88000331BC1274E6695582FCECE483EDD9D9E78 +:10B89000BD296482D3EA41807FA9BBDFD56A200D30 +:10B8A000E96B2BBB2184F4B66A10ACA73F634F85CC +:10B8B000AE8F8414683FA8200DE169D780BFCDE327 +:10B8C0006B30FE281AFF191C77078E3FAEE7F8F69B +:10B8D000213996F11D838B2CE33B34181FE87D172B +:10B8E000BB558C0FF09BC0D8F3A15B687CFBE022BA +:10B8F0001AFF6E8D1559C68FEB1AFF051CF7A5DED2 +:10B90000D63F648275FD834BACEBD7F8FA5F650BCD +:10B91000C5F871B4FE5F8716F0F50F2EE1EBB7F3B3 +:10B920007EBBC6F774C1FF751CF7ADDED63F74A2AF +:10B9300075FD179559D76FE7E3BFCBCAC5F82E1A27 +:10B94000FFBD50195FFF456534BE660FF8908EB499 +:10B9500001719561189F0D0486482519E5A7746447 +:10B960001FC6A0FD3A3684E070471CA7BBCFE2801B +:10B97000DE5CDDF28E8581A3409E55089A2FAD9F37 +:10B98000A4A19CA572907B0BC5541734C9B4DFB039 +:10B9900075F6F070986F7B931CC2FC827597876573 +:10B9A000DAEFD8BC3C6CA7B0087EFFF0A1D11BCD6C +:10B9B000EB8A4E17D6A8C75A2D7CC4E7139ACC46FB +:10B9C00056C2FCA621118CEBCE1F0339CA407EBEA5 +:10B9D0000F7214D3E32A8C07DF8F829C659A996FCC +:10B9E00096F17D3CC4DE1C99827282FF1D5338BCE7 +:10B9F0008F2D91C208FFCFD62ED2503E2DAC890795 +:10BA0000A077CF2328F0D4B9CB1EDE28113CBD0887 +:10BA10009F1B891519FB33A0B51F80B6B0B6AFA523 +:10BA2000DD2D2CBC320DEACF5F933F4887F5DF3C1C +:10BA3000DB3E56C6FD83F907D8888FD9005B0E63BD +:10BA4000B31BD7AA032073E36CF5FD5653FB3901F2 +:10BA50006BFEE6226BBE5D0DAB36D4378A25B60190 +:10BA6000FABDB5D25A6E8C9328F5E17815E3FD2026 +:10BA700085CFF7564CC7E2679DF03A57E76D8DF9D1 +:10BA800004EF525984F6CBD66446F84FA67A019D4E +:10BA9000AF3B7ABE7355873F0FE633F74E99E019F7 +:10BAA0003DFFD6BDF17EDB18486B3F569104A3D70E +:10BAB000133DFF794BA3D7A3931E961F8AFECEE9B1 +:10BAC000249A9E824D93FA1E35D52B6FB8B2EF5152 +:10BAD000137D956E9965C91787E758EA17D6E65B17 +:10BAE000CA17D6145BCAE7AF5E64C9E787EEB4D461 +:10BAF0009FB77499A5FCD6CA7B2CE53717ADB5E482 +:10BB0000E7041EB1D4BF71F6064BB96DEF25D720FF +:10BB10001F55BF2533DC373E751D7B00F5C14F5DDA +:10BB20008A0FF171A22A8DF8E0549597D2F6A64CAF +:10BB30004780CBC1025471162E6B08AD9E88729956 +:10BB400091FC2C5EB633141A08DAADE425F8C9B5B9 +:10BB50001A8B00094BAC4F171D77CAA6F2D6F39487 +:10BB6000D702A367F62C975B637F0F6ECCBF08E507 +:10BB70004E6FF200FE06E03ED721F6F7E8F232897A +:10BB8000E599BF33B69CF8FC9C90B3651A9707659E +:10BB9000CFF69BCC3C988F8CA8FCAAF11A00A82861 +:10BBA00027513B4F467A002EB0D0CB500B7FB7EDDC +:10BBB00093695E152813C6A3C8C95B23A19C891C81 +:10BBC000187CDD689C87FF7E09F9AE2999F6F5B6E9 +:10BBD000AAE97D8F2A889F3C4A4F54CDA6F4585538 +:10BBE00080D2A3554594BE5F5549696BD5524A0F23 +:10BBF000578528FD53D56A4ADFABAAA1F49DAA5AFE +:10BC00004AFF5015A6B4BDCA4FA9C10F5DF237490E +:10BC1000E8ABC2AE809D87F267C55A5640DD16E29A +:10BC2000735F1AF2F959D76723501F3FFB8E9DA10E +:10BC3000BEDF1BBCA2E9AD773CFA495F290803FED1 +:10BC4000337B963BE3389E9C36369D813CBA67F841 +:10BC500013BEDB46515E4192810DC937CB1DA3DF78 +:10BC6000618CF0753E3C317FE7986B011FC71EFD6C +:10BC70006B36F67B4EEC7F710764DA875964930F5D +:10BC8000F165821BED6B9D3B84BC3F0FFC3EEA825D +:10BC90005FCB6006E9044927FA3BDB68670AC2B15B +:10BCA000393E0CC4CFCE1EDCE4417E5C9C66D38F53 +:10BCB000C68083919637A4EB2EF3FED364CD9FAD5F +:10BCC00091A637903CF6265C3F1AE94AD78F0E437F +:10BCD000FCA7516AF4B3384DD38F02BF9EDA3234D9 +:10BCE00081EFDF61BE0FD62712BD825D48F5FFD51B +:10BCF000F3E9AD1F633E8C35B20F1C280FA06CE832 +:10BD0000F9ED9D1E78573ED1F2105FCDEA67A82F5E +:10BD1000C4C1FF5F0EC17E15CA1BFD061BE490FD6A +:10BD2000DBF8BDDE321EB4F31A3637B6EB9D6E1566 +:10BD300076CCA02B90571A1ACB64273A75EBBE929B +:10BD400068C9079BFAE9967D06FF01FC0F82524104 +:10BD5000BA291354D4A1B8564B30BF23283F012F22 +:10BD60004189D72B77B46A012F91630BEA19B7E5A4 +:10BD70001874E7BDF18F20EF4FFE4665F762F9DFDB +:10BD8000605650AE1AC520F76C909F2F72B735964B +:10BD9000CE40B977D2C6F7F9052CCF83464F11AB09 +:10BDA000C9463DE723669B8EF4FF11FB9D27D364B4 +:10BDB0006FF86C1AAD73FE6AEB3E0BFA99255F586B +:10BDC0006BCD17B06B5390DE0BD6A92C2C215F5A8C +:10BDD000CBBD369DFA2D6495ABC8DE417B05C6BD53 +:10BDE0004D67CA00985FF9738F65E743FE3B36AE37 +:10BDF000A71BF67B711F3EFF92A4B0E687F20F1AD5 +:10BE0000337F7019C3F6E15528A7426EE6DBCC7A82 +:10BE1000E2EFEBCE3F7ABEC67ED2C38F20E6216F23 +:10BE200091FCE11876DA349B24F4AD10A537E0BA22 +:10BE30004D7A6BBE8083912F8FCADF1995FFA7E9DA +:10BE40002D8959E8ED8814C8B72573FA427D41520F +:10BE50003AB5C037E93FAD47FFE5FFD2FE0742FFE5 +:10BE6000D996FEEFFC97F63FACC7FC57C6EABFFC7D +:10BE7000B96D3B43206F4A9E79C8C3601F3AA9D46D +:10BE8000A4F800EF659B577A900E4E28210FD2F34D +:10BE9000C9B03C3D163DEC467A203FA2DF25A15DAE +:10BEA00085FF84FE4F3D75DF4CDC673EDBACEA640A +:10BEB0002F6DB147ECC0AF158DC533D818CA1FE13F +:10BEC000F9BBCFC8986FB2D267C9930FA5A0FF0D79 +:10BED0002845D81311D2972AEA3ECCC57D28C83A06 +:10BEE00089CFA2DBE1F8E7FA907CCCD7127A96C32F +:10BEF0003C49CF0F0AB8041BEF3B23A3EF93B57265 +:10BF00003F6854FD22A1FFD4DBDC49C7C07462DF67 +:10BF100061DF417969C08385B9FE53BDF5E13147E1 +:10BF2000603E6D75BFF1482638197C76B661FE2FEC +:10BF30009EF7F62E8FDB859DD7DD2E4CEDBC4D4256 +:10BF40006F6BE669991AF1A05E5CB641F585E07306 +:10BF5000D9B64D4F3C8A76EABB76DF70E8BF74DB1A +:10BF60004B7F9800F9D2ED6AD20CBE0C9794D28D1B +:10BF70009720FCBF746C371E4A7EF592E61DCDBF3C +:10BF8000FFB84F373E4AB7EFD3D8E89EF098D2B00B +:10BF90004F6B75C5C04BC3915CD4AFAAB77EAEA141 +:10BFA0003D7972AFC452D363C073C34BA427209CA6 +:10BFB000088F024F5D788BAA1F04BCA03C37F01499 +:10BFC0005DFE80903FD89F7714D1F3D3CFA35FF964 +:10BFD0003DBB0FD75FF4F4ED1E5CC771A592D3F59E +:10BFE000632B53FC306E911A4AD129E5DF8B1EFF7B +:10BFF00021D15BE11B3F4CE1F6A0BF9F8DF6A6501F +:10C000003F5CDFC2F537D0FA0A5880E8AEE8313934 +:10C010002F0CE9A70A9BBE3D065F64C89C2F8E6F5C +:10C0200004850BD6771CED12F4B3FE4E0E6F267FFF +:10C03000C82286FCFF43C33FCE1653FE5307C79367 +:10C0400043B609BE026DCF4CAF7577B7207E4E0D5B +:10C05000F2A7A21F2DC894908087F425F42BBF313E +:10C060002D95E38779956CD10EF48029F81DEBB7F7 +:10C07000A87EE7184B3BF6657AF7F84BC4F830EF2B +:10C0800038DCBF8FA7B0A28618EBBB5536F81EF67A +:10C0900071137D99F89BF37BDD3D9CBF0D7E0FCF27 +:10C0A0009A8EE59FBCC9F907DBE1FE08F38AA4522A +:10C0B000F9BEEB259207761689C5D775AAE06B6B9A +:10C0C000B94127306F454A30D10BF6DF87E04FFE8C +:10C0D000B38275D0CE242F83389EA7677F06DF16E4 +:10C0E0000AFE1F255BF99FADE77CDFBB7E15A27DB5 +:10C0F000AE4C0D3FF128F22BF067C88BFCAAE6E1AD +:10C10000BA4FD71FF8C34DC0A7A71B0C3EB5CACF67 +:10C11000683E2D7A76B384F419CDA7A78B401B898E +:10C12000C5A7F03D269F16B5FE3F959F06FCAE8F36 +:10C13000829F210F7B8363B43C3C63F3123CA3E5F5 +:10C1400021FCBDC9B27BD29F417706BD95FCB2FCF4 +:10C1500022F217187469D05D175D1A74D7C3FF6295 +:10C16000815F74F960A405A093BC5D2AD95565CDA3 +:10C17000FC3C0CDABD3C208BE0E4A76D8CD5BC3CCC +:10C1800020C99C0F47E51BA2EAFBA3F27951F503F6 +:10C1900051F94A4BFDB2A6031A23FC472CF5EC4B90 +:10C1A0001F651FC4B0878CFD26D878460B215D0C17 +:10C1B000ECD450DEA9CB410545FFE01E99ECC50E3D +:10C1C00080F12A18A7A33E3D1C02B9B1D2C9EDF0F7 +:10C1D0000EBDD3D307D295893CDF99ACAD42B96788 +:10C1E0007CEF74723F47475EA727D1E4A738D22C73 +:10C1F00093DC6E0DB3E9B1FC20B0A310DE5B596F88 +:10C20000E5DCFF394D760D5E8AF6688DEC431377D9 +:10C21000C1B21B3DE82AE9681E7ACD6CF8BEF05524 +:10C22000998E553AE23C63705E2CE457FA99EC899A +:10C23000132CF4B389E8CF6CE676C5823551FA0841 +:10C240005B43F454E05AA2A13C053BE07DAB3F9731 +:10C25000F34589E8AF68BDB5DC688F275A68DF957C +:10C26000D459CB03C23EDA65F04906CB2039838628 +:10C270000FDAE7422E4F93475D331BF0D1715066C2 +:10C28000789E79B659267C9CADE7E7972C944CFCB8 +:10C2900056C13A491E1A706A437ED27A97576D3B4F +:10C2A000FE9C7D17D2CDCE3F8EF939A46D3BDF1DAC +:10C2B000B11BF3CFBD3DF88FAC67FD297B9DE43703 +:10C2C000EED8EB267AEFD8F3DBC177617E979DFC41 +:10C2D000751D7B3F1F83F4D7B1DC5E84F2AE631023 +:10C2E000B787AAF77C3EA695F6D71584B7A3B2C642 +:10C2F000F5A3E6BF1E9692308555A1DEB0379EF8B5 +:10C3000029F8BC93FC0B1D7B3ECF0EB8FE75EBA944 +:10C3100010E7391D6E36FB599C5F22F78307778F34 +:10C32000DFB40CCFA31BF769F3A17CCA0B7F1F837B +:10C3300072B4E359AE0FB5ABAD8FE3794587FCE13D +:10C340003215E0DC8E4CD59FB1FB94119343A36270 +:10C35000C1E5EFE437B95078680AB74FFFFDE12136 +:10C36000F9B9BC73871D12AEFB8BC37F44B9B0D73C +:10C370004E7469ACF774C332D257CEB7EEE1CA7FC0 +:10C38000173AB8D0754B910B59F7D47F737CFF5A8D +:10C39000F6D2FCA2F9A0279DEFB983F2DBDC3E9A2E +:10C3A000EF05D2FB82FF69787F16F0EE39FFBAAB5A +:10C3B000FFCDD7DD3BDE5F9D2BF0AEE3797FF085CF +:10C3C000BFD3FCBEAE9CDBF4DF94EE0DBDFE159B2F +:10C3D000F7CD0CA83F9DD5B850B1B8B27CFFAB19D2 +:10C3E00050FACAC0038938DFC951E73746FAA6C2F6 +:10C3F000EDA6C9928DEC419628097B90DB51038410 +:10C40000FE30604901E9210306DECFF506C5BB0E0B +:10C41000CF1F5F193CDF47B1146CEC3B01CCEB97AD +:10C420008BBCD59EFCB9C4FC78343A60F0F70FA2FF +:10C430005E3B70A04C7A2FA4A4EFBEE899CEBF97C4 +:10C440006916BBE74AAFD50ECA4DB2DA4B53457FEA +:10C45000D3189FFF3497140E031C260FFA6912FAA3 +:10C4600047270F579904F95C165881F6C55497B5BC +:10C47000BF063CC319F7CDE168570D380E599787B1 +:10C48000701C24939FF4BC70C47913DC32C2182F43 +:10C49000C3141F87639F721FF99D85BD4D474D9043 +:10C4A000575CAB5A909F15B497391CC8CE36ECE553 +:10C4B000DEE0CD84FDAD88210DF82B0365BFD3DA16 +:10C4C0001FD9DF065EBE2E3E0C3C7E53BCBC1B85D6 +:10C4D0009781AE450AF2EB74B417FA62FD0C9E1F09 +:10C4E0001852E8DC4DD80B57781729A4F70CCC501C +:10C4F000105F858EA6ABF01CC4E193681E17B7D9F8 +:10C50000687F70644904F791B50AE5DFB0E9E3108C +:10C51000DF332F7BEEF49D0CFDE67E8DC73DE5F10C +:10C52000F38FBF7DF9E5448C1714782C84FFAF4658 +:10C530003FFF7A168903382D545828A10FFABD25DC +:10C54000F6BEC5EF6DCDE3DF7753BAFB395FFDDE95 +:10C55000E4CABF3A7D0EE4D8FB00F35D980EA3E178 +:10C5600015B35DFD9D660EAFE021161EC2E32AE401 +:10C570003CD339E11D82FE9FFBD3B39968D74EEAC5 +:10C580001895C0E5EB30B21782C25E38CBBC093ECD +:10C5900017CAD7A10974FE795076C78A2BDC2AEC1A +:10C5A000ED5F627C09A41D75AC4646FB8D75921F3C +:10C5B0003754E7609B63C4B7E4AB869F4AE00DFE47 +:10C5C000E46C3C8FE1E32F84A60966BCB5CD38A9A5 +:10C5D0008CE98907FC7BDF741EF54DE18BF63DC2CB +:10C5E00077ABB335372F86FCB85DC06FE6FE2FC83A +:10C5F000FF7969F3061BD2EFA57536CBF96AA92A34 +:10C60000ECB1B16C2CCE6BE67EA73B0BF17250F611 +:10C61000613C67B0F98C1688712E180D4FEC1FFD28 +:10C62000E95B559DF86BB7DA301FE1BAFB2307438E +:10C630003B7A9756531A6B9E03EC7C9E0B59C3EDC5 +:10C6400063D2FFFDE03BA9C315998CF6671D137EED +:10C650008F68FA6344C767B7B030EEAF68AFA25CCB +:10C66000385BCF687F0790DC8F7637F0FBF7CC7EA6 +:10C670009C8B9BB6FF12F5828A6649C723860AA562 +:10C6800055433F6DB02951C67D38C36BC4BBEAA387 +:10C69000AF37F1C5565521F81E98B0FB661CF7E37D +:10C6A000368DA19EE27FB1D383FBF8C7CD99C40735 +:10C6B000BDADEB5755ECAAA948372A9787D1F4307E +:10C6C000AA3ECE92BF4C0EF447FE9A696F5DE28B94 +:10C6D00081BFEF6B923817BC40F916FEFF4CBEBD10 +:10C6E00069C8B7809C67E2A3BE5A0FF9961A4BBE81 +:10C6F0002D96BCA908F7C57B86A6225E17BFAA2681 +:10C70000C7926FDBAAF839E733224EB9A311E4DBF5 +:10C71000B74DF2AD11E45B8C7890BF5FA87C0BFF46 +:10C72000D7F0DF36946F31D6AB6B56F936A6F908E1 +:10C73000C9B7318D364B3CAF5D3B9F7C9392AF4781 +:10C74000FDF8A0EA8B8F413FDB843EFE8C884BC412 +:10C750007150CEE56A3A8D7FA172EEE20B9573FFC0 +:10C76000457036E4DCE21D8CE29C7BD22197738B12 +:10C7700077819C93901EB99C5BBC8771BF5C947C55 +:10C780001BD943BE31AA5F11E1ED834DE90FDF02F2 +:10C79000FD8DF5AB3E07D41FDB2DEFC699E55DAEF1 +:10C7A000A610DC7AC8BB831726EF76087907726C6F +:10C7B00008CAD768FAF0355BE3C1778F3F5EFF2B7D +:10C7C000E497DFCA74DEF8868D9F0FBD36FE7816BB +:10C7D000D2D763623E8B84DC6BAF0A51FF535EE4B9 +:10C7E000EB2B77F138F18A46AE1F56D44B612FFC04 +:10C7F0003377C2171ACEBF788FC452213FCBCEEB0E +:10C80000B3278DF3323623C3440F0B724AC9CFBF0F +:10C8100040610EF4E397BA724FA2FE5B9AC3FDFE2D +:10C82000A5E27BF1ABADABD0FF5DFC8844E7A5464C +:10C830007CAB11E7DB236EA27919F977A3E32766B6 +:10C840008AB8A999BF94C21B62C47F946EB1E67F77 +:10C8500022F86F96DC4AF062AFCB31E3388C7A5D18 +:10C86000703A28E05427D37EDA0527809B37BD270E +:10C870009C00D3333252BAE152FC5B586F56EFEB57 +:10C8800035E016BD6EC37F5D2AFAE90D0E069C7B6E +:10C89000AC5FC01DEC029293D1F058A775F9B53387 +:10C8A000314E09E886E44CE8D70017182F6FD27094 +:10C8B000CB7D974705FD64D64C9A82E10CB330AE30 +:10C8C0001CCA0B6A17BDDC0FE031EE1DEF58DC4EC1 +:10C8D0002F9B600FE039EC566727C941830EDB358B +:10C8E000AE071C14F0DDDDBF7232D9F94D928E7A9D +:10C8F0004830E224B80601AE78FF28A870FC068113 +:10C900001E91FF0E3CF21987E31EC98BFE9D5C63EE +:10C91000BF42BC40FDCC668E97605822BC64B14ECD +:10C920003A7FA9A8957C11845FD306829F219FE15D +:10C93000CF65C693897E9558F44B954CFB65A9A8A5 +:10C9400037D35EF307A4E7994FAA6C03811BFEFB64 +:10C950002A7A3E4F1C50349EDA04BCB6213C5D0856 +:10C96000B74EAE7745BEA0FB504679500959E03925 +:10C97000E5D1735F09AF7106BC908E51BE35E7CB30 +:10C98000982F689258DFF49EEBC5F35033BF17EF32 +:10C9900039C2FB7F4CF2B118EBBE60BAEE859E8BBC +:10C9A000806EF1BCA437BA8E86533BD2F3B7BAE996 +:10C9B000F93567E7A14CA4E73D12F74334275ACE77 +:10C9C000353D761EF7B5D509740FEBEE7C55F56D48 +:10C9D000F4C690CB82EED17E30DF37BB041782F1F4 +:10C9E000A25B1C14EF47F318C2F553B37CDEE66478 +:10C9F000C9D767F5DEBFDB2EC58C2737F423233F6D +:10CA00001AC7C3F8F926186F64F778D1FB83E12FB2 +:10CA100038DFBAFADBBFD9BA8C71BE6E3C5490B520 +:10CA2000105E8DB8A82352E0472AEA73D3254BFC49 +:10CA300015CC5CC8AD6FDC7FAA96DC7BFF2C4DA7C4 +:10CA4000FB74B7EBC6779DE8334F67E27C6FE2DBA0 +:10CA5000B8EF7FECE7E7985936F6D644DC3F26ABD3 +:10CA60000CE9EAE3432AF9A13F9ECAE36EAFF9ED70 +:10CA700001055D3ED7F0983876CD3889ECAC37B0FB +:10CA8000EBF1A8873B987F04C12F13EFED65D4D558 +:10CA90004CF1025F8FDD12AEC6D437A533E935C441 +:10CAA000DB249921DE5AFC7DA7B8207FFB872C036D +:10CAB0005DA0A01F50FBB1075932D69BE04F263333 +:10CAC000667CE3276F5E07F3187F48F679A1DEAC3A +:10CAD000032E17037D7AE47A1B0B98E0358185AB32 +:10CAE000D1DF34FEA8FF3A9C7711E83B784FA4A829 +:10CAF0007943B507F3EB256A1F0C05723DB09E6DB7 +:10CB0000B56772BF857201EA6137C1F5BC5EB04E90 +:10CB1000F261887241F35A8A2F2AA893E842E1B65B +:10CB2000B0C41CBCDFB003FADDB61EDA67E1FE0557 +:10CB3000EDB1DFBA336F5E877207E649EDEBF9B905 +:10CB40007C01B4F322BFD42DA2FE8AD74B0CEFB3E5 +:10CB500014D5F37DA9E890EAC3F2C67D8FD07E3B61 +:10CB600003C6EB978EFB50642ADD0BCA9474BA2F70 +:10CB7000191A4CF8EB601C7F6CFA20F20B52BCAB1C +:10CB800097C0A098E363FE641F42F2B3C0B74CEBBA +:10CB90000BFDBC96939C6E23BA3A43E7ED4701DE4A +:10CBA0000180F71B225EE540CE075AAB695FFCC2ED +:10CBB0003E949F9B344DA2388E852C8FE238668E32 +:10CBC000E7FAE6EB973BC3E8E77B5DED1C88DF0FF8 +:10CBD0005C6EA7EFEDDBB81C6E1FD44AFEF6E3EBEC +:10CBE0005586F758AAD7CB242F8ED7AB743F567EE5 +:10CBF0008CC731146EE3FAC781F5BCDFE3A8B7E157 +:10CC0000B9079643BE70AB11E7C0E5B4617F16E883 +:10CC10003CFEC290BBE562DD3DF6A175CB3424D964 +:10CC200068795B2EE471098B90BD1C2D77CBF11CCC +:10CC3000DD837C191D27E6EAB663900E225F105D46 +:10CC4000571C5219DA31D2076DB91497B647A2733F +:10CC50008BF1CD921FE31A8ADEB18749FF0EE7CF31 +:10CC6000FB11EE2FEFDA19862C1F433C809CCAB1D2 +:10CC700077FEE9A7F0FDE41B0E8C0802BAC927B8BD +:10CC80001B71BE599B793C4FD61BEB52F03E2F9B3C +:10CC9000DA97E44061ADCC0226397152F25F771326 +:10CCA000DF1F74D4770C7C66693505B8BF7ECBC1B5 +:10CCB000F755EF66156364D8EF843D04F6811FF5E0 +:10CCC0009BE25D6B5334131D14EF599B22C3F75540 +:10CCD000221EA61AF7576857ACF1718AF74AFA066E +:10CCE000D338463F46BFDA2EDE6EE81E9EF6D67F6C +:10CCF00031CE8FD6F9A986F222BA9F1EE3F7D24F22 +:10CD0000CEEFCFAD93605E39AFCB14AC9EF3C18C48 +:10CD1000A1E6731D2335FCCAD96FDA98DF04BF9CE6 +:10CD20003FC531BF09DF8DE380EF017F5737496190 +:10CD3000A784F9235A7916E575E4F30AE17FAE98E2 +:10CD4000CACFEB1A33DE58817C3F234B227A60A195 +:10CD500080D63789F4352FFAFD0BB378FB42688F04 +:10CD6000FCD8F808E74F90135E942315EBD7E652F2 +:10CD7000FD3AC98BFD376EC8277DA4284766545EEF +:10CD80007784F4A3A2A62349C8C7C0B7EB501FA855 +:10CD90009868D7518E1BFC68F0F7EBE23E2B73E8E6 +:10CDA000A3F17EC6FF46E68BC1D7F2212ED783F5CD +:10CDB0009C1F83399C5F5FDFA6E20A2F84BF899F97 +:10CDC0008F6FE1FC2A3F76432EDE872FDCCCEFC34A +:10CDD0001F583F45437DFA7858A2FDA6277F73BDB3 +:10CDE000359ABFAB25BEEF7D5DFDD2E06F838FE14D +:10CDF000EF6A1CAF0CF814EF4F46F3F54CB5E10F9A +:10CE0000B7C37CAF791AD603F39DF2DD3B3DAD2667 +:10CE10003909F914CC17283C9ECB902BE50A8FFBDF +:10CE2000FBDAF38B1A3F6CB7FA477E674FE4F1EBFE +:10CE3000752AD1FDF9F8B3079F5D207F5E285F9DBD +:10CE40008F3F8DF1E53DD67E7E27E82DBABF7680F7 +:10CE50006B04E0FA4AFD268AF3FDE8A92333113F6B +:10CE6000A5BB81CE91BEEADD2C82724E09D37E55E0 +:10CE7000D228D33D01A644B2AF739BF998C76D95F4 +:10CE80003EE3267A2A79D61E9E01ED4B767E3086C9 +:10CE9000E2689677525C5AE829A12F875AC7201F6B +:10CEA00094283C7E2C5A2E041CDC0FD7B62B7E36E1 +:10CEB000AE4FDAC2DF8F2869B851B59BCE256E74AC +:10CEC000A8463D3AD70D011DE3FD5D9C9FF9DD02AB +:10CED000236EAC6D2B9713254D2AD981255BB6B7F0 +:10CEE00063FC70C93B76F27705B79CA1FB10539E9B +:10CEF000D946FE9460936C397FEB11B7B9458ED853 +:10CF000031EEB0B19CCE1D217F84F20DB1E397CFFD +:10CF1000175F58FACC9E9D210061E9AF9EF4A07C7A +:10CF200039D5B2D98370877EBF326EBA479C66C34B +:10CF30003D5F19A7790AFF018C738F43D835469C52 +:10CF4000EB96BEA447C2FCB2F3629C7374E9E5DBC6 +:10CF50003E7D1CEF11B43D7BFA719C6FD93F3E7E44 +:10CF60001CE3C1D85E27ED77C1A7DEA2386CA3DD34 +:10CF700026B1DFB56F7D92E2D7DBDFB5FBB0B7F648 +:10CF80003DC707633C60FBF62F52D06FB964CF34C6 +:10CF9000F2EB2ED9312595C5D82F8C14E9367C01BA +:10CFA000F1F3D1F83AD07880E2D63E027CA3FCEBD4 +:10CFB0008ABB6D28E771CC5E116F5B1FFB9E428FB1 +:10CFC000F8DAC6EBAEB91CE57E23D71FCF1B67FB93 +:10CFD00026E0F1DB1780BF7AC32F101B7F1FE13FD4 +:10CFE000004FFBA2F0F769E3C25F3C8A658D7D7B51 +:10CFF0008DB38D5C00DC8C7B100F38FC871CC988DE +:10D00000E75F525C33E26D8617F79F4F07E3FD91B0 +:10D01000136AE75CBA5FB8C7AE63BC68C99EB789DC +:10D020007FDA77BC417E6826EE23B4B3AE3F1E3F65 +:10D030002E8975D6B9797CAE803FC6EF7A3DF45D16 +:10D04000C4E9723A36E2777B8BDB959D5CCF36EE96 +:10D050006794D7FD51C4C376E34BCA413C1DF9CA5E +:10D060007868030EBA90C3DD71E8B1E3A3BBEE2B81 +:10D07000087C21FE701FEA8A3387FCC0B1E4377A4E +:10D080009BC59007ED1B78FC7ABB1AFB5EB011972D +:10D09000FE8F683E0D5F583CFAF9E6FF75E1D381DB +:10D0A000CA4F724F38B5FD2DB61C4F774ADFEC9E44 +:10D0B0006199147D6FCAEB1C87713B4734B483BB05 +:10D0C000EC6CB1DE36E1576F7B4AA678E5550D076B +:10D0D000488E47CB8B0A7C2F25C67C33C57C2B9A88 +:10D0E000F83ED1F6AC3BEC827EDAF6EF227AAEA8BF +:10D0F0003F42F1D22F6FF995D66A8A8BC07D226CA0 +:10D100009A7FDBD3FBC690DC16EFB2448F33498C99 +:10D11000136C8E3D4EB0FE8C659CD25083A6BBCE68 +:10D120003FDE29C57F23F677AA85EB83A71AE4E9BA +:10D13000E118E30F73AAD677A160BFA4F767DCFC00 +:10D14000BD19D91347FAE51277CE3B0949986A14FD +:10D15000AF55BD4CC477FD872F0DF15DEDBE8AE163 +:10D160007C57227C4D7E1E550F30D44BD5B4BC2C41 +:10D17000F42B44CB1B2DC9C6C226FC2F714F4FF593 +:10D18000D279476420E2F370C67115FBFD4B949F82 +:10D19000EA2F0A5B950AF3FB4B48F22D837ED9DF19 +:10D1A0003E1894E7EED97F971EF163D9E257AAB0F3 +:10D1B000771E46BB84BDE0A4F80679AF93DEF9087C +:10D1C0003EEEA4F51ED8F1F913A45FFFC2CEF8B964 +:10D1D0000F582F20AF0A75DEC7F11D9F3FFE57D4B1 +:10D1E0009FB1318C5FF838D447BBA13E9EEC9C8E3A +:10D1F0006713C6A05FA4F085BB66A23C2B8CE7F446 +:10D2000058F84C6AB81AFA3B96CCF3C7B60DA27719 +:10D21000254A9F7553DCE8811DCF55E0BED4FE4CF6 +:10D220003CC37DA9FD05A1E7FF52BC5355AB7ACDA8 +:10D23000F1E3C54CF19AEFF39462DE12AFC4C82F4C +:10D24000417C84FEAAA604BA0704FAAFA59F8FD436 +:10D25000CE3B7C44C7A1FEFCFE53A43FCA83E87AC0 +:10D2600046F9BDCE21E25E39B47375D70F6A9D05CC +:10D270003C5FD39FCB9316AAFFB053F88F4579CF6D +:10D280007E79FD8784FCEEEE87B7AF10EFD044D3F4 +:10D29000EF46D16FE996BF5F1CEB9D9518F3A7EFA2 +:10D2A0003F9458C8867ACA7627BD7F85EF28E07DEF +:10D2B000859D1A3FD72AF344E89D9BDD421E97C502 +:10D2C00045E8DD9DFE621E581FF3CCD1FA34BD9FA8 +:10D2D000F69C93615C59F90B6E3FE2BB7CE7E7C7B4 +:10D2E0007E9E857189F114175FFEC2FF223A28B72E +:10D2F00047E6223F746EB7B38DC8E7DB5F1D8CFC39 +:10D30000DAA64606F7F98AF3BAF206BBF5FEBF586D +:10D31000C7A9AADACBF0BEBB71AFB6A41739F357D1 +:10D3200027D7A35F71FA5F7212BF5BDF733A55357F +:10D330003B13DF5930EA973862CBC577515E7C13D7 +:10D3400039EEEA713FF55D9CCF47AC2505FD3E15F2 +:10D35000A077A33C2FD9923E10FD04FB9DC63B0451 +:10D36000DE04DC8FF6AB5EB2A73135EF3327AA7C43 +:10D3700099CA30F4DF8CCC54601D1D1BCE14F467A9 +:10D380001847EA9C1D4BEE9D76C6D33A4A1CF69888 +:10D39000F79DCF09BA7A0F8DFE643E1EF28731EEFB +:10D3A0007E354C72F88E382FD52B01BB08BF976E97 +:10D3B000999369797F45A9A17AC0A704CF62B64E37 +:10D3C000CB32C96F63BCE2A559994A267E57FE4FFE +:10D3D00017BDCADD7866A124D20B150163B6AE9FD6 +:10D3E000E57E88A2E639107E1ACBD3151949A586A9 +:10D3F000F83D8E3550EA02758BBF5356C9504E9E8C +:10D4000010E7F6E8EFC2B41B5E7792DC0F0D626C9A +:10D41000783ABE07E14DD04DF053F1101EE6635748 +:10D420002A1997173374B493A550807D09F4545D7D +:10D43000353D13E911FEFC180749A607CCCFA3BF61 +:10D44000FC05EA4140A7FC3DBFEFB270358018C330 +:10D4500081C9AF3A99F177E856BFC3CCF6C6A5713A +:10D460009278E7681FC93117EBFEEB843C8A55942C +:10D47000B7D509FFC8C1734497CE22A817C6BB58B9 +:10D48000241E52D728E59499FF3D599037D1A93EE3 +:10D49000D15A1ECD1720D7A2C66D20F841BF9F4498 +:10D4A000F5FB4954BF9F7C55BF069C828E8D3E7C08 +:10D4B000A76265559E801B1FCF21E006F01989EFFA +:10D4C000E8315B9C4F9C87135CE3C46CEC581FF005 +:10D4D0005A1E974E78B92F616F27C641B3A45A865A +:10D4E00076EF0A89EFD3F097E732B563BA83F8F0A5 +:10D4F0001E314EB980F30AC33FD5A3BE93F4AF1ECD +:10D50000F59DBDD58F8B5DDFDDDB7CE263CF27B181 +:10D5100097FE6BE263F6FF75E552C50B6FBF86E7BA +:10D52000B65DF24907D05BF5CCF238D433138FFDEA +:10D53000A395BE703DD331D08AEF38A46FA0B7B8A1 +:10D5400061D6EFD174D21B7DE58B7540DED50FE03F +:10D550007093187F6A1D3FF7BE6509F7D38179E89C +:10D56000C7FA378BFA37390AC9DF70C4C6DFBFBACA +:10D57000A596EB91B7FC58A6F3E91EEF51E13F8069 +:10D58000DF6E5D2A8523E9B1DED76275783F6E9E36 +:10D59000183FFABDAA00F3E6AE9663BD57C5E9D2BF +:10D5A000B85717FD4EC5029627DE21B37E3FEBD458 +:10D5B000BBE467CDA8EE7D2CB416E81EF54FA07B2A +:10D5C0003C97C7EB621417E2D1785C48CB203A4F06 +:10D5D00033E4DFD991DE04DCAF997F30FFAEF3EFA7 +:10D5E0008BAFF4A69AEF1D2AE7E22CEFF554ABBE01 +:10D5F00034946FEA39D05FC154D6CE0D615E533991 +:10D60000E8ADC4FC18BE49722A4D09A35C54F43C31 +:10D6100056887AAF78EFC3A8AF255DD5A567BE0E53 +:10D62000FF6F8E4B26BE5CBCD64BF7B63F8BCFDB75 +:10D6300089F4247B727C01574F7A08EDE0EBAEC68B +:10D6400075A7F75C4FB5E6F391BE7D158080FC6F42 +:10D650003E07CE4FB67BDFF6E2FC7EA332F4BBF48E +:10D66000848FEF4418CACF8607507C889C306304AF +:10D670008EBF46BC6FBABA6A24A52BAA984879BC5B +:10D68000DC8A2AAF487344EA17E974AA776F551AFF +:10D69000E55755F92835E0EBF0D5D0FB938E617C4A +:10D6A0007C872EF0976413F00B90FEE548ABA473D3 +:10D6B00045A75E19C177DFD840D87770597A0DC178 +:10D6C00057D319F935A13EE5ED988754AD9D41F842 +:10D6D00052F44A5608E56FC5078E225C9DDE4B2D3D +:10D6E000EF5ADAD3C646BD7F1A056F83DEB671B82E +:10D6F000DF2F717A8B86FBFD6A8B17E322EEBFB2B8 +:10D70000EB5D29823B98431CEEBFE6E7B43DE1DECA +:10D71000327BBE09EEEEECE904F7FB049CEF1670D9 +:10D72000AD1678A816F0AC46B8537EA4C8FB443AB0 +:10D730009DD27BC4FBB72B111F90CA087780877DD1 +:10D740005488C9301EBA79F1CFEE1274ABDBC81F12 +:10D750002ABBF2FC08777B1287BBC3057820BA0688 +:10D76000B87BB13C44F0545D1CCE509FE341E415BE +:10D77000847B267EE7F800B8F78D1F87F27082055C +:10D78000CE5AD2E40B83FB237C7F4B127C1E0DBF51 +:10D79000248DBFAF6BF0776FFA71B588B7AE16EF17 +:10D7A00027221C51AF7908E0C3340E4FFE7DA4C878 +:10D7B000FB284D16F67F35E001CB1F16FA10C21973 +:10D7C000D31FC573FB3CC956B94F4538F5E1EFF29D +:10D7D000B0A4101B98CD78682FFEA5859817F3C6C6 +:10D7E000F9AFD74A3FB2AE44BD03E97D18E96DDD1C +:10D7F000ABAA0DCF3FE4A55759EE67CBB3FD895EC9 +:10D80000827F4042BDE63EC1876B915E687EDC1E32 +:10D810005E29E8E06EF1FEEE3D827EEE17FCFCA094 +:10D8200041373E7E3F64CD741EC798946113EF204C +:10D830004698394E30D1D7C0349817D9365E4AE968 +:10D840009D4BF68E9DF8367E14F3237D25BE7367BF +:10D8500098BF439BD70FF5A144E3DDD989DEC439D6 +:10D8600074313DA288F720656E4FB6C47CDFB5DA0F +:10D87000B7DF817E99DEE613EFF3A7AF84F1E26BA9 +:10D88000DD6447F50DE4CD590879572DD8550CCBFB +:10D89000B97C70C1BC0B4DF411DF8B5F47755D59CE +:10D8A00080F44AF638A43FA91DEA44F802ACBDE86A +:10D8B000BF7A48CDEB87FBC14389B1FD70B3E2B9B4 +:10D8C000BFC49375A9C59FB04EF5533B7DA255DEED +:10D8D000AC13FB439FA956FE30F683CB447F9FC514 +:10D8E000077E140F7496726E2AC9CFA46B63EF0F74 +:10D8F000D5AA16C2F739AA4773BE0EE56B5C6FEE68 +:10D900002177189D839C0D8CD888FE2F83BE96337B +:10D910002EE7428CEB93C6BA7E86F43E02F7019D59 +:10D92000E81EF701CCCBC334A29B945B6CE47F5818 +:10D9300025F8EC5EC15F6B045F3D807C3502DF81C2 +:10D94000F651FA13C14FEB90FF20DD129FCEF57810 +:10D95000F1BE9761C72C778CA5F71CAB5D36DA0F4B +:10D960009477ED6117DA05FBC6EBE8F791DD597A9C +:10D97000C08DE5590E3FC0434ACCD2915E3E732F15 +:10D98000B8E8ABE25B01FDF4AEB0A2727FA49E9456 +:10D99000C7DE1F45A753F49E80AA5FCBD03FFD7022 +:10D9A00052A513E1FC703C8FD3AACDCF26B8033E1D +:10D9B000B6C59BE2A552675FD5F51E1F76FF702F97 +:10D9C000EF12EC12F2820D0CB16126F9502BDE7BC6 +:10D9D00064DE101B699213CB87E732F4EBF5940FEA +:10D9E000BDC8CBCD5C5EAE9062CB4B437F37E46568 +:10D9F000B45C31D295174DB7DCA7545D3E46F26654 +:10DA0000646CFFC1EFE3EDFC1D6AE6F3E5A7F72CBC +:10DA10000778FDDE0C2FD4830C7FC5F762AC275A44 +:10DA20003E9EB8CAD85703F43ED002CDFBF0F8AF03 +:10DA3000DC57ADFB41E1B9D5A40F149CCBA1B4A830 +:10DA4000763AF111C3D318939D7C7CFD0F3D88DF9E +:10DA5000E3B5E27C7CBD1AC6B8A47D1BEF7A600EEC +:10DA6000C075C1E3329D8FE33D0DD914DFC2B2BC56 +:10DA7000A4A71BEF231E0FDFEE31C73114FCD4E93E +:10DA800047FDBF377A2C581FDB7F538DFF44BB8384 +:10DA9000F946A25D01FA5D6704F5BF9F38E9DD181C +:10DAA000231FDA18EF33C78F18E95BF1D3CE21DCDF +:10DAB000DF8AF73317D29DAB0F9DD7F4CE177CDCEE +:10DAC00063E833C773D247459C35C07D96C57FCA8E +:10DAD000CF498F097F1873F4521E27CABDBD947BAE +:10DAE000783C13D36397FFD37EA4513DECB421B8A7 +:10DAF000FEF2DAD3ABDEA52FD6F3806211C7BD608C +:10DB0000637C78790CBE5920EE072F10E75D067D07 +:10DB1000157FDFD0B3395D46D3ADF4D42544A71FBC +:10DB20001F54C95F5B01F4877A98F4D4787A8F69BF +:10DB3000D913973D780BC0F993433295979D731095 +:10DB40005DB6FF878FE2FC3B7FABD2EF267C727025 +:10DB50001AC5EBB78BF79EBBF8CEC5EDDA1B5C5C44 +:10DB6000AE149CBB97E8BB8BAEC2F335E4DB82738B +:10DB70000F905E5680EFBD4EC0758F78799222E887 +:10DB80007702B61F92BB1CEA15B6723E61134315AD +:10DB9000E48FDE10EFBB37063FDFE0F25AE2450BC1 +:10DBA0005BD750FF0CF4C324535CC802F1FB07851C +:10DBB00078B884E57A88A521DF08F9D64DFFD677B5 +:10DBC000B0DB9DD6751AE9C2AE754EB0D861DDEBFB +:10DBD000FC2EE773A16F14B6E6F07975ADE7E7E3C5 +:10DBE00063ADA77B1D13A97D7B62ECF1EF17E31FEB +:10DBF000AB2AC29B5BAC44BCB75B10BE5DC3F7D520 +:10DC00000AD627F6914CEB2AAC2DB5C42B15D4E6D9 +:10DC1000D3FB7A85EBF3B5DB4CFB53175E42FE97E3 +:10DC2000270DEBC6CBFD6B2E23BCA8AEBC3B917E73 +:10DC30008F3D557CC77B5EEC97E3E984161A534908 +:10DC4000F2EA764FACFB4DF747E3A956E009EC80CA +:10DC50002C139E0CFC44B73FB6B9FC8EF7F01CE2C7 +:10DC600011FE9A50EFF22B0A7FE9B1E1F7A4A0D799 +:10DC700063A00F042E087EDFB2C4CBF50A3F816F8C +:10DC8000033EC677D0E7C208B727913793B13F4E1E +:10DC90000FE7835BF7F8821E26C55ECF6B5DEB59FD +:10DCA000CA42A0C79CD4B83ED1FB7AEE6221C70518 +:10DCB000ACA78B4FF32D7CFADA9A5B389F0AFC9F56 +:10DCC000DC7F0FD1F5B170BC0FE3547A5BCF6B48AA +:10DCD00007E362D0C1B0101B95FD7F8F0E4E68FE2A +:10DCE000118FE03E02FB15EED3C54FDE3FC63CBFB1 +:10DCF000B7E227FD9EF6A59A0B3BA70E4DF61DF445 +:10DD0000D27E27FBAA6149435D813F63FB12CFA30B +:10DD10009FA19F6E45E2CFC6C4D28B5756052EC732 +:10DD2000F38BEAAAA2CBD18FAA0A3D97A19E9BCEE4 +:10DD30007F1723D67B7DCCCDF1BBB2AA92CE3F9884 +:10DD400023C4F494EE7700D8894CF2472B2EAB7E97 +:10DD5000A6A9011DFDDF9A78A7405502ABD3B3D029 +:10DD60005F94941132C1EF1F2E7EEEB2266DBF8EEE +:10DD7000E71A76E81FFD608E81CA598BFFEC456576 +:10DD8000415FC093F11C731C6BF04B12F913CF462B +:10DD9000F913CF5AE69104F3FE0A3B5B7178E81C55 +:10DDA0005261C28F2CE0015F681FBB5BE7EB5C1E1A +:10DDB000EF217D60D54536B2EBD609FFF4CFD02FE9 +:10DDC0004D7051E8BC01C3E0B0BE96C0D7E1C4734A +:10DDD0000C19EDAD08E5DDF862974C4F1F4A984FDE +:10DDE000645E09F37D596415DA0F1D935AEF203FE5 +:10DDF000A03390E606BC7ED6AFE5B084E712798109 +:10DE00008B11CEB57228C30BF57F21776660BDC13B +:10DE100050F44E1F9E5E84F71202A6F3CE21B48EFC +:10DE2000EEBCDC337FD15225EAFCEF6F179BCB5F52 +:10DE300071FA2FC679543BF9FB60491F4874BE57ED +:10DE4000DD75EE9447FBF26437C723D105D2D54187 +:10DE5000AE379D55BC097DC89F3D32F345CB3C7C18 +:10DE600096BC22ECD13AA0533CA732E86398E2B7C3 +:10DE7000211D0DAF81EF663CC6D077FBB8E879F085 +:10DE800098FAB9313F1897E8553E97CBF7E3287ACF +:10DE9000D82DF1F9878AEDDC6E642119F13AC7209B +:10DEA0003C6505CF2732E38FECB5778D7327B682BB +:10DEB000E7759E0BDEC6CFB9A3E733A7F9EE163C94 +:10DEC000EF99D3DC6F3E9E7BCE29BAF8434C77ABFB +:10DED0009DFBE3515EFC50227DF6A6B75E54E32124 +:10DEE000DDF1E6467A9F60AE9BEFBF7359A78AF8D3 +:10DEF0000F305DE3E756615ADF6DCC27F20D2AFA49 +:10DF00001D6E89846FB81A72B7BE18BE1AD5BDB916 +:10DF1000073B5F42B4051AF45C3A1B32DA35F95E0E +:10DF2000E679DEAE0B0E4EF1FB478A83D6D5BD6E89 +:10DF300007C1C15827D4247C74C149BCCF66C0A591 +:10DF40006BDDF1375F85FEF8DEE4DC1CC7E80F7996 +:10DF50009C3C9F57349C3EC12290930BDDFE1FB921 +:10DF6000A1FC7AB7FF2E4CCB1C9D839521C437555D +:10DF700098AF900317A5001C3E1A14B83819E1D1C8 +:10DF8000D2F782F4FEC34E2E0F0EA71B7A6DAB1B89 +:10DF9000E99BBDC8F55AE3F73256ED387EFF8D0098 +:10DFA0009F8F5EE5EFCD95CBDE6BEE22FFB2CC62AC +:10DFB000D921467A58F80D1E76DBC47BD17C9DF3BF +:10DFC000140EEF798DF174CF6EDE52D9F2BEFDBC26 +:10DFD000A53C7E95292D63AEB7D8092B045DF7ECDF +:10DFE00007FD1AD1FDCC5F3A99DE2DD9A9E993C876 +:10DFF000CFF138A7B3F953FD32C6FD4F582D911F0D +:10E0000069FC516F532BE4E787137DC8AEF3EF5CD7 +:10E010009C89EF9754B4703F67AABC28E33F207DEA +:10E02000683FDFEF31BF08E1E4F27B5DA6F39A368B +:10E03000B53243477ABED5E54779907FBDFF5DC4D1 +:10E04000A7E1E730F6DDE7400FC038CEFC5BBC3916 +:10E05000481FF90D4E3FA50EA6C4815CCB5798030F +:10E06000D3548D294E4CE39803D3ECE5427FAA9D0F +:10E0700045FA8327274FC3F7C4F39B9FFC14DB1794 +:10E080002A917D92899EF29B5FFD82EEC3F9F3286F +:10E090004EF75B5B348BDD39BAC19AFF7693359FBF +:10E0A00011B1E6330F5AF303706D267D73FF1E1E08 +:10E0B0009F527A9ADFEF7D1E60A0223CB6D9493E7E +:10E0C0004E296DCEC67887D34FBB6D58BEFBEFDCB3 +:10E0D000EEEEDCEAA47725F7BD17C7E292F01D6AE1 +:10E0E000E7462C3F1DD7908DFE45A84F714BB0BB26 +:10E0F0008E40BB71E7A506BD8629BE69E73FF8FDE6 +:10E1000094CEADF630C6519CDEF5E4D3489FA7B758 +:10E110000E207DEC792964C37E43F770FC4F88F3B1 +:10E1200058E454E916AB3D7E42E8011D27B579E875 +:10E1300017BAB8D6BAEE4BC2D67CA7A87F1B337DE0 +:10E140004FC7F810EFAA34DC6737C57EBFFD73C137 +:10E15000174F3DA519742B8BF71E9937A5FBBEE20F +:10E16000EEEE73DB2503808E4A111643BABF974645 +:10E170008DDB850FD17F92382FEBFCAD4CF03955FC +:10E18000556489EFE8D2FBAA7C69534DFB5141ED00 +:10E19000BE947CD257F7A5DC66DA67CAB61E48B9CA +:10E1A00019FA6BDBA2D0EFEB95CD79E2810949F842 +:10E1B0005D6EC0F96239FAE7DA1A5EF2603DD08B23 +:10E1C000C79AE3BD0A6BC7A54D35F1E9D7A54B83C7 +:10E1D0009FCA740E9FE7725A72F11E46692DFF1D89 +:10E1E000BED2861BAEBB1AE1BE9EDF4FCF56589EF5 +:10E1F0000CFC53B6FD86EF8F86EFC1C7C6F9703EA3 +:10E20000D9F8242DDEBBAD3F43F776EEB571FF4460 +:10E21000345C467B387EEFFD81AB08E512F4F7A253 +:10E220006D2CB53F68037DE4C4E4D06B374395D3D0 +:10E23000ACE10F57535C96959E803E25D4B73A3794 +:10E240004BBE8DF47579F6B5A85AFB97513C3A94BC +:10E25000C7B4378AC3D67EA2F17CA547327EF76861 +:10E26000A4995EA2EBF59D11A2DFB72A5B0A72CDDD +:10E27000A4EF971DADA178D8E871C819688A3BC191 +:10E28000FDD14B7CEC147A02931CD9225E7C28CF02 +:10E29000D3BBA748974010A597B2A95E84EBB56C95 +:10E2A0003AA6CF4B91076499CB03F2336D8B277954 +:10E2B000D0A6B73EF173A4A3FAD1741ED65FDCEFEB +:10E2C0006EF346E8BD58E37771DA749E2F69765293 +:10E2D0003CD5E98F349297CB308E13EB3FEDB4D918 +:10E2E000405F3BBDBDEF648C0B6E6BE0EF8A9F6AB5 +:10E2F000E83B59FB8AFD379AEF8D7DF108FE13DF6D +:10E300004FF5F88B3DB8DFACE071D3A97D2B332AF4 +:10E3100063E0C96897A45566A0BDD279ABCBB7912D +:10E32000EB53E90AF9DDD3C8AF922FFC49F7E9793D +:10E330007778A0BE1BEAFAE1FF3E07E58DE877FC9F +:10E3400040F6DDA10FED3E1F5F9015A0FBE3F40347 +:10E350003630FE7C854514A0B7F9B8AF8CA13CC916 +:10E36000CFF9EB258A235CB0C6BA1E7CE7DABC1F66 +:10E3700016E12F290EC5B8B0064A8BD65BCB8B7140 +:10E38000FFF050BC17C5CB94D459CB198B901FAD5F +:10E39000ACFE4B7B2CB87DCA8CF5F96B3C16B9A34F +:10E3A00092DCF950CEA3F595A23700D29BC4FE1C97 +:10E3B000BC33276D01A41D4B27A42DC8C47BEE7C64 +:10E3C0001F23D38EF898BF8F573A954506F1777182 +:10E3D00018EE8FA5CD526434E61D2CE419CBBFE3B3 +:10E3E000FB20B86EF33D3163DDB85EF377F626C7E8 +:10E3F000AB71CF10D76B2E2F137028ABB75BFC3AE5 +:10E4000013EAA590FBDB787FA995DA55347E69B7CE +:10E41000F42BF65FD8B79913F035A168838C8B790C +:10E42000A84B8E872F89750FE5B080DF433714F432 +:10E43000437E7D10F5CFFE02C039249F849F804526 +:10E440001C305E5C66579ECAB397F3FC3E4FE08A71 +:10E45000DA8160AFA9013A879A2FE7BD8CF71B4795 +:10E4600026065E42BCCCB7F9072BC4B7FE11E417F1 +:10E470005DCAE1F0F0D8CA4B2A63D9C502BF3F9309 +:10E480001AE85C3EB48BEFA3EEAC4ED5ECF7FE8BF6 +:10E49000904709FB5BE95E4FE70E89EE133F221DB3 +:10E4A000A1FBB68F5CE96568C7A7019E50EE3E22CE +:10E4B000B115F85E5E56E3AC452F219EB3E27C7841 +:10E4C000DE5FDE38492E77D1FAB9BE155FB901CFCC +:10E4D0008352E78D1C8B740EEB9E772D7CFFD0E36F +:10E4E000A5F1FAB938DED39687D2178FC2F1F316A9 +:10E4F000BD847C383A8EEEA1A702ACDC7D285D8D10 +:10E500007A541ACBD887FA60DA0CEF58F4B93FE4A2 +:10E51000E1E324DBE479B350CF1BCBF37D7E2CF910 +:10E52000371211AEA57152ED6C3ACE17BFA35EE85B +:10E53000403F82CB84EF299519387EEA509E2669A8 +:10E54000118A0F3C64E0BD99C7E92DD119C9E925AD +:10E550005F4C4A453BEE501B18D420BF0E0D34ECE7 +:10E56000CC888BF4F06123797D61F72DC9E0F75FEA +:10E5700092061BFA0FAFD7A1FA133251AEBEC1F506 +:10E58000F14F5C7EF2575FA6C58EBF4F48E0780A18 +:10E590009E8B636193FF3838FB33D21383E73C2CA7 +:10E5A0006CDA27F0BD4D731C7759D17EFA1D847249 +:10E5B000D642F701CA1BAC71E797C5C51ED7A0F3B9 +:10E5C000E0391B0BF525321E88F6D721A973D5C279 +:10E5D00024BA174BE73BC1731A0B99C60F9EEB6326 +:10E5E000CD77CD3385FAE9AEC7ACF59A3EA77A2C44 +:10E5F000A7D583E3B4EBADB48F04CF29D4CED86FC5 +:10E600003AC2B6900AFCDCEEE5E51DE23CCFA86F0D +:10E61000F4D73E5B13F7DEF8BBE86D552078002E8B +:10E620008F369F217F7459F33E828B410FDDF08935 +:10E630006721137C52AA5B2236E0ED690F6EB87B2E +:10E6400014D890C9FB051F8736DDED9F08E5F8BBA0 +:10E650000F26BE8ECFEAE27312330FD9642E174213 +:10E6600075774F9D68CA8BFA5DED439BAF980A346E +:10E6700095358AB7BFE6C1275E594E4E8B1A11DF1A +:10E68000DF3938CF6DCA3BA2F22EC88F36E5F5A828 +:10E69000F2A4A8F2B4A8FC405EBFCD1D192CFB402B +:10E6A000DE3FF8D415F8FB9E6DFD2273F1058F3522 +:10E6B000F2B62BF0F77CCBB3F8EFD356344B3EC910 +:10E6C000243F2BBACEF35BB5F9A3100E2D2FA31C5C +:10E6D000286B9274D4EB5D0DDB2394C7765E53BB3D +:10E6E000066E3F96351CA176BDF63FD2467C7CEF88 +:10E6F000C8F7A9DEF9CE9FD80CEBEF5BF5761E7557 +:10E70000440A2C4E48EE7E7FBD6DFBDBDDBF2F0A39 +:10E71000DFDBFBF90F901C8DBA071EC4F9B8BAF9FC +:10E72000C480E3BD23CFD27BB47F1CDDFC16AA03DB +:10E73000F14BCE2C53A0DD9FCB8F8F437D0BDFB4ED +:10E74000C57DE36752F812DC8F1E65814B70DC5B80 +:10E75000CB87EFC39F4C38ACB63E86EF956F78F011 +:10E76000E52B1498DF6177EB20FC09B74D096FF0BA +:10E770007C722B7F5145FF1DE1E7F0A0D64136C8E2 +:10E780003F99C0A6537E78EB63987F3DE104AF3F8D +:10E79000BA7590ACA30972F28AA990DFACC7E6F70C +:10E7A000DA04AE371BF39B36DCFF53840B2BE3FB01 +:10E7B0000D5E3376803C9D5B726ADB6680C7DC1F32 +:10E7C000C5939CDBDC76DD55790487501EC611A607 +:10E7D0000A78D37E48725D217DA21FEE817DBAF159 +:10E7E000E91EDCE2A5FDE2D2CAEDA837A4CE1D45A4 +:10E7F000FB45A1C72FE9C9DD69381952A82FE93AAD +:10E8000097EBB28DE22352EF72931EF5A0F83D0311 +:10E81000E03BA20F97C0CB36B19E6D09DCBFF680FE +:10E82000671AF5F39EE47FC42163CA424EF2A7C57E +:10E8300091BE72F306902B20D7D78979AF5B7B0905 +:10E84000F9296E463FF128FCEEEFD76754B7FEBFBB +:10E850002E03F2AE6EBB6EDD2C7F3FF3B9F6BA0D20 +:10E86000BCDC905BEBD2797B63BF4AADE6E3A43EB0 +:10E8700078C9465C47BCC2287E7BE1EC111B97D16E +:10E88000FE7F2DAD9FF9FDFDD00E3F5A3CC4867A28 +:10E89000A9819FC2E1FE5712603D3789DFEF35F055 +:10E8A000648C4FB7E2517F90417F403B353140EB64 +:10E8B000077D620C0F6EE0FA04D21633C19729ADC2 +:10E8C000E3F0FBFF2038B5FD2BE0F44F9F7747C9FD +:10E8D0002190370CFB2F5F7ADC72FFED3F01D123D3 +:10E8E0002A700080000000001F8B0800000000005C +:10E8F00000FFC57D0B7854D5B5F03E73CEBC929920 +:10E9000064264C9249C8E38440081071124344F0D5 +:10E9100031848851693B50D4D87A71203C022699C1 +:10E92000A8D5624BFF0C12790918342250C181021C +:10E93000C55BF506458C1A70448A7AAFF68EADB782 +:10E94000576C7FFF08888F4A32A2F5D297FDD75ABD +:10E950007BEF64CE24A9B4B6BDF93EDCEEB3CFD9CB +:10E960007BEDB5D76BAFB5F61EA6F54C0A5CC0D8EB +:10E9700066256ACEAE642C7C48F1ED61F007CF6766 +:10E980003B19FBF7B4A0D595C9D89FF1EF0AC6E6AD +:10E990007EBF29275806ED8D2318CB612CF5BBCF00 +:10E9A000D4DE00D5B94B3F7A7C0F7C3FF77BA98C36 +:10E9B000E903EF438F8CC1F7EFBC6D5BCF2E84D2A0 +:10E9C000D2193579A0BC86F956C07BEF98584327F9 +:10E9D000F4F70EBE7A096355DFBBE5353691B1DB3E +:10E9E0005D2A6393185BABF873988A250BDBE0BB59 +:10E9F000F02C4B644F11637D1153D80CFD75B82377 +:10EA00005B17C1B81DD795F9C2D05F1F637E86EF33 +:10EA10002D4BA5F73ADC3D4CC3F64B741740C20EA4 +:10EA20007EA1FA19D4E3375A22BB14785ECEC2769F +:10EA30006C5F323E1286FAF3300E7D7F634A640FBC +:10EA4000B6CF828FA0DE71A3371286FEEC2C624710 +:10EA5000783A76FA73321C8CE5AAAC05E1EF28828D +:10EA60003A94592BD9CD0107E2CF3F719673000F2D +:10EA70005F7799683EA9953D4FFF37F4C7D6DB7D98 +:10EA800063A0B0E1AB586FCF2678993B5885F86604 +:10EA90001AFC03B8EA1FC889ACC3E7CC5785EBB1B1 +:10EAA000DAE99F47F0FF205547F81FB6B335B60A9D +:10EAB0002815D666CB00FC0B7858FB43000C633757 +:10EAC000E3008097FFD770D6A9C3F32B5D0AAD078B +:10EAD000FCF96D558CCD67BC7DFEF2D477958958D5 +:10EAE000AA516B1A3C5B73A5BFC746EFB13F8FE2DB +:10EAF000A50DFA0B32F1B725EE44BA09E27769D8D1 +:10EB0000FFEF9DBA03EBF0FD445C76F8BE74E0FBCA +:10EB10003A17A3F9CF5539FCAC355547FC4AFCC828 +:10EB2000B24EC2D7FE903F713C394E72BFF7BAFC6D +:10EB30003722BE00EFD1740FE245A5754D86D7632D +:10EB4000896FB043FBDC56D57D37E033B8CC49F351 +:10EB500095F0DE9C1DBF8C150FEEFF746A739586D1 +:10EB6000F35FC6E99D2DB702E212F16219A8035DB9 +:10EB70002C64F163266588E75AF445847F5147C2C7 +:10EB8000F7F4DF2FAC89EF497E61BA9204BFA02B66 +:10EB90005DD170DD820A5F378B253E375036186EA7 +:10EBA00089CFD582EE245D24E37B35E27BD2607C85 +:10EBB0007B2C3DF9D86F709995F094DC3F6311FA86 +:10EBC000EE213BF00FD0DD1645217ADD72576A64E5 +:10EBD00025F2A73DBE17F1193A7C15AD77EF9214D7 +:10EBE0009DC12BDB2C30419433879D9C8F4B7A4AFF +:10EBF000909F7A61CE7E589FDED7D59D614502C138 +:10EC000058F3EBEA2EA4FFDE67AFE6FDAC48D5195A +:10EC1000D4438861183714FE432B03BC9E34C52CA3 +:10EC2000345E17E057C209FF7AE15F43C580BCE854 +:10EC3000C3061CBF8BCB0798E1121AE7DB296C1DBA +:10EC40008CDB6C52FC26686F5E3A3EB292C3614325 +:10EC50003E6A1420359B589B5231C0F7CDA6132530 +:10EC6000B795F1360DDEBB85F17581F78E2A005F11 +:10EC7000A36D7D4C45BA45FA87F6A5D85E3480FF72 +:10EC8000E6F5BFF913C2DF7CC048178D8F19E7B1D5 +:10EC900034919E8A06E824B592E389D5B0C81880DD +:10ECA000D729EAA9B5B1888A785A56CD4E02E966C5 +:10ECB0001EE99981F4E3ACEC64F3A10C7DC0FC1176 +:10ECC000807B4AF7CE9746C2FBEEDA583E4E37B409 +:10ECD000ECB68B4E5D34B0BE12CE4BBA37A9CC41E8 +:10ECE000E3D177008A7FBF83DE1B37FB82C4F26EDD +:10ECF000FA2ED3A412BDF6E023E41BCD9FA3C038A7 +:10ED00009B978C32E17AA6827C43B9BCB07DECAE95 +:10ED10001584677F09CAB707D380CE099FBE2A949E +:10ED20002FA5EEEA5FBBA0BFA7DCD5FF8D258E1314 +:10ED300070E2F44790BE48A6E764BD23DFCB2E6E99 +:10ED4000296F710CFF1EF017E12DBE359DCB0F4DC5 +:10ED5000A1FAA2FF30EF5C47F0694437B76D2F226C +:10ED600079DCC0DA89DE1A59C482F4BBC8C6C2692C +:10ED700040178BE0B57428176FB1323D61FD9644A2 +:10ED80008CF546210F6E6131FAFE967D49ED352CEA +:10ED9000EA84F6261B8BA662D9696C6F667141EF17 +:10EDA0007FB6263E671D7CBE378B7577D744D4204F +:10EDB000CC7BAB1D745706BED04EEB3365F94E5A73 +:10EDC000CFF40A7FD13DA84F5E35FB7601DDBE272B +:10EDD000D64BE2E75E57F5BB88F714D544F38FDFD7 +:10EDE0006325FC9C02BD8DEB7F9F9BDD3C1BCADE37 +:10EDF00056DD3B7A34A2C95530DB3918CFEB9EB3D0 +:10EE00003720DDB8DD26C2B77C7ECC65A67AD5DD9D +:10EE100002FF2B5223BB8A08DD13919EAA46497D2F +:10EE2000CA26CE82FABB6656D709F5E6EB1D41EC41 +:10EE3000AF07ED07A817B8B9DE28705B687EB22E61 +:10EE4000E72BE906C6A1FE522EE2A584638C5BC8BF +:10EE500041B6897F27F4EFE625293B49FFF6D3AF7A +:10EE60008911FD96052C88D7E7845C794ECA9536C2 +:10EE70002B972B9A6BEE32A83FF741996F1DE095C7 +:10EE80009582DE83EF1B3F4AD1919E5EF9E85FEFEA +:10EE9000FD19B49FFDC0A25BA17D01D218ACDB734C +:10EEA0000A9747607F30D48F8DC0F6386EE3C1B1CA +:10EEB000647F1CB408FB46C8CFC6B4E0D685D04FEB +:10EEC000E393993EA064F6BC39F2E85E6C3F64F7C8 +:10EED000ED817E1B53385E1B9F1B49DF3F610F4E48 +:10EEE00077C33C73AD919F3C8172E3052BD97B675F +:10EEF000597411C27FB6D3AEE07B27705EE95042F1 +:10EF00009B82F3EA76923D047C9AB310BE3BB936FD +:10EF10009BCF4BE0E9E48609C4179BCD7CBCF0B3E2 +:10EF20000ABD7FC21C989103F5134F97FB564053BF +:10EF30005FC012B5003D87EEE3765EBD49DF8178A4 +:10EF4000628753095EB91EA18D8B67627B68E9F207 +:10EF5000AFA37C1C8ECF51DEB304B9D9CBE205C878 +:10EF60004FDB1A467546519F748FF3915A655E5870 +:10EF70007CA01B177FF79499E3357EC84CF47CBEC8 +:10EF8000FDE37CB52AAE7F709C10C86526F98FE43E +:10EF900072425D1DAACEC8FE0C3D972DEC3A63FB74 +:10EFA000EBCEE01D6EA0BFE6FBFFE79D6584DF387A +:10EFB000C945D69E497C79CAEC9F8B74EBAE895AC1 +:10EFC000E627E8F30D82AFEAADC2FE63514B221F84 +:10EFD000CAF6AA6A23DDCB72BDA07F678CCBF7C1CE +:10EFE000ED26C11FDFB4A21E9BC2416685A8471C47 +:10EFF000D8BF4EFD4FF9206AA9877AE1F2A8659142 +:10F0000028914F00DF511BCCFBD45627E76F4003FC +:10F01000F6B36832237DB94805FBB5029FEB5D3D31 +:10F02000B02EA79F7673FAFA236005F03D8F89F71B +:10F03000AC60EF821C7BA64D89E27E60DE16EB2E73 +:10F040007B11F2B55F75E27A6E57488ECD6B9B5699 +:10F05000B215EA4B0F5C40EB9F3699D3E5D2889B03 +:10F06000F4E214211FEBAD110BD9DF3F5118F2016F +:10F07000F44F7674237C945331180F28D70DF41075 +:10F0800049A8835D34A593CB5506F29C25D84B52F5 +:10F09000DEA31C6749F69F913EC2521F71B9C7F4A7 +:10F0A0006C947B522EDFEB0A74B949AE8DCEC6F557 +:10F0B00085F5E47273BF42786D622DA44FA41EE8FB +:10F0C0001F57E891D36A98EB2BEB262A5F7717D16D +:10F0D000784B5927E913A95786A383D7BF840E7E9F +:10F0E000867400ED8D1FB0E865305EE372166D9A90 +:10F0F000C84BE744D28F5C4FDAB89EC432E53CF48B +:10F1000065B27E4CD687C97A30DBC2F59D5C6769F3 +:10F11000CF644FE776C094E51195C1FC36A6F93F60 +:10F12000CE9C3460D784DEB2D9F40BB11E60A3E06C +:10F13000BDC569D36ECA86F690C6FCC857A980972C +:10F140009DF07CBBB07B6BB339DD7B2D9C7ECD5AB3 +:10F1500080953B705D62B4CF8D673217D2A3C4E750 +:10F1600076277C5781DF71FDD4FFBD8DB5A5247C4A +:10F170005FFD9C9DE4EAE7CF3A2356B24782856E55 +:10F18000E82FEB5756B2537B9F73923EED15FAD0A2 +:10F1900083F628D1CB2AAE5F715D272135558F6468 +:10F1A00048FBCA352351044AFBACC9CDEDACC1F6CE +:10F1B00090682F8A5DCFE9CA4AFBCCCFDD3D7762EC +:10F1C0001DE061689FFF8F58E7D081E9E5DF87E7A1 +:10F1D000A180C3C7B11F2C477AB5AADFB9DE06F4F8 +:10F1E00035435D1EBF0BE6D194EF70A19EAB29FCA9 +:10F1F000F52F6F84FA8707CCCC8AEBBC677A1D1B8E +:10F2000035BCFC5D12319FE849E0975BF619EB4D88 +:10F210009DC67AA8CB582FC8707A4E4F20D9E1FBF3 +:10F2200033D0B5D5DAF2C14E80D7FABC95F4D1A768 +:10F23000EE607106CA5B53FC18E2D95AF8F144F447 +:10F240006F84BA3F51B0B402EDC4CA38FE91AF3FEB +:10F25000B7CF2B740D81B701FC319B89F00CD63AE6 +:10F260002F49CE85049F782CFE0F5F84F92F9A9D3D +:10F27000E2BA9B9EF8674EAA427B926064A12D572A +:10F280007F88FB2D786F09AEFFE959F01EC0D5B01D +:10F2900085EBC346164B43BE6D06BBD3064B7C477E +:10F2A000065F875BDAE25551F8DF8E8CDA7108A7CA +:10F2B000F6272D80F4B11AFB4DB093AFCDE07AE084 +:10F2C000967D76D729031EDD867AA82BC7752A91ED +:10F2D000FF84FC61798A96B81F7A57095E8BF86BB8 +:10F2E000B2F558A6C1F857FCE93392F78B97CDA732 +:10F2F0007DC4805D6D25F9B4F8AE203D7F692BDFBC +:10F30000179EDE6AD711EFA7B7F3FDE3E23C47C4CF +:10F3100006FF7B859BDBDB8BE13B45198CC764BC1F +:10F32000BDFFF0555EA4A3F7191F2FDCC9ED8FF7C1 +:10F330005D80AF62FE0EF6F77E17D8EF0AE2F9AAFB +:10F340000F512E2EDEAEFAD04E60879CE48F59BC52 +:10F35000FDCA710B1DD8DFA723A6A15F68C795E87A +:10F3600089C2F70211EED7895D01CFB51D17931D34 +:10F370007774BB95C3E9B6EDC5795CF12795F84A7A +:10F3800033B120DAC71D16FF38E467FDE13D337065 +:10F390005DDE9F956BA2F71F57980BF1E15E968596 +:10F3A000CF172B5A00F9B761CB929989F64E6A862E +:10F3B0004AEB35AD7079568F83F8E97AD4A34DDBEB +:10F3C000817F70FCD96FFFF2464F223FDD5EC54C56 +:10F3D00009F6CBC35F237AC2BF28E06BB1C0D75711 +:10F3E000E52B6BAAE48B961294A38BEF6E29710D1B +:10F3F0006157F4F3C5C39C0FEFCB50B8FF202FC368 +:10F40000B0CF186E5FE62835915EB1F9987F0F9402 +:10F41000D9B02DC6FDF7810C8DDA0F64707B5FFBD0 +:10F42000DD6DFB5E87794DCD086ECF807A21F39735 +:10F43000E3BAEB71573598B18862B2BBD8C3566E48 +:10F44000C76ADC8EDE9CC9F6AE4BD88F77627F9997 +:10F450002417F6623FBDC7FF780CF1DA5CF0F14487 +:10F46000B40F42E73EB3A01FCDD1AD903C77F80278 +:10F470000CE925D43D8B2D281B90C3211FD713C920 +:10F48000F3FA5306DFEF843C71EAE7FD119C7F3B02 +:10F49000DC9C3EB72D4B213FE4364FC48E40FFB578 +:10F4A0007C2AEDA525C2EF67DBFD945F45FA8E2827 +:10F4B000AE3158D7397FF435CC8DA830CE87BB8B91 +:10F4C000C9DFD977609A4F8536C7EE1FAD198578A9 +:10F4D000EA32FBF07D87AF270DE7F7E1EE9369385D +:10F4E000BF86DD2ACDBB21F249D6C2B201B9F033C5 +:10F4F00025F83ACA01E6521C38BE940F1FEEFE34BE +:10F500006B8183FB0B487F560E8D97A7DCD37E8ED5 +:10F51000DF5F71395F978F1EB74650EE7D6407FD40 +:10F5200096206F3F72727D772A43EEEF3A0B50DFE1 +:10F53000F4D76F2A35A19CF88E8BCFDF63E92C407E +:10F540007EFC8D62EC67E91A138B806C5FB206500B +:10F5500003F2E8A3479F294079FFE19E670AE62767 +:10F56000C097FC9D2C7BE578C26F26FDA81E4B340E +:10F570000FC79BEFB3727FE5307E54F93EDBC2FDCF +:10F58000A17D3EAB8E7428BFEB6B48F1A37DDBC73A +:10F590006C24FFE6770BBFACDF3FDA83FB18F97D05 +:10F5A00052FF151E4E4F4A9742FE83D4B238C9E32C +:10F5B000BF59DE7B603D13E43DACF3BF215F34D91E +:10F5C000E2C74632A20F0BE2CDD2ECD0503F65AD80 +:10F5D000E4F415BFC344FB2A4BAED781F2EC8A9208 +:10F5E00094361330A227256D22C601F2734BE9FD34 +:10F5F0007035A7FB7016237F5B0E6B51485EBBB85E +:10F60000DF3E6F3273AD83EAAC11DC9EF132DF1660 +:10F61000B598D65D41FF90C487D40B483F281F3F63 +:10F62000526C443F4AB74276A76AEA9C8BFD0E476C +:10F630004F1347C8FD3FA7A7FEFA3F899E268F18A4 +:10F640008E9E823AD193D736343D093FF179BFCFB0 +:10F65000C201DCBF660B7CDD27E44EFC0E9BF49BF5 +:10F660002B38DF99A2BF9936475445FDE1337F9C83 +:10F67000E8FF7D18EC5FDC27E5A0FD0EE5C895F3FB +:10F68000745A3716EB417F41EAC536D28FF79A623A +:10F690004568AF648F6FD98F74913DB7AC6225ED2B +:10F6A000FFF2DCA80F50B7921F745975E0D488049C +:10F6B0007BE110DFCF34DFE5A7E7D3BBB97D101ABC +:10F6C0006D217B38D4A584719D9B039608DA416B2C +:10F6D00015EE5F096FB0EB3CEEA3AFA0B8CF0F748F +:10F6E0001E178A48FF6FCF8EEF23BD3538C8EF91C4 +:10F6F0001C3F3AF885CAC71FC368FC8E721EAFEA6A +:10F70000B85AE7FE15B17E1DB3FC396EB407D618A2 +:10F71000F959C685FA9C8018186FFE7A3BAD43AE46 +:10F72000CAF1CCD26D5CFF0C960BE467CE9A2C1616 +:10F7300046C46FFAF91C2405D67345BB8C3739CB08 +:10F7400002456879BFBBE9B7AFA400BD66A19F8E33 +:10F750006FCAC268F7937F98D7C97DFCA00900C91A +:10F76000C5D6FF5C577369425DBC3FF0FDDC6B6B37 +:10F77000F248EFF6B723D8A08F65DD6FD7311E357D +:10F78000D0AE81BD6BEB52F8F761C7B5578E063C22 +:10F790002872FCFF5CEB477FA19D19C64B844F4B41 +:10F7A000EADF0CFD3B74F97EBCF64A78E1C10A59E8 +:10F7B000BF66AD1FE0BBCF6CEC8F502ABEC78A1C62 +:10F7C000EFD6AC6DEBD6E70DD8056027EC1A913972 +:10F7D000601FAC7E7B66FB853056AAEB530BEA5D5F +:10F7E000A9E7431E85EC8F647E3D20E4C3DF2C57E0 +:10F7F000F54176F4811124577B66204BC2FE83E4E9 +:10F8000076687980A13D07F64817C2DB7BFCE3D31D +:10F810002F427BEFECDF1F1BA9E37BB7CE45BB3745 +:10F82000744E23BA0DED53230AD0AD4DF00BE871A1 +:10F830008A0B487A5AEA1274EA0E338C73741C529B +:10F84000268589BE5A0AAE83B5CCF7F85F4238E404 +:10F85000BE3279DEBF1EC1F70FA1D2EAAD25D8FFB7 +:10F860006E85A19DB0AEF444D602DA37BD9BB530AB +:10F87000E1BB255D0F123E97EC330F89C75F8FE028 +:10F8800071DEE6679FF6A3DCF828A2904C68D022D0 +:10F890006BA740BDA1C1849620AB8CCCBB91E21C70 +:10F8A00075163606E67704ED268463DF37C353709A +:10F8B000DEF04F8147DB028B489F6EABB339284E99 +:10F8C000543AFF56C2832BC58F7858575A9D83E30D +:10F8D00034CF9AE1A2F808D871D8DE7CD7B7C82F08 +:10F8E00024E15AD765AE453BA70AECB9A700EEFC68 +:10F8F0008C6B6A7DC0C723D5FDE5B73B305E3EB457 +:10F900001CFF6E26A78B362510FE4625F94159A20D +:10F910005FB3B08BDB8D9F8DB018E22B9F8DE0F62F +:10F92000ECA5E1D874249FC35A4F2ADAD321E6FF0D +:10F9300004F7CF2CE0D0F7D03A7179E469D5C93F0C +:10F9400066F3F4DC7B21B65FAAD1FE85693D0FE04A +:10F95000B8BD6B3DBE754CF001D6EF2AA37D4FBDFF +:10F9600027A87832F9BC707D7B9FBDAA1CFD88D288 +:10F97000EE5AFBA89DF4E65AA77E7F2DCAD3DF6915 +:10F980003C1FC0168F4D877E96FE3E83C65D6B8FF3 +:10F99000ACC5F50FEF54A9BDD8117460BF4BBEB90B +:10F9A0006522D22B73444A508F9A3DED0CE918B66C +:10F9B0002BE42FB179020CE3C4D3C3F33405F5452E +:10F9C000923D331DFD55B45FF190BFB65AF0C71894 +:10F9D000A082D3366285B63F8F18B06F5EF9E31C04 +:10F9E0000D1F4ABBC764E3FEF39ABA1486F62D5B7B +:10F9F000153F66427FBD27C6D00E6EEA54689CA6AE +:10FA0000D2272DB86FB9A593F37748EC33007F0563 +:10FA100068578CF1A40A7BA08DFB3958ECD848C4F8 +:10FA2000F3637C3D1983F712FCAB8CADE0F240F43C +:10FA30006711718626E157024D48ED3E8FB45BEFAA +:10FA400016FDB7F3528CBB5989F955C46BB962F0F6 +:10FA500087CBF22AF17DFA91F80CE4DF38D017FA5F +:10FA600097B62AB36EFD29CC6FEBA4F13E34C1BC2E +:10FA7000404E6A053E075204BC57767D3203E98644 +:10FA8000D532E2D7E6AE696A9383C76FD05EC84EBF +:10FA90006DD989EDD93797927EC6F8C86C78FE3556 +:10FAA0000FE7B31C07F7D779EF0E1761BC33FD489A +:10FAB000E0D69FE2F817A490BF351BD6C69941E562 +:10FAC0001AF46F7959F98BA87FBD33F50A8447C6BC +:10FAD000F5302E38AB8CE438D5337C8A7F179437D9 +:10FAE00078DC340EECEF6A115E7C1E710CC419D107 +:10FAF0006F87E3621C0FCBDE9CA8467E7ED0E77B3F +:10FB0000904EBBAC2EC4D7CCAE97DF427D3BD3C664 +:10FB10003A29EE9A64B7C4D3BE19443AED3B737ADE +:10FB2000C73D08D775077D94CF92648F5C7139B754 +:10FB3000CB3FDA93AA233FEC12721BEC471E7F796E +:10FB40009CEF2393EDC8EFF6AF2FB723FBEB7F7746 +:10FB50003B92C317DEC3F328A47C0F897D5F5FC38C +:10FB6000D934D45F2B3DD2AE4DCAF7D82DF23DBA71 +:10FB700087CEF7D076F2F80F864149EEBA2D22AE45 +:10FB8000E5F7CE43FF87BB84E4C02B7B53C34837E4 +:10FB9000673BED6497696E4B14E16A7BDA1AC13CEE +:10FBA000883645E0EB90885759441C2CA344478382 +:10FBB000E2A02540723FFCA499C7ABD2228FEE850C +:10FBC0007AE3E11C11CF62D47FF8D954C277638AFB +:10FBD0009E8EFD37FEFB088671AA3E180FD7F909E5 +:10FBE0007B70BB87E25ABC7FF68255E7F1B3688928 +:10FBF0001BF0B033C2EDBF93A5A6A805E6BD93895F +:10FC00003C9FF532AEC5E7D9B761248FCBA03182D6 +:10FC1000FBB2B5DC5F542FE35587B91FAE5EC4A5B8 +:10FC20004ECE5EF408A658B4292DB5B84FFB7CDD46 +:10FC300034F29FDF79FF2C2AEBD718FDFD8BD03FE4 +:10FC40005F3C103F967EF7F9CC67E1F6F380FFD07A +:10FC500004F68CBE46AB46FD59C45C77A33ED0C3C8 +:10FC6000B07A1743D906251AF10A6019DED3D67A7D +:10FC70005270BD57B799486F85DB4C7E7C4FD2CB15 +:10FC8000AB1EAE67DFF570BD03A88EE038B26C33F3 +:10FC90008B7883E86F053345B13429BC5CEDD26ABB +:10FCA00087D2DFB2BF36738B6D1ADACDF926F277C1 +:10FCB0007F6EF1D791BF38A384D6A9CDD9B2A696CD +:10FCC000B7132F7D6E8F07A8FD328D1B964CCF404A +:10FCD00079FA8287C71792F1B6B0DD584F8EC32CE0 +:10FCE0008918EBF52C3836A798C70D129FBF20F462 +:10FCF000C4E7EB8A04BE7D1694BB72FE2BF238DE9D +:10FD00004CF9BC1C955F5D8774300AE3CA45587294 +:10FD1000BF2ACC84E01F75994721FA4882B7CDCD20 +:10FD2000E929BC96FB21FF5AF893E1FED09325F810 +:10FD3000D8EFC5B865BDCB4271E8F3F597A4641A56 +:10FD4000F7B7FDF5BFFFFE96EFE7D7AA22BFC6457E +:10FD50007269BE8BCFE5A4E2DB1BC5E70EB01F7056 +:10FD60001E6BD50A9423D3BFE9A079341F063982CC +:10FD700071ACE53D05A8D79BAB7B4A305E938C5FA9 +:10FD8000845693F20CDE9BEF81FD08DA0D6B8CF14B +:10FD9000B8C1F1557F616626EE7B4EEE7F19F5D72F +:10FDA0007E3BE92FF8BF17ADC8FFCF16915C8B38AB +:10FDB0008363312E144A89EEF87111DA31DC8E6AD0 +:10FDC000EAB6EE443B717E5B427C0FFFB3DE18EF78 +:10FDD000636B32C8EFCE3A8CCF1B1E4EFA6E50FCCE +:10FDE000AF9DD665B325380EF91DF410E51D9C595D +:10FDF0006262B8BEF5AA6F112AA93376A37D7EC6CA +:10FE0000C9D76B46A6D43F3EB2BFFAEB83D6D957CB +:10FE100082EB5C6F62C1C47E9A709D617D1BC53AA6 +:10FE20009F79FAE2125CE78FF75F5C82EBBCD9DC6A +:10FE3000EE47BE297507AF41FC9CBA3240F615E685 +:10FE4000EF201F9D2F3DDE94448F37FDE3E8B12E58 +:10FE5000311F32593F36F4E3CBA81F3D163D0FE565 +:10FE6000C17C9BF52FEA49FC1BD29F67B392FFE34D +:10FE7000F01F3FDD48F918DD2AD927B2BFC35AB0B9 +:10FE800018EDA3C36F797D6165F8FED385FDE5B5F7 +:10FE9000B130FA59E4BE40DA97C9F278B998CF0385 +:10FEA00099FEDF8CF81BE23CD27FDC20DEB1453EC0 +:10FEB000E576EF6EC5C7FDC79DE44F6E3E34CF8536 +:10FEC000FEE20F22DC7FDCFC7439F98F97445E8AF6 +:10FED000623E19EB565CB81F59B2FBDD34CC03907F +:10FEE000FB5ED8E7DE9F49F935C6FDEF07919369C0 +:10FEF00098370070BF8F70A77AE216A4FB66D8FF10 +:10FF000061DE60B3163F86FD367B18D905955DC668 +:10FF1000FDA08CEF6E0B5848EE6EEB562228AFB367 +:10FF20002CC1A23CD46B2CCF753A7580CF2299FEA0 +:10FF300017907E07E2EAFE5D5897FEA79EADE94462 +:10FF4000BF3D66E677A13CDBEA14F24C23F9F6DB11 +:10FF500087DD91750976C36F23DC4E5822F3C134D7 +:10FF600016D560BD16CDF11FC7F546791F4D92F726 +:10FF7000897519AFBF8545492F35B19EFEBCB0C408 +:10FF8000F792E3F9180737F4C35ACA75F493DDE41E +:10FF9000F0519CABEBCF56637B98EF9B811F96553E +:10FFA0000CD0AF5C0749BFCDC21F1D6A38B10AE94A +:10FFB00037D4A5B8707FDDE8E3F4DB08FB2FCC9BDA +:10FFC0004DE677D669CC131D8EFF7FDDCF779CFF82 +:10FFD0007F3DAC9CFAC7F85BDFEF973F9CEFE5FCF9 +:10FFE000A5FFBE7F9EDD0AE7CBA47925EF5B93FDDD +:10FFF000EE72DF79BEF2F08B247C7CF10FC6C77005 +:020000022000DC +:10000000F230256BE8FD42725CE3AF9687FFE0F8C3 +:10001000C623871E4A3381A8585214F672BBCE6F8E +:100020008817CF501D7E1E3755793E4572DC5D9F87 +:1000300021E2EE9C9F5F7A5AA5F56A12F1E1A64390 +:100040004E1FBEDAE0584CF1D9E4F8E952B67F060B +:100050002E51721CB511F9B8F8CBE3A91765393DDB +:10006000249F745684790AC9795A2F393E1D114C40 +:1000700058EFEA32D8080C41D7362DCC32129E4FB9 +:10008000CBE2F6F44B229FC86BE1E705EE73A6FACC +:10009000711FE335F17CA77C4F607AD62494EF0280 +:1000A0009FCFDEC04C809747CC9D244FC24D0E1F82 +:1000B000CA3FE9C791FDEF10718BF3A5F36F671984 +:1000C000E9BCBFFE4FE2FB8592BEFFDAB8DD16C089 +:1000D0008D811F18D1EF6B18672A1A4CB7C3F533FF +:1000E0001CFD2ECB0ADC9E4578F14FA4FCE6F39470 +:1000F0002FA995F193E82F6207AC3AFA376DE2FC2D +:100100000B5B9F23F6EBBEAA599497CDCF8FC87394 +:1001100036C3D98F1BFBF99FDB8FFDF5BF93FDC85D +:10012000DC81769CE7A9697ECAFB5FED04F8715F0C +:10013000F8A875C8F32CF2DCC597F95DF6F6C3CDC7 +:10014000E96AEFB070FF63E5E793FF34F9F9FB3438 +:10015000F4A30EDF4F58E47BC6FC229EC67625F83A +:10016000B743319EAFF79280573E7F44E8C5F46CA9 +:10017000FF515CA78F8FDB6C2C1D4C9E4A2E179B6A +:10018000030E8A2F3477F2BC97E6E58CE47733FAD6 +:100190004FCBD0AF388BA1BD373523F833FC7EF57C +:1001A000DB8EB09A8E7EF7D90CEDBBDEE3BCFEA9E8 +:1001B0003BF8736C0F2DEFA17846C7EC8F28EFAAA0 +:1001C000EACF9FAEAAAD2478C98FE0B11ACFAD7C3B +:1001D00091C5E30FB2FC43BF3CF1935FFFE3069E82 +:1001E0009F1DF2F85DE88F907EF1543D467EA6E6B5 +:1001F00003DC68AB52F97CD8F7F3889E9A0F4C2B3E +:1002000047FF29EBB497A39D5BF52B07EDF73EBEA7 +:100210002B97F224EA3DC10F513E3A2B2357A35DA1 +:100220005A08E3A0BDFBF1FEABCB116E29FF36A34C +:10023000FF1CC6DFEC34FAC7998DE7D92FDD9B4F41 +:10024000FBCB6247F053EC6FB39DC311DE23CEA30B +:1002500008BF7932FF4BBECF564D344EF6B76D1402 +:100260002F977261B399056DC503F2E478962EF26B +:100270004C445E63F72C9EA722EA0E8F31BFF381B8 +:10028000CC2B8F233CC7B3B4AF961FE618942F40F6 +:10029000FD627E18C505589CFC2DA9E7B81D3DCA16 +:1002A00065217A7202DF519C06E809EDF94BE3B152 +:1002B000E9789E6B7447F452C4F3E17326C2933617 +:1002C000EB358AD3A42B7CBCE2F53D6BC7A21FC6DD +:1002D000F5E665B8A47ABBAB1A513A3523909F4D29 +:1002E000FB8C96521CAFFABFCC3C9FF2502AF917F8 +:1002F0003A0A1A299FB2F76DABE13C4E7219667744 +:1003000053FEE4A8AE5F50BCC0794019322F76721C +:10031000B683F0D61C8ECDA01C9B4B3D2467B54305 +:10032000BFA238B5B6564309C4DACC7E139E430B40 +:10033000AF60E4EF1CD3E132E17A158AFC98BEC3CA +:100340007F9818A4FD8A8C0F44787E93B96715EEC8 +:10035000C3B4153D9787713D0EB84DCD65D85FBCD0 +:1003600099FC2D875219D24F6157F1DD53A15EB828 +:10037000C645F1B0BEE76E2924FF2ACC73CC10F33A +:100380002CCA36F3FE0FA59A509F699B980F47D54C +:10039000DC59D504F78350877E468A3C55193F4582 +:1003A0003F14EAA9F4ECE0D7303FB6FF1CD2B214F8 +:1003B0007E0E49E3FE12E7B2B71FC7F33D3B2CFCAC +:1003C0009CE791C3136693DF6FADA6E03A7CEEE63F +:1003D000F99437669B0CE74206F07F84F256471D7E +:1003E000FA05D76B3016F6AF9939BD686B3D3BD136 +:1003F000BFB8382D4879BA97B545558A9FB94E3D53 +:1004000050AB27EC73B6703DD3BC8FEFCB93F73571 +:100410005FA65F6ECB36DA2DFDF57F92DDF283FEAF +:10042000F1FFC6FD0A33EEF392ED97E47DDD203B4C +:100430003CA9BFE1EC18998F523D300EB7A79DD271 +:100440004E0A1BF275AA1DE27CA1CDD8FFE5235C04 +:10045000345F99BF93B5525F8179FAF11F30F2D7BB +:10046000C93CA27035CFF7099B6C74EED0CBDA296A +:100470007F68248B2A0AF9D37AE87C6D36E611C1AD +:1004800077EBB24751BFDB996F8D4AF25257106E2E +:100490003BE69F50BE6A64EB221CE73A078D63C7B8 +:1004A000FC938B3085C0BF15E5EBF4061E5FC805D5 +:1004B0007D8CF49B3B9AD3A1BD8EE7A1C83C1399D8 +:1004C0001722F1502DF09B3B765111CAC1B54AF06D +:1004D0005171AE99CBFF0D4E715E19EC6BCFC079A7 +:1004E000E43EC6FB0F3798F8796437AF778CD1F9C3 +:1004F00079A02FF839BB8E729E7732283F2509AF3D +:10050000323FE5C9B4E011E497E4F3CB924E12D642 +:100510008FCE476F3BC4EDFAEA060BCDA36FC9350A +:10052000E497EC5B6262A8FFABBBAD9CEE92C6DBCE +:1005300056676151EC578BD8517ECAF5FF32BB1616 +:10054000D6B514FDBE475A6B2F3A05383EDA1AA0CD +:10055000B2CFAE74AA17D2F9D2B928A99ED8F2F9AF +:10056000B55A0EE6DBC40B142099E7B77E3493EA44 +:1005700099F177B0FEEA16CFD73490C37D63E23BA2 +:100580001478FFFF797FC4DB911673197BF7A1877D +:1005900066861D5F41DFFD9125E7719C41BDD3C497 +:1005A0007A56C5C85F24F45D2597875E8785EC255C +:1005B000AFC83F6535221F15233B505F99534E71DD +:1005C0007B07D30FC4B03D8F9FCF8276A2FF956388 +:1005D000B87FDA26E882E549BF544F18E5DBCA2226 +:1005E000377DDF2F8F0F5823DC3FC6C77FE3E90B32 +:1005F00028BE25F36A1973E5CFB980F26C0CF5FBC0 +:10060000ECE21CA6E6CAC773EC2BCDC2EE15F5369C +:100610006730C58BF3443E047BEE8D2BBF5B867C3D +:1006200074E6E0F747A35CBBCA02FB8221E4D8EE84 +:100630001C2EC7FACC8E350A7C57E30C8EF0C2FA1A +:10064000BF953A77061E29A81B31CD82471758F867 +:100650005115F19A29E8C43D87C3E7AE0928987778 +:10066000BAD2CEC7CD0C6A7E3AF7109CA35C077055 +:10067000AF54B8BC868FD2C98E2AD5D3F11C61A3E2 +:1006800038D7AA0AB97149E72615EDF59FB7BE35E7 +:1006900055D306E0FB858887FFA2C8783EA2DCCB55 +:1006A000ED6259CE56F50B90FE56ADF0BC36F31206 +:1006B0007CCEE9F8CAB4659598A77D556A4B25FAB2 +:1006C00069073D4F87E76509752B7FAFD1162FC0AE +:1006D00073E60BEDC149888FCFE7BD7B27CA873B07 +:1006E00073DF7807F324DE300B3991AF88F5EE988D +:1006F0009E06EB79ACD82DF23C6C440FC7C6723F16 +:10070000647F1EDB3885F2FA66CEE1E749AF65B15A +:10071000B61EF89E9C15D03E637211D9913345DE0A +:10072000C58CB70269E8179871435C43393A9C5D00 +:100730007495D7ACF724F0C3D5BAB17E6DA9B1FEDC +:10074000359FB1FE8DC97F1A9B587FD9EE9F8DF4DE +:10075000F4BCC2F33EC3973017D1BD4709A3FD32A5 +:10076000E1995C710E97E727FEABD8773D3399513D +:100770007BD63EDB2E3C3720FDD7AA689FE065B6CE +:10078000C20C7EEF03EABBB822F21C3D14D3610712 +:100790006F75713F2EBC6B817E0ECED3893FAA460A +:1007A000DA52904EB21C267639F252A58DEC9A237D +:1007B00082EEE4B9EA2A8D0530CF02869C83E51BE0 +:1007C00066D78BE8A70E7FC818E7DB691AE55B8A56 +:1007D00031185B41F587045D1F91F2FF079A585766 +:1007E000E04018EFECFA5C1E872E65745EFE6C65C7 +:1007F00009D525DD4BFE01AE1E8DA14145F427E94B +:10080000F9A74E0BD1837ABF49F8BB34130259EADA +:10081000927080B8C9423DC9C8FE9571BA7C9B6C84 +:10082000D7FCF87E0E93757EDE2B4BD4A1296AAAE5 +:1008300040FDFCF2EF487F3B7C419C8725CD46E79D +:100840009386E3A35D827F7625F1914BBB9AF8E80E +:10085000A7CE923B08EE6B9C2ED4AFA53097BA0C76 +:100860002AFD232AF03BCE4F6A8A4F47BEF966ED38 +:10087000F1A95A829C86EF9BF8F7A9C6EFBDF07DDF +:1008800046C2F769F07DD9E0EF773B6D51D344EC78 +:10089000A74AEF217D18A5C95E23E6AD66F1EFAE4C +:1008A0001179B1A3D3E07DD45BA5C63C1336D967DB +:1008B000A3FCE4A4BC92AB94E539C85757DB9ABAC1 +:1008C0007BA0BF97C53A5E650A7EE682E72FCF2DF3 +:1008D000398AFC576B8B6898D7772D8BAEC2C5EDE4 +:1008E0009B167CC45D4CF2E159E4936635383603BF +:1008F000EA67CCEDA36F2D22FE79CE9B39185E49B5 +:1009000027125EA417A43F492FC970F7AFE7D73B62 +:1009100029116F3BD851584ABB8AB1169E77ADE773 +:100920000FCC0B886886AD6534DA352F2F0993DC40 +:10093000B8CAFD00E565BD9C1BFC4F946775177E2A +:1009400052A0E1CBDE796371DF00F0C6FE37E1959E +:10095000F6E3A0BCE30F2D86BCE3E1F84C8E1B420E +:10096000BB50C5FCE49D94471C9AE3F0E1799110DB +:10097000E6C15652FC8AECC2E7146E6F87159BB035 +:10098000E3CE373F99717BAFA9DFDE33E4D77794AD +:1009900073B83B6ED5E5FD35DC5E9CC7B83D394B81 +:1009A000B42F7451BBCCC3EFD8C9FD861D4F8FD572 +:1009B000B15FB003C97E60E9C2CE2C32DE9B837F7B +:1009C0004AD640DEF86633B75FB7997C5594E76244 +:1009D000E1F7E29C91FE8C317CFC64FF626E8E62DA +:1009E000884FF7D7FF4EFEC55277303F07FA5B5866 +:1009F000E62F504C0817F733027D3E1C6398FED655 +:100A0000321AEDFEAB59CB9BA662A2CFE21CA4CF5B +:100A100009409FC506FA1C9D93C9E524C225E9B388 +:100A20009F2E4B93F3CA8217603F1DEECE5F35A316 +:100A3000BDDC6DF5F1BC5A9E27982C0712E059A039 +:100A400071783CAA4AF04CC27193E1391F3E49A427 +:100A5000CF6CC6F961387EC9D658D85931C02F2F0E +:100A6000DB8335087F3FDFACE2FBA34170AB0EA216 +:100A7000AFEB6FE47194502AD747184FC981F167E3 +:100A800089F1AF5FCBE9F0FA7FB110DD02F8518454 +:100A90007FB6689FD5DD447954B36BCC2712ED0047 +:100AA00019B7A913EFCDF1949B9105E6CC34C64B51 +:100AB000EA6EE2F19AEB588B19E1BD7E8EB19F3A56 +:100AC000B6FE13CC0BABBBC9F83C98D31F67198B90 +:100AD0007196A3C28FD007FC82FCF4D3CCC50FDF84 +:100AE0000AF43BF6876515E877BA326BC9EE4D50CC +:100AF000FFF1B6F154FF69D6B7BFF306B6EF28A1F0 +:100B00007A0D26B9E13E08F911F54DD58DD714C1FE +:100B1000B847EDA2DF5BF939026F4AB06316BCE754 +:100B20009D388AF2216B84BCE95BC8DBAFBDD0C9BC +:100B3000535E6FD6C9DF5893C2EFF579ADFCBF2B7A +:100B4000303FB76694A8573C3F1EEB47954FE81ED1 +:100B500080DE268786F86FCEE57EDA09A54A741C0A +:100B6000E0A52643F4DFC4E735B3E2D15CE48F9A15 +:100B70006ADECF04DFB4B5C5F89EE92CD57B736D72 +:100B800069280F259FB5E770FD2CEDA980E0FB6774 +:100B9000FCEFB68D807E0336C587530C4C7E97DF05 +:100BA0005FE5E0E7CB02FE220DFDBCD3FD3C7FB349 +:100BB000DAB62207F7E75F0F5A2A715E2E5BF9510A +:100BC000B46FD2274F9B44F9BE3666463D0774DFAB +:100BD000417C78F1270569486C0E23DD4BBA9A25D4 +:100BE000E9BDC648D7C0AFDB7232BF5C5E1BE8DA36 +:100BF0003E40D7C3D9B900D78F09AEA946FDD53F2E +:100C00004E125F268F3B9CBCC0BF44793A005F27E1 +:100C1000F15F1E66C515237FB64BFEEC42382CA64D +:100C2000189DB329547CE3E960EA307686842F1F4F +:100C30007DAE1583E1C23F4DDA7FFCCF83FBF23CF2 +:100C4000D10EDFF959C6005C30FE2B240F577178A6 +:100C5000B62B2D5CBE087B5CEEE79BE57CBB8CF382 +:100C6000AD4AE1E7DEBDE87721DF7BF9F87EB8CF5A +:100C7000631DE47C42426FCFB1059C1698DB75EE94 +:100C80007AA29F1B58F869B48F963983FF17F174C5 +:100C9000C4143E84FB9C85CC4FF157A08F77721211 +:100CA000EC0D096F329E9A8791A7C9F349C6CFC050 +:100CB000BAC5C8BE93E7D8FAE77B9EF3947689C796 +:100CC00062F4776508FF5486F0472145A17E9EC9EE +:100CD000527CB82F98EE53C8BE98C96C249767D63B +:100CE000727D9EE1E0F687D4FBC3F1C7159733927E +:100CF00057331B993837C7E7954C87D9ACE70E2C8B +:100D000067DAF4AD0B90EFD14ED107E09FE9E07EBA +:100D1000ECEC5C213F58CF24D4F3FDF5417ABE675B +:100D200012CA9FE4FBC9669EE3FED28C738CCA99FB +:100D3000BE7727A19ECFA8ED998472CCE9F27B7390 +:100D4000270DDC1F988CC7D1B92619873B2FFA4C89 +:100D5000E61F193F6B7306C7E238D2CF714689553B +:100D6000E14B151E97E83F588474EC76154D43FF10 +:100D7000C51C1BE82318BACB15BC3017E9ED8F0052 +:100D80000F6E0EF155C0E37535C17B343E2CE1E1A9 +:100D90003681872B855E3DFBB04AF1891A7FE94396 +:100DA000184208BD626611E2573FE94579BFD8593C +:100DB00030A0A2F8FE634EB23316BF5A4FF195B180 +:100DC0005B4C4C4FD093E32229867B3226ECCB3010 +:100DD000D42FE8CC35BC7F61D728437B7974BCA184 +:100DE000FDA2572A0CF549B12986F72F7EABDA50C0 +:100DF000BFA4E71AC3FB533F986DA883C6D070DE2B +:100E00007B9F55D83698F765F16F19BEFFCDB6199F +:100E1000AF60BCF3A4D8F7B2B03F560A785820E9C7 +:100E2000F6DC7C637F5125AA5421DFF3BF05EB7903 +:100E3000BEF634C05C62BF0BDB8DF6C4E22DC67A11 +:100E400043F7A655281B07E779B454E35539C97908 +:100E50001E35AE7926A4CF502ED817E31011EC62C0 +:100E6000CC331B8ECFBF6CFD4BD8E82F5B7FFEFED3 +:100E7000160BD9F58B5F7DAA2A0A8FAC5EE3FADBED +:100E800075E3FAA7961AD7DFE933AE7FFA64E3FA7F +:100E9000BBFDC6F51F516B5CFFCC8071FDB3EB8CC5 +:100EA000EB9F1334AEFFC806E3FAE7B718D7BB7061 +:100EB00099713D8BC24B0DEDC9EB2FE565F19ADBC6 +:100EC0008CEF017A4D097420E96841A081F277C660 +:100ED000B47FCF304E323DC0BED144F7BFC13E6E6D +:100EE0009B72FEF401D28AFCBDC9F4F16FB9C2EE67 +:100EF000147401FAA813E50AD8174F61593756D868 +:100F0000FB81A1ED0B29BF12F579E2BE7838B93625 +:100F1000484F897DF2B07A0AF7C9F6817DF270F404 +:100F20007B1CB38FC88E5A4F7EA51B5D1C8E4FF164 +:100F3000D125E8CF7D82F4F271007032C07B1CE7CE +:100F400003E31F4F9940FE8D6FB328D9EDFF82193F +:100F50009630D8CD98A8ADE23D4F3A95F5426F2F27 +:100F600014FE8F85F6E05BB9DCEF519885E3E6C5AA +:100F7000E8BC147B6DC479DD237102E30820784F4F +:100F8000611C01CA5E3BA79BD352AEF899EE49C0E3 +:100F9000E7FCE94A29D9B56A0AE53DCDBF4121FD03 +:100FA00034FF7F781917FA2CB95CB94CE2B35DD8DD +:100FB00003DC2E48C7C39A1477624107E1CDE7C22C +:100FC0007586FEB81FFF47FC7CCDE30AD32667D0A9 +:100FD00031335A675C6F3C0FA5DA389C8F9B990DB3 +:100FE000F1398105C90EBC5703D1C6FB1BCFFB7B72 +:100FF0006314FAD354F5FF7CAD06E3CF382EFA9F85 +:101000001D3E86FE66D5EB63E8BF1AF4FCC014BA39 +:1010100024A3BFCEF87BF88778917EC23C412FBBDA +:101020009D8CFBBD92FC86235590C098BF63E6E77C +:10103000C3BDDA16BE9F3CE65B634D9837636637E7 +:101040009EE7FB327B08F36D4F27E4C7C3BA0C79E8 +:101050008FE9B43CAEEF57B6365C8671A25E1107DD +:10106000BBA7357819AEB7AAF9282F0EEF5772270C +:101070007C6FF1407B029F6A8E0643DDEC08105EB8 +:1010800056B5B610DD98C53D50ABF36E730513FC35 +:1010900012178E14F6862DCC5C594C98C6F0F7C109 +:1010A0007486F3555DDAE9C47DA8D50BFD25CA2BFE +:1010B000AD9025FAADD7B4B610DCAB9460103BB35D +:1010C0008E66513BE0DBAAE1595478BEF52A92675F +:1010D00016E76D3EBCF76738FC59BDDAE78972C880 +:1010E0003FD22887EE6FB55D8EF85AD9BA8CC69379 +:1010F000786B6F755D8EF58DAD5ED1BE82DA4DB5C4 +:10110000BA82F4711A6821867116ADC789713DB033 +:101110003319C603CD5E5B0499C8EAE1F0B2A305BA +:10112000441F735D1C06F48DE5037DBCB3CC4CFB02 +:10113000D3DBF31DF4FEEDAF8F79D10F7C60011E80 +:1011400051FF8AF9F48F23F06711728869C100F2A8 +:10115000952557237F74866B36ADE3DFDA9FC4BBDA +:10116000C5CE281FD492EF20BBEB7CE10C8D14F789 +:101170005009BC27E30FF04472F47681A7DBEFE25D +:101180007EBEDBEF6094C7CE96C15FD5005D8D1447 +:10119000F2259B05A86C6F05C15282EB6563410B7C +:1011A000E875D6492FDBD1BF83ED7ECD8DA1EA4D09 +:1011B000359E59586E9C7CAA1DD9F1BE4B3F8B6160 +:1011C00089BE74C497AB8145F0CC1FC58E3D781D98 +:1011D00035AFA789F6B43A5E4F17EDE9015ECFF758 +:1011E0003FA9D4206049F1977C47C6D5A351BE2DB5 +:1011F00060FC7CB2B8E7603B13F2C29131AB06DB16 +:101200006F6274BE40B6FF50B4E7384EAC29463921 +:101210003CC7F8FD5681876CC789F6E9149F31B643 +:10122000CBF84AA6E3EC2BF47D99B1FD41F1BDD397 +:101230007136361DDB471BC7DF20DA531D3CEF0834 +:10124000C4213F472FDAEF15ED766CC7F14B8DEDDA +:101250006BC5F82B9500AD433F9F89F8E48E569DF2 +:10126000EAC97CF6EAC80C7E8E59F0996B191BF21C +:10127000DCFCAB2379BE4C9ADEE3F70F210F657BD4 +:10128000864BA3B8AFEAB5101D591D428E083EEC3F +:1012900097234A8B8F1317F7977F193D03E17E8EB3 +:1012A000F2AC00FE909EF3BE6362C1047996DB98B7 +:1012B000C28209EF7B176418EA5937E51ADEF7CCCA +:1012C00019656877548E37B4B3583EF1C76D82AE56 +:1012D00052CA2A0CEDF2BE02A6733E9276B579F49C +:1012E00014C37B674BF574A4EDD357CBFBAB7C36B3 +:1012F000940BB7394765231FFEA475321ADF20EF20 +:101300006CA27489D24B47C956B6EAA25E4AF5C7A9 +:10131000DC3CAF7A65AB8FD78B189D6F5ED95A4B8B +:10132000F5C7812FB1FCD7563F957BA00E160EFB5B +:1013300011F4AF433F3BA17FAC3F02FD63B91DFAFF +:10134000C7F287D03FB66F857EB1FE10C085E583BA +:10135000D00F3E7F00FAC7FAA6D600D5EF6BADA33B +:10136000FA86D62095F7B636D0F3B5AD2D545FDDAD +:10137000BA8CCA7B5AC354AE6C5D43ED16A1371FBD +:1013800013E71F1F9BC6CF7D27AF7F469EF2D5EE8A +:10139000BBA804455E65C893C8C8C37D75A7312F37 +:1013A00010F14770D8391E93E1182BE018CF622B4B +:1013B00052B9DCA038EB982EDFDDA9C0A7235BF87B +:1013C000BA1775C5A93DA7818F3756CC9379C22C22 +:1013D000AF8A1FEFC5F77A9558752A8F37931F8309 +:1013E00079013F55E2DC339179C484706993417F80 +:1013F00027CCB31F5F6E0E27E26D28782BF2787C26 +:1014000043ADECE4F79BD4B64791CD52FC2D74BFAD +:1014100089AD2E10D5A0F40482744FC2F8733360E6 +:10142000930572EDDCE54C8732AFD1B8FFCA5D5051 +:1014300061D8E7A8E73632FD22E8B7CCB84F4A19A1 +:101440007D9BE13B5BDEF70CED16CFDD86F6F9B751 +:1014500014ADF2223E47328A3B59D7AF603900D7EC +:10146000C28E4D045750E0BD57D1F9FDEDFBC5EFDD +:101470004408FBFFC72E812FDB7ADAD78E75F36A1B +:10148000497AD884FAE7E3A7D2498EEE7DC444FEB8 +:10149000ED712C6242793301CC486CBF006F7256FB +:1014A000E9CA1C15EBE54C57B17E118BD3BE08EC95 +:1014B000FF3AA417B0FF1FB143FD4C7EF0C73CBFFD +:1014C0002B4A7ABA44AC6789DC076DD192FDC373AD +:1014D000F3C85F633C07D626F6012BDC55D918EF1D +:1014E000ED1D26FFCEE9FDD6D405B01ECE9C3A2ACE +:1014F000E5F30DBA69C873D1CBBE2ABF6C013D625A +:10150000E4976508FF99CA9F67A1BBAA79749CF804 +:10151000A6CD2CE5989E8E726CA0EE4B27BBA23B0D +:1015200087F0A389F5D9DB1AA4FC00394FED77D3F6 +:101530005C980F5622F24FF7B5DE3AB526211F66AA +:10154000B7A0DF5216AB453D5A5A66F245A827AF01 +:10155000C17F611FDDEEC773FA5A05F3A1181EC7DC +:10156000DAE9BCBAF6854A7940DA914B980E76B042 +:10157000C31165E1B2817E99F0837C47C8F5CF5CE9 +:1015800035340FAD40DA473ED4DDEC33873F867407 +:10159000F7598799B3E509637BA983919E5B546AE8 +:1015A00089E80AA623B4D33D8BDA0E85E515211C04 +:1015B000D3BDF3508F1F4C25BA4DDD524557C37B29 +:1015C0004CC1F57900C7991EFDA0491A57F05ED3AA +:1015D00004CB2EB41BC7225E709CD1A584C7856244 +:1015E000BEFB5A57109E9E15F368CBEFC73B87870B +:1015F000F9FC78CFE9A20EE9BF31CE734365F53728 +:10160000F0DEC6953155D874467CAE33C726CE532E +:1016100006E002389F453855849BFCBF7C7E4D8F89 +:1016200070BF19C8B15A8ABB4E32B1C4B8AB2CA333 +:1016300042FECDC87311BC4EEFDCA90B2E4AACDFC5 +:101640004474FDB8C2E71F766A3C2FCDEFD713FD77 +:10165000C4EBE47E599C7F4811F0F6DFE3369EE749 +:10166000613A586C0BE62D0DB71FFE252ECAA4C497 +:10167000FD30E81818579D64A33C9F75328F4B7F4F +:1016800043C77C332CF1FC8A4DD0E96AA731AFE423 +:101690005C1EB777CE89F5E8B371BEC6B8647956DB +:1016A000C2BD17DDF5E4FF9171CCBE6E9E0F2EFD1D +:1016B0006B4B0409F41DE578E87B58A5F8E592EE3C +:1016C0006BF97DA1871EA07B56A12F1DE9A15EBCF1 +:1016D0005FBFC6E8EF59B03BB02A451FEC575AC46C +:1016E000C2E4D748F62725FB917E9B27F6693E5634 +:1016F0008E71CA93EB8B8FA5E07EA688D1B9DB9162 +:10170000EA93748F3158FBED784F292BE3F7F424DB +:10171000AFFB250516C2F33EB9AE631CE467D837AC +:1017200089F3FFBE17CF7E7D0CF4F396AE18CE8101 +:10173000BCA59B098FE381AEB1EC64AC76A8FBA09D +:10174000B2F34D5FEDBCC0A5C6DFD768EAEA3996B3 +:10175000AA93BCCBCA0778FA8EFD3EAD8CF8274E13 +:10176000BF075157C4E141B8F1FCCB7ED3277313B7 +:10177000E9607CBEC6ED837CD35793BF3546B8CEB7 +:1017800094BD99750D876B1CC2D51B3D919568B7AB +:1017900048B8F60F73BFFAA55F154F938DFA200175 +:1017A0004F53FF129EF65B86866796C0CF4F8EF230 +:1017B000FB4206B77F45FDD56184F7CC63B1EB51A1 +:1017C0003C02BCB3087FDE5359143315F8EBAC145C +:1017D000F45929E48E8FCEA8B0D0DB17537E5EA7D4 +:1017E000C6DB43772E8AE07902DF8B0B0AD1DFE07C +:1017F0003C6EA57B9E42497922B25C2FE6B13F57F1 +:1018000019120FABF3B9BC78F1B5F9D4DFBD6F593C +:1018100019CA83ED22DFF55E57A70DEFEF9578C467 +:101820007A0594214B7C112ABA7B2B3FB3E98E2198 +:10183000C633F1F1EE4BE21B399E2C57E49772BB95 +:101840005439AAE23987FB2E7D93EED9BAAF5223E1 +:1018500099FB37E37F7D12FEA36F667D9DD3CB8A14 +:101860007CF4A32AEFA57D03EA2125FEB332C49FB1 +:101870002548F30FBD6D653B95C1786A14F42BE7DD +:1018800027E72FE1765EB680CE99E07A20E0ABC5FF +:10189000FB524FA40BBD87F3223D71A9C6CF894CE3 +:1018A000D2685DEF9B3C85CEF5EC17F914F14B2C1B +:1018B00043FE2EC333026FF79EFB450CEFA90D7755 +:1018C0009BE95E05A6F578BF0974147A5DA37B9A3F +:1018D000819E6AF1DEA8175F3B9B86FBE803F966F1 +:1018E00082FB403E97877DE7D45A3A6FF3DA672E42 +:1018F0003581FE9FCE57855D128BE1399A8D15FC9F +:10190000DC8043D8018ED74E3520FC8EC9DFB32A48 +:10191000097A764FBE95BEDB688967F9300E744848 +:101920006551EEDFA1FBEFFACF0BBA381E9A2B8F71 +:10193000929DE0E8E6F7E23D9DAF135C08F7417841 +:101940009E32EE33573DB657C278A306BE77BAF83B +:101950007AA64CE2F7D0DC77E9CF5D78EF5EBAC2C9 +:10196000E8FEE84B0ACC06395E5FC4D7A1B3321655 +:101970001B85FCE5D228AFB6337A9B0DED7AC917EB +:10198000A347A9F4DD6A9197BE7A7229F199A4E37D +:10199000B905C157916E36025F3C49764E2C309D99 +:1019A000F0E32AC7FCE3C795581DB73F2C2ED42F70 +:1019B000A5269381DF8A0B38DDC812EC52B277EE90 +:1019C00010B42CF57D5BC4C630BFFFB7E766A5A396 +:1019D0005DDA9627ED3CBF0DF1B55D09A417E1383E +:1019E000FFA5D2BEEFC5D74E34E0B86D302FE4DB93 +:1019F0007B7EEA588FF6499BCB4F7C2AC7D7DC26E3 +:101A0000B11EBC9FFD16FF2BE86F8CBBF97D4447D0 +:101A1000A65C6343FA87F74CD8CF7BADF80B1AD896 +:101A20004F0DF90716BA66CFC0EF16B1E02AB46BB6 +:101A30001775A8867B17EE11F262E1B914164DD81E +:101A40001F2C9CFC2D3A37B6F05C1A8B82BD758F2B +:101A500038177D8F3857C40A383D3B44E915E5DF18 +:101A6000CCF7BE24BD95F9CBBDF339DFB302E8B79F +:101A700049E9B114C1101BA7FC9ECEEBBCD7EA62AA +:101A8000D192047807CD73048B268CD3FFDE391BEB +:101A9000CD67607D39FD0ECCD7417878AFD54B78D6 +:101AA0001CBEFF91063C0EF43FCA80C7C1FD97D013 +:101AB000F8EFB5967E49FF1386E95F37C03FD0EF58 +:101AC000681AB7F7C8FC1FA702DF1D89DEBDEDF954 +:101AD0004AFC1D332BFD7E01EBEAACA673848F33E9 +:101AE0003A677AE7E1DFBD83F99A77EEB2F8708C56 +:101AF0003E737CAE6F083D339AB9C2789F972CC76E +:101B00001714D37C929FDBB4880BF3326DA59A0B2C +:101B10007F1FD1C66291BB71DF5269233927E3422F +:101B2000B2DF3FE5A9F23C3BC907796FCB12919731 +:101B300057EC085E81EBBED4D4DEFC13F8F683D2FA +:101B4000363A37CC989BF633326EA3E12FBF15A3FC +:101B50005F30C0F0FCCD137A70067EF74310271873 +:101B6000C7512FD81DC4BCB50D62DFB8C11EF3FA32 +:101B700012E4E60D05DA57B317DA93E876D22FF7B9 +:101B80004639DDDE50807E2235F6C4FC22CCB7ED2E +:101B900011F776E9168A77551EA3FBFEE6CB7DFF8B +:101BA0009AE4BC8E7C37DAD132CE94867977686B32 +:101BB0006CE4F7BED5A7F27AFD7F8CA07310B0FF5E +:101BC000492D43F9B25FE5FE2011DF3A2BE6D067DD +:101BD000DB5840F9F7221FE46CF74B74AFE4D935BA +:101BE0006368FDEB5FF83EDD0BB73F97EBB1BE439B +:101BF0004ED263F5565F15DE5BB83F97DBAB9D5A5F +:101C000034AD22C17E5D9D574DF2F9E335634C89B9 +:101C1000F18FEF0A79B051FA37B578159E67F9B8A8 +:101C200032FA33D2A307ECF43B51A683BFABA2FB3D +:101C30002D375AE97701AA0F8EDB5C87FBC3348D01 +:101C4000F2914D07ED04CF9975FC7E2DFC16E55DF4 +:101C5000D3C191F4FB56F5A971CA276C4AF195607E +:101C6000DCAFFEE054BAD7FFE486710528FF4E646E +:101C7000EA0574AFF1063CF409F54363F9F3B517CF +:101C8000D37955E7C6D4E0507E10A98F92EFEFDAF2 +:101C90009F5BDEDB85F81967F3A1FC7D4FF1F1B89E +:101CA000EF2BF1D93AC515F9F9D27AD769FA7DBC8B +:101CB000FA8E776F62F4DC43742BF773C9E3D50BAC +:101CC0007DB5DF129F8BBF4B56BF52E05DFC4E626D +:101CD000BDA99C7EAF4FE27D63D23DB74F08FD2486 +:101CE000CB93AF69745F20D81105E81F3A79D84AC1 +:101CF000747672E3043AAF2EC7AB079CB8802F4FBF +:101D000064E813715D9F16F2AA7E25DFA7CAE7304B +:101D10007E0C7FE7307E48A5BCAE3E573C0DE3927B +:101D2000F23D59EF9F4FB74ABF97B53FF7455A6FFE +:101D3000A02786F4647AC1497A3AF4827517AEE72F +:101D4000C7952C8CFECFF05BFCF7C78E1CB292FDC2 +:101D5000DC779CEF6F07DD9FE68817E0FDA1A117F8 +:101D600046921CEBCB8FEFE0F6B69DDFABF846F06A +:101D70006211FFCD11F711E6A09DF7F9217B14ED5B +:101D80003C28299E1066BBBDF4FC702A43FF0F94CB +:101D900014CF63CA012FFDEE0C6B17DFC7E8FB3BC6 +:101DA0000B8263512EDF590CFD3BF0FB53F4DEE751 +:101DB000A38217520C8AB15C315E2EF59B1F2CA4B6 +:101DC000E7CA675EFE7B2AEDA23D46ED216BF0621D +:101DD0009AC7AF9C6CE710F3FCAAF7EE1D2D1841D3 +:101DE000EB28E1063C93DD988C97B30526F17B3B0D +:101DF0001C1FC974D9BF9E5F021FFA5FE8BCF621A1 +:101E0000BE8EEBC659B81C593B81EC63D69662C8AE +:101E10009F5B7188DFC3D0BBC149EBDC67F63F84B1 +:101E2000FA28FE8699F17BEDC022403FC5E4A1F976 +:101E3000E523914FBF642DCFB3FBE8D1F70BE63913 +:101E4000F05CF2FB8673C9D25F089DA4A13FC6E196 +:101E5000D3D3E697717B5D25F8F8EF7A6D34EBF418 +:101E6000BB6BE10DE3C81F71D2A21FA4DF875B77B4 +:101E70008109E94A2D17F277139F9FBC2F4BDE7B18 +:101E8000958C9F8AC262927F4D2C7833DEA17E8230 +:101E9000E959C26146F7FF917BDF8469889A9FE226 +:101EA000B6AC85F4C2E07BF62C5FF2BB6CFFBBF5F1 +:101EB0002A5C2BF4EF9587D350AF7EE0E2FB463AE5 +:101EC0007D8F7A5DE5F36CC30F30AF8305A6144EAA +:101ED000A27692871F28BC5DCAB941F3477AC17EBA +:101EE000F03DE8EB9A42EE7F63AE0C71C82B6CC1FB +:101EF0003C4DA99F428A66C273F3A7DC7A1AD2E3EB +:101F0000A9B5C5192B300FC6AD6725DAD5A1A38CAD +:101F1000CE8BEB78DFF8C5F8FB32FE89E8F7DB9F64 +:101F200061F43B24C3F3E4B49EB989ED730AB99E0E +:101F30009B5F28F699854CE45726E38DAFFB62B191 +:101F4000EE6A79F072DA8726BDB7784BBAA087A41B +:101F5000E7EDCF7F97F2A01E36DE1349B15F18EF91 +:101F600083572C61E5422C5328AFBD611397730D45 +:101F7000AFCE2CB98BD7E95E85693BEFA1DFE35982 +:101F8000B0EBCA12C6E516AD83A4C70505FE12B4B0 +:101F9000E3E25B5517F245C31695E051CD3ED756A7 +:101FA000787E7A8B99ECBB0601CFE9BC601AAD9BB9 +:101FB000C6340BE0FDB4164C23FB75ABF8DDA1A4D1 +:101FC00079C07B6F6A1543E0C7C6D799F0533C04CC +:101FD0001DBC61A2755A80BF0B8970EC54C8BF79D3 +:101FE0003A3F7833D64FC1FE1FCFE9AB9B96D07DE9 +:101FF00036C9F83E6D0B127D2E16F391F84C1E4734 +:10200000E2B30FF189F6D22B5348EF851E5491624B +:10201000D98BDD9FD2BE7CDAA12BDF998ACF3781A5 +:10202000DDA2A39E1DF5B36FA39E5BA3528C7AFE27 +:10203000A1E22C96A4AF71FF39FFF53969A6043DE2 +:10204000A93EC8F1A43AE7A42DA4F7CF7E1DE9EB81 +:1020500084EECBAA4878EFF1C2FEB88361BDEA37BF +:10206000FD210DC769586FA679C975E9C379A07CB0 +:102070006B4F8D20FDF7E5C5A95FB94EFDF48DEBE3 +:1020800020E909DEFBAF429718274CF2E85451B023 +:10209000CA37049D2C7A00C6C5FEB638E9FED2F3D5 +:1020A0001D57E2A37FBD055F531DD7714711F9D1BD +:1020B0004D6F6874C8E044FB5505C8C7F5A02FD024 +:1020C0006F51AFC4DFA17B640F59E91EE6FA4DB72B +:1020D000DC8CE3D51FB79AB0FDD4E1AB26125C4986 +:1020E000EB0A782A188ADEFB8AE205BE04FC813DF1 +:1020F00041FC2DE7930037C101FB29BA8FA8AF0837 +:10210000D633410EBC59C8ED2E78DF6521FAE6F7CB +:1021100061F5CFD795345F57D27CDF6444DFCC17AD +:10212000A4F92C78DB6AC2E70BEEBFB604F73DA733 +:10213000D64DA7799DCAF04F44FE3A5500FD0F21B8 +:102140002F17DC0FF32CFB0BF36CB7D37A0D3BCFBF +:102150008CF80EF617E6F989A04339CFF7343D0D18 +:10216000F3F943CFAA0CFD2EA1FCC0C6A9BC4EBFFB +:10217000131732737A086D4AA57CDFDE6EFEFB040E +:10218000520EC078E7490F26A28753D5FAE6C9D088 +:10219000DFFF073F3717B700800000001F8B0800E4 +:1021A0000000000000FFCD7D0B7854D5B5FF3E73D5 +:1021B00066269364924C12088140983C09908449A9 +:1021C00002888A767804D1020D4F798993071042EC +:1021D0005EA0B5696BCD4002A2450D352A5AD401E7 +:1021E00081A2A20D0A0A15BC032A6245C5578BB607 +:1021F000E526405179C6A05EAEB5D7FFFAAD7D4E5B +:1022000072CE9054DBDEFB7DFF7C1FDF669FFD5AA4 +:102210007BEDB5D75EAFBDE7C23DAACBEF16E2E4DA +:10222000DD056FFFBC17A5F7AA2E81FC58DFCD0294 +:10223000F98FC32CFE144A938BA670FE659B6BA589 +:1022400022C489A6BFFD41A1FC857D36B7A0F20B53 +:102250002945F7CE467E8FEA5A41ED2F0C689F251F +:102260008673B9D844E5EA5D239A502E1E1EE6CA4D +:10227000A0F2F20D61426409FEFB56687F23E93B40 +:10228000520BA56B556F7834A54D2FFD44C9A56F32 +:1022900056378F57F3AB24F7DD347EB95558EDF937 +:1022A000A8DC9E392D4788F37B6D1303D9323F2379 +:1022B00087CB3FB052798D5DF85AF87BAD7D6A0EC1 +:1022C0008FE2B6D2388BA90F914AE9FA18EF60EA8B +:1022D0007F318D9342E37D8BBF1F5C0EDF0ECBE71A +:1022E0000B8AA89F7B6D62F673D95DF5F434DB4DE4 +:1022F0001DF6466D7B573B558825C63CE1A122243F +:10230000BF14794757BE32A4BC2AA47C47BFCFA7CD +:1023100014392F1F7F03C61FD185C7120D8F3B2C89 +:10232000F41DEB728F12D844FF2DB1BAEDCB09FE2C +:10233000E7C6889BD14FA95538AECD47BD0E9E5FED +:1023400089553486E5E3BB87EBE9F3A6FE1AC3E2C1 +:10235000281FD1CEE353BD8976439EDA9BE09AAB2A +:10236000C1A3A74BB785BB4EEAF3A07F552DB1A6FD +:102370007CCDEEBEAE93067C2FC57FFAD2BF49342A +:10238000FB91C08BFCABDADD7A3092E8A74DF1CD42 +:102390007553BF170E7E1D9DEDE6751F5944EB9BCF +:1023A000AFA63E7F98E6DBBE47F56C42BF6FD8FD17 +:1023B0004A0CFDE79B8B0F6EA7EFD52FA789BBDDDE +:1023C0005DF30FC5E385DD17A353E9FBF943F60879 +:1023D000318CE6B9377EAC9DE862475C7BB778AF5D +:1023E000D5D65DEFEFBCB5357AAAA1DE79D11A3D1D +:1023F000CD402F25BB2FD68B5CC69F5FCDEFC2EFA4 +:10240000897DBDC7AAF4BDF4F7FDC65A28BD5FC3D8 +:10241000DBBD36F7136B096EFF9E30CF1682FBFCD7 +:102420001BB32D687FFE8D722DBDCDCBE95F4F2490 +:1024300063FC688BA4777DBC356E0BF7536A697BB0 +:10244000EC1ADA8FA5BFEB93D290D2555E6AC9CF52 +:10245000C43A6FB7B52F00DCE715B14689EBEAE760 +:102460007EB79BDB9FDFF3C963E00F27EE1D904F24 +:10247000644DF941B93E2A3FFF5141A68BFA3D7F99 +:102480004F5F0FF8C2769BFB36A6B7BBA23CD8F7CE +:102490007A7F18A716FDEFB962A40FE947125ECA4A +:1024A000E7FAE4B87E25BFABDF688BFBBED1E0174F +:1024B000BFB779B650B2FCEF697D62313FECE76E91 +:1024C000D6A1744D98709BF8C94A86BB4478EC221B +:1024D0004D960B03BD958922FEBEB0C9FC7D11F15E +:1024E000097C5FBCDEFCBD5C34AD6EA5F92D09989E +:1024F000BF0BDA3FFE04EC6BFDAFC55E14057AFF3F +:1025000036CC544FF835FE401F095F25B41FC1C7B4 +:102510009E5102819558DFBB549E67E8BCDE75A7CB +:1025200070BB8722FF6741AB615D8F5B843591F0A3 +:102530007ADC2E1C89F9E8470885FAF5EF0B0B6C5D +:10254000A126770FFE2AB9047CAF31C22208BE5BF8 +:102550005DE07C42ACD8F74932FA295D53E86D352D +:10256000C077C1E67DE8E7D4BEFD5DE2D754EFF861 +:10257000D840D35882EBF8DDAAA7A11BB84EAFB163 +:10258000884001E1E32E2102F1947FF293E4625A44 +:1025900097CFB67C925C62A47F45CC36D2A39E12C4 +:1025A00024BC3EEF61EFD2FC8ED35C309FD07A5DCD +:1025B000EB6B8657C767B82A6ABBA387CF40F7542F +:1025C0009EF5775578B1EFF7D902A0CFC88D5F3C63 +:1025D000380FF4B9D7E64AA1B16BF6A95E95E62D9E +:1025E000F6A8810C9C637B4F4457E09CD953E05282 +:1025F0000DF3AED9A316E17C39BFFB62426936F711 +:1026000033C5ED44FB073CA0DF9EE0F89B5BFDF784 +:10261000F89FD7CCFFCE657F907003F8C0C6539962 +:10262000E0EFC407FFE6A6799ECFFCC68EBC10ADD6 +:1026300023417F045FB49BE0BC10F82A5A105C8EE3 +:10264000BDAA37D0CD3A44A5D8194FFF327C130923 +:10265000BE842EF8089EA894115D7056BBDBED3841 +:10266000672F38A273C14F694293F212B4F3C90DB8 +:10267000FE5A3A49107F1DBF67E1CA70C80B4D8AE8 +:10268000278CBE97ED55F9DC2ADB1B19C016183FC5 +:10269000C8C9F9D247D54018E527A8A3FF309BEA5F +:1026A0002FBE47F5D08E14FB37DEF6071BD6758399 +:1026B0004DA01C88035C4B34B896ECFDE1670A8D95 +:1026C000B378DF2D0730CEE207140F17A8F3EDE83B +:1026D00077C9438A88574067B6E3463A5BD864CEE9 +:1026E0002F12AD0B5415FCC1FC9DF09E5C41FD9674 +:1026F000EF0E73DD8DF102A1E542BC4AF0D468FF14 +:10270000CFCA583BF700D5CFDA68673C9C0F17E279 +:1027100008F6ABB53541200DB626631DCFEFF96B3A +:1027200032D6B1E677FF9529BA59BFCEFDB437AAA4 +:10273000D7A94821AE4E51C4B7A9A0FB8B538ABA82 +:10274000A96F1B20F7C5369BBF9F87CA0F6CFC8AF9 +:10275000F9C1853DBE81AE6EE8B76BBFFAC32D8966 +:102760004883E102E9F016D70DD827240F62BE3561 +:102770009B564FDB44F9F0976C38B9444D8693F77C +:102780000BF6C74243BFFA3ED906BE807484E40FFD +:10279000B601F21C3DAA9D7BDBF6774CC9E8069E8C +:1027A000A36E1BD7B30D105CEF5977D15CD05B845F +:1027B000C51F0DBE2DBC5E772FC2B3A2D157435D9E +:1027C000AD82EF89A289D3FEA285D34785F0395126 +:1027D0005F785CC0B3100362813FDEF38CCFBECC68 +:1027E000377FACAD217835E8C41F2B025BE8FFEAE8 +:1027F0004687506320EDB546A35154CEB4FB065234 +:10280000B9ED03D5A240DE1DA0AFA7C785FDF7A592 +:1028100073468C71FDF61F2E9988FEAA76A9228C2C +:10282000FA3BB7D326824ED4A7FD027C1CFEC29E83 +:1028300002BEB4571190976B288FEF35A3ADDE80A1 +:10284000012F77A4D8180FD52999F29CB67A0F4D8D +:10285000A27ECFBB4AEC90EB6D87CB26E2BCB125C4 +:1028600096D801D7FEC3631D2958B7582BEF9BD5C7 +:102870007BF5718FB8D07F54EC070C6F63B645447D +:1028800053BBC6A3610146A643F2A1300DAF8DC173 +:10289000F10E7737EBE317E393C4282ADFA94E0440 +:1028A0009CE75C252EACA32D96E8EE0A6A6FF34EEA +:1028B000BC9AFA0D8B8D8B077C6B52D2783DBF8A08 +:1028C000AD6538BF22F1C2CFFBB7B608F9C6FE65C9 +:1028D0002AE3BEE921DECF350E397ED43E95CF51B5 +:1028E00071A543E3DBEFBB4A699C05C9BE47410FB5 +:1028F0009DFC6DC4AB02FC39CB6261F9ACF135E7EC +:102900005AF021BDFC6C8AA4377D3D56F5B2BAC0A1 +:102910003F1ED5E87395ABC8916F98A7ADB745C377 +:1029200057910378DA612F3A84F3A59DBEE3DC3C2E +:102930009038CD013D85EA59D0CFA97ADA3176F4C5 +:102940003BC301FC2EEA553201ED168BDAD5D86F68 +:102950008BD7AB2268E0AB8D3639EEA24B11221833 +:10296000DF35EE225A3F6E7F295A04E9DC6D0C9761 +:10297000F51AA3E4FE792345EE9F0FB5F9B469F982 +:102980007F99AF7BCC7CFD5CEC1FB69648FEFE4683 +:102990000AF55BA5B44E48A1F9AD4EECB003BFA754 +:1029A000EA5D22986980F7B279C68BA061DCCE7AA5 +:1029B000971C3C9FAEF57033FC5DF375321E4ED50F +:1029C00027321E7BEE3FC984C7AEFE534D78BCBC98 +:1029D000FF4C1EFF547DD677F43FB487FEDD26F80A +:1029E000BBFA4DE771C56EDF40F0973B5DC40F98B1 +:1029F0006E885F50B95DF13D7E35E4DB8FC204E443 +:102A0000BEAFC27D835C06FEF00DCE65D6E782497F +:102A1000E0B77ED1CC69CDEE8B13D0DE4D7C01FBCF +:102A2000492FAF11ED0C27F885E88335B4BAB97C8E +:102A3000B76F10F4221D8E4E79E675A7DF42FB209A +:102A40006CDFDFA3B18F2F58DBA778286DD9AB4699 +:102A50001AF7757CAAA4A7B103BEC86DA5EFD56807 +:102A6000477CEFB697970E027EAAC3DA7301F7810F +:102A700097FF968B73E4AB7D4B07E2FB36AACFF250 +:102A800087BDBDDA63E82F5DB8FC96515DA933556B +:102A9000EEFFD0EFDBF635F4031CDB89BD09920BAA +:102AA000ABEB2A0A4EC6830D79EF07FF12C4B75865 +:102AB0001FDA3D5D1D03F9EE439279283F7C8F9428 +:102AC0001B860F10014B0AE4BE0F67834F548FB073 +:102AD000BBA00A47E41D61793B6284C3A550FDBFDA +:102AE000F797E3DB212FA4A17D613CE8F9CA64F1EB +:102AF000EFC96D1B42F64FF0BDEAED345E95DA3A50 +:102B0000659CC2FB283F157CFBAD2FDED6F4D704B5 +:102B1000ACCF019C6B04CFFB5A3F65A9BE2B50CFB5 +:102B2000E768BDE70AAA377356DF64E847C59A7EAF +:102B300026261152AE647E94033BC8E5E7B6D483E3 +:102B40005E527C3EE0C1DFD7E1C1F935344938FA45 +:102B5000125E456220751A8D3B21D5A2DB0F14C091 +:102B60003D449BE333FD5A96C7F2391988031DFD96 +:102B7000B3E34E4BF54E06FC7AFD0F67CDCBF175F6 +:102B8000736EE8F2BCDDDEB20C70B65739597FFCCB +:102B90000045D4EE89596141351A7A8A730DF4F9EA +:102BA000A3910B0EF6267C8C8FF2CD43FFB36FBC46 +:102BB0007E35F2CA8178F772D07371EB48D6EFC2D6 +:102BC0007D37A3BCD2E11B9840533C37C037280661 +:102BD000877C51BC5C27519453D42DFC129E6245D6 +:102BE0008EDF18E52B473FC596238F5D816FD62377 +:102BF0006C6F108DBDB99F737651DE9DFCAFE3E124 +:102C000098368FFD3671ED259ADFFE75319E06826E +:102C1000B7ECCE1B17D450BAD0529410544D70DF7D +:102C2000964A5D57FA8B07F62579EE9C4D83BB4E8D +:102C300083DBEACA34EEE750B81B7479E5170AEB78 +:102C400083FC47F917FDB181BB291F66B9F8C17430 +:102C50009C5B3916B6936C88A0BD457AE43B1A9C00 +:102C60008FD2BE73C4F1F735F89E1821DB273E687A +:102C700009C07E5034760FAFD313D54E8F4A6315FB +:102C80000BB71D7250A9F0B2FEFCD7317FDBD74ADB +:102C9000F36A4EF5DD07BCDD1C6F49FE80E1F00DE7 +:102CA0009D0A796BB49CC73F9037791ED384CBC6FD +:102CB0004299586B81FC31CD25A7B25091FB63BA84 +:102CC000F0DA30DE4CE1E37AEF9DB77BA14FBC0731 +:102CD0005D88E0BE51F8F9FB1C11E0749E0872FD9E +:102CE0009B442BE7757C137DDCDC4BD2C7277D54DE +:102CF000C6FF56C0FD6E64EE803A9AC7D48706655B +:102D0000B07ED5DC9BF1F35D704FD5E886F6EF6FB2 +:102D1000B18ED8BF33A89F693784ECDFF1BDF5F5DC +:102D2000CCF847FBE84847A7FEE4EC4B78B84E5B8D +:102D3000D2EBBC4B597F12C2C5F2D18FB47D5BA8D8 +:102D40003A452F5A9F236ED297089689639625623B +:102D5000BEAFAF106F15D03ABE3E46150D5CD3CB5B +:102D6000EDA668FD4DE93FE133D85B0F8B60AFE125 +:102D7000D4AEF092EFD518827B8ABABD3196CA27BD +:102D8000F627BDC6C0EFAEEFB5C30AFDEE8674F3FD +:102D9000F749D966FD67B2685231FE94E1E67AFBE5 +:102DA0008127A2B3F753A5FE22868821DFF27A0B92 +:102DB0008B713E1D932EDA2F101C1169BE8FB12E20 +:102DC000CB27FF7501C61556399FEAB755B6EB1DDF +:102DD00027798B28509CACA7932253CA25C87F4AD9 +:102DE000F203D2D3F56E4ECFD2798FF2F3F51ECE29 +:102DF00017A4159D40BF256B3EB7627DEE0C97F87A +:102E00002E6F699A00B02A76B71C445A162C9A8005 +:102E10006376D1A1DA8348EFECD4DB6A59BED3E103 +:102E2000BE45A3D35BA2A6FD3087D6E1963DAA8717 +:102E3000F303A64D9FDC0B791BE77BA2A3AA4B44AF +:102E400033245754ABDE2F0197776FDBC1789ADFBD +:102E500027F5A318EECFEABD0CF799FA899C4E4AE4 +:102E60002BFA1BE8CC2B3E67796CF2F6366B12D549 +:102E70002FF42A5EECDB6BBD2210A0FDB7DE26CF5F +:102E800081F5740E601F8FC999F6E8AD027CDA6790 +:102E90004BA37166DEB0A410E34C19556C45BD1B05 +:102EA000BF211920A58B4EBF8BEEF5F95769EB7644 +:102EB000EE6585F1D8B1332D0672C1F25D697D9062 +:102EC00012BFD4F5DD48E0ADE39285E1EC381AC1DC +:102ED000FA86DE6EF9AE48E63BCB07D803C260B790 +:102EE0003C43EB2C0CF2E699677EE2369E2B67E2C0 +:102EF0005ABEFA18FCED2F92BF916473EA11F0BF2D +:102F0000FEFD3CA093F39A9C4D7A4624CEBF6ACD39 +:102F1000AE08FE84FC990869CF1DF96CD258EC2FDD +:102F20008C471C4EE8FC2BF3D987527FEEEE1A6FCC +:102F30005BCBC28F1FA1FCB980C56FA3F3E99C686E +:102F400039FF3BF0DFCD4EB6EBDDA9103C387FB743 +:102F5000F4E37C96628DA8C3F92B02BCBFB314B70F +:102F6000B58EF855E5730FF703FDBD44381845E5F8 +:102F70002FAD8B647EF692CD73AC0EFD3D2AFBFB2C +:102F8000CDBD3F3DBE1BE93D55F93FC5F2A4C5315E +:102F9000FECB7EB56408DAD3F92EFA527F4FBFA874 +:102FA00004C3693FE734EF5FD997E01BB6A1CDD2E8 +:102FB0008FD2BCCD4A03D2A1036E3804BBF30D6996 +:102FC0006E6E5FB03D454DC236EC17F8F8077CEEEB +:102FD0009BE581ECE6CFC7F6135D72C110A5E5F461 +:102FE0004682352CF968BE8FF1D7C4F3D9B577FA8C +:102FF000FBF304E6411207E02EB67BF81C0AF83713 +:10300000623DCFF9B23CACD715F91F069D9DF32563 +:1030100078702EBD407AFC55A87FCCCAF37C71F342 +:10302000BBD1B0EBC4907E1C0E7F485EFB04D4AFD6 +:103030001AE0167E6A3FE0B1EB26023FD53B776D82 +:10304000E47E2A1D1EE8B9E5BB2E1E4C829C78BD8D +:10305000F064800E77CAFC2FC77B3D2A4DB57CE318 +:1030600097327FA488F345A4755A51BF54CA470FBD +:1030700069E79F68CD65FEC8A4EDEE5AAF5F523197 +:10308000CAD7A7F8FBC2AEAD9F9B74DE55A561AB56 +:10309000D865FB2363E725335EBEE77967D7CE2D7E +:1030A000BDBF87ECC21F4EFDC06C033BFA06BB3CA4 +:1030B000A7B7107F01BDE8E7348DFB0BEC5F6AEF2B +:1030C000053F4D52959C9D848FA487C258CEF8BE73 +:1030D000E3CF8E59CDE7B62E67D544483EC8670585 +:1030E000B55F18E5BB0BF35BA89DF3C2EACE861C67 +:1030F0003223CA7B37BE573ADA9331073A3FEF455E +:10310000BE5A25B92BCD207739E3BED7F95917E53B +:103110006DC67CBE6FFDB19104670C525DCF22ADD0 +:10312000A35B7E9CBABD05FCF88130C98FA30A98C9 +:103130001FE9F30BEDFF15DAF73EE233AFD179E289 +:1031400023DC8F738EB1F27ABE6AA93C48E770A186 +:103150001C01846C8D1DCE796F14E16FBC5315BEBC +:103160006EF4453DA5F57A1EF899D02BD254AFB038 +:1031700057AC1DFBF7FBCE5BD5D6478DD0F9A9BB6D +:10318000977076376F39CF5BC247F4015EC62ADF8E +:103190006FBE0E5BD141ACC338671E9F8BE39C535F +:1031A0008FF904C37F18DF43E7193A1FE1F87EF275 +:1031B000D28F15E1B760FF7D6E67FBDA5E5BEBD304 +:1031C000BF257CEE5D92ED819DE805F05EF0CF6855 +:1031D0003BCBB37BA3841F7C65EFD48400EC452FED +:1031E000414F04DFE82D6479B8ACBF770E95537F6B +:1031F000FDC2685FC05E342F42EB9F0646FB157D23 +:10320000B87D8352FB660EDAAF8864BE733420F952 +:1032100078736C709E4ADF9B3FCF14A8775404D616 +:10322000A4A2DEEDD25F43E54935D46FF3922112BB +:10323000CEFF51F9DC68CEF3F68D73321F67FB4C7D +:10324000F3546F5FF8AF7A69EBD5BC5196F7833DC5 +:1032500014E52994A7F4639BAC3F57ABF7914697CD +:10326000B4CF990FF8A6445A41E7FDD24BC2D29988 +:103270002979FBC2EFF3485906DB28E7565C9FC269 +:10328000F4A3D9CB666B7C5BEF0F0D1C23212FCBF6 +:10329000BF390BB784839E679687B741EE3B5ABE12 +:1032A000320A7AFB4C9F1A0C835C39A3D0DB29AF1E +:1032B000A5625CAF1CB74CD7FF82A5C0EBCBED0E6F +:1032C0007137CBF7C102A33EA5AF6F55CB9878A35A +:1032D000DE5C6127FE42F02CD1F66D9AD3D73B7DA0 +:1032E00004F4E9EBE38DFAF4A7650FE4F2FED2C62D +:1032F0003B5BEF8D3F990EB96D22A7FA789D7A0F4F +:10330000D64DE757A097DB25BD086BFB478B29DF20 +:10331000307B8807F6EA89D31C4C6F1D2DE12C1FEA +:1033200037CC8EF0C26ED7B02B8CED06376BFB839B +:10333000F428A61BFFBE28EEA7D22EF395CF65304A +:10334000DDBC600F3CB915E52F87B37FB6325A8ECE +:103350005BF9BB248D2EBD29AB7AB15F8EE9A53216 +:10336000C21DC3E5BF8F677A7A36DC57007C127DB9 +:10337000B25DBCD21ECC8C25FC1FD3E80F7A23FB98 +:10338000F56AA3986E8596F7FD3C9EF538927F7995 +:103390003CDF7D4339EFB37BFB2EC43E5A1EC9F0A0 +:1033A0001C73C9F26395B1BC0FE6DFB7F430FCC5FE +:1033B000C78AECBC5F8EED5559DEFA739D1A849F67 +:1033C0005BA7CF9A25C7DF86F9A8BAE1A3E4DDD4CD +:1033D000CFFC955593D06E7EC5ED5370DEF69AF610 +:1033E00029FB6943F7F3FC4AB37FD497EE9D8CF930 +:1033F000D56407761CA47E1E9C736A11D6D39FEEFB +:103400009B86F53E6F6F7DE14F0477EB8A3FB25E9E +:10341000747DB46F26BE5FD8F31BAE5FBDF2BF16DE +:1034200041CEAFB64A7AD1CFE31A8D7E45866F1E64 +:10343000EA57AE7C9DF581C8EC23927FDEFEFDF855 +:10344000CEE9BD5B5E50A8DDD288BDD59CAA815C6B +:103450009C6B679460B492067C4A3DEDAC2B188D52 +:1034600075F159A49CB8745B881F184B91A0D97F43 +:10347000A8DDD21619BF42F2821DF4195A7F297DA8 +:10348000E77ADFF37B856891DF6377DF7BB55CF7F5 +:10349000607038FCAE199BB0EEE776FD26D3E87776 +:1034A0000D4D2F8757CEFFACB65FCEEAFB65B6BD9C +:1034B000D35E00B9EBFC337D4C7476FEC9C19C3FF2 +:1034C000ADB42B114A977F57785A46727C8DB765F9 +:1034D00024E4E707B5EF4BE35B4682AFE97C4E3867 +:1034E0005A7259FFCF6AC985BEABF34751D492C90E +:1034F000DF032D9968FF8245DA53F88FE0A8783A08 +:1035000069E3DDD20FE1B70C477EE826E4F5711AD6 +:10351000C2251FE969BE8FA54B3BE6F939F69BBD75 +:10352000547FD07ABBA97C70C09CDF9A2EEDE70354 +:1035300043E26FFAA9EDFBC3708E3C21BAF5D73F89 +:10354000A38DF3D4539D713CAAA6CF0AB74E1F6E2C +:1035500029DFDB80EF8F3AF17D6B12F1E5A59863EF +:103560002ACF5F9E674F49FBCD0B79BE249C17E79E +:10357000811782FF8558CA6743BE9278D5F33A3ED9 +:1035800043E7BFF2A34549B0DF7E94AEDBF93C7D53 +:1035900040973ADE1A6CA4EF64433F2E2F386985BA +:1035A000DEEC492CB31AECDAEBF31CD8578B37E47A +:1035B000398C74D6B0ADE010491CE2EC36AB072074 +:1035C000375803F7427E6FD8A6B6F805973BBC5430 +:1035D000FFACF3C0DBA8B768436C3EE46DBDFDE211 +:1035E000F52312CB0C700EDD665E879C16737ED8B9 +:1035F0006E73FE04CE80DEFF7CBBBCA0395F70C85A +:103600009CFFE4835B67819CCB55FFBD2AF4893F17 +:103610004D3884F3F1D3175E8CC6FA2CFD4BD9419B +:10362000E849A17122B46E0AF408FF5685E9E3B2B5 +:1036300078911EF8811E0F819D61A4930AE13F6875 +:103640004DB9BCFE19D132CB4B745559B7BCE064AF +:103650004157BF57B6ACB343CE0B1DB7A7FD2F9C48 +:103660005E37EC6AC5A364D9557563C509F82DD6D4 +:10367000BE3B01F457FC4B85E58AE2E707BD0ABE75 +:10368000DFB663CE0D9CCE9AC8F8D0ED7D8BF72ABD +:10369000C128CABB4649BA5DB85E617DBDA4D11CD4 +:1036A0004757B63624DEA6D95CBE78F7FEFF869F64 +:1036B000BEDCF118C7335C1E271878057A5BC5A7F6 +:1036C00082ED3D159BBF0D3397CB792DD4E7E1BF3C +:1036D00096E3E1AE92553ACFB793C8D0F9F04B5785 +:1036E000516A06E1FDAAE68DAA949BBDC5EC9775CB +:1036F000DA39CEB0CA21829104CFA128BBD745DFE9 +:103700002FAE8F6279615118C99FF99C8A708E43E0 +:10371000F4C4A0DDA977549683AAE2251EAA1E57F9 +:1037200002B0C556C1488AFC1332BF04DE2655D20A +:103730008FD7003FD6CD98174D526FABB406F70325 +:103740002F9DE7C03673BD4A9AE7D138C859E6EFD6 +:10375000D5A29DEBD7ECFE36CCF8DD60DF657D525F +:10376000D76B55C83304A77A4704CBB3C49823401A +:1037700057AB14EFC30E15299DE3A0EF254E962FEE +:10378000E66E94E747338C839083D70D66B967AEB6 +:10379000E2CD04BEC4BA70D6A7A9DC1FDE8BE564F7 +:1037A0009643484E6639AA7D8E9DE3129BF35A825A +:1037B00090C79A1F48F1D00A327FE4F3E89E7096D2 +:1037C0007B9AA74AB9A7795D1F6EFF3140EB0B3991 +:1037D0005AE2B9F99E1C1EB79F2ADB893E520F2080 +:1037E000B93A137A02C1E541B92E4767C5FA4AB022 +:1037F000EEFAFC9B63DBA3E0C712E5F1DF4B6ED86A +:10380000A29D87EDEBC203F0539C548A0E5A0CF62E +:10381000A95B32E4F93172AC77AB568FFD1965962E +:10382000A977FF80E0297BD0E26E48E95A07E1F5ED +:103830006662FE27D785E783EE468E95F6A7637905 +:10384000929F470E171CBF73BBD6EFED1916539A04 +:103850001841F448FD9C2C94F6EDA8E1456C07A4B2 +:1038600035BAB9BB38903519F29C2AB317FDFE9AC8 +:103870006EE0E9A48BF152DE3DB94CD924E1F2723D +:10388000BCDFC85F85B3FDF0A476DEE8EB4174349D +:1038900082CF718D9FADD3E8665DCF7463A28BB983 +:1038A00090B7413773E4B9D84957DAFA12DDF07AA4 +:1038B000B7135D48BA11E26BB42F744B793B44DF08 +:1038C000EAD4B77BD0B7880E9EC8E86DA817420728 +:1038D000C21A18F18FFC2C25A362472AB40449565A +:1038E000E147DC2CCE46C6D75DD6C04A82A7BF557D +:1038F000AECB00ABA43B3A65FC11F95CDF8BF8D989 +:10390000E2FB170B2FD52F4E126CB74A27F926264C +:103910008EDB09A47007AAB0E7508AF6C531B2FF62 +:1039200062A26FC4B3517F5E4B9CC6DC46C27F2A45 +:10393000587E40FBE87C6EEFB7C8F65E2BA503D33C +:10394000E43E6A5F15C6F82BBE734026E864D25881 +:10395000339D24664A39414F1B33DDBADC90087E23 +:1039600050D23898CF9986F0A2AA5DD8A7CF487DCB +:10397000A378F54D934700BE67E33DD8C2A7A7ECF7 +:1039800060FF4A49E39C1F7F083D655B387FDF98F5 +:10399000E97B0F783FADB817ECA20F25335FB12755 +:1039A000527B5FCBD473BFA3748A7FC7DB9023A6FF +:1039B000CC50B9FE1421EDB9A2518E33D9FFB935DF +:1039C00091FA9B3C5AE1F094B67057F232F855B434 +:1039D000F53DA6D17743B898FD9C13700DC84CCD2A +:1039E000861F8224D46EE4E401995AFD31CA06C8C8 +:1039F0004303C7C9FDA7D7473FE8372D53EEB7CFDD +:103A0000B47DA7E709AF5CBF6C4D585B5A34525B7D +:103A10007010A5F3B2C69E039F99942A26AC07DEC8 +:103A20007FAA8A4D0C6F7B31F385A84C37F8828FC3 +:103A30001459A6FB6D8399EEDBC6B4B7DD49F9B620 +:103A40002D39D27EA7E9F30B5D82E582B63192EF84 +:103A5000B56F8964FE73CCD51A1527ED5DACDF9781 +:103A60006A24F1D7BA867BE1372E75DADB707E2CBB +:103A70007C603AFBFB4B9B49BF475CFD5AB37E4FD2 +:103A80007A78586637FA7AA85E0E9A011D95AD5578 +:103A9000980E073678EC7D99CF292ECCAFCC194CF7 +:103AA00007FF2FF384735CF0657AFB3784F791B0DE +:103AB0001F0B0EBA1A3AC8D70BE3163715B37E1A86 +:103AC00099ED63FE355025BC101DCFD4E86F12EC84 +:103AD000A0E04BD6D6BED897AF6568DFE35C994EC1 +:103AE000A6EB70BE6FD066736502BEB655E1169C3C +:103AF000B793564AFAA67DE7C0BD80BBAC2202FC54 +:103B0000E0B8D67EFE0A6BD146CAF777086B541C24 +:103B1000E82B8FE93B90E5FB0CEBF7E92FC428C8B5 +:103B20000DA56BD749B834FA10D623E3E3699C4F4F +:103B3000B7A4E4C3AEA0D353206B6C76E608035D54 +:103B4000CC50981E683E87609F9D9755928F72FA61 +:103B5000BE1FF432696C301D71D8856A25C7AB76FB +:103B6000240A0FE2873A443BCB231D248F803FEA8F +:103B70007C46E72744175E4742D77AEB7C656B3D6E +:103B8000814678DE56EFE0F4A97A97B0124FD85EFE +:103B90009FC8F967EBDD9CB6D467F1F7E7EA3D9C77 +:103BA000DF593F8AF32FD47B39BFBB7E22A7BFAB3F +:103BB0002FE2EF841FE64B3ADFD1F9934E5F3A9F35 +:103BC0000AA5AB058466DC33A0F6CC0F753E887978 +:103BD00058F2BBF893BECEA94A913F11FC50B4CE27 +:103BE00001FF2854CF3EF322E1B9A3DCC9F1A11DA6 +:103BF00042F2C10EA783CF8D64BBD80DFB40C33208 +:103C00006FDB9D8673785EB922AC06BABDA9365CBF +:103C1000580D747D735DAC293FBFEEFDD7FA50FFA0 +:103C20003F8BF12DC2FA1CBBE3D4A37FA4EF8FDF3F +:103C3000713A03EB4E706C7908E3DE1EA1C1D12A04 +:103C4000E1BADDCEF2D2C008A94FE1CF6188732D71 +:103C50004E897DFB3704E7316D1D06DA5DB346C141 +:103C60002EB34A75ADA42A1F63BDE8FB9FB5F52AA4 +:103C7000A90B637C96346AFBD418FF4CF83CDE57E2 +:103C8000B05CA77885801FE9F82FEC419211C471D0 +:103C9000C51150681C8594ADF9B017AE79FD28E4C4 +:103CA00074A5EE10CBD53E8793E32884DF76D6D873 +:103CB0009F527790EB89D6FEA638C8C8E15E3BF8E4 +:103CC00005681BEB56927540609F8B2685EFF1943B +:103CD00069DFCBD628A6F8E27B3355E68B8732AC7A +:103CE0009C0ECA149A13A589CF299D5E897F703CCA +:103CF0006359539E7D91812F9768DF4BB32CA67833 +:103D0000C74319322E6A109805A57767A5DA1732CE +:103D1000DF7373DCBD5EBF242B7F75EA70F483E82C +:103D2000A0AEF68F645AB9DDA10C9784C741E7595C +:103D300014C7E9747B2EE872CCA7F8EF950C3FEB23 +:103D40005915CF3EFD2CFC7B157F0AE3F3A9629841 +:103D500066DFC80E8C9CCEF28FD7A98C84FC2DD741 +:103D60007FFCD37F89467C54CD4E6957A5B40D693D +:103D7000F5EDE56C57ABF6D0FE88039F35FBCD5FC4 +:103D80007DF64FD1ADAC97F893B4F85B8EF7AADE11 +:103D90007982E3C0F4B8AFD07635CA37ACA7EA7100 +:103DA00001BA3FB6709F8DF74DCD1E85F5989A5D8F +:103DB0001713C0E76AF6AD4AE82E2E27B45F3D5EC2 +:103DC00040B7BFD588B59FC37F4884C3F80FADFF08 +:103DD000766654AF53430562D5AE603B8855701C80 +:103DE000C7722D8EB32390C17EE19EE4ED9AF5C497 +:103DF000F049BFEDB0BA6310AF7C418889DDAD53A7 +:103E0000FC20797E9FA37D04BFF085ED2ACB91171E +:103E1000B647F17EA8DE7EFF41C4DB556F56D88DD4 +:103E200057258E30DEAA77AAC261E00F35B00BC5E8 +:103E3000F70CE7D2A7A36A415F4B5A14EF16F8AD0F +:103E40001DEE98DE0678DA35FA5A1AD63292D74540 +:103E500083FF14F89A41CE5CB2F77E8E13A47AE702 +:103E600059AEF96D24C7B3510F6F03CE331B0AD877 +:103E70004FBDA4654735CB05DB235D10694EDBCC18 +:103E8000F729BED1C6FB4693D3CEC04F82F6CFAA48 +:103E90002C0F034EECCBD35A3CABDECE3248B6B33C +:103EA0006878FB0DF6E788AEFA4B5ADAA2D3A9FE82 +:103EB00027BBDFE7D43948EEE325CE23B938473FA7 +:103EC000D919C9F7ED3ED9F9EB092FD178E75AC6D0 +:103ED000F4520CFB6CE0201BD73FB741C601F32521 +:103EE00011D60F5A783E67B62729AC2703DF849F87 +:103EF000333B9F8FB6F03EF6FF7B71ABB3156BC8BB +:103F00007D84EBB24780FE5BB5FB11ED9AFDE57F4A +:103F1000A7FF6AED7B9B52A48D23EF3B083D0EC2A9 +:103F2000A5ED3BD5C9FB6E79949DEF2F2C18E6BE0D +:103F3000711EF8E89B328E51F4773F04FD6FC13B50 +:103F4000F16C6F596E73F741FE8BC336F6132C2854 +:103F5000F01CF5A17E8C9DED4A22B17504ECAD6D8F +:103F60002952BEA85C433B9350DC8FE8CD4FF8ACA0 +:103F70000C58848FF29307A5F2BA3E526EF1DAD94B +:103F8000FF13E4FB92C7ECC28F7B2FFEE7A47E5D9C +:103F9000992AFD0E8F607F515A1917CC8C87DD4E00 +:103FA000A39BCA69546EA09FCA4DC14CC84F67ED10 +:103FB000D21E8972E84D95F9B25E8346A7E807FDE7 +:103FC000B6A5B8CEB3BCBB2B4A40EFB0BC1825EDAC +:103FD00021BF09DF146638AF6F1A24E9B841F3072F +:103FE000FAB748F80017E4F825F6A64CC8B9FAB8AD +:103FF0004BA29B78BCB3DA784B229AA4FF448BC7C0 +:10400000437D1EDF26D8BFD3FE6418CBCBA7FB1E93 +:104010007901E39F7E7230C711B4A50416EDE6F274 +:10402000708EE3AE782A2C08783F7B328AED589F59 +:10403000D9A41CF6595402CB6187A21E5C80FE3ABB +:10404000368729E0A39F29C29E88F22DBD590EA86C +:10405000A8AF633F4905B117C8AF944E84DCF7D9C8 +:1040600096C16C27FAEC0D952F29D0F735F8EE1391 +:104070004D0B7EC6F2BFF43F9E7EEA6F83BBF3AF6B +:10408000546C36DBC3F4F5D7CBEF1824ED03770C73 +:10409000927AC9CA412EE97F8B6C793095E729F96C +:1040A00003AD03EB7FB41F13606F3FD6B22741719E +:1040B00002CFC1CC5F03EFDBA49E757ABB8DFD42BE +:1040C000152F4679D9FE74E7157CEFB042957278CA +:1040D0008545DEDBABD0EE99564467B27D8BF0CDE3 +:1040E0007A6DFB16551B478EFBD9D601D29F10D493 +:1040F000F22FE4F03DB84971E2E6692C5F6DC80526 +:104100005E2F6E8EE4F8791AC78BB8878A9FFD5CA4 +:10411000E2336611EB0774AE317FAED4F873D59DF0 +:1041200057C7E05E817847E5FB1217AD9E3EE0BFC2 +:10413000A1F87A4FE3634B5F7894F94125ED17C4FA +:10414000592DD5FCCB4B9F52589E5CBAFAEA879802 +:10415000EFBE6D13B85F70B6E5FE68E37AECD5F894 +:1041600067577B0FD75F4AF565FB37A3199EAD36BE +:104170000FE0095DC7EFDDFE29F55F6A5FD142F20E +:1041800045EEE5F3BF288EDCF627F095EDE16C6790 +:10419000A3F5E77B46676C2D8B30FF33CF8433BFAD +:1041A00039132BF7FD27749EFAED80E787F7B15D91 +:1041B000EDBDE902E7D0E280B95F1DAEFD1ADFAFC9 +:1041C0008AF7C4C04F5345EB81FE687D7EC4EDDFA6 +:1041D000B171FBD0F93C8E76230CFBF49948A69B79 +:1041E00033FDE4BA9C7976109F676DB192DE09DEEB +:1041F00064E84B6762658A1B3EA0870A97A48733F1 +:10420000635AD81E7046D9C1699B4DB6ABA8D3FC82 +:10421000DA447F89A01FD026ECA98EB54720C7803D +:10422000CF8FCCE73488FBCEA17673D029CEBFBE2A +:1042300059F2DC8478053ECF7E1BF6E3B4F03D7383 +:104240009F264F566EBFDC4F8875AADCAEB03FEBA1 +:104250009276FE02EA5EBADD9FE872A95FF1226EF5 +:104260006B69E3B225A0FBA5B5EBE681EEF5792CF1 +:10427000D5EE5FB7292AC3D3164EFB27FBF2F174A4 +:10428000FCAA598A1E9F275CFAF9457B382CCB2D56 +:10429000E988B24DD45F65A3B296C749D1F55B39C1 +:1042A0003F1D4FB8CD02FB5E9B76DFB9A7F9EB70DF +:1042B000F6044F5296E44F6D29F29E6FFB5BF2BEFF +:1042C000F6C56F0A62E2FE813CC891FA7A7F047FEC +:1042D000166810728FC6E796C2AE4E70666E30FBDF +:1042E00073B2369BF343B69BF3D93BCDF9DCBDE605 +:1042F000BCE75573DE85717B77E109FA36E203A1ED +:104300006F2385BEEDCE94FA36F2D0B79142DFC668 +:1043100077E8DBC843DF461EFA36F2D0B79142DFBA +:10432000C6F7391A9E2A357B29D681E3D4F684EB69 +:10433000F100BC5F2ECC49603E2AAC521FBDB024B8 +:104340009BE5C74E3BD35407DB99F438A7B7A27C53 +:10435000E3B27AC37F7B6475DF146EC7F6E79ADF3A +:1043600049FB73657EB813F68ED6559FAC86D8137D +:1043700088F24D44FD0BB6F6ADC06F55DD2BEC6FEA +:104380006F5DE17EE70772FDD8EEA2C72D15E3DC75 +:1043900003DF267D49C66F7B1C463B6AA85F48AC9D +:1043A00035E4213F359BF3A17E20F035AF695F35C1 +:1043B000311D3C6E6BEF0BBE7FE24907DFF33AA184 +:1043C000D9EDC46C17CB63BA3CDF298FDDA36CC277 +:1043D000F9BD242B8EDB771CCA30DDD30B4D4B2F60 +:1043E000E5B3BCDA995FAB58304ED98C15FB59AFA9 +:1043F0004E8CE673E9160DB64190FF0D700F0E441A +:1044000098E868E8B6B810BF653F53FD61BB5343F9 +:10441000FC96434CE5D3D71698EFB5175D6D2A1F70 +:1044200068EF8C877348FF96069F4BD6B9E8CCE7B8 +:10443000F986D64B563C7F84BF56BC25E5D3329ACD +:1044400087B7407B9F231FFE39EF14E0AFBCC51632 +:104450008BF3BE543B87449DF95C2EB70ABF2BAE4D +:104460008BEECA5DC21B4BEDBFB43625331DDD712B +:10447000345925142D19722437087DE58D2746827D +:10448000AEAAD48DC92E2ABF55096CC545ECD3718F +:104490003B12AEA4F2FFB4F81EC9A2754AB605EFEE +:1044A0009D0F3EBA234DE0BD91136B9F8FE6B83C44 +:1044B0008DFE926DAE08D0C1C62695F514D8CDD428 +:1044C000B82E3AD9D8141F01BDA67C8CE297727120 +:1044D000B449DF0BC547A19AFD8E9BE67BF1902A7C +:1044E000EF406AF35CEE92F545BA6CAFDFB3D7E705 +:1044F0007B52D3472B36BE96790B7D3F3B787F2E80 +:10450000AE8457D6EFE6792FB56CDFDA97D27B1DF4 +:10451000BE5D98D7F2B7C6455F49E37CB95DC687F3 +:10452000FFB5F989C7FCC44FEF6C7AC20EFB418519 +:104530003560871E5CFEE4463BE218AEDBB691BFF9 +:104540002FDA56CCF600FDBEDAA77A7CB3868FF25E +:10455000B1CA0617CDB3FF60C94FCA23641C4BA173 +:104560003AFA35DC13B8B84DC9C3BC6614EDB0E3F4 +:104570001EFF3B1ADF09DD371D87A717F686BDAB87 +:1045800045F120DFD33E9989CB72440FD32FB9393F +:104590009D716908EBD51F0AD2BE708E6487E8D77B +:1045A000875569CF433C12AD73B93DD86B3AE4856A +:1045B00097E5FB0F55740E8DCA87DE2EC4559416F1 +:1045C0008D564D745E333ED2B40F660BC3BEA2FE51 +:1045D00066897EA6FC8C4969A6FA37CE181AE2676E +:1045E000CEEF2A67FE7595E95D97AADBFD6E85E340 +:1045F0007BC69ABF537A3BD3D90DA6F655629AE98A +:104600005D97259BDF653C1395D9A18F956BF7418D +:1046100066FBDAB4EFADFC9D2662DAAF03D33C7FD4 +:1046200094E7A58DFD08BA1D7D36FE9FD6DD79196C +:10463000D1198F89F85BD83B7C6679E408EBA942F5 +:10464000AE4395668FAACA92F6A82AFF113BE29B59 +:1046500009FFD62442497593C2F646AAEF488A93C9 +:10466000F9DBF17DA7F95E07FABB84F2436A31F604 +:1046700057687935CD1BE74235EC47B083E9FD6BD0 +:10468000FDEAF4197ACF3EB41FDF6037EFE78A6D99 +:104690003B0EF623BC4C2F8ACD437C4965CB545B43 +:1046A00071F6E574A6F3FD8BE516B67F751C7E8565 +:1046B000E9ACA3DCEA91F1DDFF181FD55E696F0D4F +:1046C000A5BF45341FF89917ED543C0145D6035E4C +:1046D000FA812E43F092D40DBE743C75E22DA47C79 +:1046E00031FE331CF1114A007CF232BCE878D4FA76 +:1046F0005FE4132C67123C018627A43F312A74FF24 +:10470000DDC2EF20746C50844BF96E3C4CBB24ED41 +:104710003603D3E4BCDB77291EC8EBB32E59F97BF3 +:1047200027BD14C938F51993CCFBB3937E8AE47E78 +:1047300099792981DBFD6FD3D177D18FEE9F098DD8 +:10474000FFD6EF5D2D1AACDD4B1A21467CFB4FC422 +:10475000AFEB72404FE749E779E3D2F0EF4CEDF66B +:104760001C5E1E95CAF1DA3ECD8EA8F3639FD64E2D +:104770001FB798CADD05A0EFFE09B017AF6E4C4B0E +:1047800036BE17E35B65633B6FF28A784E8BC35D81 +:104790000938478A57C8774D8EDFD52701FE88E351 +:1047A000AB6CBD2651D7C77F3A3C59E4205FC8E9BE +:1047B000897561B38D76783D6D1A2CED35FA397EA9 +:1047C000CE72387A36F6DFAA5DD108055ABAEAFD0C +:1047D000912E3ACF57597C8F0F667FEF463ECF859B +:1047E0006B632EEC70BA3C51B1AAB00FCEFDCAFF7C +:1047F00079E5319CFBBE15B604C8A39F7DA00A8451 +:10480000CED079C672C4A7E192AE3FDD12C9F710CF +:104810003F558417FEA625EAFE5C97E95CDD3B0B5D +:10482000E3FFDE41E38EC0B881AD8918D7E3CFC482 +:10483000B8BE151931DDD957F4B466BD94F3B6EAA4 +:10484000F664CDEE0CF91E79C8F7706241BE471EC2 +:10485000F23D52C8F7F8BE4DF32F0C6C68CF837E43 +:10486000EA1F2BB26AF9BC7566417EBF4589F080AC +:10487000FFDCA278FA70BCC166F9DEC4F29075D58F +:10488000D36BDA490633D0ED0F2E3984316E6E8C3E +:104890008835E5C739FA9AEA17BA524CE5D7250E9A +:1048A00036955FEFCE33E57F9875A5A9FE64CF18E6 +:1048B00053FE47A3AE37D59FEA9D6ACA4F9F38C7BC +:1048C000547F6651B1A9FCC6D94B4CE5737CCB4CE7 +:1048D000F979E53F35D5BFA97685A9DC2B5C569CD7 +:1048E000777BA17711DE5F86DE45E92D6F65388D18 +:1048F000EB3A7A9CA5DB77794E697250BFA1DE3620 +:10490000D025EED7800E0768F767BEC0B9D21B7EF0 +:10491000C9A022F5DE237D4137A1F542CB47471ED2 +:10492000B8E8A6352C7A2A7AA695F8C4E82B0E1496 +:10493000A4517EF5538533ADC45F465F7DE0F954E5 +:10494000CA373DB54A960F3B7011E5514FDF20F352 +:10495000D3058B1A8F0CF97A869FE631FA07A96B7B +:104960003DD26ED26DBC69A73D88F080784DE001E4 +:104970006990E813E901A24FA4AF127D96A50B71CF +:1049800090E813E921D23FF1FDF7A47F223D4CFAD4 +:1049900027D2B749FF447A84F44FA4EFD5CFE6F489 +:1049A000837A1FB7FB437D39A747EB6BF9FBC7F54C +:1049B000759CFEB9DECFDF5D43743B4390ED31BAA9 +:1049C000FFAB1A7E47D8ED76DBCE1AFDC28A579E22 +:1049D000A7BABFB2A156B446629FB65A634F39BA5E +:1049E000FC903DF35BAB386590BF5E0FF7260DE1A1 +:1049F000F1FBBB986F6BDF8F89E903F2699D0A5267 +:104A00007D29289F995FBA2A86F8C70FBEA9B5816C +:104A10005E3EB4747F7FFB0B8D4EDA877833878CD4 +:104A2000E8F2BBEB7EEFCEF81A835F1EFE6C3D8E84 +:104A300047F7C7F39F213E47F793EBF141D76AEF62 +:104A400023E97E703DFE47EFB7F09260BE77CD1A46 +:104A50002BCB2D515611C4387A9CCF358E963CC441 +:104A60003B5C53E9E438B73EF41DEF23523D2FDEA3 +:104A700099DBFC25D5CFEDF2BBF7D1E641E53C8FC4 +:104A8000C24B3EB6D75EA3C51DA0BD4396F33B7592 +:104A9000881183FC4129DBE11E55A87D7E571C004F +:104AA000EA47CAFA41F497FE158D17DDB58F06C4A3 +:104AB000B5E4216E6C40B593E3C6368C09F2BDB9FE +:104AC000E9B1D7DED3AA224E38E6C7D8474FA7FAB6 +:104AD0006602CFEFEE730FF0507E5A5C5A6FA4530C +:104AE00043DEB5EB667DE6625D757CE978D7D74B32 +:104AF000C7B7219E8AF1FC5DEB17BA6EA1EBA5AF9B +:104B000053E1A52EFC037F97AF4FD7FAC13EFBFFC1 +:104B1000CBFA0CB7B6F07DCCB04A8707707DD77A58 +:104B2000DDDC2E26E03E78F125F741A44BD27C5FF8 +:104B3000807F968A31135CC0914BCD819D27B4DE76 +:104B4000F2EF59EFE1907A07E20AD67C9D7679BDC3 +:104B5000DD21F51A620BD67E2DED4C37E27C3DE46B +:104B6000B6B11FEDCD703D1EC3EBCCA3751CA7F1F4 +:104B7000A343A296CF0F12D7FC58DFF1DA528FCBA6 +:104B80005ECC72EE78A7596E9CF04D5123C69DD035 +:104B90002B448ED6FCE13768FD5E279AB8DFD07BC8 +:104BA000F23768F269E83DF9E78668F2658A4801FC +:104BB0009F1A2F3C122EEDBD83F12ED96F92462FF6 +:104BC000696E558C063D089F15CCF155BC77908BCE +:104BD00071FD9CBF5E0438FDA108723F938991224C +:104BE000FF23216CF29D03793FB35AF5FD27E42C96 +:104BF000FD5EE6C270DFABD877AF444E998FF728E1 +:104C0000C6158C4B47BB03E3DD2C9F1C70A4B1BCC5 +:104C1000847D658BEBDA7F6FD0F9926E95F7069104 +:104C2000E2DE603A6D96D7E9FC41FE86AC1502EDF6 +:104C300026B8CD71387AFB1FBAC60A6B41CFFCFD8E +:104C400087B97BFAC3AEF366ECA0F1B083BF197BE2 +:104C5000C578CCF7CDD83E169986D939CD7931BDF6 +:104C60003B794EA7E7AEF126086B7CCF78D6F11AD8 +:104C70008A4F1DCFFF025E2F7487D72F060B29376F +:104C8000474A3EA2E3B72AACF31E671F635C44A504 +:104C900043E2E933808C7BB87557F13C3EA917FDA0 +:104CA00081EF4575A3B83CD40E2536C7705E7FC72B +:104CB000ECCC83EF4627127CD7397CEA50C2CBD9A3 +:104CC000FC60264930E2930D0D7CEFFADCB3AA07B5 +:104CD000F27FA5EA5EEB014F7953653FA0F8E695B8 +:104CE00064F809C5E6EEE3A32B1D12AFBAFEB3329A +:104CF000AD88F7A7701524CAF7D5E43D725D1EE8AC +:104D00001F26E38BF5FBCC3DC9072323241FEB1F94 +:104D100026F9AEBE9ED48EF349D4CF48E25349F76C +:104D200045B03EB0DBE54D1A0A7FCA786192A7759F +:104D3000BDBFA3977C3FF05A91F9D068CA8F3F64FA +:104D400013012AEF182F4CF164856F94F2BB16FA09 +:104D5000FD98B044D2AF0CFC20DC1D617A6F343278 +:104D60002BCE948FF2F433D58F19956A2A8FF50ED6 +:104D70003195C74FCC37E57B175D65AADF67F658DD +:104D800053BEAFEF0653FDA4F269A6BCCE9792E4E2 +:104D90002731A076AEA9FDC0BA1253FD147F85F964 +:104DA000FD54BFF74856029E77947F696B9687BC87 +:104DB000AF6A1196915DEF90FC3A5ADE0799E85C74 +:104DC000C4EF916434FDCC0C8FFA8D8A732629468A +:104DD000E1F724AE739BF96061A2393FDE95F72AB3 +:104DE000966E9C2B34FE28A8809E926AADA6EFF3A7 +:104DF000866A7C3457E4B29EFE5DEBEF1B625AFF7D +:104E0000507C5D4E0FCFE705DDD29E6F9C17ECF90D +:104E100046BCC09E6FCCC39E6FAC0F7BBEB11CF670 +:104E20007C6379C121331D8C3862A6832B8E9AE96D +:104E300040A7CFD0F5BAB2D54C1FC2A7F8947FB027 +:104E40005E577F6AA69FD0F521098BD76F825311D9 +:104E50008FA4FCFBEBB52E64BD3AD787F00DF9F6B5 +:104E6000DAE050BE275B78481578B7E4516D9ED7DD +:104E70000DADE527C3B65B7DBFE67DAED155435F83 +:104E800049571D879E0F071F7D34A4FFD7FBF902EA +:104E9000A83F3BFE62B21DF4D12EDF456B031FEE2F +:104EA000DD15B7497ABABC77F23395E3188E599A73 +:104EB00014F0EB8218DF36F0CB9BB36B15F8671359 +:104EC00045D18E4588CBF98FB064E4170C94F77701 +:104ED00045762BDF7FD0F9E282241917D83254F3BC +:104EE000F37A64DCCEF343A5DD24CAE3E238E3E2DF +:104EF0006C79BF83D499E40539C0C7E1F041C0475C +:104F0000B385DF696CB5B9396EC4FF862AE0F783D3 +:104F10001C0BF9728026DF357CE47000FE41EB85C6 +:104F2000E99C1D1C7098E25B876E7399F2392D899C +:104F3000A6FAC376BB4DE579C12C5379C1218F29DF +:104F40003FE2C82853FD2B8E7A4DF92B5B279AEA56 +:104F50005FFD6991299F24DA1F067E072A528F3E42 +:104F6000333455E2C92D387E6FC19DB1F2DEA7A65C +:104F70005FEB72BA1EF7ECD3E83954DE1F68F771A5 +:104F80001C75435FE1E17B180E4D9F12663DC0A783 +:104F9000C52D77DEA3F09BE396F578E54E7D41D3F2 +:104FA0000F7439DD10AFEC35C62B2F08EBFE3DE05A +:104FB000FFD2D63D14FE817639DF869FDAF9DE888E +:104FC0000E57283C33B538DA2D8EEEEFF5D8B225E2 +:104FD0009D256514FD1DF4FE98CDD3CA6FDD5F36A7 +:104FE0009EA7D54FF4D5F00BBB67A5FBBBC75B30C5 +:104FF0004CCE67BEC572F3D46C8ECF32BD83DF3B1F +:105000005BEAFD51B94AB7F35B1023E3A7448CDD9B +:105010000DFAED793C89CF44BB68E4FB475A9CFF0D +:105020004D6B5BEE194445F3ED4DDA7B60011BE8F7 +:1050300061D25892C3F284D8B66557B393E4A2C73D +:10504000EAAC6C3FE9BFDD358B24B8CEFB1B0349CE +:10505000EF017D40B681BEB42147E571AEC19E1B14 +:1050600081FDF64D679C3DFB0584D0CE0BA94F75A5 +:10507000436F4C87FA3CFEAFE3ED43F1A4EBAD4246 +:105080008B334CD7E0D2F1D76977D0F0A7DF7F70B0 +:105090002FB3156D72F23D8A8988DBD2D7AF2547D1 +:1050A000D265AD860FD4033FEAA95EA19A1D03FB2A +:1050B000728770C7B8BAA1433DFDBFC28B8EFF9EF9 +:1050C000EE57F5C41F42F9C277DDB7EA894EFFD922 +:1050D0007B57063E21E368B47509A45BD83F7D6722 +:1050E00094793F6FCC96768D71DABEA2F3DD996725 +:1050F000E61702F6F18655AAC62FE4395E9C52C423 +:10510000EF118B3A17CB33E51A2FD6CFD7850FC8BF +:10511000F7E0AEF516255C45F992669BD848A015D8 +:10512000FBBB8FF366BF931B71FE9E44C0CD263739 +:105130001AB7B44909EC4FB9FCBDECC54EF97E5C19 +:10514000E8BBD98B35FD172F2A60DF86FA65EECFD5 +:10515000D6CE6B8FF07C2BE167BDA50B7E8DDE027A +:10516000F21D31E8C3AAB4F3709C968E3737FC2445 +:10517000F15D79C26F4416CEF3466BB771749DF83A +:10518000D5FD2A9D7EC2C31CAF1F1A1770D6FF4AD9 +:1051900074777E1ADD7FD3D33EE8F4DF7C875FA887 +:1051A000C369891E053E04FFBFDBE857F9F3488257 +:1051B00090FD2731F08FB46AFD898DB9DDDD4FF4A4 +:1051C000ADD8C5F110AB2CBEFF405CF219EA1FEF61 +:1051D000B0DEE53C9080FBF89334BBD3E5F3D6E436 +:1051E000B0D1F27E40875FE5F5EE9828EF73131F8C +:1051F00015D877BA1F7FAA08F642AAFB497C6B46EE +:1052000031FE753F49717014C339B361B10D4F4818 +:10521000B63E7C7B6184BBCB7FD23A40C6E7F4E4E8 +:1052200047997EC9C3FDCDB87415F7732C3B45CAA9 +:105230006B8DF72C039D0DD9266C9867ABADFBDF0A +:1052400019989223F7D152F8D27B1BE27E5628ACF4 +:10525000072C57841E07C47C5ECF5F6CD2F2853268 +:105260007FCB2A996FD5DEC5DAAAD93B304FA498F7 +:105270000FF4F0ED9A3D04F3408A79E03BF81AF21E +:10528000E06BC883AF210FBE86147C0DDF4B445109 +:10529000729E2AFD3DE30DFB03FE9EF106B909FE59 +:1052A0001E631EFE1E637DF87B8CE5F0F718CBE1D4 +:1052B000EF31E6E1EF31D687BFC79887BFC7581FE8 +:1052C000FE1E631EFE1E637DF87B8CE5F0F718CB97 +:1052D000E1EF31E6E1EF31D687BFC7587E739D62BB +:1052E000F207DDACBD3B50BA3E8EE9A339B52829A3 +:1052F00087D6F73F23FFE7C7B654ACF3DE25FC6E35 +:1053000060558447AE73D344B9EE1621D7B97D0EEC +:10531000AFF3ED76992F94F1C2A1F403BFCAF874EC +:10532000E957410ABF0A52F85590C2AF32DE2AFD52 +:105330002A48E157C177F85590C2AF82147E15A470 +:10534000F0AB20855F0529FC2A6807BF0A52F85593 +:10535000F01D7E15A4F0ABE0FB318203FE151D2E7F +:10536000C8F9E9263D94E8D0A487BA4C79C8F9C6B3 +:10537000FA90F38DE590F38DE590F38D79C8F9C639 +:10538000FA90F38DF91BF188716F29EF1BDB41DE79 +:1053900037E6739AFCAFC1863579C3F95791B646A3 +:1053A000298F292E92EB729E9A05FF586BB8921C9A +:1053B000EB213976C56F678DBF92F889166F972BF1 +:1053C000DA2D586FF67BD3BAF98282E38373FE3B02 +:1053D00091CB757F2BFFD1BAE7ED14AC376CCB9036 +:1053E00070E9ED3DC2A522D5EB77E5BBAF173ABE1C +:1053F0005E8FF9A5010E5228F310079177BB331F7A +:10540000F1ED5B2D8A8C0B5D29E37243E9AA49E338 +:105410004B5B2D3B0E4450BBF662C5837B07995610 +:1054200071C8960F3CD5E6439EA8CB89D5E2836B25 +:10543000AF423C900EB76E7F243EC1F7DD46B70BFE +:105440007B198D73CD17C28EDF5B986497F204DAF7 +:1054500041DF1CEA57BC9B0CF4BD32479E7B3EFFEC +:10546000B2ABCAE8FBD0EDB557E11EDDA408D9EE1A +:10547000378F47331EA7342A9BF0FEC9E8EDC28B55 +:10548000FBB1BFD4E01EBADD652FE3715D7CFF4E3A +:10549000EFB7784332DF172C16ADE313D927A1F00D +:1054A000FBE63ADE687EAF627EC4E20FC18EFC2F5F +:1054B000DFC32171F1FBDCC3B966786C21E2DBC488 +:1054C0005EF90EE4E4E1C5AB7A135CBE807C07F2C2 +:1054D0009A2F6A5FE3FC66F90E2493CF48868FCF3C +:1054E000C3417E85DFFF98E2DF68E9E5C6BDE015D0 +:1054F000B604D4DF2E3C500B060979AF559F57B642 +:1055000038620957402FE2957803FD11E798017A38 +:10551000C9F3D8F87D90A956970DFC4697738A5D1C +:1055200072EC4275740CDFF70B91132E36F6E6B869 +:105530008D7F3D8EA483EF932FDF15CE72858FF87C +:1055400007F8E6B93C197759B9ECC39196D4AE384F +:1055500092D32981AD78DFF374EA8EE8510ACB113A +:1055600087C05FDB1A9FE77B82C5AB5EE3FB10174A +:105570001B1F8896F7AAA47FA54CC39B6E6F5AA8E1 +:10558000AD4F99163F74BC5EBECF4BE730BFF7718D +:10559000B1D1C67246A8BC2884EB0F88732B6FB4B8 +:1055A000F1DDD3C56B8B57278AEE7E77C52BE3CF12 +:1055B000B5719734DA384EA85C7B472BF477589650 +:1055C0006A72E8D26DE6EF277242E44FFDFD44AD0A +:1055D0004EF15BAFCC6439A8D6C671EEF35748B92B +:1055E00048EC1001DC6798BF629C05EF58CCDFE502 +:1055F000F528DDD0D13B9A7C34098312DEA75E8A80 +:1056000060BE32ED523FCECFBA94C8E98D97B2E476 +:1056100077AC1DD14B6BA1BC5FFFBE2617CD441CE0 +:105620006501E4B23E4CD71D44D7182257E35743D7 +:10563000BCCA2B30C34FB2F956214E73D246C1F7C4 +:105640009126437EA282D990A70AB02F520AF93E32 +:10565000C64485EFB74C1EBE4CDB07B42F04F311D4 +:105660007EF7C3377E6A00F137B37D3B2C58777DD8 +:105670003FF8FC6DFC0EE664BF62C77B813E4DCFF8 +:10568000D6E93D745F2C88D4EC634E69FFEAB48F91 +:1056900001587E9C27F246C4B32E802DB39FB6B02E +:1056A00084AAA86C599E9C1B79632394AC7FD36E0B +:1056B00032DF6291F79F48FEE3787571A4B00FE581 +:1056C0008BD72AF98897D7E1FA7AD8D849C37A775D +:1056D000D14149E7FECCEE03BD60F95D1926FF4CD0 +:1056E000685A4AF8C63E5A10D3FA63FCD2D0845C9A +:1056F000E11D9F8877C8F5F98A20E202E76AF9DBA5 +:105700009EBDF28F6B9C8C27CE8FCDED7723E23F31 +:10571000FE65FE385FB11A7F37AA4DF17973E53D1A +:10572000C80958DFC8EC767EC76066A64B9E2F215D +:105730007696DB72DDF25D84107B4B69B63C6F843C +:10574000D59D3C8FFD3A6EB657EAF33E6E33DF339C +:10575000D5D3EA5C6937F8BFBA27F1A045DEFB7FF5 +:10576000C412D8F122D16BA0B76F01E6FB08E2BDED +:10577000197E1FCF4F7F47A3934F69EF65E8F474FD +:10578000ACEE22DF972871DADDAA819ECAD6287C8A +:105790001FB1A44EDE27F6AD51E4BDFC1EEC578FC1 +:1057A000CFF99ADF517AFC1711B250C3EF7CFB910D +:1057B000D71C295DF8FD53DDAF6C927F0633106F67 +:1057C0003FB7369CDF41FE7A58D18F017F64B687A0 +:1057D000D76912F134D49F1AE3FB29BE97882307B7 +:1057E000616F5CF0F3B7F87DE19ABD29FCEE61F1E1 +:1057F000EEBCD57847E5EB61BE3B72897E8B9D2E72 +:105800003BE490EAC6583E9717F4D1EEA98B76F6A2 +:10581000E7E9EBF360AE94078A3C729C0B9A3E4535 +:1058200008B34D35D593E77FE83ED4EDA2A1F695B8 +:10583000D0F72ABECB9E027B89DD6057D5ED31B60D +:10584000ACE373709ECFB777FFBB8DAFEB76474D60 +:105850009F5DD8A9CF664FE803B97F9DE2821DBD49 +:10586000CCE9BE11F1F565876C88F01493E2DCF2A7 +:10587000DD92BBE4BB2525B7E6313F9B8F35C9C719 +:10588000BD8751BC8FCB0294C6F7BCDFE7AD7B650B +:10589000C01ED053D0CBF7E0CB5C5E7B9C412E2A60 +:1058A0006D524CEF18E8F91773A51D723EA919C087 +:1058B000DF4DB7A6D8F186D07C128F1037F8BA46E4 +:1058C000277A3BAAC771259352C541F9AE14C19DF1 +:1058D00022C733FE4E514993F93D06AACF72DDFE31 +:1058E000DC28EEAFD845F34E41EA6238090F8CA7A9 +:1058F000F67BA83F378FC3EB511A0CD86037988FCF +:105900007816CACF75056C18A7A451BE8FE25B2B21 +:10591000C7F1AD89B5E7402EB0BAEC038CF260A3B5 +:105920007CCF78BEF6FB11042FCBCB658427DCF34C +:10593000D2EF7D86E2AB5883BFAC29D62C5F36AD63 +:10594000B3617DE6F4F05EC3971A1D97348EE1FBD8 +:10595000F565562FDF97F069F8FEEBB2F0BBE12753 +:1059600099D3FC902D05798D2F7D093CF7069E82F9 +:1059700019FC3ED2B2708E679EE36AE2F976E2FBD2 +:1059800001C20FE4155711E39BE8C48F38C0B2661B +:10599000F3FA76C11325DF656F2EE6FDB7C8EAB3CB +:1059A000BB8C70ACDF9F81FB5B7368DFE3FD27E19D +:1059B000F2F17DCC530FDCC8BFFB063881E7288F9E +:1059C0007B02DE3B22BA61BAD6E9674181DCCFFABD +:1059D0007851C3ACD20E3FECBBF6A9F720E4F30636 +:1059E0005A6FD8FF7BDAA7765C00A471ED65F2DD13 +:1059F000BAD07DABEF577D9FEAFB56DFCF8FD98AB8 +:105A000082894A17DFA1F3BDF6B96EF03449837776 +:105A1000AEB6AE84D75785C1AE376298DCDFF3539C +:105A2000CDFB1FFDA1DF54BD7C6C3003F73DF5FAC3 +:105A3000FAB8F3E3643BEC03D05BEA304B67FDE577 +:105A40005CDF62E21FA59DFC63FBAA04F08F1D0AC8 +:105A5000FBE196DF23E5BEE5CFC87BE16796BFF8A3 +:105A6000F62CAA77FAC18D0B8CF72FCA82925F2C85 +:105A700024790BFC6391260F6CCCF4E50D33ECE735 +:105A8000B2FB9FC9C4FE98DB92770A6FA8D1BCF91C +:105A9000BDA33F3FF3D28757B9BBCE5D7D1E256BBB +:105AA000DEB5153B8D7893F47E7756079F5BA5385E +:105AB000B7E853696331F36191487A8FD2B5EEA1AB +:105AC000F450DCA8B09C575A3732A0FE2FF2EBD22C +:105AD000B553F98D287DBDF4775FF47357877FA6A2 +:105AE000B64E73357A9E3D4CEEC3B9E529F645BCFA +:105AF000FF53ECF8BDCD395AF99C32F3F7CEF5726D +:105B000075F2FBD5D827B89F84F5EA586B93F6CB8E +:105B1000ED97AD5732E4021D8EC59A9D72A1666F56 +:105B20005CA4C9CBB45E8B8DEBB5F871B95EA5CF23 +:105B3000BEF517BC5346F3D3DEA393EF0A94B4EC3F +:105B4000E0759BB3669D2D85EAFD64588A29FEA801 +:105B5000B436CF053BFDDC351B6DE0073F1926F160 +:105B6000164AF7F3B5F8621DAF388F14833F47AF7D +:105B70000F3EB883C6B9755978B4F177ED021A3D76 +:105B800097D6C6C661BCD2DAE27BA17FE9E740E8DE +:105B9000FE3B112EF74509F587FD79628C87EF559D +:105BA000CFD77E372FB4FE431ADDFDDA26DFBF4C98 +:105BB0008A6C7992E33B6A223CE013E9E9AD018CFF +:105BC0000B7A06DC768B7C2F33BDB2F573C041A215 +:105BD0003CC7F520C57B5B10ED1328BFC922EF79C8 +:105BE000A5AA32DDA7E107A637948B5EADFC1E5F48 +:105BF000E7BB5121F46A179BD7E0DD1F7B2FC1EF74 +:105C0000A6E9F4A9F7A3D3A74EBF3DCD6FD7F79C64 +:105C1000DF8914CDCE92E54976D0B80BEE1BC4BF18 +:105C20006BF15DF3B46BEF3576CE374CFEDEC765B6 +:105C3000F34D97FA52CFF36D2E4CE866BEA1F3D424 +:105C4000F7891E43DFE94F6992FE94130A9D63D4DE +:105C5000EEC4B2708EABD3E7A5DBF5BFEFBD878F87 +:105C600086C569F6AAD628C897F3B5DF51114199C0 +:105C7000C7F7A986EFFAF9AFBF5FA7F3E993B5DAE3 +:105C8000F9285AEFC17E1675697C0FF558D389281B +:105C9000BC1373628C844F6F77AB4DDE73165176F5 +:105CA00037DECFBBE9D63CFEBD94858D7D589FBDC8 +:105CB000A92E8DF9C24D7E581745A71EB048E38323 +:105CC00091B716AFBE02F5D7A7F0EFC22D747A4E8A +:105CD000ADE7F6433D9013239BA7DA53591E96FA7E +:105CE00082EE17BB5511457C4F0D7C12FBCBB23FAA +:105CF0001DE7CFE2F5523F9864116BE03F1DD8508D +:105D000034A12FF8C4C38AFC3D9A0DE6F7BC860E79 +:105D10002AFA027C26F45DBC5B6D2D5EE8A782E466 +:105D20000ED8D1163A8B589EBF45E393C79ADBF83D +:105D3000BD7E1DAF8FE0BF78A72AC47E146A271AE4 +:105D4000A8D907FF1FAF8F7B3D0080000000000037 +:105D50001F8B08000000000000FFB57C0B5C546541 +:105D6000DAF87BCE992BCCC080C84512878B84850E +:105D700034C080D7DA518150BBA0BBB9BA218E653F +:105D8000CA650650DB5D77D7FE8CA1A6667DFA4515 +:105D9000A665ED80976AC376483428A8C90B99593F +:105DA0007F62376A2FB9635BE62D40BAFCEDBF6DA9 +:105DB0007DCFF3BCE7301751DBFDBE6FFCF97B797B +:105DC000DFF35E9FFBF3BCCF3963348C751B186324 +:105DD0002A8B8E413968488964998C8D09695F6185 +:105DE0004C89C3F625DB45C64640FB7C93C8621947 +:105DF0002BD731FA7D8FBF1F31761F3C37C3F3425B +:105E0000A934D607FDD737CCA072C9D6C26DAEF182 +:105E10008C250925B1936360C0E36AB6078A25CE55 +:105E20001977302BCCD3A48DD225C373B52B29C7BA +:105E3000E09F6F49E343490CC69D69D4CF77437B0C +:105E400081694E41148C5FBA332A5B32FBFB5D6F74 +:105E500011181BC958A573461C4B61CCF1DDE167D5 +:105E60004CA9B01F98D304F37FE50977BBA08BA39F +:105E7000AE2D4982233CAAB3A758A07F95D8316F95 +:105E800012CC734E70EF4DA0FEE63853C0FAA1E578 +:105E9000E93AC6CCE98C39FFCF8734CFE7E2893BBA +:105EA00016C07887737F04CE53F5F81FF201326C69 +:105EB0009D68CFB2E4E1BC8D7B4D121C747B6356B0 +:105EC000099CE3BEC7C746DA332F9FF7B668B6A86A +:105ED00004DACBDB18C157695FE88ED420DCED5EB5 +:105EE000A6316169629A6828CF486C9507CADB526F +:105EF000D8A2B9067FBB0DE100EB9E89DC9254026B +:105F0000ED157B9F48324379D6C8EBA57B7F7A9C01 +:105F10004540FFDD5A0DE2D5AE621A0B8CBBD7258A +:105F2000D8DC50B2F268C61210A36E7D9991B159B7 +:105F300096709AAF627B0E63B9FE7DC1736A3FAB08 +:105F400062C5B88F31F503D9CBA1FC8BCA7B1FE2A8 +:105F5000F32FB57A8B2B19F16226BCFC658B548428 +:105F6000EDAEFB053656C0FA7E631AAC5F16C96A01 +:105F7000717CA1F4579B04CF571C10B2B5307B78CD +:105F800066B7E61E039116D159B589D3D98A7675BD +:105F90005122E07F458B402D0E9557331CBE2A2F92 +:105FA0004D66E680FD56B6B668CCB08EA319CE0914 +:105FB000FD1D9E539AA5785EB685B17CC027FE89EB +:105FC000F86B3EA5B937003FD5AD1C2ECE56DEBED0 +:105FD0003803903B99B66213D2A0DE2650BD3E6BCB +:105FE000C2FC35AAC07AFEFC3569589A084E4C3579 +:105FF000905402F0DC94D1A341FC3BD7CAF3425D3C +:106000001DB05E0D12E548DE9E6AC0F1661AAF3C17 +:1060100077B646D178AF336C03BB0936516D50610A +:1060200059EF344460B9B356CC50597173611609B5 +:10603000E0DF111691C52261CAAA5E3D4012503BB5 +:10604000705884F6DC48FB83489F710CB802E83333 +:1060500091790506F4DFDFF9592ECE7FCB18DF17D3 +:106060000CB6AE5E337D7E01D0C3268B7C8E4C5F3A +:106070002ED2F1C84340AFB0BFA7D56C833E07CF47 +:1060800057C2E6423BCCC208CFDF84B9F7C0DFAFCE +:10609000316F22CECF74DE541CF79ACCA7255AC399 +:1060A0000601F6F59B14FB63B88F3B05F5F86C1100 +:1060B00071208DC57EFD6AFE9C6D79C2A603FC4FE2 +:1060C000E7E867A345E66240A29A51F106A463C1DE +:1060D0006663AB60FD07330FDDCB802E1E1ED03113 +:1060E0002D9CAF5ECFCF3D7D20EC9400FD468F2AE6 +:1060F000165916F437AB5829F43F94297A55D89F8E +:10610000E9DCD89FE90A6DBE0C599681FCD0887AEB +:106110001BF5EF78F31B01CA44E9E2E1483857E286 +:106120002F054B3DF4291B3CFDF4FF85B2F452537F +:10613000CBEFA1FC75A4BD19517772B0F8941D5036 +:10614000F6B0C9A3B364F2F902F7DFF1AB6F22A294 +:1061500045FFBEFA074EEF7BD98AA5CE22C0B8E92B +:106160001D92579B75F97EFAE361E3A9D48FE1395B +:10617000FB0DA25B10B0FFE10F717FD37506AF146A +:1061800081E3D4177C3AFF38661E1D75FA4646280F +:10619000F83E91B158DC3C8C1FB8687037C1B96FBC +:1061A00091F94FA1AF1E8B48F8E991F1A4C091E994 +:1061B000B222917EEBD58A5EF085B34C3F7FD6E864 +:1061C00038FF0C5E126D38FF60B9D6CD608AC18E83 +:1061D00054D2275792A77F0079CA40D7BC976AFB51 +:1061E00033C20FF94A07FC78970C2FC03FC3F9253B +:1061F00079FEBB64B8DD6510399C7E120227996E6A +:1062000014BA50F62F98635869B41F9FECD7DD4736 +:106210002393098FE3FF83E3EF13C2DF3727D60110 +:106220001BB151FF984578FC5FC09F57B4FE0BF837 +:10623000EB0EC59F577F3DE2EF71D1D284FC800801 +:10624000C8A1D226C2F9580623FE2F93C22C9BE088 +:106250007C76E4FF9B88EF8F22DF2BFC3EA6D837AD +:106260001EF5E449C69EC17DF9440FB5A766A71087 +:106270009F5FC7BA13B01DF09C3717F12ED876E890 +:10628000242C7DFB5E86F55D1506CB1E386FBF5B4B +:1062900074A961FE8628F78EA5B06EC35D991617A6 +:1062A000B63396D58672A03CCC827ABE218ACB8545 +:1062B0008605E9A4870F7E2725ADC2732C08B33469 +:1062C00041FF866CDF2313A0DE30D66C7141D757B7 +:1062D0000596BE1DC7CFD1D13A0D7338DD363C329D +:1062E000DA8D7A05F4CFF37AA83F591EC6F09C0DDB +:1062F0008DB68468A0CB9722ECA3B361FFA3244E94 +:10630000D70DC9D00EE536A164C17D38DF78BE6FE8 +:10631000DF82B017F7C22CFA341059D07E7295B1D3 +:1063200009E5A5429777A5737937C6756A07C2C98B +:10633000359D65D4C2FC7F93E94B81BB60636C558E +:10634000B41FFE0A9DC5C8701756737A734D97E542 +:10635000623573D70B085FE60B07F8966941414237 +:106360006934D9ADB8EFFAE5801709F7CFE17F526C +:1063700064E59E61F8E747282CF3884C04E48F32EB +:10638000C6F9A30CE908E96F15D05100FD31DF759E +:1063900051A7C3653A82F16B8D25D370BDCF853F80 +:1063A000E463E3897F4AF3875B67563697030BF410 +:1063B000F699D89FED8E14515FAE30F1F54E647FA3 +:1063C000361AF5C5C95FBD791D96C7234A6ECB86BF +:1063D000FEDB167C5D84E2FC6F093E359EE36F0BAD +:1063E000FEFF68B443CA56BF49F4FE43F759281963 +:1063F00032504EAF047DA615B0E474B0F23E467440 +:1064000090C86A896EE365FD050CA3473975F300F2 +:10641000D88ECABCF0FF4797746C89CE5F9FC6A226 +:1064200082EA33740941FD0B4DC941CF6F8D1F17AF +:10643000F47CA6393BA83E3B635250FFDB2DD38250 +:10644000EA774E9C19D47F8E6D4E50DDC64C241FCA +:106450003AEA8A733F01BBE1B5BA92DC4F5497E345 +:1064600063AAF6D07EB305E824DB3B5F3509EA91E9 +:10647000875626437D53CB115E4F3CF44532E06690 +:1064800073CBD1F92AD0DB536F3CF4450AD41F6D8E +:10649000E9E2CFA7C062A340ACB6BC39DF05F89AE9 +:1064A0009B62DF8AF89A77A9F6288AF9F7D7CCBDDC +:1064B0002F5942B930677406EC2737C5FE103EBF2E +:1064C0002BF69E759100FB1F7D5BAB463CBF985D34 +:1064D000B215E9A1FF22A7F353889791FF7E099691 +:1064E00003D9618A9CBD923C54F8AD03F4C61215E1 +:1064F000C24947A5B7CE44E5A1BA782A8FD499D925 +:10650000128063575D0695C7EA2CD47EBC6E229537 +:1065100027EA6C54BE5B574C65775D09950AFFB25C +:10652000BD960D6A2442972AEAB4CE4F8F57D263A4 +:106530002028D969059FD0F94DBDAD399BCE759DF9 +:1065400009E959693FDAF9815904FA9D6AD5113D83 +:106550004F35749B75565E47B9B8FB22F38A11BC60 +:106560009F2AB05F8C271BFD98A90E03F54B1B8457 +:106570007E59D8EFCD0494F7536B3516B4639E5013 +:1065800033971EF66F14DF90701DE320CA6CD80598 +:1065900018D53A905771A06BF139F4633A28770F08 +:1065A000F2F54647D72E47F934BACC60A9E7F29501 +:1065B000E44BE2086F02EE2F71A586DA8D628F1927 +:1065C000E5605F9D7716D269812CE70A345CEF3075 +:1065D00011E4BD807CFB6D5722DAF3EDDC9E2FD0F9 +:1065E00096EC44FAAE5671FE65317AF71E5C47D5DB +:1065F0005DF12CF4EB894DB46C4268C51F64696091 +:10660000B717D61467A2DCED615B88AFC15EFD13DE +:10661000D2DB8F3381DF459948609EF8E2F0A64DCA +:1066200002DAADD7E7215DCED59A0F30E0075FF6ED +:1066300000D1FBDC48731E7A0ABEECAF793DCE7CFC +:106640004080E7263630BF00EA55CFE94D9F04F081 +:10665000A9D3131554AF694B307D12C0A755F80765 +:10666000FA47B7092A94BB0E792BA704FB05C4B7D8 +:10667000B3F8730DDFDF8006EDD88BD966A26FB05B +:106680009749EF0FCC34BA9B60BF71236AB357A010 +:10669000FD9469CEC37E49EA8108F463FABF5515BB +:1066A000BBC9EF1988F8C9783F7D3DD321517B28BC +:1066B000DDB5E6707FAF26CDB019F1501DAFD351D7 +:1066C000D971B188919D56928676B94DC3FDCBD0D4 +:1066D000F17B73B81E495EAF21B940A208B66C0BBE +:1066E000634ADDC52632D6F88BB021BF07C0C93456 +:1066F00063653FC8356247415A507F1BF61F7A8E4B +:10670000F61CF38F4F7949BB63AD4A5E0FE96529EB +:1067100073A33F182AC7AB72A365B9C0F1FC748C90 +:10672000BE11F19C26017DE750C94C50268633B23C +:1067300037135FD7BB913E77EB39FDA789BCDC2DC2 +:10674000F2FE9A30E6427A57FC874DB9F629B979BC +:10675000348F97E6915AB291AE139887D657EC24AE +:10676000A51FD8437A1202AA8174C4D754491C16B3 +:106770009E2772A615E58C44FEB0B14F03E4775F07 +:1067800078C4AA40FC55E37843E0B8E9344E19EFE9 +:106790005C25B24F47905C243A72A689E42F564B91 +:1067A000EC8880FE16EBD6A09E53C6F5821CFC1426 +:1067B000F0F047908B587E08F210D7FF33C8432C77 +:1067C000FF0AF210DB4F823CC4D207F210DB3F0617 +:1067D0007988E5BCBB8D56E49F9AB669ECD3207EE0 +:1067E00050DB7D01F5DE69C3D39143A6A3DEE4E16E +:1067F0009FAFCBE17E45EF2D1C9FFDA0BFD1FF00D9 +:10680000BA5C6B8ABEB21EEF37B2F91E80D3B67C7B +:106810006E87F427F0FAD21C35D56D22DB8EE3B7F4 +:10682000E56BF8FA2962393EB745F3797BD345B277 +:106830009FA64E9EB624079EDB62A13DC75FEFBDBB +:10684000813FB78DE2ED437A567E3E25D7A4F8EF1F +:10685000E9DC2F65642701BDD3FC4AFFF726723EB1 +:106860000CEDEF4E138BDDC3C0E32D996F892FD054 +:106870009E463E480EE08B6A33F18542870AFD55FD +:10688000E57238A769653A07DD42F0431D83723A25 +:106890004E4FF625C0C5C6E03CBB05995F42F901E5 +:1068A0004AD4070A3F287CA0D07B22F09910ED3F04 +:1068B000C7CD21F4AA948FCAE7E88E35FE9CF0DAA2 +:1068C000A136A1DF7733CC87E313C5C177EF46FE4E +:1068D0008C359AD1F52C7CC8503B9C1CEBFAEFC24E +:1068E00043910B5780C76570D0F0F25F8503C939BB +:1068F00094E348BFC3C8ADFD39D1B25DCEE9F744DA +:106900008E6D1FD251BFA057A1DFD0AF67C3DAD9B8 +:10691000DBF2397F287454053A10EB8978CED4CB5A +:10692000E59E729EA1732E6324FFD2C2787B289EBF +:10693000957305C8BFC33901F11FC6B87D711DD855 +:1069400017E84F4DC935D33EFA477E56B695F9CF75 +:106950007F470E6F7F4A94881E14FD32D42E488BD9 +:10696000E66406E91D66423FAF534BFCEE057FE649 +:106970002518873E219BE43FBF20E37170FE58112C +:10698000EDBBBEAF0D2ED4637DA3064E0A30BE6FA5 +:106990003B18366497D86E1340EFDE073A06F5D4FD +:1069A00005907B2C9DB173721CA1CF73F124FA73F7 +:1069B000353B24A603504A3BBE9A87F4B4B4536DCA +:1069C000A2B8D0F6C78E213D9E6E15CC6897F4B55F +:1069D000C2F1A1BFB3C1E8D643FF22A863FF650699 +:1069E0008DDBCCD7A3F883435EEF537D750AC68554 +:1069F00066EC5013DC973E2FB9D13E3BBC7DA50A17 +:106A0000EBA7DD028B837145D2EAAE04A8573E2D79 +:106A100058B430CE61283A8BF182CAE799C50BF39E +:106A200057B618C9CF5DDAA0FED817605F94BBB720 +:106A30006AD0EE29DF19DC5EB93BB80EF822F9EF17 +:106A40006886F600F9FC6D8E3186ECCD712C1BED5D +:106A50004DD6C0E3B98A7CBFDC6E757139BA82CB82 +:106A60006DC6BE8C457F5FEAFC2AE96303AFCF9118 +:106A7000EBA7A0FEF9571C2F0A5CAAE5B53F4F60B3 +:106A8000560F9CB7BA536F42FFBFBAFDEF1118B74C +:106A9000AF09F3517C9FBD2299D0DEDBD826B91017 +:106AA000BECE0EFD2E11E0567DE03D8DD988705F83 +:106AB0004EF6CAADCCB51EE3DC5E5164DD4447DD65 +:106AC00014A766B681A5384F5FBBDE847640F52BF0 +:106AD0001F74DD8DF50302D3231E47FB884E96EE0F +:106AE0004086A52DDD26E4FBE94442BC229E3D9173 +:106AF00084AF658877C433E01DF12C213E71BC5111 +:106B0000E3E6742251FDF4731CBF0ADE8BA4CD1A98 +:106B10006CAF6CE4789EB163CFB630A2033593E9D5 +:106B200080F07E7A27C7BBA6739D6614D26F630878 +:106B30001DB46B87E800F777191D84E0BF02F08D64 +:106B40007220940E42F1DF93C3E506D8DFA79F427F +:106B5000FBDB087E01F3C7234656F51E8D81F5CA7F +:106B6000A2CF3B9743FBD8F89758DA088A7F15E401 +:106B700062FC6BE63BEB105D3DB35EC8467AA957FD +:106B8000FBF63C81718BA8708AE3F427CFD9F932E8 +:106B90009CBB20FA9BA416D87FCD6B5ABADE28C9BD +:106BA0001587EC358C9729F174C033C5C99C1D5AE3 +:106BB0001E176B2DB405FA73FD09FC5C859A81B232 +:106BC000E5E817C07CB88E60E37E5E55078F172816 +:106BD0007E59951237680E8E1B08A677A85F452E42 +:106BE0008F5FA5C6DD6C463BBC7E01B387A55E4DBD +:106BF0003FF078CCD3B2DF7445FBF10A7A42B11B87 +:106C0000992B386EA1C8A96513F91E8FFEE2B86AE8 +:106C100004C6FD760B848F8A0E904F70DE0AB7DAB9 +:106C20006D1602F849EEFF19D21BC0ED8CABF6A031 +:106C30002821DD1968BF0E993EAB918EE0BC95D638 +:106C40003722F09C0E59AE38DA8D147FAB645B8A24 +:106C500090EE2A613DEF30F454F95C0BF929D7A28C +:106C600027C5CEAC6E0DEEB7317748CE8CFF1EE057 +:106C7000BB016439D77B2E99FE3223F1DE6F9099E8 +:106C800023919F87F49FC0ED3745FE5CBF1D583CA4 +:106C900060DE716E1D5305AC7FE373A6A0FA784FDA +:106CA0007C50FF9BDACC41CFB3BD1941CF738F59D4 +:106CB00082EA79DD1383FA4FF8D016549FE42B0E45 +:106CC000EA3FE54C49507D3013CE7395FBC15BE341 +:106CD00085A0FE33CDFAA0F967674405D5070D32CC +:106CE0007C64BB52B1775FCEE5F66E68A9C0F776DB +:106CF0004BF03A8ABF7EE7C4E0F5E6D882D7FBA125 +:106D000078D90BFA54057EC273A05FB1FC1DF8134D +:106D10002AF0139AC19FC0FA8BE04F60E9017F020D +:106D2000DB5F027F02EBADE04F60FD20F83F586F64 +:106D3000AB2BA6F295BA126ABF16FCBAE4758FC9DE +:106D4000EB1E97D7FD77E174429EEF5D79BE6E9C96 +:106D50002FCDFFDC593C56BC04FC3C2DFAACC68759 +:106D60007EC30A5F11C62D06DE9218C6A599DD7D89 +:106D7000AC2E06F5D9088A33B39281B731AE527D75 +:106D800020D5B4C98CFAEC0FEFE2F3BE56C98C7C67 +:106D900079A8EDEF1138CF854B61745F4A7A10EF17 +:106DA0001BBF6154DF04CF310E3AB3050408E93745 +:106DB0000FE9B70B694ADD4DF7BD25CD2D1AC45338 +:106DC00015F2293C7FCBA30E7EFE5C63D07313F6D5 +:106DD00087B24AE5A638C2B936653E2FF577A4F1E9 +:106DE0007BCF73CF1D5E3F05F56FCBE211787F5EE1 +:106DF000D5FC5EECBD57C1C7E7075FC8A4FBCA76E8 +:106E000098CFE09FCFD9AE96EB7CFF8EB496A26868 +:106E1000541CCD021B0BC505B685EE5FAADAF63809 +:106E2000506E5565DCAD66009F7E8F24C737F8BD78 +:106E300091C3C4B81DE7F92202EF575FF71CBDC329 +:106E400086F8ED381C81EBF6B74A41FED3682BB7C4 +:106E50008F475B3584BF0BAD8723F05E77A3E730A8 +:106E600087BBCA4BE73F24D7FBA12478B74974FE00 +:106E70008A4B62D03D768655A27966B68D35E2B9E9 +:106E80007A3C7CBD1CAB99B7A72D5E82FB3F1EBF31 +:106E9000204F227B100435CAF11B66EF413BA4CA88 +:106EA00023D986F3EF0AE479BBD49C4EDF4ADBDFBB +:106EB00085F2F878F1886CD2118A9F69E5766F9136 +:106EC000C69E867AA4C76036229D3F589C6A44FCC1 +:106ED0001EC212DB8B7769EC06BCC7E6EBF598BAED +:106EE0002390EE7A5A7325B47794F9F2E57587E822 +:106EF0007B086F2EC253B9BBD180F3F8F1C7DB73A7 +:106F0000AC26EA7FDCFDDE3CB4AB7A32C2C92EE9A6 +:106F1000D230F2A7AB9AB95DDCD391D818784F92F2 +:106F20006395FDF20C91F0DAD7A696FBDDBD8705DF +:106F3000F553D3392FEC0EDE8FC97DEA51B4C71D4E +:106F40004F4B0CF5A2435D1B8BE7FF6C67F0FECA4D +:106F500065383BD4DED8D8007A75B40FF18D81E85E +:106F6000BC5DE11333E153C1634F06B7E77AE2F941 +:106F7000BDA4A3650FD1F5E5F1A4EE64F41F127F63 +:106F8000A9A378E7B5FC67C56E08F0AF18FA8BEADD +:106F9000E2D43C31C56F1FBC966BABB68E44BFAB21 +:106FA00084FCCA1E06F62CACE9447B3A92F21FB66A +:106FB000E1BA83AD6ABABF76EADA667D0276D9A015 +:106FC000051805F63DB8532DDF7BD90C68D72E95F3 +:106FD000EDDACFCCF67C09F4AF738D48E7736486A5 +:106FE000911FD327CBBDCF5B92EF24BBE1986442C6 +:106FF0007F688687DBC18E666ED7567B92FF632AD9 +:10700000DAEDCD6ACCD4608A1DE294ED90D3B2DD86 +:107010007B7ACD8086FC9B4E813D968C792A5BBB2A +:1070200012E1B9337316D9B34EA999EC8965DB83A4 +:10703000ED07B06F82EA55CF85DA17727CCB13DC8F +:10704000AEF887DBAC4376C638F4670AA5A971C8E9 +:107050000F2FC87855FC9B95E32D94B7B351659ECF +:10706000A5C421105E359DFB2B70DF6E479885FC13 +:107070008D55AF105CFBBFE47E4C7F3C2378F4332E +:107080000EDFFE364EE7356AC18DF9483540B6341D +:107090009F4E70AFC138B36B3082E41363C5C8171D +:1070A0002B16707FD586315F286B157E08D1ABB764 +:1070B000A87C5254809C68B3A650BF020DB3A33E77 +:1070C0005B69B4907E1BA3E3767AE16A4F36D2C344 +:1070D00018F0C7B501F1F831860101FBED7E80C7DC +:1070E000FF9578C21C95491D15A01F195B43FD959E +:1070F000F941A2F0F1D79ADF04F31BFCF303BC23A0 +:1071000011DE5F582DA4B793E628F7FFB5C497CAE0 +:10711000792E00BD611C1863348837C7CE37C89FED +:1071200073B2EEF538AE2882EFA308F783F5305E30 +:10713000FE5196E7B179BCBC4D2E15F9D590677B11 +:10714000DF0AF59579F63F5949AE99883E57CAB49A +:1071500002F64C9C6F18F9BBE21D89F0FA05F003AA +:10716000F2FBC25AC19C16642F713AAFE14DEC3C60 +:10717000F3F44E4538B86CDD1998D7C6387F2D5AD0 +:10718000A537A705DE0720BDA3FF5102FFF2D12FCF +:10719000E3BF7253C56D9457B52AD68CF71735C81F +:1071A0000F29D7A6FF50BA87DF4EA4B76AA6B5A0AD +:1071B0007EA9690B7D6E51A13DFE4D085F24C97407 +:1071C000DA6817E87EBDF15B158FA3950A1437BB0B +:1071D0000B1A914EE987FDCAA7B9717ECCB3A0FB0B +:1071E000AE861839EF2B86EEE17E229FFF2E95F7B3 +:1071F0000DE4EFA36A4F32C6718E3AF93DD502E62F +:10720000A17BDD52D64D656F78F5012F4DEE1A8DBD +:107210007EF807762DC5911AD7361951CE66B1B5CD +:1072200026BC1F033679EEFBDC2BDB1BA1F7689431 +:107230009F95E7C7F3CABC92F83CA0833380A3F8BC +:107240009CCBC757BD7F2002E17EFEFEFDF37ECAC8 +:10725000D00F02B905F354D6B664D0BD8C8B7567D8 +:10726000E4FBF1ABE053C11FB49983F00A67B90E98 +:10727000E0339F0DE4636ED3B5F0A9C039493DF00A +:10728000630425E8319243A17856E05ECD6AD53C8F +:10729000FE56FBEE02E8FFB3B5A219EDCACBF07EB5 +:1072A0000DFC78F5FC91D728903F7B257C29785AF6 +:1072B000C8BC54FF308A8FFB70A144F1C3FF697CC6 +:1072C00035E4D94BF2AEC2B7A17C7A25BE5CB42AB4 +:1072D000847F43F874882F2DF02F007FF65511C45A +:1072E0008F0A7E1D66F09351FF75182D6E76393E1C +:1072F000D1DFC5FD54B60AEC49E187F0AB8FFCE362 +:10730000507C01ADD8501F54E705F3A982C72BC9A3 +:107310002D45EE7DC4BC474D02DD67703EFE85966F +:10732000F2E994FB0CE5DEE2D13CAE6F42CB8FC0BC +:107330006EC17BA24D193D23D1DEEBD528F3F07B46 +:10734000D78FD6748FC67CCD8FA6F1B257C3F34CBE +:1073500094BA2D8CC7033F4AD0BA106E1F09E3A61A +:10736000A31DF091F0CB3B783D4E63C6FA82B8E99D +:1073700026A8F7AA95F8E183B2FC7653F9D18209E1 +:1073800005D44F6047101E668195D03A82105D0C7F +:10739000FBF9E8E76373F05E4039FF03793C8EF454 +:1073A0001BF91C43F1F65F09146F5F04AAC384F74D +:1073B00002D39F284E81F693BF4ECDA6FBCA15C1BE +:1073C000EBA3FE4DA638E5569AE7964B03EAC5991E +:1073D000FE7D0DE9CD828BBC7DC9D8A07C665BF4B7 +:1073E00038EE27BB5323518F297A6DF0D87E436046 +:1073F0001CF5AC1C771EAA8F7B2429502FBEB1F739 +:10740000E1749CA75CE3CAB218308FF9A924B41FB9 +:10741000CAF73E944E76EDDE8DE9E89F94373D9CA9 +:107420006EA37AB89DFC23153FF7F97D93766D0A1C +:10743000B0A36F9DC0EDFB52DD1B8568DFCEBAF1B6 +:10744000F37518B71FFB6B81E2700B59F73AD4B78D +:1074500065199CAF58838EE43FCC47F7A47BC6DD0B +:10746000BE1BE5FEF18CBFAB97A0FECD53D17C6572 +:10747000CCBD390EE36F1B048ABFF9FB8FA67BD707 +:10748000C56B054D7C0CEA519E77FDC7BC2882E395 +:107490003D1BB2BBB0BD6C356F9FA575B7F6E03C28 +:1074A0004F6828CF0A14654A49C03DF61FF3F83DDE +:1074B000DDA2CD72BEB1BCCED86DB18D81E7FCA38B +:1074C0008C7F56FE01C9833B65BCDCB6FABD23F157 +:1074D000306FA4DAFE67942BEF3E7E3A0DE55941FA +:1074E000F4D94CA4F3B11AFB931578EE262DC52BD5 +:1074F000AD5989521CF4CFB97FDA63582E5ABDF8C2 +:10750000C90A8CFB6ED7911FA6EC6F856016D15F00 +:107510003DDCF8D37B106E671EE779A42B1AAF8F82 +:10752000BB5AFEE2B3753C1FFCF93A1D952FD49966 +:1075300098198EB8AF2E9EEABFAF3353C9E673FADF +:1075400052F2A6AE345FEEA530CA5BB66ED0511EC5 +:107550007DAED6F6551EC06BEC0DCEA68DF2B9C62B +:10756000C2F86C57F20C848375E3F22E34614FE558 +:1075700071FFEAED9E0D496487AF3EF54C053CCFA7 +:10758000CC2FF90EC7EB765EA478C1E1F687CA105E +:10759000DEE54D5A7E3EF9DC671E4F8F7B12E3BC61 +:1075A0006FA9C97FAFD979EA998D50DEBB79B92629 +:1075B00090DE7FE879BF95F7732DBEBA121CFE7579 +:1075C000BE7A3889F8A709F82AF3DFE7AB9AD56BBA +:1075D000087E73F34BC6E6C3FECFA85D49C84F676C +:1075E000C6DD4C74EEEA1408FE8A1C57C6A7E6F303 +:1075F000FBE82AD1B399EC48598E7F059E23C2F748 +:107600008DF6CFD2D18EFEAA6DC155CF7DB00E3D85 +:10761000228C9BE9A80C7D9EAFB1A7625E71BEC8AB +:10762000EDE7D0E7B7E72B71781EB7C59F1090A79D +:10763000E2848D4546A3FE13BC6120979D6DB79EE5 +:1076400055A1FF067EE1C7C17628FB3840AF5F69D0 +:10765000BFD72AAB711E955FEE4EF85064DE003D39 +:107660003EC917C6BC01EB0EF92BD0A6A1FB9E04A8 +:10767000920B8837CC87EA6B1FD784F5B31A8EC775 +:10768000BE83E097F1B80C93F2FDE73CDB7E3E0B46 +:10769000E56CE879AB5F394FF4E1687BE8A240E73D +:1076A0009F79569575EDF3BFB1F77C16E2EFACDA32 +:1076B000978FFE579FC6978578A87E95CBF37F1549 +:1076C0000E4A7BC5060D8F130A26F2230BA50B1459 +:1076D00007E83BC6E300D5EDBB489E0E76F0784C3C +:1076E0008DD85D1487F18BDA535D28CF06E3B95F3F +:1076F00006F3DB28CF2155D683AA81A43920D71ED3 +:1077000019A207EE0F9E41FED5E03C1E07E561651C +:107710008533B42BCE213F437BD9AAE4F548E767F4 +:10772000DC2373503EBE9DF58F6A8ADFBD1E6E92CC +:10773000C88E9530C778084E43E7704B3CD18729F7 +:10774000767138B305F4ABD198EF24BFFA38BF9FF8 +:10775000ABB981F3137B85F39373ED1B9AF880F932 +:107760007E25F393624FCE7AFD1FC4970FE7DA9E12 +:1077700040BE0C475988F3C547521EB5F21E8772AA +:107780001F69E890FDF862899ED7B4490CEFE5586F +:10779000BC91F20A8AD916CAB79CC53C53795E8F50 +:1077A000EFD129F07CF6EB522EE6A1813D4DF7DBBF +:1077B0004561F634CCD3EA150519AE1EEB9C007D6D +:1077C000F67E3EF757A74A02E9B1818470B253664C +:1077D000CE7796E27E957E5A91EB339887EC2CE635 +:1077E0001EC8C27B55E61DC8C2FB56A5DFBCD7C369 +:1077F0006B492F328F755EC03AA7F379BCF30BBC8F +:107800001F07795223DFC3164ADF6E437F6B45277C +:10781000BF7FEC15933FC03C3317C019F17A1EF0BF +:107820006A43FD6367361BF2CFF8916EE49F9A7D41 +:1078300002C37CBDEA766D13C685AAD5BE58A4E7FF +:107840008D6DEF6B909E6BF05E763C8E6772BCDC4C +:107850004479BF3526C6EFF5DAAEFF00E376CE6396 +:107860005C8B3A55EF513C00E536AE57D5DA42FE17 +:10787000BF8379C9FF773407D3CD603C8FE787F2A8 +:10788000C9E97C73107FCCDCCEF9631EE6731B68FC +:1078900038C55F67C6C7915DE21FC7F16093CEAF81 +:1078A000433BA63F45A07CFCFE30D75AB48F5CE931 +:1078B000DCAEE97FED052BBDF7A3735B7F8CF93C54 +:1078C000B2DD3B73C3569514B09F991D3CDED81FA3 +:1078D000C6CA0F12DEEDD7213E7CB92567F231BE54 +:1078E000A31978770AC683441E1F0D3D875D8E6BF2 +:1078F0001C67FCFD2865DFB31313B93C636EA2A3BC +:107900002E39BF5BC9D751C6DF324150EED1B89F87 +:107910002458AEFA5E1ADED7609E2BDED760F93BA4 +:10792000391F16EF6BB0FEA29C0F8BF735D88EF780 +:1079300035586F95F361F1BE06EB785F83E52B72E6 +:107940003EEC71DC2AE5F16D7C0AE9A20B796D94BD +:10795000BFDE1B1D521F15DCBF375A08AE8F12A8A1 +:10796000BF69C2C6A730FF7893922FC5CC46B4C377 +:107970002AC2F9FB1AA9067BEC04F4F38B77ED45D8 +:107980007F1EF89BDE9F2B885E504AEF97C46819D4 +:10799000CAA3DB27D8474F80F1C78ECD48DB4A7298 +:1079A000524FF7ECBD3FBB3192E27A6F494C8225D2 +:1079B000A765E4AEB5427D9A4120FA85F96E2A5159 +:1079C000FC4C986746C762AB8ACB0713DACB85922B +:1079D0006309AEB322419F8B72F888D59E81FB511B +:1079E000E05D346A591ADA455D6AF307189F75BD80 +:1079F000A366E85729713CA5DF93D669F9B8BF990A +:107A000019A96B73707E60369477360D6BC6FDD9FD +:107A1000C470A19EE4975985F2207F02A79BE96676 +:107A20006E1F7B35665534FAF561D362F05EB74B55 +:107A3000C6F33119CFC7653CE33D57818ADF7361D7 +:107A400089F75C5886E6A32DCF2FB14D20780F24FF +:107A500005E6B3CD92DF97000AA1F7D49C721CF320 +:107A60004B59EE34E695DCCAC779689E2A398E7781 +:107A70005E1D7C6FA88CF38F6754CEBD89CB6B16CF +:107A8000A9E179BFD73117E615CF7D3981E2507D65 +:107A90006ED1A506BCCF055E4779C65EE6FE2E8B8D +:107AA000E77C33777F1CF5AB97E3A9CEE8EE747CD7 +:107AB000AFA34FE62FA57EF03B9E97E4CC81BA8121 +:107AC000DE23A1F339E776A74741BD4FD08B485F4E +:107AD000CE26FEBC47E63F678A3C9F7C1EA6F32469 +:107AE000213EFA3B5F4EC2F7103719BC4BB9FCF789 +:107AF000A693DC66DE74CC6F3A2F784E62BEF1AD91 +:107B00006D29A5986F7F5EED7906EBB3DBD2785DCA +:107B10006839690A7C3ED29384F9C8B7B6A59662E3 +:107B20003EF2F9912DCF445902EAEA974EE273CD25 +:107B30008369A5989F3C5BEB3E568774F37B4E5F51 +:107B4000FA7D074E237CAADAB9FD3E7DDF810B2F3B +:107B5000A17E3E60A4BC8275139209DFF5EDCF6E65 +:107B6000467AEB6B51133F6C6A7EFF99DF503F2DD5 +:107B70008559666B3D560CC994B41DBA1BF7353B4D +:107B8000DCF325D6174FBC89F6317B04E7EBA51350 +:107B9000734A914FFB0EECFB05EAB3D99160D8E232 +:107BA0007E5ED0137E2AF78F2BC0B8409FB1BB0CEE +:107BB000E7AFFE9D96E71FEC8F9B8E7182FF9CC006 +:107BC000F3312A6ED89284FA567CE5F9BDBFC1F82C +:107BD000E6EFF474DF5313CDEDBD4AA9317F39E1EF +:107BE0006FD75ECC5BE97B5E4FF7AF151893B3E2BE +:107BF0007BAC63293EFFEA3FFF5E8678289476EEF1 +:107C0000C5F62F77EB4584438FC6167933F2618F23 +:107C10009AFCCE0AB95ED13B82EF27DC5744F88B41 +:107C2000D99284FAB672C4AFEEC07DCF96B63C83CB +:107C30007E0F7B564B770E679F07B8C1B8B37BD4D6 +:107C4000984903FB30AA905ECE0B5BCA9EC4F9F73D +:107C5000F07EE7F55B089EAE3DD7335C0FFA31D47A +:107C6000C7E785AD41ED67F73C9B857EE9B9DFCD80 +:107C700026FF54A173855F2A776B83F422498258CB +:107C80008C5BCA3F938B1902E259E70EEEE87B92B8 +:107C9000F9C79F6B567B3500A30A2D5B8BF9CD0A84 +:107CA0003F5426DE5A8CE7AB141BD3D17EA9C8F50E +:107CB00095215F9CD5335D3CF47B5BD65B95AD6BCA +:107CC000E6A01D7CA5FDFC4596475FC97CF8559B49 +:107CD000DE1D78DF185AFEB58E994FA8FCF585B5E4 +:107CE0005AB2E595F9DED6781CE8AF554773F971BD +:107CF00012FA37831CFB93ACEF16AD0AEEFFEE04CD +:107D00009E4F59ADF1A5A3FE53E67F7B8289DB87A9 +:107D10002A5F3ACAABD071B32559DEBC2090BCA90A +:107D20006C154ED1FB2408D2583F3C2B752E37E6FC +:107D3000130D8787F87C190F12E6F170BEAA6CD676 +:107D4000DBF4304F55982F02ED2587D117817650FF +:107D5000DF2B126B92D117A3CC9FE25F4F89535652 +:107D600078D436FD70EBC171D04F5E867F03285604 +:107D70004FE47C53DE164EEB31932F1FE9B67C6740 +:107D8000F0383CA729801FFBDA76C506FAEB0CF722 +:107D90004DF751A7886FFAFFF931BD075E29B2B5DB +:107DA000784F794EE0EF83409DDE073927DF775625 +:107DB0007E6D0843FA39F79583F8B84FF0919C7BB4 +:107DC000B1CD4672AC4FED2339B76B6211AF47F9B5 +:107DD000CA506EBD38F1A7243FFA127C65F89ED2D6 +:107DE00066A58E2FCC811DD0D1B690E4C96C89E7F1 +:107DF00051B05D6A138F1371782F93E1C4D886DE7A +:107E00003AF243D466B4973A272AF7421AFFF92583 +:107E10003F3FF531F3BE56E4CF7203C57DC0BE6A65 +:107E20007E09EDC005B1168CA787C24DB95F8C895C +:107E3000FE6629E2E91DA37DECC43CBCCFF4919F12 +:107E400001D44EF67CF56B5AF237FBD5037B517E9D +:107E5000B98DF67113019E0E4DF77A547117D4BE89 +:107E60002E34ED6721BD911CE1F4D697B98BBF0785 +:107E700022DF4F4E92F100FA8C35227D081CCF870D +:107E8000DBF69F4079D3D79D4A723A949FCEB63D98 +:107E9000168172E343D0EFAE8078C0878B9FA57CBC +:107EA00080F9980702E53D6B83CF37F8ED8FC92F36 +:107EB000649B03DA911E1B82EBA17041BAF406F1B8 +:107EC000818BF67D3FF21BC0A76A7A7735C261A825 +:107ED0003E17EA5240FD50483DA43F2BE1F6C3FD5A +:107EE0001318CDEB18EDED253F7E1FCFEFAD07BD8D +:107EF00046F503E1743F2DEE03BD15C3F516EA8B7D +:107F0000AA886E8A5FF51DD0D2BDCA83ED9F25E198 +:107F1000F9811E294E53D5FE722CFAF7EB2698698B +:107F20007ED08FB1941773A03D16FD11A5DD217A87 +:107F3000D2E5F70CB2507E28ED4EC99B4E79E54252 +:107F400077163E5F27CB1987087509EB8CCEE110B9 +:107F500038DFB37689E47C28DE56C9F40AF2218B37 +:107F6000F2395EE1F103451E54C872E510B667723E +:107F7000FE3729F75278CF847C3F8C9CF85A8123B6 +:107F8000ABA5F8CEFD13CDBC2E8FA77979FC89E780 +:107F9000EDBD7A3E2B2513C79995F745FDF228D5FF +:107FA0002F5F500EC4931C78501D0BE7AA7C46B07F +:107FB000D4C3908AD23545D09D2D532D2FA2B81A07 +:107FC000E6E71A2EDF57281D454EE4F8AD14B91F19 +:107FD0005EB957A0FBA5736A7E6F07F286DE0F5865 +:107FE00056B0A608F9EFBE18A726D05FBED6FC4B48 +:107FF0001B82EBCB6AD714C50DC3E795ABB6768D64 +:108000006497CF57616F2C8A355FDEAEECFB9C5EC8 +:10801000D9E774F5C84078CC5F533412CA65BA7F8B +:10802000171EFCDCE7DAB55ECA572D5D43F7C4B70F +:108030005CAA0D8AB35E6BBE0AE6A67B902BED3F71 +:10804000B47408DE5E8C2B31E0AF3DC467C03701ED +:10805000EBC5CBF43A149F285F3C06FD53665F3CAA +:1080600026303E115AE29B3322E58AB8A8043E2C02 +:10807000B30C030FA5FFD1893CCE1A3F91D3F1A8D1 +:10808000D9553B5E6214D7E941F97BA5F74CFE2236 +:10809000EFEF07BF6732239CF7EBD49B30FED3DFB3 +:1080A000F90DC587FBD719E6F37B07034B80E75D26 +:1080B000F1E39B02E3C0AB26713B24DCCAED9D9A41 +:1080C0000CF5D5E34B99C6A1F812D91B99E174DFE1 +:1080D000D2D7F605E9B7FE8E3C13DE8BF475BB0DE7 +:1080E000C86F35FFFC7FB1A887FB3A3EA5BCB4BE84 +:1080F0006F3FA37CB58D72DEE0A13639DFABDB6C60 +:10810000C4F6FEE2BF1761BF4D72E98F2FF0F898F9 +:10811000522AF18300FFF93BD4537B4C1B1FC554FB +:1081200099CAB02D24BFC07F8E46BDE18F2B98E346 +:10813000868BC304C615D2543CAE8025C615D2D258 +:10814000785C01EB1857C012E30AD88E7105AC6356 +:108150005C01EB1857C03AC615B0C4B802B67F2907 +:10816000BFE7D10F828BC73D0D24F757627E33C026 +:108170006F6527BFBF5AB947A27B617CCF03F5DF8C +:1081800065793BAD72DE8E672BDD07D61C902C889F +:10819000227C1FC4958EF93B0347311E54D32258CD +:1081A000D698B17D3EED636347DE07A5D8BE476D27 +:1081B00011CD444F1C9F8D825B8F7CD5B187E257D8 +:1081C00005719D94EF5FD32C308CBBCED3723FD919 +:1081D00029416B0EDDAB921DEDD47693FF52F59CD9 +:1081E000600E7CEFBB66E2459213CA7DF552FE88B5 +:1081F000393D7AF392203D6BE37957F827ECC72994 +:10820000E777931D1260172DC57B6C6C97BEA5F7A1 +:108210004D9CE0E08E10AE9D7755D9D1B21EF3B5DE +:108220007E68FE55E124F9DE3A9BBF4752FCF89286 +:108230007D0760BDC12D5AB2536E9F60BF6D521E47 +:10824000E619D828EE72B4534F7ED6275BAF0F8A5B +:10825000BB144AD751DC63855A20FD7DC46A9F3B1D +:1082600009E87246F1BD146F99116F243E56E8F08B +:10827000496BC94F70DE15E3F977980AB5ECE7341E +:108280009F9CCFA5E0A9B05E70E3F72C16330BBD21 +:108290003FB008C0877151E5FB1F8B18CFAF50E886 +:1082A0006AC55681E88ABEBC10F0BD8445F83D1011 +:1082B000D07FF76AB9FD9B28F27BF2C44D3C8FE278 +:1082C0003E66A7FC9165487D12E9D7D77CD06E0F3A +:1082D000BF2E89DBF7E6389C7FF17135E50717C6BD +:1082E000DD9E6E273D5F40F91382F76EE9FB1BAF01 +:1082F000263F83F3278EAAB9DC0178929FD585F4B7 +:108300004AF11E3B95C7EBCAA99C22BF1F16FA5E15 +:10831000437FE7CB2D38BEB0C66041F85FF13DC06A +:10832000B0ABBFFFE694F3EB12C59E5C33C2E36BC8 +:108330008305E15118D749EF89A5CAF33F9C5BB289 +:1083400009F1698B602E5C1FEF69B6007C8BF040F1 +:1083500002C6D13D367CCF66A05330513EF56572E2 +:1083600074EB3ACC53A949134C18AF2D0ADB5218C1 +:108370000BF317A524D377766ADA781CB60F4A4E2A +:108380000753DC92C0C7AA62317ECFF1E8CBB53F7C +:108390003D29CFDF3E5BE6B3FE8E2F781EF1B5E3BD +:1083A000B4BBE9FB1C4C4FEFAFD30FF635FBC6D186 +:1083B00014AF55E868B039AE09E9A845D613A5A5AC +:1083C000EFA9D18E68CCB337231CCA965C5C174BDF +:1083D000E71C3E4EA6E4DF87C6C902E5EDFF46DE98 +:1083E000FD89BA5A2ADFAD5B4565779D8B9E07E80C +:1083F0008B2308BF1F106F7D7BD230F156A6334709 +:1084000092BE05BEE7F1ED90F82AF0BB18C0EF333D +:108410003AA2EED980F64883C682F7CD98FFBCD247 +:1084200040F2E1FD49C3C65915F819282E3BC8F49E +:10843000398887E919A92A119EFF6D921014E74423 +:10844000BEC17322DF60897CA352F9F9E6690DA3EE +:10845000EF94A17DE022FB404FF85DBF06E40AD413 +:10846000EF65A620B9722144AE8023F3337A5FAC66 +:1084700043CB3609FEFCCFE9505CCA1946CE78B82A +:108480009C191DE6799EBEB3501D46F9C5C0EF4448 +:10849000674737F2BCBD25AC84D61D46DED07B3E97 +:1084A000F78E1838F914F4BFF76103D939EB139636 +:1084B000E6FF77E4CD9F2771783C81DF73505DED57 +:1084C0007B0E9B05BC8F5DB1906523BE95EF39C4D3 +:1084D000C118F27BFFF5EF398C983C12BFE7E00A38 +:1084E000FA9E43DC15BEE7306AB27161E0F71C46C4 +:1084F0004D1EB130F87B0EC685F89DB2FFC1EF3935 +:10850000A44FCEBBFC7B0E374E36FFA0EF39803D2B +:108510009B89E34FE4D8C66399289F3BF4FDE5E3CC +:10852000F23D6497682FC5B228C2A5A276D16DC569 +:10853000F26DD1733FB6035F4C4478153D967D03D1 +:108540007E972551EBA1BCF227ADB64938FF6BB938 +:10855000B6C9F83C34DE5F2F9F0FF6730BF60BCDD8 +:108560001F53E8E2AEC95C0ECD93CBA9F5C3BFC7DC +:108570003F6F32BF4FBED6BE61BF77E07ACAFED929 +:1085800096C556DC0FECF74EDC27ECB7044B66883B +:108590000E7A0FF8727A75C9FB62742E908FB33F12 +:1085A000E1F62895E92A7714DA0DA31E7047E17EDB +:1085B00047350EE8F17D90DFBA06F4683FFC76F5AA +:1085C000801EDB7F6BE3F9DAA1F36F9FCCFD91F4A2 +:1085D000A903347E0CFCDD4DFEC14014DA6DE9E5E3 +:1085E0004734AE147A4F6DF62741769399F87B8C19 +:1085F000DC36E60191213D8CD9C1781E63410CE93E +:10860000B94A1DEF5AF9C0FD22D2D13837EC3B8070 +:10861000FEAEDFAE1A0C7EAFD74BE3AAE425C05EF8 +:108620000B7AEE643CBF74942C8FD05EC4EFD939C2 +:10863000CB8FD077A6C08E0B998FBE7930944F59CF +:10864000ADB3BFE63353BE6250BFA577FF663DFAB8 +:10865000B5E5A55B35E4172F69598FA5C3F19E26B3 +:108660008E917D19D41FECCBA0FA65FB0CD947F590 +:10867000FD17D7C70DB32ED0C156A413850E8EAAF1 +:108680003DE3D04F3DEA0CB3F0F71D3CF45D9A2674 +:10869000F9BDF45DFF39DDCAF365395DC0F81D3FF2 +:1086A0008C8EEAA9BFF21DAF6B958A1C1CFACE8D89 +:1086B00086B9285E39CB4872AE46F6FFAA9798C8AD +:1086C0001E51F8BA5AE539B51EFBC51879FE9B8ACA +:1086D000D1F7AB7AC45194CF4D3FACCF4AA5FBAC98 +:1086E000D87A8F17E71DB85DA0EFB9158473B95A12 +:1086F0002896389E85E74744FE5D81A7517E4898BD +:1087000047C1BF37302597BF3F10CFF877DB98CAF6 +:108710001CF29D36391E7AEDEFB4F1EF92CDE7F7FA +:10872000720D5125A5CBF1F9821BE8F9C1EF521F5B +:10873000B1E2FE2A94EFB4717BBF614E063D7F55D6 +:1087400030AF413DE17A805DE93B6D7AE4FB80EF3B +:10875000B3BD87F8BAD6F7D994EF0F1C5D70C32369 +:108760007B391CBD78EF5533CB18E4AFFF17313C94 +:108770009ED2C05600000000000000000000000073 +:088780000408350000000000B0 +:00000001FF diff --git a/firmware/bnx2x-e1h-4.8.53.0.fw.ihex b/firmware/bnx2x-e1h-4.8.53.0.fw.ihex new file mode 100644 index 000000000000..48d7612907ee --- /dev/null +++ b/firmware/bnx2x-e1h-4.8.53.0.fw.ihex @@ -0,0 +1,12028 @@ +:10000000000039D8000000600000063000003A40CF +:100010000000191C000040780000009C0000599866 +:10002000000082E400005A38000000D40000DD2007 +:100030000000C7CC0000DDF8000000780001A5C872 +:10004000000056980001A648000000C00001FCE82E +:100050000000F1D40001FDB0000000040002EF88B0 +:10006000020400480000000F020400540000004594 +:1000700002040058000000840204005C0000000636 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000020400CC40100000D0 +:10010000060400D000000003020400DC0010000020 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000020400EC4214000053 +:10013000060400F000000003010401240000000098 +:1001400001040128000000000104012C000000004F +:100150000104013000000000020401D00000890603 +:1001600002040004000000FF02040008000000FF79 +:100170000204000C000000FF02040010000000FF59 +:1001800002040014000000FF02040018000000FF39 +:100190000204001C000000FF02040020000000FF19 +:1001A000020400240000003E0204002800000000B9 +:1001B0000204002C0000003F020400300000003F59 +:1001C000020400340000003F020400380000003F39 +:1001D0000204003C0000003F020400400000003F19 +:1001E000020400440000003F020404CC00000001AF +:1001F00002042008000002110204200C000002008A +:10020000020420100000020402042014000002195D +:100210000204201C0000FFFF020420200000FFFF5A +:10022000020420240000FFFF020420280000FFFF3A +:1002300002042038000000200204203C00000000DE +:100240000204204000000034020420440000003575 +:10025000060420480000001C020420B80000000131 +:10026000060420BC0000005F0204223807FFFFFFE5 +:100270000204223C0000003F0204224007FFFFFF6F +:10028000020422440000000F010422480000000084 +:100290000104224C00000000010422500000000074 +:1002A0000104225400000000010422580000000054 +:1002B0000104225C00000000010422600000000034 +:1002C0000104226400000000010422680000000014 +:1002D0000104226C000000000104227000000000F4 +:1002E00001042274000000000104227800000000D4 +:1002F0000104227C000000000C042000000003E840 +:100300000A042000000000010B0420000000000A85 +:1003100002050044000000200205004800000032F1 +:10032000020500900215002002050094021500202D +:1003300002050098000000300205009C0810000033 +:10034000020500A000000033020500A400000030F8 +:10035000020500A800000031020500AC0000000208 +:10036000020500B000000005020500B40000000610 +:10037000020500B800000002020500BC00000002F7 +:10038000020500C000000000020500C400000005D6 +:10039000020500C800000002020500CC00000002B7 +:1003A000020500D000000002020500D40000000198 +:1003B00002050114000000010205011C00000001FB +:1003C00002050120000000020205020400000001F5 +:1003D0000205020C0000004002050210000000406F +:1003E0000205021C0000002002050220000000138C +:1003F0000205022400000020060502400000000A59 +:1004000004050280002000000205005000000007E3 +:100410000205005400000007020500580000000813 +:100420000205005C000000080205006000000001F9 +:100430000605006400000003020500D80000000665 +:100440000205000400000001020500080000000190 +:100450000205000C00000001020500100000000170 +:100460000205001400000001020500180000000150 +:100470000205001C00000001020500200000000130 +:100480000205002400000001020500280000000110 +:100490000205002C000000010205003000000001F0 +:1004A00002050034000000010205003800000001D0 +:1004B0000205003C000000010205004000000001B0 +:1004C000020500E00000000D020500E80000000742 +:1004D000020500F000000007020500F80000000718 +:1004E000020500E40000002D020500EC00000027DA +:1004F000020500F400000027020500FC00000027B0 +:10050000020500E00000001D020500E800000017E1 +:10051000020500F000000017020500F800000017B7 +:10052000020500E40000003D020500EC0000003779 +:10053000020500F400000037020500FC000000374F +:10054000020500E00000004D020500E80000004741 +:10055000020500F000000047020500F80000004717 +:10056000020500E40000006D020500EC00000067D9 +:10057000020500F400000067020500FC00000067AF +:10058000020500E00000005D020500E800000057E1 +:10059000020500F000000057020500F800000057B7 +:1005A000020500E40000007D020500EC0000007779 +:1005B000020500F400000077020500FC000000774F +:1005C0000406100002000020020600DC000000010A +:1005D000010600D80000000004060200000302200B +:1005E000020600DC00000000010600B80000000068 +:1005F000010600C800000000010600BC0000000069 +:10060000010600CC0000000007180400009B000059 +:1006100008180798000D0223071C0000325E000036 +:10062000071C800035960C98071D00001AEA19FE79 +:10063000081D43D057860225011800000000000065 +:10064000011800040000000001180008000000006C +:100650000118000C0000000001180010000000004C +:100660000118001400000000021800200000000122 +:1006700002180024000000020218002800000003F5 +:100680000218002C000000000218003000000004D6 +:1006900002180034000000010218003800000000B9 +:1006A0000218003C00000001021800400000000495 +:1006B0000218004400000000021800480000000179 +:1006C0000218004C00000003021800500000000057 +:1006D0000218005400000001021800580000000435 +:1006E0000218005C00000000021800600000000119 +:1006F00002180064000000030218006800000000F7 +:100700000218006C000000010218007000000004D4 +:1007100002180074000000000218007800000004B5 +:100720000218007C00000003061800800000000290 +:10073000021800A400003FFF021800A8000003FFF9 +:100740000218022400000000021802340000000019 +:100750000218024C00000000021802E4000000FF32 +:100760000618100000000400021B8BC000000001EE +:10077000021B800000000034021B804000000018B3 +:10078000021B80800000000C021B80C000000020C3 +:100790000C1B83000007A1200A1B83000000013806 +:1007A0000B1B830000001388021B83C0000001F4B0 +:1007B000021B1480000000010A1B148000000000CE +:1007C000061A1000000002B3041A1ACC0001022716 +:1007D000061AA020000000C8061AA00000000002AF +:1007E000021A1AD000000000061A1AD800000004ED +:1007F000061A367800000006061A3670000000025D +:10080000061A500000000002061A500800000004FA +:10081000061A501800000004061A502800000004B0 +:10082000061A503800000004061A50480000000460 +:10083000061A505800000004061A50680000000410 +:10084000061A507800000002061A4000000000025C +:10085000061A400800000002041A62C000200228A4 +:10086000061A20000000016C061AB00000000028E3 +:10087000061AB1400000000C061A32C00000001237 +:10088000061A335000000064061A810800000002B6 +:10089000061A25B00000016C061AB0A0000000285E +:1008A000061AB1700000000C061A3308000000128E +:1008B000061A34E000000064061A811000000002ED +:1008C000021A2B6000000000061A3000000000022F +:1008D000041A300800050248061A301C0000000700 +:1008E000061A31C000000008061A5000000000027D +:1008F000061A508000000012061A40000000000294 +:10090000021A2B6400000000061A303800000002B2 +:10091000041A30400005024D061A3054000000074A +:10092000061A31E000000008061A5010000000020C +:10093000061A50C800000012061A40080000000203 +:10094000021A2B6800000000061A30700000000236 +:10095000041A307800050252061A308C0000000795 +:10096000061A320000000008061A5020000000029B +:10097000061A511000000012041A4010000202571B +:10098000021A2B6C00000000061A30A800000002BA +:10099000041A30B000050259061A30C400000007DE +:1009A000061A322000000008061A5030000000022B +:1009B000061A515800000012041A40180002025E84 +:1009C000021A2B7000000000061A30E0000000023E +:1009D000041A30E800050260061A30FC0000000727 +:1009E000061A324000000008061A504000000002BB +:1009F000061A51A000000012041A402000020265ED +:100A0000021A2B7400000000061A311800000002C0 +:100A1000041A312000050267061A3134000000076D +:100A2000061A326000000008061A5050000000024A +:100A3000061A51E800000012041A40280002026C55 +:100A4000021A2B7800000000061A31500000000244 +:100A5000041A31580005026E061A316C00000007B6 +:100A6000061A328000000008061A506000000002DA +:100A7000061A523000000012041A403000020273BD +:100A8000021A2B7C00000000061A318800000002C8 +:100A9000041A319000050275061A31A400000007FF +:100AA000061A32A000000008061A5070000000026A +:100AB000061A527800000012041A40380002027A26 +:100AC0000200A294071D29110200A2980000000054 +:100AD0000200A29C009C04240200A2A000000000CE +:100AE0000200A2A4000002090200A270000000009F +:100AF0000200A274000000000200A27000000000CA +:100B00000200A274000000000200A27000000000B9 +:100B10000200A274000000000200A27000000000A9 +:100B20000200A27400000000020100B400000001F5 +:100B3000020100B800000001020100DC0000000119 +:100B40000201010000000001020101040000000197 +:100B50000201007C00300000020100840000002837 +:100B60000201008C000000000201013000000004BE +:100B70000201025C000000010201032800000000E5 +:100B800002016080000000010201055400000030F5 +:100B9000020100C400000001020100CC00000001BD +:100BA000020100F800000001020100F00000000155 +:100BB00002010080003000000201008800000028CF +:100BC0000201009000000000020101340000000456 +:100BD000020102DC000000010201032C0000000001 +:100BE0000201608400000001020105640000003081 +:100BF000020100C800000001020100D00000000155 +:100C0000020100FC00000001020100F400000001EC +:100C1000020C100000000020020C2008000002114D +:100C2000020C200C00000200020C20100000020444 +:100C3000020C201C0000FFFF020C20200000FFFF20 +:100C4000020C20240000FFFF020C20280000FFFF00 +:100C5000020C2038000000C6020C203C00000000FE +:100C6000020C204000000034020C2044000000353B +:100C7000060C20480000001C020C20B800000001F7 +:100C8000060C20BC0000005F020C223807FFFFFFAB +:100C9000020C223C0000003F020C224007FFFFFF35 +:100CA000020C22440000000F010C2248000000004A +:100CB000010C224C00000000010C2250000000003A +:100CC000010C225400000000010C2258000000001A +:100CD000010C225C00000000010C226000000000FA +:100CE000010C226400000000010C226800000000DA +:100CF000010C226C00000000010C227000000000BA +:100D0000010C227400000000010C22780000000099 +:100D1000010C227C000000000C0C2000000003E805 +:100D20000A0C2000000000010B0C20000000000A4B +:100D3000020C400800000411020C400C00000400EA +:100D4000020C401000000404020C401400000421B6 +:100D5000020C401C0000FFFF020C40200000FFFFBF +:100D6000020C40240000FFFF020C40280000FFFF9F +:100D7000020C403800000046020C403C0000000518 +:100D8000020C404000000034020C404400000035DA +:100D9000020C404800000007060C404C0000005BBD +:100DA000020C41B800000001060C41BC0000000329 +:100DB000020C41C800000001060C41CC0000001BE1 +:100DC000020C423807FFFFFF020C423C0000003FCC +:100DD000020C424007FFFFFF020C42440000000FDC +:100DE000010C424800000000010C424C00000000D1 +:100DF000010C425000000000010C425400000000B1 +:100E0000010C425800000000010C425C0000000090 +:100E1000010C426000000000010C42640000000070 +:100E2000010C426800000000010C426C0000000050 +:100E3000010C427000000000010C42740000000030 +:100E4000010C427800000000010C427C0000000010 +:100E5000010C4280000000000C0C4000000003E880 +:100E60000A0C4000000000010B0C40000000000ACA +:100E7000020D004400000032020D008C021500201B +:100E8000020D009002150020020D009408100000D1 +:100E9000020D009800000033020D009C00000002CB +:100EA000020D00A000000000020D00A400000005DB +:100EB000020D00A800000005060D00AC00000002B5 +:100EC000020D00B400000002020D00B80000000393 +:100ED000020D00BC00000002020D00C00000000175 +:100EE000020D00C800000002020D00CC000000024C +:100EF000020D010800000001020D015C000000016C +:100F0000020D016400000001020D016800000002F2 +:100F1000020D020400000001020D020C000000207E +:100F2000020D021000000040020D021400000040FB +:100F3000020D022000000003020D02240000001830 +:100F4000060D028000000012040D03000024027C44 +:100F5000020D004C00000001020D005000000002D4 +:100F6000020D005400000008020D005800000008A7 +:100F7000060D005C00000004020D00C40000000427 +:100F8000020D000400000001020D00080000000135 +:100F9000020D000C00000001020D00100000000115 +:100FA000020D001400000001020D001800000001F5 +:100FB000020D001C00000001020D002000000001D5 +:100FC000020D002400000001020D002800000001B5 +:100FD000020D002C00000001020D00300000000195 +:100FE000020D003400000001020D00380000000175 +:100FF000020D003C00000001020D01140000000978 +:10100000020D011C0000000A020D0124000000076F +:10101000020D012C00000007020D01340000000C3D +:10102000020D013C0000000B020D0144000000070E +:10103000020D011800000029020D01200000002A05 +:10104000020D012800000027020D013000000027DA +:10105000020D01380000002C020D01400000002BA1 +:10106000020D014800000027020D011400000019C4 +:10107000020D011C0000001A020D012400000017DF +:10108000020D012C00000017020D01340000001CAD +:10109000020D013C0000001B020D0144000000177E +:1010A000020D011800000039020D01200000003A75 +:1010B000020D012800000037020D0130000000374A +:1010C000020D01380000003C020D01400000003B11 +:1010D000020D014800000037020D01140000004914 +:1010E000020D011C0000004A020D0124000000470F +:1010F000020D012C00000047020D01340000004CDD +:10110000020D013C0000004B020D014400000047AD +:10111000020D011800000069020D01200000006AA4 +:10112000020D012800000067020D01300000006779 +:10113000020D01380000006C020D01400000006B40 +:10114000020D014800000067020D01140000005963 +:10115000020D011C0000005A020D0124000000577E +:10116000020D012C00000057020D01340000005C4C +:10117000020D013C0000005B020D0144000000571D +:10118000020D011800000079020D01200000007A14 +:10119000020D012800000077020D013000000077E9 +:1011A000020D01380000007C020D01400000007BB0 +:1011B000020D014800000077020E004C00000032D2 +:1011C000020E009402150020020E00980215002065 +:1011D000020E009C00000030020E00A0081000006B +:1011E000020E00A400000033020E00A80000003030 +:1011F000020E00AC00000031020E00B00000000240 +:10120000020E00B400000004020E00B8000000004E +:10121000020E00BC00000002020E00C0000000022E +:10122000020E00C400000000020E00C80000000210 +:10123000020E00CC00000007020E00D000000002E9 +:10124000020E00D400000002020E00D800000001CF +:10125000020E00E400000001020E01440000000143 +:10126000020E014C00000001020E015000000002BD +:10127000020E020400000001020E020C00000040F9 +:10128000020E021000000040020E021C00000004CA +:10129000020E022000000020020E02240000000EB8 +:1012A000020E02280000001B060E030000000012C0 +:1012B000040E0280001B02A0020E00540000001069 +:1012C000020E005800000007020E005C0000000F34 +:1012D000020E006000000010020E00640000000B0F +:1012E000060E006800000003020E00DC0000000390 +:1012F000020E000400000001020E000800000001C0 +:10130000020E000C00000001020E0010000000019F +:10131000020E001400000001020E0018000000017F +:10132000020E001C00000001020E0020000000015F +:10133000020E002400000001020E0028000000013F +:10134000020E002C00000001020E0030000000011F +:10135000020E003400000001020E003800000001FF +:10136000020E003C00000001020E004000000001DF +:10137000020E004400000001020E01100000000FE8 +:10138000020E01180000000E020E012000000000F5 +:10139000020E012800000000020E01140000002FC0 +:1013A000020E011C0000002E020E012400000000AD +:1013B000020E012C00000000020E01100000001FB0 +:1013C000020E01180000001E020E012000000000A5 +:1013D000020E012800000000020E01140000003F70 +:1013E000020E011C0000003E020E0124000000005D +:1013F000020E012C00000000020E01100000004F40 +:10140000020E01180000004E020E01200000000034 +:10141000020E012800000000020E01140000006FFF +:10142000020E011C0000006E020E012400000000EC +:10143000020E012C00000000020E01100000005FEF +:10144000020E01180000005E020E012000000000E4 +:10145000020E012800000000020E01140000007FAF +:10146000020E011C0000007E020E0124000000009C +:10147000020E012C000000000730040000D2000022 +:10148000083007A8000B02BB0734000031B600008B +:101490000734800036500C6E0735000037591A03A8 +:1014A00007358000286127DA0835FF40401802BD63 +:1014B00001300000000000000130000400000000C6 +:1014C00001300008000000000130000C00000000A6 +:1014D0000130001000000000013000140000000086 +:1014E0000230002000000001023000240000000251 +:1014F00002300028000000030230002C0000000031 +:10150000023000300000000402300034000000010E +:1015100002300038000000000230003C00000001F2 +:1015200002300040000000040230004400000000CF +:1015300002300048000000010230004C00000003AF +:101540000230005000000000023000540000000192 +:1015500002300058000000040230005C000000006F +:10156000023000600000000102300064000000034F +:1015700002300068000000000230006C0000000132 +:10158000023000700000000402300074000000000F +:1015900002300078000000040230007C00000003EC +:1015A0000630008000000002023000A400003FFF6F +:1015B000023000A8000003FF0230022400000000F7 +:1015C00002300234000000000230024C0000000033 +:1015D000023002E40000FFFF063020000000080097 +:1015E00002338BC000000001023380000000001AAB +:1015F000023380400000004E023380800000001063 +:10160000023380C0000000200C3383000007A120BB +:101610000A338300000001380B3383000000138875 +:10162000023383C0000001F40C3383801DCD6500BC +:101630000A3383800004C4B40B338380004C4B40D6 +:101640000A331480000000000233148000000001FF +:10165000063220000000010206328980000000C826 +:1016600006328960000000020632322800000004C1 +:10167000063232000000000904323224000102BFA9 +:1016800006323180000000200632500000000400C5 +:10169000063240000000000204324008000102C08F +:1016A0000632400C0000000306326B6800000002A6 +:1016B00004326B70000202C106326B10000000029F +:1016C000043274C0000202C30233080001000000AB +:1016D00004330C00001002C50233080000000000B3 +:1016E00004330C40001002D506329000000000A028 +:1016F0000632950000000040063297000000003CD2 +:1017000006322450000000B406322AD00000000245 +:101710000632308000000020063280000000012CDC +:101720000232323800000000063250000000002073 +:101730000632510000000020063252000000002056 +:101740000632530000000020063254000000002042 +:10175000063255000000002006325600000000202E +:10176000063257000000002006325800000000201A +:10177000063259000000002006325A000000002006 +:1017800006325B000000002006325C0000000020F2 +:1017900006325D000000002006325E0000000020DE +:1017A00006325F000000002006326B780000005215 +:1017B00006326E080000000C06329280000000A085 +:1017C0000632960000000040063297F00000003C10 +:1017D00006322720000000B406322AD8000000029A +:1017E0000632310000000020063284B00000012CD7 +:1017F0000232323C0000000006325080000000201F +:101800000632518000000020063252800000002085 +:101810000632538000000020063254800000002071 +:10182000063255800000002006325680000000205D +:101830000632578000000020063258800000002049 +:10184000063259800000002006325A800000002035 +:1018500006325B800000002006325C800000002021 +:1018600006325D800000002006325E80000000200D +:1018700006325F800000002006326CC0000000527B +:1018800006326E380000000C02322A3000000000E0 +:10189000063230000000000406324018000000024A +:1018A00002322A340000000006323010000000042A +:1018B000063240280000000202322A3800000000F0 +:1018C00006323020000000040632403800000002DA +:1018D00002322A3C000000000632303000000004D2 +:1018E000063240480000000202322A400000000098 +:1018F000063230400000000406324058000000026A +:1019000002322A4400000000063230500000000479 +:10191000063240680000000202322A48000000003F +:1019200006323060000000040632407800000002F9 +:1019300002322A4C00000000063230700000000421 +:1019400006324088000000020720040000740000F6 +:1019500008200780001002E507240000322600005E +:1019600007248000246E0C8A0824CBB064F002E7C0 +:101970000120000000000000012000040000000021 +:1019800001200008000000000120000C0000000001 +:1019900001200010000000000120001400000000E1 +:1019A00002200020000000010220002400000002AC +:1019B00002200028000000030220002C000000008C +:1019C000022000300000000402200034000000016A +:1019D00002200038000000000220003C000000014E +:1019E000022000400000000402200044000000002B +:1019F00002200048000000010220004C000000030B +:101A000002200050000000000220005400000001ED +:101A100002200058000000040220005C00000000CA +:101A200002200060000000010220006400000003AA +:101A300002200068000000000220006C000000018D +:101A4000022000700000000402200074000000006A +:101A500002200078000000040220007C0000000347 +:101A60000620008000000002022000A400003FFFCA +:101A7000022000A8000003FF022002240000000052 +:101A800002200234000000000220024C000000008E +:101A9000022002E40000FFFF0620200000000800F2 +:101AA00002238BC000000001022380000000001010 +:101AB00002238040000000120223808000000030DA +:101AC000022380C00000000E022383C0000001F446 +:101AD00002231480000000010A231480000000008B +:101AE000062210000000004206227020000000C8FC +:101AF0000622700000000002022211E8000000002F +:101B000006223000000000C0062240700000008065 +:101B10000622528000000004062267000000010037 +:101B2000062290000000040004226B08002002E955 +:101B300002230800013FFFFF04230C0000100309EB +:101B4000022308000000000004230C4000100319C9 +:101B500006228000000000A0062285000000004050 +:101B6000062287000000003C0622404000000006DC +:101B700006228280000000A00622860000000040AD +:101B8000062287F00000003C0622405800000006B4 +:101B9000022211480000000006223300000000026B +:101BA00006226040000000300222114C00000000BC +:101BB0000622330800000002062261000000003007 +:101BC0000222115000000000062233100000000223 +:101BD000062261C000000030022211540000000003 +:101BE0000622331800000002062262800000003046 +:101BF00002221158000000000622332000000002DB +:101C000006226340000000300222115C0000000048 +:101C10000622332800000002062264000000003083 +:101C20000222116000000000062233300000000292 +:101C3000062264C00000003002221164000000008F +:101C400006223338000000020622658000000030C2 +:101C50000216100000000020021700080000000219 +:101C60000217002C000000030217003C00000004D3 +:101C7000021700440000000802170048000000029C +:101C80000217004C00000090021700500000009066 +:101C9000021700540080009002170058081400003A +:101CA000021700600000008A021700640000008034 +:101CB00002170068000000900217006C000000800E +:101CC000021700700000000602170078000007D01D +:101CD0000217007C0000076C02170038007C10041B +:101CE000021700040000000F061640240000000246 +:101CF000021640700000001C02164208000000019D +:101D000002164210000000010216422000000001ED +:101D100002164228000000010216423000000001B5 +:101D20000216423800000001021642600000000264 +:101D30000C16401C0003D0900A16401C0000009CAA +:101D40000B16401C000009C40216403000000008B9 +:101D5000021640340000000C02164038000000104B +:101D6000021640440000002002164000000000015E +:101D7000021640D8000000010216400800000001D1 +:101D80000216400C00000001021640100000000185 +:101D90000216424000000000021642480000000007 +:101DA00006164270000000020216425000000000B9 +:101DB0000216425800000000061642800000000291 +:101DC00002166008000004240216600C00000410D3 +:101DD00002166010000004140216601C0000FFFFD1 +:101DE000021660200000FFFF021660240000FFFFC3 +:101DF000021660280000FFFF021660380000002075 +:101E00000216603C00000020021660400000003412 +:101E100002166044000000350216604800000023EE +:101E20000216604C000000240216605000000025DD +:101E300002166054000000260216605800000027B9 +:101E40000216605C00000029021660600000002A93 +:101E5000021660640000002B021660680000002C6F +:101E60000216606C0000002D061660700000005223 +:101E7000021661B800000001061661BC0000001FD8 +:101E80000216623807FFFFFF0216623C0000003FA7 +:101E90000216624007FFFFFF021662440000000FB7 +:101EA00001166248000000000116624C00000000AC +:101EB000011662500000000001166254000000008C +:101EC00001166258000000000116625C000000006C +:101ED000011662600000000001166264000000004C +:101EE00001166268000000000116626C000000002C +:101EF000011662700000000001166274000000000C +:101F000001166278000000000116627C00000000EB +:101F10000C166000000003E80A16600000000001D3 +:101F20000B1660000000000A021680400000000648 +:101F30000216804400000005021680480000000AD6 +:101F40000216804C000000050216805400000002BA +:101F5000021680CC00000004021680D000000004AD +:101F6000021680D400000004021680D8000000048D +:101F7000021680DC00000004021680E0000000046D +:101F8000021680E400000004021680E8000000044D +:101F90000216880400000004021680300000007C55 +:101FA000021680340000003D021680380000003F19 +:101FB0000216803C0000009C021680F00000000722 +:101FC000061680F4000000050216880C01010101CC +:101FD00002168108000000000216810C00000004B7 +:101FE0000216811000000004021681140000000295 +:101FF000021688100801200402168118000000054E +:102000000216811C00000005021681200000000558 +:1020100002168124000000050216882C20081001F9 +:1020200002168128000000080216812C000000061C +:102030000216813000000007021681340000000003 +:1020400002168830010101200616813800000004C4 +:1020500002168834010101010216814800000000C7 +:102060000216814C0000000402168150000000049A +:10207000021681540000000202168838080120046C +:1020800002168158000000050216815C0000000560 +:102090000216816000000005021681640000000540 +:1020A0000216883C20081001021681680000000812 +:1020B0000216816C00000006021681700000000705 +:1020C00002168174000000010216884001010120FF +:1020D00002168178000000010216817C00000001D8 +:1020E00002168180000000010216818400000001B8 +:1020F00002168844010101010216818800000001D6 +:102100000216818C00000004021681900000000479 +:10211000021681940000000202168848080120047B +:1021200002168198000000050216819C000000053F +:10213000021681A000000005021681A4000000051F +:102140000216881420081001021681A80000000859 +:10215000021681AC00000006021681B000000007E4 +:10216000021681B400000001021688180101012046 +:10217000021681B800000001021681BC00000001B7 +:10218000021681C000000001021681C40000000197 +:102190000216881C01010101021681C8000000011D +:1021A000021681CC00000004021681D00000000459 +:1021B000021681D4000000020216882008012004C3 +:1021C000021681D800000005021681DC000000051F +:1021D000021681E000000005021681E400000005FF +:1021E0000216882420081001021681E80000000869 +:1021F000021681EC00000006021681F000000007C4 +:102200000216E40C000000000216882801010120DB +:102210000616E410000000040216E00001010101AE +:102220000216E420000000000216E424000000046E +:102230000216E428000000040216E42C000000024C +:102240000216E004080120040216E4300000000534 +:102250000216E434000000050216E4380000000510 +:102260000216E43C000000050216E00820081001F8 +:102270000216E440000000080216E44400000006D4 +:102280000216E448000000070216E44C00000000BB +:102290000216E00C010101200616E45000000004C3 +:1022A0000216E010010101010216E46000000000C6 +:1022B0000216E464000000040216E4680000000452 +:1022C0000216E46C000000020216E014080120046B +:1022D0000216E470000000050216E4740000000518 +:1022E0000216E478000000050216E47C00000005F8 +:1022F0000216E018200810010216E4800000000811 +:102300000216E484000000060216E48800000007BC +:102310000216E48C000000010216E01C01010120FD +:102320000216E490000000010216E494000000018F +:102330000216E498000000010216E49C000000016F +:102340000216E020010101010216E4A000000001D4 +:102350000216E4A4000000040216E4A80000000431 +:102360000216E4AC000000020216E024080120047A +:102370000216E4B0000000050216E4B400000005F7 +:102380000216E4B8000000050216E4BC00000005D7 +:102390000216E028200810010216E4C00000000820 +:1023A0000216E4C4000000060216E4C8000000079C +:1023B0000216E4CC000000010216E02C010101200D +:1023C0000216E4D0000000010216E4D4000000016F +:1023D0000216E4D8000000010216E4DC000000014F +:1023E0000216E030010101010216E4E000000001E4 +:1023F0000216E4E4000000040216E4E80000000411 +:102400000216E4EC000000020216E0340801200489 +:102410000216E4F0000000050216E4F400000005D6 +:102420000216E4F8000000050216E4FC00000005B6 +:102430000216E038200810010216E500000000082E +:102440000216E504000000060216E5080000000779 +:102450000216E03C0101012002168240003F003FCD +:1024600002168244000000000216E524003F003FEF +:102470000216E52800000000021682480000000055 +:102480000216824C003F003F0216E52C00000000BF +:102490000216E530003F003F0216825001000100A5 +:1024A00002168254010001000216E5340100010009 +:1024B0000216E538010001000616825800000002ED +:1024C0000216E53C000000000216E5400000000096 +:1024D0000216826000C000C00216826400C000C004 +:1024E0000216E54400C000C00216E54800C000C066 +:1024F000021682681E001E000216826C1E001E005C +:102500000216E54C1E001E000216E5501E001E00BD +:1025100002168270400040000216827440004000A3 +:102520000216E554400040000216E5584000400005 +:1025300002168278800080000216827C8000800073 +:102540000216E55C800080000216E56080008000D5 +:1025500002168280200020000216828420002000C3 +:102560000216E564200020000216E5682000200025 +:1025700006168288000000020216E56C00000000CA +:102580000216E570000000000216829000000000B4 +:1025900002168294000000000216E574000000009C +:1025A0000216E57800000000021682980000000084 +:1025B0000216829C000000000216E57C000000006C +:1025C0000216E58000000000021682A00000000054 +:1025D000021682A400000001061682A80000000A6C +:1025E000021681F400000C08021681F80000004079 +:1025F000021681FC0000010002168200000000208B +:1026000002168204000000170216820800000080F3 +:102610000216820C00000200021682100000000068 +:102620000216821801FF01FF0216821401FF01FF4A +:102630000216E51001FF01FF0216E50C01FF01FF84 +:102640000216823C00000013021680900000013F39 +:102650000216806000000140021680640000014004 +:10266000061680680000000202168070000000C09C +:1026700006168074000000070216809C00000048C7 +:10268000021680A000000048061680A40000000288 +:10269000021680AC00000048061680B0000000075B +:1026A000021682380000800002168234000025E401 +:1026B0000216809400007FFF0216822000070007A8 +:1026C0000216821C000700070216E5180007000723 +:1026D0000216E51400070007021682280000000019 +:1026E00002168224FFFFFFFF0216E5200000000013 +:1026F0000216E51CFFFFFFFF0216E6BC000000000B +:102700000216E6C0000000020216E6C40000000146 +:102710000216E6C8000000030216E6CC0000000422 +:102720000216E6D0000000060216E6D400000005FE +:102730000216E6D800000007021680EC000000FF39 +:1027400002140000000000010214000C000000014F +:1027500002140040000000010214004400007FFF4A +:102760000214000C00000000021400000000000031 +:102770000214006C000000000214000400000001BC +:1027800002140030000000010214000400000000E8 +:102790000214005C000000000214000800000001A8 +:1027A00002140034000000010214000800000000C0 +:1027B0000214006000000000020200580000003215 +:1027C000020200A003150020020200A4031500204D +:1027D000020200A801000030020200AC0810000054 +:1027E000020200B000000033020200B4000000301A +:1027F000020200B800000031020200BC0000000329 +:10280000020200C000000006020200C40000000333 +:10281000020200C800000003020200CC0000000217 +:10282000020200D000000000020200D400000002FA +:10283000020200DC00000000020200E000000006CE +:10284000020200E400000004020200E800000002AE +:10285000020200EC00000002020200F00000000191 +:10286000020200FC0000000602020120000000003D +:102870000202013400000002020201B00000000167 +:102880000202020C0000000102020214000000011A +:10289000020202180000000202020404000000010B +:1028A0000202040C0000004002020410000000407C +:1028B0000202041C000000040202042000000020A8 +:1028C000020204240000000202020428000000208A +:1028D000060205000000001204020480001F032904 +:1028E000020200600000000F020200640000000706 +:1028F000020200680000000B0202006C0000000EE3 +:10290000020200700000000E0602007400000003C6 +:10291000020200F4000000040202000400000001B2 +:1029200002020008000000010202000C0000000189 +:102930000202001000000001020200140000000169 +:1029400002020018000000010202001C0000000149 +:102950000202002000000001020200240000000129 +:1029600002020028000000010202002C0000000109 +:1029700002020030000000010202003400000001E9 +:1029800002020038000000010202003C00000001C9 +:1029900002020040000000010202004400000001A9 +:1029A00002020048000000010202004C0000000189 +:1029B000020200500000000102020108000000C8ED +:1029C0000202011800000002020201C4000000001F +:1029D000020201CC00000000020201D4000000024B +:1029E000020201DC00000002020201E4000000FF1C +:1029F000020201EC000000FF0202010000000000E2 +:102A00000202010C000000C80202011C00000002CA +:102A1000020201C800000000020201D00000000014 +:102A2000020201D800000002020201E000000002E0 +:102A3000020201E8000000FF020201F0000000FFB6 +:102A4000020201040000000002020108000000C8A8 +:102A50000202011800000002020201C4000000008E +:102A6000020201CC00000000020201D400000002BA +:102A7000020201DC00000002020201E4000000FF8B +:102A8000020201EC000000FF020201000000000051 +:102A90000202010C000000C80202011C000000023A +:102AA000020201C800000000020201D00000000084 +:102AB000020201D800000002020201E00000000250 +:102AC000020201E8000000FF020201F0000000FF26 +:102AD000020201040000000002020108000000C818 +:102AE0000202011800000002020201C400000000FE +:102AF000020201CC00000000020201D4000000022A +:102B0000020201DC00000002020201E4000000FFFA +:102B1000020201EC000000FF0202010000000000C0 +:102B20000202010C000000C80202011C00000002A9 +:102B3000020201C800000000020201D000000000F3 +:102B4000020201D800000002020201E000000002BF +:102B5000020201E8000000FF020201F0000000FF95 +:102B6000020201040000000002020108000000C887 +:102B70000202011800000002020201C4000000006D +:102B8000020201CC00000000020201D40000000299 +:102B9000020201DC00000002020201E4000000FF6A +:102BA000020201EC000000FF020201000000000030 +:102BB0000202010C000000C80202011C0000000219 +:102BC000020201C800000000020201D00000000063 +:102BD000020201D800000002020201E0000000022F +:102BE000020201E8000000FF020201F0000000FF05 +:102BF00002020104000000000728040000BD0000DC +:102C0000082807A8000B0348072C00003406000022 +:102C1000072C800037960D02072D00003BC31AE8F1 +:102C2000072D8000382629D9072E0000124537E3EA +:102C3000082E22203BBC034A0128000000000000AF +:102C40000128000400000000012800080000000026 +:102C50000128000C00000000012800100000000006 +:102C600001280014000000000228002000000001DC +:102C700002280024000000020228002800000003AF +:102C80000228002C00000000022800300000000490 +:102C90000228003400000001022800380000000073 +:102CA0000228003C0000000102280040000000044F +:102CB0000228004400000000022800480000000133 +:102CC0000228004C00000003022800500000000011 +:102CD00002280054000000010228005800000004EF +:102CE0000228005C000000000228006000000001D3 +:102CF00002280064000000030228006800000000B1 +:102D00000228006C0000000102280070000000048E +:102D1000022800740000000002280078000000046F +:102D20000228007C0000000306280080000000024A +:102D3000022800A400003FFF022800A8000003FFB3 +:102D400002280224000000000228023400000000D3 +:102D50000228024C00000000022802E40000FFFFED +:102D60000628200000000800022B8BC00000000194 +:102D7000022B800000000000022B804000000018A1 +:102D8000022B80800000000C022B80C00000006637 +:102D90000C2B83000007A1200A2B830000000138C0 +:102DA0000B2B830000001388022B83C0000001F46A +:102DB0000C2B8340000001F40A2B8340000000002C +:102DC0000B2B8340000000050A2B83800004C4B451 +:102DD0000C2B83801DCD65000A2B148000000000A1 +:102DE0000B2B8380004C4B40022B14800000000111 +:102DF000062A29C800000004042A29D80002034C2E +:102E0000062A208000000048062A9020000000C802 +:102E1000062A900000000002062A21A80000008671 +:102E2000062A200000000020022A23C8000000001B +:102E3000042A23D00002034E042A249800040350DD +:102E4000022A2C2000000000022A2C1000000000A2 +:102E5000042A2C0800020354022A3010000000014A +:102E6000062A404000000010042A400000100356CB +:102E7000062A6AC000000002062A6B000000000457 +:102E8000042A840800020366022B080000000000E8 +:102E9000042B0C0000100368022B08000100000046 +:102EA000042B0C4000080378022B080002000000ED +:102EB000042B0C6000080380062AC000000000FC00 +:102EC000062A24A800000014062A25480000002431 +:102ED000062A266800000024062A2788000000240D +:102EE000062A28A800000024062AA00000000028C6 +:102EF000062AA1400000000C042A29E000020388F1 +:102F0000022A300000000001062A502000000002C2 +:102F1000062A503000000002062A5000000000027D +:102F2000062A501000000002022A52080000000188 +:102F3000042A6AC80002038A062A6B1000000042B5 +:102F4000062A6D2000000004062AC3F0000000FCE1 +:102F5000062A24F800000014062A25D800000024C0 +:102F6000062A26F800000024062A2818000000245B +:102F7000062A293800000024062AA0A00000002804 +:102F8000062AA1700000000C042A29E80002038C24 +:102F9000022A300400000001062A50280000000226 +:102FA000062A503800000002062A500800000002DD +:102FB000062A501800000002022A520C00000001EC +:102FC000042A6AD00002038E062A6C180000004210 +:102FD000062A6D3000000004022AC7E0000000004D +:102FE000042A29F000100390062A50480000000E21 +:102FF000022AC7E400000000042A2A30001003A0BF +:10300000062A50800000000E022AC7E800000000D7 +:10301000042A2A70001003B0062A50B80000000EDF +:10302000022AC7EC00000000042A2AB0001003C0E6 +:10303000062A50F00000000E022AC7F0000000002F +:10304000042A2AF0001003D0062A51280000000E9E +:10305000022AC7F400000000042A2B30001003E00D +:10306000062A51600000000E022AC7F80000000086 +:10307000042A2B70001003F0062A51980000000E5D +:10308000022AC7FC00000000042A2BB00010040034 +:10309000062A51D00000000E0210100800000001A6 +:1030A0000210105000000001021010000003D000B8 +:1030B000021010040000003D091018000200041066 +:1030C0000910110000280610061011A000000018B9 +:1030D00006102400000000E00210201C0000000088 +:1030E0000210202000000001021020C00000000299 +:1030F000021020040000000102102008000000015E +:1031000009103C0000050638091038000005063D8E +:10311000091038200005064206104C00000001008E +:1031200002104028000000100210404400003FFF41 +:103130000210405800280000021040840084924A87 +:1031400002104058000000000210800000001080B3 +:10315000021080AC00000000021080380000001057 +:103160000210810000000000061081200000000213 +:1031700002108008000002B502108010000000005C +:10318000061082000000004A021081080001FFFFC3 +:1031900006108140000000020210800000001A802A +:1031A0000610900000000024061091200000004A44 +:1031B000061093700000004A061095C00000004AF7 +:1031C0000210800400001080021080B00000000196 +:1031D0000210803C0000001002108104000000007A +:1031E00006108128000000020210800C000002B5C9 +:1031F0000210801400000000061084000000004A45 +:103200000210810C0001FFFF06108148000000023F +:103210000210800400001A80061090900000002424 +:10322000061092480000004A061094980000004AD8 +:10323000061096E80000004A02108000000010808E +:10324000021080AC00000002021080380000001064 +:103250000210810000000000061081200000000222 +:1032600002108008000002B502108010000000006B +:10327000061082000000004A021081080001FFFFD2 +:1032800006108140000000020210800000001A8039 +:103290000610900000000024061091200000004A53 +:1032A000061093700000004A061095C00000004A06 +:1032B0000210800400001080021080B000000003A3 +:1032C0000210803C00000010021081040000000089 +:1032D00006108128000000020210800C000002B5D8 +:1032E0000210801400000000061084000000004A54 +:1032F0000210810C0001FFFF06108148000000024F +:103300000210800400001A80061090900000002433 +:10331000061092480000004A061094980000004AE7 +:10332000061096E80000004A02108000000010809D +:10333000021080AC00000004021080380000001071 +:103340000210810000000000061081200000000231 +:1033500002108008000002B502108010000000007A +:10336000061082000000004A021081080001FFFFE1 +:1033700006108140000000020210800000001A8048 +:103380000610900000000024061091200000004A62 +:10339000061093700000004A061095C00000004A15 +:1033A0000210800400001080021080B000000005B0 +:1033B0000210803C00000010021081040000000098 +:1033C00006108128000000020210800C000002B5E7 +:1033D0000210801400000000061084000000004A63 +:1033E0000210810C0001FFFF06108148000000025E +:1033F0000210800400001A80061090900000002443 +:10340000061092480000004A061094980000004AF6 +:10341000061096E80000004A0210800000001080AC +:10342000021080AC0000000602108038000000107E +:103430000210810000000000061081200000000240 +:1034400002108008000002B5021080100000000089 +:10345000061082000000004A021081080001FFFFF0 +:1034600006108140000000020210800000001A8057 +:103470000610900000000024061091200000004A71 +:10348000061093700000004A061095C00000004A24 +:103490000210800400001080021080B000000007BD +:1034A0000210803C000000100210810400000000A7 +:1034B00006108128000000020210800C000002B5F6 +:1034C0000210801400000000061084000000004A72 +:1034D0000210810C0001FFFF06108148000000026D +:1034E0000210800400001A80061090900000002452 +:1034F000061092480000004A061094980000004A06 +:10350000061096E80000004A021205B00000000113 +:103510000212049000E383400212051400003C10E4 +:103520000212066C0000000102120670000000008A +:1035300002120494FFFFFFFF02120498FFFFFFFF37 +:103540000212049CFFFFFFFF021204A0FFFFFFFF17 +:10355000021204A4FFFFFFFF021204A8FFFFFFFFF7 +:10356000021204ACFFFFFFFF021204B0FFFFFFFFD7 +:10357000021204BCFFFFFFFF021204C0FFFFFFFFA7 +:10358000021204C4FFFFFFFF021204C8FFFFFFFF87 +:10359000021204CCFFFFFFFF021204D0FFFFFFFF67 +:1035A000021204D8FFFFFFFF021204DCFFFFFFFF3F +:1035B000021204E0FFFFFFFF021204E4FFFFFFFF1F +:1035C000021204E8FFFFFFFF021204ECFFFFFFFFFF +:1035D000021204F0FFFFFFFF021204F4FFFFFFFFDF +:1035E000021204F8FFFFFFFF021204FCFFFFFFFFBF +:1035F00002120500FFFFFFFF02120504FFFFFFFF9D +:1036000002120508FFFFFFFF0212050CFFFFFFFF7C +:1036100002120510FFFFFFFF021204D4FF802000FA +:10362000021204B4F0005000021204B8F00080004E +:1036300002120390000000080212039C0000000820 +:10364000021203A000000008021203A400000002FE +:10365000021203BC00000004021203C000000005B7 +:10366000021203C400000004021203D00000000094 +:103670000212036C00000001021203680000003F08 +:10368000021201BC00000040021201C00000180834 +:10369000021201C400000803021201C8000008035E +:1036A000021201CC00000040021201D00000000311 +:1036B000021201D400000803021201D8000008031E +:1036C000021201DC00000803021201E00001000305 +:1036D000021201E400000803021201E800000803DE +:1036E000021201EC00000003021201F000000003CE +:1036F000021201F400000003021201F800000003AE +:10370000021201FC0000000302120200000000038C +:10371000021202040000000302120208000000036B +:103720000212020C0000000302120210000000034B +:10373000021202140000000302120218000000032B +:103740000212021C0000000302120220000000030B +:1037500002120224000000030212022800002403C7 +:103760000212022C0000002F021202300000000999 +:103770000212023400000019021202380000018413 +:103780000212023C00000183021202400000030604 +:103790000212024400000019021202480000000652 +:1037A0000212024C0000030602120250000003063F +:1037B00002120254000003060212025800000C8696 +:1037C0000212025C000003060212026000000306FF +:1037D00002120264000000060212026800000006E5 +:1037E0000212026C000000060212027000000006C5 +:1037F00002120274000000060212027800000006A5 +:103800000212027C00000006021202800000000684 +:103810000212028400000006021202880000000664 +:103820000212028C00000006021202900000000644 +:103830000212029400000006021202980000000624 +:103840000212029C00000006021202A00000030601 +:10385000021202A400000013021202A800000006D7 +:10386000021202B000001004021202B400001004A0 +:103870000212032400106440021203280010644066 +:10388000021205B400000001021201B000000001A4 +:103890000600A000000000160200A0EC5554000035 +:1038A0000200A0F0555555550200A0F400005555F2 +:1038B0000200A0F8F00000000200A0FC5554000037 +:1038C0000200A100555555550200A10400005555B0 +:1038D0000200A108F00000000200A18C5554000075 +:1038E0000200A190555555550200A1940000555570 +:1038F0000200A198F00000000200A19C000000005E +:103900000200A1A0000100000200A1A400005014C8 +:103910000200A1A8000000000200A45C00000C004E +:103920000200A61C000000030200A06CFF5C000067 +:103930000200A070FFF55FFF0200A0740000FFFF0F +:103940000200A078F00003E00200A07C000000006C +:103950000200A0800000A0000600A0840000000576 +:103960000200A0980FE000000600A09C00000007E5 +:103970000200A0B8000004000600A0BC0000000384 +:103980000200A0C8000010000600A0CC0000000348 +:103990000200A0D8000040000600A0DC00000003E8 +:1039A0000200A0E8000100000600A22C00000004B4 +:1039B0000200A10CFF5C00000200A110FFF55FFFF8 +:1039C0000200A1140000FFFF0200A118F00003E0B4 +:1039D0000200A11C000000000200A1200000A000C5 +:1039E0000600A124000000050200A1380FE000003D +:1039F0000600A13C000000070200A15800000800DA +:103A00000600A15C000000030200A1680000200085 +:103A10000600A16C000000030200A17800008000F5 +:103A20000600A17C000000030200A1880002000043 +:103A30000600A23C0000000400000000000000009E +:103A40000000003100000000000000000000000045 +:103A50000000000000000000000000000000000066 +:103A600000000000000000000000000000310032F3 +:103A70000000000000000000000000000000000046 +:103A80000000000000000000000000000000000036 +:103A9000000000000000000000320056000000009E +:103AA0000000000000000000000000000000000016 +:103AB0000000000000000000000000000000000006 +:103AC000000000000056008C000000000000000014 +:103AD000008C009000900094009400980098009C46 +:103AE000009C00A000A000A400A400A800A800ACB6 +:103AF00000AC00B100B100B300B300B5000000009D +:103B000000000000000000000000000000000000B5 +:103B100000000000000000000000000000B50100EF +:103B2000010001060106010C010C01140114011C25 +:103B3000011C01240124012C012C01340134013C1D +:103B4000013C01440144014C000000000000000061 +:103B50000000000000000000000000000000000065 +:103B60000000000000000000000000000000000055 +:103B70000000000000000000000000000000000045 +:103B80000000000000000000000000000000000035 +:103B90000000000000000000000000000000000025 +:103BA0000000000000000000000000000000000015 +:103BB0000000000000000000000000000000000005 +:103BC00000000000000000000000000000000000F5 +:103BD00000000000000000000000000000000000E5 +:103BE00000000000000000000000000000000000D5 +:103BF0000000000000000000014C01510000000026 +:103C000000000000015101520152015301530154BF +:103C100001540155015501560156015701570158EC +:103C200001580159000000000000000000000000E1 +:103C30000000000000000000000000000000000084 +:103C40000000000000000000000000000000000074 +:103C50000159015E015E016A016A017600000000FF +:103C60000000000000000000000000000000000054 +:103C70000000000000000000000000000000000044 +:103C80000000000000000000000000000000000034 +:103C90000000000000000000000000000000000024 +:103CA0000000000000000000017601770000000025 +:103CB0000000000000000000000000000000000004 +:103CC00000000000000000000000000000000000F4 +:103CD000000000000177019A0000000000000000D1 +:103CE00000000000000000000000000000000000D4 +:103CF00000000000000000000000000000000000C4 +:103D0000019A01C200000000000000000000000055 +:103D100000000000000000000000000000000000A3 +:103D200000000000000000000000000001C201F3DC +:103D3000000000000000000001F301FA01FA020196 +:103D4000020102080208020F020F02160216021DEB +:103D5000021D02240224022B022B02630000000039 +:103D600000000000026302670267026B026B026FD1 +:103D7000026F0273027302770277027B027B027F7B +:103D8000027F0283028302D102D102EB02EB030520 +:103D9000030503080308030B030B030E030E0311B3 +:103DA00003110314031403170317031A031A031D43 +:103DB000031D035E035E0362036203660366036919 +:103DC0000369036C036C036F036F03720372037563 +:103DD000037503780378037B037B037E037E037FF5 +:103DE00000000000000000000000000000000000D3 +:103DF00000000000000000000000000000000000C3 +:103E00000000000000000000037F0391000000009C +:103E100000000000000000000000000000000000A2 +:103E20000000000000000000000000000000000092 +:103E300000000000039103A603A603A903A903AC95 +:103E40000000000000000000000000000000000072 +:103E50000000000000000000000000000000000062 +:103E600003AC03D9000000000000000000000000C7 +:103E70000000000000000000000000000000000042 +:103E800000000000000000000000000003D904DC76 +:103E90000000000000000000000000000000000022 +:103EA0000000000000000000000000000000000012 +:103EB000000000000000000004DC04E304E304E769 +:103EC00004E704EB00000000000000000000000018 +:103ED00000000000000000000000000000000000E2 +:103EE0000000000004EB052B0000000000000000B3 +:103EF000052B05340534053D053D05460546054FB2 +:103F0000054F0558055805610561056A056A057381 +:103F1000057305CB05CB05DD05DD05EF05EF05F2E6 +:103F200005F205F505F505F805F805FB05FB05FEA9 +:103F300005FE060106010604060406070607060E2E +:103F40000000000000000000000000000000000071 +:103F50000000000000000000000000000000000061 +:103F60000000000000000000060E06140000000023 +:103F70000000000000000000000000000000000041 +:103F80000000000000000000000000000000000031 +:103F900000000000061406170000000000000000EA +:103FA0000000000000000000000000000000000011 +:103FB0000000000000000000000000000000000001 +:103FC0000617061D000000000000000000000000B1 +:103FD00000000000000000000000000000000000E1 +:103FE00000000000000000000000000000000000D1 +:103FF0000000000000000000061D062C062C063BF9 +:10400000063B064A064A06590659066806680677B8 +:1040100006770686068606950695070600000000C8 +:104020000000000000000000000000000000000090 +:104030000000000000000000000000000000000080 +:1040400000000000070607190719072A072A073B7F +:104050000000000000000000000000000000000060 +:104060000000000000000000000000000000000050 +:10407000000000000000000000010000000204C079 +:104080000003098000040E4000051300000617C05D +:1040900000071C800008214000092600000A2AC0F1 +:1040A000000B2F80000C3440000D3900000E3DC085 +:1040B000000F42800010474000114C00001250C019 +:1040C0000013558000145A4000155F00001663C0AD +:1040D0000017688000186D4000197200001A76C041 +:1040E000001B7B80001C8040001D8500001E89C0D5 +:1040F000001F8E8000209340000020000000400040 +:1041000000006000000080000000A0000000C0006F +:104110000000E0000001000000012000000140005C +:1041200000016000000180000001A0000001C0004B +:104130000001E00000020000000220000002400038 +:1041400000026000000280000002A0000002C00027 +:104150000002E00000030000000320000003400014 +:1041600000036000000380000003A0000003C00003 +:104170000003E000000400000004200000044000F0 +:1041800000046000000480000004A0000004C000DF +:104190000004E000000500000005200000054000CC +:1041A00000056000000580000005A0000005C000BB +:1041B0000005E000000600000006200000064000A8 +:1041C00000066000000680000006A0000006C00097 +:1041D0000006E00000070000000720000007400084 +:1041E00000076000000780000007A0000007C00073 +:1041F0000007E00000080000000820000008400060 +:1042000000086000000880000008A0000008C0004E +:104210000008E0000009000000092000000940003B +:1042200000096000000980000009A0000009C0002A +:104230000009E000000A0000000A2000000A400017 +:10424000000A6000000A8000000AA000000AC00006 +:10425000000AE000000B0000000B2000000B4000F3 +:10426000000B6000000B8000000BA000000BC000E2 +:10427000000BE000000C0000000C2000000C4000CF +:10428000000C6000000C8000000CA000000CC000BE +:10429000000CE000000D0000000D2000000D4000AB +:1042A000000D6000000D8000000DA000000DC0009A +:1042B000000DE000000E0000000E2000000E400087 +:1042C000000E6000000E8000000EA000000EC00076 +:1042D000000EE000000F0000000F2000000F400063 +:1042E000000F6000000F8000000FA000000FC00052 +:1042F000000FE0000010000000102000001040003F +:1043000000106000001080000010A0000010C0002D +:104310000010E0000011000000112000001140001A +:1043200000116000001180000011A0000011C00009 +:104330000011E000001200000012200000124000F6 +:1043400000126000001280000012A0000012C000E5 +:104350000012E000001300000013200000134000D2 +:1043600000136000001380000013A0000013C000C1 +:104370000013E000001400000014200000144000AE +:1043800000146000001480000014A0000014C0009D +:104390000014E0000015000000152000001540008A +:1043A00000156000001580000015A0000015C00079 +:1043B0000015E00000160000001620000016400066 +:1043C00000166000001680000016A0000016C00055 +:1043D0000016E00000170000001720000017400042 +:1043E00000176000001780000017A0000017C00031 +:1043F0000017E0000018000000182000001840001E +:1044000000186000001880000018A0000018C0000C +:104410000018E000001900000019200000194000F9 +:1044200000196000001980000019A0000019C000E8 +:104430000019E000001A0000001A2000001A4000D5 +:10444000001A6000001A8000001AA000001AC000C4 +:10445000001AE000001B0000001B2000001B4000B1 +:10446000001B6000001B8000001BA000001BC000A0 +:10447000001BE000001C0000001C2000001C40008D +:10448000001C6000001C8000001CA000001CC0007C +:10449000001CE000001D0000001D2000001D400069 +:1044A000001D6000001D8000001DA000001DC00058 +:1044B000001DE000001E0000001E2000001E400045 +:1044C000001E6000001E8000001EA000001EC00034 +:1044D000001EE000001F0000001F2000001F400021 +:1044E000001F6000001F8000001FA000001FC00010 +:1044F000001FE000002000000020200000204000FD +:1045000000206000002080000020A0000020C000EB +:104510000020E000002100000021200000214000D8 +:1045200000216000002180000021A0000021C000C7 +:104530000021E000002200000022200000224000B4 +:1045400000226000002280000022A0000022C000A3 +:104550000022E00000230000002320000023400090 +:1045600000236000002380000023A0000023C0007F +:104570000023E0000024000000242000002440006C +:1045800000246000002480000024A0000024C0005B +:104590000024E00000250000002520000025400048 +:1045A00000256000002580000025A0000025C00037 +:1045B0000025E00000260000002620000026400024 +:1045C00000266000002680000026A0000026C00013 +:1045D0000026E00000270000002720000027400000 +:1045E00000276000002780000027A0000027C000EF +:1045F0000027E000002800000028200000284000DC +:1046000000286000002880000028A0000028C000CA +:104610000028E000002900000029200000294000B7 +:1046200000296000002980000029A0000029C000A6 +:104630000029E000002A0000002A2000002A400093 +:10464000002A6000002A8000002AA000002AC00082 +:10465000002AE000002B0000002B2000002B40006F +:10466000002B6000002B8000002BA000002BC0005E +:10467000002BE000002C0000002C2000002C40004B +:10468000002C6000002C8000002CA000002CC0003A +:10469000002CE000002D0000002D2000002D400027 +:1046A000002D6000002D8000002DA000002DC00016 +:1046B000002DE000002E0000002E2000002E400003 +:1046C000002E6000002E8000002EA000002EC000F2 +:1046D000002EE000002F0000002F2000002F4000DF +:1046E000002F6000002F8000002FA000002FC000CE +:1046F000002FE000003000000030200000304000BB +:1047000000306000003080000030A0000030C000A9 +:104710000030E00000310000003120000031400096 +:1047200000316000003180000031A0000031C00085 +:104730000031E00000320000003220000032400072 +:1047400000326000003280000032A0000032C00061 +:104750000032E0000033000000332000003340004E +:1047600000336000003380000033A0000033C0003D +:104770000033E0000034000000342000003440002A +:1047800000346000003480000034A0000034C00019 +:104790000034E00000350000003520000035400006 +:1047A00000356000003580000035A0000035C000F5 +:1047B0000035E000003600000036200000364000E2 +:1047C00000366000003680000036A0000036C000D1 +:1047D0000036E000003700000037200000374000BE +:1047E00000376000003780000037A0000037C000AD +:1047F0000037E0000038000000382000003840009A +:1048000000386000003880000038A0000038C00088 +:104810000038E00000390000003920000039400075 +:1048200000396000003980000039A0000039C00064 +:104830000039E000003A0000003A2000003A400051 +:10484000003A6000003A8000003AA000003AC00040 +:10485000003AE000003B0000003B2000003B40002D +:10486000003B6000003B8000003BA000003BC0001C +:10487000003BE000003C0000003C2000003C400009 +:10488000003C6000003C8000003CA000003CC000F8 +:10489000003CE000003D0000003D2000003D4000E5 +:1048A000003D6000003D8000003DA000003DC000D4 +:1048B000003DE000003E0000003E2000003E4000C1 +:1048C000003E6000003E8000003EA000003EC000B0 +:1048D000003EE000003F0000003F2000003F40009D +:1048E000003F6000003F8000003FA000003FC0008C +:1048F000003FE000003FE00100000000000001FF79 +:104900000000020000007FF800007FF800000704AC +:104910000000350000000001FFFFFFFFFFFFFFFF69 +:10492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:10493000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:10494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:10495000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:10496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:10497000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:10498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:10499000FFFFFFFFFFFFFFFFFFFFFFFF0000000023 +:1049A000FFFFFFFF00000000FFFFFFFFFFFFFFFF13 +:1049B00000000000FFFFFFFF00000000FFFFFFFFFF +:1049C000FFFFFFFF00000000FFFFFFFF00000000EF +:1049D000FFFFFFFF0000000300BEBC20FFFFFFFF42 +:1049E00000000000FFFFFFFF00000000FFFFFFFFCF +:1049F0000000000300BEBC20FFFFFFFF000000001E +:104A0000FFFFFFFF00000000FFFFFFFF00000003AB +:104A100000BEBC20FFFFFFFF00000000FFFFFFFF04 +:104A200000000000FFFFFFFF0000000300BEBC20ED +:104A3000FFFFFFFF00000000FFFFFFFF000000007E +:104A4000FFFFFFFF0000000300BEBC20FFFFFFFFD1 +:104A500000000000FFFFFFFF00000000FFFFFFFF5E +:104A60000000000300BEBC2000002000000040C089 +:104A700000006180000082400000A3000000C3C06D +:104A80000000E4800001054000012600000146C04E +:104A900000016780000188400001A9000001C9C031 +:104AA0000001EA8000020B4000022C0000024CC012 +:104AB00000026D8000028E400002AF000002CFC0F5 +:104AC0000002F0800003114000033200000352C0D6 +:104AD00000037380000394400003B5000003D5C0B9 +:104AE0000003F6800004174000043800000458C09A +:104AF0000004798000049A400000800000010380D7 +:104B00000001870000020A8000028E00000311806D +:104B1000000395000004188000049C0000051F801D +:104B20000005A300000626800006AA0000072D80CD +:104B30000007B100000834800008B80000093B807D +:104B40000009BF00000A4280000AC600000B49802D +:104B5000000BCD00000C5080000CD400000D5780DD +:104B6000000DDB0000007FF800007FF800000487E4 +:104B700000001500000019000000002800100000CF +:104B80000000000000000000FFFFFFFF40000000E9 +:104B90004000000040000000400000004000000015 +:104BA0004000000040000000400000004000000005 +:104BB00040000000400000004000000040000000F5 +:104BC00040000000400000004000000040000000E5 +:104BD00040000000400000004000000040000000D5 +:104BE00040000000400000004000000040000000C5 +:104BF00040000000400000004000000040000000B5 +:104C000040000000400000004000000000007FF86D +:104C100000007FF8000003E000001500FFFFFFFF29 +:104C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94 +:104C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84 +:104C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74 +:104C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64 +:104C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54 +:104C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44 +:104C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34 +:104C9000FFFFFFFFFFFFFFFFFFFFFFFF40000000E0 +:104CA0004000000040000000400000004000000004 +:104CB00040000000400000004000000040000000F4 +:104CC00040000000400000004000000040000000E4 +:104CD00040000000400000004000000040000000D4 +:104CE00040000000400000004000000040000000C4 +:104CF00040000000400000004000000040000000B4 +:104D000040000000400000004000000040000000A3 +:104D100040000000400000004000000000001000C3 +:104D2000000020800000310000004180000052009F +:104D30000000628000007300000083800000940087 +:104D40000000A4800000B5000000C5800000D6006F +:104D50000000E6800000F700000107800001180055 +:104D600000012880000139000001498000015A003B +:104D700000016A8000017B0000018B8000019C0023 +:104D80000001AC800001BD000001CD800001DE000B +:104D90000001EE800001FF0000007FF800007FF8B6 +:104DA0000000023E0000350010000000000028ADA9 +:104DB000000000000001000100350804CCCCCCC587 +:104DC000FFFFFFFFFFFFFFFF7058103C00000000D7 +:104DD000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3D +:104DE000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2D +:104DF000CCCC0201CCCCCCCCCCCC0201CCCCCCCC1D +:104E0000CCCC0201CCCCCCCCCCCC0201CCCCCCCC0C +:104E100000000000FFFFFFFF400000004000000016 +:104E20004000000040000000400000004000000082 +:104E30004000000040000000400000004000000072 +:104E40004000000040000000400000004000000062 +:104E50004000000040000000400000004000000052 +:104E60004000000040000000400000004000000042 +:104E70004000000040000000400000004000000032 +:104E80004000000040000000400000004000000022 +:104E90004000000040000000000E0232011600D663 +:104EA000001000000000000000720236012300F331 +:104EB00000100000000000000000FFFF00000000E4 +:104EC0000000FFFF000000000000FFFF00000000E6 +:104ED0000000FFFF000000000000FFFF00000000D6 +:104EE0000000FFFF000000000000FFFF00000000C6 +:104EF0000000FFFF000000000000FFFF00000000B6 +:104F00000000FFFF000000000000FFFF00000000A5 +:104F10000000FFFF000000000000FFFF0000000095 +:104F20000000FFFF000000000000FFFF0000000085 +:104F30000000FFFF000000000000FFFF0000000075 +:104F40000000FFFF000000000000FFFF0000000065 +:104F50000000FFFF000000000000FFFF0000000055 +:104F60000000FFFF000000000000FFFF0000000045 +:104F70000000FFFF000000000000FFFF0000000035 +:104F80000000FFFF000000000000FFFF0000000025 +:104F90000000FFFF000000000000FFFF0000000015 +:104FA0000000FFFF000000000000FFFF0000000005 +:104FB0000000FFFF000000000000FFFF00000000F5 +:104FC0000000FFFF000000000000FFFF00000000E5 +:104FD0000000FFFF000000000000FFFF00000000D5 +:104FE0000000FFFF000000000000FFFF00000000C5 +:104FF0000000FFFF000000000000FFFF00000000B5 +:105000000000FFFF000000000000FFFF00000000A4 +:105010000000FFFF000000000000FFFF0000000094 +:105020000000FFFF000000000000FFFF0000000084 +:105030000000FFFF000000000000FFFF0000000074 +:105040000000FFFF000000000000FFFF0000000064 +:105050000000FFFF000000000000FFFF0000000054 +:105060000000FFFF000000000000FFFF0000000044 +:105070000000FFFF000000000000FFFF0000000034 +:105080000000FFFF000000000000FFFF0000000024 +:105090000000FFFF000000000000FFFF0000000014 +:1050A0000000FFFF000000000000FFFF0000000004 +:1050B0000000FFFF00000000FFFFFFF3320FFFFFC3 +:1050C0000C30C30CC30C30C3CF3CF300F3CF3CF324 +:1050D0000000CF3CCDCDCDCDFFFFFFF130EFFFFF86 +:1050E0000C30C30CC30C30C3CF3CF300F3CF3CF304 +:1050F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFF0 +:105100000C30C30CC30C30C3CF3CF300F3CF3CF3E3 +:105110000002CF3CCDCDCDCDFFFFF4061CBFFFFF7D +:105120000C30C305C30C30C3CF300014F3CF3CF3B5 +:105130000004CF3CCDCDCDCDFFFFFFF2304FFFFFC0 +:105140000C30C30CC30C30C3CF3CF300F3CF3CF3A3 +:105150000008CF3CCDCDCDCDFFFFFFFA302FFFFFB4 +:105160000C30C30CC30C30C3CF3CF300F3CF3CF383 +:105170000010CF3CCDCDCDCDFFFFFFF731EFFFFFCE +:105180000C30C30CC30C30C3CF3CF300F3CF3CF363 +:105190000020CF3CCDCDCDCDFFFFFFF5302FFFFF61 +:1051A0000C30C30CC30C30C3CF3CF300F3CF3CF343 +:1051B0000040CF3CCDCDCDCDFFFFFFF3310FFFFF42 +:1051C0000C30C30CC30C30C3CF3CF300F3CF3CF323 +:1051D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF64 +:1051E0000C30C30CC30C30C3CF3CF300F3CF3CF303 +:1051F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEF +:105200000C30C30CC30C30C3CF3CF300F3CF3CF3E2 +:105210000002CF3CCDCDCDCDFFFFF4061CBFFFFF7C +:105220000C30C305C30C30C3CF300014F3CF3CF3B4 +:105230000004CF3CCDCDCDCDFFFFFFF2304FFFFFBF +:105240000C30C30CC30C30C3CF3CF300F3CF3CF3A2 +:105250000008CF3CCDCDCDCDFFFFFFFA302FFFFFB3 +:105260000C30C30CC30C30C3CF3CF300F3CF3CF382 +:105270000010CF3CCDCDCDCDFFFFFFF730EFFFFFCE +:105280000C30C30CC30C30C3CF3CF300F3CF3CF362 +:105290000020CF3CCDCDCDCDFFFFFFF5304FFFFF40 +:1052A0000C30C30CC30C30C3CF3CF300F3CF3CF342 +:1052B0000040CF3CCDCDCDCDFFFFFFF331EFFFFF61 +:1052C0000C30C30CC30C30C3CF3CF300F3CF3CF322 +:1052D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF63 +:1052E0000C30C30CC30C30C3CF3CF300F3CF3CF302 +:1052F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEE +:105300000C30C30CC30C30C3CF3CF300F3CF3CF3E1 +:105310000002CF3CCDCDCDCDFFFFF4061CBFFFFF7B +:105320000C30C305C30C30C3CF300014F3CF3CF3B3 +:105330000004CF3CCDCDCDCDFFFFFFF2304FFFFFBE +:105340000C30C30CC30C30C3CF3CF300F3CF3CF3A1 +:105350000008CF3CCDCDCDCDFFFFFFFA302FFFFFB2 +:105360000C30C30CC30C30C3CF3CF300F3CF3CF381 +:105370000010CF3CCDCDCDCDFFFFFF97056FFFFFD8 +:105380000C30C30CC30C30C3CF3CC000F3CF3CF394 +:105390000020CF3CCDCDCDCDFFFFFFF5310FFFFF7E +:1053A0000C30C30CC30C30C3CF3CF300F3CF3CF341 +:1053B0000040CF3CCDCDCDCDFFFFFFF3320FFFFF3F +:1053C0000C30C30CC30C30C3CF3CF300F3CF3CF321 +:1053D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF62 +:1053E0000C30C30CC30C30C3CF3CF300F3CF3CF301 +:1053F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFED +:105400000C30C30CC30C30C3CF3CF300F3CF3CF3E0 +:105410000002CF3CCDCDCDCDFFFFF4061CBFFFFF7A +:105420000C30C305C30C30C3CF300014F3CF3CF3B2 +:105430000004CF3CCDCDCDCDFFFFFFF2304FFFFFBD +:105440000C30C30CC30C30C3CF3CF300F3CF3CF3A0 +:105450000008CF3CCDCDCDCDFFFFFF8A042FFFFF4D +:105460000C30C30CC30C30C3CF3CC000F3CF3CF3B3 +:105470000010CF3CCDCDCDCDFFFFFF9705CFFFFF77 +:105480000C30C30CC30C30C3CF3CC000F3CF3CF393 +:105490000020CF3CCDCDCDCDFFFFFFF5310FFFFF7D +:1054A0000C30C30CC30C30C3CF3CF300F3CF3CF340 +:1054B0000040CF3CCDCDCDCDFFFFFFF3316FFFFFDF +:1054C0000C30C30CC30C30C3CF3CF300F3CF3CF320 +:1054D0000000CF3CCDCDCDCDFFFFFFF1302FFFFF42 +:1054E0000C30C30CC30C30C3CF3CF300F3CF3CF300 +:1054F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEC +:105500000C30C30CC30C30C3CF3CF300F3CF3CF3DF +:105510000002CF3CCDCDCDCDFFFFFFF630BFFFFF6A +:105520000C30C30CC30C30C3CF3CF314F3CF3CF3AB +:105530000004CF3CCDCDCDCDFFFFFFF2304FFFFFBC +:105540000C30C30CC30C30C3CF3CF300F3CF3CF39F +:105550000008CF3CCDCDCDCDFFFFFFFA302FFFFFB0 +:105560000C30C30CC30C30C3CF3CF300F3CF3CF37F +:105570000010CF3CCDCDCDCDFFFFFFF731CFFFFFEA +:105580000C30C30CC30C30C3CF3CF300F3CF3CF35F +:105590000020CF3CCDCDCDCDFFFFFFF0307FFFFF12 +:1055A0000C30C30CC30C30C3CF3CF300F3CF3CF33F +:1055B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF73 +:1055C0000C30C30CC30C30C3CF3CF3CCF3CF3CF353 +:1055D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF93 +:1055E0000C30C30CC30C30C3CF3CF3CCF3CF3CF333 +:1055F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF72 +:105600000C30C30CC30C30C3CF3CF3CCF3CF3CF312 +:105610000002CF3CCDCDCDCDFFFFFFFF30CFFFFF50 +:105620000C30C30CC30C30C3CF3CF3CCF3CF3CF3F2 +:105630000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2E +:105640000C30C30CC30C30C3CF3CF3CCF3CF3CF3D2 +:105650000008CF3CCDCDCDCDFFFFFFFF30CFFFFF0A +:105660000C30C30CC30C30C3CF3CF3CCF3CF3CF3B2 +:105670000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE2 +:105680000C30C30CC30C30C3CF3CF3CCF3CF3CF392 +:105690000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB2 +:1056A0000C30C30CC30C30C3CF3CF3CCF3CF3CF372 +:1056B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF72 +:1056C0000C30C30CC30C30C3CF3CF3CCF3CF3CF352 +:1056D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF92 +:1056E0000C30C30CC30C30C3CF3CF3CCF3CF3CF332 +:1056F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF71 +:105700000C30C30CC30C30C3CF3CF3CCF3CF3CF311 +:105710000002CF3CCDCDCDCDFFFFFFFF30CFFFFF4F +:105720000C30C30CC30C30C3CF3CF3CCF3CF3CF3F1 +:105730000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2D +:105740000C30C30CC30C30C3CF3CF3CCF3CF3CF3D1 +:105750000008CF3CCDCDCDCDFFFFFFFF30CFFFFF09 +:105760000C30C30CC30C30C3CF3CF3CCF3CF3CF3B1 +:105770000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE1 +:105780000C30C30CC30C30C3CF3CF3CCF3CF3CF391 +:105790000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB1 +:1057A0000C30C30CC30C30C3CF3CF3CCF3CF3CF371 +:1057B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF71 +:1057C0000C30C30CC30C30C3CF3CF3CCF3CF3CF351 +:1057D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF91 +:1057E0000C30C30CC30C30C3CF3CF3CCF3CF3CF331 +:1057F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF70 +:105800000C30C30CC30C30C3CF3CF3CCF3CF3CF310 +:105810000002CF3CCDCDCDCDFFFFFFFF30CFFFFF4E +:105820000C30C30CC30C30C3CF3CF3CCF3CF3CF3F0 +:105830000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2C +:105840000C30C30CC30C30C3CF3CF3CCF3CF3CF3D0 +:105850000008CF3CCDCDCDCDFFFFFFFF30CFFFFF08 +:105860000C30C30CC30C30C3CF3CF3CCF3CF3CF3B0 +:105870000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE0 +:105880000C30C30CC30C30C3CF3CF3CCF3CF3CF390 +:105890000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB0 +:1058A0000C30C30CC30C30C3CF3CF3CCF3CF3CF370 +:1058B0000040CF3CCDCDCDCD001000000007010051 +:1058C00000028170000B81980002025000010270FA +:1058D000000F028000010370000800000008008033 +:1058E00000028100000B8128000201E0000102009B +:1058F0000007021000020280000F0000000800F004 +:1059000000028170000B81980002025000010270B9 +:10591000000B82800008033800100000000801001E +:1059200000028180000B81A80002026000018280D9 +:10593000000E829800080380000B0000000100B0F8 +:10594000000280C0000580E8000201400001016003 +:10595000000E017000038250CCCCCCCCCCCCCCCC93 +:10596000CCCCCCCCCCCCCCCC00002000CCCCCCCC87 +:10597000CCCCCCCCCCCCCCCCCCCCCCCC0000200077 +:10598000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC57 +:1059900004002000000000001F8B08000000000031 +:1059A00000FFFB51CFC0F0038A277033309CE345E2 +:1059B000F0E981831829D35FC6CEC05001C4554099 +:1059C000BC0B883FB132307C66255EFF352904DB95 +:1059D000488281211E88D7883130A84922C41DA45D +:1059E00019182603F9A150B147403A5F8A32770F60 +:1059F000169CA68029E62A8760A7639147C6196886 +:105A0000F24BE550F99904F40F34BEA28ECAFFA2FE +:105A10000AA113A0E257D1E4BF42E53BA0FEBAA61B +:105A20008EDDDC4E32FD5DC302A101FC99B04798CA +:105A300003000000000000001F8B080000000000B1 +:105A400000FFED7D0B7854D5B5F03E731E3393798E +:105A5000E424E43181104E1E2068080384888AB74C +:105A6000271030F6D27678D5582D0EAF10F2866B0F +:105A70002DBDB67F06084978A8C11F11ADD5E12913 +:105A8000F6821D3122B6880328D2ABBD37587C552B +:105A9000EB1FD10B8A90442A6AEFB5E5EEB5F63ECE +:105AA000C99C9309047BDBAFFFFFFD7C9FEEECC735 +:105AB000D97BEDF5DA6BADFD18C93181A40D23E476 +:105AC00022FCFB0621929D1032A1379DE32021D7B5 +:105AD000184292662FFDDD921442DCBAE2BF49A360 +:105AE000A9BBFEE41A9A5F5FECF0AFA44D5B1F4DBB +:105AF000786A092DBFEFA12FC34FD07CFAEC79ADA6 +:105B0000C5B47ECE24C90F5D1D1AAB1002EDE7D8D7 +:105B1000C276015281E5979030A17F92AFE8F845B7 +:105B200084B8E89F2497FE37891CB2A5603EE4D173 +:105B3000A09E029946483631FE55607E36FC09F536 +:105B4000447767D0EF759E77E513EC7F8E5F0ADBB5 +:105B5000E94773F20372C84DD3C6086D49C71DFBF0 +:105B60005D3908F9C00C99E46387B6D8FE6FCA0F97 +:105B70004C7514D2FE670B08FFF9D94936DA82CC8E +:105B8000A6EDE13B224E1F1ACC679FD9E8B8DFE0B3 +:105B9000DFDDDF40FFA7C05F4B09A1E5CB1C0C9EFA +:105BA000E4D9D9C530CE8919D71643BF73A61332AD +:105BB00088564D9D3DF69044F3EB1A89DF4EDBCDC0 +:105BC000290D1CCF81D9F8CBA79302E8978EEE6000 +:105BD0007D5FC4FFEB38EF643EDE3FCC1E2B10FA36 +:105BE00041F6978AA95D72A0F953D14B486A052DF9 +:105BF0001F1953EE9F769AD0F2E4E9E6F64013724D +:105C00001D2125C49372EA1AFA7716C9BA2842AD43 +:105C10006A0B8CEEE50F6B4AFFFDF922D001FA12F8 +:105C2000FBD61F6A9CE9E9A0F85A377B9687D0F427 +:105C3000F5C02C0FE0EFF5D9B3108FD6F673666779 +:105C400027025EFB1BEFFE063AD008FA3DC7B3B54C +:105C50007E9048EA23F4FB393AD1C331FDDF01934A +:105C60004D256409301B4DB325D5A6D2FA6C8DE8BD +:105C70009138E39502B1693B92499928E352F30FB9 +:105C800061BB3726D94AC371E67307EFC7551AB807 +:105C9000670EA56FD674127551BA1229AAC6E2759D +:105CA0005D8A541A8E03C7DD1C5E42687BCFC0E15B +:105CB0007165D802D09F32470CC4C2F50380674299 +:105CC0006F4AA24CEEE6F818FD72BFFB6C508F33A2 +:105CD0008FBB008E0990AAEC3B0E8F0C7C9301B217 +:105CE0009682FC43C26324E0FBCC1EB9240107E585 +:105CF0008FA1F01715AE2DA47BD41214B256EC4729 +:105D0000F4A42403BD5711DE0F29514F517E1542D3 +:105D1000AB848BD75C6A9E123965F035F0A93B19CC +:105D2000C7BF1C5E48A018E55231D48878C007E38D +:105D30002BF94DED02A5CBBAD1E57E946F8A219067 +:105D400033437EE1DF57F43B37FFCCBD9CD291CA91 +:105D5000916B39D38F8ADF2C67EB928EB50820C800 +:105D600064B9490F1012244077036FEBBEA278BCD0 +:105D700004BF5BFBDD6FC8E7603298C927933F051E +:105D8000FA07BD79D37E07F0F53ADF5E07CC6B5D8D +:105D9000FE5E827A8AD3C7E8D795AF5D52CED681B0 +:105DA0007C8D80EEC348A79EF2D1A7C6027E76A660 +:105DB0002AF78B747E3B9308EAD9756B48782BD011 +:105DC000B594E5B56F69E1B5748E3B9DBCBE98D6C0 +:105DD000D3BC06EDA9BEDB3A490B87687E6B8B8D81 +:105DE000B51FAB85459A1F319184148A4F6DC5C28A +:105DF000954E5ABE75A3EA17B55EFD34A225672DF0 +:105E0000B4DFB2DEA60AF0BD8FAD233BF3493844C0 +:105E1000C7DFB139F99B23693E14B2F987D34FF23A +:105E2000F8FA45D9A5442802B4313A9C21795CAEF0 +:105E30000402E5A9BC7CCB7EFFBF8EA4F03D365D9D +:105E4000F2AFA0453BD6CF4CD0289E766881043F68 +:105E50004D7FF0C07CCCEFCC0C2600DD766E9C9F95 +:105E6000004CF1C0E6991B46417B61D2611DE96C93 +:105E7000D6FF471F283AEC00384B999E4F6A0D7E9B +:105E800053A2F9BC4912B9894E21CFAD21DCDB1FE9 +:105E9000B211584FFBE86D8BBE4ED4CD7957EBB4A1 +:105EA0008F817F5D0F160920DA3B3586E7413792F7 +:105EB000F08AECBEE3EF5CC8EA13295D800E2EBFCA +:105EC000625967965AF856477970713CB95A751CF1 +:105ED0008F487A8990D68B57FA9F4662F0E97AF01C +:105EE0002881F5E98AE76381275DA07C0F83AB9C5D +:105EF000EFB91E1CF7CA5763E3F1B121EF1EA07F73 +:105F000022C577612404EB507A61240AFCE2C95768 +:105F100034B00B9A0931C9C5A1D1FB7C1D203713C0 +:105F2000223E58AFD78D7E83C98F5681F830E66FF9 +:105F3000B4F7E4B79358FBC1A88772F8CE537869D9 +:105F400039BB87CB594F7F84AD4724731CC2754F33 +:105F5000E161755E1C7D4CC80A94CB9749E07A815B +:105F6000A6DECDED51A7066CAEDF0079B7400291F9 +:105F700038DF4D13D87AD242745DA0E9A3442F16BE +:105F8000709D4B66FAD7B22EF5D19FBC5D16E9160F +:105F900040DF68D43E803487F831CD23014C4792EE +:105FA000564CAF26114CF3493BA605A41B5343AFF7 +:105FB000F8892A427EC4C4FAC920E7A4DA638BE5D3 +:105FC000BBD06432B23ECE3C9A2D787390F8EBF899 +:105FD0001D025FE748A68AFC43F87AF16EB018E824 +:105FE000C55428FCBBDBCCEFE224BE0E38EA3D6989 +:105FF000805733DD8D5454CD7C5A6DF0A944241C58 +:10600000C7321FC463CCB8D6FE5673FBC6989F9C9C +:10601000A2231F496E66CF5038F4BD71F0D1280815 +:106020007C9E41ABDC3AB229BF4B49B6C85A9A6B49 +:10603000744F76E8382F3F894767EB7CACF02ABE77 +:1060400081C1B3A9079E0ACB3AFA97C2F34FA6FEC5 +:10605000A44CB21DD60BA28670DE56BCF6F9DE4209 +:106060008FFEE4D29169D6574A8AD70287859F0668 +:10607000687F7CE34BEA7FE4C3FA1B21412AECA949 +:10608000F90101E67FAD401A13295EC868A2EDA0B0 +:1060900070CDF56ACC8E8B693719F491660BC97493 +:1060A000BECF92EE23D03EE427911DF4B367F36D8B +:1060B000A55B697DAA9FB663FD05401EAE1D6D0BF5 +:1060C00040B9D19F4E9E32F547FD2E11F0E136E8E2 +:1060D00063F1C3E4B136B41F957CA26F89235FC717 +:1060E000B97C151D71EAB09EB8CA94B0331BFA8F03 +:1060F00014433EB59AF8615D9FD4CDE651C6E130B8 +:10610000E69DFA5940007E6AF7313BC05548D03FC2 +:106110005432DA74F01FDDB40EF5427E541753503A +:106120003FA23FD81F9E3D5F3DED0BD07E7DD4B991 +:106130006A07BE92FCE9A09F578F56C860FABDF867 +:106140003B3BF6FFB9A762188999CF470DD1B10B38 +:10615000A9C170A6E118A6671BDA31ED6C780BD3E4 +:10616000FEE94A598EDACEEB7EE2D7C01E100F3F11 +:1061700047340FC01DD5755C171CA212B32E808248 +:1061800006FF6FD3D8BCF0DA6CC46B08E64DD56758 +:10619000787836E05B0A009E873822C2D27C867708 +:1061A000C03FD001CA8B8E3CB702F15C4DC6029E47 +:1061B00037C9A40CF43CE013D6897D82ED0E800330 +:1061C000F2F369FEFA8FFAC1FB5986F78C97299E84 +:1061D000004E494B64C6AD8EF2953B910B12D7270A +:1061E000BD7A92F9D9BDF6BDF6EF00CF964689ACDF +:1061F00085BCA6684A11B7F7414A8215D3C1DFDCD6 +:10620000563EFD28D80BB9E25787645A3EB45E3A31 +:10621000D911234F596574FDA476C2B0E5E6F2ECBE +:1062200090394F07407F34B7C55C3EC4C6F5AE8792 +:1062300078401EADF35AB6E85771FDD3550D24EAE8 +:106240009663F202C3A79117BC133B42747ECB4600 +:10625000118C034CB7B1F5B315BEA37C712F4FD78A +:106260005BFA315269A2DB46C6303D196F7DBADD5B +:10627000563CCE46FB6BB04D1E67A372E4922204DF +:10628000EC77975BD1E3F993D36D128E9F20B5EB3A +:106290002285ABFB3AE2DF4AF1BE4CEE8E827C2CCB +:1062A0002BD6FC215047FE30CA6312D56162F61529 +:1062B000C153027050784A6C384E04FBE9A6380787 +:1062C000FB7D99CCFA5D364A236837F603E75536ED +:1062D00019E10CD80409FD344E97551539F74DA333 +:1062E000D94E559F05FD67260567C17846B96F7E73 +:1062F00029FA6319C3CCF42B77D467017F540622A3 +:10630000D3807F4E7B5F6C92E9BCB73610BF44F1FF +:10631000FF9E2B701BF457737BFD08B07FDF065E7A +:1063200098002A3B807AACA564A55FA2E572891427 +:1063300095293FCA130FBF2517401A2A86388B9319 +:10634000D4337D47F54B2235BD1C23F58F217EA22A +:10635000803CD072556F25600F38A8DB703286EF15 +:10636000944C731E6CFAD87C7F7AE3722998E727E5 +:106370008703FE09DAE9DD49CC7F9226FA0B00DEBD +:106380007BAFFFA606F0FCC46633F967567F4D5A13 +:10639000FE6F69791068E2FEB6B4FCD5B4BCF1803A +:1063A00097569C9763CA32940B05F02432F907BFC5 +:1063B000BE671DE478F85BCFDB582F5737BC35F844 +:1063C000C3E120A71D833FA4C4592D0591FF423E80 +:1063D000F0B5281C92998F09784F1362526E1718E6 +:1063E000F69B9C5A887494DCD2A98E98F5DDC08FF8 +:1063F000B2FCDDC11F8E87F46D4CAD7855A4200131 +:106400003FD068D713B718E0FAEF34E2A979C41F78 +:10641000A53873A4B0786A7A5E280AF37252FD092F +:10642000EBD33D235F6BC5F081C50F3B94AD203F9F +:10643000B48CB6615CB36578E49002F90C6A40D123 +:106440007A67CA5D21886D4CCD637CE3F4B3F5D4E3 +:10645000353C8C7E98A1BFBD1C1F5EAD1CF5B3679B +:10646000A2D9DE31D601272BA2F436DB51CE94A679 +:106470004FC582BE7E9A539B761AE569A4B93F2325 +:10648000DED16EE3F18B6BC9B5683759E212FDE1DD +:10649000CD6BF87113D9BCDCD34918FCE6F48951F3 +:1064A000C49BD7CFF066D89B1E3EBF9B4A2304FCFB +:1064B000BE9EF8F3CD0C6FEBAF8BA27FB77EEC29BD +:1064C000B467BD851D263FCEF81ECAA1FEFCC4766A +:1064D000A8A1F618CB1B71238AA7E91969BDEB6146 +:1064E0002BB7DBAD7453279262D0634747A7158360 +:1064F000DEBEB784C24EAB3C7A589762F0ADF27EF6 +:10650000D47C86DF7BCBD87C697BF4D3EF9D9893DA +:1065100004E366F2F8B0117FEEF1CBEBCD784F28B3 +:10652000B4C4852D7EB7EA67F4524BCCE5AB395F36 +:106530002B22A7572A19CEE835303E4F32F8BC84BB +:10654000F17932DF37482FD10E011D924A99FF4D64 +:106550002C7EF34D291D8C5E378FC8003FFCFEA9B1 +:10656000DD3E669730BA26717EBCEFC61102C87157 +:10657000728926407D723EC35332C513AC77C9A5DC +:10658000CCEFF64ED4B05D5209A35B0B7C4CE15FBF +:1065900003748A891F3B4B5B75A07F6BF14E1D74A2 +:1065A0005932C5E1200ACFD4520A1BD89DB45F806E +:1065B000D75318C5B85A524970D8A5FC7A42A2825E +:1065C000CD87F8106C684BE93C25587E6862B22094 +:1065D000D07EEFA77CC0F180713C178FA3DF5F787E +:1065E00012F5DCFDF04D36C8A9F6EB1C9A27A5364E +:1065F0003FF807F797E608F1E2E7C6BCFB83CB2A32 +:10660000C712F83531FC7295C8E3DE16FE5D4722ED +:106610006A2EC857486FF7A5F5EA0F83FF7AE4653D +:1066200012E3CBFEF489A187DD2418B265F7D51FEC +:1066300092CEF8DE9E174079EB03EF24C6AF528A64 +:10664000B9FC3691DB7F865ED19207142727A10023 +:10665000AE7722D74F4FDA020BC554F0BBC3B84E0A +:10666000B8C874AE37199FCA9CFFA6E633BDE24A8C +:1066700089B076978DA73A90DFD634A8A81F5AC65E +:10668000DED59E43F1B06678931FBE738C6B19B94B +:106690008DF6DB3C7C79702B0CC0FD30D4BF22AC76 +:1066A000838C5F8D7D30030E9219D2619FCC097E61 +:1066B00011E06724DB5F902412B58FEB1DDF954757 +:1066C000E1CD6769289FC10DFEC9EBB6E02A9C6F3A +:1066D0007E6B94A29BCE9BC9CB6A21425C22CCEB01 +:1066E000727C1EB231BE8E9FF6F75D02ECD3C4E120 +:1066F000DFDD22DBA7592D478850087E1BED89F28C +:10670000C9EA6C6A97C781A391F36BD52E67F8C36A +:10671000187EAB892499F275FB33C21FC6FA117734 +:106720000AB84F51CDD158433AB200CFEF291AF6EB +:10673000576BEB48837C17E94E5B027810038F8B15 +:1067400074FD7752BEC4B8907B60EBD6E5F0A781AC +:106750000CD18540CBE4A90F79988E17DC07E3694B +:106760002A2BBFD271E3F0F50BB17C4DC457596AA7 +:10677000E56B7F14F9DA9D12C57AB79FF1B5C18F29 +:10678000899C1FAD7C688CBF9EC7AFD6723E5F33BD +:10679000A1498570DFDA519B309EE62CDA5C017CE2 +:1067A000DE32AA250C7CDE64F035DF17A1FE2EDB7D +:1067B0001FD35AA3B04E2672BE56D4EE06907BEB82 +:1067C0007C5D9338BC3405BE06B8395FBF07F893CB +:1067D000FDDD08AEC1D76B07CCD7BA456F9BD3FEA2 +:1067E000FC27D9C2D71E89F1E767C0D7004F0AB38B +:1067F00063DC3E96CA7EEADFC7E9E70689F9996B52 +:10680000B91CACE572B0B61F39F83F22F303FE9A0B +:1068100072308BC98143A2E58993AE8C1F25B0D31A +:10682000E3C87B9E24FCB5E1DE3443BC723CFE270A +:1068300030CD84BEF434D2CF44E7C0E43B8FC9737B +:106840007F72BE76687C38FE5364F4A7F82E9226D9 +:106850005C39BEFF5A7015727E36F04382C528B788 +:10686000317A663AC02BA9869E7904D3A979AD28DE +:10687000A786BE81580AFA2B6A2BC63B9C99AD6845 +:106880009F39F398BE31FC24EB7C8DB87813D73355 +:1068900049792102EB9F3D85703FAA9EF95199CC21 +:1068A0001F30E2D586FDA8187ED4D0BB709FA77993 +:1068B000783DDA97CD37D63BE2EDC336FBEE77F085 +:1068C0004D5FD33EEB1A5A0EFDAEC9BB9FC4B3C396 +:1068D0008C7918FB464E3E6E731EB5A8605CDF32A5 +:1068E000FCDE6AC73467B2FE7ABEE77A57EED1BBE8 +:1068F0002C8F76546E8C9F6FE9C7E00385E843A325 +:10690000103718E41E09E74C9A84043FD8C74D920B +:10691000209D72901E7BA95A891640FF2766BC9C59 +:1069200085F6B23DB806E4BCE9AB8003E2A9AB53FF +:106930005EF3C6969F9DF1E6B7C16CA5DFD5E27EFA +:106940008E8348B1FB6327DCDBD17E4BC837C7E9B8 +:106950009C14AE0902C413CCE50A8FBF2899E672D5 +:1069600099C75FA4144B39E70FB934BE5E7993EB36 +:1069700015DF02764EE7C41C16D73B712B4F6730EC +:10698000FE3EC7DB75F334C2F5EE5F531F25E5F617 +:10699000C2EF9BE2C7F822996547BB3E2B859D2B32 +:1069A00020B1E726E05F6BA24462FCCCA18197FF97 +:1069B00008F1D4610BBECA063C6B15EA615846DB90 +:1069C000A56C9CC76342F72818CFE63A8BFBF5020B +:1069D00045E3726A120BF4DBDB2185EFBDC0523A4E +:1069E0008F7B0591BFECC03722D0298CA98B44B195 +:1069F000DE433A309F081BE6B9E08751BF4BC433F2 +:106A00004C611BC68D7ECCF643D688786E83A80376 +:106A1000B4BFC9ED2AF89742887EE71AF877BE40DE +:106A20006B31C8C4E0B208C693ADED7C53D839A031 +:106A30003E7AFBAF4FDF375273818F542C37E81CFF +:106A400014F54E6942DFF25F8981F312C6AB58DC60 +:106A5000CD5A5F2AE91740DEACE5C20B7F3A057ECE +:106A6000F4AA6764F4A3A73C2347BF41F3355B0452 +:106A7000F4536D079DE80F773EC2F2518FA243FB9E +:106A800073DB058C07D5D9DBEFBD01E28ACF880423 +:106A9000FD8D7019EE8B9DE27326FB59BE9C07801D +:106AA0006AB61C9A0BDF57ECB713D877A8796EF14A +:106AB000B76FA0F9C5C764F4516A76AC50607F65C2 +:106AC00049588840BE6B32C1F143FBC4F00EDABEB8 +:106AD000CBDB9E36C70DFB2B0EA25D45E1F6B4A7BE +:106AE000CDA6F4A90C3F350DBEABDC2DF8C1FF9847 +:106AF000F2CC8EA319F4BB9A27043CA750B5CB4522 +:106B0000B418BA9C6A13A3DF80F8339D27F8C58BAD +:106B100049EB34C07BCD8E0D8A1613B73CD330922F +:106B200068F6DE7CCD13741CFA5DED93821FA658C7 +:106B30006B2341E08FCEE79C65DBDC30BF15CA08D4 +:106B40000FCCAB5981768BC3F3F6C17E7A65788B17 +:106B5000328DD6573EB245298FE1A7AA5DD7102DB9 +:106B6000863F4E6DCE4DBFD47A7B86AE5BB1F0547E +:106B700012A6B788145666C4EC7B76C8499C3F457C +:106B800053FF06DF875E2718C70A3DEF41BC1A7422 +:106B90005BA632BD60D0EDBCCAE9287517CD88B3BD +:106BA000AF7A2FD0C10EF12A15D3FB1B7C986E6CE7 +:106BB000D0903E9B007F57E1BE06967B279162886E +:106BC0008B7875A2C2529F3C5D2F96214E1260F9C0 +:106BD000B4DB83827689F91BE92639380F825CB7EA +:106BE000C94F4C96E8BABE49092E257E3ABEB47705 +:106BF00072C97560A705E7C8A9B09F1DAC60F1E830 +:106C0000880FE4A289EFCB7C4B66F2D694A1607C1E +:106C100064D3F78BB6A1ED41185E367DBF7C27ECBF +:106C2000ABD17EE6CA54AE1A65DA4FEEE5FB499B5E +:106C30003BD1D44FDADC0AA39FC5D88F7360FD6CBB +:106C40009A7BBD199EB995463FF5D88F6760F34A88 +:106C5000BB6392199E3BAAB19FF4DBFD681F8806B7 +:106C6000FF9076DC1775EF4E1AB796C4F2D1E41F89 +:106C7000C3781E2A55B17C943831C1244F497AB269 +:106C8000293FA874B0A97D6A20C7549F5E76B58558 +:106C90002FDDA8BF314F818A26B138AB325841BDB4 +:106CA000533CD881F9BB06BB51EFDC757DF02AB0AF +:106CB000F70056D0F37729C1316A1CBEA1F3120840 +:106CC000C6CF341BA47DEC32BEEF3979C85723DE22 +:106CD000A7DFD7D9BA4724D1FC434AF12330EFAD1F +:106CE00032B3E38D3843829DA0FE6BCE2EDA168A36 +:106CF000C16BCB50CA2F426FBF2D72D007FCB87347 +:106D0000F56F574A14BEA6A10A1E6E7A5CFEEDE12D +:106D100010B5999B8796FB00FF7685EA8FD8F11511 +:106D20003A7E3E8EBF1BC6DF2B333BD93ABE3D6752 +:106D3000A2697C475685697C8742C7A7F2B16FF587 +:106D40003B7C7C8ABFEB0979567E07C7B76755E065 +:106D5000F8CD0AA9308D9FD033FE01909FC3FDCDA1 +:106D60003FE77AF3FCB32ACDF357D8FC8FAEFE8011 +:106D70008F9F80F37F59FE80CD3FAB92CDDFCEFA5F +:106D8000ED19DFDB83FF5761FEAFF537FFDC49E626 +:106D9000F90FAB36CFDFCEC67F63F5277C7C378E0D +:106DA000FFA6FC099BFFB06A1C5FB107FDC047CA84 +:106DB00090847AF09FA961A461405DA3E3403A9278 +:106DC000C5A937C83908C75D098CEF3E4FA0FCE65E +:106DD000EED5A7244C2590EACB5ACED355BB8B15C4 +:106DE000E62F84D05F58C4415DB85FC4F58C6CB4A5 +:106DF000878753783BF78B21C82FDC78239E5BACC9 +:106E0000B313DC77A75630FA1FFFF1C0E8ADB1F33A +:106E1000B2A68B5A65CBFE1383C738EF5424ABA6BA +:106E2000FC2988A7503D7C12FC1F9A9E96E978B4F5 +:106E3000FC43F083AE8A951B762E8C7677229FCE0C +:106E4000EBBB1CFE5312C3F7A93B05DC47F87CC320 +:106E50005205F4D9A25697C96FA8E374EA7ECE8E84 +:106E6000FB8DC679BE5B501409F9FDC16F1D05BBD2 +:106E700071F1E641A6EF6E27E1D5701473C1FA797E +:106E800043553AFFDBCAECE3448C6BEB43581C9C44 +:106E90000C81B84959DB067908CDDC52269BECF908 +:106EA0005B83E6FC6D15E67CA71C966D60CF2C110C +:106EB000C816DAEFF7EB65CBB900368E5749E676A0 +:106EC000251BEFBB948619B4E8FB908E836215E90D +:106ED0003A5765DF1AF0D4DD2D9328AEC71DA9B847 +:106EE0000F144A45BF2DA8B2795BE19D2B3BF400FE +:106EF0008567EE8F44C4A715FE8E832EDD46EDF325 +:106F00008ECD7F90217E6C9D8F15FE3B965BE7A317 +:106F10002AB03ECC0B59CB199F58F9A96E7FF13698 +:106F2000B33D7BF3B658FBB56AD70C537E49F85690 +:106F300053FBC59BE799EA17B52E31D52F68596ADF +:106F4000CACF0BFDC8D4FE8EE52B4CF5DFAF5F63D7 +:106F5000AABFAD6283297F6BF02153FB5BCAB69851 +:106F6000EA6D07477D07E468D5EB229EFDBDE03E54 +:106F7000752FD89B17DC12EE737E44ED159083338A +:106F8000D45E81B473FF78F4A7A91E2C874DA2F9B3 +:106F9000CA98552D99A09709EACF7265C2AAD02444 +:106FA0008A17B0D7A97C889B15121D04CE4C720F8E +:106FB0001F778B31F51D97A9DF4C057D7CDF7AB1FA +:106FC000237E79DDD679C3D4387E6AAFDC9221B0D6 +:106FD000CE7559CE9F1869B5E53CA7B1BF7D81EB51 +:106FE000D96A85E983EABD1993617386FAE523E2DC +:106FF0009D9BECF93E22B00D48B0FE53811F869850 +:10700000F66BAA76E59AE4FBEC2111E1AA059D4016 +:10701000F5EA1752608D0272163D92356B34C0A1AD +:10702000AF5540EFEC4FC575FD6C43E936D8AF3F27 +:10703000D310C0F4A386324C4F350431FDB0A10209 +:10704000D3930DF59876342CC7F4BD8610A6EF3691 +:10705000B460FABB86564CDF6AD88CE91B0D614CD4 +:107060003B1B744C0D79E8D1BF016E0F1B1BD784FD +:10707000DBC37C2E8DA93DE7C270FFF7BCFBF3118B +:1070800060EF9F7FCB8EFB6CFDE1CBCA6FFDD351D0 +:10709000477BA53C3C089D636BBD3381D1C9692307 +:1070A000A5641CECFFECF4CFCFC7BCC42EF584FD67 +:1070B000333C71FA85785DFAE5E944F4EE829994FF +:1070C0001EA71EFEAF22E8F702AC7F60071C1171FD +:1070D0001D26D16D7EA0D795E24D78E1F759102F8E +:1070E0003BD783BFF62C888B5DABA8D8FFF9363B26 +:1070F00081F8D2F9032EBCCF75FED8362FC8E33203 +:107100009F188E3D47614D6B22D961B7C9EF36E7B5 +:10711000CFB70AA5781E9A6889B347035FA961387B +:107120000FD2D9E0C3D4E867994FC171CEECCA65DC +:1071300071337E5E83EC4E427EA57E27B6FF9F862E +:10714000A7BF7E0C780869231F38085E71BB98DBE7 +:107150007FFB7EF949FA4C81F82A39207F0EF682AE +:107160009DFE77111C652261DEE8B72E2286EC6356 +:10717000A07CB7693CFA9D66F8F417732EC5B7E694 +:10718000FB34220468BF469CA40AFE80F330F5025B +:10719000C6AB8C784997E46E11C6F4C64BEA78BC4E +:1071A000B8C6D1A10469D1B9B6DC4BEE9F9E69384F +:1071B000A6C239AF0A47AB02CE4F45645409E8B9BD +:1071C000736DABD2C01EAC12CFDF152F7E9B6767ED +:1071D00071BD2561B9DBBC8E72FE20B45FA39C1D1E +:1071E00072749F8AC99FB5313BDBDAEF04FBC0F6AE +:1071F0002D6A771F9F7683D6174FB5FB3F55303EDC +:107200002E11535CC9C0DF7B4A60829DE2A972D710 +:10721000FB688F7E248746DC7D09FDD4777E6E9FD8 +:10722000E97C7288B4C338F327F2818876CB3B744B +:107230003DFDF815999DDBE4E7807BF695F9BEFEF0 +:10724000029E9BDF5685E7843EDEF78F68FF2D2484 +:10725000012FD281B416811D798ED84A014FE7C81B +:107260006BDEF13174B8953A4A40EF052D663B86E6 +:10727000DABFA6FCE2CDE67C39999906FAA47CA394 +:107280004CC202CECF547FB35DC57E1793FA265809 +:107290005725EE8FCC57893484EAD59A677F5634C8 +:1072A0008FC211B4333FC888BF2C49667660654AE7 +:1072B00058817DC20FDAC67FF70620833DDC04715A +:1072C000289248FC3B485FFC5E29FC56788DF5BA55 +:1072D0004F1C88C321EE12E2EE03D6DA056ECF868C +:1072E000303DC0E76DF805C72CF915767EDE5224D7 +:1072F00022D0FD9CEA08D912B1DE1F8578DC5EBB86 +:107300007F950671FCC06A7B6A6FDCDF6897640F4B +:1073100062F959E1D5723CF720450BF0DE218FEF81 +:107320002B9C1FC4046F019C23F540DC1ECE753AD4 +:10733000BD5B21DFE4A9C0F31F7520EFB4BF7BBCA8 +:10734000D38E419CDA415AA33AE55FBBCFB21FA06E +:1073500099F32E904BD0675080E7A209C6B95C2301 +:10736000CDED3C7E73FE312E8F7481433EEE39DFCE +:10737000E67047E13C0999289DEDF1B772C0DF63E3 +:10738000F0C3FD56687FA7CADAD7F27DDD3BDF9EEA +:107390009C9E7C097D54F7A540C231EB489DD4AD3D +:1073A000001FD67D2961F9D7D69B1A5D5563F4E697 +:1073B0002B4AF059FB04A627013E818E13BBDF64E4 +:1073C000BD877002F861422F3F7C6D385288497F3B +:1073D000BFA7048FC583E36BF7EFEBD3FF09E0BBD7 +:1073E000FFB1FEF3FAF4DF110FFE9A67F7EC0BD151 +:1073F000F5B5F2170F78E110D3C7526B1A9CEFACBA +:10740000DEB1DA0B72F99114F2025D3F0E8B71EF6F +:10741000E7A63B0CBED3DD708FB096F3DD999FAF2E +:10742000FB36F82F9FEF90558C0FECB247ED942967 +:107430006BDB9630F9D8657F9FE59BF1BC53DD7E11 +:10744000B3BEA87CFC81340D0F5585B8FF1C45FFE9 +:10745000A076FB7F4C03BBAB8E74A3DEB37E07E349 +:107460007F998CF6C03C25B16FBD710EAB8EE3A544 +:10747000AE6D1DDE13AF6BBBF934139A0EF43BAD4A +:10748000DF5570BBDFE1309FDF34F042C2CCEE5FEE +:10749000F5C48305EF53B8CE6E7FC52BE4C7F22940 +:1074A000D37FE7230B1EFBA5D6BF5C7552FD186B7F +:1074B0005F1BEBB4B69FFB2B07585A2D47BDE00F5F +:1074C000566F91F1BC7BF59E6D3B1F86F8CCDB7649 +:1074D000FF70DA7FD59E97DEB89EE6AB9E9253A6EC +:1074E000B369B8E19EA2419F3AFADFF271BDF4A8F8 +:1074F0007CFA25451BCDCA7F9CDC4B97AAA70E2999 +:1075000064745F7C4C891C52D87EB6853E91F7A787 +:10751000815FB1EA892F14D05F1F1F14487A761C4F +:107520007C6E7909ED63C013D293D3AB877E96F658 +:1075300075942EA8172DF4B2B6FB98AF07D02FC4C0 +:10754000E3297F3FF94BD8B7F99DDD0F78A878F292 +:107550009FBC309FD3523DE3F39FAD4E83FB20157C +:1075600072284DC59495573CFA03E4BFC5C77F9078 +:10757000C6CEC5EA19FC5C5706CC73D12373709E46 +:10758000E524887C58F13376CFFC82444A9F8A23D5 +:1075900027F739D83A767AAB1D37114FC34202FB31 +:1075A00018AF89E11D180F64E70D7F60EC3F91650E +:1075B00098BFE060F45AE430EEF1D1A524967FB78D +:1075C00037B7039DCE0CD5D3218E5C47A410C78757 +:1075D0007091F62B1E9F9ACECF1D685211FF8EEA36 +:1075E000FF29500EEDDB65DD5960FA8E5CCCEE1D97 +:1075F000FF4E3E3E853B01ECD7D369D41E8C33BF92 +:10760000030E639DA676560C9FC5C83B93FFED6B9A +:1076100098BC1BF21F9E510AF59F9D607204DF818A +:10762000FD42E18AA663FDA1D902EA073B89C69320 +:10763000F3ED32977373BD955F28FC12ACC73D7CA8 +:1076400003E324231DD0BE2DDF48BF8FD5AB30AE62 +:10765000B76FBF861C2FE6FA60AD451F90475207F3 +:10766000B47F5B2D87773E0CF24BE535A481FCCAD5 +:10767000F85EC127BB8FBCF13D2AB79F440CB935DA +:10768000EB55ABDC56EC9D40E2C9ED276E3F892BF4 +:10769000B7B43CAEDCBA3B909FFFD67AD5C0E3D3FB +:1076A000163C1A7AB23F7C5AF5E4B71D5A5C3D4944 +:1076B000FF9D20457DF9D1E04383FF2AFFA506CF3A +:1076C0000BF5F0A9C1873D7C6AF0619F78A4098F12 +:1076D000D6FABBE16F3A85C07332C6CFAB0FB0FDAF +:1076E00067FADDD12185882F1D9739D27A74484AEF +:1076F0006C3E6CC9472CED754B3E60691FB4E4EBE2 +:107700004DEDABF71F51D8B99EA8A99DB8FCA7E4D1 +:107710008338F101631DAA6BFB5409017FB8BBF1EB +:107720007B79250979205EFEBC88F1F22E8AE3265A +:107730003A4ED7EE6C7C8F60B593C557BAD46E2F96 +:10774000D893AB9358BE3B5569023D6894773B593B +:10775000DCAF2BD0ED4D8AB1EFDE3F20A21EEF084B +:1077600093D2787E28DE40A1F8ED20FDD5B3FD80D0 +:107770002EB0D761BC84AC30F0E354D19DB51CE28F +:1077800035AD22DE6B5BB8E2162F9C23E93A90FB05 +:107790009D325ABEE8D722DBA60CE952468C1FF870 +:1077A00011096D9A24C0FEF57AE49F0507985FB829 +:1077B000707D7C79A8E4DF95BBEF5440EF527FEEFB +:1077C00064ECBE87D14FC52396F203FFC8E5A6152A +:1077D000E31F95DBCDF5411E3F18ECE4E7BEC792F1 +:1077E000B1DC7FB7C5DE0F9E2AE67FA78CD2A7EB60 +:1077F0009848E03CC1F90322D2E7FC6E767E00E3B4 +:10780000FCD701BF772BB1E7A9CE827C5DD5BF1E27 +:107810003BFBCCEF8BEE063EDAF74EC14F697A7632 +:10782000DFDB237E05F967DFCC7A87F46D3FE5A0C7 +:1078300013F755BA0E7A90FFBB9EFF4DD6DD907FB1 +:10784000CE8EF1ECAE835F14003F75ADB457801E51 +:10785000ECE2E7EF563DFF454107AEBF8D48C7A9B3 +:107860004EE64F9F3FF05FEFC1FD81F307E8ACC0EC +:10787000BE38E842F9AAFBA513E36F5DCF7F511430 +:10788000EB27FCA5F3A9E5FB9D5D1E52B617E04B67 +:1078900062FB4475BFBA6E1BBC2F51D3764859406A +:1078A000EBA7BCF0A702D0AF5D7B99DDD429773C74 +:1078B0000AFB7981350F34CA945E9D20648369FF89 +:1078C0006BDE280139EA8B973F615C71A0F858FCA8 +:1078D0007F0D3E049DE93F4F184C852907FFF8DED8 +:1078E0003BA0270EDA912F8DF97E125981F6CCE557 +:1078F000E6DDF4FFDCBC85E840E6BD03E63DE1EFF4 +:1079000077DED7C0A1A1D4BE72D097CF9FBF0BF3B3 +:107910007B3C7E847780FCFED2DFF9FCAF98EE7B67 +:1079200029DDBD979FF7877FE7F3EE9FEEBF9ECBE4 +:10793000E9AEC27998BA17FE84F05DA99E9312FE53 +:10794000BEE5BDBFF91BF6FE5A9BBF35271BCF9383 +:107950003AC0B0707B66B6407871EDC8992AD89D60 +:10796000623FEFD54C48607E9528B0F721C850168D +:107970000F24DCCF82630DF80E889BDD3B93DC4D3A +:10798000687713C9DFAE53BCACBD7ABE1FCF1A9166 +:10799000716F05219F39C98FF16E8BBFD928105D9A +:1079A000A0F6AE74F5378F81DF238FB445ED0598CF +:1079B000BE0F69338F63CAAA62F287DCF9E6BC5353 +:1079C00033E7EDBC3F0761F03B7C240CF16C71D4D4 +:1079D0006115CED3896325024FA538496B08FC0E8B +:1079E000BBCFFC7D5202E17EEF5F86C78A0416A7FB +:1079F000128571ED3AE071940DE3DC78481BF1E2F9 +:107A0000C7F7BA08F7AF7BF1DAD40EF894C03F6637 +:107A1000F617FAD584FBD312EF421A69D39DE676A6 +:107A2000DC8FBE2C9D185DB2AA399D9699E862D074 +:107A3000210E7D4C7431F07CA5F4B1D2C58AFFEBE8 +:107A400013185FF7472F832E996E1DEFD7C9DC7F80 +:107A500028013F13F2990182FBABDC7F905274BC8A +:107A6000A724AA7EBC97007E5C941AE02FEFDE86E6 +:107A7000F1A4733F7FFFDB004FD5AF44E2A0F8EBEA +:107A8000DCED2151F85E0A2BE09F56B689B84F40D5 +:107A9000A468D1AC987D62C30FA8FA8507E753B9F3 +:107AA000D71E9E4EBFAFDCF74101DA612BBBD1CFB1 +:107AB00009FD5C60740F7514C03E70A5C4FC112BE9 +:107AC000BFAC4960F196B3CFB9CA20AE23EC62E7F0 +:107AD0007F2B23B7C8F698734DA10499C59B9E735D +:107AE000A15E083D21E0F928802FF6DCA9E1879C02 +:107AF0007D4260F0ED97F19D98CA5D4F75427CAA7A +:107B0000F22DBB1FCCF8BA5D9FE27EC8945FECF10A +:107B100076A01F2E9AE2127DE201BB44E48FDAB612 +:107B20001AF443681EF9A236C2FDEF2BF457AB7E60 +:107B3000F1FC3EB87056F5F4E35E887F9D69DFE1A5 +:107B4000C5B8C0AE4BC7E7FAF8FF9135DCFFFFD6EA +:107B500069764F3BBEFF7F06FEA076F1D30996FB08 +:107B6000ABBB06B1F71449B4E852EF7155EDB9F06B +:107B700028C4AFCFEEFDE45180BBFACF7F7814FC70 +:107B80000A72D0A9C27D82BA9FBF8EF13EE3BBDFED +:107B9000703DD0F9C4E3182FED7C9BFA1FF45FE72A +:107BA000F3A7B3C0CFEC7CEA8F69104FB9F3F9A902 +:107BB000F86ECE9DCF4C492771F4899102FF86075C +:107BC00010AFB5D2ED48DB11F47FCE51BA83FFD9A7 +:107BD00013D789D4B07899C6E339BBE3C7C7FBC4D0 +:107BE0006FDA667DE7C6424865BF460610C7394171 +:107BF000E939660074DCCDE375916F5D328E730EEA +:107C0000FEA0F43A6BA1E385B6458F3D0C756D83FC +:107C1000FA8DE34407803F23FEBE3F41FF2201E48B +:107C200068EFBF60FC0CE8379D4EB873CF852CD849 +:107C3000BFF848EE9E8BEF853C6F57211E51F9FC33 +:107C40009B284F9DCF1CC7F836E171F04ED2F38FC1 +:107C5000C52BF999CCBAED1E16FFE17480F890E6B9 +:107C6000C5721E07627C6DC487FA8B0B8D71B17370 +:107C700027C6BE40CDF67778BCA5976EC244A0D784 +:107C8000FB97DCCF30F0A0021EAE8D8D7BC68FC37C +:107C9000F5C43D2D74037A42BCB327AE49D8137B9B +:107CA0007561E1CD7871F4CE2D2C5EDA29C73F8F56 +:107CB00065C441AF7659E29FE181C53F2F378F2BD5 +:107CC000C5D3609786FD5AF175F6ABF8FAFD5BAE49 +:107CD000819D5FE8777FADDA7C1FE63D2538DD05C5 +:107CE000FB6B6DEF2B04CFA774B3732B7CBE67F9CE +:107CF000F9D3B33F17312ED6143982FADDAA3F8C5F +:107D0000FD572BBC7770786BF7B3F5E3EC5E4FD87B +:107D10004DFB397BF839E4EBDADDEF635CEEE8AE7E +:107D2000A7958E98F516D68F70CC7CCE3E79A8801C +:107D3000C579E3DF1BAB71317BB3EE40FC71EA76B2 +:107D40007F6A1AA72A1451981D70E9F1CE48FA2DBE +:107D5000D0DF997619DF4D3A1311E3BE171C70C9B5 +:107D60007C1FA195C90F5D47F19EC071767FA7F07A +:107D7000B5043C577FE7F1D277E0FDB73BA95883C4 +:107D8000DDDFB682F169DB4FF42140EFB6E3DF13AC +:107D900061FDDA07F88DB1FF8B4ED44FF150FD50E5 +:107DA000F46EA010D8D5AA77AE7DCB66829F8E9355 +:107DB0000EEB4223ED07EE83C0B939BC57EE9D565A +:107DC0000AF088AA4D750A7DE721BBF97D55DEAF23 +:107DD000AC9AEF2190AFC66BD08F6F268B4B66CCE1 +:107DE0003252169F0C19F787CA13C2ABE87C7FAFDB +:107DF0000637BB285E7C9E8DD92F1178276AA20694 +:107E0000F6D3632E7EDEC14BBCECBC833B64A37A0D +:107E1000FD61FFF60D93089E67D8067CD9739E819D +:107E2000440B802F8D767DEA2DE71D32E1132A5A0F +:107E300022873317EE2550FDB26A86772BE41FF1B7 +:107E4000B0F7CDB248F72138DFB08DDBA3D960158C +:107E5000E7F67DE7ECEBBE6F9632A578E9303F851B +:107E6000D3F55F53E15C7CCA2DC54F0D5169852D5B +:107E7000631ADCA34979BC786C06CDCF5FFFF4347C +:107E8000ACFFF7E2B15934FF937B0EB2FA2A01CF6F +:107E9000C1BEB0AE761AF0EFD796FBD9143366B9EF +:107EA0007F05F0772EF0EE77176970AEA25BE1EFF9 +:107EB0006504A0DDD0890C7F99EE779F027F6598DD +:107EC000AD6305F0EB63CF7F9184F716F9FBA12A30 +:107ED0006954E1DC152D9A78F112E7F3FABCFBCC7A +:107EE000F5CB8D49C177813F9AE78DBC6F1A1DEFA5 +:107EF000E18A710E760ED0F24EA39A82745DC8E9C3 +:107F00004AF83DCB457C3E8BC590C202DFAD5C7F1D +:107F100019EF51578B57F41E3587ABDBD5EFFB6755 +:107F20007F00783393827F00FC59DF3F7BC515B813 +:107F300000F519E55FE27D5CE33D33EBBB6844EAA5 +:107F40008EFB3EFB56FE2E5A7FF0FE9B3B28BA6905 +:107F5000FF392F687B8F51391BB350F1C3D1CF311B +:107F6000CB0BFDD220C226047610A71F3CCF88F78A +:107F70001FEE22B85FDB651774F0AFBBFE49457D8D +:107F80009EB9703AFA5F5DAEEC089C33EABA5BC307 +:107F90007D3D8A0101E469E881C428F887541E3ECA +:107FA000B7C8C3E766FE378FDB7551DBDF81FDA9FC +:107FB000BC3F6AA0C5DC8BED12999EEE6AD0108E94 +:107FC000A1247408D6FD818E97E3E6EB37A7CF4650 +:107FD0009B9EEB9E80F81FEE8EC1FF2877BF74CC6E +:107FE00077333AE6BBE3D0D1FA6EDD7BAEE058687A +:107FF00077BAFC28BE5F677DAFCE4ADF3AA9F5218C +:10800000783B2BEDC0A7B8FE18F41BB37C2CD2290B +:10801000869E93008E31073EB501BC061D1FECE71E +:108020003C79A99BAD73D6F1D2CA3A0607E3B49F57 +:10803000E5D64CF70E0A1C457E89CA69BA8DC587FC +:10804000FAB6EFB7FF9C4B9DF32C5059BF14FF734A +:10805000004F06FE6F75F3FBEA7DF17F3BB4A3F89A +:10806000BF1DE63F00FCCFBB14FE0DFBBF8AEB87B4 +:108070002AD89FA27CF41FDACCB41C3AEE34D18DFE +:1080800072B06487C8F731D9FB5F863E59725DFDD7 +:1080900021B817B9E46702F2EB42FEFEE527FCFDCA +:1080A0004BEBB9C1F2B210EACBCB9F1F0CA33EAA97 +:1080B000DA652EFF6777CFBB975978DE172435AD89 +:1080C000F7BD4E2BFECFBBB9DE58E8B4C57B2FD72A +:1080D0004887D6DB4CE7CC33A6F4F483FEA0CFA6CA +:1080E000BD89F1B87F9509C4137429A510DE192044 +:1080F000854209F45BCCE5D7E86FD872F3FA9F1D8F +:1081000032DF43CC6D31DF431CDE6ABE8778D56633 +:10811000F33DC45161F33DC46B768D33E54747AE03 +:1081200037B51FB37FB2293F36FA4D53FBF1C7660F +:108130009AF213DABF676A7FED5BF34DF5D775549A +:108140009AEA6FF86899297F63F73F9BDA471731FE +:10815000FD78B8617911DC5B30F07278A96253A1C7 +:108160007CE9089B5A105B9EA66B059016E9E07FA0 +:10817000F5272F531C3F2A8A5DA78B896CD26F533A +:108180001CE67CD46DFE7D8F972C7235A47E52CB7D +:10819000089A1DBC240FCF6353F93AC6F5DBB10131 +:1081A000EAB7DFA07CD5469B206F952FE3BD019AEF +:1081B00086D88FADB0779F1F729AF9D4D78F5EF9AA +:1081C0009DDB3807D4CAFA53CBC64B263931CA3F98 +:1081D0002A8C2D17164FC77340FDF5ABF8165CB30C +:1081E0007D10BC3B3C0F53A3BCA9CC16F7DCDF676A +:1081F000EEBFD07FDADCC78EFA0CF07CCEF7DA2641 +:1082000038BF567B7B37FA511976335E7AF3EC5DD3 +:1082100063039E471A483EACF7C6FDB64534E1EB12 +:1082200036CE77D1DB33D3E09C41663FFE55A18744 +:10823000E9EB471B42D72C04C21187E95E7956B49B +:108240006E1AF839C3F879EB4DB6F8E7A0923C0CFA +:108250002FE9A048C15E50DD682F9C2B7FD70B4FC4 +:10826000C7DC680F2679E838F3C7B417B1FBD4BA76 +:108270007FE6E85EB80D7D94E50E6C02FD92E59315 +:108280008896DD179EF4DB832DF08E7863B2CDEFF8 +:10829000C67CB700E3D97F4CC8203A5EE39F458493 +:1082A000AFF1F075783EC8EEAEC7B8AB314FC2CF74 +:1082B000091871E60BBED98980CFC6AB7BEE07E10A +:1082C0007B9017DCC176E8F7C24619C76D9C2C98E5 +:1082D000EA8D794B9BBF8DF7BEB2DC6CDEE574DEB8 +:1082E00000B73D93C1D5F8A8403211AEFFBDF428C8 +:1082F000F835FB5CF8DE07C5C710C0C7393DFB7316 +:108300009B31793AAF9A41EEAD6BD19E89EFA74E82 +:1083100037E6A18F34D13BE32A33FCE24619FDC690 +:1083200045496E3CEF106E8872FA9AE7DFE49BF9DC +:108330009D5B295CAB4E88F8DEB6D6D1BAF428FD39 +:10834000AEBCCDE50F6B7DF17F4E63F052F8A77B9D +:1083500040DE364FC3F9E3796A80FF31813C9C0DE2 +:10836000FC172C453E186C23B06FD3C74EF0307904 +:108370009EED51D97B35BE722687BE85D76CA7FD91 +:108380009579FA5DF76FF3B075FF364F9C75FF7204 +:10839000EF075797B51F8554D445B43708A91F1167 +:1083A0006B47533D560EFD1B7931F1C705D06FFF6A +:1083B000769ABF6544F6E5ED34B0CF800F0DFBEC47 +:1083C0004E8FD9AE8CD1BB3FF430BDFB43CFC0F450 +:1083D000EE8FA1FDE9EF45E3DA35A94A7CBDF7B49C +:1083E00087DD1FAC531582E703FBD90FD8C9E5DA47 +:1083F0003AEFFED6A5CBF91F392E834FCDFAFEFCFE +:10840000312D11F454CA0742DC77B7862CBF6D3C7E +:10841000D06B9BAD7833CCF76716FE78684D9FF52F +:108420002BCCF1188E8BC76A8A479B098F3B3C97F0 +:10843000B00FBFB6BEAF30DFF3E9E4F8A67ABF09EC +:10844000C63B37EBBD22886BD4CEF91CF5FED71E98 +:10845000A7CCBCAE187E391D6705E0A173D69F7905 +:108460007CAE03E34AAB9EB92A11E25835930D7AEC +:1084700044F07DAAF3F939489773FBEC3AC0792EA2 +:10848000999D133DB7EFDAA310F7F8A4E158722CC9 +:108490007DCF3D79BC48A6FD9DDB7BBC48C2037700 +:1084A00061D33BD435177F5B1470F7DE4BE8E137BF +:1084B000075B8F363A597CE54138173786DABF6A51 +:1084C00012F2657A9AED5E28171DBF1DFC215C39FA +:1084D0003FE62FA659B24AD03316C17ED33C37EEC1 +:1084E00067F972C9C86CFA9D12AD87E3CCC4F96A0A +:1084F00098C0EF04B84E44F1F7023CEF7660F83EC6 +:10850000F143B2029EC2FFBD1A3C09784F3AAB0953 +:10851000891AC4778A6E1E4753690AD3BFDDB73AFA +:10852000F0F78C8405AFAA53A8FEDA3C93FD8EDDEC +:10853000F9630B92C01F695599DEF20DEBE163B44C +:108540008B07E76B371723E6757C574055191D924B +:10855000336C6B8A358CC7F9F398FE25521AFF3DB0 +:1085600029CAB71ECDA6431CD8F8CEC5BF2B52FCD6 +:10857000BFCE037846DBFCF04E8FFBAB6F38CA9260 +:1085800069FBCC28BE5F5E94C0E19DC3DE07EFFBB4 +:108590004EE345D37D18B5D4FC4EB727D0B414E2D2 +:1085A000FCD0EF6DC9F8CE8BB99EA2389196BB0B6B +:1085B000CDE5AE0A9A8FE147EB77D6F6865F92AEAD +:1085C0003238F63738100FBF6C50FD79948F0E3467 +:1085D000F8307FB041C334DA3012CB0F37F8312F87 +:1085E000DAF46C984FFAAF7F9014BBEEC2EF549D53 +:1085F0008CE1C37572E4ADF9808FDF8888AF15AF69 +:108600008E47FEDE349A8E3A86BD677332C6FEFE12 +:10861000E9F257D24A285F0DF9D1AFD34AC6C3EF6A +:1086200096B0F31770413AF61EEE7A25A0F993E062 +:108630007734C6343B86C2FBA4C15BC9589423FD82 +:10864000C589F0BB0B7B336CB47E9A94D7ECF807EA +:1086500080ABDE64E7AFE7E7331F9F6CD6AFE3BCC8 +:108660004CFF660AC5E3BC71F8097E5300FDAC39C6 +:10867000C6B907331E8954BFE1768AEBE6EFB3DF54 +:108680005F4854C7FBE1BDF7CD5EC3CEA9F7C5BEB9 +:10869000E7BE99FF0E44E2E1256817293EF63B103C +:1086A000290A7B0F8904934DEFEDCDE5FDCC06063D +:1086B0009AD0571FCFE6FD151D790EFB83DF9788F3 +:1086C000F5EF87F0DFC3D8CCF5D3743550EC4DED22 +:1086D0006D67D45BBFEB59776D21D10BF6430189F0 +:1086E00080BD04ED8A69BBD40F0302DCEF33CED723 +:1086F0003E0BF8CDEFFDDD937D02C3EB933C7D8A0D +:10870000FF4E49D4139807E3FB163C12DA0376CAEE +:108710003EBB06625274E48FF87E94F83BC501E7D5 +:10872000FC530FBCCFEEE5D93A1438BFB8D25B7C0E +:1087300013C45145A53E03F3F74E6F81FC839EFAA7 +:1087400087D8A3DDC537011FA4F3F706080400018D +:108750000E08AAE18F63FD43B34E65649FCCF22BF4 +:10876000BD37368732215F3F0FF808F28DB4BF7DE9 +:1087700049C121C0476EE186E6633742DE687F0368 +:10878000B6FF895765FE8F3B980DF64A4F5EA57977 +:108790004F4C5E6279E260A931BF9A237FC473D0E7 +:1087A000B507D83B5DA907660830CFD4FD3310FF6D +:1087B000E7D5B7BC2B348C878F60EB048B971BF409 +:1087C00030EEE1A6D983F77963F8619DD76CC7C411 +:1087D000DC27BC0FF0DDD31F8FAFCB36F69E4AF7F8 +:1087E0008FD8EFC60D037B5484B8B986692EDCA3FD +:1087F000A7FEC170125C3998D65FE3CD413A5EB5F1 +:108800003BFBCDA95A2F5FA7642977803E4EB5F870 +:1088100035D95C3F8F508B7F93482B370AC1B5F019 +:108820009E6C688FACE27D935D19284767B98E22F4 +:10883000F583315FCDEFBFCB2B836B47811E59C4CE +:10884000F46E5576A058A6DF573D978DBF0B67F0A5 +:108850005D5552246D9CBBF75CB791377E47E42190 +:10886000B5D509EFF218FB5AB5FB3764C13EFDC719 +:1088700087DE463B71496236C259D3765C81DF6937 +:10888000A96DA37C47BFFBD8D963C7A35FF287C894 +:10889000A06F02BEFED068C3CBDDFDD9552F52FDBF +:1088A000A6D385EA688303D39D7AFDD5E00A9CF0C0 +:1088B0002EB8C949F9E9F11C5D05FEEABCB71EF501 +:1088C000D8E38A3A0AF8AFD3FBC366E0E7AA24915B +:1088D000F3EB0F5FD6F3F87E3DCDEFB9B7EDA6BF52 +:1088E00068DF60A1D9FEA97BC48DFC41ED92DF0257 +:1088F0001FD56EB68560FDB339DAF1BE7327E81B6C +:10890000D45FE6FB991B05A60F4373581CFA72F758 +:10891000342BBE7491708CFDBD2491E9AB0A29847F +:10892000FB76155F7AB1FE2F1FC769BA0FDA771C85 +:1089300037D61BE354F78E837C52FDF661F4CF5F8C +:10894000BCDAB0AF75D4FF773EC5CF6138F574E8B7 +:10895000E741D9D027D4CFA47886E71E793E24F901 +:108960000879A947FFAC6D2EC904FAF6D613B37E79 +:10897000D2254AB79712783E747F73C9A438ED1395 +:108980002CED738CFC4FB17F2B3C0F3A7BF30EDA4E +:108990005EFA93BD270FF06DB059FA4B36C6DF86ED +:1089A000FD19FCB7C7BBFB6578EFE9A5A440F11042 +:1089B00066DF6820875B24157F87D1C0F31EBE3E2B +:1089C000557C798D09FFBD782F30959F6ED04CFB7B +:1089D000A18B172EC37B3F7BF83A564142EC3EDB1E +:1089E00023B9A67DD0FF0FC7D785A3B81F384AFE8D +:1089F000C6708C32E9815E38F24DE55F170E316941 +:108A0000766936EC53ADB1A19F90660B3972C06E9A +:108A1000FB5FECF71A203407E799A8616CDA57CEB0 +:108A200039609F07C6798E448E49E3409E746D0578 +:108A3000AC533F91D0AFA1E50E3919866ED5E1FD5B +:108A40002B2A95D85F4E75B08619F5E6776287AB0D +:108A5000A458A2E5E3D579B8EEE594DD5507F6FD17 +:108A60003677E1CF571393BCA27DB25A588AF6C726 +:108A70009AC4179B61DF383D81D9330279B1F95827 +:108A800046BC7A26AF2DF7BD7813C431B6AED4AE4E +:108A9000067F6EAB331C390CEBF93D6EFC3DAADC56 +:108AA00075E116F8BD0A71830DD74B3129BC6B2BCC +:108AB0009C177860841FEC8BAD60D740FB356E5CF3 +:108AC000FF5B1A42682FAFE2EBC0F6F5935438E72C +:108AD000DCE8969261BD6B91EB6F05B85EBAEF640E +:108AE000B3E33AD063FE96413CEFCB80754DCB713A +:108AF0008CE5F514195B576883C18534F2C3FF44D4 +:108B0000AD12D43327D10E6B742FAB043B8ED6BF7E +:108B1000ECA0787A3C99E385D7E7F4E8A593CDA05B +:108B200007C515BDF9123AEF1D3F637AEA09DA3F2E +:108B3000BC2B45E713827718BB4749E8872524C13A +:108B40006FC7D074740EFB9D5BAA17BDE8C7493888 +:108B50005F631F4919C57E0F1DDAC37A9390918315 +:108B6000FB98CA0CF65E83E271E3FD66E37756DD9F +:108B7000C4F8A7B37829DF677159DE4370AE5F8907 +:108B80009BE94E783721864F15CB7B0B1209CC071A +:108B90007B4B54CDE5BF49E4FB4A83D8EFAD0EB71C +:108BA00085D02EA35284E935248AF6D968D281F97A +:108BB00031E06DE6C2352C0D2F8E8D27BAC8E2BB91 +:108BC0000111ECC7B45B8D784CF0F544BADEBF966A +:108BD000C8E336FC778C536614E27E7D6612AB5F89 +:108BE00015C8BB0FECBC8D33A6619CC6B0EF8CF5ED +:108BF000D2B0DF16729857AB425C7BC1B0EB163A2D +:108C0000593E75B6FEE068886BB6530B341BEE2FE9 +:108C1000B3F86AF9E6E234B0CB161EBA15EDE44CAF +:108C200095D9658B36CE5082A3E1DEDA3CF4078A13 +:108C3000374C48847D84D54E7FE27585E867E2FB3A +:108C4000B903B5C7B6A65D3519E471AB8D1290CAEC +:108C5000FB4BB2EE1E0B7CB1210FEDCCAD09C1C6B2 +:108C600024DAEFD67FD6FCAB68FEA74EBDF0388C79 +:108C7000B33A81D5C3BB51C09B3DE712B6E1BBC936 +:108C8000FD8D6F3D97F052127B7FCAA8FF6F537E18 +:108C90007C7D0080000000001F8B080000000000A9 +:108CA00000FFBD7D0B7C94D595F8FD66BE796566A9 +:108CB00092C963F2220913C24B5E4E9E80224C126F +:108CC000C243B44C102A20E8F03490A7485DDCBAC7 +:108CD000FF0C043050B60657112BEA8462C5AABBBC +:108CE00041A31B35EA8080B8D66D44DAD216FD8FD9 +:108CF0004A1510488AB5D2FEDD65CF39F7DECC7C47 +:108D00009319F0B5FFB4FE3EEEF7DDE779DF73CEE1 +:108D1000BD73E912FC4D612C94A43056CAD8C151E0 +:108D20008CF58C618CA9DE2406CF4D066FD2E2341F +:108D3000C6FA7EA367BBE1F517666F92C3C6D82556 +:108D4000D12EFA79AA99B1A089B1B3CD6E161CC102 +:108D5000D8996633956B961F98C6A09F9A0E85B9D1 +:108D6000F2195BC5DA36633FAF3B9269DC55013DD2 +:108D70000B8E64F47709FE5BBDFC28D55FDDC9EB83 +:108D8000D7B20EAABF92314F073C6BF75A59D01C8D +:108D9000AE5FDF51AC691F4AD251BFD725FB063BFE +:108DA0009C8CDD5B3DFCBE2A789F565D62F6E1FA45 +:108DB000588EE313ABA8AF87F73AE6EB88B1AE77EE +:108DC000045CDE49828A4EACEDD0B132C6D63AE0C0 +:108DD0009F2EC61E50D87C6CB7F6F715192963C2B2 +:108DE000EDD62A9E0CC798F8706ABCA86781D48813 +:108DF000B2DA67C4F5355E34D2FBF30EB35F0763B6 +:108E00001EC9F43F702DAC7F26EB5319CC539F90B5 +:108E1000388E5DCD588B2571373E67BA0C7DA10821 +:108E200038303353717E33F82BF6EBC469479471B5 +:108E3000D83E40ED67D98EA90C4073C45E7303839E +:108E4000F737B090CA0A06CE0FFAFD28B2DF5923D1 +:108E5000B5E51BDDDAF2EC09DA32637E82D74F9A90 +:108E60009BCA4E1AC2FDFE04A6D611032EB70258A5 +:108E7000B17EED5E4BE064041EEB3B9235E5C6AE81 +:108E8000ACC0C988716AF11F59F05F135F779D58B4 +:108E9000F70746DFAD0EC05B3D0B1971DD40C146E3 +:108EA000EF58C6AC16E6457C1DD86FF1B012E8CF7E +:108EB000666EB7007C1BBBAB9525F0DE6A87EF3092 +:108EC0003F2796E16935F0FA8C05880EE08FDA3994 +:108ED000BD99ED5B15E413B7ABDAFECDE7DD00FF1E +:108EE000DD93024F953DAC2446ACA30ED6911E5E99 +:108EF000C739EB0765882F58CF6FECA5481746A6F2 +:108F00002485D7F3ADE1B55C0BAFC65D36A237184B +:108F1000E7BD4418A761A7CE6F84B2CEDC63447E60 +:108F2000B917E93C06DE721C4A4C3C6F433CC7E073 +:108F3000A7EDACFC3EE4C71CE41F18C7B6EE2765DE +:108F4000278B818FAA3717FAA0BE4D05FE86715474 +:108F5000F8BFA908C8D93B6D5532D0E9293BE7C312 +:108F60000D892E7AEE50BC0AE2355DE7C947FAD585 +:108F700027B843CCC1F1A366421960CBAEC162F9F8 +:108F8000BD1EE8EF21981BCB168409F078C8C2CB30 +:108F90002F39CAEFDD08E36E4AE6E50D3FBDB9D5CE +:108FA0003F09CA16599E43E5870C6D413DE0DDFF40 +:108FB00082C9F5443EB5F728585E3032F0044C4D76 +:108FC0003F8465235EA62642E720B7F42F9A769B5E +:108FD000A05ED0EEFB2784A75CFF39FBF13C362670 +:108FE000667F7E4D7F79DFAC3F18BF537775F8FB06 +:108FF000D4C49D413D6FE7C2762CA7E7033FF49FA1 +:10900000FEA2896D85E22306769B17DAD55D2C6377 +:10901000C10839D423F079B6D941725BBEAF43F9A8 +:109020003D06F9A987E4707D47AA46FE4AB95C7FF0 +:10903000F15A4D7F398E7CC257BDDA43F2ADFEE264 +:1090400064FA1E12F2F46C7326E989F8E30CD2C8B4 +:10905000F5F0381359B0F872E34CA2EF721CE6CB6E +:1090600022B9BD06E70C24A43782BC87712E0C758B +:1090700025255F469FD976029145AC679B1A3463DC +:10908000FFDBDC071CBE18FC20E544B8BD51DB1E2D +:10909000F4231B81F4ED6348B7FFAC7ACC91FAD48A +:1090A00066F038506FA8F68A232E37344D7E6486DA +:1090B0000A286951393D7FD9B681E8D16E701F41C8 +:1090C000FCDAED3A971FBEAFB7E93C48272D0E7387 +:1090D00000F1BD51B9C1817243F66B07318FF3B80E +:1090E000601B427A3DDE7AD58B89540F669219A9AE +:1090F0001FFFF7C683C5170F1C8FBD31F1880BFA10 +:10910000574B746E0BE00B91FA71041D44F763DF4B +:10911000A9C69C77743D09FFB8F836841211FEE7A2 +:109120006DBA198118F32E4D56BE9B9E5A1425DF39 +:10913000937F3B3C88ED95D00F0AF249FE9626A31B +:10914000FC2DBC9058E922399FEEB573B185E3B68A +:10915000D88E9A7DA48F98ED13D9BF3E3EFD49B8B5 +:1091600018DEAA64881F6004867AE34A70B02B4137 +:109170002FE29715AA0CE5D3403A6FA7F9F4D777F9 +:1091800043E711EB6F51DD0EA46BFD751E33CA99D9 +:10919000F58E39E6109437AAAED9F92087FADE02A7 +:1091A0007B12D6B729ADC81C8B8F5AC16EC4F92D5E +:1091B0004DD669D6239F661DE7DFE8F75B92B99E1F +:1091C00068DD3FB1C753129F7E40D279518F9BCB50 +:1091D00054C756589FDEC0E76B896307CA7EE3C158 +:1091E0006BCB7E0BC96975A83980F644F4789B5423 +:1091F000778F07BE6F82F9F8B19CC3C7DF54A23ADC +:109200007643D71657023347D437384B08FE176CCE +:10921000694C0FDF37213DC6989784D3BCE4EF68D3 +:109220003FF9A2E832F7B7C3D9100D5DB6C6A2CB9D +:1092300079A8374BF9FC993972FE4393BE8E7C8C2A +:10924000A69BB249CC837C9701CF76586FA7CA669C +:10925000EC437D80B6D64498DFCD36E600993E39A2 +:10926000B57C6732ACB7ACE78091213F743A691D99 +:1092700075A27DF4B8A6148E3F538A839E49C73DDC +:109280004F4F01F876F624B814F8D49902FA300654 +:109290007C8F08BC33D6C69F6A681CF28FAC5FB661 +:1092A000887976C3F350026B3583BDB24FC807C6C9 +:1092B000EEE74F151817C699FDCAE8DD642F8AF549 +:1092C0001F02B580F5D3D343E314FD77C0DB5E58AE +:1092D0007D04DEEACD21C2DBDB46DF6B089FC6E3FF +:1092E000A1742C771E3D9387F870B670FBB5EF25FF +:1092F0006B00E96E207ED6D3FCEA2E0E62FEE28180 +:1093000078AB5383A45FEB2EE6D17758B7DF9C127E +:10931000FE3E1B6C8609B02E66E67042F8C4C2475A +:10932000BBE06B890F50EBA3ED021F08A78FC43E73 +:10933000A71FEF4EE36606783F6BE6EF996724DFE1 +:1093400087097DFE51425E00F7331F0D07CE467A36 +:10935000505DE9917AA7CEE2B96F3EAC9BBDAB6799 +:109360004FC06359A5AD15EDAB65264F12DA5DCB45 +:10937000DED32BEBF30984C4072B043CCF32F75D1B +:10938000883FFF368BE309C29F76FF97BFA3BCF8E7 +:109390001D68BFA24BEF46937169A5CD8FFD96F571 +:1093A000543C6D87F72B5BAD2E06FD2E9BE2FE0431 +:1093B000EDBD65F7595C1BF271BF38A43C0BFA5D3B +:1093C000FB60BE03E581759D37D3EC0693E07EEB31 +:1093D0004C2BE06D93B264895208AC7D7FCA1615A0 +:1093E000F0ACFE57E56716285F757FC116F3758CE4 +:1093F000BD82B21CED59FFD09968DFFE12A746F678 +:109400002EB76F7F794427CAC55BA6820A18E5ECA0 +:10941000D4D960CE2B538AB79861FCF4144FA10EB7 +:10942000C65B93326126F6B7F4BEB17FDD09DF7704 +:10943000A4CC9AA9E613DE447BEFCCCAA1D06E92ED +:109440002CCFB354427F695616B6A72700BF0F0929 +:109450008F8FF67767BFFDBD60E6D41CC04B4553C8 +:10946000A50AFDBF9E72DB9631573136FE817287A9 +:1094700007C63F98B264A615F0DF6994F5976DF1C1 +:10948000C0589DCCF78601BEFFF1FEBA9966A89F31 +:1094900096EA2D74C0FA53CDF76F9991FB1DF865CC +:1094A000A412BD4F2C487112DF1C4690E6ADEB3381 +:1094B00072FD2AF83D87D3717F792494ED11E54C34 +:1094C0005EEEDC105B7E9C4EE572B93321F6778F41 +:1094D000904B00EFA00EE9B3CB1A18961F9627C049 +:1094E0004FE609C45FDBB93C01BE9A63273E8ED9C3 +:1094F000DF37E55F803BF5D3A97AACE8BF90720D0A +:109500006666C571BE4C7669E47559CF5292B7BF95 +:109510004A157CEBE2F071566AE50A33F70C47B85E +:10952000C8768BC53AF3474BFF52D088FCB9D6E2D8 +:10953000C9C0F9ACDD579EC12E6387D75D2CD7F823 +:109540004BC2EB984AEF07F40BFDB944FFEE315FD5 +:10955000075EC95780571A7DBFD23AC3FD69FD3BEC +:1095600003FBE37E9E017AC5187B9E1B53B85E41C8 +:10957000F8EB22E4DA4A215F416A913D7EFEC5ABF9 +:10958000766FCD8F1C7703F50FF87D7A0AEE2F41A9 +:10959000BEA21C2B533DB3B07E594F8A03ED79A078 +:1095A000B78D82DE54A43789E7CE94A6725AEF763F +:1095B000C5B13B861DF81339AF36C583F649C622BF +:1095C0009F7E49C4FCA4FC87FE3B45FF259C9E1F53 +:1095D000EDA7E7C5C83FC22FC4DC40DF6307CE5FFD +:1095E000C136CE08FDF5822580F39170FBB6F42FCD +:1095F000ED87BAB87A2A91DA651C0F26BAA09E21A7 +:10960000C5C5F9B9E3E3C46B515F75E999E2E2EBD3 +:1096100046B95126E5A4BFE748854A764C582EBB8B +:10962000C89E917233683687EBDFBFBD67C646942C +:10963000AB26BE2F4FD383142F0ACFE3E514AE2FF2 +:1096400027F89827961D7824D92EE508ADE3E17513 +:1096500095EC63589F5DE8D709213FF9B39E4C66AE +:10966000C23EE1F090FA7BB629F4AFDC4FA6A547E5 +:1096700059063BA5415710EE1FBFCF89A0FB63825F +:109680000EA2F1F35DE513C0C18F70484DE172C8C1 +:10969000096505ED0B15F417C0FF5CB5CDBD353F71 +:1096A00062DE362E8F9D7A1D976357E08BB454FE91 +:1096B000BDEF253BF173181EDC8EF92F01F7761DE7 +:1096C000ABC17DC1211DF009D2A28DAFF3FC8B5936 +:1096D000D4EFE7293AB9FEEF452EB71B613CCED750 +:1096E000643FD6BF3CA85D3B7FDEDFDC544E8F6518 +:1096F000C73D8568C70CF3DADCB85F28EB9973C007 +:1097000000E5E1DD8A036B4B3A1FDEC1F914A84B7B +:10971000C0E5AD6722FBB5A5723AFABED631FC387A +:10972000A757C4CBE2083ECD4DB57178C1FA4C08BD +:109730004F552B47E5F3FB9B87F78001D65B07F07E +:1097400040B12DE1D6D9B1648305F9F83873231FF0 +:109750009FEF58A21B8B78DDC9C8BEEB970F0FF0A7 +:1097600075487B14E8B203E9F2EAD45C1A6FD87149 +:109770008F750C7C1F867613FA953BEC01DC574CF9 +:109780004EF5CD4D4578CEEDAB64204A1AAC4DEB8D +:109790002D11EFFBEB77417DA2639F7E2CCEF3363C +:1097A000C6B6BAC2EB81A9FAD11F5A6F043E2DA0EA +:1097B0007210E1D669E4F5FB16338ACF34E8FB8CEE +:1097C000F81DF4F72CA2CFA3BA14C42FEE9BD06ED1 +:1097D000AED37B7314DCD76798DCA807601F42F414 +:1097E0007EC8C2540BF4FF263C514E57E9EFD88F88 +:1097F000F0AA2A50DC2D24AEDA85DC6041DC37CDBE +:109800009E62257A645FDD39B41AF5BF95E309FAE3 +:10981000318B7ECCE6A230FFFD3AEF2ADAFF48FD1D +:10982000764851A89F43D78DDEDD12B12FC2FE507E +:10983000FE1F52AA73EE40FA17FB3AB20FD3C27A58 +:1098400017ED95225B24DEFD627EA13CA4A3487B3C +:1098500014EDD37E7BD6DFB1653AC8D9F1333A82B5 +:109860003A0752D1F333FF01D65105F6AC05E0704B +:109870005B2A973387F2FDFA449CDF30583FBC3AAD +:109880009CE01BD3640B8F932EFC0FE946EE2F4810 +:109890004FE0CFBFA7723BE727695C1EFE218D9783 +:1098A000D31363FB2BBE10F55413971F5BCBB9FC8E +:1098B0008FAEB741F4FBADEDDE318A667F0F76EFF8 +:1098C00086546EF71AB95F88C713960AFA063B8763 +:1098D000F014B6AB783C50DAA15FF4CCA3F272F38B +:1098E0007BD9E8BFBFED9FE6DD87F4B6F2377AF2A9 +:1098F000579C14F18295C9BEF464DCBF27C4F6AB53 +:109900003C27D675BA99911FF8538C1B82EC3D8980 +:10991000714328AFDAF9E034E4BFD52C40FEE0E52E +:109920003B37515C707940612E05F7695EEE271672 +:10993000F858BD47AFF14BDFAE361993C784E977CE +:10994000459B366E58B3AB5853FEF6F669250B446B +:10995000C8A1B0FC9946EFA3FB95F41E6DA77ED479 +:10996000ECD2F8C397EE1C46EB97F5973137AD77FD +:10997000596B8166DEAC95F349BCF949BA45BBD455 +:109980001F739E46CDFB8F00FEFE08FFFFD25343A0 +:10999000691E2DA9BEFF40BA09CFC3CAFC1ABFDA9F +:1099A00024C727B05666E17E49A023FFE5EC81502D +:1099B0002AA7FF6F0FF7D171F605E3FEBFEE0BCAC2 +:1099C000267139CCDA14360C1EE3A76AEDB4BFA0B9 +:1099D000BE2BC5A795EB6B61472D5FA4AD7751D426 +:1099E000BB28EA5DC9BF12699F290528D7787F0D7A +:1099F000828FF3CF1C35BAA0DEF8346EC716393D1E +:109A00009750EF6CB3248E437FCA364B5E00F552FD +:109A1000FFFABA381D6D33483F8A3B03E1D6FE5F3B +:109A200077B6A888C77DB00F007958FEE841168A3E +:109A3000905337AE533CCB01DE7621EFEADC7C7DE0 +:109A400075EEA07128F4935DC7E795D3B15F5123FC +:109A5000DAE5D4087F5F9A41B3CFCCC1324E258D71 +:109A6000CBE39C9AA03214EA65EFDAA3A8D85F870B +:109A7000427A33BB0900134157D925DCBEB9B1A4E2 +:109A80005D5936260C87565DF51807E0A735DDEAE7 +:109A9000467D738FD337240DE7792218C4EDFCF887 +:109AA000133D2ADAEF3F757A0AD29C6138B8F48EFA +:109AB0006CD4A7D6137C9E6DFDFB63AE6728A24DC8 +:109AC000FEABDDDC9ED1B3238CDB87A4AFD2378C19 +:109AD00024BD27E7979E22F4453AF33D67A3FAADEC +:109AE0008CF0C9683DE91B86EFE6F62CC7775581F7 +:109AF000770FBEAFCAB8AAA805DE176C0BAA4BA198 +:109B0000DDCBBB62FB83CB853E81754CC2F5C9754D +:109B10005C492EC87A86387E0AC90FD619B1F71F5C +:109B200030227D2F7F346D21CEB76EA39199943072 +:109B3000FC7FEAF4CEC6F96477B42B081BE9DF9307 +:109B4000E34AFF1D7E47FEFCC828F996D35F5CFE02 +:109B50005FA7F72C8F94671B8D8427693F87E7C722 +:109B6000EDFDD5695CCFBEEAF42EC1F934746D27E2 +:109B70007FCFAA3D1F1A63F9ABA3F9E24A70546A7A +:109B8000F8BEA06EBE3980EB2F7F54253AA8DD6861 +:109B9000A43859DD33FBB89FE71EE6463951D7B1EB +:109BA0004F590EE3D63EB34F591101D74175010508 +:109BB000E733C22EF990CBAF68BA473F32DA2D8730 +:109BC0002D5C4E9C2DB7F91580EB5983AF0EEB9DA4 +:109BD000CDB2BAFDF9613CBCB96FFA11CC37B03FD8 +:109BE000670AE2B355B73BD30CF55A4719DD485F16 +:109BF0003F75FA36235C52546F27B64F4EB3BBD72E +:109C0000435B978915A1BCFBBA70181F4527E3EF8A +:109C1000E1FCD3857288DB9145C83F8134BBB4A792 +:109C200048AE1D36F0753CC7F87CFF9EEA7990E897 +:109C3000F8480A8D9B5D1754D09F9D7FE639926B43 +:109C4000B2FF309D791E89E4DF2BCFB3C388F45671 +:109C50002BE450F9A37B948F23E6FD4B30F4916EF7 +:109C6000B29F01BAB4D1F7FD33D3A83E33B9F0BDEA +:109C700042ED6AE1FB8A087923D71143EEECC3F584 +:109C8000D84EF41CE47227C8FD8D62BED1F87C1555 +:109C9000E51F7C9A06EA99DE1BFD23312E7A78486F +:109CA00002F527E54034DFBE2AE81CE5A5CE46FED6 +:109CB0005AB22BE5FC64BD2267C5FE3482430FC156 +:109CC000A17E974AEBA9327A87DE11C10FBF16FD3C +:109CD0001DB8F90323CAFD07FEFD5DA2C7FA36854C +:109CE000E2F1ACED5DE33CD447FEA7F46867CEE259 +:109CF0002601DBF1C2BB84A7599D5C2ED777EE53BA +:109D000097D9C2749A7FE6C0AD4867F51D2686FBD9 +:109D100022A0BFDF207CA2E954C247CADD78F8B494 +:109D2000CEE07294F98DE44785FD543EFA29A4DC17 +:109D3000FE7BAA4EF809F8FB0B69BC1CA61FDFA727 +:109D4000088FB0DCB5105FE49F293A60C67DB85B30 +:109D5000213F7F5A258767E4BCAAC7C6979BCE548C +:109D6000A137D450DE1C7B58BEF7CB7FD1FE0B81D0 +:109D70006F781FE4EFD910D4F372FED1F8CB77726D +:109D80007D1B83CEFE1BD711ADDFA43D20E9E6C9C4 +:109D90005DAA468FD89D46EACF0E1B739CC78E7274 +:109DA0001ECFD861E0FA6CC77A7300E5C99B0B78C7 +:109DB0005E997DA13188CF43BAA575F8FD50361F55 +:109DC000BF55A75B83E5D60D36D64278F5243A4BCE +:109DD000917E1219978F5C1E3EF03C9767757E5BF3 +:109DE00080C13FEB7C739753DC39CDE2C6B833F3C7 +:109DF0001D34CEB30FA42BD773FB8D2E783FAB83CE +:109E0000F39FC403C853A22FC90F12AE617872B872 +:109E10004B7E92F8F8BBF46703BD7CA7BCAA3DDA81 +:109E200078DCDB46DFD54EBECF3A6C70A19F86C78B +:109E300017E2D16FEDBAB7B34F821DB53AF32D7A61 +:109E40004ABE85FDAC86BF2709BC1738B9BEAF74C2 +:109E500072BAA92DE920BEAC3DD944FC6C9BC1E58A +:109E60009AED84561E33F6CF62BDDBA85D95B563CF +:109E70001AE677543DAE3870BF1F4F6EDEAEF0FC71 +:109E8000B84F77BD9188F972EC2BB0F2319E62E148 +:109E9000EB9DEBE472E2EC5E0038D17B93F172F65D +:109EA000FB95FA63C1630AC2B356C0FAEC3395134B +:109EB000FF847EECBD49EE61B0E4CF9EB9E9EE3F90 +:109EC000C1BCCFEE99E246F7655A8B97E8A7CF69F8 +:109ED00071E37E03C4F70CF417AEEF7823F15A68F0 +:109EE00077FAE9AB8B506ED78A799E795EBF0EE127 +:109EF000B2E1C97F9B8CDF6B034AAA09C7D9FBF883 +:109F00007F6763BEEA9E46F217B53CFDBA11F317B0 +:109F1000748176FE7E6F9203EB9DFEF9F6C908EF21 +:109F2000968E16FA7EE6E7ED543EF0E4BFBDF67776 +:109F3000F4E37813DD58EFCCF3FB092F753E95F26F +:109F4000DBE2D1F58E7DFBB9BC443D8F7C309FCBED +:109F50003149D7927E4F3F79DBC448BD21DFB70A34 +:109F60007F4E6B02D7239F09FEADADE0F1CECF9EB1 +:109F7000B5CCA7FD8131341CF7C57563385DDC2D88 +:109F8000E051D77187A1C146EDA99FDF02DFE373DE +:109F90002CD0E72723298564CF25CAD7F957AA0FE4 +:109FA000F526A0BFE7E6451F2A381FEB9826432D6C +:109FB000CDF369FE1D561DF9BD6C6D6C3FFBBF38BE +:109FC0006DC22EE07C90DD599DE3223960720F8BCB +:109FD000B087B36B7C2D1827BE7EADCFAD073CBEDE +:109FE0007CEAE8B441507E72A4524CF8D72B5CCF87 +:109FF000F96D344E3DFAC1818F760B3E497730F5CD +:10A000001A9203DC1F50A532D5467EAA3E9213F564 +:10A01000AD420FEE117E6E735FDE4D766A67BB2632 +:10A02000621F06ED6C362AF7E5FD10F34A67F8E784 +:10A0300093DE711969BE67A43C607EF27B4A7E8B19 +:10A04000F61BA1BCC1FCD1579DE55D281FE5333D42 +:10A050008EBFE4EFE2FBB8744F17CA15B63755A3AD +:10A060000FE2C99503379FE77AFB950F890E1B9086 +:10A070000E717CDF498DDE5E4EC215E8F0A50F89BA +:10A080000E977771F9DAD0556EC4FDD40EE1D76919 +:10A0900010F4847484FBE8BF3A93699C86C9A1E1FB +:10A0A00028A7CE0BBA3BFF12A7B7433A1DF9010E02 +:10A0B000ED1EDDDEA20CD48F4A8D97F0DD00F8E6B0 +:10A0C00076F3DAA36867D5D73037F26B43A7E0079A +:10A0D000B07B11BE0D5DD5CBB1BF416933C9DF0D7A +:10A0E00076C9B441506EA863A5C86FD9BB2A5E4239 +:10A0F000BA605D7C3F9E5D03F62CD24D5ABD5B9FDE +:10A100008F7A8FDBBDD78F2CA3F63B725D14E7F2FD +:10A1100057318AF3EF40FB19F55DD6686E3FFB3689 +:10A1200092DDC55C09E437653E750DD66FF02F6290 +:10A1300094D711CDC72F29B40F680858291F685626 +:10A1400017B77F1ABA381F9F93F0914F43CFADE4F2 +:10A150008F7FC1C4FC11FED0375F9ACEF5EC8B2601 +:10A16000D2B39F357BD8C7B0A0B785BC9770AC6D14 +:10A17000CBD721DD32769309E7B14CCCA3CDC0F526 +:10A1800046B2D00305DBF83CD474E1774CD789A7FD +:10A19000519BE7E2F0937FE19C188FC8225DE8397C +:10A1A00018BA7E7990F8A4EE19DE5F9AC9537867E1 +:10A1B00004BD4AFB289A1E0BC4B8D9BB0E2A284CF2 +:10A1C000B277CDD1F0F9F5352CD808EBBC7E972EBF +:10A1D00038651CD94D0B499EAF37B258F92A23D2A6 +:10A1E000B9FD5695EA2D44BF76D5CD3677A43FB953 +:10A1F0002AC1A3B3A01D5724FDD8DE128C1B9D4A93 +:10A20000B7BB116FE3D25DD20ED3D85B03F7DFDCAF +:10A210000EBCA1CD3F0EF71F81F509F329AE09DA77 +:10A220008DFCDC0E688FFBF7DDD7FE9CEFDF5BB8A3 +:10A23000FF020407C999546F09FA8F9D05DEB55CCA +:10A240003FD9DDB1D6F3AA93AFE7C0CDB716E23E52 +:10A25000B161AE8DF8E1815794A59CDE4011E2BE5C +:10A26000DAC7F983017F3CE1227A243BAAA1C91B0A +:10A27000884D8F9C5F1AC0AE423B1BE8710DB793AF +:10A280006D8CF313A74BB9BF47B91569CF4A3E8D03 +:10A29000E67B49BFFD7CFF35F9FDBC81F3E37980A6 +:10A2A00003D27B3F9DBFCCE97CEB7AE047F8BE153B +:10A2B000F8B12542FE47EF7F709EB81F90F2F61E60 +:10A2C000A777513ACAA1DD6F6DC650AB948F0D2FA1 +:10A2D0006F197E39BBCB8C95A15F33F06B24FD6089 +:10A2E0008CD65E444F3FEA09EBBAD8FE8FBBD26DE5 +:10A2F000DFCD3F3F302FE5AEF4D2817929E9A87355 +:10A30000106FBBAD01B48FA51F297A3E4B049F4946 +:10A310007CCAFD03C621B0FEFD82EF37897A8F88A3 +:10A3200067C4BE84F8C1A5F37D4879F671F4916CD9 +:10A33000F77DF9B5E438522F46D38D8CA3E07AAA85 +:10A34000C7C4AFD7B65FECCFA2E8F829C15F0B80D6 +:10A350003770DE6D86E017C48F77D819E513F8994A +:10A360002715E371AF8DE07C34B26F38B6B766FA6B +:10A37000BE44BA927E5D7C8F71AA5A11BFACDD6B70 +:10A3800008449E7FB93783D138BD76B35F0FFC9107 +:10A390009BE9DB87EDFD15CC1D443DF38F168A2B21 +:10A3A00081815B8AF2A691851211CEEF25FB5E209A +:10A3B000FAD5F70C47BFE33925340EDF9F10FEDADC +:10A3C00013C25FFB7ED77BCFBE02AD17BF726EF1AB +:10A3D0008F91CE5EB4E4217D9CB0F4E7BF25A1DD72 +:10A3E0007D81B9922E770E699159EF5523FC67272D +:10A3F000ECB1FD7F6F0B3C378A782B5319EDC3B757 +:10A400006770F9193EBFC4E3ADEFEBB4FE37F91C3A +:10A4100093C1E1DF19E71C506106DFD7740EE1FC40 +:10A42000D8D7AE50BCAF66DDFA3FEB412ED4ACB509 +:10A4300007E9099FD18EAB71F8833A289F3070B934 +:10A44000047F73CD6561FD07F5D449C8337E07C528 +:10A45000BF960AFDB5ACE9CDBFA15FA14665E6494F +:10A460004518C7F21E1E049F3EB52D4F44F1BFF2A2 +:10A470004777A6A37ECA58D426F2C1A63AD0FE5585 +:10A480003C37E82F592F676FA96427131D00DE1E84 +:10A49000CCF0F6221F2F4AE27EC145775A03FE0810 +:10A4A00079B857F06134FD7C10E7BCCD97191501E0 +:10A4B000EC6F61AAF76FD4EF9DE73472EDBC12FA2E +:10A4C000C523485F77D8DD4FF0EEF222F363D20563 +:10A4D000FC6B310E04A2B1B7B067F8BA7CA4E3BE3E +:10A4E000BCDFA15FABDBE4F0BBF0BB91BECB76F190 +:10A4F000E241F1E3402E23D247C34585E86169F785 +:10A500009BC751AE37A821A293A5661BE1B1E1A27A +:10A51000CAE9A9D5703624DB03EED7A47AD232601B +:10A520009EFE7B2725533C09F889C3172A459CE3E7 +:10A53000F832C3372803E0F79035F136DC7F5D3021 +:10A54000BB92308FADD108F4703575E73547D843ED +:10A550002CC7AEA583EEB7FE86F35A6EF61951AF3F +:10A56000AFF034D179B14549C152C79848BC4FD2F8 +:10A570005F1AFDF5F17E49C897F78D3C6F64209D09 +:10A58000733C6CCF10F5B239BFBC9FC76A9EC3E75E +:10A59000287842BBF787887291280F17F5D279790E +:10A5A0009AE097F7C7F17AD1E32C15E37C99E1990A +:10A5B0008C7082764123D2C76B163A67C44A40FE3C +:10A5C000A1BC5B934B762CC8B96908771827984CC7 +:10A5D000F54CA4675813C841C0676FA98BE0B3B5A9 +:10A5E0001CE805E341AF9A281E24F12BF11A8DCF08 +:10A5F0008519CA77CB4F1F18BF5E98513A307ECD70 +:10A60000D850C217D14B8CF31FF1F0F56B3BC70349 +:10A61000F0EBF20CD283C1B1917CB349C051CAB501 +:10A62000F713B478FD3C9DE3A15ED4BB84761FDABA +:10A63000D1EE3EE2BFF75378FDB402AE97A45DFEC3 +:10A640004F022E5FA66B9F52CF44FBD1BF14F2E2A4 +:10A65000CB74EE4707BCDE8DF395FA09E44C301954 +:10A66000F878D1EB2692336C631FE5D540BDFF83AC +:10A67000F05A64EABB3515F4CA0FC1DE311651BB7E +:10A680004B284706ECEFC748BAB033D4DBAD190E00 +:10A690006E1F94F4F1B8D748BEAEA50CE48772657E +:10A6A000FC630C210BE4F06B22BF42C1BCAE146210 +:10A6B0006717F60770FF978CD230DCA3C73B21E801 +:10A6C000E0D10C4525BC15B242C4DBADEF7E6E5F18 +:10A6D0000C5D9E13E765934DBE76ECE7ECDD6F9164 +:10A6E0009D7EC2181CDE668BF1DD187CEC2125FCFA +:10A6F000FDB6A7F47EE3D5987F7EF6C19B61DD4B66 +:10A700007BF46E1C72E93D5FBC331EEDEC1E03C58D +:10A710006B40DF6F5371DE4DDCAE3CA1D3D2C1671D +:10A720007769F73DAF0B7A90E772A5DC91FA7C155B +:10A730007373799390B81BCB1FDD713B9DCB5DCEBE +:10A74000BC873D00F7D36B66925D7C3BF3515ECFD7 +:10A75000B256ED39DB156DDAF2ED3B079CC32539B6 +:10A76000BC2A10FD5EF8A52B63EBFBF3822E3F3372 +:10A770008AF8FD7A53CCF8FDEF85FC09C7D9FBB404 +:10A78000F1FB572F1FBF6F8C8ADF87ED88E8F83DFC +:10A79000EFF713616F60BF9171FCCF2A62AFE3A343 +:10A7A0000C69B75835F9199F0CB05B12E97BE3458A +:10A7B0004B9CF9D8E8FD672B638FD3D73F8E365F6C +:10A7C00020DC9EE709C8FDB5A493C68B59A4676534 +:10A7D00059DAC7E17639F43DFABCBAF46F4BBEF8EA +:10A7E0005861E62CF2476D1776BC9BF2333F46BBAF +:10A7F00008F972BAEBB5104C71D98F270E578784C0 +:10A80000F9267A1D405F674211F2D898694F23FDFF +:10A81000EB666E3A9727E8FED6BBABE87CCFFFBD70 +:10A82000A73223326E2AF7530D46698FD934FA9630 +:10A8300045E9E3655D6F911D06F6D770143E7F7A9A +:10A84000F56ED2C32B99371DE9BDF7D511746EE5AE +:10A85000DBEA61399F9BFC4B0C3CBF358DEC8739A3 +:10A86000623E3775733B5067F618681C0F7339D218 +:10A87000698BCDE70B425485F275FDF347E71D6305 +:10A8800093C4FC156C0FF0BD4E3CD9525F26CEDB55 +:10A8900084E3EA310D269089CF96896E173EA7286A +:10A8A0005E95CF83E3791A6BCAC1FA3A7348CFD762 +:10A8B000093348C7F6FDF0A2B25D9437CEBD70EB08 +:10A8C0000A7C6FB3933C318A794CCF04B988FC6D14 +:10A8D00066665CB7C9163C4DF133F1F457B8888F02 +:10A8E000FD4318F9411258079D3FB5D9CEF971B112 +:10A8F0000EE650B06C715C08E27EE29CC3E6C7F3E2 +:10A90000C4202F6765A23F5FF9D54AC40BC867EE24 +:10A91000178AF75D0DF2F31142DEA588F9B50879C3 +:10A9200097C5DC8AB8C780E4DDFDF69537E07E2662 +:10A930008D79F7A3BC7B387106C5FD32988FE693FD +:10A940003A43D5C82DA7575BCE98AF46CB3B05E71A +:10A9500097E5D3BE37B3139497A404BD9997526972 +:10A960001F3612FD310621378E59783EC26631CF2F +:10A970003B3353886E8E59785EC2B7B65BDCDA7DA6 +:10A980007D430A3FBF7F3EDD6CC6F1C08EB913E147 +:10A990000776CC077E16CEDF2C9CD24179029B6FC6 +:10A9A00054DC1BE0FD66BB6BBD0AA4EB9FA9707F66 +:10A9B0008FEA28C77C9CF63C871BF3441B45BEF7F7 +:10A9C000668BA3F619F2639A783DD6B719E396ED34 +:10A9D0005B1D0EAC9756D937CD88FBAA15CCB19B21 +:10A9E000C5A0F7AF808F60BE3FC732E04911F46366 +:10A9F0003DE2BA85D620BEEFC17F17F0F29432DC7B +:10AA0000BFF2BF82EE423A77C93C7AD2978DDD859C +:10AA10006FD860BC82B985E4AFF756F2B82F1372D5 +:10AA200060BC1C57F0D9B561BAA7EF85A23CB45BF6 +:10AA3000F87FD34C3CAEEB8021CAC49143AC9FC697 +:10AA4000F9C1CDE41FE7D36B58F80FFBAB0CF74F00 +:10AA500072696AF87398EF60A822B3BBA50EEA8DFD +:10AA60005783FB91AFAF15CF42F13C547E23E9E50C +:10AA70001E9DCD65D4713E3717A0ABC3AB47B894CC +:10AA800039B6B4603FD729417AE6CDD8DE82D39F6C +:10AA900023FC4CC999C6009E376B99007826BFC825 +:10AAA0009F0FA3FF5AFF2FAC18F174CC20F59E27FF +:10AAB00089E7FFB9683DD50E3E5997CE337B2EC24C +:10AAC000F9283FCFC6D0748BF8FE97A9554997D780 +:10AAD000BB3C0F30254BCFE5E30C1E876D9C6FA66A +:10AAE000BCE546710F03537DF93F8CF0AFC8B8C584 +:10AAF000BB06367F5F8CFD464A16B707E6DCC0FD15 +:10AB0000C28D221F477E4FCCE27EB2BF644E7B37A0 +:10AB100093EC3D1E6FFD9D945F23D948945F11F225 +:10AB2000E58F245FCADF8E277FB4DF85FC99E72994 +:10AB300036D0BE40C82129EFBD22EF6801F31810BE +:10AB40004F3DE21E95A3E5AB480EDDCC7CF4FEF74D +:10AB5000153CFF0008D380FDDD34436B3FCDF36A25 +:10AB6000CB37CF8FB6AF383EE4B80B7CDAEF73A4A7 +:10AB70009D3C436B272FFA87AF9249CF67FCA2FE1B +:10AB8000D2E0703E5163543E5183C8276AEC2A3CA0 +:10AB90009416914FD4D8CDF3891ABAAE944FC4ED20 +:10ABA00029AF29B01FE324DE5AD294EC0D917F72B5 +:10ABB00010F34F8AC2746EAFB0F33C0CE6A1BCA296 +:10ABC0001C8795CE5DB4EA8AC88FDB9A68D7F8DD1A +:10ABD000B7AE7755613DE9BF95F9434837B1F6C344 +:10ABE000D9597C5FB343E17E74FF0233ED3B9D0591 +:10ABF0005E4D5CC1A967C7D1AFF86EA64BD6273FA3 +:10AC0000C90E832FAB189E0185D17989FEF67AB6DD +:10AC100091FC905172CA99EAA6388033692CF9F5F3 +:10AC2000E77517923F92D92CEE614AB8FF7973DB32 +:10AC300055CCEB69EC6E5797DBC27437364BEC435F +:10AC4000ACCC8AF4DAEFD77BCE447EBD6493B730C8 +:10AC50000BDAD71983E4BF8BA0577A1F4F5FDE2E24 +:10AC6000E8C550E15DB002E6D7FB8ED18DFB6B0AE3 +:10AC7000CC41FFCFBF944C7E49750E233DB5B19CAE +:10AC8000CB935EF493C13A3E4DE6F7FA6CAC66A402 +:10AC90005FCFA74C233A5EC502873DE847DB0574CA +:10ACA0001879CFD21E6DB98E7590FEA97B66003DD6 +:10ACB000937C94F2B89EB9F4068C1B746ADBB3A142 +:10ACC0005A395C28F447F1BCA92D98FF50ACE3F247 +:10ACD000912D770F9A43FBF5458E4F2C28727FA15B +:10ACE0005CCEAEEBB59FD273FEE77AA154F41FADF4 +:10ACF000BF4A853D3719E417EE6FA57D06F5A97C9F +:10AD000050D7ADCFD485E75922DA49BB50EA0B8939 +:10AD1000AFF2098CE179B5BBB2847C1AC28620BE41 +:10AD2000A17FE21305375829D4BF1FF785D78AF1D1 +:10AD3000801EFCA8BFFD3A7300E96BB3D244FAD27F +:10AD40008CF63F3CB72A3ED20BFF5EE3D7237D4C07 +:10AD5000644D37DD00F526997BAC28B7804EFE3177 +:10AD6000927E5A58306F9FA2A123FA7E36F9ED9851 +:10AD70007424F55AF0F7DC9E99C5BC74CF93E70FA5 +:10AD8000DCEE3AA8F07D26D89F07D1EE7A5B3793A8 +:10AD9000E864262C03EB5539B4F89F9EA92D47DFB4 +:10ADA0000FC5D05A284374487806549C4FF4BD51BF +:10ADB0001E29F79856EEE5B3AF78DEF896C33F420A +:10ADC000FF83751D1B89F60E58AAC48FD1F4B027D6 +:10ADD000EB7B8FB7ECC98A116FE9157EE56B58687C +:10ADE000E533CA407A3B7F689D3E33822E257FBC87 +:10ADF0006CE07913CAEB3CAE35C1CCC604112E25EC +:10AE0000DCFF28F9E31AA4D39430FD9589F787A4D1 +:10AE10007C19CC0623BD5DD76509EA013F85A2BF39 +:10AE20006B90FE8AC2F689DC77B44C184067F998BB +:10AE3000170EF64C01D295B44F8A958E163CE7FD5D +:10AE4000FC4BF7B6E07C23E8EA2D84C35905E88A79 +:10AE5000FC6A03F4ADF67B14DD49FC4B7BBA9C35F0 +:10AE6000D17E676E02D7B3C1EADB49CF82B824BA7C +:10AE70007B730EA7BB2AE621BA2B675A7AA9346BDB +:10AE8000CBD1740923EAB474E723BA8BA6D77874BC +:10AE90003718E94EEADBD42BD3DDE74877DFC58FDF +:10AEA0003990EE3ECF72C6A7BB687A93F26C9FC50D +:10AEB00051897675638D42FAA1F89DA12D581E51D6 +:10AEC0009F4F76F6BE6437D9DD8D4DFC7B498F47A9 +:10AED0008F7933056BC5F77C6F25961BD7C177E853 +:10AEE000BAF418CFAB197A0FFF5EB8A1E90DBCBF59 +:10AEF000A0D1CFDBBF7C7A339D870A6C16EDCBDB0C +:10AF00002AB1DCD8CADB7F8A71AEAB31BF2DD082CB +:10AF1000EFAFDA96EFE6DB6F6ED74F11EBDDA73CB4 +:10AF2000F706B56BE3ED6E3F6C4E60E427E0F6FA92 +:10AF300064B1CE29BBF83AD33EBE7E860BE86345AA +:10AF40009F9FECB94F74756524EFE2ECB3CB95B6D7 +:10AF50001C7C4E4739A647BCBB5BF543781C743755 +:10AF60000C717536F7D3C8F821E6295447D817571E +:10AF700067733B44D64B4F61747E8DFDCC4EFE72A1 +:10AF800019DF0C3EC414D407B8466197C48C774EC1 +:10AF90002F6822BB62FA6019E70CA94B61DCC24B37 +:10AFA0009F4F8BE5472ACBE6F6F329917721DFD730 +:10AFB00004F2754817FB9048E8FCF09077D09EDBD0 +:10AFC00097CC34E7DCF6E5F3F2D4ECBC7F6ECD0130 +:10AFD000F8EA9A54BCF78BE52994B7F2831E164C15 +:10AFE0004A1C38FFE92A0B1A290F8ACF7F658B513B +:10AFF000DC57C2E5DA3C813F366918D1EF5C81A7A6 +:10B00000EA6CA1178B5931CAA979026F3F343719FD +:10B01000B8BE6E3344C98F79D9283F1E8E6BCF6B73 +:10B02000BF47C9971A31EE4A61C7AF627DE43FFD61 +:10B0300044D8F1A71EE676FC6AD641FED3DE9F71A6 +:10B040003BBE1E9687F412ED07ADDDAB2DD77768BA +:10B05000CB0DA0DEB1FFC6AE28B93386FBA57B1FA2 +:10B06000AE2F433F64CDCE77C8FF5D23E54C402B28 +:10B0700067C040E772E6A151E4BFFAD6F2E319D8FF +:10B08000D59569F24BEFC97646F8775EE4792E0DD7 +:10B090008CFB117AED236FC17D2C8BD24FD172A521 +:10B0A00050C815E9FF90F25BCA9B42C6F514EC77D5 +:10B0B000DFF1609B283BEFE16CA1AFC4FE4DFA4D80 +:10B0C000A47D5488F611D2D7A82622BAB07E72BFCA +:10B0D0006DD247E8A5052566C47B9119F81BE1A64A +:10B0E000B78DF5D934F4F168F6E5F783DAEF51F46A +:10B0F00023F7630B05FDDC84911818FF0F721FB84E +:10B100008AD3CF5CE63D84F4F3FBD59C7EE4BEF0AD +:10B110009BEF033DFAC87DA0DC4F7EDDFD603FDD87 +:10B1200058C03E86E7B15CE917E0F1FD4685D3459E +:10B13000FD9CDF3D56C5C2F2E2683373AB8670B941 +:10B1400065A6C98C7E971603DF2FCD99F57ED9D2DF +:10B1500008F913B4971F40B8B16E27F977EBADDA51 +:10B1600071362B3D77FD11F7558F5AC9AF74E10841 +:10B170002393E5C2AE11940FFE9981C75BE57C6E07 +:10B180003FBCF7B510D45BB9EE9662CC2FA8550240 +:10B190002FD6C1B70FACBE7791BF6B7541712F67CA +:10B1A0000FC527E4B8F1FDBA7E92C7C6035C3FF72E +:10B1B000290994DF0BEF8747C6E9FE3888CBEFDC1F +:10B1C0004CDF07B81EA9475BFAF327F813B4301B0E +:10B1D0009412CEA708E74D707FCB5F98E78A79136A +:10B1E0001B23E204D03E66BEDB7921CF47617201AA +:10B1F000CC6765BAA717D77F4AC4854F8938E2A9BB +:10B20000441E57FC7B7F7DFEB40DE27AE894883BB8 +:10B210009E4AD1C69B64BD44F13CD96CF66E346045 +:10B22000BC9E793782FE703D646AA27C95451C5FA6 +:10B23000BD2F256BEE11C81A543E6A10B4FB99D38A +:10B24000AB1F04E32C6FD39E83EA15F7DBF60ABA33 +:10B25000E9B5F0A71C376B50F5286CD7BB80DFB37E +:10B26000DA5F9E28CB5EEABFF7BA10C9A3FEF28F61 +:10B2700042E29C3AF793C8F840BCF86174BC30FADB +:10B280009C6974BC7FB1E43711EF5F24E4D4E26EB3 +:10B290001E6FB8D5CC360F82EFB7756750FCB82655 +:10B2A000D13F5C13EFF75BBF519E87A4CFDEDC9EDE +:10B2B000FEF8F8CF22E2E3F5223E5A2FD7D7A95D58 +:10B2C000DF6401CFEF313E3E799073607C3C3A9F62 +:10B2D000E245B4330C613CAC7170B855E9EB2AD14E +:10B2E0004F7C6139A33CF7356F2D6B413FF29A2DAE +:10B2F000E296556177D70B38C75B97D3AB632E8D3A +:10B30000BF3E81B922D693E54BD194C9928FC83301 +:10B310001D5493AD699FDB3444537FF0BA519AEFCB +:10B32000F9FE224DB9A0F51A4DFD616D159AF2880E +:10B330009DD76BEA17B22149E46F3BA2475F12BB6E +:10B340002A3047F37DF4DE859AF69FB2A61D93A0BE +:10B350005EA7457B2F33F37B7AC69485F3A9C77626 +:10B360002CD5F4C3824A50290BDF33F699B8A7795C +:10B37000790F8F875CDDB55A334EADBE8EF0181D48 +:10B38000EF2D627DE4376E0828EE201B18FF5DD597 +:10B39000D54EEDAE64F7C878C8C64122DE97CDB26F +:10B3A000395D47D3858DECC30BBBF4E47F2C64C3BC +:10B3B0001F9A44F032B0806B20FE2E30EE17BBF0A7 +:10B3C0008CDD8D7945B7BFB58CE663CAD4D205DE76 +:10B3D0001F18B95EEB482D5DD8DD5A3A489AA0A5F2 +:10B3E000836878277BB474C142F0BFCBC03B7586BD +:10B3F000966EFEB7E0DC81F0B586E15B7CD0D3626F +:10B4000023B8F1BC35699F99843D141DD790764EC1 +:10B410007090B0BB453F322EB159F1935DD51F7787 +:10B420009C10CC0BE6A33DD5C4B85FC97B10E56F7B +:10B430000CBF24BD8FE79794709D9BC0F5672DF3DB +:10B4400092FC3E66E1FEA493D5ABC89FB4923591C1 +:10B45000DDFDD99CE9C2EFE8A77A57CA5318909F3F +:10B4600000F6298BF0D7AE068B1AEF1F8A86A7D27B +:10B47000AD04ED786E98754B7DE0A3FC150FDEED05 +:10B48000A989FF68ED5FE65122E597B487E5781258 +:10B490009E52AEC9714CAC499F897C1125E7D8C832 +:10B4A000E8F893D69F23FD41328E23E34CD1FE9BD7 +:10B4B00008BBB8558F71D2C1F92D78CEB7D8E1212C +:10B4C0003F6129EBB905DF4F3077B4A82EE1BFB853 +:10B4D0008AF5FB2FE2EAAB2BC4B56FF22BA147F242 +:10B4E00007C6B3657C1C96FFF11FA1F124C5958B9F +:10B4F000F398F3F20827D2D340BFA6FBF82BD08FE6 +:10B500005ED7978AF5AA30313D22DEFDA612A2F55C +:10B51000FC907936459EDB6F601DD36E217F32E84B +:10B5200049BC27A793FBBB5857B43DAC92BF590702 +:10B530002B41BAAF651171DEFCF0772AEB079665F7 +:10B540001ED295EC89A7F18272CAA3E0F9534CC8C8 +:10B5500041B9FF8CB7CF93F918F27E4F9977549485 +:10B5600023F8751C1B87FD03BF95E594A27F01F8A6 +:10B570005389E4C7FE3C25FA3E801FA3D62FF33142 +:10B58000F4F612F21B2D8B5CEFD78087B45B7E9CA8 +:10B59000C3E8E9C871D1B33EE1C46F3DF8B9A4472F +:10B5A000933FDA68840D0DFA135E1479811D5ABB3E +:10B5B000FD961C9D801BDFF75C095EF1F121F2F81E +:10B5C000043EBEAE1D26F3F8241C970C84FB0A0D26 +:10B5D0005CFBF78FFD705F110BEE122EE74A7B7E4E +:10B5E00081F8D2DB8FA523BC17A67A5763FDDCE375 +:10B5F000A14F145D785E55FAB394877BA14B4FE75A +:10B60000FF1AAEE372B0E1253D8986F3DD268AB3E9 +:10B61000D674BD4176E1D96610B406FCBD0C187233 +:10B62000D865FC0851F08EB74F92EBD99023F6E520 +:10B6300062FD32EF07D6B93927665E473F1CB4DF9B +:10B64000051CAAF46392F01C597FBE92DA97177911 +:10B650005F5FF43A2A7278FEDB29B3F73EECEFC362 +:10B660009E9C1DD85F95BEFB7036C267AD42E7BB9E +:10B67000A698F879DC2C715E6F42A8C98DE79933E2 +:10B6800073F87D66237EA4F7621CF9FDB577A6E00A +:10B690003934D9FF084547E747197BEE837F2CC132 +:10B6A000F8E62237DE6FBFD824EE2FBACB1A2C0073 +:10B6B00039F2BA91DF476518D244E766FA92F5E4A9 +:10B6C000D74CD3B3A9487772DEF2BCAD7C8FF701BB +:10B6D000605EB17C3FA5A5AF780DFA7B043DC875CF +:10B6E0004FA9EC2B6EB285E12FF33CA3E15325F873 +:10B6F00043EE431BF05E5BD0BFE7CDBC1C7DAF6D5E +:10B70000FFFE7458FF3D36F6C8B87E83C593341EDD +:10B71000F951DC6BFB17872789DF77A4BDA7F6BC3F +:10B72000C8B797BF5312EFDE9BFFCC51BE977B8209 +:10B73000E2E585CBBCFF7870694856997A359D73F0 +:10B74000F75EAEDE2BFFAD8FB9DFBE28BEF7DFD3CD +:10B75000F96AECBCC55EB1CE707E6188CE29F7E790 +:10B760002DBE547ED97B471AF03ED20838C8BCF6AD +:10B7700006BC8FB43846BFD09FCB76E57B87AAC482 +:10B78000BC1A308F3035F23DA7B7F03869222F3020 +:10B7900094887CFBCB2E3D9DE3FFE511DD8CDD31F4 +:10B7A000E69D9BCBE132CAA9121F8D0EF2FBB5E3D9 +:10B7B000D593E779E4B9D8E8F97556846EC5F9638D +:10B7C0009E72ACF11CB97C3F2BE7DD99C2F1D1F040 +:10B7D0009A89DF9BAAF27CF2CE94D04AE2138716B4 +:10B7E000CFC3041E3BAF0FE5D1B9B299DCEF108F88 +:10B7F0001E26A7FACA51BEC87BEECAD426C511C1FF +:10B800008F57A28730DCF51ABC0E84BB91BECB7E6D +:10B810004F1F157CCB3C36DCCF2D11FA6EC99E5ADA +:10B82000B287E57EE9F44E3DE56F9C663CAE72BAA8 +:10B830004DA1FDD0521F63EB402EAD7CA27833AA00 +:10B84000AE2599B09614FE1E7F1F66E9C6A8F8BA09 +:10B85000D85F49BD2AC75FBE4D6B17D7B06D7F4615 +:10B86000FBE9F4512E3F56B026D23F2B1FD0F6579E +:10B87000B367D6A738CFE8BC8011C28F372D57ECFD +:10B8800057CA5819EA8F354F7C6EC49F6089C71715 +:10B89000F8FB4F4387F1DF7DC227FE8E083E6FC95C +:10B8A000F5FC2017FD3EEFF2F9AECEF5CDC9457F90 +:10B8B000C9BB7C7E17EA2E703DB32B8DF45B8BFDEC +:10B8C0002E92FFFAC15CFEDF8BF735009C4C26718F +:10B8D0006FBAAE499F48F64D80E8EC43E71D737E92 +:10B8E00040657726F243DAD3D36760BFCEA7AD1E9B +:10B8F0005CDFD6724F21FA2FB656F3F3A166138F91 +:10B90000DF077E39F100865386766CAF40179DA322 +:10B910007B7F10FD42ADBA3F1FC6BC98D6C93C5FC5 +:10B92000325D17DA3F28623CA7359089F17DE768E0 +:10B930007E6F4E9ABEBC90CB7F6E2736085C5CE86B +:10B940002A207F62AF41FA173B2C742EAB8EFF2E5C +:10B95000C628C6F12FF3EA700E9176F1D966A6F9E2 +:10B960009D86511D4AD09048F7A8503CA86E4330A0 +:10B97000FD16D4674FA9144F93F34B7B3DAB02E305 +:10B9800066528FDDA238B8BF4DD8FD0B98FCE3712D +:10B99000B7F9829E16087BFF162B87F752E6CEC3B7 +:10B9A000760BCD2C5107AC764B654729ADB3D690BD +:10B9B0008C76858C1FC5B74762FBC91A7E61E7E7A5 +:10B9C0009E95BEE1D8C919F4415D863FDB853C698F +:10B9D00018CECFFFB1A1CC83F1CA86D746D0EF30C5 +:10B9E0009912783C1CE49619EF113A84FA1ED6BDE0 +:10B9F000EA158BC85B0A8873CDFCDED8C639394599 +:10BA0000741EF1781FDDFF71DE10CA23FE067984F3 +:10BA100037A6BE92FBBB1FE0BDEB0DD960D741F945 +:10BA200074EE9F7879486825DE1B9992778997474D +:10BA3000853EC1724E5EC26C2A178556EAA13C3E15 +:10BA40002F939771030A0436356FF06C3FDA2DC9D6 +:10BA5000C22E7087E8BC77C3CB237491FE58771E43 +:10BA6000976767843FF94C3EBB6D0EC27B64ECFA6E +:10BA70006979D2DE6EA3F5C9F5CAF62C3376BBFF21 +:10BA800010727E9538A73DC5CA5A2D3CFEE74F047B +:10BA90003C1CEC1E41F1CB7FCD4DE1FD3B42744F90 +:10BAA0008FEC27FA771CE4B8AB15FE7B59E7A3F2BD +:10BAB000BC7E97CBE52B8CB391C619EAE1E79BE7F7 +:10BAC000E41422FE006FAAC09BCAF7C9ED7C7ED0A9 +:10BAD0002FFEFE13E88762F4FB1FFC0AEAE787E704 +:10BAE0001D4D2727C538AB5A78DCB62FB980E869D9 +:10BAF0008A55DCF752A25DC7F83C6E9FBAF392C537 +:10BB0000791D09AF0C85C6691170CC090D9F33F6FC +:10BB10009BAFFBAFFF4BEB8EC09707EF6D39D8C5DE +:10BB2000EF371E9FC7F185F49C4276E0764D7F6724 +:10BB3000D647B59FC0285FAE21A580DADF2BEE6F18 +:10BB400095F7D961BBFC71DCBE45BB57DEA7C1FCD4 +:10BB50009359641CB2FFDE8C0E71BF70FF3A6F28E0 +:10BB600011EB7488753A22EF33ECE7CF637D79737C +:10BB7000ED03E9B81FFEFDFD8D2912FD69F83C5665 +:10BB80007FC8D7F1F072551E9727DF1B5EE43CA3F8 +:10BB9000E0D90FE7A8F94978227F53BB315ABA940C +:10BBA000F3CC11F43980BFF3BFE578E27ED9FABB5C +:10BBB00079BE387369E9BABE335F87F909B2DD0728 +:10BBC00078C0A034EC27BC214FEC2773584E9CBCA6 +:10BBD000476F9E33A67F91DE47EF277B93E5EFD932 +:10BBE00069FD1ABD4EFE7B39FE73FC7E836BA3FCA0 +:10BBF0003C188F7ACE166E17D62FDAF263027E03C8 +:10BC0000FD547D7938BF1253C5F3F83B5BABF34A63 +:10BC100067AB6077942455DC990FE5A6C7C693FC03 +:10BC20002E1954F1793EC8F3358F4DE0DF47577C2C +:10BC30003E04CB791379798AE77994F760B4CC9E86 +:10BC40009A15B62BEECC73D1B8FA4A1DDD6B67425C +:10BC50002306D6637ADD44F98012AEF19E25265D77 +:10BC600053ACF3BFF7F4D3038FBF4CC07FBAD01FE0 +:10BC700028FC052155E32FE84DE4E7CF7B5FFD92DB +:10BC8000CED7DC9BE75B9F07ED1BAD676FCD87F2DF +:10BC900006EB0714EF533C6087A01FC6E5608B607E +:10BCA000BECAD9AD5EB49FD86AB75925B80AFF1885 +:10BCB000DEA907F07BE5B5A77E3C880FE3C5794C8C +:10BCC0001472A0F1B5BFFD15E3C48D676C6E341B13 +:10BCD00027763F7C27DA5F13BBDFFE1BD7C3FC3C14 +:10BCE000909CF744F47FC2FB095D269AFFC4EEAB3B +:10BCF0005660FD6BDFEB2E403AB9EE44B005C5420D +:10BD0000EFABFF3E48730E887D7AD97CD1B8F1390C +:10BD1000098F3F01A093081E3FE7F0F88AF2D9CEC1 +:10BD20003B8F6E0E9193547BDE0AEC788A3B5F600A +:10BD3000096E8C7BC873FDD17ED5E3D5B03E787F8C +:10BD40005D1FCC20C29E9E72D10C82245C2E67C9DE +:10BD50009A72A5394B53BFCA91AFF93E3DF32ACD34 +:10BD6000F799AE424D79D6C8899AFA37BACB35E5FC +:10BD7000D913666AEA577BAA35E5C26087A67EF1C9 +:10BD8000912EEDF7634C8F78283AEE7E039FA5271E +:10BD90003DE49E2D3BD5F4063E27FE858323DAAF96 +:10BDA0007CCDC58E37F0BDF42B479F9F927EE69BDE +:10BDB000F5B68031B63F39532D08DF83A0D7F1F3B4 +:10BDC00053EF25FBFE807893E7A7A6A05F1990505C +:10BDD00075DBB99FE2EF325C58C4FD6EC711319438 +:10BDE0004F6E277FE57143D3B37FE47903B928F71A +:10BDF000AEEB9BAF59F7948B3ECDBACBD9AA283C7A +:10BE0000DDA1295739EED6D49F9EB95EF37DA66B8E +:10BE10004B149EB66BCA37BA1F8EC2537B149E9EBC +:10BE2000D27C97F4DD2DFC5FAFA1DF0A9E93423DEB +:10BE3000958887C9A7FA081F137ADA2A114FD71CE9 +:10BE4000EF207C9504BD95282ECB8E34BD81CF206C +:10BE5000ECCBB0DD81E64C7A1E6C7691FFEB70F393 +:10BE6000487A1E6976D3FBFF689E40CF5F357BE83A +:10BE7000F99FCD33E8D9D3ECA567477307D57FAEDB +:10BE8000B98BFBCF52FBEFDDC845BFC1795DA8017F +:10BE900023C68EC15B499E9E4F089DC7F2067FEB6D +:10BEA000ECA92034F0671D902F7F209E452E4FFB7C +:10BEB00060780E1ECCF8FD19227FA343E729443B8E +:10BEC0007CF4E30FDEA7E632B669BD37137F3A187C +:10BED000CB662813B2E9F7901EBCCF93C3D8B3A8A2 +:10BEE0004AE8BEF7076763B957FC9EE7E0C71F241F +:10BEF0003BFC5BC7D93D03E2ECA307C788B33F7B9C +:10BF0000CA65477FCFD1AF46D8111E4785DFCBC367 +:10BF10000A0DF83B1CE56AA101F5ECF138E7215464 +:10BF20005379C9E0525CB77B1EE5915F6FA0DFE1FA +:10BF30009BA3F0FDAFAC97ECE2FAA0F74613EDA798 +:10BF40008EE93C2B903F7A95BEC710CE373DFE144C +:10BF5000E9A95E7B5F1EC2AFFAF1BDBCECEC7B4C85 +:10BF60007147940D1C3E958F3F39DB6FFB5EE133CB +:10BF70001BD7110D9FB9831D7C5F11F4E4A21D2016 +:10BF8000CBC7AA3DF514572CF70CC3751CF59A388E +:10BF9000FF7AED8161E437F294CE8BF0FFF40C363A +:10BFA000D0FAE7A2DE443FE8427D20D6EF159E1F7F +:10BFB000CCED3DA213DC672EB0D2BEE0988EDFA39D +:10BFC000105DDFEEE2FBA3CFE2DC879C28BE57DCEE +:10BFD00054FFEC0BD05FEF5A0B75DDEB1D41F658AB +:10BFE0006F13401768BAF754D339FEDDE41620A169 +:10BFF00038EF2DF82FF8FE6CF79D5FFC06EA7FB056 +:10C00000D6EA261DE21845F05B282A2F4E3593FD0F +:10C01000B4784E6E05EAC55B44BCF056BB9A4E61DF +:10C020004335D9E8807E96DB0A370304D9CAB46A5F +:10C0300023FE64534DCE1D9BF1B97AE87623F25866 +:10C04000DD987D9BD18CAD07162E25F9177AA7199F +:10C05000E675DB3ABD8BEFE7E4F9DADA6F94F722A5 +:10C06000E9F798C84F0220D07E35C9A568F649493E +:10C07000824E1F182CE23163D9D84BDA78D74EE4C0 +:10C08000A3B38BDF191E271EA1FD2EECC7DF8A7B11 +:10C090009EA3EF4F91E33A5C7CFF75CC089489F640 +:10C0A000E442AE07C6CDFF7C4329AC7F5CB7434773 +:10C0B000790DB7D5BF8078B8D025F068605DC84FDE +:10C0C00037F9977CF01B424C9AE6DCF095F4A5BB5F +:10C0D000C75119A92F4B42DECA487D39A1AFAD1215 +:10C0E000F5A2D48FC1E61A218F9B488E1E6C5E4745 +:10C0F000E5C3CD7E7A1E696E15F2B88DBEFFAA79B2 +:10C10000A790C701218FF7D2FBEEE6F9F47CADD9F9 +:10C1100047CF85A9BED7116E328E3BD7ECA3BCDCCE +:10C12000430F9B18C6F12E749B288F0338E2B1474A +:10C13000D2304FC944E744A3F395A2E57C3F3D7458 +:10C140000EB8B7E56DE4F7FE3C23B41707C7A7A701 +:10C15000A3CC6547B9F4F1E0F324878EBA5C76B4DA +:10C16000A74F3E2ECA1E97DD00E53F0DEE25FD715F +:10C17000D4E7B29BA0FCC9E3BDFCBBDF65B740F9C7 +:10C18000D3C17DFC7B8051D0FFECE02F488E9533EE +:10C19000E520F247A5397F2AA80BD0D7E507912FD4 +:10C1A000A6672E998A7CB160B08BE872A66BFD41C0 +:10C1B0002CCF1AD9AEE215151E5BE1466C5791568D +:10C1C000AD62BBA939776CC476D3866E5723DBCDBD +:10C1D00018B36F23966F70B7AB689F2E4039561A0D +:10C1E000EE4796E57729A7653EDDD5DD5ED207E30C +:10C1F000BABCA40F245C2AE6566F42FF676397E23D +:10C20000C0DFA5A998ABF4273360EE6203DE930A82 +:10C21000F2FAFF3DAE77AC87753662F91A2AB7ADF0 +:10C22000FF06FAED7F00F6E231E800800000000032 +:10C230001F8B08000000000000FFD53C097854E582 +:10C24000B5E7CE9D2D64924C360842E2649924965F +:10C250002C43B6261064480CEE3001F944651910E1 +:10C26000C2164804EB17AB7E191A17E0698D6BD123 +:10C27000AA6FC4B5AFB6E461D458091DAA52D287DB +:10C280003A5510B47974A488F0999011DC78D2C72B +:10C290003BE7FCF766E6CE248014FDBE078693FFDD +:10C2A000FEFBD9CFF9FF5F008053F8B3027F603403 +:10C2B000FE38253D8C046804F167BFD16DB295034B +:10C2C000AC34078CA0A32F41A3AB1060AF0E9676C1 +:10C2D0001400A424C3FC7A0B968DB0740B96E75D12 +:10C2E0006803480568DABA206E8185DABBE36660C8 +:10C2F000FB4517E2AF38CE52056E54E0930AD49B4B +:10C300009C89344F9A4DD21FCAC76F8550784A0610 +:10C31000E8B79A3DBA048044937BAC0DC7ED9BFB14 +:10C320004E835887AF88D6316CBD1EEBE300326C6C +:10C33000561E1FCA8219545E09ED46C846B8F5CF8D +:10C34000FBA422DA97C52723844E435F205FECF9D4 +:10C350005416FE63063D54E07AE9036E6999D7707E +:10C36000206056EAF1673974EC706622DE5ED47E96 +:10C370006F04BF18BF43FB7D15E28DBE377569BFE3 +:10C3800003545B0F8D433002CBB8DFD912FE5E85BC +:10C39000FF0D8F874967C0C3A4A1F010B51FF01A25 +:10C3A000418EDED70ACB6EA673E4BEC09DCAFCD117 +:10C3B000088121F7A7F245F4FEDA05FEF502FF2514 +:10C3C00036E7745A5FDDFC389053008E6D35794D39 +:10C3D00099DCFFA93D2944179375832D9A3E5B5B39 +:10C3E0006783DE00B0ADD5CDD0D7BA14F476803FE8 +:10C3F000B53673F9ADD6162EEF68F530DCD9BA8EA6 +:10C40000E15F5ADBB97E57EB462EBFDBEA65E86F8A +:10C410007D91BF5F3B7F6586DB124DFFD5C9CE4561 +:10C42000C48F9E7BAA13993EB8F753C8AB9E1AC817 +:10C430006FB644C30183659D94C0658F11F7E1D940 +:10C4400016E36DC37DFD738CBB89C619A8097EAD4B +:10C45000437C434A80F1D030D2BD9ABE4B461C3A51 +:10C460008966F5E412FE0EEB3CBF0764D9569BD3F8 +:10C47000A5473E381A8F551700DC82650FCEF3783A +:10C48000AAAB85FA417EC048E39CA23F93717C0928 +:10C490006677F03A10A21C0EC408E8B1492C8FD17F +:10C4A00050C8DD40BA9FF960E0E91319B68233CB7A +:10C4B000C570F8A893AB039E32A46765ACC384D55E +:10C4C0007D12F8A412845346D6008ED3976ED413EF +:10C4D0009C14445650C7C39FC9DF226386F1CB1416 +:10C4E00048D4946BCDA335EDEBAC999AFABEF45CCD +:10C4F0001EFFD2B48B34EDFA46579AC5BC532F2396 +:10C50000D865746F5C80740956991C9BB0FEBD9809 +:10C51000F822280698161BBF89E07B31195E6A371E +:10C52000EDC0C914C07D4E937D238B105597DBC69B +:10C530006BC7ED995363C37657E65769D721C12579 +:10C54000B4DFAB1D5334DFA7575EAEE9EF32FB9388 +:10C5500008ADF5CE7ACDF7C696AF419F0C30B1E568 +:10C5600024E84B01C6FB3A34E394EEECD2B41FBF8F +:10C570001B6412EB927D8E3709961F74CAC42A156C +:10C58000879BDF2458F5A53F83F6014EB059519F94 +:10C590004B8ADC8347023D962729E5CAA0B72D8147 +:10C5A000E87012F2F548BF8930C2216363A9F2BF77 +:10C5B0004E101F4C5220003207F6AB164B80793AD2 +:10C5C0008BD798456A05E51BF5C106C991A6473882 +:10C5D000470E5450F928048A08CA3A979EF86B2AE5 +:10C5E000348FA5B209DC69043F4874BF4F7CDC2F4F +:10C5F00005DAC4E282C9C4CF753FFF68DE6DAC17AF +:10C60000621C265CDFEFBAFE914A6BFDBB3FF591E1 +:10C61000376C217E6FB27ECD7852CB8D2DC7197FBE +:10C620006AB96F2DCC77E192DB0D689F1036FEAFB3 +:10C63000CC760AEDDA3AA25323FCC9B8BA20D41E4C +:10C640003ABE18C47731EABF7A5AD304C2D7DF5D45 +:10C650004E6C576F1072089E45F54E1CA73E46293A +:10C66000834FD4A72AEDA1B29ECBE96A7D95686F6E +:10C6700057C77B58B41FAD9695F12E52CBCDA29CD7 +:10C68000A9CEF7A02817AAE5FF7071394EB43F6113 +:10C690009B55EF2908E9FF53AADD180FE3C96EA0E7 +:10C6A0003D9033C91E48BB1A981FA2ED85B65EB1F6 +:10C6B00017F37F237B8CC5448FCB63DF21B9EE90CA +:10C6C00080E4BAF17683D38BF37F9ED451B4C61243 +:10C6D000C2DFE7B7087CBB6AE39C32B65FF96ADE6B +:10C6E00026E223396EF7C885F8DD3A56C77AA74E99 +:10C6F000B63881E87BAFD0FB6AFF48D8D0F2868697 +:10C700009E51F5B2C4F3C16CFCC1F9FAEF1BF5F40C +:10C7100006C2598E3F9770939929F4DC48D4AD95A1 +:10C72000F8F336EA5933D23D251B9C3A6C9FF21A36 +:10C73000EA67A2F141BFD0C7AFC5F824149C958F1A +:10C74000BDC9F66FA18C528EF87B2DCF9D97897C49 +:10C750007A34CE9F4B7CDBD0B28DD7758DDDCAE3AA +:10C76000833558108ECFE2CC28FC979E01FFA53F61 +:10C7700026FE718203A4CF752874B4BEE596B778FF +:10C78000BFCB95EFAC5F3243EDB82C47978FC639DE +:10C7900032081F0E854E0774B60A055F5713BEFA9E +:10C7A00017FB7313B1ECF0F947BAD93EEC2A97881E +:10C7B000EECD7140743F2AF98BF60E41FF8ED60EF6 +:10C7C000B6CB5B5ABB18BE8473D0BA557CDD108DD6 +:10C7D000DFF967C0EFFC1F13BFA3F401A303FBAD98 +:10C7E000DA073C4E85FF8011C2F44C2BF125E2277D +:10C7F000A14BE2FA3AB92021A0A98F13FE528E7301 +:10C800003CF1E9CA19BBAA37482179981C0B1D31A4 +:10C8100049CCD70E85AF1DC4D72AFF223F96EA1117 +:10C82000CF6F9DC47E43E037C4BFC0F3A878BA3B46 +:10C830001AAF1B888EA7C1ABB6FE07C66B27FAC717 +:10C84000A43782AFC478376546E3F9770A5E557C32 +:10C850006F53E47F383C6F233CA79E7F3C6FCBB483 +:10C86000F1B891F81ECE3E45D2475DF710725A7E60 +:10C870002E723A2DDBAAF8DFE8771646D3FD6DA2BB +:10C88000BB5943F79E33C853CF8F294F91788B8480 +:10C890008D12B83A2CD1DF3FCB1C56DF9D173C4E92 +:10C8A0000ACED6F86793BF756BFCB329186169FD92 +:10C8B000D89B34E53AEBAD9AF697A6ADD5D45F6E2A +:10C8C0005BAFA9BF32FF014DF96AC763117EE6D3A2 +:10C8D0009AFA7AE76F34F5739BB76BEAE7B7F468B7 +:10C8E000EA1778FEAA29AB78DCDA0A1C2F6D6B35C3 +:10C8F0002BF1D3650CAB03FE5A12838B0F07D9DFE4 +:10C90000ACF4B7D7B24BB2AF83FDD1329FAB96C276 +:10C91000AA8A9DCD6F12F4B55A95782D8DE15BAD45 +:10C9200036D6EF3B5AF319EE6C7528F15A25C35DE4 +:10C93000AD4E254E73318CB40BAF66BBA764213D61 +:10C94000A6BDBC4407B880E97FF867C15E5ABC77D2 +:10C95000BC8EE2DC35CA5E8E577FB3FF36E4AFE3B0 +:10C96000CD2607957BB71F31D80AA3F965EEB732FC +:10C9700038C3F86C6ECB5F0DE467CD450FBA630822 +:10C98000399D9AA5637E20F703502FCC368321056D +:10C99000F5C1ECD992A30DF8BB079218FADC583F09 +:10C9A0004D0F3E1396EB2D7A9F299E97E632A33FBB +:10C9B0003D4B2C134C7AF0503DA424739C7E0D7D8E +:10C9C000B4A13C3865B818BFCF223F1CFB5D6FE9AE +:10C9D0003090DDBD6EE72FFA6FC37AB8D353CEF136 +:10C9E0003D5C6225FD2D793ED69D1A37BCBC2035B5 +:10C9F000E150185F4F25194EA5F8D1E17752DC7A46 +:10CA000093C1F19C2DBADF05CA7EA7C912FB6FC185 +:10CA1000D74DDE4D52483E717F3B4DB8CF26E201E7 +:10CA2000DA67B3C19757447EF676F6B39B2AD716DA +:10CA3000119D9A2E913E311585E29DA6962FD98F94 +:10CA40008FD4CF91F04CF190C36F65FEDBDFBA93CA +:10CA5000F9458D8B7A5B7D5C2E0BB86AC3E3A339F5 +:10CA600093FF4DA6B8A7EA4B11FF4C3CE9DCFB5302 +:10CA7000DC77A0D5FF2FE517D4BC829A6788CC5B02 +:10CA8000A87A64DEAD75096EDCEF9A2C5106F3943A +:10CA900074A6A35E4055DFDE9A156597EFC83ABDD0 +:10CAA0007ED6D6FFC0FAF96CF9BF314DD8D548BE55 +:10CAB000DF37E30503AD53E5EF48FE9F437D70FE8E +:10CAC000394D92D7837A7AF69276C344E9DCF97DC0 +:10CAD000B9E5A0888B23EDC2F7B60736A69B5C2B81 +:10CAE000737C61926F72501E44A5434734DD3ACF88 +:10CAF00040B7CE1F936ED176F1E0BC73B38BA0F13B +:10CB0000CFDFCB8AF2273EC83ABD1FA9ADFF81F720 +:10CB10006D1D6B63B87244EF3C5927EA457C620196 +:10CB20001DF2EF8057E6B87469667B3CC533501937 +:10CB30008C277DB7AC5B06F20F41EFD48F46FE5CCD +:10CB4000A2F0671FF83E247E5C05F77E4109982518 +:10CB5000D54BAE223DB7F40943084FFCAF93F32702 +:10CB6000AB947ECB2D9D46DAEFF267B5EDD4711A0A +:10CB70005F8AC81F575FFA19B0DDF073DE6F55A7E3 +:10CB8000B6DF77597129876259164B08EF67D2A72C +:10CB900047C9AE1BC2CA275B39BF203FF3E0039EE3 +:10CBA000B121FAC46447F1715CF6E9F9585BFF23DF +:10CBB000F3B11CF7AC91E8F97DF978BFDD9945EB4D +:10CBC00056F5F3A0DE79C3C47A67A0DC26F2A43759 +:10CBD000FDAE2D9EF8E40438881D162AF9D2856A28 +:10CBE000BE749D365F3AB9CFC779B94907BD6D713B +:10CBF00048F789BD1ECEDB55ED76B759B0FCD35D45 +:10CC00004E99FCA3F16FB9645AB7EADFA8FE4E480B +:10CC10008FE5B0BEE3BC6BF6D9EB3BD52EAAF63060 +:10CC2000D20E5606DB6BC9FE4DF8B6E34D82E72BFC +:10CC3000AF1E69F7DE8B137AE2A8C157BE97FC8C52 +:10CC4000D7631CCF41F4FAAFCB167EC64CCF02039C +:10CC5000CB1F091FCADB0C456EAE4F765F974DF5B3 +:10CC60008ABDD0999D06B2A37572DF23D7125FF9F2 +:10CC700065CE1BDE7CC707BFFFB5EDCCF98526EB83 +:10CC800071F63F868B339A74E0A6F8A2A4D6564A72 +:10CC90007E0CC56D944754F38A91ED9FB0D7ACC814 +:10CCA000E63C57B5DF49EBD928D6331CBD9A5ABEAE +:10CCB000D0E431879BBFA9BBDCBA304C3E5ECA16BC +:10CCC000F12ED2DB7AC81CA2F7D9F2C5FFB7F865FE +:10CCD0009A0C1E09ED6CA1E415FE2F083F780EF8A2 +:10CCE00019CE8320433758F97C6A2138182E021751 +:10CCF000C37CBBDB4B7C3360088E24BEEA7FF5BB74 +:10CD000002E29BFE8B27B657C1F93B5F8AF4FF0610 +:10CD1000C6DB78FE8157BEDB43FC397087E1ACF49B +:10CD2000C6EA646727F151E479CBBB53643ED7016F +:10CD3000FD7A968B7AABE80397A4721BEBD84CE68E +:10CD40008B90DE1CF5B4AA371760BFC24F74ACD706 +:10CD50006099E4B563D3AE808E45AC7071A657A6DA +:10CD600072A7A82F5C99E895B05C581523EA6F4A22 +:10CD7000F44226C5430196CBF900AC0F1780D08B47 +:10CD8000378293F78991419684FD176F3597703EEE +:10CD9000160239A4FF8B288E1A224EB7E608792F87 +:10CDA000CE12FABEB8469B17F9305BC91BDB6B4A43 +:10CDB000721056E738F7121D8B93FC1B1E2AA37CBA +:10CDC000900E36A17C7D56752B9F77AAFD1AED3506 +:10CDD000BD84BFCD1270BCE2E936799F13E78C2386 +:10CDE000C3CFCDF2EDB507A8DD115A7BF9F078C5B8 +:10CDF0007E1CF747CB9587D7574CB11BE7FBF14318 +:10CE000025CFCBE5FF79E6EBFA3B0BF84CC1437E2F +:10CE100072A3DD7D9CD76F04B0D0FA9F14711440CB +:10CE20007306E547973C65D2919FF1119A63C80359 +:10CE3000F81BC6DD04FF1BE367827FC7F899E02774 +:10CE4000183F13FC07C6CF04177F3B1E8322808D3B +:10CE5000394E4B4E79E81C3072BD861C81CFC1F92A +:10CE6000BB8D3C7F9DDDCDF81DA4F7EBE0A573994C +:10CE7000CD89C10B924EC36F03DDDFF0F9E9707805 +:10CE800051CF2523EBBF53E85AD4A967FB5FD415D4 +:10CE9000886F086B77418E91EB0B5F39184FE31F5A +:10CEA000B50EE2D729E196A7E944F982672D330848 +:10CEB000BF75766709ED1BE53C83F651D4F5C18358 +:10CEC00013CB787CAB64A375041FE5B821621F9176 +:10CED0007850F7B539D1BF81FA6F7E258B76827A8B +:10CEE0000784DC101F4943ED772DF3CF7453B0CC8A +:10CEF0008AEB9D7E4A6E1E0AFF75F6298CE77754F1 +:10CF00007E53CFC715FE52E976AEF21D391E906BE7 +:10CF1000847EE76AD2A536B24B27E3C92FAC57EE21 +:10CF2000197475E6BC47FBF4EC94C16E633ED6C839 +:10CF3000DF62855F5458D86D7411BD36771FCA59AA +:10CF40006461FAE42CC6F6B372EC9ABC6761D589C9 +:10CF5000C71F4AE1F6569AEA3A78BACE8AE3DF600A +:10CF6000DEFE366D69AEF593BA442CCF4F93761042 +:10CF70005C60CB9C9A64A3E57A79FD37E64FD94192 +:10CF8000227595A39EFDB929A464C2EC43AD3996E0 +:10CF90000E1F07CB75D6644DF9D2B4319AF697DBE4 +:10CFA000B235F557E68FD3D4ABF35EE528D5B42B75 +:10CFB0004E0A66515C87FB60B980E764AF5DA27D75 +:10CFC000EFBE621C96A73D3FCB416ECA66A57EDAD6 +:10CFD000965A2FD16300F1694487EA70E5FA471F3A +:10CFE000A2C122E286C6EE6776386DE710370C13D1 +:10CFF0002FAC00718E3F5CDC10192FA0FE7C90F4EA +:10D0000067F1ABD758DB70DCCD55272EB0E13EEF92 +:10D01000CCC13882EC8D12470CC73F837222D904F1 +:10D02000FFF4C8F0DC10FC03F00B851F059CF63EF6 +:10D03000FA3305DF5FBF7D4AFA8DF3071EC5EF5750 +:10D040006044BEAFD8E8786F0DE5A7DE9181CEF9D8 +:10D05000E124AE03EB1BE87739C4F7B0E8E9BB463F +:10D06000A7F0770FB9A6AB94FCDF1F7314BFAA71AA +:10D07000FB5DA3CB42F570F3279AF670BB74B7A69D +:10D080007C67A6B67CEF94BBC3FB0FE797356C5C5F +:10D090006074A39C363C2C39BD43E88BC1F5A428B1 +:10D0A000FAA17B09EBDB43DB97196D71D1ED57E1F9 +:10D0B0007894B76C18C6DEAA7AEA3A199A87AA7FDA +:10D0C000479DCF717EE7FB08714FF6CDF39AB0C351 +:10D0D0001F25B88DE17CB22F479C7BF43FF6C01D25 +:10D0E0005FD379EEEB22BEEA4F14F6A3A8F3339D8B +:10D0F0000E61F108C15F45D6808EECD2C0D2580FC8 +:10D10000A09C352D8BF3E88AC98F087E681E4F5E80 +:10D11000C72D0F9A91CE1FEB741ABB3C40C11696D7 +:10D12000FB9EFDD98C3BE9F702712FE97CEDB32F13 +:10D1300007847DAD117A631EF19F62B7005556D307 +:10D140005D3068C748CF105EA89C6BBFF5FD87C9EE +:10D15000CFEF117A83F20A37B05FE0B468F30D1DA8 +:10D160002CE7F8BB2DFC3ED759EB8FB7DA8D96F341 +:10D17000A84746D8B5798721F4C5FB57223D9B5E69 +:10D1800097F95ED0B1ADF60408D31F91786CDA2818 +:10D19000B39CABE5A35BE5CBBC6C0F8319F585D1E4 +:10D1A000F806A783E57FB555CCB77AD23733C84E9A +:10D1B000AFEED68B4B2FC3CDB34E065BD83C9BB79F +:10D1C0009996925D53D73F6055F449F75749530AF2 +:10D1D000045C3B847D45BFC090427E41BDC4F1EC00 +:10D1E0009EEE513584A73D12F86C253CC435665C33 +:10D1F000DF4C311C7DB7505E14D2F2F99EA51AD7D0 +:10D20000AAF1ECACEE5976F2633FEC5CB807290763 +:10D2100093ECD9CC4FD78287FDEE3D89AE74CA938B +:10D220004C53EE3FEC490CF691BFBD6752AC44F74E +:10D230001970FC3B697C755F7B0CAEF466DE9792DF +:10D240002F75FE443E157BF671A2AA67EBE4DBA7BF +:10D250005C49E7F773C04AF1EC7459F8D5F04721FF +:10D26000CFAA5E6D92FC496CAAED33A6DB114FA3E9 +:10D270005A7EA9E47DDB35F700CFD6AF1E8CA35FC5 +:10D2800094987F563944BCB1AAFAF347AEC5F95712 +:10D2900061BC4FFEDDC2AEEDFB087F91F1FD607C0D +:10D2A000F52FE67BA3E333D732DADFCD771CDF73CC +:10D2B0002D44C769837181EA5F3E17CBE7D6A85832 +:10D2C000857C28FC7A645BEEDE35587FE42F0666A9 +:10D2D000D73727FDEAE8AD58BEF9B958C6F391240F +:10D2E000F0901D39B229CFEBC1064B74C15EB26F0D +:10D2F000B0258ECF693E7B32EFB72F517EF2B776E5 +:10D30000F643487E6CE8C27C46F78FE8FBCBA3B9B6 +:10D310001FB8C5BC0D8A5CCA2F14DE5F4DF52F24E3 +:10D32000737E42A5DFE127639C14AC7D05BE222BF2 +:10D33000B2DEE792E710DD5B5CA17B69BF847CF91C +:10D34000D508F706DAF7F2C7FFF3C389B89FDA17F3 +:10D35000AEFE5515AE6FD907A940E384E83AB4DFB5 +:10D36000706C6BB6907F053F2B5E8CF11E0CD32743 +:10D370002B3B1235E5A6AED1DE83617A68F09E7252 +:10D38000A3C4E7048D8A5CED37BADBED94D7A5FB27 +:10D39000A94C3F711FB584CEAB08FFF79918FF91D8 +:10D3A0007CF6A25D396756F33CC9604E23B9750B14 +:10D3B000FC0DDC97B789E2319F3D49F13B82B933DF +:10D3C0000AC3F9B377D51B9CE731897B8F31439F23 +:10D3D000EB77DA13B97D83F94B4D9E6955CB094D37 +:10D3E000FE675501B01F50D2662BBD89CE8714BA97 +:10D3F000DC9FEE7A8DF1DEF1C0ABBB189F4FDCF203 +:10D4000031CDBBD3C2F4835D4A3C16116F3598BF52 +:10D4100050E4EF698D7F7EE8B1BD4594FF38F4CAD2 +:10D42000B822CAD32E94FD877E9DC9F79CF6DF866D +:10D4300070CBCEF7392F1EB9DEA87B0C92D0438D6E +:10D44000B48F64BAFFE37AC7CE722EF4C3810D8520 +:10D450008C3F351F3D7064E878505DA73ABEBA3EF8 +:10D46000757CB5DDDFEC225FD06FF41791FD5F4175 +:10D47000E73061FBEA8FF717255AE8BB55F81349E7 +:10D48000580EE3B77FF5BC2AF27C6AF05C56C947B8 +:10D49000EDD3ADFD9911F9AFAFE321833B5CEF7E96 +:10D4A000CF732A75BDEAFDDA7EAB85FD9B937625A9 +:10D4B0001F9F0EE9D40EEB1D3EF2BFB7981CE4C7C8 +:10D4C000279A5C908BF86934FAF8FE9ADA2FD1E447 +:10D4D000E6EF9179F9814423D0BDE58154E5FCF76D +:10D4E0002B60BD4271E8169CB7AC56D7BCC512D2B2 +:10D4F00087AAFE2C1B87DF0BE81EA93EE42720DF4E +:10D5000094156BDB87F6A32DFF7BAEA06359B26E3B +:10D51000C838B92457C8651B74C8429E851D9DA88C +:10D52000E01D0DBF1CEED7AC52F4FC40BCD9430744 +:10D53000BB13B78A7BAB13F5BEED04510B404B1206 +:10D540005D99F489F1BAB4FA9C6CC81CB6CBE3D8E7 +:10D550002E4F50C87DB7D4CCF75B43F75CFD32C18A +:10D560008B21C8D009563D412403C34BC0C5702A46 +:10D570003433BC0CDA195E011D0CAF023F43F8894D +:10D58000AF0DD81EDC6E65FFE9F2253AB2CB65D748 +:10D590000EED97CF52F0353C3E50CB579C3B3EA60C +:10D5A0002AF77287C5CBD87CE67B152F26E24FEC95 +:10D5B0001703DE34829320C0E34C2646CEA678DDE6 +:10D5C000C6F77E6BC1C9E5BAB3C44765C0AD77176E +:10D5D0000C8197DAA1F9649EC22703B9C0F851E91A +:10D5E000F548AE8DCB2ADD30504C237B104D4FC813 +:10D5F000A07596C5D61CA7A722B73F5F36538F7A72 +:10D60000B4ACB4660DA9905FE64E15E589352FD30D +:10D61000517DFBF3978A72714DA9C1815EE8DACB27 +:10D62000665E82FAD9ADDC2737A311A07B6372B6A0 +:10D630003817762BF7CA4D72E65ABA2F66BA0D58CC +:10D64000DFB86300FCECD722B791BCB8451C7BB3B4 +:10D6500055D0AF3AD67D4B2ED933B32FDE8674B872 +:10D66000796DDD28B29BF718C5F89FA4DAC6BD8195 +:10D67000F83299C4BD5675BF58EF89C17240B2AD3A +:10D6800069C90CAD4B5DC759CC7BD7E9E6CD4F7767 +:10D690006F203D023607C7156314FBBE65CBC4344B +:10D6A000F430701D565E47202E774D0B56DD91EEFF +:10D6B0007A84C61B88137CF808D1297578E8CB7565 +:10D6C0003E943BC4F781B5DFBCEA23BDF4292E04A8 +:10D6D000C7F94DAEFB715A47932E90518AF4FB4522 +:10D6E0002C7A000521BE96909873100F6D4EF01A9B +:10D6F000595E947736CAF9992A17038B713CC44F47 +:10D7000099CB558BEE2254CC6E7E9360A5BBBD1693 +:10D710006B689E17683D4D72B081F8E468E207C6F9 +:10D720004F596EC70AFE54F459F7B69EDBC688A25D +:10D730000BC2E4B269DB89AFFF86746F3A66715041 +:10D74000F3903C3EB6469CE75A34FA4695D3095DC1 +:10D75000263E389CB8F5A2C5D46ED207BDD9A4B771 +:10D7600027F706DAC87D1EE8DE3B46C889EAD77F80 +:10D77000239D8B7DF9CC8CFC914010F9235E9C831A +:10D7800073FCF48A38075FADE43DA9ECE17D8B784A +:10D79000548D3B57F6BC2DDE8579F06F05BD2B12FD +:10D7A0007F963E71E355C46F91EF8BD478B449698D +:10D7B000B7A2D77B37ED27F2BD5113C5A345C3BF31 +:10D7C000376A7AA296E3D1C8F746BDB94AFE4AB194 +:10D7D0008FA0F8A14B9436B43F0BC78746AF09F72B +:10D7E000B6FAC9350E2B95D32D0ED6C7573D0EE18F +:10D7F000EDE18964E619559E97AD93D8BF56F15A6D +:10D80000FCBCC949EB287E7E14FBCDE8EF8B7BE99D +:10D810004A3E91DE12D07B83CD89C12CBA67BAB95A +:10D820003BDF41FEF81F5A9DF00F43687D6A3C5074 +:10D8300027BF544BEF878E2DC2380B3FADEE79A634 +:10D84000CD8CE5D5EBE95510A584F313C8AF2ADFDD +:10D85000298397C601EF43D5083B153937A5E9C0A1 +:10D8600016868F18DB08B00D910F3029F48BCD4F41 +:10D87000D2D4C7392ED0F44FA8CCD2D4B7C588F7AC +:10D8800032E071FA0B2A42EF48129D3FD1F4830037 +:10D89000FEAD08BD17B9277EEA4E7E4FE26FE03C31 +:10D8A00045F265259AF62679AB4CFC5DFDA55E43F5 +:10D8B000CF9F52A61BF156B91BFD1C9C67429FB619 +:10D8C0003E26E001EA17B35BAFC94B986CDAF285EC +:10D8D000794A9E622C8CD5E42906F12EF8FED86197 +:10D8E0001DF34505E4FCAABA8CF06C00AF2D1A6F4D +:10D8F000C740F85DC7C65A1CF4966A42CFCB32C9FE +:10D9000041AA4B8BFF51B3B5F81FEDD6E27BCC5249 +:10D910002DBED39BB5F8BEB0458BD74C8F166FD9B3 +:10D92000EB2668DADBDB6B34E5BC8D5768DA5FE445 +:10D930009DA1298F7BF17A4DFBC28E859AFAE2AECA +:10D94000E59A7A95CF86E383F1BED511FCA603DD77 +:10D9500069F8A074E7CF35F3FD50F49F9FA7E80561 +:10D9600085FED72B76E5DDF8C3F792B84E8B157A96 +:10D970007030DF506DE078EE3D5B726D1CE905C5DF +:10D98000DEB9147B07394F89B255941D7E71BFA251 +:10D99000649FAB36DE46F72CC4FD8A8AC3EDB50919 +:10D9A000D43EE21DD6F44A4973DE1DF92E6BA667FC +:10D9B000AD9C20D1BD44713F31F21E84FA3EABDEF6 +:10D9C00019A339271FEEBD969A5FC278018C142FD8 +:10D9D000E8CCFC3E31DA1F726C94D95F73B3FFF66A +:10D9E00067C9CD79A76BCCFE0CE2EFECB1EEF5790F +:10D9F00088B7A33A878DFD3DE5FDD6006D8CDF2FFE +:10DA0000F5CCA43CE90086BB94D7D4DFB36326BD34 +:10DA10005BC4E55B031522ACA63F8FE6B91FA4717A +:10DA20000E48D6BB4BB1EFBB133ECF207B66A27333 +:10DA3000FE123EFF7E382FFCFC7B14EE0FF56D408E +:10DA400067F3F079EECF258E533EA7C1AAC2E477E3 +:10DA50009D41794F2AE2B6B90ABED4B86D8E32FF25 +:10DA6000011C6229EAF3B95D7F66BCAC48EB53E266 +:10DA7000BD668715C7BF71ACA584EF7B394B1D22EE +:10DA8000DE57E3B831F2F7B1B367BA87B522ED8854 +:10DA9000269E86979287CC5746E6C542FB16E31F23 +:10DAA000581FCB76E8C0FA74CE3F86C63FCAF985C8 +:10DAB000B9CDDAFBDDF35B3ED2F0DF02CF279AFA75 +:10DAC000404AD03006F71F7875F4D41B107FFDAFA5 +:10DAD000982A289E45BAF5E49587C60FDC97778982 +:10DAE000F01BCEB4CFCF791DBDCAFD5A759FFB5B2D +:10DAF000F77139D01A88B8EFE4D1C4BF2A34FE09CF +:10DB0000F2C98F0E4A231C43E57366E78B38A95789 +:10DB10007977DAABBC3BED55DE89F62AEF427B958F +:10DB200077A1EABBDD5E099C74BF648EE47A6A81EA +:10DB3000C4EF760FD13E9B96078BE85D635371600F +:10DB40009E24F3BBDD23F47D8877BB459295F46971 +:10DB5000EA35F46EF7F008CF51B2D8D9F989D75029 +:10DB6000BC70D828E4A3F4C56F66D27BBDC753DD73 +:10DB7000C789BF3F95641FF3F3EB129F2B8333607C +:10DB80009C7116EF7ABFCB13E73427F3C4B9890A27 +:10DB900047E60BBD564AB09CE8726F2EBFBBDA68F1 +:10DBA000E27757389F5317761F22F27D5CC91F4DCD +:10DBB0003ED21F6ADE27215F9C37D3BB395A67CA22 +:10DBC000FD26F16E2EE0CFA07776740FCA45F2BD28 +:10DBD0001B9CE21D5EDEA6F0F73009F9CA3DBD458B +:10DBE000A079A7B7B2E7C07ED227AFE5B993F353C8 +:10DBF00043EFC756C66F677FAF20DFC6F3E27A797F +:10DC0000FFA817EE24FA9CC77C61567E79F4FFD7F3 +:10DC10006038BCF52FF63F5A90197AF716F6DEAD4C +:10DC2000203F2CAFA7AE3F34CEE9E542CD7BA9E53E +:10DC3000438FDD934B72867411F948599A3F63887C +:10DC4000FED3F305FDEF4F774DA0F997378BBC60FE +:10DC5000886FDA6FF998E8DC6319F23EBFDA3F7239 +:10DC60009F2BB7F5303E709FF3687F61FBBC8CF053 +:10DC7000A5EEB3BF7BEFA305B673DFDFF77D776E4D +:10DC80001A81716DD2507976B43E617E9949ED3F2B +:10DC900056AFED8F0E39E5B1BB48DED16FE954E2E6 +:10DCA0001EB2CBC417AA5DEE54E22029B083ED0268 +:10DCB000CD4B7271B7E461FBA8E63BDA24B47F94E4 +:10DCC0005770AF617B215F6871105F7722EFF94970 +:10DCD0001EF4CE58CE7347C4D73F8B75DF4478BC53 +:10DCE000F9AF35A328FEDEF2972B94384ED8AB72ED +:10DCF000853FCB697EDA474102F36D99B2BE0A7364 +:10DD000033FBC955E091455E43C993ACDFC1F1DFF8 +:10DD1000FF011A14AFAAD043000000000000000069 +:10DD20001F8B08000000000000FFFB51CFC0F00374 +:10DD30008A739418187A351818366B32306868313F +:10DD400030883120E46885AF7153A69F9B9581810F +:10DD50001788F981581088D73331306C60225EFF04 +:10DD6000115104FB9E2003C351207F1990EE1466CD +:10DD7000605805641F03E22F40BE801003830C101F +:10DD8000FF1561603005D2C1406C03C4C745F19BEB +:10DD90007F82807CBC082ABF1B8D9F278C5FFF255C +:10DDA00011FCF20F08C863C33216E4C74722057A94 +:10DDB00007023729A2F28FCA33303C546060D05139 +:10DDC00082F09B91E4ED8062C7E421EC2992C0B817 +:10DDD00007CAB5286237772A50FE0450CE4B8934E3 +:10DDE000F7DCD341E5AF3484D000BC3E14E4A80393 +:10DDF00000000000000000001F8B08000000000071 +:10DE000000FFE57D0B7C54C5B9F89C3DE7EC6E92B4 +:10DE1000DDCD262121BCC22601440DB8400CA04115 +:10DE2000370F5294A8E1A1A2226C782421EF22F6A8 +:10DE3000621FBFDDF088C4521B1FC5D48B7651B062 +:10DE4000D18B3640D058175C9E458B6DE845A0D5E8 +:10DE50007A13405E06B240A5B645FDCFF7CD9CDDF6 +:10DE6000734E36266AEFFFF6FEFFDB9F1DE6CCCC35 +:10DE70003733DF7CF3BDE69B8964BE91D88713F20C +:10DE800025FC6E25E451891092184E9B3C93C69F49 +:10DE90009409B1ED7E24EA3B99840C9E6B7046D1C7 +:10DEA000A25F08644E4B0621C9658D7546FA3D791F +:10DEB000917DBCE808C319987CE4BABD09840C7252 +:10DEC000D3F66682BF2FE97F3FB737C69174C87912 +:10DED00085A231E1FA4A9ABC48FA7B87AABE9B1414 +:10DEE00075A6DD48FBFB51FD20B785901FC3784622 +:10DEF00042A9CB40B2E8B8785D6F2EFD3F3A0EAF35 +:10DF0000CDE85B2910221A1CB1442424262348A002 +:10DF10009DBE9F673CEDD74908A736AAC84AE74986 +:10DF2000C8B49608F57289807888CD76257BE97823 +:10DF3000577D2EE2BC570D22A49DD62792D34E6862 +:10DF40003A95C461BDC72D2306427ED5AE3F120768 +:10DF5000851B9B19245E15DC060F210E13C5AFC768 +:10DF60008CE92A8F9DA7C9C4710D21AB3D0E4C577A +:10DF7000794663FAD8D027DB7306D0F90C32D8E99A +:10DF800048488363A6DD91118627C72D30E73809FD +:10DF9000C92629AEC4545A2FD140C84D84DC42F35F +:10DFA0007523081949EC8450FC3D93BC2CCA9D0193 +:10DFB0007907E6450371C37C6332032E91E22DC6D7 +:10DFC00069CF951CE1EFF81B80DF5F782C15D6C177 +:10DFD0007D1BCCEF19E2ECF0029EDD46E7265A7F6E +:10DFE000A5EC4C5E4AE18A46DA2E83ADBB94101E46 +:10DFF000DF4CC01FED8FCCC9D5ACD730184722B449 +:10E0000073DC05EB6471B2755A097415611DE6F293 +:10E0100075586577D919FD384924FA11ED5AFAB1C6 +:10E020006468E98F7EB19FBA9EE769BF4D42ED3BC0 +:10E0300053E93CBD4B0CCE4DF4DB60A15100F80A16 +:10E04000BC25C480FD2AF9416552A063B41A9E170D +:10E05000CBE9F7F60E73CFEF2D06E252E872532AA2 +:10E060007C77C4CEA0E3266647EC4C6BCFF187E902 +:10E0700024D925C940EF0E4C1B0447AC00E37C4774 +:10E08000249B049C7F72A4F6FFD3ED08F1E17A375C +:10E09000F07554DA513C203D791F8B463C88503452 +:10E0A000390CE7171CCF17AD454F434A48E3685872 +:10E0B0005F9A5F87F463A6792BE69BB0DC1ECA3FAC +:10E0C0008BE5C9AC3E5D5EBA18BDE3555917DA6EF3 +:10E0D00003C29142705E44389650BF9B303F2094FB +:10E0E000FF25D61FCAEAF7B71F25EDCE0D9EC2F950 +:10E0F000BF2E3B009FC2DBD6C0AD942E0E6E107CAF +:10E10000269A0FEC8C41FE757EFD0C9F89E267D745 +:10E1100038930BEA9FDF9883F9BCEDEFDB245A5E5E +:10E12000B55D94206FD879D6D641F15B636A7FFCE8 +:10E1300066FA3DB85D242F6077D3719F9DE2B448A5 +:10E140003E63F9922896ADDAB06B1EC02D6B339109 +:10E15000280AA7EACDD23B6FA6F9D20332812A550D +:10E160009BEA8C83697E894F6881FC8A9D1F603F92 +:10E17000DDB9A40CF6F739E05B942F75DBDA93EE8A +:10E18000A6DFCB7D5B0AA07EF966C1094B5CBE7E33 +:10E19000D78700BFBC551E2152F815CD31C4A1DA76 +:10E1A0002F79DB17DF09E3AD7A472694ED91B2AB07 +:10E1B0000F199118A44623E0B56AD31346E09BE7F4 +:10E1C0003C07B01F059F552FD37E68BBEAD70427B5 +:10E1D0004CADDAC0F8CD8537A3E6BC688179D51996 +:10E1E0004741FB371F3542BD525FF1EB510E18DF3F +:10E1F0000663018C73FD0663898A6F5634FF5633BC +:10E20000AE534DE903DD19BDAFE739CEB7957C3983 +:10E21000154048DF92CF3843C5879E33C421FD5750 +:10E22000348BC411811F78DFE7FB608795F103BE53 +:10E230005E4BEDC01AC2EB75C9CED74F0A66CD88CA +:10E24000C0E71EE7F2A391CB8F27417ED0F4692E61 +:10E250003FD671F9D1E471E2F7673D93305DEF711C +:10E2600061FABC671AA63E4F11D67BC13307D38D26 +:10E270001E377E7FC9538669B3A716BFBFE2598E8A +:10E28000E9668F17BFBFE65983698BA711D3AD9E8F +:10E29000264C5B3D3EACF7BAA719D3364F0B7EFF39 +:10E2A000B5A70D53BF2780E94E585F9A063CED98FD +:10E2B000EEF61CC374AFA703DBEDF79CC1742DC74A +:10E2C000BB2D9BE448146F36174139185FE8CA919B +:10E2D000693EBE88E593E67A738C349FE4A6798A1A +:10E2E000C7C195811C13CD0FAE65E5293F24B966E2 +:10E2F0009A4FF1B2F2B4B5AEDC289A4F6B64E5A345 +:10E30000D67B73A3697E948F955FB739901B43F3D7 +:10E31000D7B5B0F2B17E9267A1F9B101961F7FD057 +:10E320009567A5F9F1ED2C9FF5A137CF46F3591D5F +:10E33000ACFD4D5D81BC589ABF29C8CA6FB94AF27D +:10E34000ED03402E0B98CFB5E4E4C7D17CAE9DE53C +:10E350000B86164B8E08F4B753EE5808227C86B015 +:10E36000D125517EB3D3D8F110157D64A1F0AA4B0D +:10E37000A2FC3320934550FEB0F03A96078C641906 +:10E38000943F2ABC8DE5BB650796FF5C38C0F2461A +:10E390000796FF877008F37B651796EF10FEC4F2AF +:10E3A000461796FF5E3881F9FDB21BCB3B852E9652 +:10E3B00037BAB1FC49E953573EED2FDFE09E2EDC22 +:10E3C0000872DB5D8672596A49067E59CFF9FF04EF +:10E3D00040062DAF1F644439B8F3F3AC174581D321 +:10E3E000F600C897BC04FA0585335B48047D82C2F9 +:10E3F00011FB8673CB179334706EF9A24C81F32016 +:10E40000C289EA1F9C9D5FDCA41DCF17E50A9C1200 +:10E410009C97B57FF3BAE5CB6CED78BEAC54E0D4F5 +:10E42000209CB8FE8D27204FD4C009C8A50A9CE5C2 +:10E430000827B17FE37119276BE0B88C4B1438754E +:10E44000086750FFE0048C376BC763AC50E03C8634 +:10E45000781ED6BF79B94C53B4E3315529709EC2AA +:10E46000F1A4F60FCE6EAB163FBBAD21FCAC473826 +:10E4700023FB37AF5C9B163FB9B6107E36219C6BF1 +:10E48000FB0767B74D8B9FDDB6107E5E43FC8CE9C2 +:10E49000DFBC7263B5F8C98D0DE1E70D1CCFB8FE86 +:10E4A0008D676FA2163F7B1343F809209C1BFB3737 +:10E4B0009EFC242D7EF29342F87907E14CEE1F9CDE +:10E4C000BD495AFCEC4D0AE1E70F08674AFFE695A3 +:10E4D0003F508B9FFC8121FC7C807072DCCD4CA96D +:10E4E000A470ACBDC3D93F4C8B9FFDC342F83989A2 +:10E4F00070A65238E97DC32948D1E2A72025849F20 +:10E50000F308E7B6FEC1D99FA2C5CFFE94107EAE38 +:10E51000209C3BFA37AF82E15AFC140C67F8B955DE +:10E520001A877286CA4E27D8E7DF199AE31232C1DA +:10E530004E6279D1EE24A0F7888A3E43DA5D22AD9F +:10E540006FD91C37FE31A2D66B728D064ACF56AA00 +:10E55000E5A9F59AD849D11A3D2ACE15AFC9274C5D +:10E560001BACA99F5894A6291F38E73A4DF920F70C +:10E57000784D7E48D94D9AFAC36A7335F9E1CB6F6D +:10E58000D7D44FF5CED4E4D3D7DCAFA93FB2718155 +:10E59000A6FC9AA6724DF9B5BEA59AFCF5CDDFD7BB +:10E5A000D41FD3B242537E43DB639AF27181273585 +:10E5B000F909079ED5D4BFB1FD054DF9C463AF6815 +:10E5C000CA27776CD5E46F3EF36B4DFD29C1DD9A08 +:10E5D000FCAD9FBDABA99F43FE53AB6F9B3FD0D417 +:10E5E0009F6A3FA129FF4EF2273A3D556B1FAFCCE2 +:10E5F00021CCAF3288D9AF01AB11F3C6C11666A7E3 +:10E60000584B1C2729FD18772F740CA0F4033403F2 +:10E610007651CEE0B26B3AE8F7EFDDE4BEC64EBF0E +:10E620007FCFE8BEC11E41BFA1F4269064481D06FD +:10E6300048F5E58FCA8CDE73875C1DD549DBD7189A +:10E6400082A3E268FE2331E73EA0C7F90603EE830A +:10E650006891D442BD681341BBE9D1D4AC17BDAABF +:10E66000FDB06618D5338430DC35B23B19F528C3CC +:10E67000F83AD09BEA87D1790D2664D18A71BBBC68 +:10E680002368FB6125C9E08F3019993F24D4BF91DD +:10E69000F69F81FD2F81FE6B7AE9DF943649D3BF67 +:10E6A00039A54CD3BFD948FBB713F290E126DEBFA2 +:10E6B00019FD36CB564CC6FE4D2965D8FFA3466AD8 +:10E6C00077A9FB8F0EF5FF8881F6EB3130BBB9C718 +:10E6D000FCD36ED2CE3FA55C3B7F239BFF4A432EEB +:10E6E000EF3F1AE7BF6A450E9B7F4A399BBF89C13E +:10E6F0000DF56F0BE1BF01FAFF692FFD9BD2B3B59A +:10E70000F31F5EA99DBF89F5FF94E176DEBF05FB8F +:10E710007F7AC56D6CFEC32BB17FA3C9ED04FA31BE +:10E720000E89AEF5D1FEC9506A250D0472A1FD40D7 +:10E730003A3A1EFD08771AD2701CDF8B66F47625F4 +:10E740009AD21BF2332FB3C37D947352BBAA9AD3D0 +:10E750007AC5E61C23F03D2C4F2264311FEAA23615 +:10E7600011E99B3C6DF28DA4E3BDD0267A21BFE870 +:10E77000E9293EE0AF352632BF08DA492400DF3F01 +:10E78000FED99817D4F3D2A78B1BE55391FC45DE35 +:10E790005C32BA968EEF0210812A7F9CDA71601883 +:10E7A0007F48ED1E42ED9F1332EBEF236AEF41BE2F +:10E7B00083DA7B6838933AE657F3BADE1F41C75FC6 +:10E7C00044949F0BE7792F6E290A4F62FBF7F85AA2 +:10E7D000C107EB317F790C457E783CC5DE044DBE28 +:10E7E000C6C4EA076F137C2F0808C30DF899C1E16E +:10E7F00011182FCDCFB1B3364777DEB15FB0D17DE1 +:10E80000B466085D8B309C59C4250FA4EDEF5E56AD +:10E810002C836BA75D1086819FB066A14C02683780 +:10E820007B134906270E3ADEFBED0CFE0C977C525B +:10E83000ED479B239B5D45743C738A451CFFAC6987 +:10E84000DAF23FED8C7119C6D274CD53D8CFDD45C5 +:10E85000DAF27BE768F3F7B9B5792A576590AB0F21 +:10E8600094E9BF53B42481DF31F41B00E37C90E3CF +:10E87000E1C15AD9AB59576A761B95727084B809B1 +:10E88000CE0BDB8B3DEBCF5FAECD177BB5F9856B48 +:10E8900074F039DD9CE2EB7F1CE883A6A7813E285B +:10E8A0003E4F72FA08F3552D7DDC139A06A30F65CF +:10E8B0001EA724B604A7D633FA58DC1813991E8A6B +:10E8C00043F4E052D397420FF3383DFC99D34369A8 +:10E8D0009396AEEE23BED5C9B4FD036B77E13A1D26 +:10E8E000118A193DFC40A1870E0D3DB8393DE8D78E +:10E8F0006F1EA787798F307AD0AF6707A7878EA65C +:10E90000CB3249EBB9AE741D3479BA0EBA75B7A3E0 +:10E910001F8AAE47447A58109A379D38CD2FE46548 +:10E920003DD68BD30396A701DA09E209DBA7F7AC42 +:10E930004FF984265FDA1479FD6BDA36AC3DA9FA1B +:10E940005ED5F2F25AB57FBBA2798B26BFC4F7A67B +:10E95000A67E69D32E4D7E71E33B9AFA0BD71CD26B +:10E96000E48BBD7FD4D49FBFBC5353FE60ED594DA3 +:10E97000F903651735F9FBDC7FD3D4BF778EF0132D +:10E9800075FEEEA2A89FA8EBCF9A16A7C9CF700D6F +:10E99000D2D437ECBCF62EA0C783EF8B04F48F4F94 +:10E9A0009DA7D1FFF9A95376429D931E07EE83538D +:10E9B0009ED1989EF138719F9CF34CC2F442DB1EAD +:10E9C0000BC8152A474BE0C8A674E596BA35D9207E +:10E9D000D709CADF8A956FD4798712B21494638AF3 +:10E9E000EFC22623094C204400E1C4C7151455E5A5 +:10E9F0001D7D9437514191D0B3BCB023F2F79A27D3 +:10EA00008B87DB239C7F84F73519027A52772FE7B7 +:10EA100024950229527F276405F281AD5C4FA93409 +:10EA2000327E51B975502EB1413E30AAF6ABFA6B29 +:10EA3000A19B6C20D049BA663F97365DAFE1F704E1 +:10EA4000BCCF89406F1334DF2B9A6FD6B4EBDA2535 +:10EA5000E2B8AB819750B9FD2A297A52043E15D805 +:10EA600093326B0C8CD3F514E6DB12518FECF2343D +:10EA7000AF85F3C7739E164CCF78DA303DE509AC0D +:10EA80008573C0939E03981EF7B463DAE13986E973 +:10EA9000479E0E4C3FF49CC1F44F9E20A6C73C9F5E +:10EAA000617AC4437E02700E7BCC98FEC163C7B40A +:10EAB000DD938CE9058F0FFB51F65D5F747786CB94 +:10EAC000ED73407F11E86CBB78AC6ECDD0309DBD4E +:10EAD000B9F223A43305CF854D264E0F491A7A0883 +:10EAE00080ED7723D04B1FE54D32A7C3DEDA472EEA +:10EAF000AF79E1BF87DEAE7C4B7A0BD3D3101D3DDF +:10EB0000A5F7454F1FAAE9E98AC1CEE420A7A71FB0 +:10EB1000F3736B7DBF51123BA70CE977AEDB0C8022 +:10EB2000AAA5FCDC84906998BFC4FB5E49C1B5A36B +:10EB30001EE81B0D72EBD2E8BF8F8273874BC7E8CC +:10EB4000E2A7F63E3F3D9DF48E7717DA43253EBAA5 +:10EB5000E80911C61BCDF01A6520D3C878421A46C1 +:10EB6000BEE45C90817989C4437B9F734684F33A09 +:10EB700042756BC06F5F785D69BD3216E09D7AF6B5 +:10EB80001F59905EE1FA75F41E11F57C1278D109D7 +:10EB9000F80DC925933319FCF3C191463BEA09648A +:10EBA000BA167FDEDB35F86B4855CECF1B93117F4D +:10EBB00023AE8C1AD40FFCF5C5DFFBC2E70298F731 +:10EBC0007F033EFBE28F7DF145E272BCD646E7DF74 +:10EBD000BD73CCF8C71CC007BF1ADFCA799C7E3C46 +:10EBE000F992F4B5E8B83B49A1E3F614885BD82460 +:10EBF000DA11FEA5D66B62615D4270FA584FE1ED05 +:10EC00003FA780BD7F3E550B2F4B07EFD281176D7D +:10EC100060772D4D5ED87032C23A2869554B5D83BE +:10EC200045AD87B669F3971A85692D382E47ECEC08 +:10EC30003120276A1B18DF5E8EA90267697209F608 +:10EC400073AE393D96D97B3EC60F36C721BF38E734 +:10EC500029C3FAFFECF1F40647190F21ADE484193A +:10EC6000F8312D4BEFBD7EAFF42CFDC588E7DD7E7E +:10EC7000F90AE88966FADF9760771009F30ADC9AE7 +:10EC800016D16BBA01BE6FD6F447DB399433E22F4D +:10EC9000D3BE6ADF48E49442B7545ED483BD80E7B4 +:10ECA0009B4B1AD47A5955CB7735F99AB6471AD473 +:10ECB0007A5C05FC83F25F522B484037959C8CBAF6 +:10ECC00025CB1A818EAF18824F808F08AC5E95B924 +:10ECD000C3E8A69FCEB7B275EB6D7CE73CE65488DF +:10ECE0003B283337E2397259CBB5F92067CEB7AE3E +:10ECF0004C02F95B215EFA5E5184F6BF94042E5FEC +:10ED0000E4A056CFE7F441285CD5BCE9CF12C21786 +:10ED1000CD7719985F460FB78DCB91BEF053BDF9F3 +:10ED200050C1CD8E9E78AA6EBB6874235FA4FFCBC2 +:10ED30000AE349C15FB154D426D171973777A2FF56 +:10ED4000E28CEC1DF583AFE0973DE767493E15A3E4 +:10ED50009A9797B4433F0B26F18E88E3DE0F281F66 +:10ED60003FFB5B99001F225769AD2C74CD70BBC768 +:10ED7000400C5961BB67416B4521E0FBECEBD3D103 +:10ED8000EE5B448A6CB80EA4310BEC9CF3C480712A +:10ED900055E7C91F6C1354EBF0B164E478A65C30FE +:10EDA00089BB3410BE7B10D85FA639F5EDE258F868 +:10EDB0002E297690F025CA15B780F11773D8772FD2 +:10EDC00031D701FD527B4A63AF517B4A93A7F6943A +:10EDD000265F426626413C45C9D332F10988274D5A +:10EDE000F941C98EE32B25B5F5A01FFD9CFBE1166B +:10EDF000D8893484CA87AA379ECB2AA6F3E9929889 +:10EE0000FF4B890F584265C5205A5E5EE633BA2C27 +:10EE10003DE777A275C23D94F3033C160770BFD15E +:10EE2000C7E26B8843CAE2AA4F5AEFF31FD82ABA47 +:10EE3000A26C508F7E57C69BFAF5E7AF9F2F214FEC +:10EE4000E23CCA9B67601C568F78073E1FB9597019 +:10EE5000F922EC27511634F12E0932C39FE2D71A5A +:10EE6000AECB5F0F7995DF6BA2AEFC1BF39701442D +:10EE7000C35F8A25F7703991F113C0BF2005717FF8 +:10EE80007D63F8C93DE05F2FDFF84F843F54BBEF4F +:10EE900029FC89FFD4F18FE831FEBC48F0ABDE7865 +:10EEA000F57588772CFFD5CF6C84EEB7B35263929B +:10EEB00093AE7BE5A6D53617F01DC96B837D71D661 +:10EEC000274E8B440FDF9779DC1F715904F0BBC2CA +:10EED0003F29FC73AFFCF84EB0A3AE6C92EDE84F47 +:10EEE0006D36054C949EAB5B971492B198EF64F924 +:10EEF000472F02FDD7B4C9C7D5745AFECB9F254111 +:10EF00007C10A5942186644803689F546FFCB80068 +:10EF1000F48D1A12C4FDAA6F07FD7F168FF2B0D8C8 +:10EF200018DBB31C1D3449D09EFD6A5A7F7C51B456 +:10EF3000417ADB69E06FD4B244BF90BE5D19B73B44 +:10EF40002A64EB00E4AB13C944E0AB0A5E888FD9B6 +:10EF50001D2B5F7E666C271D57D7C6DFDA0415BEF2 +:10EF6000147BE952CBC25FFCDAD13B1FBF40F7A351 +:10EF70005ABF55E494A38DDB4B7E9656CA011BC441 +:10EF800073556E909D5EFAB9F2D5175F7A16FCD96B +:10EF90007F34394752F815AFEE3B7213CD576C9161 +:10EFA0000714B2695884A4F0FAD4D0FF968F0FAF3B +:10EFB00047F9B67D46C718F6FD87F1E175A9D8B2C5 +:10EFC000CB48C6F4C4475ECB2E638725C2FAB4741F +:10EFD0001680FEB7F2E5BF1A81EF9DDD299081A969 +:10EFE00011F0B9611FEA8780275C4FBE5EA1F5D39F +:10EFF000D5AFA1EB027246BF5EFA7A859CBF005C7A +:10F0000088B3A1F4FDDAAF210EEE4F2627E0A1EC84 +:10F01000B5876C309FD3522DA3F3E7562701BF2B42 +:10F0200093BD49764CD9F7B2E71F46FA2B3DF470F1 +:10F0300012F357BA061950767A07C13C17AFBF1BB7 +:10F04000E75942DC488765CF89453E9A7E2A916917 +:10F050005B22EC934B7C9F9C7E812E2E9DE7694525 +:10F060002EFC41E472E1BBE80F7D98CF856A909851 +:10F07000FFD4CCD6EB806CD0C8D110FD6E7C14E5EB +:10F08000C7B961AE8170EE561396172847C4435333 +:10F0900007B275627207DB51B99307DFA17EBBEC43 +:10F0A0008A1AAB69877246E97F19EF9F8E3B1AF483 +:10F0B000B7D34991ED91E146850F503D434567AA8D +:10F0C000FDCEF6FFC606B6DF95FDEF9B310DCAFFFC +:10F0D0007298ED23680772978E2B3010CB77CD1680 +:10F0E000903F984820D23EDF28F37DAE2DD7D30B3A +:10F0F0001DBF24C4AAE806FA89C77540795FF234B7 +:10F100006DAFE2A335D0AFAD275C651F97727E70FF +:10F110001EF8C1F5617E40D627F62B5EB452F6BDCF +:10F12000F42CEC5FBA5FBD0ED8BF7211CCFF93CD4B +:10F130007B8EDC4FF7ED272DCABED5F255FDBE2DD7 +:10F14000DBFA30C69FEBF7ED27436B49C47D4BBF1D +:10F1500047DCB7433BFE47F8AA82C724A396AF2AF1 +:10F160007CB2377CEAF9E416D98178D5F349FA3BC9 +:10F170004CB27AD2A342870AFD95FF47D570E0478B +:10F18000213A55E83044A70A1DEAE7ADC5A3BEFC05 +:10F1900023F02D527A297A53C6F3954A3F8B03A662 +:10F1A000EDF60FC9447CB950CC91C6FD4306A8F3D7 +:10F1B0003E5DBE4557DFA5CB17E9EABB75F95A4D51 +:10F1C000FDCAB63D46827410D0D41397FF3B393147 +:10F1D0002112DDFA98BFA1F5A211EE39D45882D8D8 +:10F1E0005E5E41BC101F19DC21E2B95137C5713D8B +:10F1F000F83736A7FABC948FAC8E627E856E7BD0D2 +:10F20000164FD3D5712C1F4C34D6031F54BE07A301 +:10F2100098DFB1BB28688B53D95B9D7E11F9788745 +:10F220002FF2BD0D2A6970DD3B7AB9D7A19C8F758D +:10F2300047DBC6627FD1293EA0C7A9A2256539F860 +:10F24000A11A4527E8EC8BEAEEB5C17955B73FFD29 +:10F25000AE39F4FBE27744168EE37549835476D0D9 +:10F2600019E25D972D405CF05AA49F857E66172DAC +:10F270005A1B793F94F37625966546E0BBD40E3948 +:10F28000AE3EEF51E094ADD77DF74FE7FBA611ED11 +:10F29000FFF28DDA7237B79F7F64E4FC671C19C7F1 +:10F2A000ED57E6BFE17C7BAA9871D71CBA3EDD071B +:10F2B0004462A2F94B7E11D7E7D266C107FE37E25E +:10F2C0004DC4FD574D8246F57D882ED85FD7F4CECC +:10F2D000C7BAB6FF39EB074047AF7F30F6DF69DAD0 +:10F2E000F5FA1F47BD05F9378EA67C407AD6CFDBED +:10F2F0001985F102DD3BAD48FFDD3BDE4BF901E452 +:10F30000DF3439619CDD3BFF3A16E8A97B85A90C07 +:10F31000F860F730E6BF5DB9E3AF633B50FEAEC2C5 +:10F32000756C361A999FC9FF8F8FE0DEC2253F9D0D +:10F3300015E8173CAEBEE6D7513E82F0FF9AA5BE57 +:10F340000FF46DE753CDE343BAAD64CE56185F1C9E +:10F350008B7FA8796BF28B75B4FFAAD65DC685B496 +:10F360003CEFEDCFC7621CFD56A6375D903B9E87F4 +:10F37000F8876DC6EFAC94299E2FC026A346F65D94 +:10F38000A63579B08F7AE2E573F4A7F5171FEF1A67 +:10F39000997DFDAF8F0FC1C5F89FD5671660DE7FE1 +:10F3A000FBE803F4839A902E95F97ED25287FA4CAB +:10F3B0005FF33EFBBF860EFA3B6F21D09F799B4DDA +:10F3C000FFDAEBFDB8D181EBA2DF073DE97CC7F79F +:10F3D00030FFAAD589E3ED27BD8F36FD3FB6EE5B42 +:10F3E000E9BADBFA9EF777FEC5E7DDFBBABF338FDC +:10F3F000AFBB1DCE536BDEFE1CC7F775F95CE9FF92 +:10F4000052BA57F4FD7643AD3D938E6F0E69B482C8 +:10F4100062715FE2254BA603A2702F0FC0F83B3844 +:10F420005F8D6057359998BFCD241858BCDADD82BE +:10F43000E247443BEB4EAE5FDC39B40CF5903B5DEC +:10F440003F417D8248B5ED39B47E7BEE4227C66AE6 +:10F4500092F1C7DC909F3D85E7B5F6E6EF04E21236 +:10F46000A87E7F67EEF403A0E7DEE512510FA62920 +:10F47000EABFEFA714B0EF93B4F6D07D6E6DFEDE59 +:10F4800039DAFCDD1CDE3D848DFF9E22C1077E58EB +:10F4900053CE5389E097352D9689900A7146B5ABC6 +:10F4A000C1EEB8BB48DB7E1928672A7FE337C5E386 +:10F4B0006F43785C8A78213922DE03ED138F7CDC80 +:10F4C000EDB3C7F920CE9A484E86C77BAA9CE83791 +:10F4D000E7F6B8CCDBCB9635EDB09F659D1DAED879 +:10F4E000D3BDE19B70FB1CE1A485F12FBB44B4CFDD +:10F4F000659D7DAEACCBD75D0F651DBFEDBA3C07FA +:10F50000EB7263785D865A5C04F6ABCCED877C8B3E +:10F5100093E587161176AEE8C3FAD20017F1668438 +:10F52000E3D197988B2BE09CCC3C5A407FC85D6B15 +:10F5300045940FE60C01C7553449C6F8E38F0D45D5 +:10F5400059B0DE851326567F9F0DC309F85CC2F1C2 +:10F550005E426A517F2557BFFC323B0BCE2508EA3D +:10F56000BF4B5C84DC41EDB8926C21100DF16A1246 +:10F57000F1C68E073FB9408E6BFCE4DA3CFC6E4965 +:10F580000AC3E9AB7E6FFCE59F9DFE17E567C729BF +:10F590009174423A12BB97D476F77C3FC3634DA572 +:10F5A000E04B43BA0BC8EAFBD30566B60FFEEB8708 +:10F5B00013904FE6FC744C2CF30764E27DC41A6E82 +:10F5C000375CF23A62C10F76C99FCECF73F36C6A93 +:10F5D000BEAAA487B81DFE9F109748D3EE7CA15108 +:10F5E000043B8B04D1FFEBCD8FC27BC5FA76A3CC55 +:10F5F00006BEAF6BD12F003F11EEAFF27994D2A6C9 +:10F60000B1F1AA755B7BC759696CCF7580DF71D585 +:10F61000F9DDB7C52FD8FD80D743511D054511E64B +:10F620003B89E3AF70F7DFF0FEEA4C7FAA0C7899D4 +:10F63000992F6ACEF99D66EECF984026C0B80A771A +:10F64000DF669B0CEB724074C27DD51AFF45A33B6D +:10F65000C2F9B11E9F001FFCF027646709E0F3C4E4 +:10F660004FA208D8D5EFF173C90CB8CF9181AE1E67 +:10F6700017F81D73CCCC4FB8CE6CC77456618E9CF6 +:10F6800048FBCD68B58F8350B5C1BCFE3AB303CB00 +:10F6900087F0764ABDC195AC5EA7D15E1D69FEBFFD +:10F6A0008B12F87999F37B93847FBD75CBF9A935DB +:10F6B000900BFA41BEE267D1D335C1FD71699AE082 +:10F6C00003F90DF630E60B05D41FDE53EEAFCF6421 +:10F6D0007256A17B3D9EABCDDAF7021EE7787F889C +:10F6E000D387826705BFFAF12AF529BFBA55ED9F86 +:10F6F000BAAB6DDC6BA0DF54FB05BB8182AA963AE6 +:10F700008CB00F6BDA9E90E17CE63E07834BA4A29F +:10F71000B1EAF8837566160FB267FCCDF3804E2E02 +:10F72000AF35812C24AE45176DC087DF33387F0F8E +:10F73000716CDEDF8964D357F0AB0F3CF6F27C5975 +:10F740000D3715E733AB32470677DA0395BBE48113 +:10F750002A7A5A678EC772E5FBE04A07BE0F42FB62 +:10F76000C371781F3711B84F92D1D28EF76C1FA892 +:10F770008D637458D6B2CB88F954CD7B224A3FFAB8 +:10F78000FD34BB501BAFBC30AF6328E0A5D014588C +:10F79000E68C40A793A39473CAAF29275C946EC7E5 +:10F7A000FE7F2427962972A203E3E395F602DFE7A2 +:10F7B0002A393130929C585AE71808EBB07447FA4E +:10F7C00040D8244BDF999A14494EBCEF61E7CC47EF +:10F7D000F97DF6EED9544EDCA09213B3A3904EF40B +:10F7E000ED3E51F6495F724259B7FFCBFCE67D9082 +:10F7F0001311F6F7173A39718FBF18E5C43DB345B9 +:10F80000CDBDAC4FFB94133949F7615E76C644A079 +:10F810009FF7B97D7394DF0B807E405E6446D911FB +:10F820006F7AB9D11B5FFF537FF9FAFF109E15BEA7 +:10F83000BE94DA3FA6D4487448909E97DE47F9BA42 +:10F8400000F4C8F8FAD207B99F53C7678B80CF6618 +:10F85000AAF92C6B5FED6672A1A62DF599B9B4FCDF +:10F86000FE46D909A2F2FE30DFCD52F3DDCCA85E10 +:10F87000F86E19E3BB97FD13507FEA6D7E7FE6FCBF +:10F8800096F2B311CE08F431676E8CE6DEDE897134 +:10F89000BFC9D806FBE53D11CF793FE67AC0C171FB +:10F8A000BFC9047DFA493E9E797C3D2F7848793E58 +:10F8B000C55FDE22A64F576D16117FD5AD6CFF5781 +:10F8C000370B3E07CD178CFF1B9ED756EC60E7B574 +:10F8D00074068539AAF5AF78AFA31ECE092A36087B +:10F8E00078DE0CF71E009FA51C9F25CE0A3C5729E9 +:10F8F0006DD2FAC11BA26D2F901B101EFAC3AB78FC +:10F90000FD425310CF1D0A7F293837209FD4B6AB54 +:10F910001A71FB59B04F2A9A75DF9D0D78AE0437E6 +:10F92000D441AFAD6AD1967BF8BC178B818C6D1436 +:10F930003EF93DB3F3F478F7E8F153F62DF173880F +:10F94000E227F39F879F25FE5D785EF075F1A2C7E1 +:10F95000475D143F1F184F32613F7E6C70217FF16D +:10F96000BE2BE2BB4E8B9E18A9790FE5A71C2FEF8B +:10F9700019DCF583A05EB580F54AD76FD99744F3BB +:10F98000735BC8383866286DD2CAE390FC6F75A0E7 +:10F990007C9F5BBB4580B8DAC5FCBE6099EF097CF3 +:10F9A0003FE6C1E554DED3FA0BC79BDC705E7E28D0 +:10F9B0002A88FC53A1DF9D40BF946FFAF9384E0CA2 +:10F9C0000EE6A39C6A13ECB82F03514C6ED17582DE +:10F9D000776DF64CFE6B015F17E65F6A63EB584389 +:10F9E000D70DF675819FE75B983EF880FF223BE7D5 +:10F9F000F4EF92D9FB380249407EE744FB5C918FDB +:10FA000070EE9A93A45ADF1D9D8CFE37094EFCE0E0 +:10FA1000A3FFFB36EBDBCBBA2AFA4C7FD757C1D317 +:10FA20004EDD3A1F8A6A2F9C80E7728213DF0BF249 +:10FA3000C7E179D1C946F6FECD41AE1FE9F705D839 +:10FA40001FEAF77866C0C0212E7A5A14C69562BFA5 +:10FA5000694C3F53F329FD3B485F376EA986B4A339 +:10FA60005E168E7F74DF6E06B93F4DD0C449D11942 +:10FA7000E1BEFF27C097A3BE023E4936A37C79C8EA +:10FA8000CEBEEE196624F01EDAE53532D2D1BD06BF +:10FA9000C7916CE02F8FC904F6C7E583371E9D3BE5 +:10FAA00000CA45A48FE2F72654836BA598C5AA9196 +:10FAB000E247985C3AC1FBFF1395D7AE6B7897A0ED +:10FAC000077BE27C70BF74B673D75407F85B320FC4 +:10FAD000AD8673CF5979F62347601D1BD8BB4FC73E +:10FAE000D7E4A19DF6D07705DC67C7E87A019CBB17 +:10FAF00067A71E3942C7F7E09A443CB79CEB4ABC63 +:10FB000007CE31E71E149D0E5A6FE15D560B9C7FA8 +:10FB10004E1F2D12B70A2F0F9276F4EFCCADFDEEEB +:10FB2000DDB04FCAA83C84F79CCAFC87A60E84FCB3 +:10FB30007A01DBD778DD46B8E7D9DE74D19849FB86 +:10FB40002FA1F500DD35EB59BD9A8D02BE1758E2A5 +:10FB50007F02F964C946011FC469A7FAAF99C1F5CC +:10FB60008129D1BE9EB6A7F952680F7037C6DD0352 +:10FB7000E79335749CD87E521D9E5397D076B498E7 +:10FB8000B46FFC2EC25BB25E2070AFB06C52EAE381 +:10FB90009300DE41D909E54777FDDC08E39E47FB8A +:10FBA0001B44E12F143BA6427DF203C18EEF2E15BC +:10FBB0005E8BFBBA9BEF3B621FCDE21404A2DCEF2D +:10FBC00093D4F12A25D169B89F4A96D7D5C3BC3AB8 +:10FBD000BC89A906A4A78B4690E32729BEDD547FE4 +:10FBE0003D616471307BBC278C1D2AFEB9323A1D01 +:10FBF000DB2F6ACB413EB39814613C85BB8EE92371 +:10FC00009DABA37CE057EB94ED29F07DCF6A137E8A +:10FC1000BFF02A933B178675A07FFBF47A99C0BD8D +:10FC2000C795EBD3D7C13A9EDE2C3BE1DC407C8EFE +:10FC3000C51194BECAFC647BD633B8A79B197FCB91 +:10FC40007BEEEE02E0DBA5944F99707E5A3E56E2C1 +:10FC500028473EF55C14E34B7A7EA5E753658D1B80 +:10FC600022CBA1650591E5D0D07AEE378D2C9F6B24 +:10FC70008885E9BBE3C978F06316570D9BD704F478 +:10FC8000FC20BB70D01E78F3D39F81DCADB4E23B87 +:10FC900065D5927D9DC0E88300FF9FEBDFF229ECE4 +:10FCA00087B2B951F80ED929580FD8476B13F01CF9 +:10FCB000BBC4578C7857E2794B9BB4F4AEF821EF74 +:10FCC000738BC4A5965F6531C4A5AA77F447946E7B +:10FCD000693FF3DB041FB0CAA33FEADCFF7026E6EE +:10FCE000ED38AEE55C3F586B45BA3EFAC8C5D54025 +:10FCF000B7F37E2810D0DB89D75D0FF2B0BA497018 +:10FD0000809FB8F487AC7D296D0FE33EFA73465FA0 +:10FD100094CE1DB00FAAD73FB11FEB6F141C00FF8C +:10FD2000E88662D427CABC22C1F28D9D684750790B +:10FD300085F1687BBC6212EC83EA55263BB86215FC +:10FD40007A52E8B393BFA740CCCEB1B3683B67B457 +:10FD500003F9B29E2EC53942489E02FDD47819BDE2 +:10FD600075BE2A3B618BF44D9FEC1EBD427F22D0B5 +:10FD70005F6698FEF6ACCF33023D9EF60918679198 +:10FD800007F40BF4F9B2E29F2116B51ED5177DEAF0 +:10FD9000E9B007FDC1CB58E961FA54E8514F87C774 +:10FDA00025720F8CFBA1D551388FBCFA37EF59CE95 +:10FDB000F6199ECFE5D53F9204FBBA446271400A22 +:10FDC0005EAB241637D6635C4FD71907F5677CBA4C +:10FDD00071CC8A0EC9EDF120B7A93E4A02B49FDF6B +:10FDE0006C7E11E32BCFBFD27927EA376F513A00EF +:10FDF000FC6FB69200DA213EE447E5AD22C66913F6 +:10FE00002990354B65BF2B713115BFB222BECBB7E0 +:10FE10009A7C85B47DF9EB27C6625CC20AA67F7B1B +:10FE20005F11D83988B7632CDC3B2A97587C8E5EEB +:10FE30002FF85D34B3C3BBDE8C99037A9BD0CCDE44 +:10FE4000172C6FB95736A9FCBBFBA265A51E9E9364 +:10FE500079E93AC3FB0A303EF5FB764A5C4ED7CBD4 +:10FE60008CFECADB64D4E7CA9BB75C8078CDF263B2 +:10FE700026B4776B9A2F1AC19ECDFBD5ABEC1DC46F +:10FE8000365113A7D7233EAE590C9820AEABB50A16 +:10FE9000CF7168BE13F32D3C1EED6BC66F55FC6A27 +:10FEA000C7EB5E8AC28A6DBFB4E17B85ED9B6C783F +:10FEB0005FAAF9ABE3557BC4C3B534F078B83B4EC9 +:10FEC00013E48F91E3E1CEC13F28217D16AD8D87EC +:10FED00023CD8CBFD17166457A0F35A477BDFAE981 +:10FEE000F310CFDDB5F593E761DC955F5C7E1EE234 +:10FEF0006CA88268073DA5E695F731FE5569171F86 +:10FF0000C3EDA0977F89F1C317FE687202B40B3B63 +:10FF10004EA780FE7161CBDF92202E78D98EA9E8A2 +:10FF2000DF59B63D0FDFBDEDCD9E05FAF5F5237E19 +:10FF300059BF6E7B5AF7603CD079BAEEC027427148 +:10FF40008E2D552C7ED4C1E31B37478E17EF11CF72 +:10FF5000D83AEBAE29C01F5B999ED0675CE361BACB +:10FF60009E37F4631D37F3F8D5963BBE32AEF13CB5 +:10FF7000FC83AED7B8186D7CE8A7AD8B7FF12C94CD +:10FF8000B526F41AD718E807FE9478F4CFA35DD904 +:10FF90003189B0DEFF81F1A4B07E850EE0D79FA647 +:10FFA00080BFF88C1C44BF44708709EF6B96EF3814 +:10FFB0008AFBE9C2F64318EF4D785CF80512FAB1F6 +:10FFC000F85DEE03AAD96865F1907C1D205ED261D0 +:10FFD000C3EF3C2E92D1B5122FD95B9CE4B298347A +:10FFE000FE3E0B8BE7ACDAF8018F3F0CAF9B30097C +:10FFF000D6ABF32BE350153CD8010F13D571C0914C +:020000021000EC +:10000000E3524371C0BA7583F5043E1E8AF3A5F925 +:10001000A110EFE9138E468A2BBFB081C50F5F9008 +:1000200023DF8F56E2826B6274FBD6D7BF78E0BEC7 +:10003000E6F175F1343FC6A1A11B055F5D5723F3BF +:10004000F72763846F64B785EE9B540AFAFB2C4F45 +:10005000C4C07D99D64E23BE93A2D8557CBE5DDC2C +:10006000DFD6F58A8871A2F52D7B90BFEBF9473575 +:100070003F47D18F77231F6F751B931F5D5BAD3E8D +:100080000B85D3B5FB4DA4EBEACD9D18A7BABF797C +:100090009BB14375FE0CF2C3A71A7FD76BBBC62278 +:1000A0003FE7EFA2E9FBD9CAF9638D3F723F359B69 +:1000B0002F6AFAA9F0B618ED96BEFB3B27B9EE05FC +:1000C00078E7DA991E75AE459CE68BD0FFCF626467 +:1000D0006E5737323F3895A3F83E9C95BD0727DA17 +:1000E000A2512F5B669D740CDE215D6635625CCC8F +:1000F000CA3A1E47F3236732ACF74AEBED04C6BB9E +:100100001AF0ABB2EF65BB9B803E27271765AACFDD +:100110006194F11B0718884FBD8FADD306827D4ACD +:1001200024EF5018C79D697F95402EB67B987F9F1E +:100130005C3D3102BEB74BF67D09146E7BBEE00418 +:10014000D76C4FBA67F0437E0697F61D5DBC5347E8 +:10015000E777C969403DD16A08D86915628D6A4F51 +:100160004603D7411C52125EA5C07889C73CE611F0 +:10017000703FD446A8DA0AF59C92E65D95D849927C +:10018000EE9D15727804A5570BA757C55F6765FFED +:10019000A6703BF0FD96B80C5207E4BBD6EA467D4C +:1001A000E2299B0BEF3FD2DF6888938827D14EF579 +:1001B000BB50B45FCD7D3BDAAF261FE7D2E613A676 +:1001C000492723C99B043E8E02D18278889B6AE02E +:1001D000FAB2AB70645278DC7189C41980F23B2C9E +:1001E000788F806E2FAF7A1E168B76DC747C1A3E69 +:1001F000119BD1E135B0716ABEDB8903DF47A7E30C +:100200003DAE1BAF266FB5707E271109F89DC5DC8A +:100210004E38FE2F69F0BD4A2A8A4F224C64C238FC +:10022000E93021DE2596CF83F6AFA96F07EF01EB0A +:100230005F0B870CB5ABEFB5DEC0E5E0114B518A23 +:1002400085EE93ACE1B518B89D9D2CB84E4EA065D7 +:10025000FE01C89FD296E7615C8AD0C8E86AC45A9A +:1002600082FB664490C755AD8A463DD56426DEA81C +:10027000F1703F8E78E5F1D08B8F9F3F395618286B +:1002800028690DA535DACE1FCC352CA68BD00245BA +:1002900014FE108B6B0CF45F3FC39D6C1807D31BCF +:1002A00056BF7728EEDA6BC16368A81BBAFFC0148B +:1002B0006421F82E08F10EDD0F72B851C953C60E35 +:1002C000EF06344687F22E33E5F78D692C7FF3DA9B +:1002D000A1F5F07E4DA7BDE8660B8CC76CBF0ECFB5 +:1002E000C302F19AF7D57B932FCA38476F0CE4C14C +:1002F000FBC7B707D9FBC523ADA17BFC288F3759B6 +:10030000947C00ED8BA2D643C8D7AA5A0E61B901DE +:10031000F2341D9E10C81B42E779BF654C41F2B50F +:10032000145E6B71323CC1B1D03266BFA4C1C3B898 +:10033000FABDD9613C482B6ED0E1E186AF85878557 +:100340006B6FA887F755FA3B6F4A170B005FD373A3 +:100350000CF88EDBC46316F4BFD05F14CA230E679B +:10036000432FF7BC153B85C22957D397D24EA1AB7B +:10037000DEE8269DD8AF63EF836AE9E7DF2DAE871D +:1003800000DE328B2BDD9688F3C77705A6BB8B8BFF +:10039000F213C2744D2CEE09F0AEFE11CB821F5A3F +:1003A00054FEDAE9394BC5343ADE1F0123B8313C3B +:1003B0009FC4E5DEA851749E892E03C6D51FB1B82F +:1003C00057403BDB9C600062CB2612F704410CF7E0 +:1003D000A3EC8FFA1DCC8EAF2F36F856B0F360FC2D +:1003E000BB1D61FAE8D0D14790D1475B27D247B512 +:1003F000BF93D1475B5D6E343F57033BBA9104C74F +:10040000C1BA37590A0BA461946E6282F54037B2C3 +:10041000F7B682C228C4EB3A185F8FF5E1E352E6E3 +:10042000D5DBFA361E48FB7106D899070D781EA653 +:10043000E04DA9B7C3C2E246FFCDE67E11FAA99905 +:10044000D4B11F966FEB813F605C87EDE0CC5DD04F +:10045000DE369BAE9023DC6FE3C115F84E78237F28 +:10046000D73B9604BD20D77BC707DB3F217C80DECE +:100470009301F8E8C4FDF20ABF6796DD26B840CEC6 +:100480000F8F61EF90BC6E6176F5BB1691A74CAFF4 +:10049000493CB85B04FB2B7B9501EB27429AA19E5C +:1004A000FF2A5E5FD2F8DD957555E88972D218781B +:1004B000CFE4F978F71E2DFDC4C7A4A9E029ED1EED +:1004C000F790A245945026EE5DF010C8554A3F3E85 +:1004D0004DBB317214E02D443F943E23AD0F6D7738 +:1004E00088AD6B7C0CE80B5BF62E15F15D8E7EAE55 +:1004F0006B16BC4749EB67C590DAADB47D562C4D01 +:10050000219FC0F303797E084BD33F741A04FA7D10 +:1005100003F7CB9EE5782592FDBA996320CFF4B816 +:10052000ECE418940BCABE856754E05C5BE2E7DB41 +:1005300069C13403AC9BB28FA5A02160A5422B4DAD +:10054000721820CEE15D8FBB08CE0B7BE33BB75F1B +:10055000CBEE81EABF7FCEC7F38DF5EBBFF4B82FAA +:10056000FE39E0B7CADCF1F84C9AAFBEF632FA6950 +:1005700057C454DFFC55EF68E8C7FFEED5DFC40071 +:100580001DFA3F3345BC3F35CECAE8F180670EB651 +:10059000CBE2EF0492814A1CB22ACE15CAB85E861D +:1005A0004B9986DF51CFBA055920ACA7578A87F6F9 +:1005B00031A978AE78AB2EAE55392FBB25C0FC8063 +:1005C00059B1BE42ECEFFA74F6F7493E63FA9299DC +:1005D000FE0FCEA1A6F27333D731FB5E1087590907 +:1005E0008DF9083F3615FD5A3944FBFE41D640AF20 +:1005F0006480F2F454849767D695A713F45B916BEB +:10060000AEC3F94D252AFD0CE546A313F8F1F4D14C +:1006100094FEF9F7CBF4BFE126327F86CACEB8CD7F +:10062000715F51BE466F69C477857EFBB9383F5212 +:10063000FCC563213C1715413C801E8FB90E6195A6 +:10064000D5D113DF7AFCE9F1ADE0518FB79C0F9D56 +:10065000F9F18E9EF8D1E3237C7EE95B0BEB3075DC +:10066000B488F24BC17B4FFCB0F5FAEDB5B49E00F7 +:10067000F442F10DF84C1730BE272B86D34F6C3A5D +:10068000E2370B14C001480F98D7E3558FC7AC046D +:10069000DE3E81D5DF0FF81A89FC00ED2165DDB261 +:1006A000D26BF7C641DEC4E84CD1ABA772BC50BDDB +:1006B0001AF5E6BC442BFA9B40AF9E9A14C65B5ECB +:1006C000151B57DE48CB0B609FFE0AFCD1B1080614 +:1006D000DFC5BC95F05FE0563C5FCAE25905DFB765 +:1006E0007EA6D593A7FA0BCE82FE3DDCE45E6505BF +:1006F0007F8C1087E77914FFC775F8D7B6B36BF313 +:100700007A7CFC0AFE31B927DE147AABB372FD7C29 +:1007100030190AFAF2D8373363817F137F7C44BFE4 +:10072000C4C4634521389C6E919E05E20E7DB7A737 +:100730007F0B3E76904A49151FBB5372AFB3DED88C +:10074000938F29EB3585AFC714E2DD057EA62944DA +:10075000FA4BC81E480DCFFF792BF7B30D2143602C +:100760009E5F581C8CFFF37986E64DD54BE83F9B86 +:10077000F79F6DB6E0FD1B1294BA42784EC3F79313 +:10078000BCC6F8F0386465BD536A09D3E7E6E2FBFE +:10079000D9142FE4CB98F038B6590509DF0FE2E3FE +:1007A00038DF6CF6429CDBD392FB0D2BF83D848343 +:1007B00063717E526014C83F7DF9E5B6BDD5504ED9 +:1007C000EB95603D3EFE0A91F91F823B4CBE1752ED +:1007D0007BD753E9F64639A1D07136DC7BBD01E801 +:1007E0003E28C2B8FDFC5C65E74576CFC145ECAB61 +:1007F000AEA7F0F65D62F702F228DB817A7AFAEDB5 +:100800008B4EF349701EB4D3D3AB22CF1BF8FD5BE4 +:10081000453FBB6875BF0FEBDEC0EFE3FA2F8EBA22 +:100820000ED6E71BD3D5612D5D29F444E9EB38F4EE +:10083000D39DF9F13A50CBDFCBBC9C04F251D1E30C +:10084000C3FA8AEB63A8D79B3E3FDCE6EEB27E8517 +:100850003EAFE8357DD92364AF4446D371CEE3EB98 +:1008600033D7DC2EB38BC6418CD36F8856DECB7367 +:1008700044833E39AF21ED95663857AC637EF90766 +:100880006B658D3DEC86DBBED89EBD673B7FB9B600 +:10089000FC238AEF41F1F8CEADD68E86FD91147E11 +:1008A000CFB767BF062FC8C97923A3317E4EDFAF0C +:1008B0007E7EFA7EF5FD3570FBAAC1D838DAA9D262 +:1008C0004FEC3616477D69CD93CDF0145E6FF8730B +:1008D0009B87B8D47F6FAEA3217A4EA4F7681478B3 +:1008E0000ABEE7C2CB98E00FA895FF1EE99DDD6C1C +:1008F00037F313F4D6EF88603EEA8386A70322E835 +:10090000F5238204F5F0ECA0CBB050630F307BB937 +:10091000873D00EFA4D07C65EB2E660FB4D4A15DBB +:100920005149ED0A903B1BE01D90C17C401968279E +:1009300084EC5E88AFCA867732B95D0C4FA7A537C5 +:10094000B2FA331F4F37358C00BBD59D0C2F93CE99 +:10095000B45DFBA899DA57F5A9248A50FBAAC8769A +:10096000ED77D64EA2DC3BDE25C0BBA434FFA865E4 +:1009700072FFEDEC99B6D18F82BF81DA67B7D95497 +:10098000766F6FFBE3669B03F1D9DBFEE8B417CD0E +:1009900004388ADF82F221E407FE28BEFFA342F476 +:1009A000170B7853E8E5F6E50BD1CE88BAE66A0A6C +:1009B000C49365733A70DBB85F3686C1A9896170EC +:1009C000264A6E37F4D3BDFBEA28F03BBF3BFA045E +:1009D000DA797E2BF3DB1FF49415A9E3DB6B6D0250 +:1009E000A797C010D87F77DCB82701EC956C59C069 +:1009F000F74EFDB2EFE9F199C09F66DB57D2296649 +:100A00004F36E2FD327F5460C8C32A3DCECFDF4D62 +:100A1000F55FDC3F441DFFDC6ECDABB531F822C085 +:100A2000CFCEDC7B0CF480DEE44E58AEB804902BC5 +:100A3000E4EAA1243C5F6ADD67039F68177FE7E073 +:100A40007CEB9EA40534ADDAF29F36B0E3EA383E83 +:100A5000CE4BEDF85E53E57611DF13A1FD263D0088 +:100A60007EEBD68559ECDE1FBBAFA6C8D5F19FEF54 +:100A70001952C49C8978FF4CD137A798BD3E189F66 +:100A8000BF8EFD1DCC29BAF7C96EE5EF93E9F5CF0E +:100A9000676CB2E22FC3F8A96576D64F6FFB2BFBCC +:100AA000B304E253EDBF6C2920C2F8B33F4BC2EF51 +:100AB000E70FA43D5508F63D919D2301AC44F6A2F5 +:100AC0007ECBCFA7E86F2FBC7BBE9367DE6EBD3CAD +:100AD000EB66246E2AD704D0C7DC0398D391C907EC +:100AE00045FFBBF533ADDF55AF072B7232D73F6EF5 +:100AF000D510027877CCC2FB1307248CF7D2EBC950 +:100B0000538305BDE8C34F207D6D6D4D8F017BFE86 +:100B1000DF609F00DDB65EC6F783AA49E01E78C796 +:100B2000A9BA55B40760FC24F37AD8678A3EA1E0DD +:100B3000A5EDEA1EF358DA7FF645837D0505F176CB +:100B4000F02F68574FF8FDC1049067FEA084E707B7 +:100B5000D917F7C62C54F145FF55037E7FFBEA6E8B +:100B6000EDF760FCF5D06E8B81D9CB7BF7FF3D06AE +:100B7000F8D4DB572F21BC903ED1536F46FD3BCFBD +:100B80002A86FCD16ABD9988D98721DE6B6A2C152B +:100B90006B42EFFA70CE87649595F4D42B42782798 +:100BA0002E09F0D0431F56F0ACD3333EB2713D77DF +:100BB00018190FEF5EB65D4DA8C07BC7FE18FB0A83 +:100BC00094CF4C8FEADE7BEEC9E9F0FDA0C8DE9D34 +:100BD000B82AE27EDABDB36278876ADF524E8AEBCA +:100BE0007665D0C50B6FD1FA57F64533FFBAE4BC32 +:100BF0005E7D4F225CDFC7F11518CCCEE9BC83E1E6 +:100C0000BDA86FACCF74F5B0F7FF61433D39580014 +:100C1000E262D4FA4E23ACFFBFD98A3E67FCA52519 +:100C200006F88B97E40E21B4DFB268920B7415AC12 +:100C30002376B033B61F3018605D3237A5625CCFC3 +:100C40002BFC1C73494BA3315545174BF839D81968 +:100C5000D99B12AFFABE3296F19733FBCA7F8171EE +:100C60001D7F34919111F4D085B14CFE6E337AA77B +:100C70006F867AC70D78DF68EFFE5FEF877793970F +:100C80001C738C03BFE09458B60FDA0EBE520F717E +:100C9000C16D1F82D4A2726663B168A0FDBE451CFF +:100CA000CCAF7798FDBDD6903F94B812609E37C503 +:100CB00032BEFDD60183E6DCEC2DFEBEEFF5B18C35 +:100CC0000FA5C632BFDAD603B9090B70FFB947C406 +:100CD000821FF064473D6C45C50FA8E86F930F6F06 +:100CE0009D3E86FE737297C10ECBED38FC8208F3F1 +:100CF000759C21244E203DF4390A6FAC1ADE5B5DF1 +:100D00000C1E1DC76ED8AF0AFEA904FE7106CDBF2A +:100D1000D52EC5433C98827F651E4AFF8E16E2DAC7 +:100D200060C1ADE4DAFA15FE68E5EF314CB013E5C9 +:100D3000EF33205D6EB7B96E89C5726F0AE4CFECF0 +:100D4000637AD2362E4F4972F170C09FB24EF3795A +:100D5000AA8CA7B7FEEFE7E354D2AF4BD7AFC80ECC +:100D60002FD2CD76164FEEF006CCE91077D6968EC0 +:100D70007F9F4A15977B3F8EFF8CF6FDC2B60E8390 +:100D800001EE8F55EF10E250DDEDA7BE1DA233A995 +:100D900005E9AFED18C17D5CDEFC5DE68FA4729FB6 +:100DA000BFEB86E7EBB07FF839FB2081A693FD1BF4 +:100DB000560E41FC066CB0AFC278A2FB06D2DA46F2 +:100DC00023D0EB92652C2DE5E7D54B9ADCB83F4B51 +:100DD000D6B378C465B1A94C3E737A2586E8C1F8CC +:100DE000DEBA4D7B8FF01F5C7E9E6D7D6A0FF44BEB +:100DF000E9EBFB808F9BDA9E5807C355E8F5EC467C +:100E000019E194456BCFF33DB1CCCFB8FD30A3F7DA +:100E1000C91BE55C784F6CB297D8C1BFFDD6C64DF3 +:100E200022F0EFB7809E53D93E07797B66DF6331AE +:100E3000DF07F9D66920E047DF6624655B54FB6273 +:100E4000EF863734FBB7BCB96E3AFAEB3BE205E00C +:100E5000F3CABE55F0BECDE8BC0DF7FF9DBAFD9FAD +:100E6000CFDAB7C2BAD07A4FF1FDFFD434BAFFE976 +:100E7000A7B88D7102C0D9668CFCCEDC4BDF90FE2A +:100E8000427CB5A3075F7D2996F91F6CE9B4FFEAA0 +:100E90003B2EA1FF21343E4E374FE52B74932A00A1 +:100EA000FE1BE90A8E007C51BC023D533D7AFECC0C +:100EB0000CDC9507243CFFE1E74B3C2E0477946A59 +:100EC000BF86F999B26FDD6FC038B2F26B57829E60 +:100ED0009F50E845FA3C2BB887C753797616F671D0 +:100EE000047EB08EE3E38AECEEEB7DFFC140CF657C +:100EF000D46284F990F5821DD6452977AC67EFBDA1 +:100F00001EE6F094EF87BF2DBE833DDE213DCCF081 +:100F10001D34425CEB281F936344C8C5FD400CB7E9 +:100F20000F867DB684CAAFFB55F2EBACDC8874AAA1 +:100F3000E0E123CEB7AEC4B1793FCEC7E9071F5D6C +:100F4000A20AFF8224096C3F8B02DBE722C03FBB71 +:100F5000EFA6DB90DEEF884CEF76B0B7E2E1EF472B +:100F60006D40FA8C9B66C77B2F4F49CEA8388D7E8B +:100F7000E4C374EFA667D0CE03FA85FDDE1BFD97B0 +:100F800001FD930874EFA374AF5A3F850E285DFCF2 +:100F90001DF0A57CD7D385720EA9E0659BEE1C736E +:100FA000AA9DE1E9FF00528D6EB5008000000000AF +:100FB0001F8B08000000000000FFBD7D097C54D598 +:100FC000D5F87DF366C93233994C76B230490CA01E +:100FD0002C0E4980B0D84E08204A88C352D7A0931F +:100FE00000094B36109556948120068B18152DB6A6 +:100FF000208385EF431B6D10A858832610112D62A6 +:10100000DCB17FA54190454122A81FED87F53BE764 +:10101000DC7B33336F26026AFFE1C7EFE6DE77DF62 +:101020005DCE7ECF39F7C56ED3313684310763AEDE +:10103000E6018C7D8F3FBFF4978C2DA1E77337CFEE +:101040005E712482D1CFF7F0BFBA795E50BD76C70A +:10105000AF571CE9E7AFCFC55F52E0FF71A66789C4 +:101060008C55F147AC4CEF89B525C0FB119DD66C72 +:1010700098B466E2196384039F781983F66F631C42 +:10108000543EAA6FDED32B1FCA31CCE985A6399B0B +:1010900033158F99B105361BAD67F927D393DDB0B2 +:1010A000DE46C6C6E3BA9BC57C72DDD93685C699D5 +:1010B000E029738F898367664F9E7BA0FFF90766DF +:1010C0004F966D88BF3EA170BEEA18404B8CC47E1F +:1010D0006355980CE69FBFC9E4336532B6059FC4DB +:1010E000C32ADBA37C9B32FDEFD9F4CCA5B73396A2 +:1010F0006BCBA475C1EA5AB1EE58686497C1BCDFE6 +:101100006696B59BE1D1D51DDEE281B08F2D46EF0D +:10111000D489993898F31A1CFF9A629DED01586A98 +:10112000ACCBA63807D092695EB68FCF9397EDEC23 +:10113000CFB2A1EE70E6B92D8C8D12F862AD30C938 +:10114000703F1C42F1C6E1D9135E17207C86501710 +:101150007A7EE2D5A81B7D66FFF34401BF2F63783A +:10116000F9ADC1D3DB660E1D27603E554966CCCA7A +:101170003C4B555CFF2866DBE4F03F778C622E1C0D +:101180007F9A1857B6CBFA8FA6AFAE10FA9A867828 +:10119000AD8EE822BAEA53D06974C0BC4C19DD8B1D +:1011A000C1FA98EEDA5EAC80BAEA71BD0048552902 +:1011B000E0EBC7F6848D33D7239ED90113CBC90C3E +:1011C000DD67B5CDC0E1B6D130FA66E897E065B825 +:1011D00003C08B83E38535DE8AF86BDC686288D7D1 +:1011E0006F6339DCAC53D96803F4B7427F24F7C688 +:1011F000A99E035741BD31D9E850609E13862EC287 +:10120000FB89ABA08DE8C3AD20BE4FBC3AE29ADFAC +:1012100040BB77A28EE5C08B5B8DB005A4C3BFA792 +:10122000F9362948A72DC427F3C7B2C12678DEBEF8 +:101230006918D1D5ACE22C05E976CEE658059FDBDE +:10124000C7D8742AF3EF63D84295E813F8A0DE16E6 +:10125000808F61DE3A15E1D53BCE936C8865EC1149 +:10126000DB35E323D281CE3259241BCCD843505FE7 +:1012700009706BB4BB14164BF506730AF121632396 +:1012800008AEAD0CF0D418D55D774560FF2C5E7FBD +:10129000A4F1EA868634C69E897135229E3E30BB13 +:1012A0001FC1F98726D5A944E782AE7F80CE7E1282 +:1012B000BDD42E2C6287F3E0F70E660EA41B904778 +:1012C000B76E06F895E83D9B705D35BD8E3E8EC3CA +:1012D000D5B67C65F484A17BB98E782117D8C78CEC +:1012E000F011EFAE53CBCD7EB9B3C566174CED52BE +:1012F000265BFCFC8672EB7933973B59509A229817 +:10130000D762C77E3EA223ACC7E4FAE5D1CA62DD4C +:10131000785F183E7E0D89EB6794CFACE57FFFF2D6 +:101320009BA1D01F7F57899F5EE3FCC4E5F5A3C551 +:101330009F26223C9093F0BDDBC51CEB973ADFEA79 +:101340008B74B95F659BA03ED864F42A31B86DE612 +:10135000B0258AF1900D5B9456CB20A8FF4B612EEF +:10136000C0C3E97FA954AEBFD73D3E13DEAFD9A1BC +:10137000732E857E352D0AF183B337F345001D3773 +:101380004759073118AF70B7D96580F6D34A04C9F9 +:10139000659C00D76190EB2FE8CA6882E7F52DC005 +:1013A0007F503D5D08A8C6F5EA9D316C801FBE8365 +:1013B000DE7CB41FEC00DA1B9DC8674F45F2F19F3D +:1013C0008ACCF081108352BEE788014A6159826E4F +:1013D000F47AC662004F5078B11CB530DBA5073CEB +:1013E0002B7AE63500BE4675B5AA089FAC2E878ECF +:1013F00099FDF3E9BB18ED3B4BEFD03903F4D5D69B +:10140000BDCFAB7A80EBD0318DF52A9489319E6FB8 +:1014100010DE2346D5D5637B5CB157F540FF7CA534 +:101420006EB705E9EC1AE644B92AF924AE93B5C1C2 +:101430007259EC814E9715DA471C77B50D80FDC7C0 +:10144000B89982E349FD0D7CC662910EE35DCA4402 +:101450001867E83F18C1478EB375EF6805F93EBEBF +:10146000638CE218104AE76B98E3B738AE779FCEEB +:1014700089F8753433D70694137FBA620CC24BF6E1 +:10148000EF1DCBF5CA488FA7084415EE2706E71DC8 +:101490007EA36FB701D6336C9677B7D111B09FD9C1 +:1014A0008CC64BEDF4D23E520E780AB1CCB6C6D201 +:1014B00038238EB7B60D807E4975B01F684FEF7820 +:1014C0004F41B8A6D7752888CFAD7B77D17AD33A6C +:1014D000DA7929F8EB79611774DB03561DED23DB0C +:1014E000CAF5CDF2535C6F66C77AB2AD09FE7D2CAA +:1014F0002FF424D7C1F86BF66675EF17E5EE952843 +:10150000E403E4526EAC91C6B9CBEAE98FFBABBD04 +:10151000B1730FD2E0F37BDFB1127FB4C4137E133B +:10152000F77D4AF8485C48BA98ADD9375F4179B140 +:10153000A61470A684C259CA8D35B87EA21F5BF46A +:1015400024A0CF27ED9E82D8407BA5CC1E9D1520E0 +:1015500097E47B8F2F66EE19B09061EDE55B59162D +:10156000C9F77EB101F27DC2C0FB22919E9A2C2E5A +:1015700017B69F56D88D38CF335842FB33065E9747 +:10158000F07A40E0333B7652B6750887930DE8F861 +:101590009948DE4F2B8FEE8DD509BB83D30BEBE043 +:1015A000F482FB08B4BF66C6723C8C74798AF49CE2 +:1015B0004EA6E2FE8617F87623DD0E1BEFDD8DF4D6 +:1015C0009FCE049D8CE774A2A5F7DB63B97C1D71E7 +:1015D000BC8B21DCF315E60E67EF54C672BB29BE47 +:1015E0006334D10FF04319CE3734B54E35A0DC66E5 +:1015F000B609A87F7E13EBA07E7905AEDD486F3675 +:10160000979BF879BED9C6E92693D307BC3F271C20 +:101610003F6D433E1AE0E7A378A44773283DDE26DA +:10162000E0F41B01DFD0F13D77E1F8F11D3A9702BC +:10163000830C3B60F631E83A6C01E849E45306F468 +:101640000F0BB4CFB215229FA5563915C4EB02B3C8 +:10165000FB1EDCD772948DF948CF3A5F3DBC976C86 +:101660007311FE7EB49E6867116C68909DF5402CE6 +:10167000B7E35795A1BC7EFA5B23CA5387E4BFBD8D +:10168000B9D1E501F4F1C7507C3F120EDF5A39A7FA +:10169000C5B75F2E04CB3980D75A8E0F6EE7C77758 +:1016A0002C50B97C08966B3DE123443E083CFCC1BC +:1016B000ECDA84EBCCC64540E91DCDFA617B4FFAEC +:1016C000F8C558F34FB3672FAC8F5F8C4D08D5C763 +:1016D000BA88AED7158047758BEA50610BF58BEC55 +:1016E0002EC4FFFA66C58976E1EE1695E861FDF233 +:1016F00028D29B72BD5F6E8F19C4AE8452F03F6BCF +:101700008F257D5A1B2BE65F06BFC0FCA76DBCBAB8 +:10171000DDE6793D500EAD6FF92612E1DC3F5971DF +:101720001D41BB4AAB8F81851478DF84BF2908D760 +:10173000C10D2A32D6F59EAD2695F0F62E8E378C49 +:1017400075BE330AD6F5A7A6D1BA407BEBEC8EAFB7 +:101750006FDD05EBAF8DE6FAB9369AEBE7D3BBCE7A +:10176000F7417ABB76E174927BC3F49E8F03E5DC8C +:101770001BFD0E7339CC4A6D47FBE3D42EE5FB68A5 +:1017800000A135A29F1EED0A35CAA906DB15441C2F +:10179000F539001F845F5B14C1AF3E07F82E93D666 +:1017A0007902D7D96E31B214683F0BFC88FDE4BAD8 +:1017B0007FC47ACF845F6F9AED68B4A00BD5BFBEAB +:1017C0006EBC201E607CD5A2A77D9C66514EC4676E +:1017D000B3D1C510FFDE83C23E1078AB113477BAA7 +:1017E00065C8010FEC6FFD813427BE7F7AC7D948E9 +:1017F0009D19ED478F6A877DA9E95D56D487BB5B4C +:10180000CE5EDE3980E49BC10EEB3BBBEFB0DD3337 +:10181000E047EDCF6ABF88FDD5EACD0D817622AADB +:101820005952941A3A525ADAFEA90C22FE63280F32 +:10183000BD19CC570FFB5E3E50D0D354E640BED707 +:10184000E27BBBCD9D610FE0DBCD36B703D785F3DF +:10185000A4E6D23EB3B03EE8CDE979061DEE6F0CAA +:1018600043BD29ED3DB94FB4C72373FDFB93F65E2D +:10187000F7FE73CE0FDAC768DF83EC740E742CC5E5 +:10188000735A2D2885073203F7DF4A78A916FBAC77 +:101890008E30B7AAB02FB6CD70B253CA83ACD07D0C +:1018A000009E86F37D380F7810CF7F373BEB114ECB +:1018B000FA0E1BDAAFB0AF91B80F5650968C70F895 +:1018C000C0EC9A8CF2FE99258CE8FAF4B3CCF714AC +:1018D0006C7A4BBB8EE86603BB82E8FF0ADD995B3E +:1018E000DD66E2EBB1F87E7E47A30EE56F8ECFA1F9 +:1018F00043B97A7947B34E47F4E0192FE074560F95 +:10190000EBEBDF54A7FE48BA98149E2E42F0F6ABDC +:1019100040BC49B88D12F4300AE18632B94B7FB22F +:1019200033C20F37C00B4BB5878EC7586706C2A9A5 +:10193000EDC5637D3A61BC9A978FDD8A70A9F9ABDA +:10194000898861CC5F2F8F41BAFFB230BC5D737262 +:10195000719D5B0FC478AB3D8BE47B15EB30A2BD72 +:101960000072DDAD0F90EBD28EDB67E828C6F1F791 +:101970000D51D91280F359E7B02416465FC8723F63 +:10198000DA6D39007FF455E1F9E4C5FC186E47DAE9 +:1019900083FC5AB2DCB778967B8CA1E7F1F60D8E0A +:1019A000247F4EB1C61E7AC8CEED8DA7ED5CCF81E7 +:1019B0006076E13A4FFDC5E2F342D3A9DCF7AD0C06 +:1019C000E0746ADBBB795EA0A353ACE3F69790DFCB +:1019D000BE36D3B9AE78F0FB794B2C7EFEBC8AFBC9 +:1019E00052D8552FBC697540FFE22DBBE3BD01F015 +:1019F000BB8AE9BFEEA6EB4C9C97EF8FE93BFB203F +:101A00003ED84B27121D5016BFF86A3CA703383743 +:101A10000D45FF14E78F3F635380DD5DBCB0C63DCD +:101A2000262FC01F732E92F902EBFA0E231E89ABEC +:101A3000CF99A9FD76BB259EE44D2FD60BE54D8FA2 +:101A4000F0BA48786ADB253CF70D3E9181F6C597E0 +:101A50003DD8C507ECC17EAF37167BDC6372FCF561 +:101A6000BF7DA7DEE60EF35E8B18FFAC737812DA4B +:101A70007DC5C6D6CBC2F9E1E439530BA737CE57A3 +:101A800046E3B87F39671A1F6E5DDBEDBA9FE63F0C +:101A9000D807AB0AB00B4BF49E37EDDC5FB06A326F +:101AA000D46B2E3F3B8ECED9925E84DCBB8A79DB31 +:101AB000907FB5F421F1FDBEC45B2A4B45BC3D6966 +:101AC0007770BA11FC20F9430B476D39C1C83CE16E +:101AD000CE03CF75C3359279411EDEBEC1407AFE7A +:101AE000CDF31F4ECD037A3FB6D6605B0A53CE5A74 +:101AF000B73BED51F4A70D36D914A81F73B45E8619 +:101B00007C5FB94E75233D1C5B7B7BE27428BF0074 +:101B1000FEAD8275546E3050FBAC0D7750FB09C1A1 +:101B2000D795EB12FAA3BC7CB3FD8144C4E3ACEFC0 +:101B3000EEBF1EF1B2C568EB3F18CAAA26C53D2606 +:101B400000DE73364606D5B7E8D82CDC87C42B53A5 +:101B50003CDDCF1DB01E63DC4FC4636B881FD518FE +:101B6000C7EDCC9229B0EF9A2167C9BEDFBD278AA5 +:101B7000F4C92B6695ECC8D6C1FFF3B72BA15EF470 +:101B80009DDE49369EC0F358816786CE40A08F8A7D +:101B9000085E2F7A514F766891452578B7825C1D93 +:101BA000434ADE651E0BFD7E21DF5347AD1E0EFD51 +:101BB000C6C61818EAA15FB4CE2966A0277F794E61 +:101BC000FF6967C07E4633971EEDE24266086A5F92 +:101BD00011657D0AED5A184C8FFAB02822F8F9D811 +:101BE000CBAE3D81F6C4585B70BBA4BF9C38A0BF90 +:101BF000FE7EB9B17BCFE78F4C807D56EC53C99EFA +:101C0000BE905CDE8FFBCA417CBF51DA04EFBD2978 +:101C1000A0F3E6F963CB5290BE0A14867EAE63E76A +:101C2000C3F3E55C419F8C019EFBF9F13CD139BBCC +:101C3000BB8E6C7F5DC1BCEE3AAEFFE2E5D90FCB47 +:101C4000AB4E3BF76F68F587967FFE53FAA378F0AB +:101C5000AB195E0B95FF85E5C92D5CFE6AE58556DF +:101C60005FC87569D75B7D4E0DD213CF0979E2D776 +:101C700017467AFE339E8F6BE286849E8FC19E212B +:101C8000787987EAE95C0E76D7EDD86F80D911575D +:101C9000084B5A66CB8A46B9D664F1DC1917E0972F +:101CA000EADFD4A843F9D1EDAF3104FB6DE4F9F5D7 +:101CB0009E38BEFFF2385E87F32B9DFB3744799246 +:101CC000F5386F2FA333307E25CBFB85FC9076AFA4 +:101CD000B477A59D2BED597D03B767B363DD417ED6 +:101CE00033D6AF5F903F18ED74E473EFAE28DAE7B8 +:101CF000678A7B10F26915733D1417A007EB0D7C02 +:101D0000FDDAF5BC1627EC13E6263B41B6CF1C1DC9 +:101D10005E9E6F8DD353FFC2C76FCA403BEEB3B612 +:101D20009B3350CE7EA6F1FFF6C40F0F0B7E7D5085 +:101D3000E89358E1277808F908EAC0EDAE2DF0FEE7 +:101D40008AC56EE2ABDF2EBE91CA47172FA4E78F7C +:101D5000C565D2FCB6C277DCD900A7232B55D217B4 +:101D6000338DEE3EB1F0DE91081DF91B0ED799C7F9 +:101D70006F33633BA3F3E5CCC7276CF206F8011F72 +:101D8000C37D0CE9799FAF09BC5E2A9D56B34E2BEB +:101D9000EAAD6E7A3D10A2B7DB112FA7596722F684 +:101DA000AB553AFA3429A1F33FC85CAF61BF662353 +:101DB000EB8F7CD31CC5F592B6DF9B027FABD09E28 +:101DC00085F233D45F61E4CC3B825E7B5B5DEFC424 +:101DD00091BC3393DD4EEB56294EF43ECE07E7B46B +:101DE0000FF139C689D05F976DB575C755F879C7BA +:101DF000FD715C187F5C4FFE1FED3AEE89E770D5F0 +:101E0000FA856429FD42C7C47E16C5D982FC44E820 +:101E10000F0FE70FBA3ADE48FBDB10D5E9C5B8A8CB +:101E2000F7667E3E4F1AE555D0DF955ADC5888FE9E +:101E3000B07FC6713FA67DBC2719CFF1BD928D4EF4 +:101E4000F4E35C2C3F0E6876F138814747EB58D3BA +:101E5000E18DEC03EB4AECF0141AA134C426D2F85D +:101E600049AC6E09E20DFA1130F2DBA37C8A3C74B6 +:101E700043973C214761A591C877DBAD1E533CBC1D +:101E80003774465D3DFAED53AB783CE284E2E96D90 +:101E9000CF0E8D1BCB32395EF0AF88BBE66F34D0EE +:101EA000BAF2373E46F1D1FC8D57EB950039941FBD +:101EB0006FA0FE275E9DD39BFC181F858FBF0E88E9 +:101EC000E7F462461FE1108A8786A5BF7EF13F31A5 +:101ED000AEDC09F650B03CEF173F24206FA1FA0C9E +:101EE000C9737D3CD7237FC07C0558D31F66C87C4F +:101EF000850DE48FDD6A6CBE06E351DE1A1D43BC1E +:101F0000B7EFF92BC56B67CD7050BCB6FBFD7DCF2D +:101F10002CC7F63FCC628311FE29BE8715F4CF7C17 +:101F20001BC9E3C9DF6E32B125B0A5D96F37533C69 +:101F3000784D958EA17CD1EE1B6632E8785CDBA0F3 +:101F40002BE0F8473928F10E0464447C48BC21FC9E +:101F5000B698316EFC02AD5FAECB807EF004DCC77C +:101F6000966B904E7A55D915F417C8755D489F4CFD +:101F70008AFF69FAE467D4C3B7C55F9C1E9E81746B +:101F8000AED5C35AFDDB64715562BF0BE9E1134264 +:101F9000FE4D89D7C443307E16066FC7841C0CF0F3 +:101FA0008FDF19FF23FCE31FA11C09E31F7FC6C8B5 +:101FB000E56FA39DDD36290CBFBC27E6D7ADEE3219 +:101FC000A2FE8C6F51C2CAB36CAB51C61357E0FA74 +:101FD00064FC442B8FC3C0B711FB5FDED4BA0B7B0C +:101FE000E5C65E168DE6DB15DFC3B937CC3C6B0466 +:101FF0009F3B16308AA33AEA18C92BA8FBB893B0C6 +:1020000095F223001F4FE0B8178A639DB615921D05 +:1020100024E35686D8E0F3F89E78D9CFF547C46F0D +:102020007A0F7AE24F625DB0FF67B05FFC02161470 +:102030009F917199F83AAF62CC4775C4C8DFDA3B1B +:10204000CEB304F33FBA8633E753508F29B515A2B8 +:102050003CB5CF72B661FC66F929EE9F5F3E8FF901 +:10206000962A0179059E2CCA0342BC05FA07760A16 +:10207000F9B653AC1BF4E45FE3F9BA5AE203F4A4F3 +:10208000C4876E75AB4A78ED0AAFA702F0DAFE435B +:1020900078FD19F9F29D8BE4CB0F2F856EFE7191BF +:1020A00074F34B8C6F0C093BDF678857ED7C4067FE +:1020B0004783F8BE073ADB7889F1D2F9E69FA8A7F3 +:1020C00042E1FA5D7C42285C5716EBFA91BC6651FE +:1020D000CE707AD59660FE4FE791D812865C7A1E54 +:1020E000C9FA7B3B8D8867190791EBD5E68FC8F657 +:1020F0009A16250FCF9F85BBCFD339E074DBBFE89D +:102100001C109A07C2E79D0FE48DFC39561DD0DCE8 +:102110000AFC77A6C948277595397E370AFDF77BF3 +:102120000DCCE7A0FE11D8FF0AC6FB5FD1B4BC03FB +:10213000FD575730BD579C4795EFB91D15837C7CE3 +:10214000C55E95F2BFD866FEBC8E452C41FF744C2F +:10215000818E3902E019EB8A628E0078C68DB7074E +:10216000D5E53979AE9837C1DD2BE8FDA41BB382E4 +:10217000FAA778AE087A9E3A2B37A89E5E3722A837 +:102180007FEF85A383EA99DE6B83FA67374C0EAA4B +:10219000E734DE1CD4FF18AB7B7C14ECB33FFA5B56 +:1021A000003FCCEBEAB80CD63B43ACB7EF9AF2A0B9 +:1021B000F781FD5A311E385390C917CF8DDFAB0020 +:1021C0001C6708FFCEE5BE3941E3CF55AB887E677B +:1021D000361A8E04FA69F4AC6B4F2AC0B9C6A73818 +:1021E0005BA15EB926F8F9EC1D1BE8BDD9BEE0F68F +:1021F000B99B83EB83DE9CD29FE701B929BF72466E +:1022000042B0DF8785D08999E4F499B5DCFFA57ADF +:10221000FB6AE824185FEC27D28D43D08D293998CA +:102220006E221DC17453F9FAD6A108072DFCA3FB39 +:1022300069E8C90BFF7E00FE1667307D69E14EFB41 +:10224000837556EC50D8EF9550B8CF6A7978792AD3 +:102250000B853B633E23D71FC1ED8F68E0FD81D91D +:10226000F318CA89B33B16A8188763E3793CFFECDF +:102270008EAF07ED7384892FE584C497D62504F8C3 +:102280007F647CE934C619AF64171167DCFD4F84A5 +:1022900007C8008F01F3110B9C11DD71C5487F3C0D +:1022A000492B3F6509FAE3B904D22BFE786C3DBC9B +:1022B0003D34E60337AE53C6E564BE8ECC2B0A939D +:1022C0009FFC978404CC0FB447E3F9754BFB7C3A31 +:1022D00077C9BC2226F202C3D8FFA44F9AF1D714C3 +:1022E000B20B762670BDFE0A8ED76D1788BC2FA95B +:1022F000D77B1A47C6DF7A2A955D2AC513BB942877 +:10230000E75361F4CA47093F51BF85E68F7F14A8A0 +:10231000476AEE38BB07F50BC0FD636CB758406FDA +:102320002B7EBDFDBB682BD16BD7EBAAAF2F349CA6 +:102330008970C4D8018E2D22DFAF45E4FBC9F5D6E4 +:1023400045A4BAF479D81E9CFF27E38ADAFD8DC232 +:10235000FE71FE3ABC1764972CCFE576DB690187E6 +:102360000D166E271813B99D50AB391FD53670FB6B +:102370000CA4D7AC9680718C8916EADFDF5C684CC0 +:10238000C47184DF6579A64276C57245217BE47706 +:10239000B6D1F4FCCF09858644E8FF6F31AF1160F8 +:1023A000886563165F8F439317FE92E8FF52C268F9 +:1023B0002A8D8936E17FB65D81F4916A7619A95D2F +:1023C0000D1FA78A4EE4FB1A29F264B47180714292 +:1023D0006EA2DFDFC4EDD2E2B18941FEFEF78CF1DF +:1023E000C2DFAFD0EB2E9453BF1478EFC9FFEFEAF2 +:1023F000676B47F1ADF5FFAF8CE4FE7F191F08F165 +:10240000FF3BC785F5FF231EA2ED7EFEE993D82D85 +:102410009FD2503EED307AEAF1FCD5B51DEC7868DC +:10242000EEE7EBA4B8C0C07DD94E3C672DCF64BBAE +:102430002C486F4B18433B7F47A76E69243C5FE9EC +:1024400065367C3E7C2D3FBF55AE7138719B520E78 +:102450005C9DC8FD8706381F5B72F1BDC96D1827EA +:10246000583995D9510D35B2C6222BDA456B59D85A +:10247000F3E368414F130A7751FE764217CFB70F47 +:10248000EDA793767E21E2735897E72C8FCF717971 +:10249000422211CFA9ED3A5FB8737DB2ADE86AA4CC +:1024A000AF81BEF0E78891C24FE632BB27E2F80366 +:1024B000B7F17CD84A297F67E8981EF03E45E07561 +:1024C000CA5A9ED7C1CE7FFFBD2AED4546E333945D +:1024D0002B95532D3EF41355B6647A695D6EC599FC +:1024E00083F2A2E56D37D62BF3F36DE89770FD9D6F +:1024F0002947FB91A9C9B8FCD2B3A3529E901E8F65 +:10250000A738D464416F23F1B09C40727E6534C01B +:10251000BB72ED925D98D7F3FE1F19C59B0EA85DA7 +:102520004371B05F017016E662A967A5E4B748A6DB +:1025300071A68A71BCFF827923FCF3FEAAE575DAE5 +:10254000CF0103F346001D9DDE798303EDEEE5091F +:1025500011E4CF9371DA83AAE73E5242FAAE1A5CD5 +:10256000DA4D2DD136F4839CDEF9613AC64D3EB981 +:10257000E7AC05EDD87FE8BB2C982F7C7CD1BB164F +:1025800017C0F193452AE59DDD2AF48684FB7D89F9 +:102590001CEE1F27BA1721DC6F5BFCDDD0C03C2A84 +:1025A000B63081E879B64FA5905CB79CDD1C8D16DE +:1025B0004A77BDBA392EA82EF540B589D5853BBFDF +:1025C000BC24E86976D30663AA03E7F7AC42FA387D +:1025D000AEE774747C9BC5E7CDF4AFA7BC69B011BE +:1025E000ED837FB498582BEA337D8781E749BB8A16 +:1025F00015A00B8FC0BF769D7B5E8EA6F1663EC692 +:10260000E54719CCB510E0EB69994D7241BB8F9944 +:102610009F38C625015C67AE5018FAE3B0FF22C0B0 +:102620009F67E1FD5FA1FDA5DD679937580E48F969 +:102630005529F03CBD21F87965CB6F699C19CC43D5 +:1026400079206027699E5F730CF50AD84741ED67D2 +:10265000F6669B518F6F4914F1EDA16CD8F7F0FE2F +:10266000AE88EC184F187E92E5C9C53622D6CF1732 +:102670004750797C31A3725122A7E3AA96B7EF4461 +:102680007BA966C716238E73C9F1819613D69B99D1 +:102690005FEF96E83DAF211ED92C25284E50B3E1BF +:1026A000AC91EC32019F52D15E8AF0003CDCC21C3E +:1026B000ABF13C505A65F0C7E9E0FF5B72BFC36005 +:1026C000BF80DAD1913917B55FB94FB96FF9BC5AEC +:1026D000057A0CF3BEE48345421FCDD83869792FC3 +:1026E0000051FDCE63199DFCBC49F67891C06B5139 +:1026F000C4FD648F1785D8E3EC3DDCB7A4C74AE678 +:10270000243DA2A53B4907CC6CA0F72384BDDE4D38 +:102710006F2D0F125C243DCC5C5D68E4E69BC7C85E +:10272000ED4A6FB2F0D726A3BF16E830C83E06BA0E +:102730000BAA6BEDF12F0D9D19281FB476B8CCE7CD +:10274000D4C2E76022CF5F9AE1708DB30DC0738071 +:102750007B39F985F146CA10E4DBC63D7723DF6E8D +:10276000E47CF30F410FB3923C1149F0DCB3F49ACF +:102770001AC47FE7125306F2B367698A1A0FFD3D48 +:10278000AB1492C3A397A61811CED3970D1E877CC6 +:102790009DCB5C34FEB43816D66E189CC4E54779E0 +:1027A0009D811963082946F40B9F6A50C82F8C9AA3 +:1027B0006422E06B96C057F58AB7ADA4AF1CF06FEA +:1027C000285E1FE03FB3EA2A091F70EE08CBC7520C +:1027D000AF54B166630A8C3B67651BD1319C47825D +:1027E000FAD7B29584AFEA664D7BDDD5843FD8B980 +:1027F00011CF89B53B829FF74F127682933991BEF4 +:102800003D775A2230AF71B4804FD94AC586726B7A +:10281000FAB2B6841BA03E7DAFEA84ED74C387850F +:10282000FA23281FEDCCDE1CF2579C713892B09F22 +:10283000C7CAED5245EF1986EDD3E23CC3D0CFD8DD +:10284000F59185617EDFA1732A73E411950FA2FCD7 +:102850002A1B1B3429C0BE2F33D812311EE965F361 +:1028600093C53DB88840F8D446AC247EA8457E8800 +:10287000F0F3C3348C7BA1DDF3A24279846C473042 +:10288000BD9F703426C29190B9EF33909C2E6F8A11 +:10289000A5F371F9B22223EAD5F26DB1641FC1F933 +:1028A000F4BDCB86FAF1796859DE9E6418B7BC395D +:1028B000D3A906E331F4DC19B0CE390D8724FE8E9E +:1028C000F480BF23E1F007780B6A2F4F127249E0C2 +:1028D0008D2D8A23BD5A3AEFD59C0858D799BA480E +:1028E000CA93ECE97CC4668CA0FC03E9BF1ADFAB99 +:1028F000DBCF44793E67570E21FC69F136FEDFD30A +:1029000087A1BDCBFE6E6168674DCB66B74D86F67D +:10291000DB14CE6FD3EAAF198F76C4DD495C9EBD60 +:102920000572D0D597B1B7410EBA400EBE0BF21169 +:10293000EBEF2F4EA6FA878B1D547EB4B81F954738 +:1029400084BF5FF21D1002D1ED92242E179724C987 +:10295000F8FA82643469C6FFFBDD213A1BDE676C3E +:102960009B30369DB1EB5CC1FAF7C6A9C1FAB5D36D +:10297000601B978CE7DB150AD9A3E5EE9141FDE1D9 +:10298000DC64C47B2BAC5F9EBF9DF486C33819E822 +:10299000F1A6E2B8A0FED737A406D59F4872D0FAB8 +:1029A000268DCF0E6ABFB9B47F50BDEC9C9131A487 +:1029B000774701F1CF0291670407778E171BEFFB72 +:1029C00075DDB0A4BB60BD5FEF33D0732D3E245ED8 +:1029D00067AC519907C69BBE06E41F2CF148E3740F +:1029E000E2AF2F0E58E85CB2BC296F7F01D40F35DF +:1029F00019280FE8D0B2B85568AF1D6A4AB032281E +:102A00003DCB5561D7D88C2C40DE152D5B42F9A605 +:102A1000653E9393EC9776EF93B2EEC0F32A2E12B5 +:102A2000F9E43DD5D7AA10FE5C04DF6722E95EE138 +:102A300071B027F12AE1F44EBEAEE30A5B86F513CE +:102A4000911FF7B90BD6716A6263850EFD15EABE58 +:102A500004929FCFAB0CE9B6749E81F20C66BFAFB7 +:102A60006EC03A53725339BE55CAA366CF98687C7C +:102A7000D6051402FD163C6D7AEA01AEFF787DFBA7 +:102A800040DF03823E918E8EC732572C2D56A1F522 +:102A90007EFE76C2067CEE87A76F10EE7BBDC1FD81 +:102AA0006612E0EFF30ADF20926F8B1288AFB470EA +:102AB0003F62E4F2CB8B7CA0F8E5A69FCF96927E96 +:102AC000986E70263A496EE5A7A0DC3AB2D24076FD +:102AD00030D3BBAC93488F3E4F742CE739A2778C30 +:102AE000C3F51D69C864985F51BE52A5F30AD21F91 +:102AF000EFEFE3E7D487550FD824CCDBA07858520A +:102B000028DDDC3E6F18E55D6AED6D597E09BCEA93 +:102B100009B04BE6ECE479812CBF533F7560E03E91 +:102B200096F1F93C0541F94A5559AF1D34EBC82ED1 +:102B30008CC173C289F754A2B313598D4393019F7B +:102B40002775BB86DE05F52F267A8FEAA13E22DAAD +:102B5000F32F84EB5CDDCA0C250BF3FA0FAF1A09D7 +:102B6000EF7DFEACC1496C2EECFC39CFCCEEFD43C1 +:102B7000F615D81BBDB8DDE14AC1FBCF731DCD1AD8 +:102B80007B80C3C78149200017DB6A056D377678E3 +:102B900088E5013C574FD7314FE079E0B0C8E3B149 +:102BA00024F373A8B41BA6247339335DC7E99BBD16 +:102BB000AC707A03FB2A500F48B93D17F3AA55BFF2 +:102BC0001E9072BB8A3552FE8A2399DB2FB3151FE4 +:102BD000D9DD35988902FD2B6C3C6856B5D9E4F3F4 +:102BE00065D298B640FB607A329727738CCF3E8EC1 +:102BF000E45BC93AF83E35FD3E37F82A3A3243F5F0 +:102C00004F856DC3323B8D6F70A29FB752F06B75CD +:102C1000A3E26B253B85EB51E9579D29F4A8563F6C +:102C200085E8258D3E9AA9D1BBAC3158CFC27AE94F +:102C3000DEB25CAF769DEE680BC1610EAC0BF56F3A +:102C400085C7B7A784D6AD3801A321EBA964EE31BF +:102C5000B1B80F78DEEA085D9F765F21EB15FBD4F3 +:102C6000AEBBC2F9552BE6BB543529042FED3E24EB +:102C70003EB4769CC44B8597C3B7A245217C7ED6D3 +:102C80006D1F32F26F4BBA61CDF02FE07D4947B036 +:102C9000AF12946F95AB411E6786D2D31CD66C459C +:102CA000BAA961ADCB5390DF5A9BAF1F8E7E86B51C +:102CB0006FD3F9A9D4DE9AA38B05507A73578EBFD0 +:102CC000CA4FE7178A27FC5CF0C3DDE9A59F1EE029 +:102CD0003573A3EA8A1C14D44FE43F7A098EB3BC3F +:102CE0005E23FA6367093FE585D659ABE7F75F2EA8 +:102CF000B85E01CF9F7BDD0F27F76477853F17769E +:102D0000DB5B1A3DFFB181FB5BA57CFE5AEF22FF26 +:102D10002EB40B3BACCEC6E37D1AB99E9E4F72BD5E +:102D200042E87939CFD1355B295E3013ED8080F6EA +:102D3000CF566FA578A5F1D99956B4CB8FAE99BE71 +:102D40000AF3528F364D27BD5FF97BA9F73DC64088 +:102D50007BA2684DD9FA7B908E3747525CB1A2DDD9 +:102D600023CE452067A19F630D97AB6C3597B39534 +:102D7000A81F07907EEC8BFDEEACF0F4457E086852 +:102D800027BD79E774CF9F77C2B877FE29DAE925A6 +:102D900050D85A7564CFDB5A513F56CFFFF020DE32 +:102DA000D3017BE0FD5F4B7B00AA45064F5B32EA17 +:102DB00021610754AB1B326C683708BDF11F807F5F +:102DC0004478F8E712FCCB11FE01F1DB4F1B389C75 +:102DD000A76BE07F7825C7CBF2A66C2B9E2F3F6DAB +:102DE000C826BBEBD3A61C82FF8C0700FEDC5F1F4E +:102DF0006C773500FCF17C81F087F596B73B04FCDD +:102E00009D1CFE0D1CEE6C252F6784C0D94BF95715 +:102E100077FED1E4443BE278642BD957C7B7A8AC1E +:102E20003EC02E9376D137ACF149B4DF24FC67F76E +:102E3000E91884F2A7F4E1D7AC8887D95B785031E0 +:102E400004FECC9544F1C7EEF9BBEDA86F115FDD30 +:102E500076D445E2A986B919E9C796D70EE039427A +:102E60007171BF458DBC6FB623F8BE19E69295DA35 +:102E7000D1C5E28C88C0F5A469EFD37918C6BDBE70 +:102E8000CDF9EAD6F9C4E75D4179B925ACD580FE24 +:102E900036D6ACD03DEDEA0585D6428671B53A5AB4 +:102EA00087334509CACBAE5675644F5619457C44E5 +:102EB000E45524897E4929DC2F909C62A3F2742476 +:102EC000237D70DA62F4E17D2A385F25E3FCDE9D24 +:102ED00026C2DB415C13C05F350A3F33A842A4B76A +:102EE0005B18A7D35BCC7B29AE07279775A81FA7D4 +:102EF0002D3439C9CE8D8FA1F8D2CD42DEDD625E90 +:102F0000EE463D31CD6C746109E37A31F9D7301A60 +:102F1000A687F90DBD8C74EFB034A2F3593C12DFD3 +:102F2000967CF88E0858EA95608EA31F187EDDF611 +:102F30007D5C285EFCF809F64BD74685F78B0C17AD +:102F400070505C2EF23F9B60EC2858C7A814076FA6 +:102F500077D8B83F7A2DE0C9E2C7AFB69D7979FC42 +:102F6000B20AF3B1F9F758BC241F545D50BDCAC86A +:102F70009F4F796243F1EA34C6DE618E8188B72AB9 +:102F8000942178EE2F8BF1617CEF3AF487DBB1D49A +:102F900013BD4CD633AF8E970D663B0EC7FDE325B0 +:102FA000029EBF2A60AD3100F7D6D783FDF337B458 +:102FB000EA5AFB027CAFD3B7B6217DEA221C061B7E +:102FC000CCE31EAFE4E239A56AE9C5ADB7E289A654 +:102FD000E2D5A3A0AEE3F9AC5DBFE6FE895B805904 +:102FE000116EB7EA59BB9ACBE900E1526B7778A929 +:102FF000DF3C85E237322E20F13F18860FC4E32DE7 +:10300000627D304E8315DF3786C7D77C812FCC8C0D +:1030100046B8CF157C3757F25B5330BF3D827804FA +:103020003E55D02E06B8DD22CA9EF8E2A1146E47A6 +:103030003F94C2CFEFF75CE27CCCDC95417979829A +:103040005FAA4D7C7C39FF75A27C30C54EE3CBF581 +:1030500000BD7E8AE3E8400220BD1E69AC27FB6804 +:10306000160B88C365FAFB49BA0EAD77CB11DDF7B5 +:10307000581ABB6620E8955F443A518EDE626CCEEA +:10308000A93387F69371E652D661A0EF03493F99C1 +:10309000D03F635533E535952AFC1EF4E9428B5742 +:1030A0000776E2C722BE7B06EC469CA73456A1FCFD +:1030B000AF69317796205F975A8D7A2C3F16F1DFF2 +:1030C0005B59178DFF892D2BE60686DF4D5031E6C3 +:1030D000070BF8A4D805FBAD47F9C3EB2B5D69E4FA +:1030E0008D12F54FF7615C66EA79A003AA1F2E7670 +:1030F000C1BCA75F15CFD991627C7EFA3E41CFDE7D +:10310000E334DEE9C7E4F353FCF90AF9FC2B5E7FF4 +:10311000508E2FEA0F6B9E2FD13C7F82D75B9FF89A +:10312000AAD88BF6EB684EDAA523149257462137BE +:103130004A97B6129C4B75BB78399AB5EAF22FDCE8 +:10314000EF648ADB989280F7CE8F58500FFF33D50B +:10315000654C817E9F2679FE86E59C498AD78872D8 +:10316000F73D1FE985921EF2278D42AE9FEAE5A644 +:10317000F7A51E8371DEC3F12F759CBB43C7F9E42D +:10318000C78C734D6AC838477FCCBEFE9CCAE12409 +:10319000C791765171BA4BE985FC3A666490BF706D +:1031A000EEBDCE18F44B31CC7703D0CF5DDA9C91D5 +:1031B00007E3CF7DEEC58C0AB49B84BEAF39A7323E +:1031C00017C8A3DA730A955FB47D64C47BB335DB9B +:1031D000DA8CE3A05F2D944501EBAA12EB047DA7E6 +:1031E0009F1CA0A78DBD74426E3CCCF3329E3BA1C8 +:1031F000477CCED5351FFD3DEAEF114AD8F8F2974E +:10320000627F077BB81F61EEC5E551616F5734EEF1 +:10321000F314063960FCA2FAF0F902BF12EB28158C +:10322000FA6FFA504B8403E03CE43D1E5FAF589BBD +:10323000998BFE6263F2E804825B8F7ED62EEE6786 +:103240006DE17ED6527BC702FC4E99BB57EC83F8EA +:10325000DDB209BF937C062C0BEF8E37C97ABF898C +:103260006346713F18D6F37E9FF920F2CDDE286EBB +:10327000CF4E1B36300AE5436766B4CE06FCAC4F32 +:103280002A73F74AC0F6ABC6617BA1C9D2A78CE00E +:10329000CB882EF449EEFEB84EEC8FFE118FB1357F +:1032A000E106D887E70D95EE037806457BC2C5CBCE +:1032B0002FEFC5E5B9BB978DE0B15707EBCCF5AF64 +:1032C00043CE0F76FD820E18EFC8D294C10F38306E +:1032D0001E53785DAF04FFFCB3923CA302E73FA20C +:1032E000637DF06871B1EB182EF0711DC2064AF7CC +:1032F00028A0B780F3DEE431D141F5A9C571CC1522 +:10330000E8BF9D9A1A54BFB1343BA8FFCD33FA07EA +:103310003D9F68EAC8AF0BB0677BB697BC049F5A65 +:103320008B250AEDBA4F5ABEF9E016B40337AA4E00 +:10333000B45967EFDCF4C148E87506F01B477E49D5 +:1033400007F9D13E9779747A973E307E748A75502A +:10335000BEA23CD75E6CDC68AEAD9DF2097FAE7854 +:10336000D1BC5EE2FC9BCB72513F9EA97B9FFC7956 +:103370003566BECF532F1EE2DF2D44BD02747F356C +:10338000BE88F6E23910FCC0FF453B0E519CCD864D +:10339000C14DB4F7D3E6E9F1FE642D94A85FC68170 +:1033A000DC8A01BAE9686303B761DE48A685DBE51C +:1033B000E7A690BF7C6F14F7FBEC4D8CA5EF48CCD3 +:1033C0006DB886DA6BCE45D3F86FA91DE3282FFAC6 +:1033D0000585E2131353A72DC5FDEC8DF20EB81D24 +:1033E000E69DF8E7ABC723DC6AB6F17B0213D5771D +:1033F000F2E74159D5780DBD3F51657B15B01F628D +:10340000CEDD42E34E441B00EAEA50CB03A89755B9 +:10341000636B9F3FA0BC315A48DED49E8BA4F72635 +:103420001471FDFD7B214F0C9D7C5D63CF4DA2E7A8 +:10343000922E7CBDB282F2F70D091BF5F8BD214337 +:10344000A742FDAF3DD79F4AB9DF37FAFD91BE2FA6 +:103450006048F87A1CE68DBE11AFD8C82CD1C8E3FD +:10346000B375C362581879D53DCF399E6F6C3AC792 +:10347000F38FFF3BCDF517E4C392459D7A8C17314E +:1034800073840DE1555230D85111C067EAAE9B8C60 +:10349000881FC3EAB78DA8AF4D5016053CAF16F98B +:1034A000585A79DD22E483FC8E9BD43F2C7906D1D7 +:1034B000E7AD3641A0828F9E167C2CDFEFA0330E45 +:1034C000E0713BF7F3B7A679DE4239D151C86E7C83 +:1034D0009EE4674706C6697EAEF5039E2314B21BC1 +:1034E0003B29AFBEA4C0A1C3F8C07BDD7A87F3F34C +:1034F00085F6D126F6FD96CA16E2B86FFDF2971D45 +:103500002E18AFEDEEBC3CD40B72DECF7AF17B0B04 +:10351000CCD6751ECF87B52F473B90EF27E2E10C45 +:10352000E3A23B4D746E81768A77D4BE6C7A0AEF43 +:10353000BBD55AE1FC0AF317BD12D98A74DCF64AEE +:10354000A41EF5C71DBD3D9F217C8A5EE93B06CFC9 +:103550008BAE16939E91FDE33A4AF2B687F55E482C +:103560007E69E94CF2A7A781F34B99A0D372C17F82 +:103570001EC14767EB92880FCF2E8245633C759141 +:1035800032701BDA0B0E0B7D974EF2E5443C1F4167 +:10359000FBC4FEB1748FA1EA5C6C101F569FCB1464 +:1035A000FC1D47ED92DFCA059F98847D3143D0B55D +:1035B000B45B243FB2744F622AEC63623DF0BD9568 +:1035C000E2FEF9C84F7EBA31DA90BE806E922B02CD +:1035D000F8A7BEED2686768A29DE4D743303CA40ED +:1035E0003B6566B79D621B9708EB2F5996A9C37B75 +:1035F0009BF2796AEAA5D17F44AAC82730B7E6A032 +:103600005D6BA88B74E27D9A33F13C1E347F058795 +:10361000E37C83BB08ED8CF94F28E43F43FB03E5D3 +:10362000D2D00375C640BFCA4DE706513C7DCAB92A +:10363000CBA834267B2E4738949DBB5EE06BD08FA1 +:103640008A3F0E7171BF92C167726EC844BF9247C4 +:10365000453C1F4F67B64703E37D6B54F28FC9B8F3 +:10366000A4F43399F0DE4F803EFD46DF9841DFA39E +:10367000D1FA9D0AB9FE3FB9D140FABFAAED9DA18A +:103680003A78FE79A62B09F5C97A83A708F733673C +:10369000B2EF3903D4E73EB8D53ADCE18767B3BE71 +:1036A0003507F56933C011FD5FCD2BD5F13E6EF7BF +:1036B00044F3381AA76F49CF5A3A9F732E9BE07391 +:1036C000B6CE447AE82CD02D0BD04352EF48392F98 +:1036D000F58FA4EB6A3D975FD5E618CA23F3EB9DFF +:1036E00049EE42A4BB7E3C1FD0AF779E5A3502F90B +:1036F000E0743CE55D4BBD21F9E085C5C9944724E4 +:10370000F592E40329CFA57C97742FF5D6E83FFD09 +:10371000EFD6BFC3AF93D23C77A5027D5DABE7FA8E +:10372000EB5ABD85E8676CFC243DD2CDC5CBD143B7 +:10373000428E1E0A92A3353DE88145A9527E5E1C49 +:103740001FCC117C33DEC4ED4894F381E3B5A68D24 +:103750007E08F7B13A95EBD99F6BDD3DC9FFD5A93E +:103760009726FF97A45E9CFCFFEF54FE9D0AADBC1C +:10377000C70F71A3BC3FBDF3721FEA83830CF40330 +:10378000EAC19668C726A10F485F44C5F87E481F66 +:1037900014F69EFEDFA9E1F5C1666CFFB1FA40D2D6 +:1037A00097E41BC927922FB47C24F962C26FE1BC55 +:1037B00088787A8BDF8FAAD67B9B280EE9881E8CAF +:1037C000FCD96DC76D5388DF42F484E01F3FBF040E +:1037D000EB0DC91F925F24FF540BFE9829F843F2AA +:1037E000C56EB5F9D111980A90E6F908E588E49319 +:1037F000AAE7B5FAA147BA424F239B195FC790AE1B +:10380000AAA10CA42B530FFC70F012F5C2BE8BA41E +:10381000A7AFFEF3F4F4550FF474E6A7D053A81D38 +:10382000FB61BE03D673361FE46DA69FDE26FC8DBA +:1038300071FB219B9F07F646F17DEE35A693FF674E +:10384000C2F73CCF57DA033385BF41D2691ED80196 +:103850006943FCF8C7F3C0BC8B937B8467537C87B8 +:1038600011CF2733A10CB4037AB27F53D32E4DEE80 +:10387000458AFE17C2F380B49FDD6E1C90161EAF02 +:1038800003D37E025E2762A22AF92BB24B5CA3000F +:103890003F0F89BAB74F09C2F1FA02F9FCB2552EAF +:1038A0003DCA07D6FDDD75F477BCA5CA7ACEFE31D8 +:1038B000B09E098F32BF1F1D9E8F1D15D3ED1F5166 +:1038C00098BF7F715AD6FE95A4E71B45DE4AA79E96 +:1038D000C783443D1FEA96807A81A6BE96F7B7EA71 +:1038E0003B59603E09D28D92CBF1EC0EB01F60FACD +:1038F000F6B3A82F6C0A43FF466DFC8657CFA25C37 +:10390000DBA1506CAA1B0EDE810407FA3E38D507F6 +:10391000EF775DC6D8CDDB78FDF6B54356792F132A +:10392000E306DC1B32342B2ECA4728507C5999A160 +:10393000F0BE3D4DCA13B91E46F71402DE6798AFBC +:103940007729EF77E74D67D1FBADA64B98FF8651FE +:10395000E1EF6FAC10FDC6E4C7847DFE709ACAE14A +:103960002FFC06343F344D690E7F9FFF09C12F1D88 +:10397000183F21784E5A85FEED0EA384B77B15C201 +:103980007B2C63417E34989FEA1BD7BA4B1AF47C98 +:10399000BB2E0DBC7E68BF77A505DB03F49B065FDD +:1039A000A61F80F7DD61DE7704BFDFFA43F85A1205 +:1039B000F2BEA0DB59928E5D41F41EA377137DC643 +:1039C000C42B36B4A36BDC912BF1BCE0E7CFD21251 +:1039D000829B8C1384F0DFB4923103C84E12CF6FF8 +:1039E0005B85FCEBD675F7E7FC28E91AAF36015C7E +:1039F000C9F507EFBF9C76EB2AF44F025DD073AA9E +:103A0000EB03D6ADE5C7664D7D94867F05FF91FC3F +:103A1000407D0070CA41F9167FC8E808A0934F04A2 +:103A20009C4E897CF28ED1DC9EECC8E2E577693C45 +:103A30002EF599A0CB53929EA202E09016443FF43B +:103A4000F72102F64D70BA295EF2F3BD25C5C0BF5D +:103A50001D76FEFC7FD6FE669537CD5FD78EF7CFFD +:103A6000B5F796205CBAC7F72EDA8F76C44D026E92 +:103A7000DFADBD67BF7780C073A2FFBBAB401FF453 +:103A80003D9E6AA40F25943E5E0DA52FAFE67DFAFC +:103A90003B043DBDFFB75079E0D2BCCFF07B10179F +:103AA000FFBEC05BB106AFE335781DA3A997CABAC4 +:103AB0002F48FE4AB95CBEE3E1FB12E3D1AFA9D0C7 +:103AC00075243F3D3F48F43CD726E97715C1D54FD3 +:103AD000CF0FED47FA9DDC2CE9B591F4CF2494C3C8 +:103AE00023FCF5292887A8FE7009C6C5FCFAEA91CF +:103AF0005528B76F6890FD1FA5FE372F93E3ADA63D +:103B0000E7128F8C3D46FAEEA67CA9AF1E27B93F7F +:103B1000A785BFEF4CFFDDFE1FE487460D5CD66A2C +:103B2000EA5E4DFFD517D06FCB34EF2FD23C5FA9A3 +:103B3000A9AFD1D41B82DF2F9BA1101F9615F0389F +:103B4000A5962FB5F4E14AEFB673BAF5B96226FB34 +:103B50002E88AF26D4F3FAB5E91B4B1ACC01F575C4 +:103B60009B4A385FC06C01F79F41E67A55A0074336 +:103B70000F72B320BD07B9D94FABEFF9F37FE0AFB8 +:103B80002914370AB24B76ABC1F53655ACDBBB75A1 +:103B9000FF820181F1D5E74BF05CDD631CC7DB5C84 +:103BA0003226D02E62CD25AE807DCAFEE3BEFB5EFE +:103BB000C5F93CEBFE5CB2D18C714F11DFB4F3124E +:103BC000F4A58AFABA56F86FC6611E2FC693A25A98 +:103BD00073E60F08D8276BEE83FB6CBB5BE5DFB7A2 +:103BE000AB07FC009CCA9883F250A73317E5A5B633 +:103BF000C5C42CFC2F786FF7DDEA42D4D30717C673 +:103C0000515ED32BE9FC7CB13BA677E24CA8B745CB +:103C1000DF46F2B6EDFEB154EE525DCBBB6C8C2D9F +:103C20005EF74A89F9727C1E4370BA3BFDA5922566 +:103C300040EFF7A63BE87D8FDD96B803EDED070C6E +:103C40001437040E7892E8E741D3603C6F972DE972 +:103C50004F71B1F2C7268DC37BA4E5F719285ED258 +:103C6000A9B3919FC8F3C058CA939AB14C94DEABE4 +:103C7000A97CE5DF7FACC77BA65DEB14FA4ECD5582 +:103C80005F37FF6D10D42B1BB2E97EC6CBE774946F +:103C900017FEE99ABE3ECC533E1C5947F9A5D09F6A +:103CA000EEBB569E77EC2FC9C7FEAA0D53388E4245 +:103CB0003BDACF4757A84FE13DCE32AB250AF3BBE5 +:103CC0008F7EC7C8AF73F43E137DEFE653B3E7D6DC +:103CD00035F1748F092D7D765471581580C3DAF44F +:103CE000FD25C929D86E12F8DC6F2D033E2FD37540 +:103CF000D30FE9938A585E5FBBEECD924DB08FA390 +:103D00004FF4A57CB1840CD7BA7480D7E10CD7935B +:103D1000548AFBD9AFFC9BC7255F3A599E88F4B5FE +:103D200059D0F5CBE7CA1303FF6E41C5293DD1C178 +:103D30002B46C702FAEE6954BA82E76CA08338F4C6 +:103D40009BCF10E716A0E7855BC3D8574BD3B93D8F +:103D5000D6F6DB84518E20BAFE98E4299D37A0FE6A +:103D600062FA47A4E78E9816622E75773E24DB1D13 +:103D70004970323445FA2233D17FEA1AE7A2F34F71 +:103D8000739FC996003E14FD3FF1F2FCDF4FA03F48 +:103D90009EFB3EF1FE3F4B603C43F6AFB45ABC681D +:103DA0005C1CB358F4888F83FAC547313FAD629DE0 +:103DB00081F440C5BA84455D287F806ED0BFA6DD02 +:103DC0009729C3C0FD183DC6573F2F199316785E3B +:103DD0003941F2BB27BE7C37FD44C9C6013DF365BE +:103DE000A58DCBA771EBF8F7752B8758F474BF7BC3 +:103DF000DDAB9BE81EF0BCC85CBC5751B9CE44F8A3 +:103E0000EAB458BCB62BF1BE81451F0BE5A174AED8 +:103E10004FF5190EC24791CAF411B954D23D0A198F +:103E20003F3CB1F0D1C7311DF373E6BB7E18C0EF44 +:103E30008C8BD3E9996D2AF91FB5F1C4EAD7B71A6B +:103E40000BD98F8827F61047AC629DE2BBE2E1E315 +:103E500089DA38E2BFD2C5BDB3EE38A281BE875140 +:103E600029E288456B155A7FE542FEBD92A238EEE5 +:103E70003F3EB218E8A02FEDDF6BCBC53C69AE7FAB +:103E80002A99E28B805FAF5E3B8FFC9975E91C5EDF +:103E900065E23BB087239D1978DEAF58174970AEB5 +:103EA0007C72F6074FE4E37DC089F181E76B9BA04C +:103EB0000F189FE13D6839CEB125F7D077678BD6D3 +:103EC000C33919F3B463D973376522DE523230DE59 +:103ED00029FB552EBDBB0FEF07E76CD877D90A95A4 +:103EE0007F0F6BBB89F421F07C320BB82F3E63D976 +:103EF000EB4623D7672C79A8B0B31DFEFB6C9FC29D +:103F000073FC0441ADB8B726E127EF5B95E9F8F7FC +:103F1000364B750ADDC3028946F7977E91C1FDA332 +:103F20007919DCCE2DCB70D23D9EEA5526E7D24CD6 +:103F30003E4EF7BD7538E755EB3A2A28AEF9171310 +:103F4000F9576A9745BA22AD3C1FE3F9019477AD62 +:103F500037023CAA1C5C6EFC42D063AD63D2D594A0 +:103F60009FAE6707F0EF07565BB89CAC8E05B89B19 +:103F70003901E986E2F73919E553E2B8298302E607 +:103F800057443B8CE3B0FAC7DDAB630DE8A7C1FE35 +:103F9000970F4238C65D7F23AEEF5995F81A80B46B +:103FA000AA00EDBF67D53C3C7797ADD83D0EE5F054 +:103FB000DC2D83F146052B7BEE5DD2237305FE3BA2 +:103FC000453E5A39D4F1BB81376470B9E951B9DF44 +:103FD000E806012F4907F279F50A03F7E383BC47A6 +:103FE0000153BDE4431AB7DAD2918872B87ABB8123 +:103FF000EE87DF8CEB0638972F491F7500E8AADCA7 +:104000001043DF51ADF24E3462BDAA51A1BAFFBDDB +:10401000840CA4D32F96BD6045FA391CD99A83FA33 +:10402000A96B5EA493EE29DAB8DFEE8B653974AF25 +:104030006986ADC382DF6599B120DB8E72FCA0ADCD +:10404000D588CF0F3667EAB0EEB2D94661DDA5BF9D +:1040500092EA5F887C17FA41BA52389EAB9A761B77 +:10406000F1EF2FDD2BE8E2D4B3EFF6413F50754678 +:10407000471FD42F40077D5211CECF28A49F6B9AA3 +:10408000781EBCA4831AA403E0BB39820E6AB6BDB5 +:104090007017F2430DE23F37948E809EDBA9FDF945 +:1040A0000DE3187FBF1DE944EA33A82F33A03FCEAC +:1040B000C8EB8B05FEA17D0C6FF70EE0F975DDF9FD +:1040C00008417CD0137ED766E8043E4C2477D78A1B +:1040D000FD76AED86E45FC9D7A76F71E8CB7543FC0 +:1040E0000FDADA11861F043C6A71FF565A3FD9195C +:1040F000B5B85FAB7FFFDD742FF8B096F1FDC9FD59 +:10410000D6EAC5FEE573F1FE3AB1CF2A26E0B5AD99 +:104110002FE73BC167C8C7F4DD21B13F8F3DF8BB36 +:10412000BABBC5FE9A44C96CCD56840FE217E50FA1 +:10413000D08FCB28E5097439B56503E5F74B7CC909 +:10414000F5BFEFD72B2EFC9354128F9D3D7CF7B615 +:1041500045F0C9A1FB92327600FCBED84C9F0D24DD +:104160007AD507CC27E946CE57F4A749D7E2BE61F6 +:10417000FC561C5FCE7BD01BADC7710E32CE1F72BA +:10418000FD922F8BEAA75D3BD88AFD4E59B2D15ED6 +:1041900011787C3FC346EFBBD06E80F75D3B14F2D5 +:1041A0005F1F12E7FD43F7BD602D1FE0A7F777C53E +:1041B000BA259DE10FFAC9E47AF7DAB93F58BB6E28 +:1041C0002987E4BA8BEEBFE15A6C97EBC7F8512010 +:1041D0009D4A384A7A95F7FAB4744B3427F5AADA2F +:1041E000337DD7A61DA2FC9D9076ED78C23E3A2C79 +:1041F000F2CDBB9E56F97DE765C9ED41F78E1833C8 +:1042000007EA9F25F3AEB615623CB749A17B1E5263 +:10421000AFC0CF4A7D803E92F6C1F0DE3C7FA5362E +:10422000DE7502F15975BC631C7E9244DAA5577D98 +:10423000DDAAC6A0FF6A1BCF8393745375B29DF8A5 +:10424000A15ADC932A5BF1EEC46148F74F1B28CEDC +:104250005376DF5823DAFBB3374D1F8AE0C07B1259 +:1042600028DF4F6C1C9247E061B6C4EBF1BEC4C6B8 +:1042700047AFC7BF5F3A63874ADFA1C171908FCB59 +:10428000EEC8237FEBE1C8CE8923D0AEFFB56A43E9 +:10429000BB7EE4A6218BB0FF484BEF58FA78D0C61E +:1042A00038AABBF431A427A41D2CF303EBC5BD90A1 +:1042B000ECDE9CAF7A75978AC80BACEF83F1F9AE50 +:1042C0000D91F4DDA852A3A3B915E7DB9944E78E5D +:1042D0005A382625DBE99E2BD969B38C2C222597E9 +:1042E000DA233045F97543C71DA84F5EBFC33218A6 +:1042F000BF8BCBD4F343CBB97DCDE39071C1DF61EC +:1043000092EBC8EACDE9573B9E7C7F2F9E2BEC7445 +:104310009F91DE3FB1ECE9EB511F9ED89C63C77DB6 +:104320001FDB1949F70B8E1982BFE778A9F7C2B4D2 +:10433000F7A9E43DD7FCDEC1F69CA4FB0BDECBB9AC +:10434000ECD2F2984E2E66744FFC5C06E3FEE4E875 +:10435000EFB6627E6145A3C986F7648E20FD637C5B +:104360006BBB4ADF01A2BBDF80AF23DBF3E83E700B +:10437000C5C7BC5ED1ACF8F0FE72FBC3F753FEC2FA +:104380004CB037F16A79B73DBDFAE1EB910DCE380B +:104390003DCBF13B006736F37C8B90EF3ABCBE75AA +:1043A0004F8AE3FFBFFD2CFD13D37B07DF4793F05C +:1043B00096E7AA57802E0A72FDF0FB72F12CB29F8D +:1043C0004F2EF650795A39B46A24D2B32586EE15A9 +:1043D000BCB4E35115BF7353BD6DF0793C1F8F30F2 +:1043E000C7D0F79FBE5CBC90829A2717D7893F8AB7 +:1043F000B654F8157C545EB5AD8DDEFB72475E0B8E +:10440000DEEB7DD91CC3C59AAB20E83B9912BF3DBA +:10441000DD5796FBFAFCD71CCF72DD9F6F9E6EC5F1 +:104420007DB5FD21AE6538E2373AC6867660A5C80F +:104430002F39BA86DBD9C72362FEAB18F07C7CED3E +:104440009444FC0ED1CCB6A9D7637BC54EC586E794 +:1044500003E7CE49563CCF7DA6EFB4E23DAACFD6C6 +:10446000C8FB573EFABB7B23C6B329D87F44AB9E1B +:10447000393229844CF432FCA49EEECB7E01EDE46B +:104480003F391F45FE13F889C37C92992F72BF4BA9 +:10449000F7F9579CFF468A7DB7F7B6CBF806B517F4 +:1044A00015F0F6636BB796D0DF4FDE68B0E1BABFA8 +:1044B000DC68A0F1E7C0B94D07EB3DBE999F83B022 +:1044C0008EE7E8139BF979674E333FEF54CF33B84B +:1044D000F8FDD260BA2C0AE847DF2DEBE1BB23736D +:1044E0005C7C7F73407FE27E2F44BFB1AC99EE9F2E +:1044F0005D6A3EA9967EFFAA9117DD74DB13BD08A5 +:10450000B822FF23DD4ABA98B386C7F5EDCD830BF9 +:1045100091FE249D68BF03586F64FC3BB2BA28FA31 +:10452000EEF724B3C380FA624A7CE718044F5F07B2 +:1045300097AF6A91CE85F7E458BD29EC77C4DE15B4 +:10454000F2781ABC4BF7BB7ADBF8F7CFC47D315950 +:1045500082BE4A477D3E29DAFE8D03BA74AEFFF271 +:104560003A3DD0F5A491F63BB29D80D7F55FF37A42 +:104570009E7D7B16D43FEF7DF63A3DEC6FD295F6EB +:104580002106A82F59F2CD7563E0B9C9E13AD83BAD +:10459000609E139B92D2717FD07E08DBA7277A8E14 +:1045A00060592BEE8F9D56BA062DCCF4F77F7BA772 +:1045B000E5E04B0E7FBDD3C0E8BB3BA77BCBF587C7 +:1045C0002F9D0ED7A9DE09A1EDE58CDD47F97C5EB4 +:1045D0007E6F077EDC118978AF8AD35DB9BCC7D303 +:1045E000A0B9C7E3E4F7D5E4FD2A797FEA72FFFDBD +:1045F000B3B59772FFECFF0069F3B24F0080000083 +:10460000000000001F8B08000000000000FFE57D97 +:104610000B74545596E8B955B73E492A4925845438 +:1046200025A984AA7C2B90C0257C0C3148E5030485 +:104630008858286AD4A005A2808214011D74F455FC +:1046400061307C9AE98E9F1722462D10957178DD96 +:10465000D1B16D868F532032FC9A0EB463EB8CD3AC +:104660001DD0D168631B3138F40C366FEF7DCE4D11 +:10467000EA562A80BEE77B6FAD975EF6619F73EEC8 +:10468000F9ECB3FF67DF5B5F192CEBA564C6240F61 +:1046900063AB53A1745A596319947BFFE9CFD26875 +:1046A000C69A83AC3B2E8FC15FA3F5D35150CF7C0C +:1046B000BA4B502E4B481ACDC660991362D06F99F1 +:1046C00089B1AE12E8263B6DCCC2D81209FE9D011D +:1046D000FFF9CA194B676C9515FEED44B84287F097 +:1046E0008366467F9F05983FDFC0D81F4F742539EA +:1046F000F58C9D9D1D2E0CBB18FB65BCCFE69C0068 +:10470000ED1DCD8EA634C6BE7CC3A4D443FF9ED07F +:10471000DF27F960FCA57AE6EF84926D1FCED824DE +:10472000282FEAC353A0DF6157F1B68DF0BCCBA9A7 +:10473000630C9E3FEB0AE7FCF578C6822E93F232BB +:10474000A37E773280EB1E9F3E1CFB9D7D7D5DFE30 +:104750003DB06E93CC5812EC7B068C590E7830002D +:10476000AC2FC30742340EB40793A0BEC5F5740E38 +:10477000237C302F9BC8D80D8CEFEB0639BC1FF182 +:10478000C5946419F7379B6F0FDB83328CA33333E7 +:1047900003AEBB9875583F4D0098B18E4BC3607FF8 +:1047A00066C063329680C724C6A6EAA113ACAFE9FF +:1047B00097FA9009D6D784781470D085237A2CD7AD +:1047C000C3F88BC5BCCB8EBC6BC4C15810FE07EBC5 +:1047D0005922E65DDC71773D9ECB9290E14CB7C0EB +:1047E000F525FA7F0F9DC772D1EFFEF2AD469CE230 +:1047F000FE1DDA7ECBD9A6AFF5F0FC52D66DC4FD16 +:104800002EEB8C6AEFA8F90CD7BB7C97B6BEDE996D +:10481000988674C2C6B2B197F4544DE7BD48F49976 +:10482000AA6F74CAB89FE166C50413373D9F47F469 +:10483000C2DE0CB0C87EAC6318D14F8B4B4FE7B1D2 +:104840006497C49CE318BB7E5716734253FDAE6158 +:1048500054265DC8A0FACF5F3936DE5732705ED776 +:10486000BF6AABC6F55DFF6A1195EA3A9A041D4E20 +:10487000D5977486611DE72CB00E809B8EC0628137 +:104880007E9A6ED68718E19999B1BF572CC76B599C +:10489000DFA54F42580E8AFD4A97243A84643C1F94 +:1048A000EF613D437A621E03B53B9979CDA55CA0CB +:1048B0001BBB8E3963E0DF24CE2FCE19CF9CEE8157 +:1048C000763958FCB34A588761AE4109417B735C25 +:1048D000D236E43316F474E5C3730DE2B9AE384E44 +:1048E0003709EE54CDF32A1DDC2AFAAD4B9A76181F +:1048F000E9B2C1B388E82151C9D4ACC7A45F6A400A +:10490000FAB9D567F8A43B621CA25F58C70D5E29AF +:1049100084FC787383B6DD50F975AD4425D4478E99 +:10492000E7D5F6FB29D203D03B107E71243D0C9CC9 +:1049300083C5A3C373F02412BDCBCCB9B912E05B1D +:104940000E1B18EEDF14CFF7790E319786FD800F1E +:1049500060E2758817A84F2ED7E237C5A3C5E7B028 +:104960003A2D7E867BB5FBB735E46ADA337C233596 +:10497000ED598BCB3470B6BF42D37FC4EA6A0DECDD +:104980000ACED4F4CF5B7FA3062E68BD5DD3BFA84B +:104990007D81A6BD38749FA67DD48E260D5CDAF984 +:1049A00088A6FF985D8F6BDAC786376ADAC71D7EE7 +:1049B0004A034FE8DAA2E97FCD07DB34ED93BA5F13 +:1049C000D3B45FDBF386069EDCBB5BD37FCA850373 +:1049D0001AB88A1DD3F4AF31FF56034FB5FEABA60C +:1049E000FF74FBC79AF619CE3F6ADA67B9BFD1D216 +:1049F0006B3C9793D72BFFA579EE5993EFDF505F70 +:104A0000344B95DD4186F4EB243EBA354DA7840145 +:104A1000FE832A97041D9E1C612539C1F2598EB769 +:104A200014E9B0328C7C7C6E9744F2E0AB28BD2850 +:104A3000FFD1EB91A09DFD4A525E7622DD415DC41F +:104A4000FC291E339323D639ACCEAA81877BED9AFD +:104A5000FEB606A7A63DC3E7D6B4672D563470B69A +:104A6000BF5CD37FC46A8F067605EB34FDF3D67B3B +:104A70003570416B83A67F51BB4FD35E1C5AAC6926 +:104A80001FB5C3AF814B3B576BFA8FD915D4B48F89 +:104A90000DAFD7B48F3BDCAA812774B56BFA5FF3F7 +:104AA0004148D33EA97B87A6FDDA9E4E0D3CB977DF +:104AB00097A6FF940B610D5CC58E68FAD7984F6A74 +:104AC000E0A9D60F35FDA7DB4F6BDA67383FD7B4C7 +:104AD000AB76D02CF7D7DA7A61175DAFFC59F37C4F +:104AE000B0DAC3903E826F484AB313D6EB02E13F7F +:104AF0009CE47C779C1EED282F18148C0129AD4175 +:104B0000FD920C420CE90A488C35A6E22840AC2004 +:104B1000B74955C1F3C9684F0090AA73B9FCA01FEB +:104B200013D85AEBA766B21B1C9740DF5DC2BF29A2 +:104B3000834B94A09FAAEB85F966A14E023A6F724F +:104B4000F93C2E58CF7D9DAF4FCB626827045B7038 +:104B50001DA00793BB416F9E886377794B068F3703 +:104B6000C30C788998EF485CABA3CC32F4FC33CC0F +:104B700067A97FFFB8063EAE04FB6B8A18FFA7A0AB +:104B8000EE65B0FB5A03C037058C3D15B012FC4CE6 +:104B9000C04E705BC049657BC04DE5968042ED1DFF +:104BA0008172825F0878080E05EAA8DC16F052FDD3 +:104BB000F64003C1AF047C54EE082CA6F2B5809FEA +:104BC000DA77065613FCF34090CACEC07AAA7F2348 +:104BD000D04AF09B817682DF0A84A8DC15D841E5B3 +:104BE000EE4027B5EF0DEC22F8ED4098E070E03094 +:104BF000C107025D041F0C7C40F0A140379587037C +:104C00003D541E0DF452FBF1C0058207CE4B6B578D +:104C10003361572E1274C0D2B83D792F3F52F685BA +:104C20008E2D46BB7791A04343359887407786CC3D +:104C3000C26DCD2E3C6AA01337D1C971B42FAF9687 +:104C40004ED070407A0D563337D29B5AB654E9C9CC +:104C5000FE0CAE90422F73BB88EB6F3353F537B524 +:104C6000373E2885D09E9B0776B211F8E623619FD8 +:104C70007C14C7E5F539BFC18D765FA314AFC0665C +:104C800001FE77B23BE02F8CA47FD75ED356B49F52 +:104C9000D4F535C2383A18E7BFEC2E5A57233B6C8F +:104CA000C0F540BD470FFC72C6E6DBE202BABE2F7C +:104CB0005B17342213594285DE44C68C76DFF348F5 +:104CC000E7E7FCF71CC2C1175995429CE77A537875 +:104CD000F8AD307FEF11BDB2CD39345E96B7CE005E +:104CE000E17D99F6B73F77A01D5FF717BD0FCFE1C4 +:104CF0008421B1210474DDE99288CF3A5D3A4DD91F +:104D000066F7FD02D7F96DA2FF4E1DA0F2DBEB5650 +:104D1000BCB212B6D4B8A22019ED55F00F0C685FE2 +:104D2000CF614E03CA879B98E75D1CEA66E623F8CD +:104D30005616A452B6F976E1BE6E6321827D15A6A1 +:104D40009C58FB8A5ED73B38D8702C759AF290DD60 +:104D50007700C7FB36D143EB3A31697A21EE4B5DE0 +:104D60009739C349FD66B3DE17707DDFEEFBFA535A +:104D7000296F309DFC88F4618169B03F33C2793777 +:104D800003EFE038CD0F4B21A473953E1AC14CA719 +:104D9000F11F857A29925E804ED07F4BEBCD99939F +:104DA00048F4D24DF26F923E68047BFA842E542868 +:104DB000E9894E8C12AC73511AD049EED0F4F0C090 +:104DC0007A2823E420D0D91738DE9FFEE11A37E293 +:104DD0006DF9DB939C88B7661D9C07D073F0A89E85 +:104DE000EC042644BBFEDAD210F907B2A2CC29C5E6 +:104DF00073E37271BF9EAD7E3D86DC4DC8E5F474F1 +:104E0000C26EA80BD1B89CEFD5767D2E3F477D2E84 +:104E10003FDFA6159F2DD5C3FA4F1CF8DCE82C8D7B +:104E2000B18FD53F79283F82AE97EF3A3DCD837E53 +:104E300017EB2EB93171A0BE50CCABD291DE98E801 +:104E4000DB6A895C573F5DC7E7225DA7005DE7111C +:104E50005D7F8A76F96C9333F95628BB013561285A +:104E60007D2F5AC97F5CC0142A17322F958B800C76 +:104E7000908EBDC1278D88F7FB5827D53F507E7790 +:104E80003AD2F5BD3A1FF9D94B5917D52F67BDB5A1 +:104E900078B437AF5FF3AE1D567D53EB9353914417 +:104EA0006F0CCD7F17CB39DBA54F834EE293EC5CC3 +:104EB000C047B7E47F2213E6BF7D67D51359503F43 +:104EC0005BCFCF851DE3E7A2CA91E87D035F14E0C5 +:104ED000F3DFA678685FFAA43A0D5F343ECE3C1249 +:104EE0008CD3BBCF14DAE68AE093F2FBFF9085F215 +:104EF0004CEEBD13CF7BF9DBA6543CEFFB18D7FB80 +:104F000092478DAFA8FA9E11BDDFCFE215ECF78571 +:104F1000A0EF2FB219D1F71712388A65037628CB84 +:104F2000F1D9CBF206F4F672DDCED18827D0EB951D +:104F3000780EF77DDCD932D685FA2094837688E125 +:104F40003593D2ECD2E817762901858D9F213E7FDB +:104F50008AE38E19BC2EA9FCD09FD1EE301959D00E +:104F60005C467CCE26227F671A89BF9A11B57938B4 +:104F70008FD7E9B70C1EFF8458EFE1EFB83F1D84CF +:104F8000FDBC2CC59A87EB2F53FCC03C2447D2199B +:104F9000CD73472EE763753E66E976A09D7E34C1EA +:104FA000773B9E8F1A4752FDC8C3AECFF2F17C66A5 +:104FB000576C50E5338DC7AEE372E984C11944F8EC +:104FC00044954B0109D62F6F6F28FFA70F701D372F +:104FD000982D618C77B04AC3D97EFF3577401FDFAB +:104FE000A0EAE3CAA8F88E1AF7618A01D757CC3E27 +:104FF00052F141F11D554E0ED2BFB0B12EC49F8863 +:1050000097F5C779FEB93FCEA3C3798D428E32E6BC +:10501000777B23F8D4D600AE8BC67F30B37C8DFF70 +:1050200060D5C0D97EBBA6FF88D54E4DBB2BE8D638 +:10503000B4E7AD573470416BB9A67F51BB47031736 +:1050400087EA34FD47EDF06AE0D2CE064DFF31BB72 +:105050007C9AF6B1E1C59AF67187FD1A7842D76A53 +:105060004DFF6B3E086ADA2775AFD7B45FDBD3AA72 +:105070008127F7B66BFA4FB910D2B457B1BFD5B488 +:10508000D7985FD7C02FC6F178E754EB3F689E9B57 +:105090006EDFAF815F88E7F19A19CE23DAE7C5F9B1 +:1050A000066F8B277E98E53EA969DFFFC8C8CD8DC6 +:1050B000C02FA14774E47FB6D5713DC51AAA391D2A +:1050C000C4F1BED72B1F6AE6CBD1F7BA908E9D7A7A +:1050D0006B26F2757EF99C034076ACD0B3A21AC55C +:1050E0009DBBEEC903588EF4BE5E8D6C53D270F238 +:1050F0000096A37D5F570319336571CA3B5896F933 +:10510000C7D6D87089ABE7BC83E5C4E08A1A94B3EC +:1051100060267EB108D67D3E38926D84752565AADD +:10512000715E0FD1EDAA0C1DF1F9AADB2C14374BDF +:10513000BFD622A33EDF1CE81A7910ECDCF4A7D31B +:10514000D762DC693DD8F9A122B017C0EEC7F25989 +:10515000B0EB43E01C6D04BB1FCB4D60F763FD73E8 +:1051600060F7239CFE74D97A7C6ED5C97BEA7261A4 +:10517000FC110FCA563453D739752B0EC07AEC0F79 +:105180001AAD284B8CAE67E29CB08EEC65B08E0AEF +:10519000428B0751FDEC52301C32391C07FDEC2BC1 +:1051A000741AB81DFF45B02E588BCF973EE9DEAE7E +:1051B00030F6F9B6B337198A619F795DB76D4D0145 +:1051C000389779E602BED3F12C60FC93798FCD0934 +:1051D000960C8697147AFF487249EE2C463EB51617 +:1051E0007D9481EBDA50FD85A2B3E23C8FCC390887 +:1051F000EB7E7E78BC58E72373AAF2AF665CCF796A +:1052000094EF50EFEF8C2147FE53E8FF93795C2F2A +:10521000C39F15E5938D9308B3819D940CF276F3AB +:10522000A4D5A7D1A790AD4109E523BB08CF4F1462 +:1052300028C823784AFC441EB247795354E433E724 +:10524000C178361FD84E91F1B1C55A78339CE71911 +:10525000C3C07A0C77E98232ECC1F0925751609E5C +:105260008E79B05F80371BB5FE65918E917D719F01 +:10527000BAEE8B372968A7DD97C7F5F09680BBECAF +:105280001303FA7F4AD9274047998BFD920FE4AB6D +:10529000ADD1AB04A19FE1D2DFEF372261DFC53A88 +:1052A000519F63FD9A08BB27478C6BB8A427BC1994 +:1052B0009ABD4A6AC4FC06BDE4EF8C617795E6C9E5 +:1052C000FCB96646ED86771E969C305F666348BAE9 +:1052D00087C6F14B0AD4DBC2BC3EABB1535A08F0CF +:1052E0001D794E3A07759CACC5B0FE083CD9E5A0C7 +:1052F0006485E7ED8F0625C483DDEA555822E2DA9E +:105300004BFCBD52F0B47DF5C4B24F86E1BABD8A04 +:1053100017E79BA5F29BDFCA703D1F2BBFA942BDBB +:10532000F61B3DC3FB8C6F9C4A725A8C7DA8A5A9C5 +:105330005BCF3C97F16792721EF1939EBCDDE22C2D +:1053400000FE7DF1364BC3D6187476471EA7B375A1 +:1053500099AADEE2EB49D7733CA9FAEA1B2BA71FF7 +:10536000556EAD4CE1B03ACECAECF12437865A8F77 +:10537000AD3D8EF922D6BB19E6B1E2FDCC772BAC60 +:105380008837F021BC349FCCE5E9D6E7DDE4374629 +:10539000D3CF203E00D19B5C8674D91D6A06BA31FA +:1053A000CD332A682FDAFE5B8B84722493B54A28AA +:1053B000476DD9B58765D4E7B2AFD81BC38EBE128F +:1053C0003FA8E7A9DA2583CFCFF9BB2AB2430D0C5A +:1053D000E9B6C9E5B4E1F9A974DA746478AA2FE2F0 +:1053E0003CD70B3A2E67AD7AE4D30AD6496525EB54 +:1053F000A2F23AD64BA58759652CAB9942652DF39D +:1054000052398DF9A9AC63AD54CE649D54D6B32EF8 +:105410002AC1BFA3D2CBACE487DE08760C96739981 +:1054200097CA5B989FCA2D48DF13F0FEA195E0DB79 +:10543000592795BB80FF9D45181F3153B917E43993 +:10544000966F833CC7320CF2DC69C2F8889BCA8332 +:105450000185CA4381722A0F073CD4EF68A08ECA27 +:10546000E3012F9527020D5476057CD4EF5460316B +:1054700095EF05FC54BE1F584DE507812095FF129E +:10548000584F659111E40AE2DBDD3D16FD9A9C8FD1 +:105490008D1E27E8A34FF384FFEBD1FDF7E2F178EF +:1054A0008E3ABA83B1D5AE94901E6D6E9D2704E5F9 +:1054B000467793743794EB4E703BD6644B243BD9BC +:1054C000D6BE4A72C2B8BBA46E7D029CEDDEBC0F94 +:1054D000E798414F54ED656B1314847FFFA419E8DE +:1054E00070ABC1DFBB15DA7FF5D2BFCE3183CEAE54 +:1054F000483CF5C7D7384CED930EB2662BC007F287 +:105500004E3F9926F175A0103EFED2C773D6E4E354 +:105510003AB91C79D5058E36FA190F5BC8CF18DB5E +:105520007E66AC0EE049AB2D65E81F47F4A3B8F5E5 +:1055300050FDA2DBD5E73A56A437231ED67D0AEEEE +:105540008913E565F7588CCF458EABBBBAF999FE48 +:1055500032F347F6932E335E5191E754DEFF037426 +:105560001E4DDF864B1FBFAEA3F8983515F5FAF632 +:10557000142E777AB3E343DB60DDDB5305BC219F58 +:10558000F6B50E61D8D7BA8DB964C76F8FF3361DE3 +:10559000C1F6BFD129DBA0697BBC6F6331C1F914AF +:1055A000AF5997EA77A35ECA49E0FAB1CDF1489CBA +:1055B0003382FFFF22E4EEE6CABEAEADE84FADD7C0 +:1055C000B102786EDBFA051BDC30CE4B9BC02E029D +:1055D0003879F2C20D05D09EBB4137512F641EAE03 +:1055E000E3A54D0B5FD928E1B823530B61DC3C21C7 +:1055F0003F7386758F5D0974DE66D4C615FAF56350 +:105600003EE7978530CC19D0BF39225EB1D5C01A9C +:1056100022F566413E97B73545BC344CE1F13CD3A9 +:1056200088F8D0E3B0FFAA113CFE93BED64CF19FA0 +:1056300074C77F9E9C0EEDE91D3A054D5AD9B6748C +:105640008D01FD9EDB5827F2E356893F1FCCE6769D +:1056500032182CB97322FC1EB037CAF223E2A7F627 +:1056600086A084718CAA114B258C37A73BEE933012 +:10567000FE91DEE0937C89E827F9A9FDAE229F2BFD +:105680001FD6676F84E735F7B1BE0C3C5798B781DA +:10569000F20964561639DFEC228E872764203DB468 +:1056A000DFD71A695DD1F89AE5AE1E993F7CE01C00 +:1056B000A3DBBFCCE7E7B8FD719802F960128F1F3A +:1056C0009C783993ECE5D96DF11EF4234F3C39B247 +:1056D00096E0A72A3C68FF9E78B9621A96B39F9A13 +:1056E00049FD4E48EC30C605663F75BB8CF53979EF +:1056F000B02E1CEFB491E871F653F789E71FA9C5E6 +:10570000F6725DF0EFD09F2E6F7E2D01E3051589B7 +:105710006F64617942D7BD6A3FCC7F8395FD1AD50E +:10572000B57743DADFD4C13FE63C996BC0788C375C +:105730003F97CEF326E631F07C072FF9B7953BBAB9 +:10574000DE018B8E5DD7D95B83D7BA9E5DD6835839 +:1057500056871534A359ED61EF412CA775F96BD12C +:10576000BCA9FBA0F52096DD237D5EC4FFABFFED59 +:1057700096375E0578C463ABAC6887E63FDE3D6371 +:105780001BC52F0D0CF9A16092BF558F046CF6A6B6 +:10579000A27C78F6195987FADDE46A8D43D8744FF4 +:1057A000AE0EE34CDB535A17D3BE0BE219E2F128DD +:1057B000E821A48B82146F2AF213F0259DC39D82E9 +:1057C0003E4D297E6B0AD68B7B8EFE7EF11C5ED809 +:1057D000DFAF354EA27952A5A0C4CD08B423EC4268 +:1057E0009FB7337F06E2C396E8DF8AF1AD822ACE07 +:1057F000FF2C91D305766F99488F50103EBDD53F51 +:105800000BCFC1E6EBCF1BE074076AB0DF3EC925C2 +:1058100098EE7F364B1C063943EBC23F8CE7A45B06 +:10582000D2C9CE51D76F6B80F122EC0EDCC78D96BA +:1058300081E754BADB20F6F584280BE6F3F1D4F5C2 +:105840006ECCE77A1DD6EDD4E17AF4623DB00F5DFF +:10585000C47A22FAD1FEFAD7CD143BD205637E89F1 +:1058600097CC2947EE7FA1CE13371AD7FFD65F61B9 +:105870005C2909E508ACF367FB2799914FA3F7F181 +:1058800042BE88FB80BD8CFEC34C1FE7DFE646BFEF +:1058900084FE940D61DCBF43F6605CD46669920CB3 +:1058A00011FBB539B89E9ED9E8DF8F7265667982A3 +:1058B00082F43D8B75AEB572FE3E980FEB2B62FD08 +:1058C0007F163671C04E7CFE99F74EE2913A5867CA +:1058D0005531EACFC7EEA5BC89CD8FCC3C8CEBCF40 +:1058E000743FB93F1506F47E2DCE7D3E8F6F6577F0 +:1058F000C89ABC872CBFACC98BC858AC6D077AD08E +:10590000C02A5DD9A5D529A86F7409253367A09D44 +:1059100092A423F90E724A9A1BD31E8DA22B817F6B +:10592000F57CDECDCFA773B359F839B05EC57C7373 +:10593000A2D8AC7A4E306F33B07932D07D73AD3EA1 +:1059400024A11F8FFDF132B2970DF7260E3EA7ADB1 +:1059500006E7CC1928A71FD45929AF2A0AAFA06798 +:10596000FE99FC9407D3A81DEA6533C53D23D6AB49 +:105970008F056BCFE34AFD3B5878CE0CD7E0FA4C4D +:10598000C7DC99A8673397323AFFE8F6A247B5E734 +:105990004A7EEF788CA3B150F8079CE74CC7F65AC3 +:1059A000B4EFA3CF55A5BB9C61B1F5C223055C2F15 +:1059B000E42428A7EAC8AE90C94EF066CBC323FD05 +:1059C000A4EFF2B91F30E55716D243EC6373081FFA +:1059D00055C25D3F298673A8EED3A1FBC2DE3D7E92 +:1059E000E0E999504EFDF57B4DC7A0DFD4EF2CE3E5 +:1059F000B07E37EB9E8181A0E06103F98D6BBE7CA8 +:105A0000A5150344CD8D4C41BDABCEE328E0FA6E25 +:105A10008F21E425F95A2CB36D2407D9C54B11F415 +:105A200002909EE887B7316F632BF991B6FC12861E +:105A3000793CCDACF30ED297678D0CE3AF37363897 +:105A40000D55B0FF1B1B9D86F9789F21B33AB423F7 +:105A50006E6A50A8FEA64685D79B79FDDC060FD559 +:105A6000CF6DF4F07A0BD45B300F29D41580716FB1 +:105A7000B6A43A75781FD0E8E5ED174CD47E1CFC2F +:105A800001CC278C8F0B91BC6FEDD1F17B237F7CF8 +:105A90004882B59A12CB0E3B117FF7E8145017CC11 +:105AA000942D332BC0CF3678437A687F8E853210A1 +:105AB00091BB1736790BA17EB743B6E2FE76837BA6 +:105AC0008BF947C1A532E19DFE00DEBDD841F73A12 +:105AD0005B45FC3EB8C44CF166B07528DECC9664DC +:105AE0000A3B86B7772CB086D01E033948E7D87BAF +:105AF0008F4C7600C8C3A36EB48B76E62B189FCA72 +:105B00005CAAE5B7F4850BAA68BC4666453FBDBEF6 +:105B1000918FD7BC5317D2A15D65B97126D241F3DD +:105B20000EA6A03FFBECC253B5C310EE50142E3F9F +:105B3000B472A179E153479CB81FBFCE5A40FD799A +:105B40001CAFD95FBD5D2F0DF0339DB773407E0C48 +:105B50009637CA611C27635EB582F1C174D827C627 +:105B6000F33B8CBC3E78A74CF72DE90BE5B075F400 +:105B7000007F670B14A6231F26917CD1F0D7C89D08 +:105B80005AF879C1A7C0EF32EE2BB89D513E67D1CC +:105B9000766D3F90933A9457D9EDDAFA5B8BFAE33E +:105BA000021A3C44E3D9E6E7722F7A9F03FB0AC747 +:105BB00015D1BE747C5F28D7A0BED87280EA8B1B3B +:105BC00065C5E94479D7790AF75FB453666180EB1C +:105BD0001796CD447AAADFA4A3F0C8F5AC8BE4C233 +:105BE00095F6ADC63BA2F719BDBFEFF2F55C8EA8E6 +:105BF000F6E01366B207DB1EB6E8F09E15ECAD7852 +:105C00008C2BDC55541D2C407B40C81DC3253D9773 +:105C100027CD16A25383ED517764FCA16554F5138B +:105C200005D46FD88D753C6E41FB8E96633F17E3AC +:105C30004DEAD6E6E35DDB131F953FA6CDC79B7209 +:105C400021332A7F2C2F2A7F6C94A67DAA755C5461 +:105C5000FED8B551F963351A78967B96A6FFF5CA3A +:105C60004D1AF886F23B34FDE778EED6B4DF547770 +:105C7000BFA6FD66EF4A0D7C6BC35F6BFADFE66B78 +:105C8000D6B4DFB1F8279AF668FF492D771570F979 +:105C9000BED9EE3F49016CD0F791F73D6A99DE28F5 +:105CA000F7469E7B5202B7A7A2FBFDB980D3FB8BC0 +:105CB000129F8F05ED9A781CF3D835F1BA7045859F +:105CC000B91BC6711A95DF21DD62E20EBFBFB66B4C +:105CD000EED9F63F0EFD60BCA6C45C1BEA3B8CFF10 +:105CE000FA40B9378774745F615BBF4A223DB86977 +:105CF000158FAB5C30523CAF7F1DAC8EC6FB46DCD3 +:105D00006BA9EBEC1071A42D18474285E49941FD75 +:105D100056C6F17E3F4D57E38E3E1A37A3DC18A4DA +:105D2000FCBC857E09E3C0CD3E66C57B9374CB0287 +:105D30009AFF9B0625995D262EDA16B0330FCC67A5 +:105D40005F155C6384BD7D52D0F7D4B3F0BCDDCF6A +:105D5000281ED35BF0ED53188FE943E108749D21B1 +:105D6000733C3FF7C0EECF5F81F9DAE6A597A15CFF +:105D70008D6ECF5ABEF7EB4397697F6ED95B1FDEFE +:105D80007BB9E71FD875BA25A27DC838694326F3C9 +:105D900044D001E02CE6FD805CC8F5F9F20A23C589 +:105DA000B1AE01FC1502BEBFAAF8CF893BE0B93FF6 +:105DB00039FBEE443B1DEA65AC877E84D73FE59F07 +:105DC000A3FC929C5160DFA3FD1D179B6EC715724B +:105DD000BA956D8DBD18076A4A343AD1CFCF32BB20 +:105DE000CA3E1907746DE07E75B4FFFE5CBFBFDD6F +:105DF00049FE779118274B947A2B7F9E99834C4EBE +:105E000017F71431F0A14F6A97505E652E943F8DBD +:105E1000E48BFD89468A23A45B44DCC1B258131786 +:105E200050E306FB13EF9590EED3C34B289E8FF102 +:105E3000021C6F5CA193D6111D2FC832E7D3BA861E +:105E40001E9FF5D7274831E6895A871A9F889E27D3 +:105E500084F604EA9965F1644F44EF7B4961557912 +:105E6000E170E4D7DE93D3517E9F32903E1C8A5E70 +:105E700030CF3C1431FEB442EEDF63FE78643DE681 +:105E8000878722E3D9CC41EF2B100C2A6684B17BA3 +:105E90004311CE7794CF77C2A0D8C91E04B587FE30 +:105EA0005F7D21D703D330976D38F219F7CBDB81B3 +:105EB000AFB1DC12B0927DD601FC87F00B012795C3 +:105EC000A1809BCA6D0185DAB707CA097E25E0214A +:105ED0007847A08ECAD7025EAADF196820F8E701CA +:105EE0001F959D81C554FF46C04FF09B81D504BFCF +:105EF00085F66001C6A9D753B93BD04AED7B03EDC7 +:105F000004BF1D0851190EECA0FA03814E820F0642 +:105F100076117C281026F870E0309547035D547F99 +:105F20003CF001C137E33EC9AE58DF15C078854F5C +:105F300076A27DF7AC6FA115ED6BFB7C9D15C57945 +:105F4000BB4FB704E31C1D8DFC1E13EF23310E0461 +:105F5000766808ED39FBFC678E4CA5F6B9D4BE19FE +:105F60008704A7C4B682DBAF6C9991FAD930210AB5 +:105F70009EEB58DA18D203DC5A184FEDB61532F9F9 +:105F80006DCFE9FC2985DCEE22F96D3370FB41A56C +:105F90008335855CDEAE29E4F75C1F16F1734ACACF +:105FA0008BAD479E2D54EDA6F587717FF679B03FF6 +:105FB0005CEFBC5566BC97B5DDA3B3727B93DFCBBA +:105FC0003A60BFB87E580FC585D97C6E2FDBE6AD31 +:105FD000A57539E6DF48EDD6A24753D04F6FF7AF2E +:105FE0009A43EB6D9429AED9EE3B9082F76CCF8942 +:105FF0007C27DBF0786FA864F07A9E8D5A7F07E3E8 +:106000007E8303ECA5D763EC03D36E49CF3011C771 +:106010007BD41C338ED729E8D72171FE630FCAC405 +:106020007F2F30B0FBE0B92D60DF05510E54BFB6B5 +:1060300002E355BD85BE9D28379F778E3F20039C88 +:106040005AC7C7CF5D25BF8276349CF7E72D50BF76 +:10605000E1BE4D5E5CEAB04DCE35C86EEDF3DFCAF1 +:10606000C0F89743D29E8F5ABE2DF6F982878FB71C +:1060700065954CF164DB8A375D07F9BCBB91FF3352 +:106080008B3E8AC3304CDE5CA70E4586639EFC3592 +:10609000CE1777FFA63A42CD268F3ADF589CEF6A9B +:1060A000F134E2B15A9B2FC6BA869227579223BF8A +:1060B0002914EF8164B12C9423CF19B8DC0A9EE433 +:1060C000F62425054D1A3C8F9A2FA0E60F44E70BC6 +:1060D000FC5EE029CBC462DEE77ED64FBF413AD7F3 +:1060E000173C1BBD9467E3923149873519D8127A62 +:1060F000EFA72ADEBA26063DA8E55328C700C11F30 +:106100001632712E9BEAF8383A3ECE64B682E02A07 +:106110008B3518435EABE533629C7F2BE4749B7533 +:10612000DFCE0D87F07C8F1A28376A8B2EB401FDE5 +:1061300084E0093DC9D74C7DE7D65722D6F51741F3 +:106140009F5B8CA162BC876E87F14A50AE22BF94E0 +:1061500050FC82D547E05D7DEE3F841DF0FCC575A7 +:106160002974FF3C6F6D1CDA47EDCC4CF46033F8BA +:1061700053C646D0830DE932067D388B8C340EFC35 +:1061800059AA26E2BD0CD7CB35289760DDFB162631 +:10619000913EAC99FFDEAC310057F6C994CFB265A1 +:1061A00029CFD39CF4EF3ACA1379FB31EEF75DF7B0 +:1061B000502DBD9F9421CA67D1CF83B2723D53C287 +:1061C000702E950B2D14BF997C413E13E9A75148C1 +:1061D0007A3CFA173C5E736DAFAC790F6D528FB697 +:1061E0003F60548F764646B7B6DE3EEFCDD353615F +:1061F0009EF6A5FCE1F68BBF3B827070958EE22483 +:10620000EAFB64509341F14D399881F99B1BCC8C8A +:10621000E4B96DBED98AF2607F7A3CC9BFF6DB2C47 +:106220006487AECB6F8A433BD9346F550A96238C73 +:10623000C1AD183BBDE6D52D37D92791BC55F355D7 +:1062400082AC1CEC81BB8DDCC8093EF7F45419E527 +:1062500025CF6799F4EA96A783F9D8AD95D6E1D40E +:10626000B14CBEF97EF876BAB796B8BE701AA11DC9 +:10627000E079A37CD715417B465A703F366DB69CBA +:1062800069A47C6B4C3282F90D0BFDCC88F58D65D1 +:10629000E6483E57F9E4FBF27F3CC687875F590E1C +:1062A0005C69DC2BF17B413EE79BA1FC69D310F2DA +:1062B00054F58F1F29E0FC8B6C4B7AF58C31A67D51 +:1062C000F5AB22CE67E5469EA732BB615A1DDDC302 +:1062D00004BB65CCE77B51DC0BB5A727D23D717BB6 +:1062E0002E0BE3BD4170818EC77BD2F87FED8DB957 +:1062F000141F6A93FC29C13CCC97F0B9F0FCDA0179 +:106300004789307F5B0E97EB2CE4B7E27D358CB389 +:106310003872FDE0EF05B574CCC81EA6F8859E78EE +:10632000CF698C88B7635C1CE317D1CF4DEED5C223 +:10633000532E68E12A66D0C035662D3CD5AA853734 +:1063400015713B7DBA5D5B3FC3A9851DD907E37419 +:106350003CCFDFC222E249F0F75E7E441C68DD6874 +:10636000FE3E5F76F7528ACBB6E5F0788F639536BE +:10637000CE91C54212E22F7369543CD6BD663F866A +:1063800097ED0BA3E341FC5E02F0A1A947318A7CA3 +:10639000F0EA689E87DE3DD2B7BD08CEB3600C5FE1 +:1063A000C7AB1D4D743FC5DAD388AF5C225F69B0BF +:1063B000BE7C8AE8401D0FF92218B17FE48748F8B7 +:1063C000A151BE37701EE48B60A4FE2CE936D0FBD1 +:1063D000AB62BEA1F843E5CF72718FA2E6DDF4890E +:1063E000B1D4BC9B55225F705754BE4E9FA3361943 +:1063F000FDE7BEAE95F1B1F810F92E68E27C88E5B4 +:1064000006917F837C182CE27C88F5A6EF56786392 +:10641000D98B0B055DDCBF63C9864F22F6B7AC7321 +:1064200085065EBEEBE10D91F951F7E33F3008BF01 +:106430009E517EED52B19D2F4FFFCB2BCD0CCD4801 +:10644000DF0728CF96159C31F27BA75E239EEB4297 +:1064500061FF99CCB3F2D12FDB11E2F26C9D88374A +:10646000345B1533C681993B5513C750E3114D4B2F +:106470005CB654D847727F7CC16BA57CDCE1F91413 +:10648000DF48AAF1DCCEC632D653649C6B0662DDCF +:106490008EC156C0E9F957D93341C7C0BE4D17F870 +:1064A0007BC9FDB0EC67248F2EE468EADB449CA333 +:1064B0009FBF2D0BAA703E8BDB49FBB031FF1A1E2C +:1064C00017D4C6D14CE23DE7C1E33B34F56D227EE3 +:1064D00072E5F1B57139D385BC21C62F8C1ADF1A4C +:1064E00073FC8171B5F1BDABB8374F714F183A2EBF +:1064F00036D2CDE9699DDDDF85713183E07F6606A7 +:106500003A9988F280FFE9E3797EAEC1A18D8F19B7 +:1065100030AF0BFA3F97B898E48AFA3EB5FD99057B +:1065200012CACB27F0FDE8A4C1F2245A8ED844DE6B +:106530007CB41C81F93470D3C35CCF364B8A0FE531 +:1065400073F47EFE7FF1877589E3BBC8AECE8E778C +:106550009A2E630FB7058263F1B975F1FEC578070E +:106560007EF78E91694F94E37BEB8CF86CC58E2996 +:1065700073310FB64DF0EB13693AA2A7F4DBD3B732 +:10658000EA23E829DDE873A13D9CAE13F95FF887A3 +:1065900071B427D2B76D8C31BF6AD7A9B0AD01D61F +:1065A00011718E6DC29EEE9FEF8ECCADFA8871D2C6 +:1065B0004DBEB1345F7FFEA398AFE587CDB759C418 +:1065C000C3D4F96C776AF76733FA697F36A187D449 +:1065D000F936E3FE62F0D515E713FE75FF7C7769A7 +:1065E000F76733F9697F36F53B1BEA7C2D3F6C3E3C +:1065F000BBE0CF76F1DE973D9E7F3764A8F7239A04 +:10660000FBF3CCBD66942FED6ABC50E8BB7351FA26 +:10661000AE49E83BF5F97369B914FF3D77F8267385 +:106620002C3D87FA8D093B93093B93093B13E1D934 +:1066300035A7570D077AFCBB1D37CF9541AFCFBEAD +:10664000FFF4F81C80DFD9F18BB932E8A9D9AF9EED +:106650007E330B1E29FEDBFB38FCF4E93E07B45BFE +:1066600082CFCCAD05386918D7CFEABAD57977B9DA +:10667000B95DB97C751E8F6F829C453DD69CE367E2 +:10668000187FFCCAD19B341FFA2FCFEE4D5F100349 +:106690002F6AB97C75217F1EADC08998CFC648AFDF +:1066A000DDA8BEC752A77D8F25296923D987712C04 +:1066B0006445399660F6D0FB97D71673BD70335397 +:1066C0001AB85FE12C10791CF4DECB4DE5625C6BEF +:1066D000E52FB1FD669DE709F477FF79D2BCE1684B +:1066E0003EAB7973A306DE3BDDFE7DDE4F9EFDB142 +:1066F000C46DE5641E8F9936CAC9DF7B8B882BA2D7 +:106700005D3C143E3F7573FF7E009F1E8ECF540F7D +:10671000C7A7B537690D9CFFF294DEF4C7894FC354 +:1067200031F13508AF51F8FB939BA97EA01EED888F +:106730002BE15BC5AB9A5FD82C390BC85E67199A01 +:10674000FC60C61467AC7B1EA4CF483D6BB47B19BC +:10675000DAA38634C58DF9EFCD7FD1C7CCDB7315B5 +:106760008BF85E523CE57D362719C91FDF9F3493B5 +:1067700061FC59B64C23BCD426D5513EA67E18EBFD +:10678000447F353A0F5D9F7C3BE509E96DE8614048 +:10679000D99FC7EC31235FE93F56925D4800579976 +:1067A000872E5F290F3D7526CF434F323A315ED891 +:1067B0009E688C9987FEAD9BFB5DFB717F69B81F5E +:1067C00023FF6E88D8976CE5F7EE589F00F546AB2F +:1067D0008F51FC5DECFF5B6107A9FD4D563F43F90E +:1067E000A0372A4EB45FF4A95C7FE0775BDC31E22E +:1067F000285FBB0DF4FCFDA3AC5CCF99B9DD3EFB7B +:1068000037B1DF27282B9644BC2436DD0D453737BA +:10681000EA78DE9DCA97732D46CA079C6BB1D3F701 +:106820006CE60221F6A446F4BFEE56FE3EB5ACD8A7 +:10683000919E7E7BED945FFE96E1B50097DBA766A7 +:1068400018E8BDC25312F328A983F35DBDDE94A9F5 +:10685000B8CC1BEA4FAF45762C18C3C84E7A75C129 +:1068600043AD954EF28FEA8A919E7D73A6A20F7773 +:1068700063C3D877B1FFF2042ECFD5FBA5E509FCA1 +:106880007DDE6B64DF6CECFF55C51749D5485F7240 +:106890006F0EAE2BA23FDD3345F49F5B3C81FACFF8 +:1068A000E6AFDDF5D27739CEA59DF9C8C7E87CEC17 +:1068B000B1EC29F4B758E4BD86901FE87745D6A31C +:1068C000BFC522CE535A506EEB8E214FD432C33EF9 +:1068D0006EE442A0D78C8CB154AAF5CF7AF475A19E +:1068E00018E7FC9038E71FECF7B4C36A270EF83DB1 +:1068F000E0EF3C84F8F872E1A9F4F1B0A5076ABFB3 +:1069000026BFC76EECFFCE16F97103B0F6BEB32DED +:10691000D05B8CDF196088878911F98B62BFF625FF +:106920006B52D0EF81B3F420DD7604BC236B0D03F2 +:10693000CFBF2CE4080B16D2F306B12E475AEB0C4E +:106940008CBB382C3ACA7360CCAA9167736A53A681 +:10695000A6A10BBB9C291627FAF75DE41764E0FBA0 +:106960000D189F7CE73686F75F59699D12DA75FD31 +:10697000F388F7C657897BE13E5F2DED27C3D6EF3D +:106980009731F25FD38273506EF53DC35794F19205 +:10699000B6DD91C6F31FEE5D181F7202BD672DEDC7 +:1069A000C24F4FB00C70F830A69F71A9D9D5827232 +:1069B000E657091477D6B7E7B320C8FBB0ECFB1B4A +:1069C000C277C8F9902E4F6C169E5BB6289EECB924 +:1069D00076A97506F931F7E858AC78D1CE62EEA702 +:1069E000FC8F622BBFCFB54FE4F4631F3F72E1B859 +:1069F000ABE7FF77849EF949B293DE7F52EDA34D5A +:106A000043F8478E913A215F845E11F833339F1922 +:106A1000F9452F7979B074C76BAFBD96CEE8535B5B +:106A200048471B84FDA38E139F1FA2C678C543F25F +:106A300052B27AB8BEB0FAED4138AF75DFE963CE35 +:106A4000FF85A0FB35D90FD9B17FADD3E7C632FAA8 +:106A50003D98969C7BDD783E2D33FBE995ECBA960C +:106A600033CEDF613E56F028CF37D89F5D68C3EF45 +:106A700041590E1B64D365E2F146D027CECBD8191D +:106A80004691AFDE7280E799B658CABA30AFA1C559 +:106A90009256466AD8C2F356D5FE16CB21D20716B7 +:106AA00085DFDF5A507F48B84CC04709AEEB10E194 +:106AB00043ED7750C85D8B1266F85E5A9CD24AFD52 +:106AC000CCB2D78379CAE63446F744662BF017E296 +:106AD000355FC7CC31F4C9BE62AE4F5A4ACABAAAB2 +:106AE000697D327EB98EB5D8CBECA4E711EFF07C8E +:106AF000738696CFBF137857C76916F9B477AE4E31 +:106B000009D68EC33893F71BA4E716CB027310F592 +:106B10005AE2F8CB8E671A39D478FBD78AF1BE4394 +:106B200079AE4F2CB3E27806C6F7158DF7E1629C7B +:106B3000FFD5FB7BC02CBD474D301D58D81EEB7DCB +:106B4000ACFEF313F7F2D1CFFD6079BC561B870280 +:106B500079EC1E09FB5A5672E65035D5F0F8D30B86 +:106B6000C29F51FD927431F60B127FBF3F28C52B97 +:106B7000F45D0CE1A7A4C769F130F03E2D3F876FAB +:106B80001A781EDE37694C7C874ECBD7DF1CFF3866 +:106B900045939F057CEC31713FC623DEA7F588380D +:106BA0001DC2186FA0179D04FFF7C7891B9C3FC328 +:106BB000EFAC99408EEB605CC9E127FA3639BA5DDB +:106BC000C8EF39E2FB0FD178FEC9482EAFA5477A4E +:106BD0005C78AF519BD69B118BDF5F7CF84206EE51 +:106BE000E7C519FD793B74DFF4E269E7E602C4CB3F +:106BF00011EDFB6FEAF84D47CEA7F822FDA5C0E5E1 +:106C0000DF2F4B3AB37125D98D0BB8DDF87FFA7DB4 +:106C1000B317E6733B7597A495CF4F08B91C14FCC6 +:106C200060BB20D3F743EE2AF2AD403A6A93AC0B37 +:106C3000502EE73CCCF3F29A1E5BD5B328067FB406 +:106C40008CF2FDD5C808BFBA7CBD91E45EB3253790 +:106C5000F972F728439FBB9FE4947ADE558F9879A9 +:106C6000BE8A8FDBD1E9BE7B290F263A3F65A87E1D +:106C7000D5239D440F6A7F138E8FF2C57223C515ED +:106C8000CEA18F81713B2BB733A2D75989C898C049 +:106C9000F163067D997460491C8E6B10FEDC0B6AF3 +:106CA0005CA4A1CCEC8978DE705B99B93A824E9AEB +:106CB00019CF0F8E1EFF372355FB22ACB1630CA8F2 +:106CC0007F31C694269FED973B6478F2FCB4950320 +:106CD0007CCCE30E43E7A3C571BE2D237BAC0DF343 +:106CE000D2C00E5ED3B06004E2B74DF6BD68033C7F +:106CF000F47E68A23CEADF0B3EED167C3AD4F9053F +:106D0000D90130D2187B9C1DC497E2804EC6272340 +:106D10005F34E7EBEA4231F6795CECF332F67878EF +:106D2000E4F7B3C70F89FE1A7B1CED6D4FD4FD4607 +:106D3000248C76B627863D7E4212F105912774C2D7 +:106D4000E0DCD50D7839313999BE975690C0EF5DAA +:106D50004EA07F52067EC8ABA7F3D17E992DF57F5A +:106D60001749F8438C60F047FE05F9620EF3BFB691 +:106D700048223EE2F735781B9F7EE573DE3692D1DE +:106D8000BA36C0F9E1FD46DBC5F93362DD67A48E92 +:106D900052FD37506511EF13333C9D88FBAC41F732 +:106DA0007451F772786DD39F77AC1FDCFF8672ED5C +:106DB000BDD9868B3C2E625AC2428F4B9897AA6DE2 +:106DC000BFA9CE107D2FA8B94FBBD96B885E0F7DB0 +:106DD00017D421D69BDD711FDDBF4FCDE6F944A648 +:106DE000658CE204D1F76DA6B15D1E3DDACF0D8C46 +:106DF000ECFDE83839E6A952FCB081B12D12E579F5 +:106E00006BDF7379A6FE73FE7D94D63A9CC70E762F +:106E100010DAD3D1EF49A8F75AEAF751553CABDF66 +:106E20008F4ABF4D47EB63C129D4AEC6FDF17BB895 +:106E300055E911F9E42B587F7F7A7F2B187BDF9B74 +:106E4000DBEA29CF2073BC7F6C189AB2144678C84D +:106E50005AC8C86F003C68F2094CD9DB699FE71635 +:106E600033364C223C68DA3340D3D3FDC0426D7ECA +:106E700001EC530347FBAB57F2534DD9F99795F308 +:106E8000578A639AC4BDE49451E2FB97A5AC14ED14 +:106E9000A2F4DB9EA1F33807E781715F749C62DD89 +:106EA0003B6E82F1D18FFC77C12FCDE26E5BFDAEE0 +:106EB0000FF3C8F41E9B54CED72C0DF3F27BE912CE +:106EC000467C6E8A6766CC8F972A4C1EC4BBC90469 +:106ED000306C5932327306D4EB453C7B8DC46484EC +:106EE000995531F3F8A3FA5DA1107D5768A879D4BC +:106EF000EF2BB2207F4E9D67D077F52EF33CF97BC8 +:106F0000D6E8E76B299EA9CE3F14FE87FA8EDEBF36 +:106F1000D5BC3781C7531D44AF8D03F44AF07C4183 +:106F20008FF83CCA85BBD5667B5729FA0F671E4C84 +:106F300050364A11FB08CED2F3EF037EBFF1FAD7E9 +:106F4000617792BCEFDF9718EFFBEE8BFE22E4DA5D +:106F50003A7C5909F35E1A19E531A4FBAA3F972937 +:106F6000FF00F6A0911311DF4980F1D63DCEEF1F4F +:106F700036E3773EF0FEE7C040FEED13166CF7D126 +:106F80007736D4BC5CCCA35D5B32F03E72F47D837B +:106F9000BD11C689986FB2990513409FA4F43105BD +:106FA000BFF3ECB96854A6037E6C7DA05001BF937B +:106FB0009989EEA52AAD7E33FF0EE10A166967EFC7 +:106FC000976EA5EFBD86BF6494BF143ECF88EEC315 +:106FD0009FC3C4702EFFF8DDFB7AE4CBA97D5D7AF8 +:106FE000D4F393FBFCA47FF6D94F3DEDE2E7629921 +:106FF00011911F751D5B54CFE98A9F972CEA275F7B +:10700000306AF8FDDA5EA3461EC8175BBE46FD6512 +:10701000EA89AA67D33FE3E3F928DE2DDBB5ED5318 +:10702000443ED0DB2ADF5FC3AEA173BC981633CFDA +:107030006EE0DCD5736EE27174C6C7796E94F79F0B +:10704000464D40FFC04771E864C42FD8172995DD2D +:10705000CC8E7958E54C998E72BDB2F31DA487E4AD +:10706000B33C0F3C7AFCFD5FBE95857EC39EC99DF7 +:1070700059682FEDF9F2153D8E57D5D3CBB03E1997 +:107080004A1EA4584C78AA10B43350CFE34491F56B +:10709000B49E4AE765E5E4CF504E1A876EDF33D9D8 +:1070A000C2C2E4877526A03DC77C7CFE64B3CA5784 +:1070B000EC2F97705E84819FF654EA526A619F7B41 +:1070C0009E91156CDCD3F34602CEBFE7EC39CD7A46 +:1070D00098FE22F345ACFB5A71EE532B7BC9FE7E22 +:1070E0004AAC2BF96C2FC5A15395DE30EADBD4C333 +:1070F0007AFAFE37B3F0BCC8614CA1389ABA5EFC8C +:107100006E2A3ED78272DE88FBB3325628EC7E2888 +:10711000332A8355988F9ACC764A486B532B7D41FE +:10712000A4E7E4A59C9E93ADFEC318BF4F5EAFA33A +:107130003845F259DF06F4CB92CB6505C9E44AF82D +:10714000EC10F3B78AF9D4F9D5F58CA8F44BE87EA6 +:1071500024B3E362FEAE2A138EBF5ACCEF14EB5970 +:10716000C5E83B2CC967AD55E82F27839D41DF3328 +:10717000B8E2799A35F345B7274FD99945E7E0B199 +:107180001ED90AE3A5645B365441B9CEA123FF3270 +:10719000A987513C3DA9279DE47D524FA128278A0C +:1071A000FA69420F703993D4F3502DAF6FA1D2A476 +:1071B000CA17873F8CFB98DACBB87C717849BE98A8 +:1071C000D2B87C51E9B856952BCC5A321FEAF70F4A +:1071D000FFACB5069E7BF773FEFEE5BBD95CBEBC7B +:1071E000FB25F7FB4D69BFD3A35CAA42C305FA4D4B +:1071F000BBC0ED33951FABBA25361148639A83E7C0 +:10720000871FBAC89F3B84D9D500AF6312C929959F +:107210006E6B05DDAEB3EA8349D8FE8189DE773433 +:1072200039CEE598C11EFE83AEF7417CEFF8F73307 +:107230007AEF5D41F5827E434B492E9A846C39E4A6 +:107240005860413E847948AE1E7218E9BC0E083A77 +:107250003E67AFE908C33F5BCCDFFC693ED4FFC1AA +:107260009EEB40934C3D971E412F5F88F33B2BE8EC +:10727000A629DD7B53C904FCFE621ECD7BCEFE0D2C +:10728000BD7FB2DCF61F9FC6FA2EA73A8EFA7C4F5E +:1072900068A519CFF5D09B1F9F40B4ABE35F237B5C +:1072A000EFE4E37E339AF8D0123BCF7890FCF3AD55 +:1072B00088967F8B4A860FC8BF7A6691791E12E73F +:1072C000EB59421E4D55B8DD5E6FE5E7555FB25F85 +:1072D000A6FE8A8BF655AFD28DF2E45AE47F9BF27C +:1072E00024D14B7D3EA797BD829E0F0A7CCEEC63D6 +:1072F0009DE897ED2F986E190BF83EE2D213FF1C14 +:1073000019BBC65206CF1D2995F04B026C7AC9D61F +:10731000B5A900CF5224A2A7FA92AD1D4DD07F96F9 +:107320003541A903F8E8F9B31634AF0E05BC8497CC +:10733000E972F8E354179E1BC7D3CCCAB08CFE4F3A +:10734000BD63BF8CFAF66DC4AB11E32E1EC1677529 +:10735000041F576A2CB88F23A526212F3DE3515EC9 +:10736000CECA37D58FA1757C7D6C4C1ABE776F5015 +:10737000F8953CA7FFC9827EEACC276B53A0DFCCEF +:10738000926619D77BD42C91FC3CDAD744F993C789 +:107390003B39ACD22D3D077479BC6F5B7312B66F6D +:1073A00097483ED52B2F1DE2EA8FD3A73A7E0F0BCD +:1073B000B6E17730CF29AFB7603EF5B1BE05CFCC8F +:1073C000013C1C7F533FC4B84D1FADC071DF4C243E +:1073D0003A9E6D3569F4B18C4E69845EAD1E6FD3F3 +:1073E000C0F54A0DC5D3CF2992E50678DEF35DAD31 +:1073F0007B3991D152DA77BDE87B4CE17C79CCA125 +:1074000023BE3CD6F7B89C8AF05946FB919976DEAC +:10741000FA921AB2AFCE295BF54467820FD5F154C8 +:107420003A3E8A4F231EED9CFF8FF66DB320BD1DA3 +:1074300075BF23E3395D67891A57D0A1AADFF05DD4 +:1074400071A49FDA51FBF37E86EB5138FE6B94D723 +:107450008F237DD53B64A2A7A3CAFE9A1486BF27BB +:1074600062D2ECFFFE1DC99AF19775DA3470B45DF3 +:10747000B5CFFDDBA7CBC40E66A447D847F9C23E03 +:10748000D21F77E0FAAE681729EBE8F74906D9452D +:10749000F9DC2E8AB68754BE6ED689B8AC8EC76525 +:1074A000A3F9DF58FAC3EEF1D82A498EBCBF5BC6F8 +:1074B000BA7390BEE6A31286F11ED075A723FC1501 +:1074C000EB6D8B07397CADCC7669BFBFCABF373F48 +:1074D000BED4771EE59574364CDF6165AB18E507C1 +:1074E000E86B789E115E66AD88D48B25FDF12D8DFD +:1074F0005DA44BD89B8578AC386BE4F18F9EE8385F +:1075000097EA1F8525F22BAE522EEA93F9B87BE657 +:10751000F078677F79338F931509FCE5941A695DDC +:107520008A80F7DC16FB9EB5A454FA41F9A2DF0766 +:10753000DF2980EFAF90E6619E3D55B1D79152CAE9 +:10754000E3B5779778F24AA12C2AF11596225E3D91 +:10755000605FD377C53D649FA9E3BC33CAE316FDE2 +:107560004661C9BCDC0E8FEE07ED63689C86D8E3EC +:1075700040FB387A7E6EECF643B839FC7D23FB3055 +:10758000D243060C64A6F2522AE3E516FAAE468808 +:10759000FBE70D1ED2F34691AF88371091FCC7F47C +:1075A000F534BE1C9E41F7582DD82583FBF9917602 +:1075B00094AC846A22E3AD6AB9A894DF73CE28152F +:1075C000EFF34C6013C8AFA8BCFC3CEAF343CDC357 +:1075D000EC6557C87B5EF363D349FAC3E4275FA524 +:1075E0007D600E4A91DF391F6ABF894A941C8AC2A6 +:1075F000D350F35CED79DC22E8F66AD75D657ACC8E +:107600004EF9D12ECE076B057DF5DBD53F1E3FBE73 +:107610003F1F86FECAD9FBFE93F87E4A4268A53713 +:10762000C67E5E14FBF931E5C1D370CE1B8CA1FB85 +:10763000D1DE9907A76302D27BC7F2F1F005B09EB5 +:1076400037C5FC2D9695EB6F85475B1CBA98F91EE4 +:107650006FFE787AA20D3FD9FF95E3DCFB6D20A782 +:107660005B1E7DD0ACB08175306BD915CEF947E388 +:1076700013755D6D5B305E624DBDAAF7145A5CAF49 +:1076800024E07D69EDE74D76FC0E46B43DA0C6438F +:1076900054BDA5C64D54BBA4C2C1E31F33EDFC7B52 +:1076A0003D15F669A4DF0FB2AE1AF2AF303B6D2282 +:1076B000B10AFD19DD5AFBE43ABF57463B2ADA9E70 +:1076C000A84D3345D907BD7A94DF1517B5FD54FE93 +:1076D000F8AC54C45154791765479ACF9F4940BBC1 +:1076E000EBED0B67282E148D9FEB2E5CDE9FBDAE5D +:1076F0005D4FF783D171ADB72FE4D2FDA011AF1B61 +:10770000C1D4CACC3FC48C80974C7B6B9511EC18CC +:10771000A38329F8DD36FC5833C60D8D17789C7C81 +:10772000849DFBD7898BC12F85513395A07DC1786E +:107730007CCE48EFD3995DEF91BDBD09EA86219ECD +:10774000C79E19A68B110753CF638AC0EF6EE6B7A9 +:10775000E3EF814DB18BF7F72E46DB59FC3C2DA2B0 +:107760007FE2622D3E2DE23C27835B43DF79ECD341 +:107770003E6F11E76B591AFB1CECA3639F43A27A7F +:107780000E13B6C5E1396C59BC4D8A750E998B2F15 +:107790007F0E5B845FA9D2EFB4AC04B2AFF7A6E86A +:1077A000E8FB417B13C359CB31FEFDB299DECFAC70 +:1077B000107136B4A4109F6BB797BF8471DB71A3AF +:1077C000F5748E7B25D1FFBC8EFFFE60CF78EA1F5B +:1077D00027B383F8BB8007FBAAE9BB1BD1FCBBD353 +:1077E0007A00DD33B6CEB93D6B019C8325FB8099D1 +:1077F000FB9B83CF07EF3F4A05BE4B7BF8B954A6EE +:107800009DD4A3BD5EF266ECF351E38F7BA49D3A59 +:10781000202B36AAAF8BFC98913BA3ECE9B32D64E7 +:10782000675BC647D5F7C039D1BD8E9FEC16D9A18D +:107830003DAFEB8738A74A1187307F7D8AE265FB31 +:10784000FA4E717EE9D1C62527F75DFE9C5E13E7EF +:10785000B453C4A17E2EE2009DC27F7E23E0A4F239 +:10786000CD809BEADF0A2804EF0A940B61C1CF7731 +:10787000563ECB4717AFAA84FBED47CF73BF7D7F42 +:1078800062A883BEEF74DE42DF17A4BD4D14BFDBD8 +:10789000077C722CCE49BF1F7834DB4CF1B3A3A513 +:1078A000BFFB7B8ABB7C6BD1F1B80BC7B37A4EEBC5 +:1078B000704E186F5D858BEEA536E04714A1FFEE84 +:1078C0003289BEFF341B0E04EF45543A37F569F197 +:1078D000590FFF6595F1DF1DC8427F618C8BE8A4CD +:1078E00042EF73223E37BA4F915F1E57D8EE1B8787 +:1078F0007180F17A26BEFB143445AC3B0E6F42E03A +:1079000079538944DF731A0ABFD1E58654AE2FA399 +:10791000EBFF7534D7831BDDDBE83C773BBAB25015 +:10792000AFEF13F910B3642948BF5F2877DDB11CAE +:10793000F65B91651FBB11C02DA35368FDFB4A4F39 +:10794000531CF8D88557C621FD1DB3765A30CE7921 +:10795000CCC9DF53871395F97BB79DF22D31F2A483 +:10796000D5F258E922FAFD957FFC7CEFDAD17CDF75 +:107970004C52F50A8C5B81FB4D42F9DEB202F9C331 +:1079800098B983FCCCE873AA705FB388DEF364FC1B +:107990007B4FBFB6862C783F1CED67027D6C42FFA3 +:1079A00078F7043D7DAFAD5EE6E782E788E7A41F88 +:1079B000A3137E99767C66653E63FAC079601DDE0E +:1079C000D7D03AF13EAAEFADBF9262F8B583D6C9DF +:1079D000FC9E58F9B0D1CFCD76B2209A86B3151659 +:1079E00076A19F70309FC6996DE5E3CC12717C9BA8 +:1079F000A0FF59177594DF81F4D680CF95CC2779F5 +:107A000072CCF550571DACB71ECEC641FE469356FC +:107A10000E09395B5F5245F7BDC7DC07C6A3BEBF81 +:107A2000BE74E5E13227C29FD45441B729A52FD5B2 +:107A3000205D5A942E8A2F4C76CB745D787DB936B2 +:107A40004ED1AF17A3F44BB4BEA88F923B11F7549D +:107A50004E43C4F9CF729F4B88A483ABC7CB1C2F76 +:107A60007EAF7BD6051EA71D8C97F7E973A503781B +:107A7000893EEFD878893EA7013CADEAAACB1D8CA0 +:107A80005F156FBF2E79C91A99E71B8DB71F8AAF93 +:107A9000E6D15641AF5C9E5708BE7D3B3B4471B773 +:107AA000B74BF9EF4B1D73FF96E2BFB358A8630DB8 +:107AB000CA45E0CB3942F9E823E44C341E06F8F419 +:107AC0003F282EBFFBF3B7282EAACA2113F225EABE +:107AD00013C11FEAB999901F916F2FF0EF875E2DA8 +:107AE0007FA87C45EB213F38A48FCC1FFCDFC55F0E +:107AF0007B71CD18177616523CB8CAD1A5C77BAC9E +:107B0000C950D23D92887FD23A9C91F53C6E1C5967 +:107B10004F712FA1F7D4B8A6DABE3EBB2B41185542 +:107B2000A4474DC2DE51FDC47D8E53647FAAFA5432 +:107B300016F7FE57AB4FF7087D3A54FBDE73BB795F +:107B4000DCE7CB433D0F801C9F9C6FA4EFB84C0E2D +:107B50003FCCDFA3708449FE6F7437911F0CFB6923 +:107B600046A304E67544E6F3A9E5BEF36D0AD6EF35 +:107B700095BBF40AF507FF16E0038656FA9D860DBD +:107B80008F737D1357F451D6E5DE83BAB34F99E670 +:107B90004AC2EF616F5F83DF010B2A8CBEEB98B5A1 +:107BA000B48B45EEF7A531DCAF9D9CFFD61D076871 +:107BB000DD1FEA69DD6857039D4F969D0E05E7CFEF +:107BC000F6DB23FDEC7DD9F7DA9D00B77C696C0804 +:107BD000D17AC3A37E01F3EC33578D074B8DED7340 +:107BE0001F18F50BC0C74673D504CCA3ACB6DFDBBA +:107BF0003E1FE5DAD95B2660FC1BECBC56D4B7838C +:107C0000F6DFB7CD8CBF3B5DED789FD631A2AFAB31 +:107C100006BFBF5AEDE0F748BED1BE87C64C407BD9 +:107C200039ECC1734F349F0C22DD4C16EB65172FD6 +:107C300051FC41BD97D9739ED347FFF8400FB88FD1 +:107C40006BBF5C45F722B97DBAF926A0D5757D3C9E +:107C50007F0CDBF17BE058BF28861D00F35CE74B0F +:107C6000C6F3EBCABA3786DECDEDFB36E083E7F626 +:107C70006470BC44B76F1EC3ED82B8AFDECF7292A2 +:107C80003DC0F57FB0C012F33B55B7A9FAD21A3BFD +:107C90000F452D5579A5DA23805FB32102BF9BC61E +:107CA00070FFFD7CA9A703F1F77DE77F0A710BE563 +:107CB000F152CFF631C391AE045FAD9763C601EECA +:107CC0001CF3A3C52B6E4113EFABBE73E96FE986BE +:107CD000A6DB41746550E9F821A2E3FF8BF47BE257 +:107CE000FBD0EF207974FE14DDC347D3B14ABF0344 +:107CF00074C8E69B9206E87928BAC17E8B9206E8A2 +:107D00007AA87EFBCEBF1F93DE07C6E9BD2CDDAB94 +:107D1000F4B759D0917A0F5429CE79FDD78CECFE67 +:107D2000A33D46F577C6357E11E83FCAA3AEB072D3 +:107D3000B97FB43797FB193D66BA9F9AE95E29BEB1 +:107D4000BB0D5D23C6AD11F27EA6DB755939AFEAD6 +:107D50000B55DFFD4F7C774398008000000000004A +:107D60001F8B08000000000000FFED7D0B7454C75E +:107D70009560BDEED73FA9919E3E881692A085C022 +:107D8000164640EBFF053D7D10321FA7C1180B9032 +:107D90004C8BE0041B49DD60E2903D9EA131321224 +:107DA0009FCD621FCC7866BD390D038C9DB177C025 +:107DB000561C610BDCE237384BECC671189C4C3C0E +:107DC000C243086C6CD318C743B24ABCF7DE7A0FC3 +:107DD000F56B750BDB43EBCC6457E740A95EBDAA9E +:107DE000BA75EBFE6FD5D37A3363CCCED817F85380 +:107DF0003DBCAC081A19CB65F4F305FCDBE2F2EBF1 +:107E0000252B63DFB9EECBB443F9932CDF0A671E51 +:107E100063AF5F35CAAC88B1AEA9E3F6EAB387FABF +:107E20008F75088C15437B12748676EF54C17700EA +:107E30001E31D1272E9D1E7DDE9F4CFDAECD958738 +:107E4000B3FA329D63687AAF3E8DB159F89B0ECA82 +:107E500020932D33A0CCED5AC712A0CC2CF9369626 +:107E60004C622EB1843193F29EE9CA6BDF15F03972 +:107E7000931983FEEB95F556307F5D0DC031CFCC65 +:107E8000BCF189387AD3C9C9D05ECD970AE369D7E6 +:107E90001DDE9FFEA529F3E430362E57A0F5CDFB5D +:107EA0008CF94CF06B756EEB023603E78771CCD121 +:107EB000C7A9601E99E9011DE55EDB2AE83F6BAAB0 +:107EC000C9E1E5AF4BF8DE6CC6DF1B3ECE7AC64A91 +:107ED00086C6D9E209C8FA54C68E494CE92F5B6FB1 +:107EE000C167E7F8C37A85B23E536ECD55C4CBEB7C +:107EF00092C7E10778670F868D6F1DCB583A63559F +:107F00009F699F8B0E6D7D385C30FB58FAE54F5FA3 +:107F1000C07C4633C78F395D47F8795D32FA903EB1 +:107F20002AAED4EE6293184B96EC87FCF0DC2A99CB +:107F30001D3E053633F6537EAFB8020404ED9FC2F2 +:107F4000BF1480739B6EEF5A27D0DD166C4C1FA2B6 +:107F500097250B4C1A38962E49D4D49B9AC769EAB8 +:107F6000CB574FD4EC6F73DBDD9AFA431B666AEA9A +:107F7000AE274A35F5559DD59AF156EF9CAB69FF72 +:107F8000D6EE6F68EA6B9E7F50537F74FFCA11E98B +:107F9000221A5F88B691E98979053BD2BF884D3AAC +:107FA000FCCFC59CD3A3F7F7217FC27EBD6EAFB7D0 +:107FB000AD82FED5573F8DE7FDB4F4C5BC7200F924 +:107FC000A356D91798C72B407B8D52AD95BE45F46B +:107FD0005E633645E41B95EEB60A5611C7AF66DA06 +:107FE000FDAAB06DBDAE477E2E1AD0EB61BE5937EB +:107FF000B5FC572135FC06C767CCAFC7F584CBA5C8 +:10800000FFEE18937A399E60B57F01FCC4ACC98C31 +:108010009547C7A34AA7B75D37635F6FDDCAFCEA20 +:108020007A2B58A00EE93EDABA673BFC7A926B5184 +:10803000D61DBE5E15FEEF6F865F81EF5FFF23F3F7 +:10804000ED1310DBB288FCE6DF5DEBCFB52B400211 +:10805000BC27157AA8918227128B900E980365830E +:108060007190F9510ED433C16F8452961C04AF380D +:1080700068EF34302AEB717E711086A6D245EB355D +:108080000ECA8D286F452CA9EE9CC7EB8E065E8725 +:10809000F7A82ED5F2BAE73E5E8792EA5E27AF4395 +:1080A0003FAAEF5A8CF5CEB8C0894401EBBE2558E3 +:1080B000370E1E5ACA4BFF05814A99E49638E85D8F +:1080C000A7A77EEC22AF073771FAD0F283315EF6B4 +:1080D000F9B3195F3D3C3F81BF4DC2FD5CD76F00D6 +:1080E0003CD48A82C30EEFD50C32873F15F7D5E416 +:1080F00090D997E033A033316D88CF8C2C98B14A5A +:10810000203E790FF1ADCAEDE1E368E9AB1EF55A07 +:1081100001EC3BFCBE3119E530A7A7FAB2E0122C06 +:10812000F1F913D03E7B32FC4B1E4E1F2A5CA2326B +:108130005FA5B55F8FAAB6321826B75917D15985F2 +:10814000799D2CD987CB6D7150E52F2E2FC2E1562A +:10815000E5AD391FF86C1AFB3A7C96B90A6AB3AEE2 +:10816000BEABF0D9BA303E93ADF79684F019103219 +:10817000D3F0D9B7899E6E275F4E09837526184FB5 +:10818000F60CE823CA9954C04342243E9BFB1BB221 +:108190001FA2C89737F01758676E7E989C51F45C01 +:1081A000B5AAE7FEA8B3A2DDE2677A11CB707CC85E +:1081B0002C3B31D273B53CBE0906BA6BA80EF890C1 +:1081C0000F81BE631F15DC06CF9BC9CE62B85A80F3 +:1081D000C7AAE2318C6EAD712F9D90ECBC05F5EC19 +:1081E00018856E4E66A711DFC376BDC742E49DB504 +:1081F000E8CBF101CD3709C7736622BFD540DBC696 +:1082000082E1FD33B10FF09935C87C3E78CFEA08A2 +:108210000858AF46FD9E8DF4CFEA51FE575F09E83E +:1082200025EAA5E5975B7400BF3F01A4578B7C51FD +:10823000309C2E64E6D3E37E7CD5FDAFB61F349030 +:10824000BC0EDBFF9A41B0CF004E39D5E420FA1ABC +:108250006464CFC84EC1C748BEAC21BCA8F6E3AD2C +:10826000F6266817E8912E627BB340F6D0A76CB370 +:1082700081F305F3FA557A86E7CBAF303911ED3447 +:10828000CBF3D47E6C1323FAA8B6973C556747B856 +:108290000676CC44B824BD0A973F15C7BD60E2708E +:1082A000F9DA087FD50AFEE4411D3343BBBF4F69AD +:1082B0000FA35FFF20B7D3FC4FC42B70DDC8F04382 +:1082C000BF07D04E069368E5DD03FF4384F7DC6902 +:1082D000773FDF015DAE28F0FC6F856E3FDA2451F9 +:1082E000B93ECDF5FD7CA0C77F916E7CE266C80FDC +:1082F0003944F7D5F6CF27901E52F1D93786F410BE +:10830000C24DF8E8B34483DBAA107538BC0ABFE558 +:108310008CC8572A9C2A7C577C7AAB0BC67BB3E768 +:108320005F131CF621F84B45E77E84FBCDC14F67F8 +:10833000B888EF9235766634F96652FC88A44C967C +:108340002BA6A23E8873CC85758CCB74D1BA4C36E3 +:10835000A31DFD024B2793F360487382CF8CF0F787 +:10836000A737ECD243FBD6A92233C1FB5BB3BC36A3 +:108370005AA7FE0986EB9993E96103D6E8F377657E +:108380003E29119C835047BFC7C6F1A29F68F4F8ED +:10839000E0B95FC7D61C0AC1CBC102EE8F9DCDE705 +:1083A000E5DA171ED97629843FDA0FADD3D4DDBDC7 +:1083B000DFDB762954DE6E1044DC9736858EDBD900 +:1083C000C004F45F5A453BE1A143379086F56B2C1E +:1083D000787E0AAE0FE78F00FF3FE75B623DFFD27A +:1083E000A950F68FE1FE69FF241FF90DEAFC1F2B4F +:1083F000EBFF385F177338A6011EBAB3BFC5709F75 +:108400006A6C7C3F4D50727AE67243F577869E73B4 +:108410007951A53E0F3ADE73121DE91CA8764C99DE +:10842000F611E97D27D2BB71A8BEB548D7E88BF01D +:10843000FE730522C17BC016B93D5BA1979D135CFD +:10844000DDD9E8DF3FAB736C8625CECBDC3A1EE589 +:10845000FD56DB7AA253E6E2EB58C038BFCECBF430 +:108460007819E8D179FEB782422AD68DCCC286F837 +:1084700057F50BE7893ED101FDBBF2D79971DD5D60 +:10848000B6F5661CCF84D6826E383CEABA0FECE6AD +:10849000F3CECBF489E0E9B2B9B97BC501A83FA31B +:1084A000AC7B5EEE3A6AAF6AF49F14097FE06743E3 +:1084B000DDE868F5E23C2687BD46C23A736CC6B279 +:1084C0004F7889EC1355BF0DE94FAD9D72FABA9103 +:1084D000E463D7159DCF44F2535E3007DE9FAFBCF7 +:1084E0006D0D727BBE6BBFA35FC4F71C02F9E3F393 +:1084F00073BF4D769D35772EB7E7B3567991549873 +:108500004FF0A13F314FC55B9E565F191D17B7A0B5 +:10851000FA30DED4EAD1592CC090BE2AC2FCF370E6 +:108520007D3BBB40B1D7725931DA2B2D26DF63C8B2 +:108530000F960D423AC2A1E27545818EE820867CF5 +:10854000B06726945DD965B4AFFACCD31704985FB1 +:1085500017DF6643BED0DB8C7EC41BB38A1F0DA819 +:10856000F34DC2FF3325B2B7B08E842F7D3979FC2D +:108570006E96C786EBEC32B0A648F2A7B680F3FD44 +:1085800007597E920FD1DA8D1B04D27BAA7C376605 +:1085900032D937C278DB8C5CCE805FD22B40BF3EB5 +:1085A000A417A0FF175AB3F7E905A27B19E5F1ADAF +:1085B00052B1EF120BB91FFE668189CA93CA7E546D +:1085C0007F7136C33582FCAFAAF23084DF94CAC70C +:1085D0003365F2F14C222F7395713F2EE27CDC5C07 +:1085E000147BB95F9A337AFB1C4B7A8D87522890A3 +:1085F000E879DD9887492EC5126F39A38837A35DC6 +:10860000A13F07A713B5FD7345DEFFAA20E674B2AC +:10861000B47214E5412CE9A4E2CF83DECF97FF7951 +:10862000EC47DA68AEE3A399F2D442E093BF9C2E04 +:10863000DF83E596D723DBBBF3632F77D31E8072EE +:10864000F104DF3723E9B37985B197FB4BD1BE48FD +:10865000E1F645F8FCCB153D144B79D20465B31116 +:10866000D61F01FF8F8EC2FCCB7350EF727B81E56A +:108670009EB9A40FB1DFE167B22EC43E067B141C85 +:1086800041B443053992DDED8DFD7E2D7D483F647B +:10869000AFCC615C1FA8F32F2CE1F87A7A14E0B01C +:1086A00000DEEA256EAF9BC2E050CBBF2D8CBD7DB6 +:1086B0002AE943E04805BB1FCB0542447BAFA7D066 +:1086C00018737E1A0B78D9E2608D91E4C9C9D8EF8E +:1086D0004B9A0DCAAAE9CED328D7964B87E7605CA0 +:1086E000F9FBF81FE61BD279BE61A5C1E545FFAED7 +:1086F0004BB23BBC768C47ACA2FACA7CBB43AF52B0 +:108700003EB6DF947CDB056CD7517DE5EF241FDAA4 +:10871000C3DF17D69DC9C6F136EB1DFB18C69D9564 +:108720007C838DE71BAC369E9F106D3CEF60B529B6 +:1087300079071BCF3B586D4ADEC1C6F30E569B929C +:1087400077B0F1BC83D5A6E41D6C3CEF60B5297908 +:10875000071BCF3B586D6ADEC1D33815E391369EB7 +:1087600077B0DA78DEC16AE379079897E71D6C3C49 +:10877000EF0070F1BC832D72DEC13A947720FFF1D7 +:108780001896A467B85F7F54A9CF067BDD34637861 +:108790005EB56AE7FE2D1817AB0972FC5539785E95 +:1087A000D914B4770A307E4566B0DF04FE65451102 +:1087B000C3F0D5B0F9C3F313DDD9E7BD02FAA3B016 +:1087C0009729BC03E529EA187F3F7CFE6171573B7E +:1087D0008FE7D6657E8BF03BBB2C4878C3E71887C4 +:1087E000AD53F213B556ADFF2A7FE6B2F9715F992A +:1087F000D49908F890456DBB88F92F8CBB5EF1D7F2 +:1088000061DCB76A501B7715331BD4B83CCF4B845F +:10881000C139DFE11C5F046B6A017F2A01E6CFC129 +:10882000A415AE53127C5EA4B7DD1B88BEBC3B45CD +:10883000C71468AA0464609EA512206A86D254C632 +:10884000ACD24CF29B389DFED7D4BDF1D9280F0392 +:108850007A46046C233CA8F9850458BF3483FC2B6A +:10886000F2EF2A33FDBF473A50EB82CCF338825DFA +:1088700062CD802FF96E265C3693ABCE906FEB45C0 +:10888000E635C37341E9379B05294E2D3389F276CE +:10889000B5CC4165D174576911F0A3CEEC75E17A7E +:1088A000AAEC6609F9853DEE3CDB48F1E47AE93251 +:1088B000E04900F6F862DA48768AC82EABF81C4523 +:1088C000BB481F2F7822C9AD8AD8EB61B2832A0A30 +:1088D00019C9C72D2CB2FC7CAC84CBCF374B5DDFE4 +:1088E000443CD7FB16D58F872E8FBED04A799B6D1F +:1088F00061F1C25BFD8A626F4724E7903DB901E9EF +:108900007AF1048F0DE18816C7782AF6F0EC491B3E +:10891000C1AE7B7614EC5AD443B7EC2AFB9993FA98 +:10892000503BCAB10E4FBAD0EFBA929038AADDC30D +:108930003C14678D1CAF796914E22099A8BF13FE1F +:108940000B9D63EA3A02FB87E5FBBC54E1F88E42DB +:1089500087E34B63CF17D3A0D4273E610B8D1B77E2 +:1089600059040E9741D0C0F5B962FFFDA024F678F6 +:108970002A81727DA9FC2EF261D574F96758AA7C10 +:108980003BDFE1BA40FC292DAA4F02F9BC667F7695 +:1089900001EA8906DB5EE32A80F7D552F9FD223A27 +:1089A0006FF41F5B1E6EB11E8F47BCF7B922CBA3BD +:1089B000BB1109C5E44FDE28E2FEE467848728FE88 +:1089C000E4AF8B63BE2F7BEA7386FCC970FE1F5B2E +:1089D000CCE39D6347018E06285746F1EBA68CC277 +:1089E000FC8D5ABF6EBF3E44CE104185E6696CDCFB +:1089F000AF6311FC3D9735BABF377B14D6B110F386 +:108A000071B591F5DA7DC531F7AF967E03CA0733AC +:108A10005BFDA9D0C4BC306FDA50BEB2C9D5AF0F70 +:108A20008D733F38E1E037E508707EB338E672F2C7 +:108A30007C9C1EF975BD19E1E96A067E8DB05F2543 +:108A400025DCFF9B3BE111968876633A43F711E4FE +:108A500009CF3736297E6383A27F762A72D4532CBE +:108A600052E92CE5F5B951E8FAD7CAFB8D4A9CB614 +:108A70005162F22B91F47FECE9E6FC3828E7C671ED +:108A800038EF0DF3CFDF53F4C49ED8D3CF9E0CA0A4 +:108A900093B9B591F17530F674B17402CCBFD4F6C8 +:108AA000F41C90F8B02F9B0D945F9C2EBF580CEFD8 +:108AB0006D8BC2579F2B7869863E3AB0FB5BA03422 +:108AC00042F91090815440FAED55EC6F018E30144C +:108AD0002004DEF1E8E7F43AE41E7CCE5C6DE47F2E +:108AE00084C81BCA9F569939DF74A783FF88FE0E7E +:108AF00033D33993AE20CF9F7665F2FC68383C6A59 +:108B0000FEF46F458F19CF71776516C485F2DDEBE2 +:108B10009B98266FDC7585E785C14F8AD3FA49C9D2 +:108B2000E427858F9F90B9745EA87F24C8DC1F025C +:108B30007F26505C3CE417A9FECF987CF95CF17F5E +:108B400002FD1DCD9F1147490F8B30073EFFDD749D +:108B5000F9DF108F23D0D31FA3D0D39FB0DF7F3492 +:108B60007A62CC11B768CCF071BBB21EB7B58E700B +:108B70003F2021D31991CE54FA027A9B503276E8E5 +:108B80007D21F3B44A6F134B8ABF3EBD5DC0BEF07A +:108B9000EFACE1AFECD649D1FB9DB57ACC280FFA0A +:108BA00032D79BF19EC4D4992E07CE6B11996C00DD +:108BB00038BB5C3E339E7B003B2FBF6484BCC1CD81 +:108BC000222E3F7EADECFFDC099CFF2A960BBE7D7A +:108BD000C07F4D6C9701F74D7DFF5849ECFD887BB8 +:108BE0007248EE35968C20F75E56F8E273055F2BDF +:108BF000DAD629E7995844FB6755ECFD8C342B9461 +:108C00007352D745A4E35B7487E78522AC6714E20F +:108C1000E0E7C7E4E03C4CCD2B6D40FC3E56C4F190 +:108C200017CDFE7D6A14FCB38900D74AF69901FD81 +:108C30006959FFC7AC48E7118E15D9399C069003D6 +:108C400080DF9559BAB731FCD995A4B587D4F767B9 +:108C50002BFEAE6714E467520ECEC3F11A7E0E4CA3 +:108C60002DCFC53E1EB0B488FBB9FF80FC0EFC734F +:108C7000A8A458E3E7FEA864643FF7B57F8FDC1A29 +:108C800050E8A8CB11D99E7D21F6FB40E7E060DDDE +:108C9000EF7C15B9116E6FAAE59ED8DB7B69597A16 +:108CA0009C87C3D1C8B4E7246EF1DF28E02D5D8F27 +:108CB000F368E97725E3FA5F85C3581AF3738CE705 +:108CC00067E831FFC3F9797DA92BBE94EC368F1983 +:108CD000F537D80714675FB939251FCD2AD8676BD8 +:108CE000A996BE934A47A6EFE4D23B40DFAA9CFC7C +:108CF00017614C53A8BC99A8C89B69A5B1DFAF29DF +:108D000018AF488E2CAF2B631FE7DB73774E747957 +:108D1000AC9E37FB47411B4F6EBD258F634E4769A5 +:108D2000A9FA2179ACEA87703C8D865E480CD10B9C +:108D30000D51E4CC68C03136041FB59D02E5AF98F3 +:108D40008DF9A6C0AF9DD839E4DEC7965188134F80 +:108D50000F8D7FC860AF47A0E3DDA5B1CF7FA3BC77 +:108D6000E9377CDB36D2F947A3D5C5283F6273319A +:108D70003BEC9FB1B395F2F6C605AD9487669D02B4 +:108D8000E5FD98F42EF979AB6CDEA7307D365C9E5C +:108D90006C8D395E8B72D897F637C5287ECDEBF88F +:108DA0004A3AF937AFA33C1524EE47B30DCC4EF742 +:108DB000A4AF7CB9FB582F2012302F9AC4E83E761E +:108DC000A7E1C77ACC471B053EFE5CE6E7F94F9763 +:108DD00077FCA3F09EE5A0317F3B547F519A4DFB79 +:108DE000DE69E5CFBBF69BF39F84A59EB6159EC1B9 +:108DF000F3E153A727531CECC5038F6BECEC5ABC73 +:108E0000C7807EDF0B1E867EA229D33571243B9C52 +:108E1000317F92AE8C509AA8947A5EFA059D6DF8D7 +:108E2000FB3BF7F748E867BD78C04C727FEA819E4C +:108E3000F85521E32796713EB6063DFE1900AF3581 +:108E4000D3733209EF1D2BF9739179CED4C22B6302 +:108E5000A4009D0FDF91576B0EA5BB2EA9D64C79B0 +:108E6000E45C9D638A1DEBFC1C43FCF4DAFD82404C +:108E70007EDD2E1150EF9AE1BA867AEC0D89EBC3B4 +:108E8000A9536B49AB752AE71E76E42D3980EFC7ED +:108E90004FAFA7F13B59647BCC58C6E5F08B0699E0 +:108EA000E67DF18048E7C855BCDE697CD6CB300F43 +:108EB000E0A3DEA6A77BD8A78D4E11E5D0E93481CB +:108EC000ED822DDFE97885EE99EC8802EF2F4AB923 +:108ED0009FCA6CA9447FA7F7772E8F747E5FA5BFCA +:108EE000C93364A90CEDC0499E2694FFCCB6E43684 +:108EF0007CF124DFBF4387E6CF03FCCF7DC17F2217 +:108F00000EF7216BCF785CF707A5766ABF450F1F78 +:108F1000BD42F4B0C5C8EFE37875718E03B08E859D +:108F2000D60111CF4F18528394E76D2AE3F2748B68 +:108F3000CA0F63811FE03D7D06BF07C526DAA9CEB3 +:108F400026072784DEA39E55A6AC970532F1F9C209 +:108F5000F87737D81D8C15F6A6378BB0FE8589EFCC +:108F60006EC8867A49EF785ECF78F7B36C89B1B274 +:108F7000DE0C5E9FF6EE6793A05ED19BC9EB953049 +:108F8000D478B09B7AB39ABD7938BEA419BF150FB7 +:108F900072147FFD526FD2458C5F3528EB871F031B +:108FA000CEE3ECFB473AEFE2345BFD782E83C986D3 +:108FB000B0F8193485DC7760A90924FFD4FB0BF3E2 +:108FC000457F3FF6D799FD84DFBB5927D97380AD24 +:108FD000DD5F147E797B2E5CEE6DD9C85C784E8C9B +:108FE000B16609EF33084CD67DC1E3784E9C5F85AE +:108FF000479D7F185CB0B5C89F43703D4FE3A87094 +:109000005DCB377951DE7A6B59AE27044FD784E0B8 +:109010000F186C45DAAC1D0FE13E5D1B139C204020 +:109020003DB97C1BEDDBB5B1C11F088E90BA81EF55 +:10903000635B6F09ED639728B7219D9B8CD66E21EA +:1090400091B1EEB884190CE6D931D6E5C57B6E40F6 +:109050007774EFD89B65741C0038EB8BB4F9A1C70B +:10906000153AFB83220FE6987679CE015DBA7B0430 +:1090700086F770DC83378CA8FF16F65D3462BEA4D9 +:10908000A3E7A211E9BE03EB304EC7F3C688F96F20 +:1090900063B95EBD2F4AE791D64B1C4FA7B2EE7A5B +:1090A0002A15E0E9582DD0BDBCF54792E6607D7DDC +:1090B0002BAE92B1E55587E720B9B438FB9FC27259 +:1090C000251B38950A24B4CCA567F6103DB9624D2E +:1090D0003CB387E8C9164F8AA6BE7217ECCE0C289F +:1090E000376668FA31E5FEEA3236F483E7989A94F7 +:1090F0007D5C66DB19C0B8EE3297C13B1032DEC230 +:10910000BECD6232C2ED111C748DD2CBCF3FADE02B +:109110002B84521C7A1FCFF7F40AC4EF1D6D7ABA64 +:10912000C7D3DCCBEDAEE63582CF2E201EF8BD0DC9 +:1091300077AF40EDEEDEA7EB9311EF1B000F00477A +:10914000DAF8847D2C114793E9DCD54A055677DFA0 +:1091500039038EB3E23B02DD6755BF9BA0C2BFB2AD +:10916000A991CE91017C5EA44F759D4DF647E95CB7 +:10917000D5CA89970DA887617D970634F8D4D65B48 +:109180003CDAFACA8DDAFAD132E59EF234360DF9BC +:10919000E9789920E23924B5FE51D6F9B7F15EE7B6 +:1091A0006ED1790AE9B3CDE89F81FA7EB7E8A2BA19 +:1091B000DA0ECF3B18F19DF8E100F1B140FCB9C5E2 +:1091C000204B35F83D977681E87605B6ABF3670F0F +:1091D000BD4F75FDF0FA4D55EE5A9C1BE8BB30476C +:1091E0000509ED907A511693F3882F229E77F9BDE9 +:1091F000C2076FA3F603B8EE4222857DBAEBFE44A8 +:109200009F17E6BDEBCD563AE7765721D0811DF981 +:109210005E47E7D6E6E3792F28EF03796881F22EDF +:10922000FDA12692EF338D12C977E59C972A2FE492 +:1092300017B5E7B6E6679E213BEBBEE776D279B578 +:10924000C93972C1D3A80F2D7CFE1D4704DF6618F3 +:10925000A723EF34C9CF71323F2FD76153E4682F72 +:10926000C85175FDB0BFE350AE612269411ECD9B70 +:109270006E56A95D263928F86B75E8FF8E53E6DD3A +:109280005F6DA775A73D7A48C0756731EF6601E647 +:10929000BB823A7CEC50F955EDD7B5F80BE85D563A +:1092A000AFB5635B45D7E365305FBB6DC0C8CF2DFD +:1092B000068DA81FEEE0F8DE48E3C3F27574EE50A9 +:1092C000E2FB30473F988076CEFAA339E3D808F620 +:1092D0008DDEACD3C8118314A79137F373B5F26751 +:1092E000A1432B77BE5196A3695F244FD3B4DFDF30 +:1092F00058A8A93FE0ACD4BCFF60539DA66EB2CD88 +:10930000D3BC6FB12FD6D4E373976BDE1FE358A5A0 +:109310006937BDF5A32601ED71B377C00578E8067E +:10932000DE284B1ED223D312E06528E30A2D562CEB +:10933000BBF34D744EB67B3CE89744ECFF1D3A7787 +:10934000694E7CC95C03E5DF0BBE5AFC7E0EA0C9EA +:1093500085F6DB3D4F68E3F0C7AB385FA96543B9DD +:10936000EBC10A28F35EB067F07BE9817B707FCCAC +:10937000718CDB45AF99C92E9A89765388BF71B03D +:10938000BA667E39F67B42BE17F982F532690ABCAD +:10939000B7CF083B8B7AEE3523F5CBEB1DD085E6B6 +:1093A000F77F59CEE5C1B3CEDA7B71FC8E3ED0B2E9 +:1093B000C84FCF7D6844BFAEA3AF3F01F5D90CE7DE +:1093C0008746B4CF879E2B7A4E0CC6619CE31F0E56 +:1093D000E923DE63DD5E6EA4F14F2B72BDE53B7ABF +:1093E0003A4F8BF7376B4A86E473CBE1A01FEF63EC +:1093F000B7B4F37B9B788E36929C06F9FC61A8BCCF +:109400007D361DF4C14C1A4FA30F9697F9E9DE3E45 +:10941000C86FCDFB2B97345CC57C25C871EDF34C30 +:109420007E1E96B10103FA7320D735ED1BCB95FB59 +:109430009CD358DE1720072E3823DFDB7DBB8A9FA5 +:1094400033B8E0AAA37D7816F089E7479F1D863FD1 +:109450008ED7DBE1ED65A48190FD1B66FF5771FFA0 +:10946000EAE52872FBA2B2BFFB8440010A55B7337C +:109470008EE87785B975EDA542DC97CFB7A2BFDE40 +:10948000F22381EEC1FFB2FFAD343BACDF78F8547C +:109490001ADE97761F3A9586F789DB0CF6CD68CFF2 +:1094A000037DD03DE48E5E3FC1DF7EA8B01F9FB735 +:1094B000F70A0E14C9EE9EEB0DB44E36B015FDA39F +:1094C0007D51E03A58CEEDABC3E5762ADD2E9813F8 +:1094D000F57E8FC9E713901E403E215C47C00F8286 +:1094E000FABE6DE6A648F6D46505DF27B71919DE82 +:1094F000FB6D83FEB88ED359A78DF8BD8596C3B09A +:109500002E01D771EE81781C7F8381A19DA1C2F7C6 +:109510007156E0035CFFFBAB0D0CCF2D6F59AD27EF +:109520007CBFBF81DB27FA877FBD3503EACB802E66 +:10953000F13B0F2756DF389D01E3BEBF86DB69751F +:109540000F1B882F97AD136EDD4B0EA56B956EFF2D +:1095500046A1D370FA0DA7DB61F4BAE6EBD1EBDBE1 +:10956000E5B7EC9019A8F761FFE78C433AFA1E7350 +:109570001C407E1A3C611807704FDA2A39C0C36359 +:10958000D3F5BEA7D2506E9CE0EDF96D7B052E7F22 +:10959000ECCB717D19DD4686F7082E2AFB7651D972 +:1095A000373B0B0AF1C8CF626012CAA96C25CEF90D +:1095B0008A81351D46FF52E4F267FA8F6D7BB787CB +:1095C000D0EF7F2BE774ABCAC56946E63A6CC5F7A6 +:1095D0000F8D5F04E3BC6CE0E7352728E34DC90934 +:1095E000362C825257C1E5E46F1538D4FA9F143EE9 +:1095F00060277F43F85C68E6F89FB7D1DF8CEBF813 +:1096000099C975BD1CDE5F30E17C1BEABDEE493FA8 +:10961000C9E3DFB973901DEE56F07FA2FC37CF632C +:10962000EECF32358EF6D772F46909E9D932A568E2 +:10963000DC48F130F7CD6CE64A01BABA9943A55A35 +:109640005F74FCAA7180FC82EB0DC42F37D3E9B99B +:10965000DAEF5305EEE9468E07D6974A7A1BE4B651 +:109660005816926750F1A0FAE39629FB69BF1E5B7A +:10967000C728EECFD8D3848F156DE7845618E741FD +:10968000836CB002BECF2736ADBD3485B19F6C620E +:10969000CC050B3ABBC9CC5C77037D6C92A81ED875 +:1096A00064A3FABB9BEC545EB638C7A2FE79E0A473 +:1096B000670AE2ED44D61E672DCC73EDAC81F04114 +:1096C0003B06F4FD98426B37FAF4CC0CED377A94F4 +:1096D000EFAD28F03F743383B940BEFC02E7838EC0 +:1096E000ED1B7F4672CFB1E67A03FA49F96D17B7E1 +:1096F00062DDBDF1770D685F7C00FA04E90CEC7E59 +:109700006613509E9C33DA810E9A6FA6D0382FEBE9 +:10971000820DC877DE630243FAFCA0F7BA711CD74A +:1097200057742DE1F94D74E69F2DAD4822FCB8FB2E +:10973000F2757C7F8B74A1F729FAEFF94302EE876B +:1097400079A3FD9D4AEC7F46CF90AFB7D70613A40F +:109750000872F8028C8B97A3701D5886B73719BD15 +:1097600053F03C419342C7E1ED8B15FA044C1B9436 +:10977000EF2932218D9F23C19F1658526232F94141 +:10978000FE38E0E796BEBAAB22961E817DA8F5CFE3 +:10979000D88721767C343AFCB2257E43E6C3294340 +:1097A00075F42343EF7FA01F19E9FB82A6ACC9E340 +:1097B000468A77B907C0BE83FDEA00C3C99E82F41A +:1097C0003E8DCA4F8E74D9917FCC71C13DA82FD8E0 +:1097D0005D3AF23BDABD5A7BA841E18706C51E7AA5 +:1097E000B442EB3F819FD45EC1FDA484E34CE33FD0 +:1097F000853F27FFC98C7C05F34E83FD7925D2FE7A +:1098000054D5AEC77E13D82EA27306748EF415BE3F +:10981000CEBFA8E07A54E5EB65C8D748BFBD9CAF82 +:10982000C3C76DA9AAF90B1C775B947B10F757F19E +:10983000F1DA9F13085FEEE752084F1FB3E79CB5BC +:1098400040971F031CFB802EAF399DF149D0FF9A32 +:10985000CB199F6C1D92031DCFC553BF6D9317A7E6 +:10986000B442FD19A47B18EF93DE3A8A6F3EF41CD4 +:10987000E73F75BE0FFCCB52909F8A0D41A303DAE0 +:1098800033FB2E26A01D587CE4FE14E4C368706EE2 +:10989000AD54E0DCF8D8DA4B299C1EF01CEE5A459A +:1098A000BFB99FF41B11FF6B3732A2DFFED77ED901 +:1098B000817CFC495FBC84FAF0E3A3F15E94FFD79E +:1098C0008E997C3A81FC106F22C8B58F0D03F791F9 +:1098D000BD79442FA1FFE83EF6DB3DC88FEED74CA3 +:1098E00068F9B1B57D5DD751EFB5F5DD7B55C4F2B3 +:1098F000A5D1E587F68D8FD37AD5FA6F3799ED2804 +:10990000473F11B99C58DBFB2AD9BF6B076FCCC00E +:1099100038EAC747FF4F09CA35F79B374A509EB907 +:10992000DFB85182EDEE1FC77B22D92D71B3F484CD +:1099300057555F66BF276AE2451B14FAC8EEDCD5AF +:109940003809F0577C6E8903F3B66A7BF1149D13D6 +:10995000DF2FFE797DCAC321FD3A0322E58D8ACE31 +:10996000D5C7AF0EA1CB47AA0C9AEF947DD5380F7F +:10997000B6E2F72D6FC575023AFA0EECB680C8BF95 +:109980002FBB46F0A1BF01F64B783FB2A7AE3D9288 +:1099900042F71099E89C3FBD08EB531CDBED2856BD +:1099A000CCA72687D84BCB023ABF09E8A8A9CFE4B9 +:1099B000277B3F205EA4BA62473D74FD3763B285C2 +:1099C00008719ADC77E7A01C0F8FD7C0CF18845B93 +:1099D000B5AFCEA7F3F851A647D22D04B89A3B995C +:1099E00084781D16D7699A4BF1A2F0F88E3DB0DB52 +:1099F0008CFDEC937512C2ABDAA5B88F3D11E4C0B3 +:109A00005F567279A6F2576780E7F53A03B5E6C963 +:109A1000507E5769EF9174CC0B78E9ECBBFF00C620 +:109A2000173A071F8C9F0EF374BEB798619EE79A92 +:109A3000546B9E82FD06E79A1FC81BA29BF0F91A81 +:109A40002AB95D34642F44D67FA50A5F8F961E2CF9 +:109A5000ACFCF3D083E09F575472FF7C058F9F705E +:109A6000FF3C5C7FA872591D77AD82EFE172F92A45 +:109A7000D939E047935C5E5B69A7F732FB16A59086 +:109A80007FFDDE9214BB75F8F839A243979C377CB2 +:109A90007CD59E737BE55366F47B643DF1A77B899F +:109AA000E0C3FC976AFFB99D02D9E5EE66830FDF3C +:109AB00053E10A2CE1F1D8076483CF220CD989AA9B +:109AC0001D79ABDD2150BB6A57AAF663C0C9E3BB61 +:109AD0004B8A78FB658B6B55E5585CA7859E17977D +:109AE000F3E78C394FA15FF5E05281911C50EC4AAD +:109AF000954EC3EDCE4FFB7212478A433DAFD0A7C0 +:109B0000CA6713C2F843D563CF54707EEB403D5E05 +:109B1000887AFCF71AFB3C7C5CD0E38F57523F46B7 +:109B2000FD8B7E2E3A23F9EB6665FCADEAFE054E11 +:109B3000D620BC592CB019FDCC68FAF57B8A9D1350 +:109B4000ADFD19C57EBC1D3F1F56E4C868F1F3CBBF +:109B500095B7F270FFA9F9F9967D688C62BF57D569 +:109B6000BC86FB1FA7F7046A90FFFE9781E2EEE137 +:109B7000EF3DA5FA9F22D3ECCFA92CA30EFD23F72E +:109B80001A1E3FE84EB2BF437ECC5B7A86E3AC053B +:109B90007F10EDB8476F2651D986F632942B5E3888 +:109BA00047F988156BB4F077634C17FBAFCBA6F37E +:109BB000032DAC9EE24C2D7D49D216500ADD630F79 +:109BC0009D46BEF21ED0DB0F84BEFF88FABE99C749 +:109BD000E136A6FB28F71A660FB478C2ED7EAD7D9C +:109BE00050A9C48DA2D9096FF45BB85C39A3273E94 +:109BF000EFC078D34CC68C7D5C2EB837F23849471D +:109C0000DFE604FC086ABBD27E450C501C8AF26B6E +:109C1000F0EAD5BEA7D3E83E97ACCD27B5EFFF3924 +:109C2000C9CBF0BC52720F974BEE36BD92472AA1BA +:109C3000EF97B7833F390EED4BBBFD1B8877808BC9 +:109C4000F948DEC89AB8CB3E25AFF4E9997F253FA5 +:109C500074C5912879A4EE793C8FA47C2777781E6F +:109C6000E9F4A90CFBEDF3481DBDE7E81ECBEDF2CE +:109C700049A6AA5B711C8A3B4E14797C77629F20AF +:109C800061BC6A621F5F77E9B638B2AF1B7EB53A36 +:109C900005E581BA4F9F2CE2F8FDE4FDCF6AB05F85 +:109CA000C9AF44C902EB7AE3FD0D3FCBE075BBD9E8 +:109CB0008EFD36C4A33FF3C9AFD6C7237EDF801223 +:109CC000F7E7C717C4C8F1C9A178756615C59D9592 +:109CD00078B508FA70CC505C27BCDF8B555C6E748D +:109CE00083BB4271CD233CEFDF9DEE9A47F5BF9ECB +:109CF000C4F8DF2990291EFD2AD035C68DA6C16281 +:109D0000312FFD3FE35827E691BAC7BA7E427CF473 +:109D1000D73A3BF211F4A7FC93F7B09DF423866A7F +:109D200031CF33033F5B40F7315229DF738FB28F5E +:109D3000E9E0CFA25F09D02CC13CF43425DF332306 +:109D40008E8938FE0E836BFB54CC2FF58B8ECDC4E1 +:109D5000048E143C6F199E7712649E2F57F34F6A3E +:109D6000DE3C5AFE49C07994EF56F0F396B280F982 +:109D70007435CFC4963A29F9B5A5CC43F7427C8017 +:109D8000B3AF73DE6B84FCCFC31511F23FEB2B989E +:109D9000629F69F38DDB735F213AFDAA79C6C378B0 +:109DA000AEE28EE6C5ECDC0F0D83BB28E9D334F2BE +:109DB000BBFEF86F09A467FB6E903EBC1634B10081 +:109DC000C51F0778DCBDCF4071866BE0BF8D0DD11C +:109DD000B3EF54F0718FF7D511FDF704EAE3F1FD0D +:109DE000DF2BCFB7BDB7E47EB4F7BD01FE1D0BC6B8 +:109DF000B83FD613108BD16EB983FBF2646584F53E +:109E000099E3B87E0AE7A35285FF4AAB389EEBDEA2 +:109E1000E77E987B03CFAF488A5C707B785EFD74E9 +:109E2000569AA0C6D3C745CABF1C0992DE687944BA +:109E3000A0EFC97CD9FCCB33E991F3F12B7A2F4603 +:109E4000CEBF343690FC8C16CF0E8F63FF9D2AFF59 +:109E5000A6F338767A9544EB4EF6E4D78C6343EB61 +:109E6000BF83FBB07456847DB883E36F9C1DDBF128 +:109E7000EBCA633BFE13311E7F7B8CC7FF61796C9D +:109E8000F3EBBA8AD8C2FFDB18C3DF1F09FEFF5706 +:109E9000CF0784E7FFC3CF0B849F0330BDF5B01716 +:109EA000DBBA849D413FC3EF8DBFD624801C149341 +:109EB000F6D37DCE05E53C1FB6ADDEECDB2B0C9D6D +:109EC0001B50F1F56835F723A5BCEB5EFC5ED404AE +:109ED00039509F82F1B272FE7743AE59785E8C8919 +:109EE000523AE6C9E0CDF4C56097745B22E7595356 +:109EF00095F1A2E99183D5358B6715E31F3D8A7CE7 +:109F00000EFF874A1C52EAE5F7E999684F5F4CF368 +:109F1000DAD3D11E4A3CC99F27F899BC97E0B267B3 +:109F20002FE67FDC201BE17B46C9FF26CFBB2B1B26 +:109F3000E3D2C96017625EF069CC0F923F2BD17BF0 +:109F4000EA7C9766713FEA190313309FEB9DCACFF5 +:109F500039B19EDF91FDA6E6F5CE1AFC975A05CAE7 +:109F6000EBB523FC3FD5F9F3F6652B440CF8CDEBAC +:109F70009128DFF876F9DFE5BA681E9EE77B4CE2B0 +:109F8000AF9C40BF19E078EC6821D1EF8AE3E5FF90 +:109F9000D48CFEC76491F03CCCAF54E205179478A2 +:109FA000871A2F50F35BFFACC4493EC0F80B9403F3 +:109FB000180F8172FB2CDD9DD64FDB6745E0FF67F4 +:109FC000041E1FF2FE94C7870A8D8E9CD0F3947FE7 +:109FD000358BEF63AB9FE72FD478CF0F95F5147EC9 +:109FE0004FEFC7EFA1156E9D6E443D5FB8352B0E48 +:109FF000CB19B24F9706F85EB6FAB04EDDBF487483 +:10A00000B45759E7B63341CAEFBD1A96F7BF348B40 +:10A010009F6768A9E6FB7B09FFA018D41F9B226EEF +:10A0200041F331B14AD247CA2BB5805F8C70B67606 +:10A0300073B8557CB7F8ED7538CFC553C1AD581618 +:10A04000ACC9AEA3B87BDBF5AD68BFB9076F9CAEFA +:10A05000A67899D18EFEC44303DAB8DB13D53CFE53 +:10A06000FE2A1AE088B77B45F28F0BEF15897E92A6 +:10A070005B2CE4BF261B98DE8AF545DC2E2A684C53 +:10A08000ADC33A5B9244F660C1197BD2C379437188 +:10A09000B0E47B378C453CDD2ECFAAC6D32E5BE4E3 +:10A0A000E3B89F5F35CFDA7EF63D3A6FAAAE4BC577 +:10A0B0008B9A2F8D966755CF3DB81B3FD39CD3709D +:10A0C0008BC1068C3F161EBD6854CE5F4AB6ECA10C +:10A0D0003C6CE191EB947F55F3AD6ECF75B2ABA1C3 +:10A0E0009F11FBF76CE2F9D7D7000E2C7B61DDB234 +:10A0F00009EFA1DBA8EC8375E3F3639B72A9F46F0E +:10A100007250797C531995F899C9F464CCDB5EA739 +:10A11000BCEDD559C3CE4D525E6FB7E8FC08F115C2 +:10A1200092F7A37A78DE4F1FC7E335EE3306FABE07 +:10A13000A1FBAC99E4774D5FEB44F40F3E3FE79A07 +:10A1400088707760DE2D842E3E911D9624F4839DC9 +:10A150000E0BE6DB0AFBAF1AF13C4C871830623C71 +:10A160000C20CFC0238BEE9EEBFCDC6F5F8D05F1E6 +:10A170007BDBFC58EFFFCF8F7D95FC5877353F2771 +:10A18000ADCA9102A74EDE8BE519D9F270889CD832 +:10A19000E6E4F9946D9327111FEE764E4A5A1D326C +:10A1A0005E67238F5F24DF3BD912FAFC97D53C1FF3 +:10A1B000962C306724795633FBEBDDC71B416ED7F5 +:10A1C00044B2FB3FF929D0E54CA08B23DF9E3890A9 +:10A1D000C7193F341EB7AD71F5C431289F2E98D8EA +:10A1E000141EAFD3C4E358585E2E5A5C6E45A34E7E +:10A1F000B6D079A1E004D4DBE1F13326062770BDA7 +:10A200002E67E0BD1498318395B161F9B95F30DFF5 +:10A21000CF27C3FBCB1A75A42FD43C5D41A3C8360E +:10A22000017D166C34F8283FD7285EA476C56FEC04 +:10A23000940A3290CE3F386B9430AE161E1F7334A2 +:10A24000EEEF9E04FD1D6D02DD0BBA5D1E4F3D0756 +:10A25000DED2DB3F07E36DF96C57773DF4CF9FAC5F +:10A2600093F0FCF4F07C1E3FFF5DA0D839E171361D +:10A27000A433B44BC2E3F01B153AD8389BEBADD7EF +:10A28000147F531D47ED174E3F3F9DCDF56DB4B87C +:10A29000FE5165BCCEC6826D93717F17E818EA93B4 +:10A2A000CEC65AF3E490F176CCE6E7DB9EC1FC60C3 +:10A2B0006A687E90E701C3F382AA9C2BECFF7D03C2 +:10A2C000E27B37C86BD4636E1BCF1F141EAB398380 +:10A2D0007263084EAEB777C39E07C8BE732431BE03 +:10A2E0002EFA7B45DEA302C5E70A167C763C1EEA01 +:10A2F000CC9944F7B0DC67276FB1A23C5A2016E333 +:10A30000BD1EB753B89567C27CD2FDEFACA1EFBCC0 +:10A31000163E907F0EF7E58166039D0F54F5DEFD36 +:10A32000EF3435F0F6BD4FC6617BAEE0B0D8F179C1 +:10A33000237D3F76FE4B7EFABB580B113A90E781A6 +:10A34000B39744E49BCB16D7DF231F152E52F24C54 +:10A35000CD5C4F3FD0B7C8C0C8CED3EACD13599F0C +:10A36000533CE8465F21E58F52F0FC43DE90BE2966 +:10A370003C0A7A6CCC9DD3633F9D2D113E67821EB3 +:10A3800043789217F13C7DF8FEEF50F63F9A5E8AD3 +:10A39000268751FFF0FB63DE0CC1365C8FDB31EEAC +:10A3A000538AF63A94E3A2D3DF1F6671BA4E8A62EB +:10A3B000CFFD49A1DFA8E7A77A4727CFF487D97F48 +:10A3C0001E7963D5FF52F34DAABFF6A0620FAB65AD +:10A3D0009352FEBBEF37A0728D78BF2139F2FD8614 +:10A3E000870E0968A7A8F71B4E1959CDE1543C4FB9 +:10A3F000ABDC77F22D223BE9D4DFFC62EB8BA97852 +:10A40000DF4990501DB51F3A477ABE1DEC23B2A715 +:10A41000FA7ECBE3AD87F8F9F0F6DEC8DFDDDBAD21 +:10A42000D8DFF53223B9D1AE9CB76DE851F244B70D +:10A43000E2968F8BA1714BB73D30563DC7EB237F22 +:10A440004F1BC78C16B7EC60413AB7DBB14670A022 +:10A450007EB8DD39DC5DCA79DDA8714C79E473B969 +:10A46000E1714CB95A9BC7B96F96C4F7DB250868F0 +:10A47000EF9A75CE363AB77F4C90229DF35E5ACD57 +:10A48000E5F47C250F72D0C8E9E3608540F76FF0F2 +:10A490001E1EEEFBC163FC1ECEC1027E0F47CD7BAC +:10A4A000A8F76BA60EE53DE8FE9D7A2F47BD67C372 +:10A4B000988FE05AF45C1C7DC76B87E1908DDBBD03 +:10A4C0005E7E3F1A6510E6434DCC13895F6BAB6B24 +:10A4D000C46A7AEF8EDB4F8F5447F07B7D8A1FE989 +:10A4E000AE8EEA2FACAFD6FA0B540FF717EE54DE50 +:10A4F000E38BD9EC4EFBFB87631C8F9E323BB6F19E +:10A50000C4EC48FBB6C5A2FD1EAF5A5E56E4DFB0F0 +:10A51000EFC50DBB2FC9F57AB760FFA74ACAA71BC5 +:10A52000289FAECAD5EE317CFC1F29E3A9654029DE +:10A53000BBA37CD7F9974ABCAC4B947B10EE692F38 +:10A5400068E397D30F69E397337B9335F57CFF7806 +:10A55000CDFB85672669DA8B03F768DA4B2F146821 +:10A56000EAE503159AF72BAFD46AEAB382DAF86505 +:10A57000F5CDC561F7387DB4BE1AA0DCD07E75E696 +:10A580006F6ADECB58A35D579647BBAE891BB5EB10 +:10A5900052C7CDF66AD797D3AD5D5F32E6E3F2BE20 +:10A5A0007E3E2E7FB65DC9C7E558B0DF338D932D53 +:10A5B00068B7A9F7A9D5F7FE2F376658DF407F00A7 +:10A5C00000000000000000001F8B080000000000D9 +:10A5D00000FFB3E46660F8510FC17BB918186E72C2 +:10A5E00021F84301CF6786D06A2C0C0C1A40CCC6E8 +:10A5F000C4C0C0CE44BC7E714E047B1D0703C34C57 +:10A6000020DEC831F0FE1A487C9D877E76A9F34291 +:10A610006859C181F73708570A3130B40A3330C45A +:10A620008840F80CA2A8F2554208B6A924657639EC +:10A6300002F5030024CC7134800300000000000008 +:10A6400000000000000000001F8B08000000000058 +:10A6500000FFE57D0B7854D5B5F03E731E3393793A +:10A6600064F2200F02F18400A242180284870827B6 +:10A6700021C4A8018380BC54263C43483211A8BFA2 +:10A680006DBD77260411ADB551691BBCE81D1014D2 +:10A690001575A0D1061CE84014B1DADBA8F8A8D5DE +:10A6A0007650444048C2CB8B2DD57FAFB5CF49E61D +:10A6B0009C4C48D4F6BFFFFFFDF1F3DBECB3CFD9E0 +:10A6C0007BEDF5DA6BADBDF61EC1329A244E22E465 +:10A6D0005BF8A365842784F4E92CDB0ADA8F9164A4 +:10A6E00042FC2F8BF2368E10EE778EF0A45184BC94 +:10A6F000B5990B98693DBCCF4608AD9FDE343D60EF +:10A70000CE2264FF08B302EF9FDE9A8FF5C92FBDFA +:10A71000E714687BD54BBC0075D3BE13CE889D1063 +:10A72000AFB9E5A16BE9F3F69778B2850E45FC93D6 +:10A730004D2485906316C2FE2EB2FA522BAB566D95 +:10A74000DE7F07F45BDE642656DA4FD5EE65D3AEC6 +:10A75000A5F565874402AF546DAB95FAD2FAF200C5 +:10A760001784FA9A7D7FC671DA0A48797028212702 +:10A770007D16225F49EBCE969459F47945606711B6 +:10A78000BC5FB183739BE8FB159BF67F0CFD5734D0 +:10A790008A0379DAFF8AED36220F61637F4B601EF0 +:10A7A0004BA601BC556F88C44CEBE5975649047025 +:10A7B00024D44BA50E18FF614976C03887701C0D54 +:10A7C0009F55CFD071E877D52F706E985AB589789C +:10A7D000009ED6DDD6394FDA615EB5D260F87EF7DD +:10A7E0007D12BCB72C50F6B25506F8364B4500E743 +:10A7F000A6CDD2D2A19DFDADD8FEA60EAE630DD9D9 +:10A80000A99EA8766379D247886CEEAC5710A20453 +:10A81000ED0077409A3EACF3F9792E8190D1D03F8C +:10A820004F644B67FF9430C807FEF7E83F810FF68F +:10A830003A02DBB23AE9B5D245FF2D77D2EBAC4B09 +:10A84000A59FD09E17DDBF563E0474A0F0D4FB5CDC +:10A85000583EE24BC372834F46BCFDCA3704CB0659 +:10A860009F1B9F3FE61B8BE5269F82E513BE622C54 +:10A8700003BE527C6F8B6F0E965B7D1E7CFE94AF89 +:10A880001CCBEDBE1A7CFEACEF6E2C77F8FCF8FC0E +:10A8900005DF7A2C83BE7A2C77F91AB06CF405F0B8 +:10A8A000BD977DDBB16CF205F1F91E5F1396215F58 +:10A8B00018CB7D405F5A867D2D581EF07D88E5AB14 +:10A8C000BE087E77D0771CCB0755BC3B27907C8198 +:10A8D000E2CDA9101715179258A2E48BB49E58CA5E +:10A8E000EA29B7F9F3255A4FF1D03AC563DFCA70A8 +:10A8F000BE99D6FBD6B0F6CC7B488185D633FDAC6D +:10A900007DC0834A8195D607D4B3F6C19BFC0571FF +:10A91000B43E38C0DAAFDE112EB0D1FAD541D69EA2 +:10A92000132293EDB49E1366F5DCB794C90E5ACF8B +:10A930006D61F5BC8FFD939DB49E1761DF8F3F1550 +:10A940009E1C4FEBE3DB59FBC44BA4D045EB130932 +:10A9500087F5027B7E6102AD17B858BDA85F9920CC +:10A96000C7E0BF7D626411A1BCB0DD7FB322A4D378 +:10A97000BA145945DC149FFE39580F8B6431B4BFAB +:10A98000E52F538471B42E91D5D0FE177F05B61FE5 +:10A9900010656C6FF7AFC2F603928CEDA6DA7BB050 +:10A9A000FEAAA8607B72EDBDF8FEAB9282ED836BD0 +:10A9B0001FC2FA41D183ED636B7F8DEF1F943CD8AA +:10A9C000FEC8DA805248EBFFC179B6005FD7719EAE +:10A9D00072920DFC1A4C2BA5FCBA8E2373403E1EBE +:10A9E00000A6A6F2B02E5D5240BFEDFB47DE933CC1 +:10A9F000A7F27632D4973EF54016F6F31CF623D232 +:10AA00007EF89EFB99F8CD585D3F13BF29D7FA69B0 +:10AA100084F7EAACBDEB67DF37E3F5F07C53A1F5D3 +:10AA2000B317FB71F46E5E13BF9DA087E7DB4AADE1 +:10AA30009F83D84F42EFE0098B6374FD84C5655A4C +:10AA40003F7FC47EFAF40E1E451AA7EB4791966B22 +:10AA5000FD7C88FDA4F7AE9FB074AD1E1E6985D63F +:10AA6000CF11ECA77FEFE6A598AFD3C363AED2FAC0 +:10AA7000398974CFEA5D3F071C7AFC1C7074E0E7EB +:10AA80001CC233A877F32A70EAF153E0ECC0CF255B +:10AA9000ECE7AADEF573C0A9C7CF0167077E440EB5 +:10AAA000E635AC77F32A88D7E3A720BE033F4E0EE6 +:10AAB000E019D13B785EEDA3C7CFAB7D3AF0938A26 +:10AAC000F08CEE1D3C85297AFC14A674E04746788C +:10AAD000C6F5AE9F5753F4F87935A5033F57613F4C +:10AAE000D7F56E5E85A97AFC14A676E02717FBC918 +:10AAF000F76C477808EDC7D17D3F07FBEBF173B0EA +:10AB00007F077EAEC57EA6D07EB27BEEA728538F90 +:10AB10009FA2CC0EFC14229E6FE85D3F0733F5F830 +:10AB20003998D9819FA9D8CFD4DECDABE80A3D7E34 +:10AB30008AAE60F899248CC07586AE9D6E9E7E723A +:10AB40007DBF7C85A3EFF32E56E75D6E02760FAFD7 +:10AB5000D933A445E1E9FBF61D09B90F9068BBA6FE +:10AB6000E076C08F835A79D1764DFCD8389D1D95FB +:10AB7000A024EAEA49C57D75EFF7291DA06B4F9D1A +:10AB800073B5AE3DDD93ABAB67948FD7BDDFBFA68A +:10AB90004057BFE2EE1B75EF67F96FD1D5B3D7CF42 +:10ABA000D3BD3FA87EA1AEFDCA860A5DFB55819547 +:10ABB000BAFA35DB7FA27B7F58708DAE7D78D303E8 +:10ABC000BAF611E14774F591871ED3BD3FBA658B84 +:10ABD000AE7DCC87CFEADAC74576E9EAD71EDFA398 +:10ABE0007BFFBAF603BAFAA48BBFD7BD9F4FDED561 +:10ABF000DBDB963FEBDE9FE2FA4CD77E7DDA9706F1 +:10AC00003BD5EE3A768D5AE741AE08FA25FE740937 +:10AC1000EDD5B043C2BAD4D7CEFC14C752F928E55B +:10AC20001FE9C0223919F992FE51BB21BF6FF99576 +:10AC300011FAFCAEF19E2B5DF4F95D9267B82B869C +:10AC40007D43F98D236950CA26288DEDF7898CDF65 +:10AC50000B322E0D3E42BFF79ADA0727D0FA703E2C +:10AC60003F08F2F1326742BB3A8E2735F05E9C997D +:10AC7000A0DF745F56DE93FE287958DF9FDA195CF7 +:10AC800067BFEB454F1ADA51B59FF8C1CE59D79F30 +:10AC9000CEAB2F21AF709F84FD03E9F7FD97A67916 +:10ACA000687F6689FA19D1E34B74FCA1387E18E4F9 +:10ACB000E1208C3FBAEBF8E6016375E35B32CB75BC +:10ACC000E35B243ABE8B90DFD77EAE8E4F89309EF9 +:10ACD0009037B9CF717C7366398E7F9F44FDAEE8A3 +:10ACE000F1E33AC66F81F9BFDFDDFC078CD7CF3FB8 +:10ACF000B3423F7F89CDFFA3DAD3EAF87138FF3F33 +:10AD000073A7D9FC332BD8FCCDACDF8EF19D1DF899 +:10AD10008FC0F8C7BA19DF9C3D413FFF2B2AF5F3DE +:10AD200037B3F14FD65E50C7B7E3F85F7217D8FC60 +:10AD3000AFA8C4F125B3C70DFC2365C4D504E8F85A +:10AD4000A41F557CA9C02E741C28872452A12164FD +:10AD50001B3700E1B82B8EF1DB577194DF509FF960 +:10AD6000F1390950CD9947FD4695D757ECC8974022 +:10AD7000EF613BF5B796A8A02E6EE291BFC90673AE +:10AD8000601085B7B589F7437DF186EB02A05FBD02 +:10AD900066B2A014BE1348189E7FFECB615BA2E78B +:10ADA000652C97D48BC72251F2D6E1071690213536 +:10ADB00014BE29C004A33BEB9F523F0E1CE38FA996 +:10ADC000DF43A8FFF399C8C6FB0BF5F7A01EA1FE51 +:10ADD0001E3ACEA416BFA3DD1D4EA3F097AAF07FA6 +:10ADE0002A3079FDF4362EE0A7F2F9D58F47A07FFF +:10ADF000BDE06E1B457A271C65FE245D9DCECB0F02 +:10AE0000746ADF6D0E6CE110BF32E06B3A8A262166 +:10AE10008BD667505C77BEFFC1BEA907392721B723 +:10AE200012454CA5EFDFBE9AEBEFA2E3CE52CCB9B0 +:10AE30006C1D52324C28D724C33496905B1A478835 +:10AE4000B407325D113F8D448D3BA3585F9F55AAD7 +:10AE5000AFB78A8A68A270B54EE7C866DAEFEC39F8 +:10AE6000FA766D9C81A644466775BC528A9374FA43 +:10AE7000683694B9F0D885749EE362DF6AF078177B +:10AE800089248C7EBCBF0F01BAFA93F1BD792E36AE +:10AE90006F23BC73448B524AE739A78C0F007F1B8A +:10AEA000E1FF689F4D31E5D072FDA32231759D8F82 +:10AEB00011FEB91EE37C8222ACF3F3CB8DCF19DFF8 +:10AEC0001C53E9FF29F0072DBF00FEA0F01F55F924 +:10AED000A353AF32FEF09A3DD3801FDA37F204E974 +:10AEE000AAF2CBAD2ABF2CA9D7F305211E11E8B8D1 +:10AEF0006C0E97FB40141FCC56F96059839E6F6E01 +:10AF0000277E313D065DE66ED87C6F9ADC757E9FAC +:10AF1000A87C33FFC1FD889FAEF36474BA43A5D308 +:10AF2000ED35FAF65B55BADEAED2754EC3C3AF51FE +:10AF3000F541E6C90111E4DDFB538D9E111D3D3D38 +:10AF40002A3D8D70DEA1D2F38E1F337A1AE18DA8CF +:10AF5000F48C349C13C980AEF01AE15B707797F9DA +:10AF6000605CABCC1F9B9EDEA6FC5547A39E57059D +:10AF70006F5875344ACE566C9FAEAB2F0FCCD5BDF3 +:10AF8000BFACA14CD7BEA47EB9AE7DD1FA3B75F55E +:10AF900032FF8F75EF2FB8BB56D77E7BCDFDBAF64B +:10AFA000F9E50FEBEA733D1B75EFCF9EB359D73E22 +:10AFB000ABF4195DFB8CE29DBAFA7465B7EE7DD3F4 +:10AFC000BEAB6E06FE7CEB3D9E803D71C1FD05C6AD +:10AFD000332FB84537BC73D427235F1FF30DC1F25D +:10AFE000B8CF8D7C7FD23716CBD6A6663BAC137418 +:10AFF0005D5C4A12086932CDAB5DDF0FD66982EB2A +:10B0000069C8E4A9F5D37AB34946792869904878A4 +:10B0100024211C2C362A1CED7C547BA487F606AA1E +:10B02000F893BAB69744623FF73E527605F06577DB +:10B03000EB03FDCB00BBA74DB5EB8DED951C298D2A +:10B040007E4EC81A84C36A627647A5C4E4BF7257AD +:10B050007A0171423D3CB8E672E3052993A7029F4D +:10B0600064EBE47859C3353AFD4E209ADC07F86D5D +:10B07000A4EEF98AEDD7EABE3BB59F47B8AB41577E +:10B080008C8365B1F43313E8E17073E68C6100A73B +:10B090007214EB4D7DD02E3CE52B5E757410D0AF55 +:10B0A00014CBE3BE39581EF379B03CEA2BC7F253F8 +:10B0B0005F0D9611DFDD58FEC5E7C7F263DF7A2C1E +:10B0C0003FF2D563F9A1AF01CBF77D012C0FFBB6A1 +:10B0D00063F98E2F88658BAF09CB569F82A52677A3 +:10B0E0003DF1DD71751D3E09FC1783CFA43A7FED5C +:10B0F000FA099D7C16C7DF877CA6E1B9A4C1ACF232 +:10B10000438A8E1F12C097433EEBA1BD4154F9B054 +:10B11000BBEF63B77BB7FC6BF86DEA0FE4B74E7E0D +:10B12000CA30F053764FFC348C8FE2A7A92617B3B0 +:10B130007B547EFA19CC23865F310F8C903E51F6FA +:10B140009A926F82756CA5BA0F421F60FDAC3A7679 +:10B150001D7DB705EDBAC0105837CE0EF9DB60D8AB +:10B160004738FB21257E56F7F333F249F77857D05D +:10B17000BF591AA0444FEADA6E8D6378B59A483108 +:10B18000A1EBDAFD839E722F1C8A758124C2F70120 +:10B19000F774478C7EA9AD0CF8ED09AF758EAF72D0 +:10B1A000A0BF638FFD3D0FCAA926662FC735F36880 +:10B1B000B793F0936EC06FC7BA6476A741BCBD7DEC +:10B1C00090E442BB814CD6E3CF5FA0C3DFFD1447C0 +:10B1D0002DB8EED6A721FE067E3538BD17F8EB490F +:10B1E000BFF784CF8530EF7F013E7BD28F3DE945AD +:10B1F000A2C82F34D1F9B7ED1B96FB800CE35E1E7D +:10B20000DFDAFE9A119E5F7E473E6E4BD1F8B8257D +:10B2100093801FA4CACBD9C62BE3812E1DFDF44019 +:10B220004FEE779F6482FF7E3A4BDFDF7DC6FEE202 +:10B2300025C20DA7E33A2489C453BF92F76CE3D12A +:10B240009F7147FC1037D86773D7C9E0379EFCAFB2 +:10B25000B00C3DEBE30B670F3DE9043F6C651A5FF3 +:10B260007334061DB5B22A9855638FF6579AF4F5D4 +:10B27000B3F55C7110E725C7CF1C06EB8CABE6A8D5 +:10B28000087A3F0D4BAD9F9569128E73727B763CA9 +:10B29000F3FF024C9FEC48407D73D267C1F7FFD9A2 +:10B2A000F074D78F060F218DE4330BE873DA96DD47 +:10B2B000FDFBDDCA83705E82F82909895F81BF6961 +:10B2C000A5FF7F3B00FA15B0AEF5EB0DF27EF370F3 +:10B2D00078BE43371EFD4ED6F68CE1BBEEE54E2020 +:10B2E000C734BEA7F4FBABBABFBD62BBB5466FC7E0 +:10B2F00026E8EADEA6F41A9D5D0BFF00C3BD8613A7 +:10B300006009AB54D9B04DB0AF077EDA03C149F044 +:10B310005F38F65E9525227964149716E0D385632D +:10B3200035FE9767FF99EAA9136F8A04E48C5CA243 +:10B3300050E5A9AE20F29B8998687D91FAF6C2C6C5 +:10B340001525B06E9D78F926F44316935227F8C759 +:10B35000E5A43E0FE2B5A789A918E4F33479C7390B +:10B36000324A1EAD82849D2E5AAFB7E3A97FAFABA0 +:10B370002F6BD0D797925B5260DF7EE9069104383D +:10B38000D01BFAF6AF7917F6BB8CD4AC8375FB579C +:10B390006ABC6BA18B0819546F55FDF6F1BC320ADB +:10B3A000874B6071166D1F7A7922F37F2A66062417 +:10B3B00085BEFF59E3C85BA906A2DF07D6C17EBCE4 +:10B3C0007F3A716F235DE9F75DE137C2ABD9035D69 +:10B3D000F6C3553892B7734A20861ECB14382667B9 +:10B3E000AABE2B105CBAB8C73443FD7BF35332D1ED +:10B3F000F1D31EDE93278C66FC03FCC009ED92E7B7 +:10B4000087F49FD6A5FF827F6AFFFD68FF79BAFEA9 +:10B41000A7FD53FB1FD805FE79B1FAAFFAEDF32F64 +:10B42000FBA93EA978F1974E42D7C913427D8A9B6A +:10B43000D2B572DBBD4E8596C705BF13F8F54480C3 +:10B440002F8E45EF87054E1542C5CE41DC0DFE49D6 +:10B45000FB3FF9ECCF301EF1D536D185F1B4EDE6E6 +:10B46000B099CA6175E3F2129283F523AC7EDF19BD +:10B470001EEA4D7AFEAB78FA9729901F4239458D26 +:10B480002F85D19EADDEFA7911AC4F5ED28E7264FB +:10B49000FC0EC6BF9888FAAF4C8AEFDA4EE1C4388A +:10B4A0008157C58BB7F16767782794377C01FA829B +:10B4B0007A22E8C71BBF2B57EDD4358223F9988D2C +:10B4C000FE7B0C19037A51C30B09303BB5EE995F33 +:10B4D000E71CA1709DDAFAA6938BC297264F67836B +:10B4E0008BFE738FDCBDDE6DA5F2166D0F69EB96DA +:10B4F000DCA4DAD72156568A6127E4F3546E16DDB0 +:10B500007EFAB8F2F9279F7A0CE2997F32BB07D115 +:10B51000FE573CFFDAFBE3697DC54E31B9844DC36C +:10B52000CEA574D2C74BFFBF3BB7931E15BF794D55 +:10B530009287B1E7F72476D265C5CEFD1219D615EC +:10B540001F9383FBA5883D067D82478AC05EA87B4A +:10B55000E6BF2588339ED8C791D4AC18F8DCFC1A16 +:10B56000DA038027A4A74AAF0EFA19DEF752BA8091 +:10B57000DE36D2CBF8DE2255BF40BF906741F9FBE3 +:10B58000853D9007F591D90D78287F619513E6F3F5 +:10B590008550C3F8FCF17B53409F958BFE141796A2 +:10B5A000EC79F9133F42FE5BF6F68F5230BE4494BD +:10B5B0007413AE45FE7498E7924DB3709E4B8907A5 +:10B5C000F9B0FC71BE3440CB0B0229DE19434EACFE +:10B5D0002293932FB650E2D2797E01FE24E8EF77D2 +:10B5E000F8C036B4BBEF24A00F7EA4CE855A0C5809 +:10B5F000BF6061F4FAABBA2E10B03EA3F977EB7DD1 +:10B600002D40A793FD9554D877F112C1AFE283FB8B +:10B6100096F6CBBF3D2595D189C8429EFA1D5DF7B0 +:10B6200027C37378BF4554AC39BAEFC8B7599DE307 +:10B63000AF56C7A770C7C17AFD454A6CFB354FD4DA +:10B64000F4005DB7A3F82C4ADE99FC6FBD9FC9BB1F +:10B6500026FF81E9C5D07EFE309323F80ED6430A3B +:10B66000573815DBF7CFE4503F503F3A969C6F15A3 +:10B670005539D7B71BF985C22F70F1517C03E324EC +:10B68000221D70DF65E906FA7D941EF5C2B8CEAEC4 +:10B69000FD6A72BC4CF35B45BD3E209B981EE8DE04 +:10B6A000AEF2239E2AC5C0538F81FC5279F5CB2080 +:10B6B000BF6229CCFFCB1DCDEFCFA372FB655093AA +:10B6C0005BBD5E35CA6DF9AED12496DC7E69779399 +:10B6D00098724B9FC7945B7B04F9F9FFB45ED5F079 +:10B6E000380CF0784D271E353DD91D3E8D7AF290ED +:10B6F00020235E8D7A92FE1D26795DF951E3438DFC +:10B70000FF2A9EABBA02F451079F6A7CD8C1A71AE0 +:10B710001F7689EFEAF0686CBF00FB3414AEF9962F +:10B720008DD38E5257D2D24E70DF267F268FFBAA42 +:10B7300096F384E5811011F3433F30D58C063B75B9 +:10B74000E2DF6F3D7D1785773EF18B2C2FA05E44A5 +:10B75000BBFFD2B7DF4EA0F399A7E2793E45FB5479 +:10B760004A973902178EA370CE15883F3E11E2B773 +:10B770001CF9340A8EF9E5FA3AFC4D4CE9ECA7A71E +:10B78000F7BFAB9FF27DCBB7295D3F1D44C8BB50CF +:10B790008A38BC10CD57D381AE147FDE515C600077 +:10B7A000EAA988501AE577BD2032FBF3EDC219A350 +:10B7B000C1BEC99F3D2C9EF1FB60F47BBDAA3E3B00 +:10B7C000EB97E341CF9F0D65A37F7BF6D02247AC7B +:10B7D000BCD06695CF5E53F75DDAEC5C3D4FF9BFA8 +:10B7E0008DB4A37DE3B75BC9B618FB821B454D5FE3 +:10B7F000AB74A37F3C1D7F8ECA8773E9A7F1B95153 +:10B80000749B39F584E0EC4A07F8FB34CA0FFBA1BE +:10B81000F805BE06FC365B2345A531E279CFA9F8D1 +:10B820009B78E06BCCCF2D0CE50B80C7423BAF8BF8 +:10B83000833CA9C9EB503214E09A7860F9CF4753A2 +:10B840003EF61EE2DD908FEB0D9D913C31FC6123B5 +:10B850003EA17FB0338F882EC4D77B62E912C0EB44 +:10B860007BB3AC04F635DF95DC55B1E02C33B3F592 +:10B87000662E29BD308AFBBF0FBFF9B31DE1028AD6 +:10B880008FB37696F7DD95FF98DC9F7571815A0E20 +:10B89000F89067F5642E0071B422E2F9F9040EE520 +:10B8A0007D52B4FECA6F9AFE3CE4F55487389789FE +:10B8B000B6570B1109F8D8DBB45300FBFD269928C5 +:10B8C000188F106A86CD8C8A7B1D1105C457F3DF53 +:10B8D000E6DD0EF83D37D34C002E65E81927D80178 +:10B8E000E74223510EBA9BD71F7C645AA108FD1072 +:10B8F000E40F233F1425DB74F55993493F37A5DB4B +:10B90000447364953B06FDEA24C667BDD66F96FF77 +:10B91000CFF4DB04AADF185F8BD1FAED2689F17D25 +:10B92000947E4B8DA5DF56D6CAA9C0172BF766A704 +:10B93000025D57BEB1A44F2CFDF6BA8FF9F76FA880 +:10B9400079E66DFDA87E1B1EA5DFFA51FD1623AE1C +:10B950003B5AEAA57EB3FCCFC8DFEBA0DF62CCB7D1 +:10B9600058C59FA6DF8A43B5A8DF8AFBF1BA7CA938 +:10B9700049524FFAADEC97B3B02EBA6D31F807F0DB +:10B980000AFAED0D55CFC138A0E7FE5D727D273D67 +:10B9900057D55B3DF73F84674DCFADECCFA13DD38D +:10B9A000950F999E5B99C5F4DCCABD4CCFAD1CC404 +:10B9B000F49C51BF1574D16FECFBEA21F47BF423A6 +:10B9C000B37E7D1B6D2F9923BA2DF4FD12593B9F39 +:10B9D00051333A5ADFFDBBD48DBE739FC1732E3DE8 +:10B9E000E9BB3F82BE1B847A6C20C891913F6E1CDC +:10B9F00068D3E5D3BDF7F5B1E75E0479F9038FFEAF +:10BA0000F70726E627EDFBFAD84890BBF7001EAAF9 +:10BA1000EF9E51F9AFD5E7477D3A792893F7AA7B96 +:10BA200018FEAA1B3936DFD57C408675E06F17D12A +:10BA30008FBE7D2FF3A3679B5BFAD8C0CFFF5F2239 +:10BA4000CA25FD2B298BE28739172B30EEB92BCE77 +:10BA5000B905FCCC3902B1801DBBE0D08D27C07E7A +:10BA60005D70713DDABD0BE07922E9C8FB98DBA17E +:10BA700027F5F6EBBCA69DAF6590AEF91013CD8C03 +:10BA80002E13577181CD595DF323A85D86F92DC61C +:10BA90003C89DFABF39FCD47105FE48F7CCCF8E5AA +:10BAA000EF8D787233BC54ADE6F578AAE162E28995 +:10BAB00052BAA42CA5132FB7BF14599701EDCB3957 +:10BAC000F4B78CF3D6F0669CBF8647CDBF59A0BEB5 +:10BAD0003F3F7424669E8886E72EF9221ADE0DF811 +:10BAE000784BD333D7906120971F983C3F1F0D7C34 +:10BAF000F47B8A170AE7AD7307E9CE2BBDA3E26595 +:10BB0000AAE748618A0C782435C067F3CA77BE96E5 +:10BB100042E777B392950B21F5597F933C108F68DC +:10BB2000B6B6A31ED4F8709499C98559D52BEFF5F4 +:10BB30007515E27AD3C4B950BEC2063DA7E699791D +:10BB4000EF61F2D7CCFDF7BA8C518867582E489137 +:10BB5000B65E015DE83FA786185DBC4017FACF6965 +:10BB6000A4FD20E0BD3A997387E1FDA69DF7023F51 +:10BB7000BD6EA5CF41CECB39F716860E7B7ACA654E +:10BB8000F95888C5C718CCC8EB5C3F17C07B895DE6 +:10BB9000ED9389E696F7008E89546E36C3C300FD97 +:10BBA0002F8AFE46FBC5C8073DE50375C7EFB92AD6 +:10BBB0009E5F073AD801DFED12D843DE305B7FB4D9 +:10BBC00076AF201722DE343A34D1F56514A38329E9 +:10BBD000069E6FD6EA2A9EBD214E84EF6FA0FE6FAF +:10BBE0001207BB7E5F1FD4F8DD2C77C513C415D2B6 +:10BBF000A3F406E8B7E87DCDEAA6B7115F37AEA695 +:10BC0000E699DC155F1A7D400F5E0E6FDDCA4FD3DB +:10BC100091987961DF557E4699F5F2B3CFDAFEE669 +:10BC20007088ABEDE550AF9050822E7E30D3CCECD7 +:10BC30009666AB07F9BCFD0DD1BD45EEAA7FA6A85F +:10BC400074017F25FA7CE2649808E84D97957CA6FC +:10BC5000CD7B00E3B7E8F5E075AB07E9D75DFF33CF +:10BC6000CCCCFEEDCE1ED3EAD7C37890D728EBC755 +:10BC700033AE475A5CA9A77979D471BFEFBCB471D0 +:10BC8000BEEBBE8497B4603C4EDB9FD8C37B768905 +:10BC9000603F1673BA7D100A39EE6FFE13FABF5972 +:10BCA0001ADD7DFF103F0A533CBFBEE3498C639F02 +:10BCB0007EF6C834909F15AFF0C442E5AF75878318 +:10BCC00084599E8804764245238FFB5D4408E7CD66 +:10BCD00088B233A827C3F0F1A203F55EC52E73A086 +:10BCE000847E5FF1F26739107F6B5DC3F49FFF596B +:10BCF000951FFD911CC807A810D8FEBC913E8FA8C7 +:10BD0000FC796AB76D0EE86F6E3B3BC75B119C2DEB +:10BD10009AA3E20CF79B4516E7DE6DC33C6CFF333C +:10BD20001CE631037CD1E748B5FCD053CF30BD5C75 +:10BD3000D12406E03C70C5F69DAD1017AFF8D08C4D +:10BD4000F6AB77FB1909ECD3C92F3ECFCE1B37F1E9 +:10BD5000BA78689738E4763E6C86F8596315EA013C +:10BD60005A3F82F5A01AF7FB8E71B2152FEE7DD9DE +:10BD70004F51B8E2374F3BF15C70CB3627C623B743 +:10BD80005F7E5FA04BDC3178BF1A779CFA05C1F566 +:10BD90002176DCF1A4CA2721B33EEE48B627613CE8 +:10BDA00092C299571A237ED1C1FFCF5F7802F6CD98 +:10BDB0004EEDFAF20980BBF29B734FFC94E2932A9A +:10BDC0002017ACDBDE67DFC37D06EDBBF7557DD208 +:10BDD000FACCD3B84FD3FA27B31B7A6BDDFB4526D9 +:10BDE000EC53B4EEFC3A05E2B8ABF74E417F6DF58B +:10BDF0004B9353490C7F402B817F03BDD82732D210 +:10BE0000ADB9B13913E03C4DE90EEB77473C3958F9 +:10BE1000C5E2F4B21A47DE117B5FAE4BDCB871C6E7 +:10BE2000CDD7C13ADE28BA65D28BF8F1614ACFE1AD +:10BE3000BDA0E30E759F2038F5B2F1E3D3F00F4AB1 +:10BE4000AF0B667D1CFE42E392FF7C0CDA1A93BABC +:10BE50008D1F877B813F6DDF6FBF59211690A35DDA +:10BE6000CF61DC1EE8477D0FD2FAFC854C88BB1CF5 +:10BE700017DBEFC0FCEBBD66CCA3AAD8FB01CA530D +:10BE8000EB4B6FE3BE1A51F7DF5A49C71FDB27514F +:10BE90007D3AEF56078B3BAB7480B8B4ECC4E76ACD +:10BEA000FC99F1B51697EE2E1E3DD63280EDBFAB54 +:10BEB000FB91555BFF2C1143BC9F1B0BF43A72D9CD +:10BEC0007D540D0F2EC0C398E8FD96D8F1FF8EFD6E +:10BED0001603DD809E608F75ECA7D07A3F88AB0794 +:10BEE000B80F62EDDFB56E66FB34AD62ECBC456D3C +:10BEF000FF65A4C5B0EF12E8DDBE4B4FF3F8AE7896 +:10BF0000CA0627B44F577C9DBA145BBFDF6AE1D4E1 +:10BF10007B03BEE7BE7E2567CC1B98057C59D57890 +:10BF200044027B4A5BDFB4F99E52FDE753CFF278BF +:10BF30004E645DB019F5BB517F5413163734C25BA4 +:10BF40006E617AABBA89AD1FA776390276DACFA9CE +:10BF500003BB91AFAB771C91FCB4BF83DB7F234560 +:10BF6000A2F2AC60FD0844C17FEA85FD396C7F898F +:10BF7000F9EBC671EE52C7F186628FE3DD71463789 +:10BF8000CE0A7F5062E77E2E3FDE4941990DFD9D2E +:10BF90006C1109E4FD9F0CF2C58118E3CFB5885AF6 +:10BFA0003C8BC90F5D47F11CA6839DBBE41325B4F0 +:10BFB000BB573BC67E08E7FD573B2419E21775B512 +:10BFC0002C2FB5EEDFDC6940EFBA845B713FAEDE4B +:10BFD000805F57B22B1FE21AAEC2D251C0AE46BD2F +:10BFE00093A09874F0AF7614A7CA14CEB5AA9D4654 +:10BFF00004379E0BE59D45C5301FDE65725963EC25 +:10C000003B88F652E289C28BE8D29FE3249746CA66 +:10C01000D08F967F53696939888D2E05538C85B1F1 +:10C02000ECDDFC992E9C77DB0ED57F5088EC4A61C5 +:10C030007964B08EB4ED8ACF21C3F143A2507EB4AF +:10C04000A9CFB91DFBF7835E5AEB244A0295338AC8 +:10C050005599CF86F3AC232C5C36F0E999FF7A85AD +:10C06000F66B0DF1E857B4D9B57C522501E4CC4606 +:10C070001EC4BC4160E56F933AE134E613127825A3 +:10C08000EA3E8D29BC1DFDA1B39B587C802757FF3C +:10C090007A028BCF9100C0AFAE2F2B5438CF12E273 +:10C0A0000EC3FB3B1C180F58F6C622941FA0433446 +:10C0B000BE928AF5E75E1BACCE1CF067365A55BFC0 +:10C0C000C6AFB4C0399BC56ABF7D4AF5E762A918FF +:10C0D000FA415E97A8F2FAE5D2A243988FE6598A10 +:10C0E0007A3E758EFEDCAC314F4B20AA9F1C60FE61 +:10C0F0007397BCADA6CD08B7317F6BC5767D5DC3A8 +:10C10000E327A037AF027412FBE5E2803DE237324D +:10C11000F8D713467D77FC9AD3F4F8B5CA7AFCDADF +:10C120008618F1A7C7AFC3ADC797E6977687DFF844 +:10C13000B1FA73C8FF2AFC8A56D58E54F14AFF4AD9 +:10C140002D294C6503DCE94218E5C2284719F63071 +:10C1500007FFEE9F1CA8C5AFDC0ED4EF69EA7CB8E0 +:10C16000C5EC3B1BC8110FF0BA518EE02420E879D2 +:10C170001BF9D875CC0AC4FA8C7C7B4DF7F45C357E +:10C18000FDD5230BE9579B807F87233FB0F3BE8902 +:10C190002450970572EA76C1FA1DF459DC8B45B834 +:10C1A000F785B8170F82FB5E5C583EA4E6ABB40D72 +:10C1B00025786E30183E9F02FAE9A1DCF669A0F7F7 +:10C1C000BC4B4829E8C11FC5B1F3030FA865BF38B0 +:10C1D00049D5AB856F4C82EF43A20CE7D5DB42DB40 +:10C1E0002C83A0DEC4E33D2ADE84FAAB60FCD6904B +:10C1F000C8E05A6C090C8238C85E11C76D5D3C01FD +:10C20000CF6576D86F21962FD216FACCB9284A9FDF +:10C21000B7363D7A15C4B9369A62E7A94CB19A7E11 +:10C22000D8FA1BEC92B737C5CAF2EA1E1A40E7519A +:10C230003DFDACBA0E3379B856A5F3AB4B6FC4F9DC +:10C24000BF14E26458478AF8DB6E1A46E739EE3DC0 +:10C25000418DCFB078E528F5FD3AD02FA85FEBDF10 +:10C26000E5E9C3DD470502E7F446D52C457FEB152C +:10C2700027E573CA17794A7024F06D612801EFCD64 +:10C28000F17E4CD0AE1FDD22E8F8334F5D57F3222C +:10C29000545EC044F950DF3E2E2218ECA0000FFC83 +:10C2A00075ED71FDF38556D5EE729214E0F30D979E +:10C2B000780EF25EDBDA897B0D85BB6D715F84A33E +:10C2C000ED3C9CFAA5E525BE38D67ABFCACAF8620D +:10C2D000A344709DD9B8D48EF1C5034B2BAE80F525 +:10C2E000FDAB1F7BAE88758E3C4A3FC5B37C2C25C9 +:10C2F0009E8C05FE5ECB31BCD7A797C6C8F7D7F892 +:10C3000059E36F8DAFD397C67962E5357E63657665 +:10C310005AC1D2219C04FEDA3E0E8FE3B6AEF15C28 +:10C32000F6DC8D9FACC90078BC4DE7D0EEB6843802 +:10C330002596BDB1C1EAC4FE5BD7F86B218FEF2E05 +:10C340002A9CA027BBEF7703FA5B3F81A02C7C6778 +:10C35000A92FC373BC4B2C640BC4BB85FAF45B1CC4 +:10C36000C0FF936F5847E17DACD484EBEB46D18D91 +:10C37000F0FBAB08C1F8831ACFED378D6C8E3ECF42 +:10C38000FC8435FF592BA5C7B35617D225C9E3E660 +:10C39000007EF73FFEDB09F2DD76D18C74ECABFA60 +:10C3A00043DA77AF5999DD36334ED90ADF93F26419 +:10C3B0009413B7C7E95E3C12EE4DA0788F92A34E5E +:10C3C000FAF9F1BB440FD571149E44BB09F99228C8 +:10C3D0008AECD2C529FD28479A5C903047208F4DC2 +:10C3E000D3AB5C880B3BA81C8CB2D8C3E0772496F7 +:10C3F000D3795310ACC4C2FA6B114E759CCBC63CBA +:10C4000079CA977970388A6048141271A17F4DDF1C +:10C410006A7A7A6D02417959FBB010A8A3FD6C12BB +:10C42000225688AF64297201A41A250A329E17EF9A +:10C430005F4E30FFD296FD784287DD42857EC4375D +:10C44000FC8258FB797C9C862FCF1F406FE41C6ACE +:10C450003F00E68DDBCAC673BF66413BBD437FA884 +:10C46000F65891BAFE8EFBDCC4F209C29348F43E42 +:10C470009B517F68F6C9B8EB226B60BF68DC9F18E0 +:10C480009CB45B05BE1BADCEB7439FA8EBE69810EE +:10C49000D527F4FBDCD0C866B8072BF76326C75D49 +:10C4A000F4C9213F0FF8FBBE7AC4C81723C2542E2B +:10C4B000D5F6A132DCA7E1EAA843FB1983DE499E49 +:10C4C0003E2A15ED5C95DF8C78D6E4DB28F7B9774A +:10C4D000BB9BCD0C2EE6471AC6215C271C7236E8A2 +:10C4E000A5B778B0F7DBF2291E285CBF02F9A3F4E8 +:10C4F0004B381FB801E6BF2174BD15E4E47BAF27BC +:10C5000021FA75549EF6D3BC273EAE0FAE274EC01F +:10C5100043F5FEF3EA7A12467A77C8019593E878F4 +:10C5200089C6FF467ED7E4A30E2EDEC8C673760406 +:10C53000D6599E0BE2653066B2C90578D5ECED3A66 +:10C54000D5BE25FE74B4FF56BB88BA1E6506804F63 +:10C55000EA44CD5E775BA2E353AB1D05A997DB4FA1 +:10C56000F55EA4FE59D4391BAFD08EFE9BF7A28492 +:10C57000CFBF37FE9A2814793AFC8D891BDD157FD1 +:10C58000F17184B0FBC2FE9F9FDF0C237FDC277715 +:10C59000CEEF5AE2792542F547DEAAF57536193F06 +:10C5A000399C96D7552F68FB9FDDE901A3BC8FA965 +:10C5B000AC6FC6704B0FF2EEB5A9F8256406E8B370 +:10C5C000F1616AB7647595FFF3EAFCBC3686F7B68D +:10C5D0005BDB07833CADE73D3571682F464C26B0E9 +:10C5E0002B7613B47BDCFB8F3A51DE5B9274EB4FFE +:10C5F00057BBC08FF2A9D9A79A5D6A7CAFC32E55ED +:10C60000D71B2D3ECA355179A1F03C19E7F1031C27 +:10C61000752EE6BFC20157D0634F583D75C05F36D7 +:10C620003A9738D82F1912CE62F196B04E3EBB938E +:10C63000479B41DE82143FB0FEF9E9FA3788EB1ED2 +:10C640009EB171090C5EAA85C0BEE99747D860D536 +:10C6500004F3C7FBE5B0FB6BFAE5B2FB3237C73139 +:10C66000FB658BA17CC25AFA18CC4B1488DF9CFB6B +:10C67000FDE10650210EF9649CD200F8B0142B386D +:10C680008F0C17717394DE19429083BC89C44A9948 +:10C6900063F147D2B9FF48FBCB2891F3813F3206C3 +:10C6A000123C379A118A7D9EE89538F187D9EB8D37 +:10C6B0005DCEC1BCA2CACF4189CE37A9849D83E992 +:10C6C00088FB50F001BFAD8E5B71B2AD17D83EABA9 +:10C6D0003F81E1D9E8BF01C1605E825ABF57228223 +:10C6E0003511FD2B3FF0AFDF6441FFCA46DC41D07E +:10C6F000B71FC4B1F8EC3ACEBD1EEABF10DA2D70F8 +:10C70000CF8F26379A3C3C34E116B7405F755E7791 +:10C7100036077C5F2A17EF009E5B279C1DBC1667BF +:10C72000D29EC9F84EE175F9F61AFD9A441DFDAC8A +:10C73000105789D6F30E6908D8EDAD5C9C1BFCAA96 +:10C74000D6E51C8397B3A8E71104DD3CD36CCC1F5E +:10C750006953F5E7DFE3B2901FB5F584CE6F3DC6B0 +:10C760007F0DF3E838876A38776A3C979A96DD112F +:10C77000074AC77CDC5209EE3223674336B4E3BC78 +:10C78000CEF64C12E3BC646AC41AF35CB05652BCD9 +:10C790007D0D784B156B12401FA7DECEF488111F5C +:10C7A0006D9C7FC441D847FB8318331F452BD3D2E0 +:10C7B0006E4A584CDF4F4BBF014BED79835D8819B2 +:10C7C000574CB2713FECDC6403B118FCCD241BED77 +:10C7D000EFB4E79DF71514FF768CBB37C431BC3737 +:10C7E000C431BC37481A3EE57890BFCEBA5B97F7A4 +:10C7F000B4C1674910200FD19F8EF2B9C4C5E8DDDE +:10C80000F9BE82F64D1FA2DC301794C406916C432A +:10C81000BE67F121ED7CC8AF7CCF2440BE94DB968F +:10C82000A5FAFB1646DF0406F7F90D5370DC14B2C7 +:10C83000C63A98E27969A9C90D71A3D30B3F72C2B8 +:10C8400091E985192D79200FA7798F1BE6974A98D2 +:10C850005FB86C8E1408D32E931BA8C26274BA0101 +:10C86000F73BCB4C31F3AEC7D8D8FEE9D138179699 +:10C870006969D3904E9DF59204F04B8C7C4AE53566 +:10C880007DF1A8CE73CC946F145B0C796B134913B4 +:10C8900087EB5B18F195ACB1B3AAB7357949063986 +:10C8A000847DAB52AA47353A0F505F4DC1B828FE80 +:10C8B00071A1D7BF067FC3795D01EA454D8EC810CF +:10C8C000A6E7ADA077A3E2A16D7B3FE80FFB8E9FAB +:10C8D000FCDB3907EC3BFD556877809E3D7ECFBB86 +:10C8E0000E38C7F4C93D2C2E7287C14F5B6463FAC2 +:10C8F0007F8FAD741EE07781EF1F799E287E2577AC +:10C90000B3FD93E501DE70DE5D7F6F505530C97079 +:10C910008F901FF15AA5DE1F66A4C7461B8BB72C4C +:10C92000DFB159CA90617C4F258C7F5CF5438F370E +:10C930003AD0DFD1E059B8638404BED95F4366754D +:10C94000FFBD4564EB875202FB671E156F46380F2B +:10C95000AAF76A2FF925CB8F29A363DD4DF5B02700 +:10C96000C4CE7B18E7B1E413B92895126FC9FD1C3A +:10C97000FADDF0FE3D743DF3DC7D1FEEB319E7D91F +:10C98000F55E1F05FDB3652ABD8DE76D9785D83E21 +:10C99000F862E241F9EC72FE36C4CEC518E38D6749 +:10C9A0000F65DB000FBFB0A9F1C43C3206CE6DEFBE +:10C9B0003A3420FE72F7569F52EF8B827BBBA13C2C +:10C9C000EE2358CE032390E2BF32F4F65DC05FD56C +:10C9D0004D3BF13EB4EFAA8FAA42279C904BADE9A4 +:10C9E000256A876E03F9208B399D7D5ABDF99CC459 +:10C9F000FC6A869FDBD4E7B7013E7220DF5BFED97D +:10CA0000044AEFDB2AC5F3D1F7A53D6FD3EFC3F797 +:10CA100076BEDA3CB5796BED556A5E9CF13B4D0E06 +:10CA2000E6A97CB978EBF4757D298AEAF67E91A9AE +:10CA30009E93C3F3421A9F2D23A545E931F849A3DC +:10CA40006F07DF847E8EF3D3E8BAB8BE4CC5833F50 +:10CA50004DDD4F4C837895918F7A3AA7DD2A463287 +:10CA600041BE8D7CD2DACD7D28211BB32F16CB4A57 +:10CA700011C4CFA8F9BBCE1565DF1C17EA0FFE1451 +:10CA8000E46E2BE3FB0E3D084E31E8F737455CFFC3 +:10CA9000573AE454B8FF0FE9370EF213CC7E784FC3 +:10CAA0001BE7984F51068A80FF622C4FFA4A958106 +:10CAB000833ADB976E3CE704FBBB6D08C1B851AB12 +:10CAC000430FEF691B8F7AE3B44A8F4AA1E59B3F7E +:10CAD00083CEDADA827917C72EA971A74BE6E2581E +:10CAE000F3B4D839DDBD7877A872A8F9350B54FABC +:10CAF000DD1162FBE90B374D477A74C9BF54FDA1C4 +:10CB0000B2460EF58E913E4BDCD7633EDAA2403E34 +:10CB10007EDF855EE441A4BB916E77DA5DEC1E3763 +:10CB2000A146827BED8E6DE270FF7185107BFF73F5 +:10CB3000B6DDF49DE6639C4777F02FDB5ABBAE2F42 +:10CB400081F98F9080CF8DF06BF35F4214A6A7D44C +:10CB5000F976372F1299C4F234D4757F399C5B81F2 +:10CB6000FD93077996CFADC6A134F835788DF328BB +:10CB7000E22BF17C415B038F79D977F8D97D067779 +:10CB8000ACE570FDED8E4E9A5ED1F67BAA9BCA3065 +:10CB90006FCB43FB013BB6ED63C2F629D67378CF6A +:10CBA0005BB7F40CB17CA5EEE84908A3DB624A3719 +:10CBB000F03FBBDE9F90AF0C8CDE270ADCA00C8C14 +:10CBC000DEB72241CC5759B17DBAEEF98D76358E5C +:10CBD000A5EAF59EE48FD424C48C6F69F2A6C99FA0 +:10CBE000268F77DA65666F0A81831959809F87D10E +:10CBF000BFA1FA7A9E9DF93D0FCDA5AF546F3CA71A +:10CC0000DBA7583296D16B095F82CFBBD3BB140F21 +:10CC10003ABDBDD8AECFC3F8A1F3D1E6A1C98936DC +:10CC20003FA39C18BF37D2438BEF19E962A407C01A +:10CC3000097EC65B7B6D813514CEB73806B77FAFF2 +:10CC400015E16E4D9BACC0B9CDEAF4F958FE013E3A +:10CC50004C07FBB0B4CE8E76AEEA878DEA5D5C22DF +:10CC600057B5CB5EB22A23D9B9A7D224E09389B5B0 +:10CC700091191617218F3E585C04F7A44E7C383268 +:10CC80000342F1BF7EF04656DF1679D7E286FBFC01 +:10CC90004B8A0A69FD71D02FA02FFA95DBE0FB6E5D +:10CCA000EBC473F9BACCDE1F652E9DCFEEB166EDF5 +:10CCB00095D43EB3D0F5AEF2F0E057417E2B5B4AFF +:10CCC0008A212E54091178BADE5529CEB02D87ADB0 +:10CCD000FBE3E97B1FD93C4FD921EE76712DAE8B5A +:10CCE000958705942F7288C567053A572BFD6E6DA1 +:10CCF0001CB593297ED7265ADCE017D3E77EF09740 +:10CD0000D7262AB21CF55CA31F7C0770AC35B17C1A +:10CD100082FD6F0C8E8F5CC62ED8EF2325E0CF34BA +:10CD2000FB2C581ADBF325179EE7C837B17889B179 +:10CD3000FD6DBB76AE49CE00BEA83E24A1FCC31F4C +:10CD4000D89F5584C9493561E7D0AA0E133C775363 +:10CD50007DA808CFDDC0B9844F757AE05F73EEA679 +:10CD600093AF189E0A04AE44881AB7D06ED5D5F991 +:10CD700054D310980FE1E3DC706E84CF30D5ECA271 +:10CD8000F3E7AFA025C587E072F370FF4CFDE4899F +:10CD90003CDC9F5527AA792D26763EBE63DD57E5FC +:10CDA0004F2BFB394A8F02DD4FFFB125CFC6F6531B +:10CDB000D0AFD6E65BC72984037FED3582E71972D1 +:10CDC000934933E0CF4694B1C06F1647A2CA976C1F +:10CDD0003F9BFE6540E9369B7E23537EFFFAC19F51 +:10CDE00022FFBBE34DABB2689D73F8593DC3742E6F +:10CDF0008BB230EFA865F56B4CE706D0BAE858C3A4 +:10CE0000EAB0F14A173EB3A3AEC83F14C67131BAB7 +:10CE1000EE50AE01FE164C2CAE231C90707F47CB1B +:10CE200057594B7906F8D1E2607A745D6DC173365B +:10CE3000889B172832E44FEC51EF41FABEA5865784 +:10CE4000DE66427F094AC07FBC83E153A30B69546D +:10CE5000AE813C5E1254AE817DBD7E0E4FA2837EBC +:10CE60003FF2AD9689A0CF1BDFF9280FEF73BF8289 +:10CE7000F533F22DEA43D2F99CFE6DFFCDD1FBE4F0 +:10CE8000FD1CF9A9F01D2503DAAF9CEC22B751393E +:10CE9000AC53882C65839FADF72F1B09D34F1FD947 +:10CEA0004AAF70A03E09E33AF613BB6700D48D7E0B +:10CEB000336949EC55DE9D947337EE172566347D52 +:10CEC000B810D685DFB17B4A3845C1FCD3173BEE9D +:10CED0006B231897B2913837C48D899BA4F953D42A +:10CEE000F89A89F155725E94FFACCE877E5F08791F +:10CEF000F2636C2CBF81CE8F07FD3A82C8588E84B6 +:10CF0000385936A0D883F53D24F8E14F69FF8F5892 +:10CF1000597CCAB29DE8E28F650E16B779C0C9E2A6 +:10CF20008F7162F016B02BE2CE1017D8156D8F4BB3 +:10CF300002EECF0BAE9B70DFEEA009E3DC4F8B015E +:10CF400017EC17B55F25C85B48677F6D2ADDB57E96 +:10CF50001F91E4AB20EEF70B27AB3F9D4F308FBB0B +:10CF6000FD841480FDDCC40C4B4D743C699E83D958 +:10CF7000BBBF7315CC043A04F7C611187FCCBE387A +:10CF800013D0E3B91DB956E08B170147140F89661A +:10CF9000D79DD05FE2390A6F163E67F9FD823C22C9 +:10CFA0009EE277FC8D7619EED17ADA1ABC11F3562F +:10CFB0009F37E1BDC12F4AEEE9507FF1ACEC023D55 +:10CFC000FC7456300EE7F3BC09E7F3625CFBD52B2B +:10CFD00029DC0F0C61F12EC14604D0CF82A940BEDE +:10CFE000933E5FAEF2B1A6AF37811CD1FA231CC1CC +:10CFF000730C82291FE548CB276A6B27984FD467AB +:10D00000660B0FFC1C375D8B3B857988174D2825F7 +:10D0100068CF4DB08B78CE05F299E1BCDB44550F5B +:10D020004FFCB8B284E507BB0FC3BD9ECD76F57E3D +:10D0300030759F7392CA27D791086FA1EDD75D24F1 +:10D040006E88274DBAA8DF8F78CA605F4E51FB57B4 +:10D05000DA5D85F0389FE8EDBF290D4527603D2C4E +:10D06000208A00FC34D96268073BD209F7F0EB9FB5 +:10D070003FE050FDDC4C92199DC7A6ED434DE18782 +:10D080006E44FBB55872035E76DA950F203FC0DF21 +:10D090002292CBC5259FF2B17CC321176D04AE2C23 +:10D0A000A4FC6987F95CDD50EFB7D2795F3D90F55C +:10D0B0000F7C08FAE5CAC7939340DF8F57E9A5951F +:10D0C0001ADF017FB9E2197FB98677CAE7D38E2CC0 +:10D0D0007C4F9337E03BE8678F18981F6BBF9BF23C +:10D0E000EBD3C0AF3BED04FDB89FA55BE6809C6928 +:10D0F000E3B4AA7C6D2CD7D5AEDC0FBFFBE4BFC078 +:10D10000D68DC2BE17A5E875BF4F0283D72BD7CFE8 +:10D11000980679687611F3CC52D47351D1FC921EE3 +:10D12000C52F1ADFB5DA599C48E39FC9BBDFE5E19B +:10D13000F9E40B84B8B24887BFA2F1CF447F18F757 +:10D14000812712E69F18F9675737FC937F5E1640D8 +:10D150006F75E19F438C7FBAE31BDA0FDE6B61E4EE +:10D160009F771CAABDDD2DFF5CC2F3FCABF74EBE62 +:10D17000EC7E65934F9F9F6A2CC7D962E72FBB5403 +:10D18000BCEF96EA6FCA01BD31D5C4CEEF0924E3E6 +:10D19000160AEFEE38EDDEFC9A6CA8EF14981EDA52 +:10D1A0001932A31EDA69F778307E9B6661E757056E +:10D1B0004F04CE23B8FB5AE4E8DF21D9EE6076585D +:10D1C000500C8FFB02ECF137181F8C9D9ACB432A31 +:10D1D0005AFA62A617461D9736C3EFCF3DEACCBF79 +:10D1E000007C9606B8A3DF798F4A78CF52F55109B3 +:10D1F000F5E36FF7BD5D04F1512DCF79CC9EB78B70 +:10D200000A86C2FB8CDFFEA1EA65AD8E4740405F17 +:10D210001AEEDD1FD7711E4B7F6F7E29F0514E67CE +:10D22000BBF13EF9601CDB3F994D6411869871B4E7 +:10D23000F45EB8DECC78AFFCEC303BFF36F3B027C1 +:10D24000F6BDF22A7F18EF37A7F6778A13ECEFE7DF +:10D250005AF6416884C86CDD0E4A35D7303FA326A4 +:10D260001BF8499343FCA3F80B7E3244F7BB06B787 +:10D27000A9F37FD02DB0FBA92212EE4BFE9CB0EF9C +:10D2800082EA3A36CAC9F440EEEA17E6039C23CB99 +:10D290009566A0CBB32E16D7F905095BB2816E6EE9 +:10D2A00001F75382A23CF90BAEF33D22940EB1D3A9 +:10D2B000F63D7DE246C2F88F3A3D639C609F09EDE2 +:10D2C00087E0BB31E37347821EB78F589B04EB9A0C +:10D2D000063785AB789BBD130E0DAE814EC6978F7A +:10D2E0003ACBC6001EE03BD04B4D478E59E07B8DBC +:10D2F0001F827BCF303E88E20BE0834EBEE01640BB +:10D300005DC383A2AECFB7FD8BF8428B6BF4C81719 +:10D3100010B7707E2FBE980B7835F205B5E73CCE7E +:10D3200018F65C50627993C6E73FB1E7E3FB6E897C +:10D3300060DE13D96765BF6BE849C07D90DFB8D860 +:10D34000986D9F1CCBA4A62859E56476BDF63B2AB0 +:10D3500023C21CDA9F23A8A2B80DEDBC7EA827DD4E +:10D360002AFEC8318E83FB4631373E03ECD0701263 +:10D37000D86B23CC256190875DB68919603FE6DACA +:10D380002664C3FC5F1EB2FA4D58D25EEE5BFE9B74 +:10D39000AD72A77DA5E9C366B55B6DFC352A7F4CF0 +:10D3A00052D87927D0EBD17068EB039009E0E0C246 +:10D3B000B34DDFDA508F8722146F93000E8A87FDFA +:10D3C0001C6904FB21DFA4244F063BB04F580038F2 +:10D3D000DBF67E9D09F1CE92D0EB1F02BC25DA3E32 +:10D3E000AC5BBF0F6BB4B7357B48F33F347B49F37D +:10D3F0007BC1AE82F632D51F7199D9BED884B005F3 +:10D40000EF5378E4AC7C95A2CAB340E751A2CEE3D7 +:10D4100066D2827069F7A94C53F1517288FAAB3920 +:10D42000D04EC8548A87A9EA7D2A53DDFAFB226EC2 +:10D430001E1BFB3E15AD9F9EDE37AE1BD71AF6A313 +:10D440007E6879C8C7EE4FF9BD8FF9C3E307F07E58 +:10D4500001D6DFB159ECFE0917C3C32129F63A768C +:10D460005195EBF1A6480E9CC7DEBFE7EFB86E1EE4 +:10D47000D8F3F7F7C18E1C77422090973BFEC4A8E3 +:10D4800078CC0F182B235F69FD7A3F6FB411F69C9F +:10D4900044FFDECC410A8F7225C067C1F295538FDD +:10D4A0003C0AFD9D3F2A90E8731F45926720C4E522 +:10D4B0008BD4DF1D3AC8317B4A6B3FA8FEDEC71113 +:10D4C000956F212143BB67C51C45E7A9EAFD1F1ADB +:10D4D0005DA71E2F3E21E474A50FFCFD33E2105A18 +:10D4E000FCE19CAA0F49F39FF07CCEF58D770A6092 +:10D4F000BF5F9FC613256ADC1B64EAE947C5214E5E +:10D500003A0DF66FF3338F4E83BCE5B7784C81F458 +:10D510008676BE9903F5163EE6BD2A46FC5E1FBA26 +:10D5200013EF55991BCFE4A3A7F1C75F4DF96438FA +:10D53000D09D303B308FDD4B62A4EF813DFF9114D5 +:10D5400019DA3DBEBBA3BF910EAF9C2AC07DAC9E35 +:10D55000E861E4DB7D749EFE2BE177532DC48FBF21 +:10D560009BEAC2FAABBE34AC6BFCEADDFB6412D8BA +:10D57000791A9F4E49627C336EF7A349C4DE492F66 +:10D5800023DE86C533FE7FC9AAD925EE59D3E8A389 +:10D5900077E93A848CEA272D903756AAC23AFB7075 +:10D5A00011DA25443DCF625CDF66F3B74D0175DAD1 +:10D5B000D3EFFECC94CB7AF57B39C56FD50BB00E8B +:10D5C0001609AB991E53ED780D1E239DDF23A50888 +:10D5D0007F77F019F9C008E74B1DF9F60AAE07DAB4 +:10D5E000EFE0CC18982526C69887868F9984AEC719 +:10D5F000D9BD5F8F6F8CD7DBEFE78E17FE11D0DAC6 +:10D600009DBC19E9666CD7F447110C908BA51FECF3 +:10D6100093B9F12948DFA28B1251E83A43FAE9CFD6 +:10D62000F593922B91DF56B9D8B3EEF8ADFA224FAD +:10D630003C233BF94E6C7AD8067CB75BA8B7411CFB +:10D64000F53AFBF43A10BDC2CF0B66E2FD1511139B +:10D6500081D0DA94D099668833783F2478BEA120AF +:10D66000B47F32F0E9AB420BFA596DE7097938CA59 +:10D67000EE6C0AD5D9C02E6B4A66E7F30E26105D14 +:10D68000FEF4C578A66F9A8E9E9DA6C4681FEE62B2 +:10D69000FC3C8328C939F49F45EB297F801FDCC7F8 +:10D6A00081719242CEFD5A32D82D7339F423DAF6C5 +:10D6B0008E792D99C2DB7A7B02EA99294DF7DDE953 +:10D6C000A28408FE63243E6F2FE3F0FE8422D98DEE +:10D6D000F5A2C559E8F78DF926694609B4DF20A2FD +:10D6E000DF3385AF14205E753A8DC3AB3CF6709185 +:10D6F0005AF83D62FF74360E71F993C03F7DA7243E +:10D700006904FE669EACD507E1EF2E1283FFB6FAE0 +:10D71000A573FBCDB47DF52C0EF38DA7B832883FF1 +:10D720008A7F8AD64B38AF5B42A905C0D7338AF5CA +:10D73000E71EC3AA3D39ABD44602D1FBF99C0BE5E9 +:10D74000FAA0B5FD56FC1DF1BD2281F969727EA3D8 +:10D75000CAEFB3E724E9BE9B4E98DDA9C9D54DAA0F +:10D76000FCDDA8FACD733D19BAF14B09B387FE4031 +:10D77000DA0B8164F7B8D87EF4B4F696C3F3E125EA +:10D78000BEDF68D087370D31F8BD7CE55AE48B34B5 +:10D79000CE8DF7C8B8F5ED378FD5D78DF26BD40F96 +:10D7A000B3208B8FEFAA27347D306B2F2F423C683C +:10D7B000563EC533DAC57ABBBD277D3126AE1B7D0B +:10D7C0007149BE17CC902EFAE2E3E2EFA52F7E4B13 +:10D7D000DD96B154AEDF8E57D7CDFEA43FE88D293C +:10D7E000FC8E47818FDAE8BA698EC147DABAA3C5E1 +:10D7F000018AA81CA31E38C5F663A65C4C27FE91BF +:10D800009D71800E3D42ED12770C7BA9353E1BE5E4 +:10D81000AB43EF687A25CA2E11F37EB85D3285DA04 +:10D82000A3522EC0D70FE12B52EF252982842B88DB +:10D830001FA69DC1389057A0FE2CAECF4F227F81EE +:10D84000FEE3123BE5C368AF6871E80A97664FE9EB +:10D85000F9A5231E3993DDC3AAF14911E013E47F32 +:10D86000268FFB04FF1BD47F03B300800000000061 +:10D870001F8B08000000000000FFC57C097854558C +:10D8800096F079F55E2D495592AA6C148BF012B67C +:10D890008424588480EC165958A314A080CB688146 +:10D8A0000B6B129A719CEE69FFA642024343B78349 +:10D8B000D2DACEE8F457D83A831AB40801039DD0DF +:10D8C00015504C5834082EF8D91A6D1AD10E4984C7 +:10D8D000D646BBBFCFFF9C73EF4BAA2A854DFFFFF7 +:10D8E0003FDF9FB47DB9EFDE77EFB9673FE79E97E3 +:10D8F000DB9B55B3AD08E0F6998A071400D0F177A9 +:10D9000022C042E07FC3ACAD16F08EC7BED7FC6923 +:10D91000870DF8E73BFC2F9C90FC2CA450CF0B907C +:10D9200009B054CE5FFC577D333D5E3C277AFE52F2 +:10D9300098FDB9920C701BF8CD301CF7F3C58EFF23 +:10D94000EC4B15C7972E8B7E9EE94C4ABF9087FF04 +:10D95000180123BE5301CAD4BA9DB722BCDD275596 +:10D960008F554C33D1FE0F39C5FE0F35970C807C97 +:10D9700080DF7416A7F8B13DB611211C0DD0BAD1C5 +:10D98000C6ED71EC07F1C5EFE8E7663C9F05FC21A9 +:10D9900007B6B45221B701480518EDC4452760FF0A +:10D9A0002A9E3F0DC78624C0EF73245CD900AFE7E1 +:10D9B00098E704F1BDC3B85E00D70DE3FA015CF748 +:10D9C000C84627F75FDBE8E6FE0D2E446A06C0FA7C +:10D9D0001427AF372FF776871FDF5BE3CCE6E750DE +:10D9E0003EDA44F836E02F7B6A080410DFAF77ACEC +:10D9F000D09474802AB7E2B166F5D1014FE3588E16 +:10DA0000F3CB25BE2BB72A10C4E7E51FAE2B07C406 +:10DA10005F5733EE87F8A92A558336FC6749D363ED +:10DA20003B45DF0CD608FADE228E0233B516CD86D2 +:10DA3000FB2CF0281E15F7F13689F76FF52A411DEA +:10DA4000FF798B279A1E8763E8BE58AEB380FE0F1E +:10DA5000DF5B30470986719D0593A2DF5B7C75D63D +:10DA6000E7CAD8FE7CB498E83EB63FBFDC4E74B738 +:10DA7000E33F86C130A2FB958BA56F8D853EBAC56D +:10DA8000B6B1748E1DBF169DEF273A675C9BCEC65C +:10DA9000FB7F8BCE0F114E90BE70F41B8B9E04301B +:10DAA000BBE9071AD179F6558DD7AD32CE3314863E +:10DAB000D279FED459F86FB742DFFCAAA62F2DFE0B +:10DAC000826B9FE76FEDBF2245E7FD695F6F7EDFE9 +:10DAD000BEF33480C178CEF939D1F88DA56B2CBD59 +:10DAE00016CAF762E9B535E61C065DA013996860B1 +:10DAF0001CBC5F55198E6BD1AD972E16FF084F7E5B +:10DB0000FF71805FF3B9FAD693748276CD5720E027 +:10DB10003247C803F2752005E95BDE0AE14404ECF4 +:10DB2000968B733ED7A8F528F069C439E8E753838C +:10DB3000CE6ADFFA655707B2FC19FB966910B0147C +:10DB4000D2732197B1F055D23A23697E80F968CB20 +:10DB50002ED3B2109E63BA05EEF5519B28DA034E20 +:10DB6000A1071A9D265EB7FB2B9B096E0478E5F092 +:10DB7000806240F83C56E709D28B2133F0FB45C95F +:10DB80003ACFDF9C048104DC1FB4769B0FF9442B51 +:10DB900006C84139D306598235B8649D16F691DC22 +:10DBA000757B34A846B9BBD178EF48E02E40926C23 +:10DBB000FE7494A9268BDE0FB74FC57937156AFA24 +:10DBC000369CE2B2EA3FA0F1AE66AB93DEEB3EF8E4 +:10DBD000CF2D665AE72BF02084F05A3332158E4F42 +:10DBE000739883A437CAD493AA09FBDD3D00A48FA0 +:10DBF000A62D0B9700D26D3AB4D738B19D42748CE4 +:10DC000043BFBFD0793384DE1A88749A21E9344344 +:10DC1000EAAB926695F54649921A84AC3EFD74B320 +:10DC2000A4D18C407B490AEE3B43533C35D8BFF925 +:10DC3000AA16C58F2F933EBAB14F1F95C9F5BD3DAA +:10DC4000BA869601664234FF96350A3D54628B7956 +:10DC50002EED0FBEC97C55E68C1E9F42BA13F9FB10 +:10DC6000628C5E8218FB53A6FE35B903F1F08AC5BB +:10DC7000FBDE5484BBE7B4199EC5E770113B93FBF0 +:10DC8000E3A731C61EC5B6070F277A7584EB15E2E8 +:10DC90002307F50779F5B1D79E3FB6A3A7988EF174 +:10DCA0004ADD220DB2992DCFBA33FBF0DE0FBF92C1 +:10DCB0000EB178AD977ADEDBE87C8D8EDB0F8FAD11 +:10DCC000B3D89E97FC49D748F5FDBDF834E4E595F7 +:10DCD0000B895EE2FF572E0CF2B2FD4AD2593E0C80 +:10DCE000793878FE7222E951C4A7AE219FF4B86C4E +:10DCF0009E67999F851C84068E0A6EC3FE8524C18B +:10DD0000F7AF24F61CCF23BCDF62F23C4BDB68EBA1 +:10DD1000872F2A20FDB975D1793380E205E5872860 +:10DD20004F8AEE84BBB10DA03C11FF055221487211 +:10DD3000628610D0BE355E789ADA19D3F414C2FB2D +:10DD4000655CB3DD41EBE929C4F7F0D72B137D0502 +:10DD5000FDF15FBF117C1AEED3B0D1E6D3502F1C7A +:10DD6000D8E8E47EE34637B78736EADC6E3A91FCC2 +:10DD700043F21FAABC169F16A157E6A50AFD300361 +:10DD8000F50EC13503946000796FC623C0F2887226 +:10DD900010DCA410BDF03C397DF844FA5CEE88E854 +:10DDA00043AD563B2193A582E95E9867E2F7D1091E +:10DDB000083E9FD57F3ED23FAABF8CFC1684C3EF9E +:10DDC000F296B9B00D397CB35D88DF7A65E9D14B45 +:10DDD000C0FDB9F4BC5EB943BD84EB8F0FCF841F87 +:10DDE000A2BD188F8421BCE2CF5D04FF84160B1006 +:10DDF0007DD0B0B27C161AF2F9B5A25CC0FD4884A1 +:10DE0000BE1B8CEF59CBC3C44F07A0238DF05E64BB +:10DE1000F3D9497E97B9043F7895DBDD0AAE3739EF +:10DE2000C3E25109B4E1BEF1EB117F2D19B821CE47 +:10DE30006F69C91CA2E713B7BDF13EC9B7D7E608A1 +:10DE4000AB6C98CC9D1D11F67C003CE3247F927452 +:10DE5000DC7768475A3F4E0EB09EBB6A09925E6BF4 +:10DE60003D93EC09E33ED3AFDAD8BFACA717516EB0 +:10DE70000F27268F653D13420D43F26313E7986D1C +:10DE8000F6AF233CA0653E7A0ADFFBED6500D2AF1A +:10DE9000D3DB3F54C90F2D31E50EE840388F2AA35C +:10DEA00053A87DF2E3E47C6ECF2477127E0E9BECC8 +:10DEB0003AEDFBCE46BD7404F2CBA98D503A02F97F +:10DEC000E3AD8D366E4F6F74727B66A39BDBA33818 +:10DED0004EFCF33A8E137FBD81E3D46FC3716A4F5A +:10DEE000E03AD47ADF7298487E67BCE5D0A82DBCB2 +:10DEF0002B89DBFA3B932C748EC3C95067EC4FFC23 +:10DF0000144E0C378007E52ED5FD53DB0D683FAD71 +:10DF1000FE02651CC0D454F75C6D3AAE3B7BE88FC3 +:10DF2000BEC2F119A9C37E6A43786F3BE3683889A2 +:10DF3000FDD2C7F59F3A883F4F24A292243C64B794 +:10DF4000795136C793D218C468F7C224ECA719FDDB +:10DF5000ECB9A5C80A4B4A3AF2C005B0F3B1E17377 +:10DF60006D88DF2576FF3F51DF12689B533A9DFA9B +:10DF7000107092BC2BE620CBFB10257D11DABFADD3 +:10DF80000EFFC4D4087FC0ABFC218DF4C344AF02A4 +:10DF9000AE74A67770A4D2F7DC98B7D55136311598 +:10DFA000F9F7D72E95F969C234C51B74F4975F63EE +:10DFB000DE84F37A29D16FE2C559B5D42E98E3E215 +:10DFC000BE6FD94DB524FFA58E6BBD5FC2EF875CD8 +:10DFD00066D647C51ACE8B63178D79E391C9C8FF02 +:10DFE000EE694B0C3E4B7C7DD65F9384FD327756B9 +:10DFF000A12A753470DFB56B1B8D97BFDEC072E54B +:10E0000049F2E859C48AEDA569383ED3A178C22403 +:10E010002AD33EA94DA371A7E221B4CDF48E3B557E +:10E0200044E32354CF4CEA9FD54B9DD89ED1664EF6 +:10E03000BD84F366E7A4786CF8DE99F08FAE10FF2C +:10E04000CECC49F224E81417049FAEA4BEC7EAA9B7 +:10E05000D6E91C8F9524D33ABAE23161BFFED6923D +:10E06000FF457014FB52405168DCA5911FFBE4C7CB +:10E070003F2975E2BCFAA10A90FC9C09E7FE91E0F9 +:10E080009FD99AA8272040F5166729BD576F519C44 +:10E090009BB8EF2BA1F9815166FD795CF7E49D7681 +:10E0A000B607E56FE5B35F74F2CEC16C17CADF9AAD +:10E0B000564CED4993F0DBCBDF2A9FC3E326089350 +:10E0C0005229BFEB1FF8BD1D253F294DC7F54F0C49 +:10E0D00073B16E413A956A117A0DE78342EFDF55CD +:10E0E000C1F35B94013F3A8FF3AFE4A7145A71FF79 +:10E0F00059E90951F3E70C7145F5E78D1858AA4520 +:10E10000D8B1F2FCACA8FEAD454AE98888F9BE69F1 +:10E110000951FD45A5AED21111F36F2B1F18D55F24 +:10E12000725B56547FA669B2D01F1BA1BC54C87D38 +:10E130007929FB9BD9AC870A9D62EE1B387E3F8E06 +:10E1400017B6097FAAD085FE14D2A5B4AD88FD808C +:10E15000367C8FC68BEC528F05A0DD3D91EC80FCA8 +:10E1600009E22FF68B6577663BFA056389AE68B7DF +:10E1700023E02F7544DBF1FA44E127CC017FAD0B9E +:10E18000E939A7751EFB5765E9D54561207C46BF77 +:10E190001F0B372AD19D77131FB66AAC37E70C895E +:10E1A000D9AFADD4C17E8CF4EFE6C8B78C7D21E049 +:10E1B0006D27FFC63887B1FFB5CE33479DC67EE1D8 +:10E1C000DF3AD7AC9C85A5A971E15FCFFE4C2C9CB2 +:10E1D00079A9324F81FE15FB85ADA9EC2FE24F7A6C +:10E1E0003C3FC1F07FCA51CFB922F59C43495F58EB +:10E1F000706D3D67AC7B2DFFCF58D7781FEA54DE9A +:10E20000DF78BFF7B9AEC47FBE1BE727C5799EAEE6 +:10E21000C47FFE5CF4FC199A5EE340793E0E8A27C7 +:10E2200040783FA96BE49A959CF5D6525BF6A15FC6 +:10E2300023B770F6F9402DB5533B8327AD78FEB96F +:10E2400039AA4EF907C32FEA1767A50A7FE4F855E4 +:10E25000DDAEE3787D40B753DC51FF886EA7F8AAA6 +:10E26000DE0B73288EF40E37ADA738C49B872DF6CE +:10E27000EF4D15FA7E857CDF680FA9FE15047F85BA +:10E28000ADE351F2492ABFE9B1105F1C277F2FBFD0 +:10E29000BFBF775C0B3A68BFE38F041DBE087D7E6D +:10E2A000BDFEDE2262A60CE253C517A94F4A6C09D7 +:10E2B000BE48FD51E67445F5C793FF83EFCD760F59 +:10E2C0008C7A6FAE9E15350FFDD81CF2876A2C90A4 +:10E2D000A3913E35257AC8CF8BC5E3EFE5F93D0E16 +:10E2E00027B951604ED7557F1CFBE42911F88B7D6F +:10E2F000BE3D55C47383C89EE33A2752756E6B5575 +:10E300009F70E6D07F267E88ED63ACBA8CD6C3952D +:10E31000DDC4771EBBE90ABAE0F0D2E3F3E76A682E +:10E32000FF3DE34DFF381CFBC71E5F21FA534DFB39 +:10E33000B2B1DFFAF87DA27FA369BCD983EC19B82A +:10E340007F6E29F90BE9BE7F27FA759B1D5B15D4FB +:10E35000039509A8D7B0D54C0A14A6F7C5C7DB2D7D +:10E36000685F91C0C86C5E17D2C06E15F17465C24B +:10E37000D020D913ADD8AB13DE2A130C7A77649270 +:10E380009D87DA0951719DDD82EFE1FB6536FF0B58 +:10E39000826FC2C93AEAA5870E960D20FE3891EA2F +:10E3A000643CE4ED9BEA267D85F0ED21FBFEFF0158 +:10E3B000BEE678F0D59AC53E9DF57925648FF38643 +:10E3C0002179943EFA156A3A3F4F0821EFB0BFEE2B +:10E3D0007553FEB1C665F190FF7E42F2EFF5B6359A +:10E3E000328FA1DA051FA929A6F57BB17D5BF2CF9B +:10E3F00019B92F6ABEA10B913FC0D933745181E87E +:10E40000137FA86A610FF9E13DFF90E4A1F8F98359 +:10E4100044813F18D2F3D18FF1F97B77E779B6F1D8 +:10E420007381A765C1EC9A0EEC8FB3066FA0FCE375 +:10E43000A134FF4784873BADC191CC878EF549B4A9 +:10E440008FE2058E538CF80FE33CDD32BC7F5C70AD +:10E45000EDFDC1467665E9648177637FC4B18DE8DF +:10E46000F1DE24F1DC8007E1E8263E30E0EA8507B2 +:10E470008638398F0022FFD425E38B2E5A8FECA7E4 +:10E48000EA1079DC3F9838FF5245C28AFD7DE74D9E +:10E490001C0F1A79E02210FB4D3EB54965E003F8E8 +:10E4A0003B51A2965E695CCBF1FD84762D26FEF68B +:10E4B000B23D9D2ADFBFA9D55FE2A0F6FDE8795302 +:10E4C000651C3F09822AC559933B62C61BE77F46FC +:10E4D000EB4FBD18FD3C294DDAC3413028324FB215 +:10E4E00041C64D974F66A7101F6B182BA8480F8B7E +:10E4F000AEC2A4D43E3DD3B011E759499FDAB82D3E +:10E5000038EBBC8FF669DC880C3F9AF4AA9B5B431E +:10E51000EE0ACEC2BD3036621F2917061E2FBF2F4E +:10E52000F038AE23E797D3B06F6E354350EFC3C3D7 +:10E5300014892F0CDF38FEBB7CD1C1F66B62DB6225 +:10E5400095E4D9EA36811E71BE043D11F4087D6C54 +:10E55000CF498DEAAB929EB509D17ECA78B94F9268 +:10E560006750D47A86BF62D0F350EAAC56F263C6E5 +:10E570003B56B1DF9232293B6AFDA293D1F82E04BB +:10E580009F97E263CF87C071C0C4B35A947F32298A +:10E59000BC83F963D287D1CFA79C8FEE97A6C9FC25 +:10E5A000562CDDAE854F18FBCB69E97F3F3E5DDE23 +:10E5B000687CA6CD89C667862F1A9F039645E36BB4 +:10E5C000A03F1A1F83578D891ABF617D61547FD880 +:10E5D0000FA744CDCF428319D91FBE755ED4FC91DD +:10E5E0003B1645F5473F7567D4FCDCE08AA8F1BCD3 +:10E5F000DD6BFE2EFA17843644CD27349BBE87FE92 +:10E600003736FE4BD47EFF53F4AF8DA1FF56D2E7D1 +:10E6100013885EA8370BFBEC19B925A43F5D4D6F3D +:10E620007C43799B40B1CEF9AAC03CF0D4E0D82F0E +:10E63000549F427A6E30A2DA847AA3D604ABC81E05 +:10E640003C6A32711ED390F317D3843FF2629AC8AA +:10E650007B19787B1AED22D94155EA4373FA8E244F +:10E66000F253549309DAC9FE691ED61FE71C10BE87 +:10E6700019F7550701E7C54A92272D9888FCA8BECF +:10E68000A972FCA90EF2838EF6A4E6E4CE53849F11 +:10E690002B0E9B4E7CABA6FA0364DFF09CA1E7A196 +:10E6A000BF9FF3DE465849F196D15FE65EBF99E61B +:10E6B0002FBB7BE6488A7F7B9FDFADAC2C8DA043D0 +:10E6C000E43917C5F1AB0EA409FB67D813C37EDC90 +:10E6D00069D56B3AD03E8C53857D40BB71200DF1DE +:10E6E000F181F28859F86901339D1FED2ADF27B8BF +:10E6F000D021DF806D4A9FDDD2BF43E6FA203BDAAE +:10E700006F7D9300A33844F7F03DE31D86FE5D95D1 +:10E71000CBF8BBEC889E7FF9FEE102AFF720F690C4 +:10E720000EE72CE23C06FC17A55EFE42EAE54ED25F +:10E73000C711F9EB55BB7626917F7E2E47F8E3C6CD +:10E74000F3DF493AFF2E4DE5F3AFDD9DB0FE7C04CB +:10E75000DE2A42AEA87E55E3C0F591F9CDB5C639A3 +:10E76000FC8A46E75827E5A8A2B523F94E607FFE4C +:10E77000C3345CB772D7957B0ED0FBA69E4C616705 +:10E7800003BCDFD2F780E382A57F8128BFB633CDFB +:10E79000CC7075A689386109364EE4BB25E803B80C +:10E7A000A87D63DA2CE23F7C1E56B0BFA015CCA436 +:10E7B000BF16FAB3CC84F433E079673F1EEDCF691E +:10E7C0003AEF731BF8F87EFBDD7B2A92D80F34D624 +:10E7D00033D64181203FEF3D57C09C49799FE90ADC +:10E7E000FB17B89F8D9EFBEE1EBC99ECB0B1DFBB52 +:10E7F000E0BFF40EF2C522F0F0BAC6FA40D73411E9 +:10E800007AF9034B2F1DED44BF0D6DA630E585361B +:10E810009CB3F2BD4A7775CFCB0F239C1FAFF9662F +:10E82000BF82707FB4BCE7BF0EE0F33B9E5241470E +:10E83000BEF1D9FD5A7A44BC79EEFE2B2C6FE8AFBD +:10E840003CFF2429A597AC1E92930FD6BC342A32E4 +:10E850005E484E9F99904EF73B93D2E2DE6FC4C65E +:10E86000A56B883F597E75F64B0DBE5C2DF972C3C2 +:10E870000BA3F9F986A4DEF388FEF32AE7C1363448 +:10E880005B39AFF18EE487352F7E333132CF578F2E +:10E890007CA95BA975724BF7A63AFA09FB4E5E1E7E +:10E8A000CB71ABEACFA2731EBEFA6932F5F7BDF9A0 +:10E8B0002D9F076EBB3EF8BB11799178AE4AEA797D +:10E8C00097F44AC501AB4EF9AC9203B927EEC27E6C +:10E8D000652BEA1F3CCF2557C7B1A7291E3BA800CF +:10E8E000E5B72AC309ACE42B1B9420E5C3D634EE6C +:10E8F000DD3218FB6BEA161611BB56250B7D5659F7 +:10E90000AF0437B11F3E87E95C2865A3E450EEBF32 +:10E91000E5E378D771B1FE858DB0F63CC69D5DF517 +:10E920005F5E2038D6355A39CF7621296C198CFB99 +:10E930005EDAAB84027A9FDC76B9441CB62AF4987E +:10E9400085F65DF5DCC211E436761D386D213DB9E2 +:10E95000AAE1B159F2799130FF41968BB5BB9595FB +:10E960009179ACD5E80E42A4FD42F80213FBEA40CF +:10E970004E49FA2C6B1A5E43E842BDB6FF6985F535 +:10E98000DA42E2970F0EEFF9DD6F68DF83FF3D9209 +:10E99000F15F747DF8075F80FD8B4AB90F5C3C63C3 +:10E9A000A1F8B2B2C17C21DEFD5263BAEF1EDACF0C +:10E9B000888F63FDEE2D1610F73FD9107C9EEC82F8 +:10E9C000A3C7B21CE1F9579A80F068CE1ECB0AECBF +:10E9D000DB48CEC85EB81DC17871F5BE748DF18478 +:10E9E000B1C4FA78F7A021395EA27758289F57E979 +:10E9F000EEB4105F57863F17F7FF8D9FCCF2C689A4 +:10EA0000B75F4E57A4333F274ADE37648C61B93075 +:10EA1000F7DAC3908DE5BE60450FD9A90D07913B8C +:10EA200014A2B7BF87E00EEC4FD0E97C25073E9FCC +:10EA3000D811B1CF1FA57CF4E6595EF964AC99F00A +:10EA4000B9EF93B15A52DFF3AE4CC7AA78799997D0 +:10EA5000D385DDDE9CECBB182D07099E30EE5BD91B +:10EA600064E77B1494832D2D45917270C7AA5DC411 +:10EA7000E74DAA0725022A1B17FAAB797E9287C8B1 +:10EA8000A336CE0C101FAA4E1FF327FC15F79B28A8 +:10EA9000EF8F50FFCD4DF73F4D72AC396065641E6E +:10EAA000A4D2D4F1AB1685E8BAC36BA2FD0A81F5F6 +:10EAB00096EAF075703C5594A953DC7B74C22C2007 +:10EAC0003CFDBC59E1BCAF39D5BF358BE87B5CE57B +:10EAD000F996A32F04E8BEBB6B1C14117CC6797F8A +:10EAE0003E2E0C2AAEB3B9003CB4EDE6834BDDC438 +:10EAF000BF3FCF38C67E86DD1302D22B35E83F50AC +:10EB0000DEC79E1F0AD33A0939BE2215F75993EE84 +:10EB100064BEB458FD1ECA273D20FB36CDB78AE03F +:10EB2000B3A5278AF87BC8F5E5F9BA48FECD746F1E +:10EB3000E9E77C4B9759F069D70DC07122D7FC4C9F +:10EB4000A6212FE3CD063BB8AD6A54D646DAD744AA +:10EB5000F0DBE879D7C1A51E82DF9C2DF93D33910A +:10EB6000E52276FF8F889FA9CEC0B4626B16E1992B +:10EB7000F0A6F79FF7A1E47B031FA0F973485E118D +:10EB8000546FBCFC923FBDF82CD17573AA2FC7956A +:10EB9000CFD7BCC2297627C6953B9CFF01C9B731A8 +:10EBA000BF95F089EF6FD1FC36C2EF51895FB3C5D5 +:10EBB000A73B59FE7D3AEDDF7BBE41F1CFF78D3C9F +:10EBC000DF966CFFF79EEFCFF27CE654E4375A2FC6 +:10EBD00019789E39391820FEAB4D82A24DF8F8A85D +:10EBE0006B969BE46ECB916F8692BCD72679DC4006 +:10EBF00079B1E69B9691DC6F197427F3FF172FE428 +:10EC000016AA11FB24A7177F45E73B2FCFB1C5E21A +:10EC1000CFA1737C2CCF699C6B49BAEF2FE911F916 +:10EC20002618927E5DFCB3D7B8D794719E47DA61FF +:10EC30008CF3388FD80D895C7FB657FAE11AF898B3 +:10EC40007FECE0D1D9BFF2C209AA2BA96931C13644 +:10EC50003A3E25B522EEFD925593110C7A6D18B20D +:10EC6000D335348D3B9FD839AF16E13E080155F8B6 +:10EC700069D1F90CF02A5E25328FF1DA9AEBCB6379 +:10EC80003CE3AF21798DCD634C0E9B965B52AE2356 +:10EC90009FF1DABCB8F98CD119D171514186CEC03F +:10ECA0008572047F86C28941913783F194BFEA2639 +:10ECB0005B85E39FE39959DE95AE1C9B0BEDE0135A +:10ECC0004F6CDB3A0DE57084C003F56B88C9F5F134 +:10ECD000EC07F5E6475E1BC37E38EA3D95F3024E2E +:10ECE000094B0C1D8BD07F1341A5272ABF123EF67E +:10ECF0006D32F1DB9E54FD2DA24F4F9BCA75280942 +:10ED00005A87C51547EE0E907F8076E09F33843E8C +:10ED1000B7358A7B4B9BEE653D99E0748E5323E4B7 +:10ED2000242F43D8A58A631F0CB5A02C5D329D4CBF +:10ED3000CEC7F5D7EDAF4FA634DEDA736F4FA4D24E +:10ED40009F3B35FF820C3CFF17CAAE5136F25BB7D2 +:10ED500006C7127E42E16CAECF2CD020A015F687FC +:10ED6000A7EA293C14BA04954FA5715BD0347E25DF +:10ED7000F15F55589C97F630A38ACC6D54B8DFD517 +:10ED800058934AEB55FDB67910E9AF9732849FF35B +:10ED9000E2D53CF1BE061ACDBF3FC325992A68A231 +:10EDA0007CE34B324FD97555E579C6FE058D335559 +:10EDB00027F2417E78C711CE8B365975A26FC27388 +:10EDC00020F0D194C07E68D5E1D94076AFDB051E36 +:10EDD00005C7F724F67C44FCD0D36CD5E93E37C197 +:10EDE000B9035271FD3DB21E2C1719B6DED1F7DC06 +:10EDF000D82FA1E997944324BEE07BE5046D074C2E +:10EE00007744E23B49D859C9577B12C326BA67E910 +:10EE100041DFEF5986AB0F4EE07D0D3873D90EEC14 +:10EE2000B1F45CF8713AC3E5243EC8050127348D7E +:10EE3000D649AF2638BD7C8E04A7EE0928FDE1AA8D +:10EE40001A8B8E20CACFA3A4CCA6F4C97755625FD3 +:10EE5000DF86B2B0271BA4FCB76E2B9D16D9478561 +:10EE600033A9EFFDFF78E2F8B6DA219CFF0BA84842 +:10EE70007F3BB649A9744E21572812DE8C42810788 +:10EE8000AA0BB4DBC478EF7CE473472ADB7F9EE7F0 +:10EE9000B13AEDF3B2585EF87ED1F00F1F52C217AF +:10EEA0006E46D2763EE64BC9C773759A8E3C5C8738 +:10EEB000F3FEB83C342A8CFD16ABFF79E2CF573F06 +:10EEC0005CB1BD80F4EF1EB3A79CF44F47E071F630 +:10EED000CB5F34EBDB22E40E86F46472DD61CC3E62 +:10EEE00055E7363D4EFE76F74145A7FBF46E73CFEE +:10EEF0005082BBB2E9330BD563561DFC84FDEBB2E7 +:10EF00004CFF5EDA6F526335D7CF4D861D5C3F876D +:10EF10007A91EB20436EA14F2E9F1DF56C75041D59 +:10EF2000DE93F2063DFE6164BF9AA4BC1EA6381CA7 +:10EF3000DBFD2D770CA7F5F7CBFC80F15E351C19B6 +:10EF40004C78DF04AF716B3CEF0E6A5CBF9CF7AE90 +:10EF5000ED5E6FC4FCD352FE4FCBFD5667FADF2047 +:10EF600078D7B67C6AA1D2C2AAF3A1A114F78634DD +:10EF70003DC519478FF4CA6F8C3C55693D169A5FA1 +:10EF8000751158AF20BD6B53907E2FBDDB386639AD +:10EF90003EDF8F3449213B8BF12AD9E3FD66DF60E8 +:10EFA0009A5FFDCED763498F1D2420F07F5F37AF76 +:10EFB0001D467843FE2F4E2439DB0BACD70C39CDE0 +:10EFC0002739C5F7F389FF8BA89FCB7A798FA57D69 +:10EFD0001ECBE57E13905C22FFB33C20FF3BC9DFD4 +:10EFE000CB77A23CF0FBA359CEF7B49BBCEC37A384 +:10EFF0005E1FC9FDE2C5D4DFD35EEA6439A73A8457 +:10F000004292D7F0115E270440D7F2450AF822FD5C +:10F01000FFBC8C64712F24F1393943D883508E9E04 +:10F02000E2C173D855354A3E22ECA5E84B7B5A9A8B +:10F03000F9976DBF98465226ED8453DA49FF78D68A +:10F04000FBFF286DD586D7A72CA8C3736E38A5F211 +:10F05000F86119F785259F1C91F91AB21B7A9AA8B5 +:10F060001FA6E713B04FF5E513BDEB4BC81C4D9A37 +:10F07000B3E328B5537CA11272DBA62D6B3F6A1651 +:10F08000629E47FCD770646E1ED5E3759FB3420243 +:10F0900082D8F06DCF472F221E1E3E8CF88F63A7BB +:10F0A000F038CC7FE87F0D0677FFF16E45EA91409E +:10F0B000D27CE2C7AE06B5AF8F8054226353DFFD2A +:10F0C000A47D7B006DE77F677A0767223ECF0CF057 +:10F0D00073DB7DFADB4C12CBFD67455CDF60F1E64C +:10F0E00011FF346463A81B874FAD9922EF536485E9 +:10F0F000B8F79C37670A39181580ED0AC7EBAA33B1 +:10F100008874BFD4A07A2DE82F5D84C092A9A46F23 +:10F11000645EF701903F5EFC45FA3C28BB0F90DF30 +:10F120008276EBC15FC4D61178D96F31F25800EB0B +:10F130004DC45F2B9B14F80FC4C5AA67A2E7AF9319 +:10F1400075F2AB1B771D1B8C745DF35CCC38F92D0D +:10F150007CFF11E278785D5D743DC3CD99D27F1953 +:10F160000EC3C97F41BE623D61D6A0D58A7CAC602A +:10F17000144322F69249E00BF52BCB67BE616F8AF0 +:10F18000855EEAB9045CA794BB3B7494EA81A6D47B +:10F190006579688F299A189FD29825EEA7B4A04A5E +:10F1A000750C93BCFE59EC7707BC67A9DE6495D457 +:10F1B00097E0C45FCAFBC8D3AF92FEDDEA606C9DE6 +:10F1C000A8C053959C37198235B4EFCADDA2DE6919 +:10F1D000EDEEE8F955124FEB9E3A7D8CD28515A1E4 +:10F1E000987189A7AAC6983A16B138DC9F29EFAD65 +:10F1F000647DFBF5D65BFCD12CFC8DB7E53AC6F8F7 +:10F20000E64C91EFADC463107DD705D520F1D12A2E +:10F2100025902CFC5E702CC7F3DD67B081ACCFBDB0 +:10F220005FE2E93EC93F7C7E7CBFE219F17DC5FD0E +:10F230003F8B867F0DF82C83F1F9830D3FB050DEB4 +:10F240003196DF56D599D9FF5D23F113CB5F6B7AE9 +:10F25000F9678785EC5B2C7F55FA956BC02FFCF620 +:10F26000FF5BF80D3AAF91CBAC3587393FB5F60966 +:10F27000C543F9AB6B9DABF73CF27C7FEFB99E3594 +:10F28000E83D06C630BDE7A45D17BD63FDEDBD9644 +:10F29000DEBC26E7052FB766733EDDE0ABD87566AA +:10F2A00049BF7DF653C27FBDD4586227FFA3FBA49C +:10F2B000C9A3E89CAF4C2EC0F38F6F5681FC91EE32 +:10F2C000A6E13B03087FE1A9A2C5945F1F7F0AED79 +:10F2D00013DD07B716FD5702DF077BD248EE67B68E +:10F2E0008D48FBBD83D761FBDE7DB2706739E9E9EC +:10F2F00093A545B4AE82E3549F5E28ED54F5C94210 +:10F300007B4784BDFA4DA6C8CF6F71FFFE518A1BA3 +:10F3100066EF357B283F32DBECDF9480F015BEA032 +:10F3200078AA71B763ED479EA47551BE28CD8AF3C4 +:10F33000FEE9088D57ED5118FEEEA6B2BC3D643FC4 +:10F3400083AA87EC6277D37DF90F921FD4FC40FE2D +:10F350007D11FB1D4B15FA66F60D66B6D79D83EC45 +:10F36000BF2EA7BCA87717EB8DCE43FB2CFC7DC32B +:10F370001E05DC78CE63EEA32F131E3A0F9CB65009 +:10F380001050D270DAD211477F1BED250CF3C29CCE +:10F39000AFDD61E1FACDFD7FB0D0792B9FFB84F327 +:10F3A0006F6B287E203FEF1995BF773ADAFCAA856C +:10F3B000F8B4B24E81015991E3661E27FD4AFDCF94 +:10F3C000EA849E36F87F85E47783FF0D795821F52E +:10F3D000DA7D5BE3F3BBA1FF1E04EF9641B8DE03C9 +:10F3E00075CBB90EE9811DD1F35752FC7A23CD17A5 +:10F3F000FCBEF2A9E8F1D5BD7C1E60FD1FAB47BF86 +:10F4000033F47F2EE4129F5F0EAF18A6A13C7D7DE2 +:10F410007ACD308893AF3C29FD06C36E5F0E9BD832 +:10F42000EEC5CEEB6ABC62217B5BD5FA27F673672B +:10F43000357DC9F4286F6AE17AD95BC0BF8EF07957 +:10F440004B93DD49FE767987D003F39AACC1A04295 +:10F45000E3A15AA273F761F1BD49E090C2FE1648DC +:10F46000BDB852E275A5C4E34A8CE306537D8C8C8B +:10F47000E32B65BCBE3A67D7312A29A994E3EBDABE +:10F480008E26131EE781D05BF342426F19F431ECF4 +:10F4900050ACBE400B770FD1776D9395EBD6E74B11 +:10F4A000BD35BF0EF596D25F7F740FB48BFCF17E35 +:10F4B0000177ACDDAD6C889EEF1A20FCD8CBD27FF3 +:10F4C0002E1C104D97F21EB0537E7F9EAE7A82FCAA +:10F4D00056BB46FBB78E457EC3F55BF5E129F1EAE5 +:10F4E000B58CF64D191718FD059467C3F921E70E81 +:10F4F0004764DCFF9F03847FB366B21A20BA46C418 +:10F50000490B0AB3E2C6497309F43786DCF7B371D5 +:10F5100091719277D728E2B77F75EF2CA7BAA6AA88 +:10F520003AA12FBA26E1BA29E4F703FBD15575D6E3 +:10F5300020C53355C82FFC7D1AF109C96393524683 +:10F540007C8271C6EDB4FE42BAEAC4F32F6C44FB70 +:10F550008ECB2F2CFD92F9AB6D843837E26D40BC19 +:10F56000B8C388372AAF0ABFD6785EA97570DC5158 +:10F57000D924EAB51B8E7C33340BE1ED6EFEF3D05B +:10F58000E5544F3E40D8E786E2D0A75457F4F51E25 +:10F590005B5CFFB557FF2BB52C0F95E68E4CF66BD9 +:10F5A0000EA21F7913EAD1B7BFE038A5E148C2BD6A +:10F5B00094CFEB5AE11FE6FC1E3A55C326F683377B +:10F5C000412DB7E41F45FA8D2B9DA24EE941693FBD +:10F5D000A9FF08F2F583387746617FF937F449854A +:10F5E000E4EBD510D83255E9AF072AA4DCACCDDF67 +:10F5F000B585AEF663FDA70A294F1831B0BD8CF56D +:10F600009FFE33865FABDF4E64FFB8BB4D7552AED5 +:10F6100019F1FBAB41E427625C901D275FFB85E499 +:10F62000CF4E797F5C3D4965FC99268BD6F0B710AB +:10F630008FCC37DDA71D41B26F79875FCD263E584D +:10F64000BB3BFADE89E8E8E7BAB1A0C84785EC7CA5 +:10F6500017658CBF74F8D531C46FD56F7F3B4AD026 +:10F66000E79B5196F46BC367B48A22E2669322E269 +:10F67000E6FD5A4732C56B5507555F643DBF41EF04 +:10F6800097A53C8126F203F50374E6ABEA26C11F79 +:10F69000A666D1E2FE4B447EC8CCFBF71B2F46BECC +:10F6A000F91E7B060417F24095B987F9AFEAB489D1 +:10F6B000E1A93A7D397344C47B015A7700E9BFEA76 +:10F6C00075C0FAC40EA46FE7D3F791D89FFF7E02EE +:10F6D000FB61C7B2B7978BFB2F15487F3DFCF69AAD +:10F6E000D191F660E200712F0E840737793FBF1089 +:10F6F000FB4B3C6C824532BF20F879AF8C9B302E9F +:10F700007B73409CB8EC7AFDE9EA662B50FEB9EABF +:10F71000032BD7197DDDBC92E37EB8EA1F4DFA06B4 +:10F72000FCFE1BA97DF8F0CAD1F4FCEBC3AB6FE47F +:10F730007CA9B2292ACF1120F8DCE45F7DF5EE5DCB +:10F74000E47FB669EC9F14B69D7D97EE69F7359816 +:10F75000F9DBD18AFD13760692C8AF2A9C4FDF11E0 +:10F76000ED6BD598FFD0DF32FC2B3BFB57A78AD837 +:10F77000BFC2757C416E8B4E94D3BAA78A8B689AB0 +:10F7800082E3A4D7C6937FE5E8F3B70C783E93F8FD +:10F79000EC6E49E0BC8B02D982CF604414DCEB1ADA +:10F7A0005E67FF645DA31AF5FD88F1DE5F06887B66 +:10F7B00087EF0C3E0B295EE6A3BDA25DD7B82F9361 +:10F7C000CEB1D61C623EA9AE338BF13DA205BA077D +:10F7D0009AC01F4107083F27E811D2659E2538844B +:10F7E000FCFABDBDF78AB22E2428EAF56A5A87F3DF +:10F7F000774C975BF7A5C7B34327E99E071DBEE388 +:10F8000059221E8A1DFFAD5BE4418E9F13FAF1F869 +:10F810004CFFE8787A3200C5225FA048FA3588EFBD +:10F82000ED63E735D37A78FEDD4302C7898F3BF776 +:10F8300026F0FD63A74BE4754BEADB34FA1E666DD8 +:10F84000833281ECD2DA9CF7F87B19EC17919E5C3D +:10F850001B3EC8F7AF15757B6779E3C0B1DD2DECB2 +:10F86000C33CF99D72ECF87C397E063C19329EDB74 +:10F870004EF73E67CACD4EF1DD9BF8EEF556A9D79F +:10F8800017DF62663FEA0CE866717F22EE391648A0 +:10F89000BD7DABD4F7B1DF631BFAFD76B9CEC2678D +:10F8A0006033DD73C47E9F7DBBF40F178197D7EF64 +:10F8B000F75DBDF41363FFFE42895BEAF551308AC0 +:10F8C000F47A08ED0DD75BE426B0DD9E5F3032AEF2 +:10F8D000DF41DFA9EBF23B756A0DFA57E7BEC7F6C9 +:10F8E000F078CBB997F9FB867309901DE79EADCFF1 +:10F8F0001E1A7AE436417779EF51E114301AF4BFD9 +:10F9000084115A647ECDA0FF83920EFFC7754539DE +:10F91000A045E6630EA9FE07DD195447DDC9FE3890 +:10F920009E80ED219E6BA83CD7506B849DBB3470AC +:10F93000795C3EEE3B5F6A40D893746E5B72ADECCF +:10F9400037568414FEEEB0220CA27F9BC2F9CA5136 +:10F950000D2D5CBFB1A454F178855A3C4BF0197C55 +:10F96000B4C026FC03835F7AF125F988C6C95FB865 +:10F9700055FA0BB1FC341ADA67D1FA4BBD8A87EA23 +:10F9800036AFC947CBC6BD4EE1EEB5F808F9D24C4B +:10F990007A31969F5E73FB1F25FC75B75F5E5280C0 +:10F9A000EB1FCFFD6C28F14FE535E4E84549BFDD9D +:10F9B0008EC071AE63A9977504F5B98D1D849756F5 +:10F9C00060BFB2D3D5BE6583F0B7B98EA0229CC00C +:10F9D000F5A5154D76FE6EADA2A13A710CE9E326B0 +:10F9E000D563C77E79C3E952CA239417893A972A07 +:10F9F000BBA8BBABB28BBABBB9E9FEE7DC13F8EF2F +:10FA00000344D711583A7EB5E17BF83E56DF359373 +:10FA10000F37E17F4E0F354BFC6C68BB923986C4C3 +:10FA200034DD7F88E0EE7EFD450B7D8A5135E6D5DD +:10FA3000595482D6ECD679DE2D752DB5945636E024 +:10FA4000B7BB9D42EF9A8343D86FCDBFBE7A9BEA86 +:10FA5000836F8C25FBD5D5D236D612C1EF9D1B50B6 +:10FA60006FC7A1633598A41C6BDC2ACA22E9470939 +:10FA7000B9AE6A3E9A49F98B4E92E77C6ADF491E1D +:10FA8000816DC5DE33C923C99FD92F5A63BD4B4D44 +:10FA90002ACF03AD63D4ED4991F06D66F82E85C48D +:10FAA0003A001DA31617448ED7FCBFD60717853E14 +:10FAB000E888D207069E4216E0EF880387AD5CA770 +:10FAC00040F73FAE083A6A0305FD6EC2608AE476ED +:10FAD00032DD7B0F27974F83BBA9AF41584BA5FB66 +:10FAE000E9B02AEAFB86B0BE9F28F7BF490BB750A2 +:10FAF0003DF064795F3A05DA79DE0CE8E1D60B4E29 +:10FB0000FE0EBA183CDC4EB285E7535A2B3F14E286 +:10FB1000EF7BC2999AEB824D7E6F1D87DE7D78D395 +:10FB2000E082810F95EED5443D53EC796E1828FCA8 +:10FB3000BC9BBC420F914B41F5C09320C4F7F9D355 +:10FB4000A143DEEBC73FC7548C0BE91E6F3ABA31B5 +:10FB5000898C8F20CF9F46E751E39DA7633E931981 +:10FB60004A9D049F12CE347D67BFFE7374533528BF +:10FB7000E5BDEFEBE9FA7151DF3DA8A7E98DF7A9E3 +:10FB80007E59F17AB9BED943DF8D53FC13D63A7B47 +:10FB9000F55936C098812B72064EE8FB6E04FCC006 +:10FBA0007524B1DF8D447C27021723FE2E9251E786 +:10FBB000BB3BB848A73A9165E936FE7B3B85B6A1C9 +:10FBC000E329AF7928CD9F333083EA7DEB46F2629B +:10FBD0005A7002FBB992BFECE09D447850BCC6F766 +:10FBE0002BC07CD3FBF70B3281BF27B25BC5773EBE +:10FBF000DB911F6DA92C053AD55FC323253AF9D3B4 +:10FC00005B5C360F7D476C25B8ED7D70D7D8441D01 +:10FC1000488D4DD47918F572B178ADB119794E8F00 +:10FC20008DFDF198EF907E62F3DF42787A28A998F3 +:10FC3000FF0E53DE2BD3DC5C0F25BF7FAA4930F0CB +:10FC4000506CE3E77DF594EC67D6523D37C259938B +:10FC5000015CFF783469540AD565D5B4897AEE9A87 +:10FC60008C00EB77B35F617D5FD35AD24AF6E2B284 +:10FC7000C3C275DD352E51071FC880D0F37A343DDD +:10FC8000A619F4A0FB4B598F64D0655C3A94D07BE5 +:10FC9000E3C2DE91849342DBCB37D0FDC2B87074EF +:10FCA0007D19D26935D1A9F73B1ECDC9F51E067D58 +:10FCB000907198D99D92EE06BD9CC6DF23F06A51E3 +:10FCC0007F8FC0A0E3F644412F3355E00CE77775F2 +:10FCD0005A37964EFF1BE114C1BAB04B000000002A +:10FCE00000000000000000001F8B08000000000062 +:10FCF00000FFCB936560F8518FC0F9D20C0CDEBCCD +:10FD0000A862B4C40C5C0C0C41405C0EC41A407B6D +:10FD10006F01E9DB401CCECDC01001C4FB81F81F90 +:10FD200010FF07620D20D604E25F407945A81B5BF7 +:10FD3000981818DA80B80388BB805887918141975A +:10FD40009178FB93841918DE8923F87A120C0CCD74 +:10FD500052F4F3FF60C33156F4B5EF29D03E4E178D +:10FD6000043FC71998245C50D570BBE03783074D1A +:10FD70009E178DCF87477F9E212ABF5C0B953F4DF5 +:10FD80008781E123929A0A2DFC6E41C78A460C0CAA +:10FD90004A46C4ABDF608CCA0F3081D000F9ADB1E8 +:10FDA00009A803000000000000000000000000009F +:10FDB0001F8B08000000000000FFE57D097C54D582 +:10FDC000F5F07DF3969949662693900D0871028AA5 +:10FDD000A88013086940B4C322A2228E5BC50D26F9 +:10FDE00002D93710FDF0AFFD3210362DD6D0824645 +:10FDF0008B74C0A0C182040D1824E0002EF82FD50A +:10FE0000D8BF7B5B0C4AC31692801B7EB5E57FCEC4 +:10FE1000B9F725EF4D26806DBF5FFBFDBF69F1E6A9 +:10FE2000BC7BDF5DCE76CF3DF7DCFB14DB2896F89C +:10FE300063C6CEE00FD2AB2C8CB151DDE96CDBA0F8 +:10FE4000A187FA74E7FF5965D3EA87421EABD06EEB +:10FE50001ED6FD9CB185547E408C6B38BB1CD3F400 +:10FE6000101B0E8F6DC91696CCD87D6E46BF01094A +:10FE7000BE742991B1CE1556F7BA0C78AE7A5C08EB +:10FE8000DFF7C8207750C2F73CC95216E43FA2BA48 +:10FE9000D701CCBE3F23B36CC666DAE06F0FFCC35C +:10FEA0007AA0BE7CAC6C1063EA699905A07FEA7702 +:10FEB00012A5033436C3EF0078F92D6CDCD0EEFECA +:10FEC000B913FDEC7380B7E8F9897E5BC0907F09B8 +:10FED00093A8FFECFB4AAA5F6F6FF1F25B6C3E07E1 +:10FEE0003616948DCF3B967FE9C2E78B9B6EA17A45 +:10FEF00018532CD8CF72B7C84FFC5C6396EEFABB90 +:10FF0000F114A27674D8D304EDFE8831E9B5BFB6FA +:10FF100032C043D556D56305BC4CD8AA867F0C7039 +:10FF2000E95A2984B065979D31C04BFB6A0E879DC5 +:10FF30009A0FCB9FA80518AA28B736FFFC0AC4DB86 +:10FF40005699ADA366FC84F7561BC73B6BE4709EC5 +:10FF50009D83A56B774FC7F70B1AADCC0EF5956E49 +:10FF6000CF9F7A05C0F9FB5486454AD72FD0FA01B6 +:10FF70005C1892EA11EE18CFA8FDE03639B41ECA1B +:10FF800077B89A936F83F11FABB431CFC5D06F6749 +:10FF900073F2AD8087A2D09649F85ED146C98B2C0A +:10FFA0003461EBFA37FBC27BA51B24AF15F0525C22 +:10FFB00017CB3C43781FCEC0BFD60639FC63C89F21 +:10FFC0000BE3641948D7EA494CC6F657681E6737F1 +:10FFD0009E8E550E611E6B375CBA01DA81F7CA5EE0 +:10FFE00094BC38C4320B0B205FB66FB74F7BD68101 +:10FFF000E35BA00D76E2B8966A582E3F94BBCDEE37 +:020000022000DC +:10000000C1FEADD526417ED1EAB55A9E81FEC575A9 +:1000100097318FCDD0AF9A412946FE884C8F019BF6 +:1000200018FB53C498AF1EF94409693719E4A29F1D +:10003000144FF42EAE934DF50326194B82FF7E002C +:100040007F02BE823B9D84579D6E73051FE9743B02 +:1000500025E487299DD9C6FAF5F4E74807E84F75E6 +:10006000A59BD25F54A652BAB2D243F47902F107EB +:10007000E972D16FD758364E81765D3EE646314BF8 +:1000800098E21BA7029CE0E770F2DD01C97396F1CC +:10009000EBE9136A20176572159BE453FA02AC056D +:1000A000E6302FB4AFDCE89B389AB1D759E0711C29 +:1000B000FF222950807465AC3ED50F745922811EF1 +:1000C000017C2DC541021E96F4057E063A3D714F16 +:1000D000F6B3B224C69A8870DE738F66503D3554ED +:1000E0008F0AF50C3A773DC9D3734CF5244F2FD0C6 +:1000F000EB594BF5D8CFAF9E27A68F31F7677A9192 +:100100005ECF0B586E91F3FCC6953C63ACB93F33A0 +:100110004AA89E94BBBD2C00E5659D7F58B34F86D1 +:100120007CC7C6F8118F32231F8DDF86F53941AAAF +:100130008C7C1497136392A7785F8209EE33B99F82 +:10014000A97C927FA0293F65DAA5117CE970B75E92 +:100150002660E854385EA3FE6AFD34D23BE3FAD948 +:10016000087EA09F83F4CE03630217BBA1DFD8579C +:1001700006F47F400B5CEE8EC237302E89A562EA12 +:10018000B1601A99BF54E5781BDFFFFBC107E1FDA1 +:10019000724BE7E07880FF4B1AF7218EFB8FA84C5B +:1001A000816E3132ABC072315646FA6F6946F6B392 +:1001B00041035E970D007E91BAEB5DA60652911F3A +:1001C0005B821541E4CF253041B07E8C1D6415E182 +:1001D000E085F0FE80BC54C4BF5503FD616C5F83B5 +:1001E000F68752FBADD87E5B2FED5B07E698DAB75A +:1001F000A51798DAB769D03EC8476770BE681FF088 +:100200003786B1936C3EB56F4D2FA0F6976AACC0A0 +:10021000D47E4C57FBDF60BBDF63FB4951C63F70A8 +:100220008C79FCE945E6F16B7CFC6C4150B41F43D2 +:10023000E397A4201F7F7A111FBF95D7DBD5BEABF4 +:100240000BFF9A04ED3AA45EC63F68AC79FC1794A4 +:1002500098C76FE5EDBB172C13ED3BA8FD78691926 +:100260001FFF0525D4BE660D78918FB4FE31152190 +:100270009C4FD34080524807FA281D92C018E8933B +:10028000DFB2818487076238DF7D1303FCE6E8D69E +:10029000A72C041208F37099E0E9E28DE3343E3FA5 +:1002A00007695E9F2DBA3AAB51A6F98CADB4862E84 +:1002B00082FEB637CA418467ADBC3224D37C0A764D +:1002C00002BEA7B0303EFFF3AA61EB8CE38A4C6715 +:1002D00057ABAD2D06B9EAD2EFE3D9900AE85F0536 +:1002E00032C1A86EB815F434033DFC39E8634C0FF5 +:1002F000ABDC2E39047A9C5D6C949B05DC2E09B234 +:10030000F78740FF7F22FADFAA707CB7CE9342883E +:10031000FF6F56CCD1509FCDAE8E05A477F7A35C6E +:10032000D0A973BB3544F6144C07889FDB491419D8 +:10033000FBD3AE1BDE945C303FD6F431BD77370B78 +:100340002D4E85F23397E70E70C3F8EF9A661D21A4 +:10035000E3FCC47CFD2D24C7ACBF2587B1690D2B00 +:10036000D4FE00DC3E4DFDBCC5F0FE1D01337C57C4 +:1003700081196E5743AA05ED994289AD857AEFA997 +:1003800030E7EBED4C9612385D457B3F011CF48560 +:1003900047F7603A021FBB89AED3DDFC5DBD3FE588 +:1003A0000FA92C4CF3714B1223FA2751B9809B8F64 +:1003B0003BB2BFD3559BCF0FFD99FEA04CF88CEC00 +:1003C0007FCBAE589F05ECD9969A2F5564C1C8F1E2 +:1003D00044F67FC6FCC8F1B8359C1F728391CF39B3 +:1003E0009F44F25379E3B85F1E32F05369FDB5BF05 +:1003F0003C6478AFB8EE26135C18BAC3543EBF26EF +:10040000D7943FBBBAD0943F73D91C139C1B7CD0AC +:10041000547EC6FC05A6FC7B2A1E31E5DF55B0C222 +:1004200004DF1178CA54FEF6696B4DF9965D97DCCE +:10043000887254F581CC70DEF8DAD1FA73B437BF24 +:1004400076285EA4C711B057500E8E81BD82697B9D +:10045000E348B2AB410FE63130A1564BFB83CBC62C +:10046000A25E66A43F43D2EF83C134C69E973C840C +:100470003FB94663616061892574F171A76CC86FEB +:1004800039477E0D08FAC89EF9724BF4E7E5EB7226 +:100490002F40BDD39B3E805F7F9CE73A843D1099FF +:1004A0005F2231BFF1B9BE7EBA5CE27ABE44AC5382 +:1004B0004A5EEA3B9EB9100E0FAE385B7BF5805466 +:1004C000D49368FD27213F801418E8515C37C82475 +:1004D000DF6DBB65EA5719EA04D0AB99CCBF574230 +:1004E0003D13DE9B7ECB30EC87EF75D4FBAC3189BE +:1004F000E6F5B6CAC9BF3CA4227DFC941EA99C4661 +:10050000696B6580D2439505947E5E5941694BE5E0 +:100510007C4A0F540629FD63E5324A3FADACA6F490 +:10052000E3CA1A4A3FAC0C51DA5EE9A35497872E0E +:10053000FDEB17F6B058B7C0036E0F8BB12C82B22B +:10054000CD24E7DE5494F3538E6F06A3BD7FEA6398 +:1005500060A28CDEF115C96FBDD3D147F64A5E08A3 +:1005600098A74FCF7C7B0CA793DDC22633D0478F53 +:100570005CF49CF7DEA1042BC832C0A9DE9B9C5121 +:10058000EA85B90FE9752E3A315FE7705C67B73ECF +:10059000FD976CACF77269209F87F7CA340FB3F0F0 +:1005A000B35EA4D70FC59BF4DA9FD25BA0DC892E83 +:1005B000FC35A73348E7486EAAFF5483952988C7BE +:1005C000A6D8102E8D4FED7BD685F2383755AE3E2E +:1005D00034B2777C95D667543B0CE3296F34C3A7BC +:1005E000AAA5C9DC7FE089BB7518F295BBFAD04596 +:1005F00048FF544AF57AE6A66AD4CEB1BA41717C76 +:10060000FE0EF17970633CF12BAC3BA9FC3FBB3F84 +:10061000BDD5A3F787B106F6850DF501E40D3AF7D0 +:10062000FAA807DD95AF343FD2AB49FD06ED85183A +:10063000F8776620D6AB10ACD75B5E2F07AD97E39B +:10064000F38DA6F6E03D8FBEA6C7F77AE75B85B5CA +:10065000EAE3047D75A5F0E714D7D9ABCDF34ABC26 +:10066000092E6FEC5B6D9A67F00F907F562129C8B9 +:100670003F25829B3A14C73209FA976AF150BDE5CB +:10068000122F576A6BD1021E62C766B433EECDD10A +:10069000F9CF73FB1F40DF1FFDADCA1EC57CE1D73C +:1006A00051F56CB06F2DE8E711D0BD0DC55350EF7B +:1006B0001DDD763DD927B398DF858BA402569D8D2D +:1006C00076CE0966998CFC7F82FDDE35D2B0DEC81D +:1006D000B768D49F99CBCCF32CD8672638BFC60C0B +:1006E000E7B19B9391DFF356AA30B7A05C9AF36F02 +:1006F000B7B849BEF259C5125AEF083FD8BD6EA629 +:10070000F407B92F7DE599ECDCA1E887E0FA5BF707 +:100710000F1426703BA52831A4F920FF8B86913F4A +:10072000B982E1FBA125A8A7824EE65DCF7AD2EF80 +:1007300087F63FB2BFFA7CD2C34F21FA21D749BE18 +:10074000509475DAC31649D85B414A978B71EB76A2 +:100750006B4D045C1B01D747C07F37BF253213BFE9 +:10076000A55A02359624CE5F682F484AA716F84747 +:10077000EA4FED517FED3FB5FE34A83FDB547FFDDE +:100780003FB5FE0B7BF4BF295AFDA5AF6CDA16040A +:100790007D53B479958BC13C7454A94EF602DD4B60 +:1007A000D62F76211F1C51822EE4E7A321797234C3 +:1007B0007EF8D222FCA2CCE790705D857F42FDC717 +:1007C0005EF8D954B4E7BE59AFBA69BD54670D5B42 +:1007D000414ECB1A0AA7A0DF17E0831C5E7A52466F +:1007E000B8D1CC9F45CFAF4A46FF1E708A584F8480 +:1007F000C95E2AABFDF3249C87CA5927C959E47BFB +:10080000D8FEE904D28FB95A5CCF7CE827D9F9E544 +:10081000022FE50D3F3B29BB30BDF630EA13B04C4B +:10082000C80E8F7CAF40D841872CCEC4565842B1F9 +:100830001FB11FA1DED4F1C242DC0EAADAF0E4F04F +:1008400083D0AFB6DADFBA2403BE74793B553FF3E9 +:10085000D7AF7A7AD7CBED62BDD7FD5E88DEF334B1 +:100860000AFBAD89A7256AD885F671C95AD51B84BC +:10087000C7259B9E7DEE695CAF7E62F55E04F51731 +:100880006F7AE3C33100176F5113A7F06138A4E406 +:100890006EFA94C3BFF923BAE951F4F21B9A6718B0 +:1008A0007FFE7042375D8AB7ECD6D8B09EF898507C +:1008B000BF5B6B7144A14FFDC1496867556DF85628 +:1008C000C375E5D15D124BC98882CFB56F90BD80ED +:1008D00078227A0A7A75D12FA27C39D005F57A244C +:1008E000BD22CBBD81FA6514AF17FD93C0DF2FBECB +:1008F0008A7EEC4FAD5EC443C18BF7B9703C8795DF +:100900000ACEE7CF2C4E463F7D811A4C7653CA9FC4 +:1009100017ACB99FF82FFFBDFB93F9FAD0D7D74298 +:100920007355B02F8E73F6EADB689C792C407C58A7 +:10093000F08CEC0F41FAB5C2266F892227C5329799 +:1009400093C3EB80B830CEC3B84E41BFEEEFE5D0D5 +:100950007AF28FCC61A80FEED7FDF16C2EC15F8BC0 +:10096000FD8471B2455FE7DA4CFC5BBBB419E974F6 +:100970006C802F05FD6AE54C090A7C4867A05EF98A +:10098000BDAB53389D9847C916EF815D30019F6319 +:10099000F966D5671F6E7A8F9DC9E86E7F9E681FC6 +:1009A000FA1D83F3F9E16456501F657C35B2AE073A +:1009B000605E37F09941DEB9FCD73EC2E55D97FF36 +:1009C000D04D9331FFABF7B91CE17B385F42BFC21A +:1009D0002994BFFB5689F4839585A3C979AD2AE490 +:1009E000DC9C1FC92FD07F458A33F00DB69340742D +:1009F00020BF5ADE4A78DFA857B15D57CF7A7539E4 +:100A0000CE17FA204F067D7059B73E60ABB91EE88D +:100A1000DDEE0AF2F59B1A7AEE69945F90D7A00793 +:100A2000E557F5E3F88F6FDCFBE19D20B7C7EB7569 +:100A3000B935EBD548B92D7869BD847C1A29B7C77B +:100A40000BC04A8926B7F03CAADC16B4FC4BF4AACA +:100A50008EC7C765B35ED5F5646FF88CD49397CA1B +:100A60009EA87A127EEFB3EC9EFCA8F3A1CE7F4540 +:100A7000BF29BD80FC093A9FEA7CD8C5A73A1FF67A +:100A8000F0CF98F018997F3BF2040CC1BF5D257F31 +:100A9000624913DF8F83F7DEEC9F45F8F2D134C74C +:100AA000AADFEC9F68844311707D44795F04EC8F6A +:100AB000281F88802B4CE54B1AF76A8CF8206C2A8B +:100AC000679DFF2BF6459475AC3E0F95379CD482FD +:100AD000C81F699D1AEA3F752198A8E83FDC299351 +:100AE000FFB00370BC04DAE9D898110A821E596C71 +:100AF000E7EBCD0E77A72B01D2C5F11CEE4CD296B9 +:100B0000A01ED49F77DAB91FA4C3DFE98A37F83172 +:100B10000E36C9A4C75B426C72343F09CC3484DF03 +:100B200016D65B3EF78F76E0BE33B687FBCE40CF5E +:100B3000AB6547FA7C5CBF56CB5E6023366BC1ED7C +:100B40002E74A177340DBA711A3C9FFDB6CCB76DE7 +:100B5000823EA5AF61DD7184059F182BE17EDE72B8 +:100B6000E29F994D7C1D326B7974792812EFE5393B +:100B7000E669A87761FDF0B9D10FACD753B03AE27E +:100B800079D3F5426EAA693D58546BCE0F88F5D4DF +:100B900037BAFEC96499A47F70A184EB7AA1B7AF7C +:100BA0009687DE380DE8D3B14F66B8BF7AAA4926DA +:100BB000FA9CDAC8F753593089E4AF8C7592BED4E9 +:100BC000F1D686F27571EF7AAC6DEB9FB21F423EA3 +:100BD000DAF687E1BF82B46DDB27837720FCCA4752 +:100BE000E97F603DCB4FD865273F73C72E27F17F44 +:100BF000C7CEDFA53F84F0762BF9F73A767D3B1C14 +:100C0000F9B163A1B500F560C700BE7EAADAF9EDBF +:100C1000F0169A7F17111D33148DE87DAAE92F076E +:100C2000302EE054138C0AED8B5DB1245FE5AFDA12 +:100C3000C91FD1B1F3DBEC80E39F379E32B1FFD304 +:100C4000E164D35EC2FEC573BF79F98ED1CF2EC0E9 +:100C5000FDF186DDDA4CC89FF0DA5F87A37EED7880 +:100C600089DB4DED6ACB1ADCDF18BA485EA802BDFD +:100C7000DA51C8FA31B66FD1C4F128473DF1F257C5 +:100C8000F2B39C2F3E26287C3DFBEF8F0FC9C7F5A2 +:100C90009F33649370DCDF1DF803EA895D56E24BF5 +:100CA0007DBCC7EB17903D73AE71DFFB3F6EDC522E +:100CB000F87CC6BDE0DF9CFFAD8A87FA1729073DA7 +:100CC000F97CE703046F727AA9BFE7C9EF6BFFA74E +:100CD000D1FD25A0BBEBDCE30EFF3F4BF7B7A70B25 +:100CE000BABB313EA0FCB5BF52FF7EA89E6BF93760 +:100CF000A77B6FE3D7EDFDB72C9EF733A1FC6456BD +:100D0000ED40C3E2DAD23D6F6742EE5B697BE3B14F +:100D1000BFE323F67BF4345EE5FEB6F1B8EF03EDF6 +:100D2000B27849AC17F93AABBFB02FFACFCB233B1F +:100D3000A47FDA63644F30C5B312F72BDF4A9FE913 +:100D4000A5D80B36E2E300C2EE2B056C5E6FFE4ABF +:100D5000623EDC4AED9F7EFD3EB473D3D264B28323 +:100D60002125FBF775D764FEBC4433AD87AEF598FB +:100D7000D7479312CDEBA889A2BEAB19EFFFD50ED2 +:100D80002914023C8C1FF0CB44F4A78EBF48651297 +:100D9000C093586011AE3B263ACCF59DC07D6C8364 +:100DA000BFF1EFC5E3C42E3C0E5CE9473C0E90C991 +:100DB000AF7A4E3C62BF096F99218CC7618A97E375 +:100DC00031A1D44B7E6AB11EC76EA21DA3389634E2 +:100DD000A33C2BB89EE678A075B8BE9EEE0DDF4C06 +:100DE000ACCF15D1A48E7F254DF6D9CDF5D1FA5CC7 +:100DF000A7CB0FA5874EC77F942EC9AA992E698EBF +:100E0000390ACAEB645C3F8CC4F2991C4E0B2AB4BD +:100E1000DF24D60FD778E628418027A4652A48AF7B +:100E20007CDBF6228C1FB57925EAC7C56D169A1FA3 +:100E30006C5912E17D488D42F07B16F728A4F7D457 +:100E40002B5E39FE20433FBB4FE306BA9FEF977CF2 +:100E50007FE6CCD86CF4C7F01FC67FDE00EBB75935 +:100E6000AB593806F0345B61C1B804F4934BEC73B2 +:100E7000939FDC0CE3EFAAE4EE7ACE55BE37BDF2C9 +:100E8000CF4E5F013DF6F9458C6DC7946F8A28C639 +:100E9000F5F68F9A38BECAF7B3D0401E8721FB0DF6 +:100EA000FB8A2FABDC3FF3CA1F5F1A89EBDC711D95 +:100EB00043E3B87ECDE271A962BD708A79E2BC0ECF +:100EC000D4AF83E268BF749FEC8C16E7B841ACBF27 +:100ED0007F83F1289076D4B26A19D757AC93FCBEC1 +:100EE000C15A1B5B1F251E668D6A117E224137F891 +:100EF000C9D9B87FC3DB9F0DAFC619E9D636E5A8BF +:100F000032BC271DF0F7B961FFEA1FC52FAEF711FC +:100F1000BF1BEC2D93FC51F447BDC0DFD43DDF91E6 +:100F20009FF4D2A6B516E4DF4B6B2DA6FDD83A553B +:100F3000F83146B011D8AFA97BECCE2CA4CB3ED96A +:100F40008BF1A5E54D27B540947DC4487C62FDE852 +:100F50007F6F55DDD4EE0EB57E26E275C7091BC343 +:100F600075F576ADBA385A3FEFB4F27ECE66F5F736 +:100F70000DCFF8F7C3EFB80E47783CAE3F6B99F052 +:100F80008344F21F233E3E55C74238BFE27A15F52F +:100F9000C2A98D8CE67740C963B8FE0679FFB1D14E +:100FA000AF7371E396DFA05D50D624B9714BA24CAC +:100FB00069D1D08F5BDE182FE33C9CE9D1E36FDD74 +:100FC000C36E35C845ABAA10BEF68ED97117B6FBF5 +:100FD000659BC6D04EF1BDDEE9C279FCCBA691245B +:100FE00007BD8DEBE54A563411E31C843E8CE48743 +:100FF000A11B634CF01572A01FCAD7546BCB3C6F7A +:1010000014FA2DD324B18F789EFA2DF4FF997E7BAC +:101010005FD76F01D96F9023BFC09B41BFA544D359 +:101020006F73254F0AE27DEECE412948D7B96FABE9 +:1010300049D1F4DBA64ABE2FBA59C44D7734807E1D +:10104000BBDCA0DF1A40BF45891F19A3E97EFA73F4 +:10105000E8B7D0BF46FE36A17E8B32DE1B04FE749D +:10106000FD36BCE920E9B7E10D16533CF0444DF8DC +:101070009B7AD56F52D2AD681FEF53BDB151F8675F +:1010800093B0C7378B38466C07F55C95F6C3F45CB4 +:10109000DEF9EAB97F119E753D37772BA3B8E89E3C +:1010A0007CC8F5DCDCEDA0E724E447AEE7E6EE64BF +:1010B000DC2F17A1DF86F4D06F8CCA9785F9FBE58A +:1010C0008D194FDE0DF58DF0A95E1B941FD1ADEF8C +:1010D0004619F55D95D68BBEDB777EFA6EABD07781 +:1010E000A0C706A27E8DE40F6F9339DE7CC7E8C3EC +:1010F0001B5F4679F99D4CFB92EF59F8FED13BA35B +:101100000F67217F7D2AFAF3A2C6E9D95E19A4FAF6 +:1011100027BCCEC757BA91FBCBCB1AB87D58562BFC +:10112000873CF0E7A431DF69D8FFC29D124B01F87C +:10113000266BF5130EB4EB9F5799581F4DC934F029 +:10114000C3AC9C62F2FB57D95DEBF0FCD12C85D986 +:10115000D0BF5FEC987414EDE0E21CBE1F502C9ED3 +:10116000EB71B0B3BBF464443C48E39C37FBB39EE3 +:10117000711653AD9CAE539F954218B7DA33EE22E9 +:10118000447AA1B8CEFCFC5D217F37C92D842FF6AF +:10119000AE1C35EE432FD785A77D024F8017139ED7 +:1011A0004252543C01A5A7642677E3A5F0772D4B66 +:1011B000705FA0F02989F69123C7ADE32D72FC3A48 +:1011C0001E753F77B1A82FBF692D9D6B8AC48B8E8A +:1011D000E7487C74E13D021FEF695D7EED9118D711 +:1011E000047C437A26F89F801768C73FEE22D3F924 +:1011F0009B8F045E46568F9B80E10F37611C3AE45B +:10120000E7D5CC79B32FE063D4C79E11389D5E310A +:10121000C61AC07DDA0DF64ED2833A1F0EB3723E67 +:10122000D4845ED9D1AF623CADF31B2537DA21E51A +:10123000613BE1B51CF8D10E45F63EF5CD24815752 +:10124000379DAF6A14F313D0C182EB267DBE0AF13D +:10125000F358239B385DCAEB385DB25827EDC7942D +:10126000D548DE308CA7AC710EC5A1EBFA197E0E05 +:10127000239DA2F0AF128D7F193A9BB3BBE7CD62DD +:10128000516EAAB5FA43DCE7990AF2B196D810FE7E +:101290007716FE3E57FC5024BD2E1378DB847875FC +:1012A00020FE3AB9FD15FE8ECE69E9F9E54AD084F3 +:1012B000D7094F9FE6FCB753F2A05FAC0B6FC8CFC6 +:1012C000903F4AC71BF233D2A1295746380FF0DDB1 +:1012D00027A3E77871BFD428F7853B0FF2FA9F91D7 +:1012E000BC2CCAB87F307FFF40BEEE4DDE8759C5AB +:1012F0003A41F0F73BF6CEFD2391BF774ADC2FD180 +:10130000146FDAF7BCC1CAD74D1BEC2007B8DFF663 +:10131000B6EA5DE7E9A91FAEB27239C0F584C7E04D +:10132000F7BA040782F1A675368A17A47E0CE4F694 +:10133000AA515F6FB2B3A45BB37AAF7F8AA8BF37FD +:101340007B498787617BA8471BA1BD21DDED45CE89 +:1013500017BAFFE05CE3BA43F0CFDF3B2EBD9D1F21 +:101360001A4F55CE9A695F4C8FAB4AB5045E51D186 +:10137000BE9B2C99E2B7A0E782CEFF70FDB76AA3AF +:101380007AAF9FA5DAC88ED0CFCB5E2D3B5810F038 +:10139000F6A54F2579012BE383B1387F8C8779102F +:1013A000922FF78FFAE86ECA97699FEDC6DFF5298D +:1013B000C57DC81B790C1DBB315322FBE13DAC6CD4 +:1013C00034DAE136E6B38A26213FE747F1213CD7FC +:1013D00092595B3DC103723DA22E5485A9774267A5 +:1013E000E23B48AF7132437A35FBFA4CC0F9F7BEA5 +:1013F0003FB34CDC8A073B81EA19B18F2561B931D3 +:10140000BE245ACE8C6EF8EAFD5BA07FA3F7CB5EBC +:101410000F94BB69AFC381723664B585050C78192A +:10142000C34255E8771A7DC8770BEA8302B07BF098 +:101430007C4941D3DA2A17C2AB257ABF3C1898E41D +:1014400082FE6DAA3939E932D40B500EAB295FCD3B +:10145000CB95D74A5E0C71CE6B5A41F14879B512E3 +:101460001D60DC1492988DD71BB241BD9B56C3FB07 +:1014700059387FC1FB586FEDC9F76F41BD03FDA41B +:10148000F737F2FDFA3C78CF8372523B87EA2B5C48 +:101490002D313C0753B091CF4F05FB552FE637EC6C +:1014A0007E8AE6DD29D05EDF0C9C8FC213E93CD139 +:1014B00048C94DE7381FBE80F456070E185FF0A5E7 +:1014C000F3F80949C062FDA3DB7FFD6DFC5C539E10 +:1014D0007781D607EA79272729C342FC7492F6E17F +:1014E0000F01BE03569C37793CCBDE9C2FB416C34C +:1014F000FC98631B44EFCF6A1C47711EB3999FE2AF +:101500003CA68EE676E7BB57DA43E8EF7B57ED4C17 +:10151000C3E77BAFB4D2F3F64D5C0FB70F6821BFC2 +:10152000FBE1D52AC3F32F55AB65D2138737AA74D5 +:101530006E577E86C737E46FE276C8DED5BCDEC361 +:1015400075DC7E9BF0CC6D93701ECE5FCFCFF9EA39 +:101550007A5A5F87E6B90B4DF35BA49ED5F570A967 +:10156000C04741F55ADA4F8FD4BBA5FA7C18A16F5A +:101570004B719F9DF6D3C32447A5F591F1658E6EFF +:10158000BF0DF243F83BE2EFB2FD2AC3758DF4457F +:10159000DB248A67C3F91EF24737493E8C7B28F863 +:1015A000D81A227B3C943BE33F709EF9C4CAF0C832 +:1015B000482BD203F4548EB5F38FBF84E747DFB3D3 +:1015C00061E410F04F2EE15F8F13CE5ACFE37EB26D +:1015D000DE5B998CE78DD9C43EA407F26B641630AC +:1015E000E88DA392EF963BF9FCE046FB47A76B968C +:1015F000569D87F36C918DEB47CF7A95CE8BC70BB9 +:1016000018D60B3EB4770AB7AF48D60CFC50B87367 +:101610004532A80EB644C4CB548973E6851A6FA729 +:101620007097E45E6B6847AF47AF57DBCEDF1BB404 +:1016300093A7BDD55F88FDA3717EADA1DE88ACA761 +:1016400047FBBDD493F35FA757E2B9FF9C77650AC8 +:1016500076CFF962CA20E33E8F9EEA7EE6ECF72D54 +:10166000CC67C05FCE1F6398CF40EF865120FF400C +:10167000BF1B1AB93DD730EAA0569A45B01BE5BD4D +:101680004CF8A3CB26F2FDBB86CCF716A1FC4FC9C4 +:1016900092881F5830A0F54924FBCD83FB00F959EF +:1016A000FCFD7C781FE5B2E1292EA7A02F3CA84FB6 +:1016B000CA56AF9844E56B250FD6DFB03697EC924B +:1016C000821C99517EED41B2930A1A0F26A23C83E7 +:1016D000FCAE447BA06CACD58DEA58974B5DCEDF59 +:1016E00015E76199CD3D0CCF77E0765834F996F740 +:1016F0003361B772B92CCFE172FBEE261547783E05 +:10170000724E72ADCBB18C729CD52DC77B574FD02A +:1017100050AE0F87248AA399807A00E57C831EE768 +:10172000C4EDD8F395F373D999A520BF385FEA7259 +:10173000AECB75A43C372B2DB7623FEEBBD24EE348 +:101740009870D5F60FEFE3FA8AF65F275CF5603202 +:10175000EAC73C85C779E9782D55785C608F7EAD06 +:101760005CA0F53D9FFE45F4E333ABD95F126F8B70 +:10177000E7F1EFB52AF1FDB9E4B3879C9DA77C9E04 +:10178000AF5C9D4B3EF5F6E59DE67AE2916947F543 +:10179000ACAF1DF018063CBEB5F1598A0F3EF1C240 +:1017A000C1A94887E21DC0E7C85F1B9D2C8C7A4EFB +:1017B00009D1BC55D420D33903A684B36F711AE57F +:1017C00098C775156F76123F15BD640D4D81F78B67 +:1017D000B67D319CE26A167652DC5AF005612F071D +:1017E0005B86A31C14293CBE2C522FFCDAC6EDE705 +:1017F000B6EDB1D3707C521DBFDFA2A8FE76D56ACC +:10180000D8A778C2A652BB508EF67983C0C778FE9F +:1018100017FB67BC57418F2B6BDBC0F54451A31AF4 +:10182000C27B328AEAB6B463BC71D1C756F27F95E7 +:10183000D79DA4F31413366F22FF4A79A36CDA8F75 +:10184000EB11DF592787AD1897D8504AFB90001F3E +:1018500024B85EC453FEC0F8C3E2CD3BB705018592 +:10186000C52F3FEF42FD72AC79BD0BF10EF59E35F1 +:10187000DEBA473C67FD23229EF386C3746F4B2F6D +:10188000F19CC7F00F1094B76DE6784E56D787ECF1 +:101890004BE867B63FCAFE47977DBEE9EB35781E39 +:1018A000A1EDA5E36BB0DF257FFB720DC689B15DAD +:1018B000769AF7CA5FF880E2B7F5F7BEB0097FC83D +:1018C00086E729FEBDFD13AB176B6BDF79381DE38F +:1018D00006DBB77C978CFECC793BAF267FEFBCADA7 +:1018E0001352589479434F917F43E7117F1F49B7B3 +:1018F000BD0D7B299EED04D01DF560579C6E7D29A2 +:101900008F7FF688F8DC8DD1CF3BF488C76DB8E5C2 +:10191000C62B51FF37707BF29C71B9EF033D2F3F0F +:101920000F3A6E14F1D7F5379C352EF704FE01F40B +:10193000B2D8CD74FCBA61F6AF9FC6BC863EBDC6B8 +:10194000E586CF037FFA798A776C3EA71DE5E8A587 +:10195000DF503C34D26F8A07E7A3AFD3F13CCA1102 +:10196000B5733ACE3F9D3BAD74DF4FD1CE8F489ECD +:10197000DAB7BE477E6A26CE35B4B3AE1F8F3F9727 +:10198000C4786B9D3C9E57D001E37D3D2E7A2EE2BC +:101990007A395FEBF1BEBDC5F95E6D1F28EE0FE031 +:1019A000F1C8A5B57F10F1B3DD749372905E07CFD7 +:1019B0001A47ADE3C12DF472771C7BF4B8EAAE3858 +:1019C000F608BA213D719EEA8A5307386D04F94939 +:1019D0003E8A762EA27D2D8F7F6F57A39F37D6E349 +:1019E000DA7D11F4D6C7DB9BBCE8727BAE71FC508C +:1019F0003CD16642524F7CB57D1F5DBFCFB44B7F5B +:101A0000D7FABEEBBC548914791EEB5EE4CBD286C8 +:101A100083E4CFEC5A7F8BF1B609FF7BDB0B32C539 +:101A2000392FA9DF4BFA3D527F94E1BD2D51FA7B4E +:101A3000BF5DD8E78D7CFE687BC91972403D6D7B28 +:101A4000B6135F976D3C4871D66FD6BDACB518E242 +:101A50002770FE0819C6D3F6E2EEE1A4CFC5FD302B +:101A600091ED548976CA9BA2B753BEF1A4A99DE219 +:101A700060BDE6769CBBBD638AEF76ACEF5833B7AA +:101A8000138FD5CB9343D1F669ECAAD8EFAFE629F3 +:101A9000CCA3740F8E93DF7B23BB62C8EE9CE7CC94 +:101AA000F9382E11538DE2BAAA168838B09F7A53AE +:101AB00091DE55CEEB18F67731E2D7E0FF51DD012C +:101AC00086F6AA9AEACF42BF43A4DED1122D2C6437 +:101AD000A0F73CE7E4140FED8B84D3909E07320F00 +:101AE000AB58EF6711FEABCF14B62405FAF7595087 +:101AF000F22E807AD9F75F0CF03B7BD6AFC381879B +:101B00006593BFA9CCDA7900D72BEC353BED47C8FC +:101B1000BBEC747F48F91A3B8D77EFD66F9F23BBE0 +:101B2000FBD756C6F787605583F796B9791D87B7F7 +:101B30007EBBE62F6857E3CBD07EFE1A288FEB8959 +:101B40008DB1B4FEE978298EEE51CB7FEDA1A9A825 +:101B5000D7F263393FE66F4E0955417DAD491C6EA2 +:101B6000DD3480EEAB287EC949F1A57BB7BE528635 +:101B7000F354FBE6580C3360EDAF09FBFF37E27E10 +:101B8000AD1AD5638C332F648AC7782EA818615399 +:101B90005C13233F06C911FAB11AE3E83C11D8C51A +:101BA000A67A4EA89D0F78898F83FDF839AA703FD9 +:101BB000D40791E5F4FCFD767E8EBDDC0AEF39BAE0 +:101BC000CB976B9D791CAEEEC7F5493395FF44E783 +:101BD0007391DFB35E5EFE23BDDEAE7AF8FB65E295 +:101BE0007E9B48FE3DD4A557FE7A71B4FB5BA2F400 +:101BF0009F9EDF2FB1A005ED962D76BAB70BEF674C +:101C0000C0730EDB34BEFF55E20AD3FD393B843E80 +:101C10002E8909D37D3EFD443FB03CC2CCD6F22292 +:101C2000D2BDF4153BC3F8B3D2D79C3EA477E9B636 +:101C30006F5B7F9585F18BB1E4D72B7DED7F111F15 +:101C4000945AC3D3E9FEBC2D5686F7E7B56D793BB0 +:101C50001DE5B54D0DA7279C655FAFB4DE6ABE5785 +:101C6000408CE35865E842BC77413FAF5BD48B9E24 +:101C7000B93286DBD7F6189F3586E4DD7C4FD4B1C8 +:101C8000CAC641C6F3FB459EE87AB17F8CFA8F9DA8 +:101C90004377F438F7DA3F2609ED99E66474409605 +:101CA000813D8EFABCA8EEE430F41F7C16A3DF6FF2 +:101CB000E089C3F9E833AD7318EABFCFD23B871987 +:101CC000E7992395368FA2925F87D28EB527F3FAD4 +:101CD000318C37B54F8BA6F786C5C412FE8A1E8E8F +:101CE0008D7A8E7A4C0CE7AB34681F536C17E54342 +:101CF0006FF7332D447AB831C6C3EB490B69F8BC92 +:101D0000B86EFB20231E0A956A2A07724AF82C64D3 +:101D10002BB52C83FED6DB2B9CEFF028743F81F291 +:101D20007FBAF855EEA6333991318E51E014665CD6 +:101D3000F233EBE74814D56F43FC69CCEF5664648B +:101D4000956A92F718564FA903CC2E7E5F5A054329 +:101D50003D7944ECEFA31F0CD36E7C3D487A3F38AD +:101D600080B18B32F0BE094F9CDB80BF6B70B33EFD +:101D700009E3692B18D71753DC688F48C1003B0370 +:101D8000FC5455593788DF03C27C182F49262CF4A0 +:101D9000CFE57EF33BB483804FF93D8457B15015B6 +:101DA000A018C386C9EF3A9EF1FBF3967DCC8CEB6D +:101DB0008F12410716DC4D7ACCC1BA7F9D00A35A21 +:101DC000457D5B15F7B71CDC9F73B85918EDC358F8 +:101DD000070BC742EA18AA1C33CABF2B0B60035F6C +:101DE000BAC79AF323E502F45A44BBF5843FA8F737 +:101DF000AB887ABF8AA8F7ABB3D5ABE3A9DC3628AA +:101E000003EFA5585C592FF0C6DBB309BC017E86F1 +:101E1000E03D7FCC12E315FBE684D718D11B2B964F +:101E200007BA6E8EC9207EFA59DCAE4E8C97668951 +:101E3000350CD7C38B24FDBE4FE67718DE636E1BCF +:101E4000C9E123A29DCD02CF8B74BF558FF276B22C +:101E5000BF7A94B7F7563E267A79676FFD898DDE93 +:101E60009FF85EEAAF8E8D5AFF0FD54B65AF7DF4BC +:101E70000EEEEF76E92737A0DE6C676E46FD541A4A +:101E8000DFFAB7167AC2ED4C5B9A99DE31C8DFC033 +:101E90006F31179A9F47F24914FE72F48571DF295A +:101EA000DABBF3617E5E4DE7835C31BE89B57C9F12 +:101EB000FCEE79DC8F07CB461FE6DF25F2EFAEE1C3 +:101EC000F6E3DD0FCBB40F1B79BFD5C1FFCDEFE13A +:101ED000B8071F80BCDD335F0A8533A2DDDBC5DEBA +:101EE0008F877A6788FE44DE8315609E49CBE4685D +:101EF000F76071BED4CFE145DE7F318BF9C5FD6659 +:101F0000E6E759316EE2DB2225A4550FED9EC7822C +:101F10002B80EFD1FE04BEC7FD2F599CC7662E8DC6 +:101F2000C7D7DF9A60D27FA78678E270BE66AF8B94 +:101F3000E76EFE7CEEB59E14E37945E574ACE91ED0 +:101F4000A02AD59B8AFA4D3D7D3DF3801C6AA707E8 +:101F5000318F211FEC56127E0CF3243D95AA84503C +:101F60002F2A6E3FCB47BB379EF3B35E5E4BBCAEB2 +:101F7000CBCE7C17FE1D46E681FFCF5DE1A1F3DFEE +:101F80005739FCA771FE955D39DE80A3273F04B762 +:101F9000F27157E1B8337A8EA74AF37AC9DEBE0EE2 +:101FA000E645F2CB796DD83FD9EAF9C883FDFBADA0 +:101FB000CAD00FD3133FDE2321C83F15EA4F712447 +:101FC00072DC94C1D8FE72BC6F14F4FF3271BFE8AA +:101FD000A24A26521E57B708EF1FA53447A43E91C8 +:101FE0004EA6728F8A7B4A97547A29D5F16BF356A5 +:101FF000D33D98B60B79FB36B7A05FA245E02F40E2 +:10200000F6972DB582F61DEDEE8A30DE27C7D26039 +:10201000DEC161B9AB09BF9A9B91BF13CA136C456E +:102020001852B5660AD1497157B07CC84F7504067D +:10203000C7A27DE331DF87694D1D71D6FB31BBF847 +:102040006D13C7FB6312E7B748BC3FA6367B306E03 +:10205000E2B16BBBEEAB22BCC37288E3FD3FF97EFD +:102060006E4FBC374F9B69C0BB337B32E1FD6702CB +:10207000CF4B055EAB041DAA043EABC4BDAF55E219 +:10208000DEDC2A81DF2AC43BA48F887B7B17233DBB +:10209000209511EFC0BFD6A14126437B7C0F0F5284 +:1020A00087E05BB785FCA4B2C3EF43BC5B1339DEAA +:1020B0006D0EA003F135E0DD83F941C2A7EAE078B7 +:1020C00086F29C0E025610EF23F139A707E0FDB609 +:1020D000D824D487634C78D612C79F1FDE9FE2F3C3 +:1020E0005BA290F348FC256AFC5E605DBE7BB38F0B +:1020F000AB445C7695B89711F18876CD2AC00FBBBA +:1021000098E3933F1F22602FA54962FD5F0574C0CD +:10211000FC27853D8478C674672C5FB7245A2A76DD +:10212000AB88A7047EDF0F4B0CB2B46CC64380F1C2 +:10213000971A641E84F5FDE15A33FFC86E25E27ECE +:1021400049CF93C86F2BDF562DB87F2FCFBFDE74DA +:10215000AE5B9EE68BF710FE0312DA353F1372B8C2 +:1021600002F985FAC7D7C38B051F2C15F7063F2246 +:10217000F8E73121CF8FEB7CE3E5E748964FE6F1B6 +:102180008E89991671BF629819E309E3BDF54C83F6 +:102190007ED1DAC64329DD9FC93EB692DCC60E6504 +:1021A0003EE4AFF88F1F0CF1FB70FD7DD11E8AD786 +:1021B000EFBF1DEB89BF830EB4871571CFA4CCD7B9 +:1021C00093CD51EF8DADF2EEB1A15FA6B7FEECBE9F +:1021D000691BF173DEE5441ED627E0BF6336C08E6F +:1021E0001A5857C12FD61BC85E8C7AA5C649FCEB7E +:1021F00080FEE71BF824B617FFCE54C7B51B505F0F +:10220000BC80062430C12F6A06D911CF80730FFA23 +:10221000B156A9FEBE382FAC8A8FEE8FFB652CDF3E +:102220008770655D6AF22BAC547DF49E7BAC59EFF0 +:10223000AC14F344C244B39CE8F3C24F457D573914 +:10224000023BB15FC9A727923C27DE1C7D9EA852A6 +:10225000B520DEF751358CCB773057E3F6730FFDA1 +:10226000C3689FE45460F03AF483E97CB690717DD2 +:102270001764DCAED4C7F504F2BD15E70337F13FB0 +:10228000CE0708CB176AFCDEE3BB2DE4875822E4B7 +:10229000ED512167CB857CFD1CE5CB8AF7587B2966 +:1022A000FD8590AB952887901E8FCDE0F6BCB83F9A +:1022B0004C5FCF2CB48DA0FB22AB1C169A17944F09 +:1022C000AC2107AE0F768F76A3FF477666B9034E33 +:1022D000CCCFA2FBDCA5F82C37F2CD37CE59179C1A +:1022E0002D1E16C84FF7162B2AF74BEAF7C8578949 +:1022F000FB0854F7CD0CFDD54F2656D829DE359670 +:10230000C787D7E46613DE811E9DB186755ACAB4AD +:10231000EBBAEEFBC3EA9FECE55E83EF85DE606916 +:102320004176A1414FD488FB249927C88618F4C56B +:10233000C28B2631F4EFF5D413BDE8CDF55C6F2EDA +:1023400092A2EB4DDD8ED7F566A47ED1D3C5174C96 +:10235000369DBF541D5E467A6748743F42B2C3CA79 +:10236000F72F99D79B9BD1331FF095EC30E00BED05 +:1023700021DD6FF1E328E389D49347AED3E7D7009B +:10238000DD3B344BF33C39FAACF3AB795EC83FFD2F +:1023900008CD4F79A747535A50732DD9230C77692D +:1023A0000CF72E1C5E7DBF0BE97BB846EC9FAF5649 +:1023B0004318BF74B8667119C1D5760FD266DC2F89 +:1023C0001E74E13D4DB3D6C8B49F7E2426984EF1CD +:1023D0009FDF9F39231BE26316AC5D9A8EFC386B3E +:1023E000DD523A377B24C137D86F80599687EC7914 +:1023F000FDFEC6BC67AD3EB4C77BE3DBBCD5D1FDFB +:102400003D55F827AE53987708AE4376BBC6748621 +:10241000810F8EFCC24EEB822A2DD88E70D5BA5811 +:102420007C83552544BF0F28D571B50FE994EAF098 +:102430005D8B297324D07E4FEF72C4DB6F455F3B09 +:10244000EEBB3E2DEE45023ADD64F2BBF27DD7567F +:10245000E14763B65EF26344BEA7977C178F936231 +:10246000EEE8F97FB7FF69688FF55D318EBFB4E69E +:10247000F8924FE889791FA150C48BCF5A171B5A85 +:102480001845CE6689F3C7B3C47E99CE8F85D7EB46 +:10249000F639E7E3483E975EB884F8FACB7D2ACD5B +:1024A0006B65C0AFA8EFA51746D37D500B9EBBE26E +:1024B000718C0BFC6ABF4CF925A7EDC4C7ED3FF545 +:1024C000D23982CEDFA9F49D88AFF65D4DE701DAFF +:1024D000C5FDD33A9ED29C7C3DBCC6C1F550DEE919 +:1024E0009F913C74F15768A686729E77FAE75C5E0E +:1024F000F0FED93138ECEBDE1C77A1E06B80D72CF5 +:102500009F346921D49BDFC2E58A8D0D96911F7B94 +:102510006DACF7D128F2BFC6E131F9B5F25B96F3A5 +:10252000F7C0AE4C34C499CC12DF7BC83FCDEF6509 +:1025300065EE204B457912FAB05B0ECCF772B7DB33 +:10254000CDE3D4D317BBC6798569FDD63DCEABE8C4 +:10255000799EB053F25B4613DC3D9E5F8D8E369EB6 +:10256000EE718CA5F2EDF1D1DBFF50B4DF5A59C00A +:102570007CA04F8BC4FDBF79A1FB34D41F79ABE3A2 +:102580001324C3B8F26B8A4DF14F7935B974DF5F0C +:10259000FEEA5CED5E83BC76D185CD36D1E543475E +:1025A00080E832D5E1DFE340B97CA1F0814F3D58AE +:1025B0002FA7D3112D38BC82F4DB7DAE68E7A73E90 +:1025C0008CA4538DA013AC1FB20C74D2E913F97E06 +:1025D000EBFAD2073EC5FD8BA7F8ED45BDEBB10880 +:1025E000FA6544C75FA783F36B2BD80F81F3C2DF73 +:1025F00065A6F8BB5EF127E8ADE3477F0EF6DF5135 +:1026000094FB4E94CD51581FE78773E1ADBB7DC15C +:102610000FE3A28F27C5A9F3C37C1604013EAA715C +:10262000FBA3F7F13CC482B6F3184F979C2E36F10A +:10263000438A7301975341FFA37B1E21BE6E0DC5D4 +:102640007AED19BD8F27C5D90B1F5C186443B3FF02 +:10265000EFF1C111CD37F8299C4760DEC279BDF09A +:10266000F9C7861BFB97EA1897E6C479A9FAFCF626 +:10267000B783E3BDFB701D1E5C277BAB6048258ED6 +:10268000C0607CBFC8F5F437E8DF5B14FFC4F068B6 +:1026900076F4E2CA7D97A0DFB5AAB2995255D8C5A3 +:1026A0000CEDE20CFE5D8F68F7055E2BF4EBE2CAE1 +:1026B00066EEB7B50599DB70CF003B3292FCD88A45 +:1026C000C36CCF696AC08D7E734DDC83A02A81659F +:1026D0001959E8674ACC0C1AF0778D93EFD72C4F35 +:1026E000DDE3C6FD102BD48FFE335B9A72CAE4770C +:1026F0007B5D99E5043AE9D744C7B07A9F24911FDE +:10270000F254841FF294A91F89CDA67D8A48BC2863 +:1027100036FE1D288509FFB3C087FE9DA4A56E3E29 +:10272000CE95C28FFD04FAAF2F023B36D645F6C1D7 +:10273000920B2C7C7D6853E8BE2B6B3C2FAFC5F110 +:1027400071D871FF43C6F559986027DE1026D3D59E +:102750008B12C2F1CC2321DC878597E07AA3635CDE +:10276000CB03F8FC797B20D70978FFA66FF301092A +:10277000F733FC818B11CF357230D303E57F2D7792 +:102780006662B974C8FA3881A717E0398780619FFB +:1027900094DFD7DC0DCB3DE10BE62B11FB86DF5F31 +:1027A0006CCCB7C7F82AB01F91DFCB4AFC42A2FD20 +:1027B00041FC4C079FFFFD343F2F77F27505F10771 +:1027C000F2D73E6E3F9D523C71B8EF87D879DDB4A9 +:1027D000EF63F3BC6E684F11EBD85AE057C5B04FAA +:1027E00077A1E2B3203F5D540DCF8DFD8D62272789 +:1027F00038E8DAF2A876BDDE3F3CAF83F8944F4F5D +:10280000227B24922F7674ED27F0EF69DDA1339EB1 +:10281000B288C3F14CFFD1FAEE93AEFDAA451C7607 +:1028200073A8FC5EBE3FFE696E1CC599EAFDB8A3A5 +:10283000696933DAC57734F59D89F8BCA3E0E23FD6 +:1028400063BA43EDDC138BFAE27E89CE97DDF9C1E2 +:10285000EB6A2CA45BDF5F47F71F3C2FE4713AEB78 +:102860005491FE01E6D6F87E5788DF47C5BC02AE1C +:1028700057D15F71773874DB0D00DDF37AE80634E9 +:10288000F7A6EFEB7C03D543A0DE3D89F694F4F781 +:102890001ABD6F7298BFD7357EC546E3E91EAF8D6E +:1028A000C6AF8F0F7A4AF8EFC28FB8F74DC7C7F897 +:1028B000997CDC77C4DE751D3BCB3AE00EDBB03F84 +:1028C000F3783EDE9F48FC7C8559A01F5F74FAF6C2 +:1028D000203F3EE3F4ED45BD5762EB4C570692BCFA +:1028E000BC85CFCBE4C005C930FE130302172721F6 +:1028F0001E9AFB9C97BD7FC0CEF9FB809DF3F781AC +:102900000C9DAF5B9CC8D7EC74228D53FF7EC792A1 +:10291000AD871FBB1DF8FBC4DBFC3EBB52D973E384 +:1029200043E4979699312E3E323D20FC0C2D5D7C80 +:10293000C8C73B43E1F232A32196CEC1CC982F9B6E +:10294000EEDB9F319FC7C332A579F8ADA675C222D1 +:1029500011D7D2B31EF48344D63373FE04BA17657D +:102960009BE61E477E91359CCF664EF4C9788E60FB +:10297000CC3289F6F1471FF234B6003C3314EF45F0 +:10298000319DF9E07F0DC2FB51CA9AB97F34459E53 +:1029900093F9534857EDE1F33DC273104F0E9FC7B3 +:1029A00061D8CF69532B32DDC8CFF7387CA80772C6 +:1029B0006FF57D8274D5FD22FABCFB0AD801181789 +:1029C0009A7BB72707F924B7DEEEA3D4C69418D0B4 +:1029D0006BB90AB3619AA231C58E690CB3619ABD15 +:1029E00050D84F353791FDE0CAF16B78BF796ED37F +:1029F000F35FE3FBF94A78B764E0ABDCA6B7BFA3AB +:102A000073763E3FC5FD5E56A799D69FC3EACDF0CB +:102A1000E58D6638336C8647EE33C36538366867B4 +:102A20008CF81EE19E9D5686DF2B2BDE6CA538F4BC +:102A30005771AEA0785E3BE9C509C54DD91827711D +:102A4000FC45A705FD953BFEFA32C559746E8A65B3 +:102A50001867B8FBD318168371BC9BEDEB30BF1819 +:102A60006887FED9E2CDF6B5184FB3ED529D4F43BE +:102A7000140FB5ED6FFCBC4BE7066B08E32E8E6FB1 +:102A80007FFE45E4CBE31BFA931DF6AA14B4607DE8 +:102A9000C14738DDC708BD3E46E8F5E23AF37AFCA7 +:102AA0000A976EAFBA87E2FC372681E3BBB5B22F37 +:102AB00087C5772574FB6D8CB067DD40CFCF8776F7 +:102AC000D37988D0CF79A17B351FD16B410CEAB384 +:102AD0008EA3DA0CF44B5D5C63C6A3CEDF9784CC87 +:102AE000CF27BA24A1E70CCF33305EC5B32415E756 +:102AF000EF67A3DF537FBD8BDB192FBCA0E9F2206A +:102B00008B7B2A99C770AEB25BEFB379FD319E081B +:102B1000E935B0FB797144BB7AFDB12E2ECF5FDA77 +:102B2000F879824481876395FBC86EE8B2232B7DD8 +:102B3000BE890638AF6677722EE16F77F2BD86F9EF +:102B4000AA64C3DEE4BB304EAE4E418F362BB9E3F0 +:102B5000B99F8F49C4E7723DF613F3118F6DF56F7E +:102B6000B8B01CD8D9238C7167F93557FB261AE405 +:102B7000FE87F2B94EB71237C7CB2B39CD93F09CF5 +:102B800048710DFF8E6171FD6DB7DC80F85ECDCFB1 +:102B9000D3672BCC2F833C966CB9EDFA61F0BCFC6B +:102BA00099515EEC0F54712B3E2FDE7892CE153D7D +:102BB0006AE1FE8E48FA04059F3DFA134701EA399F +:102BC000A8EF75CB087A7F9F05EC9B23E383EFDCAE +:102BD00005458EB3FA0F6FA0F830339F02DF4B68C4 +:102BE000BF75AE97BCEBE8E9C2EC9BD154F72DA0C2 +:102BF0007879C88FBA7E290C99EB89A4EF6AC16FE6 +:102C0000F01B62E493C8727DA604E9DC74C97CD031 +:102C10009306FF43C9A16A8ACF8D6C07235898C1D8 +:102C20000EDA81E17528979B789C16FC245BB688A8 +:102C3000631FC461BAC715F91118A2F85236D183BF +:102C400078BD994DC654D7376D39F5C3B1FCAB5239 +:102C5000CB73BFA2FA9C24E76DEE30DD6FDB4F9C97 +:102C6000476FF37058FFEE8F9E5FD464A7B8AEE352 +:102C70002734D2BF0B309E14CBBF68B758C0683D15 +:102C8000BEA5CF788C536EABE7F7A51FABEF335ED5 +:102C90003BCBBC1EA94FF4F9F620FE391AFD7ABED3 +:102CA0002617CE838B781C774A9F8ACC8A2874D2C9 +:102CB000DF4BD42A3271FDD3798FC3BB8EF014CC95 +:102CC00050C8EF9F4A7E9A5CE19F3AE8F6BFED025A +:102CD000BA39A1AC0FFE25EC93D7A1DFF30BD9FBDA +:102CE000807B50F73EFDACAC009DDFA30FF440FBB2 +:102CF0003315165680DF66E23C359C609A4F67AE0E +:102D000096289E71D672F378F0BE6EE3FC5AC0AA84 +:102D1000A9DE22564F69C16A737E21CE472E3C2719 +:102D2000C7E3768A6ACDF9FAB9C0928D67ACD1F063 +:102D3000F635D3C7E7FB02C727DD6CA3FEDDB72A54 +:102D40008EEF7769CC87F36DE72A27E9FF6216A03B +:102D50007EDC29E6FDF207737DB320ED983FD33783 +:102D6000AB0F9ECBE7F3232D19499EF9BD7EC5130A +:102D7000597800BFCF87E1BC5BDC248587216C03D9 +:102D8000511DC19FE3BD26387EE379367DFC386E48 +:102D9000E373F63EA76F119E9B92F9B88DF9250259 +:102DA0001F251BAD267FD1988D52D079399EAF6AF1 +:102DB000A1F7CA1ACE584DF58A791DEC016607BAFB +:102DC0008D29582BE3605675E9F1D025D1CECB1C67 +:102DD00010785C755B5E5F94DBC7D1BEED27109DFC +:102DE000437A4AF8A358D806EDC58CEC82293F7B7C +:102DF000218793E21EBDA6268DBE2F4AFB61336557 +:102E0000FF9B780EB3323ED0370EDA9969F1A52BCD +:102E100024BFBEC1E46F9DCFF1F0E4888A4B2AA2A3 +:102E2000ACB7753A3F21D5539C40703B9FA79D5945 +:102E30009D6AC0201723E3B8BE8CDBD342E78F3AEC +:102E4000B74A74FEF929E9209D0F7EEA5A0F43FF25 +:102E5000402AD009F5EF53125B84F7FC6535DC346A +:102E6000E70DA473568C17E30F4A1BC6C9A50E1AAB +:102E70003FB7E3622BD6E2BE54CA8C212390DF61B8 +:102E8000DC336E86E7A3E33CD45E5F07A77BEAC230 +:102E900060C6DCA1D8BE7FCE1B288FC362E8BC7C95 +:102EA0000AE0CA9940E932B4CF5259E66EB43353BE +:102EB000A77846A04F7F958BB793649167DC84F623 +:102EC000E3080E273C2CF9D61113AEA07652ACFCC9 +:102ED000937AF81CED4D1BFA271C067A4FA8C8C43C +:102EE000F65306F134510BA7613DFBBBE81EA075FC +:102EF000C83C37237D3DEFBB7129B82EDCDF060BC4 +:102F000075D063FBD3F4FD97B083ECFB0B87F0F235 +:102F1000C24E9997C9CFE724A6EBF6152FD7A1FA91 +:102F2000E246A25E7D8FDBF95F397CE407BF42EBAE +:102F3000E53C80A053F9E9581632CC0BE5D3BE210D +:102F4000FBB3FCB4CBF41CEF0935C6959714ECA188 +:102F5000EF3B94B2663A9F505A6F8E83BF22267A17 +:102F6000BB3A9F979F9659306ABB9AF9F9E93E2C74 +:102F7000D8275AB964F3F3D392196EFC569453E8E8 +:102F800039CB6971E1FA710ACE47A8674296A07AF7 +:102F900079375DDADD2DA679A8DDC3E10EB1BFA8D2 +:102FA000E7EBF5B74FD3C4393D7ECF7B5B252820B7 +:102FB000C0CFD34D27C9DF5DD2B49BF0A3F3453713 +:102FC0009E6259D080A7E4AAE6B00564FCE9B8FD8A +:102FD0004B875E0224D9A3CBF33B4B7D63211FBFFC +:102FE0006B6190EFD8AC2E792775B3CA220BFDF038 +:102FF000EED289638D302FDFFD7EF3351381B7B2BA +:1030000086F2F76BE3DE7B6B21C606759D3BE84CD1 +:10301000F73B0DB02D0276003CCC00BB23F213230E +:10302000F25323E0345EBECD194E97BD8C6D8EFBFE +:10303000E01A05F45C5BDFF074BC796479D547D79E +:10304000E0F78E4BB3F8F77BCB9A24AF64D0A3653F +:103050005E1E87E4F0B6683387221E9ADF447D50F7 +:10306000D228B971FDE0A8DF122618DFF318DEAB15 +:10307000E7EBD392FA83F45EAFF50FB1903C3F3AA1 +:10308000E4732A77AEFD2D36C5FC3DAFDEF6BB52AC +:103090002D81B750DFEAF7C7B76DF9A8FB7BAA20EF +:1030A0007FED7D7D7B499F469C5B2FC7FE38BAE54F +:1030B00045C7E3A3434ED17DBA7F18D6F4019A07E2 +:1030C000B1F34E2EC0AB75FF547A7814DA5F7827CF +:1030D0002FCE1F4F48A14B705E7A9A052EC176EF16 +:1030E00029BD68377E6AEC80DAF20C5E09F34DDCAC +:1030F00049C2FF0167CB00FC64DDE9C7FFC2E1A460 +:1031000016BA09E6B6EAEFAFC1EFCD1E18D032C04D +:1031100002F0F78F5F3A99E08B5A9E41F8C2EA04B9 +:103120000E0F6B1920C3FB03837D2623FDD6BBA3A3 +:10313000CBFD09A16FF4FEC50EF61D8943FBAA84E1 +:10314000CF3B782CDA067A757AD1B14DEB011FD3DB +:10315000FF2396F4DDFAB65BAEF3131E827E8C6F0E +:103160004C11F8A67991F4BB42F6445F9C0B13BA5C +:10317000E9E94C6FF6D0BC7169C516B41F52A60FB1 +:10318000A579E35597EF27EE51DDE9E9249EFEC4CA +:10319000EDE6FA5BB650BC46CA434EB2AB1E17DF33 +:1031A0006700B923FE7008BA58DC7C3CFF0D197328 +:1031B000D11B0080000000001F8B080000000000F1 +:1031C00000FFDD7D0D7894C5B5F0BCBBEFFEEF26AA +:1031D000BB9B4DB209F979F343081071139318A9F9 +:1031E000D64D881831B50B22626B7149F84930C948 +:1031F00046AD162DBD5948548208D146040AB8E19F +:1032000002622BFD82458C1AE88288F62BBDDF72A4 +:10321000EBAD3FBDD71B7E8A884256B45CEA6DEBAE +:103220009D736626D977935CA87A7B9FE78B8FBEC8 +:10323000CE3BF3CE9C3973FEE69C33B31ABB86902B +:1032400064428E25DC30C74E9FDF31E6159D4C224F +:10325000A4BB33F49C494BC87B1221C44548F009F8 +:1032600053687B0E21DFEDD1047589B4DEE14D7327 +:1032700016D1B2447CBD45C3E5BD7FD5DEE5B3D2F2 +:1032800072312DD3E7AB12998BF533BD690E5AFE1F +:1032900002FEAEA7E51E569FAE25AD589FC3BE7F6A +:1032A000AA84DCE5A3CFD4763A6E297DAE9DB8B56D +:1032B0009D8E6B918917CA0BE7166C5D4E616A7320 +:1032C000CC427889D79B2651F84E36E66A56D1769D +:1032D000BFA7AFC835845C51E0CDB097D1F940FFAE +:1032E000741CD2442795363CFE1C9837ADAFD77A74 +:1032F000B3643ACFDB1DFE39D0BE5EE39D42B4D04D +:1033000089B7C07705B423889F39763BB627F2404A +:1033100019BCFFFF084F95B8EE5F114F77EF34757A +:103320009D2C24F8F705FDB7B9D7A12A07FAD2BA20 +:103330004E1A87CB77C3FFD07148AD2493143A2C33 +:10334000AB226E8DFF36E8BF79E9077AA28137514B +:103350003DF42FF0BE4E0AEB52E9FC82FB24CF76FF +:10336000C2DECFB2119295E8BF13E621E09EF7C30B +:10337000E6347FD1F07C2C3F78A9E6765A9CB7E4FE +:10338000CCAEEDF4FB790F59085186DBD31E719D4D +:10339000DF7FCFB89A5C499FFADEB086E2EBFD1979 +:1033A000C4B39CB67B5F431A00FFEF73BC953F74B8 +:1033B000F7113285905FD9B5F89D49D083E4DBBD24 +:1033C00088E2B753224123D0C34C3DD2C36088D298 +:1033D000C395B0FE747DE8FBEE07278782747D06F7 +:1033E000C90091613E15C4BE5D89A9BFA300EB2948 +:1033F0009D044DB43EDA680E6D95805E28A0A55000 +:103400003F09EB5F95D8FA07EF30E238DD33191D3D +:1034100076373A43C11C00B68B00DEC6A2A3947671 +:1034200082744864EF9499B6617C6CE372C1523A3D +:10343000F0E2DBB43FB2DAE4194F1FB0843294BB40 +:1034400052713C4A0FAB91BE640647FD8FD342AB2D +:10345000705C4F39ACCBA336EF7C781FFD914501F2 +:10346000F83799C84A63097D4AA4C3E8A4EBC0E1D0 +:10347000215D4F13A083BB60008A877F6F386F5335 +:10348000E8FB9FD825840308CD584E481D61F5758B +:10349000CB2CC7A429F0D4860D09F4DDCA1BBC03CC +:1034A00082BE72D9D348FBF373BA22EBA336C08332 +:1034B0001FBE4B80FE3FB7295628D3EFA7C0F2D3DB +:1034C000EF0B87BFFF39F07D19C0C7E0276D166588 +:1034D000BB348C1FF1FCB980AFEB696FEC78629C58 +:1034E000F87E8FD9BDFF07F045F11E4E74015EB422 +:1034F000B8AEF1F0BAF4D1C74DB47E5E9BD6B182BE +:10350000E2D3BFD486F315F0DE951ABD8EE48DECC0 +:10351000FF94A5A55C86F92F65744F961928E26281 +:10352000F1A21F2E53D25D48A28735D228EFE5F0D5 +:1035300001807F5177CCF7F8DFBF1A62DB09BE212B +:103540008A14073FA72B459261DDFC125B37BD3E15 +:103550003A0FE4563CDC029FFFC6E58DA08B787CD9 +:10356000FF1BE0BB6C24BE5DFA814CE8D7BFD48062 +:10357000788AEF9F90107EF7B489044D94EED64B75 +:1035800012D2EBFA072D21909B83A6E80EC067604C +:10359000FF8DB8DEE71ACD0AA14D36EA19BF05F74F +:1035A000DB181F170C1480DC3B47E7ECA5EB73EE30 +:1035B00037DA9EA0248020A4E537DAAD40FFE75E2D +:1035C000BE89F5B3DCA2105A0E0086E9B881E07F0F +:1035D000B6118A57699611C73FB1570A19A0BE8F15 +:1035E000E239465E9EA3FF36940CCB8D41A800388D +:1035F000FA2C08079D69238EF75D335945C76FD1B3 +:10360000485E0DAD6F593229D4CEE031C6CAD51609 +:103610000DE9904A86F9BF4573BCE0DE225627A724 +:103620007079AC60BB431285B3C9B83AA205FA05FC +:103630003EA0F54BA03E67781D5A567FF417984779 +:10364000CB1E357D343DAF9EC79258BACA19A61716 +:103650004B29C317A926A1F1145E1B2F5B6A2221F7 +:103660002DE063E93472E22ADAF4E0C074A0235B4F +:10367000692FA9A3CFC069E20D51B8A7F6F7BC36F0 +:103680008EB677D4443261BA81A5BFCD3B79D5F0EF +:103690003A0B38AFE97F424BAC381E7E4741F1EE22 +:1036A000B662BB89B3AE887DAEC0EF92354C2F0FAA +:1036B000C02BE01F99E9CD755C6F52FD8AF27A61EB +:1036C000D704D4AFA0FF40CE3D95C0F431C83D90A3 +:1036D000336D8EAAAB1C749E6667D51447191BC741 +:1036E0006783E927A1FE88A7EB783D24DAA5E6B534 +:1036F00016B75AC76E47F90CF116DD90C8E4882C4E +:103700006179D1AF753DAB103E19E9E6DECD3928C0 +:10371000971B48971EE8BC8984F440C78B8C24987B +:1037200040E962116D96489F8BD71B8812B37E8D3E +:103730002175B989CB85BB4904BFBF7B675C7D35EB +:1037400009DB687DB391842DF0EC55D7B7507D8EA1 +:103750007CD6F78521F63DE966F3BD8BAFBBA33A76 +:10376000A4F5D3796F3051DDEA84065DB83E5397F6 +:10377000F5E07A269678731E06BDF22B9D672BA581 +:10378000DB3FF0F512F83966AFAA00BC9BB51A9C76 +:103790007FF46103E2E724D5E3B0FE6B1DE4AE598C +:1037A000F479AE8D78F37580267BD62CDB483CAF60 +:1037B0007AC5D40074D3E0D0A8E82AD3A1C372F9A3 +:1037C0000A8EFFE596D0D61C44F714A0A7F25CA1A0 +:1037D00057C99499B47C4C47ED3B5A6E9963F543B5 +:1037E0007F03604FD0F2FD0E26CFEE77E8713D45A6 +:1037F00059CC57D00D1D07FB335FC59E028E654324 +:10380000ED9F6074C3F5F0BA46730FEAE121FAD573 +:1038100010A4DF229F1EF0FA0A972BF3C16EA1F8C5 +:103820007E851214C88F602FB35F293EE62DA5E573 +:10383000574E1779562940674CDEBCF21D3359416B +:10384000877CF3CC4F1FFB275A7FFEB45E31D0FA42 +:1038500005406B74FD5E918817C60BBE680881BE7B +:103860006CD2337BB469FF15CC9ED1FB372C8471AD +:103870005ED079C0DE694A083DB703EBD33C94A221 +:10388000C9AB3A86CFE0CB16F6BD39F4B39FBBA0E7 +:103890003ED513A4EDA326FF4658D7748392887AA9 +:1038A000F9D75AC2C6091738285E8F8798DD7D9CE4 +:1038B0005649304EBF0DFBA17C9AB690F673A233E9 +:1038C00015E743E52FDA5927D618B682FC5D373461 +:1038D000AE84ED8FEB7CD3D368F9F88BC59EE5B44D +:1038E0006AD0A70FEB293D07D632BBAF5EA36C01B0 +:1038F000FC90FD169C87588FC09AC5B5501F58B2D2 +:10390000EC16908F63F139C87B122337CF9168167C +:10391000F0D3C686DCDE30E895FE891E54AFC44D78 +:10392000179FD28D9DB53DA963F88DEED3213D5FE4 +:103930006EFF40177239D343304E80CA6522F80FAC +:10394000E5724C593B5A99AD63E095546EDFA9EB93 +:103950005312FC47605D5A9EFC8FF7972A305E1425 +:10396000E522E94A46BE3CA9F3CE03BA755487F571 +:1039700075317AFDA483D999F5066E0792B03E960B +:103980000F457D79959AEEC5F304A77F5B84C9F74F +:1039900091F51ACE1FB71A408F4D6520936CD02336 +:1039A00056E85FC1FEA79E0EEBEB69397B5958BF05 +:1039B000883F814F28BEC3463AEF931B6C8CBF29CA +:1039C0001AA09F451504F5E5222DB5634BE0BDD245 +:1039D0003740D7E5D48B0EA42FF2678A158AEFF90A +:1039E00084B73350BB97CAB1973AA430EC0BE6AF1B +:1039F000376C35E5005F7BB53658CFCD12CAB1F9CB +:103A00001D95051B6879C99E2B70FD132A185D2E24 +:103A10000939502F4EE5F2B1DE10D2A31DFE3389D5 +:103A2000C03E88F68FF67413FD28AD64241E40AEA8 +:103A3000ABE8211453A6F6D1D45E26570995E724A6 +:103A4000C66E12F21EE43889B303D5F41114FA8855 +:103A5000C93DA2A482DC1372F998DD97E8443B3E8D +:103A60003F15D697AE27939BBB25C46B3369457D25 +:103A700022F4C0D0B85C8F9CD20699BE323C81CF74 +:103A80007C670EAEEB12D28BFA44E895B1E820DFEA +:103A9000A9E1FB88D1E960BC53C1FE9A4E93F07551 +:103AA00074BCA66524DC3C853D6D53503F323D69B6 +:103AB000647A129EE6CBD097F1FA315E1FC6EBC155 +:103AC000543DD377629D853D933A8DD901539785B7 +:103AD000B4A408FC35DEEA94E461BB26F08ED1A8DC +:103AE0005C09651FC905F99E50F9622AAD0FC8C46B +:103AF0000B7C65A178E9A1EF3773FBB72795CDD78C +:103B0000AD67F4AB937DA4D80AEB12C17D6F3499F5 +:103B1000D8811E053E37DBE87725F01DE3B7A1EF1E +:103B20008DA4C31CF37DD52B26D43F175EB6850C20 +:103B3000688FF8B31DB4BF94DF1BD04E3DF78A0DDC +:103B4000F5E939AE0F5DC2EF401E617E16BEAE4193 +:103B500052358E00ED4B33C6810814F659B383D924 +:103B60005923ED215E9F1399C3E8CA80FBCD0B8ECC +:103B70008107A04CE121A07F6E71327E0FEC995637 +:103B8000FC43FA3EE0B37A18F6FDC540AF06EDF708 +:103B9000E718297D4DD72E8B3E48E7D19C69B58328 +:103BA0007EABCEFED7DFDD41CB1FEED11103ACF3F0 +:103BB000F6697349EED8F2B731A43B3E10C32F77B4 +:103BC000EF54979B7BD5E5409FBA7CBFD3E63A651F +:103BD00041D9E1F982D2B5C1D07ABA87C26B78D522 +:103BE00080FA6886D3FF9013E4AD267A18F06CC88B +:103BF000FE780AF83B02FD9F48F03450368A1431B3 +:103C0000FC035F5F30CDCFB68F82B761FC11A30696 +:103C1000F14CAD75F6443917E07CE2D27B3F3C4075 +:103C2000E7BF6896D9BE02DF786BCBCAC19E441845 +:103C30004960FD4D1FC2BE8BB66B84F53F3593B610 +:103C4000A37035AC67FAB0894412806F5BA8DD6958 +:103C5000A44BFC1BCE6F777744CBC3F47FBB9D3561 +:103C600013014EF92FB20FE8E351E837C64EDEEAF2 +:103C70006472FC4BFB993246F899B602FE9A8D03AA +:103C8000FA4A3AFEF57FF90CE5FDE2A5AFE13E8286 +:103C9000CE633EB3AB4D0AC8A7C50F1EC0F762DFA7 +:103CA000762AD38AFBB6D7361858D9A1C7F2A9CD40 +:103CB0006C5FB9B8570AC13CA55917932A412F6CBC +:103CC000D6D90D64245EE3F1F8C1A6B713C0EFF5B1 +:103CD00001221DF67B12B3C7ECAD09B87F505A1311 +:103CE000C0BE0CACBFF143908F8B376B3D602F9003 +:103CF0007D36F4CF2CDE7CC3C48556E8E7D3A44AD6 +:103D0000F0136DB9013C54D0CE17627E9EC8F5F415 +:103D1000BDBCE56A05F8F1D06606FF62877107D081 +:103D2000D1F57FD1227FC91AE2073BB95BEF9D082D +:103D30007CAD6CDA3E1DD6E78399E91A6CBF4B2245 +:103D400076C08B63690ABC5F2CC93EE0E386F58DC3 +:103D5000B5B1764F9D93F9C72AB397A50C5891AF8B +:103D6000E6803E6DDE4CF908C69FF5DEEFEE700D85 +:103D7000F395346BFD2D53A1FF67751EE0BB217BCE +:103D800066D3B790BEE02F4CF1B598E3EBABF29958 +:103D9000C122F8A4B500E4EAE215AD05F651EC8CB9 +:103DA000213ED944F9723221A79D12F902FC9319E0 +:103DB0004ED5BE63AC7D9AB550837AC6E821DEED60 +:103DC000F4994AB7C9B01FB725C9586F4BD2237DA4 +:103DD000CB7FBA77E76FE8BC9E74FA2F80BECC2603 +:103DE000DE62D06B4AD45E45CD5A4035DA61641349 +:103DF000B3AF89CCFC85EB92C98E5531FB7353125E +:103E0000DB4F5039F105F473EEDD3F1F06FCB6645D +:103E10007D3C05EC85C0C5CFF4E05FB3F64B28DFF1 +:103E2000AD1E1F01BA09F4CF240B8A86E572C0C308 +:103E3000F446FCBCE624E9981C7545B19F4A97827C +:103E4000E56E07417ADAB8D48CF6FE4657C80440CE +:103E5000FFAD7C2BECA746EE0F346EFB85570B7441 +:103E60001E92ECE3A1AC30FE186C9817D2D2713ED2 +:103E7000DC9617C4F29E4A8F96D659B7FDE3CA5C0A +:103E8000C0539FCE03EDAD9E810498DF87DB4E24A7 +:103E9000C0FC1AB66971DE0DA14F5216160DCB0982 +:103EA0009DC65F900476825DB2C2F8425E7CB8ED3A +:103EB000D3940556E63F407D5A3A3A5ECCCECAC905 +:103EC000F0FDF5DF64EB726697210472F08C89F9DE +:103ED000F745BB3336A6FFAE4B12FECDDE2CD03FEE +:103EE000436579A206E4C4F7ED6CFE2E7D6F16F0F3 +:103EF000E54792BA9F252BB52444E552E34A8984CD +:103F0000A8CC3FF3DC4B5920FF3FDCFE52565D0C42 +:103F10007CF1DF89E78D496A7F9AF0AFBAF4E10C52 +:103F200018AFCE63607ECC31FCABA23D59CFFCA470 +:103F300083946B810EC577830D662FD8BB83C4181D +:103F400002975B5D3FF7D77ABDF92ED8D788EFE3AC +:103F5000FA5F0DF444E192FA24F427588AA2289FCC +:103F6000BFB4FC77D1F58C91FF749D8DB04ECDC65A +:103F7000E8E17104E9430F78D3B75865D05729EDCC +:103F80008CBEA2F76B709FE532274C81B8803EDD76 +:103F90006D05F9767D81B9439308EFB342D03E3386 +:103FA000BD10BF0B5631FA0FA610F4C3A5915609E8 +:103FB000FDB476E6E7CFA820F655B4F8B32466E75B +:103FC000B88967BD360FD75FC23807C78BD00F409F +:103FD00047202FCF4846A423A95F427B54ABE99DDD +:103FE00007FD8E45572BC5BA72BA1A2AFF9DE8EA1B +:103FF0004941C723E8CAAF205DB98DA3D315F72384 +:104000005F767B12F4C1BE3695E36B2D973FD1FBF3 +:104010008DC2AF2EC17C6B797FB5466B580B7AC4CD +:10402000A3FB38D63FBC89DAC5B07F4A03BB9E3EAE +:10403000C7B5CF5770DD486400FC0896AB8DA82F3C +:104040001FD34472C08E499DD4BA1BE823755E51BC +:10405000493BEE0B331CA01740D7A27F74E9341FF5 +:10406000B323581C283A538FFB9C96072B7DCC8E8C +:10407000A8417E09AC3629A007A7F5E72C07FA0866 +:104080002C231E03D271CF8645E0CF9D6DF580AC09 +:1040900013F125B252CD779D128B53056F22180F65 +:1040A0001B8E330D6CF921E8FFC622F49B0CF98FAF +:1040B000F309EA8DCB8D43D6AD3621DE45FC68D0C1 +:1040C00046117425FA91B13F9268647A68A47C40E5 +:1040D000FF734A05117FEBA19C2ECA3CDE23F85FDB +:1040E000C4A36C45BE1CB0C82B9C39BF32439C0492 +:1040F000FC776CB31684FD00FA8D5919DDCA4F693F +:104100002820E950FB9FABAA3362CABCFDD0F7C19F +:104110005537575F8BFA77A81EC0A67A5994BD26EB +:1041200005E255C3F532B5838D7D12FFBEE2E61B75 +:10413000A8AA1E94C4F87FEEF4821FD14454E3C5AC +:10414000C227C7F5AFA3FD5B15DE3E38EE26E8EFCC +:10415000A912517EA0D34BE15BAB53F78728E5DF73 +:1041600043418CF77F530EAF5A9D316C1F507BE15A +:10417000CF4965C376C2A3EFD5765D49C7B2D83FB4 +:10418000D583FE15FA3EE092D00E89E7D70497F466 +:10419000D5EC6B65847D9DE062F6F5746049BA2FBD +:1041A00041F91D58E62360DF52BBC4E942BBE4E39A +:1041B000530768FDB9599F1F1EA740BB7BE6C1BED0 +:1041C0002A705146F91BD8A90D49946F8CFDCCAECD +:1041D000A6FA1CE305827E96D839FD388204FC9746 +:1041E000DDFBA432A077425AB36EA36BF903973775 +:1041F00013C7E1FBCDF87997BB985F205058B5A164 +:1042000000FADF2611B01756151E4F5980FBA9631F +:10421000290B63BE6BEC7B0AF1D9B853372A1ECB4E +:10422000A9E104786C79F9452FC88D3321096542DD +:10423000831CEA04BBB6A141031621290DCDBF039F +:10424000E31F73F5643C9D5F06D777819DB706A792 +:10425000C2BCE9BF127DB5D1B708E5C4C6B9462BCB +:10426000C6910AEBEE413CD8CD5EC0C3AAC2AA34C7 +:1042700018A765E6743BC64DA83D07F52D0F7E07D0 +:10428000FD4502AE557DBA1AB077CAA95DF70B0A93 +:1042900077A673468D87F2F538EDEEE2FBAC10574A +:1042A0001F5D8EFFBF6446171D922FF8ED52F48FED +:1042B00092587F67761FB31F6F71E955FEF15B5C03 +:1042C000CCAEBD36189906E4B25F1EB0805D1D20ED +:1042D000DE4F605F4D7C56653BAE13935FAE360597 +:1042E000FD6646D7C0635742FDB532EE67883CF0A5 +:1042F0006318F75CA7CBB38A703E80F283452190A8 +:10430000C7FB5CFEEFC2FA96737BF5DCCB371683F6 +:104310007F51D85F9DCF99506F76DA94276B404ECE +:10432000FE49667903C668641AED67C9E74E1CB793 +:10433000D314EA84F50FF668B1BEC9EA5F04F4DB72 +:1043400078EBFA299887600D15801ED5B9BA08D088 +:1043500031DDBEA01FC5E8F21188234F0BCE972593 +:10436000D0177176CD34F063E1BEC5857EDC2ACEF0 +:104370001FE329159C32222B747C91346CE7BCF925 +:10438000E7D932BC14F68FC6C8FCEED573CD04EC69 +:104390005CF248F4B006FCF8AE08017BB8B957C22D +:1043A000719A0B5FD0C3FEE5EE5EC6DF01BEDFA0F3 +:1043B000F8CBC27894CBC2ED810E46672472781C8C +:1043C000E0F979B69E84D076317E5742963379C033 +:1043D000FBD3F3F84333F737514D88F5AB5CC2CECE +:1043E00058A18E5BF071D74911AF16F05A2CA9FC79 +:1043F000E4E2D9C3BF4F3C189D0EFC1BA5F4057E1B +:10440000A70DD2CC7B5EA7F3DB5036C903A6989BE1 +:104410009293B604DE5352A4782FEDFB643AD00D8C +:10442000A921C8AF2D7D95DA662B8BEB605E8CA53C +:10443000B507EA53EF2A44FD0C719359F4FDB31C00 +:10444000AF6956E6C773AF08E6401C34F1A0EF9E93 +:10445000D761FC2BCCE8874DA56B6373E27325F81D +:10446000BDDCA4F800E86777AD5202F088781FC47D +:104470000B67160DE7E3383D92772B7DEE76399882 +:10448000DFCE406A005E781FB20EC71FC19F07E3F0 +:10449000427C0F9EE7D2C232FAFFC9C096EDB8EF58 +:1044A00037603E486DDF1BEF80FEAD35925E8CC7F6 +:1044B000C6D92DD589B7BE02F43F78F6D4968701C8 +:1044C000AEDBF67A30EF25CE1EB9FE9BCC3E3FB375 +:1044D000DDA2003F6CE5729BDA8FC827C15D6C3F9F +:1044E000196F471E75A9F72743E5AFDD8E64F00508 +:1044F000B7B33C0B21DF037CFF37D8703E01F4D704 +:10450000BF0DC113970FB28DE783F48F9E0FF2E6B4 +:104510000E4B10E8E17CAF09FD92328F7B9DB545D3 +:104520001F002475380ECF01791B5872E6E71ACAAE +:104530007F720F8B23C9128F33FD4A4B585CCC6BB3 +:1045400007FF8B805B764C777B8B403EB27937716F +:10455000BF5193B34061F12E9637D494102E007B57 +:10456000EA55AE879ACC2C5E35E8D087615DA326EC +:10457000FF1F5D18D762DF935F1A94D8B8564F8833 +:10458000D975270A35613D9D670FD807B06EAB59C5 +:104590007C6B289F60BFA1C7C0E290581EECCC4145 +:1045A00039592FE256FB993FAE9EC7A74ECC5AF41D +:1045B0000CA45C7448AD35B03FBBB0AA12FDE80F47 +:1045C0003C39139FF52BD57EFF45E0A7CF1B8E23EB +:1045D0000BFF7B1DF1E899BD3CEC47D450FB4559DE +:1045E000295781BECC21F61520FF95205DADABE9A2 +:1045F000B3833EC168973412D83972A7CB0CEBFB5A +:10460000688706F554B043E3857602CF39C9CC8F6D +:10461000744D32F36BD0A50AC138E2D9A1E371071A +:10462000DEDF72A209C35323B1E7A376B966347DF6 +:104630002DFAEBD0B51AC14F17CDD4A0DFFB82DE27 +:104640003B17FDC6CE020279541DB6D69535AC1E79 +:1046500079E78229EAC3FAEB64664812C509F233A6 +:104660003599E7CBC5E16D6197BA1C1F8F690CA91D +:10467000CBF5C43F212D8FC50F62DFA72633F97517 +:1046800061550EC7B707F3E3C4FC976730BC6932C6 +:10469000D93337B36A2ED0412EC49773E0C9FCAB2F +:1046A0007426087FEE752E09E9230EDE0E30DA80BF +:1046B000BE3A593CF46F853F1EEECAE414AE1FBCEF +:1046C0006E885FD6DBF5188FBE5C3F495DB25A0E2F +:1046D0000D95BFFEFD2CDB27756A799E8D1DE5507B +:1046E0009D9DCDE584E4D91186F7566A2FC03C3AEA +:1046F000B525603F4CBBD58AF368D96F423F70F354 +:10470000B2812CD0E32D55030510B789C72F402B5C +:104710000BF945DBD5B9E8FE03EC84D8763C5F4B5A +:104720001D67F5FE20B90CF6392776BF01FA6AB786 +:1047300009F515FDBF0306F0B3BC9C83F6CC8736A4 +:104740007F1BB40B98C35B9ECD01BB85D94DCDFDBE +:10475000861EB00BEB3A62E27CF09FD5EAB81F5997 +:10476000E944FF3BE956BF6FD814F7DD883860177E +:10477000AEF33ABD7F22F03BD53B987F70B65183B4 +:104780007903F55ACF2290B7674D6A7BFCAC8DADAB +:10479000D796A175F6A0BDB565CC75F614C03AD70D +:1047A0006B883FB69F665867BABE4D7C9DCFBE787A +:1047B0007501ACF3C7BBAF2E80755EA7EBF202DFCD +:1047C000B439FC5B9369BF276FF0A13D25F2582FE8 +:1047D000971EF724ABFD2B43E5FF21FFCA58FA30A3 +:1047E0003C04875A1FBAF44A06C8833AA3E1BFD5EE +:1047F0008BF037AA1FCF68407FC7FE3F7FBA66079E +:10480000C8817E2DDA23A2BFFDB23F0FECA1FDEFE0 +:10481000B83D4169ECFE1BB95FD86D2441F0AB880F +:104820007D80B027E3E5F15B7C3E1F257B6F00BBFD +:10483000E6CBFA8D1BF83B63E85366E76E933CCCFE +:104840006FDC8B7EE4967DF3EDE0273E1D627EE318 +:1048500096178BD16FDC187A2D0C7965A45FB2C3E3 +:10486000FEA371DBB104C80710FB5CBAAF3D938CAB +:10487000F4A8DEEF9E0E9D4880FC010A7725E871C2 +:104880008B2BAA07BA6FA1FB3DC8236C91A387A10C +:10489000DF1617C13C97D23EF5FE4FC47937FAF4C4 +:1048A000287737F64B2190D7297A7F4E06E8359244 +:1048B00061C77820E7B38BC9DED494B2D8F8BAF7D1 +:1048C000F3E4E4E17CB0810D8948BF033AE2B583AB +:1048D0003CDB60E3F24C46F9F6C74D8E10CB0F631C +:1048E000EDFF18627642A3C80B934958A6EBB56852 +:1048F000B6F75D586F90F7E138791F5B1671FBBB17 +:104900004918F552331918CA0F8B6D171FD78778BE +:10491000B8AA1FD25AAC801FEC4EAB07E081F8B8A2 +:10492000BA3EC8F6EB941F96960CD3AF580741BF1A +:104930002DDC0F1D6838FE08D06FA04FB2837DD7E5 +:10494000E461F4DB44F75B90471BCFEFA4579D373E +:104950003A16FF97A6A8F5D150F9EFE45FBD3E45A2 +:10496000CDF762FEC26F3F34CF7E89F165DCBCE2D9 +:10497000F7A9F1FE76B1CFBC5C793827452D0F87BA +:10498000CA7F67795837B42EF1F2501DCFF89BE5F6 +:10499000E1FF705CE3997D4F27C0BE03EC78D8A798 +:1049A000ACDCAE63F91314FDB1F1E2E95AAB97C583 +:1049B0004FB5A25E1D8757A6F3383CE3EBD75ED414 +:1049C000E2BA35F33871F33E9B079A365817639C69 +:1049D000363E7EBA84EC9E0E4B151F476D027ECE8E +:1049E000BB743C75750A8B8F525872206F213E6FD5 +:1049F000EB35EBA749FE9875AF2AA21B8251E8DB85 +:104A000028078933E6FDC6146657BFC6F38BDC7AE8 +:104A1000768E60ADCDE285FD8C5BC3F29F7EE0F2C9 +:104A20006D82BC18A3C2F1FAF2ED4443F1F28CAEF0 +:104A300017E54AB0D9EA013928FC37A2FF8B3C5E62 +:104A400071D9FA3F8EDEF7FC0FD37B3C7EF68BF1FB +:104A5000FED6B8DD7A8A1B155F10A4E323105FCA67 +:104A60001949BF63F533161D1F4DF11D496176FECF +:104A700014CC57B84C3963298D9E003F11D963502F +:104A8000C0AF097E12D48FABD3783EAAA77C26E6AE +:104A900069B37325E21CCE5876E40743EBC3ECC838 +:104AA0000FC65C9F2F6747DEEEF07D087476B2D2AA +:104AB0008BE7011EB551F8617FF89C61D4732EE23B +:104AC0003CC6A5FC2D5FC4D1D517FF4B72D4923ADA +:104AD000965DF975CBD1CF13C07F3A763F419EFFEB +:104AE0001941BC45F749646B8C5F3B1061F97B1938 +:104AF0001C5EF1FE3FF8BEA121D59B994ADF7FFCE9 +:104B0000AED14812A99E2E6572B1C567C5B8424B99 +:104B10002FCB7F695946508EB780DFB408FC8933AC +:104B200009D87D4F3AFD13208FEED1F7AC416D22AD +:104B3000F8DB6711B0F3CEBDCBCA339CFEC99867D2 +:104B4000B76C00E318DDB3CE601E56F9179F3E52D6 +:104B5000538AF0A23FC165509F67B93D95C933F1B3 +:104B60009C3D846F2FFAF33F6E60F9DA0197D70E00 +:104B70007E09E10FB728118C2BB4EC61C65BB996A6 +:104B8000CD87FC3003E9A9654F6531F84D49AFA9E0 +:104B900018ECDDF2DF5B71DFF7F183E99827B1CF25 +:104BA000E5AF027CD84A4337817D9A4DC701BBF7F8 +:104BB000E3DD371503DC42FEAD03BF391D7F9D4D9C +:104BC000ED1727469677BF644726EE339BACFE5A17 +:104BD00098FF3A138323B89D9F4FE1FEF278FE17AA +:104BE0007C9FAAD5E038A9DF35629C5CC885753A00 +:104BF000E237E60DCB93129E671870F13CC7FE9921 +:104C00002C4F8597AD2E75BEE747C93794003C25DC +:104C1000A9F2578B675947E40B94A4B27896EA5CE3 +:104C2000A2E522B3A773ED7AA427DB4AC2E254942B +:104C30009EC0AEBF361A9906E7BCF2BBC3D7029E30 +:104C4000F75FD4209EE49947303E9328B1F1F256A5 +:104C50000F744E007F8CFDADEB6049952E7B15A047 +:104C6000F449A7EF8154E4FFD64218AFEA5F742CF1 +:104C7000BF729F05FD0CDD594D985F79EE3D83EACB +:104C80007C4EFC334856603E656EDF6F314E60DB14 +:104C9000238D9A27FB44AA15F9A62518998E393633 +:104CA000D7BA50CECAFB7E1F04BB43EE944102919B +:104CB0000E9D5703E7D382CB09FAF5C777DB35B0F2 +:104CC0005ED93C3F6670FF7F4EF1E3BE45C40542AE +:104CD0002CBF4937F008ECC7E4E503DF0CC27AECDF +:104CE00071685AC07FAA8BB6A0DF659F05FDACD95D +:104CF0007D792BBE41CBD92BED18071B7CE5EE6CE3 +:104D0000CCE7A7F31C3FCA3C1F4A65F948F23E8B2B +:104D100006F499FC04F1C0A8B223A50AE17E8A96A4 +:104D2000693FDF077A4A1E8E9B823F0AF45443AAEA +:104D30007F07D0CDD0B9A4A566762E899FA7B52DC3 +:104D40007D6F179CF7D9C2FDB907F74F9E85FEBF4F +:104D50004E598275B8E060F9952FA4B278E248FC0C +:104D60001FC43CD6DC7DBF657A8DE202FA97758C54 +:104D70005EE44E570FF8195F49F063DEEE751D6172 +:104D80002DC6CDEC277F5CA3C4EC77D6333DD3B2E0 +:104D900093EDCFE3F73797D22FBF1E92334CBF0C62 +:104DA00095FF4E76CBEFE2F4CADFBC6F21EAFD5EE1 +:104DB000BCFD12BFBF1B618FC7F537961D23F25094 +:104DC000AA86C761F6B44DD84941559E4E95959F28 +:104DD0003B34AAFB5F9F64477A10793B29EDCA7286 +:104DE000C8DB8FFE88A0DF4EE415893CA26015CB9E +:104DF000F7096A8C782ED14DBA307F681C094B12A6 +:104E0000FAD706F0FC6D2AE411D1EF4FA4E662FF59 +:104E10009B8967A516E5A62201FC26C83F4902B872 +:104E2000431B16C178B759713C13E49F24E13E033C +:104E3000F939DDC7F256A735B0B8433AD5CF504E51 +:104E4000CF6774699AABC73C56915722F24F045E04 +:104E5000AA38BED3272CCA01B928F254D6993DE509 +:104E60006017C1396838BF1C6C34F3BC13D66F7738 +:104E7000632E9E4FFEB27929F17816F929FA447F04 +:104E8000A6BB6CE43967413731EB89706DDCC7EC48 +:104E9000FCAA063DCE63B07106FA2B071B3504EC65 +:104EA00081AA7E03A3C3B8F136CED59330F42B8705 +:104EB0004C204F053D5CCACEA5EB5B08FEE0836D40 +:104EC0003BF34E52DE3FD4D68BCF4193D4ABBD12D1 +:104ED000CFA1CE03C9F58DB4FC5AF91AC8B78966BB +:104EE0004994846AD3AFFA964CF5C46072F47D2875 +:104EF000DFBEE17BAC3C3EBA45A2ED9BD33E62ED0A +:104F00008136D3A9D85EFFEFB541EB57D07F7F261E +:104F1000F1F91C35EE64F4EB3C12413F12D77FA54A +:104F20004C3EBAAD7AB49FDC3C1F9554F3FC5488D8 +:104F3000F8D0727B5A31C6EFAD44D91381FA0C0315 +:104F4000B32708E387F6F1CC6F6DE4F4403284BFF9 +:104F50006A2008F2AE3DC781DF0FC9E73D8610F336 +:104F60009BB1F18FBE78059E4B1279B684D833671A +:104F70005F81F936AAF25A133FA729DB33E1BC7BE4 +:104F8000BB8EDBC1BC7CC4E65F88F304BEA4F6DD47 +:104F9000D11B7E5004FC7476EF0FF341CEDDA8A741 +:104FA000FB8451E45A593A936B833AEB4A897EB7B2 +:104FB000C6E66F013A7CC7326F3A1C319A9B54A9FE +:104FC0007700BCC1E7B480D7644E278ED90C3E472A +:104FD000B54F823CD476131B37D92F7BF15C847F8D +:104FE000B6741B85BB5D62F29B7E94887655A19258 +:104FF0000871C8267EEE55CBE58896CB917F6E1B57 +:10500000C897A9C1784DEF135AB0E77FCBE3E2BF51 +:10501000CD519F9FE87133B8C5739656B902E8CF5A +:10502000A5AB3A524BE940ABF78470FD326D1837AF +:105030003E602B770FD0EFA5EC1F95423E777BE6C5 +:105040008F4A21BEA7757ADCBE98728F9BD17F35BF +:10505000B403BC595A4BC1EFFBB5F59748FB2BFA8B +:10506000F2FD0DF56360703519A359706EFE59930A +:105070007F3BACFF85F9C7302EFC40FAD1F721AF5A +:10508000E3A88ED15D3093E7E393EE690994EE0EC9 +:10509000E739785E0A8BBF1E9EC0FCA8547EB1FC27 +:1050A000D18912E621D6CE66E7626F26918E01FA8B +:1050B0003D3A5968FDF48A1CB47F6B799EC8F47739 +:1050C0007C09B07ED36F8FCA20F7C7B2E76E74EB4E +:1050D0009481183EBE4951976F2E5497BFE5519762 +:1050E000BF5DF19709B16593D97B10E8F55589DF6C +:1050F00047710DB1237FBAA420D85D935F4AE7E7DB +:1051000089593EE54FF97EF1A50A82F5293B8D5B71 +:105110008D50CFFDEF5A5E3FD94D8CD94EC407EA72 +:10512000E9A8C4F3325D1893227BEFB1333F346DAD +:10513000ABA7FDEC9DAF201FA75835E49BC0EBA5A6 +:1051400046B4C3045FB49B287D533C968F339A8149 +:10515000DEDB759EF5D097D66C50402F572618B1E0 +:105160006FED3FC8A8D7969B0CC44ECB071F376383 +:10517000B95C263EC823A120CE86E7519D27D40ADC +:10518000F3A5ED60BEED0E1657D796EB51CFD37E4B +:10519000715D0F3EA109119C7FA58CF9A61C66C10B +:1051A0007774247CFF34E76BAD8684518EA5B37B86 +:1051B000390ED1FEA1DF83BFD2F6A0DFAE50B91306 +:1051C000EACF1B27E0B9A8C0D0792F5903C015DA60 +:1051D000B97CE867E7F2043F0BF942A55EBE2B8578 +:1051E000309014F80F053B05EC0482FB0011B7CC9E +:1051F000348A7AD90BFDA60DB567E7E05278995647 +:1052000085352560A7BCF127A0C3B1E445611A9399 +:1052100013E229E4C516C3C3476AAF196D3D0AEF0F +:10522000C7F20C9B9DADC7840CE04BAD794206E8FC +:10523000CD768747F1C5940BE9766AAE13F045DB6E +:10524000D1F2AD35C7F2E518FD5498C6E4006DE71C +:105250004DA2F01E342919C0BFA38CDBCCC6B57C8F +:10526000BDE3BAE9B8B4DD411B1D97B6DB663284F5 +:105270003509A38D5FA1C078971A97A21D913F832E +:10528000AF03A59320F8C10EDA3448AF3378BEF2ED +:10529000C164361E2954E7FFE49BE9F8985FA6CE67 +:1052A000F7B951DAD4017AFA6953C256A0CF373828 +:1052B000DD1CB6FC433ED8696FCC2B388472267156 +:1052C000790710D10CD28BF246C8C10B69C7CAA1AD +:1052D0004CE5E18D6974DE0FE41E9D079D1F723C55 +:1052E0009D8FF6A5D95B935636127E419F026EA024 +:1052F00053E08B213A8D835FD01BB9A51713253757 +:10530000533B179EC2EE25A495E5C52B99C3F3A385 +:10531000443EDDD8CAE6D11844B86F74FC18F3E6F1 +:10532000EE18E7FF1EC035F7CA4FF0BE22E29E3FDF +:1053300001F67714DE7969C9FF7BF0C6DBF997CAFD +:105340000F1F8BCFC5F8D2AC9D981F1E986DC57CE2 +:10535000F1693C3F36D0A0C1B800DD0FE23EA28526 +:1053600018432097A772BB5C9C5B784562FED6E031 +:105370008B06457D3F517CDEB88279E9C1652CBF43 +:105380007CC87E6F56D07E1FD273FC9C44773193CD +:10539000EDDDF728EAFB89E613F5FD440BED2171FD +:1053A0006F8A94329CBFDFDD4390FEBB6DB9589F7E +:1053B000AE65FA887C83E9A3EE1CA2BA1F699D3909 +:1053C0003411F394785EC146C83FF86FF20B7E9AB1 +:1053D00026A9FCC243E5AFC92FDCE6F0EF023A5B39 +:1053E00058E4CD92283DD6EB997F98D2EBA6088160 +:1053F00074C5D67CD8A7DD445ADFD2E421BDFE02B5 +:10540000E97532A5D73C15BDEE61FC1544212DE8A8 +:1054100075884E0BE3F300FDFB60DC6E47EFEF5B3E +:10542000605FD36FF0B03C6896D7192F1F62E059C8 +:105430002033785C5A2DC2F33AF4130FCFE5F04DC8 +:105440002C9DA612C61F63F14FAA4C82B69261FE34 +:105450003199FD6FC1B8437CF408DBCF8E805B6B64 +:10546000457A9A73078B7F052CCC2E8038581A1DED +:105470007F261F7F4EA7AFDA01ED664A0C0F61FA57 +:105480000F857F16AF9FD9DF8C7970B3AA75C7637C +:10549000ED20212F45DC6D2E6F7FAB7DA60EF2D265 +:1054A00067D7AAE35D73EF64F1B639B3D5FDCC25B8 +:1054B000AB3FC17C4DD2AA03FCCDBD535DFF49DAA1 +:1054C000509C6C02C4C90E713FD020E513E0A3D7F5 +:1054D00093176FBA87D2F9849F149580DFF0869472 +:1054E000C66D4FD0F2B31B2761F9F594EF7EFF280C +:1054F000D46F29C072355CE204FB56E043CA67856D +:10550000E577CCC849007DC2FBBD87E07BB7D9DF1A +:105510003D93B6734FC9C53CD66AEED7185CC8EA4E +:105520006FBED2C65295EF52D05F5C6D66F7351DE7 +:10553000297EBB04F2AAAB7379B9E4D549503E2465 +:105540007D82F73A9C6BB6CAB00E2DE9CCCF3EB93E +:10555000500A4FA478A976F2FE9BD9BC6A4B9E4BA9 +:10556000073EA9AE62FD4CF65476E6413BCD792C60 +:105570009F4B372600FE05BFE5F07D95B02B7D5C87 +:105580004EBCE43DD69144FBF519250F4CD1577123 +:105590008CDD4B6665E7037DDE1C19FCF4D3BC2C67 +:1055A000EFB6CAB83C0DE4E12D7E7D29CCCB6E2C44 +:1055B0003E0479118915956598A76D24B8BE94FEAF +:1055C000C7A7033F5EFD495602109D554DFF82BEA1 +:1055D000660ABAAF56D337E5DBC9E9659796DF2A85 +:1055E000FA360DD3F758F63E85AB02E1FA865AAF8C +:1055F0000D8D13C79FF1E38E2537E02F56FE0EC3A6 +:10560000D78B7C9801D98D79C0A75D824F6F023806 +:10561000F49A089E8FCA963C93F0807185C7887A69 +:105620002F8E5F057C99E0332F190917FCC9C26ED4 +:10563000657F2EF0A364F07AFA9D973887E1A2E3A4 +:10564000DF910E7AFC1106CF66A995C919BE2F11FC +:10565000FE971631DF3EF57CCBCDEC1E0337F8CB41 +:105660003076523C6908EECB5807319F00D7E7B33C +:105670008D3E9B9ECEED36473DD2CFED54A33A28CA +:105680005EC274FF0F701ED404F7C17E6F21F162F9 +:10569000FC9CD247203DC66E12F0C6E3A9650CB94A +:1056A0001A3F9F78FC0CAF5B240D9EE2FCE1D07C9E +:1056B0002F739EF1F68A4BAFF65B3AB97FD139EC86 +:1056C0004F2C84FA5A62F6A03FD123E17EAF96DADE +:1056D0001F20A76B6B08FA719C560DFA13851D32BB +:1056E000169F5CFF4D26B76A9B083FF7C8E6174F29 +:1056F0008FA964E07E78D61A950D0B80FF1BACAAAB +:105700007306B556168F784EC8113250067A7FA8A8 +:105710003C42EF0F94811C8ABF7FAEF622F37B3BA5 +:105720002F4AF8ACF51C2B03BDEFAC1928037956B2 +:1057300067F7FE14D655DC13198FCFBDE91A919780 +:105740007259741ACF47220E7AC4E67F393DC63F9C +:1057500075568AA09F75B5CBCEE7E7CF017A76D88C +:10576000732AC1EF34DBD8AA03BB38D1E13F90CE16 +:10577000E4E8175FC0E6179A523CDE56ED7F5866A4 +:10578000C3221EEEE578B881EBD9F39BB4B80FA91C +:10579000F6163E0DA1A0C09B3A1242BEF5A27E14A1 +:1057A000F7C69DA7065518DA3F6F437DBBF857F53E +:1057B00018279BB05E4394187D39316456DD7F32E3 +:1057C00079A75355BEA2375DD5FECABE5C557D7123 +:1057D0007892AAFEAA374B54E5B2C85455FBABDF0A +:1057E000A95295AF1998A16ABF03F43DC5E3374E9E +:1057F000CF52BDFF68E3F437213E7D5DF43BAAEF55 +:105800004F703F04097A238574FE0B04BD5EAC53D0 +:105810007D4FCD9AB0540E7CCFFE16AC6679F795CD +:105820001463B1FD2DEC52DB13379028E62BB684C0 +:10583000244F9840DE9DBABEB1AF07F17AA97B0F25 +:1058400026B8E66BC05497C6513B632220825C0D9C +:10585000798363F1FBA5D6BF80E47FA9F537B8D57E +:10586000EB6F52D4EB6F2954AFBFCDA35EFFC40AD8 +:10587000F5FA3BBCEAF54FAA51AF7FB24FBDFEA986 +:1058800073D5EB9FE657AFFFB806F5BA67B6AAD750 +:105890003B7BA97A5D73824B54F5F17420E849C8CB +:1058A000CFBC95F7AADB53A46862E842D0D9025F67 +:1058B00003E6638DEF7A48355E3C7D4C203C8FF4E7 +:1058C0002BD247E5386E7F72BAA07AA96A5C32DAC9 +:1058D0001937C073EE046EFFFB46B73384FC8AD5DC +:1058E000EBB1FBE6B1E4DA087DC5F7D163EA2BD86A +:1058F000479B86F7D163D1EFBB84EA591C7C35FA0C +:10590000CFEEB033380E9A993DFF29545D43DBD179 +:10591000361514DE77613E74FC77CD93D10FF21DFE +:10592000D2AB8371EF24117CCE23517CFA895D7553 +:10593000BE6501F1E9B95F6409E0A9C938500E7A82 +:10594000FFC2FCA3EF637CEE48D265DD07721CE268 +:105950003FE30939C5E5C9498803D1F23913F7276F +:105960007A89E28AC1E729EEF7AC9B26A19E255AE7 +:1059700033E6B1D5DD2EA19EAAFB0FF66C1FC7F44E +:10598000DA88E75281D72E6E1F303BA10F0EDD6201 +:10599000FC90F8AD688F7AECB0DEB43F1687F9471B +:1059A000767FB1DBC8E0DC2511B9C289C70671DD9D +:1059B00061FDE17C9BDBC8E0DBA52346C0EF64E230 +:1059C00047FBF031998A3CD6EF24D6EFD15CF01733 +:1059D0009ACD6F7EAB1AF2A9E5E072F4DF7F8FA853 +:1059E000FDF777B64AE8BFFF1E859B3EDD768F1B2D +:1059F000F4B228EF02B8211E00EDE8FB5477AB04A7 +:105A0000FEB1AFADBF3D0FB1765FB2BFA17E0883DF +:105A10000BFE603D857F3683D2B781D2CBB6EF11C6 +:105A2000F41FC6FB6BC769A90681FC311DBB97C07B +:105A30002DAF67FBE2C31EBBCACF44740E38477A52 +:105A4000297B0EF2BE4FC59CD3A07434EAFDBA1F69 +:105A500065B07CA4F6B6C844884B9EE371D787DB5B +:105A6000DEC4B256F6605E26DCF7E588F95EEFA28A +:105A7000F531724EB6D2EF63E48DCEEAC3CB6B1E26 +:105A8000698B60BC53C7EF257B34E35EBB3FC6BF69 +:105A9000F2CE386E271983C49E42B8694FFF4E4F2D +:105AA00023403F5ABB7C2A761F6D70D3FE62F5EE11 +:105AB000C564121B7F58D9F60EC2FD88E4F7436710 +:105AC000867C1236517C1B6438034DDF6FB811E5BC +:105AD000AFDE76AF07EEA11A0B7F06B77C21567EAC +:105AE0007E388EDFCFC5E5E7936DD1C9304E7BDBC5 +:105AF000800A6F5D6D17F1FD9A3652C4EA3FC47A91 +:105B00004D8D82F4738AD24204E27AF2800DFCC198 +:105B1000D43E26107FD6B98D186F30B818BCE4A2D9 +:105B20000BE9639E9DC1003EBF4C4A1FEF2FD5E19C +:105B3000FEFABE4C2BB6BFEF37E30F7829DFEA2918 +:105B40001AB47FC37C86C761F8D373F94964BF0F69 +:105B5000E4803E5DC63885D33E0BD7F1CBF627F007 +:105B6000AE3711CC47D6675AD15EB85C38DD196ABA +:105B7000BCC7E38FE209E5FF7D1C4FF73DC8FC93EE +:105B8000F7DD4FF03C05594AFFCA87E96A1C978741 +:105B9000A9C487CFAE362A080DB05E46E29F40ED1D +:105BA00011D28B8D4DE0A7827AAFEC80D48827AAE2 +:105BB0005D33E1B9A6E26417B0E3DA6B3F8BC01343 +:105BC0006211802F7B0309C155BC98AB40C777F8A1 +:105BD000593981D727CC65E5445E9FE863E54CEFF2 +:105BE0000B523500161747CBB43A6FCA0779BC8001 +:105BF000B073F1FC7E8DCD84CB0BAB736635D4DFF7 +:105C000049F09C8BA8FF09AF4FB31E5F99077A63D9 +:105C1000B6FAFB0D1C0FA9D6E35DD330DEA6AE1796 +:105C2000F1AC64EBF937F1FB2275FD53FC7B9BF57E +:105C30007C641AD4E7ABC77F9CD75BAC2CEF8DCAD2 +:105C40007E767F03AF7F8CD79BA01EC62F64F55A4C +:105C500071DF096FD7C9E118E2331E430C2633BF49 +:105C6000F2963623F2573CBFDD07F773950DF39B91 +:105C70007D2919F5DE86FB3298DC495006BCDE51E1 +:105C8000E4A2A877DA65CC37D0BAF5484F062B974F +:105C9000279C1F87E489D4EA6144C6E4F4A5E89A06 +:105CA00012F005906B59F40FE83AE3FB1AE28F917A +:105CB00073E94D66E28FE583054E5539E5CE74559F +:105CC0007BD7EC5C55BDB57492AA9ECC76229FDC46 +:105CD000CBE9CB5C54A2AA17F765906DBC9D9DB52E +:105CE000D3E54F55B53B5FA824028D9FBA49DCA38D +:105CF000E631827CB8D7969B0AFCF8B3B60A444ECC +:105D00003BE527F6B4F3A71B8C59FA5478B910CBAE +:105D1000CF3B587E7F7B9B879573089EAF6F6FABA1 +:105D2000C1F22ECA9FF0FC699B179FDB6959A1CF76 +:105D30007FA4FD2BB49F1EDA3F949FA1FDC3733354 +:105D4000ED1F9E3FA1FD43FD06DA2F949FA670C173 +:105D5000F329DA0FBCFF31ED1FCA4FB4F9B0BCB65E +:105D60006D2E961F6FF3E3F3B1B6067CDFD9D68AAA +:105D7000E547DB96E2F3E1B6203EDBDB56627D2FA2 +:105D8000A793E7F979DCE72BD9BD03F1EBDF9F217E +:105D900061BB2F9D9F534A157AB92A3FA73F03FC49 +:105DA00002BDEAFC54C01FC26162788C87E36806BA +:105DB000B30F2791C8720B931F18071FDFE75961B4 +:105DC000A1FC35AE95AD7B4E5F14EBD31AD8784766 +:105DD000B99D405C419251CE8E9B43BB7352A4CA85 +:105DE000C2F207D00F43DC143FE5EC5A7246E621BD +:105DF0000DC02557503D1E33AF217C39189C80B70C +:105E0000D1E0FD578E376D692FBB5FA7A62B0C6CB9 +:105E100066F6B6E2FD3AC6B9BEB04C9F2E9F1FEFA4 +:105E2000E99874713ADD2452F976F19B44A1CF8C44 +:105E300026F5FE317D41896A7FA6BDB8862857D1F7 +:105E40007E8BD4FB3C73FEBDAAEF8C190FA9EAF53B +:105E5000AE15AAFABABB731E71033EC7B1B89961F9 +:105E6000F5720221E485DD4F205CE64C368F73929B +:105E7000C27E5F6037FF3D13BE7F79D6CEF1655C91 +:105E80008DFBF2090E562C480C6A400F7DFC8B44AA +:105E9000947F3B9ED1A09F7E22096940DE4CA6E6FE +:105EA00024D45F01378C6BF1AA262D948B89A285AF +:105EB000F255248AFB3ABA7FD164D2F56BD1FA9FAE +:105EC00031D1F2D94CFFB32CBF308CFABA80AF6716 +:105ED00081D8C7AD97E3FDDCC64CF437A9CF257652 +:105EE000F0FD4B8789F90D973BCA53C10E3E3746EB +:105EF0003EA8CD7DE28D0514DFB6B463F814EF1F24 +:105F00005734A39ED7CFCB94BE5A5EF77AAA4FD40C +:105F10007C9307F3385BFACF29E0766BC98F22FFB9 +:105F200074E8843C5312419E0D973D8924661E3BC4 +:105F3000DADEC9935121FA116F325F37315FF94FC1 +:105F40009576C84B2CE079D13BDBD2F2ABC70F7F03 +:105F5000EFE37450482235A05F0B8B349E1074E041 +:105F6000B5ABFC31A6FC2E2F9C0B934B8807C4F2DB +:105F700044D285F729C87FD5623E9A7CF01AA25098 +:105F8000FBD86A0D9360D170BF84FB75BECFE5FC72 +:105F900067F66A9C8F9C25EC260FE874F299D51B56 +:105FA000013AFCAC5BC7D8F4B8BABED04A50EF2D6A +:105FB0002AD4871409EECBEBC27B40E52D12C9C869 +:105FC0000138A6B9E7837EDF6B413AB6AC2FC79F95 +:105FD00030B859E3AF40FC0E287B35C2E8A2ED9AF9 +:105FE00027EBB7823D3901F06205BCDC915F0D43C0 +:105FF000E717221E17F2792FE4F3E8C81CC23F838B +:106000008778BC701FEFA26EE18F52CFF3F1D2AA56 +:106010006FC3BDA2ED112DFF9922353E57E92253E2 +:10602000E64BC37051381766825C01B8AF820FD857 +:10603000FC9A9F91C8C61C946B35686F9469303F79 +:106040003D9E2E9B3299DC8F66D8D97DE4EE534875 +:10605000CFC3E5936F2C48C2FD33B35B6C32CB8F5B +:10606000F47A9558BFF72AE15FE4E772CC1CDEA111 +:106070007B0527B1BC602B89AC87BCB4B1F6F52B8E +:10608000327370DCE17D3DB55D203FA5CC88795C45 +:10609000AB443EA172549969634F385765E474FA72 +:1060A000A84D9DF7B39DCF6F3B5F8F41A3C87BF297 +:1060B000D616C79CF3A9EBAF473F9688D30E72FF65 +:1060C000E1A0591D576DE4A43078A8ABCA0CF1C10A +:1060D0002E16A76DECBF99DD6BBBEFC7782F30EDA7 +:1060E00053017AA8E7EDEB57AAFD580B77FA915FB9 +:1060F000E3FD64F17E318A393DEC1FE3FD625B33E1 +:10610000F97EC2438A210E7B6275DE6133EC7772C1 +:10611000089E0F1FA77D01EFDDA6BB812EB84F970C +:1061200014B1FBA3E2D7FF54961EF1B253ACEF7843 +:106130002BDAA53BCB981CD879E0FC2DE3693F2BEB +:106140007324D5F98095393A5CA7B7297DC3B397F5 +:10615000909AD1EE293B94A9F96A72EF5AF5EFC1F2 +:1061600034F70D1CB62828FF5E03BA1F3CFC7942A9 +:1061700011F251147FBFC408C23099C10DE7B37644 +:106180006B3E99174B0F6F67CA58FF36A78B2F0DC1 +:1061900057B51AAEB3456FA5CC6070FD0EE4C6B915 +:1061A000F0F194587B46C0B57B8CDF03F8F0ABE28E +:1061B000A942AD1F62F074FABFC3D36EFDE8F0FCD4 +:1061C00095C3F3B343EC5E9B91F55F519F75ABE1D3 +:1061D0003DFB7C640E88490AEF5F117FEE9329181E +:1061E00013E6F8EB2DE5F459CAE58F07CF5091C0BF +:1061F0007B57631E66AF4C926AA15CBE007FF72C92 +:1062000093EFC3021A3F9EBF21EF1946957FD764D3 +:1062100031BADE9D2E8D8A87D22C36CF0347EAB263 +:10622000C1BFF1D83B0602726133CFBF7ECCDE6BBB +:10623000847BA6051EA15C429F017D741128BCC70A +:106240004A3F332AD651C6D3B0F1D6C6F18D184F86 +:106250003CA76415327B553AA48573386BAF7D0B30 +:10626000EF7F5B5B2AA3ECFDD2F85F1D87FFF05B3D +:1062700029B7307A999245E16B91FE90F06D5A0EF4 +:1062800048D17F2A827C15BD1FE71FA078EC91467C +:10629000E2292D8BD18B989F98BF80DB76DD025C45 +:1062A00007DBBB06541AA5BCBDD017895CFFC1BC77 +:1062B000505F5C2BB3734C6532AEFBDA8AA978EE83 +:1062C0006C37CF17895EA31FF577441670BC3D76F7 +:1062D000F1B711B84739D8AFC3FB3F883CE0BE15D2 +:1062E000EE1FFF8D8CF789537AAA81FBCC0E1C39E7 +:1062F0009F00FBEBF9593A847B3E97878317B535AE +:10630000781EECC867766D0CFDD76569B97D12897A +:10631000C039AF3525EC3C8B95DB03D623271B001A +:106320007E6BC543062986DE66651910AE35FA68B0 +:106330008A87F617D8A72561E6FFC17B1987CEB3F8 +:10634000DA191E5A4A0FA1BD60ED67F735D66529E7 +:106350004CCE52B8F7D2F7E6899FD9EBA1BE948E06 +:10636000973BFCBDCDCED6D35CC6EE4B5A7BED3F02 +:10637000DBE13EC844F81D47D8EFF2790AB89272C3 +:1063800035BCDF482417F8CB2E63BE5A6FF85E2366 +:10639000D8FB822FDECAD562BB47F93989472B0A61 +:1063A0004370AE4CD0B135DBFF4016CC8FF2C50B3D +:1063B00068EF447CD3103FF662C833DF2545E632F0 +:1063C0003B446F073E2CD46854FC16E1EB269E54E8 +:1063D000FDA3DD733FA75DA1F73B424602E74DFEFB +:1063E00078716622D8A71D19C2DEF31A015F9B25BA +:1063F0005F620E8CF32F5ADC0F1E3872BC01C6EDA3 +:10640000A0F302BE7DF875EB6AB0533AEC5EE4533C +:1064100031BEECD0F0F560FDECD67BDF047F64D4B8 +:10642000C1EECD3A38758611E89FB6D3403F7FA0C4 +:10643000FBF7F004E8A71AFD060BEDB3A6C3778BB4 +:1064400088FF11B06F17756B55F7833CCCE5C5C25B +:106450008B16128ED92F2CACF80E9E6B5C78310106 +:10646000DF3FCCCFED3FCCCFBDEDE2F878993F5F79 +:10647000CFFA8AFB6F4F9CDE4AFEDD8E3AC6F7BB31 +:1064800060FD9AA5013DA8FA35533FC7F3647F68C4 +:10649000B393B02106DE11F34C22E1987187DA5DE7 +:1064A00034917052ECFA32FA1D9EAF15EBFFD0E634 +:1064B000463C8EDDFF38151E87FBCF53E17164FF2C +:1064C0000558FF87B6C24BF43F798CFE7354F00F2A +:1064D000F79B8FEFCF1DAC7BD642F9EE6078C5C637 +:1064E000574BE1F7F70CF87B1BA4AFB70ACFB9EE17 +:1064F00022780EFA81FD7F7A1FF2521FD8AAF7C0C8 +:106500001883BAE83CCF287A269FD88370EF9C780E +:10651000BE9D9587EB1CFFDE2887EC90676A2C9464 +:10652000EDA0E78C24125A01FB975223CA3911DFE0 +:1065300012FDFE3453AB92B3E27EA1469E7FD86833 +:1065400061F1AF26ABFF2CACFF124D57CBCF681FCC +:10655000A70B3BF07C3B210EDCD788F88E0CFBC5EB +:106560003C707DF9089C0B9B97E3FF0CBEFB091563 +:106570002B10EFD15EB1CD0FF9798FF37DE4E3A657 +:1065800088DB13233F75D9F257B31BBAE2E8B7ECA7 +:10659000773BC28C7E75D940BFDAC8CFEB72E07C06 +:1065A000E300BF674E41FBB9AEF430DE475927FC2C +:1065B000022BE3F356321D604F8B785402E41782AE +:1065C000DDB086DD53586F61E5FA5F27E1B917BA90 +:1065D0001FB214819CD9AD65FE221E073BCF611E00 +:1065E00034AEC902FC0EF27C97F3FDAFE1BDA7E724 +:1065F000578E473AA8FFE50FF11EC3DDE94C9F0D0A +:10660000EEB3A13EAB3778CAE15ECDDDE9CC6EEDED +:1066100095C309253176ECA3195528A73F5E395E4D +:10662000131B27199FCDE4C21AE1FF94A3E570CE96 +:10663000EAE3D2F03FA13EDD63C2DF1BD3ECFD53A2 +:1066400039DEBFBAC680BF6351B577E2BAB9B05F71 +:106650004C90311F5BB3D784F09C5DC5EE83836F94 +:1066600041EE35EF1D87BFCB566F8962DE64B3D92B +:106670005300F1C1FABDDFC0DF9F38F1F8C42C90A0 +:1066800083C793952CBC6FFB718A743AEFE3FB26AA +:10669000B0F79D57E3B96ADB1A8B7F34FF88D04B84 +:1066A000F1F7CDED4E2F3ED707F89968F4801C5EC8 +:1066B00038E45F67F707D6BF199DA524A0FF06F34E +:1066C00017EAEDA7F0F71DEBBB8FDD49303EE9423D +:1066D000FA15FBBCF871EBB9FEDAAD8FCE83DFD5CE +:1066E000AB6FE7F8E7BFF759AF29C6DF9B14F85F38 +:1066F00013771FF3F738DEC5F3C41119EFB9A47689 +:106700004516F88F4EEC3720BD9D583319EF5710C2 +:10671000E3D55358ED944F8F3B9529B0BE0BB2157E +:1067200036FF76B67F15EFE9F811F8BDCEE83E2DBD +:10673000E6AF0DDAA30910C714ED4479683EFD5A9F +:10674000FCBDB7DDE90770DD295D11A02BCD2F6DF4 +:10675000A8B703BF64BF1BF7712909829F34F88E65 +:1067600001F77B07F719D09E1E7C979DCF1F71EF15 +:106770009F359A05F7DC067E390EE5DA6066740B04 +:10678000B3BF4D78CFE4E051FFD53C5E9CC6EFD15E +:106790004C03BBEFC23E5318EC3EFAC4B843906CB6 +:1067A00073E3FBFD16BC2F883ED9F924698F1B7F4C +:1067B000378974F1EF23F8FD0359FE0920A71FC89C +:1067C000A3FD5BE1FB93D8EE42AEFF4A8C591192D8 +:1067D000CEC74BC77E33FDD9F85EFACCCD7E0FA86D +:1067E0008BD747B03E60F05F8DF3F8BD8DF48C32EF +:1067F000CFAF7A5FE47DD949B88E026E8A67B42341 +:10680000E3F1D293CDF69F021FF17439B49E9780C5 +:106810000FFC3278BFC03EB68EAB26EA993CE99CAD +:106820008CF632DE30149327B87CDF074897833A22 +:10683000EFD3A097A2477584DDC3482D03F05754CA +:10684000B076F516E6F710709CE1E7071A3B591E83 +:10685000E199E73EC89A6F85F3F31FA8CECF0BFFEF +:1068600021ED2401FC33568F925057C4EC762DC293 +:10687000C57E8F6E8D4EC1DF0B0C3E3E11FD122783 +:10688000F4CA5EBC0776D5151AA0276D3197BF4FA5 +:10689000B07989FBDDC43D6DF17819C866FAB2990B +:1068A000F8EF823BFE8F132585074BF1BE4A74FF3C +:1068B0006B20CD52F69A587E3BEA8591F742EA2F3B +:1068C000F17B82FFBBE553B05665809F6002E8D53F +:1068D000D376B67FC45B2240BF6BD93C3BE003B8A4 +:1068E000FF82F84E835EC45B25281E4E4BAC3E9E55 +:1068F000CE84BC1B810FA01BE817BEA37D7F9E9D8D +:10690000C3F63F76273F9417D4435EAAD057014978 +:10691000D6C07D0F271D4A02D0E5C9CE3CE772C81C +:10692000F7712829B1F676E010C17B0E1438FF7399 +:1069300035FC2E92770AF805773BD5FE8878785E8D +:10694000A81C40FDF35F98C6C553008000000000FE +:106950001F8B08000000000000FFB57D0B7854D5A8 +:10696000B5FF3E73662633794E1E8484409824E436 +:10697000018430090F4141074810156878092885BE +:10698000930710421E88B6175BDB0C24205AB441D3 +:1069900051D18B76404154B4414141037700A55811 +:1069A0005163D5566DCB0D88BC1F31A897FFADAD97 +:1069B000FFF55BFB9C64CE90A8B5B7F93ED8D967CC +:1069C000BFD75A7BEDF5DA3BDF7C433FD7096175D2 +:1069D0002B42F41022CE6D11629810A3DC82F34298 +:1069E000D885C811FCF38DCA89DB3A5C8885F88D9F +:1069F000AAAAF9DAB59EC82BEB2D5C1FE375467782 +:106A0000F1BDF1B5FF50F228B3214C0887FE3D5D82 +:106A1000880F311E8D7BEA90DDA70C461A2EAC093B +:106A20004254AC75FA451AA56F4ECCBA53E685426E +:106A300075C76C5C99D84AE3966F2ACA1291B21F47 +:106A400041F3AAD0E7559EEACD52870AD1F6A8EACB +:106A5000DA84F6EB559E8F6AF3B81EA5EF27D6DBD6 +:106A60005CCBA99F0A7D3E277A6BD1C5B994B70A42 +:106A7000ABBD80F2562DDA45FD2E78542DF677B158 +:106A80003EAAF781B5A00BF8604D893A7C32A81E6A +:106A9000D66994E3BFF7687257D1FCC2E977CC633B +:106AA000A3E2F7D1FC4EF4D1E6217FFC9330B18212 +:106AB000F2EADA45D1EEDC2BE17DC2A1457B720121 +:106AC0005FB91E039EA1E318F0BC0878C620BDBACA +:106AD000C54BF0AB7D48F5A0CEBEE64BD180DF982C +:106AE0003D4547AEC1F7B561228CDAEC3B9CFECE4A +:106AF000AD348F8BAB55413D8AD23D198982C6DBBF +:106B00006EF97C2EE073BF4DCC7A91D2D2B7A747F5 +:106B10005B28FD46A71FF5210927356A7AF47CAE6C +:106B2000DF3EB998F2C7DC9EC482A07A3FD6E92C3A +:106B3000145F656BFF168D712AD6D8785D065E2EC0 +:106B4000621D34BF8B8D11FEE504978BBDDBB85FF2 +:106B5000034F46BF15C083414F546FA5DBA58FE39C +:106B6000B31747115CD3B4E19E2EE864C183342E81 +:106B7000FA5B1FE575E67DFF710D7874E09B962545 +:106B80000CFC038F4FA46DBC97BE59DEB30AD193A2 +:106B9000E0D0787DAA42DFCBF6840985FA2B53DA60 +:106BA0008E28099C77FB14AC7FF13C8C57F67198CA +:106BB00005E5C7F75E9FC7F30AC12BC129B52B7A3C +:106BC000BF98D696EA0982DFC53E6D7379BE067D11 +:106BD00074CE9BE751BB374C605F5C4C237C4676A0 +:106BE000C2B101F819C6F55D76A66F6F1EE0D7B188 +:106BF0005E57C87A5D21EBFD40307D0B8FC6EB29D7 +:106C0000FF24CC82EFE50FDC94E5A6718EDF3B8E8E +:106C1000D7753CCE9B87FD753C95FACFBD729DE53F +:106C20000FD03A73BF659D8D4EC657B7EB8C6B7B0B +:106C3000427CCB3A37EA7468ACF333AB3BDA8AFA7E +:106C4000BB55B19C8A6AFB14DF7F8DCCBB56D0D07C +:106C5000B536490FB56B23FCC0D78566DB047F6E64 +:106C6000271FA0F1BE273D58981E8E8F753F3C020E +:106C7000F4759FEAF2B9019721EFFC9CF2C7EF5738 +:106C80005D02F9B1127EC40F2CE00FC7538B27733E +:106C90007EAFCDB582FAF9B4F16F7F04FD5CDC63A1 +:106CA000730B5E5FF1FDB390A7F982AF115C6EC606 +:106CB000B854CEEB57EF19D68872F1E86057A6BBEF +:106CC0000BBE1402E78A35AA691FD201C1E3D53E83 +:106CD00090E2C63A0C381387CD9A3AA8131EC84FD3 +:106CE0001FD409975ABBD09AF8FB12FB944141FC80 +:106CF0000CF04997E744FF3CC9C7D2A283F673C89A +:106D0000FC42F98F51CF48FFD2C157CCFC7851706B +:106D10009EE05019925F1CC237AA42CAAB43CAB761 +:106D2000F7FA9CF940E8F813D3E4BE31E058AAC35F +:106D300071BB45917CE43EC5BF897E2DB5BAED4B54 +:106D400069FE2F8E11F3D04F995538AEE57DD9CE1F +:106D5000EB2BB58A86B0027CF7703D63DDD45F43D0 +:106D6000581CE5C3251FA27A13EC417983DF1AF37F +:106D7000094F93F030D2C55B9D8DC783E059DD1478 +:106D80006BCAD7EE4A6E3CEEE8CC2FC62FC9F46F23 +:106D900022AD7E38E0227FAA77B51E8C20FA49B258 +:106DA00068E169D4EFC583FF1B9DEB66BC0F2F26FE +:106DB000FC16A8E92F1DA6F5B6ED563D9BD0EF9B1E +:106DC000F2FC115F5F7A781B7DAFD99B21EE75775E +:106DD000AE3F148E17775D8A4EA7EF170ED9C30505 +:106DE000C901A5CDF163EDD1BCBFBA84BB5B87BB44 +:106DF000D1DF056B6BF494A07A17446BF4D4207A3E +:106E000029DD75A94EE431FC7C6A101FFF744F8F99 +:106E1000B12A7D2FFB7DAFB1164AC7E9FDDE6F7346 +:106E20003FB986E6EDDB1DE6D94CF3BEF0E62C0B50 +:106E3000DA5F78B3424F7FEAE5F4B34F53317EB463 +:106E400045D2BB31DE8834294F95598E3E311AFC2C +:106E5000FFD59E69F5699DE56596822CE0799BAD2D +:106E60006D2EE67D4111AB95B8CE7EC6A5B9B9FDB4 +:106E700085DD279F007FF8F4FE3E05602B177667BF +:106E8000E769547EE1E321592EEAF7C27DC91EF07D +:106E9000856D36F74F99DEEE89F260DF1BFD619C50 +:106EA00025E87FF755C335A41FCBF9523E4F93E336 +:106EB000FA9482CE7EA32DEE5F8F02BFF8BDCDB3D4 +:106EC0009992A57FCFE8198BF5613F778187B2D57D +:106ED00061C26DE2272B78DEA5C263871C84721124 +:106EE000445FE5A298BFCF6F347F5F407C02DF171D +:106EF000AE377FAF108DAB5A697D8BFCE6EF82F623 +:106F00008F2F11FBDAF869E2F37EF1D66FC24CF5F0 +:106F1000844FE70F0EE6C7A5B41FC1C79E57FCFEFE +:106F200015C0EF3D2AAF33745DCBD3D2781D8F44AB +:106F3000FC636E6B105E8F59843589E07ACC2E1C11 +:106F40004905E847089CABBE3D61FECDD4E4DEFEBA +:106F50005FA59632DF4BB2E03CB8C305CE47FDEDEE +:106F600039998A7ECA5617795B83E677D1E67DE444 +:106F7000E79057DF237E4DF58E8DF5378EA5791D71 +:106F8000BB57F5D47731AF33249FF9E3091EF728B7 +:106F9000C23F84F2CF9C4C2D21BC9CDE7C32B534A8 +:106FA00098FE15312B981E8D9466C2EB82AC89F445 +:106FB00018AD05EB09ADD7895FF37C0D783A55B173 +:106FC000A42B7A7814744FE5397F5705E4CE9A3DA7 +:106FD000363FE83362E3170FDF0AFA6CB6B940DADE +:106FE000B57B542FE474B15BF567E21C6BFE34BAD9 +:106FF00012E7CCEE212E3568DD740E17E37CB9B0B4 +:10700000EB5262592EF73319F244ED9E873CA0DF14 +:10701000EEE6F15C9AFAAFF13FAF99FF9DCFFD200C +:10702000F146F0818D27B2C0DF890F3E9786FD992A +:10703000F5B51D79215A8783FE687E2CBF5FF47FEA +:10704000C5F2A5A359F5FABBC0C39E343BC3FF07E5 +:10705000CF6F02CD2FB1737E349F3DE0CBC63C6B2A +:10706000DC6D769CB3171DD179E0A7B4A089F989AE +:10707000FAF9E4067F2D9B2888BF16EE9EBFC20951 +:1070800079A151F1400F286F56F9DC2ADFA0FADD13 +:107090008497C2ECBBF63B219F3E44E5D474BC3AD6 +:1070A000EA8FB3A8FEC2FB54CEEFDBF8D33FDA8001 +:1070B000D70D3611063C86476FD2C7637968913E7B +:1070C000BF45CD379D56A0B7EC513D01B4DF1CE55F +:1070D000C1F7B2D5B663C1F4351FBF507FF3D72BCC +:1070E000FE401AF884B9FCC2309FCE2742BE6F5CC6 +:1070F00035757F02522BEB898BFCE672FCBC4EF39C +:10710000A9D57FDF9AB9A617F073C129440BF6AB56 +:10711000B595F51D11684D051E2FECFE2C1578ACAC +:107120007DF57FB24417F8EBD84FCD510927228463 +:10713000384BE7C63716D0FDA5C9C55DD47FB18FE2 +:10714000DC175B6DBE5E9063F76FFC8AF9C1C5DD2D +:107150005A5F5717F4DBB95F7D4E4B12D280532034 +:107160001DDAE4BA11FB84E4C17B411F9B564DDD5F +:107170004479E76B364842A2363392F70BF6C7FCE8 +:10718000A07E8D7DB2157C01E930C91F5EEC23E540 +:1071900084D5BABCB0755FFBE4CC2EE6B33ACD26FD +:1071A000CFDB3E926FCC4D2B0E4F879C61F1450398 +:1071B0001FC2EB7527107C159DBEEA972D51F03D3F +:1071C000493472DA5B3471FAB8105A24EA0B8F0B27 +:1071D0007016A24F2CE0C77B9ED7AB31DFFC898EA7 +:1071E0003BF06AD0832F56F837D3EFEA46875063D7 +:1071F00020EDB546A351D4A0A9BFEE4BE5B60F5480 +:10720000D69FD43E063E3D2EE0F7CBC8E931C1F80B +:10721000DB77B87402FAABDE497A2EF5777E874DBC +:1072200004A0575969BF503DDBE12FEC69E04BCD1D +:107230008A80BC5C4B797CAF1D65F5FA83E0929740 +:107240002EE1919A9EC570BB60F51E9A08FA73955F +:10725000DA21D7DB0E974FC079634B2AB5635EFB0B +:107260000E8F75A4016FB156DE37AB9A8D715B5CE2 +:10727000E83F2AF6039E6F43AE454453BB868FC258 +:10728000FC0C4C87E443613A5C1B02850E7717F8CF +:10729000F189C2143182CA77A81330CFF3AE5217E6 +:1072A000F0688B957687309B7702F49AB0D8B878DF +:1072B000CC6F447A06CFFFABD8253CCFAF48BC801B +:1072C000BE41F27A31F20DBDCB55867DE323BC8FF2 +:1072D0006B1D72FCA83D2A9FA362A443E7DBEFBBB2 +:1072E000CA689CC8BEDA24D083319FA861AF0BF076 +:1072F000E71C8B85E5B3863722D7802F18E51BD294 +:1073000025BD19F858996075817F3CAED3E74A577F +:10731000B1A320689DB61E161D5EC50EC069BBBD1B +:10732000F810CE9736FA8E73737FD25407F414AAEE +:1073300067413F27EA68C764A3DFE90EC07741428F +:10734000E978B45B2896ACC27E5BB85E1581203EBE +:10735000DB6093E32EB81C2102433AC75D40F8E39B +:10736000F697A3F97B8353D66B8892FBE7CE7429FB +:107370002FAED4D3B57AFA83F9BAC7CCD7CFC7FE2C +:10738000714BA9E4EF77A653BFD54AEB788826ABBB +:1073900092DAED80EF893A97088405CDF78A75C6B1 +:1073A0008B40D0381DF52E3B45203E181F6EC6473A +:1073B000E77A23B9FC445D12C3B1FBFE534C70EC79 +:1073C000EC3FC304C72BFBCFE2F2137539DFD1FFCB +:1073D000C06EFA4F33CDBFB3DF7EFC5DECD2FA82D4 +:1073E000BFDCED227EC074D3CA7626BBA2FD067632 +:1073F0002FF1719880DCF79553CB7605F1876DE915 +:10740000765D9F0BA480DFFAC43A4E6B775D1A8FCE +:10741000F66EE20B6CE7D0CB6B451BCF13FC02FA88 +:10742000BD48B6BAB97C97960DBDC89847873CF35E +:10743000BB489F85F641D89EBF47631F5FB4B64DDA +:10744000867DAAA9598D08DED707F4FD31B6CF177E +:1074500079B0D7D5A01DF1BD9FEE5D9C0DF8D48409 +:10746000B5E561DEFBF7FE2D0FE7C8577B16F7C5C4 +:10747000F7AD549FE50F7B5B8D27A8BF7EC2E5B3B8 +:107480008CE84C9BF5FD1FFA7DEB9EFA5E98C736A3 +:10749000D83D482EAC59F656C6F178B021EF83E0BE +:1074A0005F82F816EB43BBA6A96320DF7D48320F4D +:1074B000E587EE9672C3D03EC26F4983DCF7E12CBC +:1074C000F0899A61761754E1F0FC1696B7C38739B4 +:1074D0005C389F9FED93C1EBB3434EC840FBA2784D +:1074E000A6E754F1AFC96D1B42F64FE00F35DB68DC +:1074F000BC6AB575F23885F7D131F0A99AB7BF7873 +:1075000047D75F13819F5A8C4BF0785FEF27214359 +:107510003B897A9AA3F5BEABA8DE8C9B9353A11F3F +:1075200095E8FA9998484019C9FC6810EC20579ED4 +:10753000DB520F7A4DD134C0C197ECF0E0FC1A98C1 +:10754000221CC971D8D0FEF4A934EE57E916C32E17 +:10755000AA60DE03F4353DDFAB69692C9F93FE38EA +:10756000D0D13F3BAE25C3FB77F00BA3FE8737DFBF +:107570003A48EBE2DC30E479BBBDE936CCB3AD3A56 +:1075800092F54798F3D0EEC99BC3022AEC8AB6C89D +:10759000D5D0E73F8A987BB007C1E3FE282D228330 +:1075A000DACD9A79C32AE495FDF1EEA5A0E792D64B +:1075B000E1C0E7D34E2D2683C6AF72687D1369897B +:1075C000E7FB68D93138E48BE3259E44F1A0E22E35 +:1075D000E72FE753A2C8F10F476949E8A7C4D2F2E1 +:1075E000C455F8666D617B8368E8C1FD9CB78B8AE2 +:1075F000AEE47F030E47F475ECB3896B2FD3FAF634 +:10760000AD8DF1D4D37CCBEF9E39B796D2F996E20B +:10761000C4806A9A7716D655E52BE99B4CF2F3792C +:107620009B3EEF65FABCADAEACE0FD1C3AEF7A4391 +:107630005EF985C2FA20FF50FE155FACFF5ECA8777 +:10764000592E7D300DE7D6200BDB493684D3DE2260 +:107650003DF25D7D9E8FD3BE73C4F1F7D5F89E14C5 +:107660002EDB273D6CF1C37E503C7637E3E9C99AA7 +:10767000488F4A639508B71D725099F0B25CFCD9E7 +:1076800098BFED69A575156668D7016EF3E22DA95F +:107690001FF03CB48153206F8D92EBF8167993D78D +:1076A0003155B86C2C94893516C81F535D7229F377 +:1076B00015B93FA609AF0DE3CD101AD7FBC305BB23 +:1076C00017FAC41FA00BD1BC670A1F7F9F2DFC9C1B +:1076D000DE2A025CFFC7A295F306BC893EE6254878 +:1076E000FA38D95365F8DF8C79BF1791D76719AD90 +:1076F00063CA23D999AC5FADEBC1F0F9AE794FD134 +:10770000E986F6EF3CF483FD3B9DFA997A63C8FE67 +:107710002DEC61E033F3DBF6514B7B87FE14994C83 +:1077200070B85E47E9F5DEC5AC3F15A991C247F8D0 +:107730006919A5FA21771CF22E4F48A075DCFDB916 +:10774000D4837EB75CBC3D84CA7F374615F5DCD256 +:10775000CBF2D464BD9FC9BDC79F869DF5B00824F8 +:107760000CA5B9175DD65E8FA1F94E56B735C45238 +:10777000F984DEA4C704F1BD1B12B65BA1D7DDD826 +:10778000CFFC7D62AE59DF99241A55C079F250734F +:10779000BD7D800FD1D78A0CA9B788016280EEDF4A +:1077A00063B9FB477A1FED132FD9E10B793543BB42 +:1077B00007705C3AE9B3B9185758E57A6ADE51D9CF +:1077C0009E778CE42C2F9DDFC7EBE8840893F208AA +:1077D000F2A7486E407AA6CECDE9393AE7517EA1AC +:1077E000CE23EB67143F807D56BAFA732BF072B745 +:1077F00053C2F96E67AA1F76B58AA6C6F1985EE5F0 +:10780000AEA68348CB03C5E371CC2E38B4E420D2B6 +:10781000BB3BF4B6250EDD5FC0F3BF5DA7D3DBA392 +:10782000A6DE3488F6C9EDBBA5DFEBF63E53A74DC7 +:107830004A40DEC6F9EEE8A8FAB22234DA22CFA82E +:10784000DECD58B7B7F9E8C1785AE7C9BA113CFF9D +:10785000D3755E9EFFD9BA099CFE3DA3F839AE27C9 +:107860003E67796CD2B6A3D614AA5FE455BCD8B7EC +:10787000D77A85DF4F74B1DE26CF81F5740E601F95 +:107880008F1934F5F13B30E90C6D27DACFB871511F +:1078900011C6993CA2C48A7A33BF16223EAD934EDC +:1078A000BF8BEE8DF557EBF83BBF5761789EDF1B22 +:1078B000CBF06CDF911103F960E9CE8C9E48896FA3 +:1078C0001A7A6F04E0D77ED9C2F36DFF289CF58E3B +:1078D000D0F64B770EEC897A6709DF2248DE3CFB55 +:1078E000FC7FB883CF95B3714D5F7D02FEF657C91B +:1078F000DF48B239F118F85FEF5E1ED0CB055DCEE0 +:10790000263D2302E75F8D6E57047F42FE6CB8B4BC +:10791000E70E7F21652CF617C673139CC31C19B99B +:10792000C787707F477E46FDBDFC589207FAEFB9C6 +:10793000ED8FA463FCAD4DF33F798CFA3FEFB7F8C0 +:107940006C744E9D174D175E051F7E2A92ED7B7756 +:107950002B342F9CC39B7B713E47B1862FC3392CA0 +:10796000FCBCCF7314B77519F1ADAA171FED057ADA +:107970007C8D603082CA5F5B1BC17CED359BE7C8A4 +:1079800032F4F7B8ECEFE9FBEF3CB60BE97DD50537 +:107990007752FA65461CE3A1FC814503D09ECE795F +:1079A000914CFD3DF78A1280BF6AD0BA7D2B926957 +:1079B0007E83371CB5F4A234FF29A51EE9C03E37EB +:1079C0001E82FDF96F196E6E3F645B9A9A826DD9C3 +:1079D000CBFFC9757CFE9BE582DC759F8FED253A58 +:1079E000E583014AD3998D34D7B0D48F0A348663A6 +:1079F00023AF6767F3B4F76F155807491E98778967 +:107A0000DDC3E791DFB711783EAFE57858BF2BF6BD +:107A10003D0A7A3BAF257A703EBD4CFAFCD5A87F73 +:107A2000C4CAEB7CE5A9F7A261DF89213DD909BF72 +:107A3000487EDB78D4AFEEE316F087F579E2FA09F9 +:107A4000804FCD8E9D1BB99F2A8707FA6EC5CE4BFE +:107A50000753202FDE203C99A0C71D32FFAB42AF59 +:107A600047A5A5566CFC52E65B8A395F4CDA27FCC9 +:107A7000FEA24CCA498FE8E7A068CD637EC924EE18 +:107A8000EEC4D7AFA818E5EBD37CC9B06F1BE727CE +:107A90009D7BA9FDB065ECB27DCBD85B53192EDF81 +:107AA000F3DCB3EBE797D1DF2376E173523F30DFAE +:107AB000C09EBEC12ECFEBCDC467402FC6794DE32B +:107AC000E6F593EDBDE0AF29AA326807C123E59141 +:107AD000309637BEEFF8B36256F1F96DC85BB5E189 +:107AE000922FF2D941ED5F88D2AEEE370C76327923 +:107AF000DE0BAB3B17F2C8E351DE6BFAB1BCD59697 +:107B00008A35D0397A1DE653A392FC9511247F451E +:107B1000C67DAF733410E52D42FBEF5B7F6C04CD67 +:107B2000330629F1EF68A486DE455A4897FC397D73 +:107B30005B13F8F34361923F470D61BE64AC33744D +:107B40009C03C40734E23B6FD039A3113F181739A7 +:107B5000C6CA787DDD527590CEE522390208DA1A60 +:107B60003B94F3DE28826361A42AB42EF4472325D4 +:107B7000BCCDC73AC7274498EA1525C4DAB18FBFF0 +:107B8000EFFA551D4F6AB83CBFD47083BFBA137467 +:107B9000BF7DC8FAE57A6F770E63BE3A56F97EEB81 +:107BA0002EB215DF093C8F8BCCE773735CE4942312 +:107BB0009AE075D4E17BE87A43D7251CDF4F8EFA33 +:107BC00089227C16ECC7CFED6C776BB6B53EF75BC0 +:107BD000826BF3A25C0FEC472FD3BE70809F4EB533 +:107BE000B39CDB0CD992EA37F770715CCB6BBADFD0 +:107BF000DC375B6FEF147CBE34CFEEC57EF45E6184 +:107C00003410EC48F5D26FD26C5BF216CEEBE6E5A1 +:107C1000291E9A8150C1EF69CB7CE497FCBC5E09B8 +:107C2000DC0A7F81EF73BB40FD75B1FED5E9945F3F +:107C3000F78B0C9ECF47A48FD762BC8A70E65BEBB4 +:107C400062BDC971049F97FFA1F279B22E9FF29194 +:107C5000CCD7D96EB36E8A37197EAD041D6FEB3663 +:107C6000CAF25EB093A23C4DB6FFC426EBDFA2D7AA +:107C70004BD0F1FBB14EA7B4FF993F689323ACA062 +:107C8000FF77FB95BEC6FB467893E1177AAC3C9331 +:107C90006D98B754DE90C6F4A4DBD366E9FCDCE84B +:107CA000170D1CC3214FCB9FD9F3373B41DF332A3C +:107CB0009C47211F7E54B1220A7AFD0C4D0D842170 +:107CC000BE6A7A91B743AE4BC7B85E396EB9A11F91 +:107CD00006CA00DFBD6D0E712FCBFF8121C1FA9660 +:107CE00081E745FABEAD6E1AF360B07E5D6927FE8E +:107CF0003318E5723F57456ABF077DD5EEBAE1C13B +:107D000060BDFB54F94379BCEFF471CFD5791F3CCA +:107D10009E09396F02A7C6B81DFA11F049FDF6D5C4 +:107D2000CF73DAEF3E0BF0DAE494FA92B5EDE38527 +:107D300094AF9F3580CFF709531D5ED8F5DA77846D +:107D4000F961AFAD9F15EEC5BAEAF744F9615798EE +:107D5000A7EF1BD2BBF8BB6FBB8DE9ADCAEE7F6648 +:107D60000BB5ABDADB9FE989E895ED96BE57236446 +:107D700079B4376DE55094F764FA79CDE68EE1F287 +:107D80003755C1E5E181AC5882779B533B8575132C +:107D9000BDB2FDBCCA2EBF1FD1E912FA25FBFF966A +:107DA0004471BF42CF6B3F8F677D4F58BDC9F39180 +:107DB000BF7D20AF47B3CB7D216AA47E78C425E781 +:107DC00075A4399EF785418F478AB7DC939580EF7C +:107DD00024AFD2FCFEB24C0DC01F6ED09F32F5F224 +:107DE000DB5751BB4F5F55D96F33E7D78B0FE3FBA1 +:107DF0009C15D51339ADBC6B329FCBF51FA7EEA2F6 +:107E0000F284A9A7D8BF6BE07F4E95D99F9A98E9D5 +:107E1000553381DF5CFFF68354FFE1D9271600AFAD +:107E2000C333354726ECDBF6D697FF4CF36D5DFE8A +:107E300027D6A336446B11F87E71F7D35CBF66C5B5 +:107E4000FF2C807E50639574639CDBB53A3DBF91F7 +:107E5000A9C5A2FFAA15BF633D2222B745F2D7BB31 +:107E6000BE1F3F3AD3BCF96585DA2D0E6FAEE154E3 +:107E7000F5E7E1FC3BAB04A2950C862BEB75E75CC8 +:107E80008168E047B348B972F1D610BF315092A86B +:107E9000DB8BA8DDE226558F57F4DB41A7A1F51750 +:107EA000D377AEF73DBF578A26F93D76D7FDD73059 +:107EB000FE4500FEAE33CF646E023D9CDFF9745682 +:107EC000B09F3634BD72BE72FDE7F47D738EBED8AE +:107ED000406FDBC24CF6850BCF24EBF426E9E9C2F8 +:107EE00033D9ECE74ED4F7D905C5670947BB5F081E +:107EF0008E67109EA6E11C97E36D1A0EB9FB619D7B +:107F00002F2E8E6F1A0EBE67F041E168CA63BB4127 +:107F10004E531EF464837F8AE2A62CFEEE6FCA42A3 +:107F2000FB972DD20E63CCA7F2B9148E7BA2B5F0CD +:107F3000FEAE7C6EE026E48D71EA9D92EFD43B2587 +:107F40007F095DB79629EDE8A44FE61EA7B3A43ECE +:107F500096F4825CE49365DE29F30B3794D8E16FE5 +:107F6000AFB7C9BC6B7D89FD18E6F73569B5C44F5D +:107F70007374BFC5027FA9DD0BFBFEFAE5E11C3F70 +:107F800031DB3ECF4B69F67ABB695C030FFDFDE642 +:107F9000EF8BF4F9F40D890BEAA5B6ED0BC339F6B6 +:107FA000A4E8328E6049A6B4E33EFB6C477C91AAFC +:107FB000EBDBC26DD0A15BEA1B8CD78FED065EEFC9 +:107FC00048A1F92FD6E3A55EB648B8FA9E957CE3A2 +:107FD000E57C2D05E7D505C01DE75C2CE57321EF99 +:107FE00049BC1979035FA1F05DF1F18214D8959F26 +:107FF000C894F6C7507C2C8F1ADE13E5065CCFD4EC +:108000001DCA00DC8D759DA8F37AE968EBB4BFAF9B +:10801000CF77688C8F7C47307DD76F1D7288242086 +:10802000716EABD58325D45BFDF743BFA8DFAA36BD +:10803000F904973B80977391FBDF41BD051B620BF1 +:10804000A00F18ED17AE2FF29607CD7BE056335EEA +:10805000063599F3837799F35B71060DFBE7DBE552 +:1080600007CCF92187CCF9931FDC7133B64F85EA31 +:10807000BB5F85BEF3E7F187704E9F7AF99568E0A4 +:108080006BF15FCB0F428F0B8D67213C2AD0737C45 +:108090005B14A6972BE25ABAE14346DC06766230BF +:1080A000DD540ADF416BDA95F5CF8AA69BBD4467A4 +:1080B00055CBDECF907AB3EC7764D35A3BE4CED085 +:1080C00071BBE33B22D2EBC63E2A1921CBAE5E3612 +:1080D0004E7C8AFED6BC371EF458F22B85E59B9267 +:1080E00097B25F07DD1CDD3EFB464E6F9EC0F03051 +:1080F000EC920B9B954014E55D2344877F1FF18B29 +:10810000A50D21F19F6B42E282D699CB17EEDAF7EB +:10811000FF104750E17882E32EAE8C67F41F805E3B +:1081200059794AB07DAAF2A96FC2CCE5725DF3F528 +:108130007518E7ADF05DCBF17B57CBAAE238FEA313 +:1081400073E9A84B3B8573CB3877AF5EB75195F297 +:10815000BCB784FDC891768E8BAC76884004CDEB9D +:108160005094DDEBA2EF97D647B1BCB280E45CE857 +:108170008B940A27C74D7A62D0EEC4BB2ACB65D553 +:10818000F1121ED5BF51FCB01D57C3A88BFC933212 +:10819000BF4804D8BE0B3AF206AD03F80BCE8B46AF +:1081A000A95F565903FB009F8E7368ABB95E15AD8E +:1081B000F3A338C87BE6EF35A28DEBD7EEFA262C79 +:1081C000F87B903D9AF55E43FF5675F94AFD653898 +:1081D000CB4F74208483BE6CBADCBEEE1E92236843 +:1081E0007D2B0D7BF85A29DFDDB2519E63249F67FA +:1081F000014EEBD6927C86EFA46F20CE442C0AF77A +:108200004BF95EEA0BEB6667B15CF4F23F5E0A4045 +:108210001F697B4861BBD2BA7CD9EFBAFBFA7339CC +:10822000F8A7C2E384B11CB66E8A51DE87F5914F80 +:1082300030C564C8F9FAF71E6EFEDE4BF566C13E26 +:10824000221E74B27DC490FB0DB9BE2E56CBC91A46 +:10825000D6B9FE75B16D51F0BB898AF8EF25B76CC0 +:10826000D6CFE3365A3FFC2AC795E283F08F19F543 +:108270004666C97365F858EF16BD1EFB5FCA2D53DD +:10828000EEBD8EE655FEB0C50D7BA18107E1F5661A +:10829000010EC7D73A0B4077C3C74A7BD9917CC937 +:1082A000E723860A8E371AABF73B36CB624A93C276 +:1082B000891EA99FE345D21E1F35B498ED9624135D +:1082C000CCEB2A6E65B2DE4FB9BDF8F7A3BB984F71 +:1082D000075D144AF9FBF86DCA26392F2FC7270E00 +:1082E0007FC0C9F6CEE3FA3964E081E86818CB0FA5 +:1082F0003A5F8B0DA19BB5A0079C87A00725986EC0 +:10830000CC74718B22E12BEE93F2F7BA589937E8CF +:1083100082F43FF1BFA09B22C1F0EF4E0F34D6DBB9 +:108320009D1E4874B00874D0512F840E84D53FEC44 +:10833000DBFC42A52362872B848214ABF021CE178D +:108340006724C3EB1EAB1FB178BDAD122F7DAC927D +:10835000EEE8B4F18517707D2FE27D4B1E5C28BCE2 +:1083600054BF2445B07DAD1FC9553171DC4E204549 +:10837000588E0ABB13A5685F1223FB2FE92938FE2C +:108380008EFAF35AE274E6361CFE5EC17205DA47D5 +:1083900017707B9F45B6F75A29ED9B21F598B69546 +:1083A000611CBF5C72779F2CD0C9C4B1663A39A2F8 +:1083B000D39591DE94EDD68D759E24F083D286FE02 +:1083C0007CDED43B8BAB77029FCF47B0FC59B2EA3F +:1083D000C79386617E2FC47B80C23393B7B33FA817 +:1083E000B461F64F3E84BEB4D5C9DF2BB2B5F559A2 +:1083F00090FF15F7DC9DF4A174C6017B12B5D79AE6 +:10840000A69C7F95D2C9BEEDEF409E983C5DE5FAF3 +:108410009385B43F8B0639CE24DFE7D624EA6FD2AA +:108420002885C3698E3A5DA9B7C10FA4E3F7A92CCB +:1084300045977FE43D8192557DB2D273E13F21C9DA +:10844000B80B39FD53A3FE186503E4A5BEE3E4FEB3 +:1084500033EAA31FF47B3A4BCA55BFD5E162E40966 +:10846000AE5CBF7C75D8D18C68A4B64036A5E9FD5A +:10847000C7BE84754E4C17E3D703EE77AA6213CFBD +:10848000B7AD84F94254961BF4AB9142CDFAE3D6D2 +:10849000FECC278F8E693B7A37E58F6E1E24ED8CDC +:1084A000BA7D61BE4BB07C70748CE4776D9B239871 +:1084B000FE8FB85AA3E2A43D8EED0D653A497CB615 +:1084C000ACFE7EF8B9CB22ED47717ECC7F681AC72F +:1084D0002794AD530361B807B0C66C6FA88AD4DE89 +:1084E000C67E08B51B84DA074033A0A3F2350AD351 +:1084F00061DF7A8F3D99F99CE2C2FACA2303FD70CD +:108500000E947B9C1CC77C85FDE06B82FB70D8B908 +:10851000050789B5676B9F004E258D25ACEF46E4B6 +:108520006ACCBFFAAA0417EC179DFE26C25E0BBEEA +:10853000646D4DC6BEFC55969BF13031CE9515C984 +:1085400074EDE4FB11476DAE2CCCEFE84AA705E7CC +:10855000EDC41592BE69DF39708FE11EAB08073F8D +:10856000D89A25FB9DB3DC5ABC91F2BD1DC21A15E9 +:1085700007FACA67FA5ED85FFB2DE675EA17620450 +:10858000E489B2356BE5BC74FA10D696C2781AE766 +:10859000D4E6B402D8013AE4DBFE63DB01C70EBACD +:1085A00098AE303DD07A0EC18E9CDEBFF432CAE95F +:1085B000FB3ED0CBC4B1817E881B2F52AB38BEB6F8 +:1085C0003D4978E0776C176D2C8FB4933C02BE6701 +:1085D000F019839F105D781D899DF8DE5247532264 +:1085E0001EBEB5CEC1E9B3752E6125786FAB4BE2E7 +:1085F000FC0B756E4E9BEA72F8FB8B751ECEEFA8D6 +:108600001BC1F997EBBC9CDF553781D357EB8AF937 +:10861000BBC1AF083ECC970CBE63F02783BE0C3EB7 +:10862000154A577309CCB81741ED991F1A7C10EB06 +:10863000B01474F22703CFE94AB12F09FC50B4CE2D +:1086400006FF2852CF3DFF0AC1B9BD2292ED22EDAF +:1086500042F2C1F648079F07A976B10BF689FADB0B +:10866000BC47EF0E3A876FAD508435888E7FBCC40F +:1086700029AC41743C6F59AC293F67D9FB6FF4A416 +:10868000FEDF8DD172B3691E477E79E2F13FD1F7EB +:10869000DFFCF24C26F04EF3D8FC08C6BD2B5C9FE5 +:1086A00047AB9CD75D769697FA864B7DAB6FB8D477 +:1086B000B7F0E3088ACF3DA2E3A3242DF69DA7B12E +:1086C0006FECAE9B47C04EB452DE4BFA04F8A3F2F7 +:1086D000BFE8F82B5D16C6702D6DD0F76B70DC36D9 +:1086E000C1F558B260F94EF10A01BFD7B15FD803A6 +:1086F000242B88638AC3AF407622E56B0EEC98ABDF +:108700007FF711E47665D92196B3354724C77F08F2 +:108710009FED5C707FCAB2835C4FB4F636C56F467E +:108720000CF5DAC13740E3C05F69CE7E81FD2E1AB9 +:1087300015BE7F54AE7F2F5FAD98E2A26764ABF2A7 +:10874000DE459695D3F359423F471AF9BC32E89675 +:10875000F808C7619637E6DB1704F1E752FD7B594D +:108760008EC514A7797F969DFB398FCD49FDDE9B81 +:10877000936E9FCFFCCFCDF7058CFAA53905AB6082 +:108780004F2E5D83A8A6CEF625D9567D5E2EA97FF5 +:1087900039E85C8BE2F8A22ECF07439E39855F470C +:1087A000F2FC59EFAA7CE1B917E08FACFC73189F7B +:1087B00053958375FB4AAE7FF8349683BC91CA709B +:1087C000C8E112FF85CFFD351A715DB53BA4BD9799 +:1087D000D2A3486BEEAA60FB5E8D87F6491CF8AD0C +:1087E000D9EFFFFA0B7FE6FB9D84B0143D6E98E352 +:1087F000D46A767CCAF16BB0C7F986727F1C5F1DA4 +:10880000DABE56F99AF557422CC3A768CF97893C30 +:108810008F9D9712C1E76AF7AC4CEC2A8E28B41FE3 +:1088200023CEC1B0FFD58A359FC3CF597BD7849360 +:1088300092DE65FFA1ED1ECA8E4A38315020C6EE89 +:108840002AB6935805C79F2CD5ED38EDFE4CF6633C +:10885000772777D7AEA7462492B55BDD3188B3BEC4 +:1088600028C484AEF0F449B6946BCFD33E823FFB6C +:10887000E23695E5CA8BDBA2783FD46C7BF020E230 +:10888000046B9E52D8ED582D5A38CEAF66872A1CFD +:10889000C1E71DEC47F1DDCF73F173514B405F8BA6 +:1088A0009A14EF669A4FBBC31DD323683EAF80BEB8 +:1088B00088341787350D47FFC6FC9F077F0B92371B +:1088C00017353FC8F18D54EF02CB37BF8DE0383CF0 +:1088D0003AC9DEC13CCF6E18C2FEF5454DDB6B5880 +:1088E0003ED816E182E9E98CCD7C0FE4803EDE8142 +:1088F0006C298F9CD5EDD1675F50591FC23CB12FB9 +:10890000CFE871B846BB37F5766F664BF9A7265BA3 +:10891000EE4FA3FEA2A6A3D1FDA8FEC95DEF73FA98 +:10892000BEBE6F1645B6F03DCF933B22F89EE0C920 +:108930001DFF39FE351AEF7CD3980425689F9DC82A +:10894000B6C97DBA41C62FF32517D6139A783D676D +:10895000B7A528AC2F03DEA4B79FDDF112DF4336A5 +:10896000E4EB1F1C2F384BB186DCA3183D08728D39 +:10897000A355BFD7D1A6DB63FE6FFAAFD1BF27598E +:108980008AF571E43D0D61C46FB864BD2235B72727 +:10899000F6DDDCC1EE99B8972DDE927197A2B7FB98 +:1089A00011E87F73DF8D67BBCB529BBB27F25F1C47 +:1089B000268595E0337788CE57925A87C1BE7B349F +:1089C0004DCA15863FAD6AB522BC04BF5E44673E02 +:1089D000E4FDAAD06007C949677C3D5661F1DA71B0 +:1089E0003E46D9992EEAB73B37C1BE75C42E7CEC02 +:1089F0007F7BD129FD27E9D20FF218F617A5557113 +:108A000081AC78D8F174BAA99A4AE541F453B529F2 +:108A1000900539EA9C5DDA2B510EFDA9AA40D6AB30 +:108A2000D7E914FDA0DFA369AE0B2CF7EE8C12D0B2 +:108A30003F2CAF4449BBC8D3CE4D6141E776BF1C44 +:108A40008B1177C7FE4ADF66393FCC0BF2FC227BE5 +:108A50006316E45D63DC45D18D3CDE397DBC45E1C8 +:108A60008DD29FA3C711A23E8F6F13EC776A7B262E +:108A70008CE5E633C92D2F63FC33CFF4E7B887A329 +:108A800069FE05BBB8DCC9F1E795CF860530DFD3B9 +:108A9000CF44B15DEBB44DCA63A7A312591E3B147A +:108AA000F5F05CF6633D15A6C02E745A11F62494B9 +:108AB0006FEEC1F24065DD32F6D754127B811C4B5C +:108AC000E904C87FA737F7677BD1E93755BE5C411A +:108AD000DF57E3BB261AE7FE8CF58008B6239E79A4 +:108AE000F66FFD83FD3B465AF994D93E66D083511B +:108AF0005E9423F960518ED4536EC871715A1DD1A2 +:108B0000F4703AAF53F207C203EB81B41F1361EF65 +:108B10003FD2B43B5189049C0359FF09B86F95FAC1 +:108B2000D6996D36F65355BE12E5653BD4DD57F147 +:108B30007DC94A55CAE3951679DF50F9E556B6FF67 +:108B4000D43FE32C003C08DEACDFB66D56F571E493 +:108B5000B8A7B7F4917E8D809E7F7910FB3526C62D +:108B600089795359CEDA9007B85E7A2A82E3FE6992 +:108B70001C2FE2342A7FF67309CF9805AC27D0C1A9 +:108B8000CDFCB94AE7CFD5775F1383FB10E25D9543 +:108B9000EF795CB27A7A82FF86C2EBD11C9D3FBF2F +:108BA000FC38F3832ADA37880F5BACFB13173FAB33 +:108BB000B05CB978D5358F30DF7DC726702FE25C89 +:108BC000D383D1C1F8A8CF91FCB0B3BD87EB2FA65A +:108BD000FAB2FD5BD13C9F2D360FE6138AC7EFDD5D +:108BE000FE59F507B5AF6C22F922EFCAF55F122DD9 +:108BF0003FFD33F8CB3627FB5109FF7C3FEAACAD94 +:108C00006901D67FF67927F39DB3B172DF9FA4F394 +:108C1000D4978DF9DCF46BB6CBFC619AC039B4D033 +:108C20006FEED798D7EA1C9BA4B7784F0CFC44D5BD +:108C3000840FF447F8F911B77FD7C6ED43D7B34097 +:108C40006FD7B14F9F8F60BA39DB4BE2E5EC0BD9A0 +:108C50007C9E1D8D95F44EF34D85DE743656A6B878 +:108C600099047AA874497A383BA689ED026795ED94 +:108C70009C1EB5C97695CB747F3BD15F12E807B4D3 +:108C800009BBAA634D0BE419F0F9E1059C06704F8E +:108C90003BD48E0E3AC5F9D7AAEF33E31D05F6EBA8 +:108CA000B09FA789EFC76BBA3C59B5ED4A7F25F055 +:108CB00054B54D617FDA7F19FDD0AC130C3F00D164 +:108CC000E5629FC2EF222C6EB86D11FBD396ACBD4E +:108CD00015746FAC63B17E6FFCA8A2F27C8E3A690A +:108CE000FFE45E399E01DFDFE7281DEF75B88CF3E6 +:108CF0008BF6F03B396E4947946DA4FEAA1A943561 +:108D00003C4E9AA1E7CAF5197022B0D861E73BAA98 +:108D1000DFD3EE6EFDC63CBB9BCF319DCF1F4D9385 +:108D2000F793DBDE96F7CC2F7D3D2426EE5BE44106 +:108D3000BE6160F487B863D020F5F322F81CF635E5 +:108D4000ECEB34CFAC0D66FF4ECE53E6FC806DE607 +:108D50007CEE0E733EAFD99CF7BC6ECEFF09E30EDE +:108D6000EB8413F46FC43542FF460AFDDB1D26F584 +:108D70006FE4A17F2385FE8DEFD0BF9187FE8D3CF0 +:108D8000F46FE4A17F2385FE8DEFEEFE124E55BAFF +:108D9000BD1478E0B8BADD4E233E81F7CBC5D98942 +:108DA000CC478555EAA51717E5B2FCD8616F9AE262 +:108DB000607B93118F9518AD85F7471C80D2B22A3E +:108DC000398DDBB11DBAF6556987AE2A7046C2EE01 +:108DD000D1BAF2E42A883DA7A3B418D4BF686BDBEC +:108DE00002F8562F3BC07EFFD6E5EE77AF93F863CF +:108DF000FB8B115F5582730F7C9BF4251977EE7105 +:108E000004DB5343FD44624D501EF2D33A733ED40B +:108E10002F04BEE635EDAB46C6C76F6C6DC9E0FBEF +:108E20009F3EE3E0FB699FEAF63B31CBC1F298211C +:108E3000CF23CE1B70597A9FB209E795A77F1CC339 +:108E4000B9FD50A6E97E61685A767908CBF31DF921 +:108E5000358A05E3944F5FBE8FF56ACDCBE7D2ED3F +:108E6000FADCB2D75B4CF3EEEF0F37D1D1C0AD7166 +:108E7000217ECC5EA6FA8377A587F8310798CAA72A +:108E8000AD1962BE8F5F7C8DA9BCAFBD236ECFA133 +:108E9000FBB9E4FC5CB2CEA5C8025E6F68BD54C5E8 +:108EA000F327F86FC5DB524E2DA773C61BAFBF2B40 +:108EB00052007F9D7732E057D1648B859DAD4C3F4A +:108EC00087C432F3B95C61153E575C27DD55B88421 +:108ED0003796DA7F696D4C653AFAE547A92A8168C9 +:108EE000D180963CE8AF8BDE7C7238E8AA5ADD98D8 +:108EF000EAA2F23B14FF165C203F13B73D712495A4 +:108F000027A95A497FC273AA2D70FF1CF0D1ED1911 +:108F100002EFA47CBAE6A5688E1FD4E92FD5E60A35 +:108F2000071D6C6C54594F81FD4C8DEBA4938D8DB6 +:108F3000F1E1D06B2AC6283EC8C7065C0CFA08854A +:108F400007C9EFEFBA69BD970EC9F7948C752E75F6 +:108F5000C9FAA241B637DE0730D67B5CD7472B373C +:108F6000BE91753B7D3FD77F5F9E1B7EDCBA5DBCAB +:108F7000EEC5966D5B92297DC7A1DD85752D7D7B44 +:108F80005CF4481AE7CB6D32AEFDB3754F3EE1237A +:108F90007E7A77E39376E80F9556BF9DDFCD7966AD +:108FA000A31DF10ED76FDDC8DF176C2D617B8071BB +:108FB000CFEE941197ADC3A362ACB2C145EB3CDEDA +:108FC0005FCA8515E1329EA6481DF54602D6B55505 +:108FD000C9C7BAA6176FB7E3FD8187F57AA1FBA6CB +:108FE000FDF0B4A21EB07B35291CC7D4DD3E99111B +:108FF000E8CFFB64DAE5344EA75F1EC87ADE8782CD +:10900000B42F9C23B921FAF56155DAF59A55F94E3A +:10901000983D90300DF2C25EF96E45359D43230AAE +:10902000A0B70B7135A5C5A354139DD7164698F666 +:10903000C12C11B4AFA8BF9B452F537EFAC40C536B +:10904000FD99D30786F89D0B3ACB997F5D6D7A8F9A +:10905000A6FA2E9F5B61BBC758F3774AEF623ABB13 +:10906000D1D4BE5A4C35BD47B3E8A9F718CE4465F4 +:1090700076C4E154E8F758666947F5EFADFC9D16F4 +:1090800062DAAF7D333C7F92E7A58DFD09863D7D99 +:10909000167ECFE8EABC0CEF881745BC30EC1D9A71 +:1090A000591E69613D55483C54EBF6A8EA1C698F8E +:1090B000AAF6B5D8118F4DF0B7A610486A1A15B6A2 +:1090C00037527D474A9CCCDF85EF3BCCF752D0DF4F +:1090D00065941F524BB0BF42CB6B68DD38176A6096 +:1090E00047623BD884936C0733C6D1FB37E834F42E +:1090F0007D80D0FE060C7033FFAEDCBAFD602F829F +:10910000CFB4E2D87CC49D54354DB195E45E496F2F +:1091100006FFBF546161BF7EFBE1034C6FED155646 +:109120008F8C4BFF76B8D478A5DD35940E17D0BA66 +:10913000E07F5EB043F1F815590FF0E905FA0C81B4 +:109140004F4A177033E0D501BF90727E3F6E28E220 +:1091500026E47B0A57C025149EFA380B34C17227C7 +:10916000CDCBCFF30AE9578C08DD8FB7DBD9FFB041 +:1091700041112EE5BBE131F5B2B4E3F4CD90EB6FD4 +:10918000DBA97820BFDF7CD9CADF3BE8A758C6D966 +:109190004F9F68DEAF1DF4542CF7CF8CCB89DCEEEB +:1091A000DF4557DF454F86FF26347EDDB847E61999 +:1091B000A0DFB71A26867DF34FC4E11BF24177E7A3 +:1091C0004CC739E4D2F11099DEE5F9BC342A9DE3AD +:1091D000CC35DDBE68F0694D6F678C5B42E5EE789B +:1091E000D07B6F7E67715543466AF0FB37DA4A1BC6 +:1091F000DB815397C7735AE27425E27C29592EDF2D +:109200006939764FCF44F8298EADB4254CA4AE8F82 +:10921000DD3934550C42BE88D34FD786CD0AB6CF40 +:109220001BE92D03E4F9619CEFE72D87A367613FFC +:10923000AEDC198D90A1C52BDF1FEEA273BED9A2A3 +:109240002D1AC0FEE08D7CCE0BD7C63CD8E70C397A +:10925000A37265514FC80355FF38F004E4016DB99E +:109260002D1172EAE90F5481D01A3AE758BE38E559 +:1092700094F47D6A7304DFAB3CA5082FFC518BD4BA +:109280007D792ED379DB7C33C68F70D2B8C330AEF4 +:109290007F4B12C6F5F8B230AEB63C33A62BBB8B73 +:1092A00091D6AE97F2DF16C3CEACDBA321F7230F26 +:1092B000B95F644BB91F79C8FD4821F7E37B0DFC0A +:1092C0000EF01BD7B7E5436FF58D15394BF81C8EA3 +:1092D000CC815C7FBB12EE013FBA5DF1F4E478848F +:1092E0000F62E5F91B8257231DDD46B25910DD5E82 +:1092F00077D92182E3EBC68858537E9C23D954BF8B +:10930000C895662ABF3EA9BFA9FC0677BE297F5330 +:10931000CE4853FD499E31A6FC8F46DC60AA3FC56E +:109320003BC5949F3661B6A9FE8CE21253F9CC5925 +:109330008B4CE5B3B5DB4CF95B2BEE34D5FFF192EA +:10934000E5A672AF7059710E36431F23B8EF853E04 +:1093500046E9ED6F674606E375D4384B97EF0C3559 +:109360000D90FA5674AEF739D025EE09810EFBE860 +:10937000F780F6E29C1906BF654091FA704B32E81F +:1093800026B45E68F9A888FD97F09465FFE76E9FA4 +:1093900061253E31EAAAFD4332287FFBC0E619561B +:1093A000E22FA3AED9FF523AE57FF1DC37B27CF071 +:1093B000FE4B285772F7CBFC34C122C8AF06CE9BB8 +:1093C000E1A3758CBA2E7D8D47DA53BA8C53355292 +:1093D000C001719D8003D200D127D2FD449F485F18 +:1093E00027FA2CB7097190E813E921D24BF1FDF768 +:1093F000A497223D4C7A29D277482F45DA427A2920 +:10940000D23FD4CDE2F4833A8DDBFDB1AE82D38F6F +:10941000EA96F0F74FEA9671FA973A1F7FFF648059 +:10942000617F08B09DC6F08BD5C01F097BDE2EDBA7 +:10943000B960BFB1E295E7ABE1C7AC5F225A23B098 +:109440004F5BADB1271C9DFEC9EEF9AD559C08924E +:10945000CB9CE1DECF06F0F8BD5DCCB7F5EF47C49D +:10946000B43E0584A74FD3B5B3E007330ACA56C646 +:1094700010FFB8EEEB2536D0CB8796AEEFA3EFD535 +:10948000F9DBA703BD6DE8F75AFD5DA66B1D32AE93 +:10949000F05A6B6B3DDBDBBF146EC403ED33ECEFB6 +:1094A000F758F95EB1F285E0FCE804C1F9FA2F5BE8 +:1094B000380EF15A972789CF1D3D6FC40575F8FD09 +:1094C000F11314EF63F8E18D789FC22F5AC7413E24 +:1094D000181D69778785C40DC0DFBE2FEA8FC6BC13 +:1094E000F87D27C3BFFFD4972280F7F20C3FFEB56B +:1094F0008E9634D81546DFE1F004C73319FE7AE5BD +:109500008B1615E78911AF648C63CC3BCA4AFD15F5 +:1095100074C6235DEB6ACA475C467D7524F7D79312 +:10952000BEE3DD49AAE755B95D533EECC7A3AB22C4 +:109530003D42E98C13E8A9AF9BEAF13A0BBFD03862 +:109540004E62B41E27817E1CB29CDF011C9D104818 +:10955000C6FB9FA397D83DB0833E8EB8B382CEB8EA +:1095600005D48F08DAC79827FAEDF715CD17F2BCA6 +:10957000D7CBF09DE692F429DC7A5E3FAF85632C71 +:10958000DBBB543D5F1CE6FA6B04D1CFAD19DA901A +:1095900081D4DF1F948CCC7CD617327A60DF4F09E0 +:1095A0007947B00BFA1931F0FF847EBC12EFBD058C +:1095B000DBE142E9C8C08F414F06DEBBA32B830E1F +:1095C00082E2D018EF1D71657A7FA1F4D61D9D1936 +:1095D000F475AD43D201F08CF82083AE942F9AF845 +:1095E0001EEBE82A079F7F065D85D2C5957425E9A5 +:1095F000B4FE270EEEEF4ABAEAA407C0E587D355BA +:109600008B8AF3F89FA5A7796D623CEEFF975C7695 +:109610001F44DAAB9FB6177CA64C8C190F12132E81 +:109620007510EC62A1F532BAA9174A7FA1ED6EBCA4 +:10963000A25D466E70BB71FA5919DAAE12ED7A046A +:10964000B71BC271116FE9F708DE721A712D9E996E +:1096500090530EB96DF22D2FE18DCC27BA19A7F3D7 +:10966000F34362099FBF24EEFA404F853A698DCBE0 +:109670005DC8FA426164D7710537EAEDC77F5DDCEA +:1096800080F98C4F30CBE337EAF2FCF5A291FB0F67 +:109690007D47E1C6DCEB59CE0F7D4761F3403DFECF +:1096A000204DA481DF170A8F9C9FFE0E46A1BECFDE +:1096B0005374BAC970AB62541CEE9B6A561C32AF2D +:1096C000E31D8C3C8CEBE3FC0DC2CFE94D22C0FDC9 +:1096D0004CA20309F91F096193EF5FC8FBBA35AAD1 +:1096E000F6DF90578D7BBA4F3BB557B0CF0F444C48 +:1096F0009E83774AC60D19D70FEDF617BA59CEDB00 +:10970000EFC860B913FBD216D7C927DEA473BA5FBE +:10971000A6BC378A14F746FBD179FA3B3AC791BF0A +:109720003167B940BBF16E73BC93D1FE26D7386167 +:109730008DEFFE9CBC296F776FD8CDDE8ACD2E04CD +:109740007EDF8ABDAA10EB7D2BB6A745A661764EBB +:1097500007BDD2AF2BB9D8A0FBCEF1C6F378DDC1DF +:10976000D9806B283C0D38FF00B81EEB0AAE7B0792 +:10977000089637AA23245FAD8E907CD580737558E8 +:10978000C77DDE9EC1F127550E09AFF9CBAE11564C +:1097900012F5172C1BC9F99375C207B89FC69260C2 +:1097A000100FB1F709EB58CE1BEFDC9D7DF8BDE83B +:1097B000249AE72A87F63F98DFB98240164984E267 +:1097C000E4867ABE8F7FFE05D5037DAA4A75AFF188 +:1097D000C0CEFA962AEF717D7D2015FE58F154D740 +:1097E000F1E8550E095F439F1CD2AF98F7ADB15F0A +:1097F00085FEBE80215FF50E93F1DCC63DF7EEE4F9 +:10980000ADE1E192AFF50E93FCD8C0EB06BB7EEE66 +:10981000533FC3898FA6FC3A9CF5AB98586F4C2EEA +:10982000EC8385C2A49F187695F604F97ECAB5220A +:10983000EB9151942F3C64137E2A6F074340799239 +:10984000F4B3B61FBAA482EF174529FC3E86716FA8 +:10985000292CC922DC417CC2E90E37BD4B1B911378 +:1098600067CA47797A99EAC78C483795C77A0798C3 +:10987000CAE3271498F23D8AAF36D5EF396BAC298D +:109880009FACDD68AA9F5231D59437F8588AFC24E2 +:10989000FA2CB9C5D4BEEFB25253FD345FA5A95C12 +:1098A000C53B9B3140ABB7252711CF81CA9F8CD5D3 +:1098B0004B43DEE3B508CBF0CE776BFE335ADECBFD +:1098C0009910B980DFAFC96CFC99799EEA446B2C82 +:1098D000A5D7BBCD7CB128C99C1F17B94F81DF71BB +:1098E0009CCBCC9F5396584DF91FE5EAFC344FE4CE +:1098F000B1DDE3BBF0AF0D30E13F144E440FFC7E11 +:10990000683B9DEF3ECCEBCD327E0F077E93E0753A +:10991000C06F120C07F84D82F3F09B04D787DF2449 +:10992000B81C7E93E0F22187CCF81FD662C6FF55A3 +:109930001F99F16FD06577781AD96AA60FA1299A75 +:10994000F22D78BAE694997E42F1731D895BB109D4 +:10995000C087E209B87F38BE5686E08BF0C3F73780 +:10996000DB7B47317E1ED7D7756D6020DF972E3A9F +:10997000A40ABC6F63ACF371FDDC3F6DD51A73892B +:10998000CFFCCE5D90043E769D907EDBF155164F68 +:1099900080BA7F20649CD929DA43A83F2BFE52AAC3 +:1099A0001D74D226DFCF7B0E7C79D895F1B23E12A2 +:1099B0004FF8BEF6CF54BE2775C4D2A8808FAF8EA5 +:1099C000D19E009F9997BB84D79B248AB72F405C78 +:1099D000D47F85A5223FB7AFBCC72D725BF9FE8946 +:1099E000C127E7A6C8B8A92DB9BA7FDD23E3A79E92 +:1099F000C995727794C7C571DE25B9F27E0DA98B22 +:109A0000A97307013E879DD980CF3A0BBFEBD98A56 +:109A10007BE4099DF7C8210F43FEECA3CB7FF51F24 +:109A20003B1C5847F67A613A7FFBFB1DA6F8E281A2 +:109A30005B5DA6FCA0A62453FDC1BBDCA6F2FC40E6 +:109A40008EA97CC8218F293FAC6584A9FE551F795A +:109A50004DF991AD134CF5AF39556CCAA788B6478F +:109A600001DFBE8AB4531CCD4D97FAB95B70DCE4BC +:109A7000DCBB63E57D5FDD7E61C8FB46DCB9A6D358 +:109A800075A81ED1D72EE5E8FA6421F54687AE1FEA +:109A90000AB33EA1E971E31DF7587CE6B871235E75 +:109AA000BC43EFD0F58A8E7B349DF1E2DEE078F1A5 +:109AB000B9615DBF1F7D5EC77BE8FCFBDAE57AEB31 +:109AC000EFB4F3BD1D635EA1F349C99674BBD9D150 +:109AD000F5BDAABFE54AFB466B66F125D0FD1336FE +:109AE0004F2BFF6D842BC6F3B4225EB7FE1776CFE3 +:109AF0000AF7778F3777B05CCF1C8B65DE945C8E6E +:109B00008B33FDDD84884192BEAD8375FB4AC878F6 +:109B1000736364DC9A88B1BB41BFDD8F27E1996430 +:109B2000170D7CFF4BBF67F1E3354DF7A1688EBD84 +:109B3000517F3FCE6F033D4C1C4BF2593EC9135B26 +:109B40007A3D144972CA13CBAC6C9F8A7BFE57379F +:109B5000FBFA75DE9FE94BFA10E803B20EF4A80792 +:109B6000F25429B70C92EB2B52BFEEB8E7C07E1827 +:109B700021F4F34370BC4F17F4C67468ACE3DF758F +:109B8000EFC1A0DB503819FAAFD0E33BFB19F3D299 +:109B9000E167EC07037EC6FD13F76DB6E24D917CDD +:109BA0008F6502E2E50CFC6DC993F6C6053A3C50A0 +:109BB0000FFCA8BB7A456A6E0CECF7EDC21DE3EA18 +:109BC000820E3BEAFF9BE062C0BFBBFB6DDDF1870D +:109BD00050BEF05DF7DDBAA3D37FF6DE5B109F9039 +:109BE000F14B3A5EFCFD2C1C17707794793F3F32A5 +:109BF00048F2899183F4FDE423FDD6CC2F04FC0FB9 +:109C0000F52B559D5FC8F3BC24AD98DFAFC6F98A2C +:109C1000FB5BF3374AF94788E2C4AB87C28F6FE337 +:109C2000FBCBD77A05DB6D4A1B153FDEF92AF175B0 +:109C3000AD0FB39FCFCD7207BF3BC8264D6A5746C5 +:109C4000EDF6A55DF9CEFAC248F9EE60E8FBEA0B45 +:109C500075BD192F6A60DF86FABDEE19A4FBB13C11 +:109C6000C2C3F29C1ED750A1D7E9A037BF7C6F0EAC +:109C70007A32F631A51C1F67C0CD0D3FD490CE3C83 +:109C8000C1373C07E77983B5CBF8C50EF81A7EAB30 +:109C90000EBFEC61BE27111A8F71CE7720BA2B3F11 +:109CA00098E11FEB6E1F74F8C7BEC3EFD61E69891B +:109CB000C6DFF169DF26DF67E9F45BFD65B8CB221B +:109CC000FD5331F03FB5EAFD898D795DDD0FD59605 +:109CD000EFE43894668BB67310ADEF2CF58F777B7D +:109CE000EF89DC9F88771126EA76A92BD7ADCBCDFB +:109CF000A314E98FF6A98CEFF609F25E3DF15181CC +:109D00007D67C44F4C118104A4861F4A5B3D92E1DC +:109D10006FF8A14A0223799E33EA17DAF0E468EB80 +:109D2000A3771585BB3BFD53AD7D645C54777EAA5C +:109D30006997F3B9BFE997AFE17E3E189426E5B67F +:109D400086FB6E039D0DD82A6C5867ABADEBBF4BFD +:109D500051A8F3AB12E89A3D82E2AD962BBC2F9648 +:109D60002AC288BF623E6FE42F35EAF92299BF7D8F +:109D7000A5CCB7EAEFA76DD1ED20582752AC077AF2 +:109D8000F936DD4E827520C53AF01D7C0D79F0352F +:109D9000E4C1D790075F430ABE86EFA5A2381576C7 +:109DA0005BF8D30A83F607FC6985417213FC69C12D +:109DB00079F8D382EBC39F165C0E7F5A7039FC6929 +:109DC000C179F8D382EBC39F169C873F2DB83EFC28 +:109DD00069C179F8D382EBC39F165C0E7F5A703944 +:109DE000FC69C179F8D382EBC39F165C3E6F996220 +:109DF000F2B7CDD3DF7F285B1FCFF45198511C9B66 +:109E000047F8FDEF887FFCC4960E3C372F02DD2E0D +:109E1000AD0EF7483C374E9078B70889E7B6D98C35 +:109E2000E7BBEC325F24E3B443E9077EAB429BF42B +:109E30005B2185DF0A29FC5648E1B72ACC947E2BAA +:109E4000A4F05BE13BFC5648E1B7420ABF1552F86B +:109E5000AD90C26F85147E2BB483DF0A29FC56F8BF +:109E60000EBF1552F8ADF0FD08CD03FE2B635E90DA +:109E7000F3FB99F452A243935EEA32E521E707D758 +:109E8000879C1F5C0E393FB81C727E701E727E70FC +:109E90007DC8F9C1F94983DCBCBF20EF07B783BC9B +:109EA0001F9C1FD4E87B03B6AB491B2EBC8EB43578 +:109EB0004A7942710931352F7326FC8BAD4E253519 +:109EC000D623846DF980998594D7F438C73CD16640 +:109ED00001BE39AE80F0A60504C7650FFA7FC95CE4 +:109EE0006EF8B3F987F09EBF43B0DE50A3DFAF3505 +:109EF000DA7B844B456AD4EFCC775D2F747CA31E4C +:109F0000F3CBA0799062998F7893FCBB220B70AF52 +:109F1000608B4591F1B82B643C74285DADCA93E722 +:109F2000FB16CBF6FDE1885329513CB8EF9165153E +:109F3000876C0580D392027EF72A2F565FD792ABAB +:109F4000118765CCDBB04B129FE07B86A3DA84BD22 +:109F50009CC619FD85B0E3EF734CB44B7902EDA0BC +:109F60006F0EF429DE4D41F4BD2C4F9E7B9AEFB667 +:109F7000ABCBE9FBC06D4BAEC6FDC589E1B2DDD30D +:109F8000BF8966384E6E50F89ECEA86DC28BFBC955 +:109F9000CB757E3A709BCB5ECEE3BAF8DEA3D16F71 +:109FA000C98654BEA759225A0B710F450C55F83D6E +:109FB0007C036EB4BED7B1BE2CDA2AB02FFFE0FB13 +:109FC0004F242E7E9FFB4FA387C61621AE5034CB65 +:109FD000F742270D2D59D983E6A5F9E57BA1A3BF4B +:109FE00058F206E79F92EF8532F90CE7F9F179987C +:109FF000ED53F8FD95C9BE8D960437EE652FB72554 +:10A00000A2FE36E1815805F508F78A8D75E58A16B6 +:10A010008B5301BD8803F141F4479C633AE825DF87 +:10A0200063E3F759A6585D36F01B43CE2971C9B1D9 +:10A030008BD451317CCF32444EB8D4D083E3627E8E +:10A04000789C4E3BDFE75FBAD3C97285B65E61BECE +:10A05000793E5FC6BB56DDF6E1704B7A679CCE99C0 +:10A0600034FF16BC037B267D7BF40885E588BD792B +:10A0700004D7A30D2FF13DCD92956FF03D944B0D7C +:10A080000F45CBFB6CD2FF52AEC3CDB03BCDD7F169 +:10A0900053AEC7691DAB93EF3AD339CCEFAE5C6AD0 +:10A0A000B0B19C112A2F1AF2A7F11E9110AE3FC237 +:10A0B000CE53D160E33BC00BD794AC4A1257CA9140 +:10A0C0008B75397351838DE3B22AF4F7D442FF6E56 +:10A0D000CF623D1E6BF156F3F74FF242E450E37D41 +:10A0E0004DBD4EC9DB0766B03CB4C4C6FECD39CB0E +:10A0F000A57C24B60B3FEE93CC593ECE82F766E6A4 +:10A10000ECF47A942EE8E95D5D4E9AD8EA64F84F53 +:10A11000B91CC1FC65EAE514CEDF7C3999D3999767 +:10A1200065DC2AEE22816E5A8BE43B07EFEBF2D11D +:10A130000CC4B1C6433EEBC9F4DD4EF48D21F2747C +:10A14000BE35C0AB1C807838D1A6AD449CECC48D24 +:10A1500082EF834D821C45FDCF825C158FFD9156A9 +:10A16000C4F76126287CBF68D2D0DBF4FD40FB43F6 +:10A17000303FE1F757B4C2297EC439CDD2B65B80F7 +:10A180007F635F68BEA3FC5EEA249F62C73B929A2E +:10A19000AE6F1B741FBA3FE646E876B2486907EB1C +:10A1A000B09361B27824C9B76A26E4D3B9B06DF62A +:10A1B000D20981601F952BCB7BFC76D5CC069241D2 +:10A1C000FF55FBC91C8B45DE3F233990EF0B88966A +:10A1D000A29E942F59A314403F32E6F5B967EC389C +:10A1E000CFB04E3A28EDD8A7F21EE5D27B324D7E95 +:10A1F0009BD0B48CE08DFD3437A6F5270A6168F456 +:10A2000060E12D1C81F7EB85F1285400F198B7E847 +:10A21000F9EAC13BFFB43A97E1C4F991BF7D68A662 +:10A220002FF25FE09373146BF0DF1B4BB268570D96 +:10A23000EEC1F750C703BF11B96DFC9E444AB64B3F +:10A24000F2A9107B4BF56089C750BB4B59AE3C77E8 +:10A2500084D59D7A2BFB7BDC6CB734D67DCC66BE77 +:10A26000E76BA4F307EBE75EDDBFE79ECAC316F911 +:10A27000FEC26316FFF657885E2FF7D06660BD8F6B +:10A2800021DE9EE7AFF1FA8CF74C3AF895FE6E8925 +:10A29000414F47965DE2FB2AA59176B71A444FE5F8 +:10A2A000AB15BE0F5ABA4CDEE7D6562BF25D846E64 +:10A2B000EC58BF99FDBFFC9ED56F7E112E0B75F833 +:10A2C000CEB1B7BCE148EB84EF9F973D60937C34FF +:10A2D0009089FB0EB72C71F2BBD99F7B8AAB060F1E +:10A2E000039E3C8CA771D8E5547F4B8CB604DF4BA2 +:10A2F00045CB41D81DE7FEFC6D7E8FBAB6398DDFA8 +:10A30000BF2CD995BF0AEFD97CEED17E82F5974458 +:10A31000BAEC90476A1A62F97C9EDB53BFCF2BDA06 +:10A32000D8CF67E0E7BEC1D28E777DBE1CE7A2AE74 +:10A330005711C06C534CF5BAB6631AF6D1503B4B6B +:10A34000E8BB21DF655781DDC41E645F35EC32B6A2 +:10A350009C63B371AECFB177FDF73EF7EAF337F404 +:10A36000DAF91D7A6DEEF89E90FFD72A2ED8D3CB5E +:10A3700023DD3371BFA1FC900D91B462629C5BBE82 +:10A380001F738F7C3FA6F48E7CE66773809302DC9C +:10A390003B19C9FBB8DC4FE990EEF7FBAD6B0FF44E +:10A3A000D90D7A0A78F91D827297D71E17241F9546 +:10A3B000352AA677248CFC0B8355C99748DD00FC11 +:10A3C0007E7C479A1D6F39CD213109F1997B412758 +:10A3D000C33ADB513D8E3F99982E0ECAF7BD14FE4D +:10A3E000BBE4182FF8EF5B95369ADFC3A0FA2CDF99 +:10A3F000ED1A1CC5FD95B868DD69485D3C4F8203C8 +:10A40000C3A9ED3EEACFCDE3303ECA027E1BEC0786 +:10A410007310F742F95B5C7E1BC6296D90EFD46820 +:10A420006BE438DAEA58FB20C8075697BD4FB05C9A +:10A43000D820DFBD9EA3FFDD119A2FCBCDE50427E9 +:10A44000DCB333EEDD86C2AB449F7F7963AC59CE7B +:10A450006C5C6B037E6677F35EC639DD0E5DDA30C9 +:10A4600086DF3728B77AF9BE8AA6C3FBB3DB9CF731 +:10A47000C25F327BDD23B634CAFF65B0946BCFE98F +:10A48000FB71627A2093DFA9BACDC9F1E3B35D8D88 +:10A49000BCDE0E783F44F081DCE22A6678139DF83A +:10A4A000106F59BECE8CDFCEF944C977FCD795F03A +:10A4B000FE5B60D5ECAEE079ACDF9789F8A1D9B44A +:10A4C000EFF10E9770697C1FF6C44333F9EF056214 +:10A4D0009E1CCFE6718FC7BB5344374CD706FD187F +:10A4E000F7F38DF1AC1EABB4C77BBE6B9F7A0F4206 +:10A4F0004EAF277CC30FD0DD3EB5E302268D6B2F18 +:10A5000097EF075EC1EFF4FDFAFF016A916CD3008B +:10A51000800000001F8B08000000000000FFED7DA0 +:10A520007B5C5565BAF0BBD6DA57D8C0668BB051A4 +:10A53000C00D0262116D10101575A1805B736A6306 +:10A540003729C48DB7500191ACA89FF3B10D6FA905 +:10A5500095262A9675B6A68D957570B2461B9BD921 +:10A560006A9A5D0F3A8DD33953B6CD32BB09D234D6 +:10A570009F7DD399BEE779DEB560AF0DA475A6F9CE +:10A58000CEEFFC3EFCE3F57DD77B7DEECFF35E7630 +:10A5900022634CB23136789883B1818C1918934577 +:10A5A000C83FA177FBED02639571ACBE2D13D22895 +:10A5B00056FF6B0B63DFE3DFF89E74A253642C8FAE +:10A5C000B1DBA05D1B7CAF10D9ABCCD6F33DD3295A +:10A5D000D0F78A1436D31DD41EFBC37EE3D5EF1308 +:10A5E000FC698B337BEAABE356D878BBA9D07E9A63 +:10A5F00005EB8BDDF51BA83ECFB3E92691C53236BE +:10A60000DB04FF87A594487B56C4E632D6B057706A +:10A610001AA1A8E14189B118489F8BF0B164C6BE68 +:10A6200068F8CD3BB740BDCF376FAF64437BE635AD +:10A63000C73F8A39463036F75236730C606CDEA558 +:10A640003194560FF364380706D5DBF85CBA07C6B9 +:10A65000BFAD2DFBDC7F305AB79FE530F6FE73BFF0 +:10A66000FDE368E897319FDE7D4DCF3A66AD3EA1B0 +:10A67000AFB204C38DAF734D4657158379CEB6186C +:10A680001C1214CD5E5EC5649827B333671AE413B9 +:10A6900075CC2B42BF6CFD16D904EBF330FE57B5D9 +:10A6A0005C90A95D63BE4F82F50C867AC61C5EDFA6 +:10A6B0000CF0F7580C678448A8E82D910319BCCD1D +:10A6C000F7293DF81D0CA921A707EF890A1DCC5ECB +:10A6D00057066D7BF0050333960FEB651CAEEAFC65 +:10A6E000A72AF3BF6DBD20FBA0DE0D4E07CF572775 +:10A6F0001BE6C17AE7AC4F36CC86B45CF95E3E47C8 +:10A700005BDE8D2FAB8AAFCC9576584F571BC75762 +:10A71000D73A3DE1AB6B4F2F7C2531A9671E7700FF +:10A72000BED8008E2F3682E30B53C057A5332FA817 +:10A73000DEBF707CCD7EFEED0F5E76D0FAA8FFCE38 +:10A74000078DBE1DD0FFACB6BD84B7F2D51BF4C9D2 +:10A7500050AFCE994C7051DBCFAECFB63280E76DA3 +:10A76000ABB7EB1D16FCEEE893EE219559103F4177 +:10A770009E099067BA40BC3BA2A77E39A47B619C2E +:10A78000258BCD91ECDA9E71B628F43CBB3EDA867F +:10A79000E3CDAEAF7A886571FA7767F6E6BFB36648 +:10A7A000CE17B3A03FE4CFB345CE24E48B0A51D4F7 +:10A7B000F09B9A3E847883793D06E03523FEC3DB27 +:10A7C0009E46380C5E14E66C864FA9A9011F8E8B3D +:10A7D000F48CF33688CC6B827AA935818B388F5410 +:10A7E000A0286C8769848D52160BF91D30ED024844 +:10A7F00053249EEE73F2F5C3773F7E6731813C5C54 +:10A80000BF4ACFA1F46A603B57A700FE0D31CCD9F7 +:10A81000ECE8A14FB51F953E55FAED6F7D7BAE700C +:10A820007D6793393C598633C904E3563E3CCCB925 +:10A8300046B8FC3A0D61000F5BD07A81580B6C7DF5 +:10A84000AC3735905776CD0FADB7A524B68FF586CA +:10A85000AE53E5933926CEC3C02751019877D7FA76 +:10A86000A1510CF12D302FCA9DB38BCD22CE5B5D53 +:10A87000D7534D5019E6B6BBC944E9334DC068C340 +:10A88000003E4D76CA3FDFE4A0B4AD2983CADB9D0C +:10A89000369A3F6381886980A78A3085FFFD3C8FA7 +:10A8A000E56541E5536D9CEE4E5B0311B62039FD25 +:10A8B00071BD790D8B42FA0E3C88FCCC1A87B25DD3 +:10A8C00030D4E9F56723C44CA44F3E3FB5DD127D7B +:10A8D00027C93F166170EC02969BB124FB7423E0FC +:10A8E0006BEEF2382790129BD13894E4C20C6FB40F +:10A8F0009300B07E0B4378CC53E460F892AA952382 +:10A90000B17E6BB2558071E65A9CE75AA9FDD5CE4F +:10A91000FBF17B4B99212593AACA26906377287275 +:10A920006C89C0DCC88777A09C44FE120FA5A2FEEC +:10A93000B9A355F01B29CF560B00D721CDEED27805 +:10A9400094135B05E70E6CBB0DE4A9A9479E760D39 +:10A95000737F817A817D07F407FD5F252002715D99 +:10A960006D721CCAF14D827517C379B90D089F0528 +:10A970000A9D9C6E3913E1C8EC81EBA3F85F10656A +:10A98000CC238B286F1B143D86644079454E0E31D5 +:10A9900070F841CADA113F3AA709E9A0CB9212C573 +:10A9A000FA286F884889C3F239AD12C945959EAA25 +:10A9B000D535287C3317BEA3DE2B912A6291BE5673 +:10A9C000B64CA474CE8692CD5EA0E324C11D3B9A02 +:10A9D000D6A367B89E39B513AF47BC55EF30469B39 +:10A9E000006F497A6F524E103FCED9BE2A8941BBC3 +:10A9F000F3DBCDD351FE175BCB8AA3A1FDBC6DD198 +:10AA0000D952901E49CAE67A6441EDC43806F0ACCA +:10AA1000F9FB9127ACA08FE7429F56E8FF9BB670E9 +:10AA20009F17AAD434ED4F9280E7DE3179E2B3A1CB +:10AA3000FE42F1E02DA3501F08BEA7E2A9BE23CE1F +:10AA4000DA873C50D373C00F0EA0F7DAFFF51EF57E +:10AA5000F395F8D6F5E5D0BEA6F68548EC67E1A6F5 +:10AA60003FE45BA1FCA0E849C3FE3F17B63F654544 +:10AA7000026CDD9E857A7CEEA6B4284F1FF217F992 +:10AA800000F151BD5F20F8AAE5337C510684BBC7B5 +:10AA9000CF0C564CADCC80F47E5E628D680FA8F66C +:10AAA0008C5A3E329BCBADF351EB93904EE63FB5C3 +:10AAB0002509F5CC67113C5FF1D4AD6FA0DCF2EC59 +:10AAC000341A10AF1E1D3338519F7941BF221D55D6 +:10AAD00003FFC693DD61AE047A2ACA0E27B8CE6F93 +:10AAE0001D41FA519D177CA7F2CF74CC85F318D283 +:10AAF000DC998D74FF679D7F2EE2F3CFF566A71773 +:10AB0000F199CDF5DB9FD74BA558EE0586417BE447 +:10AB1000CFEB5F8848B5F4D86F25D2FBB28476D6E8 +:10AB20008B4236EAEDF0CC76C32CB21B18D1599D7E +:10AB300095D359C3017DE9E018B2C7A8A446E73709 +:10AB4000F485AF058ABDD59DDFB7D7807C52B3872A +:10AB5000DB11356D67C88E50ED925A859F17EE391F +:10AB6000437685DAAE6E1F874BED3E5E5E9501C87B +:10AB70001DCDE5800042BA0AF105F9FBFEF5D7D3F9 +:10AB80009769F27B297FDFB5562E0F759D49A8B7CF +:10AB9000D6649C3420FE6B972BFD425E1F34DEBCD6 +:10ABA000EC81042F2C1F6AC1F60E8DFD50BB2F9A2D +:10ABB000DAFB6BC356A3BE97EB2C3A4C9B6B2DA4D0 +:10ABC000FFB7D58B19BA5C9C5C9813EDB983619182 +:10ABD000592847072E3C650648026A3B8F8850BEBD +:10ABE0003ACA732FD2671C03AE90506FF805B45F5A +:10ABF0003B5EF97404F63F6E48E06B0653D70BBF1B +:10AC00009B5E0CF26419982D641F670646201D0F89 +:10AC10003CCCE5F4E37AB61AF51BD3B9D93428F75E +:10AC2000A3DC423C7F1BE6DB05FFFF1DF30FC6FEE6 +:10AC300099C93F14DBBDA4D0A7DB68592DC0BCAEB9 +:10AC40001EEA59834BBE41D05F932D220EA434AC33 +:10AC5000D7A1E7DF557B758222A713C18E40BBC801 +:10AC600030C86E413A6E36F3F509B2CC1A611EF760 +:10AC7000671E9E8D7A7A6DA78919619D133AC3C8A4 +:10AC80007E4D1CE422BDD66C4E22BD2D3874AC0224 +:10AC9000EA1FCE14FD3AACCF4C3EACCF4C2176AE81 +:10ACA0006896B19D70F0B56F51BE0F962E1E8982C9 +:10ACB000F50DBE477036439DCAAE738FFF1BA415BA +:10ACC0009776ECFD5748FF2DCAB313E17ABACB75DE +:10ACD000C603A85B6B6D3339B9DE60C1EB3878EF22 +:10ACE000B79136B1677E1D9DE79EFB4D2EA62627A8 +:10ACF000EA9F090725D21FA1F3E9B0C3C487523DDB +:10AD0000B23B3B2CA24F10B0FE91F7707E134C1655 +:10AD1000BF84F6BA49FF65B07E618EC4E87357936D +:10AD20004A61DF8391108B93477D74D14276EB3873 +:10AD3000850F553A7B2B9BDB8F6F297255853373BB +:10AD4000C82C58AFA8F06CD6ABFA2210CE327BF8E4 +:10AD5000769152AFEB9228931D5E6DF431E8B2EB21 +:10AD6000E050D233FDC9D93FA0DD01F6C4F254F959 +:10AD70005D842753F4EECD0AFC54FD2D29FDDFAC94 +:10AD8000C0F1668BC8E1765308DC147A0AA5971ED9 +:10AD90007A8841DBA31BCFECBEF6A351C984DF6BDD +:10ADA0001EE678FD90F0FAED5B2B80CDD8A0BF4D6C +:10ADB00021FCFE0C78F58BB93F02AFEDA178F59B35 +:10ADC00087215E37896467A01D8876A307E5C0B533 +:10ADD00094E7F66006233951298539D724E3778033 +:10ADE0004316C987A3281F54B930C415B806F5E91E +:10ADF0006970E5717E01B18D97E7A4105D24B0F60E +:10AE0000782C07BCE7A17D279986667E0C72B7E592 +:10AE100001DFDEDF403FCD826FEB3C988FF7668B22 +:10AE200013EDB70E9FE8D5C33C5AA259D67E18BF82 +:10AE300065FE554E2F9633456E4C37F8D07E83EF26 +:10AE4000498DF8BD9C7F7FE9EF671F44FBAC338DD4 +:10AE5000D1BA5AB2593ADA672D6519F4FDB7AADCAE +:10AE6000793082B72FE3F4DD32DFE6433DF4E8A327 +:10AE7000BEE1A8275AB6CBF136480D519EF81C9872 +:10AE8000FF2089D37D4B329443BA597097CFC57E4A +:10AE9000AEE1F30D94873DFF1474654E05D106E5D0 +:10AEA000A71B2376A05C55E974F0302EDF8778CF9E +:10AEB0006C45387927B08C7AE8FF4385DE54F80B6F +:10AEC000C0368D00F798103CA87417A3C05F58CA0D +:10AED000E9CF3B41594F1DF3A1BF910053090738FA +:10AEE000571AC1F0837496D5938DF36F5E0CF89169 +:10AEF000701D1C0FA74556DDD6075F15E628F10D1E +:10AF00001802F9A69271BEA944BA427A6C04BA0A30 +:10AF1000A2471648883E17AED015CA8308F7B81C5A +:10AF200058E757C21FF2B1F0ADFF94A6F735CEA493 +:10AF30001C2E2F1E337B4A7348EF4DD0D89D6F6572 +:10AF40007F9A88FAE5F4BDAF25609A14E59E8CEBF4 +:10AF5000D85CFED75214FF1FC607F4B88E0FCBFF84 +:10AF60004F22DA2D954B5F23FABFD2799699983705 +:10AF70001CE01E5D2C38FD00BF792D46E724F81635 +:10AF8000575C750CE159D66A74189156D8628D1CBD +:10AF90003B2B8F40378A1DDA6A24BA39F74B89F484 +:10AFA000C1B9928BAF0E800FE756084EAC57D63220 +:10AFB0006C2590372B2916A85E9957A07A65A91C95 +:10AFC0005F271A05A23740AF253B28DE31A7F58E53 +:10AFD000A988DF13C55F0FA4F8C17A1847E5632E6F +:10AFE000DE489E9529F5AB561B9147BBBF97B5AC84 +:10AFF000BA88FC3FD31B52DE3AE953ECB7AC515B45 +:10B00000EEC635821D77574E440CCA07E664CEEF74 +:10B010001148F240F20FFA93BB407144CF300FC297 +:10B02000C389BC617AA4EB990857A0DBE8A57CDD55 +:10B0300033A70ABE49B0CE9916CE671F9609BEFB4C +:10B04000053EFF0940EF65501E0B745D16C3E438E2 +:10B0500048DD26E60FC7792E1DF609CADBD338D4A2 +:10B0600028AAEF8FB4A15CF7E81189B7322FA5E5C4 +:10B07000CC47E9EDCC4FF398C13A937490AF93FC71 +:10B080002B318EF32BB36703D2D75F8B4E9C16E028 +:10B09000FBDD3942DE2894438D0368DD975B1F702A +:10B0A000A5807606AA41AC5F96E37E14FBB3CA4C3A +:10B0B0008F71AB74958E5A993715D617BBDEE29B0C +:10B0C00004EB8B6BF51CC2F5A64F373810EF8313DA +:10B0D000F83A1374DC9F3F546E60A3810E363F181C +:10B0E000E6433ADBBC3520DAA1FEE6038001CC97CB +:10B0F000AF14BCF0DDEA614E8CD359751E11EDFE24 +:10B10000A2568F1808E2A7E1B241443991BED32379 +:10B11000A29EB45AD7533D355FACD44F3779065908 +:10B12000C94E9E4EF4335CA11FB59FD456835F0475 +:10B13000B817C94A7D99B757FB618A9E56DB6139BA +:10B14000D2677AABA34F3F454D5B503F838FF808E2 +:10B15000C605D27BCA1F71FDDA84F01B78F3AB36CB +:10B160004C370321F8711C9DC74CE379F83CD3158B +:10B17000DA87BFBF7F8FE3631EF0BBB9F5FE22E421 +:10B18000A3CD001FC4F3E69DB3CCD4CFF4599A7974 +:10B1900031A986F22508074BEF753CA2CC2F3DD58F +:10B1A000235A69BDCE4368E7A5CB8CE2016A3F769E +:10B1B0001D7405F46A777A857ACCCB905A94B84797 +:10B1C0003A8EB34E40FF315DC157496BFD6133F696 +:10B1D000E366145F4CCF85FEA1FE268483A137FC75 +:10B1E00042E7995ECCE77342A9DF8EF194746CE775 +:10B1F00058114374C5E7D7D5EA14621C97B18FA0E4 +:10B20000FDC9907E9EC2B80CA4CF4E7E6D4A2EB46E +:10B210007FFED19776B4D0520E3EB30FE556ABF514 +:10B22000E69B709C83229FFF4D72E25D98DF6D204C +:10B230003D9ABE534EDB44799313FDEBAE56DF557A +:10B240002F42BD2C18C664EB3D8F130A9CDA153AC9 +:10B25000383979CB205CEF5345772C5802ED875F66 +:10B26000F7388D3B7CCAFC9416C80F9BF8CBAB30EB +:10B270007F5F8EC73C02E4FEB0D25FDEB60FE56AA8 +:10B28000E9FC1C8297C57645F2A939DAE3F502BFDD +:10B290003747DC528EFCB8D26670482477EB19FA37 +:10B2A00059CD1177DBB1BFE5D1F9264C0DD6BF36AC +:10B2B000A19C3C6EC931211E9A2D131896EBAC0A45 +:10B2C0009EBE1B4FFA40528872778473BA4C74E565 +:10B2D0006428270C0906ADBCD671792FD91D3EB460 +:10B2E0009FBAACF54881CC600954A07C935479692D +:10B2F000717A713CC9E2B4A3BFB44291372C86AFD6 +:10B30000D36039F79F38AF5EFD632E96504B7F8632 +:10B31000B0CC2841F93FDA9BC6103E575383C5BBDA +:10B3200018F544687F5D2070508EA34F4776337EBA +:10B3300048EEDD5EB21B347AA45B5E7AA2F521F2A0 +:10B34000521E817AA2582079E961EB0CB8FE120CEA +:10B35000B2005C3CDBB85E54F97B26CE05F0E549D3 +:10B3600065915C5EE9E473260EC6EFD1AE5C2A45BA +:10B37000221E025EC9E0E9C39FF778937F501E9DAD +:10B3800041FA87A90790FE21FD44E10F8F8A076FDC +:10B39000D9F5A3505FCB12D90395CB8536B4CFE254 +:10B3A000BCD14769BEC5DC2E6897BFA6F51C2A89AB +:10B3B0004B44797962D999C7EF41BDBE299CF4FF0E +:10B3C000A4A56756603C6EA657701A21EF591A7DE6 +:10B3D000F77B986F343A5D903FABF081FB974591D6 +:10B3E000684F08B8CE8C9E75561632839BE239F1B1 +:10B3F0003396403B4FA3E0343B7AE0A1C77A52EF4B +:10B40000F505BC3746FED0FA3FBCD7A8C859773EF1 +:10B41000CAD9A2C6E4870A705DEBF57C9E8DD1D7B0 +:10B4200053DE27393976B91C9EA9D83F9EA5B3575C +:10B43000C6C3F7C06A41F9CEF156A9C8E540E38812 +:10B4400063183F0D2C17483E79BC52A21FDACD5C21 +:10B450009E4D78EF280A905DD8E53DB4925A2B7244 +:10B46000DEA37436178C58946FA7DFE3FE9F47FE68 +:10B470006325B69BD3A2B5832602FD0C40B8BC67FA +:10B4800026FDE9F196D1BAEFF04569EA55AD8ED3C4 +:10B49000E43DAB8BAEC7B0E7AC7B27523CAF9239F3 +:10B4A0002291DE2A656E37C19F251BE633579D4FDB +:10B4B00031B7C72A8BC17EA2EF5A7BB0C7FE893352 +:10B4C00020DFA87854F1133AEF5E7619E376D0AC1A +:10B4D00075DA7ADD761030168ABACAE5DA76BF32C6 +:10B4E000BB9F45B9E8DE38E01BF2ABAE501E828050 +:10B4F000217F6E26E3711FA6E843D5CE2F597A51DE +:10B500008F726866E3453DC273E6D21FE6A75F38D7 +:10B51000B5F3BEA1204ABB3E394E93BFD13544534B +:10B52000FF66F730CDF75BA75FABF95EEE19A9C9EF +:10B53000DF5E3D5E537F46FD24AD1C7A379AD6A36D +:10B54000E2A7BF79BFA5E8A37742EC12359D3AE2A6 +:10B550003F1391BF3F2C67E4BF7C7833D3F8311D94 +:10B56000232482E7805C3DF931F7E5C8EF8F20BFE7 +:10B57000C94FF4A1C2F34373A1C928A27F62E47E3C +:10B5800079A85F729039505ECED4B1FD42548FFFDE +:10B59000670EF39CC7FEBAE30D4B0FF17843881F8B +:10B5A00073A578FF7006CCBF0F79794D2EF7C316BF +:10B5B000EE36AFFF38088EB56DD19AFCA2FDF1EBE7 +:10B5C0003F0ED63B4B041DAEB346E1935A16A07D09 +:10B5D00052BBE8A0FEEAC4402CE63B58676CB4F4CA +:10B5E0008F838B0A0F808F253728DEA9FAC33F1976 +:10B5F0003E450A9ECBB4701A93CBE3905F8F10291F +:10B60000DD9C23C7E7FE03F11CB49EF4DCBC7FDCA9 +:10B610007A2247C859089F9F1BAFDFE31E0F94177C +:10B620008E900B7F26B84CFE47C2A547CF472FD838 +:10B630000DFAA3729D81FBFDDE335CBF3772FDFE08 +:10B640007CB48FF6879BF344E70E07ED97D23EE973 +:10B65000A17B8D611918DF59A1237D797A99908199 +:10B66000FEC226218CFC360FAB4816C8BEB978C87E +:10B6700048FD31AA07EDFD3A90F351053E6B09E410 +:10B68000DFCCE571B1356E714A8A03F5F61FAC1E49 +:10B690008A8B7AE2111E9EFD30E16B69DF45EE2B4D +:10B6A0007E12D06BE5D112858F5FCCD5D13A1F2E9B +:10B6B00014B99D942ABA701F6315D8A968570696C5 +:10B6C000EB285F91C7E9596DF71F0A9DC794DD14F8 +:10B6D00086F388DA24BA7D7D8CFB512E8F0F3D795D +:10B6E0005718EDB3012A7468EFDBBDD6692E58AF49 +:10B6F000BDD0968DB6DFDADC68EA6F4D469715CF80 +:10B70000A1FC8C7478CA8EFEA0C0FA8C33CD55E6AD +:10B71000ABEE0F5894FE36E941BFA29D2298281E39 +:10B7200061F11AF9F91567B126DECA1C020B6EA782 +:10B73000D6F328F46AC7421BE197F6EFD578B15DDE +:10B74000A117A41BC4BB4ACFA1FD8389EC8DCCE912 +:10B7500089F3D915528E1AE5D98D748FFDEA901FA1 +:10B76000BC5CFE076EBEC4E32CDED7DEC37988E185 +:10B770005F529C0CEC4ACE5F4B43E2BE3F914F02BE +:10B78000660ECF4084561EDEABD0C9DA7F82DE481B +:10B79000BA02BC3E9CCBE58FABC0FD36CA3BC7B2FC +:10B7A000D430A2FB1F0B2796604538515EBA723821 +:10B7B00079F33D1F109E74CC6FB4717F0BF9E17269 +:10B7C0007CA4C23149649EBEF4F2883CE5FB1BCAEE +:10B7D0007EAEB76AC80FD9612877C502C6D22CCC15 +:10B7E00061BCB6FF7A0E9C8F85E86A39D2E5AE96C9 +:10B7F0009430E4CF6465BCCA9BD2A70C77A05F20CD +:10B8000018D00E04BFC3C0E33FDC4E57E57A4FB9F2 +:10B81000D67EC4724F668F1FA6DAF7EA773C97820E +:10B82000E3AAF359A5D861FDCD7755124B72A2DC7E +:10B830005A768F80F0DCB15AD4F87D715E612503B1 +:10B840003F3ECE7FAF13FD8E38B0AFCD28CF75F51C +:10B850008233085E817B810A381387F82BE04FE240 +:10B860003ABD67895E42C757D7B1AB858F1BE75D8D +:10B870002CC8909F54512FA0DFB756997F5C05A329 +:10B88000EF69993E01E3219E16568AE3555633032C +:10B89000C6F52A33995386F2CAC64374DEEDB9025F +:10B8A00039256F20C94F3A4FE32AF0A4E7011D4D17 +:10B8B0004D28437667B84B86F1897F161DA7B54C96 +:10B8C000F0A2EF59D4E23C84FE01D011C57D3C2D9D +:10B8D000011A5FE7E571725D8BC1E98075488D657E +:10B8E000B4FF21551B9C32D43BB629DF8FF1952D37 +:10B8F0008DDCDF0DF59374D6FAD7C3D15FAB109909 +:10B9000044010A792AFA5956852E5630773BEEF7CC +:10B910003319FE41BB48A5DC5A3D6F2A6622E5D0AB +:10B920007883DC139F409E6BDC40B2D394AA8D6772 +:10B93000482D2BC9AF33627DA8AC0F897748D5A5B8 +:10B94000141797ACDAF25BF32262088E593C1E9E04 +:10B9500073EF888DB7C27C727F79E31F303D8741DA +:10B9600033805BFEB23B074C87FF16ACD87823A62A +:10B970004FBCCEE89CC18FE057668CFAF1FCFAE828 +:10B9800095F2ABB2260FD0B9C2AF7DD2BF1A4F0924 +:10B99000E54F95FE43F94E4DD75E867FD7260512BB +:10B9A000910F4FDF3B3203DB5736DE73C8C7885F2A +:10B9B0000507D077A577711123BA605697D05B5EE3 +:10B9C00084370B49ECBF371F3F867C3BFEEFE71304 +:10B9D0007F08DF95098CCE6381FD49F69C9AAADF2A +:10B9E00023F2B93EBD906724BC4E46C10AAC3B056C +:10B9F000DAE0BEC778604E2BA47F2EF03C8BE34D7F +:10BA0000813C9EEF7BFD406B0CAE374BC7F58EA79C +:10BA1000DB8EE67648B7FFA8D80F59063605EDDC71 +:10BA2000C02611776E59E0C0E73BD6E2BE6BB9C9BC +:10BA30009906EBCABADF48F484048AF6519668A7DF +:10BA4000B8E5AEB68FCB699FB1D1C0D2286EE00EFB +:10BA5000C3736400CFB0AA4CB257C3AC68AF7A8549 +:10BA6000A4AA881E7B08F5220AB42CEFAD53AC3093 +:10BA7000FEAE42B047337BEC1CD5FE599C9F4CEB8D +:10BA800057ED2068C7B0DD8FE5A74A0B4B22BB19E5 +:10BA9000E683FBF7B64C2690ED1352FFF43223D920 +:10BAA000AF76AF7BCA70B45B97A7E6A0DD0AE39AD6 +:10BAB000246E7FFD3BCA67BB4EF95E28E6E0B949BC +:10BAC000751F800574D1188753EDAAFEE7A563E7BB +:10BAD00054B905957F9B2F9FC17EFF5972DD635539 +:10BAE000E84D4D63F879E0E90ABD8DCF37539A9E52 +:10BAF000FFB3DB73A7AE93FE79EBFE39D7E1FA9F74 +:10BB0000B18ED8FF21F8D83CF97FC63A6E99F24F32 +:10BB10005C87375F6EC8CF4379D646E788EC2E7EC8 +:10BB20002E1CE4DE3DBC9CCB398B930964C7FF74AB +:10BB300079D784FD9D411F1CCFA17877083A1867FB +:10BB400088A5A188ECCDA58CF681862CE5FB404329 +:10BB5000963A4D22DA03166E270E52ECCE414BB9BF +:10BB6000DD19A79C2B888B117D32D43FF6CB5BCAA5 +:10BB7000E7C6E0BE9091ECD5E636DDF516D4535E0F +:10BB800089CE8F86DA89D2D2954A9C5F6B9FAAF6BE +:10BB9000681AE379FDB2B3B44FA7DAA34394F2B4C1 +:10BBA000A57C3F60488BD61E8DABD6DA8FFA82100B +:10BBB0003B73A9BA7FD049EBD32DD7E9F1FC7FA81D +:10BBC000DD897BB0A81407AB7A06B4FE4DD730F6FA +:10BBD000747EF7F98C1CDC1F9AB95AD0E83955CF1E +:10BBE0000224287EA4E2E343D473883FF734B55F90 +:10BBF000D26F3EAF48704C2E4FD79C5362EC7E1EE6 +:10BC00002F71733AFAF5EA116BD1AEDDB7EEC63794 +:10BC1000317D69FD9DE1E504AFF5546F7FCBC6EB47 +:10BC200030FF5076BB3D12E6F5D0A853EF09D0EFB8 +:10BC30006A3CE385EBB378298FB6149E8BD0B37A38 +:10BC4000DADFDBA40F4C9F0DE52B12451C91BE23C0 +:10BC50001D9832189D9F3059787EF5358CEEE33073 +:10BC6000E55C9F1A87093DD7B7CAC3C75905F0C419 +:10BC7000733596187E1FA939E1FEE908EF668781C2 +:10BC8000E139398B72EE4F62D5AE2AA877DC7EBFE0 +:10BC90007D16EE0B6718887EA498CE26C493D99E95 +:10BCA00063AFC27142E235CD29E9372059BCB5FBFB +:10BCB000F09E67207D7BCFC92F319D2AB5EFC3F35E +:10BCC000255246889FD26BBF9811DC9B87335F4A11 +:10BCD00032963B6E10914E75EB6F9A86FE54C150B2 +:10BCE000E71A584F5802F31B601E61BDF689797B35 +:10BCF000A9209CCED54896F5150DD8DFA808BA7FA7 +:10BD0000C0BE03AECBA7F34DF457F680A8473A0E5A +:10BD100053F68FC3327BED1FD3FCC2304DE1593B4C +:10BD2000E4C3157A5F637BCA87FB776B13526E108F +:10BD30001D3DF5695F19D6BBF2BB1BAB685FFD26E5 +:10BD40009315CF9F8529FBCAA1E374A53A5B67438E +:10BD50006AB418647316F1550F5F72E0D85383E626 +:10BD600001F5FA9CA73A6E731EC783DA9FD1C264AD +:10BD7000B42343F7AD43FB817970BE56EAA9FD3188 +:10BD8000D646E70174888B517DB5ABA7B90DDFE9C5 +:10BD900024BB1FFF82E382CC1A43FC35AC55DBCEBB +:10BDA0009CCACF0DA8F4182A2FA5D0FDF7D47A6F1E +:10BDB00038E1819F2708AD1F0AD7D0F6F0B7335876 +:10BDC000DEDD60E1FB885DA99DB922AC7BA53D4726 +:10BDD000337F5ABFD0D37FEFFD3C6DBE4C36F6B9F2 +:10BDE0003E94077DCD77824EBB6F596CD1B62F8DB7 +:10BDF000D17E772568F39245E9DF916DA2F31A8E23 +:10BE00007C139EF753F9D818E2EFF78ADF2AFA2E4F +:10BE100091C9741E7593DE790EE5C4E33340D201F7 +:10BE20007D3C2CF8CC582E55B45B510FC6ADD39346 +:10BE30009C7AFCAE5BCEE0BDA016A06B84E571F7EA +:10BE4000479B6EC57CB148F10D9BFB7039D251CB3D +:10BE5000775FBF371BCF9F3A0D74CE5B3DB7B1758F +:10BE6000AC612B1E0B8ACB94CD69F0FDA12AE68430 +:10BE700099B02363632371FC2DD1A215F5DDF3D1B5 +:10BE8000F5FF8E7194E6198CF61942E15737D246C8 +:10BE900072366E75B680F75B1E1E9B5F8972310627 +:10BEA000FC6594AF90CA7DC517C715F0F8C0B6C53C +:10BEB0002FC523BE37580FDB699E15A213A7D85292 +:10BEC000C1E57F8B85D13E7BF3A852371E4DEC72C6 +:10BED000C90E3C8BD8E2DE41F35E592D72D9AC9C81 +:10BEE000970158C851399CBE0C364AFD986E34B340 +:10BEF000F839289792C2E87C507FF681B484CB57FA +:10BF00006C6FCCE9BFDE43118DF1C85CCB67E49F59 +:10BF10009F0BFD6D9DB199F2AA3C8D53E8BBBBDF31 +:10BF2000103DBA1BF04B72361AE42C9EC7638E8705 +:10BF300089B775F5C2B4203AD555807CCDE2E72E9D +:10BF4000307EBBBEA834E387FC4C9D9BCBE51855E7 +:10BF50001EBBEB9761DC05DAFB515F633F78CE0FC8 +:10BF60005219D7B751A83F447EF30C8303EF39E849 +:10BF70002A400E437B5D82564F1C18C9F135FBC128 +:10BF8000BBCC9EA0384D8C721E66A3BEDE9C06EB19 +:10BF9000D93843746E07786CA96810FA8AC7C455FB +:10BFA000707E990DF5D16FDE5291131BBC9E668C8D +:10BFB00073C0D036D70F9FDBD385C8BF5D2379BC54 +:10BFC000BD67DD1CBE71403FA8879A4797AEE66A01 +:10BFD000DA41725567E56D6DAE7A3A07D955C1CF32 +:10BFE0005DAD13F87E82A4C4CB9B8BF249BFF44BAA +:10BFF0002F152B499F84E2579D3FFDE507E91199D5 +:10C00000F1F119879BB4CE4CFAE107DA3B74F94A97 +:10C010007DD40B1E6D7FBA625136E3F8A85F10AF76 +:10C020003AE6C57B93A1FD952AFC163A1FC969E043 +:10C03000EDB19D8DF88BF4DB6901E0C8E982CEA1FA +:10C04000B3F7383CB7243A7C6BF8012ED28774AE34 +:10C050002BA5F7788F098E65B8EFE87D5DA2F3E731 +:10C06000A17A4FCDAB7030B136E79C3EEC4D9C0FC2 +:10C07000EA3569A7D789FA01D0978AED362A4B09A4 +:10C08000BBB3D45CE0E8ADD7BA5C6DABAF82729362 +:10C090008399F6033C4C53997F30C079ED33CF1C24 +:10C0A000BF8AF53D0EAE03F899E0BCE6F94733E6EA +:10C0B000407BF3EDAD26B4B943CFA1F56EEFA47686 +:10C0C000714BAB4CD319C5236554B986080BD9AF56 +:10C0D000CC7486E4B334C9C6EDA7103DB90EF85050 +:10C0E0008FF04A6404AFD03871E8F84905C9FCDE26 +:10C0F000E4E2521A774345A71EE3905DAE7AC54E3F +:10C10000F2F4A9EF42FBB17B3AA723FF77151AC8D7 +:10C110001E7EF8C1499311CFDE6512C5D17AD17B5D +:10C12000C8BA3D23F59CAE1C8BCD287FB7CCB9DBBC +:10C13000ECE8C3FED852318BCE2F5A96703B63A5E4 +:10C14000BD81E488A542B9E7A2D8CB71AABF13A2EA +:10C1500027B7543798F1DE9B7ADE9085D8DB97EDD0 +:10C16000BF1FBDBB61F98BF1A84FEE2A6988C77963 +:10C170006F89F04F7713DFD5939F02F2381EE5F1F8 +:10C18000A2910E922FDDF27FC6393B0E1E18695523 +:10C19000F88ADB435FE27F41BF668D92A714601C83 +:10C1A0002DB5448E7660BC74DFBBD300AE93BD7AF0 +:10C1B000F2638DFB81F4C12F322638495F9E1E68E1 +:10C1C000B0229DAC6AFC468FF76BCEE2E955E87F62 +:10C1D0005502B78756C51898DF42F3A1454F752E13 +:10C1E00066A8A7F509DC3701BFC58F79162310FDB6 +:10C1F0004C8EF1BAAD00872931BEBB30AD4AACD709 +:10C20000D9609C1247B480F09DA263C5061EAF9D05 +:10C2100085F35C11F311C55927A7C5D17D54A3C57A +:10C22000ADC3FBC97A67D5F6B58CCE8B51BC15B0C2 +:10C230004AF7E18C18C7BDB6278EABEE13A9F1DC27 +:10C24000750529042F21C1FF2DE223CB1A10F11E01 +:10C250007E983E40F6F8AA4613F941CD093BDA91A3 +:10C260003D3223F83EA47A3E17E063B1027C560CBF +:10C27000BC9BD6959414BB17E7A5FA91F120AF505B +:10C28000DE6525CC9B8AEB4B7AC3ED4A867AC60CD9 +:10C290005D366016E0EAB9A278AC1EC6213C58D8DB +:10C2A000384CFBABBF22D140F1D8D0F2270B785CE1 +:10C2B000320B0521AEEB5E13DDCF5D75E0BEF7AA54 +:10C2C000507E1E3039C967678114BCFFDE1D77665A +:10C2D0007CFFDDAE9CBFB5DB0D743FA63BBECCF84A +:10C2E000BEBC1AE7881AE5D98C78F231C721F4C7A9 +:10C2F000FEAB718F1B46CA4F607FAC6DC015C56326 +:10C30000C2C6EA689F2729857982F7055629EB5F1F +:10C31000D50D877A3BEAF575289407F60F878D3798 +:10C32000E7BB2622DD46EC8847FDDA47BC431317FE +:10C33000C17B2879B10462FA93AA799C2466EA3C0D +:10C340008A774853F93ED90A1660FCDCA0C0847C89 +:10C35000BAEA4BFD0D7087E8D7CC7A929391AE90F4 +:10C36000B8482F7F45E6766588DCDBA2F0F9F1025C +:10C3700025EE91CFF2BFE79325BB2852D9F7891854 +:10C38000954272E811570AD943C41C41F0BE9C9DE6 +:10C390007350B1877EA79C8FF72BE7830F2BE78322 +:10C3A0005FC5770BC0903F86EF16407ABCC949E560 +:10C3B0006F341528CA99E36F45EE9248B21F94F97D +:10C3C000E994F9ADB04E7325037E566DD3D37958F9 +:10C3D00063C284E968CF32AFDC9E11DB73EF8775EF +:10C3E000C2BFFC9E73A75D091E3A4F3AC7CAF73F0A +:10C3F000557C2D54EAAF12B619905FC7766AE136C4 +:10C40000FE52A4C6AE2C62DAF397134D4334F54BBB +:10C41000ACDAF39793ECD76ABE4F7668CF5F5E973E +:10C42000313E641F564B570B13806E804EAA337DEE +:10C4300034FF85D6528A7BCD0DB9C77447AB363FE2 +:10C44000DFA7CD2FDCADCDABE7C9C34629F43092D1 +:10C450008DFC31F14EE4F70C85EF0701BF6FB33A65 +:10C460009911DACF1678BFF81EC6001BED4BC976BE +:10C470008C23ACE3F79FB05CC7CBBDC395F67ABE07 +:10C480006FC58EDBE8BE1D4BCCE1ED06F0EF7EFC08 +:10C490008EA4F1720EAF87FE12D61BA2F453C3E531 +:10C4A000939C45FE829BEC33236BB3626A01FEC210 +:10C4B000349A39E99E750CAB27BF7590727F325163 +:10C4C000E8A4BC43B086613E4570A6F0F8858FE4D1 +:10C4D000C35049FE752AF1895B7447F4E6970DB99C +:10C4E000BA07F0AAF8860291E4E2235646EFF9D89B +:10C4F0005CF713BF6EC316B06E336B8F49157AF8B5 +:10C50000E7EDBC61C45F135C0EDA2FB515240B7820 +:10C510002EA588859CCB364569E8A3C41A17425FCF +:10C520004342E84B4B7F7F9DECD5453990CE42E8A6 +:10C53000F02FBEE5512C18AF4C8FFA058FD58976B8 +:10C540004A059ECA02964F75469B31EE678BD173A2 +:10C5500079A5D83FA54A9FABE459EBB2E1FB6B56F6 +:10C56000D149E6F6BA2D3DF12518DF9600F635EAF9 +:10C570006399915C7DB0D31F7635D47F04FCFF6551 +:10C580000CFD1BEB64BCEF65B5E4105F3F624979BD +:10C5900000F35ED0E8587F4331F7AFE5E86C82EFF7 +:10C5A00051A1BE05EFA53DC2F24CA9C1F52DBCFEBF +:10C5B0007A596451909F183182EABF9D6766F8CE20 +:10C5C0008177A0D98771EC63F2AC77DD41EB7F7B9B +:10C5D00014D707AF191CF1A80F1E997C77A687D234 +:10C5E000748D5F684B10E4BECE17858F3672BD9296 +:10C5F0005BE2C7787C74C234579903FD1DB70BE921 +:10C6000042E712F1E85B37FD442B7EA8E406C10F38 +:10C610004B9B745D0E43FFE3110B77351E299ED5AE +:10C620005286F90291EE03D95CE2EBD9B8AE027EF4 +:10C63000FEF04AE571A81E18329ADBBF9386443C8F +:10C640003014FADF50245AB1FF0D7A2BDDE7F14E9A +:10C6500066E45717BBEA97E0BC6D09110CCF6FDA9F +:10C660000A1A78BED8C0CC004F936BBD17F1694A47 +:10C67000F58CC0F647077E7A1CED195B82483A704C +:10C68000A2CBF9AE1BEB1728F19DE279EB703C9B36 +:10C6900045B49A590F1C54B9BE9EC9CBC9FFB20A02 +:10C6A000F4DECC0A6B430DCEE7918470B2F36DAE2D +:10C6B000060BE279C3403DD14149227F576A55C2FA +:10C6C000B40ACCFF62A09171BEF32F1F8AFE815382 +:10C6D000A075355B1A685EC72E8939C1EF96A8A987 +:10C6E000D9A185CFEF46F1F89009E3F1809FB7F526 +:10C6F000CC9C9A8BF4A3A778537F7C6B735DCE7E22 +:10C70000FB61FE2A94030B11BE8597C2984F40FA35 +:10C710003D2961FE777F015B80D6D960C1FE416E05 +:10C72000BBFAA2BF88D19C7E9B0B0E4BF84E82D7E2 +:10C7300021101F345B4E4E443E7828B58CE8E8A1AA +:10C74000828F9A892F86F3FCDB79F7EE413C7A13CE +:10C75000C3697FE7A1825931C1F4BE609448F432C5 +:10C76000EE6F614E3FE2639481F8FB9108C7568CEF +:10C770004F79F3CC64BF4B8275D96C98E7C46228BB +:10C7800087FEA25D623EF17E75058F0B2B307ED554 +:10C79000653B84F8904A66317EAE4939F71491EFD3 +:10C7A0005C4335B4FA6F952597DECFD892D07042AE +:10C7B000D9B620BB6A9022570694884528DF0659CF +:10C7C000B85D65EB940594BBA1FB47AABED729EDE4 +:10C7D0008C325BA6A3541B37D215707D1B6A7FE990 +:10C7E0002CDC5EC33FBC8FAECF353F89E738743158 +:10C7F000DA7A7F19A59C730AB1AF543ADF60E57A03 +:10C800006243AED18774BDA198DB592A1FABF247B2 +:10C8100085BF2A87D47B7EEF28F695514E5E3687FA +:10C82000E4EA99E5786F07D49E7317C37B8956FABB +:10C83000FEAE721FF194626FBDA7D85BFFA1D85BFB +:10C84000EFA3BD05F986518308BF37142E76DD08A6 +:10C85000F31A902011DF143A4E4CC4EDAF71192732 +:10C860002C7DD96111D1A20EE3058F34F27B4936BC +:10C8700097ED9815F159CF95F92C6B766934BBBCBF +:10C880007CF2E37AD2D13EE4EB7B55B94F794C99F7 +:10C89000FF7165FE6F28F357ED8F4943BE32A1BC8F +:10C8A000DF10AFEF477E29FC29A7D0B9A85079B592 +:10C8B00001C408E9EB2291FC9F2078E76AE4BD25DA +:10C8C00020F7F54E59C9681EBFDB6076572C467CB1 +:10C8D0004E6614A79DE8AA27B96503B94572B3F857 +:10C8E0005CEB6CCA473883E59E518163B1CB5A8EAD +:10C8F00072BE38464F1F5724A4D0BD5BD5FE0E1D17 +:10C90000F772F00C9567A682F55EE2F3FF47726C52 +:10C910002CE3E38EBD243AFD5CDE1C4F2679239187 +:10C920007C0AED5F95376F63CC6420BE4F64A1FB3A +:10C9300000770A614E84E79D287C303F97D17DFFC8 +:10C94000C18A3D6757DED1014EA1B8CED84EB0F5B1 +:10C9500083F87AFC2553F71B6CDC8E8FD6E4279A7C +:10C96000E235F54BACC99AEF93ECC335DF273BB208 +:10C9700035F9EB324669EAFFC259A4C9DF50305994 +:10C9800053BF4C2ED3E46566A577480E36ED1EFAEC +:10C99000B11EFDA7B6A11FA7F5864FA1F1F00B0EA2 +:10C9A00060E1B5A38B67E80046855187EF4C86FCB4 +:10C9B000C6D19367E880EF0A071FFE3A195868D37B +:10C9C000E8293C7FF5E1AF5320BF65F4753C3F8615 +:10C9D00091F0DC3A7AEA0C2FE0591CEA797434D0F1 +:10C9E000F12D97EA8FA23DF8C765D3E6264BF84EA6 +:10C9F00040596206CCE76C8AE761FC7E73ECAC15AB +:10CA0000781176FC77F5748FED37A379BB8E8BFCAC +:10CA10005D8D8E8BFC1D0DBBC8F1F65353F5BECB5F +:10CA2000040E9A7EDF5F11647EAF05FDCD3969DCAF +:10CA3000DFC414FD4D4CD1DFC414FDCD397AEE6F47 +:10CA4000628AFE2696A3BF89E95B4D32A5EF34B911 +:10CA5000286D6F7253DA7DBFE029E76A3D0A38EF2F +:10CA60004F8B5B98C3E417114EA1E74A3AF49D4FF0 +:10CA7000D07ECA45E6C0FB1287224E3970BFAC3962 +:10CA8000CF44742E74B63B4CF0BD3097E79B2FB665 +:10CA90003B507E611EED9E8EE8B66C94BFCDB51600 +:10CAA00027EEBB355FF4C7239F14D61BE8DE4C711D +:10CAB0006727C5E90A2DFCBD844311C78E28E39181 +:10CAC0005CDA7991F9457C27C7DCEEB02AE3603F58 +:10CAD000306E32EAB7C225302EF55BBF98FAA9B0A6 +:10CAE000748F2B848C6BFAE171270A41E3A67631AF +:10CAF0007A1701C77568C6F54B743FFCA25FC27810 +:10CB00006147B4D38E714D355F8CDF21BF45CFDFD8 +:10CB10005F2C74F825D493B8BD89EF5BC681D833F8 +:10CB2000D3790D1FC965A84771B99D5D7C9D179A82 +:10CB3000FC0B909F8A957760C08CA57B9B4C0C73F7 +:10CB4000A2BE2891BE3B363817DF39E3EFA0151B94 +:10CB5000DDDB901FEB745CDEB01833DF57D0B5CF50 +:10CB6000FF15D43B193B98EC9504FB4B2C7504B492 +:10CB70005FE4CA44BBE3245B4F72687594E77F8F20 +:10CB8000067ABE31B35E50F427F5637785EFC0FDBA +:10CB9000888E5786E5211F4D333A5E64C0BF7F1FE4 +:10CBA000DD44FC3C2DCA91872FACFD7DF40A9E8F9D +:10CBB00073BC883783ADAC694671FC8F3F2F45F15C +:10CBC0000D749AA70A3AB47FD4735376D1133606FC +:10CBD000E054EBFACAC0E7D769C07870D41807C12F +:10CBE0006FE06146E7983A2747F876E07EDF80FA03 +:10CBF0006C8C87B24C471ED64BD277D27DF28EEF2B +:10CC0000F8FD27A819795350FCFE898392ABAFF841 +:10CC1000E3C931DC4E5D946A598778A8B39B4C9484 +:10CC20001EBC48E78299CE9D8AF16BD9D0F77BA9CB +:10CC3000AF8EE1FA2179A54131024174C294E53009 +:10CC4000A6E6BD0CF4D0F6BBC3BADF8B037032434B +:10CC50009AC8F3DE1D8F17EB34F565ACDFFD1DE3DD +:10CC6000F4ACA7BDFCDBCD8F2F4F55C6437A99C7D7 +:10CC7000C87F0CD53B6B0B6DEA3B3F84E7C763CCA9 +:10CC8000DBE93D5249798714EA5A314E11CEE83D2D +:10CC9000AEC1BF37FB9A819E769A393DA78A3CDDAB +:10CCA00029F2FAEA3BA5EABB6BCF147A6E2BCCA330 +:10CCB0007EFCD48FB4371BDFCB88676D34BEFA6E31 +:10CCC000945A2F01F420092B5D673AE2AB5012FB16 +:10CCD00084E7E7638AE6201D5C68F2B24F82F4CDF8 +:10CCE00085F0C8C660FCD549DAF75A3F1F3381DAB0 +:10CCF000A9ED6B1B27B24F2878E9273AAA4D156991 +:10CD00001FBD4E62AFE23B9C20590DA897D576A778 +:10CD100040DEE278EF82FCC5F43D90BB9FE8D13E57 +:10CD20009D4EE9FB4D1E2A3FDD544D69A0A99ECAC8 +:10CD30003F6A6AA4F496DB2372917F16ED5FC63ECC +:10CD400009A2F7DA36BD2710943F55D4371DAD51EF +:10CD5000E8E85472DFDF9F1CC3EDBB53E3383E3B72 +:10CD6000C0DEC0F7DA802E975B6DFDDB1D1DCAFDAE +:10CD7000AEA3E3F9FE65473CCF2F1FC3FD6E596498 +:10CD8000ADD8FEE87803EF3F45ACC6EFB28DF77B38 +:10CD90002A5DA477A47E35B1E8FE31583F16CA73E8 +:10CDA0007AF2A7AEE2DFE541BC5C9DAFFAFDB64288 +:10CDB000ABFAEE613A7FCF8FDFF7027AA7FED5FAA2 +:10CDC0006326703E0CADEF4BE5E7C943E1F1A9C224 +:10CDD000B7C4176867231F2407F1459D83F842A550 +:10CDE0004395FED6167238A71A153A0FE7E7EE07F5 +:10CDF000A32E847683E3CCB48F20E3BBCBB09E9D7F +:10CE000082C22FA1FCA0BC63ACF283CA072ABD0F6B +:10CE1000063EE3EF34F3758C95FA795F5859477BFA +:10CE20006CC45D84D7837A2BEAADB1127F2F79B0C1 +:10CE3000D8F5CEEDC89FB1110E8C9196ACB2D4F757 +:10CE400025C73EFEAFC243950BFDC0A3171C0CCAFD +:10CE5000BBC33F120E24E7508E23FDF621B74E8C44 +:10CE6000B1297617A7DFCFC7C86F221D7508661DC9 +:10CE7000DE7BE830F77D5FF0E878BE0E958ED61643 +:10CE8000324A07E33A87F6967BEA7ABAD7790723DC +:10CE9000F9971AC6CB43F1ACAE2B48FE9DC179A9D8 +:10CEA000F0640CEC1FE827A1C642EFE8DD56E8E08D +:10CEB000FC36F0D3CA0DAC67FD358A3E7B4C94F846 +:10CEC0007BC88A7EE92E17A49965991ABD4347CF7E +:10CED0003A5FE1EF8AFB45568DEF72A36F1D1C1779 +:10CEE0001F52C8E543D7F43C11F7132FFCD542F786 +:10CEF0008B2F0CEA3C8DF6CE85563D53DE239B2AC4 +:10CF000080DE9D8B3E130CF9A5F29EF3E7E8F70E49 +:10CF1000837A6D174FA3BDB568ABC44C789E60EBA8 +:10CF200037B7203DCD7B454FE7999A5B371E477A4F +:10CF30003CB74FC0E76FD9857D02C5316B5B227C62 +:10CF400066A85F0A79AC7FC76EC9C7E38B32C53963 +:10CF50006A94F13E31D7A5A05D3E71EB5D3A84FB4A +:10CF6000BCED028B837E8FB4DE790CDF1D39B78D6B +:10CF7000DF2F6B3647EEC0F9974AEB0C83A07CC1DC +:10CF8000765E5E6329FD0CF743173CCD28FEB36047 +:10CF90006F04F98FF35AF41F0582EC8EEA6DDAFC08 +:10CFA0007CD666403A58B0535B5EB307F241F279E3 +:10CFB00050A1122F19CEB2295ED2C2E307AA7CEF8C +:10CFC0006D5F7BB91C6D50DEFF667F89A5F70F5F33 +:10CFD000F926E9230BCF9729F93390FFEA1B8E1727 +:10CFE000152E75CAD85FC5B3DC365867DD2B662BA6 +:10CFF000FAED7507CE46E279B04561017A1799BD21 +:10D000002C59D1DE7B60BFE445F8D61E343F89FB46 +:10D0100098752F9E30603CA174DF62B2572631EFC5 +:10D020004AF49BFDA2C8DA898EDAE97D5F2677CEC5 +:10D03000C37E2E1C305BD10EA87BF94FC76EC7FC98 +:10D040008B02DDA7BC9018203A99B755A27B430C00 +:10D050002DB4FC1E3A9110AF88E7B6287A8FE50E02 +:10D06000C43BE219F0EE48463AE171D0794F4BF4F7 +:10D07000BDB9B5D980F5CFF9387E55BC974A4B0973 +:10D08000CF0B1EE7F89CB875D7E630A483A7F564EC +:10D090008F1F817683783B0D1D185EE1FD5FD8C53B +:10D0A000CF9177D3C10163371DE03C2F4707C0A75D +:10D0B000A4F72F47079DE89792BFFFDDB9C7D00EB1 +:10D0C0008FE0E787D5771BD5771A072E3C7514DFDD +:10D0D000E74AB3BF407677A5ED8BDAC58CDE099DB4 +:10D0E0005388E74B26BFBD02D17772CAB3D9142F3C +:10D0F000D507766DC178437438C5C73A92CBB6E18F +:10D10000FB98C5B66F93F6C23A16FDCE48E711EB11 +:10D11000157EC63F3C07A2BE4B0C78A7F319B50796 +:10D120008DFC5CC63EEDFBE11DF19CCE4B0C9D954C +:10D130008BD14F80FE701C41E6FEE9C283FC1D4589 +:10D14000D59F5CA8BEA7B847FB6E83607D9BEA3D78 +:10D1500050984270181A37D68176797339F3840D56 +:10D16000FD217DC1DFA97C5CF18BFAB527FBD11BCA +:10D17000AA1DC9BC21F7DA15B97547019FE3D1BBD8 +:10D18000DFD0E17B8C1D3BF9EF3BCC3F08F22A0658 +:10D19000F719F51AB953A7D4FF14E90FE076DE5B4F +:10D1A000FF922805CB97F78BB19F9AA7793F7548D7 +:10D1B000571457F56F0E83FEBE6CD333E497054CBE +:10D1C0009137FB23286ED44BBEECDCBE12CDF7505A +:10D1D000BA5A0876262E2294BEEAF669EB3D5DA87F +:10D1E000EC7B0E67D7E0F9FFAF31E090D7235FBA51 +:10D1F000DFE9678E28E4EF6E7D2868EFEF0F6B059F +:10D20000960FEA77B8CFC463A44AFEEADD564DFE16 +:10D210009A36BBA6FEB5FB1D9AEFD9FE0CCDF711D1 +:10D22000C79D9A7C5E7B81A6FEC8F7644D7E54C084 +:10D23000A5A93FE6BC5B93EFCA84F5F461CFA8E9EA +:10D2400024BBA0A93FD961D6F47F5D46B426DF6533 +:10D2500051E0A3D899AAFDFBA7426EFF86A62A7CBF +:10D260007FE1D48EA3FAED371468C72B93B5E35D45 +:10D27000295EF01D419D9EFF7E02A6F8FB09BA348F +:10D28000FEFB0998C7DF4FC0147F3F01CB7FDDE471 +:10D29000A4FCBEA602CABF047E09E6F7839F82E90A +:10D2A000CBE09F60F9E5E0774C19F7B832EE1BCA86 +:10D2B000B83F154E6F29FDBDA3F487EF0DEAF43D8D +:10D2C000DF6B5D79E225E0E322DB67745F596E086E +:10D2D00094621CA3F37589E1F967E6F11D6F8A4139 +:10D2E000FD3680A19DC4DC9D6FE23E6EDD8B43ADBB +:10D2F00078AEEF81FD7F7807BF5FD82751BCE6F09D +:10D30000FEB391D8CF9797C2E9300AE945C8D77CD8 +:10D310002B507E0D7CC7736793F74ACABB676DA419 +:10D32000EFBE4C55F33EBA2FEDDEB3D780785AB836 +:10D330007B2F7D7F1DF85AF37DF776CD772BD6872F +:10D3400074A1CE477185CFF7ABFDF9A97E4D2A7F39 +:10D350003FFEF3DD47568E417DBCB76A00C6B51768 +:10D36000EE39113BFB07F0F1D54BCF66A21EA83D6D +:10D370002029E7D1787FB507F44A9ECFBF26756F85 +:10D38000299E37637B04BAB3F4255B4FE7C416EEDE +:10D39000DF5583727661C6ED7A8A7FB5494ABC83D0 +:10D3A000BFD3506365DCAE6BFB3A12DFA9FF7DDBB8 +:10D3B000D1EBF11E74C7C123F45E4CC73E49E34F65 +:10D3C0008D1DCBF13B762CF7FFBEDC772412CF0905 +:10D3D0003ED07684C35DE7A7F51F56F21D9012BCC0 +:10D3E000F74BB4FEF99724CDEF01B8C071A1FBCD86 +:10D3F000FBD322705D27DBF878D3407D50796AD566 +:10D400001C9CFF1BF6F23CE57D32FADDA18EABAE33 +:10D41000DB857276619BD4E779F739D82FCCEF980A +:10D420009ED3E9EBA92F1C1B04707FC335209B748E +:10D430008452AF622CD79BA5064F2AEA91931647D8 +:10D4400004D2F9FDAEA11188DFC39862B9EB49BAE5 +:10D4500007BE601F1FEFA4B53D12E9EEE4BE1152F6 +:10D46000F0FECB2DCA7ABAE9BB1B6F5EC253B56F13 +:10D47000BB05FBE9C11F2F9F36D64AF5DFF09DB8EB +:10D4800005EDAC9319FCDDC0630646FEF5C23DDC3C +:10D490004E3E7970F0F6E0FB59D3147C7464F07D55 +:10D4A000F50BFBF54ABDDB77314D3D3DC7D74EED62 +:10D4B0007CACBE330FA17D5EF3B844671D6AF4F502 +:10D4C000B1B8FE4FB769E757ADC0B946EF8F8D0DC4 +:10D4D000A2D79A03DD7C63213A3FA0F28983F0A9A9 +:10D4E000E2F16486C4E765E7EFF8D5ECDD4574DD6D +:10D4F0003BBEC4E3B783EF313929BE74197F5AB5F7 +:10D500001B82FC2DFABD23BD6B689E98D2631F9CC5 +:10D510002E941F1A9B877E989BFCCC930CEC5B1877 +:10D52000B316EDEB28FA1D89CD386ED73E3DBDFF11 +:10D530005F6B3AB000DF23EF7202A3C0BCBBB6E959 +:10D54000BBDF67463B779E62E77EEAF0E44BA07F55 +:10D550006B9789B4BE9A3D920FCF175C50E4DE57AB +:10D560007B936F407AAD392E59D13F9AD896FC7093 +:10D57000612EE977B257EBDAB89D5CB75B20BB58F8 +:10D58000B5436A153BE49C62079F5BD6C9EDE35740 +:10D5900004B611EAAD0D037B04E65D9B3985ECDA38 +:10D5A0005A69DDCAC10E3C47A5B51BE61F3C44E7DE +:10D5B000AEC0CED1942FDCADCDD7B669F3AABFF8FB +:10D5C000D2D86E3B6338FA372552611CF2C39B0AEE +:10D5D0005E557FE7CE6B9CF4FB270FE81C53D4B855 +:10D5E00004C26BD12B2FCCC779FB6AC29CE47F3479 +:10D5F000FE96E0DAF117EED774E0DE1BF233E3F0CB +:10D60000EDD8CFE97C915EF0E1EFBA2C425D81FD6F +:10D610009904DF328C3B7BBB22493E29E7081ACABA +:10D62000B9FF2A630C18A6B27E2CF7E743F5EA3857 +:10D630005D408A0E921381B12954AFD8C0CF57DE16 +:10D6400019E124FD36C4C4EDF521266EAF0FD17566 +:10D650002EA3DF851824F07D8EAC9769FF606D9D49 +:10D6600085F617047B950EE1B17650950EE97D881D +:10D67000B52D03FD3A355F8CDF337BEC83528B474E +:10D6800087E3EC8C17947D04AE4FCB74567D749079 +:10D690007E656C99667EEA3DCC9F7D7E56989FA5FF +:10D6A000677E80EF286CFF75AE93EC86A432F5F7A9 +:10D6B0001AEA492EA8F0FC12E8BD187045776C8173 +:10D6C0006E6AB61D22FFB296B5AFC476A5917C1DD9 +:10D6D000A506FEBE5169184F75E3B8FC2A51D2A5C4 +:10D6E000E3B4F6C39171B27E1CA43BC6B94DE3F21C +:10D6F000683F9579617D0D6FF377D643E53E9413CE +:10D700003D7D0D7C88F26F46BD604DD5D8699CBFCC +:10D7100016F1A26E3E5AF8F693C427EA39CC6AC6CF +:10D72000F97B66A3D99A1AC4178B90DFD0DE77C332 +:10D73000BF7C8C13F0BF6AEB7C3A97E9698CB5A289 +:10D740005FB748FA92F6257E2CDF2DDAAFCDFBCD00 +:10D750009CFEFD1102F94919E3BAE30DC48F490A91 +:10D760007F6CF708740E60FB773A1ECFAB10287EF3 +:10D7700077331436DA944962BDEA22BA4F7233E342 +:10D780004763594B8CF2BB3D31B46F7993B2EE9B3A +:10D7900075FE4328578EEADB92319E74B4D6E4C4FA +:10D7A000FECB591BBD6F5AC1DA293D155EF7A29F0A +:10D7B0003AF72622DDFDC963A478D6F6E53B225070 +:10D7C000BE67B1E556DC4F0450ECC6B701FBB3733E +:10D7D00042F71DD5FBC4602FC7217D02FE27211D06 +:10D7E0009C07DCD8737AB75FF8C71723117F5F2CCB +:10D7F00079E1965B19FA5F9DE4472DA85F46F75DD6 +:10D80000819CDA33F27BF0AAE25DC55B375E1DF0E6 +:10D810002F18AFB0A6048493F46519C9A57F91E8C9 +:10D820009CD6E5F0AAC27DBC829F3B0E70F9158A9A +:10D830006F150FB7E2BBF54349EF6E233C3123C9A7 +:10D84000CB507AB81CBE8030E93CD9C41823F9A16A +:10D8500083452E4F07CF13285E793BF3BC1280F42B +:10D8600096F0F7F5FCDE0AC75B8582B73F31DF2F04 +:10D870003292FF71783B32CEDD346E606FBE0DE5C3 +:10D88000D3FEF8B2C6E1FC37555FFA18F263083FE1 +:10D8900087F06B371E9DF02F088F9EC648E2CB6E37 +:10D8A0007C4B7BAE4C2FE27F308EB55FF0F993AFAF +:10D8B000805F0546BFBFF8F838ADDE54F1A6C2A5BB +:10D8C000BFB8E007CC7FD42AD0BE0AE7E3BB8D7493 +:10D8D000FF43DD5751F74F5E19C7F55C68FA01D871 +:10D8E0004BB85FB526E3E440B4334F19D47EF8FE5D +:10D8F000EF07CBDA13F1F7B63E28E2E92903FFDDA3 +:10D900000F352F87F1B8E407F1462FC2E90361F81C +:10D9100004D4331F08F75CCFF3710607E6CBE32688 +:10D92000E03D90537A358E79BF127FF0F179948F74 +:10D930002CA67A02FF5D4A07FEDE1DF62B0836177D +:10D94000CCE783BBD2E87D9DEE7D8D71DC0E7F46FA +:10D95000594777DCFF5E81E2FE335135E1FEC48436 +:10D960002D2E7C87F3F47D43B369DFB4413B3EEA5F +:10D97000FD648A976EE0E7FE2E75EAAB82F45BB732 +:10D98000BE2DBEC8CBE7E4D1EF8CA8BF4727DB860E +:10D9900073FFDCC77FDF50D5675DC75FB004C77317 +:10D9A0003F53E2DFDDF9E10F2605EBC3434FAD4DF9 +:10D9B000C77EAA0DDE2CA7057F87EEB124B45BAA33 +:10D9C0009F5A954EF6F4530FA4A35F54BD636DBAEE +:10D9D0004CF9700FF9653ABEEE2F9E1B45E7F3D464 +:10D9E000FEF6CADCAFA8301D2A41BD3DE5EAAF56C0 +:10D9F000E0FE41DA7D02C5FF66B0F615A8672B335D +:10DA0000385FB11613C97FE88FF66B770DFFC54EEF +:10DA100094076F649CD5CF817A123E203510DFD5F4 +:10DA2000F2ADA3DF095CCD7F27B0A77E22EDFF56C4 +:10DA30002D17E89DAB19F5FC77F3A4F1D104C75974 +:10DA4000ABB38FD1FB574B79F914A36FDF49EC6768 +:10DA50008B81DF3F64EE94E0FB7092B25F38739D80 +:10DA6000F27B71CA38699B63B707AF5352F61D59F1 +:10DA7000EA7724DF6E50F03275E98957EDD0EF5424 +:10DA8000BDC73C1EBEBFB3E95CAA9F611CF4333A1C +:10DA90005F9866F03C3A1FD7BDC34871D2DCACC179 +:10DAA000521CD4CF5952B411D3994BAB1E9D8F72D7 +:10DAB000B8D594CD8F35F2F935084E11E5F491EDD6 +:10DAC000B7CE42B89DDFC47FFFAB61FB30FADDC249 +:10DAD000FEE4DEAF9AF8EFF93DDD64A2F4D9262B1F +:10DAE000C3A3EBCF35D929FFAF4D0E4AD9F43CCDB6 +:10DAF000EFD8F4D7DF884BE1F4BB73B9ABCDF43B7F +:10DB0000880D4639753CC02BEDAADA1D0F28EBC2F3 +:10DB1000F7B8B2BDC913110EB90F2C3E86A6B37566 +:10DB20003CDF977DF3E4EA2414D6772C3DF3C47CE4 +:10DB3000F87EFB78F7350827D3B68B14A7387260C8 +:10DB40005525C2BB7A8791AF4F59F7F94DE9718FCF +:10DB5000627CF9753DC50D166D3BF3C4030C7F87E0 +:10DB600077B12198DEAF74BD578FE77EE6E5F8AA5E +:10DB70003F38FC78BE5A9B44FCB303F82AF3A7F362 +:10DB8000D5A2A5CB087ECBC6BB6F42B89DD77B93F1 +:10DB9000909FCE0F1F4B74EE7D4520F8AB72BCDB1F +:10DBA000AF56E0BF506C5B5798DC23C7BF61B90428 +:10DBB000DF43073E4D47FBF99BFDE53FB8EE97601D +:10DBC000DDFE6118AF33511AFA3DDFE019EA84F542 +:10DBD000E5F7F33EE8D2F16AFC9F9F53C03F213640 +:10DBE000F89D21E68D82F9D41C14FC6159A8CF263A +:10DBF0007DA643BF11FCCF8F34E78C19FB28489FCB +:10DC0000F737DFCBA575D84F5A8FDC1DF99EC8FCBE +:10DC1000417A7B54208CF983C6EDF673A0CC40FB8F +:10DC20004EF12417106F782EECC281E13B30FF9942 +:10DC300081E3F1C24B604FF1781093F27BD6F9D9B2 +:10DC4000812FB250CE86AEB7EEE52F883E6AF6AF92 +:10DC5000BA28D0FA277FA6CBBAFCFA0F3DF54516B5 +:10DC6000E2EF337D201FFDB60B864016E2A1EEB732 +:10DC70005C9EFF5838A8E5F3571BE8F73AEB04130E +:10DC8000D14989F425C51F2E1CE7F187BA034F92AD +:10DC90003CED3AC8E3408BC4F6D2388C9BD49F3914 +:10DCA00086F2ACCBCEFD31E89FDE712B1CAAE84199 +:10DCB0005D6712DEF73BD84D0FDC8F3C8FFC3B0CD1 +:10DCC000FB69A3F3BD2C2B9CA15DF139F2F3307CF1 +:10DCD000BF307925D2F979DFC01C948F6F66FDAD16 +:10DCE0008EE286BF0FA77BB2B56D92E69C79F73ABC +:10DCF0007C123F70C454FB299CC9C1E7B90C8E1B30 +:10DD0000C86E7E83EF132EBA8AF3137B99F353ED1B +:10DD1000F243067B507FBB157E52EDC829BFFF1B27 +:10DD2000F1E5B38532FD04D54FA5C7FF9FFEF74C43 +:10DD3000FF2F4133EC630080000000001F8B0800C0 +:10DD40000000000000FFA55A0D705455963EEFBD2F +:10DD5000FE4927DD4913421208840642881A6203ED +:10DD60008172D6C4E9FC6E2033BB016B2DC4088DD3 +:10DD700022249D7482E8EC6AB96E1A02AC6475368E +:10DD80008C59471D479B9F8028EC769440C0A00D7E +:10DD90000ACBA26B45AA263A555B54ABAC0EE0A663 +:10DDA00023823BD6E2B8E73BEFB5DD1DE24FEDA69F +:10DDB0008ABA7DEECFB9E79E7BCE77CE3D8FB45247 +:10DDC00022CA226ACFCD082A0AFFA66EA245446D58 +:10DDD00029247FF641451FAFD364BC7D40A3C958B9 +:10DDE00093EB08CE9E415447DD269A45B4844265A4 +:10DDF000A471BF29F2CB5B79BCFE0D6D4117936115 +:10DE00001BAD6AB013D5A67A0B3614130DABCAAA94 +:10DE10008662CC0B952E9D4BF40DFE7E4A749B873B +:10DE2000994F222AD3140FF61B9D9C16DCC95D8BDB +:10DE300097FB1B494D98A7EAF3984F53087C82A3A0 +:10DE4000254B1DD868B46499233EEF8E37D2D60790 +:10DE5000314EA1D23B12F6F94B8F856821D117CBF9 +:10DE600017AA0F65F279AEDA037433518D76ED2976 +:10DE700085F7DD70CC4C5605FC67BCAFF239026704 +:10DE800034EA65FA52470A79ACCCCE4B1E0FCF1B51 +:10DE9000993B29D8C5E76F3FA09089E7B51DB1EE42 +:10DEA0004CE1796DE648B69BF7DD36F03B8B87DBBE +:10DEB000F6FEF72CAEB958CF4736439E1415FA6DCF +:10DEC00077F24F17917F60CEFB77313FFF694DF4BA +:10DED000ED37BD6721D6D7059E8FFD5A0EF6D58248 +:10DEE0006EA5F05627DAFD3CAF48BF9B6FF8DFE523 +:10DEF0005C5786B3387EBEF8395DA2A718BDF869B5 +:10DF00003EF702D68B46EB437659EE21967B716E37 +:10DF1000CE8E2E25719DAE5F8F76694B0ECB159DF3 +:10DF2000A9B81566154D0D6C76421F858AB39717F3 +:10DF3000475F7FB9742DF49B122CBD9DCF17B59010 +:10DF4000DCC7E2C7B69BB40479160F6A1EDC433403 +:10DF5000959A0EC9BD7BA7E23EA8BC61A96712D6FF +:10DF60008DBE7B2B6F195579BDFDFA7304CA757987 +:10DF7000CEB0A9C97D1B72D7E7E5ED80FED900C4FC +:10DF80008E4EA9FAFE1E95C7E7C7D7BF689CA74665 +:10DF90002BCE89F0F806C59DE31C679F58BB87F51B +:10DFA000BE86EFE945BE6FB42F753869CD6CA2FD12 +:10DFB0001DB942FF73874BDA504791F4BFD2E11687 +:10DFC000FA60C72D421FEAF0083DD05127EDD18EEF +:10DFD00006E93F0351FF8C70A020ECE2147C6D4AEF +:10DFE0009C1ECE1C434F499E3F9CA924D353149999 +:10DFF000FF70B83C1860FAA532A79C938DCAD1C0B7 +:10E00000FA684E4B2FA10CB4F9414A67BBB17B03B0 +:10E010001EB6FB3FD4EDDA4333C5CF4B30AF3AF3F6 +:10E02000CE46F8DBE52C2B69ACCFC31EEFDF63DEF9 +:10E03000E9D35505DBD13F68735BF9FE8757DC9464 +:10E0400001BD47FF4D238DB7AE285AB0B994E90AF8 +:10E05000BB2276CCFC6E6EC866BBC64FE65335B8A5 +:10E06000BAD4A4E38473B602FDB7AEC13E1B26DB6F +:10E07000165879FC4AB9F757D827A6F7DA29EB0AD8 +:10E08000BCD08BD9F5BECAF302FF6EA65E9EF780A8 +:10E09000C39D64DF47CB2B82B09BC545B336CF070A +:10E0A0007F76BAD9BC3FBBF57EC8E751D3944EC149 +:10E0B000319709B810C4FDF33E952E45EC306C71D4 +:10E0C0009932997F38B5222BC0EB4E19F77DDAB81B +:10E0D000EF33C67DBFC3FDD5DCBECBFD6887B81F5F +:10E0E000ED8A989E4DA385D05FF0A70D2F7944EF60 +:10E0F000A3F9A0A3665A0E3B5C023FD3F127BF8170 +:10E10000E578A25C97E36E037F866E6BE8D3D785D4 +:10E11000844F8B85BCB0FF4B589F609FB175F1F564 +:10E1200024EDB29B2990C2E7A0C3B620F4445389E2 +:10E13000805FCB0EE7082E6929B38ACF4F647A013E +:10E14000099ED2AB567D5EAE6B21FC857524FB8C9F +:10E1500004D58099EDC49F395498C9F28E187E1663 +:10E16000A30FFD4913FCF6CF679ADBD714FD7CFEA5 +:10E1700065438513B05EB1A9B033FF4E7DFCACE1C1 +:10E1800087FE99063FE33C9412CAC77D448F1DCE9B +:10E19000BF87E92E7B78AD1E07C28582DF142E5C17 +:10E1A000069C5442E7C84DD477FC7DAFE927D047A1 +:10E1B000E879D0FDC77FAFD34ADF3967E2F8A450D2 +:10E1C000BEE204FD8141F73D3FC19D409B5F398721 +:10E1D00071CBA6DF7BAB27336E5883A73B6037FF3D +:10E1E000A2DB97ED40FF27D05BCB112BC12E2B0F6D +:10E1F000F47FF60A8FB7F43BDC80FBA86786E8BBA8 +:10E20000F3C8DEC7616F237D66F187AEFDBF7BFE7D +:10E2100011996725985BBD35544ABCCFD1E37FE3A4 +:10E2200035619FB4D015D06F579C1739EA27EAFEA5 +:10E230003D54F1A93700BDF51FF86BC4B5FA0C0ABF +:10E24000C06EE965BE4766E47BF5866A2AE171C760 +:10E25000D04AF06F7BC9EA869DFA5ECDA9841F5F24 +:10E26000F3CC14FB6BBEB13B1F71573DBA6FCF238C +:10E2700059986723C8DB9EC976C47AF5693B16DDD9 +:10E280002FF7B76BCF6F20F73E1BED643ECDCC036D +:10E29000FB35EF991D0CF0D15EFBFAE395B8871AB8 +:10E2A000EDB93DE8BFB2DBA6420F672D9E8C72F838 +:10E2B000E159B3BB17EB0CBA7978A22E4F5AA4568A +:10E2C000EE2FAB3B1F71D737F1E1BF80DCF55AF77A +:10E2D000F3CFE23C7BAD843871611FEB8DD75DE8F5 +:10E2E00035CFC72D8FEC7398602F9794EE95CF8222 +:10E2F0007FAF3EEF92AD5BF419E89D43D88FE711F5 +:10E30000E2F225657B52FF85DEBD255ED6DFC5972F +:10E31000EA8BBD09F61BF317DF6E6B527C14246089 +:10E320005CF219BFC919203BC7DF6683BC78E89946 +:10E33000916729BEFEE27E73D8C23A6AB6D2E694ED +:10E34000CCB83FF8F2FEBC0EE7F3A93B0A91C73404 +:10E350002F88AC845F5CB0514A2ECF7BDB885FBED8 +:10E36000831B972A25DF2D4F4D85EEC75773F53850 +:10E370007675C0160C28DF1D8FFEA3839CEFCC8E14 +:10E38000D377AF677E29717E6F5B42AD6EDEB72DAE +:10E3900053C78F733C7F3FE35895B1CFAA8792E76D +:10E3A000DF529129F6D3668914220EC6F82FAC8865 +:10E3B000E15AA4107835765D3DD213E0C8CB8AE0EF +:10E3C00088EFA0F2A1966EA8343BAE4F5F4A20A81A +:10E3D000958C7F0FB98B8C7B605EEF55E87EE5DB1B +:10E3E0006FF3D8984F4B6A241D7953AB23928E7CE0 +:10E3F00068E4A8463B8DEBCB8AF19F19DFAF494615 +:10E40000B83F64F6D8C6DB8F8F433C6F1D7EB32ABE +:10E410003EA9D0FDA669204DF623676411ECB6E94C +:10E42000B9E47538A733C11F470676657B13E28FC1 +:10E43000CF903BAA7C287E13FDFAA37CD8814FA500 +:10E44000CD0AABF622AFB1650A4D293A1DB0B1E550 +:10E45000FBBEB4A7C27E2E5E6D153F1E5122827395 +:10E46000B927AE0A3E8C982382738ECAFF11FC181E +:10E4700099105909DCCAADB4AF96F1C991952E1E19 +:10E48000FFB2C2A0A791E40385273257034FEAB534 +:10E49000D1B711376997D9093F89E97B9DA127A297 +:10E4A000C7863B78FC0F41B30BF1614EA562E40BCC +:10E4B00096F8F9B5B83F8D90EBC041F86793DDDD74 +:10E4C0002BA3C1FDAF201FBC33DBDDE5BA5E6F328D +:10E4D00087E5CACAFC6A2DEE293BDDFB8F15CCDF30 +:10E4E0005F1CC907CEB1B54B1C6A7BDDBA13FB4775 +:10E4F000CDA37B805F171CDE272B589FAD96A1AD67 +:10E50000A52CD267E6C829A4F84B606F8223BABD58 +:10E510008D14EFB2089F1E562AEB6797710F944B2C +:10E52000B403F6A1E8F7FCE6C0ABEF006F468666E1 +:10E53000094E8FF5A70B034FA603373EE0F81E9850 +:10E5400013EFFF60F55E0BFA97BFB8C312E1F69EBA +:10E55000CDC9E7BB7CEDF60CF80B3D9ED00F7BECF4 +:10E5600049A6C7EA0576194EF28380E8FD9CC729C3 +:10E57000F2B7540EB5410FDFD2CB98D612E8136331 +:10E58000E831F3A941CF1FCE7948F8B64E0B0F43BF +:10E590006F2307CC047CEFE4B826747F5A10EF1A7F +:10E5A000F500C7AD2C3D6E215EB4A40FADC4BD8C8B +:10E5B000F45B9D98BFE9C8A7F9383FDB633ECEDB2B +:10E5C00072E47036C1CE8DF704C7C76C8CB7F41FE8 +:10E5D000C9C6BB24D6DFAA860A211747B812E0476E +:10E5E000ACDFAF850B217F8B325482F128E496F9A2 +:10E5F0004C6BA049CED1AAE87E4F4734C1F9B1F7A0 +:10E60000F651856EAF8C0F25C807371DBD5412B16A +:10E61000C7F1A0D9C09513E82FD6FDDFB9C8C0094E +:10E620005EDA0CBF1F0727BC31DCA3F516C87DAE30 +:10E6300042973BB65EF8CA3B2320E36DAF5D2A9953 +:10E64000598C75C63C4AC0A359717C010EE40A0E70 +:10E650006C3267F3B97CCF2BEE4E5ED2DCB8B1964C +:10E66000A7D33AD3FDB5D06B1305E45D3756AEB1F1 +:10E6700076F470857EBF3E557F8FFBF628C14E969F +:10E68000EB22637DEE7CC19B30F0675DF5C65AF8E6 +:10E69000DF7D597E4BE2BBF987F8AFED49A6D7ADD8 +:10E6A000DF589B338E9FFB1EDA7E6A125DCFAFD997 +:10E6B000BBA336DB757D7F4CEE8BB6989C95E64907 +:10E6C00089FA58BEB17612B7EB52FEAFFAD0CF7DC1 +:10E6D000F188358CB8CBFAB5E0FCB7FD71BD2509E2 +:10E6E000B77F805F33056B9D33BE5BFEB16DAB12B0 +:10E6F0001E56804FEC5FBDE267EC3709FB6DAA1830 +:10E7000053A7685A3D1D793779574F4FAC538C6DDD +:10E710001928A7A8B788BD49CB7EB8D23D8E3E62E6 +:10E72000F36FAED4649F4D861D4FA96F79E6151E19 +:10E730007FB9CC5356C97E55AEA992BF8FDDA7A62F +:10E7400052CF0F86B21DBF803D4507CD4EF849B967 +:10E75000A6EB334FBDFC2EFC312FDBE1EA647E35A6 +:10E760005569FABC633627EA40D1635FE57BE0FF79 +:10E770005BECCBA5CE62B2D3641E3F953B57F03D18 +:10E78000B6CFC7C63E69A57ABED35E64FEFE3A53D5 +:10E79000B1E3DB3A93E41BC569C1D91287BF90F896 +:10E7A000161D5CE8D45CC0F7A01DFED6FEF57F67A1 +:10E7B000230E8F0CFE67BA0BB875EDD374D8CFB6A5 +:10E7C000818FD3810F27066639D09E1D7239D01FE5 +:10E7D000ADFBB816F3BA8C365E67308B9CB136F65B +:10E7E0007E8ED51312DED1CDD06BAF73DB2F4B6194 +:10E7F000EFA9DD8263FC8ECE44FC88D7195C39E337 +:10E80000D56512EB0C05B3F53A035AD4190ACC7A44 +:10E810009D0134EA0C685167403FEA0CA051670043 +:10E820008D3A0368D419D0A2CE80FE2BA86BB1BC60 +:10E83000514EDE50DFAAD1EC82FF0FF46A41E4F5BD +:10E840000F1CD3747A8712C47D7FC6FB230E46AF9C +:10E85000E875B028C75379E71F34CBFB201ADA5E7E +:10E860003713F7D6AFB97155171137D914DBCDA3CC +:10E8700027511F6AEF53DC1B5DE85F2E726C1B5C37 +:10E88000F87E23FA7BCD6ED585FBBA9A8DFA976F09 +:10E89000B057EA58D539C72C72CFFB15CAE1FDEF46 +:10E8A000B0EAEF64BFC6BD2CF7B045953CDA6F1DEA +:10E8B00092F74BCB8B8A734D421EDA7ECBE78213E5 +:10E8C0009DB6F49D90D71FB239D724C5578FE47DEC +:10E8D0007EFC74C18D3C43454CAFD5A790DF5E7B79 +:10E8E000013821F948427EB4D6D9FC33E467A45DEF +:10E8F00033E1FC7E7EE84E64F9D63D6DFE2892B091 +:10E900007F733099F60DF66DCD23C899DC8F4A03DD +:10E91000E2B23F94DC1FAA74647D92C63FE6D13C0C +:10E92000E45B75FFB4E6403FEF77B9DB2AF9CA61D3 +:10E930008FF77025FBF149B347EA2F278FD9E4BD44 +:10E94000757EFB9CA4FA4B8D3655EA1F1BCC8AC4FE +:10E95000F12BE5DE63B0CBAABA7BA5EE5295EB10A6 +:10E960007F8ED9E1D1F28637C077C35C97D4BF6A76 +:10E97000ACF40BE1C77E2FF73C68167FABE95482FD +:10E980002AD3ABC96D817FAD62758A3D99ED8F2920 +:10E99000EC0FAB78AFC604BBDAB05D91BC420A1095 +:10E9A000ACE795863E570DFEEB570AFBCBBD563DB7 +:10E9B0000FCE5355E19FD7C5718BE7DF475E0BFC48 +:10E9C000661DC755B41C675F8F70BF376D6ABE9EEA +:10E9D000E7BB72C07FF51933014F6A727E5EE8951E +:10E9E000785FEDFC84EF5B09DFA57D73D3F7E1A8C9 +:10E9F000893E49C86B4F9A75FC617DCA7BEB14EC6C +:10EA000055EA3E5E69CF743449BBA28CC4FF0B3417 +:10EA10003D6F2FE0BB72664ADDA20FEB6BDAED6E45 +:10EA2000E83F860BBB8DFCBE40E596E7ED4ED55B1F +:10EA30000BD329DC3F8D5BCA147E61E77CD4715C0B +:10EA4000C23F4F3DBBC0057D7C6977431F3539C749 +:10EA5000E6E1DD31CBE0FF7259C355DC97279D021B +:10EA6000D89F8F43DDACDF5A1C48415D3DE4D15057 +:10EA7000273FA638F1AEBF1E4FB76F71C2CF0A1441 +:10EA800027EAB7B5A9DD35D9CCBF76E60C37F09CBF +:10EA9000F155EA6123DCEA76706B5053F4B5A66C4D +:10EAA000D4F30DFF29F7A6544D8AF7D71B7E141D0A +:10EAB000FC221DF1F547D46D77837F806CEE5E8379 +:10EAC0003FECA0FEA66952BF8DD9D1E5FD393B616F +:10EAD0004753ABF4758D8DEF99914F0CDDE6CDC1A9 +:10EAE000FE2BD77CBE255BCE397EBD8C713703B83B +:10EAF0003BB65E16C3F13D46FD1D786B32EABA2681 +:10EB0000A3AE6B32EABA26A3AE6B32EABA26A3AE44 +:10EB10006B32EABA26A3AE6B32EABA26A913AE97D5 +:10EB2000F6DD8E87A41DEA08C87842BCB8B9EAC7EA +:10EB3000D55D17558D5377A5145786C45DF67BBDFB +:10EB4000DE3DA6CECAFEAE26F87BD5E0847B1E4312 +:10EB50005ED26371B338546BF1163C60177CF0548D +:10EB60008D5B6F8DE9CF2EF5D9CB649B8F7BA82C65 +:10EB70009A655251C734EE2356EF84DFE09CF01BB8 +:10EB8000B4F01BD3ECB8DFFCD6C2AE5DAAE7090136 +:10EB9000C9136C72BF5B3732AE307D2F399370E58D +:10EBA000B331B8C20F9A159063EDA095BA743F23A4 +:10EBB000F84F25377F9C3F0ECE84749C99961ADAC5 +:10EBC000877DA6B5A5BA9117B3BF8B9D9DDCA6889E +:10EBD000BFAFA106D9771CBC49479E7CEFC4D17357 +:10EBE000BFE1F9F7FE835DF29DAD93D72EFAFFE00A +:10EBF0004D4D95AE8F5F77847DE75996EA54B643C5 +:10EC00008E57D5162A92BAB89A2AFE50A33DAE580E +:10EC100080A377D33CDC77B5B5E139C899C3FE2E24 +:10EC2000EFDF2CA3BE6B1A6ADECBF4D9EC3C37BE07 +:10EC3000AB4DCD3D44050B804775C5B0ABB3D4ADEE +:10EC400060DD6319DEBF83BFDC5ECCA756E3FE96B2 +:10EC50005397B6B34BEE63CE42DCFB32ABAB1FF542 +:10EC6000862D6F9E907AC2B20CD742D41BB6BC7967 +:10EC70005AA7735CFD8A1BE5B213ABAB7F82F866C3 +:10EC8000EB3E9F1067FDA1094974FBC0E4EEF30958 +:10EC900071AE053FF89D4E3F534CB8AF5643945C60 +:10ECA000D5BB1DF2F9EBFE4B7FCFD3A8C4C9A7AAF1 +:10ECB000745C9C7482C2B0E7D1C50EF9FE973371C3 +:10ECC000FD3CD4DBA8D8B510F338AFFD35ECF8E245 +:10ECD000AD9EA7C127CF38770EF1793558C7900D73 +:10ECE000ED19E3BBE429D5DB88B6363D60927E356D +:10ECF000588AF66D35F420FAD92F76814FED93F3CB +:10ED00006E2C623ACF1A9AB7DE8E78E9D98DFE73EF +:10ED1000659E5EEC37B6EEDF699C8FE5D98779C3D7 +:10ED200085AAE4F9C337EA6DCC2EC2553A0E1D37D9 +:10ED3000FCA8AC93E4FBE758FB395EA51A78F9FD13 +:10ED400072B3BC47204F4C7EEA5E5D0A7958DEA361 +:10ED500086BCAF619CEC99528FF96E7B0DC87EC763 +:10ED60000D3B657C6C39AFE3A3B485A6E004E40DEC +:10ED7000531E0D4E80BC53768CDA5CDCBE1018B589 +:10ED8000217F78E16F476DE87FC14375E3E1BF56AE +:10ED9000AD09DFC2B251593F9DF71A9277C2E8041C +:10EDA000E46F854D6F59026CB7739EE67D93F2B7A1 +:10EDB000228963D30D5B9AFEA84AB087E9CF90E41D +:10EDC000AB549D25E3BE14DDFF7D8F3EA8C28E6E41 +:10EDD00008B2DC09F637E769D3E54812DFB0AC6B5F +:10EDE000317083F3B5A4713F3347BE3CC5C023E403 +:10EDF0008F8D8C37FEA6B7BE42BEC879DC187E8CDC +:10EE00004D311C26C45DEFEB1117FC2079DEDABB17 +:10EE10001ED98AF76D53E3768BBC8FD7F46D45DB33 +:10EE2000DAFA9E258724BF4C9ACFF965127D9D9C06 +:10EE300063E4687BF0F3AD39E3ECCB76702DD10E53 +:10EE40004E9A4337E0BD7AD29FEA0E481C09DD0F87 +:10EE50007CD9D96A7723AEECFA55A5D8D7B7F5A9EE +:10EE6000328FA9FA47D951A7CC0F545211FCE6872B +:10EE7000DA11E0E1EC243C0C48DD72894370AEDD30 +:10EE80007807B6AD714A3E12F3EB3653E8C3AD983E +:10EE900097E590EF110CB745A62C7C6F9AE2EE4AED +:10EEA000C82BCE2E9915049DDD190A83EFE8CF15E6 +:10EEB00037EAC8D5693AAED6A80DAD7B79FC2D35B9 +:10EEC0002CB8F15BE007F36FB7AC977645D94CB13E +:10EED000DB5C0A29FAFF67702DC47B3DF63DAD6708 +:10EEE0005BB0EF20DEFB4AF099B5A88FFE955DE49C +:10EEF0008906D58099CFD3338104B77BEE2C94B8A3 +:10EF000013A586C6FB91FF2C4F953A6ACF04D71301 +:10EF1000F86EDAD37CA3E4F587FEA4C7FBD1A5295C +:10EF20006EE4713DF35C1B71AE9E475D32FE9AA2AA +:10EF3000F30B3CA1EBA767A97ECE9EE64C799FC55B +:10EF4000EEA167876732BEBF5932BCE5D5A803186A +:10EF5000DF1F7B66703FB74F290D77DE073E737565 +:10EF6000795794B9E4DE4EDE79E3137B747D86F144 +:10EF70001DAC7D8923E9FDFEBFFE80CBB3202200BE +:10EF80000000000000000000040835000000000040 +:00000001FF -- GitLab From 94a78b79cb5f14c09a42522738d6694c6a1cdd20 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 27 Apr 2009 03:27:43 -0700 Subject: [PATCH 0751/6080] bnx2x: Separated FW from the source. >From now on FW will be downloaded from the binary file using request_firmware. There will be different files for every supported chip. Currently 57710 (e1) and 57711 (e1h). File names have the following format: bnx2x--.fw. ihex versions of current FW files are submitted in the next patch. Each binary file has a header in the following format: struct bnx2x_fw_file_section { __be32 len; __be32 offset; } struct bnx2x_fw_file_hdr { struct bnx2x_fw_file_section init_ops; struct bnx2x_fw_file_section init_ops_offsets; struct bnx2x_fw_file_section init_data; struct bnx2x_fw_file_section tsem_int_table_data; struct bnx2x_fw_file_section tsem_pram_data; struct bnx2x_fw_file_section usem_int_table_data; struct bnx2x_fw_file_section usem_pram_data; struct bnx2x_fw_file_section csem_int_table_data; struct bnx2x_fw_file_section csem_pram_data; struct bnx2x_fw_file_section xsem_int_table_data; struct bnx2x_fw_file_section xsem_pram_data; struct bnx2x_fw_file_section fw_version; } Each bnx2x_fw_file_section contains the length and the offset of the appropriate section in the binary file. Values are stored in the big endian format. Data types of arrays: init_data __be32 init_ops_offsets __be16 XXsem_pram_data u8 XXsem_int_table_data u8 init_ops struct raw_op { u8 op; __be24 offset; __be32 data; } fw_version u8 >From now boundaries of a specific initialization stage are stored in init_ops_offsets array instead of being defined by separate macroes. The index in init_ops_offsets is calculated by BLOCK_OPS_IDX macro: #define BLOCK_OPS_IDX(block, stage, end) \ (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end)) Security: In addition to sanity check of array boundaries bnx2x will check a FW version. Additional checks might be added in the future. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/Kconfig | 1 + drivers/net/bnx2x.h | 15 + drivers/net/bnx2x_fw_file_hdr.h | 37 ++ drivers/net/bnx2x_init.h | 605 ++++---------------------------- drivers/net/bnx2x_init_ops.h | 442 +++++++++++++++++++++++ drivers/net/bnx2x_main.c | 343 ++++++++++++++---- firmware/Makefile | 1 + firmware/WHENCE | 20 ++ 8 files changed, 866 insertions(+), 598 deletions(-) create mode 100644 drivers/net/bnx2x_fw_file_hdr.h create mode 100644 drivers/net/bnx2x_init_ops.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3320e7761576..bc7eef12d955 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2676,6 +2676,7 @@ config TEHUTI config BNX2X tristate "Broadcom NetXtremeII 10Gb support" depends on PCI + select FW_LOADER select ZLIB_INFLATE select LIBCRC32C help diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index a329bee25550..8678457849f9 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h @@ -965,6 +965,21 @@ struct bnx2x { int gunzip_outlen; #define FW_BUF_SIZE 0x8000 + struct raw_op *init_ops; + /* Init blocks offsets inside init_ops */ + u16 *init_ops_offsets; + /* Data blob - has 32 bit granularity */ + u32 *init_data; + /* Zipped PRAM blobs - raw data */ + const u8 *tsem_int_table_data; + const u8 *tsem_pram_data; + const u8 *usem_int_table_data; + const u8 *usem_pram_data; + const u8 *xsem_int_table_data; + const u8 *xsem_pram_data; + const u8 *csem_int_table_data; + const u8 *csem_pram_data; + const struct firmware *firmware; }; diff --git a/drivers/net/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x_fw_file_hdr.h new file mode 100644 index 000000000000..3f5ee5d7cc2a --- /dev/null +++ b/drivers/net/bnx2x_fw_file_hdr.h @@ -0,0 +1,37 @@ +/* bnx2x_fw_file_hdr.h: FW binary file header structure. + * + * 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 + * the Free Software Foundation. + * + * Maintained by: Eilon Greenstein + * Written by: Vladislav Zolotarov + * Based on the original idea of John Wright . + */ + +#ifndef BNX2X_INIT_FILE_HDR_H +#define BNX2X_INIT_FILE_HDR_H + +struct bnx2x_fw_file_section { + __be32 len; + __be32 offset; +}; + +struct bnx2x_fw_file_hdr { + struct bnx2x_fw_file_section init_ops; + struct bnx2x_fw_file_section init_ops_offsets; + struct bnx2x_fw_file_section init_data; + struct bnx2x_fw_file_section tsem_int_table_data; + struct bnx2x_fw_file_section tsem_pram_data; + struct bnx2x_fw_file_section usem_int_table_data; + struct bnx2x_fw_file_section usem_pram_data; + struct bnx2x_fw_file_section csem_int_table_data; + struct bnx2x_fw_file_section csem_pram_data; + struct bnx2x_fw_file_section xsem_int_table_data; + struct bnx2x_fw_file_section xsem_pram_data; + struct bnx2x_fw_file_section fw_version; +}; + +#endif /* BNX2X_INIT_FILE_HDR_H */ diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h index 39ba2936c0c2..3ba4d888068f 100644 --- a/drivers/net/bnx2x_init.h +++ b/drivers/net/bnx2x_init.h @@ -1,4 +1,5 @@ /* bnx2x_init.h: Broadcom Everest network driver. + * Structures and macroes needed during the initialization. * * Copyright (c) 2007-2009 Broadcom Corporation * @@ -8,6 +9,7 @@ * * Maintained by: Eilon Greenstein * Written by: Eliezer Tamir + * Modified by: Vladislav Zolotarov */ #ifndef BNX2X_INIT_H @@ -45,33 +47,71 @@ #define OP_WR_64 0x8 /* write 64 bit pattern */ #define OP_WB 0x9 /* copy a string using DMAE */ -/* Operation specific for E1 */ -#define OP_RD_E1 0xa /* read single register */ -#define OP_WR_E1 0xb /* write single register */ -#define OP_IW_E1 0xc /* write single register using mailbox */ -#define OP_SW_E1 0xd /* copy a string to the device */ -#define OP_SI_E1 0xe /* copy a string using mailbox */ -#define OP_ZR_E1 0xf /* clear memory */ -#define OP_ZP_E1 0x10 /* unzip then copy with DMAE */ -#define OP_WR_64_E1 0x11 /* write 64 bit pattern on E1 */ -#define OP_WB_E1 0x12 /* copy a string using DMAE */ - -/* Operation specific for E1H */ -#define OP_RD_E1H 0x13 /* read single register */ -#define OP_WR_E1H 0x14 /* write single register */ -#define OP_IW_E1H 0x15 /* write single register using mailbox */ -#define OP_SW_E1H 0x16 /* copy a string to the device */ -#define OP_SI_E1H 0x17 /* copy a string using mailbox */ -#define OP_ZR_E1H 0x18 /* clear memory */ -#define OP_ZP_E1H 0x19 /* unzip then copy with DMAE */ -#define OP_WR_64_E1H 0x1a /* write 64 bit pattern on E1H */ -#define OP_WB_E1H 0x1b /* copy a string using DMAE */ - /* FPGA and EMUL specific operations */ -#define OP_WR_EMUL_E1H 0x1c /* write single register on E1H Emul */ -#define OP_WR_EMUL 0x1d /* write single register on Emulation */ -#define OP_WR_FPGA 0x1e /* write single register on FPGA */ -#define OP_WR_ASIC 0x1f /* write single register on ASIC */ +#define OP_WR_EMUL 0xa /* write single register on Emulation */ +#define OP_WR_FPGA 0xb /* write single register on FPGA */ +#define OP_WR_ASIC 0xc /* write single register on ASIC */ + +/* Init stages */ +#define COMMON_STAGE 0 +#define PORT0_STAGE 1 +#define PORT1_STAGE 2 +/* Never reorder FUNCx stages !!! */ +#define FUNC0_STAGE 3 +#define FUNC1_STAGE 4 +#define FUNC2_STAGE 5 +#define FUNC3_STAGE 6 +#define FUNC4_STAGE 7 +#define FUNC5_STAGE 8 +#define FUNC6_STAGE 9 +#define FUNC7_STAGE 10 +#define STAGE_IDX_MAX 11 + +#define STAGE_START 0 +#define STAGE_END 1 + + +/* Indices of blocks */ +#define PRS_BLOCK 0 +#define SRCH_BLOCK 1 +#define TSDM_BLOCK 2 +#define TCM_BLOCK 3 +#define BRB1_BLOCK 4 +#define TSEM_BLOCK 5 +#define PXPCS_BLOCK 6 +#define EMAC0_BLOCK 7 +#define EMAC1_BLOCK 8 +#define DBU_BLOCK 9 +#define MISC_BLOCK 10 +#define DBG_BLOCK 11 +#define NIG_BLOCK 12 +#define MCP_BLOCK 13 +#define UPB_BLOCK 14 +#define CSDM_BLOCK 15 +#define USDM_BLOCK 16 +#define CCM_BLOCK 17 +#define UCM_BLOCK 18 +#define USEM_BLOCK 19 +#define CSEM_BLOCK 20 +#define XPB_BLOCK 21 +#define DQ_BLOCK 22 +#define TIMERS_BLOCK 23 +#define XSDM_BLOCK 24 +#define QM_BLOCK 25 +#define PBF_BLOCK 26 +#define XCM_BLOCK 27 +#define XSEM_BLOCK 28 +#define CDU_BLOCK 29 +#define DMAE_BLOCK 30 +#define PXP_BLOCK 31 +#define CFC_BLOCK 32 +#define HC_BLOCK 33 +#define PXP2_BLOCK 34 +#define MISC_AEU_BLOCK 35 + +/* Returns the index of start or end of a specific block stage in ops array*/ +#define BLOCK_OPS_IDX(block, stage, end) \ + (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end)) struct raw_op { @@ -118,292 +158,6 @@ union init_op { struct raw_op raw; }; -#include "bnx2x_init_values.h" - -static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); -static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len); - -static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, - u32 len) -{ - int i; - - for (i = 0; i < len; i++) { - REG_WR(bp, addr + i*4, data[i]); - if (!(i % 10000)) { - touch_softlockup_watchdog(); - cpu_relax(); - } - } -} - -static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, - u16 len) -{ - int i; - - for (i = 0; i < len; i++) { - REG_WR_IND(bp, addr + i*4, data[i]); - if (!(i % 10000)) { - touch_softlockup_watchdog(); - cpu_relax(); - } - } -} - -static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) -{ - int offset = 0; - - if (bp->dmae_ready) { - while (len > DMAE_LEN32_WR_MAX) { - bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, - addr + offset, DMAE_LEN32_WR_MAX); - offset += DMAE_LEN32_WR_MAX * 4; - len -= DMAE_LEN32_WR_MAX; - } - bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, - addr + offset, len); - } else - bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len); -} - -static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) -{ - u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4)); - u32 buf_len32 = buf_len / 4; - int i; - - memset(bp->gunzip_buf, fill, buf_len); - - for (i = 0; i < len; i += buf_len32) { - u32 cur_len = min(buf_len32, len - i); - - bnx2x_write_big_buf(bp, addr + i * 4, cur_len); - } -} - -static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data, - u32 len64) -{ - u32 buf_len32 = FW_BUF_SIZE / 4; - u32 len = len64 * 2; - u64 data64 = 0; - int i; - - /* 64 bit value is in a blob: first low DWORD, then high DWORD */ - data64 = HILO_U64((*(data + 1)), (*data)); - len64 = min((u32)(FW_BUF_SIZE/8), len64); - for (i = 0; i < len64; i++) { - u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i; - - *pdata = data64; - } - - for (i = 0; i < len; i += buf_len32) { - u32 cur_len = min(buf_len32, len - i); - - bnx2x_write_big_buf(bp, addr + i * 4, cur_len); - } -} - -/********************************************************* - There are different blobs for each PRAM section. - In addition, each blob write operation is divided into a few operations - in order to decrease the amount of phys. contiguous buffer needed. - Thus, when we select a blob the address may be with some offset - from the beginning of PRAM section. - The same holds for the INT_TABLE sections. -**********************************************************/ -#define IF_IS_INT_TABLE_ADDR(base, addr) \ - if (((base) <= (addr)) && ((base) + 0x400 >= (addr))) - -#define IF_IS_PRAM_ADDR(base, addr) \ - if (((base) <= (addr)) && ((base) + 0x40000 >= (addr))) - -static const u32 *bnx2x_sel_blob(u32 addr, const u32 *data, int is_e1) -{ - IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr) - data = is_e1 ? tsem_int_table_data_e1 : - tsem_int_table_data_e1h; - else - IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr) - data = is_e1 ? csem_int_table_data_e1 : - csem_int_table_data_e1h; - else - IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr) - data = is_e1 ? usem_int_table_data_e1 : - usem_int_table_data_e1h; - else - IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr) - data = is_e1 ? xsem_int_table_data_e1 : - xsem_int_table_data_e1h; - else - IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr) - data = is_e1 ? tsem_pram_data_e1 : tsem_pram_data_e1h; - else - IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr) - data = is_e1 ? csem_pram_data_e1 : csem_pram_data_e1h; - else - IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr) - data = is_e1 ? usem_pram_data_e1 : usem_pram_data_e1h; - else - IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr) - data = is_e1 ? xsem_pram_data_e1 : xsem_pram_data_e1h; - - return data; -} - -static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, - u32 len, int gunzip, int is_e1, u32 blob_off) -{ - int offset = 0; - - data = bnx2x_sel_blob(addr, data, is_e1) + blob_off; - - if (gunzip) { - int rc; -#ifdef __BIG_ENDIAN - int i, size; - u32 *temp; - - temp = kmalloc(len, GFP_KERNEL); - size = (len / 4) + ((len % 4) ? 1 : 0); - for (i = 0; i < size; i++) - temp[i] = swab32(data[i]); - data = temp; -#endif - rc = bnx2x_gunzip(bp, (u8 *)data, len); - if (rc) { - BNX2X_ERR("gunzip failed ! rc %d\n", rc); -#ifdef __BIG_ENDIAN - kfree(temp); -#endif - return; - } - len = bp->gunzip_outlen; -#ifdef __BIG_ENDIAN - kfree(temp); - for (i = 0; i < len; i++) - ((u32 *)bp->gunzip_buf)[i] = - swab32(((u32 *)bp->gunzip_buf)[i]); -#endif - } else { - if ((len * 4) > FW_BUF_SIZE) { - BNX2X_ERR("LARGE DMAE OPERATION ! " - "addr 0x%x len 0x%x\n", addr, len*4); - return; - } - memcpy(bp->gunzip_buf, data, len * 4); - } - - if (bp->dmae_ready) { - while (len > DMAE_LEN32_WR_MAX) { - bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, - addr + offset, DMAE_LEN32_WR_MAX); - offset += DMAE_LEN32_WR_MAX * 4; - len -= DMAE_LEN32_WR_MAX; - } - bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, - addr + offset, len); - } else - bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len); -} - -static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end) -{ - int is_e1 = CHIP_IS_E1(bp); - int is_e1h = CHIP_IS_E1H(bp); - int is_emul_e1h = (CHIP_REV_IS_EMUL(bp) && is_e1h); - int hw_wr, i; - union init_op *op; - u32 op_type, addr, len; - const u32 *data, *data_base; - - if (CHIP_REV_IS_FPGA(bp)) - hw_wr = OP_WR_FPGA; - else if (CHIP_REV_IS_EMUL(bp)) - hw_wr = OP_WR_EMUL; - else - hw_wr = OP_WR_ASIC; - - if (is_e1) - data_base = init_data_e1; - else /* CHIP_IS_E1H(bp) */ - data_base = init_data_e1h; - - for (i = op_start; i < op_end; i++) { - - op = (union init_op *)&(init_ops[i]); - - op_type = op->str_wr.op; - addr = op->str_wr.offset; - len = op->str_wr.data_len; - data = data_base + op->str_wr.data_off; - - /* careful! it must be in order */ - if (unlikely(op_type > OP_WB)) { - - /* If E1 only */ - if (op_type <= OP_WB_E1) { - if (is_e1) - op_type -= (OP_RD_E1 - OP_RD); - - /* If E1H only */ - } else if (op_type <= OP_WB_E1H) { - if (is_e1h) - op_type -= (OP_RD_E1H - OP_RD); - } - - /* HW/EMUL specific */ - if (op_type == hw_wr) - op_type = OP_WR; - - /* EMUL on E1H is special */ - if ((op_type == OP_WR_EMUL_E1H) && is_emul_e1h) - op_type = OP_WR; - } - - switch (op_type) { - case OP_RD: - REG_RD(bp, addr); - break; - case OP_WR: - REG_WR(bp, addr, op->write.val); - break; - case OP_SW: - bnx2x_init_str_wr(bp, addr, data, len); - break; - case OP_WB: - bnx2x_init_wr_wb(bp, addr, data, len, 0, is_e1, 0); - break; - case OP_SI: - bnx2x_init_ind_wr(bp, addr, data, len); - break; - case OP_ZR: - bnx2x_init_fill(bp, addr, 0, op->zero.len); - break; - case OP_ZP: - bnx2x_init_wr_wb(bp, addr, data, len, 1, is_e1, - op->str_wr.data_off); - break; - case OP_WR_64: - bnx2x_init_wr_64(bp, addr, data, len); - break; - default: - /* happens whenever an op is of a diff HW */ -#if 0 - DP(NETIF_MSG_HW, "skipping init operation " - "index %d[%d:%d]: type %d addr 0x%x " - "len %d(0x%x)\n", - i, op_start, op_end, op_type, addr, len, len); -#endif - break; - } - } -} - - /**************************************************************************** * PXP ****************************************************************************/ @@ -567,111 +321,6 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = { PXP2_REG_RQ_BW_WR_UBOUND30} }; -static void bnx2x_init_pxp(struct bnx2x *bp) -{ - u16 devctl; - int r_order, w_order; - u32 val, i; - - pci_read_config_word(bp->pdev, - bp->pcie_cap + PCI_EXP_DEVCTL, &devctl); - DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl); - w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); - if (bp->mrrs == -1) - r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12); - else { - DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs); - r_order = bp->mrrs; - } - - if (r_order > MAX_RD_ORD) { - DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n", - r_order, MAX_RD_ORD); - r_order = MAX_RD_ORD; - } - if (w_order > MAX_WR_ORD) { - DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n", - w_order, MAX_WR_ORD); - w_order = MAX_WR_ORD; - } - if (CHIP_REV_IS_FPGA(bp)) { - DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n"); - w_order = 0; - } - DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order); - - for (i = 0; i < NUM_RD_Q-1; i++) { - REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l); - REG_WR(bp, read_arb_addr[i].add, - read_arb_data[i][r_order].add); - REG_WR(bp, read_arb_addr[i].ubound, - read_arb_data[i][r_order].ubound); - } - - for (i = 0; i < NUM_WR_Q-1; i++) { - if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) || - (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) { - - REG_WR(bp, write_arb_addr[i].l, - write_arb_data[i][w_order].l); - - REG_WR(bp, write_arb_addr[i].add, - write_arb_data[i][w_order].add); - - REG_WR(bp, write_arb_addr[i].ubound, - write_arb_data[i][w_order].ubound); - } else { - - val = REG_RD(bp, write_arb_addr[i].l); - REG_WR(bp, write_arb_addr[i].l, - val | (write_arb_data[i][w_order].l << 10)); - - val = REG_RD(bp, write_arb_addr[i].add); - REG_WR(bp, write_arb_addr[i].add, - val | (write_arb_data[i][w_order].add << 10)); - - val = REG_RD(bp, write_arb_addr[i].ubound); - REG_WR(bp, write_arb_addr[i].ubound, - val | (write_arb_data[i][w_order].ubound << 7)); - } - } - - val = write_arb_data[NUM_WR_Q-1][w_order].add; - val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10; - val += write_arb_data[NUM_WR_Q-1][w_order].l << 17; - REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val); - - val = read_arb_data[NUM_RD_Q-1][r_order].add; - val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10; - val += read_arb_data[NUM_RD_Q-1][r_order].l << 17; - REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val); - - REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order); - REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order); - REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order); - REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order); - - if (r_order == MAX_RD_ORD) - REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); - - REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); - - if (CHIP_IS_E1H(bp)) { - val = ((w_order == 0) ? 2 : 3); - REG_WR(bp, PXP2_REG_WR_HC_MPS, val); - REG_WR(bp, PXP2_REG_WR_USDM_MPS, val); - REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val); - REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val); - REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val); - REG_WR(bp, PXP2_REG_WR_QM_MPS, val); - REG_WR(bp, PXP2_REG_WR_TM_MPS, val); - REG_WR(bp, PXP2_REG_WR_SRC_MPS, val); - REG_WR(bp, PXP2_REG_WR_DBG_MPS, val); - REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */ - REG_WR(bp, PXP2_REG_WR_CDU_MPS, val); - } -} - /**************************************************************************** * CDU @@ -695,128 +344,12 @@ static void bnx2x_init_pxp(struct bnx2x *bp) (0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7)) #define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80) -/***************************************************************************** - * Description: - * Calculates crc 8 on a word value: polynomial 0-1-2-8 - * Code was translated from Verilog. - ****************************************************************************/ -static u8 calc_crc8(u32 data, u8 crc) -{ - u8 D[32]; - u8 NewCRC[8]; - u8 C[8]; - u8 crc_res; - u8 i; - - /* split the data into 31 bits */ - for (i = 0; i < 32; i++) { - D[i] = data & 1; - data = data >> 1; - } - - /* split the crc into 8 bits */ - for (i = 0; i < 8; i++) { - C[i] = crc & 1; - crc = crc >> 1; - } - - NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^ - D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^ - C[6] ^ C[7]; - NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^ - D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^ - D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6]; - NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^ - D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^ - C[0] ^ C[1] ^ C[4] ^ C[5]; - NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^ - D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^ - C[1] ^ C[2] ^ C[5] ^ C[6]; - NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^ - D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^ - C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7]; - NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^ - D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^ - C[3] ^ C[4] ^ C[7]; - NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^ - D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^ - C[5]; - NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^ - D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^ - C[6]; - - crc_res = 0; - for (i = 0; i < 8; i++) - crc_res |= (NewCRC[i] << i); - - return crc_res; -} /* registers addresses are not in order so these arrays help simplify the code */ -static const int cm_start[E1H_FUNC_MAX][9] = { - {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START, - XCM_FUNC0_START, TSEM_FUNC0_START, USEM_FUNC0_START, CSEM_FUNC0_START, - XSEM_FUNC0_START}, - {MISC_FUNC1_START, TCM_FUNC1_START, UCM_FUNC1_START, CCM_FUNC1_START, - XCM_FUNC1_START, TSEM_FUNC1_START, USEM_FUNC1_START, CSEM_FUNC1_START, - XSEM_FUNC1_START}, - {MISC_FUNC2_START, TCM_FUNC2_START, UCM_FUNC2_START, CCM_FUNC2_START, - XCM_FUNC2_START, TSEM_FUNC2_START, USEM_FUNC2_START, CSEM_FUNC2_START, - XSEM_FUNC2_START}, - {MISC_FUNC3_START, TCM_FUNC3_START, UCM_FUNC3_START, CCM_FUNC3_START, - XCM_FUNC3_START, TSEM_FUNC3_START, USEM_FUNC3_START, CSEM_FUNC3_START, - XSEM_FUNC3_START}, - {MISC_FUNC4_START, TCM_FUNC4_START, UCM_FUNC4_START, CCM_FUNC4_START, - XCM_FUNC4_START, TSEM_FUNC4_START, USEM_FUNC4_START, CSEM_FUNC4_START, - XSEM_FUNC4_START}, - {MISC_FUNC5_START, TCM_FUNC5_START, UCM_FUNC5_START, CCM_FUNC5_START, - XCM_FUNC5_START, TSEM_FUNC5_START, USEM_FUNC5_START, CSEM_FUNC5_START, - XSEM_FUNC5_START}, - {MISC_FUNC6_START, TCM_FUNC6_START, UCM_FUNC6_START, CCM_FUNC6_START, - XCM_FUNC6_START, TSEM_FUNC6_START, USEM_FUNC6_START, CSEM_FUNC6_START, - XSEM_FUNC6_START}, - {MISC_FUNC7_START, TCM_FUNC7_START, UCM_FUNC7_START, CCM_FUNC7_START, - XCM_FUNC7_START, TSEM_FUNC7_START, USEM_FUNC7_START, CSEM_FUNC7_START, - XSEM_FUNC7_START} -}; - -static const int cm_end[E1H_FUNC_MAX][9] = { - {MISC_FUNC0_END, TCM_FUNC0_END, UCM_FUNC0_END, CCM_FUNC0_END, - XCM_FUNC0_END, TSEM_FUNC0_END, USEM_FUNC0_END, CSEM_FUNC0_END, - XSEM_FUNC0_END}, - {MISC_FUNC1_END, TCM_FUNC1_END, UCM_FUNC1_END, CCM_FUNC1_END, - XCM_FUNC1_END, TSEM_FUNC1_END, USEM_FUNC1_END, CSEM_FUNC1_END, - XSEM_FUNC1_END}, - {MISC_FUNC2_END, TCM_FUNC2_END, UCM_FUNC2_END, CCM_FUNC2_END, - XCM_FUNC2_END, TSEM_FUNC2_END, USEM_FUNC2_END, CSEM_FUNC2_END, - XSEM_FUNC2_END}, - {MISC_FUNC3_END, TCM_FUNC3_END, UCM_FUNC3_END, CCM_FUNC3_END, - XCM_FUNC3_END, TSEM_FUNC3_END, USEM_FUNC3_END, CSEM_FUNC3_END, - XSEM_FUNC3_END}, - {MISC_FUNC4_END, TCM_FUNC4_END, UCM_FUNC4_END, CCM_FUNC4_END, - XCM_FUNC4_END, TSEM_FUNC4_END, USEM_FUNC4_END, CSEM_FUNC4_END, - XSEM_FUNC4_END}, - {MISC_FUNC5_END, TCM_FUNC5_END, UCM_FUNC5_END, CCM_FUNC5_END, - XCM_FUNC5_END, TSEM_FUNC5_END, USEM_FUNC5_END, CSEM_FUNC5_END, - XSEM_FUNC5_END}, - {MISC_FUNC6_END, TCM_FUNC6_END, UCM_FUNC6_END, CCM_FUNC6_END, - XCM_FUNC6_END, TSEM_FUNC6_END, USEM_FUNC6_END, CSEM_FUNC6_END, - XSEM_FUNC6_END}, - {MISC_FUNC7_END, TCM_FUNC7_END, UCM_FUNC7_END, CCM_FUNC7_END, - XCM_FUNC7_END, TSEM_FUNC7_END, USEM_FUNC7_END, CSEM_FUNC7_END, - XSEM_FUNC7_END}, -}; - -static const int hc_limits[E1H_FUNC_MAX][2] = { - {HC_FUNC0_START, HC_FUNC0_END}, - {HC_FUNC1_START, HC_FUNC1_END}, - {HC_FUNC2_START, HC_FUNC2_END}, - {HC_FUNC3_START, HC_FUNC3_END}, - {HC_FUNC4_START, HC_FUNC4_END}, - {HC_FUNC5_START, HC_FUNC5_END}, - {HC_FUNC6_START, HC_FUNC6_END}, - {HC_FUNC7_START, HC_FUNC7_END} +static const int cm_blocks[9] = { + MISC_BLOCK, TCM_BLOCK, UCM_BLOCK, CCM_BLOCK, XCM_BLOCK, + TSEM_BLOCK, USEM_BLOCK, CSEM_BLOCK, XSEM_BLOCK }; #endif /* BNX2X_INIT_H */ diff --git a/drivers/net/bnx2x_init_ops.h b/drivers/net/bnx2x_init_ops.h new file mode 100644 index 000000000000..32552b9366cb --- /dev/null +++ b/drivers/net/bnx2x_init_ops.h @@ -0,0 +1,442 @@ +/* bnx2x_init_ops.h: Broadcom Everest network driver. + * Static functions needed during the initialization. + * This file is "included" in bnx2x_main.c. + * + * 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 + * the Free Software Foundation. + * + * Maintained by: Eilon Greenstein + * Written by: Vladislav Zolotarov + */ +#ifndef BNX2X_INIT_OPS_H +#define BNX2X_INIT_OPS_H + +static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); +static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len); + +static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, + u32 len) +{ + int i; + + for (i = 0; i < len; i++) { + REG_WR(bp, addr + i*4, data[i]); + if (!(i % 10000)) { + touch_softlockup_watchdog(); + cpu_relax(); + } + } +} + +static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, + u16 len) +{ + int i; + + for (i = 0; i < len; i++) { + REG_WR_IND(bp, addr + i*4, data[i]); + if (!(i % 10000)) { + touch_softlockup_watchdog(); + cpu_relax(); + } + } +} + +static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) +{ + int offset = 0; + + if (bp->dmae_ready) { + while (len > DMAE_LEN32_WR_MAX) { + bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, + addr + offset, DMAE_LEN32_WR_MAX); + offset += DMAE_LEN32_WR_MAX * 4; + len -= DMAE_LEN32_WR_MAX; + } + bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, + addr + offset, len); + } else + bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len); +} + +static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) +{ + u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4)); + u32 buf_len32 = buf_len / 4; + int i; + + memset(bp->gunzip_buf, fill, buf_len); + + for (i = 0; i < len; i += buf_len32) { + u32 cur_len = min(buf_len32, len - i); + + bnx2x_write_big_buf(bp, addr + i * 4, cur_len); + } +} + +static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data, + u32 len64) +{ + u32 buf_len32 = FW_BUF_SIZE / 4; + u32 len = len64 * 2; + u64 data64 = 0; + int i; + + /* 64 bit value is in a blob: first low DWORD, then high DWORD */ + data64 = HILO_U64((*(data + 1)), (*data)); + len64 = min((u32)(FW_BUF_SIZE/8), len64); + for (i = 0; i < len64; i++) { + u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i; + + *pdata = data64; + } + + for (i = 0; i < len; i += buf_len32) { + u32 cur_len = min(buf_len32, len - i); + + bnx2x_write_big_buf(bp, addr + i * 4, cur_len); + } +} + +/********************************************************* + There are different blobs for each PRAM section. + In addition, each blob write operation is divided into a few operations + in order to decrease the amount of phys. contiguous buffer needed. + Thus, when we select a blob the address may be with some offset + from the beginning of PRAM section. + The same holds for the INT_TABLE sections. +**********************************************************/ +#define IF_IS_INT_TABLE_ADDR(base, addr) \ + if (((base) <= (addr)) && ((base) + 0x400 >= (addr))) + +#define IF_IS_PRAM_ADDR(base, addr) \ + if (((base) <= (addr)) && ((base) + 0x40000 >= (addr))) + +static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data) +{ + IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr) + data = bp->tsem_int_table_data; + else IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr) + data = bp->csem_int_table_data; + else IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr) + data = bp->usem_int_table_data; + else IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr) + data = bp->xsem_int_table_data; + else IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr) + data = bp->tsem_pram_data; + else IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr) + data = bp->csem_pram_data; + else IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr) + data = bp->usem_pram_data; + else IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr) + data = bp->xsem_pram_data; + + return data; +} + +static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len) +{ + int offset = 0; + + if (bp->dmae_ready) { + while (len > DMAE_LEN32_WR_MAX) { + bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, + addr + offset, DMAE_LEN32_WR_MAX); + offset += DMAE_LEN32_WR_MAX * 4; + len -= DMAE_LEN32_WR_MAX; + } + bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, + addr + offset, len); + } else + bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len); +} + +static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, + u32 len) +{ + /* This is needed for NO_ZIP mode, currently supported + in little endian mode only */ + data = (const u32*)bnx2x_sel_blob(bp, addr, (const u8*)data); + + if ((len * 4) > FW_BUF_SIZE) { + BNX2X_ERR("LARGE DMAE OPERATION ! " + "addr 0x%x len 0x%x\n", addr, len*4); + return; + } + memcpy(bp->gunzip_buf, data, len * 4); + + bnx2x_write_big_buf_wb(bp, addr, len); +} + +static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, + u32 len, u32 blob_off) +{ + int rc, i; + const u8 *data = NULL; + + data = bnx2x_sel_blob(bp, addr, data) + 4*blob_off; + + if (data == NULL) { + panic("Blob not found for addr 0x%x\n", addr); + return; + } + + rc = bnx2x_gunzip(bp, data, len); + if (rc) { + BNX2X_ERR("gunzip failed ! addr 0x%x rc %d\n", addr, rc); + BNX2X_ERR("blob_offset=0x%x\n", blob_off); + return; + } + + /* gunzip_outlen is in dwords */ + len = bp->gunzip_outlen; + for (i = 0; i < len; i++) + ((u32 *)bp->gunzip_buf)[i] = + cpu_to_le32(((u32 *)bp->gunzip_buf)[i]); + + bnx2x_write_big_buf_wb(bp, addr, len); +} + +static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage) +{ + int hw_wr, i; + u16 op_start = + bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_START)]; + u16 op_end = + bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_END)]; + union init_op *op; + u32 op_type, addr, len; + const u32 *data, *data_base; + + /* If empty block */ + if (op_start == op_end) + return; + + if (CHIP_REV_IS_FPGA(bp)) + hw_wr = OP_WR_FPGA; + else if (CHIP_REV_IS_EMUL(bp)) + hw_wr = OP_WR_EMUL; + else + hw_wr = OP_WR_ASIC; + + data_base = bp->init_data; + + for (i = op_start; i < op_end; i++) { + + op = (union init_op *)&(bp->init_ops[i]); + + op_type = op->str_wr.op; + addr = op->str_wr.offset; + len = op->str_wr.data_len; + data = data_base + op->str_wr.data_off; + + /* HW/EMUL specific */ + if (unlikely((op_type > OP_WB) && (op_type == hw_wr))) + op_type = OP_WR; + + switch (op_type) { + case OP_RD: + REG_RD(bp, addr); + break; + case OP_WR: + REG_WR(bp, addr, op->write.val); + break; + case OP_SW: + bnx2x_init_str_wr(bp, addr, data, len); + break; + case OP_WB: + bnx2x_init_wr_wb(bp, addr, data, len); + break; + case OP_SI: + bnx2x_init_ind_wr(bp, addr, data, len); + break; + case OP_ZR: + bnx2x_init_fill(bp, addr, 0, op->zero.len); + break; + case OP_ZP: + bnx2x_init_wr_zp(bp, addr, len, + op->str_wr.data_off); + break; + case OP_WR_64: + bnx2x_init_wr_64(bp, addr, data, len); + break; + default: + /* happens whenever an op is of a diff HW */ +#if 0 + DP(NETIF_MSG_HW, "skipping init operation " + "index %d[%d:%d]: type %d addr 0x%x " + "len %d(0x%x)\n", + i, op_start, op_end, op_type, addr, len, len); +#endif + break; + } + } +} + +/* PXP */ +static void bnx2x_init_pxp(struct bnx2x *bp) +{ + u16 devctl; + int r_order, w_order; + u32 val, i; + + pci_read_config_word(bp->pdev, + bp->pcie_cap + PCI_EXP_DEVCTL, &devctl); + DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl); + w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); + if (bp->mrrs == -1) + r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12); + else { + DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs); + r_order = bp->mrrs; + } + + if (r_order > MAX_RD_ORD) { + DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n", + r_order, MAX_RD_ORD); + r_order = MAX_RD_ORD; + } + if (w_order > MAX_WR_ORD) { + DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n", + w_order, MAX_WR_ORD); + w_order = MAX_WR_ORD; + } + if (CHIP_REV_IS_FPGA(bp)) { + DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n"); + w_order = 0; + } + DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order); + + for (i = 0; i < NUM_RD_Q-1; i++) { + REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l); + REG_WR(bp, read_arb_addr[i].add, + read_arb_data[i][r_order].add); + REG_WR(bp, read_arb_addr[i].ubound, + read_arb_data[i][r_order].ubound); + } + + for (i = 0; i < NUM_WR_Q-1; i++) { + if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) || + (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) { + + REG_WR(bp, write_arb_addr[i].l, + write_arb_data[i][w_order].l); + + REG_WR(bp, write_arb_addr[i].add, + write_arb_data[i][w_order].add); + + REG_WR(bp, write_arb_addr[i].ubound, + write_arb_data[i][w_order].ubound); + } else { + + val = REG_RD(bp, write_arb_addr[i].l); + REG_WR(bp, write_arb_addr[i].l, + val | (write_arb_data[i][w_order].l << 10)); + + val = REG_RD(bp, write_arb_addr[i].add); + REG_WR(bp, write_arb_addr[i].add, + val | (write_arb_data[i][w_order].add << 10)); + + val = REG_RD(bp, write_arb_addr[i].ubound); + REG_WR(bp, write_arb_addr[i].ubound, + val | (write_arb_data[i][w_order].ubound << 7)); + } + } + + val = write_arb_data[NUM_WR_Q-1][w_order].add; + val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10; + val += write_arb_data[NUM_WR_Q-1][w_order].l << 17; + REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val); + + val = read_arb_data[NUM_RD_Q-1][r_order].add; + val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10; + val += read_arb_data[NUM_RD_Q-1][r_order].l << 17; + REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val); + + REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order); + REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order); + REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order); + REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order); + + if (r_order == MAX_RD_ORD) + REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); + + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); + + if (CHIP_IS_E1H(bp)) { + val = ((w_order == 0) ? 2 : 3); + REG_WR(bp, PXP2_REG_WR_HC_MPS, val); + REG_WR(bp, PXP2_REG_WR_USDM_MPS, val); + REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val); + REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val); + REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val); + REG_WR(bp, PXP2_REG_WR_QM_MPS, val); + REG_WR(bp, PXP2_REG_WR_TM_MPS, val); + REG_WR(bp, PXP2_REG_WR_SRC_MPS, val); + REG_WR(bp, PXP2_REG_WR_DBG_MPS, val); + REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */ + REG_WR(bp, PXP2_REG_WR_CDU_MPS, val); + } +} + +/***************************************************************************** + * Description: + * Calculates crc 8 on a word value: polynomial 0-1-2-8 + * Code was translated from Verilog. + ****************************************************************************/ +static u8 calc_crc8(u32 data, u8 crc) +{ + u8 D[32]; + u8 NewCRC[8]; + u8 C[8]; + u8 crc_res; + u8 i; + + /* split the data into 31 bits */ + for (i = 0; i < 32; i++) { + D[i] = data & 1; + data = data >> 1; + } + + /* split the crc into 8 bits */ + for (i = 0; i < 8; i++) { + C[i] = crc & 1; + crc = crc >> 1; + } + + NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^ + D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^ + C[6] ^ C[7]; + NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^ + D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^ + D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6]; + NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^ + D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^ + C[0] ^ C[1] ^ C[4] ^ C[5]; + NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^ + D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^ + C[1] ^ C[2] ^ C[5] ^ C[6]; + NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^ + D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^ + C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7]; + NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^ + D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^ + C[3] ^ C[4] ^ C[7]; + NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^ + D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^ + C[5]; + NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^ + D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^ + C[6]; + + crc_res = 0; + for (i = 0; i < 8; i++) + crc_res |= (NewCRC[i] << i); + + return crc_res; +} + +#endif /* BNX2X_INIT_OPS_H */ diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index ad5ef25add3e..cdc80e0820cd 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -53,12 +53,19 @@ #include "bnx2x.h" #include "bnx2x_init.h" +#include "bnx2x_init_ops.h" #include "bnx2x_dump.h" #define DRV_MODULE_VERSION "1.48.105" #define DRV_MODULE_RELDATE "2009/03/02" #define BNX2X_BC_VER 0x040200 +#include +#include "bnx2x_fw_file_hdr.h" +/* FW files */ +#define FW_FILE_PREFIX_E1 "bnx2x-e1-" +#define FW_FILE_PREFIX_E1H "bnx2x-e1h-" + /* Time in jiffies before concluding the transmitter is hung */ #define TX_TIMEOUT (5*HZ) @@ -5232,13 +5239,15 @@ static void bnx2x_gunzip_end(struct bnx2x *bp) } } -static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len) +static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len) { int n, rc; /* check gzip header */ - if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) + if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) { + BNX2X_ERR("Bad gzip header\n"); return -EINVAL; + } n = 10; @@ -5247,7 +5256,7 @@ static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len) if (zbuf[3] & FNAME) while ((zbuf[n++] != 0) && (n < len)); - bp->strm->next_in = zbuf + n; + bp->strm->next_in = (typeof(bp->strm->next_in))zbuf + n; bp->strm->avail_in = len - n; bp->strm->next_out = bp->gunzip_buf; bp->strm->avail_out = FW_BUF_SIZE; @@ -5369,8 +5378,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) msleep(50); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); msleep(50); - bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); - bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); + bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); DP(NETIF_MSG_HW, "part2\n"); @@ -5434,8 +5443,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) msleep(50); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); msleep(50); - bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); - bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); + bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); #ifndef BCM_ISCSI /* set NIC mode */ REG_WR(bp, PRS_REG_NIC_MODE, 1); @@ -5510,7 +5519,7 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc); - bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END); + bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE); if (CHIP_IS_E1H(bp)) REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp)); @@ -5518,14 +5527,14 @@ static int bnx2x_init_common(struct bnx2x *bp) msleep(30); REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0); - bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END); + bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE); if (CHIP_IS_E1(bp)) { /* enable HW interrupt from PXP on USDM overflow bit 16 on INT_MASK_0 */ REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); } - bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END); + bnx2x_init_block(bp, PXP2_BLOCK, COMMON_STAGE); bnx2x_init_pxp(bp); #ifdef __BIG_ENDIAN @@ -5571,60 +5580,60 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0); REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0); - bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END); + bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE); /* clean the DMAE memory */ bp->dmae_ready = 1; bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8); - bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END); - bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END); - bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END); - bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END); + bnx2x_init_block(bp, TCM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, UCM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, CCM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, XCM_BLOCK, COMMON_STAGE); bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3); bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3); bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3); bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3); - bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END); + bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE); /* soft reset pulse */ REG_WR(bp, QM_REG_SOFT_RESET, 1); REG_WR(bp, QM_REG_SOFT_RESET, 0); #ifdef BCM_ISCSI - bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END); + bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE); #endif - bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END); + bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE); REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT); if (!CHIP_REV_IS_SLOW(bp)) { /* enable hw interrupt from doorbell Q */ REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); } - bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); - bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); + bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); 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)) REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp)); - bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END); - bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END); - bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END); - bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END); + bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE); bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp)); bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp)); bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp)); bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp)); - bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END); - bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END); - bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END); - bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END); + bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE); /* sync semi rtc */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, @@ -5632,16 +5641,16 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x80000000); - bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END); - bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END); - bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END); + bnx2x_init_block(bp, UPB_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); REG_WR(bp, SRC_REG_SOFT_RST, 1); for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) { REG_WR(bp, i, 0xc0cac01a); /* TODO: replace with something meaningful */ } - bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END); + bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE); REG_WR(bp, SRC_REG_SOFT_RST, 0); if (sizeof(union cdu_context) != 1024) @@ -5649,7 +5658,7 @@ static int bnx2x_init_common(struct bnx2x *bp) printk(KERN_ALERT PFX "please adjust the size of" " cdu_context(%ld)\n", (long)sizeof(union cdu_context)); - bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END); + bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE); val = (4 << 24) + (0 << 12) + 1024; REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val); if (CHIP_IS_E1(bp)) { @@ -5658,7 +5667,7 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, CDU_REG_CDU_DEBUG, 0); } - bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END); + bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE); REG_WR(bp, CFC_REG_INIT_REG, 0x7FF); /* enable context validation interrupt from CFC */ REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); @@ -5666,20 +5675,25 @@ static int bnx2x_init_common(struct bnx2x *bp) /* set the thresholds to prevent CFC/CDU race */ REG_WR(bp, CFC_REG_DEBUG0, 0x20020000); - bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END); - bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END); + bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE); + bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE); /* PXPCS COMMON comes here */ + bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE); /* Reset PCIE errors for debug */ REG_WR(bp, 0x2814, 0xffffffff); REG_WR(bp, 0x3820, 0xffffffff); /* EMAC0 COMMON comes here */ + bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE); /* EMAC1 COMMON comes here */ + bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE); /* DBU COMMON comes here */ + bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE); /* DBG COMMON comes here */ + bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE); - bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END); + bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); if (CHIP_IS_E1H(bp)) { REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp)); REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp)); @@ -5763,6 +5777,7 @@ static int bnx2x_init_common(struct bnx2x *bp) static int bnx2x_init_port(struct bnx2x *bp) { int port = BP_PORT(bp); + int init_stage = port ? PORT1_STAGE : PORT0_STAGE; u32 low, high; u32 val; @@ -5771,7 +5786,9 @@ static int bnx2x_init_port(struct bnx2x *bp) REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0); /* Port PXP comes here */ + bnx2x_init_block(bp, PXP_BLOCK, init_stage); /* Port PXP2 comes here */ + bnx2x_init_block(bp, PXP2_BLOCK, init_stage); #ifdef BCM_ISCSI /* Port0 1 * Port1 385 */ @@ -5798,21 +5815,19 @@ static int bnx2x_init_port(struct bnx2x *bp) REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i)); #endif /* Port CMs come here */ - bnx2x_init_block(bp, (port ? XCM_PORT1_START : XCM_PORT0_START), - (port ? XCM_PORT1_END : XCM_PORT0_END)); + bnx2x_init_block(bp, XCM_BLOCK, init_stage); /* Port QM comes here */ #ifdef BCM_ISCSI REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20); REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31); - bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START, - func ? TIMERS_PORT1_END : TIMERS_PORT0_END); + bnx2x_init_block(bp, TIMERS_BLOCK, init_stage); #endif /* Port DQ comes here */ + bnx2x_init_block(bp, DQ_BLOCK, init_stage); - bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START), - (port ? BRB1_PORT1_END : BRB1_PORT0_END)); + bnx2x_init_block(bp, BRB1_BLOCK, init_stage); if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) { /* no pause for emulation and FPGA */ low = 0; @@ -5837,25 +5852,27 @@ static int bnx2x_init_port(struct bnx2x *bp) /* Port PRS comes here */ + bnx2x_init_block(bp, PRS_BLOCK, init_stage); /* Port TSDM comes here */ + bnx2x_init_block(bp, TSDM_BLOCK, init_stage); /* Port CSDM comes here */ + bnx2x_init_block(bp, CSDM_BLOCK, init_stage); /* Port USDM comes here */ + bnx2x_init_block(bp, USDM_BLOCK, init_stage); /* Port XSDM comes here */ + bnx2x_init_block(bp, XSDM_BLOCK, init_stage); - bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START, - port ? TSEM_PORT1_END : TSEM_PORT0_END); - bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START, - port ? USEM_PORT1_END : USEM_PORT0_END); - bnx2x_init_block(bp, port ? CSEM_PORT1_START : CSEM_PORT0_START, - port ? CSEM_PORT1_END : CSEM_PORT0_END); - bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START, - port ? XSEM_PORT1_END : XSEM_PORT0_END); + bnx2x_init_block(bp, TSEM_BLOCK, init_stage); + bnx2x_init_block(bp, USEM_BLOCK, init_stage); + bnx2x_init_block(bp, CSEM_BLOCK, init_stage); + bnx2x_init_block(bp, XSEM_BLOCK, init_stage); /* Port UPB comes here */ + bnx2x_init_block(bp, UPB_BLOCK, init_stage); /* Port XPB comes here */ + bnx2x_init_block(bp, XPB_BLOCK, init_stage); - bnx2x_init_block(bp, port ? PBF_PORT1_START : PBF_PORT0_START, - port ? PBF_PORT1_END : PBF_PORT0_END); + bnx2x_init_block(bp, PBF_BLOCK, init_stage); /* configure PBF to work without PAUSE mtu 9000 */ REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); @@ -5885,18 +5902,17 @@ static int bnx2x_init_port(struct bnx2x *bp) /* Port SRCH comes here */ #endif /* Port CDU comes here */ + bnx2x_init_block(bp, CDU_BLOCK, init_stage); /* Port CFC comes here */ + bnx2x_init_block(bp, CFC_BLOCK, init_stage); if (CHIP_IS_E1(bp)) { REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); } - bnx2x_init_block(bp, port ? HC_PORT1_START : HC_PORT0_START, - port ? HC_PORT1_END : HC_PORT0_END); + bnx2x_init_block(bp, HC_BLOCK, init_stage); - bnx2x_init_block(bp, port ? MISC_AEU_PORT1_START : - MISC_AEU_PORT0_START, - port ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END); + bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage); /* init aeu_mask_attn_func_0/1: * - SF mode: bits 3-7 are masked. only bits 0-2 are in use * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF @@ -5905,13 +5921,17 @@ static int bnx2x_init_port(struct bnx2x *bp) (IS_E1HMF(bp) ? 0xF7 : 0x7)); /* Port PXPCS comes here */ + bnx2x_init_block(bp, PXPCS_BLOCK, init_stage); /* Port EMAC0 comes here */ + bnx2x_init_block(bp, EMAC0_BLOCK, init_stage); /* Port EMAC1 comes here */ + bnx2x_init_block(bp, EMAC1_BLOCK, init_stage); /* Port DBU comes here */ + bnx2x_init_block(bp, DBU_BLOCK, init_stage); /* Port DBG comes here */ + bnx2x_init_block(bp, DBG_BLOCK, init_stage); - bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START, - port ? NIG_PORT1_END : NIG_PORT0_END); + bnx2x_init_block(bp, NIG_BLOCK, init_stage); REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); @@ -5931,7 +5951,9 @@ static int bnx2x_init_port(struct bnx2x *bp) } /* Port MCP comes here */ + bnx2x_init_block(bp, MCP_BLOCK, init_stage); /* Port DMAE comes here */ + bnx2x_init_block(bp, DMAE_BLOCK, init_stage); switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: @@ -6036,7 +6058,7 @@ static int bnx2x_init_func(struct bnx2x *bp) if (CHIP_IS_E1H(bp)) { for (i = 0; i < 9; i++) bnx2x_init_block(bp, - cm_start[func][i], cm_end[func][i]); + cm_blocks[i], FUNC0_STAGE + func); REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); @@ -6049,7 +6071,7 @@ static int bnx2x_init_func(struct bnx2x *bp) REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); } - bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]); + bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); /* Reset PCIE errors for debug */ REG_WR(bp, 0x2114, 0xffffffff); @@ -11082,6 +11104,190 @@ static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp) val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT; return val; } +static int __devinit bnx2x_check_firmware(struct bnx2x *bp) +{ + struct bnx2x_fw_file_hdr *fw_hdr; + struct bnx2x_fw_file_section *sections; + u16 *ops_offsets; + u32 offset, len, num_ops; + int i; + const struct firmware *firmware = bp->firmware; + const u8 * fw_ver; + + if (firmware->size < sizeof(struct bnx2x_fw_file_hdr)) + return -EINVAL; + + fw_hdr = (struct bnx2x_fw_file_hdr *)firmware->data; + sections = (struct bnx2x_fw_file_section *)fw_hdr; + + /* Make sure none of the offsets and sizes make us read beyond + * the end of the firmware data */ + for (i = 0; i < sizeof(*fw_hdr) / sizeof(*sections); i++) { + offset = be32_to_cpu(sections[i].offset); + len = be32_to_cpu(sections[i].len); + if (offset + len > firmware->size) { + printk(KERN_ERR PFX "Section %d length is out of bounds\n", i); + return -EINVAL; + } + } + + /* Likewise for the init_ops offsets */ + offset = be32_to_cpu(fw_hdr->init_ops_offsets.offset); + ops_offsets = (u16 *)(firmware->data + offset); + num_ops = be32_to_cpu(fw_hdr->init_ops.len) / sizeof(struct raw_op); + + for (i = 0; i < be32_to_cpu(fw_hdr->init_ops_offsets.len) / 2; i++) { + if (be16_to_cpu(ops_offsets[i]) > num_ops) { + printk(KERN_ERR PFX "Section offset %d is out of bounds\n", i); + return -EINVAL; + } + } + + /* Check FW version */ + offset = be32_to_cpu(fw_hdr->fw_version.offset); + fw_ver = firmware->data + offset; + if ((fw_ver[0] != BCM_5710_FW_MAJOR_VERSION) || + (fw_ver[1] != BCM_5710_FW_MINOR_VERSION) || + (fw_ver[2] != BCM_5710_FW_REVISION_VERSION) || + (fw_ver[3] != BCM_5710_FW_ENGINEERING_VERSION)) { + printk(KERN_ERR PFX "Bad FW version:%d.%d.%d.%d." + " Should be %d.%d.%d.%d\n", + fw_ver[0], fw_ver[1], fw_ver[2], + fw_ver[3], BCM_5710_FW_MAJOR_VERSION, + BCM_5710_FW_MINOR_VERSION, + BCM_5710_FW_REVISION_VERSION, + BCM_5710_FW_ENGINEERING_VERSION); + return -EINVAL; + } + + return 0; +} + +static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n) +{ + u32 i; + const __be32 *source = (const __be32*)_source; + u32 *target = (u32*)_target; + + for (i = 0; i < n/4; i++) + target[i] = be32_to_cpu(source[i]); +} + +/* + Ops array is stored in the following format: + {op(8bit), offset(24bit, big endian), data(32bit, big endian)} + */ +static void inline bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n) +{ + u32 i, j, tmp; + const __be32 *source = (const __be32*)_source; + struct raw_op *target = (struct raw_op*)_target; + + for (i = 0, j = 0; i < n/8; i++, j+=2) { + tmp = be32_to_cpu(source[j]); + target[i].op = (tmp >> 24) & 0xff; + target[i].offset = tmp & 0xffffff; + target[i].raw_data = be32_to_cpu(source[j+1]); + } +} +static void inline be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n) +{ + u32 i; + u16 *target = (u16*)_target; + const __be16 *source = (const __be16*)_source; + + for (i = 0; i < n/2; i++) + target[i] = be16_to_cpu(source[i]); +} + +#define BNX2X_ALLOC_AND_SET(arr, lbl, func) \ + do { \ + u32 len = be32_to_cpu(fw_hdr->arr.len); \ + bp->arr = kmalloc(len, GFP_KERNEL); \ + if (!bp->arr) { \ + printk(KERN_ERR PFX "Failed to allocate %d bytes for "#arr"\n", len); \ + goto lbl; \ + } \ + func(bp->firmware->data + \ + be32_to_cpu(fw_hdr->arr.offset), \ + (u8*)bp->arr, len); \ + } while (0) + + +static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev) +{ + char fw_file_name[40] = {0}; + int rc, offset; + struct bnx2x_fw_file_hdr *fw_hdr; + + /* Create a FW file name */ + if (CHIP_IS_E1(bp)) + offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1); + else + offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H); + + sprintf(fw_file_name + offset, "%d.%d.%d.%d.fw", + BCM_5710_FW_MAJOR_VERSION, + BCM_5710_FW_MINOR_VERSION, + BCM_5710_FW_REVISION_VERSION, + BCM_5710_FW_ENGINEERING_VERSION); + + printk(KERN_INFO PFX "Loading %s\n", fw_file_name); + + rc = request_firmware(&bp->firmware, fw_file_name, dev); + if (rc) { + printk(KERN_ERR PFX "Can't load firmware file %s\n", fw_file_name); + goto request_firmware_exit; + } + + rc = bnx2x_check_firmware(bp); + if (rc) { + printk(KERN_ERR PFX "Corrupt firmware file %s\n", fw_file_name); + goto request_firmware_exit; + } + + fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data; + + /* Initialize the pointers to the init arrays */ + /* Blob */ + BNX2X_ALLOC_AND_SET(init_data, request_firmware_exit, be32_to_cpu_n); + + /* Opcodes */ + BNX2X_ALLOC_AND_SET(init_ops, init_ops_alloc_err, bnx2x_prep_ops); + + /* Offsets */ + BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n); + + /* STORMs firmware */ + bp->tsem_int_table_data = bp->firmware->data + + be32_to_cpu(fw_hdr->tsem_int_table_data.offset); + bp->tsem_pram_data = bp->firmware->data + + be32_to_cpu(fw_hdr->tsem_pram_data.offset); + bp->usem_int_table_data = bp->firmware->data + + be32_to_cpu(fw_hdr->usem_int_table_data.offset); + bp->usem_pram_data = bp->firmware->data + + be32_to_cpu(fw_hdr->usem_pram_data.offset); + bp->xsem_int_table_data = bp->firmware->data + + be32_to_cpu(fw_hdr->xsem_int_table_data.offset); + bp->xsem_pram_data = bp->firmware->data + + be32_to_cpu(fw_hdr->xsem_pram_data.offset); + bp->csem_int_table_data = bp->firmware->data + + be32_to_cpu(fw_hdr->csem_int_table_data.offset); + bp->csem_pram_data = bp->firmware->data + + be32_to_cpu(fw_hdr->csem_pram_data.offset); + + return 0; +init_offsets_alloc_err: + kfree(bp->init_ops); +init_ops_alloc_err: + kfree(bp->init_data); +request_firmware_exit: + release_firmware(bp->firmware); + + return rc; +} + + static int __devinit bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -11116,6 +11322,13 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, if (rc) goto init_one_exit; + /* Set init arrays */ + rc = bnx2x_init_firmware(bp, &pdev->dev); + if (rc) { + printk(KERN_ERR PFX "Error loading firmware\n"); + goto init_one_exit; + } + rc = register_netdev(dev); if (rc) { dev_err(&pdev->dev, "Cannot register net device\n"); @@ -11163,6 +11376,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) unregister_netdev(dev); + kfree(bp->init_ops_offsets); + kfree(bp->init_ops); + kfree(bp->init_data); + release_firmware(bp->firmware); + if (bp->regview) iounmap(bp->regview); @@ -11431,3 +11649,4 @@ static void __exit bnx2x_cleanup(void) module_init(bnx2x_init); module_exit(bnx2x_cleanup); + diff --git a/firmware/Makefile b/firmware/Makefile index 25200d106ee8..1c670e0c0448 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -32,6 +32,7 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ adaptec/starfire_tx.bin fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw +fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-4.8.53.0.fw bnx2x-e1h-4.8.53.0.fw fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-4.6.17.fw \ bnx2/bnx2-rv2p-09-4.6.15.fw \ bnx2/bnx2-mips-06-4.6.16.fw \ diff --git a/firmware/WHENCE b/firmware/WHENCE index 4c52984a8319..c1e9c5ab694c 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -614,6 +614,26 @@ File: myricom/lanai.bin Licence: Unknown +Found in hex form in kernel source. + +-------------------------------------------------------------------------- + +Driver: bnx2x: Broadcom Everest + +File: bnx2x-e1-4.8.53.0.fw.ihex +File: bnx2x-e1h-4.8.53.0.fw.ihex + +License: + Copyright (c) 2007-2009 Broadcom Corporation + + This file contains firmware data derived from proprietary unpublished + source code, Copyright (c) 2007-2009 Broadcom Corporation. + + Permission is hereby granted for the distribution of this firmware data + in hexadecimal or equivalent format, provided this copyright notice is + accompanying it. + + Found in hex form in kernel source. -------------------------------------------------------------------------- -- GitLab From 29b35dd868e9442914a44ff8e8be739c3d65cc9d Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 27 Apr 2009 03:28:03 -0700 Subject: [PATCH 0752/6080] bnx2x: Removed blob file Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_init_values.h | 16322 ------------------------------ 1 file changed, 16322 deletions(-) delete mode 100644 drivers/net/bnx2x_init_values.h diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h deleted file mode 100644 index 1f22c9ab66d4..000000000000 --- a/drivers/net/bnx2x_init_values.h +++ /dev/null @@ -1,16322 +0,0 @@ -#ifndef __BNX2X_INIT_VALUES_H__ -#define __BNX2X_INIT_VALUES_H__ - -/* bnx2x_init_values.h: Broadcom NX2 10G network driver. - * - * 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 - * the Free Software Foundation, except as noted below. - * - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2007-2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - * - * - * This array contains the list of operations needed to initialize the chip. - * - * For each block in the chip there are three init stages: - * common - HW used by both ports, - * port1 and port2 - initialization for a specific Ethernet port. - * When a port is opened or closed, the management CPU tells the driver - * whether to init/disable common HW in addition to the port HW. - * This way the first port going up will first initializes the common HW, - * and the last port going down also resets the common HW - * - * For each init stage/block there is a list of actions needed in a format: - * {operation, register, data} - * where: - * OP_WR - write a value to the chip. - * OP_RD - read a register (usually a clear on read register). - * OP_SW - string write, write a section of consecutive addresses to the chip. - * OP_SI - copy a string using indirect writes. - * OP_ZR - clear a range of memory. - * OP_ZP - unzip and copy using DMAE. - * OP_WB - string copy using DMAE. - * - * The #defines mark the stages. - * - */ - -static const struct raw_op init_ops[] = { -#define PRS_COMMON_START 0 - {OP_WR, PRS_REG_INC_VALUE, 0xf}, - {OP_WR, PRS_REG_EVENT_ID_1, 0x45}, - {OP_WR, PRS_REG_EVENT_ID_2, 0x84}, - {OP_WR, PRS_REG_EVENT_ID_3, 0x6}, - {OP_WR, PRS_REG_NO_MATCH_EVENT_ID, 0x4}, - {OP_WR, PRS_REG_CM_HDR_TYPE_0, 0x0}, - {OP_WR, PRS_REG_CM_HDR_TYPE_1, 0x12170000}, - {OP_WR, PRS_REG_CM_HDR_TYPE_2, 0x22170000}, - {OP_WR, PRS_REG_CM_HDR_TYPE_3, 0x32170000}, - {OP_ZR, PRS_REG_CM_HDR_TYPE_4, 0x5}, - {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_1, 0x12150000}, - {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_2, 0x22150000}, - {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_3, 0x32150000}, - {OP_ZR, PRS_REG_CM_HDR_LOOPBACK_TYPE_4, 0x4}, - {OP_WR, PRS_REG_CM_NO_MATCH_HDR, 0x2100000}, - {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_0, 0x100000}, - {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1, 0x10100000}, - {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2, 0x20100000}, - {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3, 0x30100000}, - {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4}, - {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x40100000}, - {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_5, 0x3}, - {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0, 0x100000}, - {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1, 0x12140000}, - {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2, 0x22140000}, - {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3, 0x32140000}, - {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4}, - {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x42140000}, - {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_5, 0x3}, - {OP_RD, PRS_REG_NUM_OF_PACKETS, 0x0}, - {OP_RD, PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES, 0x0}, - {OP_RD, PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES, 0x0}, - {OP_RD, PRS_REG_NUM_OF_DEAD_CYCLES, 0x0}, - {OP_WR_E1H, PRS_REG_FCOE_TYPE, 0x8906}, - {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_0, 0xff}, - {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_1, 0xff}, - {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_2, 0xff}, - {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_3, 0xff}, - {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_4, 0xff}, - {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_5, 0xff}, - {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_6, 0xff}, - {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_7, 0xff}, - {OP_WR, PRS_REG_PURE_REGIONS, 0x3e}, - {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_0, 0x0}, - {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_1, 0x3f}, - {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_2, 0x3f}, - {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_3, 0x3f}, - {OP_WR_E1, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0}, - {OP_WR_E1H, PRS_REG_PACKET_REGIONS_TYPE_4, 0x3f}, - {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_5, 0x3f}, - {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_6, 0x3f}, - {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_7, 0x3f}, -#define PRS_COMMON_END 52 -#define SRCH_COMMON_START 52 - {OP_WR_E1H, SRC_REG_E1HMF_ENABLE, 0x1}, -#define SRCH_COMMON_END 53 -#define TSDM_COMMON_START 53 - {OP_WR_E1, TSDM_REG_CFC_RSP_START_ADDR, 0x411}, - {OP_WR_E1H, TSDM_REG_CFC_RSP_START_ADDR, 0x211}, - {OP_WR_E1, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400}, - {OP_WR_E1H, TSDM_REG_CMP_COUNTER_START_ADDR, 0x200}, - {OP_WR_E1, TSDM_REG_Q_COUNTER_START_ADDR, 0x404}, - {OP_WR_E1H, TSDM_REG_Q_COUNTER_START_ADDR, 0x204}, - {OP_WR_E1, TSDM_REG_PCK_END_MSG_START_ADDR, 0x419}, - {OP_WR_E1H, TSDM_REG_PCK_END_MSG_START_ADDR, 0x219}, - {OP_WR, TSDM_REG_CMP_COUNTER_MAX0, 0xffff}, - {OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff}, - {OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff}, - {OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff}, - {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_0, 0x2}, - {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_0, 0x20}, - {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_1, 0x0}, - {OP_WR, TSDM_REG_AGG_INT_EVENT_2, 0x34}, - {OP_WR, TSDM_REG_AGG_INT_EVENT_3, 0x35}, - {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_4, 0x7c}, - {OP_ZR_E1H, TSDM_REG_AGG_INT_EVENT_4, 0x1c}, - {OP_WR_E1H, TSDM_REG_AGG_INT_T_0, 0x1}, - {OP_ZR_E1H, TSDM_REG_AGG_INT_T_1, 0x5f}, - {OP_WR, TSDM_REG_ENABLE_IN1, 0x7ffffff}, - {OP_WR, TSDM_REG_ENABLE_IN2, 0x3f}, - {OP_WR, TSDM_REG_ENABLE_OUT1, 0x7ffffff}, - {OP_WR, TSDM_REG_ENABLE_OUT2, 0xf}, - {OP_RD, TSDM_REG_NUM_OF_Q0_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q1_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q3_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q4_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q5_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q6_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q7_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q8_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q9_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q10_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_Q11_CMD, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_PKT_END_MSG, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0}, - {OP_RD, TSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0}, - {OP_WR_E1, TSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1}, - {OP_WR_ASIC, TSDM_REG_TIMER_TICK, 0x3e8}, - {OP_WR_EMUL, TSDM_REG_TIMER_TICK, 0x1}, - {OP_WR_FPGA, TSDM_REG_TIMER_TICK, 0xa}, -#define TSDM_COMMON_END 96 -#define TCM_COMMON_START 96 - {OP_WR, TCM_REG_XX_MAX_LL_SZ, 0x20}, - {OP_WR, TCM_REG_XX_OVFL_EVNT_ID, 0x32}, - {OP_WR, TCM_REG_TQM_TCM_HDR_P, 0x2150020}, - {OP_WR, TCM_REG_TQM_TCM_HDR_S, 0x2150020}, - {OP_WR, TCM_REG_TM_TCM_HDR, 0x30}, - {OP_WR, TCM_REG_ERR_TCM_HDR, 0x8100000}, - {OP_WR, TCM_REG_ERR_EVNT_ID, 0x33}, - {OP_WR, TCM_REG_EXPR_EVNT_ID, 0x30}, - {OP_WR, TCM_REG_STOP_EVNT_ID, 0x31}, - {OP_WR, TCM_REG_STORM_WEIGHT, 0x2}, - {OP_WR, TCM_REG_PRS_WEIGHT, 0x5}, - {OP_WR, TCM_REG_PBF_WEIGHT, 0x6}, - {OP_WR, TCM_REG_USEM_WEIGHT, 0x2}, - {OP_WR, TCM_REG_CSEM_WEIGHT, 0x2}, - {OP_WR, TCM_REG_CP_WEIGHT, 0x0}, - {OP_WR, TCM_REG_TSDM_WEIGHT, 0x5}, - {OP_WR, TCM_REG_TQM_P_WEIGHT, 0x2}, - {OP_WR, TCM_REG_TQM_S_WEIGHT, 0x2}, - {OP_WR, TCM_REG_TM_WEIGHT, 0x2}, - {OP_WR, TCM_REG_TCM_TQM_USE_Q, 0x1}, - {OP_WR, TCM_REG_GR_ARB_TYPE, 0x1}, - {OP_WR, TCM_REG_GR_LD0_PR, 0x1}, - {OP_WR, TCM_REG_GR_LD1_PR, 0x2}, - {OP_WR, TCM_REG_CFC_INIT_CRD, 0x1}, - {OP_WR, TCM_REG_FIC0_INIT_CRD, 0x40}, - {OP_WR, TCM_REG_FIC1_INIT_CRD, 0x40}, - {OP_WR, TCM_REG_TQM_INIT_CRD, 0x20}, - {OP_WR, TCM_REG_XX_INIT_CRD, 0x13}, - {OP_WR, TCM_REG_XX_MSG_NUM, 0x20}, - {OP_ZR, TCM_REG_XX_TABLE, 0xa}, - {OP_SW, TCM_REG_XX_DESCR_TABLE, 0x200000}, - {OP_WR, TCM_REG_N_SM_CTX_LD_0, 0x7}, - {OP_WR, TCM_REG_N_SM_CTX_LD_1, 0x7}, - {OP_WR, TCM_REG_N_SM_CTX_LD_2, 0x8}, - {OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8}, - {OP_ZR_E1, TCM_REG_N_SM_CTX_LD_4, 0x4}, - {OP_WR_E1H, TCM_REG_N_SM_CTX_LD_4, 0x1}, - {OP_ZR_E1H, TCM_REG_N_SM_CTX_LD_5, 0x3}, - {OP_WR, TCM_REG_TCM_REG0_SZ, 0x6}, - {OP_WR_E1, TCM_REG_PHYS_QNUM0_0, 0xd}, - {OP_WR_E1, TCM_REG_PHYS_QNUM0_1, 0x2d}, - {OP_WR_E1, TCM_REG_PHYS_QNUM1_0, 0x7}, - {OP_WR_E1, TCM_REG_PHYS_QNUM1_1, 0x27}, - {OP_WR_E1, TCM_REG_PHYS_QNUM2_0, 0x7}, - {OP_WR_E1, TCM_REG_PHYS_QNUM2_1, 0x27}, - {OP_WR_E1, TCM_REG_PHYS_QNUM3_0, 0x7}, - {OP_WR_E1, TCM_REG_PHYS_QNUM3_1, 0x27}, - {OP_WR, TCM_REG_TCM_STORM0_IFEN, 0x1}, - {OP_WR, TCM_REG_TCM_STORM1_IFEN, 0x1}, - {OP_WR, TCM_REG_TCM_TQM_IFEN, 0x1}, - {OP_WR, TCM_REG_STORM_TCM_IFEN, 0x1}, - {OP_WR, TCM_REG_TQM_TCM_IFEN, 0x1}, - {OP_WR, TCM_REG_TSDM_IFEN, 0x1}, - {OP_WR, TCM_REG_TM_TCM_IFEN, 0x1}, - {OP_WR, TCM_REG_PRS_IFEN, 0x1}, - {OP_WR, TCM_REG_PBF_IFEN, 0x1}, - {OP_WR, TCM_REG_USEM_IFEN, 0x1}, - {OP_WR, TCM_REG_CSEM_IFEN, 0x1}, - {OP_WR, TCM_REG_CDU_AG_WR_IFEN, 0x1}, - {OP_WR, TCM_REG_CDU_AG_RD_IFEN, 0x1}, - {OP_WR, TCM_REG_CDU_SM_WR_IFEN, 0x1}, - {OP_WR, TCM_REG_CDU_SM_RD_IFEN, 0x1}, - {OP_WR, TCM_REG_TCM_CFC_IFEN, 0x1}, -#define TCM_COMMON_END 159 -#define TCM_FUNC0_START 159 - {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0xd}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x7}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x7}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x7}, -#define TCM_FUNC0_END 163 -#define TCM_FUNC1_START 163 - {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x2d}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x27}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x27}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x27}, -#define TCM_FUNC1_END 167 -#define TCM_FUNC2_START 167 - {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x1d}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x17}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x17}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x17}, -#define TCM_FUNC2_END 171 -#define TCM_FUNC3_START 171 - {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x3d}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x37}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x37}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x37}, -#define TCM_FUNC3_END 175 -#define TCM_FUNC4_START 175 - {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x4d}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x47}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x47}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x47}, -#define TCM_FUNC4_END 179 -#define TCM_FUNC5_START 179 - {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x6d}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x67}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x67}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x67}, -#define TCM_FUNC5_END 183 -#define TCM_FUNC6_START 183 - {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x5d}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x57}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x57}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x57}, -#define TCM_FUNC6_END 187 -#define TCM_FUNC7_START 187 - {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x7d}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x77}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x77}, - {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x77}, -#define TCM_FUNC7_END 191 -#define BRB1_COMMON_START 191 - {OP_SW, BRB1_REG_LL_RAM, 0x2000020}, - {OP_WR, BRB1_REG_SOFT_RESET, 0x1}, - {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_4, 0x0}, - {OP_SW, BRB1_REG_FREE_LIST_PRS_CRDT, 0x30220}, - {OP_WR, BRB1_REG_SOFT_RESET, 0x0}, -#define BRB1_COMMON_END 196 -#define BRB1_PORT0_START 196 - {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0xb8}, - {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 0x114}, - {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0}, - {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0}, -#define BRB1_PORT0_END 200 -#define BRB1_PORT1_START 200 - {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0xb8}, - {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 0x114}, - {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0}, - {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0}, -#define BRB1_PORT1_END 204 -#define TSEM_COMMON_START 204 - {OP_RD, TSEM_REG_MSG_NUM_FIC0, 0x0}, - {OP_RD, TSEM_REG_MSG_NUM_FIC1, 0x0}, - {OP_RD, TSEM_REG_MSG_NUM_FOC0, 0x0}, - {OP_RD, TSEM_REG_MSG_NUM_FOC1, 0x0}, - {OP_RD, TSEM_REG_MSG_NUM_FOC2, 0x0}, - {OP_RD, TSEM_REG_MSG_NUM_FOC3, 0x0}, - {OP_WR, TSEM_REG_ARB_ELEMENT0, 0x1}, - {OP_WR, TSEM_REG_ARB_ELEMENT1, 0x2}, - {OP_WR, TSEM_REG_ARB_ELEMENT2, 0x3}, - {OP_WR, TSEM_REG_ARB_ELEMENT3, 0x0}, - {OP_WR, TSEM_REG_ARB_ELEMENT4, 0x4}, - {OP_WR, TSEM_REG_ARB_CYCLE_SIZE, 0x1}, - {OP_WR, TSEM_REG_TS_0_AS, 0x0}, - {OP_WR, TSEM_REG_TS_1_AS, 0x1}, - {OP_WR, TSEM_REG_TS_2_AS, 0x4}, - {OP_WR, TSEM_REG_TS_3_AS, 0x0}, - {OP_WR, TSEM_REG_TS_4_AS, 0x1}, - {OP_WR, TSEM_REG_TS_5_AS, 0x3}, - {OP_WR, TSEM_REG_TS_6_AS, 0x0}, - {OP_WR, TSEM_REG_TS_7_AS, 0x1}, - {OP_WR, TSEM_REG_TS_8_AS, 0x4}, - {OP_WR, TSEM_REG_TS_9_AS, 0x0}, - {OP_WR, TSEM_REG_TS_10_AS, 0x1}, - {OP_WR, TSEM_REG_TS_11_AS, 0x3}, - {OP_WR, TSEM_REG_TS_12_AS, 0x0}, - {OP_WR, TSEM_REG_TS_13_AS, 0x1}, - {OP_WR, TSEM_REG_TS_14_AS, 0x4}, - {OP_WR, TSEM_REG_TS_15_AS, 0x0}, - {OP_WR, TSEM_REG_TS_16_AS, 0x4}, - {OP_WR, TSEM_REG_TS_17_AS, 0x3}, - {OP_ZR, TSEM_REG_TS_18_AS, 0x2}, - {OP_WR, TSEM_REG_ENABLE_IN, 0x3fff}, - {OP_WR, TSEM_REG_ENABLE_OUT, 0x3ff}, - {OP_WR, TSEM_REG_FIC0_DISABLE, 0x0}, - {OP_WR, TSEM_REG_FIC1_DISABLE, 0x0}, - {OP_WR, TSEM_REG_PAS_DISABLE, 0x0}, - {OP_WR, TSEM_REG_THREADS_LIST, 0xff}, - {OP_ZR, TSEM_REG_PASSIVE_BUFFER, 0x400}, - {OP_WR, TSEM_REG_FAST_MEMORY + 0x18bc0, 0x1}, - {OP_WR, TSEM_REG_FAST_MEMORY + 0x18000, 0x34}, - {OP_WR, TSEM_REG_FAST_MEMORY + 0x18040, 0x18}, - {OP_WR, TSEM_REG_FAST_MEMORY + 0x18080, 0xc}, - {OP_WR, TSEM_REG_FAST_MEMORY + 0x180c0, 0x20}, - {OP_WR_ASIC, TSEM_REG_FAST_MEMORY + 0x18300, 0x7a120}, - {OP_WR_EMUL, TSEM_REG_FAST_MEMORY + 0x18300, 0x138}, - {OP_WR_FPGA, TSEM_REG_FAST_MEMORY + 0x18300, 0x1388}, - {OP_WR, TSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2000, 0xb2}, - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x1}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x23c8, 0xc1}, - {OP_WR_EMUL_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x0}, - {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x23c8 + 0x304, 0x10223}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1000, 0x2b3}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1020, 0xc8}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x1000 + 0xacc, 0x10223}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1000, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa020, 0xc8}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c18, 0x4}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa000, 0x2}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c10, 0x2}, - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad0, 0x0}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad8, 0x4}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3678, 0x6}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x810, 0x4}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3670, 0x2}, - {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x40224}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2}, - {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x4cb0, 0x80228}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4}, - {OP_ZP_E1, TSEM_REG_INT_TABLE, 0x930000}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5018, 0x4}, - {OP_WR_64_E1, TSEM_REG_INT_TABLE + 0x360, 0x140230}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4}, - {OP_ZP_E1, TSEM_REG_PRAM, 0x324f0000}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5038, 0x4}, - {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33250c94}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5048, 0x4}, - {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xe4d195e}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5058, 0x4}, - {OP_WR_64_E1, TSEM_REG_PRAM + 0x11e00, 0x5c400232}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5068, 0x4}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5078, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x62c0, 0x200224}, - {OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x9b0000}, - {OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x398, 0xd0244}, - {OP_ZP_E1H, TSEM_REG_PRAM, 0x325e0000}, - {OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x35960c98}, - {OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0x1aea19fe}, - {OP_WR_64_E1H, TSEM_REG_PRAM + 0x143d0, 0x57860246}, -#define TSEM_COMMON_END 297 -#define TSEM_PORT0_START 297 - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x22c8, 0x20}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x2000, 0x16c}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0x16c}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb000, 0x28}, - {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b60, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb140, 0xc}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1400, 0xa}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32c0, 0x12}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1450, 0x6}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0x64}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8108, 0x2}, - {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x8, 0x50234}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x1c, 0x7}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1570, 0x12}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0x4c}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x820, 0xe}, - {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20239}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2908, 0x2}, -#define TSEM_PORT0_END 317 -#define TSEM_PORT1_START 317 - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2348, 0x20}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x25b0, 0x16c}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x45b0, 0x16c}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb0a0, 0x28}, - {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b64, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb170, 0xc}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1428, 0xa}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3308, 0x12}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1468, 0x6}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x34e0, 0x64}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8110, 0x2}, - {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x8, 0x5023b}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x1c, 0x7}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x15b8, 0x12}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xaf0, 0x4c}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x858, 0xe}, - {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20240}, - {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2910, 0x2}, -#define TSEM_PORT1_END 337 -#define TSEM_FUNC0_START 337 - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b60, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0x2}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x8, 0x50248}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x1c, 0x7}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31c0, 0x8}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5080, 0x12}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2}, -#define TSEM_FUNC0_END 345 -#define TSEM_FUNC1_START 345 - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b64, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0x2}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x8, 0x5024d}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x1c, 0x7}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31e0, 0x8}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5010, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x50c8, 0x12}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2}, -#define TSEM_FUNC1_END 353 -#define TSEM_FUNC2_START 353 - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b68, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0x2}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x8, 0x50252}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x1c, 0x7}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3200, 0x8}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5020, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5110, 0x12}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20257}, -#define TSEM_FUNC2_END 361 -#define TSEM_FUNC3_START 361 - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b6c, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0x2}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x8, 0x50259}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x1c, 0x7}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3220, 0x8}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5030, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5158, 0x12}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2025e}, -#define TSEM_FUNC3_END 369 -#define TSEM_FUNC4_START 369 - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b70, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0x2}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x8, 0x50260}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x1c, 0x7}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3240, 0x8}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5040, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51a0, 0x12}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x20265}, -#define TSEM_FUNC4_END 377 -#define TSEM_FUNC5_START 377 - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b74, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0x2}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x8, 0x50267}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x1c, 0x7}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3260, 0x8}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5050, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51e8, 0x12}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2026c}, -#define TSEM_FUNC5_END 385 -#define TSEM_FUNC6_START 385 - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b78, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0x2}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x8, 0x5026e}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x1c, 0x7}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3280, 0x8}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5060, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5230, 0x12}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20273}, -#define TSEM_FUNC6_END 393 -#define TSEM_FUNC7_START 393 - {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b7c, 0x0}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0x2}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x8, 0x50275}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x1c, 0x7}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32a0, 0x8}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5070, 0x2}, - {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5278, 0x12}, - {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x2027a}, -#define TSEM_FUNC7_END 401 -#define MISC_COMMON_START 401 - {OP_WR_E1, MISC_REG_GRC_TIMEOUT_EN, 0x1}, - {OP_WR, MISC_REG_PLL_STORM_CTRL_1, 0x71d2911}, - {OP_WR, MISC_REG_PLL_STORM_CTRL_2, 0x0}, - {OP_WR, MISC_REG_PLL_STORM_CTRL_3, 0x9c0424}, - {OP_WR, MISC_REG_PLL_STORM_CTRL_4, 0x0}, - {OP_WR, MISC_REG_LCPLL_CTRL_1, 0x209}, - {OP_WR_E1, MISC_REG_SPIO, 0xff000000}, -#define MISC_COMMON_END 408 -#define MISC_FUNC0_START 408 - {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0}, -#define MISC_FUNC0_END 409 -#define MISC_FUNC1_START 409 - {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0}, -#define MISC_FUNC1_END 410 -#define MISC_FUNC2_START 410 - {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0}, -#define MISC_FUNC2_END 411 -#define MISC_FUNC3_START 411 - {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0}, -#define MISC_FUNC3_END 412 -#define MISC_FUNC4_START 412 - {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0}, -#define MISC_FUNC4_END 413 -#define MISC_FUNC5_START 413 - {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0}, -#define MISC_FUNC5_END 414 -#define MISC_FUNC6_START 414 - {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0}, -#define MISC_FUNC6_END 415 -#define MISC_FUNC7_START 415 - {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0}, -#define MISC_FUNC7_END 416 -#define NIG_COMMON_START 416 - {OP_WR, NIG_REG_PBF_LB_IN_EN, 0x1}, - {OP_WR, NIG_REG_PRS_REQ_IN_EN, 0x1}, - {OP_WR, NIG_REG_EGRESS_DEBUG_IN_EN, 0x1}, - {OP_WR, NIG_REG_BRB_LB_OUT_EN, 0x1}, - {OP_WR, NIG_REG_PRS_EOP_OUT_EN, 0x1}, -#define NIG_COMMON_END 421 -#define NIG_PORT0_START 421 - {OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000}, - {OP_WR, NIG_REG_LLH0_EVENT_ID, 0x28}, - {OP_WR, NIG_REG_LLH0_ERROR_MASK, 0x0}, - {OP_WR, NIG_REG_LLH0_XCM_MASK, 0x4}, - {OP_WR, NIG_REG_LLH0_BRB1_NOT_MCP, 0x1}, - {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT0, 0x0}, - {OP_WR_E1H, NIG_REG_LLH0_CLS_TYPE, 0x1}, - {OP_WR, NIG_REG_LLH0_XCM_INIT_CREDIT, 0x30}, - {OP_WR, NIG_REG_BRB0_PAUSE_IN_EN, 0x1}, - {OP_WR, NIG_REG_EGRESS_PBF0_IN_EN, 0x1}, - {OP_WR, NIG_REG_BRB0_OUT_EN, 0x1}, - {OP_WR, NIG_REG_XCM0_OUT_EN, 0x1}, -#define NIG_PORT0_END 433 -#define NIG_PORT1_START 433 - {OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000}, - {OP_WR, NIG_REG_LLH1_EVENT_ID, 0x28}, - {OP_WR, NIG_REG_LLH1_ERROR_MASK, 0x0}, - {OP_WR, NIG_REG_LLH1_XCM_MASK, 0x4}, - {OP_WR, NIG_REG_LLH1_BRB1_NOT_MCP, 0x1}, - {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT1, 0x0}, - {OP_WR_E1H, NIG_REG_LLH1_CLS_TYPE, 0x1}, - {OP_WR, NIG_REG_LLH1_XCM_INIT_CREDIT, 0x30}, - {OP_WR, NIG_REG_BRB1_PAUSE_IN_EN, 0x1}, - {OP_WR, NIG_REG_EGRESS_PBF1_IN_EN, 0x1}, - {OP_WR, NIG_REG_BRB1_OUT_EN, 0x1}, - {OP_WR, NIG_REG_XCM1_OUT_EN, 0x1}, -#define NIG_PORT1_END 445 -#define UPB_COMMON_START 445 - {OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20}, -#define UPB_COMMON_END 446 -#define CSDM_COMMON_START 446 - {OP_WR_E1, CSDM_REG_CFC_RSP_START_ADDR, 0xa11}, - {OP_WR_E1H, CSDM_REG_CFC_RSP_START_ADDR, 0x211}, - {OP_WR_E1, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00}, - {OP_WR_E1H, CSDM_REG_CMP_COUNTER_START_ADDR, 0x200}, - {OP_WR_E1, CSDM_REG_Q_COUNTER_START_ADDR, 0xa04}, - {OP_WR_E1H, CSDM_REG_Q_COUNTER_START_ADDR, 0x204}, - {OP_WR, CSDM_REG_CMP_COUNTER_MAX0, 0xffff}, - {OP_WR, CSDM_REG_CMP_COUNTER_MAX1, 0xffff}, - {OP_WR, CSDM_REG_CMP_COUNTER_MAX2, 0xffff}, - {OP_WR, CSDM_REG_CMP_COUNTER_MAX3, 0xffff}, - {OP_WR, CSDM_REG_AGG_INT_EVENT_0, 0xc6}, - {OP_WR, CSDM_REG_AGG_INT_EVENT_1, 0x0}, - {OP_WR, CSDM_REG_AGG_INT_EVENT_2, 0x34}, - {OP_WR, CSDM_REG_AGG_INT_EVENT_3, 0x35}, - {OP_ZR, CSDM_REG_AGG_INT_EVENT_4, 0x1c}, - {OP_WR, CSDM_REG_AGG_INT_T_0, 0x1}, - {OP_ZR, CSDM_REG_AGG_INT_T_1, 0x5f}, - {OP_WR, CSDM_REG_ENABLE_IN1, 0x7ffffff}, - {OP_WR, CSDM_REG_ENABLE_IN2, 0x3f}, - {OP_WR, CSDM_REG_ENABLE_OUT1, 0x7ffffff}, - {OP_WR, CSDM_REG_ENABLE_OUT2, 0xf}, - {OP_RD, CSDM_REG_NUM_OF_Q0_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q1_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q3_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q4_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q5_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q6_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q7_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q8_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q9_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q10_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_Q11_CMD, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_PKT_END_MSG, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0}, - {OP_RD, CSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0}, - {OP_WR_E1, CSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1}, - {OP_WR_ASIC, CSDM_REG_TIMER_TICK, 0x3e8}, - {OP_WR_EMUL, CSDM_REG_TIMER_TICK, 0x1}, - {OP_WR_FPGA, CSDM_REG_TIMER_TICK, 0xa}, -#define CSDM_COMMON_END 485 -#define USDM_COMMON_START 485 - {OP_WR_E1, USDM_REG_CFC_RSP_START_ADDR, 0xa11}, - {OP_WR_E1H, USDM_REG_CFC_RSP_START_ADDR, 0x411}, - {OP_WR_E1, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00}, - {OP_WR_E1H, USDM_REG_CMP_COUNTER_START_ADDR, 0x400}, - {OP_WR_E1, USDM_REG_Q_COUNTER_START_ADDR, 0xa04}, - {OP_WR_E1H, USDM_REG_Q_COUNTER_START_ADDR, 0x404}, - {OP_WR_E1, USDM_REG_PCK_END_MSG_START_ADDR, 0xa21}, - {OP_WR_E1H, USDM_REG_PCK_END_MSG_START_ADDR, 0x421}, - {OP_WR, USDM_REG_CMP_COUNTER_MAX0, 0xffff}, - {OP_WR, USDM_REG_CMP_COUNTER_MAX1, 0xffff}, - {OP_WR, USDM_REG_CMP_COUNTER_MAX2, 0xffff}, - {OP_WR, USDM_REG_CMP_COUNTER_MAX3, 0xffff}, - {OP_WR, USDM_REG_AGG_INT_EVENT_0, 0x46}, - {OP_WR, USDM_REG_AGG_INT_EVENT_1, 0x5}, - {OP_WR, USDM_REG_AGG_INT_EVENT_2, 0x34}, - {OP_WR, USDM_REG_AGG_INT_EVENT_3, 0x35}, - {OP_ZR_E1, USDM_REG_AGG_INT_EVENT_4, 0x5c}, - {OP_WR_E1H, USDM_REG_AGG_INT_EVENT_4, 0x7}, - {OP_ZR_E1H, USDM_REG_AGG_INT_EVENT_5, 0x5b}, - {OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1}, - {OP_ZR_E1, USDM_REG_AGG_INT_MODE_1, 0x1f}, - {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_1, 0x3}, - {OP_WR_E1H, USDM_REG_AGG_INT_MODE_4, 0x1}, - {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_5, 0x1b}, - {OP_WR, USDM_REG_ENABLE_IN1, 0x7ffffff}, - {OP_WR, USDM_REG_ENABLE_IN2, 0x3f}, - {OP_WR, USDM_REG_ENABLE_OUT1, 0x7ffffff}, - {OP_WR, USDM_REG_ENABLE_OUT2, 0xf}, - {OP_RD, USDM_REG_NUM_OF_Q0_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q1_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q2_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q3_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q4_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q5_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q6_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q7_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q8_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q9_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q10_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_Q11_CMD, 0x0}, - {OP_RD, USDM_REG_NUM_OF_PKT_END_MSG, 0x0}, - {OP_RD, USDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0}, - {OP_RD, USDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0}, - {OP_WR_E1, USDM_REG_INIT_CREDIT_PXP_CTRL, 0x1}, - {OP_WR_ASIC, USDM_REG_TIMER_TICK, 0x3e8}, - {OP_WR_EMUL, USDM_REG_TIMER_TICK, 0x1}, - {OP_WR_FPGA, USDM_REG_TIMER_TICK, 0xa}, -#define USDM_COMMON_END 532 -#define CCM_COMMON_START 532 - {OP_WR, CCM_REG_XX_OVFL_EVNT_ID, 0x32}, - {OP_WR, CCM_REG_CQM_CCM_HDR_P, 0x2150020}, - {OP_WR, CCM_REG_CQM_CCM_HDR_S, 0x2150020}, - {OP_WR, CCM_REG_ERR_CCM_HDR, 0x8100000}, - {OP_WR, CCM_REG_ERR_EVNT_ID, 0x33}, - {OP_WR, CCM_REG_STORM_WEIGHT, 0x2}, - {OP_WR, CCM_REG_TSEM_WEIGHT, 0x0}, - {OP_WR, CCM_REG_XSEM_WEIGHT, 0x5}, - {OP_WR, CCM_REG_USEM_WEIGHT, 0x5}, - {OP_ZR, CCM_REG_PBF_WEIGHT, 0x2}, - {OP_WR, CCM_REG_CSDM_WEIGHT, 0x2}, - {OP_WR, CCM_REG_CQM_P_WEIGHT, 0x3}, - {OP_WR, CCM_REG_CQM_S_WEIGHT, 0x2}, - {OP_WR, CCM_REG_CCM_CQM_USE_Q, 0x1}, - {OP_WR, CCM_REG_CNT_AUX1_Q, 0x2}, - {OP_WR, CCM_REG_CNT_AUX2_Q, 0x2}, - {OP_WR, CCM_REG_INV_DONE_Q, 0x1}, - {OP_WR, CCM_REG_GR_ARB_TYPE, 0x1}, - {OP_WR, CCM_REG_GR_LD0_PR, 0x1}, - {OP_WR, CCM_REG_GR_LD1_PR, 0x2}, - {OP_WR, CCM_REG_CFC_INIT_CRD, 0x1}, - {OP_WR, CCM_REG_CQM_INIT_CRD, 0x20}, - {OP_WR, CCM_REG_FIC0_INIT_CRD, 0x40}, - {OP_WR, CCM_REG_FIC1_INIT_CRD, 0x40}, - {OP_WR, CCM_REG_XX_INIT_CRD, 0x3}, - {OP_WR, CCM_REG_XX_MSG_NUM, 0x18}, - {OP_ZR, CCM_REG_XX_TABLE, 0x12}, - {OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240242}, - {OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x24027c}, - {OP_WR, CCM_REG_N_SM_CTX_LD_0, 0x1}, - {OP_WR, CCM_REG_N_SM_CTX_LD_1, 0x2}, - {OP_WR, CCM_REG_N_SM_CTX_LD_2, 0x8}, - {OP_WR, CCM_REG_N_SM_CTX_LD_3, 0x8}, - {OP_ZR, CCM_REG_N_SM_CTX_LD_4, 0x4}, - {OP_WR, CCM_REG_CCM_REG0_SZ, 0x4}, - {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_0, 0x9}, - {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_1, 0x29}, - {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_0, 0xa}, - {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a}, - {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_0, 0x7}, - {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_1, 0x27}, - {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_0, 0x7}, - {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_1, 0x27}, - {OP_WR_E1, CCM_REG_PHYS_QNUM1_0, 0xc}, - {OP_WR_E1, CCM_REG_PHYS_QNUM1_1, 0x2c}, - {OP_WR_E1, CCM_REG_PHYS_QNUM2_0, 0xc}, - {OP_WR_E1, CCM_REG_PHYS_QNUM2_1, 0x2c}, - {OP_WR_E1, CCM_REG_PHYS_QNUM3_0, 0xc}, - {OP_WR_E1, CCM_REG_PHYS_QNUM3_1, 0x2c}, - {OP_WR, CCM_REG_CCM_STORM0_IFEN, 0x1}, - {OP_WR, CCM_REG_CCM_STORM1_IFEN, 0x1}, - {OP_WR, CCM_REG_CCM_CQM_IFEN, 0x1}, - {OP_WR, CCM_REG_STORM_CCM_IFEN, 0x1}, - {OP_WR, CCM_REG_CQM_CCM_IFEN, 0x1}, - {OP_WR, CCM_REG_CSDM_IFEN, 0x1}, - {OP_WR, CCM_REG_TSEM_IFEN, 0x1}, - {OP_WR, CCM_REG_XSEM_IFEN, 0x1}, - {OP_WR, CCM_REG_USEM_IFEN, 0x1}, - {OP_WR, CCM_REG_PBF_IFEN, 0x1}, - {OP_WR, CCM_REG_CDU_AG_WR_IFEN, 0x1}, - {OP_WR, CCM_REG_CDU_AG_RD_IFEN, 0x1}, - {OP_WR, CCM_REG_CDU_SM_WR_IFEN, 0x1}, - {OP_WR, CCM_REG_CDU_SM_RD_IFEN, 0x1}, - {OP_WR, CCM_REG_CCM_CFC_IFEN, 0x1}, -#define CCM_COMMON_END 596 -#define CCM_FUNC0_START 596 - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x9}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0xa}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x7}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x7}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0xc}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0xb}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x7}, -#define CCM_FUNC0_END 603 -#define CCM_FUNC1_START 603 - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x29}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x27}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x27}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x2c}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x2b}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x27}, -#define CCM_FUNC1_END 610 -#define CCM_FUNC2_START 610 - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x19}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x1a}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x17}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x17}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x1c}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x1b}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x17}, -#define CCM_FUNC2_END 617 -#define CCM_FUNC3_START 617 - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x39}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x3a}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x37}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x37}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x3c}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x3b}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x37}, -#define CCM_FUNC3_END 624 -#define CCM_FUNC4_START 624 - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x49}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x4a}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x47}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x47}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x4c}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x4b}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x47}, -#define CCM_FUNC4_END 631 -#define CCM_FUNC5_START 631 - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x69}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x6a}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x67}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x67}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x6c}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x6b}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x67}, -#define CCM_FUNC5_END 638 -#define CCM_FUNC6_START 638 - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x59}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x5a}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x57}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x57}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x5c}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x5b}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x57}, -#define CCM_FUNC6_END 645 -#define CCM_FUNC7_START 645 - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x79}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x7a}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x77}, - {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x77}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x7c}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x7b}, - {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x77}, -#define CCM_FUNC7_END 652 -#define UCM_COMMON_START 652 - {OP_WR, UCM_REG_XX_OVFL_EVNT_ID, 0x32}, - {OP_WR, UCM_REG_UQM_UCM_HDR_P, 0x2150020}, - {OP_WR, UCM_REG_UQM_UCM_HDR_S, 0x2150020}, - {OP_WR, UCM_REG_TM_UCM_HDR, 0x30}, - {OP_WR, UCM_REG_ERR_UCM_HDR, 0x8100000}, - {OP_WR, UCM_REG_ERR_EVNT_ID, 0x33}, - {OP_WR, UCM_REG_EXPR_EVNT_ID, 0x30}, - {OP_WR, UCM_REG_STOP_EVNT_ID, 0x31}, - {OP_WR, UCM_REG_STORM_WEIGHT, 0x2}, - {OP_WR, UCM_REG_TSEM_WEIGHT, 0x4}, - {OP_WR, UCM_REG_CSEM_WEIGHT, 0x0}, - {OP_WR, UCM_REG_XSEM_WEIGHT, 0x2}, - {OP_WR, UCM_REG_DORQ_WEIGHT, 0x2}, - {OP_WR, UCM_REG_CP_WEIGHT, 0x0}, - {OP_WR, UCM_REG_USDM_WEIGHT, 0x2}, - {OP_WR, UCM_REG_UQM_P_WEIGHT, 0x7}, - {OP_WR, UCM_REG_UQM_S_WEIGHT, 0x2}, - {OP_WR, UCM_REG_TM_WEIGHT, 0x2}, - {OP_WR, UCM_REG_UCM_UQM_USE_Q, 0x1}, - {OP_WR, UCM_REG_INV_CFLG_Q, 0x1}, - {OP_WR, UCM_REG_GR_ARB_TYPE, 0x1}, - {OP_WR, UCM_REG_GR_LD0_PR, 0x1}, - {OP_WR, UCM_REG_GR_LD1_PR, 0x2}, - {OP_WR, UCM_REG_CFC_INIT_CRD, 0x1}, - {OP_WR, UCM_REG_FIC0_INIT_CRD, 0x40}, - {OP_WR, UCM_REG_FIC1_INIT_CRD, 0x40}, - {OP_WR, UCM_REG_TM_INIT_CRD, 0x4}, - {OP_WR, UCM_REG_UQM_INIT_CRD, 0x20}, - {OP_WR, UCM_REG_XX_INIT_CRD, 0xe}, - {OP_WR, UCM_REG_XX_MSG_NUM, 0x1b}, - {OP_ZR, UCM_REG_XX_TABLE, 0x12}, - {OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b0266}, - {OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b02a0}, - {OP_WR, UCM_REG_N_SM_CTX_LD_0, 0x10}, - {OP_WR, UCM_REG_N_SM_CTX_LD_1, 0x7}, - {OP_WR, UCM_REG_N_SM_CTX_LD_2, 0xf}, - {OP_WR, UCM_REG_N_SM_CTX_LD_3, 0x10}, - {OP_ZR_E1, UCM_REG_N_SM_CTX_LD_4, 0x4}, - {OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xb}, - {OP_ZR_E1H, UCM_REG_N_SM_CTX_LD_5, 0x3}, - {OP_WR, UCM_REG_UCM_REG0_SZ, 0x3}, - {OP_WR_E1, UCM_REG_PHYS_QNUM0_0, 0xf}, - {OP_WR_E1, UCM_REG_PHYS_QNUM0_1, 0x2f}, - {OP_WR_E1, UCM_REG_PHYS_QNUM1_0, 0xe}, - {OP_WR_E1, UCM_REG_PHYS_QNUM1_1, 0x2e}, - {OP_WR, UCM_REG_UCM_STORM0_IFEN, 0x1}, - {OP_WR, UCM_REG_UCM_STORM1_IFEN, 0x1}, - {OP_WR, UCM_REG_UCM_UQM_IFEN, 0x1}, - {OP_WR, UCM_REG_STORM_UCM_IFEN, 0x1}, - {OP_WR, UCM_REG_UQM_UCM_IFEN, 0x1}, - {OP_WR, UCM_REG_USDM_IFEN, 0x1}, - {OP_WR, UCM_REG_TM_UCM_IFEN, 0x1}, - {OP_WR, UCM_REG_UCM_TM_IFEN, 0x1}, - {OP_WR, UCM_REG_TSEM_IFEN, 0x1}, - {OP_WR, UCM_REG_CSEM_IFEN, 0x1}, - {OP_WR, UCM_REG_XSEM_IFEN, 0x1}, - {OP_WR, UCM_REG_DORQ_IFEN, 0x1}, - {OP_WR, UCM_REG_CDU_AG_WR_IFEN, 0x1}, - {OP_WR, UCM_REG_CDU_AG_RD_IFEN, 0x1}, - {OP_WR, UCM_REG_CDU_SM_WR_IFEN, 0x1}, - {OP_WR, UCM_REG_CDU_SM_RD_IFEN, 0x1}, - {OP_WR, UCM_REG_UCM_CFC_IFEN, 0x1}, -#define UCM_COMMON_END 714 -#define UCM_FUNC0_START 714 - {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0xf}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0xe}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0}, -#define UCM_FUNC0_END 718 -#define UCM_FUNC1_START 718 - {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x2f}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x2e}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0}, -#define UCM_FUNC1_END 722 -#define UCM_FUNC2_START 722 - {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x1f}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x1e}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0}, -#define UCM_FUNC2_END 726 -#define UCM_FUNC3_START 726 - {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x3f}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x3e}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0}, -#define UCM_FUNC3_END 730 -#define UCM_FUNC4_START 730 - {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x4f}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x4e}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0}, -#define UCM_FUNC4_END 734 -#define UCM_FUNC5_START 734 - {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x6f}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x6e}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0}, -#define UCM_FUNC5_END 738 -#define UCM_FUNC6_START 738 - {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x5f}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x5e}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0}, -#define UCM_FUNC6_END 742 -#define UCM_FUNC7_START 742 - {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x7f}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x7e}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0}, - {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0}, -#define UCM_FUNC7_END 746 -#define USEM_COMMON_START 746 - {OP_RD, USEM_REG_MSG_NUM_FIC0, 0x0}, - {OP_RD, USEM_REG_MSG_NUM_FIC1, 0x0}, - {OP_RD, USEM_REG_MSG_NUM_FOC0, 0x0}, - {OP_RD, USEM_REG_MSG_NUM_FOC1, 0x0}, - {OP_RD, USEM_REG_MSG_NUM_FOC2, 0x0}, - {OP_RD, USEM_REG_MSG_NUM_FOC3, 0x0}, - {OP_WR, USEM_REG_ARB_ELEMENT0, 0x1}, - {OP_WR, USEM_REG_ARB_ELEMENT1, 0x2}, - {OP_WR, USEM_REG_ARB_ELEMENT2, 0x3}, - {OP_WR, USEM_REG_ARB_ELEMENT3, 0x0}, - {OP_WR, USEM_REG_ARB_ELEMENT4, 0x4}, - {OP_WR, USEM_REG_ARB_CYCLE_SIZE, 0x1}, - {OP_WR, USEM_REG_TS_0_AS, 0x0}, - {OP_WR, USEM_REG_TS_1_AS, 0x1}, - {OP_WR, USEM_REG_TS_2_AS, 0x4}, - {OP_WR, USEM_REG_TS_3_AS, 0x0}, - {OP_WR, USEM_REG_TS_4_AS, 0x1}, - {OP_WR, USEM_REG_TS_5_AS, 0x3}, - {OP_WR, USEM_REG_TS_6_AS, 0x0}, - {OP_WR, USEM_REG_TS_7_AS, 0x1}, - {OP_WR, USEM_REG_TS_8_AS, 0x4}, - {OP_WR, USEM_REG_TS_9_AS, 0x0}, - {OP_WR, USEM_REG_TS_10_AS, 0x1}, - {OP_WR, USEM_REG_TS_11_AS, 0x3}, - {OP_WR, USEM_REG_TS_12_AS, 0x0}, - {OP_WR, USEM_REG_TS_13_AS, 0x1}, - {OP_WR, USEM_REG_TS_14_AS, 0x4}, - {OP_WR, USEM_REG_TS_15_AS, 0x0}, - {OP_WR, USEM_REG_TS_16_AS, 0x4}, - {OP_WR, USEM_REG_TS_17_AS, 0x3}, - {OP_ZR, USEM_REG_TS_18_AS, 0x2}, - {OP_WR, USEM_REG_ENABLE_IN, 0x3fff}, - {OP_WR, USEM_REG_ENABLE_OUT, 0x3ff}, - {OP_WR, USEM_REG_FIC0_DISABLE, 0x0}, - {OP_WR, USEM_REG_FIC1_DISABLE, 0x0}, - {OP_WR, USEM_REG_PAS_DISABLE, 0x0}, - {OP_WR, USEM_REG_THREADS_LIST, 0xffff}, - {OP_ZR, USEM_REG_PASSIVE_BUFFER, 0x800}, - {OP_WR, USEM_REG_FAST_MEMORY + 0x18bc0, 0x1}, - {OP_WR, USEM_REG_FAST_MEMORY + 0x18000, 0x1a}, - {OP_WR, USEM_REG_FAST_MEMORY + 0x18040, 0x4e}, - {OP_WR, USEM_REG_FAST_MEMORY + 0x18080, 0x10}, - {OP_WR, USEM_REG_FAST_MEMORY + 0x180c0, 0x20}, - {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18300, 0x7a120}, - {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18300, 0x138}, - {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18300, 0x1388}, - {OP_WR, USEM_REG_FAST_MEMORY + 0x183c0, 0x1f4}, - {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500}, - {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4}, - {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0xc2}, - {OP_WR_EMUL_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x0}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1020, 0xc8}, - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x1}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1000, 0x2}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2000, 0x102}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4640, 0x40}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8980, 0xc8}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57f0, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8960, 0x2}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d8, 0x5}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3228, 0x4}, - {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d8 + 0x14, 0x10281}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3200, 0x9}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1c60, 0x20}, - {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3200 + 0x24, 0x102bb}, - {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x20282}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2}, - {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x102bc}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0xc, 0x3}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2}, - {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x202bd}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2}, - {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x202bf}, - {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000}, - {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x100284}, - {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x1002c1}, - {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0}, - {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x100294}, - {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002d1}, - {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc30000}, - {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xd20000}, - {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x1302a4}, - {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x3a8, 0xb02e1}, - {OP_ZP_E1, USEM_REG_PRAM, 0x314c0000}, - {OP_ZP_E1H, USEM_REG_PRAM, 0x31b60000}, - {OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x35ef0c53}, - {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x36500c6e}, - {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x361319cf}, - {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x37591a02}, - {OP_ZP_E1, USEM_REG_PRAM + 0x18000, 0x7112754}, - {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x286127d9}, - {OP_WR_64_E1, USEM_REG_PRAM + 0x18ee0, 0x4e2402a6}, - {OP_WR_64_E1H, USEM_REG_PRAM + 0x1ff40, 0x401802e3}, -#define USEM_COMMON_END 842 -#define USEM_PORT0_START 842 - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0x10}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x40}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1980, 0x30}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9700, 0x3c}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4740, 0xb4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2450, 0xb4}, - {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d90, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad0, 0x2}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b40, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3080, 0x20}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b60, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x12c}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5318, 0x98}, - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x3238, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5500, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5600, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5700, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5800, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5900, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a00, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b00, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c00, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d00, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e00, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc}, -#define USEM_PORT0_END 876 -#define USEM_PORT1_START 876 - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1940, 0x10}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9600, 0x40}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a40, 0x30}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x97f0, 0x3c}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4a10, 0xb4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2720, 0xb4}, - {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d94, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad8, 0x2}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b50, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3100, 0x20}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1be0, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x84b0, 0x12c}, - {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5578, 0x98}, - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x323c, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5580, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5680, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5780, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5880, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5980, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a80, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b80, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c80, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d80, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e80, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc}, -#define USEM_PORT1_END 910 -#define USEM_FUNC0_START 910 - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a30, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4018, 0x2}, -#define USEM_FUNC0_END 913 -#define USEM_FUNC1_START 913 - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a34, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4028, 0x2}, -#define USEM_FUNC1_END 916 -#define USEM_FUNC2_START 916 - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a38, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4038, 0x2}, -#define USEM_FUNC2_END 919 -#define USEM_FUNC3_START 919 - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a3c, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4048, 0x2}, -#define USEM_FUNC3_END 922 -#define USEM_FUNC4_START 922 - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a40, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4058, 0x2}, -#define USEM_FUNC4_END 925 -#define USEM_FUNC5_START 925 - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a44, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4068, 0x2}, -#define USEM_FUNC5_END 928 -#define USEM_FUNC6_START 928 - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a48, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4078, 0x2}, -#define USEM_FUNC6_END 931 -#define USEM_FUNC7_START 931 - {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a4c, 0x0}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4}, - {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4088, 0x2}, -#define USEM_FUNC7_END 934 -#define CSEM_COMMON_START 934 - {OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0}, - {OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0}, - {OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0}, - {OP_RD, CSEM_REG_MSG_NUM_FOC1, 0x0}, - {OP_RD, CSEM_REG_MSG_NUM_FOC2, 0x0}, - {OP_RD, CSEM_REG_MSG_NUM_FOC3, 0x0}, - {OP_WR, CSEM_REG_ARB_ELEMENT0, 0x1}, - {OP_WR, CSEM_REG_ARB_ELEMENT1, 0x2}, - {OP_WR, CSEM_REG_ARB_ELEMENT2, 0x3}, - {OP_WR, CSEM_REG_ARB_ELEMENT3, 0x0}, - {OP_WR, CSEM_REG_ARB_ELEMENT4, 0x4}, - {OP_WR, CSEM_REG_ARB_CYCLE_SIZE, 0x1}, - {OP_WR, CSEM_REG_TS_0_AS, 0x0}, - {OP_WR, CSEM_REG_TS_1_AS, 0x1}, - {OP_WR, CSEM_REG_TS_2_AS, 0x4}, - {OP_WR, CSEM_REG_TS_3_AS, 0x0}, - {OP_WR, CSEM_REG_TS_4_AS, 0x1}, - {OP_WR, CSEM_REG_TS_5_AS, 0x3}, - {OP_WR, CSEM_REG_TS_6_AS, 0x0}, - {OP_WR, CSEM_REG_TS_7_AS, 0x1}, - {OP_WR, CSEM_REG_TS_8_AS, 0x4}, - {OP_WR, CSEM_REG_TS_9_AS, 0x0}, - {OP_WR, CSEM_REG_TS_10_AS, 0x1}, - {OP_WR, CSEM_REG_TS_11_AS, 0x3}, - {OP_WR, CSEM_REG_TS_12_AS, 0x0}, - {OP_WR, CSEM_REG_TS_13_AS, 0x1}, - {OP_WR, CSEM_REG_TS_14_AS, 0x4}, - {OP_WR, CSEM_REG_TS_15_AS, 0x0}, - {OP_WR, CSEM_REG_TS_16_AS, 0x4}, - {OP_WR, CSEM_REG_TS_17_AS, 0x3}, - {OP_ZR, CSEM_REG_TS_18_AS, 0x2}, - {OP_WR, CSEM_REG_ENABLE_IN, 0x3fff}, - {OP_WR, CSEM_REG_ENABLE_OUT, 0x3ff}, - {OP_WR, CSEM_REG_FIC0_DISABLE, 0x0}, - {OP_WR, CSEM_REG_FIC1_DISABLE, 0x0}, - {OP_WR, CSEM_REG_PAS_DISABLE, 0x0}, - {OP_WR, CSEM_REG_THREADS_LIST, 0xffff}, - {OP_ZR, CSEM_REG_PASSIVE_BUFFER, 0x800}, - {OP_WR, CSEM_REG_FAST_MEMORY + 0x18bc0, 0x1}, - {OP_WR, CSEM_REG_FAST_MEMORY + 0x18000, 0x10}, - {OP_WR, CSEM_REG_FAST_MEMORY + 0x18040, 0x12}, - {OP_WR, CSEM_REG_FAST_MEMORY + 0x18080, 0x30}, - {OP_WR, CSEM_REG_FAST_MEMORY + 0x180c0, 0xe}, - {OP_WR, CSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x5000, 0x42}, - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x1}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1020, 0xc8}, - {OP_WR_EMUL_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x0}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1000, 0x2}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x1000, 0x42}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2000, 0xc0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7020, 0xc8}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3070, 0x80}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7000, 0x2}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x4280, 0x4}, - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0}, - {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a8}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6700, 0x100}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x9000, 0x400}, - {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b08, 0x2002e5}, - {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff}, - {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002b0}, - {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x100305}, - {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0}, - {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002c0}, - {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x100315}, - {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x710000}, - {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x740000}, - {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002d0}, - {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x100325}, - {OP_ZP_E1, CSEM_REG_PRAM, 0x32290000}, - {OP_ZP_E1H, CSEM_REG_PRAM, 0x32260000}, - {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x23630c8b}, - {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x246e0c8a}, - {OP_WR_64_E1, CSEM_REG_PRAM + 0xc930, 0x654002d2}, - {OP_WR_64_E1H, CSEM_REG_PRAM + 0xcbb0, 0x64f00327}, -#define CSEM_COMMON_END 1014 -#define CSEM_PORT0_START 1014 - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8500, 0x40}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1980, 0x30}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8700, 0x3c}, - {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x5118, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4040, 0x6}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2300, 0xe}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30}, -#define CSEM_PORT0_END 1025 -#define CSEM_PORT1_START 1025 - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8600, 0x40}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1a40, 0x30}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x87f0, 0x3c}, - {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x511c, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4058, 0x6}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2338, 0xe}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6}, - {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30}, -#define CSEM_PORT1_END 1036 -#define CSEM_FUNC0_START 1036 - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30}, -#define CSEM_FUNC0_END 1039 -#define CSEM_FUNC1_START 1039 - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30}, -#define CSEM_FUNC1_END 1042 -#define CSEM_FUNC2_START 1042 - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x61c0, 0x30}, -#define CSEM_FUNC2_END 1045 -#define CSEM_FUNC3_START 1045 - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x30}, -#define CSEM_FUNC3_END 1048 -#define CSEM_FUNC4_START 1048 - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6340, 0x30}, -#define CSEM_FUNC4_END 1051 -#define CSEM_FUNC5_START 1051 - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6400, 0x30}, -#define CSEM_FUNC5_END 1054 -#define CSEM_FUNC6_START 1054 - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x64c0, 0x30}, -#define CSEM_FUNC6_END 1057 -#define CSEM_FUNC7_START 1057 - {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2}, - {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6580, 0x30}, -#define CSEM_FUNC7_END 1060 -#define XPB_COMMON_START 1060 - {OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20}, -#define XPB_COMMON_END 1061 -#define DQ_COMMON_START 1061 - {OP_WR, DORQ_REG_MODE_ACT, 0x2}, - {OP_WR, DORQ_REG_NORM_CID_OFST, 0x3}, - {OP_WR, DORQ_REG_OUTST_REQ, 0x4}, - {OP_WR, DORQ_REG_DPM_CID_ADDR, 0x8}, - {OP_WR, DORQ_REG_RSP_INIT_CRD, 0x2}, - {OP_WR, DORQ_REG_NORM_CMHEAD_TX, 0x90}, - {OP_WR, DORQ_REG_CMHEAD_RX, 0x90}, - {OP_WR, DORQ_REG_SHRT_CMHEAD, 0x800090}, - {OP_WR, DORQ_REG_ERR_CMHEAD, 0x8140000}, - {OP_WR, DORQ_REG_AGG_CMD0, 0x8a}, - {OP_WR, DORQ_REG_AGG_CMD1, 0x80}, - {OP_WR, DORQ_REG_AGG_CMD2, 0x90}, - {OP_WR, DORQ_REG_AGG_CMD3, 0x80}, - {OP_WR, DORQ_REG_SHRT_ACT_CNT, 0x6}, - {OP_WR, DORQ_REG_DQ_FIFO_FULL_TH, 0x7d0}, - {OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c}, - {OP_WR, DORQ_REG_REGN, 0x7c1004}, - {OP_WR, DORQ_REG_IF_EN, 0xf}, -#define DQ_COMMON_END 1079 -#define TIMERS_COMMON_START 1079 - {OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2}, - {OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c}, - {OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1}, - {OP_WR, TM_REG_CFC_CLD_CRDCNT_VAL, 0x1}, - {OP_WR, TM_REG_CLOUT_CRDCNT0_VAL, 0x1}, - {OP_WR, TM_REG_CLOUT_CRDCNT1_VAL, 0x1}, - {OP_WR, TM_REG_CLOUT_CRDCNT2_VAL, 0x1}, - {OP_WR, TM_REG_EXP_CRDCNT_VAL, 0x1}, - {OP_WR_E1, TM_REG_PCIARB_CRDCNT_VAL, 0x1}, - {OP_WR_E1H, TM_REG_PCIARB_CRDCNT_VAL, 0x2}, - {OP_WR_ASIC, TM_REG_TIMER_TICK_SIZE, 0x3d090}, - {OP_WR_EMUL, TM_REG_TIMER_TICK_SIZE, 0x9c}, - {OP_WR_FPGA, TM_REG_TIMER_TICK_SIZE, 0x9c4}, - {OP_WR, TM_REG_CL0_CONT_REGION, 0x8}, - {OP_WR, TM_REG_CL1_CONT_REGION, 0xc}, - {OP_WR, TM_REG_CL2_CONT_REGION, 0x10}, - {OP_WR, TM_REG_TM_CONTEXT_REGION, 0x20}, - {OP_WR, TM_REG_EN_TIMERS, 0x1}, - {OP_WR, TM_REG_EN_REAL_TIME_CNT, 0x1}, - {OP_WR, TM_REG_EN_CL0_INPUT, 0x1}, - {OP_WR, TM_REG_EN_CL1_INPUT, 0x1}, - {OP_WR, TM_REG_EN_CL2_INPUT, 0x1}, -#define TIMERS_COMMON_END 1101 -#define TIMERS_PORT0_START 1101 - {OP_WR, TM_REG_LIN0_LOGIC_ADDR, 0x0}, - {OP_WR, TM_REG_LIN0_PHY_ADDR_VALID, 0x0}, - {OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2}, -#define TIMERS_PORT0_END 1104 -#define TIMERS_PORT1_START 1104 - {OP_WR, TM_REG_LIN1_LOGIC_ADDR, 0x0}, - {OP_WR, TM_REG_LIN1_PHY_ADDR_VALID, 0x0}, - {OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2}, -#define TIMERS_PORT1_END 1107 -#define XSDM_COMMON_START 1107 - {OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614}, - {OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424}, - {OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600}, - {OP_WR_E1H, XSDM_REG_CMP_COUNTER_START_ADDR, 0x410}, - {OP_WR_E1, XSDM_REG_Q_COUNTER_START_ADDR, 0x604}, - {OP_WR_E1H, XSDM_REG_Q_COUNTER_START_ADDR, 0x414}, - {OP_WR, XSDM_REG_CMP_COUNTER_MAX0, 0xffff}, - {OP_WR, XSDM_REG_CMP_COUNTER_MAX1, 0xffff}, - {OP_WR, XSDM_REG_CMP_COUNTER_MAX2, 0xffff}, - {OP_WR, XSDM_REG_CMP_COUNTER_MAX3, 0xffff}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_0, 0x20}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_1, 0x20}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_2, 0x34}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_3, 0x35}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_4, 0x23}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_5, 0x24}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_6, 0x25}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_7, 0x26}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_8, 0x27}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_9, 0x29}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_10, 0x2a}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_11, 0x2b}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_12, 0x2c}, - {OP_WR, XSDM_REG_AGG_INT_EVENT_13, 0x2d}, - {OP_ZR, XSDM_REG_AGG_INT_EVENT_14, 0x52}, - {OP_WR, XSDM_REG_AGG_INT_MODE_0, 0x1}, - {OP_ZR, XSDM_REG_AGG_INT_MODE_1, 0x1f}, - {OP_WR, XSDM_REG_ENABLE_IN1, 0x7ffffff}, - {OP_WR, XSDM_REG_ENABLE_IN2, 0x3f}, - {OP_WR, XSDM_REG_ENABLE_OUT1, 0x7ffffff}, - {OP_WR, XSDM_REG_ENABLE_OUT2, 0xf}, - {OP_RD, XSDM_REG_NUM_OF_Q0_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q1_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q3_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q4_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q5_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q6_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q7_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q8_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q9_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q10_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_Q11_CMD, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_PKT_END_MSG, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0}, - {OP_RD, XSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0}, - {OP_WR_E1, XSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1}, - {OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8}, - {OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1}, - {OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa}, -#define XSDM_COMMON_END 1156 -#define QM_COMMON_START 1156 - {OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6}, - {OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5}, - {OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa}, - {OP_WR, QM_REG_ACTCTRINITVAL_3, 0x5}, - {OP_WR, QM_REG_PCIREQAT, 0x2}, - {OP_WR, QM_REG_CMINITCRD_0, 0x4}, - {OP_WR, QM_REG_CMINITCRD_1, 0x4}, - {OP_WR, QM_REG_CMINITCRD_2, 0x4}, - {OP_WR, QM_REG_CMINITCRD_3, 0x4}, - {OP_WR, QM_REG_CMINITCRD_4, 0x4}, - {OP_WR, QM_REG_CMINITCRD_5, 0x4}, - {OP_WR, QM_REG_CMINITCRD_6, 0x4}, - {OP_WR, QM_REG_CMINITCRD_7, 0x4}, - {OP_WR, QM_REG_OUTLDREQ, 0x4}, - {OP_WR, QM_REG_CTXREG_0, 0x7c}, - {OP_WR, QM_REG_CTXREG_1, 0x3d}, - {OP_WR, QM_REG_CTXREG_2, 0x3f}, - {OP_WR, QM_REG_CTXREG_3, 0x9c}, - {OP_WR, QM_REG_ENSEC, 0x7}, - {OP_ZR, QM_REG_QVOQIDX_0, 0x5}, - {OP_WR, QM_REG_WRRWEIGHTS_0, 0x1010101}, - {OP_WR, QM_REG_QVOQIDX_5, 0x0}, - {OP_WR, QM_REG_QVOQIDX_6, 0x4}, - {OP_WR, QM_REG_QVOQIDX_7, 0x4}, - {OP_WR, QM_REG_QVOQIDX_8, 0x2}, - {OP_WR, QM_REG_WRRWEIGHTS_1, 0x8012004}, - {OP_WR, QM_REG_QVOQIDX_9, 0x5}, - {OP_WR, QM_REG_QVOQIDX_10, 0x5}, - {OP_WR, QM_REG_QVOQIDX_11, 0x5}, - {OP_WR, QM_REG_QVOQIDX_12, 0x5}, - {OP_WR, QM_REG_WRRWEIGHTS_2, 0x20081001}, - {OP_WR, QM_REG_QVOQIDX_13, 0x8}, - {OP_WR, QM_REG_QVOQIDX_14, 0x6}, - {OP_WR, QM_REG_QVOQIDX_15, 0x7}, - {OP_WR, QM_REG_QVOQIDX_16, 0x0}, - {OP_WR, QM_REG_WRRWEIGHTS_3, 0x1010120}, - {OP_ZR, QM_REG_QVOQIDX_17, 0x4}, - {OP_WR, QM_REG_WRRWEIGHTS_4, 0x1010101}, - {OP_ZR_E1, QM_REG_QVOQIDX_21, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_21, 0x0}, - {OP_WR_E1, QM_REG_WRRWEIGHTS_5, 0x1010101}, - {OP_WR_E1H, QM_REG_QVOQIDX_22, 0x4}, - {OP_ZR_E1, QM_REG_QVOQIDX_25, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_23, 0x4}, - {OP_WR_E1, QM_REG_WRRWEIGHTS_6, 0x1010101}, - {OP_WR_E1H, QM_REG_QVOQIDX_24, 0x2}, - {OP_ZR_E1, QM_REG_QVOQIDX_29, 0x3}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_5, 0x8012004}, - {OP_WR_E1H, QM_REG_QVOQIDX_25, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_26, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_27, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_28, 0x5}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_6, 0x20081001}, - {OP_WR_E1H, QM_REG_QVOQIDX_29, 0x8}, - {OP_WR_E1H, QM_REG_QVOQIDX_30, 0x6}, - {OP_WR_E1H, QM_REG_QVOQIDX_31, 0x7}, - {OP_WR, QM_REG_QVOQIDX_32, 0x1}, - {OP_WR_E1, QM_REG_WRRWEIGHTS_7, 0x1010101}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_7, 0x1010120}, - {OP_WR, QM_REG_QVOQIDX_33, 0x1}, - {OP_WR, QM_REG_QVOQIDX_34, 0x1}, - {OP_WR, QM_REG_QVOQIDX_35, 0x1}, - {OP_WR, QM_REG_QVOQIDX_36, 0x1}, - {OP_WR, QM_REG_WRRWEIGHTS_8, 0x1010101}, - {OP_WR, QM_REG_QVOQIDX_37, 0x1}, - {OP_WR, QM_REG_QVOQIDX_38, 0x4}, - {OP_WR, QM_REG_QVOQIDX_39, 0x4}, - {OP_WR, QM_REG_QVOQIDX_40, 0x2}, - {OP_WR, QM_REG_WRRWEIGHTS_9, 0x8012004}, - {OP_WR, QM_REG_QVOQIDX_41, 0x5}, - {OP_WR, QM_REG_QVOQIDX_42, 0x5}, - {OP_WR, QM_REG_QVOQIDX_43, 0x5}, - {OP_WR, QM_REG_QVOQIDX_44, 0x5}, - {OP_WR, QM_REG_WRRWEIGHTS_10, 0x20081001}, - {OP_WR, QM_REG_QVOQIDX_45, 0x8}, - {OP_WR, QM_REG_QVOQIDX_46, 0x6}, - {OP_WR, QM_REG_QVOQIDX_47, 0x7}, - {OP_WR, QM_REG_QVOQIDX_48, 0x1}, - {OP_WR, QM_REG_WRRWEIGHTS_11, 0x1010120}, - {OP_WR, QM_REG_QVOQIDX_49, 0x1}, - {OP_WR, QM_REG_QVOQIDX_50, 0x1}, - {OP_WR, QM_REG_QVOQIDX_51, 0x1}, - {OP_WR, QM_REG_QVOQIDX_52, 0x1}, - {OP_WR, QM_REG_WRRWEIGHTS_12, 0x1010101}, - {OP_WR, QM_REG_QVOQIDX_53, 0x1}, - {OP_WR_E1, QM_REG_QVOQIDX_54, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_54, 0x4}, - {OP_WR_E1, QM_REG_QVOQIDX_55, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_55, 0x4}, - {OP_WR_E1, QM_REG_QVOQIDX_56, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_56, 0x2}, - {OP_WR_E1, QM_REG_WRRWEIGHTS_13, 0x1010101}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_13, 0x8012004}, - {OP_WR_E1, QM_REG_QVOQIDX_57, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_57, 0x5}, - {OP_WR_E1, QM_REG_QVOQIDX_58, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_58, 0x5}, - {OP_WR_E1, QM_REG_QVOQIDX_59, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_59, 0x5}, - {OP_WR_E1, QM_REG_QVOQIDX_60, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_60, 0x5}, - {OP_WR_E1, QM_REG_WRRWEIGHTS_14, 0x1010101}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_14, 0x20081001}, - {OP_WR_E1, QM_REG_QVOQIDX_61, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_61, 0x8}, - {OP_WR_E1, QM_REG_QVOQIDX_62, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_62, 0x6}, - {OP_WR_E1, QM_REG_QVOQIDX_63, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_63, 0x7}, - {OP_WR_E1, QM_REG_WRRWEIGHTS_15, 0x1010101}, - {OP_WR_E1H, QM_REG_QVOQIDX_64, 0x0}, - {OP_WR_E1, QM_REG_VOQQMASK_0_LSB, 0xffff003f}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_15, 0x1010120}, - {OP_ZR_E1, QM_REG_VOQQMASK_0_MSB, 0x2}, - {OP_ZR_E1H, QM_REG_QVOQIDX_65, 0x4}, - {OP_WR_E1, QM_REG_VOQQMASK_1_MSB, 0xffff003f}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_16, 0x1010101}, - {OP_WR_E1, QM_REG_VOQQMASK_2_LSB, 0x100}, - {OP_WR_E1H, QM_REG_QVOQIDX_69, 0x0}, - {OP_WR_E1, QM_REG_VOQQMASK_2_MSB, 0x100}, - {OP_WR_E1H, QM_REG_QVOQIDX_70, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_71, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_72, 0x2}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_17, 0x8012004}, - {OP_WR_E1H, QM_REG_QVOQIDX_73, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_74, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_75, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_76, 0x5}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_18, 0x20081001}, - {OP_WR_E1H, QM_REG_QVOQIDX_77, 0x8}, - {OP_WR_E1H, QM_REG_QVOQIDX_78, 0x6}, - {OP_WR_E1H, QM_REG_QVOQIDX_79, 0x7}, - {OP_WR_E1H, QM_REG_QVOQIDX_80, 0x0}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_19, 0x1010120}, - {OP_ZR_E1H, QM_REG_QVOQIDX_81, 0x4}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_20, 0x1010101}, - {OP_WR_E1H, QM_REG_QVOQIDX_85, 0x0}, - {OP_WR_E1H, QM_REG_QVOQIDX_86, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_87, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_88, 0x2}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_21, 0x8012004}, - {OP_WR_E1H, QM_REG_QVOQIDX_89, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_90, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_91, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_92, 0x5}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_22, 0x20081001}, - {OP_WR_E1H, QM_REG_QVOQIDX_93, 0x8}, - {OP_WR_E1H, QM_REG_QVOQIDX_94, 0x6}, - {OP_WR_E1H, QM_REG_QVOQIDX_95, 0x7}, - {OP_WR_E1H, QM_REG_QVOQIDX_96, 0x1}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_23, 0x1010120}, - {OP_WR_E1H, QM_REG_QVOQIDX_97, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_98, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_99, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_100, 0x1}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_24, 0x1010101}, - {OP_WR_E1H, QM_REG_QVOQIDX_101, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_102, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_103, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_104, 0x2}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_25, 0x8012004}, - {OP_WR_E1H, QM_REG_QVOQIDX_105, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_106, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_107, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_108, 0x5}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_26, 0x20081001}, - {OP_WR_E1H, QM_REG_QVOQIDX_109, 0x8}, - {OP_WR_E1H, QM_REG_QVOQIDX_110, 0x6}, - {OP_WR_E1H, QM_REG_QVOQIDX_111, 0x7}, - {OP_WR_E1H, QM_REG_QVOQIDX_112, 0x1}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_27, 0x1010120}, - {OP_WR_E1H, QM_REG_QVOQIDX_113, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_114, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_115, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_116, 0x1}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_28, 0x1010101}, - {OP_WR_E1H, QM_REG_QVOQIDX_117, 0x1}, - {OP_WR_E1H, QM_REG_QVOQIDX_118, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_119, 0x4}, - {OP_WR_E1H, QM_REG_QVOQIDX_120, 0x2}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_29, 0x8012004}, - {OP_WR_E1H, QM_REG_QVOQIDX_121, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_122, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_123, 0x5}, - {OP_WR_E1H, QM_REG_QVOQIDX_124, 0x5}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_30, 0x20081001}, - {OP_WR_E1H, QM_REG_QVOQIDX_125, 0x8}, - {OP_WR_E1H, QM_REG_QVOQIDX_126, 0x6}, - {OP_WR_E1H, QM_REG_QVOQIDX_127, 0x7}, - {OP_WR_E1H, QM_REG_WRRWEIGHTS_31, 0x1010120}, - {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB, 0x3f003f}, - {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB_EXT_A, 0x3f003f}, - {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB_EXT_A, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB, 0x3f003f}, - {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB_EXT_A, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB_EXT_A, 0x3f003f}, - {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB, 0x1000100}, - {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB, 0x1000100}, - {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB_EXT_A, 0x1000100}, - {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB_EXT_A, 0x1000100}, - {OP_ZR, QM_REG_VOQQMASK_3_LSB, 0x2}, - {OP_WR_E1, QM_REG_VOQQMASK_4_LSB, 0xc0}, - {OP_WR_E1H, QM_REG_VOQQMASK_3_LSB_EXT_A, 0x0}, - {OP_WR_E1, QM_REG_VOQQMASK_4_MSB, 0xc0}, - {OP_WR_E1H, QM_REG_VOQQMASK_3_MSB_EXT_A, 0x0}, - {OP_WR_E1, QM_REG_VOQQMASK_5_LSB, 0x1e00}, - {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB, 0xc000c0}, - {OP_WR_E1, QM_REG_VOQQMASK_5_MSB, 0x1e00}, - {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB, 0xc000c0}, - {OP_WR_E1, QM_REG_VOQQMASK_6_LSB, 0x4000}, - {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB_EXT_A, 0xc000c0}, - {OP_WR_E1, QM_REG_VOQQMASK_6_MSB, 0x4000}, - {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB_EXT_A, 0xc000c0}, - {OP_WR_E1, QM_REG_VOQQMASK_7_LSB, 0x8000}, - {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB, 0x1e001e00}, - {OP_WR_E1, QM_REG_VOQQMASK_7_MSB, 0x8000}, - {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB, 0x1e001e00}, - {OP_WR_E1, QM_REG_VOQQMASK_8_LSB, 0x2000}, - {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB_EXT_A, 0x1e001e00}, - {OP_WR_E1, QM_REG_VOQQMASK_8_MSB, 0x2000}, - {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB_EXT_A, 0x1e001e00}, - {OP_ZR_E1, QM_REG_VOQQMASK_9_LSB, 0x7}, - {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB, 0x40004000}, - {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB, 0x40004000}, - {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB_EXT_A, 0x40004000}, - {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB_EXT_A, 0x40004000}, - {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB, 0x80008000}, - {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB, 0x80008000}, - {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB_EXT_A, 0x80008000}, - {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB_EXT_A, 0x80008000}, - {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB, 0x20002000}, - {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB, 0x20002000}, - {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB_EXT_A, 0x20002000}, - {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB_EXT_A, 0x20002000}, - {OP_ZR_E1H, QM_REG_VOQQMASK_9_LSB, 0x2}, - {OP_WR_E1H, QM_REG_VOQQMASK_9_LSB_EXT_A, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_9_MSB_EXT_A, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB_EXT_A, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB_EXT_A, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB_EXT_A, 0x0}, - {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB_EXT_A, 0x0}, - {OP_WR_E1H, QM_REG_VOQPORT_0, 0x0}, - {OP_WR, QM_REG_VOQPORT_1, 0x1}, - {OP_ZR, QM_REG_VOQPORT_2, 0xa}, - {OP_WR, QM_REG_CMINTVOQMASK_0, 0xc08}, - {OP_WR, QM_REG_CMINTVOQMASK_1, 0x40}, - {OP_WR, QM_REG_CMINTVOQMASK_2, 0x100}, - {OP_WR, QM_REG_CMINTVOQMASK_3, 0x20}, - {OP_WR, QM_REG_CMINTVOQMASK_4, 0x17}, - {OP_WR, QM_REG_CMINTVOQMASK_5, 0x80}, - {OP_WR, QM_REG_CMINTVOQMASK_6, 0x200}, - {OP_WR, QM_REG_CMINTVOQMASK_7, 0x0}, - {OP_WR_E1, QM_REG_HWAEMPTYMASK_LSB, 0xffff01ff}, - {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB, 0x1ff01ff}, - {OP_WR_E1, QM_REG_HWAEMPTYMASK_MSB, 0xffff01ff}, - {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB, 0x1ff01ff}, - {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB_EXT_A, 0x1ff01ff}, - {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB_EXT_A, 0x1ff01ff}, - {OP_WR, QM_REG_ENBYPVOQMASK, 0x13}, - {OP_WR, QM_REG_VOQCREDITAFULLTHR, 0x13f}, - {OP_WR, QM_REG_VOQINITCREDIT_0, 0x140}, - {OP_WR, QM_REG_VOQINITCREDIT_1, 0x140}, - {OP_ZR, QM_REG_VOQINITCREDIT_2, 0x2}, - {OP_WR, QM_REG_VOQINITCREDIT_4, 0xc0}, - {OP_ZR, QM_REG_VOQINITCREDIT_5, 0x7}, - {OP_WR, QM_REG_TASKCRDCOST_0, 0x48}, - {OP_WR, QM_REG_TASKCRDCOST_1, 0x48}, - {OP_ZR, QM_REG_TASKCRDCOST_2, 0x2}, - {OP_WR, QM_REG_TASKCRDCOST_4, 0x48}, - {OP_ZR, QM_REG_TASKCRDCOST_5, 0x7}, - {OP_WR, QM_REG_BYTECRDINITVAL, 0x8000}, - {OP_WR, QM_REG_BYTECRDCOST, 0x25e4}, - {OP_WR, QM_REG_BYTECREDITAFULLTHR, 0x7fff}, - {OP_WR_E1, QM_REG_ENBYTECRD_LSB, 0x7}, - {OP_WR_E1H, QM_REG_ENBYTECRD_LSB, 0x70007}, - {OP_WR_E1, QM_REG_ENBYTECRD_MSB, 0x7}, - {OP_WR_E1H, QM_REG_ENBYTECRD_MSB, 0x70007}, - {OP_WR_E1H, QM_REG_ENBYTECRD_LSB_EXT_A, 0x70007}, - {OP_WR_E1H, QM_REG_ENBYTECRD_MSB_EXT_A, 0x70007}, - {OP_WR, QM_REG_BYTECRDPORT_LSB, 0x0}, - {OP_WR, QM_REG_BYTECRDPORT_MSB, 0xffffffff}, - {OP_WR_E1, QM_REG_FUNCNUMSEL_LSB, 0x0}, - {OP_WR_E1H, QM_REG_BYTECRDPORT_LSB_EXT_A, 0x0}, - {OP_WR_E1, QM_REG_FUNCNUMSEL_MSB, 0xffffffff}, - {OP_WR_E1H, QM_REG_BYTECRDPORT_MSB_EXT_A, 0xffffffff}, - {OP_WR_E1H, QM_REG_PQ2PCIFUNC_0, 0x0}, - {OP_WR_E1H, QM_REG_PQ2PCIFUNC_1, 0x2}, - {OP_WR_E1H, QM_REG_PQ2PCIFUNC_2, 0x1}, - {OP_WR_E1H, QM_REG_PQ2PCIFUNC_3, 0x3}, - {OP_WR_E1H, QM_REG_PQ2PCIFUNC_4, 0x4}, - {OP_WR_E1H, QM_REG_PQ2PCIFUNC_5, 0x6}, - {OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5}, - {OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7}, - {OP_WR, QM_REG_CMINTEN, 0xff}, -#define QM_COMMON_END 1456 -#define PBF_COMMON_START 1456 - {OP_WR, PBF_REG_INIT, 0x1}, - {OP_WR, PBF_REG_INIT_P4, 0x1}, - {OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1}, - {OP_WR, PBF_REG_IF_ENABLE_REG, 0x7fff}, - {OP_WR, PBF_REG_INIT_P4, 0x0}, - {OP_WR, PBF_REG_INIT, 0x0}, - {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0}, -#define PBF_COMMON_END 1463 -#define PBF_PORT0_START 1463 - {OP_WR, PBF_REG_INIT_P0, 0x1}, - {OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1}, - {OP_WR, PBF_REG_INIT_P0, 0x0}, - {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0}, -#define PBF_PORT0_END 1467 -#define PBF_PORT1_START 1467 - {OP_WR, PBF_REG_INIT_P1, 0x1}, - {OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1}, - {OP_WR, PBF_REG_INIT_P1, 0x0}, - {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0}, -#define PBF_PORT1_END 1471 -#define XCM_COMMON_START 1471 - {OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32}, - {OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020}, - {OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020}, - {OP_WR, XCM_REG_TM_XCM_HDR, 0x1000030}, - {OP_WR, XCM_REG_ERR_XCM_HDR, 0x8100000}, - {OP_WR, XCM_REG_ERR_EVNT_ID, 0x33}, - {OP_WR, XCM_REG_EXPR_EVNT_ID, 0x30}, - {OP_WR, XCM_REG_STOP_EVNT_ID, 0x31}, - {OP_WR, XCM_REG_STORM_WEIGHT, 0x3}, - {OP_WR, XCM_REG_TSEM_WEIGHT, 0x6}, - {OP_WR, XCM_REG_CSEM_WEIGHT, 0x3}, - {OP_WR, XCM_REG_USEM_WEIGHT, 0x3}, - {OP_WR, XCM_REG_DORQ_WEIGHT, 0x2}, - {OP_WR, XCM_REG_PBF_WEIGHT, 0x0}, - {OP_WR, XCM_REG_NIG0_WEIGHT, 0x2}, - {OP_WR, XCM_REG_CP_WEIGHT, 0x0}, - {OP_WR, XCM_REG_XSDM_WEIGHT, 0x6}, - {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x4}, - {OP_WR, XCM_REG_XQM_S_WEIGHT, 0x2}, - {OP_WR, XCM_REG_TM_WEIGHT, 0x2}, - {OP_WR, XCM_REG_XCM_XQM_USE_Q, 0x1}, - {OP_WR, XCM_REG_XQM_BYP_ACT_UPD, 0x6}, - {OP_WR, XCM_REG_UNA_GT_NXT_Q, 0x0}, - {OP_WR, XCM_REG_AUX1_Q, 0x2}, - {OP_WR, XCM_REG_AUX_CNT_FLG_Q_19, 0x1}, - {OP_WR, XCM_REG_GR_ARB_TYPE, 0x1}, - {OP_WR, XCM_REG_GR_LD0_PR, 0x1}, - {OP_WR, XCM_REG_GR_LD1_PR, 0x2}, - {OP_WR, XCM_REG_CFC_INIT_CRD, 0x1}, - {OP_WR, XCM_REG_FIC0_INIT_CRD, 0x40}, - {OP_WR, XCM_REG_FIC1_INIT_CRD, 0x40}, - {OP_WR, XCM_REG_TM_INIT_CRD, 0x4}, - {OP_WR, XCM_REG_XQM_INIT_CRD, 0x20}, - {OP_WR, XCM_REG_XX_INIT_CRD, 0x2}, - {OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f}, - {OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20}, - {OP_ZR, XCM_REG_XX_TABLE, 0x12}, - {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02d4}, - {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0329}, - {OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf}, - {OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7}, - {OP_WR, XCM_REG_N_SM_CTX_LD_2, 0xb}, - {OP_WR, XCM_REG_N_SM_CTX_LD_3, 0xe}, - {OP_ZR_E1, XCM_REG_N_SM_CTX_LD_4, 0x4}, - {OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xe}, - {OP_ZR_E1H, XCM_REG_N_SM_CTX_LD_5, 0x3}, - {OP_WR, XCM_REG_XCM_REG0_SZ, 0x4}, - {OP_WR, XCM_REG_XCM_STORM0_IFEN, 0x1}, - {OP_WR, XCM_REG_XCM_STORM1_IFEN, 0x1}, - {OP_WR, XCM_REG_XCM_XQM_IFEN, 0x1}, - {OP_WR, XCM_REG_STORM_XCM_IFEN, 0x1}, - {OP_WR, XCM_REG_XQM_XCM_IFEN, 0x1}, - {OP_WR, XCM_REG_XSDM_IFEN, 0x1}, - {OP_WR, XCM_REG_TM_XCM_IFEN, 0x1}, - {OP_WR, XCM_REG_XCM_TM_IFEN, 0x1}, - {OP_WR, XCM_REG_TSEM_IFEN, 0x1}, - {OP_WR, XCM_REG_CSEM_IFEN, 0x1}, - {OP_WR, XCM_REG_USEM_IFEN, 0x1}, - {OP_WR, XCM_REG_DORQ_IFEN, 0x1}, - {OP_WR, XCM_REG_PBF_IFEN, 0x1}, - {OP_WR, XCM_REG_NIG0_IFEN, 0x1}, - {OP_WR, XCM_REG_NIG1_IFEN, 0x1}, - {OP_WR, XCM_REG_CDU_AG_WR_IFEN, 0x1}, - {OP_WR, XCM_REG_CDU_AG_RD_IFEN, 0x1}, - {OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1}, - {OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1}, - {OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1}, -#define XCM_COMMON_END 1538 -#define XCM_PORT0_START 1538 - {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, - {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, - {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, - {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0}, - {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD00, 0x2}, - {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2}, - {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, - {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, -#define XCM_PORT0_END 1546 -#define XCM_PORT1_START 1546 - {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, - {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, - {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, - {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0}, - {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD01, 0x2}, - {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2}, - {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, - {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, -#define XCM_PORT1_END 1554 -#define XCM_FUNC0_START 1554 - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, - {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0}, -#define XCM_FUNC0_END 1563 -#define XCM_FUNC1_START 1563 - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, - {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0}, -#define XCM_FUNC1_END 1572 -#define XCM_FUNC2_START 1572 - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, - {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0}, -#define XCM_FUNC2_END 1581 -#define XCM_FUNC3_START 1581 - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, - {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0}, -#define XCM_FUNC3_END 1590 -#define XCM_FUNC4_START 1590 - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, - {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0}, -#define XCM_FUNC4_END 1599 -#define XCM_FUNC5_START 1599 - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, - {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0}, -#define XCM_FUNC5_END 1608 -#define XCM_FUNC6_START 1608 - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, - {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0}, -#define XCM_FUNC6_END 1617 -#define XCM_FUNC7_START 1617 - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, - {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, - {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, - {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0}, -#define XCM_FUNC7_END 1626 -#define XSEM_COMMON_START 1626 - {OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0}, - {OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0}, - {OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0}, - {OP_RD, XSEM_REG_MSG_NUM_FOC1, 0x0}, - {OP_RD, XSEM_REG_MSG_NUM_FOC2, 0x0}, - {OP_RD, XSEM_REG_MSG_NUM_FOC3, 0x0}, - {OP_WR, XSEM_REG_ARB_ELEMENT0, 0x1}, - {OP_WR, XSEM_REG_ARB_ELEMENT1, 0x2}, - {OP_WR, XSEM_REG_ARB_ELEMENT2, 0x3}, - {OP_WR, XSEM_REG_ARB_ELEMENT3, 0x0}, - {OP_WR, XSEM_REG_ARB_ELEMENT4, 0x4}, - {OP_WR, XSEM_REG_ARB_CYCLE_SIZE, 0x1}, - {OP_WR, XSEM_REG_TS_0_AS, 0x0}, - {OP_WR, XSEM_REG_TS_1_AS, 0x1}, - {OP_WR, XSEM_REG_TS_2_AS, 0x4}, - {OP_WR, XSEM_REG_TS_3_AS, 0x0}, - {OP_WR, XSEM_REG_TS_4_AS, 0x1}, - {OP_WR, XSEM_REG_TS_5_AS, 0x3}, - {OP_WR, XSEM_REG_TS_6_AS, 0x0}, - {OP_WR, XSEM_REG_TS_7_AS, 0x1}, - {OP_WR, XSEM_REG_TS_8_AS, 0x4}, - {OP_WR, XSEM_REG_TS_9_AS, 0x0}, - {OP_WR, XSEM_REG_TS_10_AS, 0x1}, - {OP_WR, XSEM_REG_TS_11_AS, 0x3}, - {OP_WR, XSEM_REG_TS_12_AS, 0x0}, - {OP_WR, XSEM_REG_TS_13_AS, 0x1}, - {OP_WR, XSEM_REG_TS_14_AS, 0x4}, - {OP_WR, XSEM_REG_TS_15_AS, 0x0}, - {OP_WR, XSEM_REG_TS_16_AS, 0x4}, - {OP_WR, XSEM_REG_TS_17_AS, 0x3}, - {OP_ZR, XSEM_REG_TS_18_AS, 0x2}, - {OP_WR, XSEM_REG_ENABLE_IN, 0x3fff}, - {OP_WR, XSEM_REG_ENABLE_OUT, 0x3ff}, - {OP_WR, XSEM_REG_FIC0_DISABLE, 0x0}, - {OP_WR, XSEM_REG_FIC1_DISABLE, 0x0}, - {OP_WR, XSEM_REG_PAS_DISABLE, 0x0}, - {OP_WR, XSEM_REG_THREADS_LIST, 0xffff}, - {OP_ZR, XSEM_REG_PASSIVE_BUFFER, 0x800}, - {OP_WR, XSEM_REG_FAST_MEMORY + 0x18bc0, 0x1}, - {OP_WR, XSEM_REG_FAST_MEMORY + 0x18000, 0x0}, - {OP_WR, XSEM_REG_FAST_MEMORY + 0x18040, 0x18}, - {OP_WR, XSEM_REG_FAST_MEMORY + 0x18080, 0xc}, - {OP_WR, XSEM_REG_FAST_MEMORY + 0x180c0, 0x66}, - {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18300, 0x7a120}, - {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18300, 0x138}, - {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18300, 0x1388}, - {OP_WR, XSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4}, - {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18340, 0x1f4}, - {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18340, 0x0}, - {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18340, 0x5}, - {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4}, - {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500}, - {OP_WR_EMUL_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x0}, - {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d60, 0x4}, - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x1}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d60 + 0x10, 0x202f3}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x29c8, 0x4}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3000, 0x48}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29c8 + 0x10, 0x20348}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2080, 0x48}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1000, 0x2}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9020, 0xc8}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3128, 0x8e}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202f5}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402f7}, - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3e20, 0x202fb}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x2034a}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x4034c}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1830, 0x0}, - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c20, 0x0}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0}, - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c10, 0x0}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202fd}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2c08, 0x20350}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2}, - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f48, 0x202ff}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100352}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x8408, 0x20362}, - {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100301}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100364}, - {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80311}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80374}, - {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80319}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8037c}, - {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xb50000}, - {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xbd0000}, - {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130321}, - {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x3a8, 0xb0384}, - {OP_ZP_E1, XSEM_REG_PRAM, 0x33660000}, - {OP_ZP_E1H, XSEM_REG_PRAM, 0x34060000}, - {OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38b30cda}, - {OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x37960d02}, - {OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3bb11b07}, - {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3bc31ae8}, - {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x2a2629f4}, - {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x382629d9}, - {OP_WR_64_E1, XSEM_REG_PRAM + 0x1d6c0, 0x45280323}, - {OP_ZP_E1H, XSEM_REG_PRAM + 0x20000, 0x124537e3}, - {OP_WR_64_E1H, XSEM_REG_PRAM + 0x22220, 0x3bbc0386}, -#define XSEM_COMMON_END 1741 -#define XSEM_PORT0_START 1741 - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x14}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c40, 0x24}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x14}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1400, 0xa}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2548, 0x24}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1450, 0x6}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2668, 0x24}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3378, 0xfc}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2788, 0x24}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x24}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d78, 0x20325}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d88, 0x100327}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e0, 0x20388}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1508, 0x1}, - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3000, 0x1}, - {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5020, 0x2}, - {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5030, 0x2}, - {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5000, 0x2}, - {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5010, 0x2}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5040, 0x0}, - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x5208, 0x1}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5048, 0xe}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2038a}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20337}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4}, -#define XSEM_PORT0_END 1775 -#define XSEM_PORT1_START 1775 - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3bf0, 0x14}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3cd0, 0x24}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24f8, 0x14}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1428, 0xa}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x25d8, 0x24}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1468, 0x6}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26f8, 0x24}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3768, 0xfc}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2818, 0x24}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x24}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d80, 0x20339}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3dc8, 0x10033b}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e8, 0x2038c}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x150c, 0x1}, - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3004, 0x1}, - {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5028, 0x2}, - {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5038, 0x2}, - {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5008, 0x2}, - {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5018, 0x2}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5044, 0x0}, - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x520c, 0x1}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5080, 0xe}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2038e}, - {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42}, - {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2034b}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42}, - {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4}, -#define XSEM_PORT1_END 1809 -#define XSEM_FUNC0_START 1809 - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f0, 0x100390}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe}, -#define XSEM_FUNC0_END 1812 -#define XSEM_FUNC1_START 1812 - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a30, 0x1003a0}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe}, -#define XSEM_FUNC1_END 1815 -#define XSEM_FUNC2_START 1815 - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a70, 0x1003b0}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe}, -#define XSEM_FUNC2_END 1818 -#define XSEM_FUNC3_START 1818 - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2ab0, 0x1003c0}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe}, -#define XSEM_FUNC3_END 1821 -#define XSEM_FUNC4_START 1821 - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2af0, 0x1003d0}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe}, -#define XSEM_FUNC4_END 1824 -#define XSEM_FUNC5_START 1824 - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b30, 0x1003e0}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe}, -#define XSEM_FUNC5_END 1827 -#define XSEM_FUNC6_START 1827 - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b70, 0x1003f0}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe}, -#define XSEM_FUNC6_END 1830 -#define XSEM_FUNC7_START 1830 - {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0}, - {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2bb0, 0x100400}, - {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe}, -#define XSEM_FUNC7_END 1833 -#define CDU_COMMON_START 1833 - {OP_WR, CDU_REG_CDU_CONTROL0, 0x1}, - {OP_WR_E1H, CDU_REG_MF_MODE, 0x1}, - {OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000}, - {OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d}, - {OP_WB_E1, CDU_REG_L1TT, 0x200034d}, - {OP_WB_E1H, CDU_REG_L1TT, 0x2000410}, - {OP_WB_E1, CDU_REG_MATT, 0x20054d}, - {OP_WB_E1H, CDU_REG_MATT, 0x280610}, - {OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2}, - {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6056d}, - {OP_ZR, CDU_REG_MATT + 0xa0, 0x18}, -#define CDU_COMMON_END 1844 -#define DMAE_COMMON_START 1844 - {OP_ZR, DMAE_REG_CMD_MEM, 0xe0}, - {OP_WR, DMAE_REG_CRC16C_INIT, 0x0}, - {OP_WR, DMAE_REG_CRC16T10_INIT, 0x1}, - {OP_WR_E1, DMAE_REG_PXP_REQ_INIT_CRD, 0x1}, - {OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2}, - {OP_WR, DMAE_REG_PCI_IFEN, 0x1}, - {OP_WR, DMAE_REG_GRC_IFEN, 0x1}, -#define DMAE_COMMON_END 1851 -#define PXP_COMMON_START 1851 - {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50573}, - {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50638}, - {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50578}, - {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5063d}, - {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5057d}, - {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x20, 0x50642}, -#define PXP_COMMON_END 1857 -#define CFC_COMMON_START 1857 - {OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100}, - {OP_WR, CFC_REG_CONTROL0, 0x10}, - {OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff}, - {OP_WR, CFC_REG_INTERFACES, 0x280000}, - {OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a}, - {OP_WR, CFC_REG_INTERFACES, 0x0}, -#define CFC_COMMON_END 1863 -#define HC_COMMON_START 1863 - {OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4}, -#define HC_COMMON_END 1864 -#define HC_PORT0_START 1864 - {OP_WR_E1, HC_REG_CONFIG_0, 0x1080}, - {OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2}, - {OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10}, - {OP_WR_E1, HC_REG_LEADING_EDGE_0, 0xffff}, - {OP_WR_E1, HC_REG_TRAILING_EDGE_0, 0xffff}, - {OP_WR_E1, HC_REG_AGG_INT_0, 0x0}, - {OP_WR_E1, HC_REG_ATTN_IDX, 0x0}, - {OP_ZR_E1, HC_REG_ATTN_BIT, 0x2}, - {OP_WR_E1, HC_REG_VQID_0, 0x2b5}, - {OP_WR_E1, HC_REG_PCI_CONFIG_0, 0x0}, - {OP_ZR_E1, HC_REG_P0_PROD_CONS, 0x4a}, - {OP_WR_E1, HC_REG_INT_MASK, 0x1ffff}, - {OP_ZR_E1, HC_REG_PBA_COMMAND, 0x2}, - {OP_WR_E1, HC_REG_CONFIG_0, 0x1a80}, - {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS, 0x24}, - {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, - {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, - {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, -#define HC_PORT0_END 1882 -#define HC_PORT1_START 1882 - {OP_WR_E1, HC_REG_CONFIG_1, 0x1080}, - {OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2}, - {OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10}, - {OP_WR_E1, HC_REG_LEADING_EDGE_1, 0xffff}, - {OP_WR_E1, HC_REG_TRAILING_EDGE_1, 0xffff}, - {OP_WR_E1, HC_REG_AGG_INT_1, 0x0}, - {OP_WR_E1, HC_REG_ATTN_IDX + 0x4, 0x0}, - {OP_ZR_E1, HC_REG_ATTN_BIT + 0x8, 0x2}, - {OP_WR_E1, HC_REG_VQID_1, 0x2b5}, - {OP_WR_E1, HC_REG_PCI_CONFIG_1, 0x0}, - {OP_ZR_E1, HC_REG_P1_PROD_CONS, 0x4a}, - {OP_WR_E1, HC_REG_INT_MASK + 0x4, 0x1ffff}, - {OP_ZR_E1, HC_REG_PBA_COMMAND + 0x8, 0x2}, - {OP_WR_E1, HC_REG_CONFIG_1, 0x1a80}, - {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24}, - {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, - {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, - {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, -#define HC_PORT1_END 1900 -#define HC_FUNC0_START 1900 - {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080}, - {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0}, - {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10}, - {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0}, - {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2}, - {OP_WR_E1H, HC_REG_VQID_0, 0x2b5}, - {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0}, - {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a}, - {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff}, - {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2}, - {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, -#define HC_FUNC0_END 1915 -#define HC_FUNC1_START 1915 - {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080}, - {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1}, - {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10}, - {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0}, - {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2}, - {OP_WR_E1H, HC_REG_VQID_1, 0x2b5}, - {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0}, - {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a}, - {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff}, - {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2}, - {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, -#define HC_FUNC1_END 1930 -#define HC_FUNC2_START 1930 - {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080}, - {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2}, - {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10}, - {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0}, - {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2}, - {OP_WR_E1H, HC_REG_VQID_0, 0x2b5}, - {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0}, - {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a}, - {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff}, - {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2}, - {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, -#define HC_FUNC2_END 1945 -#define HC_FUNC3_START 1945 - {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080}, - {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3}, - {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10}, - {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0}, - {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2}, - {OP_WR_E1H, HC_REG_VQID_1, 0x2b5}, - {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0}, - {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a}, - {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff}, - {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2}, - {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, -#define HC_FUNC3_END 1960 -#define HC_FUNC4_START 1960 - {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080}, - {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4}, - {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10}, - {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0}, - {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2}, - {OP_WR_E1H, HC_REG_VQID_0, 0x2b5}, - {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0}, - {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a}, - {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff}, - {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2}, - {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, -#define HC_FUNC4_END 1975 -#define HC_FUNC5_START 1975 - {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080}, - {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5}, - {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10}, - {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0}, - {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2}, - {OP_WR_E1H, HC_REG_VQID_1, 0x2b5}, - {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0}, - {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a}, - {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff}, - {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2}, - {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, -#define HC_FUNC5_END 1990 -#define HC_FUNC6_START 1990 - {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080}, - {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6}, - {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10}, - {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0}, - {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2}, - {OP_WR_E1H, HC_REG_VQID_0, 0x2b5}, - {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0}, - {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a}, - {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff}, - {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2}, - {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, -#define HC_FUNC6_END 2005 -#define HC_FUNC7_START 2005 - {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080}, - {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7}, - {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10}, - {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0}, - {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2}, - {OP_WR_E1H, HC_REG_VQID_1, 0x2b5}, - {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0}, - {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a}, - {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff}, - {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2}, - {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, - {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, -#define HC_FUNC7_END 2020 -#define PXP2_COMMON_START 2020 - {OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1}, - {OP_WR, PXP2_REG_PGL_CONTROL0, 0xe38340}, - {OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10}, - {OP_WR_E1H, PXP2_REG_RQ_ELT_DISABLE, 0x1}, - {OP_WR_E1H, PXP2_REG_WR_REV_MODE, 0x0}, - {OP_WR, PXP2_REG_PGL_INT_TSDM_0, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_TSDM_1, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_TSDM_2, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_TSDM_3, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_TSDM_4, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_TSDM_5, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_TSDM_6, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_TSDM_7, 0xffffffff}, - {OP_WR_E1, PXP2_REG_PGL_INT_USDM_1, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_USDM_2, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_USDM_3, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_USDM_4, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_USDM_5, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_USDM_6, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_USDM_7, 0xffffffff}, - {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_1, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_XSDM_2, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_XSDM_3, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_XSDM_4, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_XSDM_5, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_XSDM_6, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_XSDM_7, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_CSDM_0, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_CSDM_1, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_CSDM_2, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_CSDM_3, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_CSDM_4, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_CSDM_5, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_CSDM_6, 0xffffffff}, - {OP_WR, PXP2_REG_PGL_INT_CSDM_7, 0xffffffff}, - {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_0, 0xffff3330}, - {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_0, 0xff802000}, - {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_1, 0xffff3340}, - {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_0, 0xf0005000}, - {OP_WR_E1, PXP2_REG_PGL_INT_USDM_0, 0xf0003000}, - {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_1, 0xf0008000}, - {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ6, 0x8}, - {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ9, 0x8}, - {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ10, 0x8}, - {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ11, 0x2}, - {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ17, 0x4}, - {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ18, 0x5}, - {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ19, 0x4}, - {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ22, 0x0}, - {OP_WR, PXP2_REG_RD_START_INIT, 0x1}, - {OP_WR, PXP2_REG_WR_DMAE_TH, 0x3f}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD0, 0x40}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD1, 0x1808}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD2, 0x803}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD3, 0x803}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD4, 0x40}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD5, 0x3}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD6, 0x803}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD7, 0x803}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD8, 0x803}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD9, 0x10003}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD10, 0x803}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD11, 0x803}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD12, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD13, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD14, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD15, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD16, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD17, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD18, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD19, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD20, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD22, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD23, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD24, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD25, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD26, 0x3}, - {OP_WR, PXP2_REG_RQ_BW_RD_ADD27, 0x3}, - {OP_WR, PXP2_REG_PSWRQ_BW_ADD28, 0x2403}, - {OP_WR, PXP2_REG_RQ_BW_WR_ADD29, 0x2f}, - {OP_WR, PXP2_REG_RQ_BW_WR_ADD30, 0x9}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND0, 0x19}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB1, 0x184}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB2, 0x183}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB3, 0x306}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND4, 0x19}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND5, 0x6}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB6, 0x306}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB7, 0x306}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB8, 0x306}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB9, 0xc86}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB10, 0x306}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB11, 0x306}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND12, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND13, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND14, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND15, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND16, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND17, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND18, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND19, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND20, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND22, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND23, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND24, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND25, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND26, 0x6}, - {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND27, 0x6}, - {OP_WR, PXP2_REG_PSWRQ_BW_UB28, 0x306}, - {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND29, 0x13}, - {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND30, 0x6}, - {OP_WR, PXP2_REG_PSWRQ_BW_L1, 0x1004}, - {OP_WR, PXP2_REG_PSWRQ_BW_L2, 0x1004}, - {OP_WR, PXP2_REG_PSWRQ_BW_RD, 0x106440}, - {OP_WR, PXP2_REG_PSWRQ_BW_WR, 0x106440}, - {OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1}, - {OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1}, -#define PXP2_COMMON_END 2137 -#define MISC_AEU_COMMON_START 2137 - {OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_0, 0xf0000000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_0, 0xf0000000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_1, 0xf0000000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_1, 0x0}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_1, 0x10000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_1, 0x5014}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0}, - {OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00}, - {OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3}, -#define MISC_AEU_COMMON_END 2156 -#define MISC_AEU_PORT0_START 2156 - {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000}, - {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff55fff}, - {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0, 0xffff}, - {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0x500003e0}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0xf00003e0}, - {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1, 0x0}, - {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_1, 0xa000}, - {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_1, 0x5}, - {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2, 0xfe00000}, - {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x14}, - {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x7}, - {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_4, 0x400}, - {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555}, - {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_5, 0x3}, - {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_5, 0x1000}, - {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_0, 0x0}, - {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_6, 0x3}, - {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_6, 0x4000}, - {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555}, - {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_7, 0x3}, - {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_7, 0x10000}, - {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_0, 0x0}, - {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x4}, - {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0}, - {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3}, - {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7}, -#define MISC_AEU_PORT0_END 2188 -#define MISC_AEU_PORT1_START 2188 - {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000}, - {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff55fff}, - {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0, 0xffff}, - {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0x500003e0}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0xf00003e0}, - {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1, 0x0}, - {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1, 0xa000}, - {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1, 0x5}, - {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2, 0xfe00000}, - {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x14}, - {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x7}, - {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_4, 0x800}, - {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555}, - {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_5, 0x3}, - {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_5, 0x2000}, - {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_1, 0x0}, - {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_6, 0x3}, - {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_1, 0x55540000}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_6, 0x8000}, - {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_1, 0x55555555}, - {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_7, 0x3}, - {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_1, 0x5555}, - {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_7, 0x20000}, - {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_1, 0x0}, - {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x4}, - {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0}, - {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3}, - {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7}, -#define MISC_AEU_PORT1_END 2220 - -}; - -static const u32 init_data_e1[] = { - 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0, - 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440, - 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0, - 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40, - 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0, - 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000, - 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000, - 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000, - 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000, - 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000, - 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000, - 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000, - 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000, - 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000, - 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000, - 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000, - 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000, - 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000, - 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000, - 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000, - 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000, - 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000, - 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000, - 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000, - 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000, - 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000, - 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000, - 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000, - 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000, - 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000, - 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000, - 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000, - 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000, - 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000, - 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000, - 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000, - 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000, - 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000, - 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000, - 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000, - 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000, - 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000, - 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000, - 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000, - 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000, - 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000, - 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000, - 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000, - 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000, - 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000, - 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000, - 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000, - 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000, - 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000, - 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000, - 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000, - 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000, - 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000, - 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000, - 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000, - 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000, - 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000, - 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000, - 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000, - 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000, - 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000, - 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000, - 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000, - 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000, - 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000, - 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000, - 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000, - 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000, - 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000, - 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000, - 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000, - 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000, - 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000, - 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000, - 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000, - 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000, - 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000, - 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000, - 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000, - 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000, - 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000, - 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000, - 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000, - 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000, - 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000, - 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff, - 0x00000200, 0x00000001, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8, 0x00000000, 0x00003500, - 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, - 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, - 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0, 0x00006180, 0x00008240, - 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600, 0x000146c0, - 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40, - 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0, - 0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380, 0x00039440, - 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800, 0x000458c0, - 0x00047980, 0x00049a40, 0x00008000, 0x00010380, 0x00018700, 0x00020a80, - 0x00028e00, 0x00031180, 0x00039500, 0x00041880, 0x00049c00, 0x00051f80, - 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480, - 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980, - 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900, - 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, - 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000, 0x00002080, - 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300, 0x00008380, - 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, - 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900, 0x00014980, - 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, - 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, 0x10000000, - 0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc1, 0xffffffff, - 0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc, 0x00000000, - 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, - 0x00003500, 0x000e01b7, 0x011600d6, 0x0000ffff, 0x00000000, 0x0000ffff, - 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, - 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, - 0x00000000, 0x00100000, 0x00000000, 0x007201bb, 0x012300f3, 0x0000ffff, - 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, - 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, - 0x00000000, 0x0000ffff, 0x00000000, 0x00100000, 0x00000000, 0xfffffff3, - 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, - 0xcdcdcdcd, 0xfffffff1, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, - 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, - 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, - 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, - 0xcdcdcdcd, 0xfffffff5, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, - 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, - 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, - 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, - 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, - 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, - 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, - 0xcdcdcdcd, 0xfffffff3, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, - 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, - 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, - 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, - 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, - 0xcdcdcdcd, 0xffffff97, 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, - 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, - 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, - 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, - 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, - 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, - 0x05cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, - 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x300fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, - 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, - 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, - 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, - 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, - 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, - 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x040fffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, - 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, - 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, - 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, - 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, - 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, - 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, - 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, - 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, - 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, - 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, - 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, - 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, - 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, - 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, - 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, - 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, - 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, - 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, - 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, - 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, - 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, - 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, - 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, - 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, - 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, - 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, - 0xcdcdcdcd, 0x00100000, 0x00070100, 0x00028170, 0x000b8198, 0x00020250, - 0x00010270, 0x000f0280, 0x00010370, 0x00080000, 0x00080080, 0x00028100, - 0x000b8128, 0x000201e0, 0x00010200, 0x00070210, 0x00020280, 0x000f0000, - 0x000800f0, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000b8280, - 0x00080338, 0x00100000, 0x00080100, 0x00028180, 0x000b81a8, 0x00020260, - 0x00018280, 0x000e8298, 0x00080380, 0x00028000, 0x000b8028, 0x000200e0, - 0x00010100, 0x00008110, 0x00000118, 0xcccccccc, 0xcccccccc, 0xcccccccc, - 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, - 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000 -}; - -static const u32 init_data_e1h[] = { - 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0, - 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440, - 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0, - 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40, - 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0, - 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000, - 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000, - 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000, - 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000, - 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000, - 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000, - 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000, - 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000, - 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000, - 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000, - 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000, - 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000, - 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000, - 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000, - 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000, - 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000, - 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000, - 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000, - 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000, - 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000, - 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000, - 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000, - 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000, - 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000, - 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000, - 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000, - 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000, - 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000, - 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000, - 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000, - 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000, - 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000, - 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000, - 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000, - 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000, - 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000, - 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000, - 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000, - 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000, - 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000, - 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000, - 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000, - 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000, - 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000, - 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000, - 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000, - 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000, - 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000, - 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000, - 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000, - 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000, - 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000, - 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000, - 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000, - 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000, - 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000, - 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000, - 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000, - 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000, - 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000, - 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000, - 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000, - 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000, - 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000, - 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000, - 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000, - 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000, - 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000, - 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000, - 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000, - 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000, - 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000, - 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000, - 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000, - 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000, - 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000, - 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000, - 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000, - 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000, - 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000, - 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000, - 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000, - 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000, - 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000, - 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000, - 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff, - 0x00000200, 0x00000001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8, - 0x00000000, 0x00003500, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, - 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, - 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, - 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, - 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, - 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, - 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, - 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, - 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, - 0x00002000, 0x000040c0, 0x00006180, 0x00008240, 0x0000a300, 0x0000c3c0, - 0x0000e480, 0x00010540, 0x00012600, 0x000146c0, 0x00016780, 0x00018840, - 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40, 0x00022c00, 0x00024cc0, - 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0, 0x0002f080, 0x00031140, - 0x00033200, 0x000352c0, 0x00037380, 0x00039440, 0x0003b500, 0x0003d5c0, - 0x0003f680, 0x00041740, 0x00043800, 0x000458c0, 0x00047980, 0x00049a40, - 0x00008000, 0x00010380, 0x00018700, 0x00020a80, 0x00028e00, 0x00031180, - 0x00039500, 0x00041880, 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680, - 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80, - 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080, - 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900, 0x00000028, 0x00100000, - 0x00000000, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, - 0x00007ff8, 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000, - 0x00002080, 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300, - 0x00008380, 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, - 0x0000e680, 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900, - 0x00014980, 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, - 0x0001ac80, 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, - 0x10000000, 0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc5, - 0xffffffff, 0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc, - 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, - 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, - 0xcccc0201, 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, - 0x00000000, 0x00007ff8, 0x00000000, 0x00003500, 0x000e0232, 0x011600d6, - 0x00100000, 0x00000000, 0x00720236, 0x012300f3, 0x00100000, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, - 0x0000ffff, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x30efffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, - 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, - 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, - 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x302fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, - 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, - 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, - 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, - 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x31efffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, - 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, - 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, - 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x056fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, - 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, - 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, - 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, - 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, - 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, - 0xfffffff3, 0x316fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x302fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, - 0xfffffff6, 0x30bfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf314, 0xf3cf3cf3, - 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, - 0xfffffff7, 0x31cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, - 0x0020cf3c, 0xcdcdcdcd, 0xfffffff0, 0x307fffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, - 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, - 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, - 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, - 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, - 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, - 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, - 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, - 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, - 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, - 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, - 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, - 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, - 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, - 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, - 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, - 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, - 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, - 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000, 0x00070100, - 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280, 0x00010370, - 0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0, 0x00010200, - 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170, 0x000b8198, - 0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000, 0x00080100, - 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298, 0x00080380, - 0x000b0000, 0x000100b0, 0x000280c0, 0x000580e8, 0x00020140, 0x00010160, - 0x000e0170, 0x00038250, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, - 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000, - 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x04002000 -}; - -static const u32 tsem_int_table_data_e1[] = { - 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x19d9458a, 0x1138fc18, - 0x5980a1fc, 0xd8181998, 0x88039880, 0x81b8803d, 0x91a18191, 0xdafd7891, - 0xbf760862, 0x6ec30330, 0x0211e620, 0x1082239a, 0xf354029f, 0x0f5fc806, - 0x6512b315, 0x3a263860, 0x06a77ef0, 0x298d2ade, 0xc1124536, 0x1e4586de, - 0x93476f19, 0xca8922ff, 0xff4041df, 0x65296340, 0x229dbe54, 0x04a65e84, - 0xe4d1a5a1, 0xd7f2a1ed, 0x5192fea1, 0x0dee6ec6, 0xf8003ca8, 0x6065495c, - 0x00606549 -}; - -static const u32 tsem_pram_data_e1[] = { - 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x49999cce, - 0x424e4cce, 0x4c22f212, 0x21a08812, 0x8a80af0c, 0x2201277f, 0x282039f5, - 0x4201d458, 0xd4837908, 0xcdedaf4b, 0x11102484, 0x0547f435, 0x5088768b, - 0x340da2d1, 0x0ec160d2, 0x6d7b1420, 0xc0faf06f, 0x480bf5ea, 0xb12f3141, - 0xcbc57e20, 0xe7dad6bf, 0x264ce664, 0xafdbd880, 0xb4fdffff, 0xece7d9b8, - 0xebdaf7b3, 0x7b5ad7b5, 0x75923ded, 0xc7bf9302, 0x03fc45d8, 0x8c4d4fe5, - 0xf2c109b1, 0x80f66667, 0xc9b18727, 0x473afebd, 0x6d55633c, 0x9da23b19, - 0x99ec258c, 0x50281421, 0x2c23d5fe, 0xbfdf8250, 0xf097c365, 0x4219b6ff, - 0xd0977c3e, 0xc3e611e9, 0x02d5e4fb, 0x933a876b, 0xea0c319c, 0x4b19b98c, - 0x126b2c64, 0x4b223fa3, 0xe0ff828d, 0x8f392573, 0x27fc34b1, 0x61467574, - 0xc678c0ae, 0x5c531e32, 0x38a9d0d4, 0x843f7815, 0xbcd2c67f, 0x0731b725, - 0xbc03cf63, 0xbcf071c9, 0x61de3a5a, 0xc22eefe5, 0x3af3a1df, 0xae58cd6a, - 0x32773e30, 0x416589a7, 0xf3e33ebf, 0x3d6346ac, 0x4fe3d99b, 0xec3fc346, - 0x8c517ecc, 0xb1138f30, 0xcb3c018c, 0x632f0e54, 0x5467b2bd, 0x6a9b1f10, - 0x2c32a258, 0x852f0f58, 0x56338765, 0xed975e03, 0xf8165c16, 0x2f6c39fe, - 0xbed7e631, 0x15ead66b, 0xa362593e, 0xb50404a1, 0x67eff4e4, 0x11bfcb11, - 0x2b30fef1, 0xea4ab2a0, 0xaf805595, 0xfb765aaa, 0x67edfe95, 0x54e88933, - 0x5bf6b929, 0x5adefc61, 0xf1866ae6, 0x02d59997, 0x91fb2fac, 0x7a83e5d3, - 0x21476366, 0x36d0fa83, 0xc1198981, 0x9e00afef, 0x007f91db, 0xa52b2a1e, - 0x740642de, 0xb02bddec, 0x871c0ce6, 0x776cbbf7, 0x0c65f306, 0x6658e70c, - 0x32e73826, 0x74893a41, 0xd2073071, 0xf324bcc1, 0xcea84289, 0xb0f3dc54, - 0x9de29f7f, 0xe7f4ed87, 0x38e60b49, 0xf25700bd, 0x57a06650, 0x9d3ab5b1, - 0xea563265, 0xbe442969, 0x8decb538, 0x9e025855, 0xf7c02413, 0x08a78b7c, - 0x5798a9fb, 0xa780cd9d, 0x8d1859e6, 0xff2db43f, 0x0cf80933, 0xc4c5f3ba, - 0x76313f21, 0xf04f843c, 0x5a11f1cf, 0xde981c5d, 0xb08b2b97, 0x05f1091f, - 0x1f011772, 0x26a0423f, 0x544d28e0, 0x29fc573a, 0xd0a0d86b, 0xc3595bfa, - 0xe50069c6, 0x3f0cbc11, 0x0843ac61, 0x1cbd4be5, 0xb0ff3bba, 0x3c303b94, - 0x04f3d3ff, 0xab7e1274, 0x1fc8b700, 0xbfd97615, 0xca61f812, 0xf7c0e6ab, - 0x362a3f80, 0xd40b7e0b, 0xe8dbaf4d, 0x5e26f77d, 0x3765d80f, 0x16d74ff2, - 0xbdf00ba8, 0x1bf1fda5, 0x155ebf91, 0x3b763359, 0xfa84ca22, 0x3b06a4e5, - 0xc0750f1b, 0x578db147, 0xbbef362b, 0x692fbf1f, 0xf41b30b3, 0xf17bb157, - 0x7d42371d, 0xc33361f1, 0x6b5b1526, 0x2fa814e5, 0x582d0bf1, 0xf0e029ef, - 0xfe8976f9, 0xc7bed0ad, 0x1b389ed1, 0xc6ba73e8, 0x63329cca, 0xc4f6f675, - 0xa567c059, 0xf8851dfe, 0xc176e95d, 0xf29f6885, 0xc943d6ea, 0xb917af38, - 0x8b6d977c, 0x7f1d4e66, 0xab64f7f0, 0xbc1ef818, 0x64f3065f, 0xd662efd0, - 0xb07a8854, 0xd93aeb62, 0xebe20f69, 0xe34a8d74, 0x8bdfc9f4, 0x577c0e30, - 0xc2e08af9, 0x989a5629, 0x7bb0e517, 0xf3ce6db7, 0x56afce0a, 0xbce3b6ce, - 0x6ed8cb56, 0x2efe7fb1, 0xfea5cd54, 0xbc2172cd, 0x59b4dd2f, 0xdb910e2e, - 0x8c836db2, 0x1ac86d70, 0xd7208dec, 0xd7807841, 0x52f583b2, 0x0fa803d4, - 0x233cbf25, 0x852acf84, 0xb2cbe258, 0x1a73226d, 0xddd388f8, 0x13fc2ef7, - 0x6bdbe5f0, 0x74eabc27, 0x1aa7d3eb, 0x1aa8cedd, 0xbcdea51d, 0xf8f81119, - 0xc003a471, 0x827884d3, 0x9f06ad72, 0x97cb3263, 0x9b877fa0, 0x3cbb02a9, - 0xd999365f, 0xf563067c, 0xd2dd07b0, 0xd99750f5, 0xf582e652, 0x7bb1fa50, - 0x0493d42a, 0x9f3867ef, 0xc25bc17a, 0x2496abd7, 0x9579e00f, 0xfce0e6c0, - 0x30d0218f, 0xc0c955af, 0xa6f7809f, 0x8bcf7969, 0x3c7b0682, 0xb17f8bd6, - 0x39fa8326, 0xa198fd43, 0xf7cbac9f, 0x324e16a3, 0x9616a3f4, 0x8dfcfde8, - 0x595db1fa, 0x37854d3f, 0x2c29e118, 0x0491fbd5, 0xbf6f5768, 0x37a979b2, - 0x73c2364f, 0x13f53973, 0xbcc5d53b, 0x1ae7ae0a, 0xb776b03f, 0xed95ef08, - 0xb0d763b1, 0x5028be50, 0x0edb8005, 0x17ca1252, 0x0ca29331, 0x8eeb187c, - 0x27a1d433, 0x4175e4f5, 0x958813fd, 0x45397c69, 0x9f90bd26, 0x43faa562, - 0x85e90a29, 0x5ef06e87, 0x8e20eb83, 0x2ea192cd, 0x11ab477b, 0x14e01af8, - 0x60961258, 0x7ff52417, 0xf1ccdabf, 0x217a9050, 0x5f7c18fb, 0x8ecdea65, - 0xa635fa85, 0x6f116bfc, 0xe5eb812e, 0x63559128, 0x230b28bb, 0x233ab4fd, - 0x085f79ef, 0x00871a9e, 0xbf6085fd, 0x126f668d, 0xdaf8d7f2, 0xc0127c67, - 0xcc086ab7, 0x12ba0527, 0x60f8099e, 0xa43d5a3d, 0x69f10938, 0x43be4191, - 0xfc6197c7, 0x06ff1a1c, 0xc71ba3c4, 0xbe3fe84f, 0x61927325, 0x897a6b7c, - 0x0cab7c61, 0x4fbf03e3, 0xc6d66dad, 0xc0ddfc07, 0x99a134d8, 0x97a4b7c6, - 0x65abf8d0, 0x3f186256, 0x5bfc6faa, 0x819efe70, 0x83799fe6, 0xa5e9fe71, - 0x7ccbf9c6, 0x5f6ab3fe, 0xa28fc6d2, 0x5e16cff9, 0x2f4ff3e2, 0xf0b7f3e5, - 0x77c6fb7e, 0x5effe1f4, 0x8077bf9c, 0x93592df1, 0x5a1ff38d, 0x85bf9c6e, - 0xbb545f8f, 0xa15f1b53, 0x3b0917f1, 0x9687fcf9, 0xc5b2f8d3, 0x923e42eb, - 0xfdaaa353, 0x81a44f68, 0x1d260c40, 0x0472a6e5, 0x1fa00518, 0x04990a86, - 0x9c5143c7, 0x0145ceef, 0x7d4129bf, 0x5120fcc7, 0x352acfa0, 0x9edb2f9e, - 0xa59ea32f, 0x376889f7, 0x6d453ff1, 0x6c37ad22, 0x1c3fc5bd, 0x136eede0, - 0x5a2f587d, 0xa45f937f, 0xe5db8ef5, 0xf005c660, 0x1c9e5ff9, 0xaf3a1cd5, - 0x935172f0, 0x418764f9, 0xbe3c388e, 0x1aa23602, 0x26476be0, 0x9fac1098, - 0xc60a3d04, 0x7a0e3b2f, 0x6653cb14, 0x009c8f6e, 0x50e4cb3d, 0xf6e5a9b9, - 0x93bd8f88, 0x5bbaf303, 0xc4a4ff83, 0xb9727df1, 0x9ffc47e0, 0x4654b75b, - 0x09a8b4fd, 0x7910e98c, 0xd4e8d2af, 0x6fe2dbbb, 0x4e9f0816, 0x243dcfc4, - 0x97fd8c8a, 0xde2fd766, 0xddf0c830, 0x486fe63c, 0xd70bf682, 0xc2a21fce, - 0xc7307ffc, 0x53ed1632, 0x13548490, 0x354b31c9, 0xa7316f81, 0x15399d75, - 0x31ccf72a, 0xb9faec1b, 0x07fd635e, 0xb77ac625, 0xa1366fd9, 0x6044b1bd, - 0xfbdfa19b, 0xf5ef8daa, 0x71093671, 0x78daae9c, 0x78722777, 0x2c72c3ef, - 0xae89563e, 0x5bfcabf7, 0x87aa9e1d, 0xeb402ccd, 0x43024765, 0xc812fa3a, - 0x7caaf35e, 0xdef0e1de, 0x3dbab66f, 0x3ffdcf00, 0xe19f0912, 0x1ebc77f0, - 0x1d8136ed, 0x4be1b1d7, 0xe1b7da33, 0xff8709f3, 0xf3e11581, 0xf7d46551, - 0xcfe17df3, 0xf3849f39, 0xfe5b5553, 0xed2113a0, 0x3fbe5a2a, 0x7f0844e8, - 0x619b6d95, 0xcff12fa8, 0xbc5fb435, 0xfde1be61, 0x8625a6a2, 0x971b0bf7, - 0x7df3ea1a, 0x7fb4323f, 0xe1ad4560, 0x8fd57dfd, 0xa0ffde18, 0x3ea19d64, - 0xd0d1bbd7, 0x9b399efe, 0xaf4def0d, 0xe513bc8f, 0x915deea8, 0x5671bae1, - 0xda38f939, 0xc9156783, 0xb4f8f485, 0xe0e48926, 0xca938d74, 0x5671b6ee, - 0xc583d72f, 0x5e9c4c0c, 0x71af9ce1, 0x4665ea32, 0xc2aff3fa, 0xea0f9f05, - 0x849c137f, 0xcc83713f, 0x02c2c002, 0xe3e3eb8b, 0x7de4315e, 0x6fde65c7, - 0xd71f4100, 0x11d8bdff, 0xf35579f9, 0x046aa1fc, 0xb72821ff, 0xb9d7152c, - 0x0f7d6d1e, 0x302e5f7f, 0xc673e84f, 0xd79c9256, 0xb94ceb69, 0xf941f5cc, - 0xf402e4ce, 0x40e5cbbf, 0xc6a5f576, 0xa2a4016b, 0x3ceb449e, 0xa401f901, - 0x592fc0c0, 0xdceef906, 0x955c1227, 0xaf4013a8, 0xc19e63ae, 0x8133d426, - 0x8d77e903, 0x49dc3842, 0xa04b6f54, 0x66b3bd75, 0x1213a0fa, 0xe543c7d2, - 0xa87335a7, 0xa5e3593c, 0x094d44f2, 0xaa6bc795, 0x59a8eca9, 0x35c7e541, - 0xaa3f2a3e, 0xcff2a469, 0x1e544d35, 0xe540d9ad, 0x2a7e357b, 0x54dc6bbb, - 0xba2bf9f6, 0xecd78dfe, 0x80afcd55, 0x67ea8795, 0x43d4b9b4, 0x739276db, - 0xf9ca1257, 0x365ce519, 0x8e67e3da, 0x31996382, 0xf9c2be30, 0xba3a606d, - 0xf6295ec9, 0xf5c7fd03, 0xe28b6f7f, 0xd899b274, 0xd9a67074, 0xe17fc323, - 0x7543905a, 0x16065909, 0x7b0cd724, 0xed617e84, 0x8e5d7a43, 0x9bddcc4e, - 0x71e8133b, 0xe5bf99f2, 0xda75bf61, 0x407517fa, 0x059875a4, 0xbd21779e, - 0xeb46f042, 0x9aabef5a, 0xfe0cbfbe, 0xd7f0faba, 0xfbfe8e9e, 0xfea54141, - 0x985ab4cf, 0x13dc7884, 0x67e607ed, 0xef3f0e67, 0x965c7940, 0x444f5264, - 0x565e83c0, 0x4aa864b4, 0x66d3fae8, 0x12699fac, 0x7ad0b7a6, 0x35998cec, - 0x554af90a, 0xfa430c4f, 0xf7a95127, 0x56492cb3, 0x9ebc804f, 0xc31596de, - 0x5f3f6fd7, 0x12c7b707, 0x485f82bf, 0xf0deffed, 0x0e8fd40c, 0xecad630f, - 0x03ea2b13, 0xedf59778, 0xfd2672fd, 0x6c57e295, 0xda1cf98f, 0x7bf8160b, - 0x1207e291, 0xab7ef5d5, 0x659f445a, 0x6edf3e34, 0x73be0f18, 0xc5f73eea, - 0xadf14bcc, 0xc4864ec4, 0xf169d611, 0x366db2c6, 0xc4aeb8d5, 0x6d55ea1a, - 0x9d61aac9, 0xfc807fc1, 0x42416ab3, 0xb8d729be, 0x1a5247a8, 0xdcaf8005, - 0xab7ea4e4, 0xc2aede04, 0xe17b21da, 0xa72b5751, 0x9df040db, 0x94ec39ae, - 0xac4bde40, 0x7c0201e0, 0xa7232d25, 0x6aeb9ea2, 0x7b444bad, 0xf33c4cb0, - 0xf7c22790, 0x8d024d3b, 0xee6fc4b7, 0x1aa3ae35, 0x57e8307f, 0x167e4e7f, - 0xd4864e53, 0xcedc4d3b, 0x80f7ef0e, 0xf0e5efd6, 0x48fdb953, 0xfece8de1, - 0xfb6caa78, 0x1c92f642, 0x82f2ffc1, 0x57f1d278, 0x401cf26e, 0xedba5a7d, - 0x9fa3d918, 0x0fd97d9a, 0xf53f425f, 0x44929f9f, 0x5e7d5271, 0x6129303e, - 0x7c5a059c, 0x9ef7f817, 0xfd3d610f, 0x6ccddfec, 0x2ec7c00d, 0x6f782b40, - 0x13335fd6, 0xa17d4133, 0x5ad05b56, 0xcfdd7146, 0x2a8edc4c, 0xd1071e62, - 0xa1e53581, 0x4cc5d91d, 0x5d4f11d3, 0xb8c76dec, 0x329c3a10, 0x1667a4c9, - 0x18ed1a36, 0xf50d7fb0, 0xf58c1bc5, 0x11333662, 0x7af149f5, 0x340bf333, - 0xf7fbc33f, 0x7fe12a4d, 0x855eab31, 0xf9a4aaeb, 0x26540b23, 0x157c02a5, - 0x6f3679bf, 0x4c5fc63e, 0xe3d10fdc, 0x38e24b23, 0x7ef1a5fc, 0x3fef0dd9, - 0xf7771d69, 0x8b06488d, 0x89c6157f, 0x6d730c58, 0xfbf1fd65, 0x870fe16d, - 0xfbaf5f57, 0x383469c5, 0xdb826dc4, 0x2f7f811f, 0xeba67c68, 0xd5445beb, - 0x8ddc17e0, 0x21bf10f5, 0xb2e2d446, 0xee911322, 0x67d5aa5d, 0x14f7a18a, - 0xb4edf7b7, 0xde80eab8, 0x0679373f, 0x4ec81389, 0xed2165c8, 0xd2f26e7e, - 0xade14ef3, 0x995bb462, 0x3b45c814, 0xe218d614, 0x07e35953, 0x8b91ca31, - 0x833b66f1, 0x6fe81475, 0x9fa0f841, 0xdb92f655, 0xbbc62e58, 0xbfa1de41, - 0x87851cc7, 0x94dba805, 0x59fd8656, 0x7cf18c92, 0xaf58d39b, 0x1d207fc2, - 0x3f8a3046, 0xc2908f45, 0xa86018f0, 0xe32eed0f, 0x84e851f3, 0x201fdd91, - 0x8b10763e, 0x02556943, 0x26cf8c22, 0xfe7d9d49, 0x7bfa2656, 0x2f8a7e1c, - 0x2ae5fb40, 0xc5a95f6f, 0x507f97cf, 0x12ee3830, 0x3ceaa8fa, 0x21419068, - 0x7fbe3d75, 0x71fe625e, 0x3a6f41df, 0xd10d5561, 0xde4d739b, 0xd40f4869, - 0x009f0893, 0x760d78e3, 0x2a1a9a60, 0xf8c20be7, 0x88e1aae3, 0x5dfd0667, - 0x2ddef26e, 0xe387f426, 0xea4ffbaa, 0x4882ffd7, 0xfeeabcf3, 0xbfebf587, - 0x15ff5232, 0x977979bf, 0xf4a9f80f, 0x803a4f57, 0x5267d999, 0xe80ba253, - 0xc1b5be5e, 0xa9f97281, 0x5d2073e4, 0xd38bf33f, 0x16e7c923, 0xb74f9751, - 0xff11e422, 0x7e9d1f10, 0xd03bd1e9, 0xd5b73aae, 0x607c52ac, 0x0160259b, - 0x5d6caca6, 0x9b63e5c2, 0xafaf18e5, 0xb3f902fe, 0x2fa8cdaa, 0x32785f4a, - 0x40cde311, 0x0e7fcd49, 0xb9507f90, 0x68852fe5, 0x5eb15577, 0xdfe17bd2, - 0xe3e7f8e1, 0x2f981ec8, 0xaf7ff4c7, 0x6955f3ef, 0x7d6aa978, 0x84910bf4, - 0xcdfc83a5, 0x9a25f6f0, 0x68a4ffbd, 0xdf38a78f, 0xf9113644, 0xf307c74c, - 0xeebf7b73, 0x8f73a7c5, 0x5b9d3c01, 0xe421ddfe, 0xd727f284, 0x165a677b, - 0xe735fcfe, 0x0dd4f2c0, 0xaed4317a, 0x6767d7d6, 0xeca7e69b, 0x39b965e1, - 0xb03f40e0, 0xe5d9b37c, 0xfcbeba43, 0xc19e2ffc, 0x1607ccb8, 0xbfe870d7, - 0xef83e5ec, 0xb2f500dd, 0xdbf8e61d, 0x211434f8, 0x2a974831, 0x6c62bbf8, - 0xbfa50e90, 0x473b283e, 0x8e3fe7f1, 0x6ca3d20b, 0x8d993ec7, 0x298f8fea, - 0x0ee4fb2d, 0x5a5d0225, 0x3fa2158e, 0x57e2f751, 0xcfafea32, 0xe0d8175e, - 0xdcf8088c, 0x62ec907c, 0x51d113c4, 0xdd1f53a3, 0x0157dac2, 0xeabf505d, - 0xff7f0a74, 0xc7fe9a2f, 0xc4399cfe, 0x86bcafcf, 0xb67f28fb, 0x25fe70b8, - 0xc0e83caf, 0xaa929c79, 0xdb3f5f39, 0x7186e890, 0x44becc4b, 0xbcfe4a95, - 0x121fb9e4, 0xf23e2dbf, 0x7f8a44c3, 0x89b27730, 0x325f056c, 0xa6d16fce, - 0x62bf34d9, 0x2bbe25e6, 0xe0f45679, 0x8959e0fe, 0x4111df4d, 0xae24522e, - 0x5b354f8f, 0xa7654d70, 0x7dc0e170, 0xff45b785, 0x2dff8a56, 0x0fcaf8a5, - 0xb620fdf5, 0xad67ea8c, 0x885f4e9c, 0xac1abefa, 0xbafca13c, 0xd23b7565, - 0xf710f4e7, 0x571b8c60, 0xe1a7c931, 0xfd08b843, 0x0da6478a, 0x4e61f4e6, - 0x0efb4f29, 0x7c14fdf4, 0xcddbed8e, 0xe1ae5b6e, 0x2331763b, 0x6d72fe38, - 0x0a3b807c, 0x8953d5ed, 0x9845ff60, 0xafa4a15f, 0x85576037, 0x7c8857f0, - 0xf2df7973, 0x5d6f9708, 0xa633fdde, 0xbebffbe3, 0xbf07e5c3, 0xe0057b43, - 0xf7a60c0a, 0xa40966fb, 0x102c2c0f, 0x98b7ae49, 0xbe36b935, 0xe004f9d7, - 0xeddd7096, 0x3fec17e3, 0x764ff08e, 0xf87af16c, 0x565f442e, 0xfe8e78e1, - 0xbb72e9fd, 0x04ff9358, 0x6cff28c9, 0x81fb9713, 0x8f1f09fd, 0xbffd984b, - 0x15e50678, 0xaff713e4, 0x7b365fcb, 0x6f9fde70, 0xbddef03f, 0xb79fa720, - 0xd46a72e8, 0x5a72e19f, 0x8b0273b2, 0x639fa724, 0x3924421a, 0xe511e785, - 0x3e20e954, 0x4fe947fe, 0x85377f1d, 0x87d74fe1, 0x5c31e103, 0x7459fe1f, - 0xf087d446, 0xd7961de7, 0xbe74ff9f, 0xf4adf9d3, 0x29431597, 0xa5f3a63e, - 0x7c7d77ce, 0xbf5df3a9, 0x7f01a378, 0x182defe1, 0x3cb80183, 0x4714cdbb, - 0xf7c3df28, 0x43bbe17f, 0x4f09e3a9, 0x58c65a6e, 0xf8d4a1d3, 0xac3fbad0, - 0xded612de, 0x84f7561d, 0xd586f7b5, 0xcbed0dab, 0x3cc80edb, 0x686025af, - 0x8678ae27, 0x1228327d, 0x5fb9fabf, 0xec85fada, 0x7a50be43, 0x4af37be9, - 0x3c63b3e6, 0xf148af7c, 0xf1c01e91, 0x67a7182a, 0xf31f867b, 0x3c6c1a24, - 0xf6a3d4ee, 0x6c5ed03a, 0xdef5e588, 0xea157904, 0xaf79fd3d, 0x7af5c78d, - 0xd88ebd3c, 0xd8edfb10, 0x76f4911e, 0x8f4d9f87, 0x8ac267e4, 0xc1d47242, - 0xe3cf7a06, 0x2544d3fd, 0x5fc6057d, 0x8617449a, 0xef6a8a74, 0x419e6071, - 0x3bac9ecf, 0x45f3c0e7, 0x8db48a6f, 0x7b7683d8, 0x2dc7920c, 0x77f88725, - 0x53df329f, 0xbf7e3193, 0x4579fb87, 0x11ecc36b, 0xa9f896b6, 0xa32e5958, - 0xecbf053e, 0x82ff71b8, 0xd6a945cb, 0xe326c95f, 0xdc7bfd7b, 0xbdfb45c1, - 0xbdf18b74, 0x34078b57, 0x863272eb, 0x71fcd18d, 0xf4d28f1e, 0xe73134f2, - 0x8f4039ce, 0xc322c39e, 0x7b33fbfd, 0x99c7a244, 0x9ebf7ced, 0x23d7f6e2, - 0x3e92f77f, 0x89d4f1d4, 0xac0f24f2, 0xfd5f3aaf, 0x9187bcaf, 0x987d766f, - 0x3b2833fb, 0xfd907d77, 0xe6ffac5b, 0x590ff4fd, 0x5e53f6ff, 0x493ed1b7, - 0xe276ebcf, 0x7fbd9ef7, 0xeb187f4c, 0x9f142dbb, 0xabfd79ee, 0x9e9fe45c, - 0xd4129695, 0x80433d77, 0xec1f68fe, 0x83b72afd, 0xa27ad7d6, 0x99251fdb, - 0xfe7b47db, 0x8f10b1f6, 0xed0acc25, 0x49a3d786, 0xb35eaa9e, 0x67ad3c51, - 0xa17957ef, 0x9d77ff76, 0x7fb6a54f, 0x736763d9, 0xb17c2276, 0xeaa7df7c, - 0x5f3fd7b7, 0xad17f98b, 0xf085e4fb, 0xbeefca7e, 0xda3d45c9, 0x43db93b3, - 0xe78ee6dd, 0x68ee7f70, 0x6695dcfd, 0x0a3773c0, 0x9bac0a55, 0xa014cf0d, - 0xcbc7f4dc, 0xbc271437, 0xfcf47c52, 0xc10f835f, 0xdd9df5cd, 0xde70156f, - 0x21fc7f5f, 0x2dd785ea, 0x7cfa97c4, 0x25a96f3f, 0xf372e57b, 0x9c799876, - 0x799dffe4, 0x992b810b, 0x3ff328f7, 0x2d7fbd37, 0xe12e8939, 0xcf9fd072, - 0xf5443ef7, 0x822eed97, 0xfdf90af7, 0xf9f27ff6, 0xefba6b7f, 0x2e3bba04, - 0x7ff2ef3f, 0x4c0f79f2, 0xd7ef37f7, 0x7e62aee8, 0xbeefd54b, 0xadbef821, - 0x4ffb5b9e, 0xcd03ef2e, 0xd7ebb75f, 0x994d5c98, 0xaf439f18, 0xc569d601, - 0xc311b33e, 0xcc466b85, 0x14ced154, 0xf52bf6c3, 0xfb99af72, 0x5bee224d, - 0x086f9c62, 0xcd31f38f, 0x3d2da28f, 0x8a525a18, 0x94958ec9, 0x96bedc55, - 0xc06eed5c, 0x176b9acb, 0x887728b8, 0xc5ea3d8d, 0x1764da7a, 0xfcc3afc5, - 0xb9817ac9, 0xa56fb005, 0x8c396f6b, 0x84798dfe, 0xa5c96029, 0xab9618f2, - 0x59a4b8b5, 0x8f7e0d95, 0xdbac6392, 0x45bac69c, 0x38cacfeb, 0xe624d6fc, - 0x38b4f8c7, 0x798abf72, 0x8918e26d, 0xb1b75009, 0x17fa1f26, 0xf7e32496, - 0x1ec0311b, 0x5abdcf12, 0xe1f6f63c, 0x1bbb6c71, 0x44d238f1, 0x2e4a6b71, - 0xfcb8bc25, 0x8d9e786b, 0x55d788d5, 0x094f88ed, 0x7f6e5ffd, 0x34ccdf91, - 0xbad2597f, 0xdc984690, 0xcd3b6336, 0x9d2cbe4f, 0xcbd25d38, 0x332d3a35, - 0x43a745d0, 0xe818fa04, 0xdbf9e3a2, 0x2e9c27d2, 0x6fdff8e1, 0x07fe1276, - 0x974e97a2, 0x50cdc534, 0xbf9acd5e, 0x49fd1530, 0x1879a7ac, 0xfe6b33ed, - 0x66ef1482, 0xea93a43e, 0xf42f4862, 0xb7e002db, 0xf3fb7efd, 0x7aea2714, - 0x081dd8e9, 0x456fd94f, 0x75fc0566, 0x00b3b76f, 0x65f92f7e, 0x5b4b43f4, - 0x33fb8a45, 0x57779029, 0x6eafbec8, 0xcafd97f7, 0xdd29f34e, 0x06dff169, - 0xfaee97df, 0xb0ec9724, 0xd7e4bd95, 0x38125ef8, 0xb91d7ddd, 0x2a5bafb8, - 0x9c23ff71, 0x9e65625f, 0x3bb9d027, 0x6dc60e7a, 0xdf3c6d84, 0x1ee5b4b6, - 0x7f90c5b3, 0x91dbd666, 0x28bdf05e, 0xc213be50, 0xa9e79a17, 0x2f9d1dfb, - 0x36be1c0a, 0x76f31fb3, 0xe8edb74b, 0xe953f8c6, 0xc30b8b51, 0xbedb55d2, - 0x298dfda0, 0xd1d97abf, 0x68b6fe41, 0xf3f43f88, 0xc489b7fb, 0x15ad951f, - 0x9d4087e4, 0x25b2a2f8, 0x72ebfc72, 0xafd969fe, 0x01f2eef6, 0xfd7ecb0a, - 0x5be30382, 0x3ab7dba7, 0x76dfffc8, 0x3f5bb8e9, 0x91e5bf3f, 0xa7f9fa4b, - 0xbfe01ff1, 0xc58720dc, 0x220db649, 0xcbe0047f, 0xadef948b, 0xcbd95bf3, - 0x38c39f67, 0xcfcee774, 0xcb78439f, 0xe7cbfbff, 0xaf609fd0, 0x88add4db, - 0xa5de9797, 0xddfe9e38, 0x9dc7992c, 0x817c5fbb, 0x1fdd9fe2, 0x7f01df80, - 0x4a9ef7ba, 0x7bb27f47, 0x1889d7c7, 0x77be592f, 0xef9c60da, 0x0ca757f2, - 0x88f41166, 0xfadf225e, 0x1afe20af, 0xad03af4e, 0xe9efc807, 0xdfa37a02, - 0x69b717d9, 0x3071e0a9, 0xd9af16a7, 0xddce391e, 0x7ad33e2f, 0x8d379dd7, - 0x72ecd2c7, 0xd3882bb2, 0x1c7403bc, 0xdbf4057d, 0x7fe688fe, 0x175fa646, - 0xb4e803fe, 0x677e8c2c, 0xfcfd175b, 0x3ad77c19, 0x4d38c068, 0xa6f00ae0, - 0x27bfd1c7, 0xa3227fbb, 0x25fced7c, 0x6e90c5c5, 0xbb44c1b7, 0x8e9b3e5f, - 0x9a9f0ffb, 0xe7e7ef7b, 0xc62a2c32, 0xbef74a1b, 0xfdd3f24f, 0x538a11ea, - 0xdd9e2d33, 0xf0fefacd, 0x5396a3f8, 0xcec5b559, 0xfe1a3be3, 0x74e3fe31, - 0xce2d73d0, 0x8f58f9c3, 0xf7140cff, 0xde799569, 0xafdf1e88, 0x16a1f2d8, - 0x4bd2094f, 0x3a748498, 0x08fdc976, 0xe22a0f1d, 0x1c686261, 0xad7c7233, - 0xd1adde2f, 0xf187e90b, 0x2538becb, 0x6e30d3d4, 0x67de17e5, 0xf741f411, - 0xecff1e66, 0xa3ce4736, 0xbf9ae3d2, 0xff53970a, 0x2f33c595, 0xc5b7ff07, - 0x52765f8f, 0xea78e1bf, 0x8f5910bc, 0x75f32dbf, 0xc5f7aaff, 0xbe4305ca, - 0x7bc9b941, 0xa2b1f904, 0xcfcc98f5, 0x52f3f0a5, 0xb53b7cfa, 0x97ced1bc, - 0xad778a44, 0x7a40396a, 0xe85f5c3c, 0xf0e1a6fb, 0xade0d09e, 0x44ebe36c, - 0x5fbb4ee7, 0xf73a7e81, 0xae7e26ef, 0xe28c7edc, 0xfdb6876d, 0x5908ee5a, - 0xf09d7157, 0xf9dfc087, 0x1e5cbeca, 0xec79e5b7, 0xd19ce3e1, 0x9ed561f4, - 0x6d54e3c8, 0x4e30c2ff, 0xe645af99, 0xc7a5fdeb, 0xefb92d3b, 0xb74efec1, - 0x79e6199b, 0xa7116e9e, 0xf5173a47, 0xea6eb6ae, 0xbd707ee7, 0x23fd7ca4, - 0xf8cc5cfc, 0x1f28a3b7, 0xe991f97e, 0x63c4c61f, 0xfe878409, 0x9f396b5a, - 0x9dc4feb6, 0x3d6ef48a, 0xeb88af72, 0x6fc42ed4, 0xf79f9d88, 0x3b14f54e, - 0x8fbc85e8, 0x5d91e33c, 0xc4cdf5c3, 0xfc0326a3, 0x5c60ce30, 0x1fa1ea07, - 0xf982a73c, 0xe88f086e, 0xf08e9c28, 0xb549aa88, 0x61e7fd09, 0x5e743c56, - 0xacd7ef40, 0xb003cf1a, 0xd89ce30b, 0x1e4cd24f, 0x8bbe4c47, 0x3cfd3e97, - 0xbf94714e, 0xa059e60e, 0xf02cd378, 0x7d7d927d, 0xe78641c6, 0xde5126bf, - 0x78c59676, 0x554bac6e, 0xdfd0267c, 0x596ce4cf, 0xf949d937, 0x4258d707, - 0x20580ff3, 0x6f51f917, 0x587defd7, 0x7e1a427e, 0x1a88fd02, 0x7e5a597c, - 0x21d610c2, 0xc9bd7da0, 0x0e27cfce, 0xf84de255, 0xbd9af3fd, 0xec3f9fa9, - 0xec315e77, 0xcee5e29c, 0xc94fc627, 0x05d43a5f, 0xcf7ab4fc, 0x8f5fcc14, - 0x477f27bf, 0x12798aaa, 0xe7829e7f, 0xc85fe257, 0xf50c931f, 0x9c1fab13, - 0xc8fff54a, 0xf50e931f, 0x8dff1a6f, 0xca04cbd7, 0x3d582d57, 0xebf22a7a, - 0x2cf9cb55, 0xce5188c0, 0x75bc40ef, 0x7bba3e79, 0x1ff31391, 0x5f8e657a, - 0x4376c1e6, 0xa5bc7126, 0x40ed1f29, 0x75350d3c, 0xfe7f22d4, 0xb157ef7c, - 0x4c9c17a8, 0xaca8fc25, 0xc1fa455e, 0x2f1749a3, 0x9e174791, 0x93eba64f, - 0x01f78acd, 0xf991e384, 0xe05ce823, 0xad332533, 0x98cf5f3c, 0x78d4c0c7, - 0x469167a2, 0x1ad3844f, 0x58bf8f92, 0x5cfcc9f4, 0xafa6934c, 0x9e38aaa6, - 0x2f172be0, 0xe1edf75e, 0x4be7507a, 0xc8695ced, 0x1087c679, 0x7de29f5e, - 0xffd092c8, 0x161de33c, 0x9f7c0acf, 0x1d3e7c5c, 0x9f3f5bf9, 0x91ce7e18, - 0x48a6bd49, 0x76b35ff6, 0x782071ce, 0x2aef563d, 0x77f3371c, 0x41879dce, - 0xc91746be, 0x1ccd4c2e, 0x827c62bd, 0x5215cfc4, 0x4695439e, 0x971324bf, - 0xa310f643, 0x8b1ed67d, 0xb9bf46e0, 0xf49541e7, 0x6dd15a77, 0x44f557e4, - 0x3e60b467, 0xfcc3cf50, 0x4c66295c, 0xd90d1ca3, 0xbf401313, 0x5ce0e40f, - 0x339c1c98, 0x71c673ae, 0xdb3a2e7b, 0x553fa83a, 0xb00c0feb, 0xe0b9e0c4, - 0xe5eb911e, 0xc1271a9e, 0xf6f98431, 0xa57efae1, 0x18b56de3, 0xde02fdcf, - 0xe8bc405f, 0xc0e5ff78, 0xa3457bf4, 0xe8912bdf, 0x74fe7e17, 0x6bfbc5be, - 0xf8aa7f6c, 0x15742ad0, 0x869dcfc3, 0x6a4ab5d3, 0x78ae88da, 0x682f9ee2, - 0x36e9d19d, 0x412b857a, 0xe3a0641a, 0xe8efd8eb, 0x10985f3d, 0x4f7e9d5e, - 0xfdef900f, 0xcf5f0b07, 0x9c4bc7c2, 0x8de291d3, 0x1060feb4, 0xcf58212e, - 0xf8d1e6b5, 0xde3c4d83, 0x10bdbfd3, 0x7fd03e71, 0x30f2a5e6, 0x2fde5573, - 0x50fdffe0, 0xf110ffbe, 0xfe22223f, 0x03bc463f, 0xf6c63ffe, 0x4fff8057, - 0xdd7f852e, 0xf4d32fae, 0x2bee1942, 0xc5fcff01, 0x13313339, 0x15142dc6, - 0x5b25ffe2, 0xd21f6d45, 0x62725b7d, 0xb92c8f50, 0x199f7abe, 0xb3c970f8, - 0x9169f102, 0x73fd5e76, 0x784b5ced, 0x1cf15f5e, 0xcbc9e91f, 0x49f9f7e7, - 0x336d950f, 0xe410bf3e, 0xc7ca74db, 0x93f3f1f5, 0xe11726a2, 0x68a33ff8, - 0xd628a2fa, 0x0e9c2ed0, 0x864daa43, 0x29e4f03c, 0x9f90fd7d, 0xbe726497, - 0x3fb5f14f, 0x07c61998, 0xf8fc52dc, 0xbc63e200, 0xcdfb1530, 0xef56e4d7, - 0xe30ae86f, 0x33e19f3a, 0x6acbfb9e, 0x1bfb9e34, 0x686294de, 0x4c86cd7f, - 0xfe91fbc3, 0xafef0d6b, 0x50d636db, 0x8372d51f, 0xb6e8fda1, 0x4c7d4302, - 0xfb4316e0, 0x1a678771, 0xefda13ea, 0x789fb435, 0xfde18174, 0x86a51df5, - 0xba7e37f7, 0xa9bf50cc, 0xed0d5ff7, 0x5eb88b03, 0x94935fdc, 0x740ae786, - 0x2a5fecbc, 0xbe7c549b, 0xe6a4db34, 0x744f3e86, 0xccb1733b, 0x357fa373, - 0xb14cbc90, 0xae85a726, 0x6cccf9cf, 0xac536bd0, 0x55817ac6, 0xe07497e3, - 0xcdfe2017, 0xa55ca356, 0x026bcf56, 0x2ca59bb3, 0xd2f94619, 0x58b75f20, - 0xc5bb7eb9, 0xedfa657a, 0xaa7f6c4e, 0xece74032, 0x444be5c3, 0xd2a2caf9, - 0xcca9fb47, 0x1b96f945, 0x4d3e466d, 0xccaf401a, 0xc3cf1ab3, 0x9b61ea8b, - 0xfd139064, 0xd0a8f9f9, 0xdbe2c2e7, 0xa0676f28, 0x05a4e57e, 0x7d016eb7, - 0xa97b2729, 0x9aaf9fd4, 0x97988a63, 0x3bf590f7, 0xfa1b49fa, 0x210f4fd9, - 0xde92bb7e, 0xccf30a7e, 0x92f5e72a, 0x316c94bf, 0x775825e2, 0x5479e60d, - 0x508e7e4e, 0x54dcffe5, 0xae2b78d3, 0x173cfaf7, 0x1133307d, 0x06d203f3, - 0xd55e9ff0, 0x4d5cf1e6, 0xc345adc9, 0x14d53fb0, 0x7a45bf7a, 0xfd10aaa0, - 0x1e5aa198, 0xc8a653f4, 0xd53f4af9, 0x0a8c19fa, 0x5503ed14, 0xaba0fb21, - 0x048723f8, 0x9377f8f3, 0x17c8a7f7, 0xe7b7460b, 0x6ecb73f1, 0xabb24cd7, - 0xd75f8254, 0xe78ae943, 0xe92bd429, 0x66731249, 0xf06787f4, 0x06636f3c, - 0x338fafbc, 0xf7aa14b9, 0xe59e380a, 0x820d8cc7, 0x5bffeaf1, 0xf7eaf824, - 0x3cf94f5f, 0xe29aa516, 0x993cfaa7, 0xc7afdfb6, 0xcd26cf8b, 0xd63c418a, - 0x6e77db5f, 0xacfd6187, 0x7ec76de2, 0xd337aecf, 0x8205f5b8, 0x6f3ebde1, - 0x741dc369, 0xe15d2b1e, 0x79862ef3, 0x3496dc23, 0x73fd570e, 0xb8234b02, - 0x43d2f7fe, 0x8aecbfe8, 0x0dbc6176, 0xe889b1f0, 0x6738ceed, 0xf30f27d2, - 0x34a418aa, 0x25fb21af, 0x96fa1fb2, 0x4cdbaf95, 0xf688959d, 0x4635f254, - 0x66f5c5b8, 0xc51707f2, 0xe0af942a, 0xd1a159af, 0x55ef38d5, 0x9cef3349, - 0xbdd4f00b, 0xfd4c3223, 0x2d347671, 0x15df043d, 0xfcbb46b7, 0xef78fece, - 0x01387272, 0x6e10b7ee, 0xcd214371, 0xdc21da9b, 0x33d8173f, 0xde77c819, - 0x14ff44e9, 0x977dc313, 0xd3fff870, 0xefc4e3ca, 0x879a5558, 0xeb7c549c, - 0x16584196, 0xb51ddc91, 0x7fceb80e, 0xfcebe568, 0xeb08d687, 0xfdeee5fc, - 0x7ed39f28, 0x6dd14b08, 0xeadaecd2, 0x197b50ec, 0xec49d6f4, 0x318baf57, - 0x7ec5ce3f, 0x3ccbb607, 0x9719d94d, 0x1ed0cbb7, 0xedd3fe43, 0x8d5abfb1, - 0x9e886476, 0xb3d34afd, 0x9ea15d5f, 0x4eed80bd, 0x68881bdd, 0x91c824c7, - 0x1b38dcf5, 0x2a957fc7, 0x1be3ca33, 0x6d9f9e20, 0x0e1f6c8b, 0xce5d0eb4, - 0xd68cc8cf, 0xefd754f9, 0xc560dfdc, 0x9c2fed32, 0x247fe0d9, 0xe329f71b, - 0xedde5187, 0xaea4fd40, 0xf10d83f8, 0x886de3ab, 0xc04f88cd, 0xf9c6d3a3, - 0x648b69c4, 0x1e03960f, 0x0e3c064d, 0xd903f6c7, 0xdfad5783, 0x6ee78c4b, - 0x837c35ba, 0xbc71979e, 0xce3ebbae, 0xe545b8c3, 0xe7a473ec, 0x399c7aaf, - 0xf74475c6, 0x011c61bf, 0xd77ddfe7, 0xb7716b7f, 0xd5178a0e, 0x0c4d7abd, - 0x0a2aa7c6, 0x9586f4fa, 0xa49985db, 0x5976bb07, 0x576708dc, 0xece7cf1c, - 0x10f135da, 0xaf3e39c6, 0x85299c39, 0xaf5d2dd8, 0x4333c91c, 0x8f3b5d7f, - 0x209449e4, 0xd17e27e7, 0xfc5c57df, 0x128f3ccf, 0xc7d0273c, 0x0ebe566f, - 0xf8f1b7ad, 0xc798d3c9, 0xf7b19a36, 0xfaf963a3, 0x1c7a6891, 0xe3bf479f, - 0x7f7ea1f3, 0xc7e57054, 0xdd262b00, 0xab664c55, 0x00a68de5, 0x6e0a8f96, - 0xbe55e311, 0x4d3cfc91, 0x911b1652, 0x4728fd01, 0x8e0803db, 0x8dd7a3a3, - 0xa7ea29db, 0x0b2c3eea, 0xc402ef14, 0x2baf5c7b, 0x37fc7d09, 0xa1b38d87, - 0xe14d215f, 0x7e77b77a, 0x29ef1f94, 0x8fb9344a, 0x6767aa80, 0xc58c2f0e, - 0xe68b7ff7, 0xd258f2f2, 0x8e5c2689, 0x38a03970, 0x5a669bd4, 0x710d96df, - 0xef822f27, 0xe7884d97, 0x9805e97e, 0x9639c87d, 0x0967e3c7, 0x00b90714, - 0x14e78178, 0xb53e02fa, 0x3317cc4b, 0x89b0f416, 0x0bf055b9, 0xee4293ec, - 0x68ffc1d9, 0x4d60fc76, 0x4d38f6ff, 0x45e0333e, 0xd5db1976, 0x5c0cee09, - 0xfc81774f, 0xb4fa030d, 0x7ca958d5, 0x184d46ad, 0xa7b8f206, 0xafea8926, - 0x0ca938d7, 0xe7a08cd4, 0x545c6bfb, 0xa7b5368f, 0x552c7ad3, 0xfe879baf, - 0x0b12fdf5, 0xbc23b7bd, 0x8e567bc4, 0x97f9c887, 0x0093e62e, 0x3d352fae, - 0x38d6fb52, 0xc6a7afe2, 0xfd31d400, 0x8ad9ffbf, 0x054d643f, 0xa3fa983d, - 0x415359c3, 0x78129f8e, 0x181e02fe, 0x552e748e, 0xb7329f2f, 0xf0a9a2c4, - 0x4df31b6b, 0xc8bcc24d, 0x8e153fde, 0xe8f6cc61, 0x1d4ea69f, 0xfdc7f309, - 0xf6c614fe, 0xc7abdeda, 0xfba9d873, 0x818bab3f, 0xfc6dc8f9, 0x82899f3e, - 0x7d4056a7, 0x0bf39b33, 0x98b53c93, 0x3773d9cf, 0xbefee273, 0x1b5ece3e, - 0xdb7613b7, 0x51399db8, 0xe6c1fce0, 0x411e5aca, 0xbae86e6f, 0xef3ede11, - 0x8f74d7c0, 0x2fb78c0f, 0x2f5e30d5, 0xfa0711c5, 0xd7ff752e, 0xe95c8eb4, - 0x491f3d77, 0xc4847cfc, 0xe6ba2bf3, 0xfda66e26, 0xba1f6878, 0x4723da8f, - 0xd2ded7b6, 0xed0681d6, 0x659fb7be, 0xa68372f0, 0xf5c62457, 0x05d16bff, - 0x61b947bf, 0x5fda38de, 0x09e2d3aa, 0xe57a3a93, 0x2f7e76f9, 0x13d43e5c, - 0x3c04784e, 0xd1a5d70f, 0x1e605533, 0x6048ffcc, 0x28028433, 0xdbcf36dd, - 0xc2d24fd8, 0xd197be4d, 0x7165d85e, 0xe3a3d9a2, 0xd903eeab, 0x6121fa8a, - 0x8fda31cf, 0x643a13aa, 0x8f97f7a4, 0xcb714d7c, 0x3275733a, 0x1b176dd5, - 0xbdb4feb0, 0x99d6237a, 0x6fa9ebef, 0xd60c3f00, 0x13e3e1ce, 0x90bb63d4, - 0x3b5829e8, 0x7e06ef57, 0xf5e665d8, 0x4b391f2f, 0x5ccbb1fc, 0xe18d9f3d, - 0xef987af5, 0xaa6f58ae, 0x52905409, 0xe1fd65fb, 0xb7aeb09b, 0x77da92ff, - 0x3f6e54db, 0xa40cde2a, 0x855d5f7f, 0x2ea43dba, 0xf2b33af1, 0xc55f9f52, - 0x7f29af81, 0xe70f72b8, 0xce1bc447, 0xc3cdef13, 0x7a8ce975, 0xa4eb51d4, - 0xd73673b8, 0x9f0301d7, 0xb753e7e9, 0x2a2cbc98, 0x085ecf44, 0xce42ff5b, - 0x84a8b1d9, 0x38b4fe90, 0xbb033a76, 0x6f182b34, 0x2a2e64cd, 0x950f3187, - 0xee96dbd9, 0xbb2db447, 0x7a89d5af, 0xfad73e2b, 0x68e89780, 0xd09e1ff4, - 0xe8fae2f4, 0x01a31bfc, 0x7782f59e, 0xf17a888d, 0xe74ab365, 0xb2243a2f, - 0x35b53b37, 0x5330ad8c, 0xf73b5cbd, 0x5de95e6d, 0xeef51233, 0x19ab9322, - 0x4f0cb3d7, 0x2fbe19be, 0xaae19ddb, 0xe7bcc165, 0xc496d8b2, 0xef304ab1, - 0xaa3faf59, 0xb546d9f1, 0xd2f786c9, 0x9543fbe8, 0x71d2eb6d, 0x7db3fb7f, - 0xbd3c901f, 0x7c41951f, 0x447ad15c, 0xbf69daf6, 0x29f3c64c, 0xd6fad99f, - 0xbef75a3f, 0x0b74196c, 0xeb2ff5ea, 0x79b8744d, 0x06f43d20, 0x38373fe8, - 0xac6a87c8, 0x5dc2fe54, 0xde9a2d7d, 0xd3295105, 0xbfb4606c, 0x9156e990, - 0xb9ade68f, 0x7c0ac1a6, 0x8eac82f4, 0x179b3e44, 0x5b7c4b95, 0xbe722b16, - 0xdd07b964, 0x0dcfb692, 0x6535d4f5, 0x3c53bed3, 0x6f68c8be, 0x88526d54, - 0xc80ec00f, 0xdca83e47, 0x7ee1f260, 0x4edac9a2, 0x45e77de7, 0x368fcd31, - 0xaf5c4f9e, 0x6cdf3be9, 0xdcbddf1e, 0xf392c539, 0x511e7451, 0xe51fbfaf, - 0x9128be24, 0x55ffb47c, 0xe741de72, 0x38fbbf18, 0xc879c356, 0x0428e3fe, - 0x794e3e87, 0x57d21c70, 0x27ec1fe5, 0x6b8df83f, 0x4dd67b75, 0x3be5ac71, - 0x9b05fcb4, 0xf3f6307b, 0x1827a6b4, 0x7780b1fa, 0xeeafa329, 0x1ccf4093, - 0xf933d3ec, 0x90d3530d, 0x6cf7c1be, 0xb90f4192, 0xc1d3a025, 0xfbeead28, - 0x51f6e47e, 0xf533ed61, 0xa986ccfa, 0xf3c3fb93, 0xb7582db4, 0x1be97b42, - 0xe11d5f4b, 0xa1f573a3, 0xe3e9c5fd, 0xe9fd4bdf, 0xb51a97fc, 0xf80fa0f0, - 0x27ac60ef, 0x7a7cf31f, 0xca273367, 0x8d4966e1, 0x21d08572, 0x37af8a35, - 0x35afe725, 0xf7883fe0, 0x4ffd035c, 0xfb0d38d5, 0x968b8b8a, 0x549879d1, - 0xc7cc5e9d, 0xca6d77cf, 0xfe27ec32, 0x16ae387f, 0x7000f70e, 0xc307fd4c, - 0x5e30c231, 0x031c8e10, 0x870b577c, 0x7a6b3b18, 0x8f6bda06, 0x280f2898, - 0x66b3e4d1, 0x6ff65da2, 0x0ca78a26, 0x880f3c67, 0xfb0de329, 0x2c7b99b4, - 0x9efe31f3, 0xd2c3b129, 0xb7279458, 0xa9d716b3, 0x5f64489f, 0x39ab73c1, - 0x726e870e, 0x204ffde3, 0x665fd495, 0x1f82b7b9, 0x82fbe6f2, 0x70d33efa, - 0xbde3e595, 0xe7a39ba0, 0xfb8d18df, 0xaa1e7366, 0xe7983cc2, 0x352ff195, - 0x92bc8330, 0x2c20d21d, 0xabe33b25, 0x701b87a8, 0x147076bf, 0xf6045bb7, - 0xe4e1c370, 0xbcb9ef48, 0xf0f35b9e, 0x341b8c34, 0x8b5e74af, 0xcdb353fe, - 0xf31fb2df, 0xe8531e76, 0x47acd6de, 0x50998dfd, 0x6899d717, 0xfd6314bd, - 0xdf719adb, 0x176cc9fd, 0x68cd11da, 0x47fb60bf, 0x566bf214, 0xf0d338d5, - 0x6d3a927e, 0x76b2d81d, 0xc1798ab2, 0x87148af5, 0x732addeb, 0x773c5cf5, - 0x8dd1ee31, 0x51ebd60d, 0x071ab98f, 0x949ebca9, 0x339aeb8c, 0x7b463ad3, - 0xae68c80f, 0xb1a8a675, 0x6ff0fac1, 0x3d20fac0, 0x9dc1b1b3, 0x2b2efd86, - 0x883bfad5, 0xe2178a71, 0xef68bc34, 0xd2f4fb33, 0xcbcc06c6, 0xf5836b12, - 0xaddf30a9, 0x353d72cf, 0xfb47fa18, 0xc3e3e60b, 0x877b057b, 0xca4e744b, - 0x603b6306, 0x9991b67e, 0x0cd7dfb4, 0x2bef117a, 0xdfc91dee, 0xf234fbeb, - 0xd3ed1370, 0x6f5c7b60, 0xbdbcc96c, 0x57df833c, 0x8a15db20, 0x307ac037, - 0x149ef315, 0xf371ffa6, 0x8fb6a4b8, 0x01f78511, 0x75a3f084, 0xf73a32ed, - 0xdc661d69, 0x8cd3979f, 0x16798975, 0xaa27bfa0, 0x4637e7c6, 0x8341f96b, - 0x6dda0a58, 0x133e4dc3, 0xfcc91bb6, 0x02c75e54, 0x628d8f64, 0x8d1f541d, - 0x1e16635e, 0x41d2725b, 0x2dcc71ab, 0x47aa38f2, 0x71313b44, 0xf2471eae, - 0x74be414e, 0x61766b47, 0x7e3fef0a, 0xf7ca2cc6, 0xcdef69f5, 0x313d8633, - 0x7eb5e60d, 0x50ceddc6, 0x2f5f4efb, 0x48adfb75, 0x68cbf983, 0xa0bda221, - 0x364575db, 0xe5984f5e, 0xc6147a7e, 0x26cddb11, 0x58ad9fbc, 0x6f16638b, - 0xbb444fc8, 0x5cdf68ac, 0x44d787b2, 0xd16cbb73, 0x77b219fa, 0x9af79e14, - 0xfe7f764f, 0x183109ba, 0xb9b06fa7, 0xfe47ae62, 0xdfbf23fd, 0xb1ed4af5, - 0x0a6bc4e6, 0xc19b1e50, 0x8ffbc6af, 0xcadd9a0e, 0x758be418, 0x6ccec8c3, - 0xc7d6f28e, 0xffcdbf42, 0x41d574ea, 0xf73667fd, 0x4e3823f8, 0x8f7f1443, - 0x6f2126f7, 0x3ff7edf6, 0x1e8c5c2f, 0xfdf0fc78, 0x91b183fe, 0x43bdf1ef, - 0xfed05fc3, 0xd9dd90f0, 0xdcc4f660, 0xcbbdf087, 0xead679e7, 0x112f5189, - 0x86b4fb67, 0xd67603e7, 0xe64058b8, 0xbd62d1f7, 0xdd3f68a4, 0x22d25caf, - 0x097cdc50, 0x3a3d226b, 0xeed5894c, 0xc5e631a7, 0x4dbd1696, 0x795b4bed, - 0x42d632fb, 0xe17a75ed, 0x8301b5bd, 0xf0ce3a1d, 0xdcd11dfd, 0x78acdd6f, - 0xfffb431f, 0xc4d91991, 0x1167c04f, 0x07e22df3, 0x31b977d8, 0x371faf9a, - 0xf6c8db62, 0xb863f128, 0xe05cb87d, 0xc207b3e7, 0x9379d553, 0xde0a3d61, - 0x7ad3219f, 0x49f9add4, 0xeb7c9387, 0x7ff9846f, 0x244af59f, 0x23bddaa7, - 0x425f8275, 0x33befaf9, 0x2d1bdeec, 0xa6ba680f, 0xcb43fe25, 0x6b3ef9ef, - 0xfd0dc379, 0xf402cedc, 0x9eed61dd, 0x48a41412, 0xafd01979, 0x3adc1f41, - 0xddbf58c2, 0x39dfac65, 0x7d3df229, 0xb4d46b6b, 0xd6aa7bd0, 0xf38e700e, - 0x575e8d2d, 0x0b12df7f, 0x0b7bebcf, 0xf9815ee9, 0xc17fb494, 0x1b14faf3, - 0xd91ea0f3, 0xfb46cfbf, 0xbc8a5521, 0x55164319, 0xbde2efe0, 0x9f9d8af0, - 0x17ff4037, 0x998a05e3, 0x97de0fb7, 0x1251f7c4, 0x3c5a493c, 0x633495c3, - 0x1b87b7d4, 0x0bca2afd, 0xdc46d896, 0x27e60d77, 0xe8edef1a, 0x0f38fe8a, - 0xcf9863fd, 0xe84f8c6c, 0x3e7d5a71, 0x2c7f28ff, 0x39cfbb5a, 0x346b6e9c, - 0xa30ba8f9, 0x39d23d73, 0xb973df07, 0x87bb52f9, 0x43c129ff, 0x26896879, - 0xb3ac171e, 0x9c528eb9, 0xea0ff344, 0xf306b8b4, 0x56ef5d7d, 0x1095ecc2, - 0xed7d22ff, 0x39f5f5d7, 0x38f377e4, 0x156a2d88, 0x360dc3ae, 0xfaa66ebd, - 0x00a6e6d3, 0x5aaffdf9, 0x831f189c, 0x6718ddef, 0x411dcdf3, 0x065d5d7e, - 0x0e7bc14b, 0xb4cbb0de, 0x6abdd6fe, 0xd8f5c669, 0xdb76f36d, 0xba49f242, - 0xf9d1efec, 0xf9fd08a6, 0xf90dfd0c, 0xf8c1fd76, 0xfd7788ad, 0xa7f61bfd, - 0xceff2202, 0x691bf949, 0xa17b1fed, 0x42cbb89e, 0xf7fd4f71, 0xe7cfca0f, - 0x7a8cfdd1, 0x4e14137f, 0xd51ace87, 0x8e5d8f90, 0xe507377a, 0x67f49da0, - 0x8320cb45, 0x69f5d4de, 0x681bf9c5, 0x57482cbf, 0xb5212e2d, 0x38aa5e93, - 0xbc68bfff, 0x349e903b, 0xf7e9124e, 0x3549c781, 0x38e0e3e8, 0xf7700c93, - 0xc132671f, 0xdac38fa1, 0x9fe70ca2, 0xae3ccceb, 0x33986672, 0x1e823626, - 0x83714bd1, 0x60ff70c9, 0x62b2e49d, 0x4eca75ff, 0x287f3435, 0xef005f7c, - 0xf02164c5, 0x867ac1d5, 0xf30b72c1, 0x3d405e52, 0x072213f6, 0x62a5d9a2, - 0xf8c262bf, 0xc62ef9e9, 0xbdb945fe, 0x33727d10, 0x8bd82df2, 0x7e3b583f, - 0x49ec0f95, 0x4769ecc9, 0x93764aba, 0x6b68f313, 0x45c51315, 0x64ac92eb, - 0xca12adff, 0xbd739455, 0x2243a95f, 0x8f7df438, 0x9f29e681, 0xc33cd077, - 0x9ffb3bef, 0x76a14f1b, 0x3b57eefd, 0x0f93d730, 0x93545bfd, 0x4e5d450b, - 0x2127d853, 0x47ef0ff4, 0xec4520da, 0x8e9dbc27, 0x6ce901ff, 0x3d2070ee, - 0x88a5e3ba, 0x951b1079, 0x310798ef, 0x271f4c2f, 0xe00ecd1c, 0x238742f7, - 0xe5f48323, 0xa5f50546, 0xdc9fccfd, 0xb4cbd24e, 0x7fafadef, 0x56a984e6, - 0xbc6c4f9e, 0xfe206f57, 0x7d62f1d3, 0xf3c641f3, 0x7f94bd53, 0x483c3972, - 0xfb43cb82, 0xe2297600, 0x425836be, 0x4938fc86, 0x354fe631, 0x63e21e48, - 0x56d54df3, 0x5b4927da, 0x927dc569, 0x063392d5, 0x37ded8fd, 0xf983fec1, - 0xbe793a35, 0x6bff786a, 0xb4661ef0, 0xc4531573, 0x06a379fb, 0x34baafb0, - 0x77d9acfa, 0xf501fe69, 0x3775c1e1, 0x71524e2a, 0x399b35dd, 0x4bad03bc, - 0xe103bf7a, 0xfc7dd1eb, 0x392c1bf7, 0xffae3f56, 0x4a35e3e1, 0xbc3e4f1e, - 0x7078046f, 0xcd31acdf, 0x546df84d, 0xd5fd1525, 0xcc5111e8, 0x656fea1a, - 0x67f7a2cc, 0xccf1e3e2, 0x8f8c6b22, 0xe3a3979c, 0x1df2b769, 0x186f1ded, - 0x8f7f0e5f, 0x7c21e8e2, 0xe84ca9d9, 0x91bb97cf, 0xfc381317, 0x5aa6f7a1, - 0xbc458633, 0x7f1fb27f, 0xde4df186, 0xf7e74664, 0x19b94306, 0xeed56efa, - 0xb5c0aa43, 0xf2f4fc0b, 0xc2a6147b, 0xe477e6fa, 0xc939405f, 0xcfcfdf6b, - 0xf026b4d1, 0xefb51e7b, 0x625dc7c3, 0x12c8fee7, 0xcc654abb, 0xf12ff751, - 0xdb5a37f7, 0x5e789ca3, 0xb22e35b1, 0xd763931f, 0xb49a68f3, 0xb41d0873, - 0xcfb7a14f, 0xcddcc79b, 0x1b3dc50a, 0x257fe0ad, 0xa9ffb5f4, 0x82023fb6, - 0xf9dce30b, 0xf99aebdb, 0x7f3e51f9, 0xfb62ab8c, 0x5c8ec4c4, 0x740efc41, - 0xf70cc6db, 0x3b5855db, 0xe7ce51b2, 0x7699bc9a, 0x68eaa718, 0x5bd62247, - 0x4e9d3edf, 0xb71d6f7e, 0x47777b37, 0x3fa0dc53, 0x79f96a7d, 0xcc29f3f2, - 0xdd3fa837, 0xad00a5ca, 0xd3e7e5ab, 0xcd1c6f99, 0x0b8d67db, 0xc2d3bfbe, - 0xc8b1a4d8, 0x884f1c00, 0x30f4489f, 0x7a064ddb, 0x675e3c80, 0x7881e8d7, - 0x76b7a3ea, 0x76a74bef, 0xcd71e0bf, 0xf72a615f, 0xa5fbf5d7, 0xe5f7678e, - 0x5b7dd05b, 0x13f736e5, 0x3b0b4f78, 0xe6be5222, 0xfefc29c2, 0x771685c4, - 0x0b57da0c, 0x6a1453ff, 0xf3937f69, 0x7f0d22fd, 0xf745cc9d, 0xdad6f80e, - 0x984ebef8, 0x54f1967f, 0xc23fb8fe, 0x44da8bf7, 0x305f1bca, 0xbf61f145, - 0xbf05ed79, 0xe2f9fdc4, 0x773a68c6, 0xae7bf0be, 0x2dd76893, 0xc4e6c27c, - 0xfe597bdf, 0x327e6641, 0xc9fcbbf4, 0xdf07d50c, 0x24f0af45, 0x27a05d59, - 0x8853db1f, 0x3083457e, 0x0630be7f, 0x0ec7cafc, 0x98b8c2ac, 0xcf94cdf4, - 0xf47f506d, 0x615677b1, 0x18b7e9bc, 0xf63b26e7, 0x63b442dd, 0xf4d0425f, - 0xc1c03ffd, 0x5a4d874b, 0xa9aac4fd, 0x4daff2a0, 0x2a293568, 0x562765fa, - 0xc4d939e1, 0x1318f738, 0xfd8ef78c, 0x6fec42b3, 0xcea313c1, 0xe7f7806d, - 0xbec817ed, 0xdf693a00, 0x014f370b, 0xb278bbbb, 0x582d975e, 0x86668f8f, - 0x3339be38, 0xd9da3e38, 0x8b7c7aad, 0x718cdd45, 0xd505e3f7, 0x3fe82453, - 0xceaea1c3, 0xc4d8c919, 0x1baaf9f5, 0xc476cfc6, 0x98f18cdd, 0x837dbed6, - 0x1f18d5f8, 0x03de656b, 0xd37f7866, 0xb66e43e3, 0x07e36202, 0x30a8c679, - 0x29d641ff, 0xf4dfa7ab, 0x4463e41d, 0x0d59f3bf, 0x939204f6, 0xf4d28843, - 0xc2defc15, 0xe34ef93e, 0x1f57db7c, 0xc3cfc1d1, 0x5e24f5e8, 0x59195d6f, - 0xc312dc5f, 0x2a35baf9, 0x4d66fbf2, 0x03be003f, 0x8b6d7f14, 0x08cf0ff6, - 0x1f900fea, 0xa79224eb, 0x807f5c75, 0x93b4cd1c, 0xefec46dc, 0xab6bcadb, - 0xab79af76, 0xf8c68ee4, 0x30c7ae82, 0xcce38682, 0xfa0d3bb5, 0x017daf39, - 0x3151d7e9, 0xc9c7872a, 0xc53093f1, 0xb59847a8, 0xdf743b3d, 0x3cda77fe, - 0xe3d3ae33, 0x7439013f, 0x8ef969df, 0x9f9e4bfc, 0x7f38c72d, 0x9c1dbd88, - 0x678a54c7, 0xfa17ebf4, 0xbbfd6a73, 0x5f04ae72, 0x15f065ea, 0xdcbaf84f, - 0x19fd833c, 0xfbfd2fe3, 0xc17db593, 0x223ae326, 0xa4f38647, 0x7f8027ce, - 0x2cfe8853, 0x9ea9f4d6, 0x6bbdd107, 0x064fe524, 0x31e7e5c7, 0xc4bfbe81, - 0x81f25ddf, 0x963d453e, 0xc56fb927, 0x71ed79f6, 0xc0efda2a, 0xbf1af56f, - 0x3a6fc849, 0xaae35b9d, 0xebbe69f3, 0xfa4bb204, 0x3ada41d9, 0xd024d79a, - 0x9e0d99ef, 0x87e715e7, 0x7beba7c0, 0xeb55bfe8, 0xe7e73c7f, 0xf9f8fb67, - 0xcd1f943e, 0x0eae679f, 0x1c3d5fba, 0x732885fe, 0xd5eb2109, 0xeb8a36ab, - 0x5abb78eb, 0x85edd7fe, 0x25d701f2, 0xf8377d07, 0x84e1c068, 0x1e518b76, - 0x7cb55f50, 0xb664f742, 0x7f0c89b6, 0x8de700b2, 0xd74f237a, 0x8795be93, - 0x5bb2240a, 0x49d97a82, 0x37ae8bf6, 0xb06b5603, 0x2bb5b9fd, 0xaf51eb0b, - 0xc7ecf76a, 0xc7c5a08b, 0x7348e106, 0x9277bb70, 0xddfc4597, 0x5dbb1cb8, - 0x8f3423d7, 0xe80a2b8d, 0x6d2a855e, 0xe1d49d3d, 0x345378a3, 0x104271e2, - 0x7d7afa1f, 0x15e3a5a7, 0x8197bced, 0xd83af51f, 0xaca69525, 0x7ef8ff60, - 0xe7df0866, 0x841f3839, 0xeabbe7d3, 0x0f83c027, 0x0d43f0f1, 0xc75009ef, - 0x04982d7b, 0xfde617eb, 0x6b5c50cc, 0x56e04232, 0x104e3eb8, 0x5d8f5c4d, - 0x07e22e46, 0x58f7ed31, 0x41cf24ec, 0xe5bb707c, 0xe7168701, 0x3f29eed5, - 0xa1390268, 0xcf3e367d, 0xd4c95dee, 0xddad6cef, 0x6f2f4bdf, 0x7496f2d6, - 0xb5e2b17b, 0xf846cdd4, 0x1cbb7f79, 0x47792f1c, 0x8ed063dd, 0x5c51ee19, - 0xb5e41fe8, 0xf98fdccf, 0xf07bd924, 0x7c820407, 0xe5c2dd9e, 0xc34bb814, - 0x43db9bcb, 0xd874adfb, 0xbbfb3975, 0x28fb23cc, 0xcba457e7, 0x5a72217d, - 0xbe3850e3, 0xc4167e60, 0xa3d464a7, 0x83f7f97a, 0xcf1fb3c3, 0x3e039525, - 0x78eb6d50, 0xbf996d6b, 0x7c7286d2, 0x8e50b994, 0x9be65bbb, 0x315d2146, - 0xa219cc11, 0x79f3d61f, 0xf02876e8, 0xe5f20b65, 0x1a10c73a, 0x7751f86f, - 0x1fbc0e74, 0xc613768e, 0x7eec5b7d, 0x0efc23f4, 0xe2072eef, 0x14ef5673, - 0x8cad4fdc, 0x85b5aeae, 0xdf6bef3c, 0x8f89ed06, 0x1fee22bd, 0xf8c03f95, - 0x7cdaf1bd, 0x02cfa9a0, 0x20c855e3, 0x0f5459a7, 0x655ade20, 0x3ef7bede, - 0x5611a5fa, 0xf97bf229, 0x95befd60, 0x536df3f8, 0xfd17d21c, 0xcb93b424, - 0xee1a4f45, 0x16c1b27b, 0xe003ae17, 0x1fbf1077, 0x06c931b4, 0x4a1efffd, - 0xc4d3d3d4, 0x6b8e74a5, 0xfb40965a, 0x8f7fba44, 0xa4fd0b7a, 0x4d17bf3b, - 0x3c2ec8fc, 0xd3e30c38, 0x4e9cd109, 0xeb558fd0, 0x1b1d6ac7, 0x48ffbf94, - 0x8efe491f, 0x141dbebe, 0xe0e7ea04, 0xd735d74d, 0xd841f885, 0x83ffea1f, - 0xa5b48cc2, 0x1f9affc8, 0x7c61f647, 0x7b45dd70, 0xce21ac65, 0xebe0d3e6, - 0x0a3e4748, 0x3ed147b5, 0x7d67b3ed, 0x0cdf57f3, 0xf4e2767a, 0x715e0096, - 0x6e8acb5f, 0x6fe817fe, 0x36b3d81a, 0x8d3ec3c0, 0xf8660e2f, 0x3d4fdc44, - 0xfba05c38, 0x79450fdc, 0xe095aa73, 0x5c5a8938, 0x33cb5120, 0xe5e28c4f, - 0x1eb8620f, 0xaf863cfc, 0xbca837d7, 0x1c88e89e, 0xbdad9847, 0xeb89a9ff, - 0x91f935f7, 0x684fd1f3, 0xedaaf5fa, 0xfc211cde, 0x8e13eebe, 0xdd7dda09, - 0xe3c76f94, 0xfe340bfd, 0xe8873b06, 0xf8abb414, 0x876e9d7e, 0x4d9f6d9e, - 0xf78213f5, 0x2c047bbd, 0x9f904f3d, 0xf148aef4, 0x6f58e2a1, 0x55a5e622, - 0xcb8e4544, 0xf4f0d20c, 0x38a30d59, 0xcfdc29ef, 0xb7bfe6cb, 0x1b25f585, - 0x1d7ba49e, 0xe29f994a, 0x1a1b45bd, 0xc8aebf68, 0x80a7302f, 0xc78799fe, - 0x943a3581, 0x710d116e, 0xb552c5e7, 0xe4139b1c, 0xae1dfc5b, 0x9b25f7d0, - 0x57ea19c6, 0x1816976f, 0x7a823bf2, 0xbfec90a7, 0x3e757ef0, 0x8f4fb70f, - 0xf10d38d7, 0x861b05ee, 0x78cdf217, 0x73217ede, 0x36177cd1, 0x11ef1966, - 0xb2b84c6e, 0x1ec1827b, 0x538445f5, 0x3fa8fd26, 0xf7f80e3f, 0x17f7c485, - 0xe08c3a7c, 0x7bc38bf8, 0x8e018c5d, 0xc433e668, 0xdff326cf, 0xf8f1b429, - 0xef8ff023, 0x7e407652, 0x07f577cc, 0x1fc01dae, 0xfa87fdc8, 0xb9937903, - 0x024d65fe, 0x9c4ce0e5, 0x66cfb46a, 0x6e75f0c7, 0xc1b44c76, 0x679a2b3e, - 0x6b57376c, 0x776b5737, 0xa84a38b9, 0xa164265d, 0xe9fde33e, 0x71951fbf, - 0xffca6dfa, 0xedc310dc, 0x6eaa9fd7, 0xbbf40c6f, 0xd0773b56, 0xefdade6f, - 0xf735ad4a, 0x5e5285e5, 0x1e6fe6e0, 0x09dfc3ac, 0xf601dde9, 0xfcc1e83f, - 0x7ba0df67, 0x6eeff4ba, 0xb432d15f, 0xa954f008, 0x8bb973c9, 0x15dcafcf, - 0x3f418790, 0xae1ce529, 0x827d96b4, 0x5a5df214, 0x22b76f09, 0x2ff06cc6, - 0xffd5a27f, 0x6549c635, 0x1840495a, 0x3652ed06, 0xec24116d, 0x0b577f0f, - 0x66a949e0, 0x93dfd0fe, 0xedcf194a, 0x6fc7db9a, 0x04e61616, 0x9a68d0f1, - 0x5c62a391, 0x85da3135, 0xaa47cceb, 0x50f10eb7, 0xce8051fe, 0xa8fc4c49, - 0xbdbb425d, 0x23d7755b, 0x7078eb7f, 0xae0a6a8a, 0x711fd1a3, 0xfcfa9b38, - 0x30bebe62, 0x4766a8f6, 0xe976eb37, 0x42edc661, 0x5712a75a, 0x3efc308e, - 0xb69c6261, 0xef32244e, 0x37da854e, 0xa327a232, 0xccae24f9, 0x2c76e66e, - 0x2cb4f7a7, 0x3e7c16cf, 0xb1c8f06d, 0xd647df78, 0xbf8480da, 0x26dafe3b, - 0x51fbc453, 0xc3fc359a, 0xf9c59e3c, 0x9cb8f3e9, 0x99dbd05e, 0xe84f8807, - 0x3d3d10f2, 0xd8c1dfb2, 0xff3ef4e3, 0xe97bf8d9, 0x997acafe, 0xc74e4f7e, - 0x69eab77f, 0xb4a6bc41, 0x3708166c, 0xdc7a78da, 0x5ca39f0e, 0xe78d971e, - 0xfb94073a, 0x16873b15, 0xbd7dca85, 0x1cd9f44c, 0xdbafe796, 0xe1887ff7, - 0x5890eaeb, 0x4bc43ecf, 0x8a3adb65, 0xc2d92cef, 0x4067f77f, 0xfe215cfc, - 0x07ee1284, 0xfbe1cf94, 0x4acff95e, 0x7ab2ff44, 0xe5acfbfe, 0xb8f077db, - 0x0b998fce, 0xcb7943f5, 0x0728a10e, 0x8773077f, 0x9f0428b0, 0xca7ee5a9, - 0xaec6bf83, 0x5bd71fcb, 0x718efce1, 0x0e53b462, 0xe87eb8d9, 0xb87c57cc, - 0xf669dc1f, 0xcebb6396, 0xe61768e4, 0xfff8e977, 0xe99b8efd, 0xa77db5dc, - 0xa3658025, 0x8ac939a9, 0xcad70efb, 0x6eabe42e, 0xe9127bd5, 0x5a792713, - 0x78d8fbf1, 0xbe16abbb, 0x58d85a75, 0x3c72b955, 0x8fe30c4c, 0x72e63f89, - 0xf43aa493, 0x24b186bc, 0xeb9daa37, 0x67d7132d, 0x1e7ccc87, 0xf787193b, - 0xb3ee3107, 0xe3878724, 0xf294dc68, 0xca1f9d00, 0x70d3bd38, 0x5fc830ce, - 0x1b7dbfee, 0x2c3fff7e, 0x00284ba1, 0x0000284b, 0x00088b1f, 0x00000000, - 0x7dd5ff00, 0xc5547c7b, 0xbddcf8f5, 0x0dd90afb, 0xdc3bf79b, 0x24280c10, - 0x01049e6c, 0x878424d9, 0x28026e20, 0x47796bc8, 0xd2026c92, 0x6dfad0fe, - 0xe5318316, 0x16d46b6b, 0x882ea945, 0x835ab696, 0xb80d06a2, 0x47d62228, - 0x2d8aa523, 0x2220a5da, 0xfb1b6484, 0x6fcb56c0, 0xec9999ce, 0x0f0d9bde, - 0x7cf9fb6b, 0xdcc98fe1, 0xe6739f79, 0x9ce7339c, 0xb5331d99, 0x228ca8cd, - 0x389aa6a4, 0xfd2d34bc, 0x84e90ee9, 0xf00b9085, 0x8321226f, 0xf121326c, - 0xbd3ca484, 0x582c524d, 0x1c5a7fbe, 0x052627d6, 0xaed84bbe, 0xa0af9686, - 0x84225ba9, 0xa0e4258c, 0x31cc7881, 0x2ae8b484, 0xfd68d947, 0x7b488496, - 0x663b2d13, 0x68db4573, 0x9d63967f, 0xeab4ac07, 0xa33e6398, 0xda4bf68b, - 0x4264c7e9, 0x121230de, 0x8c1ddb41, 0x6dd3ed60, 0x42229074, 0x07891b26, - 0x233d1bbf, 0xc1dfda14, 0xbfb083a1, 0xa6eab797, 0xc37b697a, 0x19d8b220, - 0x9b74ef32, 0x6ca5db0e, 0xe8e921dd, 0x5a48b8f7, 0x513f321e, 0x595b01ef, - 0xcc67cc26, 0x43844ed4, 0xae3d56dd, 0x1ce8c2a7, 0xb05466b6, 0x8fe868de, - 0xe6ed7bd6, 0xfa7e8c4f, 0xbd2fc7fd, 0xbf50246f, 0xc1b47255, 0x37df5bfc, - 0xa9a1c9ce, 0x4932e7e7, 0x613a6420, 0xf0bf36ff, 0xdfa151be, 0x70a6efa7, - 0x76eaf5a2, 0xa32fd2ef, 0xc5a95769, 0x24268d23, 0x8b6bccf3, 0xdefd2148, - 0x74112266, 0x5736dd6e, 0xfbce8d91, 0x0e535dcd, 0x58845149, 0x20f9339f, - 0xc421f015, 0x06b4e19f, 0x3a5225e7, 0x722fce30, 0x10b3fd2a, 0x55ef46b2, - 0x95ddf099, 0xb7eb4559, 0xccf830c6, 0x42e0cc1f, 0x157bec2c, 0x0b80975f, - 0x8c0a7f1d, 0xdce5915f, 0x2454fd01, 0x329bd846, 0xaff99e61, 0xebdc2999, - 0x823d92ec, 0x672b8d56, 0x579d0cf0, 0x79b84e65, 0xe2f1c06d, 0x44f8d963, - 0x7180cfef, 0xefb2f109, 0xf9216932, 0x3873f6c1, 0x1f77e9be, 0x3a864efb, - 0xd7f38273, 0x4d836fe2, 0xe861fac2, 0xa3ac116c, 0xc7cf98f6, 0x0f53ace8, - 0xe6799674, 0xd043e230, 0xeab6cfcd, 0xd5fd1531, 0x5fd88cd9, 0x708f4d9d, - 0x1a780cd9, 0x2c03534c, 0xcc1ba69a, 0xc7850f5e, 0x1f26f39b, 0x7e297292, - 0x20fa316e, 0xb4b7437d, 0x48dfca16, 0xe8b7e361, 0xdf216b74, 0x34859772, - 0x6e1d5e21, 0x376bcf98, 0x6a7e2147, 0x26bd1ae7, 0x9f8fcfda, 0x63de5897, - 0x67fa12f1, 0x72f66bad, 0x22e24768, 0xfe024fec, 0x738c075c, 0x4ae9fdac, - 0x51bf6e79, 0xb7a7dfa1, 0xf027fdb1, 0xe8c6db50, 0x0107ec4b, 0xbd3c20d7, - 0xf024fdaa, 0x8db07f31, 0x17a505d1, 0xcecd7780, 0x3349db08, 0x0102eb1b, - 0xe5568cfa, 0x6d93dbeb, 0xf3044727, 0xd007f035, 0x81620ec1, 0x79f2d679, - 0xeeb9d3ce, 0x6755fd83, 0x50341ff6, 0x0d1f16d4, 0x881f7ee0, 0xffd66b7e, - 0x0164fb3a, 0x0e93ab21, 0xadf62a61, 0x7f7aa861, 0x6f78e56f, 0x7bb69482, - 0x4d4dd382, 0xcbee1b61, 0xb80d939a, 0x19532d9f, 0x231cb35f, 0x133c508e, - 0xdebe43f2, 0x457db17b, 0x9964db64, 0x71e2bdc2, 0xfa44d6c9, 0xaba44fcf, - 0xa36ce224, 0xf5b67dfd, 0x0025a8f5, 0xc82eafdf, 0x37ae98a4, 0x3777ad82, - 0x3b5d3be7, 0xde91c029, 0xcc248c1b, 0x3fb72f7a, 0x01223be2, 0xec386b3c, - 0x1f2e9ebb, 0x17a529fb, 0xf6c1cecf, 0xcf92e8ab, 0xf6eb3d3e, 0xbbbce94f, - 0xcbb44c76, 0x4e4d3640, 0x7c409fa4, 0xa53b7d84, 0x4c99389f, 0x37de2895, - 0x351ebdb4, 0xfcfbb68e, 0x81f3a397, 0xf7cdbf6f, 0xe5e799fd, 0xbb9700f5, - 0x75ecf67e, 0x95e35e50, 0xce304d62, 0x95ffc7ce, 0xdea9fb42, 0x26100f51, - 0xd57cbf4d, 0x74f5a7e8, 0xfbec6dde, 0xa836c1ce, 0xf713f9f7, 0x6ef0075f, - 0xf2c26b6a, 0xc36c4f33, 0x7b3f6bfc, 0x683fdf76, 0x94675abd, 0x799dea1d, - 0xa5e23f7e, 0xc077a5d6, 0xeba2077a, 0x33f6bbcd, 0xe126d97e, 0x1973237e, - 0x2d74131f, 0x9ff3f7e8, 0x2a1b1e2d, 0x16f7c437, 0x833b9723, 0xcb391c98, - 0x994d6ff7, 0xb3d205a5, 0x85cc44cf, 0xfe8dbaf5, 0xcf9868ec, 0x1f174628, - 0xb6d47871, 0x2db831ad, 0xf9fb1ed8, 0x487bee80, 0x9e7d2873, 0x6b4ef4a2, - 0x0050b8ed, 0xeb0afde3, 0x11257ad3, 0x2f37be14, 0x7cc12e38, 0x18354722, - 0xbf9e706a, 0xd574e564, 0xebc5e5a1, 0xe96a3d18, 0x059b0be0, 0x907d8beb, - 0x4d32bbb2, 0xb2603e41, 0xd6ce3e33, 0x6aed5297, 0xd7efd2b2, 0x65d973af, - 0x4f97c78a, 0x4a9c9e1f, 0x211b3ff3, 0x65fe2015, 0x8f39c989, 0x5ba9c705, - 0xd04e465f, 0xd9a2eaf9, 0x11b0497e, 0x07c8b5fd, 0xd7ba31b6, 0xf205bd13, - 0x89f200fa, 0x072e16ba, 0x1279b077, 0x96632073, 0xae59db15, 0x83ce098d, - 0x3058b3b6, 0x29b8c81f, 0x678ee407, 0xc51dca2e, 0x233df388, 0xe4f101f8, - 0xee09cc2e, 0x711d04b7, 0x8c13fe01, 0x7e30b534, 0x4ffb4953, 0x8a4d2e8f, - 0x09a60a2e, 0x16b95883, 0xf2f0b74e, 0x923b451f, 0x3b5e01a2, 0x60f25563, - 0xdaf2be20, 0x6e4cddcd, 0xe91c72bf, 0x08740dd0, 0xaa4ebbe3, 0x6472f6e4, - 0xf70e94ae, 0x5c3a471c, 0xabf8cede, 0xb8d4bdbb, 0x259ba68c, 0xefe61732, - 0x7404f4e6, 0x9bf9a764, 0x7d71a3a2, 0xd9fcebee, 0x39baa7c0, 0x61ef75dd, - 0x4e86f6f4, 0xbcf801e7, 0x36e47db1, 0xf95a0790, 0x113b5528, 0x6f8a6edf, - 0xd67a0493, 0x67a0c3ba, 0x3b1355d5, 0x6ef757ec, 0x081a1fbe, 0x7b7707ee, - 0x2fe872e5, 0x5d9a6e35, 0x992f5096, 0xeef34a9c, 0xfb04525a, 0xd96b652d, - 0xd20ba01e, 0x20ab912e, 0x0ddced5f, 0xab8fafed, 0x2099cbb3, 0x9927b6f7, - 0x47ebfd69, 0xcdfb6314, 0xf4294ae9, 0xb620a9e7, 0x706f2127, 0x9cdb3ca1, - 0xf20ed23c, 0x88daedce, 0x0651177a, 0xb89ca1d9, 0xbea16bf4, 0x6c80b3db, - 0xe3ecc292, 0xcb03923d, 0x08de91bd, 0x3b7a7eda, 0xeddc7fd3, 0x139f1f6c, - 0xa1a911f0, 0xd78c1173, 0x788982fd, 0xbd9d20a4, 0x930a67b9, 0x509a2fb3, - 0x746d9ece, 0x34541390, 0x10568c8f, 0x358e02af, 0xa03a99ad, 0x9966425b, - 0xf8cb1e60, 0x4c0d5a3c, 0x3973446e, 0x9b2f7590, 0x1fbe72c7, 0x78eb4796, - 0xaffbe46a, 0x9b05c995, 0xe0e41727, 0x921e3e39, 0x73970245, 0xe5bae874, - 0xb527dc3e, 0xe2feb34f, 0xdbbc8e4c, 0xe855e842, 0x6c7a5a47, 0x6ca6e3e2, - 0x3301203d, 0xa55ad949, 0x57d7e7da, 0x5d3d5f13, 0x755bf5e7, 0xa8b989be, - 0xfc82dd37, 0x6c91837c, 0x77f7fa97, 0x5be3344f, 0x3cceb115, 0xcdd7e409, - 0xfa3fd416, 0x8720e9f6, 0xb8f4022e, 0x84dec97c, 0xea1670ab, 0x09d3bd68, - 0xede03b56, 0x5a8e1c47, 0xbdafab7d, 0xd19c0f46, 0x4325c9ea, 0x4186e969, - 0x549e0173, 0xa198b75f, 0xa7b68d9d, 0x8fb612f5, 0xf213627b, 0xf7ec26ab, - 0xeb1b68f6, 0xd859d627, 0xcb2e2c00, 0x27c98eb9, 0x7adc3dab, 0x9e85a3d2, - 0x074f28bd, 0x82db33f4, 0xafc7e1fb, 0xbd194b48, 0x01284151, 0x41fdb23d, - 0x5278fee8, 0x3d447a41, 0xf4e0ddca, 0xb647a786, 0xaf54dc5f, 0xd29b3d02, - 0x27a65ae3, 0x4fdb085b, 0xa7232e8c, 0x7c007932, 0x159f542b, 0xefbb54fb, - 0xedf6fd05, 0xefdccbfb, 0x1fb606dd, 0x801c29bb, 0xfce8fbde, 0x9be74665, - 0x48fdd036, 0xfdd137cb, 0xffc214d8, 0x981fe7b5, 0x04079c27, 0x73663dbf, - 0x745f0076, 0x19ab7f6f, 0x47f396c9, 0xc83fcbf7, 0x65de98be, 0x5fb4ca86, - 0xa1afdd33, 0xe0a663f4, 0xea63e6b6, 0xb9113901, 0x8947ad5e, 0x266883f4, - 0xdeb1bebf, 0xa3d24238, 0x55f1c3de, 0x007d73ab, 0x46f41e7c, 0x6324114a, - 0x131bd33d, 0xde00e640, 0x417a47b6, 0x20484e3f, 0xccc2e7ae, 0x67df3f67, - 0xfce29f02, 0xeac51090, 0xff7df2f7, 0x4ff7af29, 0x4b9c869e, 0x3a283f70, - 0x0f2271d7, 0x3b448f2c, 0x172c2f3a, 0xd73be9f3, 0x137cd998, 0xbedecaee, - 0xc18f0429, 0x3e75757d, 0x5eeb37e0, 0x25a97e9f, 0x8b908e38, 0xf981ba5a, - 0xf581fc83, 0xb81a8e54, 0x7e7eeb5e, 0x71d0d33e, 0x7b5fdf04, 0xb482b8a8, - 0x2bfbe0d5, 0x5635c7ee, 0x2522fa02, 0x9d2c4707, 0xe1befd57, 0x088d1f6c, - 0xeafb4364, 0x314dd758, 0x9331dfb4, 0xdfa0fef8, 0xa09ce0ab, 0x0c531e27, - 0xf5e0dde0, 0xd3f9e087, 0x8f7fd618, 0xe991ecd5, 0xd623b8fe, 0x3ded0d15, - 0x03eec465, 0xe5077339, 0x896fb027, 0x4df808af, 0x0147f13d, 0x5d58c79c, - 0xbf4031f1, 0xc9366772, 0xf257fca2, 0x63f7c2e7, 0x84b95111, 0xfb71f3f6, - 0x85799f6f, 0xcaf85ab6, 0x03df85b9, 0x22317afa, 0x18e2e803, 0x513b97d5, - 0x830656df, 0x944bddbe, 0xfc30b6c1, 0xcc0ba457, 0x20beb33a, 0x55663f98, - 0x7a442f9f, 0x6fc30c4d, 0xe214f9fd, 0x09fe8589, 0x627bbf9e, 0x1f5df614, - 0x56ea8230, 0x78833e7f, 0xeb1f7f68, 0x985b7548, 0x30c53771, 0xc84ddb7a, - 0xf7e570d4, 0x0f7671f1, 0xb030fb65, 0x7f02f24d, 0xe1bf5eac, 0x07e532cf, - 0x3eacebd5, 0xe831694c, 0x8f36d56f, 0xc7f3474f, 0xd11f8c0c, 0xc5cdb37f, - 0xeb47b941, 0x0e03c7e9, 0x4b20f43c, 0x2e52e0f9, 0xbc3596b7, 0x13d825f9, - 0x3cc4f5aa, 0xdcb3f69e, 0x4a983cec, 0x2cb33e8b, 0xbfb6028f, 0x25b73bf2, - 0x5c4a5c80, 0x32eccad0, 0xf40d9264, 0x4331c95e, 0x317910be, 0xfa8f4b3d, - 0xe29fe231, 0xe7188beb, 0x82f7c04c, 0x80f504c1, 0x7a45b705, 0xd07c213d, - 0xa5a1e1cc, 0x7eb84f9b, 0x767feda5, 0xfe81196c, 0x739ca23a, 0xdc163e81, - 0xcfc54e76, 0x53ff25ba, 0xad5d028f, 0x649fdab1, 0x433865dd, 0x623bfee8, - 0xc43af3bc, 0x675e4f53, 0xa04cfaf6, 0x87c640df, 0x30eacf60, 0x940a3cd9, - 0xa2cf111b, 0x291a9fdd, 0xe60ecbe3, 0x361e9e97, 0x196be819, 0xde0337b1, - 0x1244b597, 0x033f084f, 0xc3e81805, 0x3f609e7d, 0x3cde3b4b, 0xaddcfc0a, - 0x2c9d23f7, 0x8f105b35, 0x9c7af3ee, 0x74316907, 0x8a7b45f9, 0x8e5123fb, - 0x9e7d60db, 0x9f47c67b, 0x263f491a, 0x7eb8efd2, 0xfdf0edd7, 0xe228c8a1, - 0x4b78fa00, 0xf3a70ef6, 0x832b35ef, 0xeabc2863, 0x460e948d, 0x734e3763, - 0xd243fe88, 0x77fc6aac, 0xcc25f5bc, 0x65d9b967, 0xc2be3904, 0x32a7cf41, - 0x6457c9e0, 0xef8a151b, 0x9185f2f1, 0x45ef8f97, 0x6c7fbf7c, 0x661ff4a4, - 0xe1c7dd1f, 0xa5ea23df, 0x71f27db0, 0x0e7ea906, 0x4a686bd2, 0x943c7ddb, - 0x3e79f3e7, 0x604bd79b, 0x9f7c1df9, 0xeacb9c7c, 0xc5f1c769, 0x3b36fe30, - 0xe015b1d6, 0x8cf9db45, 0x22fb1740, 0x16b7a8bc, 0xfc077e52, 0xea3a6d6d, - 0xedaf94ad, 0xc4d97ac0, 0x4cf58d17, 0x03485728, 0xcfb07be5, 0xcf84148b, - 0x274a52a6, 0xd7b03cb4, 0x04aedb64, 0xa9f02af1, 0x8c7b63c5, 0xc3c9eff4, - 0xd43e9251, 0x61e5428e, 0xa3b30c7b, 0xd27f6118, 0x9e991899, 0x85f10c36, - 0x3e5f2274, 0x608c6ebe, 0xf4fba078, 0x7bd418b5, 0xfba1397d, 0x97c704e5, - 0x0f1f67e0, 0x8ab5e352, 0x5e6de1e3, 0x8d8c516f, 0x007b4fc9, 0x31c7ddf7, - 0x165c7eac, 0x0f424393, 0xcb8703ff, 0xc8549a4d, 0xd5533195, 0x1c4dc5fa, - 0x44c5379f, 0x087ebc09, 0x88f215f3, 0x345f17f2, 0x5e0b0fdd, 0x217f2135, - 0xb0d9031b, 0x63bd68ff, 0x2c0a6e58, 0xe472a58a, 0x18dfaa26, 0x22ddb1f3, - 0x3cefdf68, 0x85d04a3f, 0x3e9c8095, 0x1853d625, 0xe54f7e40, 0x296bae1d, - 0xba437ca1, 0xd037fe34, 0xd694c93a, 0xd8560c87, 0x03a64ef9, 0x208fed02, - 0xe147f40a, 0xb850e7fe, 0xc63bc76b, 0x319fe0e9, 0x96f11e92, 0x9f70f247, - 0x7585ffbd, 0x9cf2ed21, 0x51d1eccd, 0xceb8ffbe, 0xe9fa0175, 0xd42dfdba, - 0x7d198fcb, 0x3096add9, 0x63df46e5, 0xf2c1490f, 0x3d973fc5, 0x762fca46, - 0xe4fd7677, 0xa5eeba66, 0x861db29d, 0x5fe77a5c, 0x7a031ddf, 0x0ec1a775, - 0xdf2a46e7, 0xbcc3d5ef, 0x791e981b, 0x83a6a74c, 0x9f55dfb3, 0x1962d273, - 0x83dea8be, 0x3be09cfa, 0x4adf7e42, 0x5c81577c, 0x461c465f, 0x66b4ff48, - 0xe1420cd5, 0x0eb2c2b7, 0x6be7d1f9, 0xbc1ea1a7, 0x7cb07892, 0x4fe18b59, - 0x4561f2a1, 0xeabf3aab, 0x56fe7561, 0x67df3aaf, 0x2f0f2e7f, 0x32c7a7df, - 0xd94b3e3a, 0xb03fe03e, 0x3d05e4c1, 0x98af5b48, 0x3ca4cbd7, 0x24f813b1, - 0x4760fb95, 0x48e11758, 0x6ebebe04, 0xc5e2696f, 0xe7f57cec, 0x10de21af, - 0x37a8237d, 0x6c6f12e4, 0x63cb7eff, 0xf4238415, 0xe071f0ab, 0x2cb671bc, - 0xc6263afc, 0x10653d0a, 0x8bbe27f6, 0x45e3827e, 0xcfea3ce1, 0x8f98079b, - 0x5d9fdb05, 0x1b9c7e19, 0xa9b1c6fa, 0x7db064e4, 0xfc6b931c, 0xa3e82d1c, - 0x7e127cfe, 0x07a17917, 0x31a5db07, 0xd9a48afd, 0xf906454e, 0x8b63b094, - 0x224270fd, 0x3bb464e6, 0xebcfcfdd, 0x5fb05cf6, 0x083d009f, 0x6514e3f6, - 0x714e9f9f, 0x66c6f7d9, 0xf70687eb, 0x941d768b, 0x43f8ceae, 0x58b2eef8, - 0x6b8e1c6b, 0x57187627, 0xdba2fbd0, 0xe8bb062b, 0x6778ff7c, 0x546ba279, - 0x30f53f28, 0xe85189bf, 0x9c95165f, 0xbc391a25, 0xd42dfdac, 0x95bea8bb, - 0xd3e74c0d, 0xbd23b7bd, 0x04ce24af, 0xbd9ef3a0, 0xff5c33c3, 0xf315fc86, - 0x6259e599, 0x9ba79820, 0x2abfee98, 0x1d599f3e, 0x99d3ef4c, 0xc71c061d, - 0x025b1441, 0x7cd9a51e, 0xd3d4f329, 0xf9be84fc, 0x908e9183, 0x12fe7cf1, - 0x9df0a7b4, 0xd4b253c0, 0x36f30495, 0xbc74b8c1, 0x824de208, 0x5dac69b4, - 0xe4a27481, 0x3079b3d4, 0x0d264f3c, 0x675f5069, 0x9d6ccbf6, 0xd0090674, - 0x985e0fbe, 0xc6fcf2b7, 0x568bbdd9, 0x158b77c0, 0xcf9188f9, 0xe52c4763, - 0x2fe46687, 0xc9b75866, 0xfd1cfbe2, 0x94f53c64, 0x3d8fb829, 0x3bda0943, - 0x02369106, 0xe72c5ae3, 0x1b58b03c, 0x8f9049b1, 0xe0faf5b0, 0x66ce70fc, - 0x2346e8f1, 0x0b19dc9f, 0x677a527c, 0xf285e025, 0x19ff6665, 0xc3ef5ca8, - 0x73e0b773, 0x4d7e7c31, 0x1325cf9c, 0xe2588706, 0xb01ef1c0, 0x40419cae, - 0x49d65984, 0xd44b7ed0, 0x25eff454, 0x7969e000, 0x8abd54ec, 0xd53bc56f, - 0xeab9c4f9, 0x9d4bb27c, 0x3f93d337, 0xcf928be8, 0x16217499, 0xc02359cf, - 0xfce062de, 0xebcf99a2, 0x3d74a408, 0xfd3e71ef, 0xbb13f58d, 0x8eeebcfa, - 0xe3b41231, 0xd0cd9825, 0xde57d53f, 0xcafa658b, 0x97281e27, 0xf3cfc803, - 0xc0f9b626, 0x837cd3ae, 0x7e8bbf64, 0x1b2ab66f, 0x3d5494f4, 0xc76624d3, - 0xf54adbd1, 0x865b7cb4, 0xe689becd, 0x1d7ec1eb, 0xd5b7f30b, 0x49f68d3c, - 0x0247ab13, 0xdc8fe0cd, 0x8366c9b6, 0x81e5717a, 0x8bd046c9, 0x76db1057, - 0xbfbe8612, 0xce86fba2, 0x53c809f7, 0x5e9c48bc, 0xf3290f22, 0x7cbc0d71, - 0xc59dfc07, 0xe18b13f2, 0x65feca5c, 0x3a75e475, 0x90e0eec0, 0x77d62e51, - 0xa16ebde4, 0xcecd65e3, 0xb3bc3b43, 0x0973f99c, 0x3463f7df, 0x905c6afb, - 0x8f3cb1ce, 0x707587e7, 0x899c6ebb, 0x746d6bf9, 0x36666288, 0x8c71fac0, - 0xfc44edfe, 0x5af2fb63, 0xfd07fc12, 0x47fb0795, 0x5829343e, 0x7467dc1c, - 0xbdb37ca8, 0x1bd696a9, 0x87edf7a3, 0xa78e3c7d, 0xa37d3c79, 0xbf9406f4, - 0x628b3a9d, 0x6d7db1d4, 0x861302ce, 0x14b80653, 0x04d07edb, 0x7c904cfd, - 0xbd4c6698, 0x5fa609bf, 0xd147edc5, 0x06ef4649, 0x12a68eba, 0x77b4678a, - 0xd820f9fc, 0x4907e5a5, 0x88e9e001, 0x0739c841, 0x7a15d39e, 0x3a1afb1c, - 0xfd406c98, 0x2a932ffc, 0xd5013bf0, 0xd2bbce8c, 0xbe2116c6, 0x755f2c0f, - 0xe36a3f28, 0xb337e464, 0x6abf32a6, 0x57b35cfd, 0x10ce4092, 0xbbd277e6, - 0xb10a6f32, 0xc43f0897, 0x773206fb, 0x44f39857, 0x4fd31c6d, 0x3b3066ab, - 0xa346fd6f, 0x1d537fca, 0x335eecc7, 0x8c8f26e3, 0xfcc47943, 0x5c7179a7, - 0x46411b6f, 0xe10a9f00, 0xaf504523, 0x81edf4ab, 0x9cba8cf8, 0x8e3999f3, - 0xfdea0302, 0xbe08df9c, 0xf6c41cee, 0xd2423cf3, 0x9367ae81, 0x87ffe406, - 0x7e456f4b, 0x18f11373, 0x951f6f00, 0x310278b1, 0xd55359ef, 0xa71cd27a, - 0x5cf37f3a, 0xf0c51ead, 0xe79dc621, 0x09579752, 0x5aaa783d, 0xfff05e0f, - 0xb9468abe, 0xdd54f89a, 0xe7e02185, 0xc000f660, 0xe873f30b, 0x1bdc6e91, - 0xbebc3f99, 0x388def3d, 0x127767d8, 0x4976cfbe, 0xb2ffd1cb, 0x82115a4b, - 0xaf5ad4ff, 0xb8647204, 0x987dd855, 0x7934e4de, 0xc3df83f7, 0x91128359, - 0x49e3cebc, 0x493c400e, 0xadbe907e, 0x57165665, 0x30b51c41, 0xa45b349f, - 0x16fef41d, 0x65da3e5d, 0x2aaca25b, 0x0da6fa3b, 0x13d4054a, 0x44c558f6, - 0x6e9c6df2, 0xd7779dc2, 0xbafe31c5, 0x71766259, 0x9e333ccf, 0x9cb3e32b, - 0xbc413f2a, 0x9d828e4c, 0x229c6470, 0x63fda3ea, 0x5c95c1b3, 0x44af5340, - 0xd2171197, 0xd11b265e, 0x4fe1a8ae, 0xb476b1f1, 0xce0fc7eb, 0x9cfd3b41, - 0x2fb43c8e, 0xfd844b12, 0xffd8292a, 0xf4dbd99c, 0xdf53a710, 0xdcbf4db1, - 0x7bbba412, 0x8d5cb8e2, 0xaf409124, 0xe7ba767d, 0x7ba7684c, 0x5ffce75c, - 0xa35acba0, 0x2171ed0f, 0x07df8af4, 0x38ab8b92, 0x9cca18bd, 0xf9d056f3, - 0xb46bbcf5, 0x1d19f9c3, 0xe7ffb46d, 0x9da344f7, 0x50455f51, 0x652c6d3e, - 0xec07a47c, 0x9f1d745f, 0xf9e35745, 0x8ad4a360, 0x663ba3f2, 0x6af1d232, - 0x073c01cb, 0x74a56f57, 0x569f2218, 0x6be750ef, 0xdf9e2748, 0x47ee9f6b, - 0x0517c8cf, 0x56ef761f, 0xd4c323b7, 0xcb8f377c, 0x7da77c8b, 0x7d4c0556, - 0x9d8b3dae, 0x8641e9c3, 0x1de8a3ae, 0x2eefb723, 0x008a9db0, 0x7494fb56, - 0xc7adfd31, 0xfb665a7a, 0x2283c99f, 0x6e568e3e, 0xedbd7115, 0xe0bfca3a, - 0xb0f42afc, 0x07f2c222, 0x92721d74, 0x42df382e, 0x7fe84ede, 0x7c084e42, - 0x52109695, 0xa743f742, 0xc9434fe0, 0xed37c050, 0x0489f71f, 0xd8314391, - 0x7dce07bf, 0x9478f8e3, 0xb7203c1e, 0x17b33a3d, 0x6a59abe8, 0x06693940, - 0x9ba69f3d, 0x83ca1724, 0x323daa97, 0x692c7bc0, 0xd6833598, 0x8cee6f1b, - 0x3a513804, 0x3f4a1239, 0xb197c44d, 0x11d1524b, 0xbf457796, 0x848e961d, - 0xc47df33c, 0x74e998f4, 0x054fd0c5, 0x7a687e38, 0xc8e76240, 0xeb1f9629, - 0xbadbfda1, 0x53274869, 0xf30f5789, 0xf1a9b0ab, 0x9d49253f, 0xa3f4a69f, - 0x70c38c0f, 0x1f4e7870, 0x08772ea1, 0xfcd4477e, 0x857c932e, 0xc1f9187a, - 0x5d80efc1, 0x193d7221, 0xd50dfa01, 0x6a1f7144, 0xb8ebe0e9, 0xf26fdd6f, - 0xbf185c75, 0x13b70f49, 0x2bfc4b5f, 0xd3fa969f, 0xeb1bf759, 0x7a10a4e5, - 0x65e2fb14, 0x907f8b03, 0xa9fe655e, 0xe5193312, 0x642afa03, 0x3fb14576, - 0x8cfa05ae, 0x315dd209, 0xcf119eff, 0x19086ce9, 0xa1367402, 0x5327c23d, - 0xfef1e4bc, 0xcbba05ae, 0xe223ea0f, 0xd254d15c, 0xa532be8f, 0x705fd42c, - 0xa47d09df, 0xd26b6a40, 0xb91f0267, 0x1be609a7, 0xe3434f42, 0x512f808b, - 0xda7dc27a, 0xcbaace4f, 0xf026f435, 0x52e5f42e, 0x367480d2, 0xea60a75b, - 0xf2855cab, 0x5b32dcb5, 0xacdfed0f, 0x0936f462, 0xea0b31e8, 0xdca5e9ab, - 0xe96bceac, 0x0ba88e91, 0x9f4b571d, 0x10dbd103, 0x5f2137a0, 0x6f4d2f63, - 0x75bfe3d3, 0x7f1e9b7a, 0xd2d37a11, 0xbb5fe099, 0xa0e56c22, 0x4b57d73f, - 0xde0a0f28, 0xf904d61d, 0xa89975e1, 0xb68aef4f, 0xdf5d7ea3, 0x3b0bcac0, - 0xbdc4321d, 0xe5e3ad64, 0xc872ce99, 0xe5a7afd7, 0x23a2ebb4, 0xd8662e2c, - 0xef3cac9d, 0xadd786ae, 0x587867a0, 0x6f3f97fb, 0xb968a396, 0x2fb799b7, - 0x7c872d6d, 0xff6b0b7d, 0x46a9f819, 0xb79a7c43, 0x7d5fbe09, 0x1d9da66f, - 0x3efe99ab, 0x9777af91, 0xd8ebdcf4, 0x5bb595ae, 0x883cd075, 0xe99ff9e0, - 0x75f1d7e5, 0xd6cadc4e, 0xfae27719, 0x8ba50aa9, 0xea0f0115, 0xb574a76f, - 0x06dfc8c5, 0x4a973f38, 0x4e9069ad, 0x5217eca1, 0x22ded987, 0xcc7e650f, - 0x7b8874ed, 0x45fd99e2, 0xce20fff8, 0x9f4432a0, 0xd99e27b8, 0x84bd4563, - 0xa0018a18, 0xa8ac4787, 0xa4ff0b5f, 0x812221ef, 0x723587bc, 0xbfac243d, - 0x03564a72, 0x865311ea, 0x5fa53f08, 0x9b8e94bf, 0xc98be177, 0x3f43ece1, - 0xe69ee3e2, 0x7a7d1371, 0x075337b2, 0x880bb174, 0xf4800524, 0x7f41afde, - 0x487e05db, 0xa43ca426, 0xf2caf004, 0xbd7fe35b, 0x853c65a9, 0xef41aeaf, - 0x2196a101, 0xccc9dc61, 0x1c1be24e, 0x53fe7fd5, 0xc467c4f4, 0xff362638, - 0x1e544d95, 0x7e31d123, 0x8fe38736, 0xe90abf8c, 0xd3c73677, 0x2a7f05cf, - 0x9fc00520, 0xddbc70e6, 0x347aa664, 0x8356c3f2, 0x133c6f86, 0xcb6a720f, - 0xbabbfa80, 0xaa57c35c, 0xb92bb8f9, 0x092b7ede, 0x4a727ea0, 0x7a7a62f2, - 0x6bdbd30b, 0xbf50472c, 0xe98479e9, 0x8fc4b5ed, 0xbed68ffa, 0x9d53b359, - 0xe7536baf, 0xf9d5dbeb, 0x8e0f1c9e, 0xaea5b3d3, 0xd58aec18, 0x768bbf0f, - 0x5fc16aec, 0x42fe6abc, 0x5fc67115, 0xed06ba1e, 0x6f98df51, 0x6f4f4d3c, - 0xd0b8aac5, 0xfa9c02df, 0xb22f35ec, 0x613714f8, 0xeb1e8276, 0x4e70f988, - 0xa4791a25, 0x9c7927e5, 0x86fb089f, 0x84792fe0, 0x8e7a23c9, 0x8241d77d, - 0xd7ab5c7c, 0xbd73c4f5, 0x84d39f97, 0xfa0793fe, 0x35d3d00f, 0x4164480d, - 0xdb7f6439, 0x9fc88724, 0xc0668579, 0xee99be73, 0x6c978067, 0x545971c9, - 0xca05f0f4, 0x7bcf8199, 0xbd0d72ea, 0x2dd6f388, 0x81665e9c, 0xff8e8527, - 0xe781c97b, 0x32b7c3ba, 0x5963997a, 0xd1faf487, 0xe22f466a, 0xe7e577dc, - 0x4dfc873c, 0x747d79ce, 0x5ef54112, 0x17491e9a, 0x8fe67ce7, 0x1d1897af, - 0xf87d55d4, 0x82cfe818, 0x246e1c2f, 0x3e10faf1, 0x64cd34d1, 0x934a3b06, - 0xaa839d81, 0xbc5c7fa6, 0x38cf8434, 0x13134a22, 0x88ee5940, 0x5d6cfb47, - 0x669c7aa4, 0x7fbbf3a9, 0x4fd2f380, 0xd44ed123, 0x954130fb, 0x70eb77a4, - 0x6b3edb8c, 0x31527e60, 0x7707559f, 0x7ec3f3ee, 0x08ebff5c, 0x359f953d, - 0x5ac5f792, 0xe4c4b65a, 0x6a7186ca, 0xb3233e74, 0x5fa27663, 0xb03b8c57, - 0xf283d65d, 0x931af8d5, 0x106901c3, 0xefd2e1c6, 0xb5fea1d9, 0x4f8c89d1, - 0x2aeb11df, 0xca0f8848, 0xa43f614b, 0xc6a49652, 0xc126fd04, 0x376606f8, - 0x5c710bf9, 0x6361be32, 0xb69e7d88, 0x568f1b0f, 0xf5f8c096, 0x61ce29f7, - 0x1da307de, 0xd39f30e5, 0x9a7b8fdc, 0x474efdfb, 0xcce03f31, 0x752cfabe, - 0xf734f4f1, 0x518e9e13, 0xbd4487fb, 0x8ecc09a5, 0x6cd1b272, 0xbf07a8de, - 0x1c6f313a, 0x21ec4946, 0x93c60353, 0xea78602c, 0x6dbd13d9, 0xa5ff8853, - 0xfbf4a12e, 0xd87f9f30, 0xba43379c, 0x31b8f5bc, 0x23df0ed4, 0x0f77f3b1, - 0x089e97a7, 0xeb718a96, 0x0fbf2a12, 0xe799ec78, 0xe5f63c47, 0x13bc8ac7, - 0xc099effb, 0xfe5f6bf8, 0xb84f2c3b, 0xf5d843dd, 0x69f7f207, 0xd0547bfd, - 0x044073b0, 0xfd6bcfb3, 0x3f050bf3, 0x05f9fee3, 0xec2d1f9c, 0x45827e60, - 0x4a9cd266, 0x247717cb, 0x946e73b2, 0x9fe55b27, 0x515e44f7, 0xcba0863c, - 0x3ecef49e, 0x2123f67f, 0xee3aecfe, 0xeb13accf, 0xdf5eaddb, 0xbadf0903, - 0x8481fb3f, 0x6d6cfe30, 0xa08bc3dc, 0xe20b0c47, 0xc18dad61, 0x2dae42ad, - 0xef6f7b07, 0xe8718272, 0xd65adf6b, 0xb5e0f604, 0x2a0b003f, 0xa7d431f2, - 0x079c38eb, 0x53bc575a, 0x9d951447, 0x4251107d, 0x8aec9fe6, 0x4351e551, - 0x4d03890f, 0xb5514ead, 0xaa186f4f, 0xfd643faa, 0x4cf2aa35, 0x9f2abe4f, - 0xaaad72d5, 0x65ad55fe, 0x87f0fcaa, 0xcfd557af, 0xa3074323, 0x0c90ecfd, - 0xb57221b6, 0x3e554ab7, 0xaa2de772, 0x86919ff6, 0xbd69e3cd, 0x79fe42dd, - 0x8aa39d1c, 0x39ce7183, 0xed554b6d, 0x62b6a49b, 0x9f46f01f, 0xbd6893e4, - 0xcb5f1c15, 0x62ff993b, 0x556afb74, 0xd8a367ff, 0x5fad183d, 0xa32e7696, - 0x912ed61e, 0x7efea447, 0xfb8eeada, 0xa8ee219b, 0xf296bfbf, 0x356eda4d, - 0xfe80bf3d, 0x8e6fd5a6, 0x5d3f7026, 0x7461490a, 0x0b0ba5ad, 0x5bbd7fea, - 0xe627b465, 0xc687ec91, 0xc40cbc23, 0x5fc7f4ab, 0xae76612f, 0x76ada7de, - 0xf559ff88, 0x47a432d6, 0x2e9a9253, 0x5d351422, 0xd3508e44, 0xa6aed585, - 0x6a25c183, 0x3dc2d03a, 0x0ba6a1da, 0x43ffa7e2, 0x2ae02de0, 0x553b1ee0, - 0x785a374d, 0xda0093e7, 0xc95eddd9, 0xfc6123ee, 0x70dbede2, 0x1fd2975d, - 0xf86a89f5, 0x34701c16, 0x2c6e1059, 0x61e84cbe, 0x68ffae26, 0xaf4213fd, - 0x7ae44b89, 0xf847ef15, 0x0f259a17, 0xfe7d51ea, 0x865f12c2, 0xa7f4132f, - 0x44ecc206, 0xf0c4a4ce, 0x3efc4676, 0xc0519d90, 0x2620f675, 0x03886b2f, - 0x882be1ed, 0xc9ddf90b, 0x3ed15bca, 0x63f2cab4, 0xad9ebbf4, 0x35527a62, - 0xbf9f22f1, 0xaa02b8e2, 0xfb109287, 0x528e16ab, 0x02b3e487, 0x20f2e1bf, - 0x79087485, 0x1378c2e0, 0x62e6864a, 0xad471f95, 0x30df82e7, 0xbd097f84, - 0xe0278c57, 0x189af829, 0xe41a44cf, 0x1a17d824, 0x6846473e, 0x3b6a48fd, - 0xe0f3b08d, 0x22fe2160, 0x44265dad, 0xe9916e0f, 0xcc90f238, 0x57f14226, - 0xdda07360, 0xce7488af, 0xe625ef87, 0xc2bd26b6, 0x935713ed, 0x80c4fb3e, - 0xfe12eaf2, 0xc91e59e8, 0x7f6668ff, 0x6bf0b43f, 0xf89fe5d3, 0x5e3c6d03, - 0x55ef1052, 0x078f0f2f, 0xa76fea7a, 0x857d1fb4, 0x02eb23f6, 0xc3f6a1b1, - 0x9206fbbe, 0x1373d71f, 0x424ddc71, 0x693710f4, 0x133f3c9b, 0x4e54c4ec, - 0xecca4146, 0xab5da458, 0x8ed1eb07, 0x012ba3ac, 0x2121afba, 0x60ccda7e, - 0xfee5e639, 0x74371179, 0x42e27d29, 0x3fc78da2, 0xc22778b0, 0x5f38a0f9, - 0x139e740e, 0xcf701471, 0x2221fc16, 0x9139a84e, 0x4973839f, 0xf74ff42e, - 0xb444a6db, 0x29fdd01f, 0xbec7ee85, 0xef2c22b8, 0xeb351fb7, 0xb2147117, - 0x42ed10b5, 0x7bd742cb, 0x7a10f019, 0x3ea86fcb, 0x1234f780, 0x0dd7a615, - 0x0381f63a, 0x553b0b8a, 0x46f59e71, 0x7b01807a, 0x8e3c8bc1, 0xafad4daf, - 0xe3c89b3f, 0xe739f893, 0x181af052, 0x4eee3c1f, 0xf532e3e0, 0x27771130, - 0x7f42f8e0, 0xc151efb8, 0xd8bcefb5, 0xe13df707, 0x72e02ee0, 0x29f3a8ae, - 0x3d6c97c0, 0xeef00092, 0x83ee7288, 0xfd47e9fa, 0x705d24a7, 0x1772155e, - 0xb6f6cbc6, 0xcf3f78cb, 0x5bc5813d, 0xc8c8f7b9, 0x4c3bba1a, 0x6ead37e8, - 0xc2f51d7f, 0x68ca46ae, 0xa6761ea9, 0xbfa90e91, 0x0340bd88, 0x47ce81ef, - 0x681f3d62, 0x75e22fd6, 0x7f7f3ae8, 0x3efc3809, 0xe42a1c1c, 0x9ee18351, - 0x919c5f57, 0x1551903e, 0x75da1f42, 0xb0f4e66c, 0x013cef56, 0x4cef1dfd, - 0x55fd0cdb, 0x53071dc8, 0x24eb3e00, 0xd1357fbc, 0x26cbeec4, 0x2574fbf3, - 0xdc3b06fe, 0xb34a4e37, 0xe1a9fde0, 0xe09d91df, 0xdd78fe17, 0x4f70316d, - 0x5c3ff44c, 0x4efde1d2, 0xe4fb9e42, 0x57f0428e, 0xa26fb02e, 0x162685b9, - 0xddf99197, 0xe5165f48, 0x891aaf23, 0x61a3f619, 0x6bde0368, 0x68cb4409, - 0xc9938cb7, 0x313ba024, 0x561f716f, 0xfafb877c, 0x7c52ef70, 0x2814d89f, - 0x0ed34b58, 0xdd620f4e, 0x0503cb13, 0xfc20960d, 0x16a65c45, 0x3c385b3e, - 0x66c6f1dc, 0xcdbb17d0, 0x52c9fce2, 0x9f23d362, 0xfb666759, 0xe255d8e6, - 0xc2b3edfc, 0xe11dd4b9, 0xf6063c18, 0x7932fbdf, 0xb17f2692, 0xe3470639, - 0xc7d415fa, 0xbb58d9d7, 0xbf071e6e, 0x44b2a3ee, 0x6f8e5f88, 0xa66f1f0a, - 0x5c73b124, 0x8beff72d, 0x1f7ab5ef, 0x42d58dc6, 0xf04176bc, 0x6bc695fb, - 0x01fc788b, 0x27ad10e1, 0xef78d1fa, 0x7ab179dc, 0x0e4bfcaf, 0x3ebebe7b, - 0x0fe22749, 0xcf4defd1, 0x0be3615b, 0xf9d8934b, 0xe807182a, 0x7dc37bc7, - 0x4a7b85f1, 0xce45c913, 0x0ef3eefb, 0x889fdc55, 0x9f9f7737, 0xfd7e7184, - 0x29fda5fa, 0xe15c6096, 0x92dff040, 0x86e5e6c8, 0xd082bf78, 0xdefb0aef, - 0x8f1c4e37, 0xc147f3df, 0xbb45fd3e, 0x7feaf78c, 0x75374871, 0xd779987b, - 0x5db83127, 0x7dc7af13, 0x1c47d233, 0x2f8cc2db, 0x35fb89ea, 0x76aa9ee2, - 0xfccbbb7e, 0x10fe608b, 0xbc6e1c47, 0xc48e9ca5, 0x30c777bc, 0x99f7b87c, - 0xed059ef0, 0x77bde317, 0xe257f8c7, 0xf1a9b0be, 0xd7b73b7c, 0x9fdebeec, - 0xa6bcf781, 0x40c33b31, 0x728de0f4, 0xd8f504fd, 0x4a65699b, 0x06fac53f, - 0xffb216c9, 0x410f452e, 0x7854ebb8, 0x23770fed, 0xfbf457e2, 0x4fbe61f9, - 0xe702c389, 0xbe5c25b7, 0x8351d92d, 0x1f38affa, 0x8cb0fe7d, 0x139f17f1, - 0xbcf927e6, 0xcff3c255, 0xeb211752, 0xf95a1f29, 0x88334164, 0x844925b9, - 0xbec3175c, 0x46e909df, 0xf97c9fb5, 0x87ecfdbd, 0xaeae5424, 0x57280d20, - 0xdd58fe56, 0xfbdc9aae, 0xb49fd067, 0xdce1fbfe, 0xb1d6272e, 0x479e8939, - 0x2629ef40, 0xd61f20c5, 0x3185f93e, 0x1f78194a, 0x777ca69c, 0xaff81e98, - 0x46aed319, 0x48bfa61b, 0x44963c72, 0xc927b7f1, 0x9ed20db5, 0xbdff59f7, - 0x7e4cbdb5, 0xb9438d6c, 0x2efd64d5, 0x087975f2, 0xc0f7ebe3, 0x1e14093b, - 0x97d31326, 0x720d7412, 0x5e2dea14, 0xf1e387a4, 0x6266aa6b, 0x74049ede, - 0x29cbf71f, 0xefce3153, 0x800e9197, 0x4752a6f7, 0x3625d81e, 0x997bb255, - 0xb3f31366, 0xf6317f7b, 0x0c837035, 0x0cbfbb6b, 0x8eb6c1ce, 0xf7b03efd, - 0x7cfee8b4, 0x5a57e210, 0x8bf163ae, 0xfeff3a09, 0xe2f190d4, 0xe049bd23, - 0x691f8f87, 0x388f38c4, 0x21af34b9, 0xcdca5e24, 0x9edbd171, 0x1ec27685, - 0xb61bb083, 0xa8bde045, 0x8183a1da, 0x18435c8f, 0x1bdc459e, 0xdf5421cc, - 0x8470a2ed, 0xbf914ba0, 0x19f24da6, 0x12fdf0a2, 0xded4e3f4, 0x0f984be5, - 0x7ae7ea72, 0xf98983f4, 0x5c9abdc5, 0x212efe06, 0x364be69f, 0xfae34766, - 0xfe223cfc, 0x5cd97f31, 0xb8f3274e, 0x923f3f1e, 0xb1297bc1, 0x5bbb4067, - 0x474a24cc, 0xf2fcd4b7, 0x675c22b6, 0xf41a218d, 0x19f7e105, 0x6f08cf58, - 0x653f72ff, 0xa58df765, 0x72743640, 0x62e7c286, 0xf9c030fb, 0xdd9b3bb2, - 0x88c323bb, 0xee8cfc03, 0x81b7c37d, 0x8834c27d, 0x7f29aff9, 0xa3e49732, - 0x73866d5e, 0x44afadd4, 0x2f22f8f0, 0xc8ec4fbf, 0xfa9cf883, 0x8c7cb4aa, - 0xc01a3913, 0x0dba3777, 0xc7dc0cfe, 0x5448ef94, 0xf2da0e36, 0xb87a19fd, - 0xf54299af, 0xd92f9a35, 0x0fcb2f72, 0xd1d4aff5, 0x4f2d92fc, 0xfdd3d0cd, - 0x7fc6bee1, 0x5b35f20a, 0xbe7cb176, 0xf34ca57f, 0x655e5bcd, 0x4960e1f5, - 0x2dc1ec09, 0x68786707, 0xb9a267ff, 0xf1fbb7bc, 0xe5fbb59e, 0x3b50bae1, - 0xe332636b, 0x9db8675b, 0x59264cf8, 0x1ef0055c, 0xb2febe11, 0x5a0f1d64, - 0xac54c569, 0x4927b457, 0xf325dbe1, 0xf7e56e71, 0x924627a3, 0xb7e60896, - 0x3c5144f3, 0x8e18e81c, 0x93afc77e, 0x6e9e9862, 0x38fbe3f3, 0x4f011fa2, - 0x77189fd1, 0xe067c835, 0xac789acb, 0x3f8664ec, 0x1c46ce3a, 0xdd839867, - 0xcb4aae2b, 0xbc51fc03, 0xf4de39e9, 0x8dbbfcec, 0x1bf68fcd, 0xa0728b9d, - 0x07f8ec00, 0x33f5a2be, 0xd2d6f383, 0x93324149, 0x3136b72f, 0x3a206b7f, - 0x6269e90b, 0xa5677f24, 0x668ebd50, 0xe4c6870e, 0x466f7e68, 0xc2512bc0, - 0x1c389a71, 0xcf78fcd3, 0x5dd74af2, 0x775a1ff1, 0xf01cbe08, 0xf681ca5e, - 0xf5b3b7ab, 0xcd7bf0c4, 0xd4188cfe, 0xf557eef7, 0xa6836677, 0xb8c1097d, - 0x164c7736, 0x8227bfb6, 0xd93bf198, 0x332ed7de, 0xa0ade997, 0x2c778acf, - 0x123ae788, 0x7bec47ea, 0xc58da2af, 0x39d70667, 0xd3af90a3, 0x6369d7c6, - 0xe8aaf4eb, 0x64091c95, 0xa7f6b6cc, 0xf7f83ee3, 0x9f2a37f5, 0xe7daa7f7, - 0x7d83fae1, 0xd65e103d, 0xd6f93a73, 0xa9e622f0, 0x9c1f6781, 0xf013f335, - 0xed8dfd84, 0x52e9a946, 0x5926b3cc, 0xfb35939c, 0x8e1bf33b, 0xd5daca57, - 0xb9e2cedd, 0xeba6a289, 0x3a99ddba, 0xed102b88, 0x1027c16a, 0x3dffb41f, - 0x89edcc9a, 0x806d2469, 0x93c7c4f8, 0x0ddac28b, 0x9cf6bbf1, 0xe2cd13d8, - 0x8af6b5d5, 0x277b789e, 0x9cf4afdc, 0x8c0aef63, 0xc06fd8d3, 0x259cf4cf, - 0x5f282ed8, 0x9c73f9d4, 0x3fb7f63f, 0x7e603205, 0xe7b2a685, 0x47d53b15, - 0x7e431cb6, 0xecb8385d, 0x7f9a4cb6, 0xc88ff935, 0xcb530bcf, 0xfca4c8be, - 0x9fb27f7c, 0x7d9647e5, 0x5bf21431, 0x44feacfc, 0xefc0f3c7, 0x633fc789, - 0xaf507252, 0x41592d78, 0x3ae5c9b8, 0x02647402, 0xc7ae8625, 0xe309aaf4, - 0x075c04f6, 0xba4d0b4a, 0x6ff77086, 0x07a3eedf, 0x812957e6, 0xf3b0153f, - 0x5f803b71, 0xf403b2af, 0xdf7bb144, 0x8eff7b3d, 0x483e5df7, 0x1e027576, - 0x16bb23ea, 0x5dfcd265, 0x1fa09f91, 0x3dd0724f, 0xc515f601, 0xf9d01646, - 0x9c9b5d4a, 0xd5913fa0, 0xe11eb376, 0x745eedca, 0xfc28178d, 0xf3f7d95e, - 0x61b2a5ef, 0xb18f309c, 0xefd40f9c, 0xe06ff2fb, 0x633fadf7, 0x7af983b1, - 0xdb96c76c, 0xdb1aff40, 0x4c97f6f1, 0x39fbb30e, 0xc163de62, 0x97bf49ae, - 0xfe709bb4, 0x5eae3b63, 0xfdc7f501, 0xe80b23b6, 0x5f31c264, 0x9e85b013, - 0xaaa52fbd, 0xcf90e5ee, 0x39d71a2e, 0xc04ddfa0, 0x54aa53e3, 0xf478460d, - 0x857c7832, 0xf1dd67f1, 0x68fd9b87, 0x7fdf54fc, 0xfa3afaa2, 0x20c97b91, - 0xc433f83b, 0xbdad7a7d, 0x5d2568f4, 0x213efd1f, 0xa2106740, 0x6f3c4f4f, - 0x98248ca6, 0xaad1252f, 0x5939b97c, 0x96c2bf55, 0x929f2aa9, 0x7caab574, - 0xcaa7929a, 0x56311f4f, 0x7b06ff55, 0x637f2aa9, 0xfd5534c9, 0x2aa5474a, - 0x536be79f, 0xd4382fd5, 0x423f2eae, 0xfe43c064, 0x90ebfb51, 0xa0749d16, - 0x74f8b5d9, 0x8e90ebc3, 0x87030bfd, 0xed7c5ed6, 0xe1d7b6f9, 0x6b17b0bb, - 0xfb0933ef, 0xc5b2cdf1, 0x276f0c6b, 0x0567d24e, 0x75901fdf, 0x18d33eec, - 0x94eaebab, 0xa67de0a2, 0xa62f6089, 0x7c58a848, 0x00e347ee, 0x3d980b4f, - 0x062028ed, 0x68adbee3, 0x686a3c87, 0x2c0fe678, 0xf81d200e, 0x5cc084de, - 0x9e27bad5, 0x5dd6a977, 0xe0d56e4a, 0x5f2a8d69, 0x555dbb61, 0x06d24a7f, - 0xe534f955, 0xdd3c1a07, 0x60dfcaaf, 0xd3c1a2df, 0x7e9e0d36, 0xf4172aae, - 0x5aedc1dd, 0x451ec0fb, 0xcefef1d3, 0x75c3c072, 0x8f8803a7, 0x72d6ce92, - 0x47b5d3c0, 0x855f10db, 0xb039673e, 0x0d43e2cb, 0xa3ea43af, 0xf76831e7, - 0xa612635a, 0xb4151a07, 0x1c6c1d6b, 0x46a1e981, 0x75ff7e3b, 0xefa60963, - 0x7d303a34, 0xa62a71af, 0x4c4e8d9d, 0xb0db1adb, 0xed8d73fe, 0xdb162ecc, - 0x3a45def7, 0x75ba07d8, 0x8278377e, 0x77923f17, 0xeecbf003, 0xc86efe41, - 0x37ec45df, 0x25f9a24c, 0xbee844c0, 0x374f29fc, 0x80023aa4, 0xca1c3757, - 0x18f1828a, 0x1e473a6d, 0xa477e1e8, 0x3ea1f84c, 0x37bb909d, 0xd16c9338, - 0x79a66f2c, 0xb3c63644, 0x83a1f84d, 0x2033d712, 0x33a9d04a, 0xf7c806e1, - 0x7772b044, 0x401b84ca, 0xfec6ff0f, 0xff3f4773, 0x61291df9, 0x9ccfe7fc, - 0xd760ac56, 0x70d5fc39, 0x30e3c02b, 0x48396fb7, 0x4d09619e, 0x0679f54b, - 0x0747b390, 0x80f0b7b8, 0xe009b4ae, 0xcfb3a6d0, 0xebef78c1, 0xb7e8040d, - 0x5fe7624a, 0xca95cf51, 0x0dcf41e4, 0x1d4f3c26, 0x605639d1, 0x7814995c, - 0x3dbce00c, 0xdee112a5, 0x00640d63, 0x4e29bcfc, 0x3c0f8f96, 0xf243d926, - 0x079f0606, 0xb6fc6e52, 0x3858f3e1, 0x62913cf8, 0xcfb6fa63, 0x807a0e91, - 0x74a91fc8, 0x3e7ec1d4, 0x0ab8ea52, 0x4d38cfef, 0xad3aff6c, 0x3ed0abde, - 0x139a28e4, 0x9219e762, 0xd1f7606a, 0xd82262e1, 0x71916f3b, 0x39e16b9f, - 0x7be99521, 0xce702748, 0xe789179c, 0xf63a2382, 0xfeb6819e, 0xb3d70e02, - 0xe3dbc283, 0xbd32a616, 0xdd566ca2, 0xfed02f33, 0x6045d67a, 0xe1ce3dd7, - 0x34f58fa8, 0x342ae850, 0x8e70dd3d, 0x1cec9b95, 0x9dbfe824, 0xf2d17f0f, - 0xfb6e3a67, 0xfd68efeb, 0xda45d64f, 0xaed88651, 0xc2ddf841, 0x358c2f2b, - 0xb0b4fea3, 0xe40cbd2a, 0x07ee7ce2, 0x27d5645c, 0x1f503ba0, 0x1727846d, - 0x9af25b97, 0xcac90429, 0x3c234ab8, 0xb69d5525, 0xd5d219a6, 0xc237eec3, - 0xa3b52913, 0x1a833576, 0x70b7475b, 0xff3ff211, 0x5e748dbb, 0x0acbd78b, - 0xfb89cf3b, 0x145735ae, 0xf7e822cf, 0xa23b8f08, 0xeaf3c040, 0xd16f0e22, - 0xd787116e, 0x3fae1489, 0x0b9c90e6, 0x67d63f6a, 0x0b5def40, 0xc01ecddf, - 0xe72ea0cf, 0x4607e3fa, 0xfdf6ae36, 0xe2ee3112, 0x3afe7654, 0x0994a462, - 0x4c2de4fa, 0xfdcee40e, 0xba22aee2, 0x9b0edcfe, 0x1615e30e, 0x7800bdd7, - 0x78e76de8, 0xd8769034, 0x4b3cb34f, 0x221df93e, 0x8f754e26, 0xd2f252f7, - 0x0f2b69de, 0x7e859795, 0xbca87967, 0x96b4092c, 0xf2145c83, 0x7d4ff851, - 0x2f9cd58d, 0x3d3f2037, 0xf31eb8d0, 0x983d1b07, 0xe16c6a1e, 0xcb15b97c, - 0x987c69df, 0xe72f65f3, 0x7bf13bcb, 0x4c5ce347, 0x58ba35f7, 0x9519ca3e, - 0xecc4fb0a, 0x37c4f8c2, 0xf80898b6, 0x4c3b7ae7, 0x77419f18, 0xc68f63c4, - 0x0991fc41, 0xe36a71ef, 0xbe7cb490, 0xf7761e8f, 0x0525377b, 0x1f8be9c6, - 0xc8717d02, 0x9874f4c0, 0x4be05628, 0xe4fe8ff9, 0x0fafd006, 0xf4158a2b, - 0xcdd482e9, 0xac50ef2c, 0x7c2f9a06, 0x8a5de794, 0x22ac04d5, 0x5be421f5, - 0x358a3d87, 0x1f8be682, 0x7b95887d, 0xc7f33a09, 0x06f5ba3d, 0x2259f00f, - 0x51fd801d, 0x449cce6e, 0xd79505c5, 0x5f6007a5, 0x325a494c, 0xcec5f609, - 0x63e90514, 0x00e1b29a, 0xd88fa7e4, 0xfaab87a6, 0x46de4b0e, 0x57165768, - 0x937687a9, 0x846cd6d2, 0xdd879376, 0x376d0faf, 0x8daed475, 0xdf619f90, - 0x74fd07a6, 0xf8b1f027, 0x2f223f60, 0x169f05ca, 0x3ba37271, 0x720f289c, - 0x0f289ddb, 0x66ca5c04, 0xf60dde57, 0xc976facf, 0x663cc126, 0x0a417d4b, - 0x86e89310, 0xbf2949f7, 0x97f53ebe, 0x5db40dd6, 0xc5afe43d, 0x7c370ffc, - 0xa6fbfcbb, 0xfbfc30d4, 0x41dfbe43, 0xfbdc43de, 0x0ef64687, 0x2e1c33cc, - 0xac4b1df5, 0x712a8ef8, 0x7acf4159, 0x97f3cb9e, 0x9fe5a520, 0x7f8bb4f1, - 0x70e7407f, 0x52ab38c1, 0x3fb21fb9, 0x6549a87f, 0x8f735ffb, 0xce728064, - 0x6d52ea1f, 0xea3cf7aa, 0x76bfbb08, 0x6d3b38a9, 0xee36b89c, 0x3b693564, - 0x1fecc8e8, 0xf70b526f, 0xc7fab2dc, 0x6a788b7f, 0xdf781c6d, 0xe3106ab9, - 0xd78173a7, 0x496eba50, 0xde4f901d, 0xdc38097b, 0xfd0e0e1b, 0x9c5843d6, - 0x2438bf7b, 0x5daeef1e, 0xb3c57117, 0xfc798d77, 0x827d76bb, 0xafaffa2e, - 0xcf5fc195, 0xbbf54fe0, 0x157e60c7, 0xec04ad8b, 0xe7fca156, 0x3fe11777, - 0x6df67e5a, 0x179bc9f1, 0x65bbe1d7, 0xf3d8f861, 0xb898f8e1, 0x854dafcf, - 0xf3f70a9e, 0xde121e20, 0x7e738239, 0x1f6ba265, 0x1653d3f4, 0xce0e9bf8, - 0xddec71a1, 0xaed183f0, 0x325df0fd, 0x1106b8b2, 0xe75a7c97, 0x6de815f9, - 0x19fa3def, 0x106eb3f2, 0xbc8f7416, 0x97a0f341, 0x7ce6c3fd, 0x4647e013, - 0xefa18df8, 0x7f140f8f, 0xff2e1bfb, 0xdf6ca7fa, 0x9ed43889, 0xa0665f6d, - 0xfb12eefd, 0x54782062, 0x70fde3c8, 0x24b7a43f, 0x9767e512, 0xdef07c44, - 0x02695771, 0xe95d2dea, 0xdfa43d46, 0x2bb8b9f6, 0xd7fb1b3d, 0x92bb8f9e, - 0xdc6ccc4b, 0x7d2153c9, 0x2154f92f, 0xf0dfbdc8, 0xa376cbf8, 0xb03de0a7, - 0x408d8f0f, 0x928dfeff, 0xa0e010bf, 0xbd77573d, 0xc94ca0b5, 0xa6be7fed, - 0xeb049beb, 0xbbae3dab, 0xe95dbe1b, 0xfd76bb79, 0xb9c408df, 0x15ff5b8f, - 0xaeeff781, 0x19ddfcfc, 0x5e80ab93, 0x12026ae1, 0xf545d319, 0x54bf9a09, - 0x8939d6fc, 0x4333d39e, 0x6f25e5ce, 0x9e2e38b3, 0xfde7cf6a, 0xed5c09de, - 0x960dc751, 0x5e308afa, 0xe147f645, 0x7b1d60bd, 0x73c4436f, 0xf3cfc9bd, - 0x243ebcf4, 0x9d70ed0d, 0xfaf3aa19, 0xfa2d1f1d, 0x0881f21e, 0xa678ef8c, - 0xcc3c44fd, 0xf19d8ff5, 0x0945793f, 0xedbd77d2, 0x9df4246f, 0xbdf5dac0, - 0x86d77caa, 0x7056fbe0, 0x5ff6ab1f, 0x2a25ca32, 0x4f105ac7, 0xdae335e4, - 0xda4af910, 0xef07dcfe, 0x55df94d1, 0xbe50c002, 0xd074cf36, 0x3cfc9576, - 0x8de44844, 0x92aeda0e, 0x67891f9f, 0xe78f2b25, 0xb09f3df5, 0xff28ba7c, - 0x7fac4ce3, 0x1c6fe895, 0x79164f2b, 0x22d5dfde, 0x9623789f, 0x25f68a67, - 0xc6239f2c, 0xaded64af, 0xade4feac, 0x7a099cff, 0x33f7e08d, 0xe09cb8d2, - 0xfe5152ef, 0xba2b4cef, 0xba8ebc68, 0xf107cb9c, 0x1dc5550e, 0x85df22d3, - 0x6126dc7d, 0x9ded61ec, 0x9fe7b406, 0x0dcb698d, 0xe22f2fbd, 0x56e59c7a, - 0x7baaf38c, 0x9976f871, 0x1e813bc7, 0xe9fb9cb3, 0xfa0b642b, 0x65ef7a61, - 0x3d207e7c, 0x97fae570, 0x57ecf855, 0x46d3dfce, 0xef1d2547, 0xf1130fdc, - 0xd619027e, 0xee02f189, 0x27c44934, 0x116abde0, 0x45971757, 0x8e7e701c, - 0xbd82297b, 0x13b27aa7, 0x97caeff9, 0x6ebb7d98, 0xef28ebcb, 0xda0aca96, - 0xea1ebe97, 0xe9f0075a, 0x2f77b2b6, 0x87dfae57, 0xc531f4fb, 0x8160fdc6, - 0xbcf0a151, 0x3dfc3fb3, 0x8517f169, 0x3ffcbabf, 0x5dad7f0c, 0x5fd7dc5d, - 0x7ff1857d, 0x07e656dd, 0xfd3c73b6, 0x7314a749, 0xf0023d78, 0x33a2b73a, - 0x20865a3b, 0x778c4eee, 0x29df90ab, 0x6f56f382, 0xde009583, 0xdccea5bb, - 0x5fe0c30f, 0x9f38ae7b, 0x69715441, 0xf7c3fb3b, 0xf7d04be9, 0xfa4dffd3, - 0x8dfbd44e, 0x1f1bf076, 0x15e5ef65, 0x18c9fe77, 0x4ef41f1a, 0x0f073b1a, - 0x317e676e, 0x2c171711, 0x713c32b7, 0xd55d53ff, 0xffc1e33b, 0xc4c3f624, - 0xfe06d248, 0x76d74a04, 0xa076d74e, 0x41bf416b, 0x176d143f, 0xfa41be06, - 0x912e2c25, 0xfdb7e9c3, 0x25e1fae1, 0x7fe1fae0, 0xa9bbae13, 0xdbfe8c3e, - 0x4ed02217, 0x3ff385a3, 0xbc055c38, 0x0e2fd323, 0xfff4c8e7, 0xd3239c0c, - 0x439d9515, 0xf9207bc0, 0x988fc5a4, 0x5a7d9877, 0xe9f64df4, 0x4f9c1923, - 0x8f18fde9, 0x4c7bc5ab, 0x27bc3f7a, 0xef1c5fa4, 0x30fff2ea, 0xd370b5de, - 0x9fdcb5a6, 0x985efdab, 0xfbbf203e, 0x7ff8e056, 0xb0b04fcd, 0x7caabf61, - 0x54b7faf1, 0xef3c4be5, 0x415f965f, 0x5bfffbd8, 0x57e105fe, 0x2afcf998, - 0xb51ff81d, 0xc43741f2, 0xc7a023f9, 0x7afe5f1b, 0xf93087d4, 0xb78c6cea, - 0xe5af8dba, 0xff7ff18b, 0xbe947be4, 0xf66068be, 0x3ffb63d6, 0xfd392837, - 0x79e165e9, 0xd084711d, 0xeff5c2d9, 0x5acf401b, 0x54fbd848, 0xa60ffada, - 0xc6307b33, 0x30be5149, 0x710c4cd7, 0x9dcc1f94, 0xcf4beecb, 0x0c630705, - 0x2d173ea6, 0x3e27a99f, 0xd2bb8f78, 0xd099f7a2, 0xffbea9ef, 0x75efe26e, - 0xd558b893, 0x21d9783d, 0x9cdf9c63, 0xbd2fe612, 0xf786d2c5, 0xba1de787, - 0x60f7dceb, 0x14f46f2f, 0x7177b8b1, 0xbaf7f0ff, 0x3e83f12b, 0x9c2a7a08, - 0x5fee24fb, 0xff40635f, 0x2addb6ba, 0xca669fbe, 0xd9a38b12, 0xc533e2c3, - 0x3beba4fe, 0xf767ca64, 0x48f7e060, 0xbe0c1b2a, 0x67a0b9e1, 0xbb3d47ef, - 0x2e4364be, 0x927eafe0, 0x1b94dc74, 0xafd4ef3c, 0xd7b60bff, 0x7a6d67f2, - 0x4fd5f6b9, 0xbd210f1a, 0xb1d17388, 0xb5e61f46, 0x1305d6f6, 0x93fd17ff, - 0x6de2ff63, 0x57dc7482, 0xd0c70f8e, 0x3b1bfb75, 0x827b2dff, 0xbb0823b0, - 0x214ed682, 0xbf7888f8, 0xe36e97d2, 0xa296b2ef, 0x59e883df, 0xc1edf82a, - 0xd7f9fcfe, 0x27d717e9, 0x61ffe5d5, 0xf4b97cfe, 0xe4c49b5f, 0x8fee96aa, - 0xed0cfd56, 0xb5be82cf, 0x6200bff4, 0x0bf8e852, 0x27bc25ea, 0xab55773e, - 0xcdf49c61, 0xe5b57de9, 0x9b830664, 0xb15c2e46, 0x3c78503c, 0x0be78c87, - 0x0ec6bc93, 0x87810f76, 0xefd5d3af, 0x48bc5303, 0xab971719, 0xfafff2ea, - 0xa2e4e039, 0x8917266f, 0xcb489f4a, 0xe56eb7e8, 0xfe56eb12, 0xb90eeb9b, - 0xd648b4a7, 0x40e3ef05, 0x81c435fc, 0xfdd978f6, 0x56ccead4, 0x5203ddfc, - 0x7e028812, 0x995eeb77, 0xde8e9efd, 0x790e4fa1, 0xf88bad3f, 0x5c7a003e, - 0x3bbd9e35, 0x769b8da4, 0xd5ea78f3, 0xbf78dd96, 0x9a0efb51, 0xf376cb88, - 0xa1efb4fe, 0x9de2f689, 0x687bed03, 0x1c783253, 0x67c93e76, 0xe7172971, - 0xcf20dda3, 0xdd35fc43, 0x5da2355f, 0x4ac7c6e1, 0x05a4f3ee, 0xa32732f1, - 0x9799df1f, 0xa3be7171, 0xd32fff2e, 0x81dd6caf, 0x94aed8f7, 0x3a64477e, - 0x827f40dc, 0x9bf1f72f, 0x6fc84c57, 0x3df33bc4, 0xf7c19e6b, 0x24be7a87, - 0xd4bd97e8, 0xbb13e33b, 0x09c435d8, 0x564dbd27, 0xc771d78a, 0x1baf683c, - 0xf785c47b, 0xe3bcc776, 0x927f8880, 0xc329c077, 0x233e85bc, 0xff209bf4, - 0x78d9f7e2, 0xf2e5d59c, 0x37f52bb9, 0x8cfca7fe, 0xb75d5ee2, 0xbf0457c1, - 0x13d9e0e7, 0xa103bf81, 0x1993ff9d, 0x93be8bba, 0x7ae511dc, 0x8b34f012, - 0x5ef109cb, 0xdecc8572, 0x94edef49, 0xeeb85ed1, 0xabfb7e7f, 0xdb4b9547, - 0xbd6dea15, 0x2265cf61, 0x7bb1d7ad, 0x0ae5f92d, 0x79c249c6, 0xc287ec0d, - 0x7fada89e, 0x297b294a, 0xe35bed03, 0xdeda3df1, 0x067cd987, 0xfafd57c2, - 0x603f8e00, 0x7ebf1f39, 0xf42d916f, 0x19f3959d, 0xdb43e77d, 0xdf107329, - 0xff174b97, 0x332dced7, 0xa891e265, 0xbc91cd7c, 0x4c25ef4c, 0x3a405dff, - 0x02445d31, 0xbb08ba98, 0xd894b0cf, 0x9c4e5d31, 0x5c55ae98, 0x3718195d, - 0xf8c04814, 0x39ff17d3, 0xdce6e80a, 0x215ae375, 0xf2dbf146, 0xbef56923, - 0xbd853c9e, 0x3fc2f497, 0xd9f4077f, 0xcb863ff3, 0xa2471be2, 0x1848641c, - 0xa57bd33f, 0x54d7bb32, 0x17dc5df2, 0x325dfde2, 0x96e1f989, 0xfee26627, - 0xc4cdf209, 0x826f826d, 0xb8e7393f, 0xdcc3c58e, 0xc67be12a, 0x6e1d7eed, - 0x99159cb1, 0xb9ddf85e, 0x3cacddf6, 0x2bda2ea7, 0xd8ce7cd1, 0x26be5608, - 0x4ff70bda, 0xee3f1216, 0xfb70c5cb, 0x4bfb8644, 0xdf8a2f8c, 0x8227a00b, - 0xbf6d12a1, 0xeeccc3a2, 0x30ff1051, 0x70b9ffe0, 0x4f170a7e, 0xf1f18433, - 0xbf1943d1, 0xb6a65d1f, 0xe5e50c87, 0xdf6529f7, 0x0cb47807, 0x810d6471, - 0x9b9d31fa, 0x3b042c1e, 0x9f808e90, 0xb7b1b3e6, 0xb4535fa3, 0x1b29517b, - 0x959ff501, 0x67bfbc58, 0x4c6fbf2f, 0xfea10902, 0x794ab5b1, 0x1a2bd42e, - 0x40d3f8c2, 0x51df8570, 0x2f398674, 0xd1d1f88a, 0xbb436670, 0xd277c13c, - 0x7e58959e, 0x6f5be3f2, 0x5f4168dc, 0xe3f40782, 0x44d71517, 0x91b46f18, - 0xffcc0b10, 0x1b7efca7, 0xbb00c869, 0x4cc7aae8, 0x3e2fd03a, 0xee18e2a2, - 0x9e81fcf7, 0x98fd21b7, 0xfd219b9e, 0x43373d23, 0x9b9e9c7a, 0xcf413d21, - 0x38ae90cd, 0xccc7876f, 0x8e2189c9, 0xf0bfd0b9, 0x5be769f7, 0xd7f18439, - 0x1af7f1be, 0x14fbfc71, 0x0fb7c217, 0xfe087bdf, 0xd1b3edde, 0x8b989481, - 0xdecf5bd0, 0x749fa3bf, 0xff08b820, 0x0a7cb6a3, 0x6eee6bc7, 0xdcffca3d, - 0xcad47f76, 0x872b7a90, 0xce7db118, 0xa0a3270b, 0x1f5b6eff, 0x5d121d7c, - 0xcb1d4cf2, 0xb9fc7caf, 0x828e371b, 0x0fbe3bf9, 0xf9f74174, 0xdb73486a, - 0xfc00fb7f, 0x1fed2a5e, 0xa47a24e3, 0x2f3c66c0, 0x85a1d668, 0xb3d75883, - 0xa09b9dd1, 0x0c2fb3fd, 0xbe509585, 0x01bed843, 0xadc2923a, 0xe7ae0377, - 0x10a05346, 0x78dd0bee, 0xa71b0e41, 0x8a529f7d, 0x7a064e70, 0xcaddfe43, - 0x025f4653, 0x7f74df6f, 0xe223fb6b, 0xa5e015fd, 0xafa5c80a, 0xac2f40a2, - 0xed04f1e4, 0x06fd87bb, 0x2439e9d6, 0xdabdf813, 0xfdea31d1, 0x49e38bb7, - 0x8d7b39a4, 0xb3d7c04e, 0x830d4f7b, 0x7e2989f7, 0xc57bc186, 0x455c86db, - 0x31ef7f42, 0x8f97ec67, 0xf587183c, 0xe769f7f1, 0x10156d91, 0xbcdf3337, - 0xd2580dff, 0x0af1db42, 0x9c599b88, 0x74841d24, 0x19399289, 0x7dc465e2, - 0x4a236583, 0x9a96c20f, 0x7d44af61, 0x4c9814ae, 0x37287c88, 0xd847f247, - 0x558a3c85, 0xa524a7e5, 0x534feaaa, 0xd3e554b2, 0x95548c47, 0xd867718b, - 0x46f5540b, 0xc28604c7, 0x83ae8e79, 0xa4ff03bd, 0x3986f18c, 0x7eb91c2f, - 0x7ccfcd24, 0x43be0e6a, 0x9f2f2cf9, 0x17b95cf9, 0xe143d1f0, 0xd50aa469, - 0x6c1f92e9, 0xd33a107e, 0xf76a179c, 0xa1d0713e, 0xe179c65c, 0x8184e712, - 0xed164fde, 0xca04e7b5, 0xbe001f37, 0xd9c5fa39, 0x3edbf036, 0x14cbf63b, - 0xcdfd4788, 0x0caefe10, 0x440c3f3f, 0x43fb7d37, 0xbcdd1852, 0xc3279325, - 0xf2440dd0, 0xe9643a32, 0x7eecc3cc, 0xb5f295de, 0xa1af814f, 0x4243c0bd, - 0x6b577f7f, 0xb46d1bdf, 0xb036e6ff, 0xc32bbd47, 0x7bbea50d, 0x6fe12b93, - 0x64ef4839, 0x93bbb6f9, 0x07bbf0e3, 0xb73761f4, 0xb8520df7, 0xffbb553e, - 0x60c2e4ee, 0x5c775939, 0x29dc9f55, 0x1bf2ab35, 0x7bf9d533, 0xdb439b4b, - 0xad8fa40f, 0xd189787c, 0x6ef70395, 0x37bfb0a5, 0xfff3e62c, 0xd5800901, - 0x00800020, 0x00000000, 0x00088b1f, 0x00000000, 0x19b5ff00, 0x6554540b, - 0xcef7bbfa, 0x7860190b, 0x77421028, 0x840a4498, 0xb0285789, 0xd71ea08d, - 0x8f4c1ada, 0xe5935654, 0xe04d7903, 0xe3d8f4b6, 0xb68fad18, 0x695b6d07, - 0x9656356b, 0xb139e4e7, 0x36254644, 0xeb495bae, 0x66a254d6, 0x42d899e4, - 0x7a26704c, 0xf75a9d6d, 0x5efffefb, 0x5b602e67, 0xe74ed69d, 0xffffef9f, - 0x27ef7ffb, 0x70ca1490, 0xf60800ce, 0x9970ccac, 0xd6f70601, 0x8018e41a, - 0xe2eff4d3, 0xf9b8daf0, 0xcf03837a, 0x3a380057, 0x01cfe3cc, 0x031401d6, - 0x7b81295c, 0x5914f3a2, 0xff60e760, 0x2fbdf165, 0x00490801, 0xde8d179e, - 0xe38456ed, 0x6e67065c, 0xf08d9ef8, 0xd918064e, 0xbfefff72, 0x25f5c22a, - 0x8c0ee3b0, 0xbd0d43c4, 0x5c75d79b, 0x9fcd7114, 0x77d1d704, 0x98809679, - 0x55706b80, 0x00e207b4, 0x3c636a9a, 0x679e3e62, 0x2e990e86, 0xa6f1c804, - 0x01529bb5, 0xc0228a8e, 0x78074439, 0xe3ef14a0, 0x245f041b, 0xa4ef39a7, - 0x67c8b9df, 0xe7c72fcc, 0x35b03245, 0xe99432bf, 0x7ed77bc6, 0xbf1ce787, - 0xce91a203, 0x8f4a803f, 0x2e5c4c03, 0x19bdbb04, 0x3f233ffe, 0x1812bd4d, - 0xf0619f90, 0x605aba1d, 0x25a9ccd7, 0xa7e92b00, 0x061dfb4c, 0x196fd890, - 0xb2957f70, 0xe57cb2bf, 0xf08b10a5, 0x2040fd56, 0xa70fbd9b, 0x7fd5fff1, - 0xf198376f, 0xda53f57c, 0x530f427d, 0xfbe52f90, 0x77b3f03a, 0x3de277eb, - 0x235ef853, 0x8499fddc, 0x697636ef, 0xc7245fbf, 0xe0e60d24, 0x3828028f, - 0x916db12d, 0xf1366bde, 0xdf4ae6f7, 0xea097bbd, 0xc925e9b1, 0xd1adc46e, - 0x00e2d3dd, 0xa83983f9, 0xf2f1d4e4, 0x7a8cda6b, 0xa7c30c2a, 0xbdf34b76, - 0xca175f74, 0x5e319ea8, 0xe2c960ce, 0x5f1c2cf8, 0x0bd7c573, 0xf735f101, - 0x7ed0d0e8, 0x1146cf00, 0xcf3c08e4, 0xf2ae31ed, 0x07f4c39a, 0xfcc79c2d, - 0x66132f9e, 0x1d75f2e7, 0x1ced01d1, 0x98bf702f, 0x093e8021, 0x60b541f1, - 0x5f4b8edf, 0xc925724f, 0x9f004fbf, 0x589ec05c, 0x5cfd4264, 0x7da39fc1, - 0x8fe02433, 0xe11d6c94, 0xfdc8a859, 0x7c7fd28a, 0x8b77e023, 0x434f167b, - 0xd750e00a, 0x0cd43eb2, 0x0c6d906c, 0xe8f012df, 0xf17d2f49, 0xa416f4ce, - 0x604932f3, 0x1f17dff6, 0x7f10161a, 0xd0b4455f, 0xeff7b026, 0xbe55f7a4, - 0x74cef4fa, 0x8e6be337, 0x26f51065, 0x4e902e38, 0x47978f47, 0x183aae58, - 0x712bf554, 0x9c7f2177, 0xfb3edd2b, 0xd1dbf412, 0x223160a5, 0x684b97bd, - 0xabc30838, 0x49ab8fdc, 0xae5133d6, 0xe8813f82, 0x6e17966c, 0xe4bbf191, - 0x97417bd6, 0x1d372118, 0x2f5533f7, 0xd3c71caa, 0xf72de2a1, 0xd1bf903b, - 0x9fb3021d, 0xecccbb46, 0xe4fcb1b3, 0x7f104b83, 0x0bb25fa3, 0xeeb2cf48, - 0x7e4847bd, 0x403b6b1d, 0xe7401e77, 0x2eb66eda, 0x527d9933, 0xd98be31e, - 0x414688ad, 0x6056ad7c, 0x7c35a7c6, 0x0c7be61e, 0x7c3f51bc, 0x3804ce06, - 0x9e7ceb18, 0xfbf35bf8, 0x1096fbcf, 0xe3ca1bb5, 0xad901f99, 0x3fa61b9d, - 0x466000df, 0xa3db43fa, 0x3c304fbd, 0x6125af68, 0x27b13d7b, 0x9e0b70eb, - 0xcf53789f, 0xc55f75cc, 0x416ea7c3, 0x68f6cd78, 0x0913e726, 0xf3a549e0, - 0x3d7ba627, 0x18a56178, 0xb9216fea, 0xb7d8c677, 0x47f1f9e3, 0x13bb3fa7, - 0xa767dae1, 0xf24c89d9, 0x7de5191f, 0xda011d3c, 0x7d953e7f, 0xef1c2907, - 0xa52fc50a, 0x57dc6667, 0x24cfe74e, 0xaa8f09da, 0xa347a1bf, 0xfaf2801c, - 0x16797c12, 0x8293bd34, 0x87c45067, 0xc79dc4eb, 0xdbcbb404, 0xc483ae0c, - 0xfe47eaf7, 0xf90ca87a, 0x37e67aa9, 0xfa44cf0f, 0x0c9bdf6a, 0xaf584ef4, - 0x6c40e2e3, 0xdffc9720, 0x915ffdc6, 0x288edd4f, 0x7111c7cb, 0x5e23a1a6, - 0xa7753703, 0x888e3e5a, 0x65c07537, 0x8e82f50c, 0xfc57a9f8, 0x1d745eaa, - 0x201aba25, 0x8422e3c0, 0x0557640c, 0x78a0e092, 0xc8c7ba10, 0xced63fe4, - 0xd1916546, 0x8b822f51, 0x224179e2, 0x6fc85298, 0xc17e5c5d, 0x713fa67b, - 0x9266ca17, 0xfbf54135, 0x223385ac, 0xf1bfb3ed, 0xcdcfb215, 0xc39f6646, - 0x8d2f3c51, 0x391ff3c5, 0xc2bf7d9e, 0x87f305f4, 0xf5a4f933, 0x17385adf, - 0x0aef141c, 0x9bc2e4da, 0xf4516d70, 0x29c52c72, 0x1dee4958, 0xc03aeff7, - 0xe6f5b9e4, 0xbf7784a3, 0x0e0fe999, 0x0507b970, 0xf7d5279e, 0xa0429856, - 0xb77a242b, 0xfdd57a31, 0xf3872dc1, 0xe0fef85c, 0x8079390b, 0xf24cbcf6, - 0xe505fe0f, 0x7fc62a73, 0x3b5c36ec, 0x853bbff7, 0x7a58e0f2, 0xd9475beb, - 0x2c3c2a7b, 0x4f5438f0, 0xf7fee07c, 0xa264ce99, 0x8b08c313, 0xcd77030f, - 0x2b9bf260, 0xfe91c6e5, 0xf4b42783, 0x7d53a58d, 0x7d4fa55f, 0xcd37bd5f, - 0x8e39322a, 0x9479fc18, 0x90cc5ff7, 0xc48d7c35, 0xcde2f3fa, 0x75e16fb4, - 0x11c20244, 0x3f4356f6, 0x2635bf51, 0x5f48db8c, 0x6f608d4d, 0xa1efb603, - 0xcfab89b8, 0x29f5e785, 0x03722b2f, 0x78ed09a7, 0x906762b1, 0x6eecc894, - 0x5ebb7011, 0xabedc4ac, 0xe80f43a0, 0x75c4472f, 0xfda035bf, 0xa03c770d, - 0x5dc64577, 0x74f151cf, 0xbb8f4fce, 0xa6c84a9e, 0x31623df8, 0x9e66bab3, - 0x7bb1d055, 0xf74e90e9, 0x43eedcf0, 0x1a74f03b, 0xcf486ded, 0x8173a2e3, - 0x6f53e515, 0x1f91e5f0, 0x2e3ddfa8, 0xb0fed8ba, 0xe9056070, 0x3cbe741b, - 0x1bc4ef56, 0x233ac040, 0x77eed938, 0x25f65d50, 0xd412b8b0, 0xe2274d43, - 0xdd12aa2d, 0x3c70e69d, 0x5167e354, 0x5ca3ee0e, 0xf55f682b, 0xa29bb457, - 0x30fded7c, 0xb8f85a3f, 0x515dfb95, 0x98eee8a2, 0x576e5fc0, 0x1d06dcf4, - 0x9e67f712, 0xb914cb47, 0x4522dd63, 0x4a8d2dd6, 0x9ac60f9c, 0x53f2123c, - 0x82f51bb6, 0xb7ce9970, 0x028c5697, 0x9dfa8ad0, 0x5efe3e05, 0x539e36b7, - 0xf2ca590e, 0xcbcb0e72, 0xaf7514b3, 0x7a40dc17, 0xc2fe5135, 0x2fc12ef5, - 0x082bfad1, 0x1601d5b1, 0x06a8ad1d, 0x2701ceb6, 0x9b81e75b, 0x9da1f3ad, - 0x83a00bad, 0x9f8297ad, 0xaf8170ad, 0xb83e580d, 0xf98832dd, 0x52bd7e18, - 0xb45cbca4, 0xfc7ae264, 0x675e4571, 0xf9460797, 0x8f2f9f92, 0x614ae079, - 0x2e4d9d74, 0xdd99b353, 0x923172ab, 0x5177e27d, 0xb5a14de0, 0x9dec0202, - 0xf190c98b, 0xeb20d99d, 0x0702ae08, 0x48fee783, 0x5c069479, 0x04ee573a, - 0xd89aa972, 0x7628764e, 0x5d364c52, 0x87d7d61c, 0x54171e56, 0x49d201bd, - 0x3ebc60f9, 0x2ce88321, 0x5cfcae8a, 0xdaf190c6, 0x3a9df7b6, 0x8545a38c, - 0x84362d95, 0xe53f590f, 0xf3e55970, 0xd91f0899, 0x9ba9d276, 0x595e7649, - 0x1563b7a8, 0x39d86eba, 0x184dcf07, 0x4e50a3fc, 0x52824d92, 0xb1515d5c, - 0x677e8079, 0x74ebac94, 0xdbc657e8, 0x5719c580, 0xd59f8014, 0xe46568b3, - 0x7ebc3527, 0x7ae1635d, 0xbd706bdb, 0x60da7e4a, 0xc8cac5f2, 0x73759ad3, - 0x6e5f2993, 0x3ff7f030, 0xbce72c9a, 0x22327282, 0x9841533e, 0x44f73c4f, - 0xe4101c21, 0x186b5696, 0xf7c08fff, 0x77c21fcf, 0x5deb8a6b, 0x594dcf16, - 0x534ffa40, 0x676779f2, 0x245d8a59, 0x3f8616fc, 0xd2d59310, 0x5207478a, - 0x7bd21f9c, 0x776e18c1, 0x5eb95a1f, 0x329ab6ce, 0x27581f1d, 0xfbae0fd8, - 0xe28f977a, 0x084827d0, 0xd599f3be, 0x34744035, 0x428c8189, 0xd11dd7d4, - 0x27640cc7, 0xa80b1daa, 0x7fc8a5bc, 0x06bc039b, 0x96e51fe6, 0x2d98f533, - 0xe5c107ec, 0xa5ca1ef8, 0xd2ace9c8, 0x8d4971e3, 0xa5ad1f7b, 0x3c2af6ae, - 0xa2413c21, 0xad0a49a7, 0x1538bb20, 0x13e19eff, 0xb953a7e6, 0xabf12a3d, - 0x6def4f67, 0x42741c69, 0xed361f84, 0x0fabe6f9, 0xa34ddf50, 0x0f5d3b66, - 0x1696dffb, 0x1ab00bea, 0xd517c4d4, 0x1b75672f, 0x955fd47d, 0x397f3eed, - 0xaf78abdd, 0xfa7146df, 0x1b40fee2, 0x9ec1cb95, 0x2fdc69c3, 0x6bfe3ad4, - 0x93e4e7e1, 0x750512b9, 0x905ecbac, 0xabe446bc, 0x050bea99, 0xdc7c20f6, - 0x47137684, 0xa9bf79f7, 0xbd0d95f6, 0x2fa819af, 0xc43c67c1, 0xff42ad6f, - 0x5c37adaa, 0xad62f54a, 0xd62fdb57, 0x13d77bf5, 0xb43b75dd, 0xd9bf6afb, - 0x4f5f7ca4, 0xea8d9af5, 0x26bded3e, 0xa8f337ea, 0x67eed3fe, 0xa6fd2a66, - 0xa940ff92, 0x772a5733, 0xeb333f88, 0x235e0cff, 0x68fcd6f2, 0x7042dd8b, - 0xe2ced9ba, 0x6606fd6d, 0xd87deac7, 0x446cc89a, 0x8ddadbf5, 0x5567eac0, - 0x1b4ff98e, 0xfc8fa41d, 0x5d5993a7, 0xab3cf58c, 0xf09e3047, 0x22651efe, - 0x173ddda0, 0x1114ca1f, 0xd93d73cf, 0x5fb7aa76, 0x7f80eb5e, 0x4fa6179d, - 0x4ae7f7ad, 0xd40cab3b, 0x7d88dd47, 0xf7356e14, 0x4266d93e, 0xd01379b8, - 0x3b2d240d, 0xe2a6ea8e, 0xe97812fd, 0x503ef01d, 0x1a976b8e, 0xbeb0524f, - 0x9447908f, 0x09e4093c, 0xa2a379fa, 0x04ece8b7, 0xfd8c79cd, 0x71f7cd1c, - 0xefda99a5, 0x6e7f0e3d, 0xfe73c509, 0x02e3bc7d, 0xc136fdcd, 0xcd91f76d, - 0xbc3ff004, 0xb188ae57, 0xcd82bfc2, 0x17e7121d, 0x886fee68, 0xec9fb79d, - 0xdd0bfcbb, 0x4b703b18, 0x01657764, 0x2f504780, 0xe7b586b3, 0x21db07c5, - 0x1d47f116, 0x57998dd4, 0x16ea8078, 0x5fddaca3, 0x54c5daae, 0x4399aa98, - 0xb73b919c, 0x9121d1fb, 0x9c0945d9, 0x117970f7, 0x5e0f59c9, 0x46dcbc79, - 0x66fba569, 0x598bf303, 0x8a762dbd, 0x5a9d9347, 0x68d727f9, 0xd2ea9fe5, - 0x956d3bca, 0x6ee9de56, 0x6dcfbcad, 0xead7cad5, 0xb6cfcad1, 0xfee69671, - 0x0d4af6b4, 0x02f37d3c, 0xbdf3fdcd, 0xce70350b, 0xf734ab8e, 0xd32c7467, - 0xaf77e79c, 0x76ab9cd6, 0x2e0ed636, 0xb18f35f4, 0x08c41133, 0x567aabfd, - 0xff70a0ed, 0xff3c1aad, 0x1f6ffd6f, 0xc8a7ffa3, 0xbdde31d7, 0x37743b15, - 0xd165ebb9, 0x999dae3c, 0x59eb9427, 0x9cb6f6bf, 0x77431558, 0x54e6fc95, - 0xff941bf2, 0x0e16c391, 0x7df6fddb, 0x8e0acf14, 0xae88ab38, 0x1f7b80a2, - 0xa192f385, 0xba38aaf6, 0x32d900ef, 0xe89c8f85, 0x02a5e5fe, 0x857e34e8, - 0x3cb094f0, 0x93acf0af, 0xd972f0e2, 0x1636de77, 0x4be9c96e, 0xa120f3c2, - 0x6a85e794, 0x22e81447, 0xeca152e4, 0x29e92503, 0xf3abf961, 0xc007ec23, - 0x6880fd40, 0x2759b6f2, 0x9bec77aa, 0xb98f5625, 0x86f67d58, 0xa57362e0, - 0x067f2645, 0x25dff7c5, 0xc4cedebb, 0xb44a76b8, 0x139eaccb, 0x54c46d02, - 0xa4a31890, 0x76afa9e5, 0xed871f50, 0xff2bcd2c, 0xb56d4774, 0x6f919727, - 0xb6f09409, 0x67f5fe99, 0xa2648eba, 0xcb0407fc, 0xf6fc42fa, 0x332759ad, - 0x25197f28, 0xcd014494, 0xe9471c4f, 0x24dcccfc, 0x78c3f919, 0x0f65101b, - 0xab73c289, 0x9390fac0, 0x08ccd8f4, 0x67a8ddff, 0xbe940b79, 0x5e451aec, - 0x54b65f6a, 0x4f803fc1, 0x7e78c2ac, 0x4c1bf74d, 0xc329752e, 0x6dca1cca, - 0x37fbe0b7, 0x5017354c, 0x428e0a5f, 0xd5e7ef3b, 0xfa4d2d3e, 0xed557929, - 0xbf76cf6b, 0xd348652e, 0xc4cec32f, 0x6391e709, 0xbe615ee7, 0x9b03fbf9, - 0x1a1e59a2, 0xe6ce94d8, 0x4ff7e18b, 0x71aff7b1, 0x93b1a3bf, 0xd7df5aeb, - 0x9ef5dfd8, 0x81e7348f, 0x0d3e90a4, 0x4aec0ff9, 0xca35779d, 0x6305e46f, - 0xa8abf509, 0x715b38b7, 0x3dc0fdf8, 0xbe10e7d3, 0xa7e7cdff, 0x6bfdbe4c, - 0xa6ee6cfd, 0xed6c79f2, 0xd6070611, 0x963ad806, 0x55bfb54f, 0x20dfc357, - 0x90e5ea9b, 0xd13ec930, 0x1b31e6bc, 0x67fa83ef, 0x7ca4a94f, 0xd06e9fdc, - 0xc38b35f1, 0x0e26a5a9, 0x6b4f9bcf, 0x48de6f50, 0x00bf6dfd, 0x61ed010e, - 0xec7ce0a9, 0x3abbe47a, 0xa36b95d9, 0x2875727a, 0xd0fe874f, 0x56b81f94, - 0x1ebe7d40, 0xfe27caef, 0x53062c05, 0x599d1813, 0x890c37d4, 0x63013c9e, - 0x764f4dc1, 0x3ffd5357, 0x8a73c934, 0xadad7632, 0x83fa9aab, 0x8ff70321, - 0x847c9e5b, 0x16b7c3f9, 0xe77a4cd7, 0x31f24113, 0xf0497e7b, 0x16f6676e, - 0xf88c2c30, 0xaf3a82bb, 0xfa9b7ea1, 0x5f14609b, 0xdff8db67, 0xacc72a5f, - 0xae3c6d4b, 0x316b42dd, 0x2ceee5e9, 0xe8ca7bfa, 0x5f902366, 0x48873e20, - 0x5cf87af8, 0x40f20a76, 0x6f560d75, 0x78285fac, 0xf8a3e8d5, 0x1675cea1, - 0xbdecacdb, 0xd79f1b24, 0xf467dd24, 0xeefcb1b6, 0x3a46a8cf, 0xef58f5db, - 0x1070df50, 0x846d1cd8, 0x7a1161e6, 0xfde36c59, 0xc008dc17, 0xd1b793cf, - 0xc0ef4379, 0xdf278a31, 0x24aeba67, 0x72880c39, 0x8693c509, 0xdeacbdd8, - 0xecc9b66b, 0xf197a43b, 0x4ee1718f, 0x382fcfd2, 0xfa455c0f, 0x7805306d, - 0x03ccaadd, 0x91b726cf, 0x7287fee5, 0x9ecbfcd9, 0xf4a9f441, 0xb6cdfd22, - 0x4a9db988, 0x1f9df87f, 0xae750bf6, 0x5b83c2a5, 0x9f916436, 0xbcf85ea1, - 0x5bae1251, 0x0ff7c138, 0x963efa2a, 0xfe10f4e2, 0xf73e6ed5, 0xfb4ddb0b, - 0xcf4947cd, 0x271666bd, 0x58fdf6cf, 0xf4f61b3e, 0x9f207932, 0x117f12d7, - 0xc91bde7c, 0xe1cf48e7, 0x9fe57287, 0x9d305fcf, 0xb8291dff, 0x190c9bed, - 0xfdd86fbf, 0xbbb211c6, 0xdf1e7506, 0x18339da5, 0x9aff6127, 0x1d1cd130, - 0x5d444fb3, 0x9fbf5466, 0x8f7ed3aa, 0xa9cd3905, 0xa9dfc9bb, 0xbff0717e, - 0xb8f9a98b, 0x846be94b, 0x1f2cebc0, 0x87f23e10, 0xe58782f5, 0xd18e7545, - 0x23de6026, 0x585abadd, 0x35ce909e, 0xbb9ec9db, 0xe4fd06d0, 0x34473a07, - 0xe98f5f9b, 0xb835bfa3, 0xd6fc9176, 0x4c9953bc, 0x9be7767d, 0x8d7e940b, - 0xc562a9e7, 0x3f098b2e, 0xc71b9fd1, 0xa148b5ec, 0xf584c4af, 0x7c852650, - 0x15e7c48f, 0xd363fcca, 0xef3e9aeb, 0x685932bf, 0x001e0053, 0x00000000 -}; - -static const u32 usem_int_table_data_e1[] = { - 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1915c58a, 0x19d44418, - 0x18344c18, 0x20685618, 0xb58969c4, 0x9fd329b8, 0x90c0c2c9, 0x40b9c40d, - 0x7cc40f9c, 0xfc0c0c4c, 0x17ebc44c, 0xf5b04514, 0x84181904, 0x026ffc80, - 0x85d70c0c, 0x8bbe1818, 0x03083030, 0xf1402ef9, 0x01ce2004, 0x58a06f62, - 0x045e900b, 0x2c40ddc4, 0x7cdf8a22, 0x6bf20251, 0x37f95185, 0x847bf8d1, - 0x1057ebf0, 0x47af2fc1, 0x161b1e40, 0x3e3f22d1, 0x3bd02922, 0x015f5810, - 0xc7265f95, 0x0f27d0c0, 0xb8a87f8c, 0x4bfc9201, 0x0e5cbb20, 0x6096f6c2, - 0xf2062860, 0x9bb0150d, 0x2f9403eb, 0x857dca01, 0xcc0003ca, 0x688cbacc, - 0x00688cba -}; - -static const u32 usem_pram_data_e1[] = { - 0x00088b1f, 0x00000000, 0x7de5ff00, 0x4514780b, 0x74f570b6, 0x9924ccf7, - 0xf2124c99, 0x00493de0, 0x210e0311, 0x9970c044, 0x46a2c024, 0x141a020d, - 0x84920275, 0x7e889790, 0x33feaeec, 0xa8a08901, 0x17acb9f1, 0x376141dd, - 0x0c06e8b2, 0x60e03518, 0xba2eb300, 0xe7c045c1, 0x36bc8026, 0xb9f04324, - 0x9d6f5ecb, 0xdd33d553, 0xc7c4099d, 0xffef7fde, 0xa55f9f8f, 0x71ebaaba, - 0xe9d4e7de, 0x278f3242, 0xdf210a64, 0x9f968fc1, 0xf890848b, 0x206f5950, - 0x8841922e, 0x6df466d7, 0x88cfa64c, 0x68e67a23, 0xd11d985a, 0xef435837, - 0x9ed5cbe9, 0x186934a4, 0x1c790f21, 0x23e21258, 0x5ab54e84, 0x16f50520, - 0xe0933ba8, 0x213e3a7d, 0x0ff8e8fd, 0x30f8e246, 0x1a18992d, 0xe0311067, - 0xf9ad537b, 0x421eb089, 0xc3e6476a, 0x213b16fc, 0x9f9f7bfd, 0xa7eb888e, - 0xf7c10def, 0xb59efa24, 0x6529efef, 0x13fd0e57, 0xf66ddff6, 0xf108146d, - 0x71c7fcef, 0x8699ef58, 0x5d130e39, 0xd9b7766f, 0xbeea053f, 0xb6899f6c, - 0xc0fb6ee7, 0xe5fed126, 0xda0944db, 0xf0233b0d, 0x8275cefd, 0xa695ea0f, - 0xa4ae47d6, 0x9136c0f5, 0xf8d30f3c, 0x4092062d, 0x613371c8, 0xeb15873f, - 0x5aac1145, 0x6dd77ebe, 0xa3495f30, 0xf7d04489, 0x2e88378f, 0x28d92fa8, - 0xaf9d08f8, 0x8c07b5fc, 0xc578e803, 0xc23ea13e, 0x1f1beb41, 0x3ee83a33, - 0xd8fcef97, 0x7ce146d6, 0x0e2663da, 0xa4a3ee23, 0x52908d3e, 0x03e996df, - 0x9ba5fbe8, 0xbe802705, 0x4ed9dd74, 0x83695f58, 0xe3a45c3c, 0x228bae2d, - 0xee6c918e, 0xd7cc08ef, 0xdbe7147c, 0xf9830f26, 0x65dfce4a, 0x6ee52404, - 0xca2e9193, 0xdf603ae9, 0x3da7bcca, 0x053e716b, 0xd22fe59e, 0x8abf68f9, - 0x6c270597, 0xdc40c2b1, 0xd7ce8eb0, 0xb05e0a22, 0x8daafec0, 0x7deaac23, - 0x7d876e14, 0x1bd6fa94, 0x7d605ba7, 0x69458deb, 0xd716f1a1, 0x7d76a7fd, - 0xdd13536b, 0xf3e3bd69, 0x748287b4, 0x4a5ea844, 0x4fe90b88, 0x8e8119f2, - 0x85e7e795, 0xe2f7c418, 0xcc38913a, 0x3a15f1a1, 0xe9c07ef0, 0xf1958774, - 0x12dbc701, 0x842ce03b, 0xc73b6eb7, 0x54c814a3, 0x8f94af8f, 0x7ae83e00, - 0x2c763d6a, 0x6124f71f, 0x81c7a4f9, 0x33da7b70, 0x1eb5cb12, 0xc67f3e27, - 0x75cb0133, 0xcf96171e, 0xe9606679, 0xbf63e4f3, 0x58053de7, 0xf1b8f06e, - 0x253d6ff9, 0xaa79d658, 0xcf26f9f0, 0x7b372c32, 0x65fcf8bc, 0xeb2c2acf, - 0x6e58b53d, 0xb2d17c05, 0x7ec3e3c1, 0x58753ddb, 0xf1ea7a36, 0x469eebf9, - 0x3870d72c, 0xb648b2da, 0x7360e144, 0x3b453b11, 0x6573cd89, 0x9b1eb4cb, - 0xf309eacf, 0x5a46d9bc, 0x3ad3704f, 0x3280cb85, 0xd689b67f, 0xf6b15407, - 0x1c92f721, 0xf10fad33, 0x3594f6b2, 0x5a089cae, 0xed65a94f, 0x7379d623, - 0x847d6922, 0xda8fb58f, 0xa289cfec, 0xacf551f5, 0xc9134c7d, 0x18fad0b5, - 0xefa7ab3f, 0x695ae573, 0xd595bd3d, 0xe6f13f33, 0xb33d68da, 0xa93fbd8d, - 0x2c3a27c3, 0x55b0f13d, 0x14202c76, 0xb9de4d57, 0x9bca892e, 0x5dc746ad, - 0x7bc849c4, 0x892ef9de, 0xd90687ca, 0xde6ded85, 0x746eacc5, 0x77b77b61, - 0x2edff629, 0xaa5db1bb, 0xb7db0fbe, 0x9ed8dd1b, 0xed835d50, 0xdb17b28d, - 0x8a3f5647, 0x2f468ded, 0x5eaa4fb6, 0x65d7f58b, 0x55e7b61f, 0xaffec7af, - 0xfed87d1b, 0x5c9bfdf8, 0x05fd6953, 0xe41dbdc1, 0x5dc10ade, 0x9e815242, - 0xee4093ea, 0xf9f970d5, 0x6d1d101c, 0x446fe9af, 0x6efadc3e, 0xbfc00be6, - 0xf507ebf8, 0x983edfa2, 0x89bce38c, 0x1c74c8e3, 0xa4e3e2f1, 0x334137bf, - 0x257bfa4e, 0x382d38ca, 0xc6df444e, 0x24defad9, 0x2bde7aed, 0x0fd9c655, - 0xdac2b4fc, 0xffa57db7, 0x9ebb4b39, 0xe329973f, 0x89eb847c, 0x1a7adbe9, - 0xa7c2d03e, 0x7c2083e1, 0xf138e28e, 0xc64f5b7d, 0x327c2d41, 0xd3e1060e, - 0xeff4e381, 0x070d38db, 0x3869f0b5, 0x97cf8418, 0x7dc19f08, 0x21c657db, - 0x0e327c2d, 0x5ff3e105, 0xbee49eb8, 0x53fdb38d, 0x7fb67c2d, 0x498f841a, - 0xef0cf580, 0x3f32bedb, 0xf327c2d3, 0xec7c20b3, 0x7da5ce38, 0x67fb671b, - 0xff6cf85a, 0xfe9f082c, 0xbee8ce38, 0xaff32bed, 0xfe64f85a, 0x149f0835, - 0xb633e001, 0xfc69eb6f, 0xc69f0b5c, 0xb9f083cf, 0xdf19c70c, 0x384cf5b7, - 0x84cf85ae, 0x64f841e3, 0xf626bee0, 0xe3c69c6d, 0x1e34f85a, 0x3267c20f, - 0x6fb9338e, 0x42709afb, 0x27099f0b, 0x8e99f082, 0xebbb64e3, 0xc7465198, - 0xce3ef6b1, 0xf0b467eb, 0x104cfd79, 0x38e3d73e, 0xa938e8d3, 0x52671f17, - 0x933e16a7, 0x29f0833a, 0xeaae71c0, 0x77af38db, 0x7af3e16a, 0x853e1067, - 0x7db5ce38, 0x2ea4d7db, 0x75267c2d, 0x3b8cf831, 0xa36b9550, 0x3a1754ed, - 0x95cafa45, 0x40972e1d, 0xd59da2eb, 0x8093bb45, 0xf62a225d, 0x89756906, - 0xe6cb7df4, 0x8907f498, 0xb9c8eeda, 0x4ac7e813, 0xddb531ad, 0x52213d11, - 0xb8c4e763, 0xb8f53562, 0xfd340319, 0x3453f3e3, 0xa30589ed, 0xddfded34, - 0xc0fa9ae9, 0xfe9a4992, 0x3472ab83, 0xaecba1f5, 0xf64ff4d6, 0xa7a9a0de, - 0xd359baae, 0x7ced787f, 0x6b25fb4d, 0x97ed354b, 0xea6896fa, 0x42fdd597, - 0xfd747fd3, 0xe5fb4d72, 0xda6a0f8d, 0xd71ffac7, 0x3cb5c7d4, 0xbe3fe9a3, - 0xfb4d79f5, 0x69378715, 0x6db627da, 0x3cafd4d5, 0xcecebaf9, 0x5f8fd8b3, - 0xd022ebc6, 0x7f76613d, 0xf8f7e67f, 0x1bac46ad, 0x8ed05807, 0x722d65df, - 0x35f8a31c, 0xd1c0b5be, 0x7017e28f, 0xf6457e0a, 0xda4b9280, 0x267bf3e8, - 0xd3b12fb9, 0xdd18f7e7, 0xd8c3db97, 0x041e94a7, 0xc3a50492, 0xfdbea500, - 0x63d19901, 0x23f3c0ce, 0x95fbe9da, 0x1888c086, 0xb312cf5a, 0x777e811b, - 0x8a2fcc0a, 0xf4154914, 0xf411348b, 0xce481e0b, 0xa2abc17c, 0x298355d7, - 0x71a10a1f, 0x24eec957, 0xaade33b0, 0x1d82f76e, 0xee983352, 0xcd21006b, - 0x4bdfbb42, 0x0607b4fd, 0xe9b92517, 0xb5232678, 0x1bf3d5d3, 0x3869fce9, - 0xebd00b7f, 0x7c7f307b, 0x294df9cf, 0x9bf33413, 0xe6689487, 0xfce91b37, - 0xafde4276, 0xa7e7c53e, 0xc8449848, 0x3853845f, 0x094869bf, 0x9180ffce, - 0xf9ea2bfa, 0x1ff38323, 0xd67ffd86, 0x2653fedb, 0xa43ff769, 0x237fbb54, - 0xea91ffdb, 0x48fe7cb3, 0xe151ffdc, 0x90ffdb2c, 0x137fb652, 0xbf38371b, - 0x93ff082d, 0x2f677f30, 0xb3529bf3, 0x5a1ffbb4, 0x89bfdda6, 0xfd5ddfcd, - 0x82df9f2d, 0xbe139ff3, 0x5a1ffb65, 0x4d1bf386, 0x8fd0276e, 0x95646071, - 0x1d4fce8f, 0x04490761, 0x40f3a172, 0xfd163239, 0x148497e4, 0x913dc75c, - 0x8abede8c, 0xf286f4a4, 0x58fccbc6, 0x996c951f, 0xb4e2efd4, 0xb67378be, - 0xb612e411, 0x21657f53, 0x8d1dea5f, 0x7937d222, 0x4e1be4d2, 0x28d9dbd7, - 0xc77ea17a, 0x207d9393, 0xe44d2aff, 0x4f787cf6, 0xfe787e22, 0x9fa353f9, - 0x5f4bef57, 0x8f95ac2e, 0x2df8a9b7, 0x90e547e8, 0x98165591, 0x1fa9aed7, - 0xa1107ea1, 0xd427c5fe, 0x249420cf, 0xbe6cca8f, 0x04bfa8cf, 0x2fea36f5, - 0xd5213b41, 0x75e25fb8, 0xae8c307d, 0x3f289f3f, 0x26f3ee17, 0x9e3a2964, - 0xc8f7f8c4, 0xf807c11a, 0x14597db8, 0x3d687e05, 0x4d38de85, 0xfb0fee9d, - 0x7c12ae07, 0x86380bcf, 0x9333e01b, 0xbd60478f, 0x67605eb4, 0xe8a21cef, - 0xb0514fef, 0x8a40d560, 0xb338d08b, 0xa44e4b88, 0x5a59cfef, 0xa2e84328, - 0x2f061055, 0x2059fa01, 0xe0119753, 0x69278de7, 0x7ae8389c, 0xf1b3b66f, - 0x63e4ba67, 0x14f5aa6d, 0x3e5766c8, 0xa1414f5d, 0x359feb88, 0xd1fedb43, - 0x619728ce, 0x3d572d0c, 0xc9ccf381, 0x54dfb6d7, 0x75cfada0, 0xef54eb6b, - 0x6ef7a0c9, 0xa73fd129, 0x9cfba160, 0x5d2b8417, 0xade75d28, 0x56b70e1c, - 0x5e0d5ec9, 0xda556dc1, 0x26e0a021, 0x5f7c2fb8, 0xf6ffd9ec, 0xa17ada65, - 0xb05f5b57, 0xa73e374a, 0xff1ce39b, 0x683e8047, 0x83e80279, 0xa718f3c2, - 0xd55c908f, 0xc18dc7d2, 0x50fa306d, 0x625c71f6, 0x8ebe3828, 0xdac2c7d1, - 0x50f4f0a8, 0x9707a418, 0x7a14be9a, 0xc3d38db8, 0x8a1e9ca7, 0x6ae96ad7, - 0x4cadf12e, 0xb2dfefa2, 0xe9e21766, 0xe8c850a0, 0x3d0a97e1, 0xc1e869b4, - 0x8f41e9cd, 0x3d38dbbf, 0x4673f6dc, 0xb67c7a0f, 0x5b687a71, 0x29264e7b, - 0xf14af13d, 0x3c53a9a0, 0x376ef0e8, 0x7c503d02, 0xf987a584, 0x8dd37dc1, - 0xde02fad3, 0x9c5f03d6, 0x053db01e, 0x4e104ec0, 0xcf6a7ef8, 0x684e54fe, - 0xc36bc5ea, 0x31b2bfe3, 0x6a98ee3b, 0x57f5e55d, 0xf5531dc5, 0x53375c5b, - 0x9be45f53, 0xbc5fe9ab, 0xbed350b6, 0xa69176b0, 0x3baac17d, 0xef42f535, - 0x6ffd35cf, 0x69ad565f, 0xb56ab5bf, 0x9296fda6, 0xb9f534c7, 0xfa6b5fee, - 0x5eb054df, 0xff273ed3, 0xacfb4d45, 0xf5345b19, 0x34d7ae99, 0x2f3b0dfd, - 0x31e81ebd, 0xc048a0eb, 0x71e638fe, 0xf71fdd20, 0xa4f2c48c, 0x717c89c7, - 0xcb0133da, 0x4fcd8d7d, 0x7cbb495c, 0x26882819, 0x91167f4c, 0x2cf64218, - 0xcaaf5777, 0x504e7d02, 0x7971feef, 0x1077b551, 0x07065395, 0xad6f39c2, - 0x11c7f891, 0xe2528022, 0x50c407f3, 0x6d1b567b, 0x3dbdeb8f, 0xb614ad6f, - 0x0a4dab3d, 0xe3e56e3b, 0x61ed4385, 0x7e2133e2, 0x3ec10326, 0xb9f6e2ea, - 0x204cbdbe, 0x84e7eaf9, 0x8ffe472c, 0x5cfd3031, 0xa2726466, 0x1cff6b6c, - 0x7fba8362, 0xe685d544, 0x95cca7ab, 0xaa91f408, 0xb5e2e3e1, 0x3ce46997, - 0x3c6de881, 0xcd38d9d0, 0x5775c5f3, 0xd8ebde6a, 0x2bbae225, 0x7d508640, - 0x07e48c3d, 0xfd97a00c, 0x8d6643cd, 0xceba7586, 0x355e401a, 0xd8fda3c6, - 0x771199e1, 0xe63c024c, 0x53d27963, 0x8f71e580, 0x9e63cb1b, 0x788f2c12, - 0xf36cb0aa, 0x33f2c32c, 0x4fcb178f, 0xfcb0ab3c, 0xe58b53c8, 0x2c5acf61, - 0x587c7a0f, 0x61d4f01e, 0x1ea7bef9, 0x234f56cb, 0x171e9d96, 0x29bf0a96, - 0xddd3d0f0, 0x4fa7ae49, 0x805dfd03, 0x07c4e2ce, 0x0a0d57aa, 0x8ae259d1, - 0x59bdab87, 0xd6f371a1, 0x249d389a, 0x0861e868, 0x81e364f8, 0x5e9c4c5e, - 0xade7b7c2, 0x9ed82f95, 0x1d8726d5, 0x7ff9f2bf, 0xf9cdbd0d, 0xa216f491, - 0x7a3a81a7, 0x3d18bd4a, 0x87c7124d, 0xc18e69e8, 0xa71ff4ce, 0x1f6087a7, - 0x628ffc61, 0xabc6ea30, 0x14573aec, 0x73f3678b, 0xb2d16a07, 0x7b9f3678, - 0x15ae1d05, 0x48df3fed, 0xc8f773c0, 0x78808fbf, 0xaa61f77d, 0xdf7b9328, - 0x7a5e9e9f, 0xfd0bbb87, 0x551f22a0, 0xb67ae3a2, 0xb8324447, 0x0cc81846, - 0xeac84e92, 0xce75bfe1, 0x44bac34f, 0x9f7de162, 0xf3986673, 0x4f670228, - 0xeb871789, 0x6357eb0a, 0xcfe3bc60, 0xca1323fc, 0xe6148639, 0x688b34df, - 0x0bff13df, 0x506f804e, 0x499c991f, 0x0c0f0710, 0x3ed1da37, 0xf0b459f0, - 0x667ad2f3, 0x29ab7e08, 0xdf515a8c, 0xfc2126d7, 0xa2357d86, 0x77e01f7f, - 0x317f3931, 0x0df7ce78, 0xf3c097f8, 0x62f1f262, 0x1cb89172, 0xfdd2372f, - 0x9d1ced77, 0xe403a0fe, 0xade185e0, 0xd7e95f9c, 0x7d28bcf3, 0x4aee3a2f, - 0x75b8e850, 0x88f3a108, 0xefc71da2, 0xc984b86e, 0xdbeec52f, 0x05f5f266, - 0xb59267af, 0xf9c53de3, 0xbbaf194f, 0xf81b05e5, 0x0c924b5b, 0xf06163f6, - 0xf5e594a0, 0xda8b76c9, 0xd6d46cfe, 0x19856bbb, 0x3a2768f5, 0x068f67a2, - 0x1fb7613d, 0x3b72061b, 0x9c654b09, 0xfb464925, 0x4ef72a31, 0x3346a5d7, - 0xe4c7cf3f, 0x9418e6c1, 0x663da717, 0xaf53ffec, 0x9471b7a7, 0x40d210f5, - 0x1e419a8e, 0xded4b6d3, 0xcf4af7fb, 0x3c4617d2, 0xbf926df7, 0x4cd0fb02, - 0xfc0effff, 0x5d61220d, 0x5eb2b719, 0x872e9af4, 0xf3359be7, 0xca1cf7d1, - 0x2977eb19, 0x891be217, 0x96e8571c, 0x5c638bea, 0x8bae2c9f, 0xcfed6bb0, - 0xb2bd4d18, 0x635dbfb1, 0x541fc28f, 0x412a92fe, 0xe329fa02, 0x5925d3e4, - 0x7d740956, 0x1090426f, 0xfd6056e8, 0x466dcdca, 0x95ce03b7, 0x5b7ade19, - 0x4cdfc51f, 0x897c9289, 0x61cf16b9, 0x9d2fea4b, 0x4ce67a0a, 0x88048ac3, - 0xbb162c1b, 0xf30fc9ef, 0x79312cbe, 0x0727c8bf, 0xa73df6b4, 0x55c7420f, - 0x945c639e, 0xeaab8e58, 0x8f16061d, 0x009b8fd1, 0x1c5fc6e3, 0xf79b153e, - 0x413b074f, 0xc68aa70f, 0xca3746b3, 0x665ffa45, 0xfc0a4e08, 0x13f314de, - 0x697e3a24, 0x2dc63b5d, 0x11deca4e, 0xbc80bcbf, 0x4b3fb9ec, 0xd528f1d2, - 0x15a4bcbe, 0x813f99e6, 0x371c444f, 0xf8e54c7d, 0x04c93fa9, 0x4f3910e4, - 0x4862657b, 0x063bfb86, 0xf90cc862, 0x161bf33b, 0x4fbc01e7, 0xe547bf81, - 0xdf241de6, 0xb5207886, 0x9cdfe099, 0x00198621, 0x7de433a7, 0x1e1538db, - 0x87232572, 0x94829533, 0xf1c14c1e, 0xefc1fddd, 0xb4d41532, 0xb9e0638a, - 0xc23ff8a4, 0x72471877, 0x50b7980b, 0x897b9ec0, 0x97e81ab9, 0x3f1a51fa, - 0x9a51fa8d, 0x34a3f53a, 0x437222f5, 0x1425e402, 0x9f13293d, 0xb4d27080, - 0x88ec928f, 0x555262c7, 0xafd1f603, 0xbe6dfc79, 0xe903489d, 0x7d5fcb3e, - 0xee90b336, 0xc5896ae7, 0xf57394fd, 0x0e0cb145, 0xa33e25a5, 0x7f73d2cb, - 0xddc61b47, 0x8c3f2548, 0x6fcfcec7, 0x051e6236, 0xdc994ab4, 0x7de949f4, - 0xa20d89ff, 0xfd06c22b, 0xbd6573e8, 0xff7fdfc9, 0xf212fdfa, 0xb4a3ee38, - 0xfa01266e, 0xc02791eb, 0x09d723f7, 0x7e185f2e, 0xaf74e42a, 0x013ba7e8, - 0xf143e37e, 0xf574fbac, 0x4abe1cd5, 0xfb5d29fd, 0xfd2f960f, 0xbcbe4688, - 0x93efba29, 0x027933c6, 0x00a417f0, 0x1e0fd7f2, 0xf8c7a93f, 0x7f1f81ab, - 0x6907f1b2, 0xff8e9ef9, 0xfeba4fd4, 0xbfd63d61, 0xcbfadc3e, 0xbb697d5f, - 0xd297ea97, 0x23653c3f, 0x494edf94, 0x8a4e09b5, 0x2b8db2f7, 0x3b902e6d, - 0x7c06d792, 0xce27ca71, 0x870f4708, 0x06a57cb8, 0x78804588, 0xc749fc2b, - 0xa1e9bd3f, 0xf89ec0eb, 0xc76ca36a, 0xc99d6a38, 0x5cf4a26f, 0x8f28b0d1, - 0x3b7ac18c, 0x16703fab, 0x51b2bfe8, 0xd3a6a23e, 0x953ddfd2, 0x94357900, - 0x921a0652, 0x7fa3f4a0, 0xf3e1b152, 0x546f60e9, 0xabf20092, 0xff983dfe, - 0x87d4589b, 0x9ee8c685, 0x499818ed, 0xafd9f780, 0xb3a1e1b2, 0x6afe0da2, - 0xbe9038c3, 0x37f7097f, 0x3f6b245a, 0x82b9273c, 0x54f2015c, 0x31f10781, - 0x8bc5637f, 0x4ed31abf, 0xe1b1d3d7, 0x0541364f, 0xea4fc527, 0x9bf05fae, - 0xcbbd1dd7, 0x87ca4eef, 0xd156bb6a, 0xee468e4f, 0xb2b13527, 0xaedbf64c, - 0x6ca4f2a4, 0xd2f4ecbd, 0xbd2f65c7, 0x2067dbf0, 0xc9a1fd7e, 0xbf8e9c39, - 0x073da5f8, 0xe2fad127, 0x3cbf722d, 0x908b0db6, 0x254bc210, 0x7a597ffd, - 0xafa50f08, 0x463a31ec, 0xc6f7e7b3, 0x78b1f086, 0x19232ecb, 0xb91e13dd, - 0x6d8cbbf5, 0xa9783096, 0x760e9f6f, 0xbf178adf, 0x3bbc8236, 0x892053b5, - 0xb9e061c9, 0x85da0f7e, 0x23c42700, 0x6f1053c7, 0x1495feba, 0x145fa02f, - 0x37dbe93c, 0xe3027971, 0x9e90d239, 0xce9d7e5f, 0xc991f25f, 0x792ffb09, - 0xec1b2ef9, 0xc55484e3, 0x95d9fae8, 0x4adf2009, 0x1d826f64, 0xe4bcf64b, - 0xde91bbb9, 0x9ddff78a, 0xae92e2c0, 0x95d406fe, 0xbfb0fede, 0xe0e6eb85, - 0x1b888afe, 0x59e4aee9, 0xcb47df31, 0x6332252f, 0xb8be184b, 0xf2726656, - 0x2354f3c4, 0x509dfdd0, 0x22fbc0f4, 0x627703d7, 0xbe6ef3dc, 0x62316a17, - 0xc3334bfd, 0xc0d930d3, 0x2bd32ce5, 0xf0dd7a41, 0xd38bea00, 0x70895d83, - 0xd21956be, 0xc437a80f, 0x1912d3fd, 0xc19e987e, 0xc99ea8f7, 0xbfd0e785, - 0x8c457655, 0x7a87bcd1, 0x297f9945, 0x3bae9f9f, 0x13b5ec12, 0x8ffde109, - 0xdf0acb9f, 0x4542bb53, 0x66fe2a5f, 0x3561befc, 0xdf856fe3, 0x4067337d, - 0x180717fb, 0xa07bc0ff, 0xfcbae967, 0x6bbed889, 0xc0f280b6, 0xf8e1fc44, - 0xf9cc837a, 0xd0aedb5a, 0x24b75d09, 0x05e8ab44, 0xf8458fc6, 0x7a2f5ea3, - 0x92a7be92, 0x9f309597, 0x0a78e7ad, 0xfe7316df, 0xf96b219f, 0xef8bac9f, - 0x99653e53, 0x33edfbec, 0x3f94afc0, 0x57e00ebd, 0xfdf61f39, 0x07cdcdb7, - 0xfa7ca66f, 0x4f857ab7, 0xcf53f2b5, 0xef5b25a7, 0x7a9f4026, 0xa0dbfd3e, - 0x4f96122a, 0x7cb0f3e9, 0x7feda83a, 0xf02a7e54, 0x45f802ab, 0xc8a7e085, - 0xa8e0dec3, 0xd9568797, 0xd21e5611, 0xd99201df, 0xba14fe93, 0xf4ade853, - 0x4143e5f7, 0x52e904ee, 0x5d20bba1, 0xdfa7742a, 0xfa7e16af, 0xc13249f6, - 0x26bfe575, 0xd65cffa3, 0xe942f2c4, 0x66077b7b, 0xa85c9c20, 0xdeed48c6, - 0x75d4fd81, 0xaf5eae9f, 0xd5d2efeb, 0xddfd75f3, 0xa6957aba, 0xb363597f, - 0xfdfe2091, 0xb2e27e9a, 0xb8d1c867, 0x63eaf470, 0x59c3597e, 0xc2e817a3, - 0xe5f7c012, 0x790bc4e5, 0x221d8186, 0x28ba05c6, 0x7e206b8c, 0xe7d939b1, - 0x656372a5, 0x743f8b04, 0x58b603d9, 0x618cae5a, 0xb1bc40f5, 0xf29ee406, - 0xe2c1103c, 0x01f95d8a, 0x9fca8c5b, 0x51126f6a, 0xc8f9b76e, 0x167e708c, - 0x47c828d5, 0x76b7a46d, 0x4d35ee76, 0x06590cb4, 0xd15aa571, 0x1df83609, - 0xe0d937d5, 0x29aba9dc, 0xfa02faf5, 0x451fe17c, 0x8ae97b4c, 0x75818db4, - 0xea4baf11, 0x4e6ff2af, 0x59d3ef12, 0x9a0b7f74, 0xc7739f98, 0x423d9d1a, - 0x153d20d6, 0x411a9659, 0xe27f529e, 0x86bcf688, 0x1f2945f1, 0xb69d64af, - 0xd29f795d, 0xa5f3fa01, 0x6eedb41b, 0xa07f0fee, 0x3258c9f0, 0x2ca3fb96, - 0xf2e5c30e, 0xfaed3134, 0xae8f8a02, 0x68989116, 0x4449bbbd, 0x166f747c, - 0x234f107c, 0xb7e478de, 0x7940120a, 0x03a9c0a8, 0xbbd8c9f8, 0xf6d8eabc, - 0x812fe669, 0x3c7fb66e, 0xd9693fe6, 0x11c3fdb1, 0xd5fd406f, 0x263e4343, - 0xeee7fb3d, 0xff73c08c, 0xa4569dae, 0xef1daef7, 0xd425f90e, 0x6139335f, - 0xbf3b5d9d, 0xd3f4031e, 0x0254dcb5, 0x306baef2, 0xd8aec78b, 0x3698f5f1, - 0x33f7afd4, 0xfe6461fd, 0x3fd37761, 0x41fa133e, 0x76057749, 0xe428cec3, - 0x23d7caa7, 0x6bbbdf30, 0x6e99d7c7, 0x9fb74fcb, 0xd1e79e0a, 0x5b052565, - 0x2c317d61, 0x8df2a18f, 0xd3542f89, 0x761bcbf9, 0xf6d01719, 0x39ff37dc, - 0xd768e406, 0x750f6656, 0x41cf6dca, 0xf194431e, 0xe29972dc, 0x8a9813ab, - 0x33bfcd3a, 0xdf02e466, 0x3fcb84f4, 0x57d63e31, 0xaffca478, 0x62e08781, - 0x33eacef2, 0x6fefb00b, 0xe318fb3f, 0x4ba4269a, 0xab7fbf65, 0xe57b46af, - 0xfecefb62, 0x82df6e7f, 0x76fb2fbf, 0xfbef9bff, 0x7abbd738, 0xe749e83e, - 0xfac1ee3b, 0xae27564b, 0xeef48fb7, 0xffc7fd85, 0x7bffeefb, 0xc52b7de3, - 0xfbe2edbb, 0x5affcdfe, 0x36f1ffbc, 0x7e3b778e, 0x3fe6f3d7, 0x57df7d71, - 0x6ff9bdce, 0xf6def78e, 0xadf5d8af, 0x067b2a86, 0xa9015f5d, 0x316182b5, - 0x92dbbe37, 0xd76c80e1, 0x8f30fd73, 0xc34bce0e, 0x23014df8, 0x904d0bf3, - 0xfb7e0747, 0x0b89411c, 0x1d751fa2, 0x1bae1fb7, 0xc8768254, 0x9987ae75, - 0xb55520dd, 0xadfed366, 0x989c0b39, 0x0fd24973, 0x7b3ea1bb, 0xfd6baf32, - 0xe204f7c9, 0x7f1da812, 0x2d35ce5d, 0xef5ed760, 0xa5eed112, 0x1fbbda25, - 0x9ece990c, 0x3dfad04f, 0xfadadd73, 0xfada054d, 0x8dde3e1c, 0xc6ffad84, - 0x7107c17c, 0x13f65355, 0x356710f1, 0x9089942d, 0x5542f90c, 0x98bfc12b, - 0x7f7daf93, 0xe3c1f81f, 0x531c3c7f, 0x971c0a4d, 0xb6485c20, 0xfa48dce8, - 0xeebe4700, 0x7d63d9d6, 0x244ccf90, 0x8de38327, 0x838c4ee5, 0xe65b7f73, - 0x5596cbef, 0xb2cfc0ad, 0xfc56cfce, 0x4de0dee5, 0xe38dffb8, 0x2fe084a4, - 0xbff444bb, 0xadff9d65, 0xe2fbe5e0, 0x8fe3c143, 0x3a97cbc5, 0xb8b20cbc, - 0xccabf008, 0x16a985fd, 0xca0fab27, 0xc8de7827, 0x9fa905fd, 0x42d3788b, - 0xcc8bdf79, 0x5f386ce6, 0x30148f33, 0x1afd71de, 0x3983f511, 0xe575c04d, - 0x8f31904f, 0x7e4373f8, 0x6f3be026, 0xbf1515dc, 0x0270cb60, 0xb871173c, - 0xb42a9117, 0xeff9c95f, 0x84cacbbe, 0xf6820673, 0x211722ef, 0xadbf52d7, - 0x47f04b28, 0x4b157852, 0x0e9d1bc4, 0x1c816f71, 0xb5bdc4d1, 0x47fdf875, - 0x8b9c6842, 0xbe4deff5, 0x5fe5d4fc, 0x323b3ca9, 0x1e41fa8c, 0x5849bb9e, - 0xaff156dc, 0x70626f6f, 0x7c132cac, 0x7e774829, 0xee755f39, 0x83e71cf8, - 0x0e3bdebf, 0xa3f664e5, 0xefd1a3a3, 0x6fd03977, 0x437ee4a8, 0x0d11d7b7, - 0xa6eeae71, 0x9b3e7e54, 0x55cb536b, 0xfdcfdca5, 0x7e40bfee, 0xa6bb2d21, - 0xf822b50a, 0xf1802471, 0x08d4ef5c, 0xfe4c31b2, 0x1931ffeb, 0x6154fd38, - 0x627e001c, 0xfd91e026, 0xd1abe98a, 0xadbc2ab1, 0x3494f6b9, 0xe01e27a6, - 0x0e754477, 0x0be163f9, 0x75c03e7e, 0xf4db447f, 0xadfb30fc, 0x5638b135, - 0xe2df5bde, 0x34379c77, 0x9700cb25, 0x9a8aa61b, 0x2655fb73, 0x238d97ee, - 0x795d60e3, 0x9b655d6f, 0x11697808, 0x66ddf09d, 0xa359d365, 0xb079cc3b, - 0x3e309e1e, 0xca8fd5c4, 0xe78022ce, 0x082387d1, 0xf2efd1f8, 0xf834c673, - 0x430d226e, 0x2b882e3a, 0xb5c39afe, 0x72c764d3, 0x1cb65e56, 0x6b4de74f, - 0xa3858fb0, 0x7fbc01d4, 0xe3211827, 0xbd878921, 0x501bf4a7, 0x1bb5fac6, - 0xf6e115ed, 0xed823c3f, 0xef3898bf, 0xfbfc2099, 0x51fb2de1, 0xec073fab, - 0xae3ca983, 0x09ae83d2, 0x0cf747f2, 0x1bfa07c1, 0xe7ac61fc, 0xdf84efb1, - 0xbeb3be55, 0x8559e981, 0xde70f5ee, 0xccace1cb, 0xe2c4dc7f, 0xfce27faf, - 0x8159c0a5, 0x4abd7eaf, 0xa6af2a7f, 0xd751e3a8, 0x197d8e37, 0x268a9bec, - 0x43a06ec1, 0x466d4855, 0xc6cac3e0, 0x6f3864c7, 0xe360eb99, 0x8c7f2912, - 0xd3a09f3a, 0x9a3bf2c4, 0x0dbcafd3, 0x1adce4e8, 0xe242e813, 0x0dace3ba, - 0x06bbf0e4, 0x7be19fe7, 0x227bef6a, 0x790178d9, 0xcea7b1f5, 0x8f525535, - 0x9ceb8c9b, 0x432d9655, 0xb296ecf8, 0x8aa2725d, 0xb14d3a9e, 0x1f3caed8, - 0x8748e650, 0x5c3e74e7, 0x1311f787, 0xd242ef81, 0xfbf15bea, 0x62aa5bd4, - 0xd4961d18, 0x3d6232ef, 0xf32bfb19, 0xf9e8f329, 0x369e7669, 0x6e4178ef, - 0x4b8020db, 0xd4bfc99e, 0x1f4e8619, 0x8ee72b33, 0xb84f53df, 0xf98edd28, - 0x2c4f48ff, 0x1b44f455, 0xef2bb9e6, 0x3e3335cf, 0xc489e957, 0x49627a70, - 0xf01123b5, 0x6a4764b0, 0x92c93022, 0x084b4e3f, 0xf03e27a7, 0x43e373b0, - 0xaeeebbfc, 0x5c4f54d9, 0xb313d2ae, 0xf44e9023, 0x959ae5ef, 0xe88b8d73, - 0xff6f0509, 0x03e6f2c3, 0xf86113d0, 0x56b346fb, 0x54d8dc4f, 0xc6e27a88, - 0xfbe6a2d9, 0x17cd6baa, 0x09d913d3, 0x3b2eb173, 0xcfd0c2a3, 0x39bfdc07, - 0x61fbf3c4, 0x6b17d01e, 0x9b8476cc, 0x26f46f5e, 0x55f6c7d7, 0x825fffae, - 0x97d722b3, 0x43f761cc, 0x8243a4f4, 0x2e64bcf4, 0xd002eb95, 0x4beb9323, - 0x4e71e56e, 0x07cd9c9d, 0x96a19b39, 0x0afdecb3, 0x950bd337, 0x9abfc98d, - 0xae6fdb47, 0xda669d95, 0xdc90e6ff, 0xddcb54cd, 0xe1096635, 0x96ee43dc, - 0xae7bb930, 0x4fda1c69, 0x53efedbd, 0x3ca96f2e, 0x430ce61b, 0xa2f3051f, - 0x1ddfdf34, 0xda76fb1d, 0xef2fc02b, 0xfb7e788a, 0xf603b739, 0x033b7d8d, - 0x7c53e9ec, 0xfcb8db3d, 0x5cf8f4eb, 0xc81ca953, 0xd3d983bd, 0x84459be5, - 0xe303455f, 0x91618aff, 0x4fad073e, 0xcf16ff4f, 0x60ef1761, 0x0774b0e7, - 0xfc2ad979, 0xadb77e2f, 0x1605ce06, 0x1cf017af, 0x005fbe19, 0x78731678, - 0xe3173916, 0xdaf14a39, 0xe53fe7f0, 0xa6a2dfbc, 0x5f0f18f5, 0x2bf6d3e4, - 0x29f5761f, 0x4cf247f0, 0xaf790f0c, 0xc9f5be08, 0xeba0cf90, 0xe78d5ce7, - 0xdaf5e547, 0x7ef907e7, 0xb4fe8a17, 0xe4fbe857, 0xd3bfcccf, 0x1ea0fbc3, - 0x123f252e, 0x5c29fb2e, 0x70f5fe32, 0xd40e0de9, 0x01f3c7be, 0x2b0e3c3d, - 0x649d2572, 0x6e7e1f00, 0xf15ca170, 0x42e143be, 0xb1e3bbe7, 0x40fb9ae1, - 0xbcb8738e, 0xf4d7706b, 0x02157e87, 0xb75e2bf6, 0xad024f65, 0x6327abcf, - 0x78a178e1, 0x070f56ad, 0x03837ef5, 0xaabcfaf5, 0xc7e4022d, 0xfbdfe42e, - 0xc31ef895, 0x5d6e547b, 0xed3cf546, 0xe4dd20bf, 0xfdf07386, 0x9b940111, - 0x47c6dd0a, 0x8e25fb30, 0x03a3a1cb, 0x3f515302, 0xe4760a35, 0xd3047f47, - 0x704f1457, 0xc4f34bbf, 0xbc73a7af, 0x2352b8b0, 0xc52563c3, 0xf4f3f01b, - 0x63af5e26, 0x4a2de076, 0x39f05ebd, 0xbbab9004, 0x8c5f7664, 0x8e04e240, - 0x847e9504, 0x04ecd5f3, 0xb4779e15, 0x28dffa33, 0x8f81f138, 0xf043f7fe, - 0x33dd2bdc, 0xf4afa63b, 0x3e29c0ae, 0xfde78b42, 0xe379ad11, 0x9bf9c1fa, - 0x737bc4e0, 0x9cf0629a, 0xbb2d58e8, 0xbf9525ff, 0xf00be7a7, 0xd1f7d43b, - 0x438584cc, 0x088cf37e, 0x79c50fcc, 0xa65d9853, 0x7bfa4f96, 0xfe6fbe80, - 0x45692551, 0xc7942c7b, 0x04de7ee8, 0x3410cde3, 0x09104ef9, 0x09ff3a03, - 0x7cd5bfc6, 0x9249f181, 0xef96f31d, 0xedcf2bb2, 0x5e2cbbec, 0x799c1e6f, - 0xef851e68, 0x13a255b9, 0x0c9ba85c, 0x2059838e, 0x09941e6f, 0x7db9cbf0, - 0x81e98bb2, 0x853bd428, 0xefc51eef, 0x0e590ad9, 0x8fbc291a, 0x7ca397e9, - 0xbd511f3d, 0x0a5882ed, 0xf70f1fa9, 0xee76cce0, 0x7880e69a, 0x95fec64b, - 0x2b39ce70, 0x20f07ed7, 0xbb3573e0, 0xaac8e907, 0xeed3f45c, 0x7e4053ba, - 0x06f14c3b, 0x9d99cfef, 0x9d20f07c, 0xf155d6f7, 0xcf396e78, 0x9c237f15, - 0x27dbce63, 0xdfb41d3a, 0x16adeb82, 0x66bcc738, 0x2adc48a4, 0x5a4adcf8, - 0xaf33be31, 0xb039ceea, 0x0faa12ee, 0xf72864c5, 0xfa844b4f, 0xafdf013a, - 0xf08dbaf4, 0xdaeb66bd, 0x3a0cc6b3, 0x07ed117f, 0xc75caf60, 0x106e55fa, - 0x5dfa909c, 0xca18f4d4, 0x020da2cb, 0x4ad3345e, 0x1b335fed, 0xe3a667d7, - 0xefa3aeb6, 0xbc317ad3, 0x886ee30f, 0x27ce11b9, 0xf13ae92b, 0x78d509fd, - 0xdf445d2e, 0x75a4cda3, 0xde389dc3, 0x810275a2, 0x264b03ef, 0x01323f24, - 0x3b27dbc6, 0xaed0fda1, 0xdd611b5f, 0xfaf9d1b7, 0x8817f1d3, 0x3fa0d36d, - 0xc760a5f9, 0x46ea87fb, 0x0baddc60, 0x542f0c36, 0xe63ac70d, 0x0c103b13, - 0x651f3a92, 0x4efb0447, 0x755968b8, 0xcdabec0d, 0x406c9f1b, 0x046b3aba, - 0xc28c7e3d, 0x3c874ddb, 0x2e79646a, 0xc6a3decd, 0xfd1c9536, 0xdf152228, - 0x1b31a3bf, 0x921626f3, 0x709bcc7c, 0xa47b3357, 0x0f84657d, 0xb2ed6ae2, - 0x6f3c087d, 0xe7c2695e, 0xfd312f9d, 0x0db839d3, 0xd627dbe3, 0x5fbe04c9, - 0xf52eb15c, 0x89e3c069, 0x9bd232cd, 0x1bcb2cf8, 0xc5897e28, 0xb1d79ac9, - 0x352c4f71, 0xa0b57bb2, 0x5f8bd69d, 0xb40af254, 0x51c8ac72, 0x2f4a728a, - 0x6b72f497, 0x46d593d1, 0xf21ed920, 0x9474e96a, 0xef54a557, 0x90f5a100, - 0x306a8357, 0x5797aa6e, 0xc8a2c495, 0x5f8874a9, 0xbe0f9616, 0xf1d02d6d, - 0x8183ecad, 0x5f6bff56, 0xb77a053e, 0x49e04acc, 0x5a7f6485, 0x80417460, - 0x6d35e65f, 0xa0f812f9, 0xde045e64, 0xf01c75c7, 0x26b37c00, 0x8bafcf0e, - 0x6f08857c, 0x78b72f25, 0x95ce96ad, 0xb75ce3f8, 0xfd6a5c48, 0x5c451255, - 0xee877eaa, 0xe74af4a3, 0xf051bdb9, 0x743ca881, 0xbbdefb5f, 0xc76eb033, - 0xf6e32d75, 0xd22b1ac1, 0x9f9fa1f3, 0x7af4095d, 0x0102bddb, 0xdd789d7b, - 0x2b0fa035, 0x880e0ad6, 0xcbdf170f, 0xefa62fde, 0xfd0fbac3, 0xa515d19a, - 0x7fd0076f, 0xf6c7bac5, 0x820dff62, 0xb43fc603, 0x89ed10be, 0xb048af12, - 0xfa3b437d, 0x614f540f, 0x57b3599e, 0xaffa004c, 0x0764dfb8, 0x23a14953, - 0xf9db2e85, 0xecc4087d, 0xbe8b331c, 0x15160ab7, 0xc51e93df, 0x4fa82102, - 0xbd2a4e81, 0x5fdace8c, 0x36409d92, 0xf64ba717, 0xae09fc1d, 0xe767c55f, - 0x74ef874c, 0x047ea98a, 0x975e6d3a, 0xe23b046b, 0xfcc04f84, 0x49749e8a, - 0x4a3b6a2c, 0x0567cba1, 0xd07baf26, 0x7b0e8ea3, 0x4ba71dd0, 0x5128fe85, - 0xb6595fa3, 0xfdf0264f, 0xdd1e9ebd, 0x908dfd72, 0x32f851ff, 0x6f5d0fdd, - 0xd1cfcd6e, 0x48e0575e, 0x2f5009eb, 0x8fde5892, 0x12e50fc2, 0xdefb0fcb, - 0xbfcdd3eb, 0x87e78229, 0x2c883f01, 0xe74fc97f, 0x0bf37b7d, 0x66792f98, - 0x6875fb53, 0xe941bcdf, 0xd9bfe000, 0x7fe8fc4a, 0x950e50f8, 0x6f988836, - 0xe67f244d, 0xaedf952c, 0xfe2cbfe4, 0x5de11583, 0xcbe4d5ba, 0x6e97efa3, - 0xf3063a3f, 0x30079611, 0x49bbc7bf, 0xde1fe760, 0xfdf031b6, 0xf2c4a950, - 0xc176f470, 0xe71648f0, 0xaa2d78ea, 0xa136ec00, 0x57b3dd8e, 0x6c937f5a, - 0x0775c552, 0x2f38ca45, 0x63e787ed, 0xb8678a5e, 0xa7d6011f, 0xc94ddfbe, - 0x9178e9bf, 0xa3695fd1, 0x695cf68c, 0xc84e96dd, 0x6c3d2cc3, 0xb2b73f42, - 0xfc11acee, 0xbc3fdcd8, 0x55f3f784, 0x3c9a8a36, 0x6ff91ebc, 0x04dfa275, - 0xe50d5bf9, 0xeb437e78, 0x0faf58ed, 0xb17a079f, 0x7fc5ad3c, 0x4bddb1d8, - 0x95f8b841, 0xbef0d9df, 0x368dd6be, 0xeea9eefc, 0x3da7f9c2, 0x57eaddf2, - 0xeddf305f, 0x0941fc34, 0x5d48baeb, 0x931d60be, 0x997d746b, 0xc4e261f9, - 0xa5eb7b41, 0x7c839f2f, 0x7fad8eec, 0x5bd60e7b, 0x9ee75ff6, 0xb21abc83, - 0xf60ec233, 0x0fa6e548, 0x79559f30, 0xd99224af, 0xfe2f9d7f, 0x3b80f30e, - 0x6139343f, 0x271dceb4, 0xd1bd8086, 0x04dbe5b9, 0xba5defc8, 0x73c61a63, - 0x4dcb6e96, 0x05e26124, 0xeb74094a, 0xb21e43eb, 0x0dcd5f1e, 0x73ff98cd, - 0xe41be286, 0xb17f3043, 0x83e59cbe, 0xe2de783a, 0xdef9f0e6, 0x1b14f23d, - 0x193f5d66, 0xb30362e4, 0xaf9a2e0b, 0xf1e28078, 0x6fe03ef2, 0x4f2e6af3, - 0x0cefe3c2, 0x54f141fc, 0x57cda913, 0xe161b2fc, 0xb6819e6f, 0xf35eb886, - 0x807dfd15, 0x3e4f929b, 0x58f5d22b, 0xd6cdf024, 0x287e63df, 0x01cf2de0, - 0x21cbf9f2, 0x293e1710, 0x10fe3007, 0xefc261d8, 0x1c774b2c, 0xdce9fe42, - 0xb5f31fb6, 0xeeebcf09, 0xcb1fc124, 0x9eb1e5c3, 0x96560dca, 0x0fe1c8e7, - 0x1b0e9079, 0x8ef9e73e, 0x3c958e8c, 0x1ff2dec8, 0xf853225b, 0x4f2c2a7d, - 0xc7c37cb3, 0x8430af3c, 0xe002612f, 0x7982fda9, 0xec1c0aa5, 0xd42b8700, - 0xf3e1bcf9, 0xdf79834c, 0x3f805f1c, 0x7cc1d390, 0x041f5a5d, 0xe13e9bf9, - 0x0f230910, 0x3cb3d73a, 0xfc394ee0, 0x7e4accf7, 0x4f9eb36f, 0xebcb7d7d, - 0xbffad8bd, 0x221a7c2f, 0x1eae381d, 0xc3e71d4e, 0x9ce3f1cb, 0xf7f07fef, - 0xfe826521, 0x81cf93fb, 0xda1bcb1e, 0x899f788d, 0xfdf13fe2, 0x5a78f076, - 0xf31126c7, 0x9bea6b3e, 0xe5eb8e51, 0x273f0545, 0x1bf7afd1, 0x468adebe, - 0xb63a27a6, 0x3a167d5a, 0xaf5bc74e, 0x6c573d21, 0xd3bcc76e, 0x18af75bd, - 0xcbe754db, 0xaa7c27a0, 0xbcbc77f5, 0x6dca0c6b, 0x7e98bf7e, 0x9b14631e, - 0xfc29b2a7, 0xcf9b953c, 0xec59e66a, 0x2dda37ad, 0xb4ef9f17, 0xc609bae4, - 0xeccadd3b, 0xe2f5d3a5, 0xf9985f0c, 0x49bd714f, 0x0f3b2d48, 0xef12faa5, - 0x7bb2b359, 0x245b44d5, 0xad4b5fda, 0xf7470e13, 0x7988d283, 0x79aa2b2f, - 0xce7dcc9e, 0x0af7c024, 0xd604d5eb, 0xabe012bb, 0xbb65e3f2, 0x26dd809b, - 0xa867e527, 0xf59459cf, 0x8819fb1b, 0xa5ff854f, 0xe08919d6, 0x3bc9127f, - 0x5d71d608, 0xe812d7ca, 0x8b0f56bf, 0x47f393df, 0x56f3c187, 0x8e27bec9, - 0x553adb8e, 0xb5e84270, 0x34fbdd27, 0x2e998671, 0xf8b17ded, 0x5fdd1c0d, - 0xf680d3b7, 0xb7e0d5a0, 0x1ac42ed3, 0x0e849ad1, 0xa43883ac, 0x0214fc04, - 0xf41e21f3, 0xfdc16798, 0xcd4236c8, 0x94e7e853, 0x449ff734, 0xf774904f, - 0xc30390a1, 0x385abd28, 0x39712abd, 0x8e9bfb2b, 0xacf786db, 0x6a91a4c4, - 0x5635df20, 0x4f0dda37, 0xe869fbf0, 0x41e4246f, 0xa74892c4, 0x3a26fefa, - 0x38fbe6af, 0x1ea6af3a, 0xe3d6d2e3, 0xc2c74866, 0xbe3897e9, 0x05a2e98e, - 0xcd3310e1, 0x796bf8a0, 0xeb4213c3, 0x4e27898e, 0x6b5fb43f, 0x2801efc1, - 0xfbd5797b, 0xebb458b0, 0xc8d3eba6, 0x36b4e889, 0x53ad81af, 0x1c4edcf3, - 0xa5dfee02, 0xabd74e7d, 0x714617a9, 0x09112779, 0xdcc59de4, 0xbbfc384a, - 0x5fbef035, 0x013837da, 0x5fb843f0, 0xcf9025ed, 0x41f7cd12, 0xb7f4d7e7, - 0xcd807443, 0x0c871daf, 0x43bfabb2, 0xbfeb9cbd, 0x25fc9651, 0x329e9451, - 0x62615687, 0x49125676, 0x9ba5efc3, 0x4a7ca1fa, 0x79839659, 0xa32d4227, - 0x086b61ab, 0x00b0cdf2, 0x3fba9bcf, 0x9351ed12, 0xd2237899, 0xe2367be1, - 0x1661d395, 0x7043cf1f, 0xa1d0372c, 0xd69455a4, 0x814d7be8, 0x8a42c31c, - 0xa2687a84, 0xb94657e3, 0x9f28a3aa, 0x2774ccd6, 0xf6c2c619, 0x3bb95ede, - 0x52f6b90b, 0xaa1a0888, 0x1969eef7, 0xef04228c, 0xbdde20f1, 0x6bc6807b, - 0xec153a95, 0x6d7f9df0, 0x32eeb064, 0x9b5f7953, 0x3e8feac2, 0xdc2577b4, - 0xcf6e9337, 0x49f6147f, 0x7851f6cc, 0xd58fe5de, 0x9bddf3dc, 0x39d6517e, - 0x173f8372, 0x3abe05ee, 0x1df5eec0, 0x777e0d6e, 0xa3787a8f, 0xd1fba945, - 0xd86fc88f, 0xbcad728f, 0x1bb63f7e, 0xa1cb4ea0, 0x81dcfe71, 0x472f9f74, - 0x74969a1d, 0xa1af1d29, 0xd93e0930, 0xd0ea357f, 0x30eef81e, 0x578f8704, - 0x82141eee, 0xc3fcb483, 0xd5932d3d, 0x0f70f870, 0x857d21d8, 0x7d0fabc3, - 0xebe87088, 0x6c5d29be, 0x935cbc07, 0xd6fbc06d, 0xc16c38ae, 0x45fd0af8, - 0xe3e23ea0, 0xbbe5efac, 0xa11fc56c, 0xd354ece3, 0x429ef297, 0x4dd1bd57, - 0x628fb12a, 0xe96a6cf7, 0xf5ca2ba7, 0x25abac36, 0x358f75ca, 0xf78ff71e, - 0x76e35c00, 0x0b8ea73b, 0xb8b135d1, 0xeefdc1c7, 0x5bf32ca3, 0xf2f254a3, - 0x6225ec9a, 0x81c9c40a, 0xfb43e217, 0x8de65f89, 0x19f74118, 0xde6032ef, - 0xfb8b28fc, 0x2b63cc20, 0x7721f808, 0x1ee20aec, 0xbe218827, 0xd9abe650, - 0x9af5fcc1, 0x396f8342, 0x6015ef3b, 0xb47d10bc, 0xc023e8e9, 0x1db1a3e8, - 0xa9a2a3e9, 0x6347d19d, 0x06644e75, 0x3f03373b, 0xc60496bf, 0xa23bde02, - 0x51269abe, 0x151a1ffa, 0x91ba01a8, 0xe5a6e7bd, 0x3d708a5d, 0x7c3f161d, - 0x7abeca7d, 0x4b6d6fc3, 0xe06943ca, 0xe033ee4f, 0x37029779, 0x858c5fa5, - 0x58b6c5e5, 0xfc035fdd, 0xedb4272a, 0x6d6fed85, 0x36f31f79, 0xd86efb6c, - 0x66dbef05, 0x42390c53, 0x5beed6f3, 0xd767f78e, 0xd87dd806, 0x05e024d1, - 0x3c3bdebd, 0xe104ff18, 0x1a4f7601, 0xf91da3c0, 0x5eff1365, 0x7051ab2c, - 0x1a1f9e81, 0x890deec5, 0xebf3b0b4, 0xd7111621, 0xcec2c439, 0xbdf7e259, - 0x95bf8225, 0xfb01bf75, 0xa69943c7, 0xbcfdffde, 0xaf89a4bf, 0xe854f82b, - 0x28d24a89, 0x4ce47fb8, 0xa2d13b8c, 0xa8d89fa1, 0xca78d514, 0x88788f7b, - 0x47aa0ef3, 0xff3dd8af, 0x94abd02e, 0xfc00be7e, 0x968dfb04, 0x4a6e0023, - 0x70cfa07f, 0x0defa1f8, 0x1e60f987, 0xecb617b0, 0x3de2225e, 0x6bc47d1a, - 0x491bdc26, 0x914667fb, 0xfdf4adaa, 0x425a68cc, 0x13d78e3d, 0x2b207d79, - 0x1a713f53, 0x3d7cfa04, 0xb64ebb8f, 0xc931fcf0, 0xd186ea3e, 0x5c766750, - 0xea245256, 0xe16f8505, 0xb738080e, 0x75f9f896, 0x00c5204a, 0x58f85378, - 0x56fc180a, 0x2452b4aa, 0x18f20187, 0x7dd0f1de, 0x9dcbbd4b, 0xdf652fab, - 0xcf9fea71, 0xc1f9ebe4, 0x3d17f5f6, 0x099eefbe, 0xb7372df0, 0xad03723d, - 0x0e7a5c57, 0x479707cf, 0xa1795c55, 0xebf42f7b, 0xdbfce77f, 0x4d874051, - 0x7ec298df, 0xe1c3550f, 0xc029e2d6, 0xbdf932f7, 0xc951242e, 0xb1e55633, - 0xcbb71b42, 0xf8299510, 0xffaced1c, 0xf8081140, 0xf0b14af4, 0x9e32547e, - 0xe5d14e1f, 0x9f87fead, 0xc132f9c5, 0x71250030, 0xcf3628c9, 0x324ecc37, - 0x9ce0ffd3, 0x173f1a69, 0xaf72477b, 0xdef1d2b0, 0x357cec21, 0x19aaae33, - 0xc6c4c4ea, 0xfbda26cf, 0x6b13320a, 0xb8c2c6a7, 0xdf18c9d1, 0xdaeb35ca, - 0xc812bd53, 0x8c9a9269, 0x88d38979, 0x7a633eca, 0x08eeed03, 0xe3902eba, - 0x742c8cd7, 0xe7ede54e, 0x4d43ffe8, 0x2a99f6e4, 0xc72ae37f, 0x8d54e75c, - 0xf78b52fd, 0x9fe9fd01, 0xf2e1ede2, 0xfce33e2c, 0x77c9e2df, 0x1eb3f9c2, - 0xe10e399e, 0x27a3ab7e, 0xd470f5dc, 0xab815dc3, 0x9fd98e1e, 0x86c6a738, - 0x2e1e9381, 0x48ed48d3, 0xdc0a63d0, 0xc77970f5, 0x9de2e8cc, 0xabde1334, - 0xe0c48ef8, 0x23350ef8, 0x9ba41ea1, 0x01ef1168, 0xf5e28cce, 0xbab04737, - 0x64a8ef82, 0xae1eb7c4, 0xc666387a, 0x58e3f7f1, 0x2f00bdff, 0xe202e509, - 0xcc9ba147, 0x31ddaad4, 0xec507a2a, 0x2e1c69eb, 0xfb46bed4, 0x8ade3739, - 0xafb02671, 0xe08425a7, 0xd6ce5b96, 0xf2dc3b95, 0xf4a9f83c, 0x72bfbc75, - 0xff3fe10a, 0xca2f3c14, 0xce0555e4, 0xdad1be53, 0xa69ad3c9, 0xc338829f, - 0x7efb9350, 0x1080cfa0, 0x1475e783, 0x707447ee, 0xd767bed7, 0xf870f5d6, - 0xb131fc03, 0x3a14bc27, 0xe3c2c0fb, 0x20c8034e, 0xbcc797b0, 0xf20d1196, - 0x86c5349b, 0x715c4b8d, 0x0e383f38, 0x63a457a7, 0xcf83b881, 0x423fa9ed, - 0x5aa3ed8e, 0x36c72552, 0x96d3ee8b, 0x4c729ef8, 0x8e64d3c1, 0xbbc4c987, - 0x934be20b, 0xd045f489, 0xed0e481f, 0xe7d95bbf, 0xf6103240, 0xc1c58379, - 0x67df3fe4, 0xbcd4df70, 0xf8b3f984, 0x0b6659fc, 0x02435f7e, 0xce104752, - 0x91df7829, 0x5a1b18d7, 0x4fbf9287, 0x66115486, 0x7bc3cdcf, 0xc85c29ae, - 0x75a15177, 0x8482ac98, 0x75f0fdf7, 0x7b33a99c, 0x5bad8f21, 0x9d814774, - 0x1bec21d7, 0xfc93fb83, 0xe9ff4023, 0xee35cfdb, 0xda7680ae, 0xf1fb08af, - 0x59162ff5, 0xc3b021fc, 0xb93e7be4, 0xb2953b77, 0x8509ea35, 0xfbe0b37e, - 0xde81cbd4, 0xdd6103fd, 0xd1d54053, 0xf659e772, 0x6376431d, 0xecf304ba, - 0xff7966e9, 0x8125c439, 0xdfa7ab7d, 0xa1a74bef, 0x08604578, 0x5d8a29f8, - 0x1eead536, 0x57cfa569, 0x9b66eff3, 0x05188ece, 0xf4c1f978, 0x4f4b4074, - 0xba511d0a, 0xecf00f1a, 0x69fcf8ca, 0xcddfc730, 0x7a009738, 0x43dfb151, - 0x026b8a76, 0x3b37a7ac, 0x3dd5897e, 0x3b017ac5, 0x2e67b15e, 0xdd9087e6, - 0x74a641d4, 0xcbc71b74, 0xccab733c, 0x600fcdee, 0x48eafdfe, 0x473b5ee5, - 0xb791d824, 0x54d94ead, 0xd586e707, 0x6b7efe2c, 0x83f1ac95, 0x86dd90dd, - 0x66fbb3ef, 0x6da65f6f, 0xfe604cff, 0xfb57a17e, 0x3412589c, 0x9cf6edf7, - 0xc035e0d7, 0x3123c3bc, 0xaf3f413f, 0x79fa7f7e, 0xe6adf3f5, 0x636ad57e, - 0xcaa748ed, 0x6560592e, 0xaaf750f6, 0xcae0ebc7, 0xe7e0deba, 0x93480f36, - 0xb5abf754, 0x082c8ead, 0x328c6f77, 0x79ef029e, 0x00e2cfc4, 0xc3dff255, - 0xe59b83dd, 0xde81f166, 0x98161de6, 0xe1a0768a, 0xf608bf49, 0x4100b0fc, - 0xe02b3bfb, 0xf8d02c32, 0xee4fcc01, 0xbdc007e1, 0xd65eb426, 0x01f98bb0, - 0x4fe8d5f5, 0x027f5194, 0x387accf4, 0x17c01e9b, 0x41fe8694, 0xfc85dfd0, - 0xcfb82ca9, 0x12c3fb92, 0x5ad497a5, 0xf5a37fd6, 0x096ae35d, 0x927755fc, - 0xe363294c, 0x98d7efc3, 0x93555fa9, 0xf508224c, 0xf8785eab, 0xc06be9fd, - 0x09758e5f, 0xad287f70, 0xf7fa58d7, 0xf8debfdd, 0xb81afef0, 0x65fa946f, - 0x7f2aaceb, 0x78fe37b7, 0x0b918c04, 0x3dba47f0, 0xa1f0237f, 0x8a68af12, - 0x111f7ce0, 0x8068bba4, 0x57274297, 0x7e8f9b2f, 0xe725c445, 0x589e4087, - 0x16ffc716, 0x46c38f2b, 0x129ff7b1, 0xbf905bdd, 0x023f3adf, 0x8cefcbe2, - 0x5cfe8a3c, 0xe7c59593, 0xd04a79f7, 0xb9f0527e, 0x3f702acb, 0xf8103fc9, - 0xcdf1daed, 0x6497e071, 0x43de02c9, 0x9efb24da, 0x7900cf4c, 0x82bedb34, - 0xa26b296e, 0x6b13bf11, 0xbc0ff08a, 0x35a7655b, 0x9b4cfbf1, 0xa81deece, - 0x661e63ce, 0x4565ddcd, 0x308bf3fa, 0xeec6567e, 0x7befa0c3, 0xfd212fd3, - 0x7f4012e1, 0x13fbf390, 0x61a8fcf0, 0x42e20d8f, 0x827efc1d, 0x09cd0d33, - 0xbe5969f3, 0xf0362fe5, 0x70e7ded7, 0xe2b52338, 0xdb654a3d, 0x83ffbc44, - 0x0b709bce, 0x161ba7c4, 0xf7efb264, 0x8a6777d8, 0x67ff4cfe, 0x167cc0f3, - 0xc8efc434, 0xb2727b14, 0xf583ebd9, 0x188b5535, 0xbbac9e2f, 0xbf0a6c37, - 0x5f6f4c37, 0x712ab49e, 0x87cc04e9, 0xf3676a5a, 0x594fc6f4, 0x9f12c4df, - 0x24b2df8a, 0xcfeb08bf, 0xc08126fa, 0x5a679715, 0x03c89e52, 0xcec89e3f, - 0x44ac30e1, 0xcafda376, 0x6fe89fcf, 0xbe43dc37, 0x6cde5793, 0x4aeb3738, - 0xfdfb6624, 0x77600997, 0xe0b1fbb9, 0x8a07d322, 0x1be5377d, 0x6f557c6d, - 0x8d34e6e7, 0x41207fbd, 0xa77fb378, 0x55eec022, 0x06ff61eb, 0x7bb587a6, - 0xe10c7909, 0xf52dbe90, 0x2947b81a, 0x3b068ffd, 0x7c02dbcc, 0x3cf80f11, - 0x54fcf787, 0xd08dff10, 0xda20d15e, 0x927eb0fd, 0x95f01971, 0x70283762, - 0x6cdf3c69, 0x91d7431e, 0x5f60d675, 0x3378874e, 0xcffa05f0, 0x2fbcfee3, - 0x5357f40e, 0x8273c240, 0xa3bbb3ac, 0x60e4a816, 0x3e0379d3, 0x5bfcf37f, - 0xd881e7da, 0x2dbde0cb, 0xef17e606, 0x28f7fbde, 0x9e6f4b90, 0x82f1c6ef, - 0xbb4f4376, 0x6b91e118, 0x67718315, 0xc44c5db5, 0xb79003ac, 0xaa9a2d35, - 0xbb77a131, 0x7213fb37, 0xb4f495bf, 0x1ec0721f, 0x11d8c311, 0x3e74ce1c, - 0x6f48f809, 0xe36e5c57, 0x24c1e6f1, 0x6ca3ee1d, 0x18b71f3c, 0x8a6e1fbf, - 0x7d472fb2, 0xaea5eccc, 0xbf1fa7dd, 0x13ef9e06, 0xe711fdd9, 0xb7a7e445, - 0xda1e2e76, 0x2a5be2a6, 0x5f4f1139, 0xf9db3ff5, 0xd5ffed06, 0x4716489e, - 0xa9979c97, 0xf50877bf, 0xf97871f7, 0x38f3b007, 0xd7b800ef, 0x2fdb07e9, - 0xfafc3d1d, 0xc3da1b3c, 0x1ea0e981, 0x376bac46, 0xac5bfe02, 0x90d9d7f9, - 0x00a3eadf, 0x33925e2e, 0xf3804c90, 0x7403927a, 0x7626a815, 0xb5b627f0, - 0x97800c18, 0x98c98d8c, 0x9f89b3a7, 0xafaa2e57, 0xe8ab2635, 0xef3f1162, - 0x877b293a, 0x1f9eaac4, 0x72f931b0, 0x6fe94f72, 0x43e34f30, 0xc61e1913, - 0x31b06cde, 0xd18afb7d, 0xe866cd7b, 0xdf80c477, 0xfbdeed0d, 0xcfb85efa, - 0xc761d178, 0x3dff8858, 0xbf607362, 0x6a9b7dc6, 0xf1b7cf20, 0x5452d013, - 0x14286caf, 0x37de740d, 0xefc58388, 0x1fd0180e, 0x893dc60f, 0xf9f60e2b, - 0x1bcf5f10, 0xf9cd062d, 0xdefc1bd8, 0x326d7bdd, 0x89b12fb6, 0x2dadc788, - 0x37a07139, 0xbbeeac5a, 0x8e2fa06d, 0x12c0d5b5, 0x629f7894, 0xb03c4daf, - 0xf4d19af5, 0x061d89cf, 0x71dba03b, 0xf61179e0, 0x484938eb, 0xd87a408c, - 0x8f3c746f, 0x3a37bc7a, 0x1d7478d8, 0x2abf016f, 0xff9aa7f0, 0x7f5a34a1, - 0x858a55a3, 0xfe052efc, 0xf9943eca, 0xb5c4f51d, 0xe4ac82de, 0xb8817ada, - 0x3a5f92b3, 0x7f944ece, 0xd2e9012f, 0x6a3d7368, 0xda0ef663, 0x30f727d7, - 0xae15e8bb, 0xe1524947, 0x829f8050, 0x8b1b7aa7, 0xe9eb2a33, 0xdbdffe6d, - 0xca549e98, 0x9bd74bef, 0xe9178764, 0x0fcb1b66, 0xe6fd7877, 0x6b23c854, - 0xcf7fc54c, 0xfb679549, 0x93e7a47b, 0x1b057bda, 0xf8060cdb, 0x8762ac0e, - 0x6de68310, 0x20ebed1f, 0x48f5499d, 0x09878d7f, 0xdd6971f2, 0x48ee2c9d, - 0x7fbf0de5, 0x81d1cf0d, 0x7a79f87f, 0x1396817f, 0x18afd69b, 0xdbf5f088, - 0x7042af80, 0x65037ca2, 0xe811ad55, 0x5652d175, 0xe973f316, 0xc8dd6b45, - 0x58eb459f, 0x5b1ee17e, 0x0ce7ae32, 0x886257a7, 0x27f9001c, 0x657f0e2e, - 0x6e9c79dd, 0xd13c354f, 0xfa52f30c, 0x73e013fa, 0x4f63e352, 0x7a1572c3, - 0xc641b53d, 0xb5224a71, 0x7cadf6e7, 0x18076dbc, 0x20dc4fbd, 0x5ffdc0e7, - 0x0ec4bd13, 0x3637ec71, 0x7e41146c, 0x9cf401bf, 0xf41cf8cc, 0x0f3dc9ed, - 0xf402fd46, 0x4081bb5c, 0x2315fcbc, 0xe2a2d929, 0x5febdd8b, 0x696ff0d5, - 0x1835f55d, 0x158b6f97, 0x7c2bce40, 0x15fdc0ab, 0xe42af3a3, 0xfc74ebff, - 0x2fbd953f, 0xdfb03b47, 0x9fff9c13, 0x9ff94198, 0x10d98a3e, 0xaf38c023, - 0x07dfc318, 0xa40ff5f7, 0x6d5ca0bf, 0xbf5721eb, 0xcdb57266, 0xafe74a96, - 0xe31bb6b8, 0x71f5c10c, 0xaa6279ba, 0x02c93742, 0x6296bfc0, 0x8bc01870, - 0x99e815c2, 0xdfb7cdda, 0xd95c8690, 0x0f39e122, 0xf9e2473f, 0x0277ca1f, - 0xe486bf0a, 0x6eb7c299, 0xd5d83473, 0x8056ab53, 0xe7971f5d, 0x253cfa45, - 0x52c687b8, 0xf80a767d, 0x383c8c38, 0x57c7e5c1, 0xf762fbb2, 0x7a000fee, - 0x221ea12e, 0x13ac87ec, 0xa51780ec, 0xdd8eb1dd, 0x5a3c3ac3, 0x2bbf9cd0, - 0xef0c1ff5, 0x41fb8f40, 0x7c634787, 0x3c84603a, 0xa63e11d5, 0x839088c7, - 0x570c40fc, 0x5b3e000f, 0xcdd7f544, 0x4a75fd2a, 0x553a45ae, 0x347970e0, - 0xc55f5f93, 0x95ff7db0, 0xe21585d3, 0x2f73aa85, 0x024890ea, 0x605167e3, - 0xf8c22e7c, 0xba4cf6a7, 0xdafde90a, 0x076ef4f0, 0xfe162aff, 0x48f5a73d, - 0xec33319f, 0x13cb1df8, 0x46223392, 0xb0f91f63, 0x57f1bddc, 0xfd01d7e8, - 0x46f7bf02, 0xff4025ff, 0xfbdd0c24, 0xf0abdd28, 0xa501d0a7, 0x55a26b8b, - 0x174f41f2, 0x02a379ca, 0xe7745797, 0x33474f95, 0x9780b079, 0x66f25e8e, - 0x60fcfd94, 0x81ec9f3c, 0xcf0cf9e7, 0x7c02be21, 0x67e1f22b, 0x3dafe117, - 0xaf6c76d1, 0xe60174f9, 0x73f2d4a9, 0x9f3e7aab, 0xd1a5eeb2, 0x4b7ce682, - 0xca34ee7f, 0x5a2bbee2, 0x48ea3e77, 0x34c7d10b, 0xd92ecf6e, 0xff73c268, - 0x7802d02d, 0xbdfecddb, 0xbb3de56c, 0x0a4f0d44, 0x4cd115ea, 0xe1f42b8e, - 0xc3246658, 0x55f2ffa8, 0xc86ee172, 0xab59f9ff, 0xdd346f37, 0x77a316c7, - 0x07e8b5f6, 0xf182af38, 0xd833caaf, 0xc6241f21, 0xde201765, 0x7c0a2481, - 0x33cd8fb8, 0x1979d52e, 0xe70ec9fa, 0x0f079038, 0xf8297c73, 0x9bd0e055, - 0xaf0deb9e, 0xe27c387b, 0x8e5ebb79, 0x9efe7314, 0x5c5dfbc2, 0xe045788e, - 0x2f711b27, 0x59fd6117, 0xe505fe4c, 0x73c11648, 0x727597c9, 0x5e9fe5e4, - 0x91acbc8e, 0xc2da1323, 0x0bfa11ca, 0x1bf1ffcb, 0x4b1da216, 0x63b7870e, - 0x3d334677, 0x93fa0f1c, 0xb2f78bf6, 0x3987def3, 0xc48a52dd, 0x0ddac9bc, - 0x5713cc26, 0x366d90e4, 0xaf7f81c9, 0x16fa06d9, 0x1f76cd7a, 0xc5e70c9e, - 0x9c074649, 0x03929f5f, 0xd453f788, 0xfa45af01, 0xc7fbc7c8, 0x0223c8c3, - 0x47ef12f1, 0x9cefd083, 0x9f213626, 0x5046992c, 0x78deee7f, 0x4955d205, - 0x74008a5e, 0x23175a5b, 0x54ec7b40, 0x94e401bb, 0x962b8fb2, 0x71b0c819, - 0xd40707c8, 0x6f0ae472, 0xcdbbfe15, 0x49dce343, 0x47210c72, 0x33fb3d1f, - 0x8da8bc75, 0x22f1d5d6, 0xfbe07f5a, 0x468e8bc4, 0x78801e07, 0xae6c3fd1, - 0x94779876, 0xea28ff25, 0x912ac4b7, 0xc5d6e4a8, 0x4a1fb7ec, 0x2e3c952f, - 0x34a95a45, 0x81c4d04e, 0x6073ab6f, 0x582bf81c, 0xe380c54f, 0x7870c34f, - 0x7b5846af, 0x1fa3ad9b, 0x13e40b97, 0x97e8f882, 0xfc42255f, 0x063b9145, - 0x2fe2ac7b, 0xa197900b, 0x037fdbf0, 0xd7b57d1c, 0x00008000, 0x00088b1f, - 0x00000000, 0x7dcdff00, 0xd5947809, 0xe77df0d5, 0x24cb2d9d, 0x7642c993, - 0x03bbec26, 0x4eb1ab09, 0x04906008, 0x8d441007, 0xb0900938, 0xd2910364, - 0x208196d6, 0x2b188a06, 0x0eb154b5, 0x4551fa14, 0xdb1ab61b, 0x1a4013a0, - 0xad563414, 0x61a5afd8, 0x80891d91, 0xe58ad3fd, 0x7bdce73b, 0x264ef333, - 0xe79f6a02, 0xcdcf0f0f, 0xcf7bde5d, 0x773dfb3d, 0x79632d49, 0x9b19223b, - 0xed50b390, 0xccc9a906, 0x831b163c, 0x43632f1f, 0x087a3e79, 0x6b9859e6, - 0xf26b6320, 0x01de7975, 0x9fc75d8c, 0xa269fd3b, 0x678e3e15, 0x30d6fe6c, - 0xb53349eb, 0x7fe1d767, 0x268c5d79, 0x649f595f, 0x9fc7d93d, 0x24bf8f9f, - 0x4c33ffc1, 0x2b1812cf, 0xe1a7e263, 0x70ffdfcb, 0xdfc7b418, 0x54dec655, - 0x805689dd, 0x12dcdca7, 0xd8ceddd5, 0x13c7f933, 0x52d491dc, 0x223ddf87, - 0xb97178c6, 0x71debde3, 0x55de798c, 0x0fc816d9, 0x4a3d1936, 0x64e2fc34, - 0xe8826b76, 0x06947e0f, 0x041967c5, 0x55437ff9, 0xfe97632c, 0xc5f4a3ad, - 0x32f2b89f, 0x7a8afbe0, 0xb439639d, 0x185068ab, 0xd1cc62cb, 0x19cd7995, - 0x4785d58c, 0x5fd0620d, 0xa748bece, 0x292fca01, 0x8329af66, 0x870800d1, - 0xa23fc241, 0xd41b7d35, 0xd8983757, 0xca5ec86a, 0xe119ac61, 0xd9a23bd5, - 0x077e3f00, 0x0fa67e1d, 0x6bca00cc, 0x630b2e1d, 0xff78c29b, 0x7b64c29b, - 0xb483347b, 0xecd192db, 0xd7a7c004, 0xf40d1633, 0x6983c481, 0x036e92f6, - 0x1f3099f4, 0x8018f33d, 0x3eadd94e, 0xadd2f115, 0x9163aed5, 0xadf471fe, - 0x4ddbe68c, 0x6039d76f, 0xf7813afc, 0x543b4d9d, 0xd873e03d, 0x156ada98, - 0xf728d2d2, 0xa8f3c458, 0x2c6aaaec, 0xa8f7cd8f, 0xa59f686e, 0x00b3ed54, - 0xe678d85e, 0xcce502d8, 0x848f8307, 0x18d616fa, 0x2398d905, 0x2828ce2d, - 0xd9c6751f, 0x1de60038, 0xf60a62ed, 0x1a32d8c7, 0xcba45fbf, 0x38b2fd85, - 0xfd0052a7, 0x2307fb0c, 0x767ec8bc, 0xec568d36, 0xf35c6f00, 0xc01ec518, - 0xe24d305f, 0xfeccf5ab, 0x73d7ec53, 0xba40e748, 0x7398ebda, 0xfaefb423, - 0x2c31bf72, 0xd2bedfca, 0xb778d0aa, 0x46b9ddbb, 0xd879f346, 0x9c8fdf0a, - 0x0067ddee, 0xf1cf8678, 0x03da33ec, 0x519733e6, 0x1e2d297f, 0x11d2479a, - 0x8ba60e77, 0xcfd4312d, 0xc6be33a8, 0x4baed001, 0xca07cc15, 0x543f9ad3, - 0x5569af10, 0x71d20acd, 0x825ed367, 0x3f79b537, 0xea11814f, 0x7201dd20, - 0x8f301755, 0xcd1d16c5, 0xa145b163, 0x99c5e574, 0x7fa82e89, 0x6c5eeac4, - 0xc79fea19, 0x62771cca, 0xbebff415, 0x7cfb5ba9, 0xb7bc027b, 0x278867c1, - 0xab72dfd9, 0xb269fa91, 0xf3847fb8, 0x72de9cab, 0x476f7900, 0x48a39fd3, - 0x88e21a2e, 0x8e8709be, 0x96123d13, 0x78a0ce00, 0x0a85a1fd, 0x85f5aa83, - 0x23a53340, 0xddb8279e, 0x8899318e, 0xf89f806f, 0x09311ac7, 0x8c62f2f8, - 0x91c706bb, 0xd91427ed, 0xb45f5022, 0xcf77c5e7, 0x598e652e, 0xfbcf003d, - 0x6eb2778b, 0x12f77748, 0xbb7b7ba4, 0x21878f81, 0xb38b313f, 0xa4bbfb16, - 0xce38e9b0, 0xf942984b, 0x979e064b, 0x95abfaf8, 0xeb11ebe3, 0x7896c5a4, - 0xf02b278e, 0xbc614bf1, 0x7a1eb05d, 0xb3bfcad7, 0xcd617e0b, 0x1e705f9c, - 0xbb64bfa8, 0xdbdfa2dd, 0x3d5cee9d, 0x08cd93e7, 0xde11c8e7, 0xc3b7c87d, - 0x90fb3cf3, 0xe098d3ff, 0x27ce3c93, 0xcfbefcc1, 0x467ea36a, 0x8865699d, - 0xb9852cf7, 0xd32ee902, 0xa1ae10d7, 0x89a3dfc8, 0xb61e407f, 0x52c378e3, - 0x800354aa, 0x13acc712, 0xdec67758, 0x5da9dab6, 0x3ee708e6, 0xd3ab37e4, - 0x207cf245, 0x2be54ac2, 0xc07f3833, 0xfc407ff7, 0x2ed3cb05, 0x7e01a394, - 0x7e438a39, 0x8fc8ec8c, 0xbcf013bf, 0x63a5e42d, 0x613feeff, 0x3acd71ff, - 0x0c9d02a7, 0x65e9123f, 0xa2f874d0, 0x8fe1152a, 0x00ffc063, 0x358e6da0, - 0xa52ce507, 0x5d20a1cc, 0x875c229b, 0x230fd4ad, 0x4732b9bd, 0xef86ade7, - 0x893b46e6, 0x3ed8df7e, 0x366667ec, 0xc01f6fcc, 0xe115fc1e, 0xb6b07b03, - 0x6ff4f508, 0x3d4469ff, 0xd7f2976a, 0x38a22434, 0x48ae3f80, 0xf7a7e0bd, - 0x410bd271, 0x73d60ef4, 0xebf6f4c1, 0x039ead05, 0xf4e05d7c, 0x9f226770, - 0x522f35c5, 0xead07eb9, 0xd1e8ceb5, 0x3a083f41, 0x7e708a5c, 0x0c5cf881, - 0x7ae38832, 0x583eb346, 0x0e1d99de, 0x76a4898b, 0x1c3b45ff, 0xd1df1316, - 0xadcceb0e, 0x47c01507, 0x576a8379, 0x8fd50a61, 0xff489cd9, 0x8714eb17, - 0x41a4e509, 0x71787e25, 0x4bd93865, 0xbb67ef09, 0xdbb107a3, 0xcff21520, - 0x8ec9dddc, 0xf188c656, 0xf18790ed, 0xd679592f, 0xc5277568, 0x1793e804, - 0x4308be1b, 0x644ff73c, 0x62c64e03, 0x0ed6a70b, 0xf0290883, 0x537f09bd, - 0x6b83af10, 0x69ac1454, 0x95269dee, 0xfb1dd6e8, 0xfe5ace1b, 0xbd700d9c, - 0xceb46dbc, 0xf537c81d, 0x05ec6757, 0xb8232bf8, 0xf7b4be5d, 0x33e42f5a, - 0x92f77f59, 0x3f7bd262, 0x13192b07, 0xeedf1fa0, 0x61eb8273, 0xd53d6856, - 0x2a76871f, 0x850023d7, 0x7a3ee651, 0x70d427f4, 0x27f5aa87, 0x7baa3988, - 0x7f107e02, 0xbf84e18d, 0x77209eea, 0x48e70419, 0xc5bf7fec, 0xfca092c8, - 0xb623c80a, 0x037f7093, 0xe2074778, 0xaa6f0fd1, 0xe08454f5, 0x5f0fd50b, - 0x0e905d3b, 0xd16abfd0, 0xb12e3cd3, 0xb3d20770, 0x4864e8ce, 0xe151cf7f, - 0x55ba081f, 0xd4bb9e08, 0x1b88f430, 0x91e2f7e6, 0x7f7e0754, 0x984afea9, - 0x46fd122e, 0x979c14f7, 0x851ad69a, 0xc35f70f6, 0x032dbe95, 0xc54dbf48, - 0x4e872bf2, 0xbe03dcd8, 0x8466fcd1, 0x7e7687a6, 0x9ac8fa95, 0x6150ff40, - 0x7cc17e7c, 0xfe3434a4, 0xf244194b, 0x7a1f50c7, 0x1ab799d2, 0xa072bde6, - 0x997ba7e0, 0x983ee51d, 0xabab46de, 0x6e402622, 0xaaed15ff, 0x9c70b842, - 0xcf342194, 0x741f9885, 0x41a66678, 0xc31bf387, 0x7f4a6ed0, 0xb0effd0f, - 0x4eff7e21, 0xfe7dafce, 0x3a0daf3d, 0x3fbe68c4, 0xf80071c6, 0xaf803ae5, - 0xeac18c12, 0xfb79c08c, 0x62e51e88, 0x48e6e57e, 0x61f30a9f, 0x5a170cbb, - 0xd6e81ea4, 0x4fa07e11, 0x19e7c20d, 0x46e238ed, 0xd235fefa, 0xd1f88d51, - 0x5fd15b37, 0xc6acf985, 0x28a2367a, 0x2fdfe711, 0xf505b9d2, 0x18cb4bfc, - 0x57a5f3f1, 0x4c137798, 0x1d7efb76, 0xd646cbf1, 0x9fbef88f, 0x570cf2ee, - 0x3af3c924, 0xb9ab3b84, 0xb77a8756, 0x43aed7a7, 0xb9b7da7d, 0x3e23a74e, - 0x8622ff70, 0x5799e4fc, 0xff5f00f4, 0x37ea556d, 0x686f07e4, 0xaf40ef7e, - 0x92f481cd, 0x7c16cb78, 0x43788d90, 0xbfaad083, 0xe3f662d0, 0x52c3e80d, - 0x63fb1d6c, 0xf11d25ac, 0xe9faf8d4, 0x5fd02d5e, 0x67a71bc5, 0xfe2a5e20, - 0x18262260, 0xd1be87f3, 0xe59fefc8, 0x2e67f684, 0xe872ad2c, 0x257a9fc1, - 0x85d91ba6, 0x446cd632, 0x6ebca13f, 0xa01f4381, 0x76ffa5cf, 0x8f9cd0c8, - 0xaa1a1ffd, 0xe78065b2, 0x5de18e2b, 0xd13b0858, 0xbfa12fee, 0x472fb006, - 0xafcf11d8, 0xff734567, 0x20f646d1, 0xa5a1fdb8, 0x7a631c73, 0xa1dfde74, - 0xbdd361c1, 0x907e7df0, 0x8634741f, 0x18b6b5db, 0x2141876e, 0x8bce113b, - 0x3d78b7bf, 0xc8717450, 0xfd0c5147, 0x641f5dcc, 0x2e8f807a, 0xfe47e6b2, - 0x35767288, 0xf971d692, 0x5cca3f83, 0xe5cbf166, 0xdcf8231d, 0x70ed78ef, - 0xe7da1d94, 0xe717df6f, 0x1ddfc009, 0x9db57f4c, 0x5c7033af, 0x7d33e346, - 0x07a42f4b, 0x04d9e3fb, 0xaff9a43b, 0xf9c715bf, 0x74874120, 0xdbf4245e, - 0xc028b0ef, 0x525fcedf, 0xf3247c41, 0xe6666de5, 0xebc80d8d, 0x04b88d9b, - 0x648b6f2e, 0x37b7685e, 0x7a4712c6, 0xa3259926, 0x5f14e99e, 0xe0cf8937, - 0x43cf8972, 0xa3a6cf83, 0x2759f15f, 0x1b6f70fe, 0xf7ced76f, 0xd74fc14b, - 0x7ceff3fb, 0x0aec3ea5, 0x8d845df1, 0x638ae9d3, 0xf7f41764, 0x1ebe8df2, - 0xe4ed10d6, 0x4f1832fa, 0x8d2b5f6f, 0xdf7f7ec0, 0x050bca66, 0xfba6de97, - 0x21ca7e76, 0x1fc02a80, 0x53baa6dc, 0x9c1fc26d, 0xbe8af90c, 0xbad1c657, - 0xd08bf25a, 0x4f30777b, 0x306fca23, 0xf77a487f, 0xfadd01b0, 0x296672a3, - 0x318bb748, 0x4237ce76, 0x047ca41e, 0x9d3831e3, 0x50ee6460, 0x62af80eb, - 0x98c35e24, 0x23e1f407, 0xdf640d1b, 0xf8fb5f0f, 0xf7e04cde, 0xd60c1bd3, - 0x9ce430e5, 0x3ea5f617, 0x0673f503, 0xe40aac9b, 0x3d7ddb4f, 0x5f4bee50, - 0x0fc85d50, 0x923c37a7, 0xf3d21330, 0x0065bf20, 0x0346e947, 0xf8d9cf95, - 0x159f9528, 0x42fa5d72, 0x97d47f7c, 0x4eaff787, 0xf9ce3a40, 0x486989ea, - 0x6b46ed97, 0x9690c1ff, 0x631c536d, 0x6f3df002, 0xbf269873, 0xe0e6c75d, - 0x995d243c, 0x47af6ee2, 0xa6d53f13, 0x1f7176fb, 0x04dfd69f, 0xa0aa72ff, - 0x3029c4e3, 0x57a18aef, 0x77dfafc8, 0xc9ec9c20, 0xf92a919b, 0xffc1be8f, - 0x20db9def, 0xde95fb9f, 0xa09dbe41, 0x674158f3, 0xb7a45cb0, 0x9f3ccc4b, - 0xfc9ebafb, 0x4a8b5ccf, 0x91f686f8, 0x7bfea163, 0xf40fbda2, 0x5321ca2c, - 0x848dd7b3, 0x0da36376, 0xf7d0ed0c, 0x19f2f37c, 0xdb3bc9d8, 0x025bc7f4, - 0xd59a33e6, 0x387f41f6, 0xca821987, 0xcf2c7a9d, 0xc7cb6b35, 0x2cfbb8f6, - 0xad630ffa, 0x77c972da, 0xfab4d88f, 0x7381df62, 0xf3009b3f, 0x92a4392b, - 0x7d237cff, 0xafc22efc, 0x5dbf3a47, 0x3bbe0db8, 0xf872b02c, 0x4915e9da, - 0x142357c8, 0xd3acf186, 0xe3cb42d7, 0x665ea41f, 0x7e3edf40, 0xe63816fa, - 0xdc51e7b6, 0xa0b119ef, 0xdff08f3d, 0x7afb1ebc, 0x8d9b753d, 0xed8233c7, - 0xfcdcb046, 0xfe46ecb7, 0x3dd2b7e0, 0x837f4a16, 0x5ced85e9, 0x89eb06ef, - 0xe1213b60, 0xbcb7860a, 0x0fb1a74d, 0x191ea15f, 0x8c27681a, 0xc3be2764, - 0x6d8370f5, 0x30f5c768, 0x2f8431f8, 0xad3d30cf, 0x6adfc1c3, 0x220376c4, - 0x0039b1ed, 0xb76b0ad2, 0x167fb208, 0x405b7ef7, 0xb6ffaa1c, 0x8dea1d5a, - 0x418cf8f6, 0xeb91a71b, 0x9d8477d5, 0x1cfa13a8, 0xceb4abd6, 0x4eee18df, - 0xc9b8e3d4, 0x8c96c746, 0x48f9f88e, 0xcfccefb4, 0xbeac7e95, 0x8fb1fb86, - 0x389a5d58, 0xa893eb19, 0x5fa2fb89, 0xd9edf28e, 0xfcf34e1b, 0x420d7154, - 0xe733d439, 0xf4016ddf, 0xf87036a9, 0x8f89e183, 0x319276e5, 0xb207f917, - 0xd0e8f67c, 0xd5895c7a, 0x679cfb53, 0xff474fef, 0x07c6d3ed, 0x7ebf51d2, - 0xede7141a, 0x169e1e4c, 0xb0a4faf2, 0x2e223123, 0x11ca14f0, 0x9dda41e4, - 0x55fbe1db, 0x57245d4b, 0x9d3a5d3f, 0x2e9667d2, 0xb613faa1, 0x9adf1a0c, - 0x775767f3, 0x35c9d3c0, 0xd989d92a, 0x18af5746, 0x59a4eef8, 0x1385f147, - 0xbb799155, 0xd19cb122, 0xb3f6727a, 0x0278b613, 0x6c277ee2, 0x6743a27a, - 0xfd8f8cf3, 0x9cbdfa66, 0xbda144b5, 0x23d7e76a, 0x2db5ec1d, 0xac7fe316, - 0x55db0125, 0xb6bdcd2a, 0xb7c71d29, 0x2c7c6732, 0xf59197f2, 0x0ba9b947, - 0xb828f6e7, 0xe72c4a5d, 0x1fa1bfc3, 0x8a7efd0b, 0x9e842b76, 0x2f3a0bb1, - 0xb1ed38b4, 0xc922efa4, 0x81b8275f, 0x728cbe5f, 0x60b84776, 0xd313d65d, - 0x7c785d61, 0x2ac5b16e, 0xf0a9c3f8, 0x5fab8e75, 0x5bf8886c, 0x609ef167, - 0x7811de38, 0xc9038e0d, 0x8681c654, 0xbcf9f2c6, 0xe26ab36d, 0x0eff1842, - 0x79f9ff15, 0x1ba3d72c, 0x2a3c5bc3, 0x7c03c3ca, 0xdb25de3d, 0x2b7c60a3, - 0x0736bf25, 0xc5775fe3, 0x2da5b8f2, 0xeb889dcf, 0xa344e4f6, 0x3736e303, - 0xea038f2b, 0xc05f7c9c, 0xd63823ad, 0x7ac27b37, 0xcd095c01, 0xa4231cee, - 0x0d317153, 0xaac2edf8, 0xa0dd2196, 0x6b23211d, 0x9157b87f, 0x92686c8b, - 0x4028f429, 0x6772861a, 0x454f728c, 0x559b0cba, 0xfa718d55, 0xffbe3294, - 0x77715670, 0x9c9f01b5, 0xa43c2b7d, 0xe8225c3f, 0xc9d194cf, 0x36b3fa68, - 0xacae081b, 0x819f3fcd, 0xf9b59f7c, 0xa012bd2e, 0x1ac79687, 0xdf67fe68, - 0xe295d79a, 0x58989f16, 0xea7a10cf, 0x1e5f8287, 0x69d87410, 0x8b7fcd0c, - 0xac6fbb45, 0x55405bcf, 0xe2f9f569, 0x5b3880d8, 0xd265f945, 0xed6393e7, - 0xfaf3ce34, 0x80c903ba, 0x3167e7cf, 0xe68a0787, 0xf148dd6d, 0xbac69dd7, - 0xe4efb8f1, 0xa431d0a9, 0x7f03fefb, 0x7e8c9038, 0x60fb2ce4, 0xbfda23f4, - 0x4ad2f43f, 0x0e7e7f2c, 0x4ff88c1b, 0x60ad3ef2, 0x619fe63c, 0x7faf84b5, - 0x65b1316e, 0xbf7db718, 0x210ffc6e, 0xc74cbebf, 0xcf04bf50, 0xe832461b, - 0x19f53112, 0xfd382374, 0xba4a0f51, 0x91190303, 0x886e921e, 0xee90edbf, - 0xc11af2df, 0x2a9ae12f, 0xb6f3dee2, 0x7c8f1f6e, 0x53665c92, 0xe1204e30, - 0x793d91ba, 0xd9dbf631, 0x0ed0ef93, 0x221b12bf, 0x0ec21d2e, 0x610d88ef, - 0x2fed8387, 0x637738b3, 0xe1d91bbb, 0x36ff82e1, 0x7fed06c6, 0x08597ee0, - 0xed8d0dba, 0x1fdf0f10, 0xe3ff621b, 0xdef0f146, 0x43ff72b1, 0xc97f0f1b, - 0xad6ff5c8, 0x293c3d8d, 0x1374bc84, 0xb5d6ebe3, 0xc67ed11a, 0xf5212835, - 0x518b62d9, 0x1c7e1fee, 0x125fb01b, 0xe0438fac, 0xefb628f7, 0x17b7cdbb, - 0xe9890d5b, 0x5bee8111, 0xdeb0ebbf, 0x29ce310d, 0x22fb3f81, 0xf6a6fb46, - 0x0afa462a, 0x141e5ef2, 0x371429f4, 0x934f38b0, 0xbec1badd, 0x1cd69dd5, - 0x3ee483f2, 0xd6ab54d5, 0x938b8c4f, 0x239f9ced, 0xd89d699c, 0x3c097f89, - 0x70dbfcc1, 0x4c45b8dc, 0xf7231fb3, 0x3caae261, 0xcd0b318a, 0x6af8a311, - 0x32f758d7, 0x1d6bb403, 0x209b1cc9, 0xcd685d1f, 0x9b6a7d41, 0xfdc468e3, - 0x7917959a, 0x02e57e3c, 0xfd4e5de6, 0x7732f9f0, 0x17ca2f37, 0x2e302dd2, - 0xe1c71110, 0x72e38888, 0x1cd27606, 0x8f0ae1c7, 0x9293b00b, 0x3e75ba1e, - 0x1adae895, 0xd0054eda, 0x77df46d5, 0x50efd742, 0x3771ed2e, 0x8cf71fe7, - 0x19be05bb, 0x7c737718, 0x4b4c14f3, 0x8f04dfec, 0x0ff38997, 0x2cf80f1e, - 0xf826ee2b, 0xee2deaec, 0x50881e8f, 0xa5dc5dbe, 0xc4275e23, 0x6b77d085, - 0x487d75f2, 0x4770b35f, 0x233abb28, 0x7dbff22e, 0xa086645e, 0x179d2df7, - 0x2d27f179, 0xdcb3a446, 0x06f090f7, 0xe591139f, 0x264a0d15, 0xf6733fae, - 0xc075a35d, 0xd37fc6a5, 0x79e3a03a, 0x42ee3e0f, 0x678003e4, 0xcea03aac, - 0x7977f207, 0xea56919b, 0x22ffb32a, 0x4df6e31b, 0x53b5e606, 0xefb6337b, - 0x7efb78c7, 0x633656db, 0xd31faadc, 0x547ac47b, 0xa8fdceb9, 0x7ee39468, - 0x8d5b2a4d, 0xbebcadf9, 0x6197998a, 0x847a3a5c, 0xf003d98e, 0x670ce319, - 0xc67c00f6, 0x7934d9e6, 0x2f9e4eb9, 0x25778dc6, 0x32efbe6b, 0x7da69bbd, - 0xa69fbb92, 0x10ce653e, 0x6aad3e4d, 0x577da694, 0xf981cfb0, 0x9addcf0c, - 0x266bddf6, 0x6b3df26b, 0x3fb4d01f, 0xcd9eaacd, 0x9c7a79c6, 0xce003dcd, - 0xdece0259, 0xdf358beb, 0x0dd5d7f5, 0xf920a1f3, 0xffee1f14, 0x326c16cd, - 0xfa73c44b, 0xfa69e77a, 0x5e6aff3d, 0x9df80293, 0x19386b5d, 0x7c219f18, - 0xea4b7e00, 0x8c1cf615, 0x5b5eba5b, 0xe9e1a73f, 0xce902995, 0xe7cb6af5, - 0x829cbee1, 0xdf2dadfc, 0x823d73ad, 0x71ed9deb, 0xe228ce22, 0x7f03ac3d, - 0x97b8d244, 0x9778f037, 0xc41de9ea, 0xb13a5a1f, 0x762fc96f, 0x44a62fc1, - 0xd984bf2d, 0x7a52fcb5, 0x1f30e770, 0x88ff88eb, 0xe47c413e, 0x78017f81, - 0xf895f897, 0x7cb438b7, 0x9de15df5, 0xdb91af31, 0x3ff96d0d, 0xb5f1b4e2, - 0xe3ee917e, 0xd4aeb7a8, 0xbf71522f, 0x7df1e58d, 0x57f52bfb, 0x6bb21d07, - 0xdb3ad7f6, 0x17173a4f, 0xfb175718, 0x3f709749, 0x137636f1, 0xfefb89fb, - 0xd900f885, 0x1f801b77, 0xb98708d8, 0xcc30ff7d, 0xac147fbf, 0x760a6537, - 0xb238cbe3, 0xd77dfe27, 0x587af86a, 0x085c5ff4, 0x9387dcaf, 0xf9e472e7, - 0xe7c91621, 0x3c01fb29, 0xf143f1a8, 0x022d9ffc, 0xf7dbadd7, 0x96f5a42f, - 0xc4c43f3c, 0x7e10bfb9, 0x3aefe93f, 0xfc8935fc, 0x6e78f081, 0x6d3123cf, - 0xf9c407f7, 0x3bcf692e, 0xb7ee47eb, 0x7b2a9675, 0x6c3fda55, 0x9b1dc255, - 0x5e93d842, 0xfd72dff1, 0x1c43a675, 0xe07c57ba, 0x2bd1ebfa, 0x00aed007, - 0xb962fbde, 0x5af602c5, 0x5febdbf1, 0xbf114444, 0xbd541eb6, 0xb2e0a1bd, - 0x036d1ed9, 0x6984363c, 0xab4c88ed, 0xf403c9cc, 0x3daf58b1, 0x11f727e7, - 0x6367db83, 0x27fd80fb, 0x8fe34ef8, 0xfdc21cac, 0x6e78ecb5, 0xe488bfdf, - 0x9114c1fe, 0x175a0caf, 0xbf70d655, 0xe9f8236c, 0x4cfd010d, 0xfb50b789, - 0x533911a5, 0xc08e29e2, 0x332bbbd7, 0x5627f214, 0x21f90a2a, 0x5347a267, - 0x9cb8b5fd, 0x623fc4c9, 0xbbe8299c, 0x6edaffc1, 0x38bb1e1c, 0x37fb238f, - 0xe6f6f3c7, 0x4e94d1f8, 0xb88ab789, 0xf21fb5b3, 0x93846547, 0xa1aa35fa, - 0xc7a6a5f7, 0xb5ad79f3, 0x6a27e930, 0x84e3fee2, 0xbf38c4de, 0xf9a3fb89, - 0x71fc1363, 0x7f66a67e, 0xf1138c68, 0x773e857d, 0x53ba9ea2, 0x78b3bdd0, - 0x758fb3bf, 0x75276e3f, 0x12fbf78c, 0x1dfbc643, 0x0fde28e3, 0x5e71ea5f, - 0xa47f71c1, 0x2fcd8443, 0xb7c48f3f, 0xd45483db, 0x7746f54f, 0x5abbae35, - 0x0eff8377, 0x2dbc7dc5, 0xf0301fb4, 0xae077750, 0xb06656af, 0xb7e416bd, - 0x7fa18c65, 0x5ba2df5f, 0x6bf5061e, 0xf58acc3c, 0x75f03723, 0xbb7ae95b, - 0x8069a703, 0x8865b075, 0x8bac1f5f, 0xd7bc218f, 0xc46e4cb7, 0xf73581fd, - 0xa19a1b32, 0x1b9b565a, 0x06d0fe85, 0xf8dd7216, 0x09b39094, 0xd4557b39, - 0xdfe8f117, 0x53d3a087, 0x0fa04e82, 0x879d22d6, 0xf0afbab7, 0x4fae38fd, - 0xfae22548, 0x1bcebf74, 0x373f3d6a, 0xf21d773a, 0xe86f40c1, 0x0b5ac3f5, - 0x1175b7e7, 0xdda8e7ae, 0xb5ee7e2e, 0x59dfea54, 0xba07a63a, 0x9d74114f, - 0xdf9f81b2, 0x5faed760, 0xc89fa557, 0x7a867fa8, 0x8b5ef4a5, 0xa543e317, - 0x821e190d, 0x7a38a5cb, 0x7868bea2, 0xd2f985df, 0xc62b2cac, 0x657f9c23, - 0xe43ea9ca, 0xbfae3262, 0xd494ecf4, 0xe3c76427, 0xb269df68, 0x16b5b7e0, - 0x0d473f3b, 0xfc008e28, 0xb6586e97, 0x7cefcf17, 0xfb466bf4, 0xd6d4474b, - 0x54d9d861, 0x2192ce40, 0x2159ea98, 0xfef82bc5, 0x1fa2bdd5, 0x5c61bfcf, - 0xa9dc7fb3, 0x3e69070d, 0x63cc0c47, 0xb4ba3e06, 0xfa3b3ee7, 0xcde32bdb, - 0xfb93c714, 0xf75547b2, 0xf48464e3, 0xda0815ad, 0x56110dfd, 0x43fc7f8c, - 0x82465df0, 0xc7d21f7b, 0x057c7cbd, 0x6596c1da, 0xa3c474a6, 0x1a92797b, - 0xd7ba7007, 0xd1ef342a, 0x788c93cb, 0x8ae6617e, 0x4f50e3c1, 0x95ce610d, - 0x2879df18, 0xd3948596, 0x9d7cf1f3, 0x60655c58, 0x849a68c6, 0x172fe311, - 0xbf8a146b, 0x015bfee0, 0x988e67d0, 0xf7aaf95f, 0xec3f88a3, 0x1e186ff0, - 0x733fe5cb, 0x1e494aaa, 0xe46bcec1, 0x19d58ca7, 0x799fa093, 0xdb39606b, - 0xf1fdec8d, 0xc043fe0e, 0x3af2ef79, 0x5b257d6d, 0x7f9d39f3, 0x5befe061, - 0xeb682ed0, 0xe8f2953f, 0xaba40e60, 0x8cc5b17b, 0x0b4684e7, 0x51ad14bc, - 0x665fa8ac, 0xbf8c68ae, 0x9b33f20f, 0xb4f20754, 0xe8eb0bc4, 0x8f39d3ef, - 0x693d4dcb, 0x6ed9703d, 0xdced82ef, 0x2bff5c51, 0x2c70f77a, 0x3dd6287f, - 0xadf1d71c, 0x9e18589f, 0x06d6399b, 0x1ec618fe, 0xc5106ccd, 0xd06cac1f, - 0x5a3b00a4, 0x6026b064, 0x16c3dfbc, 0xb7be3226, 0x779c0e65, 0xf90d79a5, - 0x07e89581, 0x1f91f9f2, 0x672c50f8, 0x15d7d6d5, 0xeac39f3a, 0x9a07e40d, - 0xd6781f85, 0xae009b5e, 0x6e3d7317, 0xde2d3920, 0x687e4316, 0x235c8af1, - 0xaef16ff2, 0xe043d218, 0x63d87e07, 0xc78e9f98, 0x481e6456, 0xeb8b7e84, - 0x96aa1c32, 0xb8ff5a7e, 0x5ba498e6, 0x4b4fbf47, 0xe8a193b7, 0x94d2f406, - 0xff0824a7, 0x3d8bd04e, 0x477e4b16, 0x7ab782e1, 0xcb9e019a, 0xee746155, - 0x83ff33a8, 0xbed1c6a5, 0xe6175c9e, 0xdfafb725, 0xcafcdf68, 0xb744a19a, - 0xfde57a60, 0xb470e667, 0x16afec27, 0xa1ec7a86, 0xc9e1ecee, 0xc2b0fe50, - 0xeaa1ebe5, 0xa72879f1, 0x6f5c0959, 0x6614b7be, 0xfdec6468, 0xece666a5, - 0x4b07d8c5, 0x68ff94ad, 0x3fe52269, 0xf4a76a5e, 0x287da593, 0x68e2293d, - 0x0180ce52, 0x25475f88, 0x951af970, 0x6cdee220, 0x8caa2251, 0x307cffbc, - 0xa1c56754, 0x4d8c27d2, 0x271eec63, 0xdfc02320, 0x046f7e99, 0xdf3db912, - 0x4b8eb062, 0x9571ff44, 0xd8befa42, 0x3da6bb75, 0x3c4625f8, 0x64facdff, - 0x9ce9cbfa, 0x1938dd98, 0xfcfef0f8, 0x69fb4d58, 0xfc9a2935, 0xcd3b04e4, - 0x775e527b, 0x8503f94d, 0xa2f935fd, 0x9e024036, 0xf8db302f, 0xb7d8aafe, - 0xd7c6cc67, 0xf6de56eb, 0x2ef0d56a, 0xaf7807df, 0x7d50321e, 0x5d243d30, - 0x31d7ad67, 0x73368037, 0xfa0dcc3d, 0x933b593d, 0x11fceae4, 0x95fdd90b, - 0x1ddf32db, 0xdb63f901, 0x7ebfb40c, 0x5aec456c, 0xb63e3fdc, 0x418a3e2d, - 0x32a95eea, 0x7ac1fa1f, 0xe80591ab, 0xcb15dcb7, 0x9156fce8, 0xf940e4d7, - 0xf9efda2f, 0xd1dbcc95, 0x5120441f, 0xbd543e3e, 0xe7e8853e, 0x14befc24, - 0xf902dde6, 0xf1afa033, 0x16ccf8c8, 0x8519d70e, 0xd9fcc0ad, 0xfaf5bfb0, - 0xb171c03e, 0x8744b6a0, 0x50f501eb, 0x1dcbe93c, 0x2dbe432a, 0xfda0605c, - 0xa91fb9bb, 0x94cf311b, 0xde9c2921, 0x64479d2a, 0x7fa8992f, 0x021c0ad6, - 0xd6fd16ed, 0x77d689b4, 0x0f77e44c, 0xfc16aef4, 0x26747c89, 0x08633986, - 0x3de08558, 0x46fc7ef7, 0xd3e3f7ac, 0xfde7083b, 0x32b5dea5, 0x5cebf801, - 0xe9107789, 0x49e2c7b5, 0x7ef182ae, 0x96f5c8d2, 0xf140e507, 0x9cbf4beb, - 0x9d3e272d, 0x38247069, 0x25655f48, 0xb93abea1, 0x98e740c6, 0x3519de99, - 0x3b3fd689, 0x38e58f88, 0x71f6f527, 0x9ac9df08, 0x96fb860c, 0xf2546bc5, - 0x78ff9007, 0xffe72f7b, 0x1b3755a7, 0x28d6fd0e, 0x23a5d66e, 0x60b23cdf, - 0x9a639d38, 0xc141d621, 0x9033e07a, 0x7f2f7755, 0x7e1ede7e, 0xb56586ce, - 0x181defe8, 0x7c158f38, 0xbfde44bc, 0xd650073c, 0xd1474fed, 0xd4dcbee5, - 0xf0ed1a3d, 0xe2550fd9, 0x6addb3b3, 0x3d022587, 0x0ef6e82f, 0xcfe43efb, - 0xe94e7817, 0xb854ff21, 0xae02677b, 0xd26b7457, 0x3e786e95, 0xdbdac4f6, - 0xaf73bbe1, 0xe6241c18, 0x7f49e24b, 0x6e697bcc, 0x8ef3c0d7, 0x2f97f51d, - 0x38bfef99, 0xe7c01493, 0x38dd7b7c, 0x775c00eb, 0xe21d84bb, 0xe6e3b1f8, - 0xbac5e02a, 0xc343c14e, 0xcb50c4ec, 0x3d773c6a, 0x3024c413, 0xec42784e, - 0x7a101f8f, 0x1109fa45, 0xa67e785d, 0x7b37f38e, 0x0dbf2155, 0xbffa347e, - 0x944f9c52, 0xebea5f7a, 0xfb4b5632, 0xf81247c1, 0x8ab9c639, 0xe055da97, - 0xa8a82ece, 0x420f2b12, 0x79356d97, 0x97d419bd, 0x480fd035, 0xfbe762ee, - 0x9e57c643, 0x652db645, 0x417e7ccd, 0xbc19ceed, 0x1d19cd25, 0x75894ded, - 0xf51b0ae3, 0xfc60706f, 0x69c854a4, 0xf5e2ad79, 0xdd9079f1, 0xd98af194, - 0xdb066ec2, 0x28f60ea7, 0x0ecd0ec8, 0x56acb3b2, 0xde01576b, 0xc2471c48, - 0x2ba70c1b, 0x987842c2, 0xbda17007, 0x0f7b712d, 0x15b8244c, 0x03b25007, - 0x35cca53c, 0x01e70626, 0x477b3ef5, 0xd5e782f8, 0xcf315e01, 0x1c4bb860, - 0xff70fb9f, 0x5187cf18, 0x1e6829bc, 0xfec11e92, 0x894ba49a, 0xa4b7e387, - 0x7e7a2141, 0x3207eeda, 0x7e491b8a, 0x9d500581, 0x44d77bf6, 0xeba567d4, - 0xf866ff40, 0xd3f247f9, 0x8517563c, 0x7cc152fc, 0xbe50932b, 0x46d3757c, - 0xe1bedfa2, 0x49ca237d, 0x53d7cda1, 0x5c288317, 0xb4bcd3fb, 0x1044f580, - 0xd7446f9e, 0x9c378a6f, 0xbdc65e95, 0x37b34f00, 0x41b0ceab, 0x1ce2769a, - 0x60e48791, 0xc463c78e, 0xb11cc6f8, 0x9c11bfee, 0x6e7e7a95, 0x76f086fc, - 0x5b7d27e2, 0x68baf3b8, 0x9fbf62fd, 0x943a33d5, 0xaff76a9e, 0xdffaec82, - 0x217e3c0c, 0xbd55f1f5, 0x5025e293, 0x2aaefc2e, 0x079b8f2b, 0x2cb4f1e9, - 0xc225e3d2, 0x4e71cbae, 0xf149dfad, 0xf768d9b7, 0x5d3fca03, 0xfee293b7, - 0x476657c6, 0x6a7dffa1, 0x78b5ccfd, 0xb6d4ebbe, 0x4be76499, 0xde76939f, - 0x1ff40c6d, 0xbd17d772, 0xdfe463f8, 0x9f1461ad, 0x16efd92f, 0xabd01eeb, - 0x9ebeced0, 0x8eb651eb, 0xb452d5eb, 0x1ec80387, 0x8b76c6f6, 0x51bddc4b, - 0xc9ca020e, 0xe99e2e4e, 0xe81eddfe, 0x11cbf177, 0xc2a10f0e, 0xdf91d3ea, - 0x3da1f56e, 0xf1f85f2c, 0x0ee73c51, 0x1fa3fff6, 0xd90ffb48, 0x92f77a8d, - 0xc26f282e, 0x1bab97ee, 0x27e8add3, 0x5ff13b08, 0x3439bfc0, 0xfe1087fe, - 0x01ff118b, 0x6bc720fb, 0x06679e38, 0x1ac4ffe1, 0xdb95974e, 0xfae147ba, - 0x774d78f1, 0x6f8eb3f2, 0x9ff849eb, 0xcff01ab5, 0x3f5a5fe3, 0x8ff006ab, - 0x3fc408eb, 0xdfbc5bc0, 0xe0eff02e, 0x78e1aff8, 0x3a786b67, 0x3d9e03ab, - 0xf1618e74, 0xf40e4daf, 0xf984ce1b, 0xb33a9fc8, 0x01d5655d, 0x83f4987e, - 0xbfb560be, 0xe24d7f42, 0xe6af6e7f, 0x0a7fa841, 0x1453fe9f, 0x76ee61d2, - 0x80efa41e, 0x82ece67f, 0xfc7fb8fe, 0x95e9bf76, 0x7e01f12e, 0xa9d24dd3, - 0xd918b982, 0x1d3f86c5, 0xe28375c1, 0x786d4f84, 0xd7dc468f, 0xd7ded7a8, - 0x851933c0, 0x382f8c36, 0x278466cc, 0x8a1ef835, 0xf91c619b, 0x9f3f3d9f, - 0xbce490b1, 0x6dbe7355, 0xba19f322, 0xa758ffa0, 0xf2c6fdd0, 0x39513945, - 0x55d4e30c, 0x2ee9c704, 0x78fce68a, 0xff23aab9, 0xfdc8ccb1, 0xf93fb948, - 0xde0ff0ae, 0x25d7c2ed, 0xd2b175ef, 0x18c29777, 0x164b81d9, 0x23ef17a3, - 0x112a7ac0, 0x31ecf7c7, 0x228edd11, 0xd57f804c, 0x6036e228, 0x1f4f9102, - 0x1f4f9c64, 0x38a26c8c, 0x5e54ac39, 0xd0f8bb40, 0xfc839312, 0x8a68b8da, - 0xf4203ed7, 0x2b9183dd, 0x1e1f685d, 0x313a348a, 0x783d7e85, 0x1a30ce88, - 0x0df18786, 0xafba46c9, 0x796e6853, 0x0fbe9705, 0xd4789e27, 0x06dea00c, - 0x55c637ee, 0xd75dd7e0, 0xc5d23b63, 0x9c6d1f4f, 0x743c32a7, 0xe055a3dc, - 0x293a714b, 0xbe82639e, 0x2b8e01c3, 0xdcb12f68, 0x9df1e56e, 0x8b27400d, - 0xe5c1be9f, 0x03f7c3cc, 0xe35cf0ca, 0x6419c628, 0x935fe104, 0xfaf2332f, - 0x26afc4f0, 0xec66cbac, 0x103ecccf, 0x3a8656e9, 0x45f7d704, 0x978c5ed1, - 0x25f183df, 0xe27aa61b, 0xe67ac997, 0x26b4f1d1, 0x89cccf12, 0x8144d378, - 0x9823a9cf, 0xeef01a2f, 0x778da83b, 0xf9d3e7dd, 0xef7e037a, 0x911afbd1, - 0xbb66753f, 0xb8e30ac1, 0xb82194f2, 0x7e5b292e, 0x25a6f073, 0xa5d7f39a, - 0xcfc75e42, 0x80feb585, 0x041e21c7, 0xcdbc4561, 0xeafdb3d0, 0x8807ce10, - 0xdd9b4a97, 0x2816ed43, 0x71950f14, 0xc1ff4936, 0x1d207dd0, 0x41f0141f, - 0xf851353f, 0xbd3431bd, 0xf5ca26fa, 0xabad1d73, 0x9bb90be7, 0x9b6de52f, - 0x27c6de56, 0x82bda9da, 0xede0307e, 0x26769141, 0xff44e317, 0x5cb912e3, - 0x78e2dd64, 0x9d35b22c, 0x7908b7ce, 0xfef13729, 0x88f7f8e5, 0x8da24c74, - 0x00f095fa, 0x7ec71ebf, 0x9001a074, 0x56d64f5f, 0x87347f93, 0x33b5c405, - 0x5f24edfc, 0xebb7cc77, 0x4c75dd11, 0x10b3ad8d, 0xc2f7caf5, 0x1f47a81c, - 0xacf5d634, 0x4ed8ec8a, 0xb214dbee, 0x3d230366, 0xc261e229, 0x23558cfe, - 0xa1407ce9, 0x5e0fefc2, 0x7478b1ca, 0x31a718d1, 0x630b6910, 0xf13f3a14, - 0xf27fb137, 0x89e2f450, 0x5185d728, 0x33a63d46, 0xfbf52b58, 0xe8b76b77, - 0x33de18fb, 0x0e763156, 0x77c88f03, 0xa8d5b8c2, 0x8d7e7877, 0x4aa29b33, - 0x21c77f22, 0xdee1e027, 0xca7f406b, 0x09df2f7f, 0x4b7a5ffd, 0xe93bb3d4, - 0x0b8f4bfb, 0xf2e4f63e, 0x7d65cffc, 0x92afcf1e, 0xff3cf9f5, 0xe45feca4, - 0x5faa0e9f, 0x4bff5416, 0x3ebc5f9e, 0x7e83df3f, 0xd2ce68eb, 0xd214a385, - 0xbe847b53, 0x23ee5c28, 0xf6ea16fc, 0xf33474f2, 0xdc6eb2e9, 0x6ba2536e, - 0xd51fda0f, 0xf682d272, 0x2764d5f7, 0x704f9fe5, 0x75c44b2f, 0x63c524d4, - 0xa1fb7d44, 0xc4c1ec97, 0xed1fce4e, 0xf8e3c2e9, 0xbfa0929b, 0x05fb7ea1, - 0x8c4eacfd, 0x1c7ef5bf, 0x80ae1c49, 0x26f99e7e, 0x23a7fcf0, 0x49be1b3c, - 0xb592b33f, 0x487f48fd, 0x86be7549, 0xe32763f3, 0xe645e734, 0x8d11c4ff, - 0xe78627f1, 0xf3f50045, 0x67a5d797, 0x5ff3ff42, 0x04bd3d7d, 0xe76125fd, - 0xcc74da2b, 0xdb34f789, 0x1be7a518, 0x7de2313f, 0x8d5d8ab3, 0xaed071c6, - 0x00dcd212, 0x9c04cab8, 0x93f4e760, 0x8373ec03, 0x3d8c1bd0, 0x5f37f7cd, - 0x7a47ab3d, 0x9dd5d7ce, 0xf6ed0e7a, 0x3ee42528, 0xddf166cd, 0x17ce4ed1, - 0xe87a15ef, 0x11b39a6a, 0x8c6bf9e7, 0xb73e4021, 0x60fb93ba, 0x855f1c49, - 0x1ccdeec2, 0x01db3166, 0xe43f43cf, 0x1b2554fb, 0x3c608632, 0xd184cdf8, - 0x6d7e24ef, 0xc795b53c, 0x3c781b53, 0xbcd6d0b5, 0x33379408, 0x31ad9526, - 0x84d8c1df, 0x0339485f, 0xf36f8591, 0x9d5f324c, 0xc79b263f, 0x767f30bb, - 0x506b63fd, 0xb9c29a6e, 0xf0d0fb1f, 0x17a8e181, 0x7422325a, 0x37e79056, - 0x498c8be3, 0x8efcb143, 0x639e5871, 0x222af4b2, 0x8be232fc, 0xc75de337, - 0x3db05f90, 0x46dc41c6, 0x307dfc5f, 0x2adbf70f, 0x0f75a79d, 0xda87708a, - 0xc087fa77, 0x4ac931ab, 0x19901369, 0x870917fd, 0xf9fc1f1c, 0xdfd0cd45, - 0x8349e5c9, 0x9f71db57, 0x3490c725, 0x467e3fd4, 0xe072fb82, 0xac7527f8, - 0x6e292e17, 0x024b8e16, 0x5dee030e, 0xd95dbe03, 0xac06732a, 0x898f26f3, - 0xcdefe4d0, 0xc0ce658f, 0x29bded38, 0xc2f4fc9a, 0x0ff69aee, 0xa9afeacc, - 0x6735302f, 0xb1f80555, 0x1e49fb9d, 0x62d2a782, 0xee7f4709, 0xfc5f0def, - 0xfff441e5, 0xf40eab36, 0xd9eee755, 0xa1db97f2, 0x4e3c65d5, 0x3b47f145, - 0xc9cecbc5, 0xa77a28f3, 0xe85f703e, 0xf3a66b22, 0x03ed9d3e, 0x7cee75c9, - 0x773a7eeb, 0x03ef5df6, 0xeb124af5, 0x086c21dd, 0x55cbc3da, 0xaebc511f, - 0xefcf9222, 0x8cc7ebe2, 0xfb8a0fb8, 0xdf81d78a, 0xd10fc2ef, 0x50f36c3f, - 0xfeb73b3c, 0x1d9bed18, 0xba7ae448, 0x1e817522, 0x42551def, 0x1c68768a, - 0xe068abe8, 0x3646e697, 0xbbee1770, 0x1fb85866, 0xb19936de, 0x1e2be458, - 0x884a69df, 0xf3d77ba1, 0xbca8f26b, 0xfa9c2da2, 0x1e6d4f7f, 0x5f09e747, - 0xa1ff6853, 0xe5a1e520, 0x29b87e78, 0x11e033dc, 0x77e0b718, 0xde21e577, - 0xf3f1762a, 0x9fea05b5, 0x5a4016b3, 0xdf479b56, 0x49aca817, 0x42617f01, - 0x05bfb72e, 0xaf21f368, 0x46acb30e, 0x7d1aabbb, 0x3d479ebd, 0x9e90b463, - 0x807b6e89, 0x336cafc6, 0x24f7f7d3, 0xd0d77f71, 0xdb1ae1c2, 0xc972a2e6, - 0xba93530f, 0x860fd669, 0x7c7acdf8, 0xc2d0c397, 0x6dddfda8, 0xf39528fd, - 0xafcfbb7d, 0x21ae3ee9, 0x14b8eafe, 0x71dbf798, 0x90dc958a, 0xa57c3d20, - 0x0b34786a, 0xc7daa7a1, 0xf4e7e369, 0xdcfc6d4c, 0x738a615e, 0x31c0127e, - 0x3d16b1f1, 0x48b107ee, 0x35f115b3, 0x7b60c471, 0xa97c8049, 0x2237ef7b, - 0xdeeb0c7d, 0x369da237, 0x501b9a41, 0x33ce2e5f, 0x05e9eb04, 0x2f4f5249, - 0x1dda54a3, 0xf9067576, 0x82ac33a9, 0xccfc8501, 0x7e54fa10, 0x1a6b4cdf, - 0x1e6ee3a0, 0xc5347fc7, 0x45f502bd, 0xbe9b0e73, 0x7366f483, 0x7cc3ee3a, - 0x9d03f057, 0x89f90acd, 0x751e742d, 0x0ebb08e2, 0x04abffe3, 0x6f8e525c, - 0xa2c58f34, 0x5b2a7bfd, 0x77befd82, 0x4ecd9de7, 0x47f1afe8, 0x0f689999, - 0x25cfb8e4, 0xcc297bf1, 0xd70d7ada, 0x446f9583, 0x0bde51d8, 0xfb863170, - 0xb44c7b9d, 0xda72814e, 0xc37ca8cf, 0x89ef09b4, 0x7ac14654, 0x7dcfc615, - 0x7c87cc33, 0x9866f8dc, 0xef46ed1e, 0x4873f774, 0x7b37dccf, 0xa1f5c18f, - 0x67a4c1b3, 0x9f38f7e4, 0x09db3d27, 0x5bd237bc, 0xe5267cc1, 0xe5c35dd3, - 0x69f048a5, 0xb73f90b1, 0x552ba390, 0xaf0e485d, 0xe340063c, 0xca63e93e, - 0x27e85dc0, 0x7ef42dd8, 0x02cb9493, 0x79410f5c, 0x3a18ff41, 0x8dfd2bff, - 0x6b2c3960, 0xe5bf52b3, 0xef21766d, 0xb94bca36, 0x6372162b, 0x2cc67e12, - 0x53bbe7c1, 0x5e20efdc, 0xee41aa0a, 0x3f1f68a3, 0xcfc9e50b, 0xf22b4637, - 0x624df017, 0x54fc8049, 0xd0cfde37, 0xb9c5313f, 0x41666f88, 0xcc9fe81a, - 0xac4ff76e, 0xfe0012e3, 0x74322b89, 0x9da9df78, 0xe6f9db7f, 0x8f7ff8e6, - 0x48e29790, 0x67f44f5f, 0x0e61550d, 0x397e873c, 0x2cf7ef8e, 0xb8f1c55c, - 0x45cae0d0, 0x2fe162ff, 0xa1978a15, 0x697a81df, 0x632a91d8, 0xfee51c60, - 0x0ecc41b6, 0xd6d29878, 0x1337d283, 0x0f1147dc, 0x04d36d45, 0xa37d06be, - 0x4ea1c5fd, 0x7832471e, 0x198d8e4d, 0xab724718, 0x6933e748, 0xe04cfacc, - 0x1d7ade7e, 0xbee4c3c5, 0x992b8ca3, 0x807cbcf0, 0x5f42fd1d, 0x37ef4e9b, - 0x7299c704, 0xb0bfddb8, 0xbf7640d9, 0xc3cff1ac, 0x2e7f5074, 0xed05d9c3, - 0x777a97c9, 0xbcf5f21b, 0x0d57dec9, 0xe4ff9f90, 0x7691a8ce, 0xf4eb3e3f, - 0x47689ebe, 0x188f00eb, 0xa35baaef, 0xbfb979e6, 0xc9f7c113, 0x7e4b7f38, - 0x79f3e60e, 0x9f88dd6d, 0xc89954ae, 0xbe015d0e, 0x48760165, 0xe7a91dda, - 0x7c91fda5, 0xfae7ae5d, 0xda323cab, 0xb408c9eb, 0x395c933b, 0xf87d77c8, - 0xddbf1a79, 0x1476b4d9, 0x38a5c1ca, 0xed28b73a, 0xbc1cb046, 0xd31c14b6, - 0x8eed1d5e, 0xcf52ebd4, 0xfa35bb4b, 0xfe772fe5, 0x8a55cd15, 0xe032407b, - 0xb73d6eeb, 0x2deb775f, 0xe3633fc4, 0x6f91e926, 0x1e8f5e6e, 0x98f47a13, - 0x74568f46, 0x27060762, 0x741c9adf, 0x4cf3ed15, 0x3d447fdc, 0xa3dfd81f, - 0xe0c7a329, 0x7327c63c, 0xc15dfb3b, 0x1ffe99dd, 0xfa6b7c9f, 0x88b2587f, - 0xff40ddf7, 0xfd732617, 0x99efac1f, 0x73a7bf95, 0x2f5f4f69, 0x0ca383da, - 0xc1da03ec, 0x16fb0886, 0x5ec80f61, 0xbf7b4784, 0x4d5c1ece, 0x7888599b, - 0x1e0f610a, 0xf616fe4a, 0x94a1f240, 0x5227291b, 0x48e5822e, 0x9f84c5ca, - 0xe9113ac2, 0x57bf1ef4, 0x6cf7ae50, 0x7b46fda3, 0xcf9460c4, 0x976e3f76, - 0xc1d6f242, 0xf1f9084e, 0x6ed68bcb, 0xf290b948, 0x5ca7e522, 0x20ecc5c8, - 0xd6a7d8b9, 0xf70a333d, 0x6bdd92cb, 0x72fde393, 0xd823b652, 0x57ca743e, - 0xb3645918, 0xf218aae3, 0x81a43955, 0x44ea657c, 0xbe499e1e, 0xd968bf35, - 0x6fd3f24d, 0xf4fcfbfe, 0xe9f84e9b, 0x3f0dbe7f, 0x3f63f475, 0x3c03b2ce, - 0xdf40b257, 0x6df9f866, 0xfb8c3bc2, 0x7af9dd0f, 0x0497d600, 0x8d319377, - 0xae133ee2, 0x2f8a2ab3, 0x7494be0a, 0x6cc0fe96, 0x93387711, 0xe1077ae2, - 0x82c0f5c5, 0x447bd39b, 0xb35c5367, 0xb327d711, 0x03f40d21, 0x9b7ff33a, - 0xbdef516f, 0x3e749371, 0xfb9dfc96, 0x4392c78d, 0xb1c78dfb, 0xb5d29bfc, - 0xf8899720, 0x300b8fde, 0x29e138de, 0x0acb6791, 0x46d38f10, 0x3c9ffac8, - 0xfa81ece9, 0x38b8c981, 0x53de39c5, 0xf4b3de45, 0x3f6818f0, 0x8fe619e1, - 0xd8fd439b, 0xb8f6e8ec, 0xedfcc288, 0x3b1fe795, 0x51e886bc, 0xddcce5cb, - 0x3ffbe7a2, 0x79059f22, 0x447e404b, 0x6f037e50, 0x616fa51f, 0x9045e781, - 0x9c21949f, 0xff00aece, 0x7fdf8601, 0x5585ed05, 0xa8d71861, 0xd6f8db8c, - 0xf56bd415, 0xb545ed0a, 0x14d581e3, 0xfbc55338, 0x735f94b9, 0xc23e09d8, - 0xbe78bb03, 0x93ed4a4f, 0x37e8bd1e, 0xa1bddce0, 0xb9d2714e, 0xb78a1183, - 0x7c47465b, 0xdad149f7, 0x6bd1fc27, 0x1e7867bf, 0x6fbe56ef, 0x8dd6cfbf, - 0x6e99f7be, 0xb2fbfc61, 0xfe7f9f43, 0xefe70a5e, 0x21d15931, 0xa8a5c7eb, - 0x37111fbc, 0x68a1f1a0, 0x7be85d4a, 0xb8c513b0, 0x425fb8cd, 0x24f6dcf8, - 0x28d9b7e2, 0x93f2fdf1, 0x196377c8, 0x60cfc4d3, 0x9fdfca7c, 0x8d4172f2, - 0x19d74f9e, 0x9bafaf84, 0xa91480ef, 0xf2f8fdbf, 0xf4cbd104, 0x8476f835, - 0xfb5db7c0, 0xe8ebefbd, 0xf7c3ac35, 0x48e76f82, 0xf86a763e, 0x22ef5a3d, - 0x538e8cfe, 0x5747e8ac, 0xe0d6c2b8, 0x9f2fc17a, 0x6cbe27bf, 0x1d03fb96, - 0x02b5efe4, 0x890abf94, 0x4febcf47, 0x74bafca2, 0x3cb9eded, 0x7335f3b6, - 0x52bc01f6, 0x7fbe0fc8, 0x27faf9e4, 0x7c092e31, 0xd794f541, 0x2c1dc007, - 0xf941758f, 0x15f920ec, 0x03fa47f2, 0xa9e001ed, 0xb8b7ea27, 0x007b4663, - 0xd04cfc9f, 0x27b8a2e9, 0xfb9a3cda, 0x78ddcd93, 0xfb8523ba, 0x7c09cf8f, - 0x9bed126e, 0x90f003c3, 0x1f1fe1aa, 0xe6025bae, 0x3fba784d, 0x93fbce4e, - 0x63d07c82, 0xbf5e36cd, 0x27a3e52d, 0x7cfed93d, 0xa6af7f70, 0x7880527c, - 0xf1fff7f1, 0xee23f461, 0x91db7817, 0x27b0e472, 0xc139d052, 0xf0214eff, - 0x5163bd07, 0x74a1fc8e, 0x761f8fe4, 0xd04f4fe4, 0x774ef4f7, 0x3a7bdf67, - 0xfa0cef7e, 0xea3de19e, 0xd05eff9b, 0xae883f2d, 0x1d744179, 0x942f9413, - 0xff46af79, 0x5c5cbd4a, 0x09e3f4ff, 0x54df1871, 0x9fbf38e8, 0xbd934f9f, - 0xfc956f99, 0xf230e67b, 0xcf9f9fab, 0xd7279e12, 0xce79ba09, 0x787a893d, - 0x51e1ea12, 0xd414fcfe, 0x5f3f9443, 0x7e61fb80, 0xea81757b, 0xed91abef, - 0x7afd922f, 0xefec8560, 0x3a4bca33, 0xb225cf32, 0xbd0bf777, 0xa4ad3cc3, - 0xf035e7f7, 0xfe7d3fef, 0x2b5fc3f3, 0x7841b50f, 0xf79410d9, 0x775fb504, - 0x22b6fb03, 0x82c7fbe8, 0xe504d7ea, 0x6be507d7, 0xcd17dfb4, 0x8b0e4852, - 0xc9fdf046, 0xe60cb960, 0xda522f8f, 0xf6ed63e3, 0xff24895c, 0x1357234e, - 0xfafe79aa, 0xa829fff3, 0xa7c80c89, 0xb21e89b0, 0xc05a30ef, 0xb9d041fd, - 0xc1f8151e, 0xbcde89d0, 0xecde99d8, 0x79ef6c13, 0xd7f03ffd, 0xd22fda24, - 0x54fb25f8, 0x9551be6d, 0xbbbd4770, 0x5f603228, 0xe2265995, 0xfdf3baba, - 0x6389889b, 0x22fc0352, 0x6744f84f, 0xfb653cc0, 0x575d5f71, 0xd4f8bc71, - 0x719b89f0, 0xd8b4687f, 0x14f1b4d7, 0xf68aa5ec, 0x6fc452ba, 0x5d39e1c6, - 0xebee176c, 0x0fd030b9, 0x70bd7562, 0x523f8d9e, 0xd550bbf9, 0x53c01f40, - 0x79d3b311, 0xea7899d3, 0x47d43bbe, 0x0df92f47, 0x47efb77c, 0xd3b412ea, - 0xd2c49747, 0xa945a639, 0x17dcefdc, 0x366135dd, 0x1e231be4, 0xf8db7d26, - 0xf74a58c4, 0xad95ceaa, 0x353ae856, 0x5f646279, 0x3c268fac, 0x4fc43639, - 0x9dfc065c, 0x38276a99, 0x426b36dc, 0xabdbfa3d, 0x085fb40d, 0xfc457e2d, - 0x3069a4f3, 0x968bb7ae, 0xb0fda7f5, 0x1a4f9fe2, 0x8ab0f787, 0x3ed0371f, - 0x4ace8b49, 0xeaf72271, 0x6a2e74b1, 0x7a910ad6, 0xcdf4a2ee, 0x1abafcff, - 0xbeb569ef, 0x0efbd0a0, 0x7bad5c77, 0x9b9e1067, 0xf74ee9ac, 0x7580de2e, - 0x3efb9e00, 0x17b7bebe, 0x089f21cf, 0xa473a2ab, 0x8bee9ed0, 0xbfb35e95, - 0xdb0b313b, 0xd0e5d6ab, 0xa39414fe, 0x956a7cff, 0x41ef09ba, 0xc2594515, - 0xa9f6fcf1, 0x75c518af, 0xa26e3d4e, 0x478e2277, 0x8fac67ba, 0xe8b8fba3, - 0x8a53b3e9, 0x3c014a3d, 0x67d0da4c, 0x96126262, 0xfb7d049b, 0x1e011544, - 0xfced748a, 0x24a4f643, 0xa527e786, 0x05b899f6, 0x97ea71e6, 0xd87ce9bd, - 0xe4e754c1, 0x2fd7c054, 0x52539cd2, 0x6e5e11e3, 0x0ffcdeb7, 0xe3fc8fdf, - 0xe404e285, 0x395287af, 0x56d1bf5f, 0xbef8109c, 0x3d45c977, 0x469bc1f1, - 0x277a22fb, 0xc14d3c30, 0x41f03675, 0x67cdc62c, 0xf00b7589, 0x219d92f3, - 0xa9e1abfc, 0xf1abd12a, 0x48d9f1a7, 0x0f5f3f5f, 0x19f5177f, 0x5f2037ad, - 0x2d7321b1, 0xa693b9da, 0x0f44ec25, 0x91fe7ed6, 0x3c230bed, 0x7985b619, - 0x7e3032c3, 0xfc871cea, 0x7aeb12cd, 0xc804b64d, 0x77ff68a1, 0xfbe73f0f, - 0xeb8f6877, 0xfe7bbfbe, 0x9fb812d7, 0x4697db21, 0x5ce83c59, 0xf458b69c, - 0xfaa38f48, 0x3cf0a7a5, 0x060bc95a, 0x2f2503b2, 0x8ad63fc4, 0x06f807fa, - 0xf3c16be3, 0x81aa63fa, 0x933a31c7, 0xad18cf4b, 0x1331b25c, 0xc99dbe71, - 0xdc86cd65, 0x3b239b89, 0x2b52cb97, 0x5ee34fd7, 0x9651efe0, 0x71e8b50e, - 0x0bf4737f, 0x7ba16d6f, 0x86c20b74, 0xd289bde0, 0xaf444c17, 0x63c58b16, - 0x13ef0dbd, 0x9031f458, 0xedca9b3e, 0x9f90bd69, 0xcde9955c, 0x7ba52843, - 0xf0df7212, 0x9e6792ec, 0xe797e3c5, 0x70da7798, 0x2765dfc0, 0xbbcbd3e7, - 0x063f8a54, 0x1f9623ef, 0x61cc69dc, 0x788fb137, 0x32c3fd83, 0xdfde22d6, - 0xf07dfd0d, 0xa9abe1fe, 0x0687fbc1, 0x2a5e4fba, 0x37730ff6, 0xe9770428, - 0x3fcf7e12, 0x8dc79637, 0xfa052e4f, 0x1ede691b, 0x0f3c10eb, 0x294eedcd, - 0xf866bc53, 0x0b0daef5, 0x13d98e28, 0x6e7184f1, 0x89e26ef1, 0xae3a4730, - 0x085e4bf3, 0xfe96fc23, 0x7e5fee6a, 0xfaf78599, 0xd702e20a, 0x2f91fbd5, - 0xde197e38, 0x9cfd941f, 0x7a63f65e, 0x45f731a7, 0x7cc31f58, 0xabd8634a, - 0xbd2067f7, 0x9f71d292, 0x5d2bb653, 0xbc5ea3fe, 0x61afac1d, 0x4ab45d1d, - 0xecc7efe5, 0x041d9136, 0x01644f59, 0xad672cf7, 0x72346838, 0x8712c63b, - 0xeedaff09, 0x1c769fbf, 0x6eeaf1ea, 0x2687b8a5, 0x51ef27f1, 0xfbf8e915, - 0x853a8574, 0x268157ee, 0x97497ba3, 0x7b5fb953, 0x679f953a, 0xd0774a28, - 0xb5f29cfd, 0x0cf2c726, 0x7dfb4fde, 0x95df584f, 0x684b9aeb, 0x26f7f33f, - 0xae54ab8a, 0x45867308, 0x3b17f3f1, 0x6af9d006, 0x51f011bd, 0xe2fae766, - 0xa56f98b2, 0x745dd27d, 0x8ecf419f, 0xdcbea1e8, 0x7963f5c2, 0x923de00c, - 0x186e8a33, 0xe8c767be, 0x9bf624dc, 0x7c602834, 0x3f439445, 0xbf7f28f6, - 0x83563a4d, 0xdf6c1b71, 0x31e21077, 0x8474da76, 0xe49515ef, 0x76b49019, - 0xaf7dfa04, 0xdeb899a8, 0x6fb55a2e, 0xf9dfea1c, 0x8de307db, 0xeaf45609, - 0xe63f6407, 0x88b7fa0b, 0x90c56773, 0x22b677c7, 0xb93cb8d2, 0x8a2f1e55, - 0xef345348, 0xf2fac910, 0xbf1e0655, 0x8a8f3d07, 0xc7d97ca5, 0xa5b96fd4, - 0x6ff50139, 0x30c36ef9, 0x6951d3d4, 0x978b2e5c, 0x011f65a5, 0x44362abe, - 0x6583bbd3, 0xe623029e, 0xca156acb, 0x4f8bbffb, 0xbf3d3e47, 0xe428b5e2, - 0xbe61139f, 0x5a97689e, 0xe8398417, 0xc795a1de, 0xe8afceeb, 0x6695f749, - 0xf82d9b59, 0x45acc19e, 0xbfa86ddd, 0x467d5a8f, 0x975a3fac, 0xd3bcc3a1, - 0xbcc6cd6a, 0xe51b7f53, 0x2df38bcf, 0xa57c83f4, 0x6d973a70, 0xbfc467db, - 0xcc44324f, 0x1f2be2f7, 0x4ff8c2f4, 0x2f737a79, 0x07c02bb4, 0xcf1052bd, - 0x9764292f, 0xf3f1b62b, 0x2a0f92ee, 0xee400f90, 0xa83e09e6, 0xf7daf5d8, - 0x902a1e51, 0xf23a43fe, 0x7ef3f011, 0x71b1df2a, 0xefdfe31c, 0x76913e47, - 0x0c2bf20c, 0xf1df8c36, 0xa71a667c, 0xe18f943f, 0xfc019ee5, 0x39fb5d1c, - 0x741c8d04, 0x1a575f46, 0xcbc587b7, 0x5d6fa44c, 0x5a1e5c69, 0x428eed56, - 0x657c5dfa, 0x67dc01df, 0x5601df29, 0x1e421eda, 0x712a3e04, 0x3f0451fe, - 0x389517f9, 0xfcff28df, 0xc85ef9db, 0xf3e32561, 0xd4adf393, 0x7acbf98b, - 0xc124fdf1, 0xe04c652f, 0x2e6f576b, 0x50ce4277, 0x0ebde98e, 0x4db73f31, - 0xf7e50efb, 0x22dcfcc5, 0x28bad665, 0x17d20fc4, 0x103e0ff5, 0x04fa9469, - 0xbedc5c9a, 0x4bf1ce91, 0x57f8497a, 0xdf403809, 0x7e6c6339, 0xf274b63a, - 0xe095644e, 0x778f639b, 0xfc07af49, 0xcf4adf9d, 0xeabf116c, 0x7c93c603, - 0x7dcbc723, 0x38ddd279, 0x87dfe86f, 0x8f71cbfd, 0xd8f4227a, 0xe5c651cf, - 0xe52fc243, 0xa1fab732, 0x614707bb, 0xee968bbb, 0x9cde7003, 0xacd2ab8e, - 0xfd13bdf4, 0x59def805, 0xfadc50af, 0x1fe75898, 0xa8b5fc7b, 0x7e7e01e2, - 0x277c427f, 0x307f0cf9, 0x6de1263e, 0x7038f1b2, 0x0f52dc30, 0x9f73b849, - 0x2c6eefb8, 0xbee3f097, 0x4a9f2051, 0x957e4a3c, 0xf982f5f7, 0xda4e7896, - 0xfe73b54f, 0x463d4cae, 0x943a77e7, 0xfc27f707, 0x5ce213a2, 0xe33c6b79, - 0x8915ff71, 0x8af735fb, 0xb40c8b18, 0xc08ed23f, 0x807d1acf, 0xa7bf69fd, - 0x8b3ce716, 0xd690bb74, 0xc73ffa8d, 0xd0398cea, 0xe699d96f, 0x9dcef871, - 0xb8ef43f4, 0x31a353ea, 0x9f8bb55e, 0x52fc9377, 0xc93f6176, 0xffb8b941, - 0x83eab454, 0xefc8e182, 0xbed035bf, 0x63e3d14e, 0xcfdfe88d, 0x187332dd, - 0x41ef01a2, 0xbb3f5ea0, 0xbf266879, 0x984d6059, 0x3621f786, 0x01ed333f, - 0xaf559f28, 0xd80dbbd2, 0xd16fca0f, 0x5f1499a3, 0x52d6113d, 0xf8fd0a30, - 0xf456a81f, 0x32df6fe3, 0x7f6c31f4, 0x0c6ba5bb, 0x39b1b63d, 0x7d4ef296, - 0xe907d934, 0x8073caf7, 0xc7dee2d5, 0x3fde845f, 0xe22a9edc, 0x2f755ffc, - 0xdd6f8fdc, 0xacef4618, 0x75ed1a14, 0x4f6f1c3e, 0x54675a17, 0x23eaf11a, - 0xbf255bdd, 0x99918e6c, 0xb9508693, 0x0fca0939, 0x451f9a1a, 0x51f0723b, - 0x3f7c60cb, 0x86d7a992, 0x9a7f7315, 0x6ac63bef, 0x70912ddf, 0x0fc6247c, - 0xdf7e4fee, 0x1b08eb84, 0xefa44fdd, 0xedf8aecf, 0x6783b434, 0xe1b4f6b7, - 0x09ef4fbc, 0xa703fba3, 0xcf77da0d, 0x57def56e, 0x79297df0, 0x9a74f56f, - 0xfc938fd6, 0x377bc37e, 0x839ed37f, 0xa5b9d1bc, 0xdd194b0b, 0x8d397efb, - 0x2263f7d1, 0xe789dabe, 0x4d6a4b08, 0x7307bc56, 0xf71ef912, 0xfcab76b3, - 0xcb99a5fe, 0x99ddc9c1, 0xe4b7bf74, 0x525f3c6f, 0x3ef178a7, 0x9fa7fef2, - 0xb30af3a0, 0xabc4cfc1, 0xf3feed09, 0xa1a7a7ba, 0xb8765c38, 0xfe7de257, - 0xf9f95bcb, 0x32ef0e8a, 0x2079dc1c, 0xdfb9dec9, 0xcbfb5dfc, 0x9f110e32, - 0x2fcfbdae, 0x4fd72cf1, 0x8c3f026f, 0xdbc7e218, 0x90e74b67, 0xa9617cbf, - 0xca4bd29b, 0x23b7b5b1, 0xe9a25b1f, 0xeb1fc0be, 0xbdf1519f, 0x835df2a8, - 0x783ae1af, 0xbd346454, 0xd2d9f293, 0x7a8fb425, 0xa5156961, 0x0e32de92, - 0x46aec777, 0xfab3eefa, 0x9fbc06cc, 0xb46446fb, 0x90b603b0, 0xdeeced74, - 0xb9d79cb1, 0x4afa701f, 0x9d6dcfb8, 0x6af38519, 0x61b63e7c, 0x2235d224, - 0x5f7e8ada, 0x724738a9, 0xabf73d6a, 0x7fa398cf, 0x3df40f93, 0x024a61b3, - 0xbb3737be, 0x5869def1, 0xb147b25e, 0xb1c07ae2, 0xae145267, 0xb7d53edb, - 0xa8fde144, 0x7bcbd74f, 0x3bfa5e55, 0xd8f2a354, 0xca3f6c14, 0x0cf667a7, - 0x7c8d75be, 0x9e82f232, 0x879ebfee, 0x5c938a72, 0x0938a70b, 0xb9e2c4fc, - 0xf3afd991, 0x3afb4af8, 0x6ef3ac57, 0x347ef317, 0x31f726dd, 0x04773ca8, - 0x61bd3f2f, 0xefec44e7, 0x158366ec, 0xb36cfee1, 0x079ffa81, 0xc01d33eb, - 0x5f2b667b, 0xd71e60f7, 0xf2b767cb, 0x3abccdf5, 0x5f29bebe, 0xfbf27060, - 0xcc7e5aa2, 0xef47680d, 0x5ef274fb, 0x9f273cc8, 0x97b03cdf, 0xbe60df38, - 0x7475618d, 0x9e9bec8f, 0xdbe60d17, 0x855f92f9, 0xd7e7687e, 0xe044f8ce, - 0xf91de513, 0xbcc3f255, 0xdedf7cf5, 0x07383756, 0x47f24ef9, 0xd5593bf0, - 0x57dfc646, 0x7bd385d4, 0xed2293b8, 0x530fb406, 0x20c65ae2, 0xe74e3e5a, - 0xab9a807e, 0x37bde273, 0xf90a6d56, 0x748acece, 0x744557ee, 0xdeefc465, - 0xcf3f2b74, 0xc97fee29, 0x86922614, 0x84527b76, 0x343b0bed, 0xaefd3a79, - 0xcfc0f47b, 0x3db76e93, 0xd8c1ddda, 0xee0bd32f, 0x267cc3d1, 0x7776da65, - 0xbff3fc83, 0xb7f3c09a, 0x201a86d9, 0x78994cbf, 0xd7c818cf, 0x4a9f3ba7, - 0xece7180f, 0x38692e96, 0x19ff283f, 0xbbc5d796, 0xa5698e7f, 0x49760fb8, - 0x24b41d69, 0xfdfedfc3, 0x7fa3963d, 0x2df3fbb4, 0x18ee9606, 0x7f097980, - 0xdd25b4e8, 0xf8f4abf9, 0x8cc5e58e, 0xf5e74e3d, 0x0e1efc3c, 0x09ccb8fc, - 0xf38a4f78, 0x97bcb15b, 0x2f741353, 0x9fefc1c7, 0xf252fbc9, 0xff5f543e, - 0xb70db27d, 0x92ec9f72, 0x2a1dff81, 0x0fbda9c5, 0x89fc34a6, 0xf6a9f9de, - 0xa23096b0, 0x4d9ef683, 0x7753be39, 0xa20bdd1b, 0x6f4c87fb, 0x57337d27, - 0xac683bfa, 0x29dff987, 0xfcfc8960, 0x1f82a3c1, 0x3d652f4f, 0x9fe8807a, - 0xca39b77f, 0x985c700e, 0xfa85ebe8, 0xfddc3220, 0xe9d7c427, 0x0ba9d50d, - 0xaa1ef0e3, 0xed0f91c9, 0x7df978cf, 0xb7e132ce, 0x42f1cdb2, 0x3bbea82f, - 0x46535da1, 0x87684ddf, 0x757c17de, 0xfe97c321, 0x192bd423, 0xed049d7c, - 0xde5d3ce8, 0xb1e2bbf2, 0x4fed85dd, 0x700d98f4, 0xbc06009b, 0xfa1e35a7, - 0xf7a3611c, 0xfb4a98aa, 0x7efe5ecf, 0xa2799e92, 0xd5eef86c, 0x3ee2e933, - 0x9413dd11, 0xeff89274, 0x1a181740, 0x999d59fd, 0xbeee1019, 0xfdfd036c, - 0xf91f492f, 0xddc2e2ce, 0x7742fe3c, 0xe31e4524, 0xe2cda748, 0xb0759fef, - 0xbf916f8b, 0xd1e9620a, 0x330d9fe8, 0x11c9db43, 0xf5d88d1b, 0xff2f6d77, - 0x92fc2e9d, 0xe0706cc1, 0xa2a5923b, 0xd0b558cd, 0x2d5bef8e, 0x7bd3378c, - 0xe85f0b25, 0x96c1fc4e, 0xb60590fc, 0x89621b63, 0xa866565f, 0xf5b9ff84, - 0x2a1dde8c, 0xf3a64fa8, 0x36f5f994, 0x12daa34a, 0x6fecfca9, 0x7ae2c9de, - 0xe0a7d389, 0xa68cba7f, 0xd3ff4b73, 0xd9d6529b, 0x6691a77b, 0xf0bbcfba, - 0x0b6bb720, 0xc7bfcaa7, 0xbbafefc2, 0xc8ae3804, 0xb90b8a1a, 0xe753dc3a, - 0xf0ba57ef, 0xe77e00be, 0x677d5034, 0xfc4a57ef, 0x82dd049a, 0x7a9cb3df, - 0xde913330, 0x59ef147f, 0x9aed174e, 0xceb3bdc5, 0x4fbcb5de, 0x6a227bb4, - 0xddf2135c, 0xc8696774, 0x9ef52d77, 0xcffa0730, 0x7a48d486, 0x373ee147, - 0xf59a97f8, 0xf11e8b4c, 0xbf9b2d30, 0xba753973, 0xfd90deb6, 0x4373e939, - 0x92778776, 0x4d8fa80c, 0xecfb6d2e, 0xf50ec2ae, 0xf6bf7d65, 0x2354d15d, - 0xbe3d4fd9, 0x69f90b3b, 0xf4515de2, 0xbfffd10f, 0xff10b4ec, 0xb83bc49b, - 0x112b2ccd, 0xbeadc2f5, 0xdbfffb27, 0xefc1b1fb, 0x03bf06c4, 0x42eb7fdb, - 0xdd607e4d, 0x6fed350f, 0xa9ae5fab, 0xad5bec1f, 0xfa6ccfa9, 0xb43f2699, - 0xfb4d39f9, 0x693647e1, 0xbcb647ea, 0xfdbfa9a4, 0xfe4d0ecc, 0x683fd68e, - 0xb6d9dfda, 0x61cf9357, 0xe7da68ef, 0xe4d03f9a, 0x57ff5ac7, 0xc4aefed3, - 0xf1fa9a13, 0xfa9af3f6, 0x68ae7d09, 0x2f8e05f2, 0x373fed35, 0x457757ba, - 0x0cea22bf, 0x433aadf1, 0xf944f861, 0x6629a6e5, 0xba6b07d4, 0xf8247d0a, - 0xd3b0b96f, 0x7ba307ac, 0x6cd563ac, 0x3d5ff11f, 0xc1a0bbff, 0xde7f4f76, - 0x1ff8c4e5, 0x6bdf8d7b, 0x527f068b, 0x8c7e301f, 0xff02ccd3, 0x9e6c5dee, - 0x778f9355, 0x77da6a25, 0xd4d76e99, 0x68fbb927, 0x38e653ea, 0xaab4f934, - 0x5df69a11, 0xf9353897, 0xa69e4f0c, 0x971af77d, 0x76b3df26, 0xef7da6ba, - 0x7d4d6ef5, 0x4d1cef5f, 0x55adff7d, 0xbac0fc9a, 0xb7f69a25, 0xf5347bd5, - 0x9a357d83, 0x5aa6ccfa, 0xf3687e4d, 0xe1fb4d7a, 0xfa9abc47, 0x355b2d91, - 0xa99fb7f5, 0x68efe4d3, 0xbfb4d7ad, 0xc9a7cdb3, 0x9a83b0e7, 0xf7e6b9f6, - 0xd6b1f935, 0xefed344f, 0xa9a63c4a, 0xab3f6f1f, 0xce7e97a9, 0x6b9f3e84, - 0x53df85cb, 0xe697f8e0, 0x6ef7f6fb, 0x1f742877, 0x6ed75cea, 0x96c57df2, - 0x24fd1530, 0x6c99c517, 0xf5111078, 0xb727de15, 0x8539f3f1, 0x238aaf14, - 0x944c887f, 0x810bcf1d, 0xab8510df, 0xf40c8cb6, 0xfefc23ab, 0xccf5ea5b, - 0xdadff79b, 0xd5dcff84, 0xf288beee, 0xfb6eaf31, 0x989f7a38, 0x1c225679, - 0x77bffdf2, 0x956dde83, 0x19f378e9, 0x17f00fa6, 0xa6d5860f, 0x389af90e, - 0x05f378c1, 0xb6c1ef86, 0x22e22bf7, 0x17bdc7f8, 0x16bff406, 0xf7f817d6, - 0x9a976b23, 0xffc76fe9, 0xf295a96c, 0x522696eb, 0x3a00fffe, 0x0047bf29, - 0x000047bf, 0x00088b1f, 0x00000000, 0x7dedff00, 0x4554780b, 0xeedd7096, - 0x9d248fdb, 0x777579d0, 0x493cdc9e, 0xf09d0848, 0x3a3e00d8, 0xc0406021, - 0x490435e6, 0x41a8c1a4, 0xf881ba43, 0xbb75744f, 0xb2021031, 0x10d191b3, - 0x0186c195, 0x099d1964, 0x09d1a32e, 0xe09af09a, 0x1c604c3a, 0x3719d9c5, - 0x8ee2a3a0, 0xcfe31e10, 0x7fc38fee, 0x937ba9ce, 0x380e9dbe, 0xf7ff3afe, - 0xb4fbfa3f, 0xab755538, 0x739d554e, 0x2aaa3cea, 0x89895ead, 0xde6d6322, - 0xf39f4a1c, 0xc99899da, 0x316f36d8, 0x0ebddbc1, 0x72defd82, 0x9d7a774a, - 0x5bcbbf94, 0xaf1ef041, 0xdebdd28b, 0x79f74a1a, 0x92fe543d, 0x9fe081b7, - 0xb6947d7a, 0xff299b7b, 0xc10b6f15, 0x046dbc07, 0x53f5eabf, 0x4bdde1da, - 0x76de1be9, 0x76f4ef2a, 0xb7a6fc10, 0x6f2ee08b, 0xbc87c10f, 0xf11f04bd, - 0x98f8269e, 0x1ed28fb7, 0xbe9467ef, 0xf2a7eded, 0x0957bc77, 0xdbbf8ebe, - 0xcd2afc19, 0x2631e49f, 0x7ae69730, 0xc9ccc21e, 0x00f63226, 0xff824bfe, - 0xcc8846e2, 0x8cfdd8c2, 0xb0d73eff, 0x9413769a, 0x3ff2fe77, 0x74c60285, - 0x1f8d8ca5, 0xf662690f, 0xc634c6ce, 0xe675b026, 0xd318724f, 0x63d75740, - 0x4e09fb07, 0xd6191319, 0x2d75dfc3, 0x58c7dffe, 0x94bffc3c, 0x834c78e5, - 0x14095369, 0x55befb42, 0x1a777f82, 0x3e20d755, 0xbf1c8dab, 0x95135a69, - 0xf82c3e57, 0x5563020d, 0x8be9f322, 0x587dfb18, 0xc11b0154, 0x2e8f25d8, - 0x2172c447, 0x04830edc, 0x443a8ff8, 0x2c5d7e0e, 0x9da5b18e, 0xd29b1d86, - 0x84aaf106, 0xfdf035ef, 0x0c1a562b, 0x3a3d64ab, 0x1df203c4, 0x9ec618da, - 0x4ba6b8b7, 0x8a60ff90, 0xf687a7c6, 0xed9fc999, 0x2dec648c, 0xe6066b8b, - 0x77dcf25f, 0xc07f1b0c, 0x7ec6cf6c, 0xe2ba1b66, 0xfdff4117, 0x9df6b5c7, - 0xe1f3f0d2, 0x6c67296e, 0xdfca0ddc, 0x02ec973c, 0xa2ffca3c, 0x9ffce175, - 0xf85645d0, 0x492f01f3, 0x1a4a78e0, 0xeadb3a55, 0x7cf8825a, 0x47b9e919, - 0xe5f85303, 0xacf6ab6d, 0xae552181, 0x82e11aca, 0x2582eeef, 0xcd8c1963, - 0x418e9265, 0x38e67cf9, 0x2d4d069a, 0x17822e64, 0x6fa51f31, 0xb1aabbc5, - 0x4fccc59d, 0x21b26bb0, 0x82b8d435, 0x78cb72f1, 0x947c65b9, 0xabab71f4, - 0x20e5e38e, 0xba4c4ebc, 0xa5c71b23, 0x5596f5e0, 0x58737aa2, 0xefc476ff, - 0x3f1783cb, 0xd2863211, 0x174077c7, 0xeb1e6826, 0x73ac3d31, 0xf7d18ea3, - 0x7e088f8d, 0x2e856ba4, 0xb791992a, 0x0be418fb, 0xf4027481, 0xd2fc8451, - 0x92373a9f, 0x0949e4e8, 0x92707c1a, 0x0b1fa7d6, 0xb3f8d4e3, 0x87d12d05, - 0x1efc005e, 0x48fa0388, 0xea0e9e1f, 0xe00d219a, 0x67afa01f, 0xaff3bdb0, - 0xce0e5dff, 0x49cdfb97, 0xa357ce12, 0xe801d606, 0xd6b6f7d8, 0x99925bbe, - 0x94ed6014, 0x6ba47e31, 0x73edda26, 0xb17ae0c7, 0xdfa84ea5, 0xfb0d65ad, - 0xfbf687f3, 0xb417ae2a, 0x2ba6c27f, 0x9cbb53f7, 0x9ff295cf, 0x63c5fae2, - 0x5eadebca, 0x16ad69f5, 0xe8713ff0, 0x131a5e9c, 0x6f0d1c62, 0xe00666e7, - 0x3338eeef, 0xe44261dd, 0x45e7f2fa, 0x949fe60e, 0x1fa144e9, 0xb5d23ead, - 0x178814c3, 0xf9e817ef, 0xd13744e7, 0x4419cf40, 0xe0f89fcf, 0x690639d3, - 0xfb4822c4, 0x20ba6a60, 0xd660bd75, 0x672cdd23, 0x99ab4a76, 0x6007d293, - 0x9d7e91f9, 0x38f4a7be, 0x76b20fef, 0xbe2bafca, 0x7cf482d7, 0x8a95c6bf, - 0xa5eb2d70, 0x2feb377c, 0x2dfcc1b3, 0xd47b5e6c, 0x6fcf5806, 0x025a6a79, - 0xff3cefcc, 0xce98a3b2, 0xe27c25dd, 0x7a3f8893, 0xc13eaf10, 0xfa113eb3, - 0x92a5fbbf, 0x3f9049f5, 0x85d7cb47, 0x175f2bfd, 0x8f047e45, 0x97a1f81b, - 0xe341cb8f, 0xab9546d2, 0x09f2a1f8, 0x9da010e6, 0xff0683fe, 0xfe00b4ce, - 0xdfe87e28, 0x898e5093, 0x7ae0f7fd, 0xc434dfbb, 0x083f7ae0, 0x29c71be2, - 0x806b1838, 0x2ad690fe, 0x882a8863, 0xe1621fde, 0xb9f7ac76, 0xa79fdf4c, - 0xcfefa230, 0x4060e605, 0xa67417bf, 0x5ae50166, 0x0456cbaa, 0xbe60acf8, - 0x6ee50626, 0x38054bcd, 0xd725234f, 0x1fd744a7, 0xa61537b5, 0xa7f7fca1, - 0xf7ff280a, 0x698dec19, 0x5d84fdaa, 0xe321408f, 0x3f9f3861, 0x0ec776c0, - 0x3e284bc5, 0x14429ff6, 0xf33d0663, 0xbf888b19, 0xebe444d9, 0x57f13d44, - 0x066d4e23, 0x3c94e3f6, 0x9feda1a6, 0xf9edf190, 0xef744b4a, 0x16ecf183, - 0xf7c3f542, 0x60f8432b, 0x2c3f243f, 0xa7d1fa8c, 0xfa563e71, 0x64bea663, - 0x6a75d027, 0x86974b84, 0xc716c182, 0xcb998be5, 0x4fb49e97, 0xe67d7133, - 0xc8a8de4c, 0xdd8f6a65, 0x09d1e5c6, 0xf843e49d, 0x1d9a4944, 0x9c80d724, - 0x97f8abbd, 0xbb8f11a7, 0x2d2ea68c, 0xdd16eca4, 0x7d94fa9f, 0xff707d30, - 0x7fd94bbd, 0xeffbe16f, 0xefb5991c, 0xf1babb12, 0x3aecc67b, 0xfd972fc4, - 0x6d8f995e, 0xf22adfb8, 0x0b7ec871, 0xf9c5eb03, 0x832b2513, 0xc7c0b574, - 0xdc253abf, 0x36c47c8f, 0xf4f8d2e7, 0xfe0cfcb2, 0x58c15ade, 0x13c651a6, - 0x19704bfe, 0x20ce6659, 0x5663549c, 0x9b1e29c1, 0x06c8feaa, 0xe69e5549, - 0x679551cb, 0x7055db34, 0xaab14b56, 0x8736a8fe, 0x97f5ce0a, 0xede7eaab, - 0x31e0aa75, 0xfaaa15ed, 0xaa5c3b63, 0x1aaec2f2, 0x1eb8f955, 0xd09e0a8f, - 0xffaaa0db, 0xaa7da777, 0xcd7d49f2, 0x9f29f2aa, 0x5be0a8b5, 0xf554dbfb, - 0x57eabf6f, 0x7fb09795, 0x354f9556, 0xd3c157ee, 0xeaabafcc, 0x16fb80bf, - 0xb61dcff0, 0x0cfe556e, 0xbbeab8e9, 0xaa4e733b, 0x75e417e0, 0x270e2df6, - 0xe72d68be, 0xfb6cd1fb, 0x5876aa07, 0xfebe68e7, 0x7b6f3c61, 0x510b1fcf, - 0xf4d76e4e, 0x4add21a7, 0xf222735a, 0xdcf16671, 0x2c664043, 0x14aab1db, - 0xf94e5bc5, 0x1d308753, 0x8a5fdced, 0x715f926c, 0x05a610f2, 0xd0a58bae, - 0x44d7b31c, 0xc8b4c61f, 0x8ad53853, 0x3dcc34a8, 0xdf44e98c, 0x5728a9aa, - 0x3f5c785f, 0x2a28f91a, 0x074fa146, 0x827d67d1, 0x7eb9f886, 0xf28fc9b1, - 0x24c532c7, 0x96139032, 0xb1d65a1f, 0x9a8b4c02, 0x1af66d31, 0xfa0f5f99, - 0xba519780, 0xfe666bc9, 0xaf67206c, 0x93fae08d, 0x43a795f7, 0x44ab233b, - 0xe699aa33, 0x48258f51, 0xe5f5bed0, 0x765d9c96, 0xb0edd6c6, 0x42e5d7cf, - 0xc59e19ff, 0x4e01a23b, 0x30058e63, 0x2398167f, 0x25b19936, 0xfa76df3b, - 0x97c287f2, 0x244d9d33, 0x5cf6c417, 0x7694ffd4, 0x6e7e9637, 0xdf2198d7, - 0x11e74bf7, 0xf1adf798, 0xc21df4e1, 0xa75f9925, 0xb60b475d, 0xf69ef90b, - 0x4cfc7c10, 0x977fdf1a, 0x0a7d73a4, 0x66eb8487, 0xacc6cbe5, 0x808ca7a0, - 0xa93adcb9, 0xf0ea0ce1, 0xa027d9a2, 0xe0d7627c, 0x892b907b, 0xe0832958, - 0x4e01c3db, 0x6c625840, 0xc7eb967f, 0xc5d5afd8, 0xfa00d9d8, 0xc351a849, - 0xcf9e615b, 0xa3e20e66, 0x89f1aa5b, 0x8fdd0630, 0xf43b769d, 0xc60aadb3, - 0x3d56f00b, 0x7a9437d7, 0xf68c34a3, 0xf8d32ff7, 0xcdaece7e, 0xf49ea3b7, - 0xe79e3ca5, 0x3e8bfdbc, 0xeb7b44ce, 0x3589a52a, 0xf205c11e, 0xb4e95acd, - 0xae9ea0fb, 0x8423e611, 0x348bf2de, 0x1dd7be91, 0xa090447e, 0x1269a7de, - 0x7e9589c1, 0x0d52771a, 0xbf801bb4, 0x6609f44d, 0xe63db7c8, 0x9b3f1013, - 0xf06769d9, 0x885a331d, 0x3cc8d7fe, 0xcbf86b61, 0x0f418fa2, 0x769d79d3, - 0x13bba7ac, 0x271f33e8, 0xb86663d4, 0x47e3c94e, 0xa3eb10b0, 0x0d3e86a4, - 0x9f40dc73, 0xd47d4a8f, 0xddc5fb43, 0xe80b2926, 0xa6c585fb, 0xda211d8a, - 0x9f9e54fb, 0xfeea310d, 0x1f3e5a2d, 0x6cbedc8a, 0xf0a8ebe6, 0xa6689af1, - 0x526be392, 0x846f5bc6, 0xc8cdb5af, 0x6ef8015c, 0xd0cc7e85, 0x55abe1be, - 0xe83f1c66, 0x4fea4ed0, 0xc764f2e4, 0x6ec8728f, 0x21c75e0a, 0x3f9408f4, - 0xa3e908a2, 0x7c08dfcf, 0xdbd2a868, 0xfeb26f51, 0x7b809343, 0x116b2273, - 0x5358be50, 0xdc447aca, 0xae5744d7, 0x793e8433, 0xd654ba33, 0x839fd94f, - 0x3d774bd7, 0x9c12fde3, 0x31d57fef, 0x1f56c7d4, 0x05718f8f, 0x3a4c53d0, - 0xd662cba7, 0x98fe45a2, 0xbd29dacc, 0x7a52f585, 0xd4a7eb1b, 0xa622ccc1, - 0x694ecca5, 0x3a527319, 0x2d28799d, 0xce942d67, 0xce94ed64, 0x8294bd62, - 0x93a9433d, 0x9aeec999, 0xa637fb07, 0xd293980b, 0xa50f31ef, 0x7e9ce999, - 0xc10b582b, 0x4a76b377, 0x24ef803b, 0x8c01fa3d, 0x9c827694, 0x904df4c3, - 0x79769873, 0xa3652625, 0xd287201f, 0xa53b5e23, 0x94c5bcc7, 0x541d78f6, - 0x396f6def, 0x9d78efa5, 0x56f09e94, 0x75ebda50, 0xde53bd51, 0xf5df4a1a, - 0xcf7d287a, 0x69e940db, 0xdfd28faf, 0x1d299b79, 0xc67e07a5, 0x2be9cdf9, - 0xf53e7d44, 0x0243bd23, 0xe591ecf9, 0xe68761d2, 0xb8f1dc99, 0x40661a6e, - 0x235b283a, 0x7359fd20, 0xa43f0e34, 0x0b56729b, 0xe1ba42f7, 0x0cdfd704, - 0x0fd248d6, 0x82f56dad, 0x0876ed04, 0x5808da7d, 0xa9e9e9cb, 0x9f208d73, - 0xbad93a4b, 0x19c23b08, 0xee81194f, 0xfd3ce876, 0x64bca03b, 0x08d734a7, - 0xc8e4d67b, 0x8fb1ff53, 0xe93e54c3, 0x03346b08, 0xfb3d2b3c, 0xe38138a9, - 0x7befc281, 0xaee6733b, 0x253c44cd, 0x34c5f3c2, 0xbf512c30, 0xfa44c47e, - 0xd9db6175, 0x93c00d42, 0x68454c1a, 0xebd40617, 0xae1fba42, 0xf2b9705e, - 0x9655b6dd, 0x0d879c46, 0x0e5a809f, 0x7d19a959, 0xd5f3ab85, 0x5ebe6aed, - 0x837b4cff, 0x09eb03fe, 0x7f6f6837, 0x7d32a396, 0x3a7effc2, 0xdd6fa60f, - 0x6bf68ff5, 0x8e640fc8, 0x5774fdc1, 0xfd339734, 0x04ee9fa0, 0xc8c577bc, - 0x1a4cc6f0, 0x5c43ca17, 0xd29b0db7, 0x77803efd, 0x1f573985, 0xd47ff2c7, - 0xd14277d8, 0xa6d770ae, 0xc933825c, 0xc621b13f, 0x8f931393, 0x97df3cfa, - 0x0d1f935a, 0xbff80293, 0xafcb9d39, 0xe95cb7ad, 0x447681dd, 0xc16586b3, - 0x979b3b77, 0x7681cc6f, 0xf419bc7e, 0xdc478007, 0x0b31bd5a, 0x6a37d3ca, - 0x19656a26, 0x78fc7887, 0x4d9ef573, 0x8f255fa8, 0x7686c98e, 0x99796433, - 0xb857db1a, 0x55bce806, 0x95a7b6af, 0x7e649ff4, 0xce6686a9, 0x954d6c82, - 0x3a1df4ed, 0xdfb81156, 0xefc64cfd, 0xd53c5957, 0x57fdcedd, 0xfee19186, - 0x25fc6027, 0xc3bfb923, 0xfe48ceb2, 0x7ff24b0e, 0xca03bc9d, 0x7634db2d, - 0x6b44e954, 0xea1d5aed, 0x3b598bfb, 0x810ee3f2, 0xe14bef7f, 0x0a28217a, - 0xec0373e9, 0xd3deadf2, 0xfc03328b, 0x9f0ab684, 0xc97bf680, 0x0fa15ac8, - 0x07e49ff7, 0x2dfbb405, 0x15c12e15, 0x8781f689, 0xb965cfca, 0xf80e927e, - 0xfbe12ad9, 0xb992fd40, 0xa15d7012, 0xd2768adf, 0x605158f3, 0xf8b3a77f, - 0x3b07ac3c, 0x75d5f499, 0x782bc27a, 0x97654ebe, 0x95f6c01e, 0xff2e0c75, - 0xabb7067e, 0x5d013d77, 0xe24c1f20, 0xdd89f376, 0xce3fa489, 0xa0770d69, - 0xa9e274fd, 0x6f0465d1, 0x3d40ec99, 0xc9eec4f2, 0xb39d31d3, 0x3bd52665, - 0xb41eb021, 0xb96ce787, 0xd4fcc45b, 0xdb0bc00c, 0x7a27a33b, 0x41e5b39c, - 0xcb47fbf9, 0xe358bcb0, 0x91da09fb, 0x22fb8dc5, 0x1c9e4ed0, 0xa6124af9, - 0xf57d3427, 0x5dffd0dd, 0xdc2bf666, 0xe31b9d9e, 0xfe1cb1fe, 0x74a9f731, - 0xbfd7ea1d, 0xf5a74f4b, 0xc41ccf9c, 0xec835007, 0xf6f65bba, 0x8a4d061e, - 0x3fded6dd, 0xe65ccc15, 0xc11f30e8, 0x5ecbb4b4, 0xd657d386, 0xe9823ce3, - 0x194f5ef4, 0xa7e52faa, 0xba608e5b, 0x3bf5d724, 0xff179f9c, 0xbcaf7be1, - 0xc7c8f008, 0x07a8cdeb, 0x37d13e65, 0xebf92763, 0x21f90c74, 0x45a7926b, - 0x746c048b, 0x787ca0c6, 0x835169f6, 0xad21b9fb, 0xc3610c25, 0xb41ae97d, - 0xb745770b, 0xb3b8d0d4, 0xe3ce19c2, 0x210fb0db, 0x3b45645d, 0x809f9063, - 0x3e1d692f, 0x10d3e993, 0x634731ed, 0x1fcf187e, 0xe1ce17a8, 0x5af503f3, - 0x27ea04c2, 0x13fb2046, 0xbfdc06d4, 0xddfef26d, 0x38093cc6, 0xcf48d61f, - 0x64ebf40e, 0x67fe7095, 0xb02e9c91, 0xfa44d37a, 0x96cd9c84, 0xb89dcf16, - 0xe897560e, 0x3ba40beb, 0xf40706d8, 0x19827491, 0x055bd7da, 0x219c830e, - 0x7e87f0bc, 0x42c98b0c, 0xbf828d7a, 0x0bda02b5, 0x1c7033d0, 0xdf834cf3, - 0x9b177429, 0x4235c7c1, 0x65acbfa6, 0xdf053dbc, 0x9f2e0cb8, 0x83496f01, - 0x7c6568f8, 0x009a1c60, 0xd1ea027c, 0x66f006f8, 0x05d21b76, 0xa7817a48, - 0xc703124c, 0x8471ad5f, 0x7a645da1, 0x4fe8fbf5, 0x02394289, 0xf753fe78, - 0x69f22324, 0x327238f0, 0x46df08d2, 0x6f5187d0, 0xfce2e99f, 0x11e958db, - 0x18423ec8, 0x3a2c9fc7, 0x35681fd0, 0x017416ad, 0xf326b5e3, 0xa5667a7d, - 0xcae51ba7, 0x3b08e2cc, 0xac9df7d2, 0xf3999d7d, 0xc04c91f7, 0xf81b146f, - 0x41c4d899, 0x4f47f0bd, 0x97127bbf, 0x97b59934, 0xf9fee2e4, 0x70b3fdf8, - 0x3a3eb6fd, 0x4ff107b3, 0x3baa79cc, 0x5e741a06, 0x197dd794, 0x6ca4ebf7, - 0x1c0e3f13, 0xe0079247, 0x8d44bf40, 0x41e81cba, 0x65742b05, 0x71a21a13, - 0xe444d1bf, 0x7a819ccf, 0xe486944a, 0x6129c83b, 0x33fd4841, 0xf9e4ae88, - 0xaee7d657, 0x375a4c8c, 0x03af89ab, 0x171bb7eb, 0x5583ca46, 0x6dfa09d6, - 0x011f3604, 0xa658df74, 0xd7680bf5, 0xac28fd62, 0x919de2cf, 0x8769d743, - 0x03399a4e, 0x1ac3f4e5, 0x74366ef3, 0x7edc815e, 0xc3ed7a4b, 0xf90e5471, - 0x7dfc91a2, 0x436af801, 0xb8f5eac1, 0xac6dfd59, 0xb48cee6b, 0xc989f9a1, - 0x3ee2660b, 0x68cb589b, 0x47cb83fd, 0x575ea63d, 0xa3c737b2, 0xbbf988ff, - 0xce7ac1be, 0x8655de4c, 0xbaf07cfa, 0x1a97742a, 0x105f7a1b, 0xa65f3933, - 0x954fd846, 0x92215e93, 0x114ce09e, 0xa2ed03e3, 0x1f7c190d, 0x1335fdba, - 0x23ec43ed, 0x5cb71fa3, 0x93ef577b, 0xa50eb0b9, 0xae683457, 0x1cefa3b0, - 0x484ce1fa, 0xddeafda7, 0xf50affd5, 0x1a657da6, 0xb06ff987, 0x10e819be, - 0x9d80f5f1, 0x2fdaf001, 0xa3a0b4f6, 0xd992b1a4, 0xfa55df71, 0xf3f723d9, - 0x49df9d0b, 0x645735f2, 0x820e493b, 0x2f401e65, 0x7e896900, 0x56731978, - 0x68dd90b6, 0x5907cccd, 0xf6bd6e8d, 0xfe5fb425, 0xefd0cf49, 0xd242af38, - 0xe7f8c095, 0x65ba4a55, 0x5917c7e8, 0xf311ea39, 0x3f94ec2b, 0xf3ced2bf, - 0x417f3c8d, 0x17f28385, 0xbe783a54, 0x3e61f209, 0x7bf85616, 0x42eed0bd, - 0x41a48c53, 0x93a5783f, 0x50355f97, 0x0f603bf9, 0x87c90264, 0xde49f987, - 0xe1a67cb7, 0xb84f12f1, 0x0d5c005f, 0x123d4591, 0x1a7ddfce, 0x8624167b, - 0x01999114, 0xe9c2b67e, 0xf3f942d7, 0x13809fcc, 0x6af546f9, 0xbfe43667, - 0x719a2c91, 0xc0386f7c, 0xabf9c66e, 0xe9de6915, 0x351bf007, 0xd8cf14c9, - 0x7dadfb21, 0x67e48c2b, 0xfc875d05, 0xa2456cac, 0xf2f0c7ac, 0x7ecdcb6d, - 0x0e40c7d4, 0xdff63ad2, 0x001e9227, 0x1cedf0f2, 0xca5e8bd4, 0x484987b4, - 0xb37e6ab7, 0xa12f2f54, 0x19992af6, 0x9559f2ed, 0x97c6bdbc, 0xea0d7e34, - 0x3379a655, 0xf71a0e91, 0xafda3b32, 0x2a9f56cf, 0x9b78458b, 0x87e5cedd, - 0x56342e5a, 0xe12e396f, 0x731a3c78, 0x7ee7d516, 0xe94f46ad, 0xc830ad2e, - 0xd2deb4cf, 0x2a18fca0, 0xd83dec6f, 0xa955424e, 0xb3d4137d, 0x8fd138c0, - 0xf3cf4dbd, 0x1488f77d, 0x8b54b067, 0x4182e65d, 0xa7914efe, 0x187c82d0, - 0xc545f245, 0x525fa35f, 0xf9923fc3, 0xc45df814, 0x3176f971, 0x5d95c93b, - 0x27207aea, 0x52af2835, 0x67f9d4da, 0x2fc504b2, 0xe0879aa5, 0xb87ab679, - 0xe71e0bdc, 0xc2bab8e0, 0x34b8d146, 0xd7285c7c, 0x74d73f20, 0x2b73f288, - 0xa124bb45, 0x853f6bbc, 0x92f51fe3, 0x9e00bac8, 0x13345d55, 0x66d669e9, - 0x6643b90d, 0x0b925eb3, 0xe2b71b37, 0x671e08df, 0x6436f8f0, 0x1cdf6968, - 0x1bd707d0, 0x7d6c1f49, 0xb8c1a4c4, 0xe15be822, 0x973857e8, 0x099e1a55, - 0x532230f3, 0x6bafd7d6, 0x34693cb9, 0xacea9d11, 0xfa04e58f, 0xa5d1841f, - 0xeebeb023, 0x72bcec7a, 0x68e91b8a, 0xac72c1dc, 0x93639658, 0x2a7c60fa, - 0x933873ff, 0xd6f7e602, 0x7c1518fe, 0x5544d5fb, 0x2e1012fd, 0x8d53e581, - 0x69f2aa79, 0xf82a71e6, 0x5514db0e, 0x54d219fd, 0xce677c15, 0xb3faaa9d, - 0xf055f3ed, 0x544bc55d, 0xee3ae7f5, 0x2fcf9555, 0xbe55487f, 0x0546b9d0, - 0x7bf8aa2f, 0xaec5fd55, 0x92f95546, 0xe555279a, 0x9293f6c1, 0x3f726696, - 0xe79b56cf, 0x8be483a4, 0x0e46704b, 0x14a967ad, 0x3dd703fb, 0x53eb822a, - 0xe51af5c1, 0xe04178f5, 0x48feb1fd, 0xe29df20d, 0x91ed637f, 0xd75cff2a, - 0x3ec6c9e4, 0xec72fa13, 0xb2dd23ef, 0xc51fdc13, 0xc53bfcfc, 0x04fdd57f, - 0x56f683d4, 0x715ba647, 0xabbf43bf, 0xf9fd0f4b, 0xb7bfe435, 0xb40bd736, - 0xe7ae6e0f, 0x7aab957e, 0xc00d8ae6, 0x7ef38583, 0x828e78e5, 0x70447327, - 0xcf1860ff, 0x95fb26df, 0x52bf439e, 0xb03f6336, 0x17787e28, 0xac509bb5, - 0x467fa1f7, 0x7a08f6a8, 0x662e5b94, 0x07284836, 0x97ff5397, 0x5823ec2b, - 0xd2567988, 0x398daf56, 0xbd5b7da0, 0xc61ead6f, 0x69399756, 0xbcd0b3cb, - 0x1fc8c3cd, 0x94e668f3, 0xe7816b2d, 0xa25321ff, 0xf9104975, 0xf75f3f3c, - 0xd03db9c6, 0xa5956b5f, 0x706ae508, 0xf3bb9279, 0x941bb1e2, 0xd5f2bf3f, - 0xd1bfee0f, 0x671d75f7, 0x87ca029a, 0x24568bf5, 0x1d004732, 0x7ed08648, - 0x74c81ff9, 0x27ac9ee5, 0x5a33d63f, 0xcfc893d7, 0xd7ff2617, 0xddf0bdc4, - 0x3dcae979, 0xfe43a7a8, 0xea1f300f, 0xcf9ebcd1, 0x29e744bc, 0xbf40f352, - 0x2c3bfd47, 0x941edd34, 0x95ad17db, 0x5a07e8fd, 0xd097a91d, 0x7e324fce, - 0x0eea7e46, 0x83abb71d, 0x07e7f7ed, 0xb276edec, 0xedcbf7bf, 0xad5396ec, - 0x8ccf7f99, 0xe45a263e, 0xf98840f8, 0x09b546d0, 0xab12af28, 0xf9024fc5, - 0x4f523ba2, 0x498b047e, 0x6a983bf6, 0xc5017e54, 0x791dd06f, 0x6f7480bf, - 0x7e415ae9, 0x6017f47a, 0x75e5077b, 0x2417f609, 0xe8b4ff19, 0xb51bd8e3, - 0x23f206cf, 0x04fd1084, 0x27f8a1e1, 0xa3f1fb82, 0xccfb813e, 0x27d270ca, - 0x397dc782, 0x6650e4b3, 0xff48f23c, 0x7e503bc9, 0x7ed1d29f, 0x84bd1c38, - 0x1fcce149, 0x266f7ed0, 0x7223efb7, 0x91f95462, 0x0fe644f6, 0x64b35ff4, - 0x321127f3, 0x48cc5b0c, 0x51c6df7d, 0xbcdbdfd8, 0xbb3a13bf, 0xd841f48d, - 0x7bfed0f6, 0xeee7e64f, 0xab69465c, 0x01b7976c, 0x9cfa631f, 0xd9fa4cd7, - 0x843fe036, 0x4a257bb7, 0x4a1cdefd, 0x54ed7a77, 0x4c5bcbbe, 0x83af1ef0, - 0x72debde0, 0x9d79f74a, 0xb792ff94, 0x7a9fe082, 0x7bb6945d, 0x15ff286b, - 0x03e087af, 0x5f8206de, 0x44507d45, 0xa533753f, 0xa85b786f, 0x46dbd3bc, - 0x3f5e9bf0, 0xbdde5da5, 0xdbc87f94, 0x6f11f04e, 0xbcc7c107, 0x78f7045d, - 0xdb7d287b, 0xeff94bdb, 0xdc134f78, 0xb1938f2b, 0xfa2f5ee6, 0x84a25c2b, - 0xaeb3ddfa, 0xd7ea336a, 0x331a65b6, 0x9736f38a, 0x39fa0566, 0x78f255b6, - 0x86956d9f, 0x87a040fc, 0xb39f51fa, 0xf8fa7b2d, 0x405f2a34, 0x49b15be5, - 0xabac4a30, 0x56cafeb8, 0x159ea9ea, 0x77c1020f, 0xfd2b6adb, 0xb25b805a, - 0xbadca9c3, 0xedbb244a, 0x3a278d79, 0x245deb9b, 0xae3aadbf, 0x1074283f, - 0x22e9fb21, 0x974a44b2, 0xa3fc7365, 0x23ef4232, 0xfc4a5919, 0xc707b9a4, - 0xf182ab67, 0xf555be21, 0x5a5f8c46, 0x49f183ef, 0x3aae3fa4, 0xc3247804, - 0xc07f1178, 0x6cc2fc87, 0xad97d719, 0xaf08eb55, 0x94f365e4, 0xda346778, - 0xfa9e6de9, 0xa56f84b9, 0x36cd7e48, 0xfbe8a1d7, 0xe7ca4e50, 0xe1f1ac7c, - 0x50fe7f4e, 0xf082327c, 0xddb8c6df, 0xd2fa0c90, 0x00e310fe, 0xc7a9478b, - 0x198f78fd, 0x26f1fa43, 0xb2627acb, 0x3d8ff9c0, 0x6dff122c, 0xc1f7a067, - 0x7e81cf77, 0x503943e7, 0xfa156fba, 0x72cd1eab, 0x3c02cc4d, 0x3f8d247e, - 0x531c0224, 0xaf4fdbce, 0x1ea0f717, 0xae7deb0d, 0x3e37f209, 0xb689d9b8, - 0x6966ec71, 0xdb5bb22d, 0xd01357b2, 0xa82c95ff, 0xcb4947d7, 0x3bb63c65, - 0xd5cf7b78, 0xb64fe48b, 0x76903aae, 0x865bf784, 0xfa8e26fd, 0x61ba187d, - 0x1a481632, 0x55c91914, 0x2fec45e2, 0xe5cda1ec, 0x66fc5fd8, 0x215fd287, - 0xe775f7f6, 0x65e3e469, 0xbc085756, 0x37279386, 0xb38b2393, 0x8e48e322, - 0x9424b124, 0xb8ebcf23, 0xe49df2dc, 0x861d24fa, 0x1fb43499, 0xc4ae7e25, - 0xe8e383d3, 0x243d3235, 0x61c74219, 0xfde80d57, 0xddb7aa3e, 0xe749c9b1, - 0x0b3e304b, 0x6c75ab45, 0xeaf3ae05, 0xdaf37092, 0xa4a0f410, 0x018e505b, - 0x468bdfdf, 0xb9b3b523, 0xe1a3b79c, 0x56cadced, 0x32625c11, 0x6bc842fb, - 0x6e5a7d25, 0x4e2c81e7, 0xbe0f49b7, 0xae18f1b4, 0x3a3adbef, 0xc69cf413, - 0x04ed11bf, 0xc92d09df, 0xfb6d44d7, 0x78013d8e, 0x79e3cb35, 0xb5cfef4e, - 0x7b40ff23, 0x915728f9, 0x7fc9f25f, 0xcc0566c1, 0x5addf2bb, 0xa3fd8fd9, - 0x29a21b6b, 0x2eb55cbe, 0x36a3f50c, 0xb07a2466, 0x85d13cea, 0x4560f401, - 0x1f410cba, 0x4af4b2fb, 0x3254d53c, 0x7c32e311, 0x728a9e5f, 0x583ef009, - 0xe1fb451d, 0xdeef65d4, 0x5be01639, 0xd47688ae, 0xe5ab9ecb, 0xfd2713e7, - 0x26e74351, 0xdb9c7cde, 0xb7fdb77d, 0x7bf41eb2, 0xb3e9c827, 0x7a41e768, - 0x77b3334b, 0x52dcbac1, 0xcdff226d, 0xb3c557ad, 0xb91a7681, 0x7da3c7a4, - 0x5335fdc1, 0x803ca1fa, 0xa67d26fe, 0xaa330fae, 0xa1233d45, 0xab6f9d4f, - 0x1a66703a, 0xcb56d3f4, 0xf6bb6e3f, 0x7d8471fe, 0x93f21af5, 0xf429f500, - 0x4dfe4093, 0xe78097d1, 0x191a3716, 0x32eb73c9, 0x41e519a3, 0xe49c25b7, - 0x1362db5f, 0x321ba1e9, 0x9ea18757, 0x8faaa86c, 0xdea474c6, 0xa77d03b7, - 0x7dffbbdd, 0xe4812d9e, 0x817f3f2d, 0xfa0c5984, 0xae7abdc0, 0xb6faf8e4, - 0x7944cb4c, 0xc3f2a1a9, 0x8b7dffbb, 0xac077d0f, 0x3490f085, 0x7e0f912c, - 0xe29bbe00, 0x2fdf02d4, 0x444e6740, 0xabae74f8, 0x4243e507, 0x8b1baf9c, - 0x56ce9ab6, 0xcae2f9d2, 0x5d33e238, 0x31e987b5, 0x18c8b2bf, 0x9f0ae7c8, - 0xfffcb5fc, 0xbbe71cb4, 0x59b81c99, 0xf7e337bb, 0xbe73a59f, 0x369ece19, - 0x154f230c, 0x9acf18fb, 0x4b6c8a63, 0x7d59eafb, 0xf6eafd48, 0xc567ce6c, - 0x643e7e7a, 0x72f4c54e, 0xfaf8c38a, 0x96c73c44, 0xa9f9cd93, 0x714912cd, - 0xd674b6e2, 0xdf037185, 0xf7f70d72, 0xdafff1c4, 0x3fc9d32a, 0xa2782ad4, - 0x3e78197d, 0xeb8695c2, 0x147306d7, 0xa6b7fd09, 0xfcceb972, 0xabc6331e, - 0x409a9da1, 0xf3dec1fc, 0x9198e9a9, 0x0bfe4c3e, 0xa49ef12d, 0xa3b7f00f, - 0x17fd1c5f, 0xdadddfc1, 0xbf6f86af, 0x984b86aa, 0x354f054e, 0x6669e1aa, - 0xe6c96c35, 0x361dfa7a, 0x490cfe75, 0x1ca7270d, 0x73f0d309, 0x7f01a6ed, - 0xbbf044b3, 0xa07e0199, 0x01769a0d, 0xafa525e7, 0xadb2fc96, 0x93dfdca9, - 0x73f6af5c, 0xb596b224, 0x6df90231, 0xfcb6f954, 0x73fa0255, 0x7cead56c, - 0x8c150798, 0xbff48acb, 0x9f95d724, 0x02e9718d, 0x4b3aee7e, 0xc5cde9eb, - 0x238b6875, 0xcf934a3e, 0x1fdd0d05, 0x95b8d0b7, 0x7c0f9076, 0xfa45e301, - 0xe62f840f, 0xc76726ba, 0x05f03e73, 0x7df997ee, 0xa503e43a, 0x41f8e1bf, - 0x3962c7e1, 0xab9ca26e, 0xa5b722b9, 0x97a9ab9c, 0x0475c7cf, 0x92b9c79d, - 0x81e7465c, 0x09aef4ae, 0xc877c50f, 0xce6cbe67, 0x946e9877, 0xdf20d7cf, - 0xef9cf4f9, 0xd5f0df30, 0xfd28672a, 0xafbcbcf0, 0xcc37b43c, 0xf8c071fc, - 0xab47b656, 0x82477760, 0xd3bcf039, 0x740ff843, 0x3a3337ba, 0x0f2b5a47, - 0xbf338be7, 0xe908d3db, 0x0b975a5b, 0xd66567d7, 0x338f3d59, 0xfe51ebf5, - 0xdff7979e, 0x38dd820d, 0xdb94c05a, 0xbb668da5, 0xccbdfd11, 0x57f2a19f, - 0xd5877e28, 0x31acd22b, 0x0188ff80, 0x4cd3823f, 0x33e34de7, 0x35118fc9, - 0x2b3771d5, 0xccf73c04, 0xa2046f98, 0x554e85dc, 0x658fc790, 0x97d0fd97, - 0x035e383c, 0xce02abfa, 0x0f441923, 0x3573b923, 0xe7014995, 0xff655bca, - 0x9b1f00c5, 0x7f609796, 0x7896cc3f, 0xd679863c, 0xda9fff72, 0x6ab8665f, - 0xd833b553, 0xdfaab27e, 0x722fd956, 0xfed5f6f3, 0xf4d5c337, 0x0ecfda61, - 0xb21cdf6a, 0xd576c1fd, 0x11afbc7e, 0x3e436f1f, 0xb5ffce18, 0x1ba7965f, - 0xf45e9e6c, 0xd818e97f, 0x06071495, 0x6a8898fa, 0xc369ff23, 0x5d5379f9, - 0xa60fdab2, 0x1f927e63, 0x90d647cf, 0x3e6048fc, 0x9859df8a, 0x47d7f287, - 0xbbf1e74d, 0x1371b960, 0x8798c179, 0xfd00dea1, 0x3f57f2a9, 0x46d3f7c2, - 0x3c42eec1, 0xfff3c783, 0x89abdd8a, 0xfa4bdf1c, 0x64b84a73, 0xdbde81b8, - 0xe32575ea, 0x3dc21bf7, 0xfeeb1835, 0x762ebb3c, 0x1b3de83d, 0x7c08c630, - 0x71bb3576, 0xfb84cfbe, 0xf58fa724, 0x27a21a71, 0x1d96ddcb, 0xb27a00da, - 0xa8695de8, 0xf2345af7, 0xa1fc2f39, 0x65bd6cbf, 0xfd10a6e7, 0x029bfa2b, - 0x8f002b5b, 0x956dba00, 0xfe81e6f5, 0xd0ee2496, 0x3163b406, 0x3fa90ab8, - 0xd2a35ce5, 0xeb37d35f, 0xf7ecab6f, 0xdeb3fa52, 0x559f1ea3, 0x59f1a1ef, - 0xe947fde5, 0x2f8e2b6f, 0xb4dd5f04, 0x1e8ed93f, 0x7aa96fe8, 0x8783567c, - 0x72d567c6, 0x7f40e1ff, 0xbfacdf4d, 0x931ef936, 0xe1d3e64d, 0x0e37fdce, - 0x1a76ab9c, 0x29b4ae51, 0x7f7940fe, 0xbfb414bb, 0x37f796ad, 0x714bfbe5, - 0xbddfe4e9, 0x18df33d4, 0xfdc35f6a, 0x247ac98c, 0x2648f593, 0xcf0891eb, - 0x3ea67a99, 0xf0b0e81e, 0x22f9b6c5, 0x1e73e3ec, 0x153e333a, 0xf62f19e0, - 0x5f6117cf, 0x99e2f39a, 0xc9f04903, 0xccbe2fcb, 0xe6787fcb, 0x9b94324a, - 0x2fcdef7c, 0x962a3803, 0xde0ac7ef, 0x8db7bf4a, 0xbba37ae2, 0xbfee73e1, - 0xfb8af904, 0x87aa6356, 0x42f17fa1, 0x32d47f72, 0xe94eefa8, 0x310f2cb7, - 0x6eea4a2f, 0x467e4f38, 0xff287914, 0x40bfe1e6, 0xee53cfb4, 0xefab9467, - 0x6d454467, 0x8c2ffd22, 0xef28cdf9, 0xba0e8c22, 0x28d6f84f, 0x642c1fbe, - 0x376e0af6, 0x39f25948, 0x31cfba0d, 0xd76e58bf, 0xb1cfcb7c, 0xb1c6a17c, - 0xdfd9ed1e, 0x478aaa4e, 0x173958f5, 0x7f783797, 0x1bf5d772, 0xbe0e1f9c, - 0x23e7393f, 0x23c2eb81, 0x3ba5bfb8, 0xb9f7e257, 0xa886fc02, 0x9f370ef7, - 0x7db8a3b5, 0x0e9f383f, 0x0e319f3e, 0xfee69f3e, 0xfeb0b5a8, 0xcb7ee8ee, - 0x5d9fc413, 0xc86be721, 0x5fcd06bc, 0xd8a628fd, 0xb7a45a79, 0x32b7cd9b, - 0xc1f9caaf, 0xa2ca4146, 0x794feafd, 0x3183fd2a, 0x8e2a14bb, 0xb819f483, - 0x4e6deabf, 0x5d19fe86, 0xcf073d9c, 0x45fe3795, 0xde5cf21b, 0xd63e796e, - 0xb9d38546, 0x3d28c6ce, 0x51dddbd9, 0x97fa1933, 0x9a74d345, 0x72a8b297, - 0x8da96f3a, 0x8f68ed65, 0xd7239f06, 0xce9bb88e, 0x68ad6901, 0x703a4041, - 0xa461d92e, 0xe8b989f8, 0xc5c8e786, 0x8f239d9b, 0x91cfc999, 0x7425e947, - 0xea45b459, 0x7f239e43, 0xf7df146c, 0x713c71bb, 0x278c3f88, 0xa21c706d, - 0x31d1c799, 0xf5f2023f, 0x7f231766, 0xc7de3cba, 0xea5075e4, 0x861ecc1b, - 0xb7ab40f2, 0x68a7a84b, 0x613ef9c3, 0x4e5869b0, 0xf7c8bf08, 0xfbe8e947, - 0x34cd724f, 0xd7231aaf, 0x5afce7cb, 0x7a4fe908, 0x4fe29475, 0xc3674d0a, - 0x0d3cc9d1, 0xf0a7473f, 0x9e9302e1, 0x302df7ce, 0x0fd14ad9, 0xef0800b2, - 0xfa8098b3, 0xf7e22db7, 0x0dbb4581, 0x5337e7e9, 0x6ff9ff6e, 0xb9f9ba18, - 0x43353e7c, 0x4ee3f747, 0x8f61cc09, 0xd57e7a19, 0x869e8ce9, 0x66bb9a6e, - 0xec87599d, 0xeff2e2f7, 0x867b6115, 0x167553e3, 0x779fec89, 0xa85ca146, - 0x0f1f5b4e, 0x42caa2f0, 0x94dfdd1d, 0x08ee44e3, 0xd19fc72e, 0xa28e4eba, - 0x51e7d178, 0x624748a5, 0xa3e22a7f, 0xea0289c4, 0x9e2a37bd, 0xd7e1cdea, - 0x18dea0c5, 0x7f67d394, 0x1eb462ef, 0x127a50b6, 0x302c4fda, 0x07cb236e, - 0xf302a3b4, 0x01627ed1, 0x2f2c27eb, 0x9085f6b6, 0x609a4a17, 0x0d5292db, - 0xd0909e7c, 0xff92a942, 0xee5b43ac, 0x57aeb10f, 0xc6fd75e5, 0x601b4c76, - 0x8ed0713b, 0x2ae5fb01, 0xd517dbce, 0x61e32ca7, 0x17657548, 0xe9b18ec9, - 0x88933e15, 0x1e6106bf, 0x45fb04af, 0xd5b0de75, 0xfba14beb, 0x6d38f2fe, - 0xa346d62b, 0x1c55031d, 0xbcdb9f48, 0x9965296d, 0xcec8e383, 0x8d13e991, - 0x17a889b6, 0x5c725ff3, 0x97f40ccb, 0x74349b24, 0x5326013e, 0x6e612f75, - 0x38b4f459, 0xccdd4534, 0x2ed0926e, 0x3f3d25ef, 0xf896bae1, 0x62f0e120, - 0xa4ab7186, 0xef0176b8, 0x23f40d03, 0x97ae6fdf, 0x5c57b9e3, 0x048e3465, - 0xcefec0eb, 0xf38d0ec8, 0x747945cd, 0x518e69e5, 0xe5d58fc2, 0xdcfc71c9, - 0xe1d5fdc2, 0x3ae8097e, 0x4057b6a9, 0x380c0138, 0x5c27c5f4, 0x426b4c6f, - 0x045af279, 0x6db58bf9, 0xf207cc99, 0x45745527, 0xfb3ce0e5, 0xc9a6ffa5, - 0xdf0b0790, 0x9c207cad, 0xa136b3f4, 0x25d90665, 0x285869f7, 0x1c98cf3f, - 0xc828c7ee, 0x609ffce1, 0x1ea94d6b, 0x44d3e987, 0xcf975f37, 0x1db39067, - 0x9f11d9f4, 0x1c58fa2d, 0x759a7bd4, 0x9b73e9a1, 0x7ec0efdc, 0x185fcf21, - 0x7f911973, 0x3b9382b5, 0xdbeef739, 0xce82cfb7, 0x55e74613, 0x8d7ac936, - 0x4e444ed2, 0xd846153b, 0x45cf0c1d, 0xdf07660a, 0x9b3ecc07, 0xf9abd60f, - 0x7b486d2b, 0x791cc1eb, 0xb26b491f, 0x4cb2fd61, 0x94fd0dbb, 0x1a55f7c1, - 0x70da26d3, 0x0c671a7d, 0x7031a9d0, 0xcb4ee85f, 0x53cf1f7e, 0x2c747a99, - 0x70591cf0, 0x2173c7aa, 0x972837b1, 0x1d3797cf, 0x9b42e7e2, 0x78bd454c, - 0x14c9a10e, 0xfec74457, 0xa99cfc4c, 0x3a64df52, 0x64def246, 0x1356f1e7, - 0xa2020fee, 0x3ba1e7c7, 0x83cd18ed, 0x0e5a6f52, 0x7b26ab97, 0x5bfbc317, - 0xd53f76e1, 0x3e9d130b, 0x161fe00d, 0x4ffee8c7, 0x55f39198, 0x318fac04, - 0x7e95ef80, 0xd1d1cb6f, 0x172535bc, 0x7e1096f5, 0x6704de22, 0x1b22b64d, - 0xdf38dbed, 0xb4636fd0, 0xaf9cdf42, 0x5be7971f, 0x3e51a769, 0x434f7aff, - 0x58b2fcce, 0xd73913f4, 0xa6bb60e4, 0x83b446e5, 0x6fe391b4, 0x6186ded8, - 0x285e6bdb, 0xf238f7b7, 0xc8b23685, 0x50e9ed8c, 0xc3a0845e, 0xfe76e467, - 0x30ede357, 0x97df74b3, 0x9f305a60, 0xa3de942d, 0xa38c46a4, 0xddfa1b8f, - 0xebbf9637, 0x90247ed4, 0xfc717bbf, 0x1ecf932b, 0xee1ca12b, 0xdb2eda3f, - 0x619d8a27, 0x2ededb91, 0x3ee87bf0, 0xef4edc21, 0x8776c836, 0x0f3d4c25, - 0xf941f783, 0xe0ae5c3a, 0xc72ee6e7, 0x046b8a31, 0x77e5f3f3, 0xb40e8a3e, - 0x73ef504f, 0x04bb7364, 0x1c4bb453, 0x610d9fb2, 0x9da01bf4, 0x80fdf0a2, - 0xfa42b75f, 0x3f005ba7, 0x0d6fc803, 0x7b242bb4, 0xc90dbe88, 0xe7c8697d, - 0x053bf2a9, 0x5cd7f643, 0x4785a72e, 0xfe434b3f, 0x4feb8b2e, 0xf982efc0, - 0xae4785fc, 0x5e78e026, 0xce703198, 0xab43e286, 0x7bf3a717, 0x1cffc7d9, - 0xfed10aed, 0x457feecd, 0x86b4dd9d, 0x5ce5c0f4, 0xdf5bfc0f, 0x8cbedb07, - 0x821d9deb, 0xcda4efda, 0x5fe77ae5, 0x7acc7de4, 0x2df7a455, 0x2eb965ce, - 0x0ab61f20, 0x7f28e5e6, 0xe7e11f53, 0x5e3f56e6, 0x2103d9ff, 0xed1841f8, - 0x804e73fa, 0xacdc5c3d, 0xa35a3f27, 0x8dc47d29, 0xafc31ce2, 0x71cb87b3, - 0x1e4b7d79, 0x24f3f235, 0x5b17ae2e, 0x39d3f75c, 0x23f3e095, 0x243bd5c3, - 0xbea53dcb, 0x7947db01, 0xfe479a62, 0x23684b80, 0x964dbfa0, 0x7678c17b, - 0xf3c864e2, 0x12b90463, 0x18456875, 0xed93abb6, 0x3f8aedb1, 0xe8c8a2a3, - 0xb75ef808, 0x1a58c8b8, 0x8c8d2f40, 0x6e0ddf9f, 0x01dcceff, 0xafa55a7d, - 0x459f70e8, 0xf89c50df, 0x433901a7, 0xcab8658a, 0x0ffa518e, 0x70163f3e, - 0xf38c2c5e, 0x5a67b729, 0xe818dcf1, 0x962b6bb7, 0x6df9c48f, 0x582f5d15, - 0x3ffa1e61, 0xe739d030, 0xecbe650f, 0xb872f993, 0x43b1f3f5, 0xf6318ca0, - 0x97823b04, 0xc64e80d6, 0x68fe408f, 0xfb94d4cc, 0x5cb38c43, 0xfd08671e, - 0xafdcd6fa, 0xe6975fa7, 0x51afd086, 0xc504767f, 0xd461021f, 0xf4211d9b, - 0xec8213eb, 0xedcf900f, 0x1d49d09c, 0x270f307d, 0x6f611d6e, 0x919ee894, - 0xf6045ec3, 0x32678bc3, 0x239f6f51, 0x23c7bc0c, 0x608c31db, 0x221623b0, - 0x6799735e, 0xc50203df, 0x48ee5a51, 0x5c04eea3, 0xa7ad9b8f, 0x3711fb24, - 0xdc613ac2, 0xb2daf5a1, 0x0ce2a119, 0x274038ff, 0xef02ba28, 0x042ac007, - 0xc48695c4, 0x63e282cb, 0x38194e18, 0x5a1dabff, 0x7562aeff, 0x35e36afc, - 0xac30bfee, 0x0427fe60, 0x2eaa1f3c, 0x0bae5f9f, 0xe2a9cf8e, 0xba9d0b5a, - 0x887c7c60, 0x6f8cb26f, 0x2907b6ca, 0x452d3e0e, 0x64acfde4, 0xc707cf64, - 0xbd850cbd, 0xc3ea2d0e, 0xf7f48c15, 0x9e363f60, 0x5eff2517, 0x09cf6305, - 0x7d5ade74, 0x59e9e4df, 0x1cfbf8e7, 0x8fd8e52d, 0x50c3532d, 0xafbe0e3f, - 0xf09bc4a0, 0x7de04c98, 0x22dde569, 0xe10d62cb, 0x53b77cc7, 0x8797e2b9, - 0x4b12a6fa, 0x55eeb9c0, 0xdd3ea06c, 0x1e85f2a3, 0x59d6d6f7, 0x1c4fef14, - 0x82ec29ef, 0xa33b24a2, 0x66aa4879, 0x3cc00764, 0x86fae2a8, 0xce345d94, - 0xc58c354b, 0xaaa038f2, 0x7076013c, 0xbf184fa4, 0xe30fce2a, 0x76c1c154, - 0x4deccde7, 0x0de64a43, 0xfccdf9e5, 0x5e39068d, 0x646e46f8, 0x633be91c, - 0x77d418d8, 0xa69f8b2c, 0xeb04b8f5, 0x34597e81, 0x03c54284, 0x68fb4337, - 0x5f90ba07, 0xc4dfd1e2, 0x30caef54, 0xc9f74887, 0xb38e6284, 0xf1e4eb10, - 0xfc467ce1, 0x9507086d, 0x9859f80b, 0xbce0706c, 0xc3000c1b, 0x333d0590, - 0x56be4026, 0x15af37f6, 0x33308898, 0x4fdc8ddb, 0xe36bbca8, 0x866d77a7, - 0xff7407eb, 0xcfec30be, 0xfa53bfc7, 0xdb8ef219, 0xfb27be0d, 0x7dfc1ccd, - 0x951df919, 0xff9b87fe, 0xfb6ddee1, 0x2777d4c3, 0x3267bf70, 0x20e56bd1, - 0x4cbc12bd, 0x1efc47a6, 0x4abdc2e5, 0x0c77adb1, 0xfb3c37de, 0xfd1d8470, - 0xf0e303e0, 0xefe5a9dd, 0xed75fdd1, 0x9361e00d, 0x8c0fbe48, 0xafef6e4b, - 0x02fd171d, 0xbc06dae4, 0x4fe78434, 0x279d192a, 0xcf4ab8b0, 0x000e7489, - 0x1392a0c6, 0x4013ef01, 0xf10e1b7b, 0xf15baf73, 0xb0710b9d, 0xd02bd45f, - 0x4255b06e, 0x483b087e, 0xbf19ab49, 0xd5e0ac1f, 0x1a3d07a8, 0xf5c352e9, - 0x3ea6d9e8, 0xe935cf11, 0xe445fae2, 0x2e68e71f, 0x37e807c7, 0x0bf9d19e, - 0xce7c926d, 0xdfc4a471, 0xfbe4cb4d, 0x84cfd29b, 0xfe591ad1, 0x47fbd2f7, - 0xd54e23b3, 0xf2c6764b, 0x442fc5f6, 0x11ecfcff, 0x00d3eaa7, 0xe167d82e, - 0x2ba9d270, 0xecc66669, 0xd10bacfb, 0xef3b3f9f, 0x807495d4, 0x78d9f68b, - 0x464614f9, 0x097df8ce, 0x319fd10b, 0xd559b461, 0xd7385bfe, 0xd53cdff1, - 0xcf21341a, 0x5a36df63, 0xe8c94f39, 0xf3b3ad3e, 0x2e31a797, 0x47f654e9, - 0xdf482e87, 0xde0b2281, 0x717f9323, 0x9d0f1451, 0x9dd9d329, 0x1452eef8, - 0x68bb2dfa, 0xfa0d477e, 0x6bfe9fe9, 0x4382f4fc, 0xccca9779, 0x1bff812a, - 0x2c2b981b, 0x99ee8023, 0x9f9d7343, 0x81b8a603, 0xffd28f82, 0x6960bc10, - 0xbc4098c5, 0x0a3b51b6, 0x0d0a175e, 0xc70587a4, 0xfd082e87, 0x549cf1db, - 0x2fd6cfc4, 0x10ba75c2, 0x002a9fd9, 0x9eb79e1c, 0x7c42edd6, 0x1ec176ff, - 0x3af8eb00, 0xa22bef56, 0xd6a3fc75, 0x027a3d51, 0xdfc5dbbe, 0xe396686f, - 0xbbc64f50, 0x019f687c, 0x32b9d1dd, 0xfc9e8a5f, 0x05e36548, 0xb03fa047, - 0xcbf7346e, 0x69d3925c, 0x49cf1686, 0x01f74ba0, 0xfa85ad81, 0xf5976bee, - 0xeecc9fa8, 0x3d47a33c, 0x19c0eeba, 0xad4bde3d, 0xa9da1843, 0x8477a6db, - 0x32feffd2, 0x97f2ab5a, 0xd1d77629, 0xe8f5ec94, 0x16abab77, 0xeade1ee8, - 0x6e1fb9d7, 0x251c32f5, 0xb2df7763, 0x55b8fc9f, 0x98f5eece, 0x477d652e, - 0xc588ddf1, 0xdceaad2e, 0x089a92c0, 0xcabe3c55, 0x9782ab13, 0xc0eac0b6, - 0x21b4bb3e, 0xc31df549, 0xef82cf5d, 0xd0fe0e28, 0xd790affe, 0x736db171, - 0x16bbfa2f, 0xcc7ad4bb, 0x62b5ceec, 0x11ede20c, 0xfece1aec, 0x84b77e12, - 0x00d2108f, 0x7de60abd, 0xa3d7075a, 0x648c2aea, 0x0c22549f, 0xab595af3, - 0x7393e3f5, 0x54f45347, 0xa810eeee, 0xbb972ddc, 0x576e046b, 0xa975f2cb, - 0x8392e38c, 0x75d1a727, 0x37a39f52, 0xa5df0033, 0x88e7e515, 0x437d651e, - 0xc4855719, 0x290d8df5, 0xddb0e9ef, 0x5817dfa5, 0x4b8d1a6c, 0xa92d47a5, - 0x1e55c351, 0xd59e905d, 0xbdf943a7, 0xff9d41b4, 0xbef2d1f3, 0x90f2c79e, - 0x2d18de9f, 0x07189f88, 0xbca53fe1, 0x81ef0277, 0x0f3ad25d, 0xead67d22, - 0xdf700abb, 0x1175a4bb, 0x7e4394ac, 0xb8afdf1d, 0xce01a2be, 0x751befc3, - 0xa7de330e, 0x8814adf5, 0x00b0976e, 0xb06d27bd, 0xa1dac13e, 0x7722bf70, - 0xe4f59cc3, 0x98283d0f, 0x13286f51, 0x83de221d, 0x8fc61c6f, 0x83e6517e, - 0x1f2fac13, 0x2246caf1, 0x9eca7585, 0x99f6823f, 0xf996b7ec, 0x3d948e30, - 0xc4bf204e, 0x4371809d, 0xc922a611, 0x37b03991, 0xad9a4184, 0xf920af6d, - 0xe66f563e, 0x58da62ef, 0xfc70bca0, 0xbe701333, 0x0bb27510, 0xfde87b93, - 0x9b6d39bd, 0xcc5ca22f, 0x3d1470cc, 0x193df805, 0xf27ffbc6, 0x16bfc175, - 0x3fcba9da, 0x0ad3f246, 0xd6fd81e4, 0xda3964d9, 0x5acff6a1, 0xc121ae51, - 0x7ea7cacc, 0x32f89413, 0xc3ed15d0, 0x9fa4a55d, 0x9f7ee558, 0xddb8942d, - 0x2e7ca0fc, 0xe2d6f98d, 0xd1befaf9, 0xf495f28c, 0xcaabfb1b, 0x5e283104, - 0xe61a3750, 0x4fada579, 0x5be9de75, 0xe901bf6c, 0x187db82c, 0x395e2abe, - 0x8a2d7b4d, 0xcc1d77ee, 0xfee8deb0, 0x3ea8d694, 0x8733a4b7, 0x53bbdd07, - 0xf6d99fcb, 0x777ba0a4, 0xeef74119, 0xddee82f2, 0x2df9efa9, 0xba094e74, - 0xe7bea777, 0x54cdb067, 0xe6930fd5, 0x9c88e0a9, 0x23f555bb, 0xe7d5cbed, - 0xbcff8eae, 0x77c74842, 0x2e7d7d06, 0xe0668798, 0xc198e28d, 0x0a2f247d, - 0x3e1a432a, 0x6984cc2e, 0x0ba1a173, 0x9139a4e9, 0xe386e7db, 0xa0badb0f, - 0x9788e31d, 0xfc6fe88c, 0x452fe089, 0x9f28c4fb, 0x18fd1953, 0xaf33ed53, - 0x52be7015, 0x5cf2dbd2, 0x7d61f3b3, 0x494af7f2, 0xdee01dfc, 0x463eb8d1, - 0xf9036c7c, 0xaf7e55e6, 0x476cac78, 0x5f3ced28, 0x0f353258, 0xcc7fcfbe, - 0xece28331, 0xf07efc1d, 0xa78f3d4e, 0xe7e55ef8, 0xfa3bf35b, 0xfe008e34, - 0xf5c7993e, 0xa59c6790, 0xeba91f14, 0xf9165d84, 0x1eaceda9, 0x75d465ef, - 0x7ee14776, 0xab3ce056, 0x60c9bf47, 0x89cfbcbe, 0xaf68e1fd, 0x743dacff, - 0x9e6d6d3c, 0x98e3f89e, 0x1eabd72c, 0x91bb72d6, 0xb9e16639, 0x575e4571, - 0xabe3e7ed, 0xe7e7a85a, 0x1d1a3160, 0x9c836e42, 0xc396ab3e, 0x707ef50e, - 0xca3d7f8b, 0xaadf900e, 0x4c174b7a, 0x12b7bb27, 0x31f236e4, 0x797573c8, - 0x17c91372, 0x7caae790, 0x3c80de77, 0xdf0ebfcf, 0x426a769d, 0x8170f38e, - 0xda78f348, 0xffe69535, 0xf4479819, 0x64333da7, 0xde7cf8de, 0xc65ebe6c, - 0xb7580fb5, 0x2ebf7ae0, 0xf2f6ebe0, 0x7dfaf230, 0x0a775d79, 0x4c2845bd, - 0xa270cedd, 0x634625db, 0x387b9e09, 0x1365f296, 0x7eaae1c6, 0xfd3dd02e, - 0x6e3eeb7f, 0xbf5ffd41, 0xfd05a8ff, 0xa3f6ee61, 0x594db016, 0x8b5a4ead, - 0x85d03c7a, 0xba9ef51d, 0x7fc22e8e, 0x6eb8fb65, 0x21d95fcc, 0xee3dfbd0, - 0xd3a71703, 0x135f5938, 0x0e770bc6, 0xf28fd783, 0x37befeb8, 0x307ee24f, - 0xfb89f417, 0xdf8301fd, 0x801d202f, 0x5ebc425c, 0x35e5f017, 0xb1a373b6, - 0xf51e9422, 0x1f7cf26f, 0xe867a8d9, 0xef85afaf, 0x52c71c71, 0x488de98e, - 0xb205fb47, 0x27edddb5, 0xfb604617, 0xfa863af5, 0x17df8285, 0xe21fbd29, - 0xd6a83ff8, 0x3580a7a1, 0xbe696b56, 0x52d7a83f, 0x74fbda3b, 0xc15e2f04, - 0xae1c55cf, 0x0929a8fe, 0x56a0fdda, 0x530c7ba0, 0x31f3fbef, 0xe0af1784, - 0x3d305afa, 0x4c1af42b, 0x3bf4c19f, 0xbe6b4e84, 0xc91e9d19, 0xe4d5ef93, - 0xe7dc02b1, 0x59a7dd61, 0xe11e7e91, 0xae2be3f7, 0x7fa1d61d, 0x6cc9bd33, - 0x31e0027f, 0x0b7aff5a, 0xbcc389ca, 0x8776b0bc, 0x748de5c0, 0x5261f237, - 0xbda19eb3, 0x971e7efb, 0x7ae3ef4b, 0xfad0e3c5, 0x31af8c05, 0xe51d37b1, - 0x4f1c9a52, 0x2ac7457a, 0x905c53f6, 0xaf319bcb, 0x96ef54d9, 0xbd71e537, - 0x40839143, 0xe4fdaee6, 0xc44f6d97, 0xcb2f147b, 0xe55341e7, 0xfa32b2f6, - 0xf485cfa7, 0x672f4caa, 0xf8143c64, 0x6cff4cb2, 0x1f68cfdb, 0x59c72d9f, - 0xd1743666, 0x833ccc79, 0x879453eb, 0xabdf52b3, 0x39ae7dc5, 0x3a7cedfd, - 0x25378d67, 0xc9fbe226, 0xd27877fc, 0x60d6dba7, 0x9c372fdc, 0xe0ec31d6, - 0x381e7453, 0x35bc6b2c, 0x49439c54, 0x7a2557dd, 0x6aeeb08f, 0x3c0aa53a, - 0x7d39d0f7, 0x1701d91f, 0x5c9f13a7, 0x2ddea9b5, 0x7bc654fc, 0x5d3ef28c, - 0x80f3f727, 0x8b8b169c, 0xf329eb06, 0x1c659e80, 0x2ed6586f, 0xab35af5a, - 0x75a92158, 0xcefe29ec, 0x0149ed66, 0xa458bddf, 0x304ce873, 0x608defdf, - 0xfc8b1f25, 0x3657241d, 0x748c4dc6, 0xd784fb2f, 0xd7af704c, 0xaf29f046, - 0x61ade944, 0x687c88ce, 0x4f11e167, 0xe1dbce16, 0xde275694, 0x8ef0bc57, - 0x336ba64e, 0xd32e2fbf, 0x2d4ee5da, 0xeb9c6233, 0xc2e3e800, 0x5cf7fe20, - 0xddfba44d, 0xa0fec3bf, 0xbf0d959f, 0xaf677921, 0xed1d38b9, 0x33dac2a2, - 0x1bbb084d, 0xf51d3cfe, 0xff610f89, 0xf41ebd20, 0x72809b7b, 0xd3bd24e4, - 0x8635795d, 0xd35979da, 0xcbf91d3f, 0xf740a6f7, 0xb8ec3e6f, 0xfdf2b7a8, - 0x7873dc89, 0xf2fd1c2f, 0xb9a3f2b3, 0xd42ce91c, 0x243afad0, 0xddeb3bd5, - 0x0a2bffa3, 0x20d8c3d7, 0x7e0a7afd, 0xc865a3df, 0xfb4a9bbf, 0xe421cca3, - 0xdff469ef, 0xb071f365, 0x15e5a1ec, 0x9e165f7a, 0xe990ac93, 0x3cbcb838, - 0xa13fc07f, 0xebefca73, 0xa1fe0108, 0x3fdfc62a, 0x2ba7bb05, 0xaab8f81c, - 0x67f92a73, 0x0dc23caa, 0xd1c333fd, 0xeb4dd7e1, 0x28cff718, 0x818dda30, - 0x1bb44d7e, 0x1f7faa99, 0x252b077f, 0x74f786f3, 0x14897ddc, 0x666bafcf, - 0x795aef14, 0xe7a53475, 0x2120df5f, 0xfbc318ff, 0x6b7ee95b, 0x8cec86b6, - 0xfeb53e95, 0xcb80a533, 0x7c052985, 0x60f95cde, 0x01b0e52f, 0xa2ec097b, - 0x5db9f37b, 0xa9887514, 0x7ce0a5ec, 0xf28c97b2, 0x13101d3d, 0xe04257ae, - 0x6941477d, 0xca977e0d, 0xd9ce885a, 0x72fefc3b, 0xe4d738f0, 0xf8553e73, - 0x35f2317a, 0xe7076fd2, 0xe776e0eb, 0x41ac9415, 0x4c38da3e, 0xe65cab7c, - 0x8c6d95fb, 0x16ddcbe6, 0x05f4f343, 0x0296736b, 0x78017e5d, 0x0bd23de0, - 0x3444674e, 0xe5c17f7c, 0x3df3c08c, 0x6ba81c8a, 0x36efa70b, 0xc58bce66, - 0x48cda373, 0xf9ded0f7, 0x9c46a98e, 0x38da7be7, 0x7dfd29ff, 0x1638b5d8, - 0xae8269f9, 0xf2876f5f, 0x5133cee4, 0x784df7a8, 0xf22c7e7d, 0xfe7870e1, - 0xcf1918fd, 0x1e12c486, 0x70bd8797, 0x004f6ca2, 0xba27ee7e, 0x87fa9de8, - 0x6fd1181a, 0x56ffabf7, 0xbe7c7c87, 0xfb8cc233, 0x230717e6, 0x0bcabde8, - 0x3de81a6f, 0x7df95a9a, 0x7d742fd5, 0x7cbf4873, 0x22f74b5d, 0x47fe6fdd, - 0xfba3f22b, 0x3b9d0355, 0xc373a87c, 0x6af7dc45, 0xc39c673b, 0x5f6b5677, - 0xc3f2dbfa, 0xd25486ca, 0x3ff8148b, 0xbe2746bc, 0xe45e7bf3, 0x8ea1e272, - 0xf77d217f, 0x0b976ba1, 0x17ca7cf0, 0x44c7ff07, 0xb7ee6b94, 0x79444f2e, - 0xe5c5fee6, 0x7eee5889, 0x4a13c22d, 0xc05eb95f, 0x7eca3efd, 0xa8aef699, - 0x90ad0ff2, 0x5d6d23e9, 0x3d07bd0b, 0x7b02e4e1, 0x130fbbe0, 0xac4e34b2, - 0x65b7e13f, 0x7c05f7b1, 0xa457aeb7, 0x93f8e338, 0x01d51165, 0x814f7974, - 0x7e2ff14e, 0x930ebf23, 0xf019c7df, 0x77f2f4e3, 0x8af6367f, 0x1aa37dfc, - 0x83a1ee81, 0x5ee432fe, 0x8affad1a, 0x88df7a58, 0xc73bce89, 0x8b38478c, - 0x3e6205de, 0x00ccd1e3, 0xaf71693d, 0x7400cba6, 0xe869d154, 0x57befd22, - 0xacb0433c, 0xf173dd3f, 0x2134c8d3, 0xe7267f84, 0xe39434d4, 0xf81a7ec1, - 0x8ade2245, 0x71e955be, 0xc1fe20a5, 0x15a59bfe, 0x287f9077, 0xd6937fd8, - 0x8f666a2b, 0xe9dff7c7, 0xf78c2f3a, 0x8bf22369, 0xfae287a2, 0xffc1081d, - 0x3970c66b, 0xbad5f0a6, 0x5dff1e5e, 0xcc6a5bd7, 0xe656b484, 0x9db003ab, - 0x75fda0fa, 0xa377f39d, 0xb5dd611f, 0x60631145, 0x3bbdd6be, 0xfc813d8f, - 0x66352e6f, 0xeed777e1, 0x1fcc2e30, 0xfee097a4, 0xf2e18ca6, 0x184f4072, - 0x97cbdf66, 0xed5bfaf1, 0xe463397f, 0x87ff6cf3, 0x87607fef, 0xedc31d8f, - 0x4fdc25f0, 0xe0f0edc2, 0xc791437d, 0x792ebb4a, 0x63ca879d, 0xc04877fe, - 0xec79265e, 0xbd51231a, 0xb1b9cee4, 0xbbbf4764, 0x0d325620, 0xb4433f6d, - 0x87f2626b, 0x71e8afb6, 0xa8e39f6e, 0x871ced11, 0x1749fb96, 0x99bef408, - 0x9db9f7a2, 0xeee3e902, 0xeb1f9d4a, 0x2ef57829, 0x85d57ee0, 0x4c3f9d0e, - 0x150fd418, 0xdca071fd, 0xa2b9502e, 0x637a2a4f, 0x71fb93af, 0xe5e78c17, - 0x16b986b7, 0xd87d7ce1, 0x13f94615, 0xc67cf126, 0x0093479c, 0x813df45e, - 0xfacbff11, 0xc1a742a4, 0xcea5e6fa, 0xd7be1b8c, 0x4fa64db3, 0x8352cf85, - 0xbfd943f8, 0xdd39f39a, 0x1dfee1d7, 0x7ff7fb8b, 0xe0f2f4aa, 0x7eff6176, - 0x466ff108, 0x1fbe121d, 0x19d15bff, 0x4aff3eca, 0x5efe0bd6, 0x23debf59, - 0x72af8825, 0x7db8764e, 0x6fd64eb5, 0xce6f2b86, 0xbcfc7aff, 0xdfdf1e47, - 0x8e779f8a, 0x9f43bff9, 0xf50bd01d, 0x4779c7a1, 0xc64fc941, 0x6b86bcc0, - 0x739e743d, 0x1ecdf7b8, 0xb055f595, 0x7c745573, 0x41af4534, 0xc35dc8bb, - 0xd1cd03fd, 0x7ec9afd2, 0xf7a5ae39, 0xef921e57, 0xd5783e73, 0xea2d694c, - 0xd92e90c9, 0xd9de927b, 0xc6a3525d, 0xb77d19bf, 0x34aafdf8, 0xb157eb8a, - 0x552bf232, 0xf19b4675, 0x7c737fbc, 0x2be431fb, 0xb4ad6edf, 0xc6feb03b, - 0x237d72d1, 0x44d5b7f7, 0x618fdfd3, 0x95407a41, 0x57df5827, 0x645305eb, - 0xfa70d13f, 0xc3ba2fc1, 0xd1e95cb8, 0x39d79f12, 0xd055dff9, 0xe0b97277, - 0xbf23086e, 0x886bda09, 0x820d67d7, 0x5f3ddf1f, 0x4cfbd729, 0x13ff25ec, - 0xcaa0d3c5, 0x2ca7ceb9, 0xd4dfb20e, 0xbb95a3f1, 0x33724b7e, 0x73148e38, - 0x0d0b8e40, 0xd2268dc4, 0x60959079, 0xbc9fe24f, 0x5dd24b72, 0x1f80ff38, - 0x71dc93f3, 0x9730fca8, 0xfb223e7a, 0x3cebc973, 0x7e2433fe, 0xc7933cd4, - 0x95ddf08f, 0xa5c87e10, 0xc51d8f23, 0xb374a3bf, 0xc75d51b8, 0x3247ba49, - 0xd208ff44, 0x518dae3b, 0x8a4719fb, 0xb23b8fdc, 0x7fa33053, 0x8f3ca46a, - 0x9c31b77f, 0x7fe9eaf4, 0x79458ea8, 0xf9d3aca0, 0xcf5e7cb9, 0x04a5707f, - 0x07f89bbf, 0xe3061cd1, 0xf507c5fa, 0xb0e249bf, 0xbbf09464, 0x63b408fa, - 0x7561ffce, 0x2febce04, 0x2fbfc520, 0x3169daf1, 0x2bd23fa4, 0x0fd82dcb, - 0xbfc80ba3, 0x45a5fb2c, 0x07230fd8, 0xdfc139fd, 0x6bbf976d, 0xfc853306, - 0xf8f3af98, 0x6b82737e, 0xa6cfc126, 0xa61efe33, 0xffcefc83, 0xfe8d7402, - 0x2c183ca2, 0x1a7f9fc6, 0xbc61d6ce, 0xf5de39a8, 0xb3d1f136, 0x08f9091a, - 0x9338a7be, 0xfb44bf6f, 0xc6194e23, 0xfcf40a73, 0x0cea465d, 0xbcb46bd6, - 0xc760098e, 0xb0093c62, 0xe6f18059, 0x53ae393c, 0x6c44ce10, 0x6b9d49ff, - 0xf997be13, 0x5f68b764, 0x8f604c4b, 0x83bf77c5, 0x83824be3, 0x3895c5c7, - 0x1f1f1293, 0x6024ce2e, 0xee9c053f, 0x8715b9f8, 0x25737180, 0xe7bec49e, - 0x635720a4, 0xf7ce87b1, 0x48c8533f, 0x718b7fae, 0x21f9259e, 0xc83548e2, - 0xd5cf2463, 0x394dc571, 0xfe9d10af, 0x3dc4f1b5, 0x1cb7d863, 0x13f3e2ff, - 0xe8f8f78c, 0xb7b2164b, 0x51effabe, 0x5e76cfb4, 0x42f0fda6, 0x8fbe41bf, - 0xecfdc7d0, 0x2ff23a9d, 0x2dbb005c, 0x3d9f603e, 0x3ddbcf9a, 0xe89539d4, - 0x596f40ff, 0x2f3fd604, 0x777c6fe7, 0x48d9fcc1, 0xbd22bd97, 0xe3e78b07, - 0xd03b0ed0, 0xbd404e2b, 0x975c5be5, 0xb1098fef, 0xd0f0c62e, 0xcbe44cef, - 0xc05f947c, 0x07ea63e9, 0xd772fedc, 0x598a38f3, 0x72ee0b96, 0x63c1c93d, - 0xf1411629, 0xc5435b9f, 0xa7ef5e59, 0x856aa37d, 0xbe1cf740, 0xa3a59c71, - 0x82b7de5b, 0xd3e5d3fc, 0xe70e6e49, 0x9b880eb7, 0x15b7caab, 0x23879c0c, - 0x815475ff, 0xe31dc699, 0xb3c12c29, 0xbff8ca87, 0x73b875c5, 0xfb3a086c, - 0x695fdb16, 0x9fdb6eff, 0xb6ddf792, 0x6e3be6bf, 0x77de6d7f, 0xf1dee71b, - 0xf57fe31d, 0xccff6e3b, 0xaf3f3c77, 0x73ffffe5, 0x70700300, 0x5cf83f9c, - 0xdfbc7040, 0x1f3efc70, 0x36106d96, 0x6a4177f7, 0x42b57a8c, 0x462d5100, - 0x0877a2ef, 0x71e24d66, 0x46658db0, 0xf0610eff, 0x5f32807c, 0x1db90b4b, - 0xe8bfce61, 0x4e79858b, 0xc596f475, 0x126c9fa2, 0x82fd877f, 0x132acefc, - 0x18cef4cd, 0xfbc04cd4, 0xa161cdf1, 0x7261aae3, 0x23edc37b, 0xdc9617cf, - 0xfe9e3631, 0xfbc8436c, 0xfec82f1d, 0x23077347, 0xa51324bf, 0xafd47984, - 0xd0fa8094, 0x3f3c2388, 0x76398baa, 0xda525e10, 0xa507b23c, 0x8b6fc434, - 0x998def1c, 0xfe869d99, 0x0bd018e8, 0x14f81e31, 0x8e2905c6, 0x4a7aa665, - 0xe58c1f7f, 0x31d16dfd, 0xe55bee81, 0xac4cf3f2, 0x9e2aa0f9, 0xebae8ef7, - 0xc50265e3, 0xfe2396f3, 0xe574d2bf, 0x89934cef, 0xff37e618, 0x8ce29980, - 0x48bd2627, 0x8956777f, 0xf331adef, 0x6ed1872a, 0x1cd63c06, 0xbbf4471c, - 0xf7a4d0e4, 0x7733e9f1, 0x750f68a6, 0x17f1514f, 0x1dfd969c, 0x8940bf8a, - 0xf65efd6b, 0xfe887c93, 0x221fba17, 0xab1dea51, 0x27f7b6f9, 0xfc10d8ef, - 0xfee045bf, 0xb8afdf21, 0xde9c687f, 0x6e78119e, 0xaf3cb372, 0xdc78bacb, - 0xecf7f142, 0xee33c793, 0x01976d11, 0x4d71d2f6, 0xcfb8f463, 0x094a6b8f, - 0xe1c0b4c7, 0xf07de0d7, 0x35fbd5c5, 0xa285faca, 0xb2b1d6a3, 0x9fa7a31f, - 0x12ff7ae2, 0x60ffe714, 0x30bf3f2c, 0xf1e390af, 0x0824d801, 0x1b12c9af, - 0x711c7d51, 0x2a1b598b, 0x7605549e, 0xacb9e231, 0xccade399, 0x34975577, - 0x7339fb15, 0xd309bfb4, 0xa9b49aa2, 0xbdaf6fe4, 0x9bfa84d8, 0x63e5dafb, - 0x4cbf93b7, 0x713da12f, 0xefda9f4f, 0xa5a30ab6, 0xfd2784f1, 0x0cdf5a9d, - 0x71e3ec91, 0x9fa24433, 0xb230aa98, 0x4c74635f, 0x2e78426b, 0xca8a8bd7, - 0xcc22a6e3, 0x3e934416, 0x4523d458, 0xe83f97df, 0x51998b07, 0x74f38f1f, - 0xe2aaf8b3, 0xcc35bb4f, 0xe7ae1af1, 0x5d5f1b5f, 0x74bbcef9, 0x971954ae, - 0x9c4a2f32, 0xaaf8b874, 0x5dc1ce72, 0x2e75457e, 0x4ff62dc3, 0xb8e3ff47, - 0xf2f46783, 0xfe334b39, 0xfe25611d, 0x8bf5ee3a, 0xe2557714, 0x45cf6eac, - 0x3be1abd2, 0x0e3f7e3d, 0x06213f96, 0xf1e217df, 0x9ef157d7, 0xffef1e94, - 0xd4bee999, 0xc5fdf21b, 0xe63f184e, 0xa1cde9bf, 0xa76bcbb4, 0x98b790f4, - 0x45e77752, 0x387ed78a, 0x53ef1d56, 0xb49779e2, 0xd56333ce, 0x0e0923e7, - 0xc369f78e, 0xddc6bfb9, 0x97bfa3a3, 0x48c77ee1, 0x73a4bbf2, 0xfaebdd19, - 0x246ba4f2, 0xf1875de2, 0x38ba00b6, 0xe187b0ef, 0x9de7613b, 0xb38c30f6, - 0xa73eeb8d, 0x752ff3c7, 0xfd1eaf62, 0x12718061, 0x1f744d1e, 0xf7cfc8b8, - 0xdfd09676, 0x5c69bae3, 0x136fe3ac, 0xe59ffb17, 0x00210141, 0x00002101, - 0x00088b1f, 0x00000000, 0x17b5ff00, 0x67534c5d, 0xb7b77cf4, 0x0bdf96e5, - 0x72223f2a, 0xa29862c1, 0xa740c2dc, 0xac741631, 0x4a8a5c13, 0x66b50102, - 0x2d09922e, 0xcbc2ccd9, 0x01893ad2, 0xb8b2c3dd, 0x26a9f364, 0x87b6e883, - 0x6ead93fa, 0x840b0b55, 0xc3e22e25, 0x52c9719c, 0xba33330d, 0xd8dc6281, - 0xdf39d85c, 0xd8bdb5bd, 0xa4da2cbd, 0xdf3f3d39, 0xfff9df39, 0x0730000a, - 0xb956e7da, 0xf84ce706, 0xffc6cfa5, 0x4fa43d0f, 0xbddde38c, 0x1726eb4b, - 0x3ebbf1c4, 0x036935c9, 0xce9c5df8, 0xf6002b94, 0x1c5ace87, 0xaccf1f04, - 0xedfc2176, 0x4ab5dfc2, 0xd2f7803a, 0xee202d4c, 0x96a666fd, 0xd2afdef8, - 0x4fe9027a, 0x8ed77bdb, 0x70045e97, 0x106b4196, 0xc12e55f9, 0xb8e08271, - 0x4546fac3, 0x25c06e5c, 0x80fce938, 0xe89b34ad, 0xd9a55cc7, 0xf5f4137b, - 0x00674539, 0xdaaf39e9, 0x09f489ac, 0x06a019bb, 0xc15c0ce9, 0x556bf624, - 0x7fdfdb81, 0x4a4f2ad2, 0xdbf11c7a, 0xe036cc1d, 0x3c8150de, 0xf7c71e59, - 0xfc028fd3, 0xd422666e, 0xb9e97402, 0xd77264b8, 0x3bafa8aa, 0x52816a3f, - 0x5c5b4ca2, 0xdf5e30ab, 0x12acfd4b, 0xbefcf860, 0x170568e2, 0xa0172095, - 0xe0373f4d, 0xb19c5bdc, 0x3d7fc010, 0x4698ca05, 0x4adf9113, 0x2a8e143f, - 0xa769da22, 0xb6e5785f, 0x4c27f7fc, 0xcdba11ab, 0xbdc268fe, 0xc3829dda, - 0x2eedc99a, 0x7920ce6d, 0x212fce31, 0xb74bd3a5, 0x51cc22ad, 0xf413e428, - 0x025ac217, 0x36ada8d2, 0x0406ef6e, 0x7ca1b07e, 0xa488539b, 0x70d69da0, - 0x6f50044a, 0xdf045395, 0xcd7b088b, 0x7c461281, 0x2be726f1, 0xbf11366f, - 0x042aae4f, 0xcbe7e3f4, 0x09417916, 0x3464dfbf, 0xf3aa8e21, 0x3c52fed3, - 0x953176af, 0x34ef6adc, 0x4193f1f2, 0xe3d6ee7e, 0xfc3433b2, 0x5ff72172, - 0xcb9e0136, 0x8e38031d, 0x18f67776, 0x756eedcf, 0x3f7461de, 0x337fa0f8, - 0x904d81ca, 0x6bde8907, 0x3b3aa394, 0x001ff18d, 0x43d62670, 0x0d41d537, - 0xe7e1c641, 0x45d513e8, 0x582a0615, 0xbf373f11, 0xf974467e, 0xf062faf9, - 0x5117f10c, 0xd80d567d, 0x024dbf28, 0xf5e10194, 0x9f412d92, 0x9eb9155f, - 0xfc01650f, 0xde17d728, 0x7e30c83e, 0x915f8f7d, 0x4a6e505a, 0xd2ca97ae, - 0x32f7b8e3, 0x401653d6, 0x036cf0f5, 0x9858fbc5, 0x794d1581, 0x28bef1f3, - 0x6eb17d57, 0xbc4ead9c, 0x31dfe6a7, 0x3a44f9cc, 0x0d9a81d5, 0x61205f9a, - 0x5817fcbc, 0x55ed1060, 0x491c3d35, 0xb2b9f8a3, 0xec8532d5, 0x23a50ed8, - 0x6b126dee, 0x3c2ee118, 0x160ef840, 0xf6e7f090, 0x005b9d2b, 0xd8b754ed, - 0x5bdc52af, 0x15aacc3a, 0x40dade88, 0x50596bf4, 0xff122937, 0xc4a97bc4, - 0x55aa672f, 0x9eb3be21, 0x445f8df8, 0xade7aa44, 0x7865a514, 0x8d28cbb7, - 0xeac1b37d, 0x551f500e, 0xf411a337, 0x3587476f, 0x84b5fe40, 0xce90cd9b, - 0xbea041eb, 0xedcf5b7b, 0x328f45b7, 0x099f48a3, 0x5f916757, 0x16d3cc0b, - 0xea356115, 0x7841c82e, 0xb005bee1, 0xb4e2bc1f, 0x73b94645, 0x05ac4c3e, - 0xc49f4be0, 0x8327c861, 0xd7c03963, 0xc30e7cbe, 0x2fd3853e, 0x8c39cafa, - 0x470e54f8, 0xa8356b7c, 0x959e3cca, 0xdd02fbe1, 0x7059a727, 0x7e6f9b25, - 0xf9623ebd, 0x29ef0baa, 0xba3e7ba6, 0x93962eea, 0x5a20c7c8, 0x6ad6142c, - 0x6730c9fd, 0x06c3e75e, 0xe881e3b2, 0x60a73a61, 0x460d61be, 0xef308421, - 0xaa6febbf, 0xd96f9b52, 0xf193b802, 0x04faf467, 0x3cd02287, 0xfad24b7a, - 0x5fc5787f, 0x48529e3c, 0xf31eb2b9, 0x413719e6, 0xd48fd20a, 0xbe7f736b, - 0x4f18eb9e, 0xc0ddb8c0, 0xcf9c1278, 0xcbf8b56f, 0x74ad1f28, 0xa7e7248f, - 0x0ac4faf4, 0xb432bb30, 0x4fbc329c, 0x600e6c47, 0x8f30b220, 0x4916211d, - 0x19df3ec5, 0x244774de, 0x96e0c3d8, 0xd73c7e71, 0x46e6d87d, 0xb6f389a5, - 0xf9268d33, 0xd54a5c13, 0x34592ce2, 0xf6d56fd8, 0x8b5d935a, 0xb56e0c73, - 0x9471756b, 0xfbeb059a, 0x381679e8, 0xa9e7fd88, 0x734ebb18, 0xd001cf2c, - 0x93c7c38b, 0xd1311e9f, 0xef990f3c, 0xd8e3993d, 0x0c8a791f, 0x3794391d, - 0x41f6260c, 0x24077e81, 0x63946dc0, 0x6e611c91, 0x192dca25, 0x9f7d259f, - 0x2f6e15d8, 0x01905777, 0xfe0450ba, 0x465f3483, 0x1a77502d, 0x639d77ed, - 0x3bfa9070, 0xf70502e0, 0x1bf1e8fd, 0xdd214f87, 0xb4c98e73, 0x5783ba8e, - 0x16ef9ef9, 0x78ff7827, 0xbc2d77c2, 0x3537831e, 0x0239887a, 0x403af249, - 0x6eed1dfb, 0x6e687f46, 0x05301f74, 0xc36ed052, 0xbdafad39, 0x41404b0e, - 0x1de8ac7c, 0xe79df091, 0x1cd1e419, 0xa5162653, 0x1980ff11, 0xafdc2502, - 0xfd84baa6, 0xfc855f84, 0xd8cfed8e, 0xf4c0f1fe, 0x6bd52158, 0x0a235327, - 0x8cb73fdf, 0x922f05fb, 0xed2fdf1b, 0xcd3361a1, 0x0643dc1b, 0x868eddb9, - 0x713f343b, 0x4be918cf, 0xf9e7df0e, 0x53af2880, 0x7e062fdc, 0xe1633d8d, - 0x58092c6d, 0x38731509, 0xca5536cf, 0x6eaddf3c, 0x1f18dcc6, 0x91757049, - 0xc991709f, 0xc7e76f34, 0xf5aed1ab, 0x419fa341, 0xc877e62f, 0xd0c7d5a2, - 0xa3f0163a, 0x94a2237c, 0x7b8ba1f7, 0x1cfd0cfc, 0x40aa62aa, 0x8c2120f1, - 0x3e3d16c7, 0x6e1f802f, 0x70a9fc4b, 0xe01aae6c, 0x2b61ac35, 0x5ea353d6, - 0x6e01000f, 0xd4e3f9a7, 0x8e23bd08, 0x2af9839a, 0xf9f8977f, 0xe055677d, - 0xe814d4fc, 0x6bafd649, 0x6ab375ec, 0xf33dc90d, 0x7b2ed3f7, 0x47d3f792, - 0x3b2276f8, 0x244ced7b, 0x2bbe30bf, 0x15efbfa9, 0x411ccb5d, 0xb5c981f4, - 0x5975ce8f, 0xbea9ab22, 0x1cdc981f, 0xee91f18f, 0x8b82fda1, 0x91f516ef, - 0x87cf8c00, 0xcc67e523, 0xa2769794, 0x125beec7, 0xe9b8e397, 0x0aa1fc69, - 0xa1efdacf, 0xfda79aca, 0x17fa867e, 0x7f57cfab, 0x1dbcb26e, 0xa497f9a2, - 0xe7d27e7e, 0x9912c01f, 0x3893cbf7, 0x6487b683, 0xaa3c75e0, 0xa67ef5ef, - 0xc87b48fc, 0x06199dff, 0xed5cf895, 0x7ff4d0cf, 0xc18beba6, 0x9bf61d51, - 0xf6f9b935, 0xfc39f427, 0x8a71c98b, 0xa4f2bdee, 0xdf824a00, 0xa0a982ab, - 0x195df824, 0xf6e031ca, 0x7c8362c8, 0x81a978f5, 0xc2b1335f, 0xbd735fc0, - 0x14bf80ca, 0x5f90675d, 0x01bd6bff, 0xc5bd30df, 0xcff1bf20, 0xd63c066d, - 0xb95875bf, 0x4936e789, 0x0ae41baf, 0x157e8d3b, 0x2afd18f5, 0x15fa35ee, - 0x37e25bd3, 0xdfacb7fa, 0xf64e5fe8, 0xde855c83, 0x91fcffa1, 0x2060fb49, - 0x34f3c33c, 0x13029d35, 0xa8c44734, 0x66c21fb6, 0xf0a617be, 0x84a2e2ff, - 0xd7a72c3c, 0x0919da3f, 0xb9d2b32f, 0x2b369d0f, 0x512edbbd, 0xfe3e600d, - 0x2e76d705, 0x000ee017, 0x00000000 -}; - -static const u32 csem_int_table_data_e1[] = { - 0x00088b1f, 0x00000000, 0xe3e3ff00, 0x51f86066, 0xb8d3c10f, 0x72361818, - 0x0143f821, 0x684333b7, 0x0606163e, 0xc77e2001, 0x9ef0c0c8, 0x38330491, - 0x207eec10, 0x27880abb, 0x7dcf5071, 0xe52f1143, 0x5f5d9fa1, 0x153d76a0, - 0x837f7818, 0x031083b0, 0x03309b83, 0x8408b483, 0x55045fbf, 0xc10851de, - 0x99412e7e, 0xfa819f5d, 0xbbeb8d01, 0x00038031, 0x00000000 -}; - -static const u32 csem_pram_data_e1[] = { - 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c0b, 0x733ef7b5, 0x9993331e, - 0x420f264c, 0x084f0042, 0x21842a20, 0x38880840, 0x8d069009, 0x8808089a, - 0x420100ca, 0xa9113248, 0x676d5e97, 0x6ad11422, 0xa36d2d1b, 0x4101da97, - 0x180d45a3, 0x1d0340e8, 0x5abc414c, 0x5b4a0a8d, 0x3c3141b5, 0xe878490a, - 0xef5bd6c5, 0x33ef6b5e, 0x42667399, 0xfddfb6a2, 0x7f17dfbe, 0xecfb36fe, - 0x7b5ef673, 0x7b5affad, 0x231fb5ed, 0xd313c659, 0x057c8415, 0x7213d77f, - 0xf4842448, 0x0b3b4eeb, 0x108e3a68, 0xb0398e7f, 0xb4242055, 0x24edefef, - 0x4db39085, 0x267355b3, 0x98c7fb21, 0xf2d3d743, 0x80fc81b3, 0xdd4f9699, - 0xd121c479, 0x514ed57c, 0x3ed37282, 0xb1df7e2b, 0xde400851, 0xf1fd6e6b, - 0xb5df34b5, 0x699b2453, 0x376424d5, 0xda425491, 0xa9fd842d, 0x6a5f98f1, - 0x4daad965, 0xf682effb, 0x626683ca, 0x37b7dfa5, 0xafc86e89, 0x08042adc, - 0xf76aaf6d, 0x5a00ca83, 0xd080b2df, 0x7e695568, 0x1a8a63eb, 0xfb03c84f, - 0xb368ecfe, 0x67da7213, 0xfd82aa21, 0x491c6f28, 0x7b604548, 0x7dfa00e1, - 0x65c136c5, 0x6c57f5a2, 0xf401d73c, 0xc3c93455, 0x8adf5a44, 0x47511b06, - 0x22bfb6b0, 0x07cb5ed0, 0x794eded8, 0xfe57b428, 0x110a3de5, 0x1bb29fa1, - 0x74a2abbe, 0x76b5bf40, 0xb1eafb4f, 0x559f8d3d, 0xe8f6d1cf, 0x0a2fd57b, - 0xb562e82e, 0x8e807889, 0xb9d6dd8e, 0x7fa1db4f, 0xf8f0cab5, 0xdc2c7ec8, - 0x08a8fd05, 0xed0a526c, 0x6526df40, 0xfaeec8e9, 0x87fc3456, 0xacfabe9e, - 0x72889efe, 0x47da7a63, 0x3bbc3a59, 0xbb88415f, 0xa44bd691, 0xaa3a5280, - 0x4207f9fb, 0xa1e32122, 0x96a8917e, 0xe4a9faee, 0x23fe0711, 0x0f949ff4, - 0x81f1bdfe, 0x72dd99ad, 0x9904e95b, 0xbcedcb75, 0xea51cb93, 0x5fac8dca, - 0xf20c7f4b, 0xf9d4f4a0, 0xee3e989c, 0x8374c34b, 0xfdbe454f, 0xd30237dc, - 0x9f0b9f7a, 0xc3cbe93f, 0x8dcfa374, 0x22be53e9, 0x12be034c, 0x6fb36f7c, - 0x7c5ba62e, 0x8cfe7c1e, 0x06d31caf, 0x7f3e0d5f, 0xd31ab7de, 0x3e3f3e6d, - 0x1eb7d17f, 0x1d5f46d3, 0x5e403ba6, 0x05f26d34, 0xbe5dbdf0, 0xbe834c06, - 0xc7be7c46, 0x11f4c417, 0x64c747ce, 0x3e512f92, 0x49c4dc38, 0x8a924ec5, - 0xcd32f9dd, 0x7cb09527, 0x7cfe1dea, 0x3d53e685, 0x32f94f34, 0x6f9432a0, - 0x3501f9a6, 0xfdf07cac, 0xf342c0a4, 0x7cacfd83, 0x02ee23c8, 0xa90fcd2b, - 0x37c3e563, 0x68e20bfa, 0x9580787e, 0x542dbd5f, 0xabf9a360, 0x7679591b, - 0xa76a9933, 0xcb10ecf9, 0x9ee1bce7, 0x39f34f1a, 0xfb9f2cad, 0x83aa7f81, - 0xd8db73e6, 0x04ce93f7, 0x2d1ed544, 0xbab21d87, 0x6d595098, 0x4b70cff4, - 0x515e6913, 0xca2e21ef, 0x6eadff1f, 0x43f29d29, 0xc8796376, 0x9bcb1f3f, - 0xbf963714, 0xfcc32fe3, 0xe583d92e, 0x2c55fdc7, 0xfcb078af, 0x98bdff73, - 0x2c7eca0f, 0x58fad4b7, 0xf963f15e, 0x58f5da80, 0x80391eff, 0x1f6b23e5, - 0x4a3df2c3, 0x5f1fcb00, 0x1a7ba4fb, 0x3c11afcd, 0xd23c073f, 0x01649cb4, - 0x4ad31a9e, 0x09d69e28, 0xf7e02e64, 0x8a3a0007, 0x0ae975cb, 0x3f8ee1ea, - 0xfa0d3ee4, 0x90297f8b, 0xc3ccfa5f, 0xaffdf899, 0xd6991eb0, 0x4f5ef623, - 0xba799bce, 0x2cde727a, 0x8069ead7, 0xfb58d6f7, 0x378ecf56, 0x79e9e927, - 0x67ab42b3, 0xdf13d23b, 0xbce57eb7, 0xcf4f5935, 0x3d5a955b, 0xc49e907b, - 0x74d3d1be, 0xa69fcf44, 0xb4fe6123, 0xfafd3d20, 0xf7b8cf46, 0xf719fcf4, - 0x6f3f985e, 0x7de93d60, 0x3de9a7ab, 0xde9a7f3d, 0x08e7f30b, 0xdf506bf6, - 0x7dee35fa, 0xbdc67f3d, 0x47cfe61f, 0xdf664f48, 0xa1f5d9ea, 0x3ebb3f9e, - 0x04e7f30c, 0x6fac33d6, 0x48fdcafd, 0x8fdc9fcf, 0xc2e9fcc2, 0x5beaae7a, - 0xd23ebb3d, 0x47d767f3, 0x817cfe61, 0x5bea8cf5, 0xa2ff72bf, 0x5fee4fe7, - 0x0931fcc2, 0xbe98cf50, 0x54fc13d1, 0xa7e09fcf, 0xb0d8fe61, 0xa37df19e, - 0xcf5daf27, 0x30f6bc9f, 0x9004527f, 0xd5bec4fb, 0xf3d76c13, 0xe61ed827, - 0xe7ac20cf, 0x2bf5beba, 0x3f9e84ef, 0xfcc22779, 0xcafd8e19, 0xf40f7aa7, - 0x7c4f5a10, 0x39ecf5cf, 0x9ecfe7ab, 0x8cfe61b3, 0xd3a67ac6, 0xaf7ab27a, - 0x9e875267, 0xc23a933f, 0x7ac3c9fc, 0x9eadf466, 0xfe7a1d3d, 0xf308e9ec, - 0x73f91f27, 0x35fadf53, 0x9fcf53a9, 0x3f8c9d49, 0x4cd70f63, 0x3a72d075, - 0xfa44ba16, 0xdc67b5c9, 0x45e6816e, 0x4e8bcb27, 0x44bf0117, 0xd20dfcd4, - 0xf7e916ea, 0x39896df6, 0xbf48930f, 0xfa14a0a3, 0xb1bd4f15, 0x2123bf48, - 0xe7e74e2f, 0x7493ba24, 0x01a2e4f9, 0x95fbf7ba, 0xf795d10c, 0xaeb57b9f, - 0xa393dd3c, 0x4f9467cb, 0xa83fbdd2, 0xbf9740a6, 0xba0df562, 0xb7fd33f7, - 0xeb59f2ea, 0x3fbdd76f, 0xae916eac, 0x0afacafc, 0x8155f95d, 0x35fcba95, - 0x7baeff0d, 0x03e3547f, 0xc1d1f2ba, 0x63e57587, 0xf2eb8f42, 0xa93d0f63, - 0xeb7c7f7b, 0x84f95d66, 0xcaebcfa3, 0xd0edb627, 0xb93dafe5, 0xd9e7e0c7, - 0xf0d7ed9d, 0x27b808bc, 0x574fefcc, 0xc50bdfd0, 0x0657982b, 0xdf8fd1d8, - 0x3d54bf1f, 0xbcabe54e, 0xa14d58b2, 0x129905f2, 0x0fe7ae3a, 0x8db2bf28, - 0x9277bf3e, 0x7d274ae7, 0x19e2af7e, 0x9fe18ced, 0x24083c52, 0x04d5520d, - 0x41fcb1a9, 0x20b1e199, 0xc7e1cbe3, 0x535ef7e8, 0x9a44f0d7, 0xd7e62fef, - 0x129e5e03, 0x38d3884c, 0x7bc0d491, 0xf3826671, 0x73330782, 0xe047f69f, - 0xaa20fd75, 0xbd774287, 0x1a4f65eb, 0x6b9b19f8, 0x1f83f6df, 0xed106eb2, - 0x9e4200d7, 0xf90ede16, 0x07efd287, 0xd0f34d2d, 0xf50accfa, 0x57db23d3, - 0xb123fb68, 0xff6806fd, 0x37da1ec5, 0xb5d3c90f, 0xae5c196f, 0xd0a2df6b, - 0x1fd49df6, 0x6f23fda8, 0x12610a9f, 0x7f0b2f21, 0x83cdf6c4, 0x07fdb1cb, - 0x895f3a15, 0xdc2e3f6c, 0x77f4107e, 0x3e3fb41f, 0x4c87ff46, 0x707ff7d2, - 0x0affbe85, 0xb52bffeb, 0x71fb78c7, 0xe116ffd8, 0xe0ffeb18, 0x337fd60a, - 0xbedc37ab, 0x43ffcc23, 0x7b37ffd0, 0x64d67fea, 0xa8afff7d, 0xccdff7d4, - 0xf6a77fda, 0x8edf6f14, 0x9c2bbfed, 0xa2bffd62, 0xcc57db12, 0x47e0171e, - 0x09ab88c9, 0x40c9f6d0, 0x03fa986a, 0x903b685c, 0xa0a2488e, 0x6151e426, - 0x6f71d208, 0xe7dbc31c, 0x686f1471, 0x9cf8fc6f, 0xcb65a804, 0x8e2ef3a5, - 0xf2db15f5, 0x584bb015, 0x4b2be74e, 0x4165a938, 0x364df111, 0x28c30398, - 0xd1411dbd, 0x0db2f90f, 0xfec005d7, 0x4164cd79, 0x91277c09, 0xf4ff3c10, - 0x4736a367, 0x2e98cbf6, 0xdbdb93a9, 0x3c2df422, 0x23202a8f, 0xd37d286a, - 0xbbe30401, 0x79d31ff3, 0x8bf3a110, 0x833ce80f, 0x227e4850, 0xa23ef6b3, - 0xb7c825f3, 0x9412f9d1, 0xdf8b5213, 0xa70eead1, 0x384bfa51, 0x4c4b1ffd, - 0x43be3f5f, 0x7ea9f808, 0x31bdfe7e, 0xb05d4f38, 0xde9946da, 0x7f42c74d, - 0xfb4f2eb2, 0x753907e5, 0x360736ed, 0x155fc80b, 0xaa8a55f8, 0xf5e2c849, - 0xddd79419, 0xc54fbfef, 0x7f594e9e, 0xfdcb711b, 0xae77fbe9, 0x69390612, - 0xe6ddb3bb, 0xb84e361c, 0xd7a84c33, 0x4794c324, 0x634dadc8, 0x29035a64, - 0xb71fcb75, 0xb33bb445, 0x5d9f9f48, 0xc877cfa2, 0xe944d96e, 0xc81528ea, - 0x9cef5a26, 0xad72fab9, 0x8929bb1d, 0x57b799c9, 0x9be8ca92, 0x3c0e6903, - 0xe79ca276, 0x1ab7d93a, 0x32c5de3d, 0x3c82c29d, 0xc808fdfd, 0xef829fd5, - 0xfd64eedd, 0x573bd236, 0x684bb8b6, 0x142ee73f, 0x236f8003, 0x67da7ffd, - 0x69b29b73, 0x32a7feba, 0xc7f74531, 0x8f3cff48, 0x328d3fb1, 0xcbf3c38c, - 0x6e19cf8d, 0x3ffcb9da, 0xf4d07c06, 0xd283e004, 0xa3e39c7f, 0x7c32aedb, - 0x9b9ecd78, 0x4f5d0f01, 0xcae50488, 0xc71b72f1, 0x3d3a92cb, 0xc8f1082e, - 0x7365c720, 0x23879c85, 0xe3873070, 0x1ebd5960, 0xbf127737, 0x2e431e9c, - 0xfa6c36f3, 0xdd1a9a61, 0x6e390fbf, 0x1fb23fe6, 0x4fdd13f9, 0xb8bba726, - 0xd1acee9c, 0xe5c6df97, 0xeb97277a, 0x0ec7fadc, 0x6e41f350, 0xe8320357, - 0x4d3ef7bb, 0x793a6d9e, 0x8d3cb87a, 0xe5c5de74, 0x98f7d779, 0xb6f48d3c, - 0xd5b67971, 0x90c9905f, 0xf48d7a68, 0xd51d582d, 0xb9e4051f, 0x9e5b1fd0, - 0xf27e60de, 0x55e788f1, 0x8f92338d, 0x8ad9e847, 0x7e5d5286, 0xee9e6079, - 0x0bf565fd, 0xea4be575, 0x17caeb96, 0x975bbfaf, 0x9effe85f, 0xab05fdee, - 0x77e5756b, 0x2ba43cd6, 0x98fe5f9f, 0xf3cf3f2e, 0x39fdee84, 0xcae93773, - 0xa73c9767, 0xb4599f2b, 0x752f975d, 0x6fbdd6ef, 0x2dd577da, 0x8e37cf80, - 0x89fc0488, 0x30275ccf, 0x4b99f82e, 0xc73bc176, 0xbae22a7d, 0xd30237dd, - 0xe2173e93, 0x0f2fb4fe, 0x8b608ed3, 0x3a09c61d, 0x89252e2e, 0x6e9bccd4, - 0x103f5dae, 0xe38269c6, 0xacd316e9, 0x4264ff5a, 0x91526d7e, 0x0af5c5df, - 0x44258d09, 0xd386c180, 0x944625d1, 0x5e52f5b7, 0x727f0d4f, 0x5b717974, - 0xc7dee7ec, 0x8ce15e17, 0xd6e97711, 0x7e019253, 0xbbf7274f, 0x0295e58d, - 0x4e7c8929, 0xd7a803c8, 0x5bb8f8e7, 0xaffd30a9, 0x405e91dc, 0x0d0f901c, - 0x7b5cb9af, 0xfde4148d, 0x3a592701, 0x7f565e3d, 0x13bece8d, 0x03f6ca88, - 0x3dd58dbc, 0xad70d15f, 0xfb33bbee, 0x1abba445, 0x1844c56c, 0x375e4b16, - 0xb50e1d81, 0x0a399e0c, 0x61bf74e8, 0xd82a7182, 0x33c2fd0f, 0xe3e4a2be, - 0x04afc812, 0xb9be93d3, 0x3cfbb698, 0x95f71e98, 0xafb1fa63, 0xdf36d306, - 0xf23f4c6a, 0xc0fd31f9, 0x3fd31eb7, 0x3d30eaf9, 0xf4c7abea, 0xd3005f3d, - 0x4c06bec3, 0x6235f1df, 0x620beada, 0x6373e1da, 0x6f5de9aa, 0xc7c93bb8, - 0xbf80d3e1, 0x78eb3818, 0xfaed5560, 0x3b38ddc9, 0xd6afba6f, 0xcf9bb03f, - 0x8e66f5c5, 0x1e1d5487, 0x336080be, 0xf297ace2, 0xb0e3997a, 0x9763efa7, - 0x6bff377b, 0xc4de36f0, 0x8a6fccfc, 0x653c6eb7, 0xd594f018, 0x89fa9e1b, - 0x34f1bbe3, 0x7e64e4de, 0x8fd3c70f, 0xe6311fa0, 0x84e00515, 0xd7f08bf4, - 0xa71636dc, 0xd409ebe6, 0x6a716553, 0xfa1af6de, 0x75fa2b6e, 0x6e301181, - 0xb7f11f9c, 0x3f8710e1, 0x274cd47f, 0xcff73d7d, 0xf99e9388, 0xcdf9c6ee, - 0xbc1d00d2, 0x5b9746c6, 0xad5f18e3, 0xe8445226, 0xb0d0f6b8, 0x468b5c67, - 0x49225e62, 0x55c07df0, 0x5ea31f1a, 0x7f032bea, 0x9aebe37b, 0xa1b3cff8, - 0xff27f6be, 0x78e90b9e, 0xe397f313, 0xdbf4445a, 0x1769e849, 0x2e3c37f0, - 0x10695d99, 0xa61aeedf, 0x086fd138, 0xf3fcf5d8, 0x376e7cd3, 0x3ca21eff, - 0xb771c56a, 0x37f90d2e, 0xe9e1f3f4, 0x6f5fe07d, 0x7e37bdf6, 0xf80c0a2e, - 0x37b3f097, 0x5d9bd8fb, 0xc5f56e24, 0xe77fed20, 0x0f3951be, 0x870760ab, - 0x0f5a79b0, 0xa5d6d6fc, 0xff7cf48c, 0x33b8e26b, 0xeb71c355, 0xf9db4260, - 0xf9cbeb88, 0x40132ba6, 0x9c1eb42e, 0xe4ed741f, 0x722f7e7e, 0xafa99b3d, - 0x2fac6bcf, 0x68c22141, 0xa2bc6eda, 0x6a420490, 0x22a3cf44, 0x6d5c6fce, - 0xec1b887e, 0xa8d6b9b3, 0xfd3c6f30, 0x1a854866, 0xf385f1f5, 0xc0769e87, - 0x9a656c3c, 0x863c79c9, 0xaab4b51c, 0x8f69d331, 0xf504af9c, 0x4275f3f9, - 0xe7ce2351, 0xa35984d4, 0x3a719c60, 0xbb050f8f, 0x56a9869f, 0xc534cacf, - 0xddda9c79, 0x09590dd3, 0x6017fe6c, 0x225b64f6, 0x3ed39bda, 0xcfffbe0b, - 0x7aa7a7a6, 0x69087a34, 0xc0589f22, 0xacb2d39e, 0x51efdf9e, 0x0a8ba41f, - 0xb34937c4, 0x37cc39fc, 0xaffff4ad, 0x12bd4086, 0xbd7ab5e6, 0x3cdfa28d, - 0xd36f9e1a, 0x53bf47b5, 0xf857b5b5, 0x93bd67ae, 0x7b86bb48, 0xf957bf2a, - 0x068af0fa, 0xc7ef53ab, 0xdef2ea26, 0xe753ba60, 0xc03fc2d7, 0x2411af71, - 0x87255fc0, 0x5f64a75f, 0x0cda780f, 0xbf9843c1, 0x2abdec08, 0x51e29b4b, - 0x015a5d51, 0x34f28b9f, 0xfe73abfc, 0xa9d4ed4c, 0x7a0265d7, 0x54a4be46, - 0x20a9f2e5, 0x4c44cde2, 0xbf98bf34, 0x4569a8bd, 0xa75b8c31, 0x50fe6c4c, - 0x301c4a46, 0x75272e3f, 0x3d4f10b9, 0xa0454c4b, 0x3bc9679f, 0xfa11b18e, - 0xb0544e78, 0xf5ebc5d2, 0xdf9d3c7e, 0xeacbf2eb, 0xe4a5f9f5, 0x075854d6, - 0x2641ba5f, 0x86ec0101, 0xe898fcbe, 0x91977ac4, 0x6e30759a, 0xbbc79cff, - 0x94893916, 0xfaabe941, 0x17732fcd, 0x892e3a52, 0xd6d5fc6c, 0x31279771, - 0x05662bfa, 0xff7d3714, 0xb7b1a693, 0xbf440b51, 0x7583ac0f, 0x71297f6d, - 0xf2d1256d, 0x1bf4bafb, 0x81fcd5e9, 0x4e64f5a8, 0xe0834a47, 0x63b0c40e, - 0x3d30248a, 0x6aeef6e3, 0x838ba9c9, 0x223e42e4, 0xf18df20e, 0x78744294, - 0x067a2cda, 0x7e19e34b, 0xd4820f00, 0x4dbe78a5, 0xf55169fd, 0xfbf52d5f, - 0x903fd627, 0xabab9fd6, 0x4a9ff73f, 0xfa28d0ff, 0x5fd5620b, 0x76179bf5, - 0xa93da9f9, 0x0e67e978, 0x53c9c742, 0x8baa5d52, 0xeb72b5ca, 0x9a6e1d0f, - 0x0efc949e, 0x80a9ebc0, 0xde4b1458, 0x76f2c3ab, 0xbb8805db, 0xfd693fc1, - 0x11ff9fa7, 0xdf3e23c6, 0x9e313b2a, 0x990e60d6, 0x37563ea9, 0xd9262f2d, - 0xf2c63f98, 0x21139e0f, 0xafe3d41f, 0xa59fd9e2, 0x8a0afec2, 0x0a5f1e14, - 0xbd5b3fa1, 0x1c42d3e5, 0xea17489f, 0x683bf191, 0xda1252ff, 0x424a85bf, - 0x13a53974, 0xce5e04e3, 0x8fd36f17, 0xf80e89ce, 0xdfce1b57, 0x7397ef8d, - 0x14b974ff, 0xa36ed29f, 0x26409eff, 0xf8d43d80, 0x3fcc0241, 0x2fdcf35d, - 0x7a518fb2, 0xdd796cce, 0x49f04421, 0x8df3a3d3, 0x47b57f8b, 0x76ded9ed, - 0xf48b3d50, 0x4af1b483, 0xbabf720d, 0x7295a599, 0xd52d71c8, 0xb24dcafb, - 0x571f4fcb, 0x33f4f0be, 0xf31c424f, 0x30d7668f, 0x178aff5a, 0x8937bc0e, - 0x976c57e6, 0x37598a53, 0xb76a42ec, 0xfff4bc5c, 0x72dd39d5, 0x80f978a8, - 0xcf628ea2, 0x96ea4fef, 0xfbed8ac7, 0x9a2a3215, 0xf71b531f, 0x18f66d2b, - 0x563c6972, 0x9ac27e08, 0x814bfee7, 0x7da9e2f8, 0x199fe902, 0x0e9b9f83, - 0x7c001fa0, 0x39723942, 0x7866e585, 0x02e54bdf, 0x93935af6, 0x6e46fcb1, - 0x753ea04f, 0xc5f9e224, 0xf2fdb43d, 0xd05d993f, 0xef17f2ff, 0x4e3f4071, - 0xd70c3548, 0x2a61fcbf, 0xd972afd8, 0x94c4ea9f, 0xea7f2f3d, 0x65b788bb, - 0x15377f6f, 0x9dc449e3, 0xc7b1c26e, 0x5bfd0e9f, 0xf63671b2, 0x20f1296f, - 0x297fcaee, 0xfa680496, 0xb68a4499, 0x0e8bd0c7, 0x362717ae, 0xf68c4753, - 0x1fcc04ef, 0x23bf5ec1, 0x422abee2, 0xffa026ee, 0xa17de5df, 0x3fe6021e, - 0x1d3930b3, 0xaf5c4c90, 0x8919b7a8, 0xb60f2dd7, 0x0f4e7c82, 0x7587f772, - 0xfc912f16, 0x57c21f9c, 0xedf15eb4, 0x7c99fde9, 0xf2e52a88, 0x3f38e8ef, - 0xfbc39e15, 0x9adbb2ad, 0x7c8efbad, 0xfeddd995, 0xa53ede2a, 0xe7c60e3b, - 0xfdb1a913, 0xa6b201d5, 0x8e9c74f7, 0x7e8457c0, 0xf2df7d33, 0x4d6fd310, - 0x45a503df, 0x30f17e50, 0x0ef81fd3, 0x574a3fc6, 0xef963fa8, 0x3da0259f, - 0x58e6f3a0, 0xe645bd7a, 0xd72fad7a, 0x96e94270, 0xbc088484, 0xc849fd40, - 0x595f5c7f, 0x177e81ba, 0xd0bd2f61, 0x3eba239e, 0x71976f4d, 0xfa053ffd, - 0xfeb74d7f, 0xef4c8d93, 0xfc9ff67b, 0x07236e2c, 0xf412799e, 0x5fa7ea95, - 0x4b957d05, 0xdd7fdfa0, 0xeddef2d6, 0xdaff4f54, 0xdea9e9a8, 0xb4f51a7e, - 0x1278c77c, 0x6aff4f4b, 0x7a989177, 0xd4c79f4a, 0xe21b7b53, 0xfd94fff8, - 0x2897f8d4, 0xd9a7f9eb, 0x68f89ec3, 0x4a2f87b4, 0x68d3f22a, 0x61dfe90f, - 0x3f8d1b92, 0xde1a770d, 0x755d7e2a, 0x309dd805, 0x85dc352e, 0x2ee1a971, - 0xe3ab7e2a, 0xcffcb19f, 0x74a26b10, 0x4fd4b7cd, 0xa5847981, 0x2bbce08b, - 0xeb88967f, 0x048b96a6, 0xc880bef5, 0x7df06fb8, 0xf078cd53, 0xfdfca743, - 0x52f7b3b6, 0xbf13e77a, 0xebe5d6cc, 0xbfebf464, 0xc9abeafc, 0x73b73fb4, - 0xeca7cefe, 0x63ca89be, 0xe28424ae, 0x24f39d28, 0x82484fe2, 0x3e40acf8, - 0x7e63a08e, 0x7f0f3eb9, 0xebbb5253, 0xaffdede9, 0xa6f90f3b, 0xb63edbe9, - 0xa42ef576, 0x2979b143, 0x20a54f12, 0xef3fca57, 0x04302138, 0x549b52ed, - 0x7aaf3112, 0xb79ddb9c, 0x0f1ccda7, 0x9cfe4bfe, 0xe70c0951, 0xeb7e7183, - 0xbcebf6e5, 0xbb004d5f, 0x0b39be7e, 0x0fe7afe7, 0xb58f8e2d, 0xe385b26f, - 0x575f00ec, 0x750bb4e9, 0x277dc522, 0xc5ff42e9, 0xad92b76f, 0xbefdd631, - 0xe4f89b2f, 0xfe8dcb83, 0x736e5489, 0xd1e70e39, 0x2272134f, 0xa6eb36e4, - 0x5a239253, 0x71f7f00e, 0xdbeb3cc4, 0x0d7017f2, 0xb6b16dfc, 0x88c49615, - 0xf384fdd7, 0x5f2bca6f, 0x69d5fee0, 0xf012f9cd, 0xd45d9a71, 0xd41e39c5, - 0x192475f4, 0x794d7409, 0xe3a3f965, 0x87bd8e29, 0x57ec1744, 0x539f36f5, - 0xbbe6313c, 0xfd427e46, 0x901e47e0, 0x23afc89d, 0xe012c972, 0x56d991eb, - 0xef96eb02, 0x58aaae2a, 0xb3374e74, 0x523cc878, 0xe138d9f2, 0xe6fe3eff, - 0x150f89cf, 0xb79c7e50, 0xd1c0fdb3, 0x7f7a63f8, 0x6a0429de, 0xc8a1c005, - 0x004229f2, 0xc48564e2, 0x0164e8f3, 0x48fafdf5, 0x2c1f95fb, 0xd5f6017d, - 0x4e0b3754, 0x96af2d13, 0xb1c014da, 0x025db837, 0x9546fcff, 0x20de31b8, - 0x159a8cd5, 0x203ad711, 0x96afc84b, 0x277eddbf, 0x2cc2f7f0, 0xdcba0133, - 0x6039cf23, 0x3cd0bfdc, 0xa7a0f516, 0x47c1fd7e, 0xa0934ca6, 0x30f8821e, - 0xc530a1e2, 0x9ecfcba6, 0xa8ba064a, 0xdb98a6dc, 0x90c571ee, 0xe18532df, - 0xcdf6cfac, 0x7d99fff2, 0x1bed4c9b, 0x691cb5c3, 0x512b46df, 0x2c7fadf6, - 0x56b2b6fb, 0x58b80fed, 0x3fab37b9, 0x6be575c8, 0xb2c5fa4b, 0xd8faaf6f, - 0xbe35fdfc, 0x2073bb0f, 0x23a36fb5, 0x6a40dbec, 0x6dc462df, 0xffcd15d3, - 0x59bec5ec, 0xeff477fe, 0x316fb055, 0xd1523bfa, 0xe6a2b7db, 0x456fb45a, - 0x7edd4503, 0xcf852ca8, 0x6fb47ae7, 0x1b367f0b, 0x16cbb2f3, 0x57c03f03, - 0x71af6fb0, 0x80ed073b, 0x38a45b9d, 0xdabefdb1, 0xdabed2b9, 0x3e25ffb9, - 0xe56e766b, 0x239e7620, 0xcecc871a, 0x7664ccad, 0x665ee56e, 0x630e56e7, - 0xdf68ce76, 0x1beca20a, 0x047abefb, 0x8be71efd, 0x83b8bf99, 0x95cf1796, - 0x7efa165d, 0x5f9daab1, 0x691f19a8, 0x122916ef, 0xdeca39f2, 0x39e1ceb9, - 0xddecde90, 0x86ef605b, 0x0a1b1da2, 0xc7c4647a, 0xba6d430d, 0xbe4772fd, - 0x4bf5ff68, 0x107f2fa0, 0xbefd9e71, 0xf68bcd89, 0x163ed17d, 0xa7376ef4, - 0xc98551e7, 0x47e7c3b3, 0x24753a7b, 0x43aaf7d3, 0x544e3871, 0xbfac0937, - 0x15010bf7, 0x5dbf81c6, 0x9df2f9c2, 0x797cd97b, 0x83f1998e, 0xcec89bfc, - 0x2c16505d, 0xdcc3c08c, 0xd718154b, 0x0b112b9c, 0x0e0baff8, 0xfc0a70dd, - 0xd69705d6, 0x00bbbfa3, 0x89bec39e, 0x32eb6ded, 0x2e77bb68, 0xa1de7017, - 0x1798efed, 0x3f7a97b6, 0xec737e76, 0x38531a7d, 0x13ee533d, 0xa72fb002, - 0x2f107db7, 0x239bfd72, 0xc8bf21b6, 0xf8cc625b, 0x985ef6a4, 0x97c62e4f, - 0x6fcc55aa, 0xf289f30e, 0xf9a2154d, 0xbc5d2544, 0x2f9bb530, 0xfda4ee77, - 0xbfb9e94d, 0xf7a2df1a, 0x3e71b8e1, 0xd7bf80b3, 0x3e341f13, 0xf39ff547, - 0xb8a9fa9d, 0x8fc8c79f, 0x5ccecd46, 0x5e814643, 0x3cf26fbe, 0xf4701e3a, - 0x942f949f, 0x0de6dbce, 0xd9e79dd3, 0x9372f9c5, 0x54b4d8e7, 0x6a48f815, - 0x97b76700, 0x4a903f6f, 0x3b8b77fb, 0xe6420733, 0x78a6ffb3, 0x62d0fe20, - 0xa83b42ed, 0xcccd30e1, 0x8e57f870, 0x9c0323c3, 0x09bc70d3, 0xafd44e0a, - 0xf1cec190, 0xca5e647d, 0x6f5fd067, 0x144f8f90, 0x859fa09f, 0x720578da, - 0xa9bcffa1, 0x5bc5c999, 0x6e5ca023, 0x81075d26, 0x8229d5ef, 0x2aab442b, - 0x21ff6e0c, 0xd57ab7ec, 0x9e839f4a, 0xcdae0b97, 0xf4f61d8c, 0x963898d4, - 0x3718e162, 0x9b8c4609, 0x24bde00b, 0xc668b7d8, 0x1efceff6, 0x3f4647b3, - 0xf5b98a65, 0xe533d008, 0x09b264df, 0x7fe8061e, 0xfa303811, 0xf07a5131, - 0xa4fdf735, 0x2afdfb72, 0xfc0ec1c8, 0x1fc052ee, 0xf8d886f2, 0x257b95a3, - 0x4df21a75, 0x8e904393, 0x1c98e32f, 0xc8dfa960, 0x3cb45be7, 0x6fde1fe0, - 0x7ef86416, 0x324f9506, 0xfa6a9a2d, 0x7786a0e2, 0x2fcd1ab3, 0x47a42788, - 0x6fb00dd8, 0xd596eb91, 0x4f91b7c1, 0xeea2ac37, 0x27cd1a99, 0x07603e4d, - 0x28afc72f, 0x8fee09fd, 0x9bea7fb9, 0x599a4fea, 0xacfb3faf, 0x868faf5d, - 0x015eda38, 0x4e690aed, 0xf20fc5d4, 0xd65e6ccc, 0xce20f562, 0x5d935ebb, - 0xfb68d59b, 0x0b971573, 0xcf2257cc, 0x0e854def, 0xd3b1bac1, 0xfad13e4a, - 0x2ce1843d, 0xd5783c72, 0xf5f941ea, 0x5e04ff54, 0x98fe4f7f, 0xb40eff96, - 0x5516fb07, 0xf1c67b7d, 0xf5278b48, 0x6669afd6, 0x69be3f66, 0xbe76b4bf, - 0x9783baee, 0x4dfc62b4, 0x2cd87f5b, 0xc32e7e7a, 0xd048b8fc, 0xca5073ad, - 0x9ff2fd71, 0xe558ff50, 0xfc43f532, 0xfcf94428, 0x31a7b6ea, 0xf9f67d5e, - 0xfe833763, 0x48adf8ac, 0x3a9f542c, 0x1093c5b6, 0x80a207db, 0x24d1509f, - 0x91167ae2, 0x2333b942, 0xd6420cfc, 0x14bc7e30, 0x62a7768f, 0x4c503987, - 0xf5d8afbf, 0xddc43649, 0xf6601e3a, 0xc73cffcf, 0x1b2dbfa3, 0x242bfbd6, - 0x946f8eb6, 0x9f1cbdcf, 0xe6db7667, 0x1a16fd82, 0x8ad779d8, 0x39b239c6, - 0x6550ce22, 0x7b5c5996, 0x59f70db7, 0x70139ffb, 0x17d0329f, 0xdb52ce79, - 0x39e679ff, 0x822b9766, 0xcdce0072, 0xef6c3456, 0xc5783880, 0xaffa3351, - 0x0a7386de, 0x5f53a7f8, 0x23fd017a, 0xc5d4506f, 0x8fe2a341, 0x0cc8620d, - 0x2aa6b3f1, 0x7f3403b4, 0xb18df30c, 0xc5bdf0e3, 0xb4bc56c9, 0xb29f9777, - 0xcfcbc570, 0x6cdcf03a, 0xc60756eb, 0x1f2e1b21, 0x378a8fff, 0xd9743e36, - 0x8e69e378, 0xf5995f8f, 0x21a435eb, 0x9490e319, 0x1892dcbe, 0xee308b71, - 0x29ecf85f, 0xb33b0f58, 0x014fafe3, 0xb8ff95bd, 0xe07dd4f0, 0x3ab3ed8f, - 0x3ef6bc61, 0x13d7047f, 0x7376efb4, 0xee78ef3d, 0xe9875c59, 0x05d9a3f8, - 0x3dec75b5, 0x23d61831, 0x917fb63a, 0x55db710a, 0x3ce3a77b, 0xa9ced56d, - 0x798c49fd, 0x6e029680, 0x07587d03, 0xa5abca32, 0xd03065a9, 0x1bca9679, - 0xfc70b65c, 0xc58ab1b8, 0x371e55e3, 0xbd7b16de, 0xdc4e2a2d, 0xeb96f334, - 0x926efc60, 0x43e92a5d, 0x9530f8bc, 0xc83ee8e3, 0x9a43db6f, 0xbf298fbd, - 0x2a0ff0b3, 0xf20df7a7, 0xc969acfb, 0xb2849eaf, 0xe31ee4a6, 0xf03ea1c5, - 0xdbcf5b4d, 0x6c7f7662, 0xf1d9bd06, 0x83cf8c6b, 0x835ce8dc, 0xd9f0bc74, - 0x9cb38860, 0xc2eebb94, 0xcd7b33fd, 0x62aa2fb8, 0x3fa8fbef, 0xc6df3b1d, - 0xd7c232f5, 0xf8483ad5, 0xf083ad8f, 0x4b779c39, 0x73338b3c, 0x5a1c43fe, - 0x1e73e075, 0xd638666f, 0xc53dd0e2, 0x6c2dd39f, 0xceb6913f, 0xcfe5b558, - 0xf5c4310a, 0xd3903c85, 0x8baecbb1, 0x02707c6a, 0xae44261f, 0xf38ec4a7, - 0xb8ddd787, 0xe07e40bc, 0x4bd7857f, 0xc4207e68, 0xfbc203cf, 0xe83d8624, - 0x61d6c4d8, 0xfbd8e43a, 0x95f5b50f, 0x4f418b14, 0x575b7d03, 0xaffe8de9, - 0x26191fcb, 0xf9a3e39b, 0xd8cbe674, 0x45827c76, 0x61fb76f8, 0xf5a8852a, - 0xcfac0b7f, 0x60531d37, 0x638da1fe, 0xf0cf7f5a, 0xe799f279, 0xb1ef3c45, - 0xed05b1ae, 0x545ed1b8, 0x341f1613, 0xd3833bd2, 0xe3641d5b, 0xf11d99c4, - 0xe7ad3b01, 0x11bb2bcc, 0x8edbd5cf, 0xdf5a7e29, 0x959786c1, 0x52fd88b6, - 0x22044e30, 0xe2f33fe8, 0x7eb66cfe, 0xc6e5e6c4, 0x76f0e676, 0xdbb1cdbc, - 0xa73b6ef1, 0xbf85676b, 0x77e76151, 0x69dedf2e, 0xea073dc9, 0x132add3b, - 0xba7fbfd8, 0xc40a2c51, 0x45927f68, 0x4cf2e2d6, 0x8978e86f, 0xd9e31de7, - 0x493146f9, 0x557aff41, 0x84d1de7c, 0x15154814, 0x6a6b14e2, 0x35d2fed9, - 0x81a577df, 0xde24d7bc, 0x756deb86, 0x533afe06, 0xbf10f99c, 0x192b4e70, - 0xda357007, 0x49b7449b, 0xf8aaff47, 0x1e70fea2, 0xc7f72d7f, 0xf3c2e488, - 0xb0a3a297, 0x3a23fa08, 0x8c6b4e4d, 0x5ed905f5, 0x7c113c42, 0xf3fa9d91, - 0xb1cbe492, 0xeda3d42a, 0xb4b4a9a3, 0xa742c41e, 0x4b0ab71b, 0xfcddec79, - 0x77ec4e59, 0x4f3e36e7, 0x99d51370, 0xc183f6ca, 0x23b9d1b8, 0xc68c9b21, - 0xe29b890f, 0x0b9fc6d1, 0x07eff6db, 0x41d6b47b, 0xcf5489dc, 0x31555728, - 0x8e8dce0b, 0x805908b1, 0xfe6f73d3, 0x6d6bd696, 0xd0fe7116, 0x85f6d769, - 0xcf4113ba, 0xdc11e46c, 0xfe5007ff, 0x4e9bb92a, 0x0240bee3, 0xdf76a4af, - 0xb45d312b, 0xfce7bce3, 0x10071646, 0x98bfd5c9, 0x2470e2cc, 0xf1f3f400, - 0xf3a70564, 0x7ef0a43c, 0x3ae78299, 0x72f6bd96, 0x3930886e, 0xb92bf244, - 0xb4be7f48, 0x86c8eade, 0x77e27975, 0x9939c2b7, 0xbf5f5e32, 0x53b9fd12, - 0xd07e7eaa, 0x4f5c25d3, 0xf0b4baff, 0x32bfd810, 0xebb452cf, 0xcfeae7fd, - 0x59f71aa5, 0x2fb0bd21, 0x93ddea8c, 0xabbef442, 0xd6c7e6f2, 0x7a397cc1, - 0x011915ff, 0x482ac9fb, 0xe7ce0b9c, 0x97d068ac, 0x79bb03ef, 0xd893b015, - 0xebef172f, 0xc36dbf95, 0xdc79317f, 0x0aebf965, 0xe2dbfbc1, 0xecb2ae31, - 0x9f68c5b5, 0xfe7a69cc, 0x7f3d555a, 0x7c8c236d, 0xde39f3d4, 0x369be7a5, - 0xcf89ecff, 0xf3fa7909, 0x4b3e46be, 0x021bc784, 0xb5110e2c, 0x09b82dbf, - 0xd9f236e9, 0x0b76d7c8, 0x7ce2f75f, 0x96257fa5, 0x81b26654, 0x842974ee, - 0xa3d4617a, 0x80487b0c, 0x094a0f7f, 0xae57e2d4, 0x69efb478, 0x19423fbc, - 0x7a06cefb, 0x2ebd0224, 0xd13823d4, 0x46de7607, 0x5bb6703e, 0x909f5841, - 0x59e9aeaf, 0xfe94f79e, 0xfa22d8fe, 0xefc046d5, 0x762bd468, 0x0489376e, - 0x9e8264d6, 0x6e309cba, 0x6a2cfa37, 0x9ff70499, 0x286cb510, 0xc4e27bdc, - 0x1f7cc7f4, 0x8248e74a, 0x431b82fb, 0x3ec15317, 0xeba738fd, 0xde7bb066, - 0xec04a425, 0x6c71cde0, 0xa798b29e, 0xdc2ab77f, 0xed7b4eae, 0x59bef87a, - 0x785ce156, 0xcb56f367, 0x4507c830, 0x9bc47fbc, 0xb4157758, 0x332cd1df, - 0x812ccaba, 0xd8bf1061, 0x1dbb632b, 0x7cf19365, 0x6b6fd865, 0x3a40fb66, - 0x2c713f9b, 0x1de7b08e, 0x055e9fc1, 0x4c27acf1, 0x0c9ff7b1, 0xfdf89ab7, - 0xfc70df35, 0x7fda8c6d, 0xf6cadc37, 0x0878fdc7, 0xe97547ed, 0x330e3e79, - 0xcb96b87d, 0x6f4bf7f9, 0x6ceffec0, 0x47185416, 0x6e3bc50a, 0x39fb451c, - 0xe3c488f1, 0x392e2c30, 0x9bbfbf8e, 0x1f80d2b8, 0x0223af13, 0x3fc4f3e8, - 0x35b7dc12, 0xce2966ae, 0xa0eb7eab, 0x7586cf38, 0xb05b8a52, 0xe8ec6773, - 0x956f8fbf, 0x9c4cb874, 0x798169e6, 0x04a384e6, 0xa384eded, 0x123cf2fa, - 0x369db110, 0x4f6bf3fd, 0x5605f3ea, 0x49076f8e, 0xf86f7c05, 0x3aba4452, - 0x01eb88bb, 0xd9676f5a, 0xa6efbc00, 0xda9c22f3, 0x6297e9a5, 0x7e71ac51, - 0xf281e026, 0xe08509eb, 0x52c4f2f8, 0x5fefc63b, 0x05715a59, 0x7f9feb8c, - 0xac4573cf, 0x7611e073, 0xafed8129, 0xe2502772, 0x0ad7ae29, 0xe975df8c, - 0xebf63125, 0x70d6386b, 0x7d39e1ad, 0xd6279c69, 0xad0fc4be, 0x58290fcc, - 0x6050423a, 0x204fb65e, 0x078ed7c0, 0x373d973c, 0x640f27e3, 0xe0de3d00, - 0x2db3f405, 0x963b82cd, 0xeacab19f, 0x07bef360, 0x1fb0b5fc, 0x94aa5eef, - 0xae7b1f60, 0xabce0377, 0x2ba0876e, 0x5ba9677c, 0x9770e788, 0x8866c858, - 0xe9754b67, 0xee03c6b7, 0x4758cea7, 0xc4b27de9, 0x427e7284, 0xfefd2176, - 0xbe30422a, 0x03b5e3c0, 0x229b266f, 0xc0ff23cf, 0x95b0ff9a, 0xd5b0fbd6, - 0xf6497289, 0xdfa004b8, 0xe5ffdff5, 0xbceebd00, 0x0e394664, 0xed1ff3e0, - 0x4f9cadbb, 0x6bdce3a3, 0x3ca4ff01, 0xe5c3f505, 0xc965a871, 0xe5012f70, - 0x54758c7b, 0xf24d2fcd, 0xe946db50, 0xf09bb249, 0x76e22e7e, 0xdf6d4eab, - 0x45efe119, 0x090903e8, 0x69a5f604, 0x166854f6, 0xff14f142, 0x10f62ce3, - 0xca9233cc, 0x0929bf69, 0xf5616256, 0xc2674ab5, 0x9f71aae7, 0x2e65c53b, - 0xb8226e1c, 0xd2360daf, 0x9d9afd42, 0xdaf3ecd5, 0x66f68244, 0x605263ed, - 0xa367ad0d, 0xf88566d4, 0x2d5ba649, 0x4944ad80, 0xbde78a92, 0x7d339507, - 0x32fd65b4, 0x50afec31, 0x0ff31f65, 0xf5ac4171, 0xfcc38fba, 0xfc00bcf2, - 0xf5d43eca, 0x2e35b80a, 0x75cf6b2b, 0x79fe82c0, 0x3f706ed8, 0xbb8f90ac, - 0xb1353f13, 0xeba102fd, 0xb69dbf71, 0x1bb4668e, 0x15de0f54, 0x953eaf41, - 0x75cf9e08, 0xb572ffd3, 0xf611772d, 0xb9938f83, 0xf4169ac1, 0x2d91c4dd, - 0x5f6bc780, 0xa238bbc7, 0x3784c8ec, 0xde806b3c, 0x8c3f6a6f, 0xa2131878, - 0x33e5c8fa, 0x2a7b8552, 0x943ce19c, 0xfcf95ab7, 0x949bdb8e, 0xd1fd71d2, - 0x3338e5af, 0x6bd357f2, 0xace7bea3, 0xb198b576, 0xc13200d6, 0xba110ed8, - 0xc0b350e9, 0x8221bd1e, 0x4f99df7f, 0xbae942f1, 0xfc0ef417, 0x19818bf3, - 0xcd0d9b80, 0x7e82b1df, 0xa3f1e37c, 0xb11d7e99, 0xa227fabf, 0xf6cac3a7, - 0x0f803b87, 0xf22ffbd5, 0x728423f1, 0xea95cb0e, 0x443c6447, 0xe711bdc3, - 0x81ac5e9a, 0xf0b2330b, 0xf9011c7c, 0x0a234288, 0x3a364cd6, 0x7f9aaf81, - 0xcfec26bd, 0x9eb9e226, 0xded64e55, 0xcbf3591a, 0xefe8165d, 0xfe82f8aa, - 0xf5175b97, 0x97f3a25e, 0x5e30f388, 0x67e70ba9, 0x090a4bde, 0x7e0b7f24, - 0xb9eb6905, 0xc4a57e3a, 0x0757e0c5, 0xfff8d1e8, 0x6d93fb27, 0x6a83cfec, - 0x25ae7f77, 0x51b6df9e, 0x4f7b90bb, 0x05c33a7d, 0x89169c39, 0xd95ebe0b, - 0x51e77e93, 0x2dd706fd, 0x7a0d9f4a, 0xea99b13c, 0x8f5a29b1, 0xde09725d, - 0x6bdae75b, 0xd4677b43, 0x5fbc8beb, 0x7be31b5e, 0x1199e88d, 0x5371f307, - 0x5dc060d7, 0x8b924ab6, 0x41d9b129, 0xb6afad91, 0x91c6eb26, 0x8fddf1e8, - 0x2ff35276, 0xf8d2bf35, 0xe4afd85e, 0xcf1686e3, 0xff148214, 0xc7f7dfb4, - 0x5f01e679, 0xfcd938d7, 0x829a0e13, 0xab03fcbf, 0xcfa00ee7, 0x0710fb46, - 0x42231aeb, 0x125e2c99, 0x4f5be9d2, 0xe83365fa, 0xc248634f, 0xc74fcc71, - 0xcf4261b1, 0x4b8bf4f4, 0xab52f464, 0xc0ca7e02, 0xab1ac25c, 0x7bafb826, - 0x47bb3660, 0xbb0e6066, 0xe3dff1f7, 0x7dcc7ad8, 0xd0dc6c71, 0x4b581fd2, - 0xc97e81ee, 0x739bf112, 0x40dd39be, 0xef0fc42a, 0x0ddf738f, 0xb914b0fc, - 0x4e191fb1, 0xde2812e2, 0x0146a432, 0x552437f6, 0x1b8b02aa, 0x40ee3612, - 0x28cbeb4a, 0xdc61f356, 0x16b6a0ca, 0xcd1920e2, 0x6cf5cfb1, 0x5dbf9388, - 0xea29abbc, 0x3886ca3c, 0x541f6fe6, 0x8b937f68, 0x709479d9, 0x0f9286dc, - 0xbf88edfc, 0xf1db3b0d, 0xf50f5b19, 0x1b3e3227, 0x30205fe7, 0xf3c497e8, - 0x6488543f, 0x91f9c24d, 0x99df04df, 0xb23f382c, 0xd8235711, 0x58e297cf, - 0xe09d755c, 0x9ff90f5a, 0xb8165d48, 0xffc3476f, 0xeadf278f, 0x8e2be892, - 0xc367ceeb, 0xc3ea959c, 0x8eaf20f3, 0xaf87e7c9, 0x0d741ec5, 0x8b737866, - 0x9aeffdba, 0x4eb282dc, 0x8788566e, 0x78ebda44, 0x1df7e705, 0xe60b9c42, - 0x05cb1d43, 0xe160a746, 0x7d2403e7, 0x43db869c, 0x27781c6d, 0xb7e9132e, - 0xbc18ff11, 0xb2e2cc1f, 0xfd1a3d00, 0x86a473e1, 0x73c69e73, 0xe15969a0, - 0xee3a4db8, 0xe0512d93, 0xbe722f8e, 0x97fe86d9, 0xdff4c1d7, 0x60fe8788, - 0x6e732e3c, 0x15abf292, 0xae5fdbe4, 0xdb7b0449, 0x0ee3ceff, 0x0f91af90, - 0xcc7f829d, 0xfadf5841, 0x9f731c83, 0xa5a69688, 0x7f05280d, 0x0d3d2d34, - 0xbd79ed53, 0x07198a5d, 0xeef5cd3c, 0x9eb5e31b, 0xc3f30c58, 0xb39fd0d3, - 0x73de779e, 0x6177baa3, 0x8e3ebc7c, 0xd15ebbf1, 0x8026a8f8, 0x5de7759e, - 0x927eec09, 0x90ff7644, 0x8373c993, 0x492a52cf, 0xd1b9ef91, 0xdc47e91f, - 0x1181e633, 0xad9320d8, 0xbf166b88, 0x5065ced1, 0x97e4c743, 0xb9fae8c8, - 0xec294c6f, 0xcc6d919f, 0x30dc5d2e, 0x254bdb1d, 0x5387580f, 0x312d2ebe, - 0x73ae20b9, 0x1c9fd176, 0x517c1470, 0xe02e6b46, 0x91e888fd, 0xd431e36d, - 0x65b7f38d, 0x88409573, 0x9ea52a42, 0x9726241a, 0xb8eeb819, 0xff7314d0, - 0xe6c6ddb3, 0x4e71cddf, 0x06d2d34c, 0x8d8d9697, 0x39440fcc, 0x7aa47869, - 0xae365e98, 0xc5309cfb, 0x6fb40a47, 0x994ea7d4, 0x40dd6104, 0x9c2987b3, - 0xd63d9aff, 0xf40521f4, 0x4b01d60c, 0xe4d47da8, 0x9abf8439, 0xfc4af18a, - 0xfd5f9a13, 0x8e03e602, 0xded00aeb, 0x8f5ffd51, 0xd98232fa, 0xd3d82b6f, - 0xe7653888, 0xc107f7de, 0xdf87dffa, 0xeb0f10bf, 0xba917f40, 0x9e7ec1e2, - 0x78ddffbc, 0xe1f43738, 0x715e2cfd, 0x351e6197, 0xfaecc6c1, 0x6c92b6a3, - 0xdf02d7e8, 0x227ae77f, 0xb3564970, 0x01e58d75, 0x5c9e70d1, 0x554f2f7f, - 0x9ee1b263, 0x5bd63f1e, 0x32e7efc5, 0xcb92a1ca, 0x4db6f961, 0xed0a864a, - 0x7eb6dc7b, 0xa08f6e70, 0x14d93cbd, 0x8d11f38f, 0xc6db459e, 0xfa773028, - 0xaf99b34b, 0x6ccab77f, 0xc317705c, 0xf387967a, 0xc1e748cd, 0x6fac367d, - 0xfed8cfc9, 0xadb48594, 0x7abed4d5, 0x0b79d99a, 0x7c963f63, 0xa7f616a8, - 0x90f25bc2, 0x7862f380, 0x4e3a7eff, 0x883f5679, 0x7ec65eeb, 0x31cdef1a, - 0xe6d55f9e, 0xfcb8cb53, 0xf50788cb, 0x6b5cea2f, 0x369f5b33, 0x1fceffc6, - 0xff61b2ca, 0x91fe3c6d, 0x79c0264b, 0x86871de8, 0x3eee5c24, 0x1efc33e5, - 0x1a57b826, 0x823e93d2, 0x654db669, 0xbf3464f7, 0xaae02f7d, 0xef1db83a, - 0xf6bafb19, 0x94f9aaa6, 0x6b30f603, 0x91fa8776, 0xa43f01ab, 0x97f9d04c, - 0x282e9bd5, 0xf8cbbe6c, 0x7e7f0770, 0x1b37f407, 0x3fab59f6, 0x7ce54c9a, - 0x317ca547, 0xbf321ef2, 0xa6ee7f4d, 0xfad5fdaf, 0x2b5bf5a9, 0xd1fbe2af, - 0xf869df8c, 0x2c78e6cf, 0x6eba52db, 0x9ad16500, 0xf30627bd, 0x4e7868f3, - 0x1197c347, 0x4948cb3f, 0x8110ba61, 0xb147e693, 0xcb3c9a5f, 0xfef216ea, - 0xbaf8d3fb, 0x8fc41a5e, 0x118dc37a, 0xdb721d1f, 0x2367d060, 0xb87a3a3e, - 0x3627e45f, 0xa99427e6, 0x678842ee, 0x9d763751, 0x394fc233, 0xbc1dd529, - 0x0b6cf40f, 0xf8c479c3, 0xd7b99ccb, 0x57cf1c65, 0xe1fdabc6, 0xdb943d3e, - 0x6017d844, 0x5a7bc3f6, 0xb73eed3b, 0x7c04a86b, 0xb4f4c22f, 0x7435c4af, - 0xd2f97768, 0xc0382e27, 0x411cee8f, 0x11d38e30, 0x77f7a7af, 0xf9e91136, - 0xa543971d, 0x3f8ffad4, 0xd2da8d83, 0xda1dfb8a, 0xa071e4bf, 0xb145cd2f, - 0xfe27f9fa, 0x86f7e11d, 0x4cf5c5dd, 0xe02c979b, 0x99abbb72, 0xda2f67ad, - 0x30f28a58, 0x437ad7ee, 0xd0661670, 0x638d3caa, 0x51bf9014, 0xdf5c4b3e, - 0x51607dc1, 0xf08f2272, 0xdc1e017d, 0x2f5653a7, 0x28c3dc62, 0x93bb7cbf, - 0x6b57a39d, 0x42b71e70, 0x790ebd8a, 0xb5f4dda5, 0xc7ec63fa, 0xed0126c2, - 0x65fe91a4, 0x0dd76a5b, 0xd67fd020, 0x847ee8bf, 0xe25da206, 0x55fad4fd, - 0xff785c46, 0x50fad440, 0x7224f5db, 0xe6f2f53f, 0xbf2fb8c5, 0xb09ff69a, - 0x85c61238, 0x7a35fa34, 0x1428fd8d, 0x8816c8cf, 0x5c16aee3, 0xefa39f60, - 0xeeeb7327, 0xb0d85c3f, 0xafc8207f, 0x66fb625d, 0xce02fddb, 0x203f3b0b, - 0xbd607d6c, 0x3d69eb80, 0xed99afca, 0x8e59ea07, 0xe7dc0a35, 0x8851b657, - 0xf565c729, 0x11a1aef9, 0x60796a76, 0x8ea86b86, 0x1fdc46de, 0x54a1a2b2, - 0x9d807cf7, 0xfdb893c7, 0x48df4dee, 0x38cc624d, 0x9a5fa693, 0x97fa69be, - 0x3cd9576f, 0xcc1c0a47, 0xfebb04c8, 0xa84bce18, 0xcedabe5d, 0xd1e607d7, - 0xb89faa57, 0x581f5ba0, 0xb3e4c792, 0xe7c62c44, 0xca57d93d, 0x1e7d9d07, - 0x7fefd767, 0xd1fdb6f8, 0x85e9a1fa, 0x5ea33fd6, 0xc5aff918, 0x30728cd5, - 0x82e81ff2, 0x7b1bc1f9, 0x0407816d, 0xa74677d0, 0xe915af7f, 0x702b48ec, - 0x3fc839c1, 0xce9407c0, 0x31dbf4ea, 0x9496235f, 0xc75e71da, 0xfae34de7, - 0xe1c83f16, 0xab4ed67e, 0x473b2c7b, 0xb80c9254, 0x36db5298, 0xf8a4e2d3, - 0x2174647c, 0xe53a2bdc, 0x1099b6b1, 0xc8f25efa, 0x5fb84298, 0xb6d6ca7e, - 0xea2e2d77, 0x2d8ed5d7, 0x57e5fb84, 0xf680dd80, 0x10db9607, 0x89e53d57, - 0x9579f2e7, 0x5cce3fbd, 0xcbdd9f32, 0x292bcacc, 0x3c742d8f, 0xfc3c3cab, - 0x959fa0f7, 0x1045c5ad, 0x8884a9b7, 0xaacf1d37, 0x2d908edc, 0x93e78d9b, - 0x6cdb7be8, 0xf076559e, 0xc5ad2eeb, 0xb0f2adf1, 0x0e44fa84, 0x44a8b8b1, - 0xdfa56afb, 0x7ea38dad, 0xdaefe52f, 0xe60b8b24, 0x1fb9f4af, 0x936bb5e6, - 0xf11aaadc, 0x7c1f935c, 0x35ac7407, 0xfdfb75b1, 0x684f0daf, 0xbf78ccbb, - 0xc32647df, 0x67c5a43c, 0x9e58d4c1, 0x7cf138af, 0xc589be44, 0xbfe58c35, - 0x512cecd2, 0xd5170033, 0xaf161487, 0x4fe07fa6, 0x17a61156, 0xeb9d84d5, - 0xf04c3aaa, 0xa1f54b1c, 0x02c73c42, 0xd63ffcfb, 0x735ff0e1, 0x571ba58e, - 0x92054f8c, 0xc08a5930, 0x55bb34f5, 0x9bfb1797, 0x887f4046, 0x7382e718, - 0xa9866218, 0xbfed0766, 0x294d0578, 0x4ba7243f, 0xea5afb84, 0xe1114ea6, - 0x3235a9be, 0x62623fdf, 0xf6b5cce7, 0xb47f389a, 0x64bdb4f4, 0xecfdc807, - 0x36b9ad5b, 0xf3817eb6, 0x6bbfad61, 0x60113704, 0xe08075de, 0x149c80f9, - 0xb3fc02d2, 0xe01e7711, 0x127b3ded, 0x375b37e7, 0x90197fa6, 0x97a6ccba, - 0x57f78a55, 0xfa84591f, 0xdd304ae0, 0x6ff34993, 0x7cb197d9, 0x2642e986, - 0xf6dbf085, 0xc6bf9672, 0xcd086174, 0xce5f6bbf, 0x49c0b0f2, 0xf623b607, - 0x48ff428a, 0x7de38768, 0xc01afb9b, 0xf16264b7, 0x0515e917, 0x7db453d7, - 0x44e96b21, 0x1ef8f00b, 0xa7884dd8, 0xdafc16d4, 0x02eaf106, 0x3dfb0ab7, - 0x837bf336, 0xf1aa69be, 0x7099b455, 0xf02903fe, 0x4fce43ff, 0xc9a42e4d, - 0x8bec0d7d, 0x6bee8d25, 0xb4ed1d60, 0xf606d3dd, 0xad1bec66, 0x377ec053, - 0x5ca7f3bd, 0x0afc9fbc, 0x37d8cf56, 0xf6909ce8, 0x066fece7, 0x8f5c8a6d, - 0xffcf6d3e, 0x62a3be14, 0x5054ff40, 0xaa0ee49d, 0x44dc6b87, 0xbe60b255, - 0x362f9fac, 0xb69f6611, 0x82ce4ad9, 0x10c0c95c, 0xf6455b8e, 0x6bc84e92, - 0x26b49cf6, 0x9b5f69f5, 0x845abd92, 0x23293971, 0xd8117478, 0x7bb1dfff, - 0x1bb7043d, 0x14be73f7, 0xed8cd7be, 0xfec1b10f, 0x177fd010, 0xf2a7f349, - 0x2f8b17f8, 0x88dc9493, 0x07ef3079, 0xec1a7efd, 0x63609f37, 0xbf6807fb, - 0x63abb044, 0x58e98a88, 0x81656788, 0xdf983d28, 0xde8f1a43, 0xdc7feb47, - 0x9649e2ca, 0x0f8ba206, 0x38b3c766, 0x8b074ccb, 0x8dc9c60f, 0x10ff82b7, - 0xc1388e77, 0xa5fce87f, 0x22fee122, 0xae2379c9, 0x11341d8f, 0x3959f7a0, - 0x99f584e0, 0x7524abae, 0xafaee933, 0xab5bcb93, 0xbd4571f7, 0x7372e20a, - 0x7d3fcc1d, 0x7ee09f36, 0x4a53aee8, 0x934dd600, 0x91352c32, 0xf92b9ff1, - 0x0b390f77, 0xfe21e332, 0x408e37bc, 0xc5f613fb, 0xbf0e4099, 0x056396de, - 0x3c04bc3c, 0x32487ca2, 0xfa86ef3b, 0x7a502e92, 0xdb39f133, 0x63a92f27, - 0x277f2812, 0xe15760dd, 0xad67a9be, 0x7ee0378d, 0x784c17d0, 0x8a4beebf, - 0x2ff214ab, 0x609d579d, 0x6ccd9f7f, 0xbcfec38c, 0xbcfec260, 0xf575d714, - 0xc3f74a4a, 0x4a7c5823, 0xec0911b2, 0x502a64b2, 0x73cfa6ef, 0x493cd9e3, - 0xe3cbd3b3, 0x2e3cfe99, 0x200f3c10, 0x7f51f299, 0x9d3afdb4, 0xebf7045d, - 0x2ad59bf4, 0x4ae38e02, 0x4851b8b5, 0xe4cf7884, 0xdb7e8212, 0xe78cbb64, - 0x307f6072, 0xc29b1b9c, 0x0f94efed, 0x813d712a, 0xdc30e04a, 0xe762d97f, - 0x75f168f7, 0x4e39ebc5, 0x226d23ae, 0x5dd791f8, 0x07882e22, 0x8a497f5d, - 0xe74e47e9, 0x10233ef5, 0x97be8129, 0x0095517f, 0xef44f977, 0x2faf4de7, - 0xe0e3053c, 0x39e18b54, 0x8f4889f8, 0x4ff7cf1b, 0x4fee1a77, 0xd6f3e78e, - 0xe47064c1, 0x1d6d313e, 0xf238ba68, 0x8b53f409, 0x65f01714, 0x3efdddbb, - 0x5bfa7bac, 0x38b97265, 0xb63e33e2, 0xa5c46f9f, 0xa1ff5c38, 0x2e03b4f8, - 0xf3afaeae, 0xafbf695b, 0x07eaca1e, 0xb95d821c, 0xc92997f2, 0xf1cde760, - 0xa968decc, 0x97c03b86, 0xcbe18133, 0x3f5bba39, 0xe267c557, 0x01be9a7b, - 0x3d9ea0ee, 0xac7e6072, 0xd78a6575, 0xedd78055, 0xb3f38276, 0xe65ba51f, - 0xed699e82, 0xf86789ec, 0x6aeba637, 0x7587ee57, 0x6c67ff1d, 0xe03698bc, - 0xde391292, 0x3864e87f, 0x3375aaf3, 0xf3fda66f, 0xbf5c65da, 0x8be7e549, - 0x1e92f122, 0x770d1781, 0xef16761d, 0x7533f0d1, 0x3c22bbf7, 0x2119fa9f, - 0x9e124cce, 0x99f86887, 0x9c3867e2, 0x138d8872, 0xddc7e1bd, 0xe6069ce5, - 0x87370a31, 0x280a6e18, 0xb7f7f03e, 0x118fc07a, 0x8af54f37, 0x3cf12f9b, - 0x53bdaafc, 0x186ebb2f, 0x7df7e9f4, 0xb689d31a, 0x8f82fbd8, 0x56ef7e72, - 0x06cc6eea, 0x8993717b, 0x48937f9d, 0xe714adc6, 0x7bb4e3bb, 0x20b26be5, - 0xf6625dbf, 0x19b37b67, 0xbb76cfed, 0xd77183c7, 0xcb9e0b34, 0x0da79226, - 0x06bbf5f6, 0xdfc8d458, 0xc72ef8d1, 0x9a1ca361, 0xeffc0278, 0xf3fc98d7, - 0x1b81ca6e, 0x197a48ec, 0x93b8c393, 0xe21126ca, 0xfdfc8e42, 0xe04faf80, - 0xc3c02d4e, 0x25ef0571, 0xa0ae3eaa, 0xbecdfc5d, 0xbe210bb7, 0x9e1feda9, - 0xc2ede7b0, 0x3ef09182, 0xdc6bd9c3, 0x3c796aae, 0xd276014a, 0xc4fd2f70, - 0xfd2679f0, 0x8025f2bd, 0x72eeec9f, 0x73eb7de3, 0x1d1784e0, 0x736d6e77, - 0x60b3074d, 0x4e7d6fbc, 0x9b1f9d88, 0x1d3dd47d, 0x7dd4654c, 0xb70f1ceb, - 0x715dd691, 0xdffdf462, 0x163e7c74, 0xd7fbf10f, 0xc1c40a43, 0x6b9a951b, - 0x26a27cd8, 0xa68fec0b, 0xf947f877, 0x08e1f8d6, 0xc3ff7ddd, 0x88f3f8f8, - 0x38f7624b, 0x4eb829b5, 0xdf6128f8, 0xeb71f235, 0x39f7ae2b, 0x0f9c5eab, - 0xb96c70f6, 0x576dd71b, 0xfe7c4539, 0x64b21213, 0x125cbc81, 0xca3477ae, - 0x4213d4ea, 0x2a447bf7, 0xe5a76119, 0x8dc5fa7b, 0x70eff685, 0xf00e4c78, - 0x43aea42b, 0x4984ddf0, 0x6ec16339, 0x4dacc7db, 0xa34c7186, 0xb455d29b, - 0x874dded5, 0xc7275746, 0x858e1dc9, 0xf678c726, 0xe0a1d81d, 0x7c0b76b1, - 0x71a0e1af, 0xff2639ef, 0xfc803c08, 0x2c20f1bb, 0x07c6bc80, 0xfcb54f1b, - 0xa10f1f3f, 0x1e9f2081, 0x087100f1, 0x43c2b7c7, 0xc355f016, 0xaed7f503, - 0xfe68fe02, 0xf6c2a35a, 0x0d796a1d, 0x7cf64507, 0x10a5cf7c, 0xf6443fdc, - 0x6d39d959, 0x57ae224f, 0x6d64ecbc, 0x3ed87e74, 0x6498ba98, 0xebf983b2, - 0x8c89efda, 0x57e80909, 0xe106a18e, 0x06e3f40e, 0x71743da2, 0x4176917e, - 0x71377b80, 0xf806796f, 0xd064a197, 0xe2e6318b, 0x877fe010, 0xf8064a6d, - 0xc9b63987, 0x5daf8059, 0x0ebd5623, 0x01aed643, 0x516f2fe5, 0xcd27fdbb, - 0x6af0b5ee, 0x746ff6b5, 0xbd74fb30, 0x020f9d9b, 0x87491dbb, 0x2c41ff66, - 0x9a108740, 0x86cafa63, 0x0db9baf6, 0x41d039ec, 0x205fbaf9, 0xe41fe04d, - 0x5329dc9b, 0x17ebcfc1, 0xcece8092, 0x860c5fbd, 0xf3716538, 0xde8147ab, - 0xd43d6d62, 0x350f5fa5, 0xbf9ad1fa, 0x342bcda3, 0xcf9b487f, 0xe504df82, - 0xd3b9fcd9, 0x26add6cc, 0x6e782c87, 0xeaf3f1f9, 0xbfae6e55, 0x3147ed12, - 0xa42dc7ef, 0xeed2e915, 0xf399b91d, 0x9d10f8a3, 0x39436687, 0x3e513721, - 0x1defc4dc, 0xbfa5c9b9, 0xbc96e157, 0x688ef7d8, 0xbef6f4f5, 0xd6b87c71, - 0x6df46eb0, 0x763e43d3, 0xfa7fc8cf, 0xd2773cd8, 0xc12fd110, 0xce979a80, - 0x327069ee, 0x62521c3e, 0xb9fb578f, 0xb5324efe, 0xe5b9c365, 0x8efe7bfd, - 0x7b2be3e3, 0xf81efefe, 0x494f1389, 0x4eb5f604, 0x012e353a, 0xd2f3e7d7, - 0xab593d70, 0x9369fbd7, 0x88e7b08d, 0x5777ed1f, 0xdc7a520e, 0xc167d00a, - 0x1e67b7f4, 0x77d429ff, 0x2244b8f1, 0x2a144dcf, 0xc710a19e, 0xbfbfe42d, - 0xfe605073, 0x907e5692, 0xf3c5eeff, 0x21b0b71c, 0xc48fbb42, 0x9be7211c, - 0x9a193df8, 0x593a6f5c, 0x8eca4a74, 0xfdfc0f96, 0x5a0be233, 0xf399a15c, - 0x11fcb48f, 0xa77cb7cf, 0xfc096ee9, 0x89a4eff3, 0xeed11dc4, 0xe0ce950c, - 0x2f1ce223, 0x4a7e0c3b, 0xbd3f73cb, 0xde2b8e99, 0x4adc4437, 0xfede6de8, - 0x5be4367a, 0x8ff798c5, 0x9dfbf918, 0xfef1bbe6, 0x2a092191, 0xfb5bd3d2, - 0x38a6ae93, 0x27720d19, 0x65cbcfcc, 0xe51877f7, 0xff9ecafb, 0xd91b6e48, - 0x927bbf33, 0xbf0e51bf, 0xeb80533d, 0xc3c9bd4e, 0xb47ddb88, 0xbfda7e9f, - 0x9fa7ed10, 0xf8af63fa, 0xbdff989c, 0x1af30d2f, 0x9f7bbd5e, 0x4e7f064e, - 0x64f4e9c3, 0xbb899b86, 0xec4c9a7f, 0xf232f2dd, 0xf30773ed, 0xd710e66b, - 0x3fe99bec, 0x78ae0a77, 0xd27e17b4, 0x4ab3fb0a, 0x0e738d38, 0x41ffa217, - 0xe31079f8, 0x1c473638, 0x7bdee789, 0xa19bddfd, 0x5b9832f9, 0xbf0578e3, - 0x36b802c7, 0x6f45538e, 0xb2e049d4, 0x98ab4a15, 0xba7ee31d, 0xce519746, - 0xf6094847, 0x8d3a27a3, 0xabd23038, 0xefdae7f9, 0x4c7e50c0, 0xddf5a24f, - 0xff63e6aa, 0xce61c6a2, 0xdfc69e97, 0x9c95fa9e, 0x1cdee3c0, 0x4e4e17ff, - 0xdbd80b7b, 0xe519be93, 0xecd72c66, 0x90342147, 0xfc1fa983, 0xa9092191, - 0x97850fa8, 0xe3a6e214, 0x3fa8190c, 0xaf8a4eff, 0xe3ddbc40, 0xc27acf64, - 0x1325f55b, 0xe37724f1, 0x663e0e4e, 0x96eddc03, 0x1f106cea, 0xba5ecebd, - 0xda6f5406, 0xf0b305a7, 0x1336879e, 0xf4d99081, 0x102d73e6, 0x251ef047, - 0xa0a03e78, 0xc054ff79, 0x56a5efe9, 0x5e75479c, 0x08b1e424, 0xbcd8333f, - 0x587e06c6, 0x6f9d8530, 0x7448983b, 0x27f790fb, 0x8f06bc30, 0x1dd9bf9f, - 0x2f12fca3, 0x29dc499f, 0xc72e38d9, 0x70a3fc63, 0x3ffb09bd, 0x481d704d, - 0x9e65bf01, 0xce85f380, 0xa40e13bd, 0xee3b7a50, 0x333b444c, 0xdde0f83d, - 0xc6882a4e, 0xcf8b1eff, 0x780a16bb, 0xeaa140cf, 0x59617cc2, 0x98dfee26, - 0x99e48ff0, 0x433e50c5, 0x74cdf9c6, 0x788252b1, 0x2134d9d4, 0x7b8be607, - 0xf85ab684, 0x297f5c1d, 0xfd38876b, 0x7cff30c9, 0x0c7938a7, 0xaa9c76fe, - 0xefe187e5, 0x3cc31203, 0x0bced56d, 0x7cb4cdfb, 0xf7016cd5, 0x66774eef, - 0x7e047f10, 0x7953d70a, 0x6cb8a58e, 0xb8005fee, 0x3fa4599e, 0xc4bb3837, - 0xeb910246, 0xef138216, 0xf7c83b21, 0xfc097769, 0xe7ae7c5e, 0xcfbc7037, - 0xfbac9b99, 0x3f3094ae, 0x6453bbd3, 0xb3e471f7, 0xf4d6a1df, 0x87ae46eb, - 0xf1f9f037, 0x8e864f3c, 0xd288628e, 0x5b3f4088, 0x62e5be47, 0xa5cf0e1b, - 0xe78707e2, 0x1c6ef6d3, 0x8ad79861, 0x17116b95, 0x6f1d6c69, 0x1382ec36, - 0xdfea6ec1, 0x9f4f25bb, 0x97c7a18f, 0x3d9a13b5, 0xc457bd98, 0xf9d9c375, - 0x8902cf94, 0xaebfd3f2, 0x726098bd, 0xd078801d, 0x78dc97ad, 0xbd944e8f, - 0x1be8a0f8, 0x50df8bd9, 0x7aa3cc1d, 0x1f0264fd, 0x41910737, 0x8ba63760, - 0x380a7edb, 0xa6e3a4ea, 0xb48e0639, 0xef9b4771, 0x063d5217, 0x6c3390dc, - 0xa5fa659d, 0xa4efdc34, 0x76c3f7cd, 0xae25fa84, 0x6fd2fe18, 0xf774b212, - 0x4aed847a, 0xe7225f84, 0x64bf7b7e, 0x9547f53a, 0x206fa01c, 0x7b458ff1, - 0x42c97186, 0xf10518d8, 0x1873b4c1, 0x744af1e7, 0xf3e38afe, 0xb02f88d3, - 0xb752427f, 0x15fd187e, 0xd63cce2d, 0x7a53f9a9, 0x8de3849c, 0xa57dd8b3, - 0x810a4e1a, 0xb3ffa09f, 0xf4eb8c44, 0xfdad1b86, 0xa212f0de, 0x564c08f6, - 0xfae1788f, 0xf2f175f7, 0x197c6d17, 0x05f6864a, 0x343e1a27, 0x9bc718bc, - 0x83c434ff, 0xba6f1a7a, 0x0e6f197a, 0xaed1908c, 0x7cd7e6f7, 0xeaf3e4ea, - 0x37a62704, 0x7f1b355c, 0xd82c6897, 0xf937f011, 0x6b8e15b8, 0x1c9c33d5, - 0xc1245b68, 0xec1791fa, 0x1cb76647, 0xfff078b4, 0x81c4c600, 0x008000d5, - 0x00000000, 0x00088b1f, 0x00000000, 0x7cbdff00, 0xd5547c0b, 0x67b7efb9, - 0x332479ef, 0x49926649, 0x1d843c32, 0x09212108, 0x11bc210e, 0x11084937, - 0x88a80ca2, 0x1f01d68f, 0x4d092060, 0x6f53d5ad, 0x52812133, 0xbd583d6c, - 0xf4f47bd6, 0x41ed5837, 0x0108750d, 0x26702783, 0xd0f098a0, 0x7ac0f820, - 0x452968da, 0x5a18921b, 0xf5cf6a0f, 0xf6b7df7c, 0x8326664e, 0x73def7a5, - 0xd62e9f87, 0xf5af6b5e, 0x5ff9efad, 0x4a9b5adf, 0x500a9fc0, 0x982015b3, - 0xe1f95006, 0x06484a86, 0x01203be8, 0x96d40314, 0xfe1b41c9, 0xb1fdb4b5, - 0x0cdd45c7, 0x51df8956, 0xf5c02661, 0x950b7e20, 0x06e6c50e, 0xbc95e658, - 0xd6801672, 0xe1bfde2e, 0x62a82592, 0xf9af7afd, 0xe89b1ee3, 0x5fff35fb, - 0xb800c803, 0x197f7f51, 0x2ffb0ffd, 0x1860a4d3, 0x3b365d5f, 0x978dffba, - 0xa6913fca, 0x62d72c02, 0x3e4fc39e, 0x22f2a793, 0xac24becc, 0x8fb74457, - 0xcfb92673, 0xe32ff1d9, 0x32d7fc61, 0x65f3c5c0, 0xaff7516f, 0xc8ed77e9, - 0x523d48f2, 0xace80166, 0xdb1971b7, 0x7f016e5e, 0x4d2581c8, 0x0065c450, - 0x9d0a0152, 0x581998b8, 0x0d0164bf, 0x136308f9, 0x3ab9f7e0, 0xdf86131d, - 0x07e3883f, 0x8e30dc70, 0x3801c81f, 0xfae4ef54, 0xae1ef56b, 0x2f82935f, - 0x877fe3a4, 0xb8a8b0bf, 0xdfedc59e, 0xdf38fc51, 0x8f0a4be2, 0x93d69b3b, - 0x71830b4f, 0xf73f9eb4, 0x0de3fd16, 0xb6bfdc30, 0xbf8b33fd, 0xf9ebf2f0, - 0xa7e7f35b, 0xcd3f3ca8, 0xcf0c15ab, 0x180144bb, 0x9a5ceb83, 0x635fcd1b, - 0xc6f9589e, 0xfeb96fca, 0x56fcac7e, 0x90c7acc4, 0x32a2f40f, 0xffc38a8d, - 0xa6d0264b, 0x437e5e5f, 0xb3f8b1f2, 0xdb2305bd, 0x72c97e01, 0x974f1e1a, - 0xbe2b7417, 0x19974142, 0xb752baf5, 0x40efd40b, 0xb2b9ca0a, 0x4889c213, - 0x2be7f5d8, 0xf4a8513e, 0x9471f04a, 0x6c7c033e, 0x1e1e5bc8, 0xe425d17f, - 0xbcf0da6b, 0x7764148b, 0x0b1f3d11, 0xa8eb3881, 0xea1471a1, 0x6c39601f, - 0x155a61d9, 0x635c75c2, 0x547d3b81, 0xe0328a26, 0x937db894, 0xf6e3c4d3, - 0x8266c5ff, 0x3e5e01ab, 0x48025998, 0x3cead79f, 0x42011306, 0xbff7e066, - 0xdfb9524e, 0x240824e6, 0x74a0fce0, 0x945ec8db, 0xb45c8012, 0x25b4653b, - 0x364388d8, 0xd91f612b, 0x8157bf61, 0x2fdbb406, 0x050ef78d, 0xc914076e, - 0x4c738fe6, 0x7ef4598d, 0xf61e7bb8, 0xa8a4559b, 0xcb8bb0db, 0xda877eaa, - 0x9d580efb, 0xfeff5ef4, 0x699877ef, 0x1780bf9c, 0x0ed78429, 0xe7da8158, - 0xf241cc3b, 0xe3e48b1f, 0xfdeb09b2, 0xec560003, 0xb8557f3f, 0xd76e5014, - 0x13a37740, 0xc724b9cb, 0x8d7bf238, 0xfece9bd6, 0xe50a31c3, 0xd39740b4, - 0x956fdd02, 0x8fd9901e, 0x41c92694, 0x53f61ac8, 0x5a32ead7, 0x3a256c80, - 0x7ae1b416, 0x4bdafdb1, 0xb4bf5c4a, 0xe1771f48, 0x9321419f, 0x7ad1085c, - 0xf84da8bb, 0x14d012a3, 0x6d4b29c0, 0x97e4ed31, 0xce459e90, 0xc973e7e8, - 0xef5ea277, 0xf84bf18e, 0xf7bcd133, 0x8bbcc53b, 0xf726bfe4, 0xb65ffae0, - 0x43cdef68, 0x9a4e077a, 0x0e7c59e1, 0x6732b1e7, 0xd0da5f24, 0x973983ae, - 0x07fd8bb7, 0xe9153513, 0xc7f49979, 0x9ad1f541, 0xfdf2f53a, 0x940cf6a7, - 0xb9787760, 0x13028579, 0x7b4f1d58, 0x3df98632, 0xff3aaf82, 0x22d9f963, - 0xf91d9341, 0x5bddb0bc, 0x0465ae46, 0x8f913b1f, 0x80c95ef8, 0x295cf3c6, - 0x78fb0d1f, 0x46a25cf9, 0xb9f2fefa, 0xffcd1ad1, 0xfa6be92a, 0x3feffeb0, - 0xfe48983b, 0x2aa8f913, 0x2e0317a8, 0xd659f79b, 0xa1f7a15f, 0x6dc13951, - 0xf5d16f58, 0x81c4e5fc, 0xefc4f9a3, 0x67de4deb, 0xe3651a69, 0xe48515c4, - 0x9c96b737, 0x0d2477c5, 0x7ed107a4, 0x7709d524, 0xfb401960, 0xa40b7d21, - 0x1993eb02, 0x36f34042, 0x9534f06a, 0x29abe60b, 0x1c41efc4, 0xe341dbb3, - 0xe7a429a9, 0x338bd7f0, 0xf923857d, 0x0a8f52de, 0xd6b4f385, 0x1b2534db, - 0x93bd5f60, 0x1ef56deb, 0x57ad5f2e, 0x2c74dcb9, 0x8e20c1f9, 0x3459ab53, - 0x7df86d25, 0x8fb0aa57, 0x8867e805, 0x052005ae, 0x0b73a803, 0x5ef5d61e, - 0x249b8291, 0x27ae1392, 0x97289f82, 0x08dc9ec1, 0x4d2936fe, 0x35b26693, - 0xf28bbcb0, 0x063efc4d, 0x59f3e0ff, 0xdca3fb23, 0x4baaeaa3, 0xbae67e62, - 0x961724b4, 0x52f8743f, 0x6e916ca8, 0xb8017c39, 0x5bf512ee, 0xfe380be5, - 0x7842f0f4, 0x74c3e310, 0x15f10c14, 0xfd13b77f, 0x402c3a33, 0xca80c1f2, - 0xd3a45976, 0x492e7da3, 0x323e70e7, 0xe0c7af9d, 0x30cad67b, 0xe83ed1e9, - 0x17be2349, 0xb4767cdb, 0xc843a428, 0xf66e9355, 0x9cde3848, 0x26578b74, - 0xa6fa26d2, 0x75fe446f, 0xd884e3a4, 0x6323a3bf, 0xa6f68aac, 0x4fbc6f29, - 0x1cd9ad76, 0xcc2b8161, 0x71113dbd, 0x719e133c, 0x9f22bc52, 0xbdf235f6, - 0x01c977f3, 0x73886bf6, 0x9e758fc8, 0x7186f64a, 0xd92e6b9e, 0x7fd256bc, - 0xf5ed117a, 0x54f26260, 0x5dd0cff2, 0xd6b8ebc6, 0x6f91d626, 0xd8bb17f6, - 0x9f0f859f, 0x6dfef7c0, 0xe9fc8010, 0xca1fdd35, 0x9a94f480, 0x907b32f2, - 0xe4d2c3ce, 0xfc9f2a14, 0x9701725d, 0x897b92a7, 0x764d073f, 0xa77de695, - 0x46ce2d5e, 0x72ded17d, 0xd61d0098, 0x0a1cb782, 0xa1ea2795, 0xe5f51b38, - 0x971b7aad, 0x5c9deb27, 0x70f7aa9e, 0x49db1879, 0x76c75e9f, 0xb037b7d2, - 0xd85dea9d, 0x1c31e54e, 0xdba2ca97, 0x96bc7893, 0xb42c92db, 0xd0c9838e, - 0xfa4fcc6c, 0xb70c4e14, 0x3fe01782, 0xab6afb1e, 0x978c2aed, 0x34a17f56, - 0xb3f4f90d, 0xac142aaf, 0xee3c5b1f, 0xbb60bfa1, 0x1fa667f9, 0x9bde90db, - 0x8f5a394e, 0xaa9edd63, 0xfa41d8fc, 0x9d112c79, 0xb9b59923, 0xa63a434b, - 0xcd1c6f93, 0x3660d76c, 0x7af4d3d6, 0xd95d7cc0, 0xa595807c, 0x42e0f93d, - 0xaf597125, 0x577f21b3, 0xa3dffdda, 0xabb025ba, 0xaa2aeca2, 0x7b248863, - 0xb641cc97, 0x7b92b1f7, 0x95bbc605, 0x127fff0e, 0xd17b0dbf, 0x91a43fa4, - 0x49a9987f, 0xbcb372e0, 0xe1a49383, 0x95bf46e7, 0x49ff458e, 0x25debafa, - 0x98cd7db3, 0xc741692f, 0xfa35fb48, 0x96ab38cd, 0x9e66fc91, 0x72a26f2f, - 0xeb8b8559, 0x9ab355be, 0x1ccbfec8, 0x94bf7b97, 0x65d07fdf, 0x512dbd66, - 0x389c5fb0, 0x8e9bf468, 0x7bb8464a, 0xf8312ba0, 0x69f5e92c, 0xd612637f, - 0x8ab27917, 0x0337dd64, 0xb63b5dd7, 0xebe57b51, 0xde576cad, 0xf2e12f24, - 0x6990a899, 0x21d0bed8, 0x2a64c379, 0x4a6a3ff3, 0xe4a776a3, 0xd42db625, - 0xa6289da6, 0xbbd96cf6, 0xd5a7ea90, 0xa7510a32, 0x2ef38594, 0xb9c5bf60, - 0xbe1b5e29, 0xd0fc2a77, 0x85dfd245, 0x04de49b9, 0xf04af3f2, 0x7baa1ae9, - 0x9506dead, 0x6958f1d6, 0x4aa38d32, 0x5bd6135e, 0x1ffd286e, 0x2f894744, - 0xda892405, 0xd7e10a5d, 0xc3f77f27, 0x6bf62732, 0xd9012719, 0xde70a9cf, - 0x85fe889f, 0x026a899d, 0xb38b69f9, 0xb16bde8c, 0x5c4dce48, 0xff5295f7, - 0x7d598e40, 0x7e3dc71e, 0x41e39d9b, 0x8c055be5, 0x36df8e83, 0xe542e386, - 0xa84bf35b, 0x78126e3c, 0xcaadf2bd, 0x41376e0a, 0xe54a9c98, 0xf7e2dfed, - 0xb0fe97b6, 0x1fe38dcc, 0xdf62ef1b, 0x562a7282, 0xf624fc22, 0xbfde8907, - 0x77fb9abd, 0x9d0f9948, 0x0b17fec5, 0x38ac8a52, 0x213bb97f, 0x58c57faa, - 0x497d5457, 0x2562a8f6, 0x16564fc2, 0x6fd54564, 0xb38a9628, 0xe6fbfa23, - 0x57d54427, 0xb38ab994, 0x54dffa23, 0xbeaa2a39, 0xa8aca6f2, 0x1cd342fa, - 0x61ea3fe1, 0xf3b0997e, 0x20d965f9, 0xa9fc898c, 0x037df453, 0x3b26efdb, - 0xa9f812ef, 0x09f885c8, 0x55d652e5, 0xd8b971cc, 0x00affbae, 0x92667b74, - 0x2ebf17ff, 0x83de8f1c, 0x4999fe20, 0x16fc4878, 0x201e2376, 0xdc60a47c, - 0xcca7a08e, 0x2bc71d11, 0xff27cd40, 0x84b9d15b, 0x67b954f1, 0x319a1979, - 0xbdfa31f2, 0x8161f90a, 0x2ee86243, 0xa5c732ea, 0xf46c62b7, 0xabae06fb, - 0x316be9d0, 0x09529bf9, 0x6eb4058b, 0x7ac635c2, 0xb72e3a0c, 0x8ef90a9e, - 0xdfff1432, 0xfd2c575c, 0x7f791b00, 0xa0d74b11, 0x8881c74b, 0x760718a7, - 0xc43e32a6, 0x3e1e3b9f, 0x254f7030, 0xa45737fa, 0xee48737f, 0xf79785e5, - 0x97b8c66f, 0xb8c67bc3, 0x2cd0fbc6, 0xfbc6fcf3, 0x2955cf43, 0xd89df3fe, - 0x73ce293f, 0xf9ff14b7, 0x17fdd173, 0x03a36a28, 0x4828f8ed, 0xfbf100de, - 0x2410aab8, 0x35ad3d2b, 0x43e8b951, 0x747842bf, 0x1340d9f1, 0x837af395, - 0xfeb8adc7, 0x956572eb, 0x1e060df2, 0x8cd75d8a, 0x3a4fb154, 0xabb5497a, - 0x5012ded8, 0x68bfb4ed, 0xd3b55879, 0x8345aa3e, 0x6a2fda0a, 0x691b4d13, - 0x63e5a1bf, 0x549cf589, 0x52f3e7e1, 0xca318e05, 0x5e7f6567, 0xb6d5962a, - 0x8b09479e, 0x60317cd4, 0x94703021, 0x48c15e70, 0x0954779c, 0xa3be683a, - 0xbe1d070f, 0xa57e3f08, 0x29146f38, 0xa7e93a5b, 0x91fa45a4, 0x16825b52, - 0x391637e9, 0xaff5515d, 0xc7d8aa9c, 0xbd45467b, 0x159a9d77, 0x6bf10fd5, - 0x46a0e12e, 0xe42ae40b, 0x5e894d47, 0x7cb177c2, 0xfd7d17fc, 0xe093875e, - 0xaadd9813, 0x97138fec, 0x7f82a5bc, 0xa457cfb1, 0x6fea7d8a, 0x6e583d68, - 0x35f4154f, 0xe2013ec9, 0x3e933710, 0x4f71d6c4, 0xc3c68aba, 0x77a43d91, - 0x22e9bb5e, 0x4ef86f42, 0x29d7d5ea, 0xe9decfa8, 0xc44eefa6, 0x8ba923fa, - 0x699e7d44, 0xffac04cf, 0xd45cb534, 0x374d36af, 0x057e017b, 0xc32baf8b, - 0xe7dbba7a, 0xfb79c54f, 0x12ad8ecd, 0x24c519e2, 0x787b9141, 0x0588fbff, - 0x160a29e3, 0x21734c95, 0xd8ab76ad, 0xa024d72f, 0x25fea3ff, 0xaafc4a9a, - 0xdce43049, 0x1d714193, 0x9134ceee, 0x6ff630bf, 0x87be0b76, 0xfcd8e7ef, - 0xc25f42b5, 0xa5fa2ac9, 0xca2ff7fb, 0x9ed8bd24, 0xe7f5e4ea, 0x21e799ef, - 0x7d74857f, 0x7ffdfa97, 0x3c536ba4, 0x62cc9aba, 0xfc96de9e, 0xf9bb8a52, - 0xd21c51e3, 0xbb70bcb0, 0x4213cfcf, 0xcb8c2ba8, 0xf5848f35, 0x4bc59746, - 0x90fb7d38, 0x6cacaf7c, 0xb213f3d4, 0x9c8de85d, 0x1bb8da62, 0xfaeb9fcb, - 0x3bcd14f2, 0x1819e683, 0x01f51cb7, 0x56e3039c, 0xe93a8a14, 0x0d172c83, - 0xf81ede10, 0xf7979256, 0x7e0763c7, 0xbfac03fb, 0x97be4777, 0x8907f470, - 0x82ab3f82, 0xb07b1a13, 0xbc1acd3e, 0x3e748c2a, 0x967fe694, 0x6b36e0f4, - 0x9beb1270, 0x8d126363, 0xfbc0692f, 0x877f6310, 0x32d538fb, 0x1fee2471, - 0x88d82f39, 0x11ccb7cf, 0x45e6367c, 0xee28da9e, 0x3c5b37bc, 0xf9c0e837, - 0x06ff885b, 0xc074433d, 0x03c72758, 0x45a47910, 0x61e443b2, 0xbce260ff, - 0x1f192d49, 0x359cf7d6, 0xcfaebef1, 0xe68057d8, 0x9b933d58, 0x27399e78, - 0x6c4cc936, 0xd4ccff00, 0xb6af4859, 0xfa7de7ad, 0x7de8ee8c, 0x7f4eacfa, - 0x9bdf03a9, 0x7cfc7ef5, 0xdc7d3cc8, 0x299410d9, 0x89e9cf5e, 0xdf4f37ee, - 0x1f3bcfa7, 0x54cdfcfd, 0x868dbe3d, 0x8e7991d1, 0x33ff7d3a, 0x0a427c78, - 0x3af929e9, 0x516ef919, 0x3a9d9865, 0xeb5a37ec, 0xf90e5fb1, 0x85971b47, - 0x11779da7, 0xa8f56dfd, 0x93f216d0, 0x7b0d2e1e, 0x770d3c2a, 0x7988d4c2, - 0xf837bd74, 0xe0bef838, 0xdc9eb4e3, 0xbac7cf9f, 0x410cd3b9, 0x739d7875, - 0x820d3e75, 0xd3a0f3e0, 0xd99e7cc2, 0x61e9cbf5, 0x98f5647c, 0x5f588d40, - 0x6a089a82, 0xe7b53f84, 0x65d546a6, 0xce3a3e43, 0x9f8fae98, 0x351d1de4, - 0x0c37818e, 0x5a9abdf9, 0x643849de, 0xe31d63ba, 0x13d9948e, 0x3e2dc6a2, - 0x64272b1e, 0x2476e11c, 0xd7089ff2, 0x70a2569f, 0x80772cc6, 0x3fb30038, - 0xc9706254, 0x68ec9976, 0xe7e8d9ee, 0xc8cbb4e6, 0x84fc72ed, 0xef9f3fa9, - 0xe9f9fbfe, 0x99f9a2d2, 0xcfcd1156, 0x3f345f74, 0xf3455733, 0x9a3f946d, - 0x4dd6632f, 0x6abf6a89, 0x7d545163, 0xa37383fc, 0x006167fa, 0xdc4fac8c, - 0xffaa24ba, 0xa22beda4, 0xba9f93ea, 0x5e7faa2d, 0x7b544d70, 0x2baacefe, - 0xa8617f92, 0xb11faa2e, 0xf20df4d7, 0x1fedbabf, 0xeff9e6a2, 0x34a2ff96, - 0xcbaf2f3d, 0x438e997f, 0xc7fa1a5c, 0x4538e1a2, 0x93f215e9, 0xbe37f6ae, - 0xa04bfca0, 0x53bce544, 0x1b780960, 0xd909edb1, 0x1b5f9127, 0xa136ac83, - 0xc13268df, 0x8ff7f23a, 0x879c4c9a, 0x2abcec34, 0xaa8be04d, 0x9ff7e134, - 0xf8a69b46, 0xeccff066, 0x78449ede, 0xa0993643, 0xe29ae29b, 0xc671bf65, - 0x716be101, 0x7034793e, 0x7934ab5e, 0xa899b2f6, 0x329bf287, 0xd1e51fef, - 0x7d71507e, 0x3f1fc78d, 0x8b9ff941, 0xfa4a9b0e, 0x03faa72a, 0x7d70b714, - 0x2461e7a1, 0x3eaf795e, 0x49f6893c, 0x67957d46, 0xbfea66e3, 0x93858eea, - 0xf43aff68, 0x498e8efc, 0x88721165, 0x388adf5c, 0x697be8f8, 0xc4673f22, - 0x6aacdb87, 0x6bca0f63, 0x3ffc2c9a, 0xa5ef85c6, 0x903ffae1, 0x9c0b361e, - 0xbad33015, 0xde724e31, 0xba8085df, 0xe194cb0e, 0x8d7ea478, 0x84c1f54a, - 0x26f9dc68, 0x08fb4411, 0xffc72a5b, 0xbb7f0d5b, 0x36f98f2e, 0x3fee88e8, - 0xc144f778, 0xd7236fcf, 0x2c67df90, 0xdd061d62, 0xfc3f75e7, 0x7b87eea9, - 0xe446ffc9, 0x78edd79b, 0xf5f0893c, 0xa7815c99, 0xe8cfe78d, 0x4d267d72, - 0x3bf5e9e0, 0x79919c13, 0x2b90eac7, 0x36db5eaa, 0x423679ca, 0xeb1bd70f, - 0xad0a4bf0, 0x3f6e8363, 0xc93d9dd5, 0xf1e301b7, 0xdc70d3a7, 0xbf171d9a, - 0x37de8fbd, 0x3888640d, 0x6ef9e01a, 0xd7180f79, 0x4415f2df, 0xd297d2e1, - 0x25e57e44, 0x95cb0ba2, 0xdf513858, 0x776c6256, 0xfcc6f951, 0x7c3bb272, - 0xbeb0961e, 0x84cc13ac, 0xb3fb96d3, 0x53f4c4cc, 0x2f677de0, 0x9a5f6d2e, - 0x04dcf3ca, 0xc5c5333e, 0x9d5dbf77, 0xc686fd44, 0x4319c633, 0x2bd459b9, - 0x419cc057, 0x246b9af9, 0x9f380dc6, 0xeefb9e8d, 0xe299b318, 0xbbdf31af, - 0x0ef0bfe0, 0xf00ac5ea, 0xf8c6b8f2, 0x7e51a900, 0x90cb03f8, 0xbf24ed1c, - 0x98532eba, 0x677539f2, 0xd1fe7cac, 0xebf030df, 0xdfce9007, 0x57b17d55, - 0xbb7fba42, 0xfb57e07a, 0x4fadf9f0, 0xb5c5dfa1, 0x87fddb66, 0xc3ce22d3, - 0x917ddcce, 0xc8f10ced, 0x33924ff3, 0x25eac97a, 0xeaa0f8fb, 0xbc489ca5, - 0x616d227f, 0xb307bd27, 0x479ee2d3, 0xab2beec4, 0x6ed93f48, 0x8699c655, - 0xeba7de5e, 0x930bdd65, 0xd25d79f9, 0xfd447ad0, 0x57f39979, 0xbcac0775, - 0xd7477fbf, 0xbf17aa87, 0x9f991998, 0x54bd416b, 0x7274a873, 0x2a9ce749, - 0xf1cf66f2, 0x6fd4a9c1, 0x21efeca3, 0xe978393d, 0xefaa64e3, 0x5e4bf379, - 0x6574dc0f, 0xf323f7f4, 0x9b5cf922, 0xf92ef034, 0x567dea93, 0xa550f295, - 0xdd8ef2fb, 0x4e9af58e, 0x9eb83bf4, 0x239eae0b, 0x6a7ed34f, 0x979404bf, - 0xb02709aa, 0x9569af73, 0xaac79482, 0x65bddb6a, 0x9aabd60c, 0xba931797, - 0x3f0b26d6, 0x0522d356, 0xa7f03c69, 0x748a7f31, 0x357d28db, 0xb00b1fef, - 0x18a8efbd, 0x787d5cff, 0x4ff459ea, 0x9d9f2d7d, 0xb4363a23, 0x763f3959, - 0x196c292e, 0xd85ef383, 0xea02852d, 0xb9f6ddb0, 0x5d6a3ec4, 0xcd0b31e8, - 0xe5b9eebb, 0xfb0f04d9, 0x90b49df6, 0xfad75c7f, 0xbcfeb958, 0x20fb8458, - 0x9dfac5db, 0xf322931d, 0xfc21f749, 0x81f8c883, 0xf70805f4, 0x09e39082, - 0xdaab3e5d, 0xbb123627, 0x7dedafd0, 0xe6bf625a, 0x3bdf9374, 0xffdfebb8, - 0xffdde695, 0xff98932f, 0x7fc657c5, 0x4f1805f0, 0xc0f3e8d4, 0xda1653f9, - 0x9ab4d61f, 0x173bc5cf, 0x77dbbefa, 0xf0c67b95, 0x571636fe, 0x3880b16f, - 0xc10099b7, 0x381e29e7, 0x91ab2c06, 0x07511f9e, 0x0e7147a4, 0xdd60d658, - 0x71467646, 0xc608e3c2, 0xb9d717db, 0xf70f9e15, 0x9de31b08, 0xedead657, - 0x858f6aa5, 0x9e3570f2, 0x75e90b5e, 0x7113f84d, 0x51f6df5e, 0xbf6716b9, - 0x7e16ed5c, 0xc303d0d3, 0xa7d2ebde, 0x87985db0, 0xc6c860e2, 0x66b85f76, - 0xdd53e280, 0xda0ed47e, 0x03fcb817, 0x6f607744, 0x2beb4a82, 0xccc9f7dd, - 0xfe79889e, 0x5187dba4, 0xa3f979af, 0xe7e266a9, 0x2aa68f9e, 0xfbcfc349, - 0xe2eb1c32, 0xddaa55e5, 0x4e6f4e22, 0xb68f9df6, 0x186f0483, 0xb769ade7, - 0xda07f9f3, 0xe28e96c1, 0x75b83b48, 0xf3d20edd, 0x168bd976, 0xcb6d3501, - 0x3fdc0dfd, 0x91e24bc9, 0x480616db, 0x8fa7650f, 0x8afe13f5, 0xcfd4cdf3, - 0xae52267d, 0xe91b7fdb, 0x4f08e291, 0xd46bcc8a, 0xd17e7a98, 0xb75c9121, - 0xaf9a266b, 0xc96fd808, 0xef0f5f0e, 0x54338a9f, 0x9e1ec7da, 0xa7c40e51, - 0x38901e9f, 0xf54e6b5f, 0xf922cd6f, 0xbfb9951e, 0x010bf0e5, 0x9bee973a, - 0x9f44c506, 0x4e9fdeb1, 0xe38c830b, 0x2f042e6c, 0xff79bb4d, 0xdfd21e2d, - 0x611fa69f, 0x86f7617c, 0x234afc80, 0xe7ca06e2, 0x61420bd8, 0xd721271a, - 0x3ce32c57, 0xf3276e79, 0x7bf562cb, 0x4d941f29, 0x4d875c75, 0xfa23adf1, - 0xb144ee6c, 0x657b1e9f, 0xb23eba79, 0x1bce857f, 0xe92f9cfd, 0xed3d0b33, - 0x5f180abb, 0x399d1df3, 0xbe09a4d4, 0x6b2e76c1, 0x46a63adb, 0xf044dbc6, - 0xdf79e8db, 0x44bc5bfe, 0xd75139bf, 0xb6448cf7, 0xfff9d88b, 0xe499f499, - 0x35b35a6e, 0x7c4cf88b, 0x7bf64753, 0xf067ef5a, 0x2e7f1403, 0xaa922bd9, - 0x8d0fcbc5, 0x4e3c9777, 0xea9cdd72, 0xf01575cb, 0xc300acf1, 0x76b8c49e, - 0x57fffd87, 0xe91fff64, 0xf8a2dcfc, 0x4ddfc46d, 0xf16cdd7a, 0x7fb64ea9, - 0x0ff34a9f, 0xfc746fad, 0xf6e9b5f5, 0xff8265ba, 0x4fb7d71b, 0x15399f5f, - 0x4bc68df5, 0x4e67ee06, 0xff48060e, 0x78a0929a, 0xec3e3e13, 0xdd90f72a, - 0xc5f4396d, 0xa6f7b238, 0x2807af24, 0xd66075af, 0x2dfbb22a, 0xfd636fa3, - 0xbc85f4ff, 0x9e623922, 0xad256913, 0x697ebfe4, 0xcfe2cbac, 0x42fc75a5, - 0x5d6323d7, 0xabdf6ee9, 0x11bc88ee, 0x915f758c, 0x9fbe80fe, 0x17f1eaf3, - 0xff9c73f7, 0x2f4487eb, 0xd6ee279d, 0x3e02b771, 0x783b1bd6, 0x1a55c655, - 0x1f7ba31c, 0xd8261d8d, 0xe4a6cb46, 0x5d39c454, 0x36326cb2, 0xb70d9a7d, - 0x4c6c74e6, 0xebba6fed, 0xbd213496, 0x0b2021fb, 0xaf9d167c, 0xa4d24d00, - 0x6bc53cc8, 0x14f3f155, 0xc91bf8cf, 0x9e56ff2e, 0xb4d84e62, 0xf7f292da, - 0xbace2be7, 0x9f3df7a3, 0x2a2655ba, 0x31f42b94, 0x8a0c4e14, 0xa74c17bc, - 0xf133537d, 0x067bff12, 0x2df6cad7, 0x5cdae5f5, 0xfbee4f68, 0x8b1d6db7, - 0xd62d9776, 0xfa46f54f, 0x3dc0a77b, 0xd78ff943, 0x46ee30a6, 0xfef3273f, - 0x12d3a9df, 0xc462b723, 0x88f7c06b, 0x27f2a352, 0x265f23e1, 0x4aed7e93, - 0xb922df55, 0x7cc9740c, 0xe941244f, 0xd8e2b8b1, 0x03c23ed9, 0xd38bf7e8, - 0xd6c43ec5, 0x6d17ce26, 0x317ec6aa, 0x269ce9c1, 0x79c5d847, 0x579fc8b7, - 0x9c60f91f, 0x05dc3105, 0x02e4f1d3, 0xdec37f1c, 0xc34a6496, 0xf6f33fad, - 0x5392ba4c, 0xe91df8a2, 0xa54ffeb8, 0xc236391d, 0x53835ba9, 0xf0a13f89, - 0x93f21484, 0x94040a85, 0xf1f138a2, 0x14de22a9, 0x87c53cd7, 0x3ed850ff, - 0xe5e12d7d, 0x2f58b0da, 0xa6c661cd, 0x7ae036bc, 0x2a635b5f, 0x6ffb578d, - 0xbf934607, 0xe05d297a, 0x4d2f179a, 0xa02bef11, 0x74acff50, 0x41e7ae97, - 0x5f0be513, 0x7d8cf3d2, 0xcfdc4c97, 0x6db0bf98, 0x3d44eca1, 0x3f6f0828, - 0x76cd79c4, 0x4df24aab, 0x3f040e78, 0x771813da, 0x0c5c1ed6, 0x5dfae714, - 0x7db095e0, 0x6fc0e257, 0x0e061f49, 0x773a5558, 0x876e704d, 0x977f1c54, - 0x0f2b4f7e, 0x31c5b215, 0x2f98dcfc, 0x94e7fda1, 0xe0bd2413, 0x6504dff3, - 0x88e35c3b, 0xd31277e4, 0xd5eba25d, 0x89b0c4ae, 0x260645ce, 0xe9875ee1, - 0x7813a61a, 0x3cce835e, 0x2cbbfbf6, 0xe07ee703, 0xa49cba66, 0xe8207907, - 0x2ac9f684, 0xa704d1f9, 0x7048ebc6, 0x3480deaa, 0xa9daae92, 0x6ed0fc08, - 0x35e7251e, 0x6baed877, 0x36eb8713, 0x135d85b4, 0xff8f3f40, 0x8f3a36d5, - 0x8393aa1f, 0xfefc3d99, 0x6c2fe92d, 0xf9cb1a6b, 0xa28c80bd, 0x949963b6, - 0x7954eb4a, 0xb545e87d, 0x07c122f4, 0xb767afba, 0xfea1f689, 0xaa0ee7a8, - 0xaf3f443b, 0x925f69d5, 0x8742f6c5, 0xf07843d7, 0xee7c297e, 0xded7b45a, - 0x05297cc7, 0xd35eaeb8, 0xb19a07a1, 0x87569fdf, 0xe93ee872, 0x1aff5673, - 0x3e57cfd2, 0x2148f35c, 0x665ddbf9, 0x9df9256f, 0x18cfc09e, 0x5668bf87, - 0x1dd845b7, 0xe0c81d8c, 0xf33180fb, 0xf4d99ed4, 0xfdd7c233, 0xce9525fb, - 0x03cdfbbd, 0x9aee88e3, 0xe85a3ff6, 0xfeed64be, 0x4b4f188f, 0x9a1afe19, - 0x035b766f, 0x039b6bdf, 0x1b5ef9db, 0x9fbe43fa, 0x7f08f218, 0xe73a7832, - 0x390886d9, 0xec2e913c, 0xe3fc060d, 0xebb55e29, 0xf6907af6, 0xedee58dd, - 0x8d2275b8, 0x07cf57bf, 0xc035ef18, 0xf7c431a1, 0x971af04d, 0xa0fef3c6, - 0x967a4152, 0x4eedaeff, 0xa3ffa22d, 0x3dbf02e9, 0x66702e9a, 0x89bf8676, - 0xf1df5de8, 0xd69925b1, 0x8e343679, 0x4521b9f6, 0xf1c6714d, 0x1bf64323, - 0xcab54f63, 0xd7fa8580, 0x2bf6079e, 0x14a6ef28, 0xef4bdf94, 0x8d594db6, - 0x4ca2f7cf, 0xe2ae2852, 0xefe294fe, 0x0c6fb35e, 0xe7786ff5, 0xc7e4a9f3, - 0xe74f481e, 0x607e7ff5, 0x1be278fd, 0x22497fea, 0x606ed9d9, 0x69d866bf, - 0xbe29d901, 0x5ffa405f, 0xf63cf54c, 0xdd2cbbcb, 0xf72ed84b, 0x12ec809a, - 0x01ed9ff5, 0xf849dff5, 0xf689c0ae, 0x664fefc0, 0x6dd5df3b, 0xa32718d2, - 0xf5c49f5f, 0xbea91b92, 0xc9ccbbab, 0x05f74e76, 0xc35ec88a, 0x109c7887, - 0x9d1224c0, 0xfca8be04, 0xe9993b88, 0xe7e5fc36, 0x86e3d06e, 0x75c5e29a, - 0xca3965d8, 0xa4e2223e, 0xf4711ba8, 0x9edb33c9, 0xee817b40, 0x0fdc28d4, - 0xffbf0bef, 0xd5563d5d, 0x59773ebd, 0xeeb3ae33, 0x07edcc84, 0x585e7df5, - 0x7a4393d7, 0x86e2867e, 0xefdc5d3a, 0xb033e7a5, 0x675df74e, 0x094b1b6a, - 0xd8aecd63, 0xb9ca987e, 0x412950be, 0xbaabf9c8, 0x99859b0f, 0xb5fe93e7, - 0x9f2eba1e, 0x9ff5cdee, 0x920242b1, 0xc0e5fad8, 0xb5c45f6f, 0xf910703d, - 0xe14e271f, 0x10ff5872, 0xcf018d6f, 0xc97ef6c8, 0x4bbd23f0, 0x5afb1f48, - 0x123ae1e5, 0x4d8a8352, 0x3fd277f5, 0xbac016dd, 0x9f7b433f, 0x99c7e254, - 0x3f49f7fe, 0x997e4ffb, 0xf7b96641, 0xb7c7d8b4, 0xd27cb45a, 0xb809d69f, - 0xa7a38db5, 0x3c8ba5af, 0xe215b14f, 0xa57e4b9e, 0x009cc1c7, 0xfef1223c, - 0x5106765c, 0x655a17ee, 0xe7f882cd, 0xce56043c, 0xe7a37f23, 0xfd01ef6f, - 0x941fe1a7, 0xf57abdcf, 0x182bc21e, 0x627deeb7, 0x89bfb9c4, 0xbb6d69f4, - 0x6b84ff04, 0xfc4cf75f, 0x5e46097b, 0x1db6beeb, 0x3ca0c647, 0xee8b9eab, - 0x9ee861b7, 0xbdf7887b, 0xefa39a1b, 0xae957c1b, 0x308996e3, 0xea0b7091, - 0xb307fb13, 0xd4569d02, 0xfd3257df, 0x7e5e109f, 0x84f824c9, 0xf2ed957e, - 0x671eb713, 0x1a3f844a, 0x8f7c00b8, 0xe8676f28, 0x99d7dd30, 0xa5e59cdb, - 0xa22ae639, 0x165b6e7d, 0x825019c7, 0x9837dd32, 0x19cbf9ad, 0xd3b4075f, - 0x9d642f74, 0x89c127ee, 0xa3bf287f, 0x8e9d6baf, 0x460beee7, 0x82073dd3, - 0xdacf348d, 0xd1fee29d, 0xbff19dfa, 0xc7d5a813, 0xc9d4f0d9, 0xac0e9423, - 0xabf7450e, 0xdb53f9d5, 0x05bcfd16, 0x9f181278, 0xfccf7d11, 0xfc43ef4a, - 0xc5f02cc9, 0x4638fadb, 0xc219b5fb, 0x7920d67f, 0x410ddf24, 0xb37a4839, - 0x0b240a4e, 0xd58e0b7c, 0x865df748, 0x65f7e8be, 0x73f9d6ef, 0xbc2fae97, - 0xfabf7c2e, 0xe7482919, 0x24ff7780, 0x427bfe9a, 0x1f49cbab, 0x5d6af562, - 0x6df199b3, 0x10b46c15, 0xabd58dbe, 0xd97d21aa, 0x1638a16e, 0x7e354fab, - 0x0b7432e9, 0x4b7ffe5c, 0x98737af7, 0xffeb4cf3, 0x3ca5e4a7, 0xdfadbdd4, - 0x745e50b1, 0xf9087da4, 0xa27a1956, 0x5defebaf, 0x7c86edcf, 0x9614c0a7, - 0x15da456f, 0xf1a283ee, 0x50cb6ef4, 0x7cf3929e, 0x38139d83, 0x51e86e3f, - 0x3ae538ec, 0x14fc5f2e, 0xada17970, 0xa2f84ed4, 0x2bc9b8ff, 0x4c7f9ca9, - 0x4c3e442e, 0xe103203f, 0x89f6fe8d, 0xfe90078f, 0x37c513a2, 0xfa7cbe52, - 0xd83f8c09, 0xf8b3a7be, 0x115fe457, 0x7d91a4e1, 0x4ecaec2f, 0xc783bdfb, - 0x7fddf8e1, 0x4af1e8bc, 0xcbc7c3f2, 0x095c698a, 0x787ee9db, 0x1a871e91, - 0x7bd9178e, 0xfdd1e222, 0xbedf2219, 0x47fbf3c5, 0x78b05f69, 0xf94bd9b7, - 0xff66c58e, 0xafa404a6, 0xdbc905e8, 0xe91db380, 0x8d24f43e, 0x52a4f68b, - 0xeef166be, 0xf6a21def, 0xd3125dda, 0x28bedfdf, 0xc7c5177f, 0xb8a5eca0, - 0x577edfd7, 0x7384bdc1, 0x7053dc0e, 0x477cc457, 0x595f8552, 0xe399957c, - 0xfb68ef71, 0xcf292b2f, 0xff60eda9, 0x1eeafbd0, 0xb0577f0b, 0xae0f024b, - 0xf0e788f3, 0xbd0f89af, 0x085a4efb, 0x9eb697e4, 0xf1c4f4b4, 0x017946cf, - 0xce6171b7, 0xf0b76ebf, 0x7fbdca3d, 0x6b7ad0b0, 0xf388fb9e, 0x126d5569, - 0x67aaa7fb, 0x794aa0e4, 0x58af039e, 0x9a6b3f48, 0x8accc825, 0x3b73376c, - 0xffaa51f9, 0x65f859b1, 0xe8d7ef43, 0xbde86e7a, 0x746b0761, 0xd6d775ff, - 0x17bf3d68, 0xf1a32db4, 0x579a7bfd, 0x7ba03df3, 0x5ff7c7b6, 0x4b5c1f86, - 0x2b8c52fb, 0xee8a9f6b, 0x7e90df77, 0xc7bfd807, 0x3257c9fa, 0x3cd8f3f4, - 0x1efd23c8, 0xaf19af0c, 0x7e7d3da0, 0xc43c6ab2, 0xd71e3bc9, 0x8f1180f1, - 0x8e26c307, 0xfafdb167, 0x285a2eda, 0xfe76d68e, 0x796bf199, 0x872c67fb, - 0xbe0ef6ca, 0xf83d7aaf, 0xaf1f1037, 0x093bb76f, 0x08f65747, 0x6ed25fbb, - 0x6a25060d, 0x7c91350f, 0xef8a0ffb, 0x4aaf023b, 0xf740a38c, 0x7e756b7f, - 0xb7f9d5ae, 0x6367f716, 0xbe8adee8, 0x772fbeff, 0xe2ba11c7, 0xdf3fa351, - 0x993875d0, 0x8404b8f8, 0x12125a7f, 0x8790c9fe, 0xc6465f11, 0x936f81d1, - 0x5bb7d73c, 0x52f8bef9, 0x6d2d3fdd, 0xc593df16, 0x51fe8bfa, 0xddff9176, - 0x8d8de82b, 0xd1ad35a7, 0xd232bbfd, 0xea0fdfd9, 0xc313f878, 0xa8f2e8df, - 0xe53b001c, 0xb2a897e7, 0x756fc837, 0xe77f342b, 0x63cf8954, 0x2989d53b, - 0x194beef1, 0xce3a9be5, 0x28cbea37, 0x43fd864f, 0xc88eedce, 0x998dfc7d, - 0xcd54af02, 0xcf240391, 0xb2cf7d88, 0xfbb8aca2, 0xba44c81e, 0xd77b18df, - 0xee45a64f, 0x391db47b, 0xf23f67a4, 0xf7495e3c, 0x859b6a8c, 0x8d9be87f, - 0x8e10a6e3, 0xb5c5c607, 0xed20d6cd, 0x4f516a4f, 0xd2307bf8, 0x76bfb20f, - 0x07e91169, 0x991c1bee, 0x3a72cf48, 0x2ff5c4aa, 0x8e38c36f, 0xfb2f2fc3, - 0x2baaf58c, 0xf91bac5b, 0x1f6f1996, 0x6a1fec61, 0x6a9c092e, 0x7a51af3c, - 0xd3511f78, 0xb749ee2e, 0x5c62fa1e, 0x7fdbd216, 0xadc63fe0, 0xa64172c6, - 0x25adbf88, 0xbee98fa1, 0x6cbbe7cf, 0x90e8f171, 0xd89a97bf, 0x3dcc6a0e, - 0xf6578c19, 0x859c2e23, 0x4fedf37e, 0x7ad1df79, 0xca4ee128, 0xf1adf5c7, - 0x837e778f, 0x13601a9c, 0xd04ddae3, 0x9ee125c4, 0xd6b81c48, 0xdd0fee29, - 0xaa49c7ab, 0x7d7a8c3f, 0x505df62f, 0x03eecf14, 0x2349e65b, 0x1bf0dded, - 0xafbebad5, 0x85b1d82f, 0xf163e08e, 0x476eb551, 0x2e39fc88, 0x1ba2e2c6, - 0xb4f5a333, 0xc644ede1, 0xb25dfdb9, 0xc8c47293, 0x268c5fd7, 0x7ef887dc, - 0xeb3c9c42, 0xf65ebaa7, 0x0dbee7ea, 0x9be665b3, 0x0d288e69, 0x63fc851c, - 0xe93fe97d, 0xcb1c5208, 0x04caf83f, 0x9dfaff92, 0x2445e7d1, 0xdfdf3f3f, - 0xaafcb20a, 0x433e7643, 0x3a5fda32, 0xd214caf8, 0xbfb786b3, 0xf97211cc, - 0xbee2c722, 0x29467d3c, 0x6bff6249, 0x77fec492, 0x4c93d2af, 0xfddaaefb, - 0xfef22fb2, 0xbbe721bc, 0x4501fd75, 0x65d7f3ec, 0x686f5caa, 0x3a617a17, - 0x7f9c4a20, 0x98f3c8a5, 0xed11fe79, 0xdf2fa825, 0xe880b710, 0x9ad7d942, - 0x6aef5807, 0x9e989a4f, 0x198393da, 0x05ef11d9, 0xf24cdc68, 0x801b0d7b, - 0xc81d88fd, 0xefa52ebf, 0xf4beb10f, 0x59c604fd, 0x523c2647, 0x64adce29, - 0xc0f5bf20, 0x239355db, 0x3d05fffd, 0xc1f103ee, 0x09e72843, 0x87cebf31, - 0xcf42b04d, 0xae3d0813, 0xee2c71d2, 0x8ec89aaf, 0x5757f763, 0x0e1b938a, - 0xc7f28158, 0xf9581fb5, 0x07e7d03e, 0x1dfef2d6, 0x9327f92e, 0xffbf019f, - 0x381f2a6a, 0x3d3276b8, 0x7de0fcff, 0x53de7357, 0xaf9514da, 0x1e7d1008, - 0x797f51c2, 0x97c276f7, 0x90e30a5d, 0xefd3aea2, 0x9eeaf9d2, 0x9b7f3356, - 0xc677bd59, 0xc22481e3, 0xe94b454f, 0x9d3d9dbb, 0xe21feb0a, 0xd947032a, - 0x289d4719, 0xe3851c66, 0x165c82f8, 0x71a4ab1f, 0x5314944f, 0xc9db0937, - 0x1c274d9f, 0x55c618e5, 0x9cff3d06, 0xdfd9f829, 0x13f9c091, 0x3d082609, - 0xba28ec83, 0xcebeb437, 0x9b436438, 0x86bdf51c, 0x4ceedef1, 0xd7b0ae71, - 0xa490b3d0, 0x16ed1eb1, 0x3db686e5, 0xf58eb419, 0x49eb10e6, 0xb459b343, - 0xd02512ef, 0xfe0ccdf9, 0xfc4038d8, 0x508f4639, 0xc12c4b2e, 0x77db84b1, - 0xea079d0f, 0xe28239f7, 0xe7635d5e, 0x686efe44, 0x3b8f73b0, 0x4e39fc5e, - 0xda4833e7, 0xcfb12cd1, 0xf3af6d89, 0xd1c67c88, 0x1e2fc233, 0x1c9fe85d, - 0xa0063fcf, 0x25fbec44, 0xe6ad7e5d, 0x86e7788a, 0xdf223d1b, 0xe06c73b4, - 0xef71e928, 0x373e04ee, 0xfc8975ec, 0x974b696c, 0xac9fdf42, 0x5066956f, - 0xfb9f5a3c, 0x829f7f1e, 0x83f662f5, 0x6e7cfde1, 0xbbbcdd5a, 0xc7438b5c, - 0x1f111eb5, 0x01dfe897, 0xbd57d08f, 0xd37814fd, 0x23da7df5, 0xaa735e74, - 0xdf14ecd2, 0x4aef8999, 0xf9fdd06f, 0x199bd78d, 0xd5029d37, 0xc43fce2c, - 0xdd32c539, 0xfba0df2f, 0x3bdf11f9, 0xe99b033f, 0x7bf6229c, 0xdfafc367, - 0x02bf8fac, 0xf6371e34, 0x759bf5bb, 0x2fb3783c, 0x4ca5f9fa, 0x40e6071d, - 0x10f3f90e, 0x1fbe17c6, 0x71c09791, 0xa4e1697a, 0xbe8338b8, 0xeff55703, - 0xe434a9c0, 0x1ef790de, 0x1da3bfc7, 0xdfcd7e67, 0x80499c13, 0xc5ce7109, - 0xe19fe386, 0xf2126e3f, 0xaa2dcfd6, 0x4346829d, 0x077017ee, 0x331f9916, - 0xe7463ee4, 0x3df1ffff, 0x22505ca0, 0xcacf25f3, 0x3a1e31fe, 0x32f5b09f, - 0x7015c6fe, 0x8d75c41c, 0xce35d7d3, 0x2edf111a, 0x571d5a8c, 0x97d7877f, - 0xc471101a, 0x9e4765cd, 0x75627195, 0xfbefe248, 0x5f62c3aa, 0xf6265d5b, - 0x02ad39b5, 0x49bcaea7, 0xbb126a0a, 0x9f44d3c3, 0x6ccb3fa1, 0x7a180f02, - 0x5d2fc432, 0xf09da87f, 0x3e3a0dc1, 0xc9a3d588, 0xf94e5dd0, 0xc9345be6, - 0x472af74b, 0x6abf3f7c, 0xeee4ebda, 0xa83fa72f, 0x22effc6f, 0xf7d1eac4, - 0x0f12fe3d, 0x07bad3e5, 0xb8e21657, 0x38fef347, 0xe6a6f48e, 0x2df37632, - 0x3b13888f, 0x7ca3811d, 0x3f45a4df, 0x6bc96fef, 0x747e21eb, 0x5ec7e302, - 0x3a96f757, 0xbcf9ab81, 0xc09c3abf, 0xb75643df, 0xb0bbf9db, 0xc486d6ea, - 0xdb7fe429, 0xeb1daf65, 0xcb27ad95, 0xc5959f88, 0xad4a3ee2, 0xb38bdc5d, - 0x10b7fdb9, 0x3b7bd77d, 0x2df9cfa2, 0xfba8bf3d, 0xf58f3d06, 0xa3091b6b, - 0xf9f7ffa5, 0x5f3a8d9b, 0x662ebaea, 0xfea9c14c, 0x26afe690, 0xfd7fec7d, - 0xd71d0b45, 0xa5794ed5, 0x6d88ae9c, 0xefdca8f4, 0x268ee6fa, 0xf41af34a, - 0xf93a6477, 0x707351f9, 0x82d2e32c, 0xd30fbb2b, 0xa98dffb0, 0x3afaa714, - 0x225aa6ba, 0x0eb7bbf4, 0xf91c73fd, 0xb7498035, 0x494b855b, 0x25e3a15a, - 0x07b5c761, 0x3e50670e, 0xb7ec97a2, 0x9277ca80, 0xdeacb1b3, 0x12792a7d, - 0xa2bd96e1, 0xed19c21c, 0xa503f732, 0xa4e6e727, 0x3336fa48, 0x6242177d, - 0x9c9e801c, 0xdb230b1b, 0xdb5fff1b, 0x27a4d3ff, 0x289eb6d5, 0x84f837fb, - 0x3efe7cbb, 0xcad07037, 0xbce808f7, 0xc72115c6, 0x347f7457, 0x644b370b, - 0x7ce873a7, 0x3b41227a, 0xbaa0ee05, 0x95256102, 0xb2c38bce, 0x96377fb8, - 0x7d4cf7fd, 0xb84a59fe, 0xcee9ee83, 0xe737cfd1, 0x5bf73742, 0x6a5c0300, - 0x8befe4e0, 0xe5cbc04b, 0x29785b6c, 0x5082f1c1, 0x099fbf88, 0x73ae2867, - 0xe63bfd36, 0xe61ef238, 0x0ce7029b, 0x0e74c87e, 0xc51bee26, 0xd75ba7ae, - 0xf09a59c7, 0xe81d043b, 0x086cee7e, 0x35fbb9f1, 0xbf9fa3d0, 0x3cc75fc7, - 0xb9d1f7dc, 0x3b6835db, 0x208fcc89, 0xeb4f9ff7, 0xa7ade391, 0x198b2967, - 0x9f449cca, 0x7d30ce14, 0x75f2bf6d, 0x4d6dd3f4, 0x35df57ca, 0xe283f7d0, - 0x6f4b73e1, 0xd3ef1bfb, 0xd349627d, 0x97b1bef8, 0x7da6c7be, 0x1de9584e, - 0x001363f2, 0xe6b3ddfe, 0xc66f6437, 0x07e01af7, 0xfb11e7be, 0xf72d06bd, - 0x3df0c67c, 0xedfee335, 0x950ae0ce, 0x72ac6fee, 0xaddff8db, 0x9b8db229, - 0x87ca794e, 0x21bffcd2, 0x6a40fabd, 0x2883c49e, 0x638c19c1, 0x83b2bd75, - 0x2fd69b36, 0x22f7c669, 0xf432fac0, 0x006401ef, 0xb763b77f, 0x1e69ef8a, - 0xa5b43d41, 0x74abf6b2, 0x2e1e1a0f, 0x6f2f0955, 0xf4bcd971, 0xe895ae5d, - 0xdbd30fb5, 0x2ff71368, 0xb16bfb8c, 0x19b46c7c, 0x8daf4a79, 0x77cc7671, - 0xfcda773e, 0xbfe89bff, 0x9324a93f, 0xcbfe6070, 0x3f7c3df3, 0x7758c129, - 0xc3eb8d89, 0x37191af7, 0x6a7dd136, 0x1d31aba4, 0xe1e21ef8, 0xba149ca4, - 0x25d8d51f, 0xa63753ee, 0x9b7fd807, 0xf3fb12fd, 0x4ed2cec6, 0x0e83078a, - 0x6eabdf0b, 0xaa34f974, 0x4421d207, 0x3ef89ffe, 0x69bbe0df, 0xfd21ef98, - 0xed91505e, 0xde5157d7, 0x4a1b9a7f, 0x6169bde9, 0xc0f1126d, 0xe5061ef8, - 0x4e9519e0, 0x7befa3cf, 0xfbe4e281, 0x501c8617, 0x9d995831, 0xb90d7cba, - 0xf8ef8d38, 0x3bea2535, 0x8f5e437e, 0x98b90a24, 0x44cc26e9, 0x71a5577e, - 0xf061e563, 0x8f00bffd, 0x30b1ae40, 0x0030b1ae -}; - -static const u32 xsem_int_table_data_e1[] = { - 0x00088b1f, 0x00000000, 0x243bff00, 0xa3f0c0c3, 0x4aef811e, 0xf1303031, - 0x12d18aa2, 0x6064e3ef, 0x6062e010, 0xfbe20530, 0x330c0c3c, 0x204cf480, - 0x6066e516, 0x1ae20310, 0xc40dde20, 0x19f8807b, 0x1039fc50, 0x1be200ef, - 0xbefd103c, 0xfe0c0c4c, 0xc4081c40, 0x95fc40c1, 0x1be18181, 0x73f6f103, - 0x4c30330a, 0x2ff04715, 0x249fd903, 0xc1ffe7e9, 0xe90c4386, 0xa071df6b, - 0x10acf37d, 0x7b20467c, 0x9aaa15be, 0xcdf85605, 0xbf268858, 0x18bf8d08, - 0x0372fe8f, 0x4d5afe54, 0x81b5b334, 0xcd4909e9, 0x6efc4d3a, 0x40aac741, - 0x3101a9ff, 0x5ff1ad00, 0x000368ca, 0x00000000 -}; - -static const u32 xsem_pram_data_e1[] = { - 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5947809, 0xe77df0d5, 0x9926665d, - 0x6c81bc99, 0x44d84eac, 0x4242740b, 0x61db101a, 0x8311688b, 0x9817054b, - 0x264f6408, 0xdac7f520, 0x0040cfef, 0x8b435151, 0x03b45a35, 0x341b0504, - 0x024180d8, 0x2d82e00e, 0x5d6ad8d5, 0xc8a0d2da, 0x1b80931a, 0xcefc5dfe, - 0xc9bef739, 0x82264efb, 0xf5ffffb5, 0xf8f8fefb, 0xf77bee5c, 0xce73ddb3, - 0xe28ef73d, 0x8b94c718, 0xff12fb18, 0xdd98c7be, 0xd71b18c6, 0x2356329d, - 0xcf2d4ad2, 0x03d058cd, 0xac62ccff, 0x9785addc, 0x653633a7, 0x5ef91a87, - 0x4837e412, 0x6de43b61, 0xde549d7b, 0x23e79ebe, 0xa0cfcd6e, 0xc83aa3fc, - 0xdeded04b, 0x5065c0f2, 0x6643b9de, 0x91dbb11b, 0xc2963671, 0xe30731d8, - 0xcf90597f, 0xc9c0ac66, 0xf61be5b3, 0x45f6c5cd, 0x84e6764d, 0x1577cafe, - 0xf20cbcce, 0x86550785, 0x2f37ca55, 0xbe43fad3, 0x60352c38, 0x9f3263be, - 0x1ca7685f, 0x3bf50cde, 0x37292d3c, 0x553b18b8, 0x8d5e60e5, 0x4b776ab1, - 0x18a3f5ca, 0xcf6f092b, 0xf52576c5, 0x3a970f92, 0x97e6c765, 0xb6bae1fb, - 0x97bb3e4a, 0xf12dd2b1, 0xcf923bcc, 0xfff84be1, 0xf91ca358, 0x862f941e, - 0xb7e83275, 0x32e4d590, 0xab5fc719, 0xf0dddd79, 0xd3a5553b, 0x7cbe4638, - 0xed038c2b, 0x7c969e2a, 0x1b0ac4b8, 0xf8c0340b, 0xb39cbbed, 0x7d70b937, - 0x6e11b4cb, 0x1addd75c, 0xe70c2bd6, 0x717a74ef, 0x5cb41b7e, 0xbf592f28, - 0xd5182b41, 0x96e95fdd, 0xd579d6be, 0x980d4d0e, 0x53d3a3ca, 0x47798c55, - 0x184be774, 0xbf4037f3, 0xb36b094c, 0xff7f7746, 0x96322580, 0xcccbfd8c, - 0x1feee8eb, 0x43df4920, 0x013fc16f, 0x6e3da15e, 0xb781ab82, 0xdbfc3ac5, - 0xb3b78ddb, 0xd2a3c0ba, 0xdfee6d99, 0x3c401f48, 0x106a7cc0, 0x11ae904e, - 0x644cf3f3, 0xdfe81493, 0xc4ba67e3, 0x918f5f7a, 0x9f2ca8d6, 0x420b58c1, - 0x78cafda3, 0x116c6bc8, 0x93f631f3, 0xa9fed915, 0x059fbf90, 0x57bce2e6, - 0xc4228148, 0x690d6313, 0x24abbf48, 0xffd71b36, 0x94349c03, 0xf407eaaf, - 0x99af7009, 0x9649bd96, 0x3093dcc4, 0xbdc4f05f, 0x214fd4e9, 0x3f42a3f5, - 0x8fdfcf43, 0xe9639b9e, 0x322dcf47, 0x7ea4a9fa, 0x4fd6179c, 0xeb04ee4d, - 0x8c4b727c, 0x7ea4ee7e, 0x2eb617dc, 0xd6898afd, 0x46515cf9, 0xf54e24fd, - 0x97d400b1, 0x2d607a0d, 0x5dca197e, 0xef6389f5, 0x98ba6665, 0xdff912bc, - 0xa6625c0d, 0x389c848b, 0xfa261d0b, 0xd0f258fb, 0x5bec7e93, 0x44830f22, - 0x5f1a3512, 0x5c91afeb, 0x41dfd498, 0xbbfa3bf9, 0x31dc2e48, 0x0eb17021, - 0x59b1c0f3, 0x816bc83f, 0xe831eb6f, 0xb129e61a, 0x36bd4c34, 0xefcba34c, - 0x261c3956, 0x88dbf80f, 0x683ed023, 0x08911ceb, 0xa4d2f5f9, 0x365c205f, - 0x27c11b33, 0x5895664e, 0x48cece2f, 0x9e9ddd3e, 0x826429bd, 0x8041ead3, - 0xdfbba97f, 0x0d206ad5, 0xbb2b6be9, 0xb6f48421, 0xa7ac106a, 0x854f633f, - 0x14848fae, 0x20a83f68, 0xd769e10d, 0xe3cdbf80, 0x28fe306b, 0x1c19ff1a, - 0x3f8e0777, 0xf6f8e7ae, 0xf1963921, 0x2c8b831d, 0x18343be3, 0x177de81f, - 0x0f8c55bb, 0xd8c09bf0, 0x685ba1f3, 0x22e0fb7c, 0x8d6eff1a, 0x8fc65915, - 0x05ff1aeb, 0xdea5f71c, 0x82643fd6, 0x4b83fd75, 0xf8d7ebac, 0x0b655ffa, - 0xb471f8c5, 0x16875ffe, 0x2e0ff5f0, 0xf3b7ebe1, 0xf7c6bb7e, 0x75ffc174, - 0xdeadf71c, 0xa2743fd6, 0x9517fd75, 0xe76fd759, 0xcacbbfe3, 0x1a2ef8c5, - 0x1950bdff, 0x6545ff5f, 0x0f66be34, 0xb48e90f8, 0x61957101, 0x040d9f18, - 0x19254886, 0x6474a7e5, 0xfda0c61f, 0xe084363a, 0xa71c4770, 0x80e2cfbb, - 0xf2dd5cde, 0xa381858e, 0x08559e40, 0x9fad2f9a, 0xa59ca1a4, 0x0b7b9072, - 0x341754c5, 0xb0dfb4c9, 0x70f0f675, 0x937b6f98, 0x82fcc21c, 0x65879775, - 0xbcd8efda, 0xb0a76c3c, 0xf0ff7e08, 0xcd1bd1a1, 0x174e8aeb, 0x5ac7a8d6, - 0xe7c47c2d, 0x46cc9a13, 0xa6fcc256, 0xeb8c1121, 0x39031fce, 0xbe7e40ca, - 0xd314720f, 0x078c2ae3, 0x9c828fdf, 0x6f999a65, 0x3c7df196, 0x991cdec4, - 0xff827282, 0xbc38531d, 0xc2912d8f, 0xd6cfff08, 0x3e50d22e, 0x0789ac2d, - 0x23cf77a0, 0xb9d4f028, 0x28de1ecb, 0x08bd3c11, 0x15891b9f, 0xa033fb19, - 0xb6801fb5, 0xa5afb6b0, 0xbc2c2ddd, 0xcfea0d32, 0x483f935f, 0x3cdff587, - 0xc6563edb, 0x07f983fd, 0xd98f88d8, 0x630e5b00, 0xaad71bb3, 0xe3732003, - 0x56fdf56c, 0x0139fb53, 0x22e6fe6b, 0x0d5dbe6b, 0x37d436ab, 0x01b6258a, - 0xd2b5bdfa, 0x938c6e5a, 0x78e1f528, 0x20fde315, 0x56f7cf85, 0x67e2c74c, - 0x573af09d, 0xf98d6de7, 0x5952ef04, 0xd6cbf684, 0x4ff84664, 0x9d017aa6, - 0xbe7a3baf, 0x3f875573, 0xf733e60f, 0x19e0994e, 0xbdd6ff3d, 0x18db7ef1, - 0x563f6b48, 0xd7a30491, 0x79ff3d13, 0xa3d7a34b, 0x1f961e93, 0xe9cefe8a, - 0x829e9a24, 0x1efa934d, 0x6f2bd535, 0x51efb2b8, 0x6e957d13, 0x17c96599, - 0xea58e787, 0x5be6d617, 0x14d617ca, 0xafe7ca5b, 0xe7c9645e, 0xd4b4ee87, - 0x9974b79f, 0xcad6fca5, 0x37e52c7b, 0xe4b5ad17, 0xb11e04e7, 0xf671bfd4, - 0x6db94b06, 0x20d725ef, 0x25bf551f, 0x3e37dc33, 0x007b1d75, 0x5d4fc1f5, - 0x71f10f8a, 0xf88d2aa2, 0x979554e0, 0x4ca6f6d2, 0xc1cb8047, 0x16715402, - 0xad086b2e, 0x9972889e, 0x5e2cfc91, 0x1a1433b6, 0xe4adda08, 0xb5c9f825, - 0x09008b1a, 0x174fac4b, 0xa6ca771d, 0x94f3d6f2, 0x67a302d7, 0x5b972cf6, - 0x6e0f7f63, 0xe508bfcc, 0x00f26f4e, 0x3ee006fe, 0xf7f621d7, 0x8932f2e8, - 0x33bf99e5, 0xfcf89cb6, 0x65b3909c, 0x6507971a, 0xcc9bf6cf, 0x8c8f983c, - 0xf1aafca8, 0x28a8001a, 0x4f3b5127, 0x2e007a46, 0x50cbd0b0, 0xedb77f0b, - 0x155e6993, 0xa3c61328, 0x235bc9c8, 0x1c899ca1, 0x68dd7c18, 0x7eff879c, - 0x29aef909, 0xb6f5f699, 0x8f7de9aa, 0x3c9f882a, 0xcd544f4a, 0x5558f4a6, - 0x55a3d280, 0x5fbe9445, 0x6b694955, 0x0f4a52d5, 0xfd288557, 0x4a6ad553, - 0xa1aaabdf, 0x5aaa9df4, 0x1550ff4a, 0xcabdb4a6, 0x0fc1a94f, 0x4937f25d, - 0xaec2abe8, 0xf2879d80, 0x565ac567, 0xe216dd40, 0xf21a5f73, 0x67d759f9, - 0x3f1f5023, 0xa19d8efb, 0xbc1bdfbe, 0x77ade9a2, 0x5f49fa3c, 0xfe030829, - 0x3b967b33, 0x9c9e38e3, 0x819d3636, 0xf867ba3c, 0x46dbbe13, 0x92415e51, - 0x37c90d81, 0xdfa31dcb, 0x75f08c61, 0x7f313c3e, 0x016b98e7, 0xfd1ec71f, - 0x7bf6366b, 0x717fec4e, 0x87da6407, 0x0f936459, 0x1b8265f1, 0x3b9d6bed, - 0x0f3fbc84, 0x82ea3efc, 0x0660cb5f, 0x274904e9, 0x68db3bfa, 0xb1c20a67, - 0xc40c3e39, 0xdc1ececf, 0x5c7e41e4, 0x8fd3669c, 0x918380c6, 0xeba43796, - 0xd3fef32e, 0xad9fcd64, 0x9037a691, 0x5c26f63c, 0x4ae91a3f, 0x430e8fd7, - 0x6a51a7fc, 0x4d38b3f4, 0xbf028fd3, 0x3432da9e, 0x61dfef81, 0x27d60fbe, - 0x5d82bd12, 0xd5fff548, 0x1fade9f3, 0x358c3e63, 0x281c0fb2, 0xe86ca00f, - 0x1e9dedf9, 0xd13e5778, 0xcd5f10f2, 0x2fa867ea, 0x5fffc1c4, 0x157ec10e, - 0x06fd1bca, 0xfd90e41b, 0xdebdf8db, 0xf3b41e32, 0xb637361a, 0x156e9deb, - 0x2ba0cc76, 0x1a1a5790, 0x3a2764cb, 0x92beeb75, 0x9b07c968, 0x7d96e9fa, - 0xfc01ff06, 0x4152820f, 0x541329ba, 0x56b8a1d4, 0x23bf304b, 0x2f013f28, - 0x2bd78941, 0x016ab477, 0x0b63912f, 0xe5b719ea, 0xbde77418, 0xef208ff1, - 0x6546fe4f, 0xdff962f7, 0xae505660, 0xf720c51a, 0x2f9f906c, 0x9635b772, - 0x77b940ce, 0xf9f7c6d2, 0x83cf2c05, 0xab114f46, 0xe73d46c9, 0x8e9b6623, - 0xfb11fff4, 0x64d3279d, 0x1a6cf86f, 0x6afe73ad, 0xfa0b3eeb, 0x585f2599, - 0xb017cd6b, 0xde90536b, 0x2ca9d60b, 0x5a5f212c, 0x9d36bdcb, 0x95642dfa, - 0x41dec8ab, 0xbdc6057b, 0x00ca674d, 0x73f95f98, 0x43e7658f, 0xae363bfe, - 0x7bf61ba7, 0xff3e1f71, 0xe6b0a492, 0x1a0ff287, 0x19707f33, 0x55e1f6c3, - 0x6e42a728, 0x7accdbe6, 0xceebefe2, 0xc6be7a3f, 0x8fc3d27e, 0x6f21e620, - 0x18e1fc91, 0x9b34da76, 0x10adf424, 0xbae037a5, 0xbe6b7a4d, 0x2f918380, - 0x19dfca8f, 0xe9a7ff95, 0xe859892d, 0xc81488ed, 0xfa7325b7, 0x52417d42, - 0x37c0b53a, 0x47ad3fe9, 0xd2ffe5ff, 0xff4207fe, 0xeffe96d9, 0x3ff697fc, - 0x57fcc7ac, 0xfcbfeac6, 0x433b6db9, 0x9e4a6f20, 0x60c3c879, 0xd4a93a1f, - 0xef00f8a4, 0x7a579b65, 0x284e0e90, 0xf3d20f21, 0x3d3cb0c9, 0x46ec3d16, - 0xa23f207a, 0x5da125df, 0xfe84ff85, 0xdf753d4f, 0x3e67dc4c, 0x64eaacdb, - 0x47b16d2f, 0x15afc0ec, 0xd833c58d, 0xe11fca18, 0xc8cfbbf9, 0xd2b26f98, - 0x0f93c967, 0x0dffa0a5, 0x13d84528, 0x2a97d211, 0xc5cc3eea, 0x3ac8287d, - 0xdba2cf89, 0xfae7f8e1, 0xd7cc7c90, 0xc3967a12, 0x0fcf493c, 0x1b04b80a, - 0xa3233bef, 0x72b593ef, 0xfd54683f, 0xd4ffa122, 0xc749dcdb, 0xdf6274c0, - 0x7941df61, 0x8583c069, 0xbd53feb9, 0x4731e1f5, 0x756d3e60, 0x2648f1bf, - 0x767c1938, 0x2ffe61b6, 0x2ef6f79e, 0x9d85db8f, 0x4c2eddd7, 0x424dbced, - 0x69e66b6f, 0xa0f11a99, 0x41b65c5e, 0x73e085f5, 0x4f4db6d9, 0xea768a3c, - 0x70df76bb, 0xdb74bfe8, 0x00987f4b, 0x6aedd2f9, 0x0cbe0cd2, 0x8dd29497, - 0xbffc2097, 0x1e376c74, 0x92f57e4a, 0xbfcd1de6, 0x374fb8ff, 0xefb74a3e, - 0x9ee8d8d3, 0xb0d298f0, 0xc5756b4f, 0x91c34bc0, 0xaaafd45c, 0xa1ae7eb7, - 0xaf72793d, 0x63d352c4, 0x4bc373c0, 0x9c2027a4, 0x4f028f08, 0xaa8b785d, - 0xa0bc041f, 0x14f0373c, 0x9080fe5d, 0x779fd83f, 0xd3f3d114, 0xf95fa3cf, - 0xd70fbb3d, 0xedf4f45f, 0x71c75c1e, 0xf5d392a5, 0xfc532b63, 0x1a916e30, - 0xe529d14a, 0xff1e8bdf, 0xe15bd121, 0xe14c3f1b, 0x9fbfa0f6, 0x50a6f68d, - 0xc2df5c3f, 0xfad037f5, 0xe880580a, 0x3931e8ae, 0xa7e90c2f, 0x3dbe9b0a, - 0xc8645f06, 0x6f8e2f9c, 0xd60b8504, 0x12ed1c77, 0x4efeb3f4, 0x7f266f0e, - 0xfc8622c8, 0x3fc343ff, 0xfe5316ce, 0x93c70753, 0xbe09b643, 0x4ccf6d02, - 0xb77775af, 0x0d4e7e20, 0x1fa2a7f2, 0x9094c82d, 0x25f48780, 0x31bf2bf4, - 0x87e3952d, 0xd16c9579, 0x2980f40e, 0xb7eb1df8, 0x18e77ea8, 0x65f63b4b, - 0x4bf8f77a, 0xef30f8c4, 0x8fbfdc38, 0x86a2b0a7, 0x55bbeb18, 0xf61ef836, - 0x997d1371, 0x7bf39bf8, 0xbf9c3ddd, 0xcf0f7e0d, 0x9fe58e9a, 0x07f9c9bc, - 0x08fee1db, 0x52a48af3, 0x25ebbef9, 0x16760792, 0x75d7c589, 0x6b6be0aa, - 0x302741b9, 0x304a456f, 0xdff60bd1, 0xfe4fe087, 0xd07582b3, 0x832f24ce, - 0x67a79e38, 0x16df067f, 0x251ffe0a, 0xad9ff95b, 0xbbdf7ce7, 0x7da2157e, - 0x3f0d4cae, 0x2bf228f1, 0x8bc867f0, 0xe1e6aafc, 0x1fd74fba, 0xc04dc3f8, - 0x0c1ba7a7, 0xcfcab53e, 0x7a2d3e68, 0xf484b376, 0xa7a7cd19, 0x891b408b, - 0x3df0a7c5, 0xb5169f26, 0x9f953ffe, 0x8faefc06, 0x0f219f82, 0xb463837b, - 0xf3633c3c, 0xe5a33c12, 0xc9bdfc21, 0x9fd27bb2, 0xbd067741, 0xfcb2fc95, - 0x1817f222, 0x5dd06974, 0x741a5d17, 0x62ffc3d7, 0xf9745f81, 0xa005a460, - 0x2a5dbc93, 0xcd6555d9, 0xda0c3cfc, 0x8b203cbd, 0x6da7e4e0, 0x3cbcd58c, - 0x0f9cc920, 0xa21be547, 0xf2a3fbea, 0x03f55179, 0x4b4af951, 0x03a6b2fd, - 0x47fc231a, 0x4becf52c, 0xc41f651f, 0xfd8c87b0, 0x4678d826, 0x0c5d210b, - 0xde50d4ec, 0x0541cba9, 0x1ee0ff45, 0x0ec5ec99, 0x182af180, 0x3d3ea3a7, - 0xb1b9021c, 0xf0edc9d2, 0xd3d3bd0e, 0x8995d207, 0xac99df3c, 0x67b942ad, - 0x7274ef7c, 0x5e47473f, 0xe4d127a7, 0x2cd238a7, 0x0d6edc93, 0xfcb1e9b3, - 0x10a3b020, 0x6f595bde, 0x39ffdce5, 0x5e0d764d, 0x8d68f68a, 0x771343ec, - 0x3d1bb2c1, 0x68e92ae8, 0x6ccd7a1e, 0x55f0bef8, 0x3a558e99, 0x70633ce2, - 0x57e42c5e, 0x89ec99fa, 0xb3f42c13, 0x6ccfe889, 0x82c576e6, 0x08fa5135, - 0x54f4435b, 0xa1a25ae0, 0xe03b053c, 0x973fab7d, 0xe88945f3, 0xb5bd68af, - 0x278f68dc, 0x95df685a, 0x03cb59d4, 0x65da3ec2, 0xcb0649f0, 0x86833920, - 0x42e7da0f, 0x47934f2e, 0xf01b335d, 0x665071d1, 0xb6799e78, 0x9c7c2659, - 0x97e7e7ad, 0xfc4c942c, 0x493ac156, 0x6a701a1e, 0x7ad27e43, 0x3b6d5797, - 0x177d9cfe, 0x3fcecdd2, 0xa439f98e, 0x1ddf3b6d, 0xcff31bb1, 0x8ff83dbd, - 0x29fd67ac, 0x37e49d7b, 0x26ebd8ee, 0xf3d8ef7a, 0x6177c1db, 0xfc9d977e, - 0x3f7b1d75, 0xd7f4831f, 0x845edcb1, 0x1063aef2, 0xf7aa87b7, 0x95a63e7c, - 0x8415d7f6, 0xc6b2a3b7, 0xbfe6a3f5, 0x3092961e, 0xdea15585, 0xf89e37b0, - 0x93bcf829, 0x7b1d0bfc, 0xb80ecf3e, 0xa9eb75fe, 0x1d39e710, 0x59fb366e, - 0xf7225f9c, 0x8f770783, 0xcf0cb4df, 0x69f71ba3, 0xca7ca1f3, 0x831f7f0b, - 0x59e3b472, 0xabb50fae, 0x79e38fad, 0xe1fc8745, 0xdce01532, 0x9fd54c8e, - 0x1194fbb1, 0x62a34393, 0xe4efe5c1, 0x7850b937, 0x4fb70a68, 0x21e1fdff, - 0x73bcb9f9, 0xae121d87, 0x7fc38bfb, 0xd7b0b944, 0xac69744e, 0x32c374f7, - 0xb7ce57d2, 0x7fcae1ee, 0xd0b83a17, 0x0b914b75, 0x7fd4f759, 0x5aff7c73, - 0xa2fcd2f6, 0x9d27a0f9, 0xf283b9ef, 0x9a3edcdb, 0xfbd205ef, 0x7869ff82, - 0xeef0167f, 0xabbaff39, 0xddd7cdff, 0x9d5fde3b, 0xe3aef02b, 0x85f07f79, - 0xbefcd3bf, 0xf4db9cae, 0x0dee94df, 0x9b15febd, 0xa80ccdf7, 0xb8d59d3f, - 0xb2b8b150, 0x19abff7c, 0xc0cafa50, 0xdf388903, 0x37e751c9, 0xc2a6fa46, - 0x92c9a6ed, 0x9641ec8d, 0x907b0928, 0x840351db, 0x496030fe, 0x0321e901, - 0xf5cfde06, 0x0ebbc506, 0x195f1fcf, 0xb147df3c, 0x3bec6c14, 0x97ebcc01, - 0x9ed5bc8b, 0xfcc4b9fc, 0x603a3478, 0xa20ff7f0, 0xa0703b5e, 0xa42f7a4c, - 0xe8beefa4, 0x97bfce99, 0xe7bb1669, 0x0ed5af4a, 0xdab24dca, 0x7f45534b, - 0xff9f18d3, 0x0e149734, 0x0f261c03, 0xfa1269fa, 0x570f2747, 0x5cf90499, - 0xf6815816, 0xb59754c5, 0xc33c06bf, 0xe1cdf719, 0x380d5768, 0x8797590e, - 0x93241c70, 0x70bcf49f, 0xdc1379c4, 0x2f18c232, 0x871f14c3, 0x1f729f63, - 0xbd859df9, 0x904d474d, 0x5aab5c57, 0xb4159f90, 0xc81c3997, 0xe5ec36ce, - 0x84cde0de, 0x2188adfd, 0x032bf80d, 0xdad3bf65, 0x06dfd91f, 0x3e2ebe5e, - 0x537e3c0c, 0x851bbcbc, 0x45ae8197, 0x74ebf20a, 0x62fa17b4, 0x1f9e0cfd, - 0xdce85218, 0x570bd84d, 0xa4291778, 0x50cc0cf7, 0x8e855f10, 0x1cf0aba6, - 0x6893e1c4, 0xd9b7171e, 0x64707f68, 0x91f70449, 0xdfe50ab5, 0x10e3e9b0, - 0x7b2f33df, 0x0c9df4ee, 0x8d7ee6fd, 0xf1e53dc7, 0x7dbf8ff3, 0x8c44e5f9, - 0x2c781417, 0x46afff84, 0x167aff3f, 0x2d380389, 0xa1285854, 0x25bdfa0f, - 0xefc5bef6, 0xdfe3cd6d, 0xfbba5377, 0xdefd5f39, 0x3abfcae4, 0xd8e40e7d, - 0x5df300fb, 0xe1a30e98, 0xfd5db315, 0xaf0e669d, 0x1e1621e0, 0xe42ae3c2, - 0xe139d33c, 0x9ffe821d, 0x99b3d3fb, 0xea4ed768, 0xe5c09518, 0x17b230eb, - 0x385ec282, 0x3e09bccb, 0xa1d7ca17, 0x79fe7409, 0x8ac77650, 0xec2adc2b, - 0x7c625fed, 0x751da409, 0xfb4646ac, 0x1f92758d, 0x60e75437, 0xb7c4639b, - 0x9f86abe4, 0xfe0de04a, 0x8f3c6ce4, 0x842fe3e1, 0xbc6609a6, 0xa938cdb5, - 0x0789e98c, 0x74df7bfc, 0xe14df51e, 0xc23df68b, 0x35b3ab77, 0xfc862f37, - 0x6fc05db8, 0xc82ffee6, 0xf36979ff, 0xefd21b06, 0xcb3675a5, 0x2aa96af9, - 0x6cb1b1ec, 0xe66bce2c, 0x0b3ba77e, 0xf65072f1, 0xb0673c61, 0x88168cf9, - 0x0d182e71, 0xfd1fec4f, 0x9d555be9, 0xdab76bf8, 0xbae11f30, 0x430723fb, - 0x56977a3b, 0x9e6b1a53, 0x9e7cec03, 0xedc3590b, 0xfdffd263, 0xc3a93be0, - 0xf68c9915, 0x7e131d67, 0x63fa688f, 0xb767c744, 0xafee30b0, 0x5ca2af68, - 0x68cf5b38, 0xdc90077f, 0xf037768f, 0x7eccf7fb, 0xb69b8b9c, 0x82f512ff, - 0xc749668a, 0xa50a8623, 0x6d3f4355, 0xc65129b0, 0x6bc3387d, 0xa3eabbc4, - 0xc5f137af, 0xf8215556, 0xfbb0981e, 0xe3f71c66, 0x9ea18d36, 0xd3b17fe2, - 0xc7f8fb83, 0x07c499cd, 0x57ebadbd, 0xa9aaec55, 0x972a3748, 0x30f4d187, - 0x92ce3eaa, 0xf40e4cbf, 0x699afe47, 0x8be25d6f, 0x6befbf81, 0xbc173892, - 0xfe16f940, 0xbdbe4cff, 0x80b7c869, 0xa3e2679c, 0xf90f5abe, 0xbe4b1a96, - 0xa9bc962d, 0x7bc5f708, 0x5e22a686, 0x26aabf17, 0xdb6f92c7, 0xe739f8aa, - 0xb94e2233, 0xdbe411a3, 0xadf24db7, 0x8c5be411, 0x5fbf9078, 0xff0b7ca8, - 0x36dff0d7, 0xd6316f94, 0xf9566bab, 0x08f9a636, 0x8d31b7c9, 0xaf3c4b36, - 0x7c9f3b5d, 0x47af9293, 0xeaa0f8fd, 0x3f418f8b, 0xfe3e84db, 0xc44b888c, - 0xe5ce5071, 0x7f8d3a6a, 0xe2ee72a1, 0xff73950b, 0xe4367045, 0x8c1de2dc, - 0xd27b9ce2, 0x8b739721, 0x939c8177, 0x9cb91e90, 0x7187bc5b, 0x7c945cbf, - 0xbe43d91b, 0x115faa31, 0x4d83ede1, 0x02df0fe9, 0xabf58dfd, 0x1fd4073e, - 0xc6ef2ddb, 0xae5de599, 0x7adc10a6, 0x1783bbc8, 0x0876ef26, 0x6c720779, - 0x68d7ca08, 0x5b35f0fa, 0x8f77c1e3, 0x2bff5e3f, 0xcadf97e4, 0x86f8de74, - 0xbd0f9f8d, 0x1678fe36, 0x6263d7d2, 0xdc848b3e, 0x510aaf6b, 0xe45e53ff, - 0xf1772beb, 0x468af138, 0xd4561fae, 0xfc2f614b, 0x17c27733, 0x78bfce1a, - 0x2152c48f, 0xebcecb3f, 0xf38d27b3, 0xc3233632, 0x720b0f44, 0xbfcfc94a, - 0xf40e6140, 0x72ba97e3, 0x5bfea24f, 0xfefdc39a, 0xf17be2a5, 0xd0abadab, - 0x88fc5dff, 0x46a5e744, 0xe711ab7c, 0xa26e23db, 0x77f91979, 0x6627e3a3, - 0x99a9b88a, 0x1bc294bf, 0x947fc462, 0x7fe6b16e, 0x966ff822, 0x62f04adc, - 0xe331cbaf, 0x5d7a8c38, 0xe0283a70, 0x7ed32754, 0x802705da, 0x27bd379b, - 0x33d3009c, 0xe1ba5232, 0x585bfc52, 0xebef566f, 0xbd16e035, 0x5d7fc36e, - 0x0de9fa2a, 0x7b9c060e, 0x1dc05fac, 0x939202ec, 0xa758f0d1, 0x33b5f975, - 0xe8094e31, 0xe84ce486, 0x181700d7, 0x70d26f2f, 0x47977dcb, 0xd664fd05, - 0xe1829a4c, 0xae30b30c, 0x6a0bca1c, 0x0fdcbd17, 0x1dee31e0, 0x4edc58ef, - 0x0f609b2f, 0x56ec39e0, 0x41c92767, 0x35db0e83, 0x141c07ae, 0xbfddddf0, - 0xf9d93272, 0x7a8e924d, 0x24e23048, 0xae0106b8, 0xa828ff78, 0x8106fc70, - 0x0eff911e, 0x8719f23c, 0x8bc91ee3, 0x635c9dfe, 0x40bc42bf, 0x8e66ccfd, - 0x22586097, 0x4eb164bc, 0xa8a97f3a, 0x84117c95, 0x8206d35f, 0xe19f219f, - 0x93c665cf, 0x58957e89, 0x4c954bf4, 0xa8a965fb, 0xf35ed337, 0x99e7a407, - 0x036caa4f, 0xfbfe1b81, 0x4f3e7a2a, 0x9e34501c, 0xb6bc04da, 0x085d3c21, - 0x77ae4eb7, 0xfba0be45, 0x50794650, 0x39e05909, 0x5f73d1e5, 0x0671af09, - 0x518e90bc, 0xcbe735be, 0x92682f98, 0x9ef4df58, 0x50f3c5eb, 0xef17bf33, - 0x7ffbc239, 0x18b1f24c, 0xba60beeb, 0x8b9e85ee, 0xbcf16e80, 0x8eba37a4, - 0xd23b5386, 0xe9bab7f3, 0xe76735f9, 0xe7a44ca1, 0x43f7123d, 0xce5a2734, - 0x1e763d35, 0x09d5b5f7, 0xeeeb0f74, 0x6df5557c, 0xcb90c6f4, 0x7ed1ee82, - 0xbb37df30, 0xf1821704, 0x141c5ba2, 0x18f347ef, 0xb353f5c2, 0x64e6de7c, - 0xf567d7c9, 0x2edbbfde, 0x37278cc5, 0x3f2323f4, 0xf8c3c71a, 0x6f1826f9, - 0xd178f764, 0x2fe183fb, 0xfabadf38, 0xbad9bfdb, 0x6ebe718c, 0xb590543c, - 0xb88d5e10, 0xe05223a8, 0x73ea2a47, 0xfc4b25d3, 0xc85ccc15, 0x7fdc6fad, - 0x7bdc96aa, 0xa74d2cff, 0xebb774fb, 0xe89d77c6, 0xe2674f33, 0xdbe26f7c, - 0xec7fefb8, 0x5998e7e7, 0x44d6f636, 0xab263fdc, 0xe3eae90c, 0xa1f92a43, - 0xe3ca9e3f, 0xedf9af6e, 0x3e5d0501, 0x3898f0d7, 0x8938cd76, 0xb037acec, - 0x87a8f1eb, 0x047f983b, 0xef132fc1, 0xd5d465ed, 0x5f02f14c, 0xae12dd8f, - 0xa537d4c6, 0xc435e933, 0x219924db, 0x7dfc5ade, 0x7f20b8a7, 0x032c87fb, - 0x1fa0a05d, 0x07b1fb50, 0x9bd63259, 0x33264fe0, 0x27e37c66, 0xf3075e6f, - 0xf6487f18, 0xacdea179, 0x03172e03, 0x7ae47a7d, 0xe0980b1b, 0xab858135, - 0xfe34dfd1, 0x9c3affa8, 0x3be81177, 0xa8a44f78, 0x07b54379, 0x6a25ebf3, - 0x72050c1f, 0x6d9eb03d, 0xbf7267b5, 0xea017285, 0xf5c13761, 0x4eb05ebc, - 0x728861f2, 0x8a5af341, 0x93a82a2f, 0xb6e142e8, 0xbc1cc4b0, 0xfa03b0df, - 0xda1eb6dd, 0x05fee167, 0xbadfb1ed, 0x875e6f33, 0x49e60772, 0xb9f9ebed, - 0xf3b4017c, 0x2dd4bf22, 0xd78afea2, 0xb3ef0c4b, 0x7df3d514, 0xea90e8a9, - 0x7dc6f2c3, 0x3b7ed08f, 0x97ebc603, 0x6450fb8e, 0xca0bdd2a, 0x2fba7494, - 0xf84c1a19, 0x7f1c60eb, 0xf220fa6c, 0xabbc520b, 0x98a0c097, 0x64fe63e3, - 0xb3f2421f, 0xeb4cb7c0, 0x96bcfd0b, 0x236e9c93, 0xe7433aba, 0xde0147ed, - 0x1bf78001, 0x40e55e22, 0xab5a07ce, 0xc2fc5f69, 0x9b9f943e, 0x38a24d34, - 0x8f2c858e, 0x8e6638e2, 0xebe6fae7, 0xe8c33b97, 0xed5d7be7, 0x0fdf881c, - 0xefa76e5c, 0x1cb8dbed, 0x4ad41f6e, 0xebe3f6fe, 0x58f78655, 0x24cbd7aa, - 0xabd78e2f, 0x7e563f74, 0x1431c78c, 0xc7fae36e, 0xdfbcf581, 0xe1b7a8e3, - 0x439607b9, 0x11ab70be, 0xb4e5c0e7, 0xe8167f61, 0x90c2fe3c, 0xdd62e5bb, - 0x75a1f63d, 0xd92434cb, 0x2e5b7968, 0x8b0971e4, 0x2d1cbd90, 0x1cf1cb77, - 0x197c83dd, 0xeae6271d, 0x0e9063b6, 0x5d105f22, 0x19521c57, 0x07d231da, - 0x9714b96d, 0x73a247b6, 0x92cdf18b, 0x8a1ae31f, 0x4987b1de, 0xcfe70eff, - 0x2fee11fb, 0x8619daef, 0x3c431f2c, 0xb1ca9c80, 0xa7e9fe77, 0x1be4fdf0, - 0x02088c0e, 0xb827c9ba, 0x59be711b, 0x4f3c799b, 0x52eb1bd6, 0x9b2f3ef0, - 0x40e497da, 0x02ccad61, 0x52713926, 0x13775ff2, 0xd4741fdf, 0x667c0c77, - 0xb8053569, 0xc1cb7ebf, 0x66ef55f7, 0xd8646315, 0x043d84ef, 0xf51f81f6, - 0x6b5de29b, 0x1d133453, 0x9b59ef14, 0x55f7c322, 0x1aa61e22, 0x576857f7, - 0x8a71f1ac, 0x06fa4af7, 0x3f4638d3, 0x2edabf46, 0x1ee86ede, 0x7fd6f69e, - 0xd68fce31, 0xf286a9f9, 0x1e9fba22, 0x4fd2f7e3, 0xadcfefce, 0x395e6093, - 0xac14cbaf, 0x8cc1f39e, 0x1d73e6a1, 0xcafc3523, 0x98da6fd9, 0x9cbf04df, - 0xbf31c53f, 0xe38ddf09, 0x7f01ef80, 0x61493757, 0x23f984a7, 0xe516795a, - 0x0af3e475, 0x98ae7fe1, 0x1aebcfca, 0x8158de33, 0x4b233f7c, 0xa1607a22, - 0x8937d680, 0xfa2f35f4, 0x78b30bfd, 0x8f6842fb, 0x08f8d8fc, 0x13904fe7, - 0x1523945e, 0x52e6d7eb, 0x8bc93afd, 0xc86e37fd, 0x28a47d27, 0x5e546647, - 0xa3f48477, 0x4923a6a2, 0xb7c0c7c8, 0xa81f50eb, 0x51d76898, 0x68fc1b8e, - 0xe2ebf7f0, 0xe8732b3e, 0xc67ef1a3, 0x8be646ff, 0x21f2d7c1, 0xf583d72e, - 0x39831f9c, 0xdf5f5f9c, 0x2f0ae2a6, 0x9f89bf84, 0xfce16f8f, 0x43763f2a, - 0x2f87de2e, 0xc3efccdc, 0x453f581f, 0x78fa7d43, 0xa6fda258, 0xbd737f27, - 0xabbf9a35, 0x7defbe25, 0xe0d2fd5d, 0xe18f836f, 0xaf1c6aef, 0xef14f80c, - 0xf5f3464f, 0x0fe1b54c, 0xaf7cc3b7, 0x03d61a79, 0xddf29df3, 0x26ad3d3b, - 0x14f90939, 0x3c2817cc, 0x2b90cb9e, 0xfb8f0ae5, 0x8bf3dafb, 0xb76c3f1a, - 0x677e47fa, 0xebf1e44f, 0xfdd12a75, 0x07b3f8f9, 0x7f205d9f, 0x9d5f285e, - 0xf18d3f8f, 0x7ed63de5, 0x2de8277e, 0x8076bfba, 0xfae0046b, 0x8a26fd4a, - 0xa9e8fdf3, 0x3f113323, 0xce81bba5, 0xddeabe91, 0x4e72822c, 0x557ed309, - 0x3dd328d2, 0xb244a601, 0xf99b73af, 0x956dc798, 0x7a26e33e, 0x1ed6792a, - 0x4bed019e, 0x86307e76, 0x779668e2, 0xe85a5c52, 0x872fa129, 0x1f20c75a, - 0x7e3c2894, 0x042e5a2c, 0xd70fdc1c, 0x367e2bb6, 0xc2da4fae, 0x69288fdf, - 0x9bb551b8, 0x746e25ce, 0x3a3d46a8, 0x1d010dd7, 0x9c5dfde3, 0x02ddf99f, - 0x6dac6e23, 0x2513972b, 0x81d92a4d, 0xb7b65b25, 0xc970fc63, 0x77f2763b, - 0xa19cb705, 0x9e5310fb, 0x94fe46d9, 0x396c9360, 0xb711eb7f, 0xd88e45b9, - 0xb1b0ee31, 0x211dce9c, 0x0df2847f, 0xcf97e3b1, 0xfa585f17, 0x219d9ecc, - 0xafe96100, 0x7ca0f49e, 0xd9b2d539, 0x7e877083, 0xba6e32bf, 0xc3669c47, - 0xa7195f3d, 0x01ff0a79, 0x438f738c, 0x9c4635d8, 0xa4be96eb, 0xb2fcc247, - 0x739c62f3, 0xdbe5e974, 0xef1c7d3e, 0x7b3db411, 0x6f9c71fa, 0x7e3e3fd9, - 0xd8c1e31c, 0x77ed275e, 0xa2dea7c1, 0xdda36c38, 0xb5dfb126, 0xe2927d6f, - 0xb5dfdbd7, 0xf6b7b0fb, 0x6307c73d, 0xf6fb603c, 0x6fd0522f, 0x34cf64b9, - 0xd92eebf2, 0xc5952531, 0x148c2fd8, 0x017c36e9, 0xf8d1f3f1, 0x8078d03a, - 0x023ed6e2, 0xebfca37c, 0x286dbb8a, 0x5ecc71e7, 0x1f5b6f11, 0x8f429efb, - 0xebc6daf8, 0xe51cb9ae, 0x1fd7237e, 0xfb671bcf, 0xdbf1e026, 0x7abf8017, - 0x1b102fc3, 0x3fe11f7f, 0xa2fb4f00, 0xe369f7f0, 0x8a3c5fc2, 0x7b7d8d65, - 0x5c8db38d, 0x7b8cdc00, 0xfc380f10, 0x88c91c87, 0x5c525fe7, 0x866de233, - 0x4f9ff717, 0x91fde307, 0x5ce76a13, 0xc7b85fba, 0x68bc63ae, 0x89b79ec9, - 0xbc77da7f, 0x26687e41, 0xb3b423ee, 0x3f1e3fae, 0xd675892e, 0xae7c79b9, - 0xefc63f80, 0x5df43d7a, 0x3a72e9c4, 0x7b77e236, 0x9d95db8b, 0xee36cf5c, - 0xfdd79467, 0x76c3c451, 0x41ca4be3, 0xcaf91d3c, 0x0e036878, 0xddc390ba, - 0xe3b1e871, 0x2beebba3, 0xfe217c08, 0x8aea1f70, 0xc0fc8733, 0x7a37e4b1, - 0x0790c59b, 0xfc781bed, 0xfb1abb7a, 0x9711b05e, 0x3e688ffe, 0x3c585f0d, - 0xffe6f9fa, 0x81d3e175, 0x4f724fca, 0x2dfdb538, 0x774f1cb6, 0x9eecdf4a, - 0x7d149961, 0x1cebca6f, 0x473b7187, 0xbb83b434, 0xdeb16cec, 0x6f57e136, - 0x78a64a7b, 0x070d55e5, 0xcb478e48, 0x2f7c0a8b, 0x337cc625, 0x9a2b7cc5, - 0xf6d13ef8, 0x82ec3bac, 0xeff6da7e, 0xa8ae7a22, 0xd2f1423f, 0x95f96f2f, - 0x8b8a6ad6, 0x6c227dc0, 0xd3db7f9a, 0xdc90c6fb, 0x44b2ef16, 0x8c49338f, - 0x3d8e6c13, 0x8cfeb04e, 0x50d29c65, 0xcebba683, 0xc529de3f, 0x77f6237f, - 0x83eb85aa, 0xe9e41aa7, 0x0fe318e1, 0x77d6aa73, 0xa4bf60a1, 0xfcdc67f7, - 0x13d919bd, 0x12e5fa47, 0x093bce77, 0x146a9849, 0x4cbd55af, 0x87fd77c4, - 0x5df10d2f, 0xe18abeed, 0x7c22577c, 0x551e7e4d, 0x4bd4300f, 0x2cbcb4d5, - 0xcb442bf4, 0xc6c92d1b, 0x2ffc26c2, 0xf54f4f71, 0x644779d2, 0x70f3e220, - 0xfb1571c6, 0x9f944bfd, 0x5b0a2fea, 0xfbf30a95, 0x2df2484b, 0xdfd97e83, - 0xe794183e, 0x977fd9ee, 0xd963f11e, 0xb0aa57e2, 0xbb461e77, 0xa4e0bd84, - 0xaf7906f8, 0x08f9de93, 0xf5a4ee3e, 0xf9f1d81e, 0xff5fa413, 0xb9f8cec2, - 0x202f580f, 0xde750aaf, 0x9f1df1c7, 0xd457fe3f, 0x8c31b19f, 0xd438f85f, - 0x3ea1bb47, 0x8e9cec9e, 0xa0c61367, 0x85f0a45f, 0x3ca266bb, 0xf4e78c2b, - 0x6a4cf858, 0x3bfa1ab8, 0xc7f3cc96, 0x77a20db6, 0x759f4a25, 0x81e8dc53, - 0xe055cf1d, 0x4cfed4be, 0xa97dc33c, 0xe7a105fd, 0x53bc52ff, 0xcd7aab55, - 0x4cc5e3f1, 0xf3ef9af1, 0x12de6294, 0x2fc8c4af, 0xfe847c41, 0xba04a6aa, - 0xaffa0407, 0xd48f9fa5, 0x447c3bce, 0xfcfea1c7, 0x3fa453fe, 0x7ae883ca, - 0xcebdf946, 0x395ee221, 0xd77573b4, 0x059d6a0f, 0x9fd35f3c, 0xaa1693cb, - 0xf853b0ff, 0xcf79458f, 0x87fd797e, 0xeeeefc84, 0x10afb787, 0xd344d0ef, - 0x6fd146ef, 0x5fbf96e9, 0x959deb1c, 0xefa7f318, 0xc858943f, 0x76ca7a86, - 0x857fbd27, 0x7de028ef, 0x3f1a9d85, 0x44f32ad7, 0xdd9b9de8, 0xc5971e42, - 0x9ddde845, 0x581e62fe, 0xd1ccf31f, 0x9fbd34fa, 0x61939cf6, 0x0bf9595c, - 0xbbe23f6e, 0xc7e7e77c, 0x71859e7e, 0x1714f189, 0xffc2fe5f, 0xb7283a22, - 0x3f22e647, 0xb3b76e74, 0xdbe7c88d, 0xfc8c1d5f, 0x0646a6da, 0xf38af9f7, - 0xbb06f2ba, 0x58bffef5, 0xdaaaa9c7, 0xbbbef0cb, 0xa4b6af71, 0x57f33917, - 0x5fa3d727, 0x725ffa71, 0xdf5bbf12, 0x35553a73, 0x59df133b, 0x3897ea30, - 0x77c5cb62, 0x137c5e51, 0x71eaee39, 0x9c5df53f, 0x25ac47cf, 0x153efd05, - 0x3ca377a0, 0x3e92d92f, 0xfb04fd10, 0x043bc69d, 0x8fdc04de, 0xb25eabf6, - 0xef3531a7, 0x7caa2733, 0xf430ca99, 0x54cc8cdf, 0x1b1d1d60, 0x67f414ce, - 0x9cea4718, 0x9dee4b1d, 0x3ad3c676, 0x98f61c4a, 0x09cf9df7, 0x8d0f7aba, - 0x1e3e64fe, 0xee3187f2, 0x724c357e, 0x2f388ef8, 0xbb012bd5, 0x6e97bf08, - 0x79699399, 0xa1a9457f, 0x04a7c07a, 0x4eb662cf, 0x6fc932cb, 0xa5e2bc63, - 0x264a9959, 0x4ffe577e, 0xddcabd17, 0x24a16678, 0x01150bd2, 0x9faeb663, - 0xa2887ee5, 0x7e1039e6, 0x15d3cb1a, 0x86a54919, 0x358e3df8, 0x7502ea50, - 0x5653bf8b, 0x9e4e50c9, 0xe8f6e710, 0x1bb4c2ef, 0xdc92775e, 0x6c620d0f, - 0x07be3a78, 0x4dd04de1, 0x10f153f0, 0x5763e61e, 0x1797192a, 0x93b47433, - 0x7d8050a5, 0x5d54f409, 0xe9133d35, 0x18fcfe11, 0x07a64907, 0xbfa3cfcc, - 0x41ea05fc, 0x3dfca740, 0x70b2efbf, 0xc3188035, 0x3aafc981, 0xe877f199, - 0xccc3bf56, 0x71a5c6f6, 0x68e77892, 0x1731c91f, 0x84ebfeeb, 0x94558a3c, - 0xff09d5b7, 0x4473c1c8, 0xa822ce97, 0x58bbc617, 0xd7521e24, 0x9994e528, - 0x90593dff, 0x3ea9d137, 0xcd1e5ad1, 0xa2d72017, 0xf8206dc6, 0x449fbf41, - 0x5449fbf5, 0x557c9fbf, 0x829c06bf, 0x7c3e8d8e, 0x556562a7, 0x1f1b809e, - 0x06e021cf, 0xef8919f0, 0x9c5b31e8, 0x13879c4f, 0x6cc4e35c, 0xf01f58ec, - 0x4e971e5a, 0x612fb978, 0x41c6276f, 0x865aa4b3, 0x890aef76, 0x97f0d3ef, - 0x63b532e7, 0xf0f883ba, 0xb94e311e, 0xc30af380, 0xbea3d53f, 0x1eaff493, - 0xd5bd9df5, 0xdf5d8b8f, 0xe27cdbdd, 0xb127cf63, 0xe26bfe97, 0x75fff663, - 0x0bc552e5, 0xe786bf6f, 0x49f25db6, 0xf55bd007, 0xd438f2cc, 0xfd8f1333, - 0x70be95a3, 0xd031d33d, 0xa438ef8a, 0xb8b7a06f, 0xd1efd661, 0x7d1bd274, - 0x40758be5, 0xe00fd5de, 0x7f189370, 0xf73f1d6a, 0xf70965be, 0xe87981d3, - 0x8b37fac7, 0x0a3937fa, 0xc470dfc9, 0xbabfdfc6, 0x91eb96a5, 0xa658fcb7, - 0xef1ee9f3, 0x803fe151, 0x2a5d6edf, 0xb1e92385, 0x7562d7de, 0x9e6e3f78, - 0xbdfa3f18, 0xe6f300aa, 0xbd6396ae, 0xd2e9c557, 0xfd1757b8, 0x9602c54e, - 0xb321de27, 0xd4eb3f7e, 0xcd67e4bb, 0x2c7deea8, 0x1ee816b4, 0x7ba04ff5, - 0xebc7973c, 0xe2171462, 0x485c78d1, 0x4f3a20cb, 0xd9dfe433, 0xdc04de91, - 0x307f99af, 0xeff3aeff, 0xa6f4af8b, 0x2a1def9a, 0xef2ce2e7, 0xbeab54f5, - 0xea6f9434, 0xc15fd039, 0x0dced654, 0x39535e61, 0xfcc4ade8, 0x7249be18, - 0xa3094d2a, 0x3cf4545c, 0xaf7a8856, 0xa8c3ef78, 0xd55d25af, 0x0ebe67a5, - 0x4b8e6fff, 0xbc5cbe26, 0xb6f74bd6, 0xdbcf8b3f, 0x7b24f489, 0x57017c72, - 0xed087a4f, 0xc6aeebe0, 0x5cf7a775, 0xf3e6b54f, 0x157dbe91, 0x6ffc8080, - 0x4fce073e, 0xf6df7bb6, 0xa37efce2, 0xf4bbf432, 0x44ef8f84, 0x86cfca18, - 0x887c5007, 0x0463309c, 0xbc46bf8e, 0x6ababa6f, 0xaa2ba524, 0xbc794898, - 0xaf2a8adc, 0xea447348, 0xaa74e917, 0x1a556f77, 0xf95557e5, 0xebe03528, - 0xfbd0d5f0, 0x7c618e93, 0xf02e877c, 0xf0136497, 0xe5fe900b, 0x73a4ab48, - 0x195ea745, 0xd8df77c1, 0x7077d840, 0xc10d7a59, 0xf919d357, 0xe53ea135, - 0x548798ed, 0xf8419dad, 0x564af452, 0xc56fe508, 0x5c228e07, 0x2d4bde9d, - 0xd3da5aef, 0x7fbd46c6, 0x836f051a, 0xb871b6de, 0x7a712fdf, 0xfdfb868b, - 0xe3178b6a, 0xb2bfee22, 0x82295deb, 0x1c43983b, 0xe7e6bfee, 0xdee13db4, - 0x09be7b32, 0xe9eceeee, 0x04fbf704, 0x7016ef9c, 0xa87816ad, 0x46acf016, - 0xa47e53b8, 0x3a44fbc8, 0xc47bd29d, 0x112bb7fb, 0x08ca901f, 0x7d878077, - 0x30c98854, 0xf179ba1e, 0x7412eecf, 0x1fc8dbab, 0xfcf2bb2a, 0x127b7708, - 0x05c3bb87, 0x06ba2078, 0x3cb17bb8, 0x5d54f044, 0x9f50ce1c, 0x15e441e3, - 0x7e267b84, 0xb800f8e7, 0x871f8df7, 0x058270f2, 0xe4d25ace, 0x23fb830b, - 0x124b7f7c, 0xbf0d1e7c, 0xafbf8d24, 0x6f77f06b, 0x88b571fa, 0xef16aeb7, - 0x511c2227, 0xe00879af, 0x4f0e34c3, 0xc8a47dfe, 0x164d28fb, 0xe0357ff6, - 0x161fcb01, 0x19c210fa, 0x73c51fd3, 0x56c93cfb, 0x38454fb9, 0xf2efe1f5, - 0x1b10a4b0, 0x6878cd98, 0x85a5fe2f, 0xc6f31798, 0x4ad7aff9, 0x44aeb23f, - 0x7de903bd, 0xdd6de918, 0xcf0daaab, 0x57a5e43f, 0xcb67ee59, 0x5e89fdb3, - 0x42407f82, 0xc13ee6bd, 0x5e916b87, 0x1edc7e68, 0xe0e8295e, 0xeefef16e, - 0xee7e823d, 0xa0fcfc17, 0x7e3e3741, 0x74cd643f, 0x9498c71e, 0x20ef1361, - 0x4e399846, 0xc0d7d130, 0xd9179834, 0xe94a5e36, 0x8ef64b9d, 0x7e36f89d, - 0x7d23f314, 0x6773be25, 0x9b43bf98, 0xa1f50fd7, 0xd9dde344, 0x39c4de89, - 0xa23d3174, 0x6520f788, 0xc4b64f6e, 0xdab5df7c, 0x7e81dfb7, 0x13e6de99, - 0xafa7f3ef, 0x6be2f184, 0xf54764dd, 0x59cde40d, 0x2d577908, 0xcb0c55d8, - 0xc1707cb9, 0xf44d0bbc, 0x5f8bdf11, 0x595d7547, 0xf64af480, 0xa93fa438, - 0xf844ea1d, 0xe8bdac02, 0xcd487abf, 0xc1fb87eb, 0xfdb18943, 0xb9e2b370, - 0x7593c4bf, 0xb09fc5a9, 0x3b53f54e, 0xde55a27d, 0x43fb13ac, 0xfe56a99f, - 0xcb83f630, 0xc59f7f44, 0x0f147e07, 0x6e729674, 0xa4cfc92a, 0x0fef636b, - 0xc216aad5, 0x47aa39f7, 0xe50ebe73, 0xee6f5c6b, 0x9d187721, 0x8c0d9c83, - 0x2ffe88d8, 0x3396be83, 0x8c42e72e, 0xbac693eb, 0x3ef4867e, 0x9d01f702, - 0x01f71ee8, 0x34c3cbcc, 0x5b949ba2, 0x587fe46c, 0x5eecf825, 0x046b5fc1, - 0x7c803d5f, 0x81df0235, 0x13fa51f6, 0x90eb4fc1, 0x12dd20ff, 0x78f5ce9f, - 0x6197bef1, 0x8c772cc7, 0xab1cf7a5, 0x0fda365d, 0x61ed7794, 0xfb05da17, - 0xf7e8ebc6, 0x7a59dd91, 0x59e58dc0, 0x43c03f0e, 0x91d2cc4a, 0x2f733e5e, - 0xe2abe8b8, 0xf4fd015b, 0x72a2b0ae, 0x949ea47f, 0x451fdec7, 0x9ef453a7, - 0xcb5faa80, 0x70fd3fd0, 0xe113a552, 0x8f3c70fc, 0xcfcdaad3, 0x3e03b826, - 0xe29bc5b6, 0x5f6752a5, 0x1f1ef5d5, 0x2f70ff76, 0x12ec12ef, 0x0c0d82f2, - 0xf92661b1, 0x7bde2b50, 0x1b10de64, 0xcb139269, 0xf432e787, 0x0f94f5eb, - 0xcdcbc8bd, 0x90ae5e5c, 0x434bcb62, 0x65e4377f, 0xd2315cb4, 0xb74d1795, - 0x5d54a7dc, 0x66f2463e, 0xc1ff6c64, 0xfcede3ef, 0xf3e66a1d, 0x2cf7a7e5, - 0xdefd7807, 0x83d42f0c, 0xf7c57f0c, 0x5a27ac62, 0xcab89e3e, 0xf40357d8, - 0xcd02d03e, 0xaff8f0fb, 0xfbad57dc, 0xd5b9e141, 0x9c140fa4, 0xa8b4a1cb, - 0x11f13a76, 0x9318d3c3, 0xfd7c7c9d, 0xdf883d0f, 0x7ce2b5e3, 0xc61abd7c, - 0x1b7da4b8, 0x0e607aef, 0xe3c175c0, 0xe38f9d32, 0x14d90d3d, 0xbcb2c2df, - 0xef1ba7a4, 0xdf0f1e23, 0x31c731ee, 0xe9d4fc14, 0x37bffd47, 0x1f582c7a, - 0x8d537fdb, 0x83bb44ff, 0x5da246f9, 0x675dfa01, 0x9fbff504, 0x18dde938, - 0x18da1f23, 0x8fc733ef, 0xf15be918, 0xdc21ced3, 0x33f78adf, 0xab9dd217, - 0xf4d79d0f, 0xdc7c17ce, 0xc733e863, 0x4547d273, 0x7dc0359c, 0xca7fc596, - 0x098f49cf, 0xf473187f, 0xca271e52, 0x7b94bdbd, 0xd3133c78, 0xd3ff9763, - 0x3d51a47e, 0xb821b4ec, 0xd3daf2fe, 0x2fa5deab, 0x6280f3d6, 0x60bdc711, - 0x79787c63, 0x2059be0c, 0x102f07ee, 0x7d065de7, 0xd0df7f15, 0x465d39b3, - 0xd4f4add3, 0x1fa74425, 0x5fc9541f, 0x87f4015b, 0xd4f4987a, 0x698f7a78, - 0x3d9713d9, 0xf9c00b78, 0x95324393, 0x10739d97, 0x87ffb65d, 0x3bfce28f, - 0xefd2ab7f, 0x70727c26, 0xb7ebc51a, 0xbb9ef78b, 0xedc5cef8, 0x5c5c1bda, - 0xbb9c14ae, 0x8bbbe897, 0x35f3c2ae, 0x7382dbe4, 0x565e900f, 0x4ebdef80, - 0x788f75c0, 0xe8229279, 0x1fb60277, 0xea1cbb92, 0x3e72b615, 0x15431361, - 0x10de8fe4, 0x0637bbef, 0xf2e0df3f, 0x0b45e25a, 0xff50d75b, 0x24c3f40c, - 0x02c85c53, 0x8507fbf1, 0xe584b878, 0x21a5887a, 0xd6f908df, 0x77d6ff4d, - 0xd69ddbb0, 0xc2e91a75, 0xb04e75ae, 0xebdd61d8, 0x73e72efc, 0xb6146fa1, - 0x7579f0e6, 0xe3e7e7ad, 0x7ba7ad63, 0x7da9131d, 0xf1ec627b, 0x1fe317ef, - 0x9bc22aab, 0xbc44ac5b, 0xbe105bb7, 0xd5f7c35d, 0xf627d60a, 0x2aeb4c91, - 0xc4b52dac, 0xe6d4152b, 0x857afbd3, 0xdbb5f3eb, 0x1753fb4c, 0x97fe425e, - 0xc6eb0d27, 0x2e6bfdcb, 0xaea8bc23, 0x7e913bbc, 0x7c553d8f, 0xec5e7bc7, - 0x84e9e397, 0x49531a16, 0x4f76eaf2, 0xf74dfbac, 0x56a9e347, 0x80ec09e0, - 0x0c9e132c, 0x3fb744fc, 0x8efcb9b6, 0xe21cf0f7, 0x509afe11, 0x0a2bf2ef, - 0xe1b1e97f, 0xd7a0a4f7, 0x040fa063, 0xdf7e082e, 0xf5cbc4b2, 0x6f813f0a, - 0x77c63e03, 0x08c2e7d0, 0x379127b7, 0x4e3fb193, 0x5b83e70f, 0x1e82f8f7, - 0xcf5ec526, 0x59eb5d6b, 0xc7a042ca, 0x3eb8d49c, 0xee7afbd1, 0x05c72162, - 0x4f8ba7ac, 0xfa7c2df3, 0x385b9ada, 0x9ffc0a9f, 0xd10f7fdc, 0xbc70b1f5, - 0x7a54e30f, 0x486bcf5b, 0xd062e307, 0x1b10b0c1, 0x8f7ffd95, 0xfe684e0e, - 0x3ee08f11, 0xee15fb02, 0xde4fc5d3, 0xbf3cc63f, 0xfd27e2b7, 0x9aa5f69e, - 0x0ea73b0b, 0xf41df64d, 0xfb277ed2, 0x434961aa, 0x633f815d, 0xa3cf12fb, - 0x6e9fa19f, 0xc6cfe245, 0x578bd2c4, 0xc72e0556, 0xaaea8bf3, 0x8fd1cba2, - 0x973d0aaa, 0xce9b9ea1, 0xd623177f, 0xcdcc7d7b, 0xaab2bbf1, 0x983fce92, - 0x94f4c423, 0xd80077ee, 0x47f24c89, 0x7eab2e2b, 0x1d01a9a6, 0x789adffd, - 0x025540a7, 0xd0b3d3ab, 0x1194945f, 0x1fefc132, 0xb2ee7e2e, 0x8ebf6d26, - 0xe8761ae7, 0x8e60fd1f, 0x8b59ca81, 0x6545ecff, 0x93c05f41, 0x1c731cf1, - 0x124bf06b, 0x46cf13f9, 0x5acf13f9, 0xf30491e6, 0x5b3b0afe, 0x1ce87871, - 0x8fc26152, 0x5f01e02c, 0x5bbb1f68, 0x1e5cebe7, 0x607d21ef, 0xb23645d5, - 0xff09d6eb, 0x2fd0cff4, 0xe851704d, 0xe0c301bc, 0xc096beb0, 0x73c4e1d7, - 0xaded190c, 0xf8dde508, 0x4f4c9762, 0x4f984a1f, 0xf3095e64, 0x1564597d, - 0x931d0fda, 0x3f20ef5a, 0xe69033a0, 0xd67ebc06, 0x84b0e5af, 0x817912e7, - 0xb5ce118b, 0x0bc32872, 0x77217ff5, 0xc1bd6066, 0x1f4ef450, 0xf7845e9e, - 0xf3a60212, 0x8eb421ce, 0x33dcbcee, 0x2552d17f, 0x6feffcea, 0x5fcb9b17, - 0xc62ffa71, 0xf93b5479, 0x1f4960fb, 0x57be7448, 0x94ee75dd, 0x64f2fb47, - 0xd123c737, 0x41d5d205, 0x559d37ae, 0xc87d09bc, 0xf3323d9f, 0x7c3ccb45, - 0xec22bc96, 0x53a03ad1, 0xe832a73c, 0xb7e29863, 0xaf0d1d21, 0x3c66ef81, - 0xfb77d0c6, 0xf079e8b8, 0x31b9fa98, 0xe897183f, 0xcb973e55, 0x7a28e3f7, - 0xf9f12dd8, 0xdced8a87, 0x1921646e, 0x20c73af1, 0xcf05653c, 0x8fe33227, - 0x8d77b5ec, 0x82b62773, 0x0b9e75e7, 0xb9cfc6de, 0xa733e7a3, 0x3c16eef9, - 0xdcd399ef, 0x7b9e3e6f, 0xf8ba29ce, 0xab774c43, 0x51e3fb9d, 0x2250fc5e, - 0xb7a6f67d, 0x21e3545e, 0x46e6f1dd, 0xae609f7a, 0x73bfef9b, 0xf88aa759, - 0xe35d300f, 0x5a6156e7, 0x27cc6ddf, 0xfa2a0df2, 0x84896e1d, 0x721ab86f, - 0xbe18beb7, 0xb9bdd51a, 0x425f3b07, 0xf41a05b4, 0x321b3a5c, 0x5ef935da, - 0xaede79e6, 0xf14e0e0b, 0x838a47fb, 0x6ebdd5d6, 0x58c1c107, 0x7c24d427, - 0xbc49c174, 0xa5c066cf, 0x37f1dd6b, 0xf8fe855f, 0x1cdce4de, 0x790fe8c7, - 0x579f3c9c, 0xc13e9c34, 0x0b939022, 0xb91ffedd, 0xb77afca1, 0xcb4c2eff, - 0x95839d1c, 0x5537c421, 0x0390af98, 0x1c00a517, 0xb8141a3e, 0xd1e11938, - 0xf482f7d2, 0x2e4ec3fe, 0x1ba70e0f, 0x1bab6d7a, 0xc8bd9be9, 0xf7e35af5, - 0x38ed5632, 0x008dff7e, 0xe55e8f9f, 0xcb95cdef, 0x22ee6bde, 0x62ccb2ff, - 0x7a4621d9, 0x1e0df858, 0x7bc4db76, 0xf39d7cd1, 0x79ef0e14, 0xcf74f18d, - 0xd952de6e, 0xbcfdbef2, 0x957e3ca5, 0xae632d29, 0x2b09d8b7, 0xecf75d04, - 0xd11afd07, 0x3a5fccfd, 0xd92dde99, 0xc893e9a9, 0xa738f1cf, 0xfd53f9b3, - 0x4ffdc632, 0x1f912d58, 0x6f51fc69, 0xe7e42b53, 0xc87d1387, 0x5ceff3ae, - 0x97ef899c, 0x3f70b454, 0x28bcaa67, 0x7d203fe3, 0xefdf3f68, 0xe108bf31, - 0x5d7bf2e4, 0x369af3a6, 0x474332b5, 0xe5d5be7a, 0x7f907947, 0xc45dffbd, - 0x30e7e1a7, 0x40e7ddf6, 0xce38c00f, 0x39bc5bfc, 0x0df91f48, 0x0ea53f4e, - 0x5c81c4a6, 0x039857cb, 0x298d54d3, 0x98e34c4e, 0xe5ecd303, 0x9daa7f42, - 0x2783fa45, 0xf7c34f27, 0x9f9bf3c4, 0x17db14fc, 0x927d912a, 0x9bf29e89, - 0xee82fd5f, 0x28f3f9c3, 0x5b5bf74e, 0x39dd8b34, 0xff9ac1ba, 0x9f359376, - 0x33e6b111, 0x03f35a0f, 0x7d266d70, 0x1e1eff73, 0x9a7a529f, 0x1e7defdf, - 0x3c22a060, 0x3e49d9b6, 0xce6d294e, 0xd38778c6, 0x586dbb4f, 0xdceffbbe, - 0xeadceeee, 0xf72577a4, 0xe2c717bd, 0x6a1df092, 0x3f2c46e7, 0x8d90d71d, - 0x4fa845fe, 0xbbb04b71, 0x71bb408e, 0xbd06a5e7, 0x69be2986, 0xfdf83fe7, - 0xf6adce94, 0x9c51c630, 0xd3e4f5de, 0xb7a79f48, 0xec7d200e, 0xc3642979, - 0x70f7437e, 0xf3884ffc, 0xe954e458, 0x7e3dab16, 0x1d01e842, 0xe879b527, - 0xd6b8ba17, 0xc24beeba, 0xa8a77cd6, 0x7d331b7f, 0x10f8c74f, 0xdc34aaef, - 0x7ec53767, 0xc173fdbf, 0xa53d4f17, 0x8b2b7419, 0x37991ef7, 0xe2befba5, - 0xdb73eeee, 0x8e800325, 0x4316114a, 0x4697bfba, 0x0f85db8d, 0x38927fd1, - 0xadfceb2f, 0x5539f04c, 0xef896455, 0xaafbd2e8, 0x4d53697c, 0xed4151fb, - 0xd27c94be, 0xdca5f757, 0xca67da66, 0xb9481eb6, 0xdb6bfa19, 0xebefd0a2, - 0xe279cd95, 0xf8490981, 0xf9c06e5d, 0xe7fa3962, 0xf25e1ada, 0x8bd03d60, - 0xbde39ac7, 0xa5c76b0a, 0xe9f1354d, 0x834ba5d7, 0x0e74ca9f, 0x5a72e79f, - 0x461ef172, 0x1dff2d69, 0x1b86d2be, 0xe11abbae, 0x4fdf9ebe, 0x9e5856cf, - 0xb653fc0c, 0x8fef86fd, 0xc7c1ef86, 0x3e70f9c6, 0x2d24f8d9, 0x3fadbbde, - 0xee76f743, 0x44ff71b5, 0x7b465c34, 0xfdef7e38, 0xe508ab81, 0xa2f7f412, - 0x3fb52c6d, 0xe47d0368, 0x6bd0e4c4, 0xd3954337, 0x570fe1ac, 0x95965c53, - 0x253e809e, 0x373ab7d4, 0xf48dbe4b, 0xb5f67975, 0x97fb5aa8, 0x943a3c51, - 0x8a37b4c7, 0xa27ed6c3, 0x47a57cf1, 0x68f77e32, 0xa25e99a4, 0x119df5eb, - 0x2ab7dfa2, 0xcd720a5b, 0x1d97efa4, 0xd878a1ad, 0x19c871e8, 0xc13b8a68, - 0x7c4bd1fd, 0x027a14ec, 0x22d91c93, 0xcf287c5e, 0x48a7bbd3, 0xa5104097, - 0x5ea9b297, 0x6cb5eb84, 0x4bcfa63a, 0x99640791, 0x33f203cb, 0x79278b6d, - 0x3eb7a6d0, 0xa3a473f1, 0x1e74d1fa, 0xefdc5fd6, 0xe846f36e, 0x77e358bd, - 0x9e74da71, 0x5276692f, 0x8fe9d53c, 0xcb979234, 0xeb138e30, 0xd9b4ed3f, - 0xbd3b5f40, 0x8c64efbd, 0xe06b6e0b, 0x6a9f8aef, 0xfb593be8, 0x9a37fd8a, - 0xf17d8def, 0xdf13fe08, 0x8bf8f54f, 0xacdfb83d, 0xa9d371e0, 0x2a332b7d, - 0x68c9e063, 0x6655a497, 0x79d2bda0, 0x91b7cbab, 0x0ae953eb, 0xc8d3ddf9, - 0xfc2f92af, 0x79e9f749, 0xbea07877, 0xe1faea1b, 0xe5073eff, 0xfc77e88d, - 0xa1ddf640, 0x1f3eed0f, 0xa015905f, 0x03f4e3fb, 0x7cfe3036, 0xa0144585, - 0xafb8f9b7, 0xc93ca18c, 0x25ebf9cf, 0xb05c238a, 0x7c1ebac6, 0x1fbcdae7, - 0x292fe116, 0xb0b8c50e, 0xd68b4a06, 0x718bcb5b, 0xbc50f0ff, 0x94cbc517, - 0x19cb59d4, 0xad1f908b, 0x7b4bfeac, 0xca7db82c, 0x6bf9f58c, 0xa3b9163c, - 0x50f9dc92, 0x95f5a3ce, 0xd20037a2, 0x1cfec49b, 0x6d2733bc, 0x4b1da401, - 0xc82da427, 0x7cee7bc4, 0x8ed3231f, 0x8fbf98f8, 0x45953a57, 0x7177f106, - 0xa58fee18, 0x346452cd, 0xe42c1de6, 0xe3bfcb19, 0x6eb820fb, 0x63313df3, - 0xf35eb8dd, 0xc726f677, 0x10cf71ab, 0x2f2e6bd7, 0xab287013, 0x3afc5bb7, - 0x90a5ea13, 0x7f78dbfb, 0x55da95a9, 0xb7697e34, 0x5ff62bf4, 0x1399b7d8, - 0x68a135f0, 0x798b8c83, 0x878e4ba8, 0x0f75892f, 0xdf80b0e5, 0xf4143743, - 0x107d7e43, 0x02fecff5, 0x9f2439c0, 0x45809f84, 0x5c5e301c, 0xca9e5766, - 0xfcf397b3, 0x8ae04f3e, 0xaf6081da, 0x873a01a9, 0xbde72f9a, 0x471bf78c, - 0x425e0626, 0xf9b7ccbc, 0xb7c42b07, 0x17e411fe, 0xf0e1ca5d, 0x4bcad8f0, - 0xc5d9632a, 0x933fbf02, 0x3e5ce81a, 0xa3ef8bb4, 0xd54eacee, 0x8bfef7ec, - 0xfb094790, 0x4f5ee95b, 0xee890ee7, 0x1d223f13, 0x8fb6fba1, 0x6865e95c, - 0x9e01a7c7, 0x223eee50, 0x5ef815b1, 0xace3565e, 0x9e212f45, 0x787ce2b3, - 0x38de5fde, 0xd1772e49, 0x15beb9fa, 0xcf01b95f, 0x8de75283, 0x0e748b1c, - 0x2d779eeb, 0xe3d0ff7c, 0xb9faf1a5, 0x96d3de38, 0x8f17d287, 0x16f3f1c2, - 0x387c84bd, 0xa1ee8e3a, 0xdcac02a7, 0x8d5d287d, 0xcb1a547a, 0x60fa87d8, - 0x58ef0cda, 0xe43fb9f4, 0xdb24e3e1, 0x50b379e4, 0xf3cb1bcf, 0xf92c7e7d, - 0xae111237, 0xed5271a5, 0x17ce3a6c, 0xe85ea3bf, 0xcb823f40, 0x9529ef84, - 0xea7e3819, 0x69269e50, 0x3c0f8a11, 0x99bde064, 0xd12de9c7, 0x25e9c919, - 0x454a4c5f, 0x1b50ee3b, 0xbf20d418, 0xec340d0e, 0xf48b88cc, 0x792361f0, - 0x2df7617d, 0x5ff7e0c9, 0xfa1b0692, 0xa1d7af0f, 0x513213fa, 0xf5c1beae, - 0x7e5c4ff1, 0xa65f57f2, 0x4fbf8ec5, 0x0a78e048, 0x61638b9e, 0x3838ff93, - 0x13d233fb, 0x2c3ce783, 0xf027da6c, 0x1c734dbd, 0x7ed15977, 0x72841dfa, - 0x01f742d6, 0x71ac1bca, 0xc5c597e7, 0xf3a0d71e, 0x0b1b39e0, 0x1e3225f5, - 0x21d7f688, 0xc2d573a9, 0x4b17ba24, 0x73c13be7, 0xc6990b1a, 0x63eb9e0f, - 0x33cd77cd, 0xaee9fa85, 0x9af5acc7, 0x2c7aa73e, 0xe383d5a7, 0xb4adebb4, - 0x29cf048f, 0x6fd8ced4, 0x90b6c23a, 0xeedcfc0a, 0xe21de5e5, 0x6fa8cf3c, - 0x5b3ed7f4, 0xf8def713, 0x556de8bb, 0x2e007820, 0x219f368f, 0xf359747f, - 0x418b823e, 0x89f0dd0f, 0x7c132167, 0x225baa52, 0x69ede036, 0x7bb86e0f, - 0xc990d814, 0x871f05fb, 0x9feddd36, 0xbbf8e508, 0x8ebe260f, 0x73e2eacf, - 0xd90f3312, 0x42172e64, 0x9d4f7775, 0xfa8bca68, 0x9b43ed5d, 0x340a98af, - 0xb78a3595, 0x27c1e6bf, 0x4e4e595e, 0xdf111a8b, 0xcf3839df, 0xa23bca6d, - 0x8fc82ef2, 0xa8f5e536, 0xf2a8a4f2, 0x40fca8b4, 0x1dcdbf5e, 0x40fb2c19, - 0xd4f83fde, 0x9efbf815, 0x7322fd6d, 0x358f05f1, 0xf02bb6f2, 0xb3cb7cf7, - 0x56d3eff8, 0xc93e4b34, 0xba2b3f24, 0xb55bf3ce, 0x0e10a3f9, 0x1ca32f2d, - 0x74926b28, 0x0d5debd4, 0xc79423db, 0xbb535e76, 0x963f6e06, 0x76a11c35, - 0xd23ff6bd, 0xef7c7c46, 0xdea9f7c8, 0xd89fcef9, 0x5befeb0c, 0x751e76f5, - 0x4e2c0a44, 0x7f7eee48, 0xdbfb6dbd, 0x0a2fbfdd, 0xf9fbdbdf, 0x8d1c900f, - 0xc41e07ba, 0xf9bab8f9, 0xbde380c4, 0x7bd2cf23, 0xdd1c7fb4, 0x03aa16fc, - 0x2cce4bf1, 0x9fdda053, 0x438f8fcb, 0xb4df0b7d, 0x67e37dc5, 0xdc12f852, - 0x81651e8f, 0x5bdc704b, 0xc3ef87cb, 0xac384c9f, 0xef863eb6, 0xf0786f95, - 0x98142be5, 0xeb7761df, 0xb709fc20, 0xf06f094d, 0x7f2b727c, 0x1dff4551, - 0xa0f0e7e1, 0xc83641d6, 0xa6c0993f, 0xeb787e53, 0x3d7f9863, 0x3faf04e1, - 0xac9075ba, 0xf27209a3, 0xdf90a98a, 0xf7e6c7ac, 0x37ae04da, 0x369bf31b, - 0x8453ffdc, 0xfbe32b0b, 0x76335e0d, 0x5b9d3c80, 0x66db6a72, 0x1fdcc780, - 0xdb9c93c5, 0x55dd76dc, 0x50870479, 0xa611c61e, 0x7ed3780a, 0x215d7248, - 0xee1fa27d, 0xf1ba7d81, 0xe2dc1ee9, 0xd2e2fda5, 0x37a8edca, 0x451dcea4, - 0xc7a145fb, 0xddc9e92f, 0x52193869, 0x3ae92fa8, 0x8db2eb97, 0xef5223e2, - 0xf51e9372, 0x033df8a0, 0x0fa23be0, 0x36cbc097, 0x096d9eb1, 0x80f6bfdc, - 0xf3f51a67, 0xc47fe49e, 0x42ca6321, 0xc5a7f24e, 0xf372be91, 0x202b9006, - 0x7989d7d7, 0x097b5baf, 0x466e29f9, 0xfc28f13f, 0x67d7efee, 0xbffeb754, - 0xaef2032e, 0xdd6ebb6e, 0xf33f7f2c, 0x0dbaf6b9, 0x5b90dcbc, 0x7b79d2eb, - 0xad4abf63, 0x3ea4e3e6, 0x5c46c978, 0x28c2bc47, 0xece17b7e, 0xd1971b11, - 0xad2d7ffe, 0xfdfdf99f, 0x5a3f0ed0, 0x7a86c43c, 0xc29f81a9, 0x1257fee1, - 0x89373d60, 0xf035efdf, 0xb74f8c64, 0x907f51e2, 0x3b407f41, 0xeb403135, - 0x0c627d07, 0xfae06e0f, 0x3316d204, 0xad2997c1, 0xfffbf0e3, 0xfdb53820, - 0x4ff4e02b, 0xc947779f, 0x0c379021, 0x7a5f2ffb, 0xedff72dc, 0x23d1013f, - 0x8000702a, 0x00008000, 0x00088b1f, 0x00000000, 0x7dc5ff00, 0xd554780b, - 0x733ef0b5, 0x9992bcce, 0x924c2664, 0x84e3c849, 0x71100840, 0xf0444312, - 0x51888431, 0xd4503b69, 0x20717ad8, 0x9926023c, 0x4b62d5a8, 0x79120cff, - 0x22341809, 0x0281c150, 0x06f55bc5, 0x701a8c45, 0xaf7a8a44, 0xb7ad8ef6, - 0xff7f6c57, 0x4a8f8808, 0xd2f5a232, 0x5ad7fd97, 0xce64ef7b, 0xb6b4a924, - 0xdc3ef9bd, 0xd9cfb3ee, 0xd7b5ed7b, 0xf6b5af6b, 0x4cf5a61e, 0xd8c05c0a, - 0xce6a2566, 0x7c2c64ae, 0x61edf148, 0x67cf07f0, 0xf7fb193b, 0x95d5a0b4, - 0xf19fd8c9, 0xe6c60aef, 0x2729bf7e, 0x8ded0658, 0x61cb1823, 0xcfbbf52c, - 0xd500ded4, 0x7a3f4bb9, 0x3f7c0f7c, 0x8ca97bf7, 0x43ef03e9, 0xf7c18c8f, - 0x5b6dbcef, 0xd2842ecf, 0x793519d2, 0xf986bca0, 0xef7bc056, 0x27435898, - 0xbe0ef7f4, 0x5563097a, 0x35e5bbdf, 0xdbb19136, 0x93632a5d, 0xf8ab5b18, - 0x258a9873, 0xbbe0db0b, 0x644b2cf0, 0x7d63114f, 0x0cd85311, 0x23b875fd, - 0xb8c1175b, 0xf995d71d, 0x1f5fd0c2, 0xef867e63, 0xf7a54b2d, 0x4c3ddc3a, - 0x744bf6c3, 0x0ec24017, 0x19faa17e, 0x5a37e3d4, 0x7814bb22, 0x76c2ce5e, - 0x3e325f6c, 0xf3fa8612, 0x7f7d0e30, 0x0f644a63, 0x8f82cfb6, 0xa371dea0, - 0xfe861237, 0x47622cec, 0xfa763a78, 0x8c1c3273, 0x05acaae5, 0x8228efe1, - 0x2b59943a, 0x0701cdd9, 0x713fcfe2, 0x0f007396, 0x6899775f, 0x3d95a93e, - 0xf437ff4f, 0x7ddbd6c7, 0xe1b0a063, 0xcf6f58ab, 0x3b997826, 0x66f88558, - 0xb803fc1a, 0x89c81fea, 0xcce7c3ac, 0xb1eb8557, 0x479fe9da, 0x5520fff0, - 0xb61ff847, 0x0ab635b3, 0x66d61528, 0x0bfc00cb, 0x43fb5878, 0x37630c00, - 0x978000e3, 0xd670d7ff, 0x2bf3c3a9, 0x07ad0a5d, 0x556df9fc, 0xbc67cd8c, - 0xd4f2fe7d, 0x58899577, 0x1a6b51aa, 0xa5735b3c, 0xef46c7bf, 0xe28f3fb1, - 0x0bfa0da5, 0x25b7f132, 0x09ba44ee, 0xd86977e2, 0xba9defff, 0xfdf0eb03, - 0xf8765c44, 0xfbe074be, 0xf9a3173a, 0xfc3955cf, 0x475535ac, 0xc8fc4afc, - 0xd7c24eb2, 0x713f90fe, 0x724e393c, 0xfcbaf7bf, 0x00be2237, 0x0f74d1ef, - 0x75a545e2, 0x63d7864d, 0x43b06f89, 0xd556dcfb, 0x33e0377d, 0xf349ccb8, - 0x9cdef095, 0x158cbf1d, 0x74ffee0f, 0x8695736a, 0xe9c65ff3, 0x02b72d9d, - 0x62f112e2, 0x5d03a819, 0x63f1642c, 0xe7886526, 0x8445f45a, 0xc247517f, - 0x2fdff4f7, 0x49ef89ac, 0x92ba617e, 0x2ba0bf04, 0xdd70d15d, 0x375f0a82, - 0x373e258b, 0x6e183650, 0x82d5cf89, 0x245d24ee, 0xe2357be3, 0x7c60d27b, - 0xf93d2c7b, 0x99706fd8, 0xdc94f095, 0xfa11633f, 0xf03b21ee, 0x16ddd00f, - 0xdd7a2145, 0x646a5772, 0x3da7f225, 0x19f117be, 0xad157c3a, 0x1492ef77, - 0xdb2bc19d, 0x9441302c, 0x9c9d8733, 0x4a7a4b8f, 0x617a9f90, 0x9f587ece, - 0x9dd5d7de, 0xc1024561, 0xeaebf358, 0xdeffa42e, 0xfde6af67, 0x19d548ac, - 0x618843d4, 0xfe143718, 0xbc032b43, 0x2cc5349e, 0xe0175e34, 0xff09c257, - 0x435fe17a, 0xe8bc80c5, 0xbf1c06c3, 0x9807cb8b, 0xe71a12e1, 0x1d6c29db, - 0x526cdb8c, 0x6f6826fc, 0xb23e3a5e, 0x4361c392, 0x20146a3e, 0x9b589b35, - 0xf7c03152, 0x2513a6cd, 0x36f195b7, 0x85bbde0d, 0xf78175f1, 0x5f002a8e, - 0x4c7d6da3, 0xfa45ba45, 0xd8a5f687, 0xff80345e, 0xf9bff5e6, 0x7cdfc213, - 0x8d1748c0, 0xb1e7198f, 0x8a9e9134, 0xb524e806, 0xd589e392, 0x8018c8b0, - 0xa9ea29d7, 0x8a88b1b5, 0xcd565a78, 0x66e9024e, 0x8199e91e, 0xecace3f4, - 0x0ca1f364, 0x11fcc07d, 0xf74a7b80, 0xc24697ce, 0x58daeefb, 0xb4374e3e, - 0x4e8bb6ec, 0xbeb0345d, 0xba4bce12, 0x41cca937, 0x0077d1e3, 0x83bf7f8a, - 0xfb371bde, 0x6ef2c482, 0xa4d32efa, 0xe0f6bd12, 0xcd1be423, 0x38c0a39f, - 0x328c979b, 0x82a67ae1, 0xbcb9437c, 0xaeec7db0, 0x7f678415, 0x07b7ca09, - 0x09ce80d3, 0x942abe9f, 0xeaeea52f, 0xbfa0bb5f, 0xffd5dca7, 0x138e258d, - 0x47f4e270, 0xa648be90, 0x23bd64e7, 0x6e2ecbdf, 0x0c716f29, 0x17f01eff, - 0x35be2de1, 0x4d0fcb9d, 0xffa2faa1, 0x475cef30, 0x374469f0, 0x222f6db7, - 0xdac0dc79, 0x591ade89, 0xbbf482c4, 0x69c2c6c8, 0xe08b1740, 0x172874b5, - 0x3d32b16f, 0x4496fd61, 0x2146f58c, 0x31616e0f, 0x7d96fefa, 0x2c35ed49, - 0x26f684ea, 0x62a68b1b, 0x6f6c69d9, 0xef417166, 0x3e26b67f, 0xbe7c1d67, - 0x77758b37, 0x20d444d7, 0x1dab7bcc, 0xbe065774, 0x33eb4ed0, 0x5a4ef965, - 0x7f0af4cf, 0x4fa83dd1, 0x76fb355e, 0x27bedd01, 0xe7e24bd6, 0xbbf5575e, - 0xd514f788, 0xdf8ff344, 0x9cfc2563, 0xeb8dbd02, 0xdd9b9f7f, 0xdeca1b3c, - 0x7a3bdd56, 0x55c9a234, 0x1839db30, 0xb39eebcf, 0xb8dd2037, 0xb7c226dd, - 0x65cc7e7c, 0xddd57aa6, 0x522bff02, 0x088abb23, 0x9e9113dd, 0x7d4946aa, - 0x82ce26ca, 0x5666bbfa, 0xe6f509d7, 0xec411deb, 0x07ed07af, 0xb9b817a8, - 0x5b7028de, 0x2eb27e68, 0x06e92be7, 0x52fea1c6, 0x84a5e22e, 0xc85b8c63, - 0x7f89b641, 0xe6eff427, 0x493b2925, 0xafd3f6ff, 0x96fd1189, 0xd7882c05, - 0x795c84e7, 0x3695ca4e, 0x9a2b972b, 0xa832ee6b, 0x9941f73f, 0x95e01d6f, - 0x83de8295, 0x4a3f1bef, 0x5e9e91d1, 0xef5fe8f9, 0x9fb419fd, 0x5ba2c0fd, - 0xd2017da1, 0x73dbac18, 0x6047970a, 0x8fd4307f, 0x38f6c08d, 0xb1c1e36e, - 0xb41c7f64, 0xc846fb08, 0xe0b4c6cf, 0x4fd085d6, 0x3e9993e3, 0xbcf664a0, - 0x5ee8f239, 0xf7643f6c, 0x1b7e81ed, 0x1b5e3853, 0xdf491b9f, 0x4e0f613f, - 0x733cc377, 0x3c9f91ad, 0x05e37281, 0x677bd92b, 0xc2117459, 0xaed3b67f, - 0x70277be0, 0x4250e95e, 0xeaf3829b, 0x043d9276, 0x10b39a7c, 0x36b93bbe, - 0xe04bcf9b, 0x0986e4e9, 0xcd9b17c4, 0xb3f0bc7c, 0xc27fbd0a, 0x0391981c, - 0x974f13f5, 0x534056fb, 0xb512c05f, 0xee873d00, 0xbd5e76e3, 0x7881df49, - 0x09538762, 0xa11eb95e, 0x62678b8d, 0xf2e9687b, 0x1c7ca3af, 0xde51cf8e, - 0xd9b904b3, 0xc805e2cb, 0x461adb4f, 0x9f514675, 0x91f38f74, 0x585e655a, - 0x171ba07c, 0x9994f77f, 0xc87e35e3, 0xbe7cf44c, 0xb57ce3fd, 0x707fae2a, - 0x65c8109c, 0xe48ff926, 0x1d5d4272, 0xfec8ceaa, 0x2d973d0c, 0xfb633aec, - 0x1de0ceeb, 0xe6bfa06e, 0x9de7fffb, 0x38df8465, 0x9ed645c9, 0xca797c49, - 0x748b9fec, 0x5a89aeeb, 0xf3e827e6, 0xeaaf820d, 0x63fec2ad, 0x1f224b51, - 0x6aaaf6ca, 0x72cbdd23, 0x677fa0bd, 0xc1f7cb8c, 0x1fc126ed, 0x1ea2b4df, - 0x6641c29b, 0x1c47a885, 0xfd4ebfd8, 0x6a20f94f, 0xe17a87a9, 0x9165a8f2, - 0x004f9128, 0xcc1b51df, 0x2756d4fb, 0x03406fe7, 0x3268b3f6, 0x48b97d23, - 0x02b5fb05, 0x3d5deb9f, 0x9fa72eb0, 0xfafa7376, 0xf0056023, 0xf7898f3d, - 0x82ef60ac, 0x4da67b1c, 0x607ee289, 0x2eeb16de, 0xb5f2117b, 0x7ae2755f, - 0x8e48576e, 0x569b6bcd, 0x4bea15b2, 0xeb405c0f, 0xd399369f, 0x9b88d2e5, - 0x2114e2f4, 0x11adeb1f, 0x3fdfd90b, 0x01f21851, 0x74764ff4, 0x53947c23, - 0x280f1831, 0x10f40dd7, 0x5d83a849, 0xcb93a534, 0x9cf20655, 0x524bd825, - 0x671ca3de, 0x919ff649, 0x1f52c23e, 0xf4c7b971, 0x527b946c, 0x0aebdf2e, - 0xae49b974, 0xf5c6ce8d, 0x72e4f585, 0x7842bf73, 0xa42d626d, 0xe81ea44f, - 0x91e8571f, 0xeb986ad3, 0x2a26eb2b, 0xd117775f, 0x27594b78, 0x57a913e9, - 0xd783a386, 0x7e0e84bf, 0xed007486, 0xe8b01f8d, 0xe35e3065, 0x9a6d1672, - 0x44e74bc8, 0x4f5c8fd2, 0xc49eb8da, 0xf43ce532, 0x4c7eb265, 0x7ac987d6, - 0xf5c2db30, 0x69675c9d, 0xe74f64cf, 0xe594c076, 0xfcc19511, 0x3ff9a636, - 0x60349cce, 0xb2de84d7, 0xb10bf4d9, 0xe0a3601e, 0xd369c5bd, 0xf686ca6e, - 0xc8fcc690, 0x9780a957, 0xbb7cf09d, 0xb36b7bb0, 0x2d7bdd39, 0x5acd7e9c, - 0x703b9580, 0xcfb4625d, 0x1732678d, 0xe7c4a3d2, 0x577c2776, 0xfd71df81, - 0x8dbdffd4, 0x7c24a5b5, 0x9d9cfd5f, 0xcfe7eae4, 0xb256233a, 0x6e858247, - 0x57eb2fe8, 0x7b53b256, 0x3e92739f, 0xd0fa15ed, 0xd128f683, 0x5fae2acb, - 0x21275d71, 0x648f5535, 0x35cafb48, 0x4a045123, 0xcdc9acfb, 0xf6c1aced, - 0x8a2f6890, 0xcae9cf5d, 0xcfccfb4a, 0x62773ddd, 0x6861e01d, 0x588fff9f, - 0xe981d0e7, 0xe787dfe5, 0xc7c380a1, 0x472c1fb1, 0xdfaab57a, 0xf406deb9, - 0x1e5d4335, 0xd1e60bbf, 0xa170ef94, 0xfc29ab9e, 0x846f2ff5, 0xcc0787fa, - 0xbceb8acc, 0x1b1d7a67, 0x5dfcbc35, 0xe89f3112, 0x5b97e049, 0x4deb19f6, - 0xa87ac69d, 0xc82f58cb, 0x4f4e7a70, 0xfbe1d920, 0xd5b5d033, 0x4ec1f2da, - 0xbcfad780, 0xa7d1f495, 0x067160ee, 0xfc535bca, 0x5ad9e218, 0xf444f1f8, - 0x3fba846f, 0x02b4b051, 0x38cac4ed, 0x3faf91fe, 0x742bcfb7, 0x01b7810d, - 0x899b31fc, 0x3ad60cf0, 0x85ce492f, 0x2c789f04, 0x845f0ffe, 0x9d9a2ff9, - 0x9e9bbae2, 0xaa4e67f8, 0x60927b42, 0x572da164, 0x2dfb887f, 0xae096f78, - 0xf059e9ff, 0xb0d5c01e, 0x46c3eb85, 0xbe434b16, 0xd3bb066d, 0x477c4b06, - 0x5b875f06, 0x5155e2da, 0x8c8edff8, 0xa70871da, 0x802d27f6, 0xfb1ab1f4, - 0xaf93b04d, 0xe07ae0cd, 0xd7767d96, 0xdd1e0329, 0x2ba87a86, 0x912a75c7, - 0x61fc84ff, 0xb8968a79, 0x09577a1f, 0x6bf88b5e, 0xa658f5b2, 0xfc57f8c1, - 0xf79233e9, 0xa7cd978b, 0x5d80c47d, 0xb4f9256d, 0x3d20aef8, 0xdf2b697f, - 0x6ade9e17, 0xa7ef11d7, 0xe3fdf3b7, 0xc4473ce2, 0x857bff06, 0x8bdbdb9b, - 0x19453be1, 0xbc64c78c, 0x55f0ffbd, 0xf7a3a45e, 0xdc2f1f19, 0xf78fedc9, - 0x62af805d, 0xf7f60efe, 0xefd8177e, 0xaaf9e20a, 0x2e2e510f, 0xd0faaede, - 0x9c87604e, 0xbc598fe4, 0x0b71cafd, 0xa7dfd81d, 0x5fa1a623, 0xe895c768, - 0x02f7c289, 0x89d7ee11, 0xb5cf015d, 0x1d93171d, 0x95bb7477, 0xedb6e9c3, - 0xf15c79c5, 0x4af89527, 0xda20b133, 0xff161dc7, 0xfd67e438, 0x70333de1, - 0x959fde5d, 0x1ff7a26b, 0xf10b9857, 0x85965ee1, 0x5a2b17cf, 0x61b7f900, - 0x899992cb, 0x866a4ef6, 0xad35eb4a, 0x8f567970, 0x7ae9f883, 0xdb4da3d4, - 0xfc707f81, 0xf2ff6fd9, 0x3f224f46, 0x4cc55edd, 0xc3cbf609, 0xc27a235f, - 0x6be028bf, 0x57d7c0b1, 0xaa6b2be5, 0x12968be4, 0xef8ba394, 0x0d71296e, - 0xf3f45761, 0x0f9cc3c5, 0xb850cbef, 0xc32f20ff, 0x6e18cfb0, 0x3528e65f, - 0xf9b15e91, 0x940f7f98, 0xc62db0d9, 0x0c81f7fd, 0x640fda8d, 0xfb5f7b70, - 0x5efb6ddd, 0xcd4d7987, 0x80cf6e08, 0x97f3217a, 0x71ebbae3, 0xb1983557, - 0xbbb26288, 0x6e56c3d8, 0x8edc6ac7, 0xf6c99cde, 0x8fd84bae, 0x997f6277, - 0x62f61724, 0xffc7bd3f, 0xdaf10c78, 0x44f1f05c, 0xe7420fb4, 0x1fa0b33e, - 0x90add1cd, 0x02f8773c, 0xd425e90c, 0x282d8b3d, 0x21c3901b, 0xc913d71f, - 0x0653faf3, 0x3c84efdf, 0xfde7ea71, 0x3b7f9c11, 0xb73e9cdc, 0x3f214b2d, - 0xc44f36e4, 0xb5ff408e, 0xa5ed2a7c, 0x67efc225, 0x5f94fddb, 0x288efa45, - 0xd75831ae, 0x35f47f39, 0x30a88dcc, 0x8bbb87ce, 0x77d9dfc9, 0x854f9a60, - 0x1feec736, 0x788519ad, 0xf0fb32ea, 0x27af877d, 0xe1f7e70d, 0x386993ee, - 0x2add86bf, 0xf221bbcd, 0xb2c2d649, 0x33f0b901, 0xca3af825, 0x1c52e601, - 0x0f94be38, 0x34feee1f, 0xfb83816b, 0x567f480b, 0xa7978d0e, 0x8e7ed3dc, - 0x39715fdf, 0x1e8f975f, 0xee5046b7, 0xfd07647d, 0x3f6f2096, 0x777d7272, - 0xefee432a, 0xdf500b3a, 0x2a6fd7f4, 0xf89ca135, 0xdfcf8b8e, 0x402ce963, - 0x628dfc7e, 0x1ae967ec, 0x6c808b13, 0x5006b25f, 0xa3e8f203, 0x40299f47, - 0x9ee1ff79, 0x27e60a67, 0x9dfc97c0, 0x78e57b2c, 0xfd266fc2, 0x344b1ea8, - 0xef9bc70f, 0xe57f72b3, 0xf9547e30, 0xfdc2db3e, 0xab3e7da1, 0xbf28748e, - 0xf1486beb, 0xc7db7da3, 0xe6ff246c, 0xacbf0b77, 0x83da3fdf, 0x7df918fb, - 0x1e15ff52, 0x974a4f4e, 0xd483fe42, 0xe3c938b2, 0x7bde59bf, 0xe4133d60, - 0xbff3ac3d, 0xd9345f21, 0x3246c7e2, 0xe20b0fa2, 0xd0ecd2cd, 0xad653f50, - 0xbf15f4e4, 0x2afb44c3, 0x81d7ae4b, 0x928aecf2, 0x30133694, 0x6d2527a2, - 0xf201c622, 0xfde94b73, 0xfba73570, 0x7f231670, 0x516b0e5b, 0xb8bb5e48, - 0x326f3edf, 0xea83ad73, 0x9edc11ac, 0x16df32f1, 0x5dd698b5, 0xc490ff41, - 0x480bd487, 0x3f1f283f, 0x3f446c52, 0x7642b74a, 0x9cea6aa7, 0x470efd8b, - 0xc847134f, 0xa7a73ffd, 0x893ffafe, 0x188f269e, 0x3a829e8e, 0x36d793d1, - 0x3f093d34, 0xcfbf79f1, 0xbfdc01c2, 0xdd7c0b66, 0xfc4ee427, 0x9bf49b0e, - 0x99df382b, 0x3699bfa2, 0xfd455447, 0x9c7f33e1, 0x187dffe8, 0x27dc5fec, - 0x0efda0e5, 0xf395c8e5, 0x16375a74, 0x417f41eb, 0xd236c5ea, 0x629af78f, - 0x64af6845, 0x8fd96f8f, 0xb73d9174, 0xed2562ac, 0xa8dcf2ff, 0x92b7500f, - 0x7559741f, 0x0488d4e0, 0xdf10e17b, 0xe5df34cf, 0xbbd3e7a7, 0x1a107db9, - 0x387b216d, 0x7184a5d4, 0x96039b9d, 0x6b41da08, 0x095fee15, 0x3cebb06f, - 0xa0afa3ee, 0x740fcfb8, 0x488a171e, 0x8ecf6fff, 0x35bd23ef, 0x91efc838, - 0xf83a3f1c, 0x1fc7ca85, 0x8efc68c3, 0xeaaf1e72, 0xfee75ab8, 0x1d7eb115, - 0x6e39fcb3, 0x18d607b4, 0x85c659f9, 0x18809cfa, 0x7afe6f18, 0xae43ad3b, - 0xd2ccf1ca, 0x0cff5c6d, 0x67e40b96, 0x162c9ace, 0xfa6fc446, 0x05241cf9, - 0xbb4573d6, 0xcb39378c, 0x79684502, 0xb7e9bbbf, 0xbd00a4af, 0x8e9fa166, - 0x68c2ca6f, 0x987f93f7, 0xfc7dc9d7, 0xc90009a0, 0x5cffd6c5, 0x42697357, - 0xf03fbc5d, 0x6b6bdcfd, 0xf6ef48f2, 0xa0d823b7, 0x6fdd658f, 0x351e31d7, - 0xbd81aed0, 0xf852eb6b, 0xb5c761f7, 0x3c068e57, 0xfffc7228, 0x7f47eb5c, - 0xc6199da1, 0x4b4f844b, 0xfd0cdfea, 0x7ef9743b, 0x784af6bc, 0x590ac1e1, - 0x1fad66bf, 0x6ccfbbe0, 0x2a508fec, 0x1c8ac7be, 0x6dacd6ef, 0x0de7d6eb, - 0x276005d8, 0x39911aec, 0x7eac1f60, 0x85fb667b, 0xebaa5630, 0x5dea0b53, - 0x1e43e7a9, 0x648fec85, 0xe4203d7e, 0x572cdfc3, 0xf47641f5, 0x57241181, - 0x4b20667b, 0xe483fec2, 0x80796876, 0xf6073da1, 0xdbc21748, 0xd3e3fc7b, - 0xef7b422f, 0x1b1fdfec, 0xb77be3a9, 0x37bb45ce, 0xba234e74, 0x2353ed0d, - 0x4dadd00a, 0x71e80bf0, 0x7a480b8a, 0x7412ea5a, 0x8c330eea, 0x521c7473, - 0xbe898526, 0x83ae0a5a, 0xf8f7ccb5, 0xe438425f, 0xde7932be, 0xf7c11ebf, - 0xead2a10f, 0xffd825ad, 0x9da1856e, 0x44f4aeb0, 0x37da02d6, 0x30b59bbd, - 0x5d25bbe1, 0x973e120f, 0x890f33ec, 0xe08f5fc7, 0x67e6de71, 0xdca3f69f, - 0x90a228f8, 0x22d0684c, 0xbd40a76b, 0x9684c1a1, 0xcc8cab20, 0x1ce291bb, - 0x06361675, 0xed0477e6, 0xdf638426, 0x7053c337, 0x814ff0de, 0x8b02db47, - 0xab6e9f48, 0x4e2839b3, 0x56ff3a54, 0xc52b83c2, 0x5758788f, 0xe3839d5a, - 0xe19acf34, 0xd808f8a2, 0x7cded871, 0x2fc8b7d7, 0xd75ae124, 0x3b45ae65, - 0xb9ec0aa7, 0xfcee00a7, 0x7d6a6b8c, 0xd523c7c0, 0x3bb7e5fd, 0xb43e5e30, - 0x266eff1c, 0x25368ba7, 0x2546fe10, 0xa25941f9, 0x8bb0b35f, 0x8d9f8ddb, - 0x2be218b0, 0xf6e08d9f, 0xd8e1a5ec, 0xc39f2474, 0xda2a4f5a, 0xffe621d3, - 0x2ccff704, 0xd0f7d0e0, 0xe479713a, 0x3fc9d569, 0xdcf4f366, 0x5fb6217b, - 0x85fed1aa, 0xe00f3d69, 0x3d6bbdb8, 0xf04c75be, 0x2aefd601, 0xbd4f7da3, - 0x3278a827, 0x7d70bcf9, 0xaabd9f7b, 0xd288fd1c, 0xa8fb5aee, 0x5ae6f49d, - 0x2d7f7ea7, 0x69dfd3ca, 0x16c01f3c, 0x7e874d8f, 0x833efe96, 0x8f6b5dc6, - 0x0ff5c5ac, 0xbda954ef, 0x607411d8, 0xb9be4bbf, 0x2bd22265, 0x504a4473, - 0xed3d9a8f, 0xb618e90c, 0xb12fe42b, 0xe30c0279, 0xf3c3d3c4, 0x45f50534, - 0x1d333d92, 0x5fb455fd, 0xb6bf90f1, 0x18c7f05a, 0x36d382a0, 0x3fb68562, - 0x6fb0188f, 0x1ce3f95e, 0xbb4a1f0d, 0xfee364c7, 0x14ba9af3, 0x5b2df686, - 0x42663f15, 0xc627bd7f, 0xea6e0ed0, 0xa69c6854, 0xb82d27d2, 0x93a5b96f, - 0xec4877f3, 0x057f0033, 0xf18c5768, 0xa07b0aa4, 0x5839fb8d, 0xc448d8ec, - 0x3d7c63f3, 0x12f78319, 0xad8cabfc, 0xf440f2e0, 0x86711167, 0x0257e126, - 0x3eed484d, 0xef5bb48f, 0xf3b7fd16, 0x59bb8c52, 0xc455f989, 0xf062b96b, - 0x2af2cb87, 0x91fa7df1, 0xdfe40cf8, 0xfa17d038, 0xb32ab697, 0xcc29fd6e, - 0xf1a4eb6f, 0xbcc1343e, 0x056a4e40, 0x0452073e, 0x7d7657bc, 0x86e90332, - 0xd7e232d5, 0x6a69aee6, 0x6fc78393, 0x4ec85ed0, 0xed89d96d, 0x929737d9, - 0xc8f8c67e, 0x35fe786c, 0x1cb3e70f, 0x79d7f707, 0x61170eef, 0x48fd33bc, - 0xe29fd6e0, 0x90a417f8, 0xd61b35bf, 0xe54199c6, 0x796ff41a, 0xa88bf959, - 0xf533bd7f, 0xc647840a, 0x382e30f5, 0x38e48cab, 0x8a7c33d5, 0x3794177f, - 0x0e34dc78, 0x116aefec, 0x711e7c5e, 0xd119c40c, 0x62e3876f, 0xdecb0f1c, - 0x7e46a89c, 0x7be7d07e, 0xacbb4e90, 0xccd7c42e, 0x42df97ae, 0xc6d33b7d, - 0x9aee293a, 0xd3c4b764, 0x3a4419be, 0x7a733bed, 0xd7083dc7, 0x947d0775, - 0x8f6492cf, 0xb739715c, 0x93da3fcb, 0xec3f23aa, 0xec1b7212, 0x797f1e47, - 0x9323ef9c, 0xf6efc8ed, 0x23b72faf, 0x777febfb, 0x17c3923b, 0x28f3c3de, - 0x890f7ca4, 0xc35f5f7d, 0x5fd434d9, 0xaed23d2b, 0xd8f7ca4d, 0xba3df22d, - 0xd0f7ce87, 0x0ff8f276, 0xee494186, 0xae222dba, 0x43cef7e5, 0x84bb87ff, - 0x7b2bc0e4, 0x3748c353, 0x64ed3b67, 0x4b6e6997, 0x7b6ae114, 0x3cc11ada, - 0xe0453688, 0x578890eb, 0x2c1c4459, 0x834744a3, 0x4025a0e2, 0xa4fc3f72, - 0xd2abc799, 0x85ee8f22, 0x1ce1e37a, 0xd462cf11, 0x54d9f87f, 0x8a6377c2, - 0x37fd8e9e, 0x8608fbfe, 0x183eaa71, 0x09f9d70f, 0x87bb707b, 0x7fbc5ae2, - 0xe75582f6, 0x8968b3f1, 0x33b0f01b, 0x93bfedc2, 0x05a8a6a5, 0x8993bde6, - 0x32f59f3c, 0xd9e7c5ae, 0x8f2461b7, 0x8231a0cb, 0xdcb5b2fb, 0xe32f545f, - 0x1fb98755, 0xa5c45eae, 0xf45ece4e, 0xb458a608, 0xb8b52d29, 0xdd7cfb4f, - 0xdf9ff234, 0x2a2cff79, 0xfd18d7eb, 0x3fd08bfd, 0x3f103c5f, 0xf9f77e96, - 0xf6e167cc, 0xd0ff80f3, 0xbe8cf604, 0xfd46ab46, 0x775cc459, 0xc3d03ea3, - 0x43177ab0, 0x1a2506d9, 0x19600af1, 0x7ad6d3de, 0x57bd7052, 0x6f4899b7, - 0x7e4cdb85, 0xcbd24f7c, 0x67ae1eab, 0xbd70f5df, 0xe08ea803, 0x336cb238, - 0xe883788b, 0x4533056f, 0xbc2934b1, 0x6ad2ed5c, 0xb2dfd287, 0x8b7336bf, - 0xcdda1a6d, 0x77f226f9, 0xd7f16e7f, 0xa338bf91, 0xcda9d684, 0x96a6b2d9, - 0x7d2f13b7, 0xa8078f6e, 0x1b8d32fd, 0x40cf4c96, 0x8782fa79, 0xf19217c7, - 0x58ddb0b6, 0x2cc38e4f, 0xf5eb1889, 0xa736382c, 0x120dc798, 0xf420bf9f, - 0x8aebe7c4, 0x167dbe04, 0xfe72bb94, 0xde38f22b, 0x1cbcf94c, 0x875d5f95, - 0xe30a3074, 0x725845ca, 0x84cc2abf, 0x99751fe0, 0x48fa2147, 0xcdcdb782, - 0x96bc29e9, 0x5aff21fb, 0xfee193f8, 0xf82593d0, 0xb8c5efd8, 0x42cbbd65, - 0xf5f3e871, 0x1a64a497, 0xf5fdb7f7, 0x96feffbf, 0xaad7e7ef, 0x45c6bf22, - 0x8bbe6972, 0xe2a4e5cf, 0xe7c51bdb, 0x701fb00e, 0x0ad56b1e, 0xbfd32394, - 0x3479a0e9, 0x8239061f, 0x3de5ac71, 0x9bd7a805, 0x304a7bab, 0x5f8c935e, - 0xf2935684, 0xef9bde0c, 0xda08fd81, 0xf18c6b0d, 0x55f1c1b8, 0x2666617f, - 0xee4e7bee, 0xd7f5197f, 0x2fe93b7e, 0xad17bff8, 0x16cfffc8, 0x388b5c91, - 0x2e316383, 0xee894a14, 0xda1171f8, 0x6a8edc31, 0x44eeb6ea, 0x5b7e713b, - 0xff0f7c42, 0xef18deb3, 0xc8326b63, 0x8c3aceef, 0x4e1e1bcf, 0xfc506efa, - 0x65d69daf, 0x0e3825b3, 0x10f41df9, 0x599c1de5, 0xbeb86262, 0x116faaf5, - 0x7633a92a, 0xc67e7da3, 0x466bd7c9, 0x3e3fd4a6, 0xebfabfb2, 0x57d9d683, - 0x6f5ceb82, 0x7ec4c162, 0x619d709a, 0x3ac51b7d, 0xe2fa799f, 0x8fe75c12, - 0x825c5ff7, 0xdcd9bceb, 0x29be47ee, 0x41af0775, 0x32ba9cfc, 0xe615f640, - 0x9d1f20ef, 0x94de3d2f, 0xfd378f44, 0x2eb1e8e3, 0x59321f31, 0xe3f4363f, - 0x3d1fa8cb, 0xe50f3d16, 0xf59b7cc1, 0xfc49ea2f, 0x679fd21b, 0xe3ff92b3, - 0xdd3f1ff0, 0xdd18f948, 0xb227d92a, 0xb05ac3bf, 0xc3a3ed18, 0x617d796f, - 0xd3fef865, 0xb5e5fd85, 0x59fa30b1, 0xda40bee4, 0x78f2c997, 0x03cf98b9, - 0x8cdffe99, 0x3ce21bf8, 0x20dc7fd2, 0x3e45b1de, 0x6eef76e5, 0xc7fdc7c5, - 0x6e4fe49d, 0x85cf343e, 0x220fe2fe, 0xfcdc7fdc, 0x8ff93974, 0x8a5e4497, - 0xeb193e62, 0x1fb85c56, 0xddfbb259, 0x9003cc34, 0xe7d85efb, 0xf9499fde, - 0xeffdc635, 0x69939107, 0x70003798, 0xa7708fbf, 0xa416e27a, 0xffd866fb, - 0xb360de61, 0xfd863f16, 0xd9187b36, 0xc65d9505, 0xef8ca0fd, 0x48580b6e, - 0x56eb6eee, 0xb3af2822, 0x3ca2c12c, 0xcf2c6bd4, 0x80753a75, 0xfe9922cf, - 0x077e9017, 0x5dfeeae2, 0xa7fe9758, 0x44e9ad9e, 0xe6663dbf, 0xdb3ca177, - 0x4cf214ea, 0xdbf6f923, 0x7591dd87, 0x6fc37609, 0x584edc23, 0x34c1f322, - 0xbd60d516, 0x1ff1cd16, 0x7946f5c7, 0xf7924d1f, 0xaf197589, 0x494585bf, - 0x9eb1352f, 0xc4b0bcfe, 0xf9e392f7, 0xf4370718, 0x75ca5ac3, 0xe4dd93f4, - 0xab9c51f0, 0x6356cfeb, 0x9bef987b, 0x55961f81, 0x5cafd00c, 0xcdbf4907, - 0x6a1d1fc2, 0xe90ab138, 0xb8a5d437, 0xe8dd7f70, 0x08dbf4e3, 0x9bcc2ffb, - 0xd677e64d, 0x1d13cc69, 0xdd7fff8e, 0xff9c77cf, 0x9cac3d7f, 0x5bf8c7fa, - 0x3f97efdf, 0xfce5ef9c, 0x7fbeffa5, 0xe70add9e, 0x2579a4cb, 0xfd935bef, - 0x79df72ee, 0x8bf0f2be, 0xf17c7c24, 0x70c7c60f, 0x6b2530f2, 0x7242fde8, - 0x96afe35c, 0xf8e0ff87, 0x1e8723c6, 0xa881334a, 0xf6145258, 0x6fcebb72, - 0x50cf1788, 0x371e7e1d, 0x453e7955, 0x9f5ddc72, 0x9ceee221, 0x5a7a5f9f, - 0x126af5a5, 0x43a6e1f1, 0xdabe1f4e, 0xf14c58e0, 0xe9f8e4d9, 0x067fb652, - 0x1c72512e, 0xb8f911b5, 0xa9e3cbf8, 0x3d396517, 0x56749f24, 0xc90a7984, - 0x392f5a79, 0x4c111d3e, 0x32eaef58, 0x410c08d8, 0xcc2d36d7, 0x4f9e1232, - 0xf4f6e2cb, 0xc89f224b, 0x05e7e16b, 0xfaa673ee, 0x35e31f71, 0x7ca77cf1, - 0xd67a604f, 0x02ef9424, 0xc0decf9f, 0x4797804c, 0x4f249dcc, 0x1f0e4dc2, - 0xc7e93fca, 0x10effd91, 0xa5f38b71, 0x19676ff3, 0xfebfbce9, 0x85fbe24f, - 0xdaffbe92, 0xc016ddb8, 0x181f818d, 0x186befd1, 0x4c1a2a67, 0x33f5c3b7, - 0xcb2efd1c, 0x459edc0a, 0xa44ff178, 0x94f3e6fc, 0xf195a92f, 0x622fe893, - 0xfa3aac07, 0xfce26d37, 0x239f5b0b, 0xaabeebf6, 0xcd979459, 0x73c88fcf, - 0x8fd9c336, 0x9ff9fb1b, 0xf5fd8fdb, 0xc8fd93bf, 0x9c7681dc, 0x7e69a9e7, - 0xed5ffbca, 0x5f71f804, 0xc875a8f8, 0xdcf22cf3, 0x5df997c5, 0xcdc3f6f6, - 0xb0ef6ae9, 0xe563ff70, 0x34ff93e7, 0x34fbf9f9, 0xdf0ea3f4, 0x7be4584f, - 0x9e22fcc6, 0xf82576c6, 0x9e3143b7, 0x8092f7af, 0x447f3e57, 0x6cf4c5e8, - 0xa75c51ff, 0x6cdb8f8f, 0x9e4c1d2c, 0x9b172e4a, 0x2f8a0e03, 0xbcf27734, - 0x8ce5e697, 0xfa3377e4, 0xafd0cb4f, 0xbda18b38, 0xf8233537, 0xf57efc33, - 0x9ab08edb, 0xd9f77e8e, 0xdebbed0c, 0xa9febce3, 0x6c73f83b, 0xa1ef2d0f, - 0xecc74678, 0xaaef288f, 0xae9fcfea, 0x7824adaa, 0xb1e08fc9, 0x7cadcf1a, - 0x0fe3c591, 0xbf43fcb2, 0x5f93f13c, 0x9e06e3ff, 0xf8f21d9f, 0x908fe85d, - 0x3d54f17e, 0xe6a67e46, 0xab68dc03, 0xd87cf952, 0x9e88f3f7, 0x2b4c0f9a, - 0xeb29ff47, 0x9da397b4, 0x072bf55b, 0xbe3ef7ed, 0x24f2972b, 0x0fc13dea, - 0x2b3a3e51, 0x5da35723, 0xa0e3085a, 0xfef1fbbd, 0x6e11cbab, 0xa336ff29, - 0xdfc61cff, 0xc7fa34ec, 0xd9e78d99, 0x4f9bdd2f, 0x4762cbfb, 0x6fec53f0, - 0x11c39db3, 0xa3ce23de, 0x3279bf08, 0xcfbe4bff, 0x4e344d56, 0x146db7f6, - 0x6172972f, 0x6d0599b3, 0xe4f203c5, 0xf22e9678, 0x635e444c, 0xa79e2cf7, - 0x8f0eea22, 0x81f3bf31, 0x238f2bcc, 0xb4b3c73c, 0xe61f96af, 0x402f9418, - 0x187e62fd, 0x9c5805c5, 0xe7a92dfc, 0xca3d1db8, 0x727a2165, 0x9c51df02, - 0xed09e806, 0xb1e34bf9, 0x6b9e78e9, 0x52f44774, 0x73e1f3c4, 0x3693c226, - 0xd38a35eb, 0xbc7c2ba4, 0x6b3df5e2, 0xc61fa2c7, 0xb865e6f5, 0xabbb7aa4, - 0x353a511a, 0x4d9f9023, 0x52968cfb, 0xbffaaf1c, 0xf29f3ccc, 0x17f92a50, - 0x291a0a3a, 0x6df7b29f, 0x4e3ce1ab, 0x77661972, 0xa8e4fe53, 0xbc505fae, - 0x194079c0, 0x72762f32, 0xd6f083b6, 0xa0cd8e1c, 0x3d4b9b1c, 0x43b56724, - 0xb538a2bf, 0x094356b6, 0x7eccdac4, 0x0b439e13, 0xefe460af, 0x32e1d31c, - 0x8a157ae1, 0xc3be98fc, 0xa418987f, 0x0f8c8afd, 0x937e7844, 0xee1567b9, - 0x3d15b4c3, 0x3d718797, 0xcd4db80e, 0xbc5fd865, 0x872dfc99, 0x4fd21952, - 0xddf15761, 0xb85ea153, 0xb0f145c6, 0x296ee7be, 0xcc2aff24, 0xf310cc73, - 0xf336ca2c, 0x9aa50ffe, 0x9b699f50, 0xd5470f98, 0x04d559dc, 0x875083f7, - 0x3c8a467e, 0x453f1955, 0xa9ea143f, 0xd7e0ecf4, 0xffb63f30, 0x14b2d21c, - 0xe3490e7e, 0xb2e712fe, 0xf3c71fb7, 0xfc2c3b3d, 0xc391e79c, 0xdf936613, - 0xe0a6ad6f, 0xe6ee7c3a, 0x663794f9, 0x42e70c9b, 0x847ff006, 0x1d4756f2, - 0x6bd705fa, 0xaff61630, 0x68bd3999, 0xd13b3d6b, 0x2d38b8bf, 0x97ba7948, - 0x8a5545b5, 0x3d4eb99f, 0xec27ab50, 0x3d70b673, 0xef8fbcd3, 0x35f793cb, - 0x6e5fa65f, 0x2dda36cb, 0x927ff5fd, 0xfe83f2dd, 0xfdc6fff1, 0xf3ee330a, - 0xe497ed92, 0x3b20dd7d, 0xe1bfa93c, 0x8f9918ec, 0x0e303d52, 0xd29da7b7, - 0xf21b0a4e, 0xe21daa75, 0xd8cda17c, 0x5c23e5ff, 0xbf995f34, 0x5f52b593, - 0xf1fa7981, 0xd7f2301f, 0x70a23cc9, 0x09f7cf35, 0xee746c9b, 0x29dacbd0, - 0x8b24687f, 0xd3f90a2a, 0x6d7ce87a, 0xc111e636, 0x47b2eb77, 0x99dbbf51, - 0xf24a8d6f, 0x6e105752, 0x509fe63b, 0xeb646abe, 0x3ae71c22, 0xc7638d07, - 0x308b93fc, 0x15bfc085, 0x06f4ebe5, 0x05c85f1e, 0x9bf48c7d, 0xa1d39a3b, - 0xa1e78ebd, 0x99133cc8, 0x50f12217, 0x3b9bf02d, 0xca115176, 0xf04ab5c1, - 0x99ae7151, 0x4e0dffcb, 0xec195e71, 0x79c0cf6b, 0xfbc63ee4, 0xf898370f, - 0xaf376479, 0xf9d18c77, 0xf82fa079, 0x728ebb39, 0x2832779e, 0xaf09253f, - 0xc9e53f32, 0xe411e0b4, 0xcbf3e497, 0xd6124e92, 0x6f47ce8f, 0xfaedc43b, - 0xcd0b06ea, 0x35c96fa3, 0x5bec97e4, 0xffa86262, 0x9cadbbab, 0xdbc692ee, - 0x51616756, 0xd88b57ec, 0xf5ca7e51, 0x16bb32ff, 0xfd14b5d6, 0x6b5a47be, - 0x38053a2f, 0xa01ada3e, 0x74aecfb2, 0xf9d217aa, 0xa928b9d2, 0xf9f2d89e, - 0xe60e5ab5, 0x140bc4db, 0xb7e79920, 0xea93347e, 0xb077f199, 0xcf16eafe, - 0xc39034d7, 0x3be2637d, 0xffff7814, 0xdbc47f79, 0x19731691, 0x87a1f77b, - 0x5f1d8666, 0x91fddf41, 0x9c71e725, 0xc4d3bd41, 0xc8c5567a, 0x5df4245f, - 0x5e879725, 0x25ec8587, 0x653fc8af, 0x151f2235, 0x5f503b23, 0x714e5399, - 0x0fd3077b, 0x8f3db0c4, 0x7682cf9f, 0x6395ffa2, 0x26da7fb8, 0x49e582e8, - 0x184f54bf, 0x22cadbe5, 0x2fdf7d37, 0x23580f8f, 0xc7c63fdc, 0x0be9e37f, - 0xf325be28, 0xe573196a, 0xf280b9cf, 0xfbf50c6c, 0xa61ce2ec, 0x73c7cae6, - 0xc2cd2bec, 0x36f515ee, 0x8bc53067, 0x043e44f3, 0x2b8dee7b, 0x7c865bbf, - 0xf7e0e674, 0xbb5ca347, 0x82fb02ca, 0xeed8e421, 0xfac72e1c, 0x0a358ecc, - 0x0ce3577c, 0xfac2f08e, 0x773a95bf, 0xa8291e06, 0x82cd311b, 0xf8581747, - 0x9af11551, 0x3dc4e829, 0xaee7c387, 0x77982809, 0xc7ced2ba, 0x7e6a0ccd, - 0x9c10f73a, 0x70075ca3, 0xbcb854af, 0xc9d28f86, 0xd3d52a8e, 0xa3611cf1, - 0x0aaad738, 0xe74971b9, 0xf5ed1526, 0x35beb79f, 0xe006d355, 0x878885fb, - 0x78c8a2ff, 0xcbdca23e, 0xce5962ed, 0x900bf556, 0xf0ad56fe, 0x12f336bc, - 0xf8e9ce7c, 0x9565b4ca, 0x557da798, 0xfa254b6a, 0x4f3d0769, 0x0965e787, - 0xaf7f2b75, 0xc02f16d1, 0xed0be673, 0x8f8849c1, 0x7bbde7cf, 0x3b87ca27, - 0x0778df73, 0x30de24f3, 0xaf91390b, 0x98eef588, 0x79eb069e, 0xf22dd8ac, - 0x0f446c3c, 0x3f72c6c7, 0xdb1e7f64, 0xfaf28538, 0xe7e1ce66, 0xb165af49, - 0x9ef81eb6, 0x3ed0159c, 0xd9117263, 0xde453391, 0x02b78cc5, 0x9817e869, - 0x435c4371, 0x5d9c3a39, 0xacd79574, 0xc3f024f7, 0x7eb1bad5, 0xfeb1a96d, - 0xfeb19f35, 0x1a7fc98d, 0xd97f589b, 0xf48d9fee, 0xf3c2bcf4, 0x3097c33e, - 0x47bdd117, 0x32fda309, 0x715c99e1, 0x27e7970e, 0x77d8abfe, 0x5199333d, - 0xdb3ed67b, 0x20373c2e, 0x68aad7fd, 0xb665e09f, 0xef7e0cc2, 0xb8bbea03, - 0x3d1cf222, 0x0761d314, 0x3f71756f, 0x816bbc2e, 0xd3ce0e7e, 0x46aa3f89, - 0x4e9052da, 0x76261cb2, 0xa552f239, 0x239aec8d, 0xb9e4ee82, 0x058d2aea, - 0x8602cf30, 0x1be5839c, 0xe88bd766, 0xc87f0ea7, 0x69dbe718, 0x8a5be51a, - 0x415b1831, 0x5d0487f5, 0xfff2911f, 0x57589a07, 0xef1840e0, 0x1e5cfaec, - 0x74652e87, 0x656cfe5e, 0xdd25d509, 0xae01fe4b, 0x41a18d1e, 0xe927f445, - 0x0b4ea7f9, 0xbf7a83d1, 0x34bbf849, 0xea590213, 0xb8807092, 0xc93d42c9, - 0x7195fec8, 0x6c9b7cba, 0x7ef8fcd7, 0x7e75930e, 0xd44b2bde, 0xaa6a29a1, - 0xf2fcfd40, 0x3b7f48ef, 0x879c417c, 0xe746cd25, 0xa3e38693, 0x767f825d, - 0x4b91f125, 0xe8f89abb, 0x3b92cea7, 0x9c6bee08, 0xa5afd42e, 0x0cba9730, - 0x2a23fd2a, 0x4fce3bf0, 0x474f8a6a, 0xed66f9be, 0x825aa9f1, 0x9bef869c, - 0xc6a9f7f8, 0x7df0bdef, 0x69f7c246, 0xe0d97df0, 0x6d3b77ef, 0xec44d351, - 0x21ef4aa7, 0xc9a5187d, 0xade6235e, 0xaeeff166, 0xa3b17911, 0xd47de0d3, - 0x3cc6a55b, 0x67d93613, 0xa4e4fca3, 0x94ab92bc, 0x57c839e5, 0xba9adb57, - 0x97bfa07b, 0x655e3ac5, 0x82e67e0a, 0x2dcf2fe7, 0x57fc8a39, 0x98688b6b, - 0x8b2d77d7, 0xedc5c2ae, 0xc47c169b, 0xe1f24c5d, 0x6693e459, 0x03363835, - 0xedcc67ea, 0x222d6fa3, 0x9bce79fe, 0x495e1839, 0xa45e1227, 0x493fa417, - 0xf770c92f, 0x3bd7e7af, 0x3b6f1129, 0x4a5851d8, 0x16b18abb, 0xe7ad779e, - 0x880bcc0f, 0x65ad8668, 0x2f35da34, 0xdc93092f, 0x00fdcab8, 0x9cbd65e5, - 0x944ffc1b, 0x7e177567, 0xcbe1a052, 0x716379de, 0xc6f000df, 0x95e137fe, - 0xbca0e3f6, 0x862d0fe3, 0xf8e1e3bc, 0x421b8e4c, 0xfcc550bb, 0x47949de4, - 0xf0e39a1c, 0x109179e1, 0x5256c1e6, 0xc2ec8afc, 0x6f6e14e7, 0xb09b1587, - 0x3f37cee3, 0xaf7b7199, 0x33dedfa9, 0x9477d7e4, 0x6e3bb873, 0x35fde5d5, - 0xc79c5edc, 0x4b393db8, 0x51742fb4, 0xefc3ccbb, 0x86fdc9d8, 0xd58f4f1d, - 0x03b05fb1, 0xe9607ec9, 0x322ccec2, 0x7f839bde, 0xde40d64a, 0xb73366f8, - 0x7c99b75f, 0x62e79455, 0x9ce2f7e1, 0x318cfe91, 0xff64fc7c, 0x628e6e62, - 0xd7f74f88, 0xc5fe4eff, 0x3f307752, 0x585bfa07, 0x4c502fe6, 0x33f71708, - 0x1c3e7d02, 0xd6fe9863, 0xfeed1a32, 0x9bcb59ab, 0xcfa262a6, 0xcfa41ce2, - 0xc59f4009, 0x9d1cfa06, 0x24e5c993, 0xb3e925c2, 0x934b2e9f, 0x1782caf3, - 0xee1d3f60, 0xa3355fce, 0xf56ddcbd, 0x9e5abcf1, 0x072c9827, 0xa059e012, - 0xaa3c7871, 0xc24cf04a, 0x39e19371, 0xa4493e1f, 0xf9c66ccf, 0xc97e3861, - 0x59d858d6, 0x2f2fc031, 0x083583db, 0xacdf3f7f, 0x41a3fbe2, 0xa20eab70, - 0xe46febaf, 0x2a509471, 0x4f1847d7, 0x67f181c9, 0x5faff189, 0xfaf0e9cb, - 0xdd10b17f, 0x8451f802, 0x9f68b67f, 0x7944ddd5, 0xcc6bb354, 0x00ed1227, - 0x13a9b719, 0x94f1cdef, 0xe605919b, 0x4bc634cc, 0xf1e26eea, 0x8b58eb9a, - 0x7ebde119, 0x3a9fb18e, 0xcc13feb6, 0xc9bbab0b, 0xd3983cf8, 0x8b19671f, - 0xc2a39671, 0xfc07d08f, 0xd3f4fc82, 0xdf0fc5cc, 0xf63bf40a, 0xe8156587, - 0x6b32ba77, 0x504deec9, 0xf1b6f1ff, 0xd669ff54, 0x06f3bfb7, 0xa128efb6, - 0xb9260d7a, 0xf9083ee1, 0xd54df511, 0xc114d78d, 0xa2ed47b8, 0x39f95bdf, - 0xb04a6f02, 0xe7bc1663, 0xf28a389d, 0xbc846b21, 0xdbc85be9, 0xc9d0bdaf, - 0xd66f5e53, 0x9358dfc9, 0x79f5efc2, 0x2bbffcad, 0x66b73f30, 0x3c57a894, - 0x47eb1e3f, 0x1ee84f95, 0x8726de80, 0xce6ff886, 0x09da7ee5, 0x1c744aa5, - 0x4326a5e0, 0xe7c4dff4, 0xd1e2b335, 0x9a8fe45c, 0x04cfde6a, 0xc5b5b4df, - 0x2ce99ef8, 0x6d737bd5, 0x250f2869, 0x70e7b59f, 0xa9ed2cfd, 0x67fbe080, - 0x8db6effc, 0x36037e80, 0x0c5387c5, 0xdf977e4c, 0xe7e0e55f, 0x22fe02cb, - 0xd3bcfd0d, 0xb37f3cfd, 0x0722b6da, 0x0f5fe7f7, 0x5e712a5a, 0x51f95b2e, - 0x27d26fb4, 0xf9449b4f, 0x466636be, 0xdf74073d, 0xf1787c41, 0x48690527, - 0xdd230e6c, 0x259aba4b, 0x48c6bde9, 0xdbafc0d7, 0x5cbf3272, 0xdae81b5e, - 0xc3d7403e, 0xd700b9d9, 0xa9ae098f, 0x3fd5fd46, 0x265f124e, 0xbc9c3b8f, - 0x7944bfc0, 0x275f003a, 0x661e5ff1, 0x7f2315c5, 0xecfe4bb6, 0xa62c3842, - 0x29b39d18, 0xe9e37c54, 0x7630ea60, 0x1f2f8486, 0x8315ae7d, 0x4d3fc2e1, - 0xcffc7fda, 0x3cf2fb83, 0xf9df0ed1, 0x5c00c659, 0x242bfe30, 0x7871570f, - 0x5c2d2bb6, 0x5c7b08be, 0xe59be7ee, 0xf38cbb7c, 0xe7e14aad, 0x77e8bdde, - 0xf97bdf21, 0xcfb87ef8, 0x7ce41d63, 0xcf6f4242, 0x169c05b1, 0xee75db98, - 0x1b9fa27a, 0xb469f858, 0x8339968f, 0x74f117ff, 0x843e14c4, 0xcc859cfb, - 0xa057f14f, 0x1272778f, 0x6f090dec, 0x879a9e32, 0xf3c9a791, 0xc0cfc649, - 0xbec8c5ba, 0xfad8e793, 0xf39e7be7, 0xc7897694, 0x6577f462, 0x8654ff08, - 0x452147f0, 0xc99e7ea1, 0x2fb87c52, 0xc853ee98, 0x6cc998be, 0xd6679724, - 0xe19e7d72, 0xd487f6e0, 0xc7f1c3fb, 0x92339715, 0x991b3357, 0xe7c73738, - 0xd9874c95, 0x2c0ee7ac, 0xadf4da67, 0xd1ef900b, 0xe007d14e, 0x7ee0e99f, - 0x215cecec, 0x24cf583f, 0xf5fdf3d4, 0x67be7a41, 0xe49fca12, 0x9e66c9fb, - 0x8cd2fee3, 0x99ca8c73, 0xa12777be, 0xeda8cf9e, 0xcc728499, 0x737bf2e9, - 0x1fdc0d27, 0xd1c78c98, 0x871926b9, 0x4cfa2f3b, 0x3f191fe6, 0xc706736b, - 0xcfd238e2, 0x55894671, 0x1e154be1, 0x583fe897, 0x76ec7484, 0xff434d15, - 0xe81b1cc5, 0xcbba1823, 0x1730bc15, 0x008fede9, 0xf10e6e0f, 0x75e3c055, - 0x347bc135, 0xe1e12c3e, 0x2b878136, 0xfb3d5e85, 0x89f14ab0, 0x43e97f1a, - 0xbd084218, 0xe2116662, 0x45e93f57, 0x59d8bf79, 0xf8a2a030, 0xb24e63fe, - 0x5abf1633, 0xb195f14f, 0x4f4c4c5b, 0x22e393d0, 0x327b8629, 0x30cbec26, - 0xcce82fd4, 0x617fbc35, 0x7b4328d7, 0xa1bc7479, 0x2a57a2fd, 0xb149f50c, - 0x2ff78629, 0x50daab7e, 0x1ae7a4bf, 0x3f53fbc3, 0x83a86d98, 0xde70d0c6, - 0xd8559f7b, 0x65f79836, 0xbe196ff1, 0x19b6cdff, 0xf3bc60af, 0xb2f7d8a4, - 0x0a563fb0, 0xe9205878, 0x637cdcf6, 0xaa25517f, 0xf3df2154, 0x79eb05bf, - 0xc034f6be, 0x0bbf625c, 0xc4f68ddb, 0x7ac62de2, 0x55a6f743, 0xe7071b28, - 0xe354b479, 0x79c93955, 0x79ae351e, 0x50cfa426, 0xe317d82e, 0x62ec1110, - 0x8e1b33cc, 0xfd6cbfcf, 0x2fe8d84b, 0xfefe7f5b, 0xf5d90b16, 0xaa7d5f8b, - 0xac8f0a2a, 0xdbfae35e, 0xa7fae375, 0xdfd71a96, 0x7fae33e9, 0xfae364fa, - 0xf5c6fdbb, 0x5c6b511f, 0x7180ccff, 0x8cebb3fd, 0x34139feb, 0x06c8ffae, - 0xb7e7fae3, 0x70bbd718, 0x8b3d7199, 0xed0d4bc2, 0xe52febc9, 0xdb9af165, - 0x7a01ef8c, 0x2074094d, 0xa04168e9, 0xc677f281, 0x30cf7fb4, 0xc03d324e, - 0xf744d1be, 0x6e3ec1bf, 0xf4fe729b, 0xfc8ad201, 0xf1f4c9bd, 0xeec2b96f, - 0xfa017414, 0x0ae513a8, 0x614f17d8, 0xd8563759, 0xeda181fb, 0x12bf290b, - 0xbee279f5, 0x36b93878, 0x7d894f48, 0x0a7ab0f2, 0x81f6c9f7, 0xf470f27d, - 0x8fb31c7b, 0x4f5a8ec8, 0x5d1ba57e, 0xf14f8e1c, 0xcfe825d1, 0xf2f4827d, - 0x32700071, 0xe71c7bc0, 0x4f1fe303, 0x8dfe4099, 0xd928b36f, 0x1982ffed, - 0xcdd83096, 0xe2ada898, 0x953a4f3d, 0x2f6f42f5, 0x858ffe14, 0xb95be0f6, - 0x9851efdc, 0xc5e6e385, 0x7b14bce8, 0xdd79c46d, 0xe3027123, 0x4f782008, - 0xca011c61, 0x9ba73b5e, 0xf8ae52d3, 0xc049ee99, 0x4ae9fce7, 0x6ab5d929, - 0xcd3de50a, 0xfd2141bf, 0x787fff34, 0x2cfa1719, 0x4cb95cb9, 0xd85db3e2, - 0x482edc03, 0x149ac3c7, 0x07416277, 0xc2e7cde1, 0xb8fe8675, 0xfc47ff1f, - 0x0ae3cd7c, 0xd06726d3, 0x675a3331, 0x0f3c6f5c, 0x9c38daa5, 0x0d999b8f, - 0x058139f1, 0x57bc0ec9, 0xfbc6d103, 0x7bfbcf1b, 0xd3fa1463, 0x7cfff554, - 0xcfe306ad, 0x9ffa2e38, 0xfe863e1d, 0x63ebd566, 0xf41abfe8, 0xba14c0fc, - 0xcebfa324, 0x87f87bf8, 0xc27e9178, 0xbb2f413c, 0xbdfb8c9d, 0x2386fc92, - 0x98c09055, 0xe7e663bf, 0x16dabdc3, 0xe63c9fbe, 0x984d635b, 0x37666337, - 0x32fbe79e, 0x6df3087b, 0xc7e4274f, 0x790cbac3, 0x3cb4e98f, 0xb657efae, - 0x71865c36, 0x07115ea2, 0x7835a7bb, 0xaab7ae19, 0x0e2f28f9, 0x277257ef, - 0x40f16f7c, 0x6a9f027b, 0xdd43068e, 0x5e1008ec, 0x10b6b556, 0x3dc598dd, - 0x6ef3ab50, 0xfc130573, 0x148e1712, 0xcc2d86f6, 0x984c595c, 0xc1f7f0c6, - 0x55f38674, 0xc4e9da5d, 0x0bd5a87d, 0x2bca25fd, 0xfa2590ad, 0xb6b4d7ad, - 0x94abdc10, 0xb33b1060, 0x3b51668e, 0xe1aadbe0, 0xbe785459, 0x67922af5, - 0x3e6de716, 0x3867f7bc, 0xdabd59fc, 0xc87289e7, 0x8728d23f, 0x5db56fee, - 0xd95af88e, 0x93c68cba, 0x756f6b78, 0x8df58e5d, 0xbed15ead, 0xb54dda82, - 0x71f482ba, 0x8621681a, 0xc7ad1671, 0xb03d7189, 0x03c61933, 0x045b5ecd, - 0xe1eac899, 0x05a3b2f0, 0x5d731f44, 0x8df4061c, 0xbc7d03e5, 0xfb4cccb3, - 0x1df3dbd3, 0xafedfef4, 0x0fd1798f, 0x1e01607c, 0xf98aff51, 0xf0238ff4, - 0x88721167, 0xf200c169, 0x23572595, 0x6b86747f, 0xdfe3ad36, 0xbbc49fda, - 0x1f28cec5, 0x20ef92d4, 0xe17cebbb, 0xf7148d0c, 0x27bc0950, 0x44f00fe3, - 0x8176f472, 0xe2efdba7, 0xefdbbe7e, 0xcec79460, 0xd55fc196, 0x148d5d00, - 0x059b25f2, 0x056f6ca8, 0xeb8252c1, 0x0b416365, 0x49d675e8, 0xbfd1db2f, - 0xcd7eed83, 0x4deaa18d, 0x58599e35, 0xaa7c9c6e, 0xbef1d91d, 0x618b3f4b, - 0xc474be89, 0x4581ab97, 0xc51fccf0, 0x1d783d8e, 0x89a7af35, 0x5e3ab4f6, - 0xe9ed174f, 0xf7cf5e01, 0x20d4a93f, 0x97f14960, 0xd5c6477c, 0x2dbe51a3, - 0xb27cfc60, 0x3b60e7b8, 0x91c2f213, 0xdb06ab31, 0xbe74626f, 0x50ffb640, - 0x4e38e7b4, 0x394629ac, 0xfdf8c73c, 0x6c878156, 0xe9f689c7, 0xb6319f14, - 0xa64af8cb, 0xf42bece3, 0xfdb1997d, 0xd3bdf141, 0x1d363671, 0xc71b47db, - 0x53da20df, 0x08ef3c1d, 0x473f21c4, 0x15efda2f, 0xc76c76ed, 0xed8d4bf1, - 0x2bf8c56b, 0x43ad0095, 0xf8899f3f, 0x9d568ee4, 0xf67cc9ea, 0x7e0cc8ea, - 0x99f0598e, 0xf21b196b, 0x23abfcdc, 0x9a4cbe79, 0x0ff7e3de, 0x7b650f21, - 0xb8a34b86, 0x10b5eaaf, 0x421d591d, 0xec3e088e, 0x8b4a2397, 0xf717138f, - 0x3d197f97, 0x8e7ee103, 0xfe00acf2, 0xbef39e90, 0x04c16263, 0x98db9679, - 0xef0982c2, 0x1864177b, 0xe53759ea, 0xccf7de1a, 0x77686519, 0xb4378e54, - 0xf13e58b3, 0xae826dc7, 0x0c2aca52, 0x02bef2ed, 0x923e73a6, 0xf479b576, - 0x677bc314, 0xa474f54b, 0xcb57d3ed, 0x367cabfb, 0x39b70b94, 0x1f236547, - 0x3275a4fe, 0xef20df1a, 0x8974a26c, 0xc9474bd2, 0xa2eab656, 0xc7f54a5e, - 0x7aaf3cdc, 0xd78fab65, 0x6f9d188b, 0x4b5ad95e, 0x2f81c7f5, 0x56d7fcb1, - 0xa07b953f, 0xfb0e160e, 0x43aff411, 0x7fa13b3f, 0xfd023fac, 0xfa1db963, - 0xd087f2c7, 0x856fb63f, 0x10feb17e, 0x83e585c0, 0x7f3e0fd0, 0xfac7fa00, - 0xd500d6a6, 0xa3ad6bef, 0x20d686fa, 0x36b6f795, 0xadb5f3d0, 0xdd5f542d, - 0x7bca8cba, 0xae54c35a, 0xed435d6c, 0x1f37a116, 0x1f1fe713, 0x7dcfc69b, - 0x467faf27, 0xeed5f29e, 0x4504a8bb, 0x93c8655e, 0x7dc3c8c8, 0x2f31a775, - 0x7047f110, 0x931e39d8, 0xe02b18e1, 0x2b62cf18, 0xa0dcb952, 0x2e98eb38, - 0xc0a9dddf, 0xf85b23a7, 0xc57517ba, 0x81a73da9, 0xcc56378f, 0x2cc27993, - 0xef1f8aaf, 0x957af7c5, 0x8f2a7558, 0x831f9337, 0x553f0179, 0x9133dce2, - 0x7084c479, 0x7f419369, 0x1fb3cc27, 0x270e6e5f, 0x78286de2, 0x7c78f22b, - 0xe4ecad43, 0xb6d49bf7, 0x52cd9147, 0xbf742dfc, 0x102ead89, 0x04f4a0d5, - 0xc24f7482, 0x603373f8, 0xed720593, 0x874ce5dc, 0xb8d1af32, 0x505dcaff, - 0xa8e7d861, 0xfd3236e7, 0xccb7e822, 0x194a4fb8, 0x3be19b7d, 0x0cf7de5b, - 0xddcf16ed, 0xb7f9f686, 0x22f2ad14, 0x8a32473e, 0xafd7593b, 0xd7003960, - 0x044d8ec2, 0xbde05057, 0xfdf9d157, 0xefc5fbed, 0xfffb0844, 0x2f812ec7, - 0xd7da7adb, 0x6af3758e, 0x84d87a49, 0xa7e3e7fa, 0xee8e49d2, 0xfe44c47d, - 0x622c71ed, 0x01337942, 0xbf6c48cc, 0x56726f00, 0x151ccae9, 0x574ce5eb, - 0x8b117eb1, 0xec08bed3, 0x17a43aff, 0xb11fffb0, 0x7e4cfd43, 0xbf3cc7f0, - 0xba7a4a2b, 0x8967ac44, 0xd16d07dc, 0x73c3fd92, 0x635fc8f3, 0x26d6073c, - 0xdc2b01f6, 0xef18d955, 0xff261ded, 0xd6fde9ce, 0x1eb005d4, 0x2a3a9cce, - 0xba0df3e5, 0xd173c869, 0xbf2abecb, 0x623d016c, 0x086597e4, 0x9fca99ff, - 0xaabba167, 0xf89c7479, 0xe52ccda6, 0x728e9e98, 0x4beea06c, 0x3ba2bb27, - 0x89a3f087, 0x1adbd9f5, 0x3900fca4, 0xd377ed4f, 0x560f985c, 0xf74ff222, - 0xb53adeb5, 0x661f2126, 0x52dfa0b7, 0x3d45ab16, 0xf2665a5a, 0xaf27a845, - 0x1f617fc1, 0x73c7eedd, 0xf3055afa, 0xc71e18a1, 0xbabce9da, 0x794a85f6, - 0x4b91da40, 0xb0760e98, 0xe16511c3, 0x997e81b2, 0x477c83f0, 0x5ccff5c8, - 0xad0f3435, 0x3e47da40, 0x33ecddd4, 0x74863f87, 0x998759f7, 0x6309e5b3, - 0x9183a97b, 0x6a545b9e, 0xa60ae889, 0x3dd3b423, 0x850eda8b, 0x1c2115e5, - 0x50f3bdd3, 0x254c1f8f, 0x52dd4dba, 0x7bc35745, 0x79f5c14c, 0x1e99c700, - 0x1a49a0fd, 0xd35ef057, 0xb42ecb04, 0x5e22c71b, 0xa5d19c70, 0x6285c784, - 0x575afbbe, 0x159e9e10, 0xefcb68f3, 0x87873bc7, 0xcf78fcf9, 0xe90ea2e9, - 0x73ce31bf, 0x37f56543, 0x95c6def0, 0x74d85531, 0x33ae7c46, 0x53ce26c7, - 0x3802e006, 0x5538459f, 0xbffc9b84, 0x8f4d7e7c, 0xc819bf70, 0xbb8a5ab1, - 0xc4b1324e, 0xa32cabb8, 0xc8cdfe42, 0x4ebc1173, 0x0ba9dcef, 0xdfac4a2e, - 0xb8fd7444, 0x761fe7c2, 0xcd2f3c6a, 0xfd13d7ef, 0x7ee4ebc4, 0x487f9c59, - 0xdff6f011, 0xe79e36e3, 0x6c583a61, 0x0d2de60b, 0x25fe1fb7, 0xc4a4ca2e, - 0x18e830fd, 0x649d5718, 0x759f3ca3, 0x7f4b8f32, 0x337cc743, 0x8afcf12c, - 0x6ae9d04d, 0xe4af31a7, 0x77b71e5c, 0xe8f589ce, 0xc6be71b3, 0x567964b8, - 0xdd17bdc2, 0x91ffe4f5, 0x6ebecc71, 0xfd2e0f9e, 0x09044b6b, 0x78e51df4, - 0xa5587be8, 0xee92e5f8, 0xa17df96b, 0x7ba01e87, 0x1d2fa156, 0xbc5ea1e9, - 0xe8c6bf5f, 0x3bb059ef, 0x1f452ab0, 0xc45a57ec, 0x48d7e4c2, 0xfb2527f6, - 0x279b7e91, 0x563e69f6, 0x93ca718e, 0xa58f8beb, 0x88a67ee0, 0x91dbb9d1, - 0x8f7493ea, 0xedfb5831, 0x2b294f78, 0x24f4f7e3, 0x0525fbaf, 0x3ef3c216, - 0x1c63aeb9, 0x37d867e4, 0xbefff389, 0x7d7ecf17, 0x96f3f40c, 0x81ce18ae, - 0x099ba5bc, 0xae81e38f, 0xac64ecb1, 0xa0fba876, 0x5f4df3b2, 0xa5c0bced, - 0x68d7dfc6, 0x9639eaea, 0xcbbc93aa, 0xfa7807ca, 0xad3efd8e, 0x4e27f88c, - 0x575107bf, 0xb841e1c4, 0x7ecbfcf1, 0x137327d3, 0xbe7c60e9, 0x7c83edc6, - 0xbf9357d3, 0xceb84635, 0x7599bd94, 0x1c6b870d, 0x3d1bd5c2, 0xb7689591, - 0x0ff6b848, 0xa5fabf73, 0x934f155f, 0x0120fa8d, 0x12ff534f, 0x865bf69e, - 0xc0966786, 0xf28e4fcf, 0xb70642fb, 0xd5fd457f, 0xccf78461, 0x51ebb163, - 0xb3bc023c, 0x53de7f08, 0x15331459, 0x14acebf8, 0xe42959f4, 0xa8ce8f8e, - 0x17dbd0b0, 0xa75e7e53, 0x7743dbc6, 0x79e08a2e, 0x0b8bdf02, 0xe0dfd10a, - 0x7ba56e3c, 0x7949429e, 0x2f5cb222, 0x573fb1e6, 0xab0f1219, 0x78bcb9f3, - 0xd4f9b5f1, 0x596fbddf, 0xed83ca19, 0x5ef5df22, 0xef0da757, 0xc47895ef, - 0x2194057a, 0x2a117c4b, 0x3f2b7bba, 0x218ee9b3, 0xf1f133c6, 0x1be24bee, - 0x572c9e39, 0xbb7297e4, 0xe2aa3954, 0x2efb8739, 0xd9ee937d, 0x2352afba, - 0xe337fb99, 0xfe127d7f, 0x7d666fa3, 0x8acbd39d, 0x2aa3f47c, 0x037da5ef, - 0xfe2521ea, 0x9fc432b3, 0x0ff34825, 0x3b656dbd, 0x6a78c195, 0xe72bf414, - 0xe12fe727, 0x80b65e76, 0x7ae099ce, 0xc5abe020, 0xa44f52fb, 0xf387bd0b, - 0xa9713d22, 0x4c89cfc6, 0xef5d68d2, 0xce853c9b, 0xf917ecf5, 0x2c4bf114, - 0xc32efe43, 0xf76f0233, 0x0c45fb9e, 0x770da9ef, 0x055ee99b, 0xbf78f5a6, - 0x7a147409, 0x9a7ba35d, 0xf16a9e81, 0x5f17a8de, 0xfb869b3b, 0x66f903e8, - 0x3e40fb82, 0xe77d8797, 0x6f3a5ad4, 0x2e67daf3, 0x9ffe8135, 0x5d8557ce, - 0x39e18b12, 0xfc158d9a, 0xd84380dc, 0x4ed78e01, 0x8efc2035, 0x2ab3dfc9, - 0x4f767a09, 0xdbbe95be, 0xf9678968, 0x48740e30, 0xdfee5165, 0xfaeffba1, - 0x38ba0bcf, 0x8f2b9a1e, 0xe8e09d92, 0x3de2f7e6, 0x5c13af9d, 0x7841f708, - 0x33ee329e, 0x57b63d57, 0x06a378c2, 0xf8ba77be, 0xe24ca67a, 0x77dcd0f7, - 0x785dcfe9, 0xc2ba5eef, 0x4be8fee8, 0x3906cc0a, 0xd7c45f5e, 0x1632b3a1, - 0xe5fc851b, 0xb6af28d2, 0x0d9b7a33, 0x17c97aed, 0xf4a947a3, 0x97916add, - 0x29727abe, 0xe3a499f1, 0x57c105b9, 0x02366e91, 0x76493c5f, 0x9d302c4e, - 0xc72ae3f0, 0x95c7e3fc, 0x3fb71d58, 0x2fd42e2c, 0x819326a5, 0x380b8adf, - 0xec12c8dd, 0xee77b252, 0xf52cb410, 0xc6c45b7d, 0xb7ffbf30, 0xa3a566e7, - 0x2796da5d, 0x0dbf3ced, 0x095db5f1, 0x38e117a4, 0xbed2a5ff, 0x4ed7c5ef, - 0x6db8e034, 0xdbe42f30, 0x58ea7e7b, 0x9b49f68f, 0x2a7c4fcb, 0x26dcd7c7, - 0x9fbc1eb1, 0x2bff16fd, 0xbb8c6fe8, 0x47447df9, 0x43635ca6, 0x4cf787fa, - 0xad7bcfd8, 0xd81a0bf8, 0x07f90d4f, 0xcf66ba16, 0xb116efc0, 0x6bb42ae0, - 0x86a87517, 0x11ee177b, 0xb9e162f2, 0xd84d1614, 0xfc9c2c1f, 0xb6373a2d, - 0x8b1a5cf0, 0x8f75bd82, 0x8f7d1738, 0x0ac45738, 0x443b3d38, 0xdfe515e9, - 0x24bef7cc, 0xcbf995bd, 0xdf39f3bd, 0xb7e802b3, 0x14b1e949, 0xa71b10c1, - 0xebce9efc, 0x62ead7bc, 0x780492d1, 0x0473cd07, 0xd38c268b, 0x1b39deff, - 0x7d6067cd, 0xcc0efd39, 0x787841d7, 0x784bd5af, 0x91ffbe1c, 0xf40e3c06, - 0xc780ca3f, 0xd097fdc1, 0x96b5eff8, 0x13ff497e, 0x375fe986, 0xefd03fc0, - 0xf7b71a68, 0xa71ffcc8, 0x891ddf02, 0xf9edbdde, 0x331dfc4a, 0x017efd2b, - 0xa6aceaeb, 0x338f8473, 0xe77a673a, 0x83bddfe1, 0xee779af9, 0x8c70f8b2, - 0xae7c733e, 0x333d086f, 0x78c2b99a, 0xc72c979f, 0x7cd31417, 0xb4db9f92, - 0x32f30b88, 0x0b9aa56d, 0xc6d11f7f, 0x71bb9162, 0x236952df, 0x42e32739, - 0xe53fdfb2, 0x3b3cf2a9, 0x6f7907c9, 0x979112cb, 0x5e08ec57, 0xd4beeb81, - 0x13fcded4, 0xd283f6f8, 0xcc373a36, 0x33f69b98, 0xe1a36e32, 0xa315bf2f, - 0xf0c0305f, 0x7a13cdfc, 0xf77e0670, 0x18271043, 0xd82f51c7, 0xb5bcc41d, - 0xb8df620d, 0xfaf31ec1, 0x0de6e412, 0xb357da05, 0xe893da17, 0xf72fd276, - 0xdedd3946, 0x227e8050, 0xfcc4f635, 0xedb7cc22, 0xe976f711, 0x55778a16, - 0xfefba31e, 0xff7dcbe6, 0x8ebce49a, 0xd1da377c, 0x8694ce32, 0x6b687779, - 0xbef7e46c, 0x7af2a7d5, 0xa08c7ffd, 0xffb01073, 0xf9432d49, 0xfee55fb2, - 0x3adf1120, 0x67d0e62b, 0xf94058db, 0xe41f22f7, 0x744bf76c, 0x35d9e4af, - 0xebfd6863, 0xdd3ef85f, 0x973fb70b, 0x43beb1eb, 0xf563d24e, 0xde155f56, - 0x973fb85b, 0x5a9dabdb, 0xc122ad34, 0x579d5d7e, 0xe3f9f24d, 0x894c6335, - 0x0aef8ff1, 0xfa51b079, 0x1578b537, 0xb8f9679e, 0xd233fa32, 0xf4ec07a3, - 0x83a6513b, 0xfba2abbf, 0xe95a372d, 0x0faa0177, 0x875cdb8e, 0x8d34c3fb, - 0x074d91f2, 0x99cf04ed, 0x2d7efc75, 0x5de516fc, 0xf491c1d3, 0xa9f556fb, - 0x6c27ca71, 0x6095f14a, 0xe0feafdc, 0xffd7ba54, 0x057186e4, 0x644eff28, - 0xaf7405ea, 0xf43c06f1, 0x6343f509, 0x17b5f3f9, 0xe75579d3, 0x50e0d4c6, - 0x8fa9107e, 0xdaefef92, 0xdbde5b9f, 0x6719f885, 0x7dfca1f3, 0xb8f1f14f, - 0xd9f12bef, 0xf915c53a, 0xd77ad2f9, 0xbc7dfa69, 0x6f778efa, 0x43dcf462, - 0x73f72b74, 0x0bd5e3c9, 0x12dfb57d, 0x4bbf8b9f, 0xe052bf56, 0x624efc5d, - 0x7e9ca9bd, 0x7de24faf, 0xb73dd263, 0x24fd084f, 0x69af93cb, 0xd8205f74, - 0x1fe80511, 0x4ad8793a, 0xe3727674, 0x2eaf3a04, 0x9c07abc7, 0x4f2f80b8, - 0x7113e864, 0xf2169f5d, 0xdf257eaa, 0x30e7caa7, 0xe77f0c7e, 0xa5487e30, - 0x573eaebc, 0x92e30d3c, 0xef593df2, 0x4ab74f9f, 0x3fb597bf, 0x6f5a45f7, - 0xf48627a0, 0x49c17a64, 0x82f43a7a, 0xe7ae1775, 0x8c2c95c7, 0x5bf0cffe, - 0x8ec7f7fc, 0xfd92b21c, 0xef9c77dc, 0x9fdd076f, 0xe01788e6, 0x17a1a1fd, - 0xeb1c9246, 0xe0ef8fcb, 0xdf9db6f6, 0xf046f8ab, 0xcdff1162, 0xe611f711, - 0xf9f79da0, 0xed147b21, 0x9e29283c, 0xbdbb6610, 0x2a70fcf4, 0x940fff43, - 0xca63cf14, 0xeefd2f01, 0xdf176b0c, 0x3bfbe8c7, 0x5163820b, 0x0c59df2e, - 0xfbf03bfd, 0xe7def453, 0x521782a3, 0x5cb18a0c, 0xf52e5e31, 0xa42c1f9b, - 0x5e67cae7, 0xed2a7bfe, 0xed463da2, 0x62f06b21, 0x9cafc79a, 0xf310e76c, - 0xeef7aafc, 0x41182d1d, 0x06e128eb, 0x98dd933c, 0x05b3978c, 0x3b7bf126, - 0x74c91f1c, 0x5f9ebfd9, 0x5ffa1f02, 0x21f6bce8, 0xc6eb8ebe, 0x591cb859, - 0x63ec813b, 0xc86296d6, 0x88715b9f, 0xbbd0c3df, 0xdceb49c1, 0x843ff667, - 0x86fe28fa, 0xed7bf199, 0x3f4022c0, 0xf9a1e4c5, 0x4f9123e5, 0xcf2d64bf, - 0xd1e8fbb3, 0x39e60bf7, 0xfbf25cf0, 0xd2c97386, 0xa49d085f, 0xe1c63fa1, - 0x97e6d3d3, 0x255d7b71, 0x7aeff8f8, 0xf4eb346d, 0x0de16bbb, 0x711fc8e3, - 0xa41fa2d2, 0x775b87df, 0x4ae90981, 0x77f2172d, 0xbc9f9f13, 0x7bde4b2f, - 0x8a9f8c95, 0x7f9262c2, 0x33782c4d, 0x827ea1de, 0x61c259e9, 0x91fff746, - 0x6984df7b, 0xe29f9a88, 0xf485acb6, 0xf67be0c2, 0xbbf25f2c, 0xf5bbff6c, - 0xf42b5c2a, 0xd38795ef, 0xe07eaf50, 0x3a46fbe2, 0x5d7a8f7d, 0xc36cf3e5, - 0x83af300f, 0x4e14a605, 0x879276a2, 0x5dbc281f, 0xf341b9ca, 0x7ec17a47, - 0xebe83df0, 0x7fee429a, 0x710cae63, 0xc16c2bc8, 0x9fa94d3c, 0xc2668a42, - 0xdca7f373, 0xe3d21a7a, 0x19c5b5a9, 0xc60f302b, 0xda2567ad, 0x8ca3a1d5, - 0x78eb8bce, 0xf8c5f8df, 0x89fe32fb, 0x9fdbf7e8, 0x243bf461, 0xb4e4f3c3, - 0xed89b99e, 0x9eb90a73, 0xf6285f9b, 0xe44c8599, 0x8de32657, 0xb162fbaf, - 0xf0796aee, 0x2687da72, 0x4b78b7bd, 0xa487a0ba, 0x7fcfede7, 0x1ea0f297, - 0x4913de36, 0xef185fb1, 0x612c5783, 0x532c42e5, 0x61bdaf28, 0x0d739713, - 0xb92cceaf, 0x5ee9d78b, 0xef3b6985, 0x59e3dfa1, 0x12caebb0, 0xad16e5c6, - 0x05c7a483, 0xb412fe05, 0x555be2e3, 0xc345f217, 0x51e09516, 0x56d73ecd, - 0x8b7a7e78, 0x06bbec99, 0xbce9cf01, 0x9bad1a60, 0xe00b34c6, 0x4c16b4fd, - 0xab75fb23, 0xa4a1ddf8, 0x6f7bc079, 0xe043156a, 0x99d7c6c7, 0x043c53f0, - 0xa261bc1d, 0xbf805a75, 0xec70890b, 0x79bfc854, 0x33783f3a, 0xfec14fd6, - 0xabe9cf1f, 0x7dd0969b, 0x3ef8c936, 0x7d120b6d, 0x91f3162e, 0x471e4cf8, - 0xf10fb3e2, 0x2bd2f689, 0x85ef4853, 0x6291541e, 0x9fdd8bd9, 0xda7cbed2, - 0x99df2ba1, 0x8137cf8a, 0x9ea3a2dd, 0x6fb3f51d, 0xa35b9ea3, 0xfe7a8c52, - 0x962ce2a1, 0xff71afa4, 0x39f5ff39, 0x3d04a669, 0xf1c83ea9, 0xa4e73aa4, - 0xcff7a42d, 0xebe91d7e, 0xaacbee84, 0xf1ef7848, 0x83b8fec2, 0x37eabd61, - 0xc70d21fd, 0xa66f5869, 0xe975c979, 0x7ca079c3, 0x208d4f6b, 0xc5e5f7fd, - 0x4eb95fa9, 0xeb8df4fd, 0xde09e920, 0x9742affb, 0xf24c2718, 0xb05154e8, - 0x9d0437ca, 0xc6007a2c, 0x38b6fec5, 0xf3d2fee9, 0xa3e2571d, 0x5f05bd7f, - 0x71d71d53, 0xd1f91147, 0x74686f4d, 0xfb44e0c8, 0xc7c80555, 0xd02fa0f5, - 0xc4af516f, 0x647ba1df, 0x1ee9590f, 0xb74dfae6, 0xd5e38cdc, 0xb09ab71f, - 0xabe1d4fd, 0x495c1226, 0x2a780aeb, 0xfbde8a18, 0xbe05e28a, 0x3d81fc04, - 0xe72dfc41, 0xc1370093, 0xba29fb01, 0x08afa88f, 0x0e4133d6, 0xedc859bc, - 0x65df782e, 0xf7e6fa21, 0xd7cff561, 0x575f3495, 0x64df7cd2, 0x17ccdf44, - 0x782cf9a4, 0xe7c26adb, 0xb6bfee0b, 0xa73df704, 0x79a74dd6, 0x4ff0ca9d, - 0x553afe44, 0x210ffd00, 0x0fdc172f, 0x0bfb2cf3, 0xd3b76cf3, 0xcf3b0d7a, - 0xf60ef88c, 0x89f9e617, 0xcf3943a0, 0x0d3d34f7, 0xcf43f9f3, 0x2efd0caa, - 0xc6c0fca1, 0xbf4ebca9, 0x73321713, 0x4a6d087a, 0xdedf7ca5, 0x04fbfe6e, - 0x78c00e52, 0x260f49e7, 0xd55387a2, 0xd0c9e6fa, 0x3f07ffdf, 0x00b71737, - 0x0000b717, 0x00088b1f, 0x00000000, 0x7dcdff00, 0xd554780b, 0x733effb5, - 0x64932666, 0x08124c92, 0x3c984081, 0x49849009, 0x768a8802, 0x02d10478, - 0x89794f0d, 0x42100793, 0x69b5a05e, 0x0240cd6b, 0x350d45a2, 0x01d45a2a, - 0x0da2a281, 0xbc150a0a, 0x45622a03, 0xb68b57c5, 0x514026e5, 0x5ea0c679, - 0xffd7b5ae, 0x4e7dadfa, 0x5490ce72, 0x7dfbdedb, 0xdf1f7cff, 0x5afd9f66, - 0xd7b5ed7b, 0xe7bdaf5e, 0xcbaa3dc2, 0xe4e216ef, 0xff6f05dd, 0xf7a517bc, - 0xfc812eaa, 0x02cddf58, 0x2cc38ff9, 0x934a14fe, 0xfe70a68b, 0xa56b9b65, - 0xa689c422, 0xa141fdbf, 0x367d85fc, 0x0bf2a0b7, 0xcef74529, 0xea8f7e46, - 0x2fed415a, 0x259f680c, 0xd8b97386, 0x5deae544, 0x2e509a23, 0xcae61e1e, - 0x0df2f2a0, 0x09644261, 0x6856fbfe, 0x3be9237f, 0x6ba50b52, 0x34786f55, - 0xfd2f4da5, 0x6fa5c944, 0x578f3756, 0xf724abf3, 0xb97e34dd, 0xf9ed5855, - 0x399edca8, 0xf388472d, 0x03136d7b, 0x233f32d9, 0xb03fcb87, 0x5d8d7952, - 0x7bf85af8, 0x0e6a7dad, 0xd2b6e28f, 0x0fa98b38, 0xfae94a91, 0xea60ef18, - 0x938d317f, 0x8b7de342, 0x0e5c1fbf, 0xe7cb0edf, 0x9fa88a0b, 0xf6626d7b, - 0xf55dd973, 0x4ddb34f4, 0x6d46f61d, 0x553b577b, 0x3cc62588, 0x2422a1e1, - 0x477914bf, 0xa432be57, 0x7ca42abc, 0xa7cfbf47, 0x1f2f3914, 0x1fc6037f, - 0x12c785d1, 0x2c3b8f0d, 0x72eb1df4, 0x44d8128f, 0xbab12dff, 0xfe09cbed, - 0x9b88c6e7, 0x55a94fd1, 0x47cdae38, 0x5f9e0ebd, 0x86345589, 0x87bbe3e5, - 0xa6f3e9eb, 0xe2c31afe, 0xced11f28, 0x89bd53e3, 0xda9e4376, 0xab9ae09b, - 0x4ba7a3c1, 0x4ebb85b7, 0x7fa0f3ea, 0xa6b12d55, 0xbeeecd7c, 0x7c0693ae, - 0xfa7fc52f, 0x3449bfd2, 0x8bc091fb, 0xdddaabfc, 0xe892307a, 0xcdf14da7, - 0x17bf5375, 0x9d1d7e0e, 0x1f75e6ed, 0x9beb4459, 0x7f3ea6af, 0xbedbe698, - 0x426cf547, 0xfdd86fbf, 0xe7fd0c4a, 0x6e0f8b9b, 0x2fd5efa7, 0xddbb89a7, - 0xc50ff35d, 0x17dd85e3, 0xfbe953a3, 0x08f643f9, 0xb9e68c31, 0x9dac7e37, - 0x5c4762e8, 0xaf78b77b, 0xef5dd6d5, 0x35b5bcef, 0xdea1aa7a, 0x3d1ad179, - 0x252f40cd, 0x8bd62fbb, 0x5f9fc65c, 0xefc2efcd, 0xc7bd7d89, 0xf4bdf4aa, - 0x5ac6fdf7, 0xc35fbd28, 0xf736bddb, 0x6e096b13, 0xcf309eff, 0xfcfb8216, - 0x682db31b, 0x728dfe7f, 0xcbcdbd2d, 0x244f5fe9, 0x8b68fc63, 0xbc7d77a4, - 0xf70b6e35, 0x7b696a53, 0x8fda1aec, 0x93ebbfa5, 0x55d290d2, 0xcfc96a5e, - 0xb76f3ac4, 0xdc002fb5, 0x46b115e7, 0xe7eaeb89, 0xdb9bb77e, 0xc9f3df9f, - 0x270fe063, 0x4f901dee, 0x41f94d64, 0x3f2a3eb9, 0xa64151ff, 0x7f3dfa8b, - 0xf80f5f4f, 0xfb9b76c2, 0xbbb7a636, 0xf7d83ca2, 0xa7187f7a, 0xb9effd16, - 0xe90fa462, 0xca5e1247, 0xb8e4fae7, 0xabbf257e, 0xfb8b68df, 0x17e0d1be, - 0xb679b7bf, 0xeffcb250, 0x31627d69, 0x6ee7ec3f, 0x4d74a1d6, 0xf89b7098, - 0xbb864ac9, 0x22ec7844, 0x030b964d, 0x228995bd, 0xc9b0befe, 0xf1117dfc, - 0xbc5f7c09, 0x5cbdfcde, 0xa56ead34, 0x98092df9, 0x3fda0bbf, 0x6bec04fe, - 0x5ec5affd, 0xff7a0514, 0x4f54cc36, 0x40fe35f8, 0x255f091f, 0xc7c11fb4, - 0x8102519e, 0xbbdf5895, 0xe8679e54, 0xa775debc, 0x2287bb70, 0xab4167ff, - 0x5b8f5d61, 0xf0913584, 0x1c2edc7a, 0x47e8f989, 0xf5fa8508, 0x6c0b0bef, - 0x0f7726a1, 0x04b92afe, 0xc231af7c, 0x5bbe0822, 0x427ce05d, 0x49f7d8ac, - 0x5d29fa32, 0x356de853, 0xe6c177c0, 0xd4e7e87d, 0xe25dfdbe, 0xf8ef54d7, - 0x58d340d8, 0xddf8eb82, 0x1ba1a7aa, 0xb1af4eb8, 0xe1014088, 0x02212ee3, - 0xf27f94f1, 0x5a62e493, 0x7cb6cf97, 0xa4625c92, 0x36cc457f, 0x129ea3d2, - 0xef3ebc24, 0xfcd2ef61, 0x305cd38e, 0x5d7ad09f, 0x57866beb, 0x2ab867c7, - 0x87a3bb6a, 0x54f740cf, 0x5577f59e, 0xf7efb178, 0xcfa002d9, 0x3c5f8dc8, - 0xb9f40f38, 0xa14ae6d7, 0xa9f66bb1, 0x2de6955e, 0x0c81a8f6, 0x4f7b639c, - 0x9ce05744, 0x52e053d9, 0xd9aef30d, 0x7ce116a3, 0x62fbbf39, 0xf7366942, - 0x44edc533, 0xa03c07fb, 0xf8e09edf, 0xf7fd5b9b, 0xccd79ff8, 0x7f65ceff, - 0xf8037090, 0x9953c6c0, 0x07c4efe0, 0x79a6e6ff, 0xc6fccf9e, 0xad10bc8e, - 0x047f4123, 0xe09bb45f, 0x2af810bc, 0x8e5c105a, 0xd037aabd, 0xa5443acd, - 0xff4f19d8, 0x09137c32, 0xf82e84be, 0x94a89e08, 0x56705d11, 0x38eddbbb, - 0xa2382f67, 0x694fc173, 0x12f29342, 0x0dc9f3b4, 0x493a5afe, 0xbf1d7f10, - 0x70cae167, 0x8a4d0bc8, 0x97be8c27, 0xdcf955ed, 0x191bdb2a, 0x3f1816c0, - 0xd2f9c9c8, 0x1840d547, 0xa3a827e5, 0xea9b30ff, 0xf547be2f, 0xfb148ed0, - 0x07f6de37, 0x8375d61b, 0x881ca04d, 0x344b5c03, 0xfdec96b8, 0x8d0a67e1, - 0x2ddf78b3, 0xe2ce3007, 0x170f1407, 0xe8edf3a8, 0x8a43c977, 0x67405788, - 0x3a46e3b6, 0xce64d85b, 0x0bad122f, 0xc1fc1554, 0x9ef09dfc, 0x96fd415c, - 0xdd730eef, 0xa102f18d, 0x4abc42e5, 0xff68d4f0, 0x3b58cacf, 0xcfd500f7, - 0x3c6768da, 0xe2170f9c, 0xb5abf608, 0x0d204135, 0x1d6326b6, 0x6bf9efcf, - 0xe6b1d632, 0x2995ff77, 0xcebf59ba, 0xaa37b4fd, 0x2148a9d7, 0xc4514eae, - 0xfba0a9b7, 0xba8a538b, 0x201b6fa9, 0x9b36c5f7, 0xca879fbf, 0x8afc6c0f, - 0x3d85c1f9, 0x6eae81be, 0xbf6bb7e8, 0x892dc3fa, 0x02e18348, 0xd716f0e9, - 0x2427d80d, 0x35be620f, 0xdb4f569b, 0x97f0f944, 0x44b9386c, 0xf793864d, - 0x42c7f60b, 0x3efabf43, 0x80be06d9, 0x0fe48474, 0x1cf201b6, 0x7b9daa3d, - 0x4c77f6db, 0x9e06e8c9, 0xd71b6ea3, 0x5c100db3, 0xd17759ef, 0x845bd05c, - 0xbe0d1fc5, 0x775ebc2d, 0xa2b3c22f, 0x5d4357d1, 0x89ef82ad, 0xfed389a2, - 0x47d385a2, 0x5139f085, 0xc05c785f, 0x620310b3, 0xf3de3f81, 0xccbecf8c, - 0xadac7f37, 0xe8357821, 0x022b1fc4, 0xeaffe85b, 0x63508746, 0x46b5ed20, - 0xce5451a3, 0x5206fbb4, 0xd503edb9, 0x1dde40a2, 0xc7a7afa0, 0xa5f7fd85, - 0x718c4673, 0x2e1ff6fd, 0xaafe8899, 0x8c22a976, 0xd3b73bfa, 0xd44e8226, - 0x7c02fda7, 0x9ec2fe1c, 0x57b4be02, 0x6b979011, 0x35ef8f28, 0x80deada3, - 0xa4772f01, 0xd50f18d8, 0x9cf29929, 0x4d0f7ab6, 0xbbcf7ea2, 0xeb90ec4a, - 0x26cb876d, 0x25b1bce2, 0xd701d896, 0x1d63c3fe, 0x58b75829, 0xd59bef2b, - 0x8f71f57b, 0x547fd0b8, 0x6f0c07ec, 0x4445b663, 0xa3c6bb53, 0xa6460161, - 0x30a1f243, 0xc18daf0d, 0x37770ef1, 0xe317e3eb, 0x2a28c493, 0x044ea9df, - 0x255ce79c, 0x2da3ac2e, 0x0aeee896, 0x4ef36f6a, 0x0dfa9abc, 0x078b8d8b, - 0xd2526b7c, 0x8abf3d78, 0xbf3865ad, 0xcfc2f122, 0x08b6b7fb, 0x65fec6f9, - 0xe9bee32a, 0x35cfde21, 0xd47e390e, 0x51cf953e, 0xe343a571, 0x4abbefdb, - 0xc9059c69, 0x0f4147be, 0xc46dfc9d, 0x39fc02ab, 0xf96162cb, 0xe735f1ac, - 0xbd21f05a, 0xa48a6cfc, 0x563d7d37, 0xc0bab2f5, 0xe8d51e3f, 0xc8ab9573, - 0xa7986f91, 0xc345b7ad, 0x78039157, 0x3a2f61da, 0x9da5f384, 0x3cdce3be, - 0x01cd3890, 0x59ea853d, 0x7aa9cfd0, 0xf47631da, 0xfc01c33b, 0x3255ea2e, - 0x8b16ed01, 0x6fd8d5da, 0x22abd78b, 0x8dabe068, 0xa2ee3936, 0x1822114b, - 0x22ee35df, 0x7f6e3f5a, 0xe9045a29, 0x970c6ddc, 0xe4a31af5, 0x452379fe, - 0xb50f9fee, 0xf969b4f9, 0x7baf997f, 0x5cfd7ccc, 0x96b61fec, 0x46fefe48, - 0xa55bf50a, 0xa1484eb4, 0xec4eadf9, 0xa7bf03b0, 0x98225dea, 0xb2f78069, - 0xa08bc679, 0x7acedc61, 0x9f3c1c97, 0x3370f5ae, 0x75f35dfc, 0xd54e1e32, - 0x7b1e3227, 0x84c93fee, 0x53feaec7, 0xbcbc784d, 0xff1e4cff, 0x77d67d54, - 0x87b43ff4, 0xf826ddfe, 0xe74dfabb, 0xdf6ec571, 0x3b97f040, 0x980fc45d, - 0x505f886e, 0x3df15db9, 0xdbe4357e, 0xe404c28f, 0x7dc2afbe, 0xfe065c83, - 0x65ce0df0, 0x4982e7d6, 0xd17eb7e0, 0xeecd69cc, 0xded0138b, 0xfb017c4d, - 0x11af2f49, 0xf8270ced, 0x3583e885, 0x7cb9bab4, 0xf4106fb7, 0x4e8e1d22, - 0xa775e679, 0x20fb42df, 0xa3dfdf6c, 0x582f8fb1, 0x2878a7db, 0x46abd96d, - 0x7c75f71a, 0xb1a7a4aa, 0x6dc8be03, 0x68d5efa5, 0xb6ef7c47, 0x020e9797, - 0xdac3aa7e, 0x81f70173, 0x8b96ff97, 0x7dabe473, 0xfbe2074b, 0xf2cfaa36, - 0xdabdbd87, 0x5d2fe863, 0x5196fcb8, 0x5533a95d, 0xefd0ffee, 0xf435f6db, - 0x89db1c03, 0x0b9209bd, 0x0a2aebab, 0x0d83c64e, 0xff07ef79, 0x58b7c412, - 0x5d3dda1f, 0xeef9031d, 0x28799243, 0x948f7c3f, 0x100f861b, 0xe40a4b01, - 0x83670fbe, 0xb08f544f, 0x470aa0bb, 0x79611de4, 0xc384623b, 0xbffd50a5, - 0xdbe397f7, 0xa1a42f21, 0xe83c617d, 0xf164caf9, 0x1b6dc9ef, 0xf04ff642, - 0x34edeabd, 0x3ada955e, 0xfbc29c65, 0x7c153f28, 0xde2fadfb, 0x04d7f4d6, - 0x9c01cfac, 0xfbcf046b, 0xa9653f5a, 0xcf502bbe, 0xe7bd68e7, 0x7337aa0a, - 0xe864df56, 0x7e9ac547, 0x52112626, 0x947e64ae, 0xe5c83b03, 0x83d4b6e7, - 0x3e7c525e, 0xd7dfc1e0, 0x35f9c1e1, 0xfa384934, 0x62455e12, 0x8d1a7520, - 0xa2d5213b, 0xc0140fdb, 0xe39b443d, 0x965afd33, 0x1939f2c7, 0xfd1d0388, - 0x4b4ee3b3, 0xfc064ef5, 0x670ffd7a, 0x75f1cbcd, 0xf2e86e73, 0xb2deddbc, - 0x57b6700c, 0xfc7f5939, 0xeed44500, 0x41615989, 0x8a7a1a35, 0xf9f40d73, - 0x0e0b91a3, 0x8c7c26f6, 0x43cdf28f, 0xbc6fb3ff, 0xcaf2357e, 0x72f77881, - 0xeb7173d0, 0xc2efd648, 0xbca3377d, 0x981be1d2, 0x373c5340, 0x062837c0, - 0xbc517c87, 0x9451275c, 0xfc2dd453, 0x45629e12, 0xe518df8e, 0xc53f472b, - 0x5d8f2396, 0x23d66f81, 0x8d106f6c, 0x739fb9bd, 0x9dde5176, 0xe1e3affc, - 0xfd8f3698, 0x25ed7136, 0x75fedf9a, 0x82069e31, 0x1bceecb7, 0xba50d417, - 0x109452d0, 0xdf704d54, 0x575d4a96, 0xf6078bfa, 0x9cee7925, 0x4ebb834d, - 0xcaeadb83, 0x50e7ee34, 0x79741bb8, 0xeb0a17e5, 0xf947fc83, 0x81b1fd17, - 0x661f29bb, 0x74c1f8b9, 0x16395b9c, 0x886c93b6, 0x7a45bda0, 0x9c1a3be4, - 0x73bed28f, 0x35f7f1c4, 0x21189ef8, 0x683e27db, 0x507ec009, 0xaf0f7634, - 0x4ed513d3, 0x15634a8f, 0x721db70b, 0xb2f0a950, 0x31d7fcfe, 0x4ad7db7f, - 0xf54e6af3, 0xddbc07dd, 0xfe496f1c, 0x0df0e180, 0x6b790a9d, 0x3fc79cb4, - 0x1e793790, 0xc6cb84d3, 0x6b589942, 0xcd31fc81, 0x50b2a725, 0xba63fb91, - 0xde30daf0, 0x7ae3e14c, 0x7bb79def, 0x07bc4fa1, 0xbee0885d, 0xfbf9f851, - 0x74e0111c, 0xfd72089e, 0xe72b449b, 0x7d137c75, 0xd24bdcdc, 0x547d27c7, - 0xc056ffc6, 0xee646efd, 0xc79a3a80, 0x650687d4, 0xdcd57eb0, 0x5df3f19b, - 0xe8d54f70, 0x6feff686, 0xbfd88eb1, 0x699fa833, 0xdfec8437, 0xf5f5bdf1, - 0xfb47f8cc, 0xa74748e8, 0x4bece4fe, 0x5b4eb878, 0x4bbcebd2, 0xc2127f59, - 0x8fd1f2c5, 0xa85b7db4, 0x5a2f453a, 0xd26e239f, 0x89960897, 0x62259663, - 0x10afafbe, 0x3ad0156f, 0x15463ebe, 0xcbd35c0d, 0xfd68a6ed, 0xe13fe94d, - 0x0f5bd833, 0xe1af608b, 0x92f0aed4, 0x8218d5ef, 0xbdba8a7b, 0x27ca9631, - 0xc6bd27f6, 0xefaeefc0, 0xfd0ac3b5, 0xf37486ee, 0x66d949f7, 0x68b267fd, - 0x94fe3152, 0xfb7ae6e1, 0xb3a22781, 0xfea553f7, 0x21888622, 0x0b7af2df, - 0x1d3e718b, 0x2fda2e93, 0x69111c10, 0x2eb18fbe, 0x75ff27cb, 0x5615c601, - 0xb7ea9f39, 0x1debb655, 0x288b7927, 0xa7ac9c50, 0xca532293, 0x4a7fc825, - 0xd3d203f2, 0xcf4e6ef5, 0xf28f79d2, 0xce1ef5f3, 0x9d15a417, 0x6b25bf40, - 0x7d62b73e, 0xf8970cee, 0x9a696f2e, 0x762ab000, 0x5a441cb7, 0x809a2c16, - 0xa1d17663, 0xef4883da, 0x6adbd4ec, 0xe1d3be59, 0xd3a345be, 0xfda6a25b, - 0xe1d68730, 0x87aa3d96, 0x4da603f3, 0x790bdc9f, 0xa27be71b, 0x444baaa3, - 0x54572433, 0x012fdeab, 0xdb6f7797, 0xdf9a78c1, 0x18a3f527, 0xbdeacfee, - 0xfa99f70c, 0x4a4e9c89, 0xe81bfa2b, 0x673e2bcc, 0xf6f26c79, 0xd5126b36, - 0x5e2af42f, 0xbd6bdbec, 0xfda01022, 0xcf26deb7, 0x0e74f581, 0xc98f1f60, - 0xade8f699, 0x67da7c02, 0x6671a34b, 0x10a4b0de, 0x55194ce3, 0x1bbd456c, - 0x201921bf, 0xbf4e8ba5, 0xf9f5ee8b, 0x76eb6957, 0xf18565ee, 0x2d33b1d8, - 0xf2c17206, 0x907d695d, 0xf5d4bf12, 0xade048dd, 0xe18592e3, 0xc11a38ec, - 0x6ede86fa, 0xe648aef9, 0xd807cb3b, 0xb760c203, 0x2ceb433c, 0x99e6f20c, - 0x36e27e67, 0xe2672b9e, 0x18fabe5a, 0x922fedfc, 0x736491bf, 0xbff011ea, - 0xa03cfdfe, 0x9c9af393, 0x24467a4d, 0xcd6abfce, 0x84fe08ae, 0x690899fc, - 0x6cf91dcf, 0x2fec58d2, 0x4e1c478c, 0xf32bfce8, 0x7f5287d9, 0x6f1aeeee, - 0x8fc2cb5b, 0xb9fca11f, 0xa36fc580, 0x689ce9f3, 0xf03bff39, 0xb64ecddf, - 0x10a9ddeb, 0xb77f383c, 0x967ce3f4, 0xc3a88d62, 0xbc022bf9, 0xb714b3bf, - 0x55f88eb5, 0xf70f73e5, 0x44bdfd03, 0xe5451838, 0x648bad2f, 0xcd92f67e, - 0xfd0eac73, 0xfbfb2a3d, 0x3d3fbdcd, 0x3de91bbe, 0xc53ff955, 0x31c5a4f2, - 0xb57ecbfe, 0xd3da0864, 0x52fa2ef9, 0xa8bf4f7f, 0x3f69c304, 0x5fef34e7, - 0x1be097d9, 0xd2cda1b6, 0xcdbcd28f, 0xa1d2034a, 0x04386e03, 0x690df3bb, - 0xb05f6e6e, 0xc24d453d, 0xf817ec36, 0xee7c07f8, 0xec81e59b, 0xf6c7cfe6, - 0xc1725d13, 0xf4e5a510, 0x2c358246, 0x8fbe68f9, 0xf3c4d7f1, 0xfa77b5d9, - 0xe604f3fb, 0xe0071241, 0xf87bb62e, 0x37f80a1c, 0xf9cf3d62, 0xd7ac3cb2, - 0x061ff915, 0x25f39d9d, 0xbd2e7078, 0x55fc7a40, 0xcacc7fa8, 0xf3717cf3, - 0xebb0d1bb, 0x1c7e90c4, 0x5e487f0e, 0xafd404fb, 0x7e16e01a, 0xb1e03f6a, - 0x3f0226eb, 0x6d773bd5, 0x1d2a7ee4, 0xe5b9e81e, 0x4c1e2ebb, 0xbd789c82, - 0x0e8064f0, 0x2ffcca77, 0x2a3d7bc7, 0xe37cb54d, 0xa47f3297, 0xa445f388, - 0xbf515a75, 0x0f47ca54, 0x689fe769, 0xc8fe65cd, 0x5aeeeda4, 0x31525faf, - 0xf8a7d7ca, 0xadaec2fb, 0xde749b9f, 0xab61a555, 0x23fb65d8, 0x3325e763, - 0x79e7be5e, 0x2dced767, 0xec87bfbd, 0xfd4e1fc2, 0x3b036cc0, 0x3cbb06fa, - 0x7f10b7a7, 0xe7e8bd01, 0x0bfb8d34, 0xef6a5fec, 0x524d3f05, 0x849d9c95, - 0xc287a48f, 0xbef8ce58, 0x598ecfe3, 0x2eb6e7cd, 0x4844d567, 0x0567c83e, - 0xe5185fb5, 0x5bf30bbb, 0xc2f39da8, 0x1c86ceea, 0x7bca2332, 0x3a57be37, - 0x073193da, 0x45ef3f3a, 0xb9255abe, 0x7720cd2b, 0xd7bee339, 0xe51759f9, - 0xbe7cc66d, 0x91b1fd6f, 0x520c6704, 0xad22cf5d, 0x9c7e5ba3, 0xfc05bdba, - 0xc93081f8, 0x980aa38f, 0x0bf3e91f, 0xda15ffed, 0x33e23ef7, 0xe279d1af, - 0x738fdc23, 0x7af2b18e, 0x3ca96abe, 0xa170e748, 0x6c84011c, 0x79ce1d8d, - 0x6fe1146f, 0xbe1553bc, 0x3d45f46e, 0x1e7af5a5, 0x2bd099f8, 0xb0af54d2, - 0xfb1dac57, 0x5bcefbf7, 0x8d47d6d5, 0xbba9f9d0, 0x37767097, 0x5bcf396f, - 0x01f447c2, 0xdf2ac65e, 0x5b0ebe6f, 0xc3ac41d1, 0x9f1e6738, 0x539ce38b, - 0xc304f98f, 0x43df187f, 0x1f3a19e7, 0xf27ef8e1, 0xe1158fd2, 0x7dff60b7, - 0xdafb676e, 0xd3eb5b5e, 0xee7c25bf, 0x81ed925d, 0xf005e89d, 0x68cff05e, - 0x7bb3cb3b, 0x7c1f84a3, 0x84d4ef65, 0x2f45ec00, 0xdf044f41, 0x79642de8, - 0x77bfacb8, 0x7f53950e, 0x5f68c2fd, 0x2f345ec0, 0x069feb42, 0x7d15fb46, - 0x52837db8, 0xda0e66fb, 0xbe6488af, 0xf9203473, 0x706c7378, 0x9bdf4a9e, - 0xa814cf3f, 0xd6045477, 0xeddea2a4, 0xe5435fd2, 0x6fd43549, 0x122192f3, - 0xf951ffce, 0xf3ce68dc, 0x32738df6, 0x4cfb671f, 0x5f6f54f3, 0x697aaff8, - 0x51bcd5eb, 0x3d83f796, 0x9429e514, 0x9b63f4a7, 0xab573fac, 0x974691f7, - 0x0f99cfb4, 0x5a44a6f8, 0xd2fde741, 0x99d2c24b, 0xc2fb7929, 0x5948f3ef, - 0xe728db06, 0xc29f5c56, 0xcbd9a3f4, 0x5b7c6b66, 0x1c0d0fef, 0xcb2f2123, - 0xb70b39bf, 0x679e8384, 0x41b78796, 0xbe5a3bee, 0xfb7a0a32, 0x0c1a9f4c, - 0xa3395c83, 0xaf29dbd0, 0xaf5c62a5, 0xd74cb71c, 0xc0a582ff, 0x0eedcbeb, - 0xf7cb3771, 0x3ea302c1, 0x556fafa5, 0xa37898cb, 0x27615cde, 0x2cf042fe, - 0x9a6df6d1, 0x7d3bd7d3, 0xebe9f404, 0xf4fa8de3, 0xe40f65a7, 0xc6d2fef2, - 0x8def5b3b, 0xb90e993f, 0xfaa7226d, 0x0f7a9d78, 0x57e74dd6, 0x25db97a0, - 0xfb6b08bd, 0xdf298b47, 0x07887b30, 0xd389eaf6, 0x1d6f4c1c, 0x1f2ce12d, - 0xf08ecc37, 0xb0d76ec2, 0x06ed8c2b, 0x83fb6b37, 0x1ba628f4, 0xee28beff, - 0xf32ed2a7, 0x3065cf95, 0x0f60bcdd, 0xe515b93c, 0x7fb3872f, 0x8e5a32b6, - 0x24bbf95b, 0x29bd2e8d, 0x5fb17aab, 0x32a5e98e, 0xe5c31dc2, 0x7a678fbf, - 0x57dc367a, 0x7d127c00, 0xd2bc5db2, 0x258ccc1e, 0xe8d31ffc, 0xfb237a0f, - 0x98a36af5, 0xf796856e, 0xf59e3cfd, 0x797f9238, 0x437ddf3c, 0x7bb3ef39, - 0x3ec42efb, 0xf0c91e5a, 0xf2c9731c, 0xbcb19563, 0xb7dfe60f, 0xc5fc30f4, - 0xbcec8ac7, 0x55ed8e5f, 0x73fade59, 0x9f841a9d, 0x9acfa75b, 0x86dfc725, - 0xe1baa8f9, 0xd4dde4a3, 0x5595fccf, 0x7e6ed093, 0x7053edc5, 0xf69af6de, - 0x4369fb29, 0x4afcf3f7, 0x97d47fb3, 0xf98c9dee, 0x760764d5, 0x1e7ea41c, - 0x116a739c, 0xee9fd3d6, 0x3ef5869b, 0xe17d6f6f, 0xeb77044f, 0x5eb23f8a, - 0x6fb47d74, 0xd85fbe26, 0x5fae1bf3, 0x16bff2bd, 0xb6afce41, 0xcfd17a4a, - 0x7e8d1ae3, 0x1e6f8645, 0x7cae57ea, 0xc881f59d, 0x7f9223ec, 0xf8fdfede, - 0x5bbde9ce, 0xdda8505e, 0xd5bd88d2, 0x5c81aa9c, 0x94676b9c, 0x0692b460, - 0xed3d4a7c, 0x8d182bac, 0xa459f175, 0x5b74b89c, 0x4b181f88, 0x7fd9a091, - 0x16d2dda8, 0xf242bf19, 0x19f41d82, 0x7d297f5a, 0xf3df7ae7, 0x9168857b, - 0xdf7763df, 0xf75cb57b, 0xfc387060, 0xb09b19ae, 0xfd76e7ee, 0x77e8d326, - 0x872f4d0d, 0xacffce57, 0xeace5fb6, 0xbdb665fb, 0xb9005ed3, 0x7d33fceb, - 0xfe76744c, 0x3f9cc1c9, 0x112bb4ad, 0x577f974a, 0x72465a78, 0x65b78d7c, - 0x07e7e424, 0xe34befb5, 0xaf82465b, 0x384e7ce9, 0xff59725a, 0x85c96acf, - 0x47f3abbe, 0xc992d451, 0x992d03df, 0x4582ff68, 0x8ff853da, 0x3a78a8e0, - 0xd2dde369, 0x0cb7e10f, 0x26e87e47, 0x1a71f5e4, 0xe91f25c2, 0xa58fbe69, - 0xf9e63b4b, 0xbd9bf639, 0x7ad07f54, 0x707ca9bb, 0x9adf9cc0, 0x03e7ed2e, - 0xfa6fe243, 0xc3fbeda9, 0x213c8e70, 0x3fd7f5ba, 0xd4f38da3, 0x3c719d53, - 0x0acfa6aa, 0x6e1f4eb7, 0x80dbdf29, 0xf13a8fef, 0xf1126b7d, 0x6398a5e5, - 0x9e5fcf2a, 0xfb494f67, 0xbe790bcd, 0xe7179c24, 0xff821781, 0x67ca5885, - 0x7892be43, 0x3e3af3d5, 0xf2bfe743, 0xb04945a3, 0xae947edf, 0x7d3cf9db, - 0xde3a9740, 0xefa46c1a, 0x2e3f4364, 0x8569382f, 0x2c49ecde, 0xdaec1ab3, - 0xd81cf3eb, 0xe4378b57, 0xd6748c39, 0x10e0adb0, 0xece21c49, 0x2007ab36, - 0xf7035837, 0xd86f7e42, 0x05f8b6a6, 0x54bc3b97, 0xc0f3acff, 0x68b7a8db, - 0xe43e6c43, 0xe2fdbd6d, 0xcb1223f5, 0xdd0e700c, 0x9c875e66, 0xd87e7316, - 0x04fe736e, 0xffde80ce, 0xa0bcbb7c, 0xc8705f39, 0x83e4ff9c, 0x9c81675b, - 0xbdff55cb, 0x3f89f42a, 0xf384384d, 0x5e17d3f1, 0x2cfac68c, 0x41d94bfd, - 0x71a149e8, 0x0a6eb422, 0x56ff08f4, 0xb2e3e985, 0xf81e9178, 0x810f1e81, - 0x93a4619d, 0x683fe10a, 0xfebcb94d, 0xcb32d119, 0x5955744b, 0x64e0bcb7, - 0x57bf5741, 0x43b3acb6, 0xb71d0bce, 0x9c2ffda7, 0x6aec375e, 0xd964a3c5, - 0xc5637555, 0xd62df809, 0xf4013bbe, 0x854bfc57, 0xe7e28ae5, 0xbe0abd07, - 0xce63b6df, 0x9ace9c0d, 0xedd0f8c8, 0x2af78b7d, 0xbbca28c1, 0x5dba4946, - 0x7d615eb8, 0x1cd1a4bd, 0x36b65747, 0xd9a6de24, 0xf778be5c, 0x9f86fffe, - 0x18f1dcbe, 0x1e5c33c7, 0x05781827, 0xa7c55b7a, 0x153ded82, 0x330dbf9b, - 0x2d79cb97, 0xbfe1e7d4, 0xaee1e396, 0xcf3a5592, 0xd0c893b7, 0x574bf0f9, - 0xe1066a51, 0x8de6aafd, 0xbd9b94aa, 0x7597ecc5, 0xb0ce39da, 0x918221ca, - 0x28a1cf04, 0xdf45d7bb, 0x628fae2f, 0x18516179, 0x9cf99fc9, 0x438e708a, - 0xdda0c4f4, 0x965477a9, 0x25e2aa83, 0x571eaa1e, 0x56c5b002, 0xfc8a48c1, - 0x04bf3213, 0xd25526de, 0x3f00d78f, 0x1798cdd6, 0xab6f524d, 0x03f706b4, - 0xc0e79d2f, 0x4abd7336, 0x38d1e79a, 0xefe659c8, 0xeb9da2d5, 0x36feecd7, - 0x60ddf8cc, 0x527d65df, 0xc8556bd7, 0x7aa70433, 0xb3cb0447, 0x402398c4, - 0xef14ab57, 0x29150ec3, 0xefa0e39d, 0x2f964e25, 0xe7946ee6, 0x838c3347, - 0x0dd78390, 0xae67b966, 0xbe04cde2, 0xd670bac4, 0x1fdca9a7, 0x64e58bde, - 0x4e484396, 0x7daa3966, 0x12e39d8e, 0x825af39b, 0x1f9ac790, 0x0ad0f148, - 0xf3e47f32, 0x96709ee8, 0x4aa79a7b, 0x5d79a7b9, 0x31ff6e1f, 0x390beb40, - 0xf9b9e25a, 0xb71e1c9e, 0x89db2a9f, 0x200f523e, 0x7a133ab9, 0x41e5c102, - 0x67472eb9, 0xb04afac5, 0x9bfcfaee, 0xe0a3db63, 0xf1e512c7, 0xd86e4bdf, - 0xed879da2, 0xf003c2eb, 0x8a549c53, 0xf60c5a0e, 0xe4325ba9, 0xac7231f9, - 0x8f56ab77, 0x966519fd, 0x80ff77a9, 0xd07b29e0, 0xe9486ee2, 0xf5e1075a, - 0x27fe6266, 0x83e785d7, 0x958e46ee, 0x7963a7f6, 0x0e479f92, 0x73bf1c17, - 0xedefd6bb, 0x9a531619, 0x48f44118, 0x942c9cfd, 0xe1a8edf6, 0xa4076c45, - 0xbbb9ba35, 0x19359038, 0xb32a9cf2, 0x9afefd17, 0xa4e9e06e, 0xde52f18b, - 0xd94cb93d, 0x72f2e124, 0x5fc8dfbc, 0xf0fdb385, 0xe8de76a4, 0x347441eb, - 0x8d71cf82, 0xe8d3ad9f, 0x74cf5d66, 0xb98ba263, 0x3741b790, 0xd8b9e473, - 0xfada5749, 0x7af0dd12, 0x485d13b7, 0x6be211ba, 0x4b742fb4, 0xdf443b79, - 0x7bb7d4ea, 0x0e88b7d0, 0x6de8c89e, 0x074217a8, 0xf1181ac2, 0x252cfc8f, - 0x2a4762a3, 0x564904b4, 0x2cdc47e1, 0xd7c646ce, 0x4ac0d65d, 0x55bfa782, - 0xab00cbae, 0x653a3ba4, 0x5cf911fc, 0xd9f88bdf, 0x0b17fbe2, 0x4e2fd52f, - 0x4ab76c12, 0x2626f927, 0xa409db8e, 0xb0aa0770, 0xf68a50e7, 0xffb231c5, - 0xc46fa262, 0x5e7f51b3, 0xdcc69c4b, 0x2a7fc246, 0xfb407e58, 0xef6e7ce8, - 0x5ef6c8b7, 0xd303a52b, 0x5f6a3ee4, 0x2bf8c615, 0x264073be, 0x58d264e8, - 0x66249d33, 0x4f41394a, 0xbadd331b, 0x7e0890dc, 0x9838d250, 0xf08699cf, - 0xd85daaa2, 0x7d48cfa7, 0x4df578a3, 0xbe004793, 0xd83de367, 0xeca7a7c2, - 0x494aff60, 0x7f1f9ce3, 0x5b653d08, 0x98df7f38, 0x780f7be9, 0x17b8ad3f, - 0x250fa2ec, 0x27b15f33, 0xcb5f7b52, 0xa3bf73d4, 0xc77f8a74, 0xa62390db, - 0xfeb950cc, 0xb9ed2114, 0x338e51a2, 0x35b9ffd9, 0x3c9bfa91, 0x94f0e15a, - 0xf25770b6, 0xb455f832, 0xd1a63df5, 0x98b84377, 0x70139cfd, 0xcd4cc80d, - 0x24821f86, 0xe4e46ed4, 0xfd5a9901, 0xc806ca31, 0xc9c70343, 0x47d7a7fd, - 0x2d37e83f, 0xcfb7ee53, 0xe7a77db4, 0xbf5caf09, 0x5b584d6c, 0x5b52345a, - 0xf3a51070, 0x039ec6b2, 0x2a94999f, 0xde07ac26, 0x4d8aaa7f, 0x317b6f0c, - 0x4ca885f3, 0x8f82f837, 0xfba65914, 0xee99836d, 0xb7b4c6db, 0xb6f949dd, - 0x7ed2392d, 0x0bf3e9a7, 0x82e5825d, 0xef9231b6, 0x64896fb5, 0xd5cc73fe, - 0xed27151a, 0x97dfac5d, 0xd7f1246a, 0xe17b86ba, 0xda752e37, 0x2c7e70db, - 0xfb3a607c, 0x499b4bfb, 0xfd5c47bf, 0x4f7eb35a, 0x6658787a, 0xa87afa37, - 0x019a0e5e, 0x55ad951d, 0x36070e98, 0x997dec78, 0xcc2e29cf, 0x4c19ccaf, - 0xf32fff07, 0xf05c7384, 0x37fb7a65, 0xb091f784, 0xba0e0b1f, 0xd7c83a1a, - 0x3716e30b, 0x1a7eb315, 0xfe63ed99, 0xbc255035, 0xd4cf1d10, 0xec126fe8, - 0xd64be0a0, 0x97d8bed6, 0xdf6865af, 0x4e995ce3, 0xbe70eba6, 0x7366d06f, - 0xb6be0265, 0x9c16e155, 0x4a5693b7, 0xe77da6fa, 0xbb80bdc0, 0xfc0222ac, - 0x7ed6b8e0, 0xd16b0afe, 0x77f7ca46, 0x1c546b08, 0xe98f2be8, 0xfbe5903b, - 0xe9f7eb0c, 0xc828c42f, 0xd76ba50d, 0xfa34b849, 0xe323d610, 0x4f9c69e3, - 0xc3e4a4b7, 0x53d3a0ae, 0x766c6b20, 0x5d0308e6, 0x1e9850cc, 0x60873e68, - 0x55979d9f, 0xfa728f92, 0x32f41fbe, 0x1d306c69, 0x6a85d871, 0x76abc725, - 0xe20f0a24, 0x3b443a87, 0x241d23cb, 0xea3f808f, 0x27e7467c, 0x475e1744, - 0xeb7ad742, 0x3d6b657c, 0xde784681, 0xf4e0ef56, 0xb0977aa9, 0x5ed84f12, - 0x67f9c89f, 0xb69cddeb, 0xf7f167d4, 0x9c3deae7, 0x8a3f59df, 0x7bd42ff3, - 0x7ebbbf39, 0xabbfa722, 0x84efe22f, 0x3a4be61f, 0x93f9d1df, 0x9f3a5f4e, - 0x05aba50a, 0x33dc6684, 0x0fccf6a0, 0x79883e75, 0xf8bbf258, 0xa9cebe93, - 0x113f914a, 0xceb450fc, 0x5428ff01, 0x22f33ecf, 0xdca3b9e1, 0x1da1f1c9, - 0x0ec1f242, 0x8dcf83a7, 0x0dd8bb64, 0x32c340fb, 0x869ddb6f, 0xb95e7873, - 0xba06ac22, 0x5c36a9bd, 0x7d740d58, 0x29ac5d73, 0xfdeebf3f, 0xff50fad7, - 0x2df18b3f, 0xbb1cfac2, 0x7fa3d4e3, 0xdf8fefa4, 0xeb033a71, 0x796c704e, - 0x1edee308, 0x2ad1c1a1, 0xceddbae1, 0x08c0d2f2, 0xcfe14fa9, 0x2d738861, - 0xfb7d894e, 0x31e70437, 0xda061d6d, 0xc146b35d, 0x754ab32e, 0x1f2aa4ad, - 0xfbe8bd63, 0x2af5b59f, 0x7c630ba9, 0xfb6a3496, 0x4cff18d4, 0x57de3cf8, - 0x78a75cb0, 0xe91f8085, 0x41ec2ff8, 0x71c41192, 0x685011c5, 0xad94851c, - 0xae17b0f9, 0xe428fd79, 0x10eea574, 0x873ed5cb, 0x8428e393, 0xd8d676df, - 0x9077529f, 0xfed689eb, 0xc8c838a6, 0xf83b5ee1, 0xeb1b6805, 0x40759256, - 0x268b9f60, 0x94f1ef85, 0xd6cbdf69, 0xe2f8a628, 0xe655337b, 0xac32878b, - 0x14ca0e9c, 0x89a5139a, 0x5e9d29cf, 0x3c707f89, 0x9e535963, 0x2f81917d, - 0x4bdf6897, 0x78a62cb3, 0x321943c7, 0x98106a2e, 0x6777a505, 0x3217daa5, - 0xdc7373df, 0x24bf5ebd, 0xea757f2b, 0xe883f470, 0x8ff6aea0, 0xddb95a64, - 0x84970ca1, 0x59e741c7, 0x74e9c714, 0x72e82e7b, 0xeff8a7cc, 0xeb3f0c95, - 0x3ecf1559, 0x7bfc2cfd, 0xe30a7f15, 0x9862a9f3, 0x0ec8df66, 0xf2ce9c8c, - 0x8ca9d78f, 0xd72dfc84, 0x7fd3fc7f, 0x547c4689, 0x57694ecd, 0x690db4a5, - 0x6ce5edf5, 0xd0f6ab57, 0x9f0388fe, 0x5fcdfb35, 0xd14ff67d, 0xf897acad, - 0x5bf8b493, 0xdeaaf78e, 0xc0e38279, 0xd0afb8f4, 0x37ca3576, 0x71eaa7ac, - 0xb63fba01, 0xf78d9f70, 0x851ecd4d, 0x5d9a98f5, 0xe7c01317, 0x4aadf66a, - 0x272e2ee8, 0x5e3d5fb4, 0xd5bfb740, 0xc39fb588, 0xc384487f, 0xffad0ff8, - 0xaf546676, 0x62054353, 0x3b60aed5, 0x1c705588, 0x8e2d72c7, 0xc19023b3, - 0xe49ee17e, 0xc4f59aed, 0xedbf49f0, 0x1063bab0, 0x88417caf, 0x53addd89, - 0x7e7920fc, 0x047da39f, 0xed85f0bf, 0x1791cb2a, 0x7ef147b6, 0xff7edea8, - 0x55dbc441, 0x8dd8566f, 0x308e2557, 0xaa77aade, 0x0fe061c2, 0xc50bb035, - 0xd2e70cf7, 0x416aa3a7, 0x145a4b5f, 0xadf816ef, 0xde98ee1d, 0x35da7806, - 0xd61a5afa, 0x45d79232, 0xf814ff83, 0x5cce419a, 0x8e7ef7b2, 0xe77aa413, - 0x6df9ae59, 0x51b3c724, 0xce036f0f, 0xd80a1b33, 0x65a4bd4f, 0x05cb3547, - 0x105d23db, 0xccdb4e69, 0xd1be29f7, 0x9346fbc6, 0x4fc0ced3, 0xaacff682, - 0x4e030f2c, 0x5ad3cbec, 0xcedeab3c, 0xb3b64832, 0x0dfb7868, 0xae88e7f6, - 0xda5a4bfa, 0xfea9d3a2, 0xe7dfbb27, 0xee4839d4, 0x23ce25e3, 0x3f4738b9, - 0xf7c919d9, 0xf9d93eed, 0xd12f09eb, 0xc65ae778, 0xfb0c52f4, 0x1b20e06c, - 0x41b73fd7, 0x25f301c6, 0x5a0fd611, 0xb6673e78, 0x27ac2927, 0x9f84df03, - 0x8f9f3b33, 0xf63ef0b6, 0xab717bff, 0xc86b15b3, 0xb2eb847d, 0x5bfe8047, - 0xed11fbb5, 0x7fe5fd9a, 0xed6affa7, 0xa4529b7b, 0x3bef238d, 0xc20e3d08, - 0xd53beda5, 0x796efbc9, 0x2fef9d94, 0xbee6182c, 0xe8f81e71, 0x518e329b, - 0x043f77f4, 0x3bc16ffd, 0x596f6cf1, 0x41f7736e, 0x36c38bfe, 0x282c13f6, - 0xa1f51cf0, 0xed9d8c7e, 0x75b1224a, 0x6dadec04, 0xa8be5229, 0x933b435c, - 0xe88fdc50, 0xacf84fcd, 0x8f84580c, 0xa50793f2, 0x523ebaf2, 0xd9daf16e, - 0xfbe413ff, 0xc2ecc792, 0xfe2f7b8f, 0x5d7ea4e7, 0x0efd2a99, 0x517f608f, - 0xcc17195a, 0x4edd878c, 0x69ca9ba3, 0x9fa06e54, 0x4cc14dca, 0xed674fc8, - 0x72891ed2, 0xf9954de8, 0x46835eb2, 0xfd07e8a7, 0xceb8a5b6, 0x2bbbbcb3, - 0xb0ef404a, 0xed2518bc, 0xdf09bf21, 0xaf386614, 0xe9241a6f, 0x07f341b8, - 0xf848b7fa, 0xf8e41700, 0x4ca6f625, 0xb8fab9c8, 0x789ba24b, 0x78dab3bc, - 0xa49a224b, 0xc78b44ff, 0xdf1e7d43, 0xd3bfd826, 0xcb1864fe, 0x1efba7cb, - 0x9fe30179, 0xc730727e, 0x04a5b411, 0xf2e6ed16, 0xaee38e70, 0x082c2a78, - 0x327b3f78, 0x9f58ed8a, 0xf61ca4d9, 0xcb025459, 0x1ea28761, 0x3afe805c, - 0xe0298736, 0xc2299fa3, 0x2df2889e, 0xa80e59bd, 0x3f63afa8, 0x17b10549, - 0x4e94afc8, 0xd9f7dc84, 0x276cc196, 0x950decfa, 0xf7d0292f, 0x13eef835, - 0xc67e0b4d, 0x3ff4bff2, 0x6fea7e9e, 0xaff3bb83, 0xdb366c54, 0xd7f5f4c3, - 0x2418efcb, 0x0c7703ed, 0xcac97a92, 0x7fe92e41, 0x30796c8b, 0xf929e795, - 0xeb03ad03, 0x131fb47f, 0xd63f6f60, 0x714127b2, 0xccc1cf02, 0xdbef035f, - 0x7a759ea4, 0x42fd8dbb, 0x79462f15, 0xe774fed9, 0xb0ef7c15, 0x78729542, - 0xdbde4585, 0x99eed0ab, 0xb2674456, 0xcdf08b7d, 0x16fb6d7a, 0x8e471b55, - 0x01d6d9fb, 0xd4109fd2, 0xf0e42ff2, 0x7149b83d, 0x2c69e6e2, 0x05c86d5f, - 0x8e6e2f5e, 0x1a79f8e4, 0x87b88bc7, 0x5cfd9f8a, 0x116633e2, 0xae7407eb, - 0xd4ae7f31, 0x9dd573f8, 0x5ee0c757, 0xe5477881, 0xad1712fb, 0xbfe03e9e, - 0x4f7af8a1, 0x5f4b63e3, 0x41f99478, 0xc417ed25, 0xfcd52d59, 0x529f4bcb, - 0xba5c9e58, 0x9887eafa, 0x136dbeef, 0xb6705fb8, 0xe368fee5, 0xf8d5ec7a, - 0x0f7b5767, 0xf54a5fd7, 0xa337fb65, 0x36ad9e19, 0x5d09e00f, 0xfeddefc7, - 0x6a5ff529, 0xf242d15f, 0xf3e5ee45, 0xdc8e28bf, 0x95f027f6, 0x676ce1ed, - 0x7be7f5a3, 0x2d6c6746, 0x33ff308b, 0xbf3384cf, 0xf72b1339, 0x9e7427fd, - 0xe780edfa, 0x5db1f787, 0x02e9bded, 0x80e2d0e7, 0xae1d5fb9, 0xafdf1afd, - 0xc0c4f78a, 0xeb45534f, 0x7d68fe81, 0xdfedc47e, 0xd0fb71b1, 0x768e3cf9, - 0xf4fb0c23, 0x9ba64899, 0xbae4fd33, 0x1076799c, 0xb16d679f, 0xde09de92, - 0x674be864, 0x1b8a6562, 0x0a87a03e, 0x3387a497, 0x1ed85a63, 0xc1d94670, - 0xb64d9b69, 0xfcd3a8ab, 0x897f44da, 0x26d01fa0, 0xb58ea9ec, 0x80c72047, - 0xe7cc8fcf, 0xcefb8834, 0xd07376a1, 0xbebfce29, 0x84dcf259, 0xcf3e0578, - 0xe3f61b7e, 0x733df0b4, 0x564f269f, 0x4fdcbf6e, 0xdcaa7588, 0xeb3fb0ae, - 0x02fe7692, 0xddba5eea, 0xa972e89f, 0x6e22f15f, 0xb2e3696b, 0xa5fba025, - 0x81e6ebb5, 0x2c79f5ee, 0xb75feed5, 0xd3c32a29, 0x27fb4e16, 0x74f1f2fb, - 0x8a59aafc, 0x5c279f1e, 0x7b45f9fa, 0x2dcb2c38, 0x4db288e9, 0xa3655fd4, - 0x49c796b2, 0x395bf5d1, 0xb84f1d3f, 0x5efb02cd, 0xb9df769b, 0x70ebf9a7, - 0x524f04f6, 0x6d4fe496, 0x6f9ef229, 0xbef25bfb, 0x0a6fc5f6, 0x81fee262, - 0xfa91c83c, 0x7f047f7a, 0x72106816, 0x96e7c68f, 0x704eaec2, 0xfb306e66, - 0x9b36b273, 0x9bb643f3, 0xcd3bd9f3, 0xe6bddcf9, 0x7355e7bc, 0x7b7185de, - 0xfa09e177, 0xa103e236, 0xbe85236f, 0xfa94ceed, 0xb7d0f236, 0xc6df4291, - 0xc8dbe877, 0x1e46df43, 0xd0f236fa, 0xdf4291b7, 0x1a39f7c6, 0x7b352a9e, - 0xe381d629, 0xeb84f6d4, 0x5fbc00f1, 0x6049cc2e, 0x52ac2a3e, 0x24b0bd1f, - 0x4ec7e59b, 0x0754d33b, 0x38f499db, 0x7ca2b7a7, 0xc37ab2e3, 0x75647b7f, - 0xc76e14df, 0xdf9ae7f6, 0x6573fb49, 0xf613b87e, 0x9f55d68e, 0x13d886ac, - 0x444df288, 0xf6b60bfd, 0x556fc0ad, 0x6fec2bdd, 0x7ee15d6f, 0xfd7207e7, - 0xc7a2eed8, 0xdce3152d, 0x7d26df03, 0x7b6fc649, 0x6a3b461c, 0xac485fa8, - 0x3f21e435, 0xa1f39b35, 0x35f0207e, 0x355f69af, 0x6e3c1d31, 0xbe0bef6b, - 0x0749e27f, 0xa13af3df, 0x6cc4edd9, 0xba63cb17, 0x8f29df3c, 0xc26ca3dd, - 0x2b24bdf9, 0x1c77db8e, 0xd3dd30ca, 0x2f4b4d0b, 0xdabcb3e5, 0x58ab5f99, - 0x8cd94e30, 0xaf59fb15, 0x73e68c4e, 0xb60d16e9, 0x0dff9041, 0x440e0f70, - 0xe868e898, 0xbf10b8b6, 0xfd533f65, 0x4353bb61, 0x4c4396fc, 0x16d7d3e5, - 0x17b5ef98, 0x1f2a6d5d, 0x878cef68, 0x96ff4873, 0xd64b9f06, 0xe7cce8b9, - 0x4bd686f9, 0x847f3c56, 0x25bc56bf, 0x9a32d3e5, 0x7b40b787, 0xfe1f239f, - 0xe014ef39, 0x16c5bcaf, 0x54bef38b, 0x9d44873b, 0xb72e5cf9, 0xae2bbf0a, - 0x5dcaee8b, 0xed4b1bc2, 0x2536b4bf, 0x71dd1d33, 0x14255934, 0x2472192d, - 0xe57d0837, 0x8246278d, 0x8dd4aaae, 0xbf2a2ec9, 0xc56c0955, 0x71d3ec45, - 0xa4ae123b, 0xf8b4fff2, 0x75a2c91e, 0xef05b64a, 0xba3e0f9d, 0xbde04d23, - 0x9f6b1391, 0x3cb8e68f, 0x6d92fe8d, 0xc1d008ae, 0xf59526c6, 0xd4cdd814, - 0xd93a2eb8, 0x011f14d8, 0x8c7ca6bd, 0x717297e2, 0x0bdf49b4, 0x9aa147c5, - 0xe69b8efd, 0x2a90f17b, 0xf36a40ef, 0xf592ee5c, 0xaf6cba45, 0xe7d7b3df, - 0x47d3527b, 0x96be362b, 0x3f7d0b79, 0x2e7f783b, 0xd65784ae, 0x2f79e6ef, - 0xdadf6cb5, 0x1d7bd297, 0xd7985dbe, 0x45c6b7f2, 0x7ce3495f, 0x87c65db9, - 0x89f9b5ff, 0x4fc4fcc7, 0xc27a6cef, 0x8541fb0e, 0x1e876035, 0x46e4fe5c, - 0xae18e23b, 0xbf91b6db, 0xcc56da2f, 0xbefd00f6, 0x7c7aa7da, 0xf28f86b3, - 0x1706cab1, 0x60ffb3cd, 0x23ca4fc9, 0xa14b1c64, 0xdc35fa3a, 0x4db8b813, - 0x66bcc3c9, 0xe3b0ed14, 0x1a3bff1e, 0x37dd09df, 0x17a7871d, 0xabbd86f6, - 0xdf20f145, 0x89993ed3, 0x0f4472cb, 0x39b92fd3, 0x0869719d, 0x0a1fd5eb, - 0x8e70bed2, 0xd7e88764, 0xcf695587, 0xad123c43, 0xd83db973, 0x85e43a6b, - 0x0ffbe597, 0x8d0e7455, 0x2ede87ca, 0x169455c4, 0x744d568d, 0xd23e335e, - 0x0b660fb4, 0xfea2bec3, 0xa67e8966, 0x69498cfc, 0xce37faa6, 0x67e21a18, - 0x672aefce, 0xe99575fe, 0xdbaa975d, 0xe3856efd, 0xbf9ac67b, 0xd33b7a53, - 0xf6a60dd9, 0xe99a6255, 0x9b25975d, 0x133c65df, 0x8fa1d995, 0x41f76b95, - 0xb4dafb66, 0x9dfcadef, 0xafda6226, 0x7f3cd303, 0x8da5e794, 0x1dba08fd, - 0x9ffe367d, 0x1979ddd6, 0x898f19d1, 0x3bd85bf8, 0xe479667c, 0x42a9eb08, - 0x669543ae, 0x92caaa8f, 0xff2aa8f6, 0x9be23b11, 0x24d6ff09, 0x93754942, - 0xaa46f6c2, 0x938a48ef, 0x7df1dbf9, 0x075ef9a7, 0xf284bbfa, 0xf6316a43, - 0x35796857, 0x42e71bcd, 0xb047ec35, 0x6bfde983, 0x19f4eafd, 0xb43ecf7a, - 0x3760df1f, 0x6d8ae7ef, 0x23f60e3b, 0x8a2f4cbc, 0x497c43cd, 0x5b54cb65, - 0x74e5f671, 0x8bfdf3a6, 0x7fb616e5, 0x857e1c75, 0xdca3ace9, 0xddf191ea, - 0xd51f18ff, 0x0d6f695e, 0x3445bfa5, 0x1799f81f, 0x013c54ed, 0x5e03d645, - 0x432e81fa, 0x0dd492f0, 0x753c74be, 0x7ca42de2, 0x1c33fe31, 0x004a11f1, - 0xbc32f27c, 0xfad478e8, 0x2c13e45f, 0x013c1267, 0x3fa42786, 0xff742a31, - 0x20efc2dd, 0x84506c74, 0x3c6ef94b, 0xed24bb4c, 0xe4d30336, 0x2977dbbc, - 0xb3ebc81e, 0x7bf9592e, 0xc914bd27, 0x9319f538, 0x93b3fbcc, 0x7ee48a7e, - 0x81297999, 0xd36ffddb, 0x8fd177d1, 0x8d099fee, 0x5defd6ff, 0xddac1a2d, - 0x46211a4b, 0xc44ffb7c, 0x4072ebaf, 0xe749e74f, 0xf0d2e379, 0xf6ed4cef, - 0x951e5e1c, 0x3edaf1ca, 0xf3a88ecd, 0x4ed69f63, 0xca98b71f, 0xefa005dd, - 0x17b009fe, 0x4b4c6eaf, 0xe317be36, 0x3b63655b, 0x788af26f, 0x5dc38b4e, - 0x8a473809, 0x4d77c857, 0x27d5df8e, 0xe388fe01, 0x26bd6cab, 0x7fc7d751, - 0xe4593c3a, 0xe9c85f20, 0xb3617589, 0x3d78768d, 0xed2c1a6d, 0x7e39fa35, - 0x7a3872ce, 0xaadff636, 0x0508d15d, 0xfdeaba5a, 0xcf3a2e91, 0x8f7c5957, - 0xef7f660f, 0x85cf3e46, 0xec2e636b, 0x513cba70, 0x0fb0aab1, 0xffcafdce, - 0x9c31e579, 0xb615befb, 0x9fa3c804, 0x840aa07d, 0xc679d0ce, 0xe1a7c472, - 0xdd3fae92, 0x10f7c912, 0x1784553f, 0xea25a6fe, 0xe9975cfe, 0x0b3bdd5c, - 0x41deffe3, 0xb8c08ee3, 0x1889ad81, 0xc4cfe3d7, 0x1915beb8, 0x57d9dd31, - 0xbd66b4f4, 0xeab6f394, 0xeecd64f6, 0x791ef90c, 0x6270f7c8, 0x1e47be41, - 0xc8523df2, 0x4dbef8f7, 0x6c0c2ff3, 0x7e83cf68, 0xb22b1fea, 0x75bcf96a, - 0xbf7e4166, 0x80f08945, 0x78a2dcff, 0xc1bc70fa, 0xc4def966, 0xd57590f2, - 0x49da6bd3, 0xedd03306, 0x84392e0f, 0x8c6e6e31, 0xc7e53588, 0xea9afa39, - 0x4c52ba17, 0x0e25d7e5, 0xef5f9536, 0x7fe533ce, 0xa9a57598, 0x18cf64fe, - 0xa347fe53, 0x9fd537ae, 0xca6a9dea, 0xc7389f4f, 0x51667f54, 0xc6fca9b1, - 0xe54c4bd9, 0x4ccb7c73, 0x3fe579f9, 0xa9bfd535, 0xdca98576, 0x9c565c2b, - 0x77a17b77, 0x865fde11, 0x2de945de, 0x8d38656f, 0x9c7a3aeb, 0x7977dba5, - 0x5072694e, 0x36dea1bf, 0xd7ee25d0, 0x68070e80, 0xc0be67f7, 0x7e1bd2b9, - 0xf522a0c9, 0x417d23de, 0x42f5a137, 0x1e4747cb, 0x35a6e8b8, 0x7a2a7a2c, - 0xc4f895a6, 0x140e2be8, 0xf57e51a4, 0xad338553, 0x5f465fc4, 0x54f9e07d, - 0xb53d37ca, 0x3b0f964a, 0x51e51170, 0xf320df4f, 0x1a8b05d3, 0x7af90c8f, - 0x31e69f86, 0x6ba907fa, 0xd26ed23d, 0xa769bc6d, 0x80f0883d, 0x01e04d78, - 0x13e89069, 0x4fa201e9, 0x7d12afa4, 0x710ba596, 0xe913e890, 0xf13fd221, - 0x7fa4f7fd, 0xfa4c3d22, 0x49b7d227, 0x847a44ff, 0xefa44ff4, 0xf4e6cfd5, - 0xb71f7a83, 0x397d43fb, 0x6beb47a7, 0xf5c7fbf9, 0xb9fe9c75, 0x5ddfcfde, - 0x433b7443, 0xba31ed90, 0x7e1aabff, 0x76edd847, 0xfd1acedb, 0x9e578ac2, - 0xb2bfbaa7, 0x46b456a1, 0x5ab69f62, 0xba394f63, 0xf33d90fc, 0x6538ab5b, - 0x0f5ebf90, 0xe10d26f7, 0x98bbfbf1, 0x8fdf6b6f, 0xf203e989, 0x520a9d69, - 0x9f28297d, 0x2aba5f99, 0x0fc7f886, 0x81b5a9be, 0x74b43e5e, 0x0bfb7f7f, - 0x87da4e8d, 0x8c873378, 0xebbbf2e8, 0xf8ceef7e, 0x1e5f831a, 0x8e3d6cfe, - 0xf3c7f747, 0x473e219f, 0xf1eb93f7, 0xef6ad741, 0x707ee923, 0xef47fe3d, - 0x6092f0b7, 0x1acd77be, 0x512dcb2b, 0x38c41156, 0x35cf9c7a, 0xc43c968e, - 0xe9535c3b, 0x3eb738e4, 0x23ef1df4, 0xde2f3d52, 0x25fcdb99, 0xf2edcfd5, - 0xe6d1f7bb, 0x8f3ce541, 0xb63e4bc2, 0xc5a35ed7, 0x43bda01d, 0x753bf396, - 0xfc831188, 0xe1db2941, 0x7da8551e, 0x001c577e, 0xfaca47ea, 0xfe97f441, - 0xdd178d15, 0xc4068fb5, 0x6e21e4b5, 0x93b5406c, 0x8c36c6e3, 0xb9bdf209, - 0xded7b1e9, 0x4e22aad3, 0xd8c7e638, 0xfaa74f47, 0xefcf0266, 0xf00f73ee, - 0x5c5a7e50, 0x53a46f5a, 0xebb5de43, 0x62e67d66, 0xe97c755d, 0x4bd7d778, - 0x9e21b7c7, 0x5dfcf18a, 0x6eba17eb, 0xafa5eba1, 0x2ea5e153, 0x977f03fc, - 0xfad74faf, 0xfffb3ec1, 0xb70cfacb, 0xcc7df0b6, 0x07874ab0, 0x7ad77d70, - 0x262edcdd, 0xf1783ee0, 0xa441f725, 0x5f7cd24b, 0x8a967f80, 0xc05c1331, - 0x81cd4b91, 0xdeb4279d, 0xef59eff2, 0x077a90e1, 0x7cd60ae2, 0xbd79769d, - 0x1af521dd, 0x7ed60b62, 0x374ced2d, 0xe43d7ce2, 0xed1fb1b6, 0x1e3d70cd, - 0xa3ccebc3, 0xf1a71c75, 0x96a243a3, 0xd7120fcf, 0xf1df58fc, 0xcb8f52da, - 0xee72cc5e, 0x6e59a778, 0x514df09c, 0xd09dc623, 0xd68e442b, 0x6837e1fc, - 0x9a275efd, 0x7bd0dfb8, 0xf26837f2, 0xf93de869, 0xf26886e7, 0x01488a65, - 0x3c2f1a9f, 0xbded2e12, 0xd92ef183, 0x2f46926f, 0x8c556e69, 0x9f083d06, - 0x55f1cc15, 0x8b9077bc, 0xbf9cfd71, 0xfd38045e, 0x3f7208a1, 0x22918993, - 0x6c2123ff, 0x79039df2, 0xf55ab33f, 0x2ce427fd, 0xc2e65efd, 0xd8abdf70, - 0x4e44af77, 0x28f78f99, 0x4b8c15c6, 0xe303bb47, 0x1c9f2cdd, 0xbcb1a470, - 0x8b657d84, 0x6f7fdaeb, 0x6e92f9d0, 0x9106f795, 0x3a60dee2, 0xe9d7966d, - 0x86fe41fc, 0xed0215ac, 0x71cdb826, 0x1ffb7a38, 0x6b0ac6ba, 0xfdfccf41, - 0xfa7bb987, 0x66f3aec3, 0xb0f1a0ec, 0x7b19bf83, 0xf7cc78c5, 0x163ed8cd, - 0x39d98699, 0xbd3179cd, 0xa74e793b, 0x26f1aee7, 0xcf7c6b08, 0x1af1d678, - 0xcf1d4f8a, 0x2f5e02ff, 0x2fd78774, 0x37290b06, 0xa23e4a47, 0xac2ab7e3, - 0x1f671ef3, 0xa5445c63, 0x33e9e243, 0xb87b8c80, 0x3cf15775, 0xfd17a93e, - 0x7545ef81, 0xd43cb8a3, 0xc736250e, 0xc77f5e70, 0xef83ccec, 0x7c122746, - 0xea7c39d7, 0xd9cbc250, 0x492660fc, 0x0d93e230, 0xfaef7c0d, 0x07aab3dc, - 0xeaa57ff2, 0x4f01eb5e, 0x3f655379, 0x95e6f8a0, 0xc509f864, 0xa3e3eee6, - 0xaf121d2b, 0x32b3feba, 0xa7f788ad, 0xca241570, 0x3de4d5f7, 0xe81e5d72, - 0x8be3261f, 0x3dccfbf5, 0x232307c9, 0x1feb1f24, 0xbeaef926, 0xf38ed49e, - 0x48cfd449, 0xf74953e2, 0xb03eb045, 0x1a4de5db, 0x78ca7f0a, 0x75a79261, - 0x97a3bfbd, 0x5af03f7c, 0x68d0f991, 0x643f8fca, 0xef2a0113, 0xf14c2f18, - 0x946f8564, 0xfa16bbf2, 0x44b098fd, 0xfc0cafd2, 0x611ddc20, 0x32346f7a, - 0x8f94ce2b, 0xd533f4f2, 0x6a95198f, 0x0ef58f2a, 0x4fc79531, 0x7be537cc, - 0xaa655d17, 0x58f667df, 0xefafbe53, 0xa4fd5306, 0xbca669f2, 0xe49297ce, - 0x76a03127, 0xc0fda9ae, 0xfd5312ba, 0xf9857f14, 0xf7bf54fd, 0x9e025648, - 0x697f9477, 0xbc87966b, 0x96116aaf, 0x90ef5d91, 0xde5a3afc, 0x5ce89907, - 0x6491efc4, 0x0cccfd34, 0x8a8dfa8f, 0x46292673, 0xae24f7e1, 0x60f99b73, - 0x3f39a261, 0x2af795de, 0x2b9c6e96, 0xa828fe34, 0x6a929e80, 0xf3efa6ad, - 0x347c6a86, 0x9eb2e457, 0xefeb5dfe, 0xff5a621b, 0x4e5d7c50, 0x05e7cf0f, - 0x6f9ed2dd, 0xf9ec179c, 0x9ec0bc46, 0x9ec3cc6f, 0x7b0fac6f, 0xf61cb1be, - 0xc179637c, 0x8c1d3321, 0x83a66238, 0xe99a8e2b, 0xd0cfa740, 0xd5b2baf5, - 0xa7c21f4c, 0xb07f94f8, 0x6a7f575e, 0xf5d09fa6, 0xd78b0921, 0x1153826f, - 0xfbfca48f, 0x642eb5eb, 0x87d73abd, 0xf6f90df0, 0xbe50e0da, 0x48785b27, - 0xe4b77815, 0xd79e6d51, 0x27e5ad0d, 0x7d5bb6c3, 0xae7de6bf, 0x5f4355d1, - 0x871d5749, 0x1f070f9e, 0xffa4347d, 0x02f9fbd7, 0xfe3b3fa8, 0xf41db262, - 0x45df2ed1, 0xee1f036b, 0x49b715dd, 0x77bcba7a, 0xe39533f2, 0x9a598e18, - 0x82ebf014, 0xf036df18, 0x6bb39bcb, 0x1367f815, 0x458ed145, 0x8ff9cb88, - 0x17e464b0, 0x77f7940c, 0xdf2b7645, 0xe2f9d07f, 0x17192482, 0xf35432d8, - 0xdc647af3, 0xa543f3ce, 0xe3ca24dd, 0xe2e338e2, 0x83bf796c, 0x05e499d4, - 0xe1c7c039, 0x47c041f0, 0x69df85b3, 0x39b9b56c, 0x86ffc46e, 0x83f7e02a, - 0x72f90b1c, 0x35df2680, 0x0070e47c, 0x85eb41fe, 0x1c1d9ce9, 0x5be29870, - 0x99736e87, 0x892d39f2, 0x76c3faa6, 0x79e54dbb, 0x79532cc1, 0x298f21c1, - 0x28c8e23f, 0x8e2bfd53, 0x2bf94d7a, 0xea9a275b, 0x9169fd5f, 0xda249f29, - 0x077e061f, 0x3e8f522a, 0xe2553433, 0x7e382dc9, 0xb19dc16f, 0xa6a7def2, - 0xba72eb5f, 0xd3ecf71e, 0xde5439e8, 0x71f7681f, 0x5f43751c, 0x187be1e1, - 0x129f4d0e, 0xa7c03d66, 0xde772dc5, 0xe39bf0a3, 0xe578f596, 0xd3417d4e, - 0xdd39740f, 0x35ecaf10, 0x082f2bc6, 0xe03dfeeb, 0x3dd6d2ff, 0x7681fe14, - 0x9f86df39, 0x88def9da, 0x3c28570e, 0xda38b533, 0xefee8e2d, 0x25b2d8f5, - 0x1465259d, 0xfef41dfd, 0xcad3cd98, 0x365fdd6f, 0x4fd5a79e, 0x0bf0d5f4, - 0xfba567bb, 0x305bc7bb, 0xbe67ce4c, 0xd4f372c5, 0x32cf8e6c, 0x3bdf83bd, - 0x51fdea5b, 0xf3b74ab9, 0xe323105b, 0xdd8c44a7, 0x79edfa0d, 0x44cf893c, - 0xfbe468bb, 0xff9c5a47, 0xee5b6b4d, 0xf3454419, 0x7bda4ded, 0xe81b0160, - 0x9258d261, 0xd884f2c3, 0xb35765b6, 0xc7a2e493, 0x3f6cacea, 0x35ddbfe9, - 0xceb8248b, 0x49031bfb, 0x407d01ef, 0xb4be81b6, 0x71e54721, 0x1b9ec1ae, - 0x4df6fd81, 0xfb3d9c67, 0xced08405, 0x754fa90b, 0x874c6f43, 0xaffe3cfa, - 0xf143ede3, 0x42adeba4, 0xd74c338b, 0xd7f1d2e0, 0xf0d07769, 0x707fdfa7, - 0x6d15b32f, 0x8a3df272, 0xd2db8889, 0x4725afd7, 0x86ad65d2, 0x3f03d40f, - 0xa15ea9ea, 0xfb031d9a, 0xc7708772, 0x43a1bab8, 0xc2bffd3d, 0x9eff8e8b, - 0xc4f557ee, 0xc2f9421f, 0xeab7dd77, 0xd9ff4e89, 0x3e06577b, 0xb468e321, - 0x5ba40975, 0x677d3fd8, 0x6f3f7994, 0x8d7696cc, 0xa2beda71, 0x6799ddf3, - 0xf60217e6, 0xaa5586f1, 0x39e42fc6, 0xc4529c5e, 0x3a8b11ef, 0xe533cb17, - 0xcfd62f1a, 0xc80f85d7, 0xf5aee0f7, 0x455c2516, 0x9b6692f9, 0x15a048d8, - 0xf38fbbfb, 0x1b93bf66, 0x449efe71, 0x3726cdc0, 0x49b4b71a, 0xb94fec09, - 0xc5ecbdfc, 0x5c7ef94e, 0x8bd9bbe8, 0x2f17fd35, 0x86df602a, 0xcfee65fa, - 0x8f6bced6, 0xe12b7cf0, 0x0ba5bd67, 0x02de8d7e, 0xe8311df2, 0xf3b4aac3, - 0x8e969c70, 0x24fc3737, 0xc2795df1, 0xce16446f, 0xb76b46f3, 0xf89d7471, - 0x9d2afdd5, 0x1cc3c27e, 0x171a1faf, 0x4affd670, 0x1a7e7774, 0xd3d37fdd, - 0xdff4e83e, 0xa85f877c, 0x1e8969c3, 0xff043e05, 0x57e8dbbf, 0x8248f3f9, - 0x3127fd90, 0x6ab48ff0, 0xb98d89fd, 0xf44fdddd, 0xf1c5d8ad, 0xbe2cab10, - 0xf25c40ff, 0xef1fea19, 0x3ce5deb0, 0xf8fb8090, 0xd3bb3493, 0xe4d6f3e5, - 0x7ef2d1b0, 0xe55f8740, 0x2898eef5, 0x1f1373ef, 0xba77d815, 0x08aa7f1f, - 0xfbaa42f6, 0x466b7c49, 0x3f75fe31, 0x14707149, 0x61b339c3, 0x484f0db1, - 0x7b7c3eb6, 0xcbbb8461, 0x403ad27f, 0xe4f4e7c6, 0xc97e9947, 0xb8cdfdc3, - 0x73f71574, 0xca453b2c, 0x2cf78d6b, 0xd90d9d03, 0x67986c26, 0xdffbadab, - 0x23929819, 0xf852d1f7, 0xe21b7bd2, 0xac28567e, 0x84572c07, 0x7cc4071e, - 0x6c5fcf5e, 0x3285f2d2, 0x992acb7f, 0xc5ded56f, 0x3bd9aada, 0x98a44f30, - 0xedf0f40f, 0xf3043d9a, 0xe0798a40, 0xf21af83b, 0x83c86be0, 0xbe0f21af, - 0x0d7c1486, 0x51444bdf, 0xfd2a9e72, 0xfb0de33d, 0xf19efe03, 0xfe09b906, - 0xfe1e631e, 0xf87d631e, 0xf0e58c7b, 0xe1cb18f7, 0xe1e631ef, 0x87d631ef, - 0x8798c7bf, 0x1f58c7bf, 0x1e631efe, 0x7d631efe, 0xe58c7bf8, 0xcb18f7f0, - 0xe631efe1, 0xd631efe1, 0x58c7bf87, 0x629d737e, 0xacdd07f2, 0xba503bbd, - 0xa3e98e3e, 0x2928b539, 0x3ff7d687, 0xc7e7ff23, 0xf3ac54b6, 0x6efc25de, - 0x47845560, 0x44d373ae, 0x2116eeb9, 0x0e7db9d7, 0x76edf3af, 0xf1942f99, - 0x03f4a1c2, 0x74f8cabf, 0x0a4157e9, 0xf8520abf, 0xafc29055, 0xfd2ade32, - 0x57e1482a, 0x55f877c1, 0x82afc290, 0xa4157e14, 0x8520abf0, 0xfc29055f, - 0xbf07682a, 0x55f8520a, 0x157e1df0, 0xe0abf0a4, 0x038231fb, 0x2e1d15fe, - 0x26e9f9c8, 0xd0e8943d, 0x4cba87a4, 0xc6f9c879, 0x8df390fa, 0x8df390e5, - 0x8df390e5, 0xc6f9c879, 0x8df390fa, 0x88f11bf9, 0xef296f71, 0xde41db1b, - 0x9a73e637, 0x86c1affc, 0xf9c37935, 0x46b69157, 0x2e298f29, 0x9e72eb92, - 0x58ff059a, 0x1c92b86b, 0x763921eb, 0x8d676fc5, 0x89f892bf, 0x2b976f16, - 0x6f582dda, 0xbad37bf6, 0xe38282f9, 0x3bfe7383, 0x7f75cb91, 0xbad1ff2b, - 0xac14ede7, 0x90cb6c37, 0x3dede970, 0xd522a5c2, 0xbbe577eb, 0xbe3a17af, - 0xa5f98f5e, 0x28520e01, 0x910710f3, 0x1f33bb77, 0x2d5bedf1, 0x5d0b8c8a, - 0x4372e329, 0xe349aae9, 0x3b2d5b4b, 0xbb50440e, 0x83c562f6, 0x5699077b, - 0x0f96c871, 0x43e6d53c, 0x89cba89e, 0x6b83e2d5, 0x903c42af, 0x7f6eb70e, - 0xf7c13e24, 0x0bb746dd, 0x738d197b, 0x8ec217cd, 0x64985bdf, 0xda04f297, - 0xea1cdf41, 0x0c9bbc57, 0x4732bdf4, 0xff3e7b9e, 0xe8caabb2, 0xb5edd0fb, - 0xdd1ee157, 0xeed908a4, 0x33478f37, 0x2a34a71e, 0xc9fef09b, 0x8bc2ede8, - 0xd4bfb1fb, 0xddba1ee0, 0x71e32f65, 0x4eff7c5d, 0x4378b7ef, 0x2c17df32, - 0x13e3ad16, 0xf0a127d9, 0xde3ae6fb, 0x62af7e68, 0x0fe2c47e, 0x2ffc8ec1, - 0x7121c3df, 0xc3dcfbf1, 0x6c7866b9, 0xc4dbe221, 0xe40ef95e, 0xabc5e1e4, - 0xbe5c137a, 0xf2077c80, 0x5f6a2f9a, 0xf966fce3, 0xcf93240e, 0xcf8f8648, - 0x857e41c3, 0xe298ffdf, 0xe5e968df, 0x15e0bdc6, 0xdfd404b6, 0x0b503c2e, - 0xaf790906, 0xb6579f55, 0x57096238, 0x95e22f40, 0x11fd0378, 0x7a0198e7, - 0xf8d8f3c9, 0x56a9907d, 0x46fc0d97, 0x5d8a7397, 0x7542ec72, 0xf7df0c74, - 0x2e13910b, 0xb8e6f636, 0x8e3d7f8d, 0x93ef83a4, 0xce15df2f, 0xf88f8572, - 0xb9e6f807, 0x5977193c, 0x91c3ecb9, 0x38aed496, 0x8129d392, 0xf3df78ad, - 0xe88eea74, 0x11cb0a51, 0xdb5fc087, 0x7be79f1a, 0x5eabc582, 0x1710fbe3, - 0x96881f1b, 0x7fa4aaf7, 0x9bc34ca5, 0xa85a6f6e, 0x16994fad, 0x5ebc743f, - 0xe74bcfbe, 0x71f7bf30, 0x72c6d1b1, 0x28bca846, 0x880feb84, 0xb46f2b73, - 0xc5d3ddf1, 0x27578b6b, 0x777eee8a, 0xcfe32bc5, 0x349771b5, 0xa84e38da, - 0x2b477b5c, 0x965877f4, 0xd2e8726a, 0x27efe66d, 0x4fe44272, 0xad44fdfd, - 0xaf5bf14e, 0xa83964cc, 0xee71c6d6, 0xb94857f3, 0x0110ec48, 0xbf9867dc, - 0xef059c62, 0xe5dfcc58, 0xd0dd28f5, 0x7c9a3bd1, 0x12830934, 0x8a5ea7de, - 0xed32be60, 0xcfce3f52, 0xe9c894ba, 0xe4b2978d, 0xd11dac77, 0xbca16b4b, - 0x26beff5f, 0x1c44cd17, 0xb2e40165, 0x1dd74c3e, 0x2218d744, 0x4357e357, - 0x302bcabc, 0xf9b24fc3, 0x734e2156, 0xf7c146d2, 0x7e432691, 0x90d982a2, - 0x2fb00aa7, 0x3ef90a52, 0xef8544c6, 0xbe1e4cb7, 0xb407db4c, 0x11f3042f, - 0x37c3f77e, 0xf1006a7e, 0x3b7db337, 0x7d77582c, 0x6dfcf83f, 0x64e60efc, - 0x7bc762bf, 0xcf4d3e81, 0x743de9d6, 0xd4882c5f, 0x694e63ec, 0x8fb4eaff, - 0x9c7e5801, 0xc446f227, 0x2d802eb3, 0xb0b69fb3, 0x6ca8aa84, 0x1b9c9e59, - 0x94236379, 0x6ed37fac, 0x9162df32, 0xfe489ff7, 0x717578e3, 0xe50fb0a4, - 0xf92ad78b, 0xe1d79788, 0xd8d87afa, 0x777ac349, 0xe74941d1, 0x03eeccfe, - 0x5df960bd, 0x4cff2619, 0xf84a5a68, 0x105a3ec6, 0xfc63fad3, 0x5c84d0d2, - 0x889f1de1, 0xf9f5c877, 0x02e2208a, 0xdbf96ae7, 0x8ff2bd9e, 0x278c9c6b, - 0xedcd8fce, 0x3fe22377, 0x38fe65fe, 0x7f1ab15f, 0xf14daa37, 0x3de57379, - 0xdf5809c8, 0x7e76ecc8, 0xa66660c7, 0x212f9e4b, 0x72db9676, 0x845df2dd, - 0x694b7b10, 0x846f3cb6, 0x8f3c9dd5, 0xb66e3afd, 0x3ef3ea57, 0x33df336e, - 0x5cead3d5, 0xbff83769, 0xa0f127ba, 0x7ffbde45, 0xf1d812c4, 0xa06bd122, - 0xe6016fb7, 0xbde208fb, 0xcf1f7e19, 0xa3477f4f, 0xef694f93, 0x74f4e865, - 0xdf22eeac, 0xda712897, 0x9e81aadd, 0x7c28d6ca, 0x4ea4b11f, 0xadf627de, - 0xfcbde451, 0x8f57ec1e, 0xdf9af9cf, 0x17fc7a51, 0xc350b211, 0x91fb7cef, - 0x5d291cd7, 0xdd53fdf8, 0x7f926caf, 0x6f103306, 0x9c36b73f, 0x7afe41df, - 0x018fd158, 0x87b6647f, 0xf11269d7, 0x1a9fd434, 0xbe29fbe3, 0x07238897, - 0xf05c6f61, 0x7df8b7f3, 0x29bd9ae1, 0xf161eefc, 0x78d5bcee, 0x61ebe547, - 0x89723bbe, 0x2e9d8b7e, 0xea90e43b, 0x973e58c6, 0xeed1f417, 0xf6768ba9, - 0xf3ebe9e7, 0x0794ae60, 0x9c723c8a, 0x453e9a0b, 0x354db308, 0x7fe793d5, - 0xedd43ee8, 0x95f6a1a2, 0xbe2af7d0, 0x7b029ecb, 0x5760dd89, 0xb631edd5, - 0x7073e3ac, 0x77b7cf9e, 0xaf8dbbff, 0x4d4776eb, 0xa9d85d9f, 0xe84f66cf, - 0x9d7fb903, 0xbd1d82e2, 0x11bee9cc, 0x8765f5f1, 0x14f0886c, 0xf2dce293, - 0xe4bb92dd, 0xb72525bb, 0x9b3f31e6, 0xc7c9358f, 0xbc5187bd, 0x9402cb8f, - 0xdfbcf7c6, 0x657bade7, 0x53d01ec0, 0xe0f7cbd0, 0x7b5e5ccb, 0x2a2e419c, - 0xef4c526d, 0x17f9e818, 0x721da573, 0xc019a93e, 0xa6b74ddf, 0xd086f1d8, - 0x108f127c, 0x46baf837, 0xaa3b7a27, 0x932571c7, 0xf941c552, 0x9dc114ae, - 0xfe33c722, 0x9349514e, 0xaa063df9, 0xfedd72cf, 0xafee28dc, 0x4ef345d8, - 0x3862ea41, 0xa78c0f09, 0x3fa87bf6, 0xebc38f37, 0xd80c1a51, 0x8f983760, - 0xcfca1678, 0x186c0575, 0xbe51a4a7, 0x2b5be28f, 0x89adf1c7, 0x2e40e7b5, - 0x03ecbab0, 0xa360f28c, 0xbe78cf7c, 0x0411fbf6, 0x65cbcb2f, 0xf3dc2784, - 0x867defd2, 0x8358abe2, 0xd629acbf, 0xad365f2c, 0xe67d61b3, 0xc35ef0f4, - 0x971d1a97, 0xfbe18e34, 0x2f5665f5, 0x69f097df, 0xb2ebfef8, 0x27e1bbf0, - 0x90fcd399, 0x8d79052d, 0x3c097d2f, 0x829e06f7, 0xd23efc19, 0x678e70b2, - 0xe26ae39e, 0xfbe276f9, 0xe40fc201, 0xe3115715, 0x8fc4e89b, 0x66b2c038, - 0xc176faf3, 0x65df2513, 0xfde62e6f, 0xb3eac8b7, 0xac708cbb, 0xfb819fdf, - 0xdf68735b, 0xe127fde3, 0xcc7df1f2, 0xc8dc0f53, 0x3806fbbf, 0x8f28e781, - 0x3bde027b, 0xba61ba22, 0x4167e9d6, 0xfacfdc81, 0xacc35178, 0xec3f0ed2, - 0xf7a9f6bb, 0x06f3e420, 0xffd86f5a, 0x76a7da7b, 0x71a4005c, 0xddf265ed, - 0xab7dd0ba, 0x9f7d57ef, 0xdf56fbea, 0x8ad98fcf, 0x174a8982, 0xbdf3a1df, - 0xf06eb9f6, 0x77834934, 0x84aeb6ae, 0xc18557d7, 0x986237ae, 0x53f3dfdc, - 0xfd1ffbcd, 0xbd54dfa1, 0x03306c7c, 0xfaf53df7, 0xe3f3b8fa, 0x03ec3b64, - 0x30ea5bd0, 0xe5fd674b, 0xe262df5c, 0xfc9da51f, 0x04aafb63, 0x0a1d8ff0, - 0xdf96e1fb, 0xe5bee523, 0xe17bc8cf, 0xf8bf9667, 0x77aa2cf6, 0x0b8dc1fa, - 0xca2ff78c, 0x2c5f9282, 0xfc0b7924, 0x0f269163, 0xe5f4cc6c, 0xe7ec330d, - 0xc99ffbb2, 0xdb98fec4, 0x6f0a7792, 0xf9bcd1a8, 0x3f3fa3bd, 0x5787d2f3, - 0x5dcebbb9, 0x6b251e7d, 0x3b15b5de, 0xf493788d, 0x0756777e, 0x38a55b9f, - 0x6953e8b7, 0x61f33163, 0x8f7a4891, 0xa1eeb5d2, 0xa8dc50f4, 0x5a579cb0, - 0xfea03237, 0xd2ebf22f, 0x8df953b5, 0xf4bd7d28, 0x73f45f77, 0xa67f8757, - 0x35734eb6, 0x4c3d9e7a, 0xe5b9c3ee, 0xbc45f629, 0xf8ec53ff, 0x5a39cdbd, - 0xf3329cf9, 0x72f5cef7, 0xd5fbf275, 0x9fb827d8, 0x58eaf584, 0xcbf6936b, - 0x57ad97ed, 0x1d02e432, 0x9d9ac58e, 0x6f66a172, 0xcbc9a45c, 0x8d8b5eb4, - 0x71f8b5eb, 0xcfa55eb9, 0xbc17f5be, 0xd3f34653, 0xef93a3de, 0xecb4940a, - 0xb39b75e0, 0x852d9d66, 0x5864fdea, 0xa8fe298a, 0x05cf36b4, 0x35dcfd3b, - 0x07e06d1b, 0xf126193f, 0xf3f74a16, 0x1d62f8b5, 0x148f38af, 0xaf473f83, - 0x83b83e0f, 0x5975b9c6, 0x77f1b478, 0x3d1a02ed, 0xc6c6d697, 0xdad2bc61, - 0x7fa17be2, 0xe840e7e9, 0x2e113bfe, 0xf50945f7, 0x6279fd87, 0x55ef878c, - 0x377ed7cf, 0x43feb42f, 0xdafddd1a, 0x4cbfdf26, 0x92796c8a, 0x226a3be3, - 0xe913e03c, 0x8c01ade9, 0xdc067a0b, 0x2f7c8b76, 0xf5b2bd33, 0xa241c073, - 0x20f5c73c, 0x105b7bc5, 0xbf2813ed, 0x79ef22c9, 0xdd32aaa5, 0xa607e1a7, - 0x5e8b9437, 0x5f1efcad, 0x2151bbe7, 0x9b176af4, 0x1fdde0d7, 0xefc12f7b, - 0xa9f4e9a6, 0xa7d3a3f7, 0xcd3dbf4e, 0x9cf7d76f, 0xcd1489df, 0x49e592ce, - 0x0bb8d076, 0xbfc41bee, 0xf35df16b, 0x35ef6bb4, 0x4c37ce76, 0x65c7defe, - 0xfa974df3, 0x6df3cf52, 0x66e84c2e, 0xd4f3a1be, 0x431e89f7, 0x694fe9df, - 0x1394fe92, 0xd4639d0a, 0x70b2c4ee, 0xe7d3ab8e, 0xbff5dba5, 0x8f87bdef, - 0xf669c586, 0xc828d6aa, 0xdfb5f397, 0x99411151, 0x86a9f7c7, 0xaff9faef, - 0xf3a75fbf, 0xdab593e9, 0xef5a28f9, 0x75167ec1, 0xf50f7c69, 0x2889d358, - 0x627313bc, 0x6f4f848c, 0xde4dab77, 0x76511673, 0xbbcfde37, 0xfe3cd6e9, - 0x8d8594bd, 0xbd9f587d, 0xf98d2ea9, 0x587e4dc2, 0x1ea74517, 0x83e348b0, - 0xaf16b791, 0xd7f502be, 0xc2eff0a7, 0x4e7a742d, 0x43f6e7ad, 0x2313903d, - 0x53daa79b, 0xfa961e59, 0xbb17ee82, 0x7c451155, 0x127c0d4f, 0x3fb2cbfb, - 0xe2cfe71d, 0x983f52f5, 0xe06b1164, 0x50d81d3f, 0xf82fa134, 0xfc8ac3c4, - 0xe60d9a3d, 0x0e86bcf7, 0x7c02fa2a, 0xbc5df426, 0x5e2d6d5b, 0xe482a7e8, - 0x16d1d80e, 0x9e588b3a, 0x93e345bf, 0xf8db9ac7, 0xaf1d7ebd, 0x78bfe08f, - 0x7ec42aa7, 0x1a276a14, 0xff07d9a8, 0x7b8faf1f, 0x0080003d, 0x00000000, - 0x00088b1f, 0x00000000, 0x7cb5ff00, 0x65545c0b, 0xce7bf8da, 0xc0cc2b99, - 0x1245c880, 0x85848b87, 0xd780c034, 0x508151da, 0xb9bba0bb, 0x658e21ba, - 0x500665ca, 0xd7775ddb, 0xa6a18cfe, 0x45fa7d66, 0x80ed65a6, 0x76c36a97, - 0xa8283448, 0x59990bc9, 0x6a37627f, 0x5b63b92f, 0xba402de6, 0x6dbfedfc, - 0xbcf3cf7d, 0x511730e7, 0x6fbefddb, 0x797bf9fc, 0x9f5ef3df, 0xcfbcf3fb, - 0x8c346339, 0x63181b75, 0x418e8b2a, 0x89486839, 0x8d8c9964, 0x615f6909, - 0xf6c3894c, 0xc645db25, 0x7cfb4046, 0x1962c893, 0xfa31d72b, 0x1fbf8f7d, - 0x3c1f7631, 0x42f3c337, 0x07d634a9, 0xcc37d7fd, 0xd6c972a0, 0xf1ae6dc2, - 0x2509258c, 0x606393b1, 0xb66ae3c0, 0xce258a07, 0x2b307719, 0x8da4d3cc, - 0x73c325d2, 0xc7292bb5, 0x496f9fe0, 0x0c4943e3, 0xd4699dc6, 0x7b4377cf, - 0x414e6981, 0xba5f8c14, 0x325b2a33, 0x6f5dfbfb, 0xc91b1811, 0x4673a558, - 0xcc614b1c, 0x67e1ddf1, 0x1fb0a94c, 0xf304d398, 0x7709e57f, 0xa38ba0bb, - 0x82492dae, 0xb3aa3c23, 0x7fa058a7, 0x6f31d895, 0x4e73cc12, 0xa04def70, - 0x5338e6fe, 0xe5a1fac0, 0xccc63ae9, 0xff398ce9, 0xcf3487cf, 0x3b89e2e7, - 0x8778c016, 0xce047f73, 0x1ff8f553, 0x6c3201f2, 0xb2cf689d, 0x8dbce1e4, - 0x1c124d7b, 0x56637b74, 0xbee39c09, 0xda46c7c7, 0xf79f2f33, 0xa8b668b6, - 0xdbcbda04, 0x6957c118, 0xd48ee85f, 0x5eeddc20, 0x696131a6, 0x28689a62, - 0x956c48cf, 0x52dbca07, 0x06b9a2d8, 0xe10dbb7f, 0x899eeb00, 0x025492dc, - 0x9f7b15ed, 0x79433248, 0xa5ebc8d6, 0x9c7a7f7b, 0xddff4045, 0xd5e20d5a, - 0x0b1a62ae, 0x25d7bb8c, 0xb250dcd8, 0x12c668f2, 0x7d6ea310, 0x59b19199, - 0xaf9a7096, 0x630e7b62, 0xc17dfeb9, 0xab3f6a73, 0x8fb8c562, 0xd903f531, - 0x8bfca1cb, 0xe21f7bca, 0x7ab52ff3, 0xf1192b8b, 0xfcbc2662, 0x84548b65, - 0x05fbaeed, 0xfac05636, 0xac1a637e, 0x6ac9165f, 0xf4a17c71, 0xcf049b57, - 0xb2101c57, 0x787b30b5, 0x1ee6b766, 0xd1169103, 0xd389b559, 0x75768ad9, - 0x7fe02251, 0x2d408b45, 0x3357950e, 0x2f2abe1c, 0x80e6664d, 0xb6b656fd, - 0x8eb0cc68, 0x09ce19a3, 0x539e1dfd, 0x5e78a59a, 0x7cb185b6, 0x89fe27c0, - 0xa53e6bf8, 0x3f0037b9, 0x2e1cadd5, 0xbede56ce, 0x3b900338, 0x1362b699, - 0x26dea0d2, 0x6b3ebd50, 0xaa35fcc2, 0xfcfe7ac0, 0x9a586935, 0x354c4e08, - 0xf0025490, 0xa3d194dc, 0xd73bfc41, 0x5d42f3ca, 0x0d5eb01d, 0xde48e512, - 0xf1c06a9e, 0x3caf1a66, 0xd146b677, 0x6c33af78, 0x3609bb03, 0x61506d51, - 0x4434ef59, 0x56b3b960, 0x715950cc, 0x09166173, 0x1611dfe0, 0x6122c591, - 0x3d5eaaca, 0x3b501240, 0xf6845870, 0x83fb48dc, 0x0c719f48, 0x33e802b8, - 0x06057991, 0xf9dfdff4, 0x7fce2e59, 0x17df18cb, 0x5eaeb60c, 0x017e7d33, - 0x8b26c3d0, 0x5f4c8e7c, 0xc8f1d22e, 0xb0af4043, 0x6cd5a7bf, 0xcf073e83, - 0x42e6c257, 0x08c2cc3b, 0xb984dfcf, 0xafdfc0f7, 0xce226f31, 0x54de74cf, - 0xcc9af71c, 0xc35a25a7, 0xf5f60106, 0x63fb149b, 0x053b8fb8, 0x116cf8f5, - 0xc58d2071, 0xfe6afd7e, 0xc2796d9c, 0x4ffc03a6, 0xa367e8e7, 0x4062e645, - 0xf1519aa2, 0xc163a406, 0x60ab6366, 0x0f3307fd, 0x2e80cbdd, 0x31d01e1e, - 0x5eaf9c2d, 0x7d3dcfcf, 0x0094ec20, 0x2a8f46fd, 0xf4165916, 0x2958ab37, - 0x29943ff4, 0x9fd8557a, 0x9fd8dce9, 0xbe6d0ae9, 0x8196590c, 0x7a88d0fc, - 0x78eff51b, 0xca011bf3, 0xe1e2e944, 0xe2573848, 0x3d4b052f, 0x3c1b29f4, - 0x85fff4fd, 0x5352f4b2, 0xfca1efcb, 0x19bda475, 0xb0727751, 0x501d94f8, - 0xa3c9b0f6, 0xf9f264b3, 0xf1dff702, 0xa2226fab, 0xfabeff45, 0x7bef4e07, - 0xcea58ad9, 0xe9b8c022, 0x9b57921d, 0xfa7ef975, 0xa9e361e3, 0x39e18fd4, - 0x5ba20dfb, 0xe1ffb010, 0xd37f710f, 0x14af0675, 0x17d4e381, 0x38ff3a7c, - 0x751d1e66, 0x284646fa, 0xb1913ef8, 0x8c3cdc58, 0x7068b81f, 0x6fb9c137, - 0xa14ff991, 0x488b1eaf, 0xf191e9f8, 0xe991c0a4, 0x7e9122b2, 0x5e8ad5eb, - 0x4cb385f0, 0xe8d67f3f, 0x5e0cff38, 0xff386d12, 0xcdd6b960, 0x8ec18a60, - 0x5727d254, 0x007fa792, 0xd740ca79, 0xfb6a97bc, 0xf90fc233, 0x78fc074a, - 0xc02f0c97, 0x25f9c33f, 0x64bbfe79, 0x1065ddb8, 0x127e9c39, 0x6e992702, - 0xf650ba14, 0x5863982f, 0x9f1fb469, 0x47ddd7ec, 0x8f099323, 0xe383ffe3, - 0xdfc213ef, 0x01d62737, 0xff51b11b, 0xfc784598, 0x579fc05f, 0xf80bfeb4, - 0x9fc50eeb, 0xe23d7f57, 0xd2d171ef, 0x0880fc84, 0x26d2a1c8, 0x0658f9c2, - 0x932ffe23, 0xe09b2cc2, 0xffe4767c, 0x8fef889b, 0xfc2bdf22, 0x37d8a63e, - 0x49e4f51e, 0x7dc19ec6, 0xb50f44f9, 0x10a766a7, 0xbac75f9f, 0xf01db013, - 0xf117379c, 0xe876d82e, 0xfb7d2c24, 0x5df5865e, 0x1ecb0615, 0x5bbf6f38, - 0xfe61a974, 0x8ef72886, 0xc36eb0a5, 0x1716995d, 0xd59633b6, 0x3ca07286, - 0xbe7a82cc, 0x85cb8a21, 0xa4e90586, 0x277e0f87, 0x73c2ad25, 0x34b3082c, - 0x6c86ff41, 0xa01323df, 0x6cd630de, 0x57d74171, 0x1dbe9605, 0xd1d1cfc7, - 0x38730d3a, 0x323c36dd, 0x057a8dda, 0x7af3cff4, 0x1e593fa8, 0x0d9cf0c6, - 0x6884b68d, 0x2297cba0, 0x61b3a3ec, 0x4e24a3ff, 0xd0c90dd7, 0xa136e50e, - 0x387dc164, 0x6fbe78df, 0x17b082df, 0xfa2cc2f7, 0xd0591034, 0xb195727e, - 0x42a5e509, 0x73a57797, 0x75c63779, 0xc9c2076a, 0xd4659d35, 0x937ffcc2, - 0xbb814be9, 0x556c6360, 0x0afe1fb4, 0x70c8c59d, 0x7a735617, 0xe5974d73, - 0xd7733562, 0xe65f080b, 0x96f8070b, 0x42414169, 0xadd93469, 0xe5faefb8, - 0xf7091780, 0x527fe1cf, 0x619ee564, 0x2847e7f8, 0x4c88f32c, 0x328fe404, - 0x0ca3f9c6, 0x6fe908e9, 0x0051d015, 0x75df31fd, 0x65c3a751, 0x6bf1823a, - 0x70d3258d, 0x3f85cfbd, 0x89e363e4, 0x87f34a7f, 0x3656675b, 0xf40b0397, - 0x9fd899f6, 0x51148eed, 0xf130ae5f, 0x7f644ef5, 0xc5f51a36, 0x79bd5fc9, - 0x23c7961d, 0x86cb6e4a, 0x7c16dbfe, 0xfce2845d, 0x353e096f, 0x0b6fe39e, - 0xb468fffe, 0xbf56ca43, 0x43fef449, 0x192859f7, 0xaf4e5032, 0x15a67d04, - 0xb074e4b0, 0x74463ef2, 0x896ac890, 0xfd65e36e, 0x47a30c05, 0x00f37539, - 0xbcca8ed8, 0x9747fff0, 0xce896c74, 0xa2c69f5f, 0x7433ea82, 0x0bfd4109, - 0xcf41c94d, 0x171f8d6f, 0x39a67cf4, 0x3b3ea83b, 0xff505263, 0x82d32ddb, - 0x9c4e77ea, 0x8e7fd419, 0xdd504e6d, 0x1f244cc6, 0x738aea3a, 0xe1bb013f, - 0xdc92bab5, 0xe397544f, 0xd0f6aa63, 0xe805b37e, 0x5f3bdb24, 0x91ea0935, - 0x43265687, 0x11cb537d, 0xf43c4f5e, 0x66e03245, 0xf9d1cb73, 0x53dbd02a, - 0x45f43c6f, 0x6d1fd40a, 0xa7cfe2e9, 0x40a362c0, 0x39bcb6ac, 0x9af805df, - 0x8adf629b, 0xa9779af8, 0xf98a28f6, 0xbdccd7f7, 0xb942592f, 0x06746730, - 0xc53727ec, 0xbf3e10fe, 0x759ef62b, 0x1ffb0091, 0x46ab5b7d, 0x5d98bf3c, - 0xa1e915b2, 0xf3a722ff, 0x91978853, 0x96097eff, 0x8a61d903, 0x3c92bd9c, - 0x03adf854, 0x1512c6f4, 0xa54749c2, 0xe544ceb7, 0x2a78baa1, 0xd999d48f, - 0x57638012, 0xc795065d, 0x7ed42cea, 0x95226ebc, 0x546cea27, 0x4c575bbe, - 0x095d7765, 0xb2ff0a95, 0x6a0d96bd, 0x2a974224, 0x4fceb4ea, 0x63d2578f, - 0x69d92820, 0xf9d09f05, 0x39adbd4d, 0x9d75ce9b, 0x6959e909, 0x81f9da3f, - 0x9dfa0459, 0x3d11d56a, 0x9b74354f, 0x475e5675, 0x22fbb8b9, 0xbc118af3, - 0x5fb02a9f, 0xfd1b278c, 0x030ea998, 0x841b4bf5, 0xefd8597e, 0xf79404cd, - 0x16356b53, 0x509e63b4, 0xf61e9733, 0x90df146f, 0x20e31d70, 0x05d86cca, - 0x903ad518, 0x6ba07157, 0x63f439f1, 0x0f77283a, 0x4746f5f2, 0xf9472ed7, - 0x60ccba34, 0x95f2e7a9, 0x08e24be4, 0x2fee026f, 0xda86a571, 0x198f628d, - 0x9d5f60e5, 0x69d21677, 0x0ae72c81, 0x30ef5c34, 0x80bde411, 0x576dfb7c, - 0xedf3da22, 0xd02f9edc, 0xfa44ec96, 0xfe7156ae, 0xf77a3165, 0xd5475c1e, - 0xf42cf15d, 0xb44d89eb, 0xc568426c, 0x6069641f, 0x14d617b7, 0xeddca267, - 0xaf885b61, 0x13fd5ec1, 0x338fdbd2, 0x9945df81, 0xf89e6048, 0x4da6f0e2, - 0xd7adda02, 0xce5d21e7, 0x300f9ad5, 0xf65f07e0, 0xdcfbd100, 0x7a1e7348, - 0xafecbe0a, 0x7cce3d79, 0x26e78040, 0x00bf3036, 0xe9cf55ea, 0xf0049f4d, - 0x1513d3a9, 0x4b69af54, 0xc0127d30, 0x07f855a7, 0x09b747fa, 0x0ebb942a, - 0x04a72b79, 0xb7c405fb, 0x0d73f8b3, 0x0680dfdf, 0xd98bd8ed, 0xb06fa266, - 0x0fef4997, 0x9bba34cc, 0x2371bf60, 0xa057b36a, 0xce6994fd, 0xea497ec3, - 0x63f40881, 0x1555bffa, 0x19efc9bb, 0x78c9f888, 0xd33d7d3f, 0x287b5121, - 0x70e6b5dd, 0xcd26af7f, 0x50f119b0, 0x51d3af1d, 0x88b171d9, 0x92569d91, - 0x4db97686, 0xd0cbfdc3, 0xb8737bf1, 0xaf5e491e, 0xa240b921, 0x0b6cb608, - 0xc5dd4a63, 0xf8d63226, 0xbf21b08b, 0x34c9c007, 0xc83f6563, 0x41476235, - 0x1b7f505a, 0x8e7a1ff6, 0x8ff31cf6, 0xbb49794f, 0x5e4aad63, 0x2965e90f, - 0x183fa373, 0x72abc72a, 0xc0b965a3, 0x8c74fcf1, 0x9cf111be, 0xe77d0126, - 0x504cc950, 0xb2338626, 0xd75f1337, 0x773e91bb, 0xa7fd39eb, 0x2ddcbc89, - 0x309afef2, 0x577a42e6, 0xb94d87fc, 0x79b929f6, 0xe6978f34, 0x91b25a91, - 0x879813ae, 0x24ec57d6, 0x43d81fa5, 0xaa02127a, 0xd7c47481, 0x161c4954, - 0xa672279e, 0x448ce515, 0x4fb1b0fe, 0x5f77e403, 0x40aac478, 0x78e355fc, - 0xe9b8e043, 0xef194e34, 0x4fb2255c, 0x245c9047, 0x89a6723a, 0x4b562fe4, - 0xfe8088ec, 0xa0d6eb16, 0xf5c6539e, 0x14fc1c82, 0x9047f0f0, 0x087e588b, - 0xffd710f2, 0x2c43c833, 0x10f20aff, 0x3c824fdb, 0xf207d2c4, 0x063fdb10, - 0xbce58879, 0xe4568dbb, 0x69b69a9f, 0x7e20d3ec, 0x017ddb50, 0xc369def5, - 0xa64391d3, 0xe1e4dea3, 0xe1cbaf9f, 0x2def457e, 0xa0fd9f1c, 0x00ffd1bf, - 0x8a6b5cba, 0xef1eb2be, 0x1ef9b237, 0x7cb6d380, 0x27f4876e, 0x1cd2faf0, - 0x226dd535, 0xb7e38edb, 0xfaf86be5, 0x3e396229, 0x79f345b7, 0xb245d37b, - 0x9e4ea69f, 0x9e0724b6, 0x3da162db, 0xbdef5fc7, 0x8db73f81, 0x7a43ede2, - 0x253e7e56, 0xeff8a4d7, 0x652fdce9, 0xbd012764, 0xff4afcd3, 0x3e7226f7, - 0x4eefed0c, 0xc3dd8b13, 0x992de3c0, 0xd02f896f, 0x483e469e, 0x6a8be00e, - 0x4285f133, 0x55fd0a87, 0xa73872e5, 0x073a6569, 0x43f042dd, 0x3a72831d, - 0x25f64f4e, 0xe0c6c5c0, 0x9905bb3c, 0x01f9425f, 0x0a07d44a, 0xa07c283f, - 0xf0227bd0, 0x3fed1099, 0xf421cdc7, 0xca8f94aa, 0x358ee8e7, 0xdaf09cfe, - 0xdfa136a1, 0x87cc3377, 0xc1c513e3, 0xfe46ef77, 0xd19a358c, 0xc87c2cf5, - 0x1c9c3b50, 0xc2effaeb, 0x570b9143, 0x7065c780, 0x5ff2f0d0, 0x39c90385, - 0xbf48e394, 0xfdadc8c3, 0x5db2d139, 0x44f7e9ce, 0xd21f6d8e, 0x57a0bf51, - 0xafd0dfa1, 0xd9dac367, 0x7f39f2db, 0x05547428, 0x89eb103a, 0xcbd4ce78, - 0x9e729ee5, 0x632e73a1, 0xc2d2ff24, 0x9e287b78, 0xc8057395, 0x0139c3bf, - 0xb8c61ff1, 0xd81d717d, 0x4d4fe817, 0x3ed335c9, 0x567e47fa, 0xcff995b6, - 0x6f0e477f, 0x88944a7f, 0x32fd141e, 0x8b482ed4, 0xe90664e6, 0x3f42661d, - 0xfc4b53af, 0xe67f05ee, 0x3e871825, 0x3fe49b21, 0x71e320bf, 0x1158fe70, - 0xafbebbed, 0x63d42e0d, 0x4e06a37d, 0x6fbe300a, 0x6436183b, 0x136ed897, - 0x07deef40, 0xd4f5063a, 0x2c7b9005, 0x7273b19d, 0x73cfa11c, 0x73fa24f1, - 0xa6243b35, 0x3b4a5003, 0xf4879abe, 0x6d53b4b4, 0xf6d0b8a2, 0x3d218ec7, - 0xcc156e9e, 0xb5f49768, 0xbfa1f1c2, 0xd6e8c1b3, 0xa822ff43, 0x0665ff63, - 0xd7ccdb8d, 0x4383f8a3, 0x7d53ef5e, 0x85c60a75, 0x1350ec66, 0x2f3e97dc, - 0x3b3ed1b9, 0x0aa57dbc, 0x02dda7eb, 0x4571838b, 0x04aeead2, 0x2d3e57a8, - 0xce30b458, 0x8b3a2861, 0xe7ca82f1, 0xf30bc599, 0xc918b657, 0xa0da5dcf, - 0x6017d8fe, 0xb7bb945f, 0x29eed06a, 0x5edc19df, 0x0eb83bb9, 0xeff922f8, - 0x00f68668, 0x8e6dfcf9, 0xcdec8631, 0xed1b2c71, 0xe3c0d64d, 0xbf7c8ab9, - 0x71756edc, 0xcb82ba39, 0x8cbec66d, 0xea5f7f45, 0x63e92afc, 0x91cfaf03, - 0xfea0a7eb, 0x2f1c57f9, 0xe5aa5c0a, 0x604f3fb5, 0xb79c0f56, 0x426f53ba, - 0xfdbabfff, 0xb71811ef, 0x51f309af, 0x22bd9f7c, 0xdbded099, 0x10b926d8, - 0xfd0ecebe, 0x56e0112e, 0x8d3de07d, 0x5f7088d9, 0xadcaf64e, 0xe31eb5cc, - 0x64515edc, 0xdd4744dd, 0xb666a714, 0x4f38a581, 0x84debb5f, 0x2bf54076, - 0x8ddd741f, 0xd30203f5, 0xfb471e23, 0xee964e88, 0x2da58640, 0xfbe426dd, - 0xbc4244e9, 0x913d9e22, 0x8865af84, 0xe033c477, 0x212cf11d, 0x51bc713e, - 0x2274e6e3, 0x73f4fd51, 0xde0abf1c, 0x1acda48b, 0xe46caf6c, 0x63b19e78, - 0xa230b6cf, 0xe9933503, 0x7a7ef080, 0xa6bbc727, 0x14669d73, 0x08636fd2, - 0x876bb41d, 0x77f700e8, 0xe0841d19, 0x8df002bf, 0x0e942072, 0x93dff142, - 0xd806e5c3, 0x429fa7df, 0x7e08dbfb, 0x23c7f301, 0x1ef55646, 0xcaf5818d, - 0x973bcfa2, 0xf8d8fb43, 0x08da5897, 0xe4157f8a, 0xe66bfc62, 0x5d10eb3b, - 0xc85eb33d, 0x57a97a46, 0x813cf6fb, 0x70a88b71, 0x27f4e38a, 0x32f9d9cf, - 0xfa20bb9c, 0xd816a49b, 0x5a6bcd7f, 0xc928deba, 0x35ec8715, 0xf129978c, - 0xc533c074, 0x5a1d9cc9, 0x2d6b171e, 0x73fa05b4, 0x5cfc09fd, 0xb2819a85, - 0xc017e8e5, 0x608eb87c, 0x555e7ee3, 0x28178f07, 0x1295597e, 0x8e0e6837, - 0x77a6081b, 0x2e455fa8, 0xc6a55f8f, 0x3b466cdd, 0xb3017ebc, 0x4d5ea587, - 0xcc78f03f, 0x74dfb2d3, 0x0af1fb45, 0x1bb1427a, 0x6e382b99, 0x65a9c8a1, - 0x8f1ef913, 0x6ab8e2fe, 0x76fdc604, 0x8a8f840b, 0x704f900e, 0xdab70ade, - 0xf802166d, 0x19ffee49, 0xedc01bd2, 0xa0f6ab8c, 0x19dd2128, 0x990ebf68, - 0x8e91ab3e, 0xd695bce0, 0x9cf02237, 0x38ae590e, 0x7f148dda, 0x8a5b64ab, - 0x612aee90, 0xf430ef3d, 0x0b5cf954, 0xa2d729f9, 0xaccec527, 0xb7ee0d6e, - 0xce487731, 0xe01eff8c, 0x396401bb, 0x992e7bd7, 0xf12332fe, 0x99906fde, - 0x879f9123, 0xedc09ff4, 0x5cfe4537, 0x3c581dbf, 0x6e71de60, 0xac05531d, - 0xa673e37f, 0x4f78faa0, 0x9bff507c, 0xcf41ccda, 0x4119bdb3, 0x598f73cf, - 0xdd79ea82, 0x4ffa8313, 0x5416d0f8, 0x0e2be49f, 0x4ce53fea, 0x307d5049, - 0x9573ce13, 0xe35bc1fb, 0x33fea085, 0xf9a0facd, 0x05446767, 0x320d07d5, - 0x52bb647c, 0xce5f77b1, 0x686ef6e5, 0x76f7c0a9, 0x8a3af04b, 0xc4e77ebf, - 0xd8e6f5e0, 0xa1fbd782, 0xfa0bd978, 0xc27e0554, 0xb15fa073, 0x13f81dfc, - 0x9a13f02a, 0xfac09fc1, 0x604fe08b, 0x027f01e9, 0x7f025fdb, 0xe0adeb02, - 0x20fd604f, 0x6f583ff8, 0xf2a62bab, 0x6a12ba95, 0xbafc16bf, 0xc98f75e4, - 0xd7971eeb, 0x74e177fd, 0x5def9e42, 0x9c6ebe79, 0xdcffcd2f, 0xbc563c59, - 0x2d3cfc04, 0x87c6acfa, 0x5f0ac37e, 0x062dc611, 0xc61892de, 0x7ddd99a5, - 0xf5062eac, 0x338a08d9, 0xb78192b3, 0x7d52ae31, 0xc9b4d520, 0x0fecfa8c, - 0xbef3e2ef, 0x7c8cc956, 0xefeda879, 0x85cf3811, 0x5f74614b, 0xef107a4a, - 0x5461bf1b, 0x31cf04df, 0x05b33a0e, 0x37e90804, 0x0bb7e90f, 0x4ddd4a69, - 0xcd25bdf7, 0x53c41a2d, 0x3c29f215, 0x0ea3cb7f, 0x635cfe7e, 0xf61373d0, - 0xe54ab287, 0xb9c238a6, 0x2f3e6536, 0xf1a477f5, 0xcf73cf7b, 0x053f5e1d, - 0xe2cb6ff5, 0x5e7f7811, 0xec5efcd5, 0xc7c157bd, 0xc85f07e7, 0x76cafba4, - 0x9fe0cf98, 0x96aed9cf, 0x8eff7ceb, 0x68a296b4, 0x02cd1c54, 0x05c50b1b, - 0x5fee85b6, 0x38f6daaa, 0x65556e50, 0x0066addc, 0x248f7e9f, 0xbdf837c7, - 0xb8c4c391, 0x22f9e71d, 0x5f57ef02, 0xc3bd1cf7, 0x38edf886, 0xf6eb811c, - 0xfe414ab7, 0xb72b68d3, 0x355b478f, 0xad0bbf84, 0x5ef02387, 0x30e7a377, - 0x4bcabb87, 0xd7243fe7, 0x7824a1fb, 0xfe7449b7, 0xd0624b8a, 0x5586763d, - 0xb66679a2, 0xb9e2358d, 0xbd7c3c7a, 0xb799ab1c, 0x825e2da7, 0xbf1e3ffb, - 0x7b224f20, 0xca350410, 0xef661bf1, 0xcaa43b41, 0xf386d923, 0x79e40aef, - 0x4e9cd4bb, 0xdfdb4adf, 0x78f8f285, 0xd26c88f1, 0x699f8a11, 0x916f76e5, - 0x7a869ec6, 0x3660c7a4, 0x583f9d22, 0xfc446a9c, 0xdb12c21e, 0xec69778b, - 0xe6c7bc06, 0xba98f5eb, 0x7aee9023, 0xb425735a, 0xf2f99477, 0xe88775e5, - 0x2e6f087b, 0xbbb953c2, 0xf8f380d1, 0x73dbc7f1, 0x7fea26ac, 0x3cdefddc, - 0x327aabb4, 0xe92ec9c2, 0xa7f230d2, 0x5db99aab, 0xd891d3dc, 0x924f7818, - 0xf2fd9563, 0xdaf0910c, 0xfb96a6d7, 0x0587bddd, 0x39d353f5, 0xde0eec2f, - 0xea7dc98f, 0x1dc7b451, 0xf50c4b4f, 0x1b5d43a2, 0x6cffe78b, 0xcafef067, - 0xd43b3865, 0x00d8d8de, 0x0fb4757a, 0xe8818df1, 0x13e15dbc, 0xc153e133, - 0xb7064f63, 0xf9e27ae7, 0x65a3a4bd, 0xe5f5d10f, 0x64eea4f1, 0x7f121ff4, - 0xe778a3a9, 0xc567fcb5, 0xaff0086e, 0xea8bfa18, 0x313cd4e2, 0xbc1f6fc5, - 0xb6ab6b96, 0xabbf448e, 0x1ecafc84, 0xac2cf606, 0x3a7b44e9, 0xb61ff292, - 0xad83bae1, 0x76bfba6a, 0x7d66daea, 0xa0d97602, 0xf6051805, 0x2d53b83d, - 0x0cd97bdf, 0x952ed768, 0xcccfdaed, 0xf4097cf6, 0x488d73af, 0x866473e7, - 0x27d31f91, 0x5bcfbdcb, 0xbb24ef92, 0x426498e1, 0x8786687f, 0x668ec1db, - 0x7b56d76e, 0x2a63ff92, 0x6acdedda, 0x8a60d4cc, 0xed94e21d, 0xddb2d390, - 0x80cd7a7b, 0x4e9bfc86, 0x8c963d81, 0xbb5b2a79, 0x33b9e112, 0xb3d91673, - 0xec99a94e, 0x83db6589, 0x6fb007ed, 0xcf55ea82, 0x7217da85, 0xdc13cb7c, - 0xdb87f8ae, 0xc67643ac, 0x0a67f438, 0xc871a9a5, 0x78c82f0f, 0x959bfc55, - 0xb7942de3, 0x9e6551b3, 0x1021c4a5, 0xfb9d355e, 0x6edf702b, 0xfc859847, - 0x10af558d, 0xe4bffb5c, 0x3c7f4c7e, 0x33f47823, 0x36fedf0e, 0x6a35e74e, - 0x48f98dc1, 0x34b64035, 0xaf704e9f, 0x6bb338c1, 0x13e48230, 0x17c8c563, - 0x7f70162b, 0x5f3186d5, 0x7e156b28, 0xb7abd108, 0x54527ca8, 0xb3689c80, - 0x02bf50a6, 0x3ea3b30d, 0x90b4695b, 0xe3a31b7e, 0x6ae17a76, 0xc3d2364f, - 0xb5c7f018, 0x31f8f101, 0xfb010186, 0xc7807eed, 0xc27895ff, 0x1d49951c, - 0x191fa015, 0x95fd435b, 0xf0a241f9, 0xdf9ad7f1, 0xfc1bf304, 0x23bc03f3, - 0x585fde11, 0x93b7a42d, 0xfff728e6, 0xca97c4b5, 0xbd002e79, 0x63181c61, - 0xc7378834, 0x9fc837ce, 0xf5eeb273, 0x8228ae38, 0xf708a3ef, 0x5e30f583, - 0xe79651fe, 0xbcbc79b1, 0xf9152e4d, 0x7b6790d5, 0x95f50adf, 0x593ff679, - 0x8899ae49, 0xb4ca573e, 0x9c4cf602, 0xbbf9186f, 0xf0891de2, 0x03f005fa, - 0x5ac2fbf2, 0x64169cc1, 0xaf3a712f, 0x3cec4de1, 0x454ef4f3, 0xdd6cb838, - 0xc6d79819, 0x5a2d7f38, 0x05a737a5, 0xbd2007de, 0x0251ffa3, 0x2fd1f2ff, - 0x5372bfe3, 0x57946dc5, 0x8cd62ab5, 0xc83517f7, 0xa6d7290f, 0x87ba50ff, - 0xb7a44edf, 0xa0b5a66a, 0x0b69a97e, 0xa1516e7d, 0x084dfe3d, 0x74c9245f, - 0xe81768da, 0x5bf1bd7e, 0x95a38f15, 0xbb37140a, 0x4e911a0b, 0xcafd87e9, - 0x7e71b9a7, 0xfba0b3cc, 0x391886ae, 0xee862bef, 0x9f227ee1, 0xf7952eff, - 0xa3efe40d, 0xc6324f6a, 0xf93a8e71, 0xe602d53d, 0x52dd7ba1, 0x6f654dd6, - 0x2f01f578, 0x8d1aee4d, 0x7607f87e, 0x1a91c52d, 0x511936d7, 0xb5b166ce, - 0x031fbc26, 0xfbee7936, 0x1bdb2bdc, 0x9468f7a1, 0xc7e7959f, 0x92bccaf3, - 0x83a03cf8, 0xf8a38033, 0x57c7cb9c, 0x02207fbd, 0xfefe7ee1, 0xca7ef3fd, - 0xb9020fd0, 0xd654f305, 0xbdd064b6, 0x67758b8c, 0xabf1fbe4, 0x1fc153e0, - 0xf08399b4, 0x0eb9670a, 0x0d9f33e0, 0xd36e63e4, 0xc0a9f0b5, 0xf03d4939, - 0xe8250463, 0xa1439231, 0x5ee05678, 0x3cd56acd, 0xeefb56fe, 0xb3ffe802, - 0xed19a2b5, 0x7ef0cbca, 0xf578fc0d, 0x28d791fc, 0x257b3f90, 0x5a78297c, - 0xff54bcc8, 0xfb8f8a30, 0xf144a170, 0x7c69ffc3, 0x4bd9e435, 0xb7c2aef2, - 0x257a7ca1, 0x2ab45cbe, 0xf8437f84, 0x2d2f8874, 0x7f002ff0, 0xc41155f6, - 0x1d7e0a8f, 0x5193f066, 0x2d1875ff, 0x3e39766e, 0xfdc5dfd1, 0xec0ab654, - 0xf087e149, 0xe3fc8fab, 0xad017c50, 0x541f50d8, 0xa9f305e7, 0xc92bc782, - 0x7dee452d, 0x4d47bcc4, 0x7067dd02, 0x9685fe3e, 0xfb94e9f2, 0xe2dee50c, - 0x6fae3cd1, 0xc08fcb42, 0xa27bc16e, 0x233d194d, 0xd5ebded1, 0x7bf0f328, - 0x74d68fd7, 0xcd7cc68f, 0xb2f1a68f, 0x4cf3c357, 0x8c2dba94, 0x4a3f03c7, - 0x6e10bad0, 0xa6e3091f, 0x91f01da3, 0x783bcbf0, 0xc6634e3d, 0xe9b882fa, - 0xaaf7a826, 0x83e1f895, 0x5376fcb2, 0x0982d1f9, 0x604fd405, 0x661e1047, - 0x3ad09581, 0x0c5d1082, 0xe7e8f9fb, 0x5ef07363, 0x03ff3940, 0xf48e3c79, - 0x431cf91b, 0x095ff6f1, 0x045f6f14, 0xf784c3aa, 0x289fd302, 0x93f6814e, - 0xa6cd4ebf, 0xc115cafb, 0x4dfea3eb, 0x56e538a6, 0x4b96e79a, 0x99c5ea03, - 0xe90d7dfe, 0xbc8b82cd, 0xa0d8c97d, 0xf45b667c, 0xbb27ee38, 0x8f512353, - 0xf06d7a29, 0x60437ed8, 0x1cacf51c, 0x8faa1e77, 0x5029247b, 0xf7b1be2f, - 0xa79c74e1, 0xb2cae35c, 0xf98f3018, 0x1fb424a9, 0x943ef7ca, 0xdeed764e, - 0x9fe8e98d, 0x9c3d3794, 0xb87aa36e, 0x1523fc9d, 0x7df9f73f, 0x0a6d7693, - 0x9d6fa3b0, 0x52fbedc0, 0x68851bdd, 0xf1bacedf, 0xb71875f3, 0x816bfb1f, - 0x590b70e2, 0xb7d43af7, 0xaf9c1965, 0xe48e8358, 0xf747cc3f, 0xddc67ba4, - 0xfee51bbe, 0xabbf8cf1, 0xcdfea097, 0x657cd153, 0x0e39bdcc, 0x041b6fe3, - 0xfbf9bf8a, 0xd77ba68f, 0x4d056bc5, 0x51ea0c7c, 0xc7fd779e, 0xe38228bc, - 0xbbb21b3d, 0x356cbdb0, 0x75a59f6f, 0x3ce0f6b7, 0xcf28684f, 0x4a65140a, - 0xf63dc049, 0x3df8f31f, 0x72cda2dd, 0xcebcb1be, 0x8db16dd8, 0xa3fce781, - 0xfe567f8c, 0x3b83c901, 0xb6dcbc65, 0xf123bdfa, 0xdaa46f30, 0x2b9467fe, - 0x3a7e3eef, 0x4159e50d, 0xa44cd9f4, 0xfb1ab1f3, 0xee781593, 0x2bc52d26, - 0x528959ad, 0xb9cff41c, 0x5863da7f, 0xf8bd5a2e, 0xfb8c0ac9, 0x1f91d76e, - 0x856feca6, 0x5fd11660, 0xd3f8dc3d, 0x676e107b, 0xa479e71e, 0x8faf1a2b, - 0xe2fe5abb, 0x1f3c75b3, 0x1d3af9fc, 0x99d42f95, 0xb88e1998, 0xea9e2eaf, - 0x5333afbf, 0xfa73e6c9, 0xaea6f252, 0xa5ee5f34, 0xb65bca30, 0x1e51d06e, - 0xf6d6ae7d, 0x6bc01e55, 0xa6ce0dec, 0xc6b9f28d, 0x576cf8c2, 0x83840cf2, - 0x2ef2e375, 0xe54f6134, 0xedeaff71, 0x64490d9e, 0xf53eaf87, 0xcf3c054c, - 0x0ef92fcc, 0x5e76ebc7, 0xe1c178a4, 0x10ca87f6, 0x5a4de5de, 0xdcf93e7e, - 0x8f4f1e67, 0xbce3127b, 0x7fc9a96f, 0xea79d9af, 0xde508d99, 0x26b979bb, - 0xe87fde90, 0xf795bf79, 0xbabe2d73, 0x75fe1c12, 0x89387abe, 0xf809a7f8, - 0xe7dff32a, 0x6bd59aab, 0xf3737e08, 0xc3e6c64b, 0x5da8cffe, 0x674fc849, - 0x744cddc6, 0x0814eaee, 0x571c8afe, 0xf3e6a7c6, 0xd12ae8fb, 0x48ec99b3, - 0x057f8e59, 0xf7c2239e, 0xd2cff68d, 0xaafe8ed1, 0xcf55c16d, 0x3d0eb07d, - 0xe99b8c22, 0x9e7d0ca8, 0x62a7b1af, 0xc8be715e, 0xe7d0e7ed, 0x712be7b7, - 0xc5b71e78, 0xa790109f, 0x458d84e2, 0x13fea346, 0x972061bc, 0x9eb76d9d, - 0x06ffa155, 0xc1c7e17e, 0x38fb2876, 0x695faf40, 0xab2ad7bf, 0x5f951e71, - 0x50f84eee, 0x3d00de64, 0xc617c93e, 0x0eeb01bc, 0xa6d02bf9, 0x049efba1, - 0x37880b92, 0x6bea87cc, 0xf584d71f, 0xc78e1ab3, 0x97e083be, 0x930cb8f1, - 0x3ce7fdf2, 0x0b3e7edb, 0x79e86ce5, 0x4f395fab, 0x7b68e1f4, 0xe740a2e8, - 0x9556799f, 0xbff3ed75, 0x167cf7b1, 0xdaacefe2, 0x57fe8f97, 0x8597c69f, - 0x957ea878, 0x157ff3cb, 0xc57b4a0e, 0x138f0d06, 0x23f2260a, 0x140ba50b, - 0xc63be807, 0xedd500e3, 0x0e9e48bb, 0x4c78f076, 0x145dd88d, 0xda8bf187, - 0xcf285d53, 0x5fb9e306, 0x28dbf306, 0xd65521cf, 0xa481aa83, 0x1ed72039, - 0xee07a219, 0xfe419e0f, 0x1e3ce0d5, 0x6561e507, 0x2bb43385, 0x433f21ce, - 0xe4aad97b, 0x67e748f5, 0x507323dc, 0xf59dbe3e, 0xdf8a6a8f, 0x926e1ebd, - 0x30958ec8, 0x4e0878c7, 0x4b70e743, 0x2987d13c, 0xb3387176, 0xd1abf405, - 0xbf24ef98, 0x9fbf38fa, 0xf381b9ab, 0xf3857b13, 0x1bed7393, 0xf980f89a, - 0x93f3257e, 0x7ace4f62, 0x97c41ffd, 0x9edae70f, 0x470cbe40, 0xc5f38859, - 0xb51e5247, 0x72871ef2, 0x90e8691f, 0x8962f8fd, 0x49b4d79e, 0x58e5ef0c, - 0x0af291bc, 0xca16d98a, 0x3cc59cb7, 0x8f5e7953, 0xf029d1ef, 0x52ebf67c, - 0x81a1e62e, 0xdbf74d3d, 0x34f66145, 0x15ead3cc, 0x1eae1905, 0x7d009ceb, - 0xf73e7ef6, 0x024aa757, 0x8481b1e9, 0x6653b270, 0xe29677ce, 0x5a7e957e, - 0x9833eb91, 0xe62cec87, 0x7bc2c81e, 0xc81de655, 0xa556fbc2, 0xc3d7bcdf, - 0x322f496b, 0xc05e758f, 0x79f3a73a, 0xbc0bf3bc, 0x5279071f, 0x16c3df23, - 0x436edf4a, 0x27456b7f, 0x15ec7fbf, 0x3cc03f93, 0x19c01733, 0xf01e7af1, - 0x63fd436a, 0xf21b3667, 0x6e91f8cf, 0x7d9a9fe4, 0xbd7cc302, 0x136d76ea, - 0xd5aa85c6, 0xe7a458be, 0x6bef6d8d, 0xf06b9e90, 0x8e3c765e, 0xdcbc7267, - 0x35bf7944, 0xf5efc626, 0x00ffaeda, 0x63ce76e3, 0x553a8b5c, 0x003c51ef, - 0x57ae36e5, 0xfe42dad5, 0xc97983bf, 0x073477ff, 0x3c60cdd3, 0xf287e78f, - 0x737ce9c9, 0xdccc7f10, 0x1e63f9ce, 0x681b73e6, 0x675fc538, 0x5d91c7c6, - 0xf1c71fe2, 0xafce9360, 0x3fa63b43, 0xfc7ca045, 0x5ad730fe, 0xe95c8fb4, - 0x7fe9aedc, 0xbd2b05ed, 0x5b73a3f7, 0x3cf98c7f, 0x733bddb2, 0x149556c3, - 0x1d999fb0, 0x1fd8de3c, 0x120fcac6, 0x21d7edde, 0x25b97c3e, 0xbe31f267, - 0x777819a3, 0x4483c60a, 0x3d0d1f1e, 0x6b8e5d87, 0xfdfc671c, 0xb3df6528, - 0x3cb91313, 0xa3a26e63, 0x5bbf392e, 0xc651d7c9, 0x504132df, 0x9fb8d1ee, - 0xfaae5824, 0xd7de1a5e, 0xde2b9e60, 0x3bf960d7, 0xef161f39, 0xa2feb06b, - 0xf78b0f9c, 0xf78ed835, 0x956f5835, 0xbef161f3, 0x5f78eb06, 0x722be583, - 0xdc71ec3e, 0x6df1e52a, 0xa2e90a7c, 0x946d790b, 0x1d1bdebf, 0xdc151f52, - 0x085a37bf, 0xa8128fae, 0xc6c269bf, 0x78ff30a7, 0xc52f9293, 0xc3b446cc, - 0xfbf9c22a, 0x7b06a91a, 0xf3f404ec, 0x45ed778b, 0x9bf81e7f, 0x882b9fde, - 0xef4a505e, 0x1968c497, 0x27dba3ca, 0x804f47d8, 0xcd8ec7f1, 0x724adb48, - 0xecf74f52, 0x31bb3fbd, 0x6f7ae292, 0x25824c49, 0xaee465a7, 0x9a7d42b5, - 0x85fa2041, 0x512a6ef9, 0x67984cfc, 0xab62c746, 0x1307cb8a, 0x9285cbda, - 0xb3ae0963, 0x8b9f4122, 0xd588f872, 0x51fb819e, 0x6a345de0, 0x45da1a59, - 0x07f36a5d, 0xbd759f18, 0x57e866a3, 0xa53c7129, 0x69d693df, 0x99bfb8f9, - 0x736ba919, 0x36607e70, 0x0d367794, 0xd9fdc66b, 0x9ea170c4, 0x855997e4, - 0x027f20f2, 0x66e99ba7, 0x357b1f6e, 0xfa345566, 0x62d361f5, 0x4bb75ef0, - 0x1931f3c6, 0x3c65c7cf, 0x81573de3, 0x6173df8a, 0x585cf789, 0x2da3e686, - 0x4db12fcf, 0x240f7820, 0xcdb3e605, 0x0097df92, 0xd4f7a10a, 0xf31c729c, - 0x34ee594b, 0xcadc95e6, 0x9e6879c7, 0x778e392a, 0x6f7c1d5e, 0x8ff38ca8, - 0xbdce5467, 0x166bcb89, 0xbf79e1a9, 0xe61731d7, 0x397dcf15, 0x7d50e281, - 0x06a5d16e, 0x5e05cfbc, 0x5ec67947, 0x8b2efee6, 0x77337ce7, 0xabf51c7f, - 0xcea9e397, 0x7c74eee8, 0xe64fa3af, 0xf07ea52f, 0xe4979e3b, 0x81ba81cc, - 0xf3a123de, 0xa776e739, 0x4fbd4147, 0x5f488bd0, 0xbcfe26ce, 0x673fe647, - 0x7c9f3c8a, 0x24f3a61e, 0x3bfa3e21, 0xf7c24e5f, 0xbc193710, 0xf7fcb94b, - 0x66dc93a6, 0x6fcc74de, 0x4e782f3a, 0xadf1be62, 0x98a5296d, 0xed5e7f6f, - 0xb3eb0679, 0x5d78d2db, 0x0a693968, 0x93d23e7c, 0xb7c8f984, 0x6296a5b6, - 0x91f9f23e, 0x5944cf2d, 0x97eaea02, 0xcd73e24e, 0x98a56983, 0xeb5b3c9f, - 0x7487563e, 0x5f4e7bf3, 0x4e077dfa, 0xdaaa7c23, 0x7d3efdb9, 0x2f0b81df, - 0x603e7ea1, 0x7582bca4, 0xdf099213, 0x6ecfedf5, 0x6beb7a46, 0x6c3f1351, - 0x99ff7e6a, 0x2d3f50df, 0x6b665985, 0xc90c563d, 0xba1db494, 0x3b35f71b, - 0xd625f3dc, 0x89bc4f17, 0x047b31f6, 0x13a5ebe7, 0x4f914a73, 0xfbec0efb, - 0xd9b3ea05, 0xe2d86091, 0x13d05e7e, 0x8ff72a7e, 0x40b8c02b, 0x0cbbb19f, - 0x9dfeafe7, 0xec1fe796, 0x718e9b8f, 0xc09cff82, 0x6e2a31f3, 0xfa8492d8, - 0xf9e57c56, 0xf8c1bfbd, 0x74f4efe6, 0xcd1353df, 0xa94abded, 0xe1397f31, - 0xcc5ed76f, 0x5e7be95b, 0x15aff74f, 0xe2b39318, 0x2963ac7b, 0x3feaff3e, - 0x78865eff, 0xee769428, 0x772ff6c5, 0x438445eb, 0x7916c68f, 0x8f61f233, - 0x0acefc9a, 0x3bd15eb9, 0xdc27ef82, 0x8bf84457, 0xfa8492d9, 0xafc472b6, - 0xcf7dc0ee, 0x833cb696, 0x567b0f7e, 0x670e774b, 0xc1b8079f, 0xd47bb3b8, - 0xfb034998, 0x5e90aa30, 0xca5b0bce, 0xf7f9c49e, 0xf5e77ef0, 0xae9e085b, - 0x5c33d73d, 0xd431fa0f, 0xad85e7c7, 0xf767ed41, 0x7e859b3c, 0xcddfb9e9, - 0xa154ff26, 0x2a5f8573, 0xf4836b77, 0x58824922, 0x3fca5b8c, 0x02198b93, - 0x0ee759e2, 0x927be8ee, 0x6b9fc7f9, 0x00357b56, 0x5b2d0aa3, 0x0acdf98b, - 0xde26543f, 0xabe78c5a, 0xd1d31b14, 0xf5c8a97e, 0x9c5f2195, 0x3c5d33d5, - 0xd65b7bf4, 0x6bad955b, 0x7c1da0e6, 0x45fcfda5, 0xc95f4796, 0x9b55f87c, - 0xdf781dde, 0xb5fe5a18, 0xa84f998e, 0xb585f5fc, 0x95e5b25a, 0x78d6def9, - 0x55afe81c, 0x71f97347, 0x8337fa12, 0xac93fb1c, 0x0aad16ef, 0x04eeffee, - 0xad594f9e, 0xfea3a5f1, 0x7b7fe653, 0x87db8982, 0xca3a5f2a, 0xb371d0ab, - 0xbcde5925, 0xa9bc9020, 0xd14e156c, 0xd20824fb, 0x2b3c3f58, 0xe6372e75, - 0x87870d13, 0x0f197cf8, 0x70f1e612, 0xd66caabe, 0x4f30f4db, 0x022f9855, - 0xd18725ed, 0x50768117, 0x6b122bdf, 0xa317d192, 0x5fe29fcc, 0x5653894f, - 0xfd36d478, 0x71c1eb70, 0x865e4fd0, 0x5628037f, 0x537ce44f, 0xeb4e16de, - 0x1f2f9331, 0x677cb6e9, 0xa73c38f0, 0xfb1f8029, 0x06c576da, 0xf70cebfa, - 0xa751f74d, 0xfffa6f88, 0x07bd31f9, 0xb5b2295e, 0x4e794f78, 0x4083efe0, - 0x3907de9d, 0x5677df27, 0x43086d7e, 0x95f739fa, 0x4fb8f883, 0x7b9c91f0, - 0x7246cdb1, 0x23ed4fac, 0x626bb739, 0xf947af11, 0xbd6e50ca, 0x24a7f138, - 0x7c12fa3f, 0xd29ef865, 0x2f8ea566, 0xd01d81cc, 0xe490b6d1, 0xe7896cc9, - 0x6a5db051, 0x71138f13, 0xe1932f78, 0xde86d8c4, 0xd443f23a, 0x3a97b466, - 0x42f72a27, 0x25f9ff1a, 0x31f53f3f, 0xe456bef3, 0xc50372cf, 0x6abec07d, - 0xc0ed097e, 0x8c16b105, 0x4dc287a7, 0x898c5fb9, 0xe22966fe, 0x7da31de9, - 0xbc3cc4ec, 0x9f91f4cf, 0xf64ed401, 0x5a6bf57c, 0xd5fb37f2, 0x7e517b03, - 0x71f68db9, 0x0e9e0113, 0x547af74d, 0xbed41771, 0x67ed342e, 0x1c91bd21, - 0x97d6f4e1, 0x07bf8bb9, 0x4e4fdf22, 0xfa00f192, 0x7d22358c, 0x87cf1c08, - 0x409ff6db, 0x9dd7d379, 0x943a724a, 0x3db6ce9f, 0xe3728116, 0xaeefd043, - 0x87c07880, 0x7ca59f8b, 0x0798f980, 0x6b3de502, 0xf837cf83, 0x2fc98fed, - 0xda039b64, 0x821b1e91, 0x4170a1eb, 0xf106f4ba, 0x7df68b81, 0xc01bf23f, - 0x777a6aa7, 0xa861c235, 0x52ea173e, 0x4850fd40, 0x2b3fa43d, 0xfdc3f6e1, - 0xebcd1813, 0x25eded18, 0xcf1f7e3f, 0xbd07adef, 0xe103f546, 0xee2d3f74, - 0xc315bd03, 0x8bea16f5, 0x8a6e88aa, 0xd01df55f, 0x83cabdd2, 0xe1259fed, - 0x291e81f9, 0xfed5534e, 0xf7fa2c72, 0x699826eb, 0xb18fd07e, 0xa0731794, - 0x11fd163d, 0x7a21dda5, 0x0cf7e5d2, 0x287e50b2, 0x9bc94eed, 0x42e5794e, - 0x5f3e1677, 0x8719cb27, 0xeb097508, 0x10e1ce8c, 0x76b3df38, 0x287ce489, - 0xf4c956de, 0x8b21f20a, 0xe15e39f2, 0x1e4503f1, 0xe572c854, 0x7267b610, - 0xf72937fe, 0x84cf7852, 0x9c8c3f7c, 0x23815af8, 0xcef8a5ab, 0xbccd13fd, - 0x79a78f2e, 0xe789fc79, 0x3e7abded, 0xc713252b, 0x45f79599, 0xd528f2fd, - 0x0e505f2f, 0x781c93c4, 0xe70b1d50, 0xb0467caa, 0x8a90c3d4, 0xd04535d2, - 0x2d532d9d, 0x1ab8a22f, 0x2e1ae7e6, 0x1d2857df, 0xf8e44e45, 0x1fb914ad, - 0xa057b95e, 0x6a73a5fb, 0xf2076f7e, 0x580fde86, 0x08a6b056, 0x18beeff9, - 0x5fd026a7, 0x4bfcd6be, 0xcbeb821b, 0xc514d76a, 0x95e7c30d, 0x8d76b6ab, - 0x57cf9764, 0x8a2c6f61, 0xaede5f35, 0x5e9cfbec, 0xf574e7d9, 0xcc7840c8, - 0x1234535f, 0x7fba65ca, 0xdcfc1e17, 0x5eb5dae7, 0x5d2d57ca, 0xb7c4f743, - 0x8a0daa5c, 0xbe6b5eb3, 0x7ba6e60a, 0x3fed2b90, 0xde0874b4, 0x312b8c5e, - 0xc43dafe0, 0x0137c067, 0xf4cbc5eb, 0x289f143a, 0xfd063c5f, 0x3c5f6653, - 0x113e3026, 0x339be25a, 0xb88ae522, 0x2c3e04a8, 0x0f030cb3, 0x89d1ffa5, - 0x3f1ace3c, 0xa8f1d391, 0x5e3b55d9, 0xe9d71462, 0xa57bf941, 0x22fe4cf7, - 0xbf07efef, 0x9c233267, 0x9bd4ebf7, 0xdfd3fe30, 0x87c50df9, 0xe619d7fb, - 0x03077bf3, 0x5de7804b, 0x029be3f1, 0x26abc0e3, 0xdc243b71, 0x9a9dedca, - 0xe3d5f50c, 0xa1c6994b, 0x1bd912f8, 0xdf74e199, 0x05f6d7d2, 0x8efeb7e9, - 0x8bde133c, 0x0dbb75f4, 0xff356fc8, 0xa8b17ffc, 0x3e3afb87, 0xbeb4bca5, - 0x7ca33f6f, 0xde728db5, 0x3936a1e0, 0x6cdbabdf, 0xe2fef6c4, 0xbf6117bf, - 0x8fe9724d, 0x98f8f02f, 0x83f12a52, 0x3bf9ff00, 0x4c7b53d4, 0x54c51f1b, - 0x2db0ca99, 0x7fc0bf24, 0xe1bd468e, 0xe3982b8f, 0x04c38b86, 0x54d215c6, - 0x2580ae3c, 0xd2d215c6, 0xeb015c78, 0x12c05718, 0x8ed80ae3, 0x63ac0571, - 0x18eb015c, 0xc63ac057, 0xb8c4b015, 0x297fb602, 0x0fd1e7bf, 0x3dc78b82, - 0x57f7240d, 0xc0337e62, 0xbf27656f, 0x47b95abf, 0x7c617ba2, 0xdff503cf, - 0xad3b7965, 0x678ede72, 0xd607dd2b, 0x882c901c, 0xc41f7c22, 0x3bf98e95, - 0x1e314703, 0x5822d354, 0x7db198d6, 0x6363ed3e, 0xa507de47, 0x6d47bed8, - 0x4f44cd11, 0x828d9f1c, 0xd57c8f5b, 0x57e287b1, 0x949d7105, 0x2cd35fef, - 0xcebb8c30, 0xd93f72d3, 0x0e6b4129, 0x1d92abdd, 0x9376d4ed, 0x9cf552ff, - 0xef7c0e60, 0x45e266bb, 0x7dca1392, 0x88fe52f5, 0xf37a3d39, 0x6b3d2092, - 0xf85779e3, 0x29c7ec27, 0x1d9377e7, 0x2d176012, 0x6c6c7bc5, 0xf7a5be97, - 0xe0e09c4d, 0x9dae108e, 0xd1d95577, 0xb5f31eb2, 0x55fe687e, 0xdef924e1, - 0x47bf9b3a, 0x92f8fc52, 0xbd60077d, 0xb25a2dc1, 0x609f6e53, 0x1e526dbf, - 0x28d819e6, 0x53b472ee, 0x27d67e4f, 0x8a0faf5b, 0xd74a14bb, 0x8563dc51, - 0x7dfd205a, 0x3b9f6ac4, 0x4672e809, 0x6f14bdf1, 0x246f1199, 0xf0e8563e, - 0x4fc96b49, 0xe315de70, 0x0a9877f9, 0x34e7ecb5, 0xa5cf9c9f, 0x5eb0a9e0, - 0x2cf7e370, 0xbd0b3316, 0xc008b03f, 0xe5517187, 0x188b1ffb, 0xe850afcf, - 0x8156c56a, 0xbcbe8ae8, 0x84bdf010, 0x103df845, 0x6af77fd0, 0x289bfdb9, - 0xc4f27bf2, 0xe28f3c4d, 0xfca7663e, 0x7d486591, 0xd7d7e912, 0x0f6ed07c, - 0xdb892ebf, 0x9c38e6f7, 0x3571f17f, 0xc61707e5, 0x276e9edd, 0xf9405f3d, - 0x6ef78213, 0xaf1bfbe9, 0xf3833f26, 0xb9aa8e27, 0x927801dc, 0xf485d59f, - 0x3b1ef14a, 0xcaebc795, 0xbf229ca9, 0x5efa161f, 0xcbe77f43, 0xb0be382d, - 0xf84160c6, 0xc03df15f, 0xffbfabb0, 0xebf394e6, 0x5c9ec512, 0x6be3c233, - 0x51e10583, 0xef49d718, 0xf3caa589, 0xb25b9c3f, 0x8b69f109, 0x1f5c2e60, - 0x00b669ef, 0x40f08b7c, 0x3dd1c602, 0x66cf7c36, 0x513053a0, 0x7265f53e, - 0xcc3aeb74, 0x1349a953, 0x2daf184c, 0x1852db0a, 0xa517f30b, 0x7677d324, - 0x1c78da6a, 0x4e4a0fb6, 0x92dc5307, 0x62aac7c0, 0xf1cf7e31, 0x3fb5cbe8, - 0xdfcf293d, 0xb3e65b3e, 0x782f8efe, 0xe3b5f11e, 0xfbe9bbb4, 0xef4f4c1c, - 0xf60fd3af, 0xd1c6fb35, 0xe855af14, 0xae39b068, 0x45a8e909, 0xa5a513d6, - 0x8ed1a9ef, 0x37b3cc68, 0x96ca1c23, 0x4b175c5c, 0x4e3e1ce7, 0x87dfe4a6, - 0xe502c9c6, 0xde46ffed, 0x5aba89fd, 0x5baddf2a, 0x9d776545, 0xe8079e8b, - 0xbf08238b, 0x7d6f101f, 0xf130d27b, 0x4733a656, 0xbe05be92, 0x90edf1e7, - 0xbbf02af8, 0x33efc018, 0xd9eea23a, 0x8348f680, 0xcdf782c6, 0xd2bcff98, - 0xfde1f240, 0x59c6c349, 0x2819f815, 0xf4c83b2e, 0xe9878839, 0x112aa919, - 0x926dff9e, 0x44e71410, 0x2273c1be, 0x7c8960df, 0xf9f952a3, 0xa30d69e6, - 0x7da194ef, 0x40fb22e0, 0xbf5df84f, 0xd40ae406, 0x20a665ef, 0x442172b9, - 0xf32380ae, 0xac5f7a33, 0x0936cb43, 0xe9cffcfe, 0x19ca5c50, 0xb878ce46, - 0xe61d199c, 0xb3be9e79, 0xf9461d50, 0x44efc0c5, 0xf2374767, 0xac25bdbc, - 0x461dd684, 0x3e7bd0de, 0x38188ef7, 0xbff414f9, 0xd90361f7, 0x9613eb39, - 0xe477ffe6, 0x71279fcd, 0xdf813c78, 0xed5d5073, 0x059b0e7b, 0xb15d8fbc, - 0xbe236590, 0xc439ef95, 0x7bf218c1, 0x39eff5ff, 0x123c988c, 0x0ae0e7bf, - 0xdc439efa, 0x30e7be15, 0x6171b26a, 0x461cf7e0, 0x30b11e4d, 0xc60e7bf8, - 0xb29df885, 0x39efc1ff, 0xbbce4fa4, 0x370e7bfc, 0xa0ff364e, 0x3d8039ef, - 0x4fe3899b, 0x63c6d8e4, 0x3b9f2899, 0xe3e5fdf4, 0x97643df2, 0xb2c52f68, - 0xa2a5c228, 0xc56dd176, 0x73d16df2, 0x5f03b63f, 0x1578444c, 0x037d963d, - 0x5125977e, 0xf2bca1eb, 0x49b6ad27, 0xb96bff38, 0x3cf8c9b6, 0x2f5fde34, - 0x73f60f9f, 0xcd0bf60b, 0xe2e8531f, 0x0e5cc9ae, 0xa9cb93cd, 0xc7bfc3f5, - 0xbf326f3f, 0xbed6be4f, 0xe077bf61, 0xd9feca7a, 0xdc56c596, 0x4ef7ec0f, - 0xb7ec27dc, 0x88664b04, 0xf80f7a0e, 0xc9757a72, 0x2e7462fb, 0x3fb38f90, - 0x9528f6e1, 0x14772ae9, 0x1ea30dda, 0x7ee14770, 0xe80e3547, 0xdf907df1, - 0x68f406ba, 0xf576fc3f, 0x7fdb1e80, 0xdaf9e36b, 0x9f6ff3a1, 0xf491fdcc, - 0x7e3403a9, 0x4dddfc0c, 0x1440c1fe, 0xe5e96dda, 0x14ae3447, 0xf66d4f7a, - 0x93764127, 0x8c7bf899, 0x01e636dc, 0x8c3d2191, 0x1e78c1d9, 0xe90c4163, - 0xef1d4ab9, 0xfdc0f95a, 0x38d1d222, 0x803bec37, 0xaedfaefe, 0xaf7e0c1a, - 0xaae34bd7, 0x5ec025e4, 0x64ee7a0b, 0x9474bf3c, 0x5ed08f2c, 0x39d9efc4, - 0x77d08fcb, 0x0b8ec0a6, 0x79be8f99, 0x594f9430, 0xe6bfb3ad, 0x62be5333, - 0x77a5bf50, 0xfa3d66ff, 0x5ba5e5b5, 0x2f17e435, 0xa58f5969, 0x269ef1c3, - 0x197d918e, 0xcbec1fd4, 0xfb65faa0, 0xf547d90c, 0xc7d717fd, 0xd02eb30d, - 0x13a456c1, 0xaa8e0e85, 0x4fd0e33d, 0xb30cea3d, 0x3c1df7f0, 0x269a5df4, - 0x5df4bdf9, 0xcadd39ff, 0x5d3965f3, 0x3f1df8c0, 0xa9ea8e8c, 0xaf1df2bf, - 0x1c8a956b, 0x8dcefa1c, 0x5e28b986, 0x7248cb39, 0xfff646ae, 0xc89897aa, - 0xbaf8511e, 0xb539e55a, 0x18c5fb1e, 0x8a9bfe79, 0x7aabf7d1, 0xcf9451c4, - 0xcfac3f4d, 0xacfba54a, 0x178f7ad8, 0x5db81de7, 0x15b9efa0, 0x5ab97384, - 0x9e389628, 0x4447e785, 0xa7815dfe, 0x98487e51, 0x37bfc147, 0xbf972530, - 0xf8cf103f, 0xca98db77, 0x369df21c, 0xed7a1e39, 0xeff1b4ef, 0xf7e7cd92, - 0x25510d72, 0xf9f1cba5, 0xf9e81b82, 0x1f52efc1, 0x2afee2b1, 0x71b4ef94, - 0x4e61bf7b, 0x557f3d06, 0x3d41af30, 0x5d807ae1, 0x7a6d3be9, 0xef80fbe4, - 0xf887bdb3, 0xd9f7d6ba, 0x1c0fef94, 0x23c3705d, 0xbd1c397b, 0x3355ef78, - 0xafe418cb, 0x3c3117ff, 0x56c0d29e, 0x000056c0 -}; - -static const u32 tsem_int_table_data_e1h[] = { - 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x3370278a, 0x45e39c30, - 0x8381e9f0, 0x5fd32918, 0x50c0cec6, 0x4055c401, 0x3f880bbc, 0x7c3032b1, - 0xff5e2566, 0xdb042935, 0x21818248, 0x88d7881e, 0x49a83031, 0xa41dc422, - 0x03261819, 0xb150a1f9, 0x5f3a4047, 0x0f77328a, 0x80a69c16, 0x872ae629, - 0x9163a760, 0x6819c647, 0x50e54bf2, 0xf40499f9, 0xa2be340f, 0xa2ffca8e, - 0xa013a10a, 0xe4d157e2, 0x3be542bf, 0xa6bafea0, 0x4edcdd8e, 0xc35dfd32, - 0xfc01a102, 0x9847b099, 0x009847b0 -}; - -static const u32 tsem_pram_data_e1h[] = { - 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x7993331e, - 0x31e424e4, 0x1e4e1081, 0x03086820, 0xb78a8884, 0xf6301027, 0xd57876d2, - 0xaf0e2d58, 0x6b86f210, 0x7fb6bd2d, 0x78490806, 0x111fc1a8, 0x29e1d5ad, - 0x311d82f6, 0x0388b622, 0xbdabd228, 0x557c5837, 0x0bd11feb, 0x2a44908a, - 0xe5b5ef6a, 0x3ef6b5ee, 0x09939cc9, 0xafdb7b04, 0x7cfdffff, 0xc7ecee9f, - 0xf5ed7bd9, 0xfdad6bda, 0x8131c918, 0xe4230da4, 0x06fbfc22, 0x109d9221, - 0x9d37a132, 0xd72120e3, 0x66924218, 0x92ddfd2f, 0xbadc4214, 0xa349bfe2, - 0xe4febba9, 0x5f5f9a1a, 0xa4aff0ec, 0x4d1f5b4d, 0x2d096a78, 0x2fa1efbf, - 0x7cd04fc3, 0xad79ecfa, 0xce7eb4c5, 0x5d0fc924, 0x10ab1a1d, 0xd8e7ed02, - 0x520176c2, 0x9097e581, 0x927fa130, 0x45f8e8af, 0x9fe8b884, 0x37fe9724, - 0xa5b21c89, 0xd1e43e60, 0x99029ea0, 0x31364846, 0x7e6055fe, 0xf509fc36, - 0xd0677744, 0x779e75ef, 0x7fec13e5, 0xdb0a5f8e, 0xf27347e9, 0x4dc87203, - 0x6d08c6d3, 0xfb1dc749, 0xf908395d, 0xe4990cc0, 0xd8b68763, 0x0fca6ffe, - 0xd214754c, 0x080b67fe, 0x49d9f9ff, 0xcc82da36, 0x3be1eda6, 0x1a1f4e22, - 0xd99f67cc, 0xe0dfb8e8, 0x40dfdddf, 0x5fc0a7ff, 0xe5a1094b, 0x9e0c1ccb, - 0xc5d9d9e4, 0x1989ce30, 0xbf4316d7, 0x3213a673, 0x9d4d5688, 0x4490f63d, - 0x891aebf3, 0xcddb4edf, 0xcf1c0d29, 0xcbf8d981, 0xe80293a7, 0x60ee8e97, - 0xffc45f7d, 0x64ef38eb, 0xcc3fde3e, 0xfa102b1e, 0x8a97f641, 0xa0725da9, - 0x4bd153f9, 0x2d056a48, 0xee53191f, 0xd09a769f, 0xe6e9e4f2, 0x721340f6, - 0xc425211d, 0x1aea7293, 0xc91677fa, 0xad4228ba, 0xee8c0b6a, 0x4a6b0fe5, - 0x22f9fdff, 0x12fa01d0, 0x6a1fd6fb, 0xa0e9e99c, 0x7b375af8, 0xf4d08796, - 0x0f2cc0f5, 0xd9f5efe0, 0xd68f10b3, 0x676673f6, 0xfb5e0227, 0x06feef1b, - 0xfa08d03a, 0xb5b3c73d, 0xea48907e, 0x39fbf423, 0x31c3d13a, 0x9301dffd, - 0x0964254d, 0xb34d1b30, 0xd2a6d525, 0xe88d6cfa, 0x95e33891, 0x3b69b102, - 0x28994992, 0x0ff352e3, 0x2637bb61, 0x71c34ad9, 0xef0773e6, 0xb81a55c7, - 0x6fa50e67, 0x751274d6, 0x2912ba51, 0x75e2c6aa, 0x1a548a5d, 0xddc7038e, - 0x68425e1c, 0xe1c0cf7b, 0x02d86571, 0x47329fd0, 0xf5c2c40c, 0x42678003, - 0x4ca24a6f, 0x18f8e6ee, 0xfbbf72fd, 0x338f506c, 0x8e00bb8f, 0xecaa9009, - 0x0c8f0e3b, 0xb201937c, 0x43fc8296, 0xe02463c2, 0xb91eccfb, 0xe5070124, - 0x17f0a18f, 0xa42dae15, 0x1412d47b, 0x47ec56b2, 0x0324a4f4, 0xde1157bd, - 0x4f51290f, 0x42157e51, 0xd78b84ab, 0x129e6a5c, 0x35f06539, 0x193ba9f0, - 0x5e1cbfc7, 0xe518a048, 0x88d43152, 0xe307c078, 0xed4df92b, 0xbacba502, - 0x947ee5d1, 0x90218a6f, 0xe17e4333, 0x3bf457df, 0xbdccff37, 0xca91d29c, - 0xd3396b91, 0x2cdf8a8f, 0x8e92eb67, 0xc82008b5, 0x0f49b964, 0x40241210, - 0xeb6f0377, 0xbc78a2be, 0xfb5bbf04, 0xe7c86fdd, 0xc9983260, 0x053f9327, - 0x79bd07fa, 0xf0077ed3, 0x5edf3af5, 0x5d6bcc07, 0x7a825efe, 0xe8c7d38a, - 0x5daf95d7, 0x81d6ce52, 0xee808d7c, 0x9ea748c3, 0xc6a7d1f2, 0xa6767e02, - 0x748bf72a, 0x08933b7e, 0x6b75d9ea, 0xd02b7848, 0xb5e594b5, 0xb5e1696f, - 0x9d3b8e74, 0xd698bebc, 0xed06bcd3, 0x3adbbea9, 0x68870b49, 0x8d8b6b7e, - 0x85ab1fb5, 0x311f9a45, 0x8a148491, 0xc2c56d4f, 0xbe5a4e95, 0x17eaa375, - 0x34fd5eb5, 0x2d6725a2, 0xdeb2dfb4, 0xbdf00aa6, 0x3b23ad8f, 0x443849f3, - 0x39b1dfc7, 0x69239bf9, 0xf9b2143e, 0xf24fd387, 0xd945faf8, 0x022844a5, - 0x9c3a31b4, 0xae5c7921, 0xa9e50204, 0x7ecb7cbc, 0xa48ebfff, 0x5d363df0, - 0x45a0aff2, 0x4ccfd63b, 0x769e28d0, 0x3f048168, 0xc0f07f4d, 0xccefcc7c, - 0xdd00260c, 0x9f9c6e76, 0xc0f14c00, 0x461b99e6, 0xd2617b41, 0x6ce91d61, - 0x1f47ffd6, 0x00ec3a28, 0x9e994b38, 0x7e0d6a4f, 0xbcf9a253, 0x89b91249, - 0xadcf214e, 0x1fdbdc21, 0x4f5811b2, 0x8b6de8fb, 0xcdd44ebe, 0xb4eb5779, - 0x5d7f818f, 0x2009160f, 0x86353bda, 0x923741e7, 0xbeec8af0, 0xc85cefe3, - 0x5d2913ea, 0xbf2e0e80, 0x96675962, 0x4756f85a, 0x3c717079, 0x1c755ab9, - 0x897a488f, 0x578bd690, 0x62469ffa, 0xf07ae9f0, 0xe9f58128, 0x8163e78a, - 0x7ca05d27, 0x9cab830f, 0x1c1eb9ef, 0x6357caf7, 0x21b1f1e3, 0x7fa01eef, - 0x6177c522, 0x50eb0424, 0x0a24617a, 0x57c9e2fc, 0x9a0bb034, 0xc5c93109, - 0x7cfbd1a1, 0x1337201d, 0xaf583e22, 0x837e8dd7, 0x81568fc9, 0x6fe630f8, - 0xb7e4f7b4, 0xc1fb5893, 0xf87287a8, 0x697853ce, 0xcb87bb39, 0x847f4f59, - 0x732447ad, 0x4f75c21c, 0x5e7561e1, 0xc84c7d1c, 0x97cb940a, 0x817ae049, - 0xedcddea6, 0x6c06a751, 0x7900dfae, 0x910240b7, 0x134ddf38, 0x42d27ad8, - 0xe9a05d74, 0x162f44a3, 0x664b9d70, 0x2eb2d7fa, 0xbc9fd1f5, 0x16e9165d, - 0xd468df40, 0x8734803e, 0x23cd31f8, 0x92474c01, 0x26af4c56, 0x49f34c11, - 0xa405a63b, 0xaf43531b, 0x422a89f8, 0xfac4c47e, 0xa4e720c9, 0xe58b63da, - 0x3264d0bb, 0x3cce3eb2, 0x73782d9a, 0xf8ebf890, 0xe75f021d, 0xfc8aa648, - 0xf17af843, 0xe818b06e, 0xfc2854c5, 0xefccdbbb, 0x0ebe24e2, 0x693dea38, - 0xdd335780, 0xcd54548d, 0xf06d5a7c, 0x1c2444a9, 0xc41f32c7, 0xd6b8cc63, - 0xfb7356fe, 0x9c9f98c6, 0x491f23a2, 0x50cf666e, 0x71bdf438, 0x0828d1f0, - 0xab419e7c, 0x29b23adc, 0xb6494bbf, 0x6b9a5ac8, 0xe8764f74, 0x893f2f38, - 0x7ceb6747, 0xbe2af0ac, 0xa9b3c181, 0xcb0a9e07, 0xc297fa3a, 0xfea64ff3, - 0x1db24ca4, 0x86a20bd6, 0xbc56de70, 0x42def9f6, 0xd2e4fe8f, 0x57d66991, - 0x02d78a4a, 0x069f8587, 0xe37c7f68, 0xe47fea4b, 0x211bfac3, 0xa9ec2a41, - 0xe60101f9, 0x1a40ad7f, 0xc85e2913, 0xa0eda268, 0x6af5cd70, 0x698b8ecc, - 0x91f41937, 0x74c90b66, 0xee92cfbe, 0xe43ed023, 0xf41d9127, 0x6df367b3, - 0x7d695ba5, 0x63b69faa, 0x1e4005fd, 0x0b6d1dae, 0x9fd1b940, 0xf5329e4e, - 0x112efd47, 0xe836e1f0, 0xe4c3f163, 0x1fb436b1, 0x6fa27c95, 0xc75f2389, - 0x1d157cb9, 0x9eb0ea71, 0xb094cab8, 0x8ffa1b33, 0xb53e4314, 0x5d61f89a, - 0xe6cdd49f, 0x30e1c651, 0x59fa9de6, 0x6a7e0040, 0xc03b31f7, 0x3fd04855, - 0x74da3254, 0xb4dd1ff0, 0x7e42f50e, 0x50531754, 0xd83fa23f, 0x5f3d9e1f, - 0xd00bed3d, 0xb9d47d7e, 0x92be076a, 0x9fa0e9fc, 0xc8568f57, 0xf8bdfa60, - 0xfff63b3b, 0x1862a7b9, 0x47cf9989, 0x0bb1d10d, 0xa670c1a9, 0x67a618e1, - 0xed31da1b, 0xd30b786c, 0x594ae9fe, 0xebceda8e, 0xc0d7e27e, 0x3f0f101e, - 0xc00f3447, 0x5c75d51d, 0x12a21c17, 0x82802eb3, 0xd36fff06, 0xdaf0bcd8, - 0x086bc46c, 0x67d54de6, 0xe0367878, 0x9e000a5b, 0xc2223887, 0x77867cd2, - 0x01d03fc0, 0x3c8e8bca, 0x5cf102b7, 0x9e02c64d, 0x0ca4c937, 0x13e03cf4, - 0x827d89d6, 0x03800eed, 0xfe69f3f2, 0xc1fa8ffa, 0xf78659fb, 0x9e29978c, - 0x4b494e00, 0x8eadc664, 0x913b95f2, 0x27d7120b, 0xf9927abd, 0xbdf6bdd9, - 0xcf00eff6, 0xac894696, 0x68a6bc85, 0xf7b7114a, 0x15824a41, 0xdcdfc1d3, - 0x28fd3e56, 0xe2b90bd8, 0x5a648757, 0x3a5eb43e, 0x4f2311d9, 0xfd746559, - 0xb0c276a4, 0xecf2e6e5, 0x074f3990, 0xb7347f40, 0xc43e5cc5, 0x87aef5c6, - 0xad1e4078, 0xe8b65af3, 0xd3fd7157, 0xea240d55, 0x02f26396, 0x1791a7c3, - 0x423b13bc, 0x46cb7e74, 0x4c038c11, 0xb3f5b1b7, 0x7ca3be15, 0xd74f2f71, - 0x5231fa5b, 0x46dba269, 0x193d30c6, 0xddba7d6f, 0x46ce3c56, 0x4db06bfb, - 0x72a3671e, 0x042292e4, 0x5b9777ec, 0x93f9e3d1, 0x8e126dd3, 0xebb5209f, - 0xfbab8522, 0x4adfe23a, 0xee4cbef1, 0x2c7c828e, 0x21fcd62b, 0x30fe4750, - 0xd51263ca, 0x15f66261, 0x700253c1, 0x6c4a7850, 0xfb044e38, 0x0738a6e9, - 0xcc997dfb, 0x4a365dfa, 0xf6376823, 0x3655e703, 0xd80ce119, 0x34fd0904, - 0x1555974e, 0xa34df739, 0x9f554ed9, 0x2667fd05, 0x78c16705, 0x7e6fb946, - 0x1963fa29, 0x2bf4ccc3, 0x0167d477, 0x2206547f, 0x4e7f80d3, 0x926c5f7b, - 0x36b7bce9, 0xf144bf10, 0x702b9eff, 0x7357f41b, 0xb008fd7b, 0x5e06df7f, - 0x3b2a0098, 0xa5ac7a80, 0xa25fa564, 0x148972e5, 0xca3f2995, 0x25bf0f13, - 0x2a1a4017, 0x938b3886, 0x477d33d4, 0x35224bf5, 0xf5231cbd, 0xa27e218f, - 0x72d03c80, 0x60256f55, 0xdba8380f, 0xef863270, 0x1e734c94, 0x7cd8fa6c, - 0x72e37a7f, 0x27e79829, 0x09fe0387, 0x49dde9da, 0x26927fcc, 0xde000bfa, - 0xa6ffaf7b, 0xc4fcf006, 0x67f93366, 0x5a4d7f56, 0x79696ffe, 0xfee26810, - 0xd5fcb4b6, 0x80f1bcb4, 0x979c5697, 0x9432ca63, 0x24f0050b, 0xbf07f932, - 0xe41d67be, 0xcf5bf878, 0x572f58db, 0xf835bc37, 0xa720e1c3, 0xa43f831d, - 0x052d59c4, 0x3e42ff91, 0x1c28b5f0, 0x098f9992, 0x62134f78, 0x18176e52, - 0x5a9c9bf6, 0xdc947488, 0x988ea9d2, 0x8fc0ddf5, 0xc1ddfcb2, 0xf4878e1f, - 0x78ad4c6d, 0x0120a455, 0xd768d03f, 0xe018b713, 0xe234effa, 0x1fc479a9, - 0xa47338a5, 0x7a6a78b0, 0xf30a285e, 0x09fd5272, 0x233dd3eb, 0xf0c56b5f, - 0x3b0fc581, 0x3f20ad94, 0x61b68cb4, 0x7865b35c, 0xf90290e4, 0xd1406a0c, - 0x5dca677a, 0x4c6d8821, 0xe37c63cd, 0xd4f5b3f4, 0x7e8c3c35, 0xbdbfa198, - 0xad5e1f1c, 0x67b3f51c, 0x31ded9a2, 0x2b2701d6, 0xdb36f4a2, 0xa694ce51, - 0xbe82c54f, 0x9b539a7e, 0x69e51a76, 0x233fb9a4, 0xe36ed1de, 0xc96b8bf1, - 0x593768b5, 0xe1fd12e2, 0x71f86bcd, 0xdcbcd913, 0xfc1849d3, 0x5189f4e6, - 0xcfd79bc4, 0x9bd866f0, 0x9bbf3e1e, 0xfc04234a, 0xf3f89ebe, 0xeb6f0ccd, - 0x7fa28baf, 0x29ec7eb7, 0x85bd67b4, 0xce3f261d, 0xa1ca1ef8, 0x76c4fcfe, - 0x18f6a1a8, 0x23711bcb, 0x19e9a78a, 0x61ebbd69, 0xaddbb72b, 0x92275374, - 0x4763d062, 0x8315a747, 0x84b7bede, 0x3cab4ec2, 0x6297587a, 0x7ef2adf0, - 0xdf867cd4, 0x7cd8cb7b, 0xd3f47b69, 0x93989def, 0xf266e304, 0x7f11b0f8, - 0xebcbf1ee, 0x284f78cd, 0x2d85c4b4, 0x67eab77e, 0xcc4b52f4, 0x5f39abe5, - 0x57a7222b, 0xe8ce192a, 0x4f3e3035, 0x84bcf832, 0xdf3279f1, 0xd12f4837, - 0x921d010e, 0x4dff994a, 0x4df37e2c, 0x5e8c1d29, 0x00c88f37, 0xa9fefc3f, - 0x97663edd, 0x7126ba30, 0xc6efbc7e, 0x71c80211, 0x40268972, 0xc33e727d, - 0x13c53253, 0xa5c977ac, 0x4ef6efcc, 0x525db0d4, 0x0b5ba309, 0x5fe14c7c, - 0x898a7403, 0x5b4b3b1f, 0x6b7fa075, 0x741d4ef1, 0xe1c53259, 0xd4cf0a20, - 0xd81b0a52, 0x805fb49d, 0xc51853d7, 0x49525ab8, 0xfca5d870, 0x82a2427a, - 0x10f887cd, 0xe94b686c, 0x7e58253c, 0x20b26268, 0xa7ef7ed0, 0x80f1c07c, - 0x8f173c71, 0x785fdfa3, 0xfddcf512, 0xc8364df0, 0x1cebf6a9, 0x36a5279a, - 0xf707f83f, 0xf108e697, 0xbcc6e7e2, 0x2acb83fb, 0x35f812c7, 0x9572fc31, - 0x16dee3c8, 0x22475dfe, 0x57c82e6a, 0xa5f76f48, 0x830feaf5, 0x65e47aff, - 0xfecbe312, 0x87a189f4, 0xb21824dd, 0x1fd5f765, 0xdef8ce92, 0x7940179e, - 0x24ef03eb, 0x8a52afc6, 0x9136fcb9, 0x5e867fdb, 0x140792d1, 0x00a12727, - 0xd72277ae, 0x02da4f4f, 0xf054c50b, 0x4eb8c3bb, 0xae74c8b8, 0xca9f1937, - 0xe6a6ff9c, 0x4ae2bd33, 0x9776b089, 0x903aa78d, 0xa834d6df, 0xc65a1fa8, - 0x439ed5de, 0x7866b0f1, 0x73be1f93, 0xb9196b8c, 0x3cdbf68d, 0x2b70797c, - 0x30fdc00c, 0xac22bfd4, 0x8d5f8c83, 0x0e03307d, 0x61d21992, 0x7e09cc9f, - 0x2467e011, 0x24905fdb, 0xeb8fb512, 0x4795df1d, 0x6967cde1, 0x0dc19f28, - 0xb6ebc9fe, 0x6f9c2ae0, 0xa2946b7e, 0xc99bce9b, 0x42216acb, 0xebcc225c, - 0xb21e7c72, 0x9f8ebe31, 0x025df7f6, 0xe1c4d3ec, 0xdb22dddf, 0x472d59a7, - 0x7e085088, 0xf289ed1b, 0x6a6ceac9, 0xa381c797, 0xd56bf391, 0xc3f8672e, - 0x89ab7e18, 0x75f29924, 0x1fc233fb, 0x7711fac6, 0x514fb80a, 0x4358d1cd, - 0xcf00b23a, 0xf61a29ef, 0x48eb6b57, 0xe9177c83, 0x78025b4e, 0x8b8f0310, - 0x5277fd74, 0x90b8c4be, 0xd6eb607b, 0x81a7f0e5, 0x4085d10c, 0x0fa9e4cb, - 0x178e9879, 0x69e307dc, 0xd2bf2b2a, 0xf5f0e371, 0x4d7cb10b, 0x6a5957c4, - 0x147f6be5, 0x129ddaf9, 0x9fb77ac5, 0x8fc1b5f1, 0xad1f9c89, 0xbf8c687c, - 0xd6afc79e, 0x335f3e72, 0x708549a1, 0x9b51dadf, 0x2ce69e30, 0x7c015cda, - 0x25aa32de, 0x64de7c0c, 0x17df35f0, 0xdb2efea1, 0xa35ad31f, 0x72264eb0, - 0xeed456be, 0xeb7b9006, 0x38935d7c, 0xbe0534bc, 0x5f39b806, 0x93f807bf, - 0xae08ddfd, 0x076bd7c1, 0x45bad7cc, 0xfed39b6f, 0xc2d927fc, 0xf1891ed7, - 0xd7c067e7, 0xb30a4f00, 0x963edc63, 0xdfea7eca, 0x06e7e9c7, 0x6b99f989, - 0xe5ac1cb9, 0x1fb6b072, 0x223ff839, 0x9afe03f3, 0xc98b3072, 0xe5a24381, - 0x8cae9389, 0xd3b0251f, 0x9e7bc8e3, 0xe1b5fc24, 0xbc4334de, 0x27fe3c72, - 0xbe84cd30, 0xcfd234f4, 0xe4c0e744, 0x73c98f3b, 0x76be727f, 0xfe387c68, - 0xa7f46453, 0x26922ef8, 0xffbe395c, 0x7215705a, 0x43f0367e, 0xb728c582, - 0x3a667a31, 0x86a92bc0, 0xd304799e, 0x28ad79a9, 0x81be86a7, 0x2bfa0a58, - 0x3bc62b6a, 0x68ad999c, 0x98f3399f, 0x24fc31be, 0xb88d7ceb, 0x33d71378, - 0x02217949, 0x853d9feb, 0x9eaa3f70, 0xcc9951f9, 0xd5e2301f, 0x18a8fd86, - 0xbbd0d47e, 0x79a79f70, 0x97da3d78, 0x3bd637cd, 0x36c3ede2, 0xf077eefb, - 0x3ed35f4d, 0x0e5a1aeb, 0xbbc9aefd, 0xc3b3c49f, 0xfb18798c, 0x6e3e4e46, - 0xa8b51e73, 0x32df5c60, 0xc76adefc, 0xfeb26734, 0x7ae7be7a, 0xbbd1ee57, - 0x54768f2c, 0x6f9f8c6e, 0x03e0c7e9, 0xa343e885, 0xe4183710, 0x4ce7091e, - 0x3f04849a, 0x924dc7d8, 0x90729d20, 0x5aa97b1e, 0xff401689, 0x9cbc6627, - 0x3db2f685, 0xbce406b8, 0x0380abe9, 0x53aba9e2, 0x96c6f35e, 0xe6f19d9f, - 0xa56cc1b7, 0x7ee2d5df, 0xb148838e, 0xdc2763fb, 0x4b7ed1db, 0xe9c737c8, - 0x09ae149c, 0xcc13c402, 0xbf8f0ae5, 0x72e69928, 0xa45fc799, 0xe7394b14, - 0xbe34b90f, 0xeb93795e, 0x7602df15, 0x1cc4e74e, 0x713bd716, 0x30674f2b, - 0xdbc73efe, 0xc234f375, 0x535feef5, 0xf6e5251f, 0xe29befc2, 0x9922f8c7, - 0x3ebb4765, 0x2b9d852b, 0x26e7b120, 0xa26b5fe0, 0xccfc6244, 0xff9781a1, - 0x61d4f108, 0x06cabe0b, 0xea156b3c, 0xdb465861, 0xc79c6ca5, 0x28f74263, - 0x3ae6cf18, 0x02f5fb8b, 0x6a72e345, 0xdbf40b12, 0xef8521db, 0x3a52c0bd, - 0x91057b8f, 0x37c0ecbf, 0x8c29d022, 0xb1448ba9, 0x303a43de, 0xe61b089f, - 0x5187e0b9, 0x33c44bbf, 0xc61b614c, 0xf6cc7e8d, 0x7888d643, 0x03a8836e, - 0xedc9bfb4, 0x4297f82a, 0x1ae77e88, 0x40be77f8, 0xc4c8316b, 0xc608b2e0, - 0x7cedad93, 0xa039d853, 0xaffb7a3e, 0x5237df4f, 0x548f8173, 0x1ce8372c, - 0x694ef514, 0x5ff2df42, 0x12f38189, 0xdc58abc6, 0x2a5f5acd, 0xde4017e9, - 0x0bc2e5ac, 0x7e053a7f, 0x6467aaf4, 0x3ca7a3f4, 0x41bf4723, 0x045b35f3, - 0x076d53f4, 0x770fe89d, 0x51f2c23e, 0xfb43a28f, 0x8c05db73, 0xdbd9d507, - 0xe201bdef, 0x0488cf8a, 0x19708dfd, 0xe29d8bee, 0x59fb2673, 0x80079cbe, - 0x9a1cb66a, 0xec57df0b, 0x77d813b7, 0xf16e79a8, 0xf9a06fb7, 0xf464c7c5, - 0xac766a51, 0x657f6050, 0x40885849, 0xc1326bbe, 0xc4fb43f1, 0xbeda0ef0, - 0x369edbcb, 0x2bfb0dc7, 0x455da20e, 0xa7b4f6e1, 0xa9f4a6cd, 0x0d353f0c, - 0x2ddcabbe, 0x98ffc1f8, 0xa38eccf2, 0x9abbf419, 0xa73c0427, 0x45cbb550, - 0x9cba18b4, 0xdfa3136a, 0x9d33f880, 0x8bc5f827, 0xc034eb49, 0x0d8ecd7b, - 0xb713168a, 0x9230d33c, 0x7cdef668, 0x1c7413cd, 0x93ed5dfa, 0x58a61f82, - 0xe041236b, 0x9ce7ce8f, 0x30dcdb65, 0x08ca15bf, 0x59abcc0f, 0xc38b7681, - 0x7ec1f6f3, 0x8b78657a, 0x57d68d32, 0x2945b23e, 0xaaa7e18f, 0x2d10d75d, - 0x6d4e3f86, 0xd4bf4dce, 0xae867b7a, 0x54f0b15b, 0x88b7a612, 0xc4665614, - 0xc8767bec, 0x453f9c49, 0xdf06ff53, 0x18275e87, 0xef3d0ac7, 0x741abc41, - 0xbd32a65b, 0xbcedd060, 0x7528e9ca, 0xb388cd17, 0xd02f7aaf, 0x2af10ec1, - 0x1bfbd315, 0x6c6e987c, 0x9b3e90d0, 0xe1577f00, 0x7b9606be, 0x88629127, - 0xa275788b, 0x3c9f52c2, 0x21962f5d, 0xf960124e, 0x8283dbb4, 0x1bf98976, - 0x383926e9, 0xb75c820f, 0x964c4fc9, 0x49bebae8, 0x7e252e09, 0x77b4be3a, - 0x6075c972, 0xc8e705a7, 0x1d9fb0a9, 0xe8f160ac, 0xa2e40f88, 0x7ccbef89, - 0xd6f2664b, 0x7c60a194, 0x8bf7d364, 0x41eda1b6, 0x7d365e18, 0xec277cbf, - 0xe67ed1ab, 0x1aae54ca, 0xee4fda65, 0x9b49fbe5, 0x4fd4d13b, 0xa30adcda, - 0x8fd8c59f, 0x6cfd6073, 0x19bd7b9a, 0x4695b99e, 0x8fd8f53f, 0x4af36067, - 0x199263bb, 0xb1aa3b9e, 0xfddbf49f, 0x06881f68, 0xdc7690ff, 0x4eef7517, - 0xc496b71a, 0x1fe4d1f2, 0x2a1e78c3, 0x947cb155, 0x24c13138, 0xb27a494f, - 0x74a83f29, 0x6a7da9b0, 0x9f54c720, 0x85b5765e, 0xbfa8dd2f, 0x8a814f31, - 0xab38b126, 0xbd415832, 0x81d83c53, 0xbb06bbf9, 0x75dcef51, 0xb02af07d, - 0xd05600f7, 0xc12977f3, 0xbe1c6a31, 0x0812f3a1, 0x1b34cfc6, 0x32ec7da4, - 0x7939efbe, 0xde2357c8, 0xd9d7dfa7, 0xd12447ba, 0xf14a43fc, 0xadef3023, - 0x8de3b332, 0x9d824338, 0xce6bfea0, 0x8a16da2e, 0x50cb6bc1, 0x6f422fca, - 0xd0722dbf, 0x73b8fc07, 0x4a576ff5, 0xa1a6be14, 0x7a6e1e0a, 0xe1edfe5c, - 0x9b99b510, 0x00fb9687, 0xea8576ff, 0x15f1d88f, 0x8e3e7e3a, 0xdfc61bbf, - 0xd93b332b, 0x673dbe3a, 0x477c69a2, 0x7c698556, 0xa7c74287, 0xf56fb1f2, - 0x8a7c7c3b, 0x7909ebbf, 0xc7077e56, 0xe05567b7, 0xa90acdf8, 0xd09f8d30, - 0x9001fe33, 0xcdfdc39f, 0xf37ae73f, 0xcd2ab3fc, 0xfcd857f3, 0x80feae8f, - 0xf3809f8f, 0x80fe597f, 0x92ab3fcd, 0xfacedfcd, 0xdbdf19ed, 0x6157ff83, - 0x37f5affe, 0xe649dcff, 0x36ab0ff9, 0xc6cedfcf, 0x27f5637f, 0x8e377c7c, - 0x09fca6ff, 0x6ab0ff9b, 0x07b15f1c, 0xca47c0fd, 0xf07a8490, 0xa461a99f, - 0xa35d4061, 0x923a40e3, 0xc837a9c5, 0x5dc70839, 0x3eef8c09, 0xe6fca04f, - 0x24a7d5ee, 0xea90254c, 0xd3ce5acb, 0x158bbb55, 0xd0842fe6, 0x41c4585f, - 0xc45fb85d, 0xb46c8cf5, 0x78538787, 0x218bf73b, 0x78dc2fc8, 0xac5b9e23, - 0x77dc13b3, 0xfa3056a7, 0xc0f1ff1f, 0xf3b1ade8, 0x5a8ba6b2, 0x13fecb65, - 0xef38c783, 0xa6ab2454, 0xa78829fc, 0x127c3d50, 0x9e9a1ffc, 0xb478e996, - 0x83f043fc, 0x1b958aae, 0x768c2e76, 0xce9f2277, 0xfe1cbbeb, 0xf7c31253, - 0xdc053ba9, 0xc37cf847, 0xd9f40552, 0xc99756a2, 0x74e3a86f, 0x8ece7eea, - 0x79c68dfb, 0x14505bbe, 0xc1fdf909, 0xbb051d6f, 0x41e6f171, 0x276eefa6, - 0x1470d5e1, 0x79fac173, 0xff3a5543, 0xe3eccadb, 0xeb6b8c44, 0x9c1c5843, - 0x49b8810c, 0x7906db59, 0x52dccd08, 0xf9ec9b26, 0xfce6835b, 0x7ce6156d, - 0x6d961ca7, 0x112ccf60, 0xefda16c8, 0xcb65ebf7, 0x8e3600b9, 0x76e64957, - 0xbbef1b25, 0xb4198694, 0x8e90fbe8, 0xe9156283, 0xdf65573a, 0xddd4f01a, - 0xae28932d, 0xb8a91dc7, 0x454a140f, 0xb2a82dbf, 0x9de15b79, 0x00f43b2b, - 0x8fee6785, 0x15a7c444, 0x2e838efe, 0xf3ed46dd, 0x907fcd8e, 0x9d6c7e21, - 0x3bfe158f, 0xa3e75b96, 0xcc3eb02a, 0x19cb590b, 0xa9f9589f, 0x36f17f6e, - 0xf37b3db3, 0xb5fb58b6, 0x530cd76a, 0x56f8497e, 0x9bc5fb53, 0x17ea99e7, - 0xd5312eb5, 0x6a59682f, 0xfd0bcfca, 0x8efed4c8, 0xf54c2be5, 0x635fafdf, - 0x62adbfaa, 0x6b7f2983, 0xfb5321f0, 0x98b6ca5b, 0x47076dea, 0x68e4077d, - 0x9e22ebd5, 0x3ee0bdfd, 0x9bd82f75, 0xee12dc17, 0xed447e73, 0x33839015, - 0xb4815ed4, 0xf478ff73, 0x2c1ea9a7, 0xf9a24d87, 0x2d5598ca, 0x0997a099, - 0x6572cfea, 0x24d0aac2, 0xd7b0178a, 0x9b887ca9, 0x041d1215, 0x0f724cce, - 0x318b771f, 0xa9971df5, 0x7d054cdf, 0xb17adf7c, 0xdd797e23, 0xd4c379d6, - 0xaf6a7e38, 0xb02192dc, 0xce5975ce, 0xb569189f, 0xb1a73ce5, 0xeb817dbf, - 0xe9856ad9, 0x19bdea83, 0x86736193, 0xe223e5fa, 0xf9ec9b9d, 0x0db0223e, - 0x53feb048, 0x98861f81, 0x76aa6bf6, 0xfbe49ae5, 0xe11121ec, 0x409d05aa, - 0x5217eaf5, 0x72028d60, 0x35923d16, 0xa1c0346b, 0xef4055af, 0x75c54fec, - 0xe9436cfd, 0x3fafd836, 0xf4c010d3, 0x4c3286a3, 0x3104354f, 0x02a1b0fd, - 0xf50d93d3, 0x2c347698, 0x86bdf4c7, 0x36efa610, 0xbbfa60b4, 0xdf4c5686, - 0xe98cd86a, 0x4c610d1b, 0x4c741b3b, 0xd1e8790d, 0x0f6e01bf, 0x84d71b1b, - 0x2e7cc3db, 0xe73da98d, 0xf7ff70c2, 0x11f3fbbc, 0x7f9fef60, 0x6cfb8ecb, - 0xcacbe1fd, 0x51d3fd6f, 0x3ca57b47, 0x639d083c, 0x8133bd6b, 0x2369c9d1, - 0xec1c64a5, 0xcff4ecff, 0xc4bcc7cf, 0xfd84f52e, 0xfa713c33, 0xfa5d7885, - 0xf444e9e5, 0x949982ee, 0xfe1ea71e, 0xf7e822af, 0x607fac02, 0x71111c07, - 0x6dd1261d, 0x95d7a07e, 0xe1784de2, 0x2f1059f7, 0xbf83d73b, 0x8b882cf6, - 0xd8a8ab5d, 0x3b36f9ff, 0xf9d2f881, 0xcfbc2e03, 0x36d8fe75, 0x32e3c82f, - 0x3d8e189f, 0x6b4d6147, 0xb761d922, 0xe736efc9, 0xa50ab7cf, 0x689a1e78, - 0x0347b389, 0x3861a95f, 0xe0d9d20f, 0x67e8d4c3, 0x71c14f99, 0x65caecce, - 0x5e7e3371, 0x424eec83, 0x277ea57e, 0x869fffb6, 0x0c7ebfa7, 0x23690878, - 0x5e08381f, 0xdb98bb71, 0xf97efb7f, 0x814cfa49, 0x20392af8, 0x82f60e7f, - 0x1177fe9d, 0x6122651c, 0x2eb7e8de, 0x63ec8622, 0x69b77ca0, 0x669dfa3c, - 0x7317f4f8, 0xe6b7c52e, 0x042234fb, 0x9c46bf68, 0x80fe0aa4, 0x02f530f3, - 0x788cabc6, 0x6ee49749, 0xc6f4c611, 0xbc78ea4b, 0xa1d1c6b8, 0xb9d16904, - 0xee4bdcb6, 0x38699e9f, 0xaf39c2a6, 0x02ab470a, 0x64454fce, 0xb9e80954, - 0xd2ab6d73, 0x12ac1ec0, 0x2f15dfcf, 0x67679b7e, 0x6125bd71, 0x8ebcdbb9, - 0xb420fe72, 0x1d9ca35f, 0x8a9f7472, 0x31b59fc9, 0xefdadb3b, 0xf6c0fb04, - 0x1f776a2d, 0xd683769f, 0xfbb54f17, 0x3e30553f, 0x5c53112e, 0x7bdfc0c9, - 0x9d82604a, 0xd772a9e2, 0x7e8f68fb, 0xdc468724, 0xd4fd097d, 0x9f6e7e77, - 0x88727ce9, 0xf338c3b4, 0x8881f227, 0x743bcb76, 0x15f8fd3d, 0xe4db9d99, - 0xf67b80e7, 0xfebef995, 0xdf9b9e02, 0x84e78556, 0x8ff7de3e, 0x242dff68, - 0x81d22f01, 0x1d8116b4, 0x4ad88e79, 0xc8e74f01, 0x31f1de6b, 0x3a95b874, - 0x05ef404a, 0x863b662d, 0xfca6bfda, 0x7ce6cde2, 0x06999939, 0xa37ca4fa, - 0xce02c24c, 0xb37f54cf, 0x177ec55d, 0x5826fa93, 0x8fee2557, 0x348957cc, - 0x9ad5ea84, 0x34567f67, 0xb411c28f, 0x88c83f33, 0x66492cbf, 0x4a656076, - 0xc27d8158, 0x7fc6da0f, 0x832006f7, 0x7104dc3d, 0xfc489228, 0xfc5f483b, - 0x56fc295e, 0xbaf58d78, 0xc3881c4f, 0xe212ee21, 0xdad603ee, 0x86cf6e05, - 0xe7c03d30, 0xc705f86d, 0x7615f92c, 0x2452de7e, 0x9cfdd022, 0x12d908ea, - 0x851fdeb1, 0xbb5edc78, 0x7106957f, 0x7b6ac0fc, 0xdfdc6f6a, 0x0f649768, - 0xe159f962, 0xf73c72d5, 0xf00b4520, 0xef8f21de, 0xc41f9c2b, 0x9c016f04, - 0xdc40f523, 0x3a75ce1e, 0xdf215bbd, 0xf3c0a9e4, 0xef20751f, 0xbc7bbfb4, - 0x9c418ed3, 0xa35a41da, 0xbb5fe53a, 0xa01fb2cf, 0x902ef399, 0x5067d04b, - 0x09a2e780, 0x235cb9c6, 0x7e3cedcd, 0x2e31fe73, 0x4381748f, 0xdf39ee3e, - 0xe14770e6, 0x2899093c, 0xb7f1ed9d, 0x63dfc072, 0x56fdc3f0, 0xcaa77f68, - 0x7df2d7da, 0x9edf3bdd, 0x097c9e9c, 0xa5f7547d, 0xeb31c240, 0xadd49d48, - 0x7dd61f00, 0xd7f96129, 0x5d1a9bd6, 0xe6f46355, 0x59f04a2b, 0x27a604fb, - 0x8e813e01, 0x64dfbb13, 0x027087bd, 0x2f4261f8, 0x386d7c3f, 0x7f498852, - 0x8f04a7bf, 0x6be383c5, 0xd3ebeff7, 0xbbe009ff, 0xf3feb1ff, 0x11dff4fa, - 0x679afe0f, 0xd10becf7, 0x17f2b5f5, 0x10e1780f, 0x6b52c7d3, 0xacef9c1a, - 0x0bdab1de, 0x1491f972, 0x3f5d02f2, 0xef718b0e, 0x0c3ba6e7, 0x70ddd3be, - 0xf396b08f, 0xaf9f99dd, 0x2ff836fb, 0x5590ef9f, 0xb2ec0f8c, 0x2994ed47, - 0x3096db6b, 0x7f65d8f9, 0xf19be59f, 0x7edd53bc, 0x7ca8beb3, 0x0d3481fc, - 0xb885550f, 0xff451cff, 0x7ffb76a0, 0xabbb034c, 0xdea3748e, 0xe3077eb3, - 0xf68c997f, 0xb1253cc0, 0x0e71bd6f, 0xa5e38eab, 0xde1d6dae, 0xbb6baf13, - 0x9a1334f9, 0xad3bf40e, 0xbb7055df, 0x9f30e1df, 0x42f034df, 0x5feeccc2, - 0x0583c4f5, 0xceb853ef, 0x2bc57f6e, 0x29f2c7e4, 0x23e77fd3, 0xa5fb1e0b, - 0x755cbfd6, 0x6b18fd52, 0xb4eb1b5f, 0x2bfb9fb6, 0x2d5a5807, 0x0fe0bd47, - 0xf1916f56, 0x9ef57bbc, 0x861f3b6d, 0x76dbccf8, 0x7fda70ff, 0xde979ed5, - 0xabe69eb8, 0xa653929e, 0xe1b869b3, 0x9f41a29e, 0xf2dffa3a, 0xa8f4bd71, - 0x4525fa7c, 0x7fcacd1b, 0x974bdc9c, 0x290ea7aa, 0x7c5f7464, 0x521c894c, - 0x85b67ed8, 0xa7f7913e, 0xeab15f81, 0xd0142f89, 0x141f1f5f, 0x1c767a48, - 0x09796e7c, 0x13c063ed, 0xabd393d2, 0xf6967e87, 0xa82e9475, 0xb2f42d17, - 0xaf98fbb6, 0xc42fd007, 0x3f7f29e3, 0xb7d84bf9, 0x0fdd9df9, 0xf278a878, - 0x9f30bc9f, 0xe33d52d3, 0x4ead9ff3, 0x1520fb83, 0xc54d2872, 0x3c579594, - 0xbfe403fa, 0x907fc7c5, 0xeac5cec6, 0x575cfc19, 0xd173cc06, 0x9e707323, - 0x7c8824e5, 0x7633f158, 0x4482fccf, 0x238a9f4a, 0xd839f727, 0xab7a763a, - 0x4f11371d, 0xfb0242c3, 0xe189af18, 0x640f181d, 0x607f0de7, 0x65913fec, - 0x60e0bf98, 0x30e45af4, 0xa5d1f1ee, 0xb77f9624, 0x9d03b737, 0xd3d50cce, - 0x475c8e21, 0x87c710a4, 0x2bf69170, 0xce9a9f1e, 0x52681dcf, 0xea8eff11, - 0x0e5029ff, 0xdd65dbed, 0x8efa6059, 0x1deecc5c, 0x3e3e4eff, 0xec013b85, - 0xd469d3d7, 0xbf338c1e, 0x9d630e03, 0x0c5676a6, 0x3bc8c59f, 0x6bedff93, - 0xf21bbc98, 0x0a519e1f, 0x609d9ff5, 0x81df0472, 0x8ae142fd, 0xa1fd63a6, - 0x07ea02d9, 0x93c6893b, 0x9732edf3, 0x95bd7373, 0x12fc285f, 0x7c3dc7ac, - 0x2324e303, 0x2dbed01d, 0x8fbf48df, 0xae30abd5, 0x86bf6fb7, 0xfae62f1c, - 0x1f45ad60, 0x07524790, 0x2d5b7fb4, 0x0c3e7787, 0x35e54bf2, 0xcafc81a4, - 0x27c15ef8, 0xf1bc8fbb, 0x9fb72a3d, 0x35b90c44, 0xdcab55eb, 0x409dec56, - 0x27edc9e2, 0x2b893f6e, 0xae3cb4b7, 0x903bbadc, 0x7ad6ff9f, 0xd3e3c0d5, - 0x7a1a3c16, 0x5a7c3fb2, 0x1db7e4f5, 0x493d5c5a, 0x45209dff, 0xe0d1f97d, - 0x2aff8343, 0xcf06a5ff, 0xa9f0f50b, 0x7c3d87c1, 0x9f61f06a, 0x8f09a478, - 0xe1bbfad6, 0xc0853a6f, 0xcfc63273, 0xfdb00fab, 0xd1ddfa67, 0x2f888521, - 0xd239971d, 0x4a48747a, 0xc96c3e6c, 0x75ed2c47, 0x69603e4b, 0xebe4b41f, - 0xf7abed4d, 0xb9d8511f, 0x9da9a89e, 0xe4a7fcb8, 0x01f13883, 0x6baa1d63, - 0x010954fb, 0xf1bbb87f, 0x0925797b, 0xfe5e2079, 0xf2f188bc, 0x26e38a2e, - 0xeed74e3a, 0x608f7c6c, 0x57c593b5, 0x2f6ed4ba, 0x93ab93d8, 0x553bbe58, - 0x683d0269, 0x593b7794, 0xd02bafdc, 0xb18a4ded, 0x203fdeef, 0x08ef1ea2, - 0x7e78d293, 0xa140de28, 0xfd20edf8, 0x80fdb3d5, 0x61d7b02e, 0x30ac84bc, - 0xd154e3f0, 0xe21cb59d, 0xde22ad35, 0xe2b85b6b, 0x239c2f16, 0xfb903ae9, - 0xbe5a329d, 0xdb22d7e8, 0x52e90ca6, 0xf81f8c46, 0x9a6d0911, 0xf5fec024, - 0x059fe47a, 0xb85f9807, 0x797c7d70, 0x95dfe4a8, 0x4054efbb, 0xee7f52ef, - 0x87beec64, 0x23c54fd1, 0xff03f296, 0x15a6e5c8, 0xdb951fe3, 0x1e41f5cd, - 0xe4ec183f, 0x92c7bee7, 0xb77fdcb1, 0x9e0fdec5, 0xa77fe62a, 0xeba7d28c, - 0x3ce04898, 0x2203f9c1, 0x6efce7d2, 0xe3007e76, 0xbf01d7fc, 0xe7b12b77, - 0x7c82cea9, 0x1ebfd55d, 0xefccfb3b, 0x3e06ee8b, 0xc14ef7da, 0x767a694f, - 0x7e23dbdf, 0xdf67f905, 0xf4877acc, 0xa0e53f6d, 0xba55f713, 0xff907a0e, - 0x4dff9ebb, 0x7f90ddd6, 0xecf18ece, 0x145f83ae, 0xad753f00, 0x1e8057b4, - 0xefe7e2ec, 0x45ff3d56, 0xbfae0741, 0xa9c7488d, 0x9f4fe64e, 0xef5ff03f, - 0xf381fdc1, 0xc0ace807, 0x42e838be, 0xa5fbaaf9, 0x5d6fe313, 0x14517fcf, - 0xa5fc27eb, 0xfbe5a9f3, 0x521e5d9d, 0x4be017b6, 0x7544fb62, 0x1b6ebabf, - 0xd3512fbc, 0x40594876, 0xf0bca7eb, 0xafd002a7, 0xdd997b5d, 0x3c7729d4, - 0x8179fb0a, 0xca340f35, 0x209d5e94, 0xff698364, 0x0128de6b, 0x978bea39, - 0x715c613f, 0xfc58f8a0, 0x043e0d7f, 0x4f3fe99d, 0x29854c18, 0xdef8ff07, - 0x0e27a03b, 0x8d2f91da, 0x59127ef9, 0xe5ccf681, 0xfff4dde6, 0xe885bcdc, - 0x03bde640, 0xefe13de6, 0xc0d7de77, 0xbed4a1a1, 0xcf97d072, 0xf30bbf9f, - 0x847e3c7b, 0xfefc8077, 0xfcf9dfd2, 0x7bee98af, 0x97bddd29, 0x7f87f79f, - 0x9feef3e7, 0xcb9ebfee, 0x79c2aee9, 0xfe17ba98, 0xa95df084, 0xfe12939e, - 0xbfbde5be, 0xfef61bf9, 0x35bf9b5a, 0x93cf1b27, 0x70b0c03a, 0x40b6667b, - 0xc8ed7178, 0x9dd82a99, 0xd5ef3f62, 0x7e60484c, 0xf7b02895, 0x1650c821, - 0xcfdc240f, 0xf80d6382, 0xdd9b880e, 0x4ddc933b, 0xc9137768, 0xbc53aedf, - 0xbe7abdac, 0x911acf1f, 0x21056f71, 0x8fc9399f, 0xbf8b6ef1, 0x5d1028d9, - 0x74aef6a0, 0x818f37f5, 0xb48f23df, 0x9805ed45, 0x33690fbe, 0xaaca638f, - 0xdc87f262, 0x53bce6f9, 0xbcede733, 0xf061073f, 0x0c247c3b, 0xd4716cf1, - 0xd3ce1561, 0x02256389, 0x4938a54f, 0x0efc086b, 0x7dfccfbb, 0x7ee10252, - 0xc7865fef, 0xa716048a, 0xed718512, 0x9471e03a, 0x78dce30d, 0xe2f11b48, - 0x08baf7c7, 0xf17baff7, 0xf80ed4da, 0x663fc094, 0xd5fa17f6, 0x12d3fb84, - 0x691a42ef, 0x76e69dd3, 0x2cbe8fdc, 0xb25d189d, 0x969d39aa, 0xd062e899, - 0x4c7d0e21, 0x7cf03174, 0xd2b1f4a5, 0xebff8ac5, 0xf75f1813, 0x2e832f47, - 0xef1d6e99, 0x7fdcc9d7, 0x133f0128, 0x820199f2, 0x7fdcabfb, 0xbc745290, - 0x7eaa24a7, 0x7e0097bc, 0xe01a945c, 0x86deef2f, 0x3f73a4f1, 0x00dbff7f, - 0x44afd54f, 0xebf8a0e2, 0x5121eddc, 0x2b0a5ef8, 0xb6569fe0, 0x404fb889, - 0xacd168a4, 0xc3627d98, 0x85faa80f, 0xb953e707, 0x4e9e1ed7, 0xf7dcafbf, - 0x61da0141, 0xcfd1bb2b, 0x605cfd09, 0x14750f74, 0xa5703ec0, 0x2b11fcc4, - 0x6049acbf, 0xcfb396f1, 0xae20cab9, 0xe762ec23, 0xb7232b7f, 0x7398f6c8, - 0x9904a14d, 0x739e9bc5, 0x3d085ea1, 0x28f9e021, 0xdcf62f80, 0x9c87e1a9, - 0xf060427d, 0x9df197ed, 0x4f5dca98, 0xaa7c4275, 0x1fbb2df2, 0x5dbaf8cc, - 0xc87ee29f, 0xf1ec5f94, 0x2e1fa076, 0x7d12e29a, 0x44bb01e2, 0xb6da8fe4, - 0x6843f41a, 0x36a2f91e, 0x2beffdc2, 0x7eab57f4, 0xb83efcf1, 0xf4f55670, - 0x7f885ee3, 0xe1df699d, 0xaec0b8c5, 0xfae7c74b, 0x3591fff8, 0xd6ffffdc, - 0x3b4f7669, 0x067fffbe, 0xf176a0fe, 0xfb9609d3, 0xb106bbab, 0xb44914f7, - 0x71ef52e8, 0xf0b9ed55, 0xcfafc428, 0x51e4fdee, 0xcffabb80, 0xfc14787f, - 0xa9d0720a, 0xba827dc2, 0xf18ebf9f, 0xdfbbe33e, 0xf9d03d70, 0x2f18e3c4, - 0xfa9b7ced, 0xe75ff41f, 0xc0b3a7f3, 0xea7ceccf, 0x4f10698f, 0xa9f9f3b9, - 0x9dce6ef8, 0x27494ccf, 0x9189f471, 0x0786ff02, 0xd2b5af10, 0x11db48ed, - 0x51ce7ff4, 0xd9ff83ba, 0xd489d713, 0xc69978b0, 0xe3bb39e3, 0xc4fbc7c7, - 0x7d66da6f, 0x4842c6e7, 0x0646bf65, 0x4139c710, 0x006639e9, 0xe3cddc74, - 0x5d6f9175, 0x0e738e32, 0x3af4a0fe, 0x85e3a16b, 0x3d8f45b6, 0x836d750c, - 0x44e38dfa, 0x233f8007, 0x413fbefe, 0xe40122ff, 0x60bfef68, 0x37e80cfc, - 0x73b84e9d, 0xd82c85cf, 0xee48f8bf, 0x85ef8b9e, 0x21576f3c, 0xfcf9511e, - 0x9d4f289b, 0xf8c71ccf, 0xf071e136, 0x8ff3d24e, 0x99f92bc5, 0x1eedbacc, - 0x74e1ff16, 0xe690f880, 0x071e72c5, 0xc46d7c62, 0x0b8bfa87, 0x73b1718d, - 0x40bec627, 0x7877f6cd, 0x6e97a5bc, 0xd7a044c2, 0xcfdc97fb, 0x02a0f030, - 0x8d8dae1e, 0xc38fc67b, 0x2d3dc4f5, 0x427a0374, 0xae27b3bc, 0x7b13d849, - 0xcde16175, 0xcef47178, 0xda5e2c2d, 0x8f3fc729, 0xaf41c465, 0x9fe25976, - 0x3fc581e1, 0x2b8f372f, 0x9760d3c5, 0xf15afd86, 0xf8abf675, 0xae5bfdfa, - 0xe85f9d81, 0xdaad7f77, 0x3de61f7c, 0x05dd3825, 0xef6d6bfb, 0xa7cf042b, - 0x2b73b374, 0xf967be7c, 0x3fb3d3f9, 0xd62e3117, 0xfa823914, 0x8c3faadd, - 0xbc2b57fd, 0x6b787077, 0xe3f5b3f7, 0xd84f5eec, 0x7b39fb4d, 0xebe439f8, - 0x63efddda, 0xaee8ee5c, 0x988e95a7, 0x8fd616f5, 0xce7ccc70, 0x80a8793e, - 0xdfe379c5, 0x3171ab1b, 0x40eeb37b, 0x76ea71fc, 0xa71a6a7f, 0x9851142a, - 0xf1e9701d, 0x2dfa48ce, 0x7699dfd0, 0x3a4ddf19, 0xbee31113, 0xc9701c17, - 0x95a11f7c, 0x475d0fc9, 0x71c09ef1, 0xf0a77f76, 0x573c04b5, 0xd2f1e77f, - 0xb7fde077, 0x8358a93b, 0x82b6dfdd, 0x4fdb69f1, 0xef4021f4, 0x13dfe3b6, - 0x07dafd61, 0xffb18df8, 0x4fd44e8b, 0x50fd50f1, 0x10a06ef4, 0x77aad5d8, - 0x66cb7dae, 0x938e9f82, 0x2342eb0e, 0x83ee07ed, 0xbc39b9c0, 0x569dee57, - 0xaa88f00a, 0x7d0a754d, 0xf9bb21e7, 0xafde557d, 0x21ef9aac, 0x6bc6af90, - 0x266f8fd0, 0xcc664b8b, 0x9f165232, 0x87f7190c, 0xabc213ca, 0xaf7f7ce8, - 0x28bb3706, 0x8d9e7c5e, 0x78112fd9, 0x06a26a27, 0x2e63d3f6, 0x4bc1de7e, - 0x83bcecbc, 0x7aa3643b, 0xf6ff61fd, 0x9e08930d, 0x7c06d867, 0x819e73d9, - 0x2f800b44, 0xea7d768d, 0x321de72d, 0x5a2a13e1, 0x17338722, 0xfd5025ee, - 0x77866ab2, 0xf11fe42b, 0xb2cdf7b0, 0x3821f748, 0xdb8db0df, 0x1560d9a3, - 0xe77df6e7, 0x6fbeebec, 0x78a53296, 0x853f30e9, 0x535ff5d3, 0xca7c5ce1, - 0x0d4fc52d, 0x2d856951, 0xa3dc1a63, 0x78bc7949, 0xcfcd066c, 0x34f4ff5f, - 0xe2f7ffac, 0xff3459b1, 0xb20e7b93, 0xcf012afa, 0xaeb0bec1, 0xeff01a76, - 0xd9fb96d7, 0xb9663314, 0x77f0057f, 0x77eef02e, 0xae706917, 0xefe15ba2, - 0xdda00465, 0x7f0c89d0, 0x9f77ee99, 0x98657f02, 0xf00563ad, 0x7fcf63eb, - 0x16f78491, 0x2aa1fbf9, 0xdce15469, 0x789a2d15, 0xf3e712f1, 0xccfbbcfa, - 0x498dcbf5, 0x3f8177c1, 0xbc8de79a, 0xef1d1a6f, 0x0e718ae1, 0xf2d00e76, - 0x829aa34e, 0xe9c85d74, 0xcb3df84a, 0x8b3e7c45, 0x02c290c5, 0x7f5caddf, - 0x5751ef19, 0x1ef4578b, 0xdbab8735, 0x67fbefd5, 0x3378007f, 0x007f8293, - 0x3fdf59fc, 0xb815c57b, 0xe519f500, 0x5c7de25f, 0xeb333de3, 0xea4468bb, - 0xfb3efb8e, 0x5a2efe56, 0x9bfef07f, 0x69ba283b, 0x682f39ff, 0x39518f7b, - 0xf150b31b, 0x31cfd1c3, 0xd2fd0bcb, 0x0426c220, 0x1fa71076, 0xf788cf3c, - 0xb822ee1f, 0x1765db5f, 0xbbaff074, 0x7d4549fe, 0x3a70b99e, 0xae5d5ffa, - 0x339c08ec, 0xc35bbaea, 0x018a3d7d, 0xe869e401, 0xf828c481, 0x3e1e5487, - 0xe7c3c8b7, 0x8f37fe66, 0xdb5175db, 0xa9fd81df, 0xa06a3fbc, 0xed8bdcc5, - 0xee9e9912, 0x8e10d06a, 0x087424a1, 0x8e81fdd6, 0xebe6e397, 0x46cfa737, - 0x9eeb9e9b, 0xee1ff880, 0x28ffc18e, 0xcc74bf77, 0xe63a3377, 0xd1d0e3bb, - 0x7bdd6efa, 0x6858e0ae, 0x28fcba77, 0x7d675fbe, 0xdf4aceaf, 0x21f5a93a, - 0xed2b3b78, 0xfeb8a7c0, 0xb31bf418, 0x29d22c7c, 0x00939e86, 0x3e07318e, - 0x06bc01b5, 0xe7ec1f1d, 0x9ba9793c, 0xf1d673ad, 0x063acad2, 0x9fb4e307, - 0xf74cd6e5, 0x451c0a0e, 0x69ca897e, 0x87c58dba, 0xb7efb6fa, 0x9d4b9cff, - 0x59502cf3, 0x73ff14bf, 0xfe064f00, 0xfbf3756f, 0x7ff17dea, 0xf8a3b43b, - 0x3fe61dbf, 0xbbcffc00, 0xfb0dfe14, 0x87eb8abf, 0xa29fd82a, 0xda1ff47c, - 0x3a1cb4cc, 0x8dd134ee, 0x8764b072, 0xd931f7c8, 0x3e865ffb, 0xfd5d7259, - 0xb917b821, 0xf20267e4, 0xfefe42eb, 0xfdfc27e5, 0xc1b9eb4b, 0xea10b2f2, - 0x1f9fcbcb, 0xaa3ea30c, 0xff2e65da, 0xbbcf7767, 0xde785997, 0xad352417, - 0x2b4ebdf7, 0xb9bbcffe, 0xb4e858de, 0xd72f7bc5, 0xdbd68748, 0x33cce74c, - 0x83f4f4a6, 0xa6cfa0fe, 0xb8f189bd, 0xc409957f, 0xa5297413, 0x2019de10, - 0xf4094285, 0xd7e5cc5b, 0x72d86fe8, 0x1d9ffaf3, 0xcc43df32, 0x43df316d, - 0xbe6ade1c, 0x66d57887, 0x51c43df3, 0xc43df361, 0x338d766b, 0xae4747e5, - 0xb31fb537, 0x3f29b27f, 0x534dfa36, 0x66c7f1fb, 0xda13f29a, 0x7f6a67bf, - 0x4df35bed, 0x5475d7f5, 0xf86fea9a, 0x7f299968, 0x9b3ff763, 0x311747da, - 0x61b878fd, 0x5bdc1179, 0x7872f030, 0xa15362a9, 0x9b08e97c, 0x9e5b105a, - 0x90056ba6, 0x7fe0e916, 0x532f27f5, 0x8a2a3f1c, 0x898ba75d, 0x536fd26c, - 0xd47ce61c, 0x8f7dfe6d, 0x35722c97, 0xcb527ea4, 0xbc1d9a08, 0x63cf0f24, - 0xc63af953, 0x01b1dbf5, 0xa0dfb7ea, 0x9b46d57c, 0x2f956f20, 0x9a01bde3, - 0xad8fd886, 0x1f9f77b0, 0xd4f99a72, 0xf95e8fd7, 0x0738db9d, 0x53facad4, - 0x264bc6cb, 0x3fca3139, 0x172d8c2a, 0x73c74f16, 0xabf5fd40, 0xb35c16f8, - 0x3bbc107d, 0xa3530f3c, 0x16cca9bc, 0x67dfdcf7, 0x7fd0bfee, 0x8ec7dcda, - 0x7cf00cfa, 0x26daf7ce, 0x7b56bf38, 0x51fa377b, 0x5e337619, 0x5decf37a, - 0x479e0363, 0xac3e481a, 0xb6fdc6f7, 0xebe13445, 0xd177ce36, 0xe0d333db, - 0x3f66419c, 0x87a155fe, 0x1b47ebe9, 0x042cd742, 0xe98711c2, 0xb456795e, - 0x39f81a6e, 0xeb79f8c3, 0xe7f8b64d, 0x0c3c92a0, 0x48a0e92f, 0xdd505ec1, - 0x2b9c2f68, 0x4f0bd77f, 0x0f68dcc7, 0x38e87926, 0x17b4c7f3, 0xbad4fbb1, - 0x5ee8e67f, 0x947d0db8, 0x026c0ee5, 0x93e592fd, 0x17dd9688, 0x83dbf49e, - 0x788ef02d, 0xefcdb263, 0x00b77cc6, 0x4c7fd9e3, 0x5e3a20c8, 0x84459fe3, - 0x75f0f1af, 0xeec83e78, 0xabb8c7ae, 0xcfc24f31, 0xe6711809, 0x89d9be0b, - 0xabc6cf80, 0xe107ee7b, 0xdc17907b, 0xf7e876c1, 0xc71946c2, 0x982c9c6d, - 0x4b798dea, 0xf78dbf9b, 0x6cdcb2be, 0xde74e5de, 0x933db700, 0xa8f8d5c1, - 0xae113240, 0x28f4bdff, 0x5cfb35f8, 0xc507def8, 0xc7c010c7, 0x73fb3d39, - 0x3a79319b, 0xee419aaf, 0x9ed16bad, 0x4ea7ef89, 0x8fa1e637, 0xe33bd134, - 0xe2fc332a, 0xc6fd1946, 0x3c6e4945, 0x886e10ef, 0xe79afa72, 0xf99be4df, - 0x5c295b9d, 0xf8884eab, 0xd1d6b6de, 0xfd28f4ba, 0xe5cdbcae, 0xf17d6b0f, - 0xf0634e7f, 0x7ba7f852, 0x4f36de40, 0x79e3f9c3, 0x31ff806a, 0x0d9c3c81, - 0x452c17fc, 0x236c183e, 0xc7d36fb0, 0x7930f04e, 0xd951ed9e, 0x72be357b, - 0x85be8726, 0xfda76cd7, 0x5dfa7995, 0xb0f36ff7, 0x4f36ff75, 0x72ff759c, - 0x975707ef, 0x54851fb5, 0x37b445d4, 0x111fa908, 0x3d53476b, 0x1bfd0e56, - 0xc7f13179, 0xff6fd005, 0x65bf9a76, 0xede5f644, 0x80cfb034, 0xecfb0d0f, - 0xaed98f4e, 0x3fbbd18c, 0xfbbd30f4, 0xf4c0cf43, 0xfda18fee, 0xe345efe9, - 0x4aa935da, 0xb4f7bd7c, 0xac1fdd87, 0xe7821553, 0x0fd9fb03, 0xdae5c9d8, - 0xd6feef3a, 0x1ff9cba5, 0x4f832e39, 0xfcfefacd, 0xf4112d31, 0x4207ca54, - 0x86b777dc, 0x3c6dbf2c, 0xad9b6bd0, 0xf7cc3378, 0x78fe1667, 0xf59f4d68, - 0x18f1cc2b, 0x6ac78b8e, 0x099b478a, 0x973c3b8f, 0xb6bf0fb0, 0xdf30afbe, - 0xf8e4e9f3, 0x09bf7aa6, 0xeb373bc6, 0x6b8822bd, 0x1cf9ced4, 0x1ed7fef5, - 0xaebccca7, 0x1d397e18, 0xa1e00567, 0x799fd673, 0xe303ae7c, 0xb99eab4a, - 0x58e2112a, 0x7a0d9335, 0xaa7df044, 0x4839f9f3, 0xecfb7397, 0x2e79c03a, - 0x3d139d99, 0xa3daefb7, 0xa4f8f710, 0x2c7258e1, 0x793dcf7d, 0xfda648bc, - 0xbc7bdb9d, 0x7703c248, 0xd43bd361, 0x5b7f1735, 0xdef77014, 0x37e1e84b, - 0x368f5b07, 0xe57c593a, 0x37173841, 0x6abfda86, 0x7a65f212, 0x285eed9a, - 0x1dbf1d17, 0x395c21fc, 0xa62fe63f, 0xd04ab259, 0x7ec11633, 0xee373cd3, - 0xc972f967, 0x9dfa6cc8, 0xe387ad12, 0x6af9c4cc, 0x04efc098, 0xf1444eb8, - 0xef3c02f7, 0x3ef86076, 0x02b243f1, 0xbdffc29e, 0x78093c1a, 0x09ab3a4f, - 0x77c41a89, 0x471e6e8a, 0xd30a6953, 0x3ab7ddbf, 0x848cf7f0, 0x53aaaf05, - 0x3cdafea8, 0xdd8efd93, 0x920b63f9, 0x55691fc0, 0x0df2de99, 0xb463e1eb, - 0x6be7078b, 0xe6231737, 0x40577c75, 0x921d1955, 0x8a6b6c33, 0xf9c78c35, - 0x25fe98f3, 0x3dff1a52, 0x1eb7ca29, 0x1c43a6cd, 0xc5cef8d8, 0xfc522bbf, - 0x7803cebf, 0xf0fcdb46, 0xabfb8f4e, 0x92ca386f, 0x28ccfb69, 0x945e5fbe, - 0xc39de1c0, 0xfbef07de, 0xd345e34e, 0xd4b5187d, 0x27b74efc, 0xe214b4d0, - 0x6defd0fc, 0x8bcef8c9, 0x38a29eb9, 0x0bbb9691, 0x0aaee5cd, 0x47e18f9a, - 0xf6d677eb, 0xae925f86, 0x37f63832, 0xbf0f1038, 0x79fd506c, 0x340e8f94, - 0xb07f30f8, 0xda34c341, 0x0fcb1230, 0x2f31f837, 0x986cf4da, 0x7faffa4f, - 0xeebb1490, 0x9d54efc2, 0x75c3e18c, 0xf9ade472, 0x88df8f80, 0xaf15af88, - 0xdefe478e, 0x3a8e9a34, 0x7367bd86, 0xfefec632, 0xd257f2e9, 0x0d5f284a, - 0xd3afd1f9, 0xefc3c64a, 0x17f3b096, 0xf63a4170, 0x257aee1e, 0xe093f9a0, - 0x34c63477, 0xfbc2863b, 0xc95bc1a4, 0xfd239458, 0xbbf089c5, 0x6c337b0b, - 0x949a7eb4, 0x07f8ecd7, 0x64deab80, 0xe7e7afe7, 0x6c9f1f33, 0xbce3afd6, - 0x0a66ff4c, 0x71bce3c5, 0x537e09f8, 0x39acfd00, 0x3307b9c6, 0xbf54891e, - 0xeb8a76e1, 0xdfb3efe6, 0xc754485f, 0xf7bde1fb, 0xcec35ecd, 0xbec5f7a9, - 0xff99bee7, 0xe1e2440e, 0x29176825, 0x103bf63e, 0x0f7b0a29, 0x4d930489, - 0xe5cdedef, 0x0606ccfd, 0x1f57d09a, 0x15fde6cf, 0xfb0e791d, 0x8897df83, - 0xf087eff5, 0xccd8c3df, 0x3574d3f5, 0xed4dec50, 0x5bd4676d, 0x7759ebbf, - 0x0bd1216d, 0x890143f6, 0xed04bd80, 0xd4bb698a, 0xdc02030f, 0xd7ce33ef, - 0xcdf80b3e, 0x93ddfdef, 0xebc3027d, 0x8a7d3c93, 0xd4494eff, 0xe3079813, - 0x123c16fb, 0xca7603da, 0x6206bb3e, 0x8fe47452, 0xf8947ef8, 0xe701c53b, - 0xbc0f53fc, 0xd9e5eecf, 0xbf38143a, 0x7c5bd2b8, 0x4551c413, 0xf3033ea5, - 0x816f4ef7, 0xfa9e83fc, 0xdda3d887, 0x1f0137c5, 0x06f7f3a4, 0x01000408, - 0xe1aa080e, 0x43fd638f, 0x64654eb3, 0x2bf2cc9f, 0x873637bd, 0x3f5f2132, - 0xf208f80f, 0x7dbfb48d, 0xc021c149, 0x86e16e47, 0x423763e6, 0x037f68de, - 0x5789ffb6, 0x3b8ffe65, 0x4af60d98, 0x79a55e4f, 0x625e4c4f, 0xa960e279, - 0x239abf31, 0xd073c47f, 0x3bd807b5, 0x6607a95d, 0xd4cf3008, 0xff1033fd, - 0xbcb7d5e7, 0x878c342b, 0x04eb608f, 0xf41b978b, 0xa6e1ee30, 0x79f783d9, - 0x9d61f863, 0xc4c76cd7, 0x0fbc27dc, 0x1fd3ddf0, 0x36cbaf8f, 0xf74a9ef6, - 0xc6efd88f, 0x547b030d, 0x86b9b884, 0xa3dc2e69, 0x70c1fea7, 0x98395c12, - 0xcde35fd6, 0xb55e3a41, 0xa9cdfb3b, 0xa75f2f5a, 0x80772964, 0xf8b54e3e, - 0x3f5cd935, 0x7f8b508f, 0x372b4893, 0xf0b5c10a, 0x8f686c9e, 0x937de2ac, - 0x4728195d, 0x228eb967, 0x5f3183f5, 0xcbbfefcd, 0x476b832b, 0xc4591e81, - 0x76556ef4, 0xdfa658a0, 0x8d973d57, 0xf0670bbf, 0x2452555d, 0xf7bb9c6d, - 0x3791b75c, 0x21e4477e, 0xef09d5b5, 0x5afb18f2, 0x6437fbb5, 0xc7fd3ec1, - 0x3b46de87, 0x36624971, 0x76d359c2, 0x69df815c, 0x7ca36da9, 0xd8fbbf47, - 0xa3c763d9, 0xc887f25f, 0xbe026fa0, 0xc368d0fe, 0xd9fdddcb, 0xfd522f55, - 0xea85d3a6, 0xd3038368, 0xd5fd7a9d, 0xf09c0ae0, 0x49c9b82e, 0x1cf1e9f9, - 0xeafe055d, 0xf51eb7bc, 0x3a8ae3d8, 0xd3aff80a, 0xe066c3fb, 0x9124aae7, - 0x5f0febf3, 0x7ef8f3d6, 0xb9efcd3d, 0xbfa6edb7, 0xa160df68, 0x7ba9fed9, - 0x41fc8dc4, 0x02df92ed, 0xb66ed51f, 0xb3fd6085, 0xbef1da39, 0x1be82773, - 0xfbe65fd4, 0xa6051b99, 0x5873430f, 0xf772fa1c, 0x74be2b34, 0xfd8c7091, - 0xe99124bd, 0x84290aab, 0x5f1576fb, 0x2ffeb17a, 0xba69c71f, 0x1c77da0f, - 0xe31bd637, 0x838ef754, 0xf6fd527c, 0x5fcff461, 0xafb0dabc, 0x77ffd475, - 0x61cfc53e, 0xe874f538, 0xd0d941e7, 0xa4cfd427, 0x1ee78678, 0xf9243e79, - 0x47a97908, 0x2e6dacff, 0xf6fa04c9, 0x7eb313d6, 0xb74a25d2, 0x3e781297, - 0xc9737f74, 0x13ed38a4, 0x8c73ed2c, 0x7fb14ffc, 0x3a0f3c2b, 0xda0ef37b, - 0xbd93fa5e, 0x6df00f27, 0x4bfa59b0, 0x86dfc636, 0xb7fc19fd, 0x65fbbbc7, - 0xa5e9ef78, 0x10f140a4, 0x2068df66, 0x15245b87, 0xc0d1877f, 0x3ebe1ef3, - 0x8d797c55, 0x78bdff09, 0x9f95302f, 0xfb4cd06e, 0x2e178ba1, 0x7b3f7bc3, - 0x41563af8, 0xdb3eec42, 0x7da6b923, 0xc70fffd0, 0xb8a385d7, 0xfe4a381f, - 0x328c70c6, 0x385e81e9, 0x5fe54df2, 0x69310e17, 0xec366976, 0xa1b1ad53, - 0x0b66909f, 0x6ec07239, 0xf7ec5ffb, 0x0734201a, 0x61a899e7, 0xce57da6c, - 0x079f6039, 0x448e79c6, 0x40e3498e, 0x056d749e, 0x913f53ac, 0xe5a1afd0, - 0x8619390e, 0xfde1d56e, 0xd8952a2b, 0xb0754e5f, 0xe6f51986, 0xab876277, - 0xe5a258a4, 0xb879d5e3, 0xdd94e5ee, 0xfdf60755, 0xcfe17736, 0xbc931357, - 0x5ab27da2, 0xc7f68a58, 0x9b17c49a, 0x3d38df61, 0x0233d981, 0x58f9b179, - 0x267abc46, 0xbdf72daf, 0x31c41378, 0xaed4aeb6, 0xab6e7f06, 0x0c391c33, - 0x6e3df9eb, 0xdcaa3dfc, 0xf816e175, 0x83710abd, 0x314bd70d, 0x2b6bbc29, - 0x6078179c, 0x8bec1f84, 0x40d760ad, 0x5c6e35fb, 0x421a5bff, 0xe2af2f68, - 0xf5f6c0eb, 0xe7385493, 0x9296e8dc, 0x916bbd61, 0xb8056feb, 0x64efba5e, - 0xd03ae3b3, 0x4196fe63, 0x80cbef3c, 0x71cb4d75, 0x14f5e58c, 0x68575b19, - 0x3485c183, 0x44ffc3f2, 0x33d412ad, 0x6b0ed127, 0x04ab2f74, 0xbfd68e3b, - 0x7a78a0ec, 0x85e3993c, 0xe8f4e7d7, 0xa0cd93a5, 0xbd15c507, 0xef3a12f9, - 0x7a633f1d, 0x3fda09ea, 0xe7452bbc, 0x18778213, 0xe84947bb, 0xc1242587, - 0x74d0c76f, 0x9dfb0e74, 0xbd17aa5b, 0x3849c7e8, 0x491f635f, 0x0f7ec519, - 0x7ac3da1d, 0x83919093, 0x0cca98fb, 0xe2835ef6, 0x66fde371, 0xdd5677e3, - 0xb3a7f8c4, 0x67df2978, 0x43de5971, 0x895fae70, 0x784ee99b, 0x4f862137, - 0x0b7bcb15, 0x07cc0912, 0xcd544b7b, 0xe449bfe5, 0xd8834afb, 0xb70eadef, - 0xa32ed085, 0x35e98452, 0xd9f68a24, 0xf981d268, 0xe66de031, 0x0d2c35c2, - 0x278d8e2f, 0xbbe2c8ba, 0xc7ec1101, 0x788d5bb4, 0x44f5f04c, 0x96bfdeba, - 0xfc36e3c8, 0x66538c77, 0x7d7ee214, 0x5fab1266, 0x0fbbc815, 0x338dbcec, - 0xc69c61a6, 0xf58cefb0, 0x16dfb0d2, 0xab579872, 0xc17b5c42, 0x3a16ebb0, - 0xb6753e59, 0x8868e0fe, 0x0b53b66b, 0x2fee1b34, 0xf96af8b3, 0xb034e2e6, - 0xba1e16cb, 0x4ce4ed15, 0x8b65d995, 0x8250ce36, 0xdadee1a3, 0x8a07f43c, - 0x84484c37, 0x4ed5847d, 0x8575e27f, 0xfbe267e8, 0xc7b503b9, 0x355da6b6, - 0xab71e419, 0xca90128d, 0xeeb24bfb, 0xb17c0b1e, 0xcced0f21, 0xc6c109ad, - 0xd6efda24, 0xabfcd67f, 0x4ea7fe68, 0x8c38f0bd, 0xd5813ab3, 0xc051bbc3, - 0x12e73d9b, 0xc9bbe1b6, 0x3d6f8dfd, 0x1252f097, 0xa8ca7f7b, 0x7e536fff, - 0x80007d7c, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5947c0b, - 0x66fdf895, 0x666579be, 0xf263c992, 0xc2130922, 0x9e4e5e4b, 0x124c2280, - 0x4cb443c2, 0xe8202a10, 0xa79034f0, 0xbadc5d48, 0x30040cff, 0x5706b650, - 0x84ea2b11, 0xbbaac562, 0x351ba341, 0xb88080ea, 0xda446dd6, 0x8ffd16d2, - 0x4810154a, 0xfed2b58a, 0x39cf65dd, 0x7cccdef7, 0xb5f01993, 0x3efeb4ff, - 0xe7ddf7ee, 0xce73df79, 0x12e973bd, 0x2c614dfc, 0x5630a494, 0x51c1d8ca, - 0x618cf58c, 0x24dea98c, 0x064dcf06, 0x34e2d26f, 0xa37efac6, 0xf5e1bb67, - 0x926f6617, 0x25d8c6c3, 0x79fa2ed1, 0xa0b199aa, 0xcdb3b189, 0xc11c166e, - 0x336699d8, 0x1f966b95, 0x9fa0c698, 0xb9850e9a, 0xc55b19f2, 0x3f6336da, - 0x69923baf, 0x3d0155dc, 0xf4648e0b, 0x5bfe0977, 0xd528fcbd, 0xebc9dd5f, - 0xaa0eb2d7, 0x4f3192bf, 0xf76b3c07, 0x1cd0595a, 0x51df5fae, 0x4a1f69ac, - 0xd7bf51d2, 0x3b06fb25, 0x5bdd8c9c, 0x2abefc3d, 0x5d569f78, 0xfae1f662, - 0x13e38e58, 0x87afa8ab, 0xebe63af7, 0x77aeb188, 0x49de5c04, 0xac4e8a82, - 0x32b1d0ed, 0xe03ad6c6, 0x1ec62e9f, 0x6c7cd850, 0x15f7f6b7, 0xc2632919, - 0x9e2ad6ed, 0xf898c70c, 0xa8bc6a70, 0x88d48167, 0xc467dab2, 0x345e35f5, - 0x0ef3fbd2, 0x63075fb3, 0x3ff4c91e, 0x7fac2d70, 0x1953eb26, 0x909f53cc, - 0xcd5d8e38, 0x71258b58, 0xba673e37, 0x08a17d0c, 0x53333038, 0xf8337e71, - 0xc4ebf62b, 0x71944769, 0xed403ed8, 0xa98ed967, 0xc473400c, 0x8303735e, - 0x90b037f7, 0xce060aca, 0x28fdfa0f, 0x2359dfb2, 0xdd1be5b5, 0x09ecf2da, - 0x7e6332da, 0x9a4fd782, 0x1a4eca9b, 0x04fefdc2, 0x0311d6a6, 0x5802b72e, - 0x5eed7eb1, 0x0464e04b, 0x923beb1e, 0xaec6e535, 0x88c9c0ac, 0x1ff16a71, - 0x135ff059, 0x589d775f, 0xdf4607f7, 0x5bc00ead, 0x71190b3d, 0x46c140dd, - 0xacc658ef, 0x7c45e616, 0xf16fd81d, 0xcfe812b0, 0x00b76e66, 0xabbb1b7c, - 0xdef02595, 0x30ef876a, 0xe196273f, 0xfaf03569, 0x0e88058c, 0x39da8fe0, - 0x5bed99bd, 0xb713e415, 0xcdfedaab, 0xff00dde7, 0x4f0293dd, 0x24ac3d95, - 0x0ea3ac46, 0x5e1e91d6, 0x07eb39c7, 0x582f8865, 0xa5ec6fcf, 0xa6461748, - 0xf3d78524, 0x5cb5e1ad, 0x5dc6af0b, 0x1837a236, 0x1844bde7, 0xcea761a7, - 0xceb2846f, 0x7e4463dc, 0x3ce917b9, 0x1c72de06, 0x6f3c4c4a, 0xe0c73c43, - 0xfcaceda7, 0x1cc7e43e, 0xc7181fe4, 0x6527eeb6, 0x8f818b27, 0xfa1737aa, - 0x054dbea0, 0x547186fe, 0x08a9bff8, 0x6d3bd9c8, 0xe9d03255, 0xc3e73b29, - 0x7a2e890d, 0x0abc50ee, 0xe75d35e2, 0xd5fa47c9, 0xcc43b827, 0x66a3f1c1, - 0xcb601942, 0xf962c1ae, 0xefe81ebd, 0xcb1b9821, 0xf0098416, 0xcbc2c878, - 0xefca392f, 0x6ee308dd, 0x0de5e64a, 0xd5b9bd3f, 0x16ca093f, 0xe5439e59, - 0x416d0c87, 0xffdde03d, 0x44f5c982, 0x28f7b53e, 0x32305e58, 0x4d4c04f0, - 0x2365843f, 0x4226a65e, 0xf4b720e7, 0x9b769a2f, 0xeed05ea0, 0xa78427fb, - 0xfb39ff5c, 0x26363cf1, 0x4d7e7f66, 0xacdf797f, 0x53bf183f, 0xfbf87577, - 0x419dc4d4, 0xc2e76f3d, 0xe7a72c76, 0x9ff43f03, 0x6d89a2fe, 0x0623e285, - 0xda179b76, 0x632c5dd5, 0xd43908c1, 0xb679f023, 0x5b7241d9, 0xf943afbe, - 0xa9f9063d, 0x7d70e487, 0xfe46aa47, 0x7f5cb94a, 0x7f4d5af1, 0xc27c8e39, - 0x43dabd57, 0xe2feadf2, 0x121efa64, 0x736cf4f2, 0xf889e926, 0xc8d20ce3, - 0x1338f0f5, 0x72f8b059, 0xefa24ce3, 0xcbe61c72, 0x06bdb922, 0xa4240ce7, - 0x87bc8237, 0x750c2e71, 0x465f2525, 0x0276d99f, 0x67ac4591, 0x63341a9b, - 0x07dcdbff, 0xfc18be1c, 0xb844e520, 0x1edb51bd, 0x811b23f4, 0x4863edf4, - 0x7aacffb7, 0xd4fa91cc, 0x5038f066, 0x8af6a86f, 0x34372e23, 0x86647e4d, - 0x5169280a, 0xd97f3d39, 0xd1e881b6, 0x411f706e, 0x3aeddafc, 0xafbe1f97, - 0x483ce9b7, 0x730e2d27, 0x51bdf100, 0x7281c1b9, 0x076bf643, 0xb8f38f31, - 0x7a421b60, 0xd57ade3d, 0x0f54898b, 0xa9199266, 0xc6f7ff1f, 0x0f17c583, - 0x31bd8f1c, 0xfa0b88f1, 0x6e744b57, 0x910be00b, 0x1d0471fa, 0xdf63f744, - 0x779cc6a9, 0xff093d74, 0x8436f8b8, 0xe7fe1112, 0x8119ba6d, 0x4d2ef318, - 0x9e9bbe56, 0xdf25145a, 0x3c3b7f93, 0xd095ed88, 0x49f20a0f, 0xa32696fe, - 0x90bc2dfc, 0x3922e958, 0x73b5ee9f, 0xb6e385b1, 0x7d9a8ed8, 0xed988fa4, - 0x3ebfd913, 0xb849fd3e, 0x64aade18, 0x04601f88, 0x4ae37a86, 0x412bb070, - 0x1597e22f, 0xd3e50caa, 0xa76f3a40, 0x77d7f4f9, 0xeb11e743, 0x0edd516f, - 0x75fd6ba4, 0x99ca331e, 0xe6398ef5, 0xaa379410, 0x20f9d9ae, 0x02defa87, - 0xb7d6127b, 0x1cc8ad29, 0xc15a8f8b, 0x2df9c46e, 0xd669d64d, 0x1d669f23, - 0xf7e8dfe7, 0x9eb9925b, 0xb13fdd68, 0x9f1253c7, 0x79d2407e, 0xcb9b8f51, - 0x5856c754, 0xe7c0de9f, 0x0763896b, 0xc1e37eca, 0x0b7ecb6b, 0xa87569c9, - 0x44f68039, 0x549b78f4, 0xbe078f77, 0xf8f9826f, 0xc7c39cb1, 0x3aa254df, - 0x16d74376, 0x47330257, 0x4b3837d4, 0x6c17fe08, 0xdf0f4c69, 0xc63d2137, - 0xd3849798, 0x68efe4bc, 0xe8a2f93f, 0xc3b7f732, 0x5d0d10d9, 0xcba2c6b6, - 0x4b37a879, 0x3999fcf9, 0x9343fe72, 0x8c7c8ebe, 0x49b29ba6, 0x977c83cc, - 0x5876cf01, 0x66caa76f, 0x807d43ec, 0x9844d6b6, 0xe636cddf, 0x393e9900, - 0x32677cb5, 0xe7acb7ac, 0x3f219180, 0x1d693a74, 0xf47da275, 0x8e14a6b8, - 0x838a533f, 0x3dc7499e, 0xf8014f4f, 0xb824f676, 0x99d4f814, 0x0630fa02, - 0xbc088f7c, 0x9fc6d633, 0xf21c686a, 0xb65fac8f, 0xc3767988, 0x6b0250f3, - 0xb2bd8335, 0xc607c84f, 0x154fe7ee, 0x99c61718, 0xdde8cafd, 0xf58a2f64, - 0x80b5021f, 0x43d3d3f5, 0x77fd14e3, 0x585edbc0, 0xeade047d, 0xdbc221cd, - 0x6bdf46db, 0xe3c69f08, 0x772c74a1, 0x87933d1e, 0x70b670f8, 0x25efb5fb, - 0x6ee9006b, 0xd3d67e20, 0x0e2eeafc, 0x81e2fe62, 0x8353ab78, 0x2eeb5fa4, - 0x5877d1e6, 0x129cdfb7, 0x6c1b3efe, 0x2eb00986, 0x4270e666, 0x47c2c4f8, - 0x896be0bb, 0xa3eb500f, 0x081f02ed, 0x3ec48fa7, 0x4eef1fa7, 0x780666e3, - 0xefe66b3f, 0xdf246799, 0xfe7d0987, 0x005e4251, 0x0d1f33f7, 0x7a46ce07, - 0x91e95d50, 0xe2cea77a, 0xac3e6fb9, 0x67abbd9b, 0x5963c04f, 0xed15ada5, - 0x4f2665ab, 0xcb5dda12, 0xeb2bd3de, 0xc48409f3, 0x3c042b07, 0x5df732cf, - 0x36ff3f88, 0xc209e38b, 0x97ff769f, 0xf8bca3bf, 0xa2bf681d, 0x9346ef4b, - 0xcda56971, 0xf596fd8f, 0x876d3c54, 0xad5b2bf7, 0x2efd062e, 0x04fee29b, - 0xf765bded, 0xf21b5c59, 0xa438bf71, 0x5dfa0b3c, 0x03be60fb, 0x9d7581e5, - 0x06ecd337, 0xeb7ee093, 0x6de02b4c, 0x8964b293, 0x7dac0852, 0x1516ca7f, - 0x57feacf0, 0x281667e5, 0xc17f755f, 0x8c75f316, 0x1cb282bd, 0xd0ff59ed, - 0xfedf6899, 0xf646a712, 0x7f6fb72e, 0xca274479, 0x82a65bc5, 0xece5180a, - 0xce60d9d4, 0xb78a532b, 0xf4fc6198, 0x0ea14f14, 0x32935bc6, 0xb7f62661, - 0x7fb1bef4, 0x77df09dd, 0xa99acca4, 0x44de13e6, 0xcaccef7b, 0x926ed0a1, - 0x54b3cf2c, 0x56697f42, 0x27a7b616, 0x090fbf00, 0x77f68f8f, 0xbdfdbf67, - 0x1cd4e660, 0x53454bc0, 0xbffd0aa5, 0x96db729e, 0x36315731, 0x877281fe, - 0x983fc607, 0x15a664b2, 0x9469dff0, 0xf16d97f5, 0xcc9d58c0, 0xbe0186f7, - 0xbafef1ff, 0x9fa86699, 0x742dea96, 0xcd53fac0, 0x91996ff7, 0x65f81dfb, - 0x4fbd12a4, 0x1271482c, 0x90461cdf, 0x33ebade6, 0xf82afd72, 0x71d3873d, - 0x9424797f, 0x4ce511ed, 0x10dcee5e, 0x4e9c7e5b, 0x33b972e5, 0x8f77f621, - 0xef004b90, 0xb3e90ea0, 0x96181acb, 0xc027961f, 0xc409e64f, 0x3cb9db5f, - 0x639abe01, 0xd98e3e27, 0x5fe537df, 0xd3f53b80, 0xe8ac7aa9, 0x0d7290bf, - 0x71c56666, 0x69764cbe, 0xcf5975e4, 0xbfb79252, 0xeb7c154a, 0x5671f0e2, - 0x330ae56a, 0xb8470cf7, 0xc58b76c8, 0x4b47f33a, 0x88d052ff, 0xe2d6b9fc, - 0xacf9c0c9, 0xc19e57dd, 0xd787632e, 0xf8d72c5d, 0x98ebc24b, 0xf407ef4a, - 0x44b9fd0b, 0x5f31eeff, 0x57c95e07, 0x7d1a5780, 0xc33ad2bf, 0x3bfd69fd, - 0x7ee3fb03, 0xc57a019e, 0x1b9e7b18, 0x415eb853, 0xe422ebf8, 0x5f214ada, - 0x3d916a41, 0xabc5fe7e, 0x8fcd6f76, 0xf503771c, 0x7a7df80f, 0x412fee0a, - 0x2b1ca2be, 0xb0b33d53, 0x8a4f597e, 0xa079ed03, 0xde828db7, 0x8937a454, - 0xa694cee7, 0x76ef5a72, 0x863bb1c5, 0x3913f81d, 0x83c536af, 0x22c649f6, - 0xc4497e9f, 0x87fca4fc, 0xff453bfe, 0x1f9e9c25, 0xc5e7a7ed, 0x2fc23fc8, - 0xdf40dcc4, 0x5fce0763, 0x08ce36c1, 0x2582f5fd, 0x7091f380, 0x2ff4b6fb, - 0xb8ba87ed, 0xda912a7a, 0x260f1c65, 0x219ea0ba, 0xb9f9c5c5, 0x6bc4e3e3, - 0xe9755f51, 0xebe2e299, 0x2651b946, 0xe7bfa4e5, 0x764a8548, 0xbb2e584c, - 0x72919ec8, 0x87366833, 0xbdbfdfeb, 0x9446c667, 0x2fbe26ab, 0x1483d34f, - 0xe3cf0a2f, 0x2fae14e5, 0x2798f827, 0x24781d96, 0x08e52ed9, 0x75e1e3ad, - 0x5863ec95, 0xd7e85d9f, 0xf93f2109, 0x664c9eb3, 0xf0e13ec2, 0xb67bfa90, - 0xdcaff429, 0x47a5a64f, 0xa53b0659, 0xee105741, 0x89cfbf1f, 0x8263fba0, - 0xf3f1a20e, 0xc013e55d, 0x48708fc1, 0xc872e14d, 0xed056509, 0x17f4150b, - 0xb55cffc0, 0x3f35bdcd, 0x2e36de62, 0x1d7a9d8f, 0xe0576397, 0xfe54b48b, - 0x3b25efbd, 0x1e1873f1, 0x2ff98edc, 0x1d76f701, 0xc17dc1ab, 0x09f01d21, - 0xaf8da2d2, 0x598bfcf3, 0x29e7efd4, 0xeffeb93a, 0x1bb72e45, 0xd7ce3c61, - 0xbfd63f64, 0x3b5da83c, 0xdcdfde7f, 0x658f4e54, 0x68853dc7, 0xdaf30cc7, - 0x285fb8dc, 0xc07399eb, 0xdde1e500, 0x4b6b038a, 0xc1de1f3a, 0x4ba814f9, - 0x67ade5c0, 0xa5b5fb22, 0xbefa3a72, 0x38fc31d6, 0xcbc457a7, 0xcd3e08e2, - 0x7871b54d, 0x084cfac1, 0x472b554f, 0x9bfbf3e5, 0x0180f787, 0xf0075bd6, - 0xe12db140, 0x64b1d9d6, 0xf8f90583, 0x1f237338, 0xa258ef9f, 0xdd788b1b, - 0xebbec8c9, 0xf00f0f97, 0x147b4875, 0xe903b2e8, 0x5cd4eaf2, 0x71d86f1a, - 0x7c0c758f, 0x1376861f, 0xec3b95fa, 0x4c57dc01, 0x4dcdf54e, 0xedce7845, - 0x4a2064ab, 0xeb4dac1a, 0xfbef112d, 0x7d4177eb, 0x7e9f63a2, 0x36f3ce2c, - 0xc2bab6c6, 0xfaa981eb, 0x6f5a1fd1, 0xa02d3e04, 0xd6e11072, 0xfbf5e469, - 0xcf8a3316, 0x8cfbe834, 0xf7f41df8, 0xa3cfa22c, 0x2fc414ba, 0x6ed09bee, - 0x737bd3ae, 0x67d7dc14, 0x07a8dc98, 0xf4421f60, 0x54c2c87e, 0x26fff40b, - 0x574e513c, 0x8fd8efe9, 0x502aaaf0, 0xae242ddc, 0x60dc85da, 0xcd37dc41, - 0x7a25629e, 0x39dd5f64, 0xbff51ab4, 0xfa09e395, 0xcc7e8b31, 0xff30a2e6, - 0x2aef3afd, 0xfd48ffda, 0xa8514876, 0x8dd7439f, 0xb112ddde, 0x50fec22f, - 0xaa521ffe, 0xfa40ee73, 0xb23afb17, 0x7ac2d30f, 0x2295ed17, 0xfdde245b, - 0x3ca17e62, 0x7b48a3a4, 0x7ed3ed14, 0xb1dfd67b, 0xd9c83a65, 0x823a33f1, - 0xd152073a, 0x01ff33f3, 0xf60551d6, 0x70e005ac, 0x33972a5b, 0xfafdf287, - 0x30df9c44, 0x3abc3f58, 0xd31be09c, 0x938f0b64, 0xe90ffc2e, 0x482fee46, - 0xbfcfe04f, 0xe73b72a7, 0x1e5c6927, 0x978d21fe, 0xfb6313d3, 0xf510be2b, - 0x1f971354, 0xfcb9cb5b, 0x41b7ae8f, 0xedadfbf4, 0x668a31de, 0xef760f7f, - 0xf76e5486, 0x885fb91a, 0x0a9613c7, 0x873b06fa, 0xabb614f0, 0xda503c78, - 0xccf45fa1, 0xf372f2a3, 0xbfe8d97b, 0xe69fedbf, 0xb6f487dd, 0xf27a37f2, - 0xf1149c57, 0xbec99582, 0xbfdc64f4, 0xabf6c427, 0x75d6273c, 0x1f9199ba, - 0x1b8c53f8, 0x893dec82, 0xaf284371, 0x34e0f9da, 0x2cd5bfe4, 0xe5e0fe40, - 0x5c51373b, 0x61407970, 0x69f7052e, 0x1627ee5e, 0x47bd58f8, 0xdf4bf1af, - 0x931936ae, 0x77e984c7, 0x6e369b45, 0x58abb358, 0xf6f6fe53, 0x440b2569, - 0xfcb0a1c8, 0xa3ef4699, 0x1ef495fb, 0xd47ea76d, 0xc3f8d2ec, 0x461cee97, - 0x97f597eb, 0x77ad3731, 0x66816b59, 0xf395acde, 0x49f9bc49, 0xd4bb45ba, - 0x469e731f, 0x008ffbcd, 0xff08fefe, 0x4353d2ff, 0xa92d1e69, 0xba40ffbe, - 0xcac3cf09, 0xdabf1afc, 0xb027c724, 0x7ee16656, 0xff23a049, 0x5081ece5, - 0x6fffa72a, 0x71d1f70f, 0xfee305f6, 0xca0beebf, 0xcc397126, 0x0c3614da, - 0x6aa7e31e, 0xa0bfb4ed, 0xa7c52bbe, 0x616beb95, 0xa45f2d47, 0xd45177ad, - 0x5dea28bb, 0x6912bfc9, 0x2805299f, 0x0d7f78d7, 0xcff38f82, 0xa0ba351c, - 0x6e34f8de, 0x3d3916c7, 0x6cef5097, 0x438e24b3, 0x4b36ca7f, 0x52f5005e, - 0x38bafaff, 0x48336d1d, 0x033b8a3f, 0x5ffed6e1, 0x88a8b677, 0x0fb07dc7, - 0xfe587900, 0x8a1641e8, 0xae375390, 0x01cb3c53, 0xef2176de, 0x7d7cdcea, - 0x71a0ee75, 0x5d93f428, 0xd395e7c7, 0x23515fb1, 0x08d4e5da, 0x419a5f7f, - 0xc1cccfb3, 0x8d254e32, 0x9a9ce3cb, 0xea1432a0, 0xa3daef65, 0x875fd8a8, - 0xbb337a42, 0x41130009, 0xdc25d957, 0xa4b1b9be, 0x2636595d, 0x5d56870c, - 0xe00718f5, 0xeadd35a7, 0x8f737d46, 0x0d2437d3, 0x182279e7, 0xf8fcedc4, - 0xda2a3d13, 0x7a753fef, 0x619cd20a, 0x8ef4b838, 0xd6a7d46c, 0x6d9e7c13, - 0xae63fbfd, 0x4da22867, 0xdcddabfe, 0x23b3d19e, 0xa487db8c, 0x8c37d2af, - 0xe727bd24, 0xf4229e97, 0x3df33a45, 0xadfaa367, 0x68c9f08c, 0x861be93d, - 0x2cf6e6ef, 0x815577c7, 0xafbe0f77, 0xa8aab8ca, 0x6c17de05, 0xa14baa0b, - 0x62bbcbdd, 0x85cb83fb, 0x4c75813e, 0x75c9f5c2, 0xc82e495c, 0x7e38867a, - 0xd60fc90a, 0x1ff7b119, 0x2f7d2230, 0x216d347f, 0xa36eb7ce, 0x30949991, - 0xf4ea7ffc, 0x64f9c6ce, 0x082bb477, 0x93dfe91b, 0x1dff4ae3, 0xfcfe477e, - 0x96f928c8, 0xfe5c5fd3, 0x2cf7a75f, 0x1b67948f, 0x6927848d, 0xc7e7873f, - 0x69d5fded, 0xeabecf5c, 0xf9c12ef4, 0x276d7434, 0x3daacf7f, 0xf9631a1f, - 0xe2f9a3ab, 0x6a54704a, 0x6ea0bef8, 0xeb8039be, 0x25547f2f, 0x68dda83a, - 0xdd5938a4, 0x9fb8fb33, 0x46e61ee7, 0xb1d75139, 0xe30e594f, 0x4fb33ed6, - 0xd7011159, 0x05017541, 0x2ec233e7, 0xafcb90f9, 0x3f47ba68, 0x872dda32, - 0x9c4e5c2d, 0x15f9b72d, 0x8359eb80, 0x9deb0eaf, 0xfdbab2cd, 0xbc3c61f9, - 0x11fa6fb9, 0x3fb037cc, 0xb3e20a67, 0xd33bb755, 0x475af50c, 0x5f48dd19, - 0x36fa753f, 0x54525c23, 0x4fb6276f, 0xd7bbb34e, 0x89975b43, 0xfbbca115, - 0x1f1870ba, 0xefe32745, 0x85d3fce1, 0x91db8872, 0x813fc845, 0xa7b4bb34, - 0x361dae48, 0xc73c75f0, 0x9eff7cf8, 0xe89079ea, 0x8d0a48f8, 0x54175d9b, - 0x7f9d9fd0, 0x6b9239e6, 0x9d30ffb2, 0xe4891e79, 0xb3cf2bdf, 0x56f488c3, - 0xf950e42b, 0x8f947ba3, 0x4bfde623, 0x6e91f430, 0xba019fb2, 0xfdf7d1b4, - 0x3ea8d333, 0xbdf0b933, 0xe16aed42, 0x79088afb, 0x4311d723, 0xf5c3ecee, - 0x1cf44ed8, 0xc82772e4, 0xbe628dfd, 0x157cf8d1, 0x9a7c1fe5, 0xde99ea06, - 0x3123fd1b, 0x48787a2e, 0xe527f502, 0xbedf3440, 0xe51ce82a, 0xfe46cea5, - 0xe52bb25a, 0x22bd64fc, 0x34fec567, 0xc10f4382, 0x4a977ea1, 0x7a32a9eb, - 0xc111de87, 0xfd16bf0f, 0x03f9b81d, 0x07fdca23, 0xa25dfdfe, 0x8536fac7, - 0xedacf1e2, 0xd43ce35d, 0xf4a7fe47, 0xe2ce6768, 0xf1db0126, 0xa784bbc2, - 0x2e5c9d59, 0x53ee77d7, 0x74c2d997, 0xc0e67f9a, 0xf56748ad, 0xfb86261d, - 0xdfbfa022, 0xe9a27c20, 0xca47c254, 0xb4f878dd, 0x9472e0ce, 0x47e48df9, - 0x3e54fd85, 0xdca429fa, 0x4eaa7bfe, 0xfbf809f8, 0x1cbc690b, 0xa7df1fa6, - 0xdcb08f08, 0xe45f10b5, 0x603a299f, 0x5bb87dc6, 0x5a7f3f21, 0xe4678725, - 0xc6c7aabc, 0x54ce9b97, 0x50d437a1, 0x587b1cde, 0x7fcbf7be, 0x810bfed1, - 0xe41f786f, 0xd410d9ef, 0xd1fe72f3, 0x7277cbf8, 0xce831b7d, 0x11d71bfe, - 0x3da4dfad, 0xc9e6e920, 0x8f46aa5d, 0xea469dd8, 0x731b0ecf, 0x728ec79c, - 0x61d8cf1e, 0xc76cfae0, 0xe500737a, 0x780b9bc9, 0xa17d995e, 0x43cf8831, - 0xf875a5ba, 0x1f3650fd, 0x5ba755bf, 0x0dd6e583, 0x7842d636, 0x4b3a24f5, - 0x19127e91, 0x1e5c8f97, 0x973cf03e, 0x5b7e7567, 0xeb3fc180, 0x5397737c, - 0xe2cd39dc, 0xf333b8c6, 0xb3ce341d, 0xd72ba40f, 0x2e8dfb73, 0x83ab3f78, - 0x03c49ff3, 0x2fa253c8, 0xae120fc9, 0xb8727861, 0xf8927e4b, 0x67f4bbf8, - 0xa77cbd03, 0xda3daabc, 0x46dbdc78, 0xbe4ed5df, 0x706c3acf, 0xc7869fa1, - 0x6fd1e217, 0xb3b7baed, 0xb51d824f, 0x7a2df33a, 0xfd85be4a, 0x27bf86ac, - 0x3817bc09, 0x74afbeb9, 0x2da9ba72, 0xacbe20e9, 0xfc44d93d, 0xe5c19b6c, - 0x5684ed9a, 0xcff6331e, 0xa8dbbd62, 0x63b5955d, 0x5477e61a, 0x7038ae3d, - 0x6e4f1fbf, 0xfcf0aede, 0xbd774fb8, 0x72f98891, 0xf2b02bec, 0xe1629e31, - 0xe4eb9deb, 0x5eece272, 0x7bd13800, 0xf672f193, 0x63fa95fb, 0xc20a63c1, - 0xfac056b3, 0x139533ec, 0xec7e84ff, 0x61ee49bd, 0x9ecfe4b0, 0x3feee9b9, - 0xeecfbcc1, 0xf746e299, 0x978b5a65, 0x69cfa7e8, 0x037ee371, 0xf40cf7c4, - 0x78efae17, 0x685af123, 0xabe9fa77, 0xd76e508b, 0x799e798a, 0xe10ebf5e, - 0x7fc9e1b2, 0x6bdf8c9b, 0x09aa4a03, 0xf8fbd9c7, 0xbe63677f, 0xf2469eea, - 0xfd3cb517, 0x17f311ba, 0xfe768174, 0x03926f7e, 0xf9fe9deb, 0xef08c9f6, - 0xfa168e96, 0xede7e67e, 0xe4f03e54, 0x77f6bdbf, 0x1378e3f4, 0xccef58dd, - 0x2f09fbf3, 0xf2953e75, 0xf5d1e2db, 0xb9fb7d8e, 0x8f3d44bc, 0xcb9f307c, - 0x92d74931, 0x793f4f7e, 0xbd48c4db, 0x0ab7df21, 0x026b4e7f, 0x099f23d7, - 0xe0adadfe, 0x9ecfcef1, 0xfda7ccb5, 0x1c343181, 0x6375c5f7, 0x2ddc5d38, - 0x71d751e0, 0x46c1a187, 0xdf9fa9ed, 0x73e3df02, 0x27e7d02c, 0x64852923, - 0xd7ca25cf, 0x0faa57f9, 0xbfa026f5, 0x1f45e6e7, 0xeb1f382a, 0x2d432698, - 0xfe69f3cd, 0xf91d561d, 0x6c6d6cbd, 0x38bffb3f, 0xe02ec26d, 0x59dd907c, - 0x3922e39d, 0x8b0f7260, 0x6bb387b0, 0x27182d7c, 0xcfad7ebe, 0xbe3c07ad, - 0xb4e8ea7c, 0x727e5041, 0xf84c52a4, 0xcf5c2bd7, 0x4e346df9, 0x81c1fa3d, - 0x3e0b768f, 0xf5307749, 0xdc03921a, 0x32a5501f, 0xaa7e46d5, 0xf513923e, - 0xee0f42ad, 0x736e7e11, 0x764dde5f, 0x26bb676a, 0xed061f62, 0xf72a366c, - 0xf310fde5, 0xe7f8674a, 0x1971de93, 0xa467be69, 0xf27e603c, 0x8b7e4a7b, - 0xbca11bf6, 0x57d1fcc1, 0x285de59d, 0x3d33e51f, 0xefe4bf8e, 0x74b8fbe2, - 0x15ca174f, 0xa35537b6, 0x95c9e20f, 0xe79f3703, 0x0f95fb7a, 0x901b0e89, - 0xdf7c710e, 0x5ede8d49, 0xe815c24e, 0x890fa5f0, 0x7177970e, 0x55d0daf9, - 0xd4fdc46e, 0x69d7e10e, 0x7484f410, 0xbfe8fb84, 0x9c69933a, 0xe1a1c986, - 0x0bcea728, 0x12ff3bba, 0x3a43b7a7, 0x0e01f91d, 0xdedd1eed, 0x8fd40ca2, - 0xf0978d4a, 0xe6f800dd, 0xa3daf376, 0xd7d56768, 0x6bf23730, 0x07e0a743, - 0xbe117bb0, 0xcbd55d0d, 0x6941bfb1, 0x0ddfc933, 0x41b4c976, 0x63a86e50, - 0xd96fc8a5, 0x425e2abb, 0x7c5d60ba, 0x035d9e3f, 0x4dd22cf6, 0x9f5bbd5a, - 0xdb8f7a8f, 0x2c8fd7bd, 0x723bf6a3, 0xf2e7145d, 0xf38a3157, 0x19fb40ef, - 0x68d65df5, 0x36fb3f6e, 0x5cc5dd92, 0x6537e409, 0xd60d753e, 0x622ff06f, - 0xcd11d794, 0xb4292fc7, 0x5808680f, 0x56681f29, 0x1a7fb717, 0x9f1f38ba, - 0x4f91f093, 0xe4adcf43, 0xc4c17f8f, 0xd0fe11fc, 0xce9a5f37, 0x268becf5, - 0x359fb3d2, 0xb0c7d87b, 0xbc85b7a0, 0x6dac7097, 0xdd21d7cb, 0x09937632, - 0xcc4cb1e7, 0xf5c0cda3, 0x03d0b246, 0x3cf8db05, 0x77e174d4, 0xa789d74c, - 0xe2e79b51, 0xe17f93f0, 0xc88f189c, 0x39e85d22, 0x797eba18, 0xeea4f890, - 0x9a5fde19, 0x677853c9, 0xfb4abd04, 0x0b1e9a28, 0xbbd9b8c4, 0x4c282a0e, - 0xd1cd77b2, 0x35f5f9f0, 0xeb08d82c, 0x2e977ebc, 0xd91c6538, 0x9e490b4d, - 0x58b237af, 0xd2232af9, 0x9556fdb9, 0xbf442dea, 0x36cdd576, 0xb93fa477, - 0xb3a3c12a, 0x24571da0, 0x12ded8fd, 0x4a9d1b8c, 0x6f11bbb7, 0xd25dd2e3, - 0x5bd8d30e, 0xdcdff703, 0xcda1bc0e, 0x1ff70e3f, 0xf309f581, 0xda09ae29, - 0x0edcfc8d, 0xf7fb8f68, 0x9cfed7dd, 0xb85bdfef, 0x070402ff, 0x6f5499c9, - 0x9d8ffa09, 0x5cb5de05, 0xb1ddd93f, 0x93aaf3d6, 0xcdc0e7af, 0x3ee216b7, - 0x8dae61b1, 0x5781e1f8, 0xde9ca594, 0xbee21140, 0x83f9c7da, 0xe13c7f01, - 0x3b247a22, 0x1bc9a1aa, 0x9c8f4d88, 0xaec01a5f, 0xe81b3b42, 0x93b70d71, - 0x13f38c6d, 0xbfb94ba7, 0x6915b947, 0x8d3e4acf, 0xbf497be6, 0x35ff7cfd, - 0x81bcfdf9, 0x8079e3f3, 0x3f7bd203, 0xe9ccbf9d, 0xe07aeb7c, 0x15bef847, - 0x4225b1f8, 0x7fef47fe, 0x1fb89e70, 0x1ef6f290, 0x3a5177a7, 0x6fdda1ca, - 0xab50c66d, 0x2f0d8f94, 0x397e196f, 0x958ccbbb, 0xf0335fa1, 0x60fd246b, - 0x445ed68c, 0x09ea3f4f, 0xfed8baeb, 0x6dd2bb8f, 0x3f3fcddf, 0xaee52f30, - 0x7981d2f4, 0x73a8e929, 0xadbb6f10, 0xa58fb401, 0x3e7a291f, 0x499f044b, - 0x03fdca7c, 0xfeb021c6, 0x37ef82fd, 0x888f7a89, 0x84bec467, 0xf3a5c1f8, - 0xf679487d, 0x6c91f471, 0xb5f97df7, 0x2f5238e4, 0x8c8dd346, 0xaa7ae0a3, - 0xd7afc4c7, 0xcfec5fb6, 0x29f8e8a2, 0x800b5fc1, 0x6dde7037, 0xc417e086, - 0x19d8778f, 0x99f813e5, 0x71e31527, 0x7ce08daf, 0x386fb234, 0xfa66b7b6, - 0x92ba44be, 0x8f7c5d7e, 0x115aaa71, 0x6bddacbf, 0x7f9e4408, 0xd18337b9, - 0xb376bd38, 0x91fc0f5f, 0x87dbe99b, 0xcc15fded, 0xf33d441d, 0x2b8a168f, - 0x8a5b8181, 0x8591a6f2, 0xefce1112, 0x205efb25, 0x0cf7d5fa, 0x39e3bf47, - 0xdf0e3425, 0xdafe109f, 0xfb5fc213, 0xcf7bd77e, 0x17ad02be, 0xf16e72bf, - 0x5ece918f, 0x7d21e4b4, 0xe7f4b09c, 0xdda125bf, 0x92b9817d, 0x690e772e, - 0x55ef5991, 0x2767fc23, 0x7ffdb1ec, 0x373c0b6f, 0x532b788a, 0xb7c3ed19, - 0x19f97067, 0xe3c4bf3e, 0xb4ebefad, 0x1cf937fe, 0xdfe1c193, 0x501ce719, - 0xd7df0661, 0xfce10e74, 0x50aed7d8, 0xdd66afbc, 0x41eb3ffa, 0xb5acd42e, - 0x9f09e907, 0x71ab8ed1, 0x283a83f8, 0xb970309f, 0xcd737f04, 0x07fd6165, - 0xc849d4f5, 0xc5077e33, 0xfd0a96bf, 0xcde9acb5, 0xa15fa1bf, 0x49e66546, - 0xf2c71845, 0x9f041e1e, 0x4f2db53e, 0xf2bff144, 0xa3a67747, 0xd458ca7e, - 0xa6c1f226, 0x55fed03a, 0x2fe8373c, 0x6f672f59, 0x132764a9, 0x1ede001d, - 0x22f6f0cc, 0xe24a2f1f, 0x7745c17e, 0x08fe035a, 0xf057b879, 0x7cfd3461, - 0xcdbce710, 0x01151997, 0xaa616fec, 0xefd46ff7, 0x7234e79d, 0xfa12bced, - 0x5f4823c5, 0x4fddd877, 0x22f2eef0, 0x05d263f3, 0x0e316bfc, 0xb7b1a204, - 0xbaf867b0, 0xbee3a47c, 0x5fa1dfbc, 0xf0e4dbab, 0x91bbf0bb, 0xf176cbbe, - 0xe3f141e2, 0xd2232e40, 0x8545c347, 0xf76961e8, 0xae51c79b, 0xa221a837, - 0x1b66a593, 0xa2e1b1e1, 0xd5a9e9ca, 0xdb243670, 0xa4d7ee03, 0x6032d27a, - 0x277bfe9e, 0x093c5325, 0x17c389f8, 0xe39c452a, 0x37c332f8, 0xf7e00328, - 0x36f13590, 0x305d7fdc, 0x8f3092bb, 0xf408d1ad, 0xe7753570, 0x43d84735, - 0xa5aec72c, 0xfeb7ee83, 0x6e5af386, 0xaf5119f6, 0xd134f0af, 0x4945b179, - 0x98c752c1, 0xd24fbc48, 0xf5fd1a5f, 0xc8497ef1, 0x3c8df797, 0x9d20646f, - 0xcf6c3c73, 0x39b2f510, 0xc79fbcbf, 0xe7c39e6a, 0xbb427828, 0x728887f7, - 0x170f2891, 0x7979d2f5, 0xf797e09a, 0xd17af1c7, 0xe3152ce3, 0x99e1997c, - 0x7682708c, 0xc7d22341, 0x673a166b, 0xfe404ac4, 0x935bbca1, 0xc82c764b, - 0x770869b9, 0x4c982718, 0x67a44cf5, 0x41c81358, 0xa96f67c0, 0xb5b3e08b, - 0xe305e81c, 0x289aaf41, 0x2bf1241e, 0xcf8d1af1, 0x77ca1985, 0x181f4fcb, - 0x51985ebf, 0xcd7e303a, 0x17c250d8, 0xf38c4bd1, 0xf5f0f11f, 0x03c73b6b, - 0x0cf2ebf0, 0xb1c183d2, 0x49b37c91, 0xb5ca51c0, 0x78b413f7, 0xe39d3cfd, - 0xbbd45ea1, 0xda1f7684, 0xe23eeed1, 0x7853f7bf, 0xae02b4fd, 0xfe5da497, - 0x5f2e024f, 0x529f6ba6, 0xd1fb44cf, 0xe2f214bf, 0x47ee74cb, 0x8ddebc07, - 0x09fa95f3, 0x19304ce4, 0xebd178f8, 0x6c339226, 0xd5e51f63, 0x83ffbd40, - 0xea645af0, 0xf41535bb, 0xdec10fca, 0xbb511631, 0x0647284b, 0x48c7efec, - 0xd433b0ba, 0x0e19addb, 0xf4941f6e, 0x48d7b8f1, 0x0ca5aebe, 0x657287e4, - 0x210c63fc, 0x6bf0e40b, 0xc142bf22, 0x6214aebc, 0x07f61767, 0x8c97ff70, - 0xa3dc30d2, 0xe8213bc7, 0x450cd1e0, 0xb215bc25, 0xaddbc442, 0x5f6e7eef, - 0x139e5d0c, 0x4d9365e7, 0xe7ec76be, 0x916fddec, 0x18c27e9d, 0x8b66de1c, - 0x7c18ddf1, 0xfc2521ec, 0xf4a7b6fd, 0x98d5e37e, 0xc1f67e7f, 0x4bdd619b, - 0x1c6ef47b, 0x5f3de972, 0xed1e33bc, 0xc5031eec, 0x6fdf406b, 0x4dde7153, - 0xa13caedc, 0x67c1d2d3, 0x3df76977, 0x907a0baf, 0xdca572e7, 0x157cfa91, - 0x93797373, 0xcb1bb890, 0x3b71dd1f, 0xce5dcb9d, 0x003d87bc, 0x666bd3f7, - 0x3b7c5d92, 0xcf5e51f3, 0x39ed56b2, 0xda6d15db, 0x073bedf2, 0x3925c39c, - 0xfd102abc, 0x2ba5f85e, 0xf3fbeb63, 0x333f2e82, 0x7afdf88a, 0xfdf8cc53, - 0x09fc85ef, 0xb4fbd9c7, 0x2f57fbf1, 0x8c6fbf1f, 0xed87df8a, 0x3df8e888, - 0x6113f7ef, 0x91bf606f, 0x2acffc71, 0xa3e3af62, 0x58b7690c, 0x9f19f935, - 0x125bb00c, 0x45e37be9, 0xd8f99c4b, 0x2b67fde8, 0xd7d38f63, 0x5f368e3f, - 0xe79edc20, 0xb5fdc809, 0x8bc693a4, 0x6567a459, 0xe1c7da59, 0x3df43976, - 0xf4babcfa, 0xf8be4b6f, 0x2ce66158, 0x176d47f2, 0xf29bbc76, 0xbb463f33, - 0xba72f908, 0x4c10b5eb, 0x278fd971, 0x8487570e, 0x1d7a26f9, 0x42675f40, - 0x98d8f211, 0xfd234f69, 0x3a6e66eb, 0xfee82797, 0xe8abbbd6, 0xbdffcf7c, - 0x322332a7, 0x53f72a6e, 0x8f69460d, 0x96fa34d9, 0x65e3e945, 0x1d916f5d, - 0x70d7f606, 0x7a7f3e14, 0xc3d26ef5, 0x1d37992b, 0xd5f7bde9, 0xe56e7411, - 0x3961eadb, 0x4bfc9b9f, 0x35bf3c0c, 0x3987ec8d, 0x75373e62, 0x67503b73, - 0x1c6818f6, 0xd239730f, 0xe7cd8b69, 0x8554420b, 0xf3fd75f2, 0x631de747, - 0x15fcc493, 0xbdf00f6c, 0x52d93c4e, 0xdbce265f, 0x31eae384, 0x8990260d, - 0x6e8996cf, 0x28a73e17, 0x83cf955e, 0x6b1a79e3, 0x3afac1ca, 0xd7cf4873, - 0xc7483309, 0xa2f0fdf6, 0x37945db2, 0xeb70bdce, 0xb36f7c0a, 0x8a313c93, - 0x04cf4c79, 0x6dfc88b9, 0xb75c6666, 0x4d3c16c9, 0xf4f133f1, 0x8f88b857, - 0xf91843fd, 0x07581241, 0xd9b53f9d, 0xb171f9ce, 0xb050e60e, 0x085c716c, - 0x9ce27ee2, 0xf3c7e6c3, 0x672f20c4, 0x5f3fa265, 0xc44ad5f9, 0xee67c80b, - 0x5df78a17, 0x11f3f20d, 0x88a5de42, 0x7908b5f9, 0x8adcc597, 0xe480c7b8, - 0x95f6fddd, 0x267ee037, 0xa3f7798d, 0x71387bbc, 0x32fdc506, 0x93e68f98, - 0xc8d5433a, 0x5b57a72d, 0x46af98ce, 0xe7053bcb, 0xbed3e597, 0x9413b337, - 0xbd04a497, 0x69529799, 0xfd12361f, 0x37210631, 0x3e78598e, 0xcf3166c2, - 0x8853333b, 0x78598e6e, 0xb6b7c25e, 0x7ddadc5b, 0x3f0a437d, 0xdd3e7fbf, - 0xc0f1c66c, 0xe113b98e, 0x07cc7607, 0xdfce167e, 0x41d29c2c, 0x6f9b0279, - 0xe01bdc54, 0x6bbb66fd, 0xeba40abd, 0x7f70a99f, 0xc728ea8f, 0x3cf69c7c, - 0x44f31b87, 0xf7be451b, 0xf6a38b66, 0x9a63f219, 0xb7d63d78, 0xed96e319, - 0xac0e1d5b, 0x37d95697, 0xaafb88cd, 0x9bb1cc15, 0xaff7a0c5, 0xbe608f80, - 0xe032c73f, 0x63f41149, 0x85bae23d, 0xefbe20d6, 0xf0177fc1, 0xdc3294f2, - 0x82bff2bf, 0x773a42ee, 0xd27a3cc9, 0x85dd8d97, 0xbc60d86f, 0xe485b982, - 0xf256f7af, 0x72132fb8, 0x571cbc60, 0x61b5d9f0, 0x85efa7ba, 0x5bb43ca2, - 0x4cd37ff8, 0x80ebae3c, 0x91c4ca21, 0xc69fac43, 0xe4cdc1f9, 0x6bd3e71f, - 0xfb0ff858, 0x4ff70cab, 0xf86a6972, 0x60ef9873, 0xbbb322a8, 0x8dea0ea5, - 0x91fb8357, 0xcf15afaf, 0x543cf142, 0xe5e9237e, 0x65cd9d1e, 0x373e71d4, - 0xc3aba017, 0x94b847ab, 0x60b4b639, 0x4129d73f, 0xd8cde67a, 0x9fd382de, - 0xc94cfc23, 0x9e00c699, 0x00996b37, 0xc8bf2678, 0xffa30f9f, 0xac2fff5a, - 0xcc74f118, 0x279ef520, 0xb9ffe789, 0x0ed53d68, 0xce97593e, 0xc22e7b33, - 0xcf3f28f9, 0x8b74d0c6, 0xa997fef8, 0xd7974955, 0x300f3cbb, 0xe5cf4b25, - 0x871e0ce3, 0xa66f9c6d, 0x7146e5bc, 0x7d53030f, 0xf08c3ff9, 0xc5b8c8af, - 0x7f3606bb, 0x46fd8c5f, 0x07b7164a, 0xfdc0dce6, 0x1f228dc2, 0xcc4f7e47, - 0xbfb27ee2, 0x377b4e64, 0x1e3dec93, 0x949dfd6f, 0x48d9235f, 0xf2115f94, - 0x5f248fe5, 0x278edfca, 0x85dfb47f, 0x29e799fc, 0x40bed036, 0xef2921c8, - 0x68ef22bd, 0x1018f301, 0x1ee23d4f, 0xabe5a395, 0xccdd0e48, 0xf7fef47c, - 0x00ff3c15, 0xfd80d308, 0x6b4334dd, 0x6af3cd3f, 0x8fcf37cb, 0x3e38afb6, - 0x7c0bb8e4, 0xa473efda, 0x6b433c9d, 0x87fa2f27, 0xcf4992af, 0xfea2fc67, - 0x3e70e0d2, 0x3e546351, 0x27c88351, 0x3c2aec6a, 0x4f911694, 0xf3cdd8d4, - 0xaeba1a89, 0xedc44f94, 0xb029af29, 0xde24e31f, 0xec94d25a, 0x727f910d, - 0x8a4ff310, 0xaf6e74c2, 0x0c3cf3b0, 0xa2bca1e6, 0xce95871c, 0x8aeab45d, - 0x9adb8fc8, 0xddf8d768, 0x5577aeb7, 0xbfe93d61, 0x4843f995, 0xc3f6b137, - 0x5f7c59d9, 0x7ee143b3, 0x3302ff74, 0x059d3bed, 0xc15c4d5e, 0xd1c767a9, - 0xa66ef8af, 0x3f27d64b, 0x2f830ec9, 0x019e18ab, 0x8979d185, 0xb67af6fe, - 0x5190fc91, 0xea99ca72, 0x338038a6, 0xf5f92c69, 0x921775e7, 0x2cd9923f, - 0xb84a61ee, 0xdb7379ff, 0x69ebcc55, 0x97576eec, 0x3774c2db, 0x43ec4b36, - 0xf48accac, 0x7bd7efda, 0xbd7e44ce, 0x30b79364, 0x19d7da0b, 0x8bbfe483, - 0x1f7a57a0, 0x2ede5f4f, 0xe150c5e8, 0xe602b05d, 0xd18efbd7, 0x0a6bfb8d, - 0xcfff41cc, 0x7e4c94bf, 0x230e7549, 0x9cb1b53d, 0xf45e93cb, 0x3e3ac193, - 0xfaf7e64d, 0xa466ac6c, 0x4ca7cf5f, 0xc55e3a23, 0xe83d8702, 0x7405db47, - 0xd2cf7918, 0x8eb96d1e, 0xa9fe9075, 0x3d00667b, 0xf2947c93, 0xf4b99eb8, - 0x741b8c06, 0xa1b3db6a, 0x285c395a, 0xbcf147f4, 0xff982da9, 0xf2e3ac50, - 0x0f772d91, 0xf5fb439a, 0x2c4f8e45, 0xa17f7228, 0xebaece5c, 0x73d29fb5, - 0xa17ae7fe, 0xad1ff454, 0x3d854abf, 0x17e41937, 0x7da56fee, 0x7ca9f506, - 0xcfadd750, 0x59e785d4, 0xbb49da22, 0x890bea50, 0x8c09f2af, 0xbbb579e1, - 0x1a7c84b2, 0xbe2086c2, 0x13e27fa1, 0x29583705, 0xf71fbfd4, 0xf18ad785, - 0xa8fc1e80, 0x733afdbf, 0xb36be900, 0xd2fa44d2, 0x3c3ff68c, 0xd23e2ab7, - 0xe35eff0b, 0x4c7d23d7, 0xdd374d64, 0x9926f500, 0xb728ac7b, 0x31fe4e80, - 0x585a7e92, 0xa29f6f30, 0x7efa23a1, 0x98edf936, 0x5af52474, 0x9edcf7f0, - 0x74bcc599, 0x0fe793cf, 0xa83aeedc, 0xd8267df0, 0xeed1079f, 0x93375b7a, - 0x2c2664e8, 0x3955eb03, 0x9e9ff8b4, 0xdf472da9, 0x5ad0c50f, 0x48744328, - 0x9c540678, 0x51bdf44f, 0x98f7291e, 0xb3e5ee56, 0xf8de78af, 0x423fc396, - 0x1d7583ff, 0x0ef6891b, 0x8fc4aa58, 0x27b0f4d1, 0xb78f7beb, 0x118ac9ec, - 0x7e15e96f, 0x68586be5, 0x40ca33e5, 0x687f3b7a, 0x82333e9d, 0xbc7f252e, - 0x1379e06c, 0xae3cebca, 0xc6ccc135, 0x252e1104, 0xf928ffdc, 0xd3a41ae3, - 0x95fd3094, 0xa487f789, 0x06cc197c, 0xd75dbd23, 0x01ea0965, 0xbfa2853f, - 0x8afe906b, 0xdc89f6c2, 0x184cb477, 0x98f96740, 0x4cf60e17, 0xb495d201, - 0x8e958a4f, 0xfde73c16, 0xb6f74bfc, 0xe8237ce0, 0xc3842dea, 0x8ae80559, - 0xf4036afc, 0x147bf6ad, 0x4bfc49dd, 0x359cba7b, 0x6e677ed1, 0xc1b3d702, - 0xcf49dbea, 0xba24b882, 0xa70e737b, 0x21e62abb, 0x5a672bba, 0x6b34a97a, - 0x0974d1cb, 0x74b4ea23, 0x8bba23e7, 0x7478d7a6, 0x4ee91837, 0x2bd4dbea, - 0x48e7ddd3, 0x8fc5df77, 0x3eee9039, 0xa7c672cf, 0x937a68bb, 0xc59f6cf2, - 0x75768951, 0xfa428d63, 0xa19df8a1, 0x511e582d, 0xf6764f9f, 0xd93764be, - 0xfc4d8ddd, 0x478f497b, 0x0533798f, 0x7cf7c56b, 0x1b96256f, 0xe877c1d7, - 0xcf18f4ba, 0x0f7a19ab, 0xa1b85eff, 0xbfbc0de9, 0xdbcfd1a0, 0x337a7cbf, - 0x6c0a879d, 0xdbcbed16, 0xd8dcb12a, 0x8a7fdbca, 0x31abae71, 0x82d02dbf, - 0x96daafef, 0x6fdbe6ef, 0x114fd76e, 0x3ca7ddeb, 0x6bb506f7, 0x3f6eede3, - 0xe4604e6c, 0xfaf6e027, 0x29ceb164, 0xd33af8bb, 0x867ebe3e, 0x4563e80b, - 0xb9ec9f9f, 0x6575744f, 0xece2ef24, 0xb695cbb3, 0x474e7c1c, 0xbc47a639, - 0x43f55bbb, 0x37741c78, 0x3675710c, 0xf8c8d3f7, 0x5429e621, 0x5717d847, - 0x443b7367, 0x614f4bd6, 0xfd8d7e74, 0x72fe4ecc, 0x3e0cdf19, 0x07d414c4, - 0x976146b8, 0x4e778cc4, 0xbb22682f, 0x1960fa62, 0x4ba90ce7, 0x4bc2dc61, - 0xe58b4f9f, 0xe6cb2a47, 0x9129f3f6, 0xd7df2177, 0x4875f204, 0x4890fb17, - 0x90f0fce8, 0xdb9ed077, 0xe734cc97, 0xf3e5f6dc, 0xbcecd4f2, 0x01cd6e7f, - 0x549aeaf8, 0xe58bf7bc, 0xf2b79429, 0x4c161e83, 0xff381c4a, 0x1a0b2ae9, - 0xcf8a0f29, 0x518b657f, 0xe5c257dc, 0x3f813cda, 0xd1186936, 0xa7815cef, - 0x17a16cea, 0xca31598b, 0x6f0279a9, 0x1937343f, 0x336ebeb8, 0x798fc944, - 0x1e3f28d9, 0x6bcf6b8e, 0x97c947bf, 0x4aee311a, 0x62afc761, 0xfd3fe47d, - 0xa7f1d844, 0xfc76e61e, 0xfe41d66a, 0x719fded3, 0x961ebe3b, 0xed12f487, - 0xabddad07, 0x6877d72d, 0xdea00dcb, 0xaec6ffb1, 0x8633b928, 0x1f7ba5fb, - 0x3f432fae, 0x77cecd64, 0x235dffc8, 0x2b404ce5, 0xe740c067, 0x51a1e672, - 0xd6fabfe4, 0xd819e3f2, 0xf26995d5, 0x76c9ef4b, 0x5e77f846, 0x0d2e79e4, - 0x7a11fb8c, 0xc16f23ed, 0xd28b2c7d, 0xa572d14f, 0xe915c850, 0x5bf290ff, - 0xc6429bca, 0x77ec14f5, 0x9b60f1df, 0xe1ef3b28, 0xc4afa16c, 0x4dfa4dfe, - 0x88547da4, 0xd7d211f6, 0xba2226a8, 0xbf727eb0, 0xe847d26d, 0x662505a5, - 0x19917bc4, 0xa6e11bf8, 0xd9f58db7, 0x68f1f434, 0x83f7e5f6, 0xf451efda, - 0x0b63f723, 0x84dcfd05, 0xff181891, 0xb81f720f, 0x5ccfd38a, 0xf4843de6, - 0x9cd5fbf3, 0xf0bee47e, 0x3d03ef9b, 0xa07dc8fa, 0xdd7e4fdc, 0xdd3f60fd, - 0x863ec058, 0xe95cb1e7, 0xfdf1e017, 0x45d38546, 0x3ddf9cfd, 0xf2c2c556, - 0x733368e2, 0xb97086ab, 0x8cc9a665, 0x0316977e, 0x99cd2fdf, 0xd2d97ef5, - 0xb413f908, 0xb8401f97, 0xf9276eb1, 0xdaadeb77, 0x3d2b3671, 0xf711fd77, - 0xc95a8f55, 0x08e174af, 0xc2e59323, 0x0f9411ae, 0xc78199fe, 0x6e7ce55b, - 0xb5f7bc3f, 0xb95bd410, 0xcc6296ee, 0x0255a82f, 0xb7c1d62f, 0x77beac0f, - 0x756bbf91, 0x672f7141, 0xe427c50f, 0xbafdf1b8, 0xc6c7927e, 0xf73f5c03, - 0xdf940929, 0x4787ef0b, 0x38fee9c6, 0xdcefcb88, 0xb807df4c, 0x5b47a91e, - 0xf827f3fa, 0x1b30b413, 0xa7ce1294, 0x704de708, 0x985fcb7f, 0x13798ae7, - 0x04e2231b, 0xbe663ed0, 0xcf2179db, 0x01726147, 0xba6567cc, 0x7fd717a7, - 0x4f85c44a, 0xa9e23889, 0xfc571e44, 0xfe7d7f7b, 0x7ae20db4, 0x3b8894e8, - 0xc6d14a9e, 0x44bd649b, 0x6cd93cf1, 0x60346ef6, 0x37799ebc, 0x3d70fe82, - 0x7ca26a64, 0x5f1c4595, 0x6b252fbd, 0x1ac811ee, 0x106a3e54, 0xd399fbb4, - 0xe3041fab, 0x9ed36f2c, 0xf715ea83, 0xba0af6db, 0xa7f0b5e9, 0x506b371c, - 0xd76c28f5, 0xb3df80bb, 0x289e5fda, 0xbfea5ecb, 0xc910baf7, 0x8ff2fea3, - 0x3a9ce242, 0xf8c893f7, 0x61f8bc40, 0xfa30bc74, 0xbc74699c, 0x37e4b17f, - 0x245fef11, 0x6ee2d4e4, 0xd5b86f1e, 0x820f36cc, 0x6775b7ef, 0x26b8fc50, - 0x135c3fd1, 0xbf5bf7ef, 0xa4879e51, 0x9edcdecf, 0xcff8f8fe, 0xf5e3e222, - 0x2f5a3e22, 0x5da9d7d7, 0xcf0164df, 0x3e3e31ef, 0x60739079, 0x9f3a3c7c, - 0x33b445e2, 0xac3c610c, 0x55b87071, 0xd12aebe9, 0x39617c4f, 0x35f73ca3, - 0x416b2d6f, 0x2d9af23f, 0x615596e2, 0x380bd777, 0xd3975bc7, 0x8d2e63ab, - 0xb9813ebf, 0xe593d622, 0xc994d14b, 0x33c88f92, 0xad93541d, 0x34db9f69, - 0xf07f5344, 0xef9a51ba, 0x4d22fef9, 0x1af5a0b9, 0x6d61fd4d, 0x88f29a15, - 0xea6bd79d, 0x4921b217, 0xa23b6fe4, 0xbb125f47, 0xf347302a, 0x85def47d, - 0xb29ff69a, 0xa0931da6, 0x7b45a75e, 0x7bf3332f, 0x8594c67a, 0x76c7a9f3, - 0xc3f4d52c, 0x29504a82, 0xf633df0b, 0x79a7b899, 0x878f0f79, 0x5ab5dd5c, - 0xbead4e33, 0x1d18f08e, 0x7d622def, 0x086e37e4, 0x1b20ee28, 0xd55dff18, - 0xaeed4ed5, 0x78c8f764, 0x2241c6c8, 0xb2cd97de, 0xd3475d39, 0xc3ec8d85, - 0xe4f4bb0b, 0xc3642c7f, 0xf0449a1f, 0x6b80b032, 0x302efe20, 0xf0bb17ee, - 0x798ddd8c, 0xb5bfb745, 0xca63e68c, 0xde05d2d4, 0x5eb9181f, 0x5d2d48eb, - 0x3a5addd8, 0xa5a09a48, 0x27786883, 0xc174b47b, 0xcbbff042, 0x86753bc0, - 0xb7fe6e96, 0xf081dce0, 0x5be186b5, 0x62d3d07c, 0xbcf1b823, 0x999f6935, - 0x1d143d84, 0x4e7690d7, 0xbbb09070, 0x2e323f45, 0x93f159b1, 0x771fd55d, - 0x0bcc109c, 0xd53da3e6, 0xc95fb8c4, 0x6fe5107b, 0xbd24bf0c, 0x9497e78f, - 0xc09b9d70, 0xf32d67f5, 0x663efc92, 0x93a4fee1, 0x9fc8abd5, 0x913592b4, - 0x9cd9fddd, 0xe8efc2e9, 0xca577aa7, 0x9f901853, 0x8b29f600, 0x06aed7f0, - 0x1fef1a8b, 0xd2a7868a, 0x78ed04ad, 0x4b75986e, 0xfca3e07d, 0xedde0f15, - 0x68ff89a9, 0x51e65fed, 0xb497e522, 0x1278e587, 0xc9ae529e, 0x49ac4c71, - 0x117c899f, 0xc8d8e725, 0xd693f8e8, 0x41fd239f, 0xe3238e32, 0x9bfed14c, - 0x55b8bb08, 0xc1d2718f, 0xce782df9, 0x21e1d8b7, 0xeb29613f, 0x4fdf05b9, - 0xa8b47730, 0xb8bfe12e, 0x2ffbf58a, 0x2babeae2, 0xf26fb5c4, 0xf247a12b, - 0x65b3c607, 0xff961c7c, 0xf1a11ff1, 0x8b95c524, 0xf2f398f3, 0xd3d22708, - 0xfba6bf40, 0x8fd02bf8, 0x8a97d75e, 0x3130aaf5, 0xfdde223d, 0xf5a212a6, - 0x367990fc, 0x6fdb9e45, 0x6ed31d60, 0xe8327f21, 0xa727bc49, 0x58bbfb93, - 0xac3db457, 0x0759bf92, 0xafba412b, 0xde711165, 0x2a77f0fc, 0x659607eb, - 0xec95d21e, 0x82f1a789, 0xe0a3ca72, 0xc84c53f9, 0x8cffb941, 0xf993cfb7, - 0x4f7ef218, 0x94547799, 0x1c75f823, 0x03fd871b, 0x94e595bf, 0xf8017fa2, - 0xc7e48953, 0xfa253cfe, 0xa31f803e, 0x31f32fd6, 0xf212f6f4, 0x5c8b2d1b, - 0x8780d7ef, 0x9c7e5bb4, 0xc8e9e8c3, 0x3eb3d171, 0x3d6fc4e1, 0x47a4b9f8, - 0x68da3f93, 0xfa0d0d84, 0x79145e13, 0xbb5a1d81, 0x9d1c96fd, 0xf7df1b80, - 0xf15e095c, 0xf8f221f1, 0xaebe3e04, 0xf8f3261d, 0x0c971c24, 0x0d0afb84, - 0x8ff7fb5c, 0x115f70fd, 0x2e12ee0b, 0x7e7b4ae7, 0xdbd2f881, 0xbc23a58f, - 0x577aa617, 0xe3dcfd63, 0x5d144fa1, 0xfa555e78, 0x7b8794b3, 0xe74f4ba1, - 0xe3ae1aff, 0x25e1b072, 0xf386893d, 0xb38a26dd, 0x41bd74d6, 0x66d9e176, - 0xfc06b410, 0x72180cbd, 0x08fc65d8, 0xb78ef051, 0xd9eb924f, 0xe5f62390, - 0xef32fd62, 0x39b9d607, 0x475e6627, 0xdfb41c3f, 0xf4aa1c05, 0x1cf09263, - 0x92be7f59, 0x791797da, 0x3af45f5f, 0xfe78722a, 0xf7b329db, 0xc3efec3e, - 0xd81d9c9e, 0xfbbe955f, 0x67c23670, 0xbbe742ad, 0x79f898a6, 0x5e712cdc, - 0xc9a8426f, 0x3399e78d, 0x667df873, 0xf7a47e23, 0xfdf91c62, 0xe0a677b5, - 0xffd93439, 0xe7474508, 0xee7b1947, 0xc12c7f83, 0x3722e6f8, 0xd8bf6fde, - 0xba2fee24, 0x002c1acb, 0x91baf239, 0x186547df, 0x66e744d2, 0xe4f592fa, - 0xb3d34cd7, 0x727748a9, 0xadbcf2de, 0x01f78f7c, 0x7cb15e60, 0xafa5a53f, - 0x7bfa0d78, 0x75c83d04, 0x2beca94f, 0xe185b26e, 0xa33cf32f, 0xf82553e1, - 0x1b43ee43, 0xd05b5ef0, 0xbccde7bf, 0x6daf7d1c, 0x5874feff, 0xf6363dff, - 0x837eb8c8, 0x1e3493c5, 0x6bdc51f9, 0x278717fb, 0xa477df89, 0xbcf6a7bd, - 0xbf97b7c8, 0xdeef1253, 0x51ccff9b, 0x827b97be, 0xcb85e5e2, 0x7078ffbc, - 0x99564869, 0x739d357a, 0xdeae5ef7, 0x8fadff2b, 0x28bedfb9, 0xd3dff7be, - 0xbcec6af9, 0xceb15ec5, 0x88617e70, 0xe7f729ce, 0x7e54be2d, 0x1a477bd9, - 0x08d23ef0, 0xf6bcc838, 0xb48fbc06, 0xd0bf4638, 0xe576cb9f, 0xc4aa877b, - 0x8f301abc, 0x3df23530, 0x38f0b7a7, 0x302f2269, 0xfb7c8894, 0x9d3d2ecb, - 0x11e5ffe3, 0x31dd8cdd, 0xcb9b9de6, 0xa9ca32e1, 0x0e8d1f12, 0xe3b5fbf2, - 0x79e793d5, 0xe8d8b9e4, 0x845675f9, 0x63f9c56e, 0xf1ac729e, 0x3f7cb91c, - 0x99dde72b, 0xf0d1f1c2, 0x9bdf899a, 0xf27cf2aa, 0x4ad094ce, 0x168713e2, - 0x1e04c3cf, 0xe50faf3b, 0x99b2b9d1, 0x8f10efdc, 0xfaa7261e, 0xc8be51ca, - 0xd4caee7b, 0xc111c526, 0x87a2578f, 0x1af5dc30, 0xbb840ebc, 0x7ecbbe91, - 0x7c151f4f, 0xdc363ccb, 0xfa112dcf, 0x5a9ec96e, 0x7ee587b2, 0x3d4ef4e9, - 0x669c6fe5, 0xba72ae3c, 0xd0fda14d, 0xeb631f52, 0x7cad2e40, 0xaa3378a2, - 0xb09925ae, 0x1efe1496, 0xe9661f7f, 0xbaf8a8c6, 0xbd495fd8, 0xbe5fc72a, - 0xd7176b4d, 0x467f6db0, 0x51f4e9fb, 0xb0563f2e, 0x2b3fd226, 0x57f6d01f, - 0xa7d667b3, 0xbce8cf38, 0x8fc21180, 0xec572d37, 0x1958ca57, 0x4f358fea, - 0x9fc46e7c, 0x17c78960, 0x434ffbf8, 0x7ddff187, 0x8efe27c2, 0xc96f3e08, - 0x1720fcf5, 0xf2ef3efd, 0xf5ceaef9, 0x7f45c9cd, 0x7e7cbbc9, 0x702eea17, - 0x8d2bb33d, 0xfd8b5bf4, 0xfaff922e, 0xdffe5cc1, 0x0035f78b, 0x71264c9c, - 0x49aeba6f, 0x4df6489f, 0x43ece880, 0x7e731de7, 0x26776540, 0xd3da43f2, - 0xbf6067d3, 0x1eada7ce, 0x72d6df5c, 0x2ffa214f, 0xf3f356b6, 0x8f1366a1, - 0x397e07df, 0x538600f1, 0xaf6c7686, 0xa39d1740, 0xfd107f7b, 0x3fbaad42, - 0x98bcc61f, 0x5f3cc9d6, 0xda175d32, 0x3c62283f, 0x899035a7, 0x68e77df1, - 0x9a4e6f7e, 0xcb90bcbe, 0x36276e7f, 0xe85c5c08, 0x627f202a, 0x17fa41af, - 0x2e742c3b, 0x2eff8eab, 0xf1c628c6, 0x70eaf32f, 0xf176910e, 0xf9a666d9, - 0x1d51869d, 0x4890d04a, 0x3c50a8f7, 0x30436ea8, 0x67d416fd, 0x4f14a94f, - 0x7b4bf393, 0xe302ab3d, 0xdd8f5266, 0xbfb838a2, 0x0bfdd84d, 0x71e3fc98, - 0x9e82f9b7, 0xff7b0816, 0xf7872b16, 0xc3cee652, 0x2ccd0b76, 0x76ac0751, - 0x2947654b, 0x90d6b3ad, 0x8c85768c, 0x47b7c51f, 0x1ac9fb62, 0xe7e7617e, - 0xe1be959e, 0xf419c9d8, 0x3f865d41, 0x693c85db, 0xffcfce18, 0x83cca1b1, - 0xd786caf1, 0x30efd046, 0x3c781299, 0x1996e41c, 0x843a11ef, 0xbdd61efa, - 0xc88b15ea, 0x73880a5b, 0xd8defccd, 0x453939c6, 0x78f11e74, 0x71ffdd1f, - 0x23ca10de, 0x847906fe, 0x92bea637, 0xe01fbbfb, 0xd90debbd, 0xf941d760, - 0x789fee74, 0x25684879, 0x92991bde, 0x47978977, 0x72c13e85, 0x6cc25e4e, - 0x5685172a, 0x3e3ca1ea, 0x7197932f, 0x36040a03, 0x6cf06f35, 0xc92dda3f, - 0x87702ec2, 0xc377bce8, 0x917423cb, 0x1e7758fe, 0x84676797, 0x3e4cf93f, - 0xc20e6dbb, 0xfaec647b, 0xded27969, 0xc9f5a36e, 0x2cf6caf5, 0xffbb7633, - 0x957e7210, 0xc53da738, 0x3c2d5aca, 0x044fe7fe, 0x1eec1c3c, 0x7fcbf141, - 0xfde14dcd, 0x4f74423b, 0xfa27ec8f, 0xb8e41c77, 0x7bfe15ab, 0xf2a3e759, - 0xcb977ebc, 0xb38c2be5, 0xea19c691, 0xe79be7e1, 0xfe2214e4, 0xc0aa6f00, - 0xc9f7ca9b, 0xd07e7ced, 0x13fefe2f, 0xf46287e8, 0x0afc1ffb, 0xe787e7ea, - 0x27274d1d, 0x5aab38c5, 0x2fb6dc78, 0x69e880b9, 0xf7dc558a, 0xc75da252, - 0x9f6e3cf8, 0xc592f3ba, 0xaf091d79, 0x69c6850c, 0x09cc7011, 0xf6339f0d, - 0xaffbaf9b, 0x8eeb4bff, 0xef0797c0, 0xc5d8396d, 0x9f1e37ef, 0xf485f1c7, - 0xe076429c, 0x677f4d76, 0x9fb547d6, 0xae5f28c0, 0xda80a521, 0x6fee2bdf, - 0x61d9f795, 0xdc71fcbb, 0x57bb45be, 0xfcc1a7de, 0x1c645993, 0x8cdeffb2, - 0x70bf710e, 0x286f3aff, 0x8874eb11, 0xef223a75, 0xcfe7ec33, 0x73797d63, - 0xb8e903ed, 0xfdfdfe1f, 0xfd12298d, 0x563cf869, 0xf1d7c87f, 0x1e5572f0, - 0x1bdf2797, 0xa33ce45e, 0xe70fd9e0, 0x7849f9a8, 0xbb537f22, 0x94ba5a31, - 0xf411ccf3, 0xf3bf8039, 0xe278e5bf, 0xbbfad97e, 0x7338be79, 0xbebae969, - 0xf9875f33, 0x07ddb209, 0x34a0c078, 0x21bc27ec, 0x7327ec4f, 0xbc9c4e58, - 0x339e6f47, 0xde917fa6, 0x7b27ef47, 0xd9efe593, 0xbd1afd69, 0x397bfe4e, - 0x7efc73fe, 0xfca36b83, 0x7a8f183c, 0x176e16ce, 0xf2da2fd6, 0x037e0263, - 0x797d54fd, 0x5312bf38, 0x3bf8f3c5, 0x4af3ab5b, 0x7760ab67, 0xdc552494, - 0xa6e50f99, 0xfc93c6c7, 0xf154192e, 0xf3c83e79, 0xe04d8f35, 0x7c5747df, - 0x79cb043e, 0x8a797913, 0xf79479e7, 0x9eccb460, 0x2bb6159a, 0xd173ccee, - 0x1d4afab8, 0x42676bdd, 0x63d60623, 0xf944dd7a, 0xf1ae1280, 0x5d26259e, - 0xbff3ac53, 0x03d3f4f7, 0xc04cbf8f, 0x1fd0ba7f, 0x2105fc28, 0xe82fe355, - 0xcfe7e44d, 0x92fd5f7b, 0x9bdcd7ce, 0x079f5be7, 0x67ad1bed, 0xf287cd6f, - 0x1407eb06, 0x603c53ef, 0xc61fa087, 0x608b60e5, 0xadd9cabe, 0xd89fb45e, - 0x2559b76a, 0x18ff0ab8, 0xf007a9de, 0xa7b5e57b, 0x0f883c7e, 0x4c79c5e3, - 0xf1a07214, 0x15fdbfb5, 0x678dc4e3, 0x1b346e6c, 0x7c3f7627, 0x135fda27, - 0x1bfedfbb, 0x3cfcc3d7, 0x44f79c90, 0xfbc27ff4, 0x9a265d09, 0xabeec4ff, - 0x6bfd6056, 0x402eebdf, 0x44eeb93a, 0x42c505b0, 0x3effabef, 0x880e7348, - 0x7cd97a7d, 0x39f1b8d1, 0x013f8f09, 0x1e0893a0, 0xf8f0e73f, 0xced9f28a, - 0x0e6e8f3b, 0x7b549391, 0x78ec0ade, 0x605f3b8a, 0x7b8c6e09, 0xd1fd73c8, - 0xd5e3d57e, 0x7f783eb0, 0x20cc1f5d, 0x729e9ec2, 0x24820cd1, 0xc9672e5c, - 0x39a5729a, 0xcabf534b, 0x3ef9af91, 0xcd2af33d, 0x42ae99f7, 0xc8d6794d, - 0x37fa9a89, 0xe535cbba, 0x6a6613d9, 0xaa7b57ea, 0x60c2e535, 0xf17ea687, - 0xf7ed2e91, 0x788f4c63, 0x7eee3a28, 0x27a59f03, 0x2d9ee43d, 0x06f4d53b, - 0x85fe273e, 0xafda2383, 0x8ec5cd7c, 0xf4bdf037, 0x9f9f472b, 0x9be67e92, - 0x3180b6f5, 0x53393fb6, 0x83df082d, 0xf3f1d7a0, 0xfb25ef53, 0x937880fe, - 0xa0a6a7e7, 0x5090195f, 0x9fb9db75, 0x5c32efe2, 0x6efdc458, 0x943111c7, - 0x7f276e4f, 0xd34371e5, 0x79e47fb3, 0xf728b903, 0xaf9bebae, 0x8b94f759, - 0xcbbacd3e, 0x3c28aad9, 0x5729a1dd, 0xd4d6ee39, 0x5eb99e9f, 0x6ba67df3, - 0xb69e144b, 0xba37ca6b, 0x53c28e1f, 0x9e9e147b, 0xf4977cd2, 0x5ffc2ddd, - 0x0adfa1af, 0x3d42939e, 0xc9878895, 0x1f08faa7, 0x2ada7a13, 0x1cd74f11, - 0x957c20ef, 0x2895bd04, 0x348ecb2e, 0x20cf81bd, 0xddb0cbec, 0x7a4ce681, - 0x91766c1e, 0xf370ebff, 0x691e7a48, 0xfffbd376, 0xcf409e68, 0xe87b355f, - 0x33cd9ff9, 0xecd3d9e8, 0x734767a5, 0xae7fd507, 0xcffb8bb9, 0xddeffb52, - 0xc1bf45c8, 0x01a85d79, 0xc18ec623, 0x9e9e495b, 0xc79d084f, 0xeb7f06f2, - 0x3420a9ec, 0x901d67f0, 0x9e207f2f, 0xfb4f2e45, 0x1e0e7860, 0x19fdf8cc, - 0x43a37f22, 0x3b4429e7, 0x0fe3f47c, 0x32e6a7de, 0x37bd69b6, 0x183a7f13, - 0x132866cb, 0x90f7e9b2, 0x93cfbc1e, 0xa8b3d8c3, 0xf7bee84a, 0xb9636707, - 0xe79efc57, 0x241fc7e0, 0xc75bfc3b, 0xe2033dd9, 0xc707a3ec, 0x7b3fb388, - 0x7f4765ca, 0x46afd1cf, 0x471e11d8, 0xc3cbdf85, 0x3bf80d0a, 0xa16ae51c, - 0xf1ecf501, 0x5421e738, 0xe0c97953, 0x7bb75c52, 0x5f91e51e, 0xe1dfa06f, - 0xfdf0a39b, 0xec97acaf, 0xf7a0fae2, 0xa7ed1346, 0x2b3ce98e, 0x957a3f90, - 0xce10c7be, 0x14fe3d37, 0x7b5ea9e9, 0xafc21e5f, 0xbcbdf1fa, 0x4c7becec, - 0x0d944771, 0x8f953e1c, 0x6fdb393f, 0x33e15efb, 0x0d11d71b, 0x1d83b99f, - 0xf4115f7c, 0x201da2e4, 0x3daac7cb, 0x2c5714f5, 0x75c30cf7, 0x389af51c, - 0x81ed7aff, 0xf237e461, 0xf08bce94, 0x360cf4ff, 0xa2e7fad0, 0xe83f44de, - 0xd6207d42, 0x1f9e15ef, 0xa23dedcc, 0x2e67dc13, 0xe0bed2b0, 0xa3df8e98, - 0xeedf5d10, 0xcfa3fbe2, 0x9c87dce2, 0xdc57be28, 0x0becff54, 0x5aef5fd0, - 0xebdd750b, 0x58f6411d, 0x1740136f, 0x54f7ba68, 0xddfe39d3, 0xa12016e4, - 0xf82def38, 0x6cfef82f, 0xfc5f9df7, 0xb07fea06, 0x1d26ead6, 0xf04518e2, - 0x2f2a285b, 0xfd93354e, 0x6e4e78b4, 0x5bc5ea05, 0x56f0bc44, 0x614e9abb, - 0xe8d93543, 0xdb967e80, 0x0403370a, 0x6ab4cad9, 0x5364fe23, 0x9b1dce4d, - 0xe87ab9f1, 0x58f22376, 0x9b7d98dd, 0x07ad8cd1, 0xf9252e16, 0x19a77a17, - 0x3adb75e6, 0xe7ef8bbd, 0xdadaf9e4, 0x22f7946f, 0xc898f7e9, 0xd020024f, - 0xa5c9357e, 0x4949f668, 0x181f4e82, 0x6331e22c, 0xda4bd8d9, 0xe44ed778, - 0xdf8bb3a3, 0x1e271e19, 0xec2efda1, 0x7b8adfc7, 0x4fefa39e, 0x5c3ae391, - 0xcc75ff7c, 0xf6899408, 0x07ae42e4, 0x7cffcdc6, 0x7fac2943, 0x4743b75c, - 0xd5b70d79, 0xb87880bf, 0x68f025d0, 0x4fc85d60, 0x7c97f937, 0x4c421bf0, - 0xf0dce69a, 0xbba5f495, 0xa91951c7, 0xde424b2f, 0x397d48ca, 0x12adafa1, - 0x8fd4a2f5, 0x211ae6c1, 0x8e489b8f, 0x475e6c1e, 0x7ecdc3e5, 0x6e691e7a, - 0x8db8f215, 0x79aaffbe, 0x01c790a7, 0xd2f78f21, 0xf9e6eefb, 0xd9ad7cf4, - 0xa985cf47, 0x6e11d7be, 0xd73b8e32, 0xdcbca3ec, 0x189b0f43, 0x742ef1c6, - 0x038f289b, 0x47b1e238, 0xc94f30d2, 0xa344e744, 0xe5a295f3, 0x743d3f7c, - 0xe5b7b80e, 0xfef7e46d, 0x17b4233c, 0xa7a7c707, 0x4765cca3, 0xe0f1f4b9, - 0x8e8724f3, 0xb4765cba, 0x2e3e4fa7, 0xdd971eca, 0x0d3fe500, 0x71fd25ee, - 0x9bb2e7d4, 0xe3c9fca0, 0xdfbbfcbd, 0xf940b765, 0xfc7dc1d3, 0xd051807b, - 0x2fe0ecff, 0x33958e48, 0x47f220e5, 0x2a7f39a5, 0xd7d00ba8, 0x2f9107e5, - 0x992e67a6, 0x60b17c8a, 0x72e88bb0, 0x41fd6ba6, 0xd91acf2c, 0x1515e2ae, - 0x46e15b1e, 0x5691576c, 0xa9bb62ad, 0xc46c7739, 0x6e86d376, 0xcddb2357, - 0x236fb318, 0xb7706f96, 0x2e9f68ab, 0x1a563940, 0xe59647ee, 0x65a72977, - 0xddd5dd3e, 0xe307d25e, 0x0fa4bcba, 0xe62a5c24, 0xff426f56, 0xe2976367, - 0xa9a5dfc0, 0x27f4ab98, 0x62ee6033, 0x0a93de03, 0x3dfffaf2, 0x87ac77ae, - 0xf9623675, 0xadb72a1a, 0xedfa06ff, 0xe2f6007f, 0x8000e831, 0x00008000, - 0x00088b1f, 0x00000000, 0x3cd5ff00, 0xe5547809, 0x9dcee7b5, 0x4c92642d, - 0xe2420836, 0x96249964, 0x26b6432c, 0x0c486410, 0xf90130ee, 0x10196544, - 0x044816c2, 0x7eab17eb, 0xe0171a19, 0xd16b8d69, 0xb5c46faa, 0x61e4b6af, - 0x1d0958d4, 0x87d252aa, 0xb410553a, 0x88a47479, 0x119099f0, 0xc7d278dc, - 0xf7fce73b, 0x24cee666, 0xbefd1480, 0xff938607, 0xcfd9fbfe, 0x005ffff9, - 0xb3f85380, 0x34607f02, 0x3d2538fe, 0x0468048c, 0xd1bf67f1, 0x0395b26d, - 0x8c0734ac, 0x412fa3a0, 0x6010aba3, 0x76960eaf, 0x24a40014, 0x0b7afcc3, - 0x74b08d96, 0x5de7960b, 0x05480368, 0x20bada68, 0xda85816e, 0x6066e3bb, - 0xe21745fb, 0x52ce38af, 0xe0546e05, 0x9bd40a93, 0x4f34899c, 0x1fd24d9a, - 0x856fc7ca, 0x064a7850, 0x3d9ab7e8, 0x448004ba, 0x0dac7b93, 0xfb9bedc7, - 0x8758834e, 0x31d688af, 0xeb1ebd6c, 0x6c3200e3, 0xca1f1e56, 0x5e541982, - 0xc846ed09, 0xcff5b846, 0xda22a4fb, 0x2327c597, 0x5f434e84, 0xf9ec5f20, - 0x63fe1654, 0xe0543d06, 0x6e03e97a, 0x70d79969, 0xea566020, 0x743967f1, - 0x226670ec, 0x7ed45ede, 0x18bf046f, 0x7dfb43bf, 0xbe8de215, 0xbf697537, - 0x0f5b5403, 0x0230438d, 0xd9dfb8cb, 0x855efe12, 0x878f0dff, 0xc3c06749, - 0x10f0a1a4, 0x1af01fb5, 0xd7de8e41, 0xa66ecb0a, 0xc0bee473, 0xd1fcca9d, - 0xf7218108, 0xf445f2a7, 0xfe05dafe, 0x25ff02f5, 0x5a74e736, 0x38fcdd5f, - 0x8e005390, 0x4d79356d, 0xa9ffdc99, 0x1744293d, 0x2d837593, 0x5b5b3e9a, - 0x00de8367, 0xcdd5adb0, 0x14bad7d0, 0x3f8076f4, 0xf97336b5, 0x2e16d6ad, - 0x30f568ef, 0x8ebad9dc, 0xdb5a5fe1, 0xeb577eb9, 0xdbbf2e46, 0x6fe865ea, - 0x5fbf917d, 0x86657f3b, 0xff4d12db, 0x45cec9d5, 0x7b9e8fc4, 0x3e9913aa, - 0xc853f7b8, 0xc81a9eab, 0xc344b66f, 0x9d658301, 0x8f65c094, 0xd9e1f711, - 0xc36de316, 0x8c73fd7d, 0x19c689bb, 0xad7e09a8, 0x4a437c43, 0x30d0f180, - 0xbe9abdd2, 0x3a1c464b, 0xe4f56689, 0xeb0efe12, 0x6407bf3c, 0xd39b56d9, - 0x383e47a5, 0x17558f1a, 0x6582dc00, 0x78f3ce0f, 0xfa85abaa, 0x48c07e41, - 0x3fa29ce3, 0x097c7193, 0x3af07766, 0x0e1ca210, 0xb1e808c4, 0xd18f2c49, - 0x40ddc850, 0x60f99fba, 0x1913e9e0, 0xcb3382b6, 0xa8f870c5, 0x9e03ab93, - 0x6567a432, 0xd584c3ac, 0xa4f8127d, 0x46538412, 0xd38e00d6, 0x13d46e97, - 0x5644149c, 0x9fc3c750, 0x6322dfc9, 0x14cbf186, 0x6b94d448, 0xed35a3cd, - 0x9a99aceb, 0x5cf4befa, 0xb4d2ff1e, 0xfaed348b, 0xc59a5746, 0x232f53bc, - 0x6f7465d8, 0x0974805c, 0x9b1c9956, 0x98bdfeb0, 0x062822f8, 0xbf1b1698, - 0x317be089, 0x376a5e19, 0x14c9c0ed, 0x934e7dc0, 0x108b237d, 0xc6db9755, - 0x99edc76b, 0x76c36353, 0x6957e657, 0x25c121d7, 0x1dabdfb4, 0xa7df3453, - 0xe9ae5e57, 0x93fb32ef, 0xcef5ad08, 0xc6f7cd7a, 0x9f41af96, 0xe5b1300c, - 0x014be824, 0x343afbc6, 0xecee94e3, 0xbf1fb4d2, 0xeb12641b, 0x378e7d92, - 0x741f9609, 0x152ac4ca, 0x24df9b87, 0x3fa5f558, 0x4e01f683, 0x9f5159b0, - 0x83dc8a4b, 0x963d0247, 0xcae52927, 0x812db7a0, 0xf21270e8, 0x89bf48f5, - 0x6321c230, 0xbff2a963, 0x4c1f104e, 0x32002052, 0x16abf607, 0x3a79804b, - 0x4598d78b, 0x1be5056a, 0xc906c1f5, 0x3847a691, 0x50540e47, 0x8a0428f9, - 0x973aca08, 0x2a6bf89e, 0xb2a58f34, 0x0469dc09, 0xbf74483f, 0x2fdc7c4f, - 0xe2c4da05, 0xcfc4c982, 0x68ff3f75, 0x17ac6dde, 0x5c261c62, 0xfebaefdf, - 0xfd6b4a91, 0x91f53fbb, 0x7e216c37, 0xcd7eb26f, 0x8dcb5278, 0x7f19c72d, - 0x2d6fb96a, 0x92e177cc, 0x9f680ddb, 0xaffe3610, 0xed0a76cc, 0x53a23ada, - 0xb8c9fc23, 0x1ed420ba, 0xc418be3a, 0xbfea3177, 0x04d35a7a, 0x5ddfd7c2, - 0x6f576c4e, 0x9e087210, 0x1c4ef545, 0x29463ea7, 0xa7d44f83, 0xb2a1ed2a, - 0x6ae9cb9e, 0x6f68957d, 0x587bc757, 0x96ad1fb4, 0x522ef195, 0x9ca2cdcb, - 0xa0f7cea9, 0xe5aa1728, 0x397170ff, 0x613fb44e, 0x29ef559b, 0x53ffe908, - 0x0f18ddaa, 0xa06ec9e3, 0xc933903d, 0x1abb481e, 0xeda21f98, 0xb15eb685, - 0x237ff317, 0x44c58c7b, 0xdf63cb8f, 0x90eeb921, 0xf1bae480, 0x8bd38376, - 0xd49e7ff3, 0x12c6b451, 0xb7e7dfc2, 0x6abb7c08, 0xb6329ce3, 0xde6af95f, - 0x3923e226, 0x85c8f76e, 0x563addf8, 0x4ea77ac7, 0xe88138b6, 0xfbd0af7b, - 0xd848ff6a, 0x8686f2d0, 0xb2f5519e, 0x6cc1f3c4, 0xfaf9c1fc, 0xf4f51bef, - 0x8e59c206, 0x9370973f, 0xdcf42999, 0x95add448, 0xea36f3f8, 0x3dd23359, - 0x3a9c1b25, 0x1af29f6c, 0xf1a267ea, 0xc7d0bf41, 0x24f8c5af, 0x8f959c14, - 0x6ff6c9bd, 0x8e528ca1, 0xcf2d7bf8, 0x7c89979d, 0x9fce347a, 0xd0db7c4b, - 0x75d78db2, 0xe3cadd8d, 0x10583583, 0xcce2cf8e, 0x9e97fc28, 0x3fa5ff01, - 0x8271fe26, 0x75cfa403, 0xbeb47428, 0x78b796e5, 0xef95cbbf, 0x43325fac, - 0x472cb8ed, 0x39c68f97, 0x0e1f0832, 0x74074e85, 0x5f050ab6, 0xfabe1357, - 0x1373fb17, 0xf9f0ecb1, 0x3ed9ba47, 0x88972aec, 0x4071cdee, 0xf92a3f74, - 0x410ef68b, 0x0ed68eff, 0x5a5bcbb6, 0x84be18bb, 0x55bad073, 0x8d10dd7c, - 0xc067f9df, 0x131ffcef, 0x01f4a3bf, 0xadfb03a3, 0x4e3c07da, 0x1180ff85, - 0x2b4cf4c2, 0x27e225f1, 0xfae24ba1, 0x2120b93a, 0x138fa9a0, 0x738e52fe, - 0xcae9f13c, 0x37aabb19, 0x98792148, 0x311d0b1c, 0x0ed7cc49, 0xc41daf85, - 0x22ff2ad7, 0x11ea963f, 0xc49d6fcf, 0x37e0437e, 0xf3c0bfc4, 0x3bba78a8, - 0x881baf1a, 0xabc1a78e, 0xc607feb6, 0xc7fa276b, 0xaf8237a4, 0x653778c4, - 0x77f9e346, 0x7c555e0a, 0x7fe4536f, 0x236f3c38, 0x7f9ea73c, 0xb4cb6f3c, - 0xf891b8f1, 0x453ece1e, 0xf75d47d2, 0x7e5a7210, 0x2d3a722e, 0xdff8aadb, - 0x461677e8, 0xa26dfdd3, 0xf74359bb, 0x53c8339e, 0x4f298fcf, 0x848b7891, - 0x3ab8128d, 0x3fdfd12c, 0xdf561ccb, 0x4e3c179d, 0xf8d6ce0a, 0x75bf9367, - 0x29b3fc6b, 0xfd696118, 0xe5349bd8, 0x9aadeb3a, 0xada697f6, 0x6e5fd4d5, - 0xbfa9af5b, 0x4d01ff32, 0x63c76af9, 0xd3e67e11, 0xe77afa9a, 0x73f5346f, - 0xea6bb79b, 0x68f4b7e7, 0xfe7817ea, 0x78ab29aa, 0x1c0adadc, 0x356b6d2f, - 0x65d3f12b, 0xfe03ab0c, 0x8b83125a, 0xdfd9070f, 0xd7b7f4ac, 0xafb24bb2, - 0x32d1fd83, 0xc296ab9f, 0xcd9d8aaa, 0xb5f4126f, 0x2d78955a, 0xad5be18d, - 0x3befd636, 0xee19f35a, 0xf128756c, 0x5dc3255a, 0x4e254ead, 0xb48c3173, - 0xbb66af0b, 0x3d2164a7, 0x44bcbda6, 0xe980b807, 0xc167f87f, 0x77bc5a5e, - 0xdce28ebc, 0x8e5eca35, 0xffb37f57, 0xe3afe436, 0x950726cd, 0x311fb77b, - 0xf9a30ad8, 0x32b7ee65, 0x6cf8c338, 0x0d5fcb6e, 0x45cd67e4, 0x0863ba0f, - 0xa59a9d39, 0xf7207e63, 0xcc2f5003, 0x05218336, 0xd9ecc1f5, 0xf80da392, - 0x189207bb, 0x3f58dcfa, 0x133e0f4d, 0x7a2deb96, 0x979e299f, 0x3fa332e6, - 0x132c4b3d, 0x50f07a4c, 0x7324a43d, 0x7d0d7e9c, 0x383ca1b4, 0xbf18b865, - 0x1c3f22cf, 0xe96f5dfb, 0xbddd9030, 0xfa2fe76e, 0xb87ac36f, 0xf1ce53d3, - 0x25625c3d, 0x3e792dfd, 0x371a9dd6, 0x3520bcbc, 0x5f1850e1, 0x4e19254f, - 0xe1d1f8a5, 0x7adc5277, 0x9cf1c193, 0x05dfba2d, 0xc9a77eca, 0xc16ffb12, - 0x4dde4dd7, 0x713e4852, 0xb84d3b7f, 0x01e226cf, 0xc1b367da, 0x7e445797, - 0xb3f676f6, 0x16d72a9b, 0x2e9a9d11, 0x15313e91, 0xa69de285, 0x8fd92f96, - 0x91cfd48f, 0x90f14cf0, 0xfe656fc3, 0x93badfdb, 0x8b8d45f9, 0x5c7d5b7a, - 0x6ab80b2e, 0x39a3e3c3, 0xa64dff93, 0x4beaa7b8, 0x3c4cff11, 0x53fbdce9, - 0xd5a077dc, 0x17e52fff, 0x9a82bcd4, 0x5bcc8867, 0xde647aa8, 0x6e0975ad, - 0x2c9aefdc, 0x94f30651, 0x5ea3a674, 0xdedf5540, 0x9765159a, 0xbd3ac8ef, - 0xffd6d67e, 0x6cf9fac0, 0x4d31bff9, 0xbe48d5d8, 0x05e337df, 0xe553ad03, - 0x9ffe48ef, 0xfe707d43, 0xd7924d39, 0xf67a7a83, 0x44c37692, 0x7df9dce9, - 0x88a0e5b9, 0xc2ed238b, 0x3607b6f7, 0x2b5c9ba6, 0x92617c73, 0x1e50726f, - 0x4743a544, 0xcf3add34, 0x1fceb740, 0x76d16e93, 0x73bce0f1, 0xf1a08bb3, - 0x8acbdfcf, 0xc83e27f2, 0xa91fbd3a, 0xf781ffad, 0x636b1d6d, 0xef4472b8, - 0xea27593c, 0x01627c45, 0x80eff21d, 0x74b8e657, 0x3c7b6669, 0x195033c5, - 0xb77d278c, 0xf2065bac, 0xd4ef410f, 0x5cfe468f, 0x1f67f0a2, 0x7e243ef8, - 0x7ef7055c, 0x25980941, 0x22ae4bd5, 0x09f4b73d, 0xfc4f0843, 0x27f393af, - 0xcb7e94ab, 0xda469d2d, 0xb567f2ef, 0x1a71d4ed, 0x1fc88a5f, 0x19fa5f57, - 0x73f0ddb0, 0xa7556fde, 0x5977dfb6, 0x62872971, 0x084b1659, 0xa7d267ef, - 0x1baec947, 0x5b27cac2, 0x3f20bf39, 0x9e03e0f3, 0xc4fa21b1, 0x71f14764, - 0xf9e9f65c, 0x23ff5b58, 0xf71cb1f3, 0xf9e891ac, 0xbf78f97d, 0xeb4599dd, - 0xa0f3f556, 0xc4c379de, 0xdca0677a, 0x37a4f226, 0x9e2daefd, 0x3804e4f8, - 0x2a161d88, 0x6a85d2f9, 0x369d74be, 0xcfb93a5f, 0x49b979c7, 0x716dbd07, - 0xbd89f748, 0x55dbce1e, 0x59b776ed, 0x5dd3fcb0, 0xa3fc994e, 0x64b96ff1, - 0xdfeab75a, 0x484efea8, 0xbeb0e58f, 0xf66bbce3, 0xd53bebd9, 0x30f6aa2e, - 0x06560ed2, 0xfec96bdb, 0xe3b6f84d, 0x2be7824d, 0xf7691eaf, 0x7a138bde, - 0x57c1a8e2, 0x8cfc97be, 0xcf1c63d7, 0xaffaf441, 0xc67e16cb, 0x0302cf4c, - 0x1f091fcb, 0x450cdbca, 0x764fae6e, 0xf54d975f, 0x99d0bd8a, 0xa3b2069d, - 0x23df7275, 0xf95f12d7, 0xde1bce65, 0xbf07c77c, 0xccedb5ff, 0xeb2685f9, - 0x863ff671, 0x749a338b, 0xa2f8a6e0, 0x4a56d6a4, 0x6dc50c7e, 0xf3544794, - 0x9fed918a, 0xc8acd7b0, 0xb5573ce6, 0xd9eb49df, 0x1c33d628, 0xbe5a9abd, - 0x8731e4d0, 0xbba9bf9b, 0x4c30badc, 0x16ca5e3e, 0xdbd22ef1, 0xa21cc87a, - 0xc5f2d9f7, 0x65f8b7ff, 0x091e0c9a, 0xe4a16ced, 0x082ffe15, 0xf80e783f, - 0x2083ce19, 0xf9583743, 0x38216a7c, 0x17022e18, 0xdbbb7cc3, 0x60337c4b, - 0xbe248e08, 0xbbf57fea, 0xfe9be202, 0x57b6278b, 0x5f3bf9c1, 0x06fff48a, - 0xfe78dbc6, 0xdbbe5781, 0x7039fc43, 0xf4ace187, 0x6764eac6, 0xe451f127, - 0x53bbcb79, 0x01d73e64, 0x8b967afd, 0x03e8ab7a, 0x1b72a497, 0xe64cd8eb, - 0x1cde908b, 0x37aab4f5, 0xc2bf6017, 0xd7ac744f, 0xb5e49960, 0x80aed363, - 0x70ac458e, 0xa657a671, 0x2fa8a772, 0x95e8995c, 0x15585cb0, 0x4a6fea23, - 0xc52642f4, 0xcb960143, 0x0fac00f9, 0x8bd08017, 0xf7938237, 0x96419189, - 0x6f17fd84, 0x3e709735, 0xa4390216, 0x8e288bff, 0xb74e221a, 0x2f7908e6, - 0xbefa12ce, 0x179b46b8, 0xc95b30f9, 0x4a6bdb1b, 0xe7561072, 0x1d12f738, - 0x1bfc938b, 0x7ca32a1e, 0xa1360e90, 0x75567d7c, 0xaa779f2b, 0x35ed1afd, - 0xcdbf84bd, 0xe2bc7012, 0x9f7936e9, 0x238ce713, 0xf2cdcfc3, 0xa807b5ed, - 0x7b5a11dd, 0xc578f0f9, 0x47f71c7e, 0xd78795cb, 0x1bb14c57, 0x43f1fbe7, - 0xe5cbcf25, 0xebe679ff, 0xf80b3bfa, 0x7e43c14c, 0x7ddda372, 0x046fd79c, - 0x9ffad0b0, 0x40147114, 0x47e50673, 0xd2653c97, 0x11f19f91, 0x03c8639a, - 0xddc61bf8, 0xe31bff04, 0xc77f8267, 0x27e099f8, 0xfc133f18, 0x04cfc607, - 0x1e3b7f17, 0x8d802283, 0x4e4b4e39, 0x301ce879, 0x1c86bd72, 0xf9c1cf81, - 0x7f3c8dbb, 0xf8cddd9d, 0xebf7a41d, 0x9973a5e0, 0x0bc189cd, 0x6fc34e92, - 0xf0dfdd03, 0x7870e9f9, 0x2325cf51, 0xe853bfeb, 0x67a9d45a, 0x15d45ffb, - 0x6b086f88, 0x918e4177, 0x395f0beb, 0x1fe34f18, 0xd7e20eb5, 0xa796e129, - 0x82f944e9, 0x08332d67, 0x677675bf, 0xe51bed09, 0x51f6833c, 0x83c1f5d4, - 0x7c78cb13, 0x75a364ab, 0xb8e51f04, 0x911f6221, 0xb5f75078, 0x81bfd139, - 0x257e6ffa, 0x7a82768b, 0x10dc8407, 0xed43491f, 0xcff32d77, 0xccb05374, - 0x7e9deb8a, 0x0a1e6e4a, 0x29f675ff, 0x5477e78c, 0xc7cf537e, 0xe952fe15, - 0x1df2ae76, 0x6b901e39, 0x6ae77e84, 0xb236a5d2, 0xc9e3274b, 0xee57ac2f, - 0xe6757419, 0xf4fb47bc, 0x6ec194ec, 0xc8d63e63, 0x5f8562df, 0x6dd85854, - 0x36bd1174, 0x59ca1f77, 0xe4fa6164, 0xb3f6c62c, 0xbc9aec72, 0x89d56167, - 0xe14a1fc7, 0xea9a56f6, 0xceba783a, 0x60dfe38a, 0x6d36fede, 0x93f5ae69, - 0xcf2c44ba, 0x1076934f, 0x9ccb605c, 0xe5a3649a, 0x37fd797a, 0x41d94fe6, - 0xa3957522, 0x29b9fd9e, 0xecc264a4, 0x9639ad43, 0xcb071f0e, 0x4d64d675, - 0x31b4d2f9, 0xdb97f69a, 0x57f535b2, 0xd4d38fe6, 0xe55ef3ab, 0x2bb4d528, - 0x51660a4e, 0x60fb875c, 0x64e780b9, 0x7da25daf, 0x1c62beef, 0x3f3da796, - 0xca6e41cb, 0xda7ea566, 0xd12f5a96, 0x69f10063, 0x70ea8744, 0x1f47fae5, - 0xe222c1a2, 0x67eec686, 0xe76d3876, 0x130c3710, 0x7100ac2f, 0xdc5c3f8e, - 0xa02f1910, 0xf4907cfe, 0xd7abf167, 0xdc70db58, 0x2e2755cd, 0xef3ee1b0, - 0x8238c1cc, 0x47128dec, 0x833fc70c, 0x04d92272, 0xf0c8f4ff, 0x03fc10dc, - 0x1f850bf0, 0x3ef69c05, 0xdf0533fa, 0x4a7dbf5f, 0x07f38dfa, 0x57efc51e, - 0xafbe4460, 0x6f78e8d8, 0xdea7e50d, 0xf9ce8191, 0x03ae24e1, 0x77e81beb, - 0xb0f7c439, 0x46bbe9e8, 0x0f77f0a7, 0x94aba6b9, 0x731fdffc, 0x71aabf14, - 0xcba35dfb, 0xf370f542, 0x70f69a27, 0xa6b774bb, 0xb6a6677c, 0xbb94ef7c, - 0xe70ffbc3, 0x5c6c3597, 0x9ca37460, 0x392c3c36, 0x8be843bd, 0x28a4f5c1, - 0x097ba1fa, 0xdb43dbeb, 0x716d1997, 0xe157edd1, 0x6cb79478, 0xaadec618, - 0x193aea7a, 0x7faa879a, 0x71cf9d47, 0x08fbe77e, 0xcdf64f71, 0xc3b09af3, - 0x8db8251f, 0x2fb27ce1, 0xf47b9c47, 0x1dc0f63f, 0xee79d35f, 0xeabe22eb, - 0xa3f6144f, 0x9d33f3a8, 0x08f1610e, 0xd6455fc1, 0xd2ec8e80, 0x0f58d2c0, - 0x2d359ca0, 0x8ae8f38b, 0x7e088fc9, 0x5e4f1e68, 0x9a0f2dc7, 0xeb1fce91, - 0x3cbb1a74, 0x9616c140, 0xd9fd9efb, 0xf7e93b8c, 0xe92f7102, 0x2fb3ed7c, - 0xad7d8407, 0x1e637a11, 0xb7629ff1, 0xd3565500, 0xc768305d, 0x5e10cf48, - 0xbf6b9ca8, 0xc987fdf5, 0x7a11efcf, 0x370af283, 0xb4e05fb0, 0x1d0df368, - 0xbbf8e72c, 0xd73efc2d, 0xb78feb59, 0xf3968dda, 0xd84647a8, 0x218779b5, - 0x57fbc5f4, 0x5e9b3d22, 0xd05ef997, 0x04f6adb1, 0x911fd308, 0x28da6c78, - 0xe5ab9cb3, 0xcbe55ba3, 0x830f6cbc, 0xd185f519, 0x83a706f8, 0x55b57fe5, - 0xd27ab7cc, 0x4ec83337, 0x8bd6eeaf, 0xcdc32f4b, 0x5b064eb3, 0xb79b3cd8, - 0x5d929699, 0x603fd753, 0xf749f455, 0x0a534957, 0x843b5c04, 0xc0bf457d, - 0x417e4290, 0xecf1c4bd, 0x3551ee9e, 0x123da784, 0x3c256cf8, 0x5c6635c4, - 0x1c314cdf, 0x5e50b77d, 0xf9f2d214, 0xd71aa59e, 0xacecf1aa, 0xf27659ee, - 0x5cec3f63, 0x072907b8, 0xccd9ec93, 0x8782d74f, 0x893deefd, 0x93ca74ae, - 0x3fee534c, 0xf60c49ec, 0x67bdbf91, 0xf744ac52, 0x3bfc7019, 0x5f757c69, - 0xf4ae0c7b, 0x9297de66, 0x44fe752f, 0xf67b153e, 0x67aaa271, 0xa7dbe4eb, - 0xf7e7495c, 0xf14ac073, 0xf85974ec, 0x2147f0d5, 0x6d5eaacf, 0x6c49fc92, - 0xa633edaa, 0xa34f11db, 0xe4a97e5a, 0xf735db7d, 0xafd6cf00, 0x5fa38c1e, - 0x567f9894, 0xb1bc4439, 0x47f3faaa, 0x57f9c5ae, 0xfe4fbc61, 0xedaec2dd, - 0x917f08fb, 0x7c60fdf1, 0x7be62ff5, 0xd733e3a3, 0xcddfda32, 0x73df1c77, - 0x69c7442d, 0xea817183, 0xcb173e5f, 0x58a8d6e7, 0xfc287c85, 0xee5b647a, - 0x7f5835de, 0x66062fe4, 0xfd2737d7, 0x58ade8ea, 0x58b9f9be, 0x2491f3c6, - 0x391d90f0, 0xebcf29b2, 0x744b06c1, 0x6fb25ec1, 0xcf8e25b0, 0x327b3e69, - 0x512fb7ef, 0x76b7f27e, 0x7e4843f6, 0x7cc2e86c, 0xe88ff746, 0xb9a3cbfb, - 0xbcc5b81f, 0xca5c8a0d, 0x5fde142f, 0x242ff54d, 0xa5427e73, 0x6327e1df, - 0x7dac149c, 0x2b22be05, 0x92e7deb2, 0x5bdd10e7, 0x697ba15c, 0xf97c84bf, - 0x06f708d5, 0xc7f2f7da, 0x89c3f3ff, 0x17da9fb8, 0x1555feae, 0x07d96fae, - 0x84e340a9, 0xdfb43ae8, 0xb66b6c70, 0x3f057f90, 0xf18c5e2b, 0x27d30c1e, - 0x35123b2b, 0xd1aea6e5, 0x7a6183de, 0x729ef068, 0x04e7c4a3, 0xed5c8a8d, - 0xeddbba37, 0xfba5d794, 0x713f4ca9, 0xce84b51f, 0xf7ff08ab, 0x91ff1899, - 0x5da2f67c, 0xf3566739, 0x4e60c93c, 0x0b75b923, 0x97dc0dfc, 0x31e289b7, - 0xf1493d9f, 0x33b9823b, 0xb3f9c30a, 0x9c1bd577, 0x7b8931e7, 0x9f43318f, - 0x13da77eb, 0xf9837db9, 0x699e4d4b, 0x4d09cb55, 0x015567fe, 0xd2501fb0, - 0x89bd2b66, 0xba1487ce, 0x7aee9fdc, 0xf1def18d, 0x18bbabc0, 0xf2dc4f9f, - 0xd3bbcd31, 0x5d83f4c2, 0x11163c4a, 0xbf98356f, 0x69efe450, 0xe87e7f8d, - 0x9445bdb1, 0xcaf438ff, 0xd3ca22b8, 0x87fd942e, 0xf7c99d7e, 0x86dff69c, - 0xf7cecb70, 0xb91e2f39, 0x0c7ba8de, 0x8d43d092, 0xba648fb4, 0xc77ae3ff, - 0xf42e72ce, 0x850d81c3, 0x1f353f8c, 0xe864703d, 0xa75d5078, 0x3ebabe3a, - 0xddb57c75, 0x5f22ecdf, 0x17f46fd0, 0x415ffd91, 0xfb6130e7, 0x17f78fea, - 0xbbe85a25, 0x4913f855, 0xb7e30e58, 0x2abcf57f, 0xf06a7cf2, 0x47c9565c, - 0xfdadd3ed, 0xaff91199, 0x8321e3af, 0x7eef5c3b, 0x752a73cf, 0xdafdeabd, - 0xfd85ab7e, 0x2576939b, 0xe90e9f1f, 0x1deb0ed4, 0xb7bff23e, 0xc7e41c98, - 0x905c9a27, 0x3469f88b, 0x9afef8fa, 0xe4d12fda, 0x7991efe6, 0x234481f9, - 0x81e5bdd0, 0xf7fce554, 0x42bd602b, 0x9c16e871, 0xd756acb7, 0xd212c5bc, - 0x2cfeaa87, 0x0bdf871b, 0x3ea91ee8, 0xdf2027e4, 0xdb6b1594, 0x2da3f687, - 0xa0ae7bff, 0x6eb25963, 0x24b938c8, 0x1b65c857, 0x9e42c874, 0xa89d1d85, - 0xbf0d1de0, 0xacd7ee1c, 0x40fcf452, 0x0743d9bc, 0x8ab713bb, 0xf513ab7b, - 0x5104edbe, 0x124b400b, 0x89f4995d, 0xfab4baf1, 0x1cc86c9c, 0xd8e3cbb6, - 0xc8504f2e, 0xccd4b77d, 0xf7435bf7, 0xc132fd5c, 0xd0c8218b, 0x413d5609, - 0x4bc30324, 0x2a70c5c0, 0x0cbc3334, 0x015e19da, 0x02af0c1d, 0x89f8433f, - 0x1ed80daf, 0xff656edc, 0x3a25f2e9, 0xd765cbb2, 0xcf97ed0e, 0x3c35f052, - 0x57cb503e, 0xa63e3b9c, 0x8772f72a, 0x7cd8cbc5, 0x2f157be6, 0xec4fe226, - 0x34de0317, 0xc0209382, 0x46264ce3, 0xdd78a6ce, 0x6b7ef7c6, 0xbae5c9c1, - 0x6547c4b3, 0x1777adc0, 0xda97810c, 0x9e64f9a1, 0xb90327c2, 0xe951f8c0, - 0x8dae48f5, 0x30dd2acb, 0x7b234c50, 0xc84f4d10, 0xc59675a0, 0xa7a71cd6, - 0x5f3fb722, 0x7a8f5336, 0x66b4acb4, 0x5f90a90d, 0xe5154ee6, 0xd32f3589, - 0xf3fb7d51, 0x71728a97, 0x81c1a94d, 0xcbdae85e, 0xfa825e66, 0x27dcadd9, - 0xa011a337, 0xb672637b, 0x2b761738, 0x724dcaf7, 0x2fba5ae6, 0x580dba66, - 0x0063b8df, 0x22d7ecfc, 0xb8bc91b7, 0xb37b1c45, 0x3aafd055, 0x2e4b7dd6, - 0x2fb333d9, 0xb87486de, 0x28dd6d79, 0x18f79bb2, 0xa49ff8c5, 0x81bdc6da, - 0xc49932f8, 0xbf7556bd, 0xc189ef58, 0xadb24072, 0xad0cc969, 0x59c75d4b, - 0xe9d77bcc, 0x774fcde6, 0x023d206f, 0x15c70736, 0xbefb1463, 0x34c4cb65, - 0x1d7030f4, 0x20475e56, 0x0b4d772e, 0xee91dd56, 0x1bc6847a, 0xf87c1388, - 0x7529d108, 0x75cbe878, 0xc43b943e, 0xdfb581f7, 0xbd23eabc, 0x042e29f4, - 0xae4df9c7, 0x475a71fb, 0x51902e93, 0x45fbf48a, 0x05007a2c, 0x9096be21, - 0x0f107398, 0x1af04e6d, 0x77945e59, 0x99f9ca36, 0x8b03172a, 0x4fc43c71, - 0x8b55cb99, 0xcc5422ee, 0x60937e6e, 0x16bdbba5, 0x179e686b, 0x724d3d68, - 0xe4f881b0, 0xc607e268, 0xc76e594f, 0xf454fe0a, 0x9eb6f759, 0xa288c6db, - 0xb2e4c20b, 0xaf89db69, 0x6f7486ff, 0x5071663a, 0x3e3c90f3, 0xe79c46b6, - 0x46fa345a, 0x5d09d395, 0x9c383e26, 0xc5a2f5b8, 0x07d26ed4, 0xb7a4d9bd, - 0xda06f727, 0xe81e7dc8, 0xc8463bde, 0x7fd7ea89, 0x7d8b9d23, 0xfc8cccf9, - 0xf9104091, 0x839c5e23, 0x8af4fc73, 0xad5f0738, 0xeca93de4, 0x788b7de1, - 0x573b8d54, 0xde2dbcf6, 0x6ff07985, 0x122bbd05, 0x713e967f, 0x6fc455e3, - 0xd48bef91, 0x6949b478, 0x7bd7a2b7, 0xf227ed37, 0xc51351bd, 0xbfc345a3, - 0xa27a6a37, 0xc8d1e396, 0xb9bd46f7, 0xb14afe4a, 0xa1f8a08f, 0xb436944b, - 0x87c70b3f, 0xf709af46, 0x35c9fab6, 0xd3952b0e, 0xc7d60e2d, 0xe10e3d57, - 0x6489e1ed, 0x9e5519e6, 0xd893ad97, 0x5af156bf, 0x49c9bcfc, 0x7e7e28eb, - 0xe8cdfb14, 0xe97b8bef, 0xde913e4a, 0x837bd012, 0x2cc189cd, 0xb9ba67ba, - 0xfe41df3b, 0x9d5a1ff8, 0x68430ff0, 0x503c6a7d, 0x4b54bf27, 0x2d8e87ef, - 0x3f0b38c2, 0xa679eead, 0xd5e58ccd, 0x1055e9eb, 0x13f384a5, 0xdf2aafc8, - 0xc6978329, 0xd543ef01, 0x39153b08, 0xc0e9a537, 0x188f8616, 0x0db008db, - 0x29300f91, 0x4fcd8bf4, 0x39c7d4d2, 0x4ff4d02e, 0xd4d2cca8, 0xf788c5b7, - 0xfa71e032, 0xef422a0b, 0x3f9d1248, 0x0083f4d1, 0xbd08adfe, 0x7e27b917, - 0x4f7e4eea, 0x3ce06fe2, 0x2565f245, 0x7926f69a, 0x5dfc4cab, 0x435ea5fd, - 0xa6529fcf, 0xb956f11b, 0x9c1cfd1b, 0xb69f4267, 0x01e0263e, 0x5bb317ea, - 0x984bc9af, 0x85f2da6c, 0x629e4a79, 0xe4d58c2c, 0x2ef10629, 0x61d8fef8, - 0x0545f31d, 0xbaaafce4, 0x006cf08c, 0x6f1a2daf, 0x5df840c7, 0x1c5ac6c7, - 0x426a96f4, 0xc932cbcf, 0x8b4baa41, 0xb5b351ff, 0xd6ed1ff8, 0x52cc7be2, - 0x9bd3be2d, 0xb0bef8b5, 0x4cd78b45, 0xd96f168f, 0xda6826eb, 0x346bdbdb, - 0x578dbce5, 0xe45fda68, 0x8f29a19d, 0x4d7af17b, 0x858ec2fb, 0xaee2fa9a, - 0x957a9ae5, 0x83e386cf, 0x11d5bef1, 0xdd03a6fc, 0x74a0f869, 0xf335cfe7, - 0x9ff450fd, 0x05e8a79f, 0x2bd7fe85, 0xf8dde576, 0xb892f7c3, 0x7a158b4e, - 0x50df3070, 0xee78e06d, 0x6d725b3d, 0xc505e91c, 0x7b14b9de, 0x894f3907, - 0x1d9455b2, 0xa2bf717e, 0x36ab9f64, 0x2cf746de, 0x8a8afdc4, 0x09b5edc3, - 0x1de23ed4, 0x494af4d6, 0xf91dde73, 0x67a66b2e, 0xd1209cad, 0x3f7144bd, - 0x841ef231, 0xdeab3efa, 0x2739a319, 0x96bdee1f, 0x78c25f9a, 0x2f148c01, - 0x3efccce8, 0x721fda31, 0x5fd9946c, 0xf6ffb373, 0x79cdc967, 0xfecc6ba7, - 0xecefe20c, 0x79f5eeb1, 0x3aa3b788, 0x3dfd8d87, 0x00d6fde5, 0x2fdf8c6d, - 0x3ca4ccf5, 0xbb8600e9, 0xdfd4d794, 0xbd2663b3, 0x5be5c45b, 0xac221503, - 0xe68f3fa6, 0x71a41fb9, 0xbbd6480e, 0xbbefb14b, 0x20cf3e13, 0x73a2667b, - 0xff3e12fe, 0xfc2f387e, 0xee147bfc, 0x406df50f, 0x79f0f367, 0x8e25cfee, - 0xc1a73e53, 0x77e4c2aa, 0x4f79419d, 0xb9b6e22a, 0xb8d4be0a, 0xff328e6d, - 0x29621c01, 0x5db9f3ea, 0xacbc667f, 0xe253eb48, 0x158766bd, 0xac71bfc7, - 0x7bef84a5, 0x221d4b39, 0xb8e357de, 0xb1f7f231, 0x87ba67b3, 0x88ed22b5, - 0x97869e26, 0x57cc8792, 0x42c5e646, 0x1fe316fb, 0x76cb1f58, 0x74fac0e8, - 0xc6863fce, 0x85f9ca3f, 0xfbdacdb9, 0x3e5bf3dd, 0x02dff0d2, 0xfa9a27cf, - 0x30d04a40, 0x781ff706, 0x1bd4f475, 0xaffd7f10, 0x9e282a98, 0xe4f5ba45, - 0x0fc68795, 0x897797dc, 0xb4ce1bf0, 0x1d79cfcf, 0x5afdcabd, 0x5bfb9f75, - 0xd03971f7, 0xefb8881a, 0xbfc4d1e4, 0x09fe342a, 0x0e8fc9f2, 0x431c234a, - 0xe76673e5, 0x57a9388b, 0xabda7779, 0x55ed3bbc, 0x2af689de, 0x957b42ef, - 0xbbeaa177, 0x9c095edd, 0x8e64bf74, 0x816a7ae4, 0x0f76efc4, 0x969b3ed1, - 0x5de88b07, 0x60715363, 0xbbf3249e, 0x7df423dd, 0x45bb7788, 0x69f49592, - 0x6ef435ea, 0xcf08f0f7, 0xd9d8b251, 0x50d789f9, 0x28d870bc, 0xc5f4a3e4, - 0x7bd2666f, 0xdd53c7bd, 0x3fbf89c7, 0xf31f6495, 0x9f12ebf3, 0x6033832b, - 0xef16719c, 0x13cbbf7a, 0xf32734e7, 0x0a89b9c4, 0xbd0be647, 0x9cb04a56, - 0x2e6f72e8, 0x68dabbbf, 0x385777e2, 0x7617539f, 0x7df2221f, 0x4d1fc95c, - 0x6a1fd23e, 0x5f2127de, 0xbbd3379c, 0xca675a39, 0x6ef126fd, 0xa0cfe02e, - 0x0f747677, 0xbdf245ca, 0x1de29c1b, 0xf0a6de5e, 0xf90930f7, 0x45bd3dca, - 0xb7a779a0, 0x7ec0e7b2, 0xe5af27d2, 0x53f393b9, 0x56c7ef43, 0x7f676fc6, - 0xc6df20af, 0x797ae2f3, 0xee17a8ff, 0xc79cfa24, 0x7e56617c, 0xd7fff479, - 0xf5bc3860, 0x5a3ff62f, 0xf77a1990, 0xaddef616, 0xaf2c3f20, 0x343faea7, - 0x42e5e9ce, 0xe5a97bcd, 0x93dd8f43, 0x7486724b, 0x5948f911, 0x88633f9a, - 0x05f3d3fe, 0x774feffd, 0x97f9a04d, 0x60bc8b37, 0x6fda6f88, 0xdce898f9, - 0x3ef21963, 0x723fdabf, 0xf5b72b9f, 0x9f703e30, 0x617f68f3, 0xf08cbcfb, - 0xbfb3eea5, 0x05a3ef7b, 0xdfdf73b6, 0x6e777df7, 0x6d71811a, 0x767950d2, - 0x7e613eb4, 0x3fed4999, 0x8fedaf56, 0xb1e5390e, 0xd1de48bb, 0xe254e96f, - 0xc4cbb21e, 0xee5daa17, 0x2920e254, 0x02ed83b0, 0x71724bcd, 0xfb61e4b7, - 0xda3be6a8, 0x947fb424, 0x61af7057, 0x685f217b, 0x775f1071, 0x49f9ef22, - 0x58cef41e, 0xc44773ce, 0x758b3fd7, 0xbc7844df, 0xa335aff9, 0xf2defe28, - 0x38942b97, 0x72abd84e, 0x69cb3f85, 0x4147da7e, 0x996df302, 0x730abeb2, - 0x55c9fb33, 0x5e4591e0, 0xac93c943, 0xdff1c1df, 0x141a01ff, 0x43d0aaaf, - 0x000043d0 -}; - -static const u32 usem_int_table_data_e1h[] = { - 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1894738a, 0x18357a18, - 0x326b3618, 0x31686830, 0x20318830, 0xaf8568e4, 0x9fa65371, 0x8181959b, - 0x81f98817, 0xd7881058, 0x6c303133, 0xff5e2260, 0xfb045111, 0xc303209e, - 0x197f2051, 0x6614ee90, 0x64055860, 0x2fe2031f, 0x1080be40, 0x100c8303, - 0x606115ff, 0xc1d20530, 0xc4036c40, 0x9bf145c7, 0x7c80827f, 0xbf2a08bc, - 0x279f8d1b, 0x25ff5f8c, 0x0ff2fc11, 0xc363c808, 0xc7e41632, 0x7a052247, - 0x29370207, 0xca8ff2a2, 0x543c3033, 0x51d06060, 0x919bf082, 0x6280ede4, - 0xec21e4c7, 0xb8c09229, 0x28b5ca07, 0x2a773762, 0x5004fe50, 0x34894bce, - 0x41d3dcf7, 0x8434afe5, 0x3ebc00d0, 0x03a8e414, 0x000003a8 -}; - -static const u32 usem_pram_data_e1h[] = { - 0x00088b1f, 0x00000000, 0x7de5ff00, 0xc5547c0b, 0x3d9cf8b9, 0x926eece7, - 0x2126cddd, 0x26c2bc21, 0xb80d4401, 0x41a00c40, 0x94520f37, 0xa2a1e1a8, - 0x24786c22, 0xf622ef21, 0xddbf1f62, 0x52c488f0, 0xd4c51f1b, 0xb051768b, - 0x40368bd1, 0x5c1758d0, 0x6d8b459e, 0xd5a045e8, 0x5e40137a, 0xa540b206, - 0xcffd45b6, 0xdd9ccdf7, 0x26364e73, 0xf6ffef6a, 0x9fdbfffe, 0xcccce61d, - 0x7cdf3337, 0x9be6bdf3, 0x91be6489, 0xf21387d8, 0x256efc25, 0x108951e4, - 0x9b4e1892, 0x9fc6933c, 0xedb10994, 0x3bea247e, 0x9e0c8499, 0xd146706b, - 0x64085fa2, 0x21064b4e, 0x758d65c9, 0x793dfa46, 0xe8bc7d91, 0x9819c308, - 0xbdbae47c, 0x720c8409, 0x8266f6d3, 0x7fe92fbf, 0xc637b73f, 0x79c87491, - 0xe131a285, 0xbc9a4afa, 0x877bfa48, 0x149bbeaa, 0x48dda675, 0xfd51fbfb, - 0x9085b720, 0x4678c31f, 0x40cba942, 0x78b8e8b2, 0xfd2e6f5d, 0xaf0e3a3f, - 0x295be8cd, 0x1c1a2210, 0x242444b1, 0xa0482326, 0x679fbe9d, 0x49d7ed3c, - 0xaa36a708, 0x49e74ac8, 0x0896b4c8, 0x808972f5, 0x76cd8878, 0x78e97b25, - 0xe22e7d57, 0x220d57bc, 0x27d69da4, 0x684ed392, 0x61c4953a, 0x232dc7bd, - 0xd57e4206, 0x07123fae, 0x199b1b85, 0xdc155e24, 0x0e210f06, 0xc7afc513, - 0x8f2ae98c, 0xc4c9a79d, 0xab210d71, 0x574c0e3d, 0xfa634679, 0xdb27d0d8, - 0xf9d00673, 0xe9d8320c, 0x63834848, 0x1191dda6, 0x2dc72786, 0x0938e730, - 0xae2926c9, 0x2f5a54c4, 0x4dc840d1, 0xf342dc84, 0x19082375, 0x5084ec49, - 0xbc933dfc, 0x019dca2c, 0x45e60779, 0x7cc37103, 0x2e033263, 0xc62de291, - 0x1c95cf69, 0x1bf8efe1, 0x785fdf80, 0xc1d6152c, 0xefcc1b7d, 0xf0ece219, - 0x46dd9e02, 0x7f5a26e7, 0x5e4ceca5, 0x468ae14a, 0xad832eda, 0x1e1094bb, - 0x1fc04cdf, 0xc9cc8fed, 0x30d7acd5, 0xb4224718, 0xeb05dc73, 0x75b27164, - 0x1574095a, 0xf2e61d61, 0x77655875, 0x38fd19d9, 0x11fa2449, 0xb1fa5aed, - 0x8fe96864, 0xba9fb17e, 0xbf69e79e, 0x3bed424d, 0xbd3ce953, 0x4dce0c4b, - 0xa160dbf4, 0x0af80051, 0x80c425bc, 0x41f92afd, 0x63a05265, 0x179e1ab4, - 0xf6f7e9cb, 0xefcf730e, 0x52e2062d, 0x2a5372e8, 0xcec4777c, 0x6626e3a0, - 0x6b4cec47, 0xe987f1cf, 0xc925d924, 0x4c0eef40, 0xac47041b, 0x477ce300, - 0x9c049b24, 0xf6a4727f, 0x08edd3ff, 0x377ae1f1, 0xda5475f0, 0x3d203c51, - 0x468b1f79, 0x3450883c, 0x17e70c39, 0xad17cf1c, 0x4a434f45, 0x5868e348, - 0x875f9a5f, 0x79a663f4, 0xb09be62b, 0x3fca1edc, 0xacc9e58b, 0xba5e5d3e, - 0x55e3bd18, 0x6eda1759, 0x4291c203, 0x38445e70, 0x9bbf5096, 0x94203f30, - 0x1fd625ff, 0xb7f7eaca, 0xceed251f, 0xf9c29e0d, 0x003b2ebf, 0xd6dbc29f, - 0x2e94adc0, 0x7c106e0e, 0xec0f9a26, 0x75fe418c, 0x9f0cfd7e, 0xd767e289, - 0xea0b9338, 0x8398df9f, 0xefedbcf9, 0x5e5a24db, 0x20945db5, 0xd679d86f, - 0x5bf141d6, 0xfc7f6a63, 0xb83dfa66, 0x602f245d, 0x9f71d377, 0x48b4e29d, - 0x92f9633e, 0xdaad9628, 0xc01e6bb0, 0x91336b2d, 0xeaa70a28, 0x6f3bd2cd, - 0x03d2f9a6, 0x552a8132, 0x838cea9b, 0x4f897e69, 0x8afc8168, 0x3f601f9d, - 0x0ca4b9dd, 0xe039f7f6, 0x752f945b, 0xee93dadb, 0x7dcbdfa6, 0x7ea00a5b, - 0x09c166f9, 0x7ebe5c4b, 0xbf0087d7, 0x211e55bc, 0xcd15f852, 0xdaa1c431, - 0x17db792f, 0xade309df, 0x9426477a, 0xabb291ed, 0x1891190f, 0xe02346a4, - 0x13d36ab5, 0xe79be046, 0x1fb0073c, 0x2f559f05, 0xbb687ed3, 0x2704d7ea, - 0xc0daad4c, 0x3785cdf8, 0x68bce6a3, 0x19d57981, 0x37fb4147, 0xbd42351f, - 0xebf15f52, 0xdf180e51, 0x8c016306, 0x6306fd73, 0x566f8a89, 0x3356ff34, - 0xe94d53ae, 0xbd19dd03, 0xce39e7af, 0x397c95b7, 0xdf484015, 0x4338cf92, - 0x339e87c5, 0x57fd21c4, 0x11c48b34, 0xdf781f81, 0x8760fbe7, 0xbe03f195, - 0xc0ed4b5e, 0x75ebc21a, 0x4fd7cec9, 0x88cd660a, 0xe71ee7c0, 0xcb91a3f2, - 0x7e41278f, 0x2e69f4d0, 0xf971d63f, 0xe271e4d1, 0x933d67f7, 0x71ef5d30, - 0x67bcfa61, 0x4f3ea61a, 0xc17bd611, 0x8dd30733, 0x7f7e371e, 0x698653c9, - 0xbf16a7b3, 0x8e59e2bf, 0x178f66e9, 0x59e6bfbf, 0xa78b6983, 0x9eadd311, - 0x3d5b4c26, 0xbaf7ac3e, 0x36d319a7, 0xff7e0b4f, 0x530da7b5, 0xe98027bf, - 0x9a5f584e, 0x98ed3c06, 0xc31cf6ee, 0x03a7af74, 0x9cf7eddb, 0xc72d74c1, - 0xe49b2dbb, 0x366f1448, 0x18394117, 0x91cae85f, 0x88be3e69, 0x7ae693e5, - 0x9f348c73, 0x8a79a6e4, 0x8195c1c7, 0x0fcd131c, 0x29e565ae, 0x66b9243f, - 0xb2f14f9a, 0xaeb5b4f2, 0x4f9a28dc, 0xa3e5646b, 0xa3737bd6, 0x8f947e69, - 0x39b75f95, 0xf3431b90, 0xf2b0b5d7, 0x67927eb1, 0x01b1f9a1, 0xd07f1f96, - 0xf9a56795, 0x9f2cedf1, 0xcf37a1f5, 0x1d59f346, 0x5d4dfdac, 0x9a58bc81, - 0xcac829bf, 0xf24ab96f, 0x2e4003ed, 0xb5cf980b, 0xd1c7e4e4, 0xe59dae7c, - 0x4b16860b, 0xb7f4088e, 0x0858ee53, 0xb0867c22, 0x7e5125d1, 0xf1d8d3b3, - 0x647d1510, 0x4baaf0a1, 0x2033fca2, 0xfe504593, 0x963af0b0, 0x19648c07, - 0xbc2a3f94, 0x65bbe58d, 0x5cff9607, 0x46f2c038, 0x87ff9607, 0x7bf30870, - 0xef961765, 0xf2c4fe10, 0xff961746, 0xf981385e, 0xcb1bb2fd, 0x962e853b, - 0xfcb1ba37, 0x5753e949, 0xdf2fed3e, 0xdc2e9ee0, 0x5ddb7208, 0x6a597286, - 0x597e0649, 0x04fff9cf, 0xaf2d0640, 0x3944641f, 0xacf3f3b8, 0xd3814517, - 0x97c800f6, 0x05fa04bc, 0x485b3385, 0xc2827d04, 0x7386fb11, 0x349317cb, - 0xa2f96e70, 0x20f3814c, 0x1fea89c2, 0xdc5f9d9c, 0x17cf1da4, 0x129c0ae5, - 0x7fb5979c, 0xcbe5baf3, 0xbe78ed6c, 0xd4e054ac, 0xfeb89c20, 0x4f20278d, - 0xc809c0d4, 0xe59c0aa5, 0x7fb12708, 0x271971e3, 0x8cb8e06b, 0x7538144b, - 0xff506708, 0x378c04e0, 0xac63c76b, 0x863ce050, 0xbfd61e78, 0x534cb979, - 0x5531e3b4, 0xc29e7029, 0x0ff6a4f1, 0x16ab6ece, 0x21adbb3f, 0x3847acfc, - 0xaf37fb23, 0x3f169b5c, 0x7e10b6b9, 0x6b9c2136, 0xb76707fb, 0xdd9f8b4d, - 0x5e7e10b6, 0xe98cfc43, 0x6372bcdf, 0x8dc9f8b5, 0x0de7e10d, 0xfeb8cf1c, - 0xa26f678d, 0x137b3f16, 0x2009f843, 0x37fb1b9c, 0x2d24fc9e, 0x4293f27e, - 0xe10779f8, 0x9c1fee4c, 0xfc5a49bd, 0xe10a4dec, 0x67080fe7, 0x95e6ff4a, - 0x9f8b503f, 0xfc2181fc, 0x7270807c, 0xa94ccddc, 0xbdac70a4, 0x4c3fd9c3, - 0xc3fd9f8b, 0x8939f842, 0x3852a670, 0x29c37de9, 0xa7e2d148, 0x9f842520, - 0xb6e708f3, 0x9fd9c1fe, 0xfecfc5a2, 0xae7e1094, 0xfa3b9c20, 0xe182af37, - 0x0c14fc5a, 0x55b9f867, 0x8672871a, 0xd8274eca, 0x9a19dfe7, 0xc13212e3, - 0xd179624e, 0xf7a024ee, 0x433e8a88, 0xad225dda, 0x371cd96f, 0xd6a231fe, - 0x068d726b, 0xaa56cf4a, 0x9af5a9e5, 0x1ad149d8, 0x15ce2a3d, 0x4c27c9af, - 0x9fa9ac1b, 0x29a69458, 0x3ae7381f, 0xf720f94d, 0x487e4d78, 0xfa9a4dd9, - 0x35736ac3, 0x6fcbe1f9, 0xf54fd4d7, 0xd3e4d4ce, 0xa9afdcd7, 0x8171b23f, - 0xa69afca6, 0xb5f94d72, 0xfc9aa5be, 0xd7dfcdf5, 0xb2d31fd4, 0x437e5342, - 0xf29a63db, 0x35278171, 0x9e0709f9, 0xb1bfd4d5, 0xf94d05fd, 0x68af63c4, - 0x6c7727ca, 0x3e6fe4d5, 0xfd4d6bf3, 0x9addc129, 0xbd9fadfc, 0x439fa9ab, - 0x6fab53fe, 0xd4d03f9b, 0xa13f6a9f, 0xf24eff29, 0x553d3a27, 0xccaf1f6b, - 0x32afcc21, 0x01afd988, 0xc6f311ab, 0xa76616c1, 0x271c4b58, 0x7718fd29, - 0xa00c742f, 0x033403f4, 0xe0ce5176, 0xe83a6bb2, 0xe4ddeff7, 0xbf4ec6be, - 0xbee8cf7f, 0xbf411ec1, 0x9026f4a1, 0x061d4864, 0x8fe5f548, 0x73de8cca, - 0xd51d5c87, 0x18d7db49, 0x68e2a382, 0xe73123fe, 0xf9c7a03e, 0x83ee0306, - 0x42d49168, 0x411368bd, 0xd4d1e9bb, 0xaabd17ac, 0x1866b0fd, 0x308433d5, - 0x3bb235dc, 0xc328f519, 0x9bd03af8, 0x79d187ea, 0xd164260d, 0xbcbb718a, - 0x61fb6823, 0x8fe0c925, 0x3f991930, 0x91bfd424, 0xfd819ff6, 0x6bfe812f, - 0x94dfe97a, 0xbfd34936, 0xd34ca539, 0xfb48d9bf, 0x90f213b7, 0xbfde26e1, - 0xcb36fd19, 0xfec64c56, 0xd865294d, 0x6a46a3ff, 0x8ffba977, 0x88fff50e, - 0x31ebf681, 0xc7b9bb30, 0xd26ed3fc, 0x5ca53fce, 0x9b237f3b, 0x2e434aff, - 0xe71a3fef, 0x0e456abf, 0x394a7f9b, 0xc189bf9b, 0x0b6ff50d, 0xfa01bfe1, - 0xfd2f69ff, 0xb5b3d29b, 0xa95e1ff3, 0xf589bf9d, 0x76e194ff, 0xfb05bfde, - 0x6dc57a7f, 0x2bc3fe6c, 0xc9a37fb1, 0x31fa04ed, 0xf5ae890e, 0x50c9fed1, - 0x040d256a, 0x40fda172, 0xfd1e3a3a, 0xd21a7708, 0x8bdf1c70, 0x2576f466, - 0xf21bd29a, 0xc3b32f33, 0x5273947d, 0xd39aaabb, 0x1ce6c57a, 0x2c3df023, - 0x3164224f, 0x36a2ea1f, 0x3c9be911, 0xa48df26d, 0x26d0bde3, 0xe8bf217a, - 0xe03e29e9, 0x322635af, 0x49da08bf, 0x3fdf0024, 0x1798d9fe, 0xa7d2f3d4, - 0x53e51b8b, 0xde45fc91, 0x96ba325c, 0x1002ef8e, 0x9c7f2a81, 0x186071da, - 0x1eed487f, 0x139fed42, 0x23efeb32, 0xbe41ef6a, 0x687bda83, 0xe63a9338, - 0xdebaf357, 0x5fc7411f, 0x0b9f9444, 0x6e2f79e7, 0x624f0a29, 0x5af8f7fb, - 0x31eb07c1, 0x450c797f, 0xc53c787e, 0xbe4d04de, 0x07eac4c6, 0x2f7c136f, - 0x0dc30808, 0xe1c199f8, 0xcd2f1811, 0x36b3b1cf, 0xb1de7747, 0x7dd1b05f, - 0x5d0866b4, 0x599c308b, 0xa40f25c4, 0x565eefed, 0xa76b832c, 0x8186105d, - 0xa166b09f, 0x3768024c, 0x0649137b, 0xde3a0e27, 0xfe0cedfb, 0x527c970c, - 0x239b47ed, 0x74455d9b, 0x458a733c, 0x69acff1c, 0xed3ff2da, 0xc619718c, - 0x53cd74d2, 0x45ddcfd8, 0xe77bf2da, 0xb9f7f368, 0x572a79b5, 0x0fab9065, - 0x53bfe994, 0xdf8124b4, 0x001bf431, 0xe3907ce3, 0xd95ac1e1, 0x6a5759ab, - 0x72951b76, 0x09b88470, 0x8bdb0bce, 0x5fcfeb3d, 0x7b17cdae, 0x6b85f9b5, - 0xdd39f074, 0x7febe29c, 0xa683e81c, 0x283e81a7, 0xfa724f3e, 0x2d55f308, - 0x9a13dc7d, 0x650fa306, 0xb624a71e, 0x33d6a704, 0x18dc58fa, 0x8a1e9913, - 0x52e0f443, 0x0f4297d3, 0xfc3d38f3, 0x6943d399, 0xeeae9693, 0xc9d5be23, - 0x6b03fdb4, 0x1d3ae177, 0x3d198a11, 0x87a140fc, 0xb83d0d0e, 0xd7e83d39, - 0x87a71e6f, 0x7a308f79, 0x0767afd0, 0xa68e87a7, 0xeb4932cb, 0x1d74aeb9, - 0x0eba7934, 0xa3b775ba, 0x47ae8a1f, 0x10587a44, 0x389d379a, 0x65e42fcd, - 0xd38bd63d, 0x01a79603, 0x09e209da, 0xacf7a7db, 0x2684f94f, 0x7914da5f, - 0x36da6bfd, 0xfaa93dac, 0xf2f2d55e, 0xbb7fb55a, 0x268b79a2, 0xa6f7c4bf, - 0xd3697ea6, 0x717e4d2e, 0xfa9a3be3, 0xd21cd70b, 0x7fbd8be4, 0xbf9fd4d4, - 0xfe5353bc, 0x4d59ed60, 0x176503f9, 0xdcfbf935, 0xbfd4d37f, 0x13f08e77, - 0xa2eefe75, 0xeba89fa8, 0xa7169acf, 0x0d70cfc9, 0xec37d4d2, 0xa02ef6bc, - 0x8bef83c7, 0x4f8ff404, 0xffd1a79d, 0x7653a9f9, 0x1e939d42, 0x5383ee07, - 0x9e98d19e, 0x9f7138f1, 0xc24cf39c, 0x1edb42f4, 0x2a15c80b, 0xc8e04b47, - 0x96e574a6, 0x20d935ba, 0xdfca09d7, 0xd46f958a, 0xb2128779, 0x8a639414, - 0x2326c2ef, 0x44204c09, 0xc7c4e100, 0xe5551415, 0x37947d1d, 0xd0914151, - 0x23b0bcb3, 0x279af7f2, 0x23db878b, 0xf7847f9c, 0x7a021935, 0xe72f7752, - 0x29029524, 0x64277f52, 0xad81f205, 0x34a94f5c, 0xb9517e32, 0xb12e5075, - 0xaa303e41, 0x6bfaabf6, 0x206c9ba1, 0x66ba49d0, 0x5d36973f, 0x04f7e1af, - 0x4089cfbc, 0xdf34136f, 0xd66f9a2b, 0x25daebb4, 0x81abb8e2, 0xfdb95097, - 0x527a292a, 0xd8153e04, 0x0c6b3293, 0x14f5d38c, 0x5112dbe6, 0x34f2ec8f, - 0xc7f385af, 0x4c169e73, 0x30da78cf, 0xac09e53d, 0x93c07385, 0x1e98039e, - 0xda63b4f7, 0xe98639e1, 0x4c0e9e47, 0xc19cf43f, 0x209e4ff4, 0x9f3cc7a6, - 0x43c47a61, 0x0e70027e, 0xfe98cc7b, 0xb4c763c1, 0xe98c93dd, 0xfb0f8f05, - 0x5f5df651, 0xcb867774, 0x7f4073ed, 0xbb6ce811, 0xcd6eac78, 0xbd9d30d0, - 0xa423f2b9, 0x85cf0533, 0x0f4e264d, 0x087a1a49, 0x2377ed80, 0xe51f4bd0, - 0xc3a7324d, 0x2e47dade, 0xbfe179af, 0x7caede87, 0xd30b7a4b, 0x3d1d10d3, - 0x4f45f7a5, 0xe9e9aa1f, 0xe4cec18a, 0x1fa7a720, 0x7d6b73f3, 0x3b1251bf, - 0x77e90ca7, 0x800cdbae, 0xdcfca5aa, 0x98699084, 0x5efbc4bf, 0xa3b5c149, - 0x0d1be81e, 0xe8d2eb72, 0x73828fbf, 0xe8c74b87, 0x3ef6a7e2, 0xf49d3d3f, - 0xda17778e, 0xba3e2543, 0xc61109e8, 0x1af0cd1b, 0xc8d32065, 0x461a4278, - 0x905ce4be, 0xc4897981, 0x739f7b43, 0x3af38446, 0xc06b7542, 0x5d785f6f, - 0x1632bd69, 0xf67a9de0, 0x5e90591f, 0xf475fae1, 0x7cf5111e, 0x09d17812, - 0x25c90df8, 0xfc193393, 0x4691c1f3, 0x6409ea3b, 0xde7f16ba, 0x6bf835db, - 0xcfce5548, 0x7f11931b, 0x1a8cae23, 0xf5fc0fd4, 0xc2fbdfc5, 0xf79802e7, - 0xfb3e037f, 0xf17d8fe2, 0xbc72e245, 0xdfe746d6, 0xf8cc73bd, 0x07c01cc7, - 0xcadf1abf, 0x3c7e9c79, 0xb5f492f9, 0x493bb8e8, 0x14f6e3a1, 0x24d85b88, - 0xa5fe11da, 0x61626bd6, 0xfa70425d, 0xede14f58, 0xbd80a73f, 0x0b553e7f, - 0xef074b2f, 0x6d1781d2, 0x4d2d7760, 0x3270d85e, 0x69283ac2, 0x835d4b55, - 0xb687ad45, 0x1a97f369, 0x382d6985, 0xecec472e, 0x6a272031, 0x5edf181b, - 0x6702a98e, 0xf6097269, 0x3d39ae73, 0x3e7bd996, 0xc7360fc6, 0xe738bf21, - 0xfffac329, 0x06f4f1ec, 0x210f1947, 0x1984e4ad, 0x4b2d31f8, 0xaf7ebdef, - 0xc5fd2cf4, 0x7edde788, 0x89e80af9, 0x97dffa66, 0x09107760, 0x9adc0af3, - 0xba6bd116, 0xd66fbe01, 0x39db47f4, 0x2fe23394, 0xdf6abed3, 0x4294e448, - 0xd45e54b7, 0xe780bd83, 0xd41a4b9b, 0xcb55597a, 0x9af93577, 0xd41a47b6, - 0xfc055c7a, 0x525ff283, 0x3740482b, 0xba8c9c95, 0x811acb25, 0x8218af8e, - 0x088f804f, 0xb9955eac, 0x9fa6e8c3, 0x75b2b7ce, 0xe77c6deb, 0x8854e63c, - 0x3733283b, 0x597239e2, 0x20f9b5cb, 0xaeb7ce67, 0x5bf9024c, 0x5efa5e21, - 0xbff68451, 0x5f2e0494, 0xcf56a0e4, 0x2841f4e7, 0xe9bcd55c, 0x17c212cf, - 0x981977cd, 0xb70f465f, 0xbe91cb8d, 0xf9bd53f0, 0x8ecdc150, 0x6eaa789e, - 0x237468bb, 0xcbffa45f, 0xc149e30a, 0xd454b15f, 0x9771d126, 0xffa27737, - 0x1dec8ce2, 0xe0af83f5, 0x67e73d97, 0xa3153e49, 0xb497979a, 0x260b3f43, - 0xe3888ef1, 0x1f280fde, 0x995bfb3f, 0x57221f00, 0x742cad69, 0xc7bb70cd, - 0x61590c40, 0x6b4167bb, 0xfbe02145, 0xd1d3ebec, 0x8a445bee, 0xa40eb86c, - 0x9cec0b31, 0x7180c4f3, 0x1fc9e755, 0xeb54136c, 0xe464b1f0, 0x305ca678, - 0x1034bb89, 0xd8107bbe, 0xf539a65f, 0xf858e2ed, 0x9076292e, 0x15ca25f0, - 0x17f180b7, 0x2f77d873, 0xfd01d731, 0x634a7b52, 0x4a7b51af, 0x94f6a793, - 0x66425f26, 0x453c4126, 0xf132d3c9, 0x4d278809, 0x8ec941f9, 0xb5252be3, - 0xfd1fa0f5, 0x16e1fb9c, 0x843489d8, 0x37aa87ca, 0xa62acb9e, 0x9892e9f3, - 0x0f894bff, 0xc5654258, 0x5e5e5a20, 0x2cba33e6, 0xa277e73d, 0x943dc275, - 0x163c03f3, 0xd1bf7007, 0x886be2c7, 0xaae2ca43, 0xf3ef5a4f, 0xba2ad81f, - 0x8f506ca2, 0x9bc6577e, 0xafe7f5fa, 0x4f212f9f, 0x9bca3ce2, 0x561c6067, - 0x3e07788f, 0x7059b91f, 0x27ec22f9, 0xf1341651, 0xc332092e, 0x1ad7e29f, - 0x0f5fcbae, 0x6bdf9579, 0x1bfcaea2, 0x440197f3, 0x258a5fc3, 0x913970f7, - 0xbfc013f1, 0x7f710520, 0xc9f8637d, 0x2f5fe03d, 0x844ff8df, 0xefbb543f, - 0xff89fc29, 0xe88ff1d4, 0x48bcfe31, 0x78deabf0, 0x778875f5, 0xcfd5ff2c, - 0xb7ee846c, 0x926352b3, 0xe57bae93, 0x1736d5a6, 0x6bc91df0, 0xd6717d83, - 0x448b4e27, 0x7997df0f, 0x59711fdc, 0xc2bbf004, 0x73fc293f, 0x4ef8fcaf, - 0x6caea3b0, 0x4fe8ed92, 0x4c05366d, 0x5bab9e94, 0xb1921497, 0xf964ef98, - 0xfd022f47, 0xc7c9b4d7, 0xfe5a74d5, 0x41259fcb, 0x94a5107c, 0x48648621, - 0x549f6803, 0x00b8fc6f, 0x121a8df4, 0x6faafdc4, 0x167ffd07, 0xd8b0f28f, - 0x1cb3db18, 0xd049341d, 0x5a6afd9e, 0xb4517c7f, 0x69db7a41, 0xb2d46fe0, - 0xbe90bf44, 0x3bb7195d, 0x00eb642a, 0xc913abe4, 0x0aabe044, 0xd98f885e, - 0x7e5f2b1d, 0x1d276c66, 0xdfc6d757, 0xbe1504da, 0x52e97b14, 0xfc5fc2cb, - 0x1f3bd1da, 0xa3f740bf, 0xe455bf5a, 0xdb8da394, 0x56967e4b, 0xc41b01ca, - 0x906e5573, 0xb9fa5e9d, 0x5f17d5f2, 0xd9fc167a, 0x4739347f, 0xaf15f852, - 0x13723bee, 0x916c57cd, 0x69b21407, 0xf0a48458, 0xffd0d4fa, 0xaf0f8f96, - 0x7db6f947, 0xf618c746, 0xe1f187fd, 0xb2d8a975, 0xf4c648cb, 0xcb5e47c4, - 0x2587632e, 0x74b4fac2, 0xb7fe8016, 0x1abfe5f2, 0xdd9def81, 0xa9819029, - 0x61b9f011, 0x8087ea1f, 0xbe4f5c27, 0xd3f5a15e, 0xeba1afd5, 0xbf467202, - 0x857afa5e, 0x5c00bf9c, 0xf4a1b388, 0x21afdafd, 0x264fee0e, 0xeca1e027, - 0x306c87b5, 0x2d52d39f, 0x56e7f3a3, 0x2bbf0127, 0x7649bd93, 0xb2f7d94c, - 0xfa461fe7, 0x70f43d2b, 0xba57f312, 0x76501906, 0x3cc1077a, 0x1bbfaf17, - 0xdc4259e7, 0xcf658748, 0x9a3e4589, 0x69912a7e, 0x93ec225b, 0x9c9f7c4b, - 0x2e2e817e, 0x4569e79d, 0xe441fc2e, 0xe8bbe172, 0xcf987d0f, 0x98906a85, - 0xd6ccd4ff, 0xd06c80eb, 0xfd10d1c8, 0xe5147c6e, 0xae61b9c7, 0x56ee7081, - 0x28179613, 0x5343c447, 0x6275b207, 0x51db0772, 0xdf0793b9, 0xecbb7ea1, - 0x69ab1a8a, 0xe9467287, 0x9fef197f, 0xf41a3b8e, 0x9149d3b7, 0x46e191ed, - 0x3d500f85, 0xaa674543, 0xfff6cefd, 0xdfb606c6, 0x9beffd95, 0xffca0d31, - 0x23ed9872, 0x97720768, 0x10302b8e, 0x16cd77cb, 0x48983f90, 0xdf3ed220, - 0xae7df328, 0x0bd3d72d, 0xc424bf1d, 0xfa06e8aa, 0x4075c789, 0x34f25f79, - 0xa3e2af6d, 0xadafd035, 0x1f655c27, 0x707e7297, 0xf5c1f81e, 0xd6407e61, - 0x5e2bf627, 0xbdf652b4, 0x5fec2cf4, 0x0ebd5fba, 0x1172bfd8, 0xcd93ffcc, - 0x4fdc8e7b, 0x2d27edf7, 0xf2d5beca, 0x2dbefd55, 0xc630fadb, 0xedf7eb9f, - 0x496b4327, 0xbf4b7dc4, 0x43b7dc47, 0xf847fe3b, 0x24c782aa, 0x2aaf96a3, - 0x7c37b27c, 0x16e4f9ea, 0xd57881d9, 0x3bfa49f3, 0xd27ab24c, 0x0a8742a3, - 0x47ff95fd, 0x47e070d5, 0xe8553a21, 0x0aa74430, 0xade7ea1d, 0xfcbea3c5, - 0x522df023, 0x537a297a, 0x4a95f3c6, 0xa6038b3f, 0xc90ff6ed, 0x50b97c44, - 0xfdc691cc, 0xf3a80643, 0x45be5d3e, 0xcba5df57, 0xbbeae917, 0x4d5af975, - 0x3db6cafd, 0x10748246, 0x9713d4d0, 0x31393bff, 0xfadd1221, 0xf5a1bf98, - 0x39ee11a2, 0xd88258d4, 0xbc415e5e, 0xdc191f10, 0x51b9e221, 0x3d71c537, - 0xa73637f8, 0x8f94bcfa, 0x7e628eac, 0xd07b6e85, 0xd5d34f16, 0x4c1f2c71, - 0x1f03d634, 0xa307be54, 0xbbb1df98, 0x538b6828, 0x7e9d5bd9, 0x8778f911, - 0x0dbdf22f, 0xdd70692a, 0xd7b97a3b, 0x758f9ca1, 0x62c6db47, 0x3e29d17f, - 0xa2a9c7a0, 0xf8396525, 0x27451aa1, 0xea8bece8, 0x79c1b5ee, 0xfd3fb755, - 0xfbf439ae, 0x164477e2, 0x4975e38e, 0xd0765483, 0x975de219, 0xf05c402d, - 0x859fa45a, 0x2d17667e, 0x3f791b5a, 0x2576f394, 0xe0466596, 0x390ed4bb, - 0x51ef3eae, 0xd7ad94e0, 0xe74ff77d, 0xed11a6fb, 0xda8df2ff, 0x9fb73772, - 0xfce4647f, 0xc7191c67, 0xbfe657ed, 0xaa7b7ce1, 0x1cd77198, 0x07dd3eba, - 0xf9a26244, 0xd7117e4b, 0xc166d2e7, 0xe237fe07, 0x57fdc44d, 0xf546824d, - 0xd82e887d, 0xcef4d75f, 0xffb6bac7, 0x4007eb39, 0x307faf47, 0xda69dff6, - 0x471ffaf5, 0x37f905bd, 0x407ca68e, 0xdbcfd67a, 0x02f18519, 0x48ad3bdd, - 0xde3bddff, 0xe401f94b, 0x613934df, 0xff3bdd9c, 0xa9e8163a, 0x0ca9857b, - 0x30f760f8, 0xb95dbfe6, 0x3b63afe3, 0xc2aefe50, 0x1a366c75, 0xffc99f99, - 0xdee08f8f, 0x9d3f25c2, 0x3c17e815, 0xd7e6beae, 0xf0823e51, 0xbea59aff, - 0xe76df40f, 0x43e3cd53, 0xce64adba, 0x1c5f1856, 0x79a87f8b, 0x758bf26b, - 0xd6aaffb4, 0xb485c65d, 0xcfedef3c, 0xfd1c62c7, 0x5d37a656, 0x879e3b90, - 0xc66d87f8, 0x2994acef, 0x26c02f9e, 0x5df646a3, 0xb07935a6, 0xe5e27a8f, - 0xf5a7f473, 0x1aef1f17, 0xaffd7d99, 0xc5c10f8f, 0x67d59ff8, 0x7fde6016, - 0xf403e8fb, 0x2e909a83, 0xd27ef995, 0x4cfa8752, 0xfb3ef35f, 0xfa0e86bf, - 0xd0216f3b, 0x4d9b799f, 0xfdebdaff, 0xeb81d1b8, 0x3d07dfa2, 0xf7c77ce9, - 0xd5aaff30, 0x27ede389, 0xfd368fbd, 0x5beeb63f, 0xfadbbae9, 0xfe77f79e, - 0xfbdde7c5, 0x8f33bfba, 0xce1dbbaf, 0xfede6b53, 0x75f7c71c, 0xffe95cf9, - 0xf457ba52, 0xad4376fd, 0x6f8e933d, 0x82b4690e, 0xe25f7162, 0x03a64b25, - 0x0f2f70a2, 0x383bf8c0, 0x57608d5f, 0xbf989935, 0x581824cd, 0x82dddabc, - 0x3b4447e2, 0x5fae4eeb, 0x0cb439dc, 0x5d3b90f5, 0x827d413f, 0x39edb548, - 0xee7b7eb4, 0x6ac62742, 0xdcc7f192, 0x853d9f90, 0xe6f6b5e7, 0x12e204ef, - 0x677f7ea8, 0xa003f4ee, 0x12e5dee7, 0x29a60f51, 0xa7efbfea, 0x93efb014, - 0x7dd0f6b4, 0xdefe6d6e, 0xddfcda39, 0x843dde1c, 0x229eff8d, 0x587e07c1, - 0x8953ce53, 0x2d3597e0, 0x0a908996, 0xabb54671, 0xbbb8eec1, 0x197edb48, - 0x7f2a6728, 0xe3c537e3, 0x5c78436f, 0x3921788a, 0xed03de22, 0xdc7c8f13, - 0xf9c7b3ed, 0x489ace20, 0x7bc7864e, 0x37e89caa, 0xccb8f6e7, 0x3596cbdb, - 0x659fb0ed, 0xd8ae1d9d, 0x9be1bdd3, 0xe11cfb70, 0x2ff185a4, 0xcfb444bb, - 0xae7d9d65, 0x5dd7cbac, 0xbf1d650f, 0x073cbaed, 0x786372eb, 0x5c5a865d, - 0xccabf604, 0x8b7c87ed, 0x1687e593, 0xe8ae7611, 0x00d2fac3, 0x8466f117, - 0x9897d1e3, 0x9ce02b8b, 0x405a3ccc, 0x6b5dc87f, 0xe60f9445, 0x55c7010c, - 0xf8c64934, 0x450d8fe3, 0x85deb059, 0x7f562613, 0x09c30d9f, 0xf1c25cf8, - 0x516a425e, 0xbf57257f, 0x0b3b32fc, 0xea0825ce, 0x845c4bbf, 0xb8ed41dc, - 0x10216c92, 0x126af10d, 0x078ec6f1, 0x8e40b93f, 0xdae4fc6b, 0x496efc3c, - 0xabe9c30a, 0xe5fc6f7e, 0x17fe9d9f, 0x29c767e5, 0x3a427491, 0xd497bb12, - 0x3f7cf776, 0xa54d63c3, 0xba434be0, 0xfbeac80b, 0xb66605d3, 0x87ebfe0f, - 0xe64f9013, 0x2c4c74fc, 0xe26407f3, 0x6e1ac47d, 0x3af25c37, 0x760fc162, - 0xcfce9fc9, 0x6a6cf373, 0x87a4aabe, 0x9ffe1db8, 0xd3489710, 0x51a17cee, - 0x048b3b04, 0xcdebffd1, 0xc57bc28f, 0xcca376fa, 0x6bafbe06, 0x3f002fd1, - 0xf2afee11, 0xa6d29479, 0x75aaf1b1, 0x59c77b5b, 0x75cf6c69, 0xd571df80, - 0xc5b7ddf9, 0x80fdd82f, 0x1d5143d7, 0xe6114505, 0xafe3893b, 0xf0dff770, - 0x7f4ceafe, 0x99780caa, 0xce6a2f99, 0xee669df9, 0x264098cf, 0x770ab8c0, - 0x0c9b66df, 0x744072eb, 0x1ad57dc2, 0x3ba345ff, 0x1eb1f9c2, 0xfc1f009f, - 0x676427f0, 0xc4f3e009, 0xd808a24f, 0x73f1efd5, 0xcfb80cc9, 0x1eae8191, - 0x731df817, 0xb84fcccc, 0x74c76cce, 0x9c8e6156, 0x68cdfb48, 0x50838fb5, - 0xfebcc1b5, 0xcb03b33a, 0x4a76f087, 0xac95c1bd, 0x5ed1a75e, 0xbffe691d, - 0x79f8128b, 0x937bf399, 0x75bd7f84, 0x35a9f9cb, 0x41fa0b90, 0xd167e2be, - 0xfdc135d3, 0xe09a6971, 0xf60df903, 0x050be630, 0x53de1fd4, 0x64cfafee, - 0x7ba15672, 0xcdab9e3d, 0x1e02f7da, 0x887f78e7, 0x678287d3, 0xf1fabf05, - 0xbf29f52a, 0x9fed55ba, 0xdc6dabba, 0x54dfa06b, 0x81bb05fb, 0x3a96aa82, - 0x6b0fb08c, 0xe1909eda, 0x073ee67c, 0xa2a44b83, 0x83f8eab1, 0x0f166675, - 0xcdfc67b2, 0x2e4e80f3, 0x2c8135af, 0x1745ae24, 0xdf87c06d, 0x0f7f3833, - 0xdfde6c71, 0x57d36489, 0x3c0fabf0, 0x597cf2f6, 0xe715370d, 0x4732ab33, - 0x03da7706, 0x81e4bb95, 0x675a7a2a, 0xe572c78e, 0x074ae0fb, 0xfb420fbe, - 0x1f7871c3, 0x4fb81137, 0x8ed2d192, 0xa81f6cf7, 0x5874638d, 0x88cbb2d6, - 0x7bcd54f9, 0xfa3f4a22, 0x50bb34fd, 0x30bcaf1b, 0xe02863af, 0x5814d0a5, - 0xa7408ce6, 0x7394a393, 0x2729afca, 0xc76e945c, 0x27247ffe, 0xa2722996, - 0x95e3e303, 0xe7df02f6, 0x3031392a, 0x5a589c92, 0xeb0818e7, 0xfa4774b0, - 0x4b24d840, 0x149a99df, 0xefbc4e49, 0x47cce761, 0xeef67df9, 0xdc4e54d9, - 0xb31392a0, 0xf44e90a3, 0xf6513eed, 0x42725f49, 0xcbffb759, 0x907de6fc, - 0xf7f61113, 0x71393a17, 0xe518bf8f, 0x45b33dc4, 0x4facbdcd, 0x391394fb, - 0x5e61f749, 0xa044c676, 0x7db9f79f, 0x0bdf9473, 0x5e407e80, 0x11d94664, - 0xd1b97a6f, 0x53ff5f1b, 0xfffaf97f, 0xbe159e10, 0x3fda94be, 0x7448d4a6, - 0x979e9048, 0xbaf947de, 0xf8c8f400, 0xb907d2fa, 0x67c7539f, 0x66cf808b, - 0x6b2cf9aa, 0x7266ed5f, 0xf52da6a1, 0xfcb4b999, 0x09d946fe, 0x30fef2a2, - 0xf352cddf, 0x5ea8ccdd, 0xe3196ef8, 0x13fd97bb, 0x6dea7f50, 0xfce67f7e, - 0x11b3f296, 0x31f408ce, 0xe68c6e67, 0x7189dede, 0x06d8c9bf, 0x113de5fb, - 0xe63f79cf, 0x71c1c07a, 0x7d04c9bf, 0x9e3e49fa, 0x2f3d7c79, 0x3e794878, - 0x22de5fc5, 0x6d574fa6, 0xd57f1116, 0x57ff6cad, 0x073e0b37, 0xff8c17cd, - 0x56d79e1b, 0xb5e760ec, 0x39850674, 0x78aff5aa, 0xce1ea3af, 0x08362a09, - 0xf70cde78, 0xa59f001e, 0xce259f1c, 0x29573c0a, 0xc1fad26d, 0x2f6da21b, - 0x1e101b90, 0x78abc3fa, 0x105342fd, 0x7f0a1dcf, 0x20373829, 0xabb6d49f, - 0x59fb711a, 0x9a2a4fb0, 0x0d9ddf75, 0x3704ae78, 0xadaf41d4, 0x7b96d16a, - 0x8b17bcf8, 0x146d8c81, 0xb33df93e, 0xf778f4f3, 0xf653f1e8, 0x8873f12d, - 0x9ff327e2, 0xfe259f87, 0xf05e785d, 0xc7a2f175, 0x3f145d47, 0x324f181f, - 0x6c7e3f61, 0xf17f2170, 0xbbe22bbe, 0x189e8b4e, 0xe50f79a9, 0xef2f1ca7, - 0x83f5dc19, 0x80b55ea0, 0x6fd74af5, 0xf34497d9, 0x38c85b73, 0x6d286638, - 0x90e3cad2, 0xa0756ffc, 0xbb5b9f7c, 0xdab88045, 0x60befcc5, 0x7c09ef99, - 0xe5c1e63f, 0xfad3de54, 0xdc9bc70b, 0x287e5e70, 0x53fc882a, 0x409ddfa1, - 0xfa6f94bf, 0x0c4e38f9, 0x9ca3e60e, 0xb8ec136a, 0x4c51032f, 0x8275d16e, - 0x4cf66d77, 0x5f016bfe, 0x6a5fe617, 0x4358eb63, 0x75f60dd7, 0x5be79f81, - 0x80f83e98, 0xe73b22ff, 0xd992eff4, 0x490238fb, 0x44e77e40, 0x8f915cfb, - 0x939aee70, 0x1ddf5aa4, 0x37fe8c9d, 0xe0fc4e09, 0x36fbffa3, 0xbacbdbeb, - 0x7f4cfa2a, 0xd3c157d7, 0x1f3add4e, 0x9c2f6a8a, 0x8272e780, 0xf20bdf13, - 0xd179e1c7, 0xfef646c9, 0x1fae41cd, 0xd805f7e9, 0x78f7ea1f, 0x21c0c066, - 0x145a7a2e, 0xbf6295c6, 0x533f4c69, 0x3bfd29f3, 0x6e375f48, 0xa3b486a9, - 0x7f8e165e, 0x066edf74, 0xd04d3fb9, 0x19d149c4, 0x27ffbee1, 0xbea397c0, - 0x36493e02, 0xc8797ca3, 0x19eebece, 0x1ef02466, 0x3235e5da, 0x06bdd1d2, - 0xe06c91c7, 0x04c98f2f, 0x83e5c7f6, 0x3b9d1e37, 0xa445ca00, 0x26f7e28f, - 0xa56b8354, 0x91aac598, 0x5c9847e2, 0xfffbc13a, 0xaed79513, 0xa097786b, - 0x7ce27b07, 0xb674bf70, 0x0754d773, 0x0f325bf8, 0xcf7386ad, 0x23f67959, - 0x1b1d6047, 0xc74fbbd8, 0x9da1e4d7, 0x0577d0f6, 0xe8c767dc, 0xbb9c017a, - 0x391ea767, 0xe0f7c742, 0xb73c449a, 0xbc4aeb9c, 0xe731ce07, 0x0e9d141e, - 0x5de16f5a, 0x7f9c0b56, 0x122d1f4e, 0x0f2f0ab7, 0xeff47692, 0xeefdadcc, - 0xca4fb0dd, 0xf7843ca8, 0x87fcca9c, 0xfc840ea6, 0xd7db017a, 0xb846dd78, - 0x74ded9e7, 0xfb4998d1, 0x00f5a12f, 0x59eb35dd, 0x028d9abd, 0xe25817be, - 0x64f9027f, 0x1f0146c9, 0xfaa769c4, 0xf5c199af, 0xbed12981, 0xf9a7b69e, - 0x700f6852, 0x03ddc637, 0x743593e7, 0x527ed89c, 0x97539e1d, 0x98b476d0, - 0x2efc6fb4, 0x5eb25bc2, 0xb0af7020, 0xe3ea526c, 0x41de0093, 0x47e509d9, - 0x08dcfd77, 0xfb479ee3, 0x2fe1441b, 0x42a63b14, 0xc103f27d, 0x152eef8e, - 0xbafb8b5e, 0x623bef9b, 0x14e2cd1f, 0xefdca204, 0x2af1d493, 0xb869d125, - 0xd7964a9f, 0x3abcc3d5, 0x06a989bc, 0x468ba7a4, 0x2927e390, 0x7f54ddbe, - 0x7164613d, 0x27bc7b30, 0xfe2a1d8c, 0x1d3a32b9, 0xcb6a2fdb, 0x98b33e41, - 0x853c6114, 0x23e98ebb, 0x7ca3ab9d, 0x94eb57e0, 0x7df029ed, 0x7e136acf, - 0x932af0bf, 0x7586173b, 0xf4fb7fa0, 0xbdc0997a, 0xd3eb95c7, 0x9e3ac1d7, - 0xe13b2cde, 0x8e7c40dc, 0xbe9411c5, 0x7b64fcca, 0xa7b833d6, 0xcb7f199b, - 0x02eeee7b, 0x94a5dbe0, 0x7e70994f, 0xe2563e5a, 0xf53e4728, 0x4be3145c, - 0xe7a57e7a, 0x1b8d6553, 0x65a1cb22, 0xd0e59105, 0x37ee7ad0, 0x6b9f2c8d, - 0xbbe98588, 0xf078c9e3, 0x0d571663, 0xf404d79b, 0x70bb20fc, 0xf3781ed0, - 0xdc819fd3, 0x3be2b4ad, 0x7d92d565, 0x83e8c09d, 0xeb9fff00, 0xec29f2df, - 0x51b9b287, 0x29d90ef8, 0x47d80f58, 0x1cf0136b, 0x8c57c4bb, 0x79e25778, - 0xf4b49b4b, 0xef21f8ae, 0xa5c48b73, 0x31655f96, 0x77aaa5c4, 0x6e9447f4, - 0xdbf33f69, 0xcab01f04, 0xdcea3fa3, 0xe62670ff, 0xe5ae38ed, 0x6b583f5c, - 0xfa3eba45, 0x40d5c5c8, 0x287ef3b7, 0x89dbd010, 0xf20f5dd7, 0x7049bab0, - 0xf4b89f80, 0x297dac87, 0x3ee30f6d, 0x5f4673fa, 0xb01dce94, 0x3fd7aa0f, - 0x6feb1fb1, 0xff001c14, 0xd46286e8, 0x22bcca27, 0x9d8df2c1, 0x79504768, - 0x7b68f185, 0xec1262bc, 0x2655ea83, 0x1562b83b, 0xb3e8527a, 0x40a7bf93, - 0xb3b1cecc, 0xb4673b68, 0x9eb2f903, 0x4239c52e, 0xfd029e48, 0xbd1978d4, - 0x3b2abe75, 0x4df48b61, 0xbd1eec9f, 0xd0227f42, 0xfe98665f, 0x33cfacf6, - 0xf69e3d02, 0x91671809, 0xf40bf407, 0x9fe2b2f9, 0x1eb51621, 0xea7d17d5, - 0xfd07b0e9, 0xe958cbc1, 0xe854fa61, 0xc7874f51, 0x8c0f7225, 0x51d5a1fb, - 0xfabc8f38, 0xce59ef37, 0xcf9e19f6, 0x923fd5e5, 0x44bafb04, 0x0a407162, - 0x1624ab5e, 0x5c63d637, 0x0719d74f, 0xba7c67f5, 0x0e8acc71, 0x20f1edc9, - 0x4a3ea9b7, 0xdf9fb402, 0xe3117e6c, 0xd2bfcf2b, 0x37ea2779, 0x003a516f, - 0x92b66ffc, 0x3e21da00, 0xade547e4, 0x1369c622, 0x4b359029, 0x712bbf65, - 0xb2bf1531, 0xb7cbbe22, 0xb4857c9a, 0x27ebf97d, 0xc25c62c6, 0x7b7fa60a, - 0x39d8115f, 0x2c63b788, 0x972a3bdc, 0x5e8e7c58, 0x345df82f, 0xdebbc3b3, - 0x7a03998c, 0xdeccd09b, 0xb96f2c17, 0xfca93657, 0x65a2fbbb, 0x939e1ea5, - 0xc33ae979, 0x3e300afb, 0x4a76fbf5, 0xcbd74e5c, 0xdbcafe8c, 0xcae7d464, - 0x805cb79b, 0x63f2cd78, 0x6b77b426, 0xc11a2f9a, 0xd5fbcd9e, 0xc41decab, - 0xa7135136, 0xae3e23d7, 0x20980c59, 0x0ab5abae, 0xbe6871cf, 0x3c2df313, - 0xc66bed1e, 0x6afc556f, 0x8a5eebc7, 0xbf6d8ac2, 0x857be1b4, 0x786c9bed, - 0xabf9aa5f, 0xc47b55e3, 0xf034b5c3, 0x4e3bb878, 0x918fe413, 0xc1cee1e3, - 0x7d21283f, 0x878dad16, 0xbf8ccd23, 0x456671d1, 0xa4350f7a, 0xe9fabd77, - 0xddcf10f3, 0xe793f5b5, 0x5f95dc61, 0xe21e7e5c, 0x6882a86c, 0xe6a53d07, - 0xfe31f795, 0x1f176955, 0x97a0edc3, 0xc3f1897f, 0x7268fe17, 0x3b0bb402, - 0xfe80a74e, 0xdfcb6171, 0x782e2092, 0xe8a98ed9, 0x3db659df, 0xedbddf0f, - 0xfa059ecd, 0x7e23f5f5, 0x7b6ebf59, 0x3c60f75a, 0xeeba79d0, 0x714227c0, - 0x2c552d8e, 0xe3c1d47e, 0x8e47371b, 0xcf11ef17, 0xaeeb3ad8, 0x5b1fc029, - 0x67d09e99, 0xba61e35c, 0x63f4379e, 0xf8f3371d, 0xbe3b96d5, 0x3cf1ae32, - 0xd7ae83fc, 0x7c6d18b8, 0x8bada7e8, 0x942cf17f, 0x1af426b5, 0x07e818d7, - 0xf47894fe, 0xd95da3cf, 0xdeb08931, 0xa4f181ff, 0x0e857eb0, 0xa69fd7e0, - 0x8cf8bf80, 0x44bf441c, 0xef098770, 0x38ef966b, 0xc2e9fb8a, 0xef1843f6, - 0xf85c784d, 0xb1fa1205, 0x03ee5df8, 0x6568d9aa, 0x1d7c90f1, 0x61d25e20, - 0x2e3cefc3, 0x12b5d192, 0x9c5bd92f, 0x3498b2e4, 0x8b0b3efe, 0xf8daace7, - 0x0c3f8f01, 0x09309baf, 0x2bf3abd6, 0x3c1550e3, 0x130f01d8, 0x91c071d5, - 0x714352e3, 0x8375bac0, 0x1e3e04f5, 0xf9a5f38a, 0xe9ef10a1, 0x8a468e13, - 0x81b0bf2b, 0x905f0fc5, 0x568fdf23, 0x626b82e2, 0xd7d6fb74, 0xbee078bf, - 0xf175f1e6, 0xa1c63f34, 0x5f051ba1, 0xf323575d, 0x846327f7, 0x85b7646f, - 0x0a549bee, 0x4f2cfbfa, 0x997dc0c4, 0xbe234ed6, 0x55d8a293, 0xdc5dbe7c, - 0x8af5d6df, 0xf5a27188, 0xbf907b2d, 0x3547f9eb, 0x8fd1473f, 0x6f1f2377, - 0x1f931b75, 0x3ead5b5d, 0xb5d3850b, 0xeba44dfb, 0x189dcdea, 0x79bfbaa7, - 0x7543b19b, 0xc3f20cfe, 0xd77f1aa7, 0x22c6bb6b, 0xa2efe73f, 0xcad9fbe9, - 0x3f8d63f9, 0x9b353f72, 0xa9fa6a2f, 0xed18b6f0, 0x3bfbbe96, 0x05eeb927, - 0x99dae778, 0x45ae751e, 0xd08be69c, 0x6462cfff, 0x3237576e, 0xa395383f, - 0x959c3ef8, 0xda2707bd, 0x5b2f51a2, 0x0c749d66, 0x665d21de, 0xcc5c6235, - 0x471e3aca, 0x326723f3, 0xeb4af7ac, 0xbbc604ed, 0xb2abf01a, 0x9bbb65ef, - 0x27273e80, 0xcfaa6517, 0x1bf19461, 0x4f881807, 0xd3ad8fbd, 0x4a7d8206, - 0x1850ef24, 0x7f699dc7, 0xb62e4095, 0x9f7f987b, 0x02313d5c, 0xf64bb7be, - 0x6e14097d, 0x04e0be7b, 0xba4f6cd7, 0x7e43f067, 0x1df69706, 0x4753bc5d, - 0x69c977e7, 0x6ad13d40, 0x1569d808, 0x4f6a8d62, 0x41d70346, 0x5e12521c, - 0x8978c0a5, 0x11e63cc7, 0x46d43f70, 0xf50adaa8, 0x5de6929c, 0x9249d895, - 0x72159dee, 0x57a50478, 0xc557a70b, 0xff65675f, 0xf03b70a6, 0x0cb896fd, - 0xbbe40752, 0x7d46ead6, 0x0b9b29e2, 0xdfd23fef, 0x88938868, 0xf54ed127, - 0x5fb450bb, 0xda3b7dcd, 0xe71f26af, 0xa613e6d2, 0xc9232749, 0x8e3e049b, - 0x7882d102, 0xe06a9b88, 0x70abb2fa, 0xdc785264, 0x19c48971, 0x2c3bf280, - 0x6e808f78, 0x1e7aaf2f, 0xdc768b16, 0x3e1a7c74, 0xe1d19b11, 0x6a71b035, - 0x0389dbbe, 0xe3a747df, 0xaf1bae3d, 0x70b56f26, 0x0911277e, 0xdcc59df8, - 0x2ffe384e, 0x4abdf069, 0x224f8a2a, 0x38c2644c, 0xde2130e9, 0x83cf9625, - 0x6fa9aff6, 0xeb01ef07, 0x0c870b5f, 0xb5efabb5, 0xe0e5c0de, 0x8a514b11, - 0xac93ee85, 0xb818b5e1, 0xb82c9d9d, 0x65a04e4e, 0x9fc801fe, 0x61e796d2, - 0xc8d08a5c, 0x5ac46ae8, 0x4466fb82, 0xad55c790, 0xd53d468a, 0xa8de2664, - 0x8e3f70f1, 0xd0f1e578, 0x3f9f8f8b, 0x28185639, 0xa50d6928, 0x1fceda35, - 0xa62c35cc, 0x4502d08b, 0x8b10fe14, 0x5ff40c6b, 0x6c9dc33f, 0x1bd30718, - 0x2877bf56, 0xc16bdaee, 0x1ba86863, 0x14c0ffba, 0x2ef82164, 0xdd0ef108, - 0x51b8720f, 0x0ec653c9, 0x463406ef, 0x332ef287, 0x698df7e5, 0xdaf37f2c, - 0x7ef0f5a1, 0xe8bda74d, 0xc78c0b66, 0xcf0ebf6c, 0x9af102c3, 0x937bd5f7, - 0x4738ca2f, 0xc1e40c6f, 0x07b7c7fb, 0x23c5fbd9, 0xfc7ba1ad, 0x59378f28, - 0xed007c94, 0x43d6a28b, 0x5aaad7c8, 0x01b9610e, 0x9e1d34f2, 0x421bc810, - 0x65bf79e7, 0xb5f2414c, 0x716b5e14, 0xb1c13c32, 0xbf6632d0, 0xb8c3c1a4, - 0x61d9bdfa, 0x6e2b483c, 0x86e1e1d0, 0x858785af, 0x87a86f6b, 0x3bfa55f7, - 0x0b174a6f, 0x73d35f00, 0xdb8ef80c, 0xf41663c4, 0x145fd0bf, 0x670e23ca, - 0xbcf72f43, 0xc2853b15, 0x97d35729, 0xaba14ed2, 0x9d26e8de, 0xef63afd8, - 0xe7e96a83, 0x87ae2ddf, 0x8b32de00, 0x8896dd2b, 0x0577c7f3, 0x8b8bbba6, - 0x74c213f2, 0x09ee2c4d, 0x11feaef0, 0x5a1f82cb, 0xe9dafe54, 0x34c54b39, - 0x011fde3a, 0x3c31b823, 0xdee5c49f, 0x9e7451a8, 0xc6032e89, 0xb8b11fd5, - 0xdb3b4057, 0x6200609c, 0xf71226cb, 0xf70c4104, 0xfa8feca3, 0xaf8ecc1d, - 0x56f8362f, 0xfc60f3b0, 0xfa611dbb, 0x47d1d0e8, 0x5b47d190, 0xb547d227, - 0x47d193bf, 0x346e5d5b, 0x3b03573f, 0xc70491ba, 0x5937bac1, 0x61a40b0a, - 0x82626e94, 0xb23740f5, 0xc282b6f7, 0x3aebc428, 0xf58f5f18, 0xe652e3e1, - 0x36fadbd5, 0x71fb481e, 0x0799d806, 0xa61e780d, 0xb7a94de0, 0x46e2c2c3, - 0x7ee6cdff, 0x99a9fa11, 0x961fb1d4, 0x3f81eb6f, 0xed875c60, 0xd05dcce0, - 0xae9b36de, 0x6fdc2390, 0xf815c1e3, 0x7f23784e, 0x04963bd7, 0x7bd720bd, - 0x3fdb07c7, 0xde807c21, 0xe8f80193, 0x0af2fdc4, 0xdd9667bf, 0xce40b826, - 0xef618f0f, 0x616ebc90, 0x16bbf576, 0xaf4ca791, 0x5bb83c49, 0x7b2bfb04, - 0x27eb0195, 0x9ea19a42, 0x5f5e2aff, 0x95ddf8d2, 0x89e85575, 0x7818d272, - 0x78f9e4cf, 0xfd2d1ef7, 0xa9a4c7c4, 0x1eed29e0, 0x45a290f7, 0xee265094, - 0xc810f05d, 0x3e3f4a55, 0x7231bb4d, 0x442de014, 0x233e943f, 0x776d0fad, - 0x7c6bad88, 0x5b0be80c, 0xf1152ef6, 0xae7e8e5d, 0x47bc166b, 0xc567eb49, - 0xb4adda90, 0x4d2c567d, 0xf3c09f21, 0x087e7903, 0x743fd34b, 0x7dfa041a, - 0x9ecbf703, 0x922578e5, 0x6399bafd, 0xb8f4cf20, 0x9418e4ec, 0x85beca0b, - 0x5ce05467, 0xdbe7e25b, 0x0334c169, 0x8fb29bac, 0x6021a0a5, 0x4d2b42a5, - 0xce201872, 0xbb8f5de1, 0x7b0bce08, 0x5fb73be3, 0xea81eecb, 0xc7ce7fbf, - 0xebf58df3, 0x2fb8f4bf, 0xb7e039fe, 0xf8f1dcca, 0xbeaf9a4c, 0x69fa32f6, - 0xdf54c457, 0x68ef55fc, 0xeeffc7e8, 0x00c4dfd5, 0x333ffa1d, 0x353fbc45, - 0xf1e8cace, 0xb60e6780, 0x04efe2cb, 0x1c4a8192, 0x15ce2ab2, 0x865eb8ca, - 0xdf86994b, 0x05bacf51, 0xa7ac2059, 0xf6878a57, 0xae78a931, 0xae2eab78, - 0xbb2f3955, 0x80fcc025, 0x42beb159, 0x74faefec, 0x3e49f7f6, 0x9992fa63, - 0xa1ce0ffe, 0x3373f2a6, 0x5efb31d7, 0x09598710, 0x3f08f98d, 0x5afd1536, - 0xfefb4439, 0xaf40d641, 0xf4f28064, 0x67978454, 0x13a795d6, 0x6b915bf4, - 0x4df9c3ae, 0x0cfd2a25, 0x13a346e5, 0xd1f4f1f8, 0xf7f9fe94, 0xe1bff4cb, - 0x867f3226, 0xcdb8ceca, 0xbe515f71, 0xc4696f46, 0xfb7e8577, 0x523f38b9, - 0x2163c5fc, 0x4115173c, 0x8f1e803c, 0x95610eb9, 0xdf13d1d5, 0xf1e9fc7a, - 0x8f51e0ad, 0x9d0f9cb7, 0x9e8ef1f9, 0x23e3d1f8, 0x5be97e7c, 0x7530eb0b, - 0x4bf288b4, 0xfc4f7bc1, 0xedfaf5b0, 0x009eb4b5, 0x0df142f4, 0x30174cf8, - 0x862b27be, 0x3a6c4fd3, 0x140b37e2, 0x0f4801c0, 0x55e3d798, 0x04acc78f, - 0xd5813ede, 0x1af80fdf, 0xed00fc89, 0xb2dd6521, 0xc6f76bd2, 0xe8c4de41, - 0xa7abd14c, 0xbd50bc72, 0xbce6f51a, 0x9bfa2b44, 0x9a9eaf40, 0x5e5bc614, - 0xde571b15, 0x600bcb48, 0xfc0afe9f, 0x0608b1d1, 0x95bcc5df, 0x56e05ff0, - 0xe2ca5f3c, 0xb7df0559, 0x93d5a67e, 0xce0bfaa7, 0xdc3dfe82, 0x05655ee4, - 0x87108c7f, 0xff1479e7, 0xd7f875c7, 0xf36bb3b6, 0x0afc7c7a, 0x27b931fe, - 0xab7a14de, 0x7cfd72b3, 0xfa0a1930, 0x3337d8f2, 0x137f8163, 0xbf447c7f, - 0x4563c4c4, 0x6e9c3821, 0xe2059e91, 0xa7b77d0e, 0x763e0b7f, 0x15494a90, - 0x7253bb1f, 0xd8deb3af, 0xeb298f93, 0xc7af8535, 0x05dde214, 0x4429a67e, - 0x1ec84bfa, 0xffcf0d48, 0xb3f72b79, 0x6043210d, 0x1c585f9e, 0x79f3ff8c, - 0xd54de686, 0x9b3fe84b, 0xb66d9ff7, 0x121bfde0, 0x7842ba94, 0x93f7c34e, - 0xf0f8c6bc, 0xbd656438, 0xd3096a53, 0xfbe2e6e7, 0xe42f14d9, 0x38f098cb, - 0x090559b6, 0xe3e20fdf, 0xf66cdf38, 0xd3db9c42, 0x2b0dfb92, 0x83843df8, - 0x527e7163, 0x3fc81460, 0xb6e5f97d, 0x4e50d5bd, 0x3d6095eb, 0x910afe3e, - 0x3b821ff9, 0x5217be4c, 0xe953d77b, 0xa13946f6, 0xdc3671d0, 0xe801bd7b, - 0xb8c2283e, 0x655cfcfd, 0xcf7645e7, 0xabec45c1, 0xf6f0a7ae, 0x02f7625d, - 0x81db28f2, 0xedfa7a7a, 0x49f34e8b, 0xd3b41e70, 0xcf22abd3, 0x5bfdf81b, - 0x68bb3f45, 0xeb0fbf75, 0xe3efc0de, 0xba8e2ffa, 0x1be7d60e, 0x2d61d5d3, - 0x44f4295d, 0xf438ebe9, 0xf1f99dd3, 0xdfcb503a, 0x049cbccb, 0xe3d151f2, - 0xeb8afac3, 0x9bd7a863, 0xe6dc3f3e, 0x857eb2ee, 0x35e8af3e, 0x6423d97d, - 0xd34644af, 0xebe3ce71, 0x2edcd733, 0x41c68bb3, 0x886fd38c, 0x73cbde56, - 0x393e8344, 0x95ed21af, 0xac573866, 0x07f97e63, 0x3d8d656b, 0xbedb86ec, - 0x67bd9ed8, 0xb6b97f3b, 0xef8a23fc, 0xcef8f141, 0x868ed6ad, 0x7e1491fd, - 0xbf67b7cf, 0xc9c82f06, 0x31a32379, 0xafdf4e7e, 0x7efa7e7e, 0x7035fdf5, - 0xd8c1aafb, 0xd2a9da38, 0x1636ec4f, 0xcd697d47, 0x14f0cd93, 0x73f86f5e, - 0xd4b8879b, 0xa3ae6f7f, 0xa44e7a21, 0x781468f7, 0xc2e7be0a, 0x0fe098cb, - 0x1eff95a8, 0x6cdd9de9, 0xf413f337, 0x6088efd6, 0x8683ea3e, 0xe82203a7, - 0x048223f5, 0xa0ecf0f5, 0x6350b0cb, 0xb97b300f, 0xef003d87, 0x657cd0a4, - 0x0f662eeb, 0x5da1d4b4, 0x0aed4951, 0xe01b3b90, 0x7cc1901d, 0x27681940, - 0x885eec84, 0x7786caaf, 0x0c5db932, 0x37a5a74f, 0x1f33fab2, 0x8c35374f, - 0x9dd5bb00, 0xce932f0c, 0xa8fb5db4, 0xf557da99, 0x508a24a9, 0x76c8aafb, - 0x4ed677ed, 0xde3bdca2, 0xa4bbc025, 0x65a8ff34, 0xecedff72, 0x8fd1b699, - 0xda81bf82, 0x54d9b767, 0xfb6f6f76, 0x039b66e3, 0xfedbd9f1, 0xcd17b4e8, - 0xdf8a3804, 0xe421f282, 0xbe28fe07, 0xf442a3ff, 0x53780b17, 0xe5f6e5e8, - 0x88ced10b, 0x0a6ae6ba, 0x736593c4, 0xb8db703a, 0xc186365f, 0x706189a9, - 0x376e4a26, 0xfbbdd3f4, 0x3bf028ea, 0x04fa3bbf, 0x2b7e79da, 0xf41fdbf3, - 0xe3a91594, 0x026d6bdb, 0x10c097a7, 0xdc777fd8, 0xec0127b8, 0xc0596c95, - 0xb2fd4ef7, 0x99f1e9ef, 0xdb669fc0, 0x6629d257, 0xfde2364f, 0x60547f32, - 0x3d2ac3c8, 0x4ddfcfce, 0x3fdc5ff5, 0xdcff1d44, 0xb5abcd6e, 0xc022f831, - 0x7bdccecf, 0xde80f40c, 0xae584ee4, 0x2b9004b8, 0x24a1eae4, 0xdd6a5f3c, - 0x689f0367, 0xe0e77f17, 0xa49eeb7c, 0xdaad3405, 0xb0369ff2, 0x3e38eae3, - 0xf8ed4bce, 0x76e5535e, 0xa113df11, 0x003d26fd, 0x85d6eb7e, 0x1fdeec59, - 0xc8a6afbb, 0xef9ff1d5, 0x9cc45219, 0x4cff7889, 0x98a737d1, 0x9f183ebd, - 0x1dfd8ebf, 0xf7ba29cc, 0xefe56ec9, 0xcff5e993, 0xe2b26c67, 0xa9f8c32f, - 0x4fd67665, 0xfb2bfb6f, 0x53e204b3, 0x296cbfed, 0xb3f8c220, 0xefc24b3f, - 0x3da40fe7, 0x3df60855, 0x01239d91, 0xa2f644ac, 0xa7cfcb7e, 0xbc2f6fe8, - 0x6793be7b, 0x3cbd6ede, 0x6e2466eb, 0xd004d72a, 0x9803dcc7, 0x07c991d3, - 0xf5bbff45, 0x55dfad33, 0x722b07af, 0x6e3fd732, 0x780210d5, 0xfbc2cc77, - 0x8c240713, 0xc9ebd2f7, 0xbd058353, 0x204fc3e8, 0x4d6d6d7d, 0xfe7b018f, - 0x009f60df, 0xc65eb6dd, 0x49aa83f7, 0xc7781ee0, 0xb455baa9, 0x24fc6007, - 0x67d87af3, 0xe0a13e8a, 0x1eeaeda5, 0x7fda58f3, 0x7d8345f6, 0x76f10505, - 0x57682ff0, 0xc1fdf84f, 0xfe679004, 0x07e784a0, 0xc6f717d9, 0x45f1542c, - 0x7e0355ff, 0x6eeafb7f, 0xfc60f7ed, 0x8b6ed0f5, 0x7bcbd981, 0x063dfff7, - 0x57dbd4f8, 0x90bc212f, 0x6f53d13e, 0xcf3bfd46, 0xd1fc862a, 0x8899bd6a, - 0xde2187d9, 0x152c6a6b, 0xfaef426b, 0x6487ce70, 0xd4f49595, 0x2778422b, - 0xd0f0092e, 0xf0561f43, 0x3e33d3ac, 0x773d71b2, 0xef0f1918, 0x4d5db65e, - 0xc77bc0a8, 0x0afb18fe, 0x8f4ccf94, 0xee7bdeea, 0xfdf0e9c9, 0x9ddec8a0, - 0x7ee22ab8, 0x62b3bdda, 0xdf6a8778, 0xeb8a4e52, 0xc5d06576, 0xfad16f0b, - 0x3345f657, 0xbce4baff, 0x224f7d5e, 0xf1c7df5c, 0xcecc1815, 0xe183bce9, - 0xac6fa8bd, 0xb0f574cf, 0x4361fff7, 0x0058393d, 0xfad462e2, 0xffac234e, - 0x3e8ad9bf, 0x25a5fc67, 0x978bf806, 0xb4210ee4, 0x9268b2df, 0xac15740b, - 0x33b07623, 0x18301fb6, 0x37325d60, 0xcf5c62a5, 0x731cfc2b, 0x31a34b49, - 0x4b174555, 0x19d839f8, 0xaf129bd9, 0x9632befa, 0xfb3397f1, 0x71817fca, - 0x91347f1d, 0xd0f41191, 0xfe4cb185, 0xa77a336e, 0xc77a866f, 0x68df780d, - 0xef5ffeef, 0x97937787, 0x038c731c, 0x5894e0bf, 0x0eda0fb6, 0x710f52be, - 0x821f6dc1, 0x6672a2d4, 0xa068b163, 0x1c45befd, 0x9877afcc, 0x90d6bdfd, - 0x12b8943f, 0xc5379e60, 0xd6fdbe32, 0xdce68301, 0xbefe2dec, 0x8cb1f5ef, - 0x32c6a50f, 0x03d6dabf, 0x700b09b9, 0xc447b9ff, 0x64f01f82, 0x456c3d47, - 0xe8a80fc5, 0x6f0f936f, 0xfe863e9d, 0xc1977273, 0x38edcb0e, 0xf30882fc, - 0x24219c75, 0xf43d204e, 0xac6f0a39, 0x5d5bde1a, 0xc71d1e0c, 0x0aafd86e, - 0xfe04a9fe, 0xbfcd0671, 0x43c52ed5, 0x7f82983c, 0xff4a1e65, 0xdae2168e, - 0xe4adc160, 0xfe15fada, 0x31efe568, 0xe513b04c, 0x5d2033ef, 0x6eb9b76e, - 0x6f72c589, 0xeccfe40a, 0x36d27a63, 0x72494f2e, 0x9fc070f1, 0x79f34eb2, - 0xb7a78caa, 0xe3e7effe, 0x4bafd254, 0x0ec8afd7, 0x76cdd22f, 0xf0ee4f16, - 0x10e9cc06, 0x8e96d677, 0x154a9f7f, 0x8e3f7b97, 0xfdf68cff, 0x830eb6c2, - 0x558fee01, 0x50e210ef, 0xbea7eddd, 0xa933a21d, 0xedafe905, 0x5c7dc118, - 0xe65dfcde, 0x9f72a48f, 0xe786ebbf, 0xf87fb0eb, 0x8120fb39, 0x1bfd93a6, - 0xfc410e56, 0xafb06c06, 0xfba278c2, 0x46dad206, 0x92ebd023, 0xe52d2c65, - 0x9a4bd5e7, 0x4b3fb8dc, 0xc478b3d6, 0x4ca9b165, 0x257a733e, 0xf8c1e886, - 0x7b4dbade, 0x5c1ff08f, 0x7d6d9e7e, 0x4bf40f6a, 0x80fbebe9, 0x9eda9b8f, - 0x55c30758, 0x46ecf5e8, 0x4594e119, 0x3df3cf6b, 0xb8cfccb1, 0xf7a330fd, - 0x5ce51bc9, 0xb26c4f78, 0xbfc1d897, 0x4dc6d6fd, 0xb7eff022, 0xd9539e80, - 0x7b79073e, 0x3163df66, 0xd6f907df, 0x47e02069, 0x652466df, 0x62fb545b, - 0x343786ef, 0xb9bcb7fb, 0xebfa3a6e, 0xe005e23b, 0x55becaf3, 0xe8cdbef0, - 0xfff70dbc, 0x9ffdba9d, 0xc2b7dacf, 0x4f7ad0ba, 0xd4fffdf1, 0xe9ffba34, - 0x718db8a7, 0x66d9c002, 0xdccefc8c, 0xfe90df4b, 0xa3b57c42, 0x297d5f07, - 0x6c1ff996, 0xeaffb4e9, 0xffa12e3b, 0x4e3e3421, 0x2be54f37, 0x002a9374, - 0x0ae91bfe, 0x517c008e, 0x533d02bc, 0xccfe7a3d, 0x0795dc0c, 0xe1ff3c24, - 0x2e3c4be7, 0x6a947704, 0x99f986bf, 0x6fdd6fb2, 0xf2b238c0, 0x9e82576b, - 0x45e8509f, 0xb82b3cfa, 0x7953c787, 0x71f61676, 0x8eb07e04, 0xec8ae3e3, - 0xff7debee, 0x65cf40c1, 0xf98462d4, 0x1d82f590, 0x772945d6, 0xbdef67ac, - 0x94f0e61e, 0x2dbf87ef, 0xde3d83be, 0xf0cc3d21, 0x5c42341d, 0x931f28eb, - 0xc5c84463, 0xb70c40fd, 0xb67d860f, 0xfbafca84, 0xacebf255, 0xaa7488dc, - 0xce23e1e0, 0xb1c4aeb7, 0xc7ce3f79, 0x5d1f07e9, 0x82ff0aa2, 0x3f6c0924, - 0xe7db028b, 0xbb3fc022, 0x90dba6ef, 0x4c88efde, 0xb7b076ef, 0x47efe1e2, - 0x8cfa406d, 0x7bc7669b, 0xce494f2f, 0x7e8d38a8, 0xef74c3e4, 0xced067a6, - 0xfd85fa03, 0x97fd1bde, 0x0893fd01, 0x74a3ef74, 0x853f5aaf, 0xfc5d280e, - 0x7ca5f01d, 0x7285d3d7, 0x65e0a90e, 0x731cee9b, 0xe9e19daa, 0x8d5200ff, - 0x8000b56e, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5547c09, - 0xf37df8d5, 0x3332c966, 0xb2764c99, 0xa00c4930, 0x80490e2c, 0x084ed8b0, - 0xc3884a20, 0x93a0d752, 0x364b0900, 0x94569510, 0x8b062081, 0xb62d1518, - 0xef858320, 0x106d1b43, 0x268358a8, 0x622d1110, 0xa57fb1dc, 0x41459041, - 0xed1fa822, 0xe73bf587, 0x33337bdc, 0x6a02266f, 0xefc7e1ff, 0xdf77dee6, - 0xcf7ece5d, 0x6ec5f739, 0x843631d3, 0xae630731, 0x7d8c01e6, 0xf4bf3f8f, - 0xa12d8c97, 0xcf3773e7, 0x8224715e, 0xf0f7cfd1, 0x5e79babf, 0xc776bd50, - 0xe91c57af, 0xc5cfafe7, 0xffe0525f, 0x8967a671, 0x47f1558c, 0x89ef4cac, - 0xfbc025b5, 0x6cd69d11, 0xe266b498, 0x03846319, 0x8319789f, 0x1c636ff6, - 0x6faa3e54, 0x1f2bd3de, 0xe9cc31ca, 0x9b39a685, 0x998f1533, 0x1b3605b1, - 0x27f967ad, 0xb0dd93d3, 0xc6c646de, 0xc59bbae3, 0xd9dd727c, 0x99c68536, - 0x8f7329e0, 0x66678389, 0xa07b9e4f, 0x6607f9ff, 0x886d964f, 0x70a13ebf, - 0x4018eabe, 0x7ec48c4b, 0x0c985563, 0xc9bf9fe6, 0x326533e4, 0xc49f05b6, - 0xa3db2ac3, 0xfd329b7c, 0xccf4d9ef, 0x9633b7a5, 0x75a4cb6b, 0xb15aeac1, - 0x646858ee, 0xdfbcc197, 0x9bb59666, 0x1dd5d1e1, 0xb081e2de, 0xef462d8f, - 0x389989d4, 0x1c1af398, 0x9d629aff, 0x6a5801ed, 0x38a6cbac, 0x6992d007, - 0xcf8fb65e, 0xeced9793, 0xeea1b2cf, 0x2db9e670, 0xf8128d8c, 0xc930ad62, - 0x421c3f70, 0xd9e1c6f1, 0x20175e13, 0x1750867c, 0xd5e27e7a, 0x667d1ba8, - 0x0144f3ff, 0x78632fbf, 0xd3c1adf9, 0x1d0e66db, 0x553e6027, 0xcacc6649, - 0x5c554b3c, 0xdb6628ff, 0x773ff0e4, 0x1c2e628c, 0x57189a7f, 0x8ffacbb6, - 0x10aeafa6, 0x78869afa, 0x22e88ead, 0xd053eaba, 0xbcc07469, 0x8bdd194c, - 0xee98fac1, 0x80ac5eda, 0xbd71eaba, 0x29554800, 0xf6c7ebe0, 0xd7338d84, - 0x01d99e23, 0x0cc9cb13, 0xcdb567dd, 0xd1b6e1c0, 0xe866fa30, 0xb865e097, - 0x838bc003, 0xde3585e3, 0xdc6bf88a, 0xd7886268, 0xdc39636f, 0x68d953ac, - 0x42b7f403, 0xc6f7247f, 0x57039ea9, 0xd931bd41, 0x9e6050e8, 0xc22e8613, - 0xa0ab89fb, 0xadc3e88d, 0xbc4fbe20, 0xdf9ae23a, 0xa277bb40, 0x8bc0e58e, - 0x05b08d5b, 0xa7bfc3a4, 0x482936f9, 0x27c42da7, 0xc1b2c7f3, 0xbede7826, - 0xd5d11869, 0x052ce2ac, 0xe6ce76e9, 0xdb9f0558, 0x2a74d8c7, 0xd863eff3, - 0x13e89542, 0x16dea0f8, 0xde618f80, 0xd5e1153a, 0x6c93ce3b, 0x11ec6588, - 0x23e335db, 0x32ce81d2, 0xcc1b2459, 0x5f5043d8, 0xb46b7009, 0x4b1614bb, - 0x0a7306f5, 0x236321f1, 0x0cadae08, 0xd518d4f0, 0x6045775d, 0x7f5e2cff, - 0x86eaf1a4, 0x9ec63486, 0x22357189, 0xbb303e9e, 0x87f9c11f, 0x44a9d526, - 0x7fae82e7, 0x127ece80, 0x2c2ed4bd, 0xe0f38762, 0x0e660ef7, 0x47901ba4, - 0xf8066eb7, 0x9b3de895, 0xbd355d70, 0xc38e3e8e, 0x657cb6d5, 0x7ba184f4, - 0x21788eb9, 0x8cc7d817, 0xaeef11f0, 0x7ecdcb53, 0x66c5b3b9, 0x52ed4c17, - 0xfcfc5b26, 0x79eb7286, 0x593b9733, 0x98229a50, 0x7ec762d7, 0xac23a23e, - 0xe5fae4c7, 0xdd62cad1, 0x3e185f78, 0xeb890d7e, 0xaccf9467, 0xf2ff7fe5, - 0x1fd0a19b, 0x9f89577f, 0xc4fce35e, 0xc5a3f5e5, 0x3c22269f, 0xbdf09390, - 0xeb1cc5db, 0xeadf3a97, 0x5fb9748b, 0x3ea09b65, 0x2af464d8, 0xe66db831, - 0xf18a25b0, 0x945b0d90, 0xa820cb56, 0x2e614bff, 0x7fe9c3c0, 0xbfae54a9, - 0x133e3dd7, 0xa1d9afde, 0x7e852e73, 0xf10a2d35, 0xf337b383, 0x371d0045, - 0x31075947, 0xb770af18, 0xf68065d9, 0xc9044ad3, 0xd7009c65, 0x2feb9061, - 0x8268cae8, 0xc02df5e7, 0x5d3d507f, 0xf5c6a808, 0x6c319dea, 0x83be1f80, - 0x1fb47cde, 0x1bda00ec, 0x4f67c89d, 0x9ff1f245, 0x81f0cc8a, 0xbe528310, - 0x4a0188e7, 0x6e825961, 0x62c67af4, 0x78504f00, 0x30b51cb1, 0x3c07a5db, - 0x35e67a2b, 0x7546be00, 0x9f08aab5, 0x8e872eac, 0xe9f3fd99, 0x3bed18bb, - 0x39d0ef4b, 0xd6d5f403, 0x7aabcfbd, 0x31d0eb80, 0x942af58d, 0x6f9e3189, - 0x4623de10, 0x7b63d5d5, 0xf557b15c, 0xa57cff40, 0xe905b76e, 0x44e61aec, - 0x24f92ab9, 0xc1b593ae, 0x81ec5972, 0xda15974e, 0xb5771c47, 0xc7fd800d, - 0xe38299b8, 0x7c0dfd49, 0x0e9162c6, 0x44ca5de3, 0x3fe86718, 0x8e47c118, - 0x68ef75b3, 0xbe3ef905, 0x18e28c63, 0x6be74a10, 0x38b7e398, 0xce9f77ae, - 0x3475f889, 0x9406d733, 0x62ba7f13, 0xf64bc20c, 0xf5cb1def, 0xa78f48ca, - 0xee154408, 0x1de70627, 0xb76fa37e, 0x6c33d601, 0xd1b77796, 0xd99fb011, - 0xed4bc68c, 0x523ed2f4, 0xb10a780e, 0xd2c6b6cc, 0xb78e2338, 0x7e800db6, - 0x1fb07549, 0x78ef4f68, 0xa6b8414f, 0x882875d7, 0x777badcf, 0x3ad37ad1, - 0xf82979da, 0x176179eb, 0x5603db74, 0xdb23ed1d, 0xf2cdf5ca, 0x666f5c53, - 0xadb27ac7, 0x2c7dfe09, 0xd724f42f, 0xf66bf8c1, 0x17ef7566, 0x2895eee5, - 0x52e403e4, 0xc691ac6e, 0xe9eacbb9, 0xbdabfb8f, 0xd20f73b1, 0xdf7bf3e0, - 0xb47f12b1, 0x137e13c4, 0xf84a7df7, 0xba485c48, 0x37d9ad98, 0xb179415f, - 0xa67014a6, 0xca59c284, 0x7eb8358d, 0xf45b1fa2, 0x27cfa024, 0xd8829eed, - 0xcca57b40, 0x20159d1e, 0x8f7be497, 0x19ee662f, 0xed6190b0, 0x16595be5, - 0xb17ef7c9, 0xc27df201, 0x9122fbc0, 0x2e2c9a9e, 0x569fb617, 0xcf388dd8, - 0xfb425833, 0x975e0633, 0xe0407af0, 0x52763b33, 0x870875b6, 0xf8e80d93, - 0x4fde4899, 0x8dee8f2b, 0x83bb09d5, 0xe0eb0bd3, 0x08fb82f4, 0xc666bfb4, - 0x748c3c72, 0x9cf48a79, 0xfee2a64e, 0x76f81786, 0x1b0edd23, 0xf48dddef, - 0x9d04ce9f, 0xa274e78c, 0x63dbf7a5, 0x711d7cb9, 0xdc218bbc, 0x0ee615f3, - 0xc654ef67, 0xbe29bb72, 0x0fd13463, 0xce1943f0, 0x4eb53437, 0x66dca035, - 0x7fa809b6, 0xa0eb137e, 0xae05797e, 0x366f48dd, 0x79f89b97, 0xe9c6d9be, - 0x07d39326, 0x1c273fbc, 0x3e436d3f, 0xa3e7e01a, 0x7347a478, 0x26de3d28, - 0x011bf4e0, 0x3df1d0df, 0xf1f8e177, 0x02973a1d, 0x603b0c83, 0x3ae831f6, - 0x49e8016c, 0xf40653e4, 0xcfb40b0f, 0x9f2215b2, 0x153956a5, 0xb302ebc4, - 0xd7dc1efb, 0xf98d9472, 0x5f3acf48, 0x6c97bc3d, 0x7efe1173, 0x67689eb4, - 0x90686c11, 0x2c40f59d, 0x9557e3b7, 0xfa7ebca1, 0x53ca235b, 0xbdbfe487, - 0x01e5d1b9, 0x50c7f1f4, 0x0e123f7c, 0xa7395adf, 0x2e5fb7c5, 0x8039cb04, - 0x0f8e5ad7, 0x77c7e76e, 0x7cb9502c, 0x3d6b9608, 0x3e4423e1, 0xc1fc3c08, - 0xeb84daec, 0x4045c6cc, 0xfacd1de9, 0xfa4f7b61, 0xf358c5f8, 0x2f67b34f, - 0x8c5f8fac, 0xc7d5084d, 0xd7ae88ba, 0x75478015, 0x6150ea8b, 0xec8bf50b, - 0xfaffc42e, 0x7689c566, 0x9516eee1, 0xf2fd61e8, 0x729bd228, 0x8f6e5fbd, - 0x84aec419, 0x6b3ff052, 0x5a7d258f, 0x5fe62b1b, 0xfcc0bf06, 0xbabc6da7, - 0x3d79e6dd, 0x6fad0e50, 0xe11226f9, 0x71593fdc, 0x4abb411d, 0x85818fab, - 0x84df7814, 0xd70829bf, 0x322a0dc1, 0xad9ef5d6, 0xf6f09526, 0x8c378e2e, - 0x0a33be75, 0xa6a7f5d6, 0x7b40bad1, 0xaf8eeceb, 0xeb05dd6f, 0xfae68daf, - 0xeb9a36b9, 0xcebbd3e7, 0xbb7a41f7, 0x9274e176, 0x9ef4c37b, 0xdce5038f, - 0x730efd1b, 0x6d4acc39, 0xd4e3fb47, 0x68fbe52e, 0xa235a100, 0x0aed1e9f, - 0x06a9ca35, 0x1c4415db, 0x1f0039f5, 0x145b5f84, 0x073eafc1, 0xd6932ef8, - 0xd9d70279, 0x14b2316e, 0xfc0b3f68, 0xbae4fd88, 0xcf7ac47f, 0x9a6f5f84, - 0xa0b468ed, 0xbebfd50b, 0x1e20bc6e, 0xa2d57c60, 0x669c7da7, 0x67c44e51, - 0x10c5d1b3, 0xc283deff, 0xab78103e, 0xba773411, 0x0f01c865, 0x81fd6fec, - 0x7fbe2734, 0x48d9c77a, 0x47ed199d, 0x7d876a8f, 0x565de9a9, 0x5bbb87d4, - 0x39de5ece, 0xc19be480, 0xbb3beb0e, 0x33ddb0ef, 0xcfed47e0, 0xfd88bf6a, - 0x0dcdead5, 0xaa227681, 0x1a945259, 0xda5a523a, 0x220ca9fe, 0x0f2863fe, - 0x57cc19bd, 0x3e5efb0f, 0x54d3d050, 0xd7be40e6, 0xcdbb7be2, 0xe00f619d, - 0xb736cddb, 0xf385d703, 0x3ed2e6a4, 0xe83eb0b3, 0x0679e9cd, 0x0c6fee1d, - 0xed29bd43, 0xb44fb93d, 0xfd7323c7, 0x5ef693fb, 0xce73fef7, 0x68c7da0f, - 0x74ec83df, 0xc52c740e, 0x282d5a73, 0x03320785, 0x784adff7, 0xacfb16a9, - 0xaab7308e, 0xcdb62fb0, 0xca53b270, 0x7dd0ac83, 0xf3869e00, 0x780f387d, - 0x377fcf10, 0x4e11eb3b, 0xda1b0efa, 0x91afb0af, 0x50560fb8, 0xf8708c96, - 0x8c9aecc0, 0x2599fef2, 0xf4fae88c, 0x14f7ccb3, 0xbb4b7a6c, 0x0366e88e, - 0xffe882bb, 0x5b99dd0a, 0xebe266dd, 0x7e7ef8b1, 0xe50ea347, 0xa1cf8e6f, - 0x797ab943, 0x474eb347, 0x2f19e0f4, 0x0f5674e0, 0x54dfebeb, 0xba48fea7, - 0x2e9e1498, 0xabf6f042, 0xb849bc40, 0x30f4128d, 0x3286e10a, 0xb27f4bb9, - 0x370fc233, 0xb54b0bc0, 0x58c78e87, 0xa9c20667, 0x7d63c5ed, 0x9abc613a, - 0x8add8f97, 0xabf9a970, 0xcc618889, 0x418f2f5f, 0x30b2ffba, 0x72735dbc, - 0x0f5b9d71, 0x3dab78c4, 0x157be48b, 0xbda230eb, 0xaddd7200, 0xd2eb900f, - 0xe867db8e, 0xf7f1c628, 0x12d9510d, 0xe759f380, 0x461624b0, 0x3f72c85f, - 0x00396dda, 0xe155f47f, 0xfcc5e4f9, 0xda476e18, 0xb25afc83, 0x9678b7dc, - 0xe7a18c7b, 0x8e0df6f1, 0xb14e7f24, 0xc87a1ec6, 0xa78dedce, 0x81cf5ced, - 0x3ae17660, 0xe2c5fd4f, 0xa9d342f3, 0x0cadf7dc, 0xdb6a74e0, 0xa05e79bb, - 0xe3ac53a3, 0xdf9097f6, 0xb9d336be, 0xfbf078ae, 0x7e2c4b79, 0xfb8abcfe, - 0x2f55d852, 0x407569bc, 0xbb2de2ff, 0xf001bde3, 0xbfe98abb, 0x4ceba6ee, - 0x8fef979c, 0x20fb3be9, 0x274bd83e, 0x16501d12, 0x3c6af8bf, 0x373803a7, - 0x14ff450d, 0x633f8fe7, 0x5ddd8053, 0x3dc6b0bc, 0x1fc02f26, 0xf9922e73, - 0x0efaeb02, 0xab891e23, 0xfda999cf, 0x9e25bb76, 0xd62f4de4, 0x8f4de50b, - 0x7848baf0, 0x3c25db6a, 0x913e0df7, 0x97c5f681, 0x07c5d83d, 0xaf7ec1ec, - 0xdc7b1637, 0xf5fc7263, 0xdea77dbf, 0x5ef30ee6, 0xacff188b, 0xda127873, - 0xd6c6c57d, 0xe1f9c2cb, 0x0b5339e4, 0x57ce37a7, 0x7fb8e346, 0x1f1a6739, - 0xeddb5d6e, 0x3fe69fba, 0x0aab07d8, 0xf44b0bb0, 0xdced379e, 0x326ab05f, - 0x3f2e6bd4, 0xd9ce8e3b, 0xdc845e92, 0xdb798abb, 0xf4b57f90, 0xbefdf121, - 0x4b2a5bc4, 0x693dbc45, 0x11ba7077, 0x43f920fc, 0x396d470b, 0xe13cc8c1, - 0x75cf03ce, 0x799235c3, 0xbede1e41, 0xfe7a40c1, 0x4e1ff3cd, 0x3f7a03cd, - 0x5b60d6b6, 0x5ace530a, 0x51ed3bb7, 0x360da7f4, 0x1fa814d9, 0x865eb473, - 0x4eb95f7c, 0x1c3d2375, 0xe27b7b5b, 0x00bf2874, 0x7582adfe, 0x50306e54, - 0x770dacfb, 0xc109fb50, 0x12eb95d7, 0x7cbca3fa, 0x4481fdb3, 0xeface3c4, - 0xf11ebfee, 0xeb68c5b2, 0xaaca183f, 0x263dc526, 0x3673de00, 0xb7d50646, - 0xdc2cd8e8, 0x532bc487, 0x1dcfdd3c, 0xdc631eb0, 0x6b63c44f, 0x18d51f88, - 0x92ccedc7, 0x9aefb029, 0xbec96721, 0x8a27bddf, 0x662bc9f4, 0xd6c8ec95, - 0xb7f3ffc1, 0xf45ea12b, 0x3649de9d, 0x58f3c09e, 0xce866781, 0x8a8fa040, - 0x7a2f5e08, 0x68764f51, 0x78254591, 0x1d5c82b7, 0x65de4a43, 0x7efd0b1e, - 0x4753df21, 0xfd0e1ead, 0x1818c6c6, 0xb45fa1ea, 0xa06629ce, 0x4e797f27, - 0xc06769ff, 0x9733467e, 0x42e2ed1e, 0x5f6a0866, 0x0a7d6511, 0x4c185aed, - 0x28b0fa8f, 0xd8f9f822, 0x813daecb, 0x5b58c4f6, 0xbfa4bb70, 0xbfa0389c, - 0xb1b97efe, 0x8fe7cf7b, 0x567d804c, 0x9ec953ec, 0xde5c90be, 0x41cafb8f, - 0xda51bf7c, 0x29bdef04, 0xf9e6f3a0, 0x9052cb63, 0x86140abe, 0xe763ae7e, - 0x5ce5f3c3, 0x018c9f41, 0xf1f9fb9e, 0xbb39d13c, 0x7f6c8ebb, 0xeebcc15d, - 0xe2ffae3a, 0xcb0fd9e5, 0xf73b4eab, 0x87f5686f, 0x53fe7f96, 0xf078a3fa, - 0x0b5e19ab, 0xe585ff95, 0xfe5c2dc9, 0x5685e56a, 0x6975c85f, 0x4e7d5bd7, - 0xcf13d20d, 0xd7e27909, 0xfe7a4617, 0x6b8f9e33, 0x9e8486e2, 0x219ec18f, - 0xea877978, 0x760e5ce9, 0x6fd8edd7, 0x5711d980, 0x665a4b08, 0xb9468acb, - 0xdcf164d6, 0x97e01719, 0xa8d4dfea, 0xedd1f943, 0xfb0431af, 0xf5f9e46d, - 0xffbe389e, 0x875e38f2, 0xfb9d2bf3, 0x92794437, 0x2f6f38f5, 0x7e3033a3, - 0x85fbcb25, 0xaf7690fc, 0x9da577b4, 0x7d59ed2b, 0xb367b703, 0x7e41dd63, - 0x5fafd633, 0xed183f90, 0xef73e474, 0xe7da28ae, 0x107b8a67, 0x731569f2, - 0xa017143d, 0x7c0deb07, 0xbcf5dafd, 0x13ec2716, 0x413b26e6, 0x1d1ccfb6, - 0x8d6f9e5e, 0xc2ff53d3, 0x40ca6fc7, 0xb6b3ee3b, 0xce50339b, 0xfff1a67e, - 0x0f0fc4f6, 0x507d7e0b, 0xe15893e8, 0xf9087827, 0xedc0ea08, 0xfef02dae, - 0xe26ec58a, 0xbe2edfab, 0x1747ca91, 0x8fe7a42f, 0xfcd265c5, 0xdc77c2b6, - 0x23a700d9, 0x17d2552b, 0x3eee8d33, 0x91def0b1, 0x1bf91d08, 0xc799d70e, - 0x3b63336f, 0xcce5f3a3, 0xf26c27c7, 0x1f01f806, 0xe90c7dc3, 0x09af9f79, - 0x9d2a5ebc, 0x2b4eb356, 0x7a6eadea, 0xb7a2103d, 0xa72f11db, 0xf6226759, - 0xfa3a55ab, 0xf3a12934, 0xaf5cc83f, 0x2366bf61, 0xd37c8feb, 0x92f5c51c, - 0x029bdfb6, 0x9ed0ab7f, 0xd433f285, 0xcce4615f, 0x7b5e823b, 0xc4ef5d5b, - 0x9333bc91, 0x56eb4edd, 0x3ef44e29, 0xb4e707ce, 0xc639f10f, 0x975fd089, - 0xc775b56d, 0xc779f855, 0x185c71fd, 0xfe4f5c7f, 0xee3aed1f, 0xd570e789, - 0x296485fa, 0xc4c742fd, 0xd9c5167e, 0xe844fc82, 0x0fe70f0f, 0x48de3aba, - 0xd510dbfb, 0xa8b8c5e9, 0x3e7e66f7, 0x55e51a4f, 0x5a95dfd0, 0xfe8858dc, - 0x71c67fb0, 0xbc7da63f, 0xf1cf1927, 0x4e8d92bd, 0x2c5ce3f4, 0x76680e3f, - 0x478138f1, 0xd358eb47, 0x03ec8de1, 0xf0ec4aeb, 0x34a11a14, 0xf8d226c4, - 0x096eac49, 0x11fa0de2, 0xa3dbf230, 0x743c8a7c, 0x213c9743, 0x91a56147, - 0xaddb77c8, 0xbc3c531e, 0x5d467437, 0x53edfa3d, 0xe23c78ab, 0x6de9e284, - 0x1b8d0ecf, 0x5e3932cb, 0xbb88aff0, 0xd0346fe6, 0x3e37f2ba, 0xfcd1f146, - 0x95eb578d, 0x1f943900, 0x27fea06f, 0x9bd39d5e, 0x851f18fc, 0x880ebf8f, - 0x4662f4e7, 0x8a10e11f, 0xbfa58687, 0x313ff17e, 0xf609dcae, 0xef3cb050, - 0x20243f17, 0x0cfaa16f, 0x3c7d73c9, 0xc07f23d7, 0xd358057c, 0x7cc8661f, - 0x8fe40d85, 0xbe6c6add, 0xde51e306, 0xbc431d1a, 0x2bf9efb7, 0xcd676bc5, - 0xb6bc5070, 0xcf7dfdfb, 0x3ff6c72c, 0x118362cc, 0x87be29fe, 0x7ccff415, - 0xc9e3c91b, 0xb1326edf, 0xd9a5b025, 0x3c53376f, 0x8e954d78, 0xeed17ca1, - 0xe832661b, 0xa0db5c78, 0x47f8e02b, 0x0ef12839, 0x7c446404, 0xfc21bc48, - 0x6e3198b6, 0x5fad02fc, 0x7e80cbae, 0xc7dc04f0, 0x4e906b96, 0x15d9557a, - 0x75c817f4, 0x4c9f485d, 0xfa69ff8a, 0xc3d467e4, 0x9c5fc5b7, 0x74819e1e, - 0x5ac3d5ae, 0x7164dbfd, 0x0bbf6255, 0x4213e1e9, 0xd7894dfe, 0x7e3043c4, - 0xc76f0616, 0xf00c1c84, 0xff19df8f, 0x1fe3fc23, 0xe3091ca1, 0xc8c67f1f, - 0x9da36fe5, 0x0c2936dd, 0xe627bcbf, 0x32eeadd7, 0x6f8cfea2, 0xb3cac251, - 0xc651ab6c, 0xfae05713, 0x2b44fc64, 0xb7c0c38f, 0xde5ffb11, 0x7b0bbad4, - 0x165ec6e5, 0x15dbe68d, 0x37b9c3df, 0x046b3ccc, 0x30163b9f, 0xea3aa38a, - 0xa82bc918, 0xb093b8fb, 0x0023f295, 0xb8e04f1f, 0x9d638a17, 0x1d9215b6, - 0x8656e324, 0xf8f3e0d8, 0xcfd9789e, 0x6fc447f5, 0xe27a0f7a, 0xb05d624f, - 0x5fb067ff, 0x141602fc, 0x9971919f, 0x62af3af8, 0xc47547cc, 0x3bdadfc8, - 0xf304b3ce, 0x3386ba3f, 0x8f5053e7, 0xa215b529, 0x72cfb53c, 0x66fc61b6, - 0x9fee29f9, 0xf98f3e5f, 0x79012a96, 0xca2c9e05, 0x05bc4203, 0x0a7607fa, - 0xac53b6f9, 0x5fe4f41b, 0x5abaf9e3, 0xa4f403e2, 0x756e87c4, 0xed784aab, - 0x02a7af0a, 0x43fedaf0, 0xf919fd78, 0xe48b9df2, 0x852f0fcb, 0x9171fe6e, - 0x8c4bf374, 0x3b090c6f, 0x578867df, 0x67407ced, 0xbef88347, 0x78db3a07, - 0xf9d2f189, 0xa7a89fe6, 0x5dfae142, 0x5c28427c, 0xfaeb1657, 0x5166bc91, - 0xd57a70ce, 0x4ffe6096, 0x12d891e7, 0x1e7a5c86, 0x3b7bfac9, 0x1967888d, - 0xd5eb9107, 0xf6c88fe6, 0x0f25169a, 0xbb859fcf, 0xe039d3cf, 0xe8bfdb74, - 0x079a101c, 0x0f9de7c2, 0x39fc8de4, 0xdcd01d56, 0xa677fc0a, 0x752748c9, - 0x377e3995, 0x7bf7fd0a, 0xa0e7cc0d, 0xffd811fe, 0x5ffbc60a, 0x03bcb4d1, - 0x305757fd, 0x479c57bd, 0x1db9ef95, 0x7c7c8315, 0xf2955ec5, 0xfe66d8bf, - 0x2c458ebc, 0x4c74ff41, 0x02398e81, 0x8aeb19e0, 0x78008e62, 0x07b78dc6, - 0x7939e5d5, 0xc13798ae, 0xfde82bdd, 0x82b31ba4, 0xae78a7fa, 0x3a9e7a08, - 0x9ea8372b, 0xa822375e, 0xa385ef7f, 0xde99ea83, 0x67fa836b, 0xaa0e4c37, - 0x1cde34e7, 0xab18ffd4, 0xec147c7b, 0x5bfa3fb3, 0xebcc3f00, 0xd60cb8ea, - 0xb7ac433b, 0xa0f29aef, 0x5afd81f7, 0x53381e31, 0xcf17c990, 0x00abdf8d, - 0xff08671c, 0x39bee5ce, 0x55cfe341, 0x677e88ab, 0x048e1a36, 0xacf469fa, - 0xc02a4f6b, 0x38a7c6b9, 0xb95ea15b, 0xecf9f826, 0xbde81b1d, 0xf6e0bed9, - 0xeb839bb9, 0xd29cde83, 0xb901e79f, 0x4672bf29, 0x87dfb042, 0x9989d085, - 0xb599f4e4, 0x7aa5ffdc, 0x24e86afb, 0x27ec5f18, 0xd0438dd2, 0x9839298d, - 0xc11d226e, 0xfaf95374, 0x0708a1d6, 0xfba3fc2d, 0x0bc9e869, 0xfe007eff, - 0x7d306716, 0xfb4ee169, 0xec567583, 0x95efd850, 0x6acfb850, 0x2a797879, - 0x633b850b, 0x1fd7233e, 0x688fedc1, 0xd981fde0, 0x89ca18f3, 0xa8163bb3, - 0xe3638718, 0xecff3c79, 0xed07af8e, 0x2f898473, 0x97c484e5, 0xf80425d6, - 0xe97c647f, 0xaf19c634, 0x67111764, 0x844ffddc, 0x8f00c807, 0x0b11f301, - 0x71dd119c, 0x3c7f48c5, 0x653f2b49, 0xb9e3fa09, 0xfe2bd204, 0xbc3d6c78, - 0x03e6343d, 0xc653ae37, 0x8ebe64e5, 0x930a2bcc, 0x8497fc9f, 0xb40fcc04, - 0x75f9e347, 0x3a7cfb4b, 0x22bcc977, 0xc302f226, 0x4fa4ffd8, 0x14d7f19a, - 0x26760bb2, 0x0afebd70, 0x176dd78e, 0xa92fbc88, 0x471a7bd7, 0x2a7adfc6, - 0xc52a5d95, 0x2894bb13, 0xf46153e7, 0x3f0947ca, 0xe685bf51, 0xa8147f8f, - 0x38ee6a47, 0x0bf507bb, 0x6c63fdc0, 0x6f4058b7, 0xfdbd7e2b, 0xd12b68bb, - 0xaaebd76b, 0x9c342faf, 0xd8c47089, 0x222d8e01, 0xe445afdf, 0xd6f5c9fb, - 0xf4baa445, 0x9c1ed879, 0x8ae327ff, 0xc28dfdda, 0x3afe71fe, 0x976417bc, - 0x76e5cf2c, 0x870169db, 0x276e160d, 0x9db91318, 0x1f39ab50, 0xfb7036d5, - 0xacd7a40c, 0x8c718096, 0xdfea1689, 0x4c685cdf, 0xdf8471c4, 0x42a67965, - 0x4572c576, 0x77e47b21, 0xfcf4d1b6, 0x868509cf, 0x6fffe844, 0x6011af31, - 0x16636588, 0x93438f5f, 0xe892fe17, 0x68c252ff, 0x36898d2a, 0x5db67fe1, - 0x6a91f481, 0x5da91976, 0x8aa71f0d, 0x1afbe44e, 0xb464f229, 0x42718071, - 0xdfdfa26e, 0xe2d2edc4, 0xfe4189b1, 0xf18cf7fe, 0xd0afdfc2, 0x53942eeb, - 0xef7814bf, 0xeaefffc9, 0xf1476b67, 0xaffff5ad, 0x7ffee48c, 0xf1081f19, - 0x85c73bff, 0x1e23fff5, 0xfe7eeda2, 0x2dd893e9, 0x3e50d29f, 0xea7a30ed, - 0xb5d5fcf1, 0x6878ec1d, 0xa4ebe7ee, 0x7dc0c0b8, 0x673c4ed9, 0xbb64cf2d, - 0x4b6f482c, 0x7f3b4318, 0x696ea747, 0xe95f3c24, 0x3e7c3665, 0xbf3f2d7c, - 0x3871ae55, 0x0e529b71, 0xfdc89d5c, 0x1f380687, 0xbdf1725b, 0x27186dc9, - 0xd9953958, 0xb2350d51, 0xda2b22c6, 0xd8596b45, 0x4168e3f3, 0x770a134f, - 0x4276fe51, 0x0fb7cf17, 0x7693a7ed, 0x73e2217e, 0x2ce79758, 0x7971cf8f, - 0xcf112242, 0x5f3aeda9, 0xb27d73b8, 0xa46ae8ad, 0xf0be81af, 0xc29188e7, - 0xbb32e64f, 0x03f8e227, 0xd87cf1b7, 0x677f294a, 0xf01e98e8, 0x75e0453e, - 0xd79e5aca, 0xff7fcec1, 0x45ed2abd, 0x9433e346, 0x2d53952b, 0x5513f43e, - 0x697a64b6, 0x99c56e5d, 0xe5a2f283, 0x2bd6376d, 0xe86df3f3, 0x9dfd7097, - 0x91fb4729, 0xfcb8c9a9, 0x52a3b3d2, 0x8f1e909e, 0x64d438a7, 0xf1236f41, - 0x72409cb0, 0xc034657e, 0x92ed72bb, 0xf3d7985d, 0xc5191ffe, 0x5da80e9b, - 0x5fb07143, 0xe6167001, 0xa567a962, 0xa648b7e4, 0x718aa671, 0x7982ffbc, - 0xfef3fc23, 0xda75e5aa, 0xf30301cf, 0x9d1d0046, 0x038379de, 0x09e5eeed, - 0x93cfe411, 0xaa83da71, 0x42523ee7, 0x5c1aaefa, 0xd12d4dda, 0x9c83f436, - 0x3a61f9de, 0xb93e4dc6, 0xed05ace7, 0xbbe87fd8, 0x7c2f982c, 0x16bbd17c, - 0x93f1c017, 0x9de52a45, 0x86f42add, 0x897dfb84, 0x271fee1c, 0xdc2117ba, - 0xddfc5b6f, 0x2a3cc0d0, 0xe88130b6, 0xa54fb679, 0x9cb75c90, 0x168d1cdd, - 0xbabd774a, 0x2ea82e39, 0x89b540f5, 0xbf3b85d5, 0x69e824bc, 0x6306d376, - 0xf7e703aa, 0x38fa42ac, 0x7474e7ae, 0xe7c59b7c, 0xa7aff4cd, 0x11b069bc, - 0xb47f83ed, 0xea2b5898, 0x81877d33, 0x8abb49e7, 0x8f0ba015, 0x9d76bfc0, - 0xa68e5e7b, 0xc63e66f1, 0xcc1947e5, 0xebe010b5, 0x724d9969, 0x998fbb41, - 0x25c6389f, 0xae675c01, 0xe3fa1850, 0xc022ffb0, 0xfde1679f, 0xa5fda15f, - 0x379967dd, 0xf9480e58, 0x3cf02955, 0x79f821bd, 0x696fcb65, 0x43cc199c, - 0x27602079, 0x735f9e69, 0xd80af50c, 0x67ed4147, 0x519b66f6, 0x14496f8f, - 0x6ca1edf1, 0xfef0f7d8, 0x18ec88ae, 0x927e184f, 0x36c5c9e5, 0x17cfd622, - 0x7c795047, 0x5172a331, 0xaae3a722, 0x44efb796, 0xc766a97b, 0x738e2316, - 0x9681f1c9, 0x999bd613, 0xe896ef5f, 0x1e21af3d, 0x28252cd9, 0xe1b3504e, - 0x32ec91ac, 0xd1529f01, 0x00f08a5e, 0x1cc2dc3c, 0x503cf1ab, 0xc7f0655a, - 0x5bffe0e9, 0x60c3bf72, 0xd1da80bf, 0xb5173991, 0xb94fb95f, 0x5abcf96f, - 0xf30c7a05, 0x4583e4be, 0xd8cd1f42, 0x2f796938, 0xcefd5100, 0xfc9d1963, - 0x78f649bc, 0x516bc091, 0x8f64fdc4, 0xe3d88517, 0xb7dc3dec, 0xe64ac7a4, - 0xa5a23d24, 0xcc07493b, 0x23f7a06c, 0x4ddebd84, 0x120f2d6f, 0xcc3d245c, - 0xe4685d5c, 0xc8c79be6, 0xb26f4aed, 0xa326d7f0, 0x30e816bf, 0xba063ec8, - 0xed6baa0b, 0x9d0d2ff1, 0xb41f2819, 0xe7ccb876, 0x60e7c2d4, 0x9a5fcf22, - 0xb38d70e1, 0x8073c00d, 0x85f9397b, 0x10ca46f1, 0x3dc6dbe4, 0x6edf2377, - 0x0ff37ce4, 0x92b30f41, 0xf049113c, 0x9af4b3dc, 0xe77fc41a, 0xf2065312, - 0x8a6967b3, 0x3dfd0f1a, 0xc39214ab, 0x18a697a3, 0x97d3ce11, 0x7c871e0d, - 0x345ccb9d, 0x1638b4fe, 0x9c186ed6, 0x7947e5c4, 0x6319819d, 0xf4462908, - 0x506a9f0b, 0x9a8c2fc8, 0x6be02264, 0xf557c096, 0xa4adb78a, 0x6ff01caf, - 0xe01f5e28, 0x2aeab33f, 0xee701f09, 0x52c7cb08, 0x66b154af, 0x3b8c0a63, - 0xd11b6567, 0x82479c31, 0x95b2d7fa, 0x66eaaf84, 0xd5dd7b4d, 0xb9d83f84, - 0xb589cf11, 0xf79f823b, 0x8276124f, 0xbe913993, 0x225a773d, 0xb471af30, - 0x4ad94f80, 0x6b7286c5, 0x84b6b2fa, 0x7d3ea01b, 0xed84eaaf, 0x8587c374, - 0x1f2823fa, 0x1cdecced, 0x719c57f2, 0x9fb09238, 0x52edcac7, 0x8619ef45, - 0x3ce2d3ed, 0xd8cfd0c3, 0x618591f5, 0x73a1df7e, 0x11e4732a, 0xfca20f95, - 0x341b1b2a, 0x2fbec029, 0x3112d833, 0xf365e91e, 0xb83dc593, 0xd4f84088, - 0x7e24ac46, 0x887e45a8, 0x34c3f3f0, 0xdda17b8c, 0x7942a2f3, 0x30476c84, - 0x34709fbd, 0x9091c226, 0x9033efb9, 0x8a6f2e9c, 0xf971f3a5, 0xea2322b2, - 0xb16df2d5, 0xf9c11f64, 0x86cbbdf4, 0x6879f1fa, 0x649ede59, 0x39bcb718, - 0xe306a9d3, 0x19dcf431, 0x0d39ceb0, 0x8efe2487, 0x23bf80f4, 0x7807f0e1, - 0x4f2f6a0b, 0xe0497212, 0x238a2d8d, 0xef3a5abd, 0x58089cd5, 0x48ba99d7, - 0xe9ec93ca, 0x8c66c47c, 0xe903fca0, 0xabdf1abf, 0x7944cfdb, 0x0e57673e, - 0xf169fc21, 0xd3dffe36, 0xcbbda187, 0x68616efe, 0x66cb4d67, 0xf6864db7, - 0x6fce14db, 0x19afead3, 0xddc4768f, 0xbd9e5c49, 0xd5d07205, 0x41b7b197, - 0x0e40ba0e, 0x11f20bbe, 0x4e2fefeb, 0x8b87faa6, 0xb47e541d, 0x47951fb8, - 0xf25fbf84, 0xd102101d, 0x2e2492ed, 0xc9249717, 0x6482faf8, 0xffc66934, - 0x3a21ddfb, 0x6c67de1b, 0x9d36309b, 0xc15cebb1, 0xa9c6f7fa, 0xd3b5fac1, - 0x8c971b60, 0x0a15dbe7, 0xeee5a3d9, 0xe1fd4191, 0x7bc464dc, 0x9e5fac2b, - 0x86f49dbf, 0xe81938c3, 0xb8e2a6f1, 0x37d7fea0, 0x9fd506a4, 0xfad07248, - 0x0ecf8d26, 0xb4b9bf6a, 0xecbd507f, 0xa431919c, 0xf1014777, 0x679102cf, - 0x8e770704, 0xfbef1b17, 0xa4b0dd75, 0x5fbd60bb, 0x73d033ef, 0x5e243e2d, - 0x9951ac67, 0xbe9bc607, 0x2c1fe406, 0x74e348f1, 0x0e2fafe2, 0xb25ce858, - 0x7f6f29bc, 0x350fd401, 0xe80f2819, 0x55b8b2d0, 0x6a1daf68, 0x2832b04a, - 0x6155cb3d, 0x2c8cd8d7, 0x2d15de40, 0xa6f9425b, 0x93933e65, 0xef7697ec, - 0xc0eeb293, 0x122e2af3, 0xd53de4f9, 0xfe10aad7, 0x67df045c, 0xe15ee922, - 0xf127b071, 0x4ef4e12a, 0x0ae3aebe, 0x13f5865b, 0xb9f71f91, 0x6a71d60b, - 0x0e856362, 0xbeea15fd, 0xcf9f9204, 0xb6e90cab, 0xf2819e74, 0xafbf660c, - 0x533ac06e, 0xbe395372, 0x66a3ca55, 0x7c6898cf, 0x021405d6, 0x6d3c16fd, - 0xae01ea7a, 0xfb7d78ff, 0x8203df40, 0x8e8e913e, 0x2c5732c7, 0xf5a1562d, - 0xc276fe7e, 0x87ee7c06, 0xee106fa7, 0xfdc1bd7b, 0xefe01266, 0x20df0af3, - 0x128b6f92, 0x70b4af88, 0xf2e4623f, 0xa07c8bcb, 0x9fa6e5f8, 0x7e9296cf, - 0x26706e98, 0xe56e493a, 0x3adca0a7, 0x7640d2b2, 0xacbbd330, 0x3e8f4893, - 0xe72c744f, 0x8c77a239, 0x691df5c3, 0x5f9864c8, 0xa552be51, 0x1fd20af3, - 0xe7e3efef, 0x0f5587d4, 0xdbcc24d8, 0x525878a0, 0x3edcdd28, 0x5de5186f, - 0x596ded6a, 0xeabc097e, 0xe64bb009, 0x8179e4ec, 0x3f53bf2c, 0x3ee06075, - 0x3cf9f196, 0x4af94105, 0x1daf5955, 0x2ec8eb34, 0xc273c18c, 0xa254f789, - 0x8d5913b3, 0x9f019343, 0x86bb7527, 0x2ff505de, 0xea8f7a26, 0xda223ea1, - 0xeb842ff3, 0x0ccadd5c, 0xfaf30b25, 0x091aaf0f, 0xacfe7def, 0x2e6c49c1, - 0xcf39fcec, 0x43fdeecc, 0x1bd815f6, 0xe1ddb8bd, 0xcffbc14a, 0x1acd1d73, - 0xc7c3807b, 0x00204981, 0x056adb17, 0x7876376d, 0x3c01e588, 0x31d74f57, - 0xe079e04f, 0xb1e3c8b0, 0xa873f324, 0x24a61bb4, 0x5d333973, 0xbd9be9c7, - 0x037a70ac, 0x0f502afb, 0x173db948, 0xbf55aaf3, 0xbb72901e, 0xfe52358a, - 0xdb99238a, 0x1f15b32f, 0x9835ddd9, 0x2bfd0289, 0x56683c6c, 0xf3e4d9b5, - 0xb698d265, 0x7a60fb40, 0x73279732, 0x8e3ecf8c, 0x3ac95be4, 0xfd353ef8, - 0x2af8373e, 0xf543323a, 0xc36d854f, 0x6f8d3b32, 0xb79fa270, 0x756bf052, - 0x256be2a3, 0x51eb853b, 0x299d57e9, 0x3f56a8f4, 0x8d25e885, 0xd1a99a3e, - 0x5831acbb, 0xe97ac2cf, 0xaf5cb2de, 0x68ee9d76, 0x0e61c10b, 0x6ff50bac, - 0xa7b7c785, 0x38add684, 0xeb21a301, 0x31ee64a9, 0x780fb8b1, 0x5d08eade, - 0x215f769f, 0xd4fb15eb, 0xf9c2bbae, 0xbbe62b55, 0x04293554, 0x243eed2f, - 0x9c76b43e, 0x97854bc4, 0x45a2b7c3, 0xd67e7c21, 0xf2321f6d, 0x61ba4b6f, - 0xe02ff0cd, 0xb047497d, 0x6f9412af, 0x1e41ab95, 0xd3d28667, 0x456cd61c, - 0xad61a9ba, 0xdf9053cb, 0x1faf9b5a, 0xb5867e8e, 0xa9f9d36f, 0xa39aded4, - 0x7a50058b, 0xbf8e5773, 0x17e74fca, 0x5cfc278a, 0xe9ddc3f0, 0xe01e9fa5, - 0xeaa37335, 0xd4141c8a, 0x7a3fe44f, 0xbcb38e09, 0x63fa235e, 0xe53f0967, - 0xab59d685, 0x2e5ff7e7, 0xcf015eb8, 0x0fdd7b9f, 0x7764f727, 0x76173f85, - 0x3d1a5bdb, 0xfb81b1ff, 0xfe7ca55b, 0xff22ef5a, 0x3b0bb42e, 0xe3c6ceac, - 0x9eb91a7d, 0xbd724f9e, 0x3979e842, 0x5b35d1cf, 0x13305e29, 0xf68080ed, - 0xa56f56cf, 0xd9f1a578, 0xcbb45699, 0xbe99ae8f, 0x8f52f30a, 0xbd274d36, - 0xa97bf95f, 0x40c63df7, 0x4d68a27b, 0x907bfad9, 0x5247378e, 0xdda2b15c, - 0x2045ce23, 0x639fa167, 0x6cab970d, 0x95b39735, 0x90071fa8, 0xfd8bec7e, - 0xf4f0acee, 0x68087e45, 0xe779bd27, 0x779fcf74, 0xfe77b8c2, 0x25e9da29, - 0x755ad850, 0x5adbcf64, 0xcf563f51, 0xde20f0ff, 0xe07b01d3, 0x7b4b5ffd, - 0x0645aa00, 0xea325b4f, 0x54076121, 0x6c321bab, 0xbd083768, 0x7f801ff1, - 0xe7f87844, 0x11cbfc12, 0xdbf101fe, 0x9c381b4f, 0x7fe06ba7, 0xcbc72578, - 0x2b6ca6f2, 0x6d3f2f9e, 0xebbb26c8, 0x821ca6d3, 0x00078cff, 0x1f5fdcfe, - 0x0035776c, 0x817cf1fc, 0x96f587f0, 0xfc043bb7, 0x0dfe1c9d, 0x256cee1c, - 0xc084672f, 0x57f94bd9, 0xe4d1fe77, 0x78e23b44, 0x57d92b64, 0xaca8b7c7, - 0x932ec03e, 0xac37d176, 0xdfb449f1, 0xf767fc24, 0xf28418e9, 0xd7e1f4a7, - 0xd98788ac, 0x3150785b, 0x95ccfe04, 0xeec7f144, 0xa8edbbf9, 0xdd5f116f, - 0xe245d476, 0x19b986a9, 0xd796c7e9, 0x4239e00e, 0x45bf7171, 0xb66fbc8d, - 0x19bef823, 0xda9592e6, 0x8ce2c5d1, 0xa4f5c088, 0x79d3ef69, 0xbebdc618, - 0xd6eaf9cd, 0x5de7c4f9, 0x25b97941, 0xfe80d5ac, 0xd0acd636, 0x05eaed3d, - 0x8642d685, 0x5a3ab571, 0x09453387, 0x56aecbca, 0x564f6475, 0x447c4519, - 0x892455e4, 0xdc29497e, 0x629c902f, 0x2474f2a3, 0xda707d23, 0x7de1f462, - 0x255f382a, 0x9ddefce3, 0x41dbc226, 0x5fc0135c, 0x333f0a35, 0xb7a442a8, - 0xd3a7185b, 0x297bcc5b, 0x972707ae, 0xa71fa875, 0xc939342d, 0xa18f8dce, - 0x42cdd2f8, 0x5e62ddde, 0x313d46ee, 0x61746ccd, 0x317ae309, 0x1a30d7f9, - 0x0df987a6, 0xef748cbd, 0xf3a234b0, 0xdf123c59, 0x8ef87c96, 0x95ea5808, - 0x1fa38e60, 0xf6dd7e18, 0x5e285c7d, 0xf609f8fc, 0x8546d74b, 0x170c8bf7, - 0x2e5c5070, 0x609b3ff2, 0xc75828ec, 0x6f0714a8, 0x3fb8d877, 0xc9e02d7a, - 0xb6afc7e2, 0xfc79799d, 0xb1f30ab2, 0xbc58f7f9, 0x5d541f24, 0xc8cabd50, - 0x62794f9f, 0x34eaf143, 0x8e61dec6, 0x2ab78881, 0xee782194, 0x61f18b2f, - 0xf43aef7c, 0xd4b1db87, 0xd64cbd13, 0x978eaf33, 0x0e3b660d, 0x25e3fdc7, - 0x2abf9e02, 0x0031ad60, 0x83d7d6f7, 0xb437f3fd, 0x02fb5aea, 0xb7d3af7c, - 0xea7d21b6, 0x1b061c22, 0xaf1ee3cc, 0xa539e2e4, 0xadc5e96a, 0xa689e2b7, - 0xa0a3d5e2, 0xacf9e3ae, 0xfee6bf5d, 0x59805b89, 0xeab76e11, 0xcb9abb59, - 0x52e100e9, 0xa978776b, 0xe2853cdf, 0x202e3237, 0x86183ff1, 0x2de3c40f, - 0x4e307d62, 0x37df1583, 0x7cd7c786, 0x8ccc2f81, 0x15cfb846, 0xf257377c, - 0xbf30535b, 0x0478823d, 0x2ed0553e, 0x22ddb806, 0xe2f89eca, 0x476e14a1, - 0xcfc2943f, 0xe25cf7ef, 0x95dccc7c, 0x82797941, 0x7c4daa5f, 0x75ff397c, - 0xc5307ca2, 0xf5cbe34e, 0x8a7ebd00, 0x0240e8e3, 0x691ebd20, 0x68fb27ac, - 0xc3880b16, 0x49fbfa65, 0x77ad0eba, 0xf7dd11cb, 0x66bb1a58, 0x5f95e820, - 0x8e513a44, 0xce6c62de, 0xf68733a9, 0x52e67193, 0xefa061d6, 0x993f4903, - 0x55633fd0, 0x9535e533, 0xf41efc2a, 0x578b42e9, 0xc7e27607, 0x067bbe22, - 0xa79c46ec, 0xfca15634, 0x773169af, 0x975f2096, 0x2c7a8d5a, 0xdff1163f, - 0x8d17595b, 0x2b2d89ff, 0xdf8606e6, 0xe631504d, 0xa4f80b07, 0xadfb05d8, - 0xebc3f947, 0xe4695d2b, 0x4ff5128d, 0x665c61f7, 0x03a079ea, 0x762e1faa, - 0x5fa7bcc1, 0x91d9cf15, 0xfa7e7c62, 0xdecf413e, 0xe9de34e3, 0x53f3e4c7, - 0xf90af9fc, 0x7f5e2bfc, 0xea2f8e50, 0x2f9e6b0f, 0x827f3cd1, 0xf89f5bd7, - 0xf68bd8aa, 0xda4e68eb, 0x921423a5, 0x37214657, 0x12b6974a, 0xbb754b9c, - 0xb59a3978, 0xdc2ff2ea, 0xdb8a64ef, 0xf7809298, 0x50588fce, 0xd533ff0f, - 0x7e814c65, 0xfe79269f, 0x499ce586, 0x7288d78a, 0xe91f3df7, 0xf21e9285, - 0xae428d27, 0xa6e5ea9f, 0x831ea5f7, 0xf1c3de71, 0xbb9c752f, 0xe4f9c743, - 0x4d738cc7, 0x4738c86a, 0xfebecc7f, 0x24e1ca9c, 0x517691c7, 0xe94bba71, - 0x663afc85, 0x70bf9064, 0x18cebdee, 0xcc314bf4, 0xcfd00377, 0x919cda5d, - 0x7dcfe307, 0x0a8cc5ee, 0xbe849bb4, 0x32a739af, 0xdaa3c817, 0x5f950a73, - 0xc4647db4, 0xdb35b37b, 0xa0e38cda, 0x45942d5f, 0x12aaeb01, 0xa77d04eb, - 0xa7a01c9f, 0x4274bd8d, 0xf3cc3c6e, 0xa13b9e32, 0xd5ce7c47, 0x3dfd1f35, - 0x4a11efea, 0x97f2f8d8, 0x7b077f62, 0xee611fb8, 0x6151e5c5, 0xee34576f, - 0x390614f3, 0xfaa2fc60, 0xbf02f9f0, 0x1528eb12, 0x50fa6ffa, 0xe003844b, - 0x1e3de43c, 0x9b58af5f, 0x62fe8b99, 0x04e8f263, 0x7e8f5b82, 0x67ee2ed6, - 0xd67ee16d, 0x02c77b52, 0xbb994efc, 0xf883ec57, 0xbf09b2dd, 0x2c067c93, - 0x378eef0b, 0x89bf7ac9, 0x3f714663, 0x7ef3d618, 0xf220f99f, 0x6e28decd, - 0x361b4ecf, 0x43e50a30, 0xceb46667, 0x4facfc06, 0x4af7732a, 0xc6abf6c0, - 0xc9a17b61, 0xe08ca7d2, 0xf42e88cb, 0xb8feee49, 0xfe8fec4e, 0x35b18f11, - 0x87d806e1, 0xee950de7, 0x45067803, 0xcbc5c27b, 0xe5c5ef2f, 0x8d97bbb9, - 0x0757b1e0, 0xaff5cceb, 0x760fce43, 0x180e82fd, 0x94d2c8ef, 0x30380fc1, - 0x5d78531e, 0xfcff04af, 0xa33c92b3, 0xa23fe702, 0x68f07d63, 0x18ebb171, - 0x1d71f02e, 0xf74a06c2, 0x80b7a028, 0x31e4def3, 0xa9f541d1, 0x15cc71c5, - 0x9a9dbfe8, 0xb1bf541a, 0xffa83b34, 0x07fa33cd, 0xea689f3d, 0xb00bafc8, - 0x97b67b67, 0x5a9f04bc, 0xed0a258b, 0xbe5a4fba, 0xb416e0f9, 0x4eaa3703, - 0xef6759b4, 0x48c1f4dc, 0xf00675e8, 0x497e471b, 0x3ed1f907, 0x7a747997, - 0x7e303e97, 0x50758a74, 0xd73ca2be, 0x68dc6c5e, 0xf29dadae, 0x78ae7f09, - 0xe25ebcd1, 0x72cb9bfc, 0xa99e3f51, 0x79fc9f7b, 0xcfbe6635, 0xe21e2f53, - 0xbd442ddf, 0x357f7402, 0xe2f688be, 0xc0fc1039, 0x0e3b45ff, 0x86cd9c51, - 0xf7b44dc1, 0xf1e9e6d3, 0x942d64fe, 0x81c65fa8, 0xba018adc, 0x036368e9, - 0x48de61b7, 0xe5db85a6, 0xbf90a6e7, 0xf7146f7c, 0x8c4decfb, 0xcc48efa5, - 0xda86b86d, 0xd345ce6b, 0x1da96ff8, 0xfa2f28e3, 0x13e28505, 0x2da75313, - 0x8decfdc5, 0x1db80ef2, 0xe7f89de6, 0xdc23c7ab, 0x7bf1b66a, 0x77d51302, - 0x5941e7f2, 0xbd0d78d5, 0x7b65513f, 0x621fb015, 0xe342ddce, 0x001b444e, - 0xcb50eaea, 0x5597a803, 0x3f9f6b63, 0x5a31bca0, 0x9ed4de48, 0x26f7a48b, - 0xfdfd7114, 0x0c4f217b, 0x635d7c9d, 0xe7a24dcf, 0xbd7c2e92, 0xf7f282b2, - 0xf51b090d, 0x4321bdf8, 0xaffd42a7, 0x4a9fd73d, 0xfa37dfb9, 0x2fbe91fd, - 0x7af84860, 0xbe8de61c, 0xc8d8af11, 0xe3c8d12c, 0x62c375b3, 0xd5791858, - 0x9e39cf3d, 0xc73a6c6f, 0x3bff8ff3, 0xe417f5cd, 0x9d4592c3, 0x31178c7a, - 0xe10d8473, 0xd8305255, 0x67c01151, 0x8c9baeea, 0xeac31f88, 0xafa88db7, - 0x0516504d, 0xf916af3c, 0xdd795a58, 0xfc83e422, 0x3fd49b8e, 0xd106792c, - 0x4136ade7, 0x9e8f82a0, 0xdf2c7c16, 0x0e33a0ef, 0xf73b71e0, 0x79a6b7f3, - 0xd13942de, 0x7c6ec851, 0x4767e49e, 0x7e69c606, 0x9e03f5ae, 0x1bb21423, - 0xbeaf293b, 0xc3a1c0a4, 0xdd7bc0f8, 0xf3f3877a, 0x26d1f685, 0xca96fdf6, - 0x6fb8e216, 0x1d97f2fd, 0xedaf182e, 0xd43cbcee, 0xcfde720b, 0x0b7bf17a, - 0x1e75d6cc, 0x2fb587cf, 0xef903b47, 0x0ce1e227, 0x4d3ba2e3, 0x76816e74, - 0xbed4778a, 0xef0a7a6c, 0xe15ad5bb, 0x17f30afc, 0x8ad912bd, 0x4af6dc74, - 0xc7f51ea4, 0x9f3dbd1d, 0x5e8a7c21, 0xcf063be9, 0x9316ae8b, 0xe3fd919e, - 0xb6f24a3a, 0x485ef587, 0x4ce9697e, 0x81a7a7f2, 0xa0994bf3, 0x7fc172d3, - 0x6747c11e, 0x0f8892eb, 0x45822ecf, 0x91753c63, 0xda1b7032, 0x7d0b0e0b, - 0xe5f24e97, 0x411f3c44, 0xb1fec4fb, 0xeaa18f74, 0x1f106c5c, 0x14cb9f56, - 0xed471dfc, 0x05cadf92, 0x7d84989f, 0xb5d04331, 0x3f245bb4, 0x624f74b2, - 0x6263ec2a, 0x95bdf03d, 0xc8f9fee2, 0x31ba7e4f, 0x80be90da, 0x022b926e, - 0xedbea7f8, 0x8a768626, 0x744dde29, 0x40ca0333, 0xb766653b, 0x971b629d, - 0x592feb08, 0x7bc3a996, 0x6a79f29b, 0x7fd1a5ea, 0x27c8aa44, 0xa0e6b730, - 0x8ba86b5d, 0x9a7de274, 0x1e3cf133, 0x87057f34, 0xbb837ce3, 0xf98ced08, - 0x3fe4284f, 0xe503fb43, 0x7503d0d2, 0xcabf40c6, 0x5106e74d, 0xb9ca7d3c, - 0x2634a8cb, 0x38472e7b, 0x5ebb9d94, 0x8fd06be0, 0x710e3f8a, 0xc192bf71, - 0xc86e7267, 0x4792bf44, 0x4f1f3c45, 0x0347b667, 0x546b7de3, 0xb8c98ff2, - 0x9933f4a4, 0x804fdef0, 0xdf46fd3e, 0xa3df4198, 0x0a9dfad1, 0xb93ffeb9, - 0xbffa40d1, 0xa19dedaa, 0x79fe783a, 0xf5092ba6, 0xa7837ac9, 0x6733f708, - 0x0339efb2, 0xb83ee7d4, 0xe1dc3ad5, 0xbeb36787, 0x69f50735, 0xfd11c033, - 0xd52bcd5f, 0xf76e3ef1, 0x1a38f344, 0xcf496fa7, 0x739f3a5a, 0x73e09b2e, - 0x7a44ceb6, 0x2dd02ce8, 0x5243d00b, 0x2f3948ef, 0xeba48ff5, 0x5f973d6a, - 0xca18e6d5, 0x9debf323, 0xa442ee49, 0x1f3c7ebb, 0x9e77afd0, 0xf902355a, - 0xe53c74e0, 0x21bd4b5d, 0xc585e0f9, 0x244794c9, 0x03e492f5, 0x7ca5cf29, - 0xf52f7497, 0xfd3fe8d6, 0xc3bfd6ef, 0x3cd293af, 0x7d02a577, 0xfae7ab5d, - 0x85bd5aeb, 0xfc6c67e8, 0xcdd23d24, 0x43d1cbc5, 0x0a1e8e42, 0x3d35a392, - 0xa94581e8, 0x1c5e7e52, 0x7c11cc1f, 0xedc4de33, 0x81f39448, 0x8da6b5e3, - 0xb1f7087e, 0xd9eb953a, 0x3ddd6b9f, 0xa9d5ffc9, 0x97ff2697, 0xfc9c5ea4, - 0xfe54efff, 0xbcad0a9d, 0xa3710fc7, 0xf3bd3fbc, 0x83ea1f72, 0x03f40c83, - 0x6896c1ea, 0x0fa126c7, 0xc5445f48, 0x1f487ef8, 0xfe9ef614, 0xf5e1a9df, - 0xff6c66c1, 0xd240fab1, 0xc91be497, 0xb42f9227, 0x62f9247c, 0xbce16fc2, - 0x8b7a7888, 0xd6aa8fdf, 0x0e289b7b, 0x8c1e88e9, 0xc76dd9fc, 0xdf88536d, - 0xe084f442, 0x04bf3f1f, 0x1fc90deb, 0xff245f92, 0x98fe0b54, 0xf243f829, - 0xf9b56ec5, 0x0a9811d1, 0x08f9e690, 0x93e488e5, 0xfab5e7aa, 0x42ba47a1, - 0x199b234f, 0xae90c75f, 0xa40ca1aa, 0xfc0f532b, 0xf512f070, 0xa48bbec2, - 0xf3feafa7, 0x0f55f4f4, 0xa7e674f4, 0x1da853d0, 0x03be61fb, 0x1f3673d6, - 0x9fa66de4, 0x8dfc26de, 0x9b21fb71, 0x46f6079f, 0x35ee7df1, 0x67ff93a6, - 0xcf3cf7c2, 0x3303da57, 0xd241bf85, 0x01d81e69, 0xf8fc4369, 0xbcc0f3c7, - 0x847b938b, 0x877c5367, 0x3327cf11, 0x03b40ca1, 0x537fb27a, 0xee4d2ed3, - 0x17fe8a45, 0xb480f3c2, 0x1c6edd9f, 0xaf1e1690, 0x027ed303, 0xa262275e, - 0xb22bf92a, 0x00a35c4b, 0xba890f3f, 0xc2094fb7, 0xf902faf1, 0x2e55b2fc, - 0xd607ca3d, 0xf475ddfd, 0xcaa5bc77, 0x31fece7a, 0x8f099eb0, 0x1d1fbf32, - 0x151d8f9e, 0x511fedd3, 0x717fbf98, 0x95fed65a, 0x451be7a4, 0x9ea74ade, - 0x3d4483c7, 0x8096ea1f, 0xbea6817a, 0xeab7f796, 0x3e60593b, 0x928dd209, - 0x0eecf1cb, 0xfa601fb0, 0x2fa8b3f6, 0xff430a6c, 0x86fc6d46, 0x5ca2cf57, - 0x6c50a1db, 0xde0e1baa, 0xfa070481, 0x07d5383e, 0xc65d77ef, 0x78dbcdd8, - 0x43b5f6fd, 0x132f7956, 0x1bdc06e3, 0x2e2b3432, 0x502847ca, 0xa199597c, - 0x4d3dbef0, 0x1eb913ca, 0x0214f746, 0xaf9867de, 0x77ef2977, 0xd1674de7, - 0x4ba6adfb, 0x5186ff98, 0xac6fefe1, 0xe4c6fd10, 0xfe7d84c7, 0xe1ca9a70, - 0x3406fc2f, 0x694d343f, 0xff9f7f0e, 0x1d2fc109, 0x78213f18, 0xfe855a4e, - 0x84a30eed, 0xc2157bb7, 0x41632c7b, 0x9f98347e, 0xbad71bea, 0x7cf41a4b, - 0xbc0d2ebb, 0x77bf687e, 0x03db05a5, 0x5f069bf4, 0xf7801fa6, 0x77de61dd, - 0xfadfbf04, 0x125af843, 0xdba0bef2, 0x5d8e9259, 0xa31ef441, 0xc67d1377, - 0xb4362bc4, 0x91dc6ba3, 0xe0bcf12b, 0x12d2cfe7, 0x138c9b82, 0xb4dff084, - 0xc8033192, 0x6fcf124e, 0xebfc855b, 0xe7f775d6, 0x1ae928fc, 0x5c0136af, - 0xef07f5c9, 0xeb769cbf, 0x024ff42a, 0xaa73d05d, 0xadd603eb, 0x4d66c7e5, - 0x7f86947d, 0xfc91ff05, 0x70007d40, 0x16f941ca, 0x08e8c87f, 0x044f93a0, - 0x7c894e9c, 0xdcd18ef2, 0xe2c8ec9e, 0x3c6977e5, 0xa099f52e, 0x9e9253cb, - 0x90e002a2, 0xf43f4416, 0xf60221f7, 0x29ba704d, 0xbdf3f25e, 0xbfc0c525, - 0xfcfe761d, 0x66fed67f, 0x5fcd3795, 0xcff78ed7, 0x2096f7b5, 0xf7c7ba5c, - 0x768fda2e, 0x6e024dc4, 0x67bdaddf, 0xc08077bf, 0xbbffa273, 0xf41f40ab, - 0xa46a9e3d, 0x3e94250f, 0x2fa50d5e, 0xfa7de6af, 0xbd3d043b, 0x7950b7ff, - 0xcfbcd2e0, 0x17107bf0, 0x5bc0beff, 0xe3af06b1, 0xa31d7835, 0xbaca97a9, - 0x4afe482f, 0xe3be5cb9, 0xe312fbe1, 0xd0a9afd1, 0x3d3f2475, 0x3cf4483f, - 0x77e926d7, 0x4fd5c115, 0x47ed0fcf, 0x2cdc9dfa, 0xf491b5e9, 0xc39424cf, - 0x29f5fc23, 0xfea88728, 0xc5c60970, 0x91eafafc, 0x6fb72855, 0x1ffd9068, - 0x2f37fea5, 0xa6ade393, 0x8c8f12e7, 0xeefa463d, 0xafa97ca6, 0x3fb9271e, - 0xefbf85a7, 0xfeddff4c, 0x4687e41f, 0x6ad65c0d, 0xff4d5eea, 0x6fd017d5, - 0x2fef34cb, 0xa95f3cd2, 0xd4d1afa9, 0x2fdf821b, 0x1f10a19b, 0x38f01596, - 0xb52f96a5, 0xef4ae1f4, 0xf5ba73b6, 0xfb2662b9, 0x26af882e, 0xb5faf3d4, - 0x1a4b1be9, 0x75f501cc, 0x5f384a9b, 0xf7016cc0, 0x7ae6419f, 0x4307a055, - 0x20b3720f, 0xd9b907bd, 0xf9efab4f, 0xafe07ff3, 0x0a371429, 0xab764bb2, - 0x5536f5c1, 0x75bbdbac, 0x810182ff, 0x4be7d5f1, 0x63dd5cf0, 0x5cdbc71c, - 0x2ed02632, 0xae25cd62, 0xfeca7d80, 0x5efbbee3, 0xeb3cf9c5, 0xd1b25cfe, - 0x114f718c, 0x12f3b4df, 0xfa8aa5f4, 0x6ff856ba, 0x2f1e61c6, 0x5aa293c6, - 0x080fe673, 0xee6b27d8, 0xbb6cfb83, 0xb7dfe55b, 0x00fc07ab, 0x8398ca9c, - 0x33a750f2, 0xb6a5e517, 0xfc2cc4c5, 0xf76f782f, 0xd442eadd, 0xc61707d3, - 0x2bd35e51, 0xb17cfce9, 0xe277a63b, 0x45b7a84c, 0xb6f246df, 0x54b1feed, - 0xcb5d52ee, 0x2d8c6cbb, 0x894af75e, 0x1e7c72f9, 0x3bba7043, 0x2592a5fd, - 0xa6f7ef40, 0x8f7de83b, 0x03b896dd, 0x0c07eded, 0x0e043714, 0xe7e89278, - 0x3c60d341, 0xe92d976f, 0xf2b1714f, 0xc38d26c7, 0xf7e5a47b, 0xd25e2819, - 0x9f91b3a9, 0x58c0f3c8, 0xb19a93ca, 0xabde944c, 0xdfe57ca9, 0x7bc7ac7f, - 0x14eb5da6, 0x55cd4efa, 0x6dff375f, 0x1b2bd410, 0xc67ee9b2, 0x9474e7cb, - 0x9ae9fe17, 0x53cc3ebe, 0x47591c3e, 0x9fd0a5f9, 0x9e56bbee, 0xc92fec77, - 0x0daafec7, 0x428e3853, 0x47cfda3b, 0xe14fa857, 0xab32ce3d, 0xbbf30a25, - 0xc8c77e8f, 0x3ef473af, 0xe6ef7d13, 0xd6e7b353, 0x8f74f135, 0x767d2d09, - 0x15587154, 0xf4dac380, 0x29c925fd, 0xf8126ed8, 0x032d6fdc, 0x75d32f3e, - 0x93e90fd3, 0x5f5e588a, 0x92cdeebb, 0xa38fb04d, 0x7ca5f44f, 0xd70c84b1, - 0xd78074ba, 0x93d70ce1, 0xd9fb8a54, 0xc79bfcaf, 0x593a5f25, 0xb5f4889e, - 0xcbf5d059, 0x0313cae7, 0xc5416eff, 0xc1d13d29, 0x02c7462b, 0x5469eefa, - 0x6ce782ba, 0xf43883a0, 0xe710cf9b, 0x85e7a016, 0x57d8c35b, 0x3db9d34b, - 0x84dbf6d6, 0xba208e51, 0x29e498fe, 0xfea0379d, 0xa447fa62, 0x16988ee7, - 0x77752e62, 0x1ddb243e, 0x34327049, 0x3322fa45, 0x1aea7fd1, 0x4ff3a2e7, - 0x96c99f73, 0xfd143e00, 0xfcf2f13f, 0x3fa04fdf, 0xf13efb9e, 0x604b3ffe, - 0xaff6433c, 0x68bc5ab4, 0x58b31c5c, 0x838f88f4, 0x3147c5fa, 0x9d62ad3f, - 0xc540f481, 0x5d4584ba, 0x6e807f28, 0xdda6bfd0, 0xc0c32997, 0xc63d18fd, - 0x192f3f57, 0x5e781693, 0xbbf24139, 0x377cbe27, 0xc6c944fd, 0x65f33d01, - 0xa7cb8da5, 0xf7f8eb71, 0x58872b75, 0x7bbf74f4, 0xe89babdd, 0xc8bcf01e, - 0x5157bc5c, 0xf844ceb9, 0xbc58b4ea, 0xbef12bb6, 0x0b1f4581, 0xae74a1e5, - 0x0e19f54f, 0xca9147c2, 0x54b911f4, 0x190a3dd2, 0xf0b13c3f, 0x1d31c7d1, - 0xbbe673f3, 0xefc0187e, 0xe9d38b8c, 0xf92a6d99, 0xc4f1b51f, 0x1ab7d7ea, - 0x888fd90b, 0x4710f627, 0xe29d62ac, 0xe3e1e2bb, 0xe238da89, 0xbdc5d2bf, - 0xa238eeb3, 0x5187be81, 0x4588e229, 0x7f5a156b, 0xbdfe42e5, 0xee38a292, - 0x18b23e3f, 0xed2fa0e8, 0xc5cb6bdf, 0x7fae693c, 0x8be2992a, 0x5eaf5f80, - 0x99fc8f3b, 0x5e1ce975, 0xb03be265, 0x199d2387, 0x58afde78, 0xae704917, - 0x07f6727c, 0x7de3e44f, 0x81f189c0, 0xa09b6be7, 0xe19f180f, 0xce39683d, - 0xd0f725b1, 0xd68b6777, 0xf31939c3, 0x73d963b4, 0xde226537, 0xde303252, - 0x2e55fb29, 0xef0fbbbd, 0xd86ce707, 0x950ad977, 0xbb6b0f7f, 0xf021f489, - 0xb80b327c, 0xd9633e2f, 0xd72346eb, 0xa8792c67, 0xfe1db3b0, 0xc29f6cfb, - 0x4104fc73, 0x26b7b8ad, 0x5bef27e1, 0xf7f8e995, 0x0a754b36, 0x8902c3dd, - 0x7e97f746, 0xa3fdc191, 0xcedc1979, 0xd270cb2d, 0x55ea9e3d, 0x4cd2e726, - 0xbdf74e3e, 0x55e73875, 0x282a3aeb, 0x1317f9ae, 0x976a57f9, 0xad22ba45, - 0xf9e31f3c, 0xad779401, 0xaa3c0237, 0xfc6e5c1c, 0xad63d042, 0x94d5d263, - 0x0767ae9f, 0x5607eff0, 0xac9cb85b, 0x9bb8058e, 0x86e90139, 0x1939f7e2, - 0xb8e253e5, 0xe6028329, 0x8c3b4457, 0xc7fab0e3, 0x0d63abdd, 0xfec1a7e8, - 0x38420f97, 0x237f5dc6, 0x9559efae, 0xb4801af8, 0xbfed00aa, 0x3c3cd567, - 0xd8ad9777, 0xf0e50e3d, 0xf1832ddc, 0x7b2b0546, 0x23d25dee, 0x3bfe0573, - 0x395a3e45, 0x81bbf1d4, 0xb9706437, 0xdfb951e9, 0x2f0106e8, 0x79f20749, - 0xf7030af5, 0x47bc83e3, 0xe4bd5301, 0xdab71a43, 0x728891d2, 0x81bb7ab8, - 0x8cdf87ee, 0x973806eb, 0x751f492f, 0xdcaae800, 0x51df4310, 0x344ef2ad, - 0x51aabd62, 0xbdffbaa1, 0xd3a40c84, 0x60bd962f, 0x1c39fa45, 0xfa839ad9, - 0xa45e6ba9, 0xda29ee93, 0x8beedfb8, 0xaf743965, 0xc3ad8669, 0x9965df82, - 0x8edb20b1, 0xada0fc72, 0x0fcf88d5, 0xb0ea6736, 0x46d9b2ee, 0xbfa5dd61, - 0x885fea92, 0x41fa177c, 0x9e3852ba, 0x1b769aab, 0xdd2feff1, 0xd4e2e82b, - 0x41f6efb3, 0x4675503f, 0x2fd41f47, 0x527d0740, 0x28cfce11, 0x9a6b9fa4, - 0xa4bc1e78, 0x03a41a83, 0x8239bbe0, 0xbdb66a0e, 0x43f21770, 0x373fe20d, - 0x9e808e94, 0xf9fda9db, 0x7f18e30d, 0x44e91dbf, 0x2fa833ea, 0xce3fa033, - 0x058bebc8, 0x0c7da1fe, 0xe00ef76f, 0xf9dd75f9, 0xd07c4108, 0x66d77e13, - 0x4c3e04e8, 0x8ad77724, 0xd8ae76fd, 0x9dfc456e, 0x1ef7767a, 0x3f54b78c, - 0x11dada0f, 0x3c041f86, 0x56ff716a, 0x19d93f5a, 0xab5fb8b5, 0x74ddff7f, - 0x96b0f82f, 0xfdc9fdf1, 0xfec5ead6, 0xfef173e5, 0x2acfb13a, 0xadb5e026, - 0xc13be72f, 0xf4c7c867, 0x3fb121dd, 0xbbf83d8f, 0xfec5bbba, 0x6cc9449a, - 0x0f8456cd, 0x0fe517e2, 0x28cb8fd0, 0x397409e5, 0xe50365b5, 0xc97c4bf7, - 0xd7efbff5, 0x93fc2e2b, 0x9d8f1254, 0xb6f77c3d, 0xa1c9f045, 0x763292fb, - 0xd8befc00, 0x240d9f4c, 0xcc07d57a, 0xce46e927, 0x49a7f457, 0x61bee2d7, - 0x5f1c56fc, 0x1bd07bce, 0x0e71c7ad, 0x721fce32, 0x8b2f92fd, 0x3b5da7ea, - 0x4efd8ad8, 0x5ed1b259, 0x3f7c7811, 0xbbef46c3, 0xf7806ed0, 0xf2143b5d, - 0xe7121f5f, 0xbdf743fd, 0xe01f2d60, 0xc577f7a7, 0xe19d25ba, 0xe4c9fa0f, - 0xb9daf77a, 0x6ebb583f, 0xbae48729, 0xe1bfee8b, 0xeb976c5a, 0x2051f8c7, - 0x4a384a9d, 0xfaf7957a, 0x344b74b4, 0xdaaaf527, 0xa6d77d33, 0x9dfca21d, - 0x78ed7690, 0x2c3a3ec2, 0x9ebbcdf2, 0xe77df956, 0x41edc965, 0x33188ef7, - 0x259fea07, 0x15b6aef3, 0x49b73c62, 0x521e7ba1, 0x4acfc0af, 0x923e807d, - 0xdef0c1f6, 0x36a57f3c, 0xf10275de, 0x63bc7559, 0x44927e1c, 0x7d57a5da, - 0xa0c6aadd, 0xcf1b6aff, 0x53749383, 0xf89db275, 0x93dc5aa1, 0xeef15b2a, - 0xf74861c4, 0xce281b4f, 0x58df7653, 0xb3fbda23, 0x8a1f4d37, 0x127bc0e0, - 0x6c4fdf28, 0xe047921c, 0xebc4b661, 0xc6c4bef1, 0xbfc7af47, 0x87633a5f, - 0xc1a1df4a, 0xcb8f9071, 0x7f23c8ee, 0xcec8e1eb, 0xaed02389, 0x436ab5ff, - 0xa6e47ebb, 0xffb08b21, 0x58ef4b48, 0xc6d078fa, 0xf4bbaa38, 0xa427a431, - 0x03f32c1d, 0x90bdc5eb, 0xaf9cdeec, 0x8a97757a, 0xefac0bc8, 0xaef9f183, - 0xddf4910d, 0xa3a352a8, 0xdbe715b9, 0x8ee74499, 0x2526385a, 0x2b9ee9db, - 0x8cb369d9, 0x9725222c, 0x453023da, 0xc74375f9, 0x5e4fa81d, 0x1832c3bf, - 0xd4cb8bbf, 0xb9cb43f3, 0x90e3cd7d, 0x61dfc171, 0xeac8eb92, 0x3b57e9cd, - 0x2f7f7c9e, 0x74ec2b9e, 0x3fde919f, 0xebe9ecb1, 0xd89e1f51, 0x7dc7639c, - 0x4919db1f, 0x198e0bf7, 0x78e7bf82, 0xb4c2f7a9, 0x3de4a9f7, 0xc1defcd7, - 0xfba49cf6, 0xb9cbde0b, 0x98f2d2ec, 0x74662e4e, 0x065cfc4f, 0xe8e4fee3, - 0x7e62b6ef, 0xc9a34561, 0x8e64f786, 0x7c63fd20, 0xdf4abb6b, 0xdfbba201, - 0xdb23af80, 0x703ee8f3, 0x5ebcc7c5, 0xf0f8acd1, 0xc3fb72fe, 0xc2fe53f7, - 0xf137b04c, 0x3db7796a, 0xebe1fabd, 0x38ce0d91, 0x3bf1cb3d, 0xf3366700, - 0xef908b7c, 0x75bebc3a, 0xffe38a4f, 0xfd2cfdbf, 0x077bd313, 0xf09347df, - 0x57aae796, 0x720a2e80, 0x72fbf0fd, 0x9fb22cf1, 0x50f62e4f, 0xb4395a79, - 0xb3d2246a, 0x15ee8625, 0x51e3b4bc, 0x5373bf15, 0x79f06dbd, 0x308f1f3c, - 0x9ff7d0c7, 0x90bc5cbe, 0x17279a82, 0x8a3f89d7, 0x15f854b6, 0xb55e547c, - 0xfbde8dad, 0x0b5e4772, 0xd97debde, 0x9ac5c31c, 0x3be820ab, 0x3dbf1299, - 0xfb9657dd, 0x1cd7fcfa, 0x9fdd72cf, 0xc56e9e6f, 0x21fdb57d, 0xe23865ae, - 0x86c63a37, 0xc8a56076, 0x86ba392f, 0x23c7d9db, 0x18abfe62, 0xed7c7cf0, - 0x0efc4494, 0xa9b6ccd1, 0xc57b63d7, 0xe786c54e, 0x49cee703, 0x7dcf3c56, - 0xe2b4efa6, 0xd6cfaa3d, 0x3e57fbc8, 0x237bbbfa, 0xd829b3c6, 0x9eab447f, - 0x84293239, 0xfc32f44c, 0xcbee9ea4, 0xe4ed017e, 0x451f393f, 0x89f813fe, - 0x99927cc3, 0x4bbf722f, 0x9c57f9f7, 0x7d8a46ff, 0xcbb6f7b7, 0x17b506f8, - 0x63f6f015, 0xd096b76b, 0x68de4fdf, 0xbfbae1b0, 0xf1a068dc, 0x4db9c0e7, - 0xbe3deb07, 0xb0839f99, 0x13e8e78e, 0x6779f99b, 0xef3f334e, 0xb833cf54, - 0x60d2fdf8, 0xe80a2cba, 0xeb2ddf47, 0x7323bbe1, 0x737f7c5c, 0x7ee27f40, - 0xb1bf442f, 0x9fee99ac, 0xa93e6a5d, 0xaaff7e96, 0x74dd1791, 0x08bd13db, - 0x23ff22b8, 0x98ba4add, 0xf5c786b3, 0x0b83cded, 0x9d24fe91, 0x5803bf68, - 0x3bfc646f, 0xfa28bab2, 0xb324f7ee, 0x62fa80c3, 0x18e77c4a, 0x075f4f04, - 0x916aaf97, 0xe4f785ce, 0xec29bd58, 0x15dec477, 0xbc1a78f2, 0x7abbf74b, - 0xcff7f8db, 0x59317dc4, 0x474abe82, 0xda293e7d, 0xba038dfe, 0xf2ffae74, - 0xf5d03d3a, 0x3bf691a4, 0xd7809db2, 0x7af35ff5, 0x167b7d9e, 0x7def3fd4, - 0xec3d3af6, 0xf695d26f, 0x2fa80621, 0x75cdf259, 0xc9b9e063, 0x3bd83ae1, - 0x9b139e60, 0x7f71d292, 0xdb087ed0, 0x8e7a27a7, 0xee2b5960, 0xba569d8f, - 0xf4cc2d06, 0xa77b7ff7, 0x0e4be0e5, 0xc0d3bd7f, 0xa73bbbe8, 0x87f5cb7b, - 0xd70e9d2f, 0xa109dea9, 0xdd8ce5ed, 0x5e7cf947, 0x7e076f7e, 0x788911dc, - 0x5dd38aaf, 0xd3c7bcb9, 0xe3c7b9a0, 0xe4d5f7e4, 0x7f792afd, 0xfdff72ea, - 0x7297b5b3, 0x00ffecff, 0x4fb2f369, 0x00008000, 0x00088b1f, 0x00000000, - 0x7de5ff00, 0x5554740b, 0x55b9e896, 0x2a493eb7, 0x54842549, 0xaa84a925, - 0xc0902b7c, 0x310c7c25, 0x0403e548, 0x6a285888, 0xa205a0d4, 0x01148280, - 0x55f4741d, 0x9a7c3061, 0x179f8ee9, 0x102d4622, 0xdd787195, 0x866db1d1, - 0x3220538f, 0xb40e9afc, 0xd38ceb63, 0x68d1d01d, 0x38311b63, 0x6f360cf4, - 0x4dce7def, 0x802a56ea, 0x6f7be7be, 0xf65e97ad, 0xee739f61, 0xffb3ecf9, - 0x5f5bdf67, 0xa5eb2c19, 0x0f24c664, 0xa153ab63, 0x63595a74, 0xff7b9419, - 0x68d2cfe9, 0xac839ac6, 0xc18f2e3b, 0xd3f5a35f, 0x7ccf5051, 0x2e504bba, - 0xcd1a484b, 0x139960c6, 0x996fd062, 0x12aeb189, 0x6d3b26e8, 0x12d8c2cc, - 0x019dfe09, 0x19caf9ff, 0x956c674b, 0x44edfe15, 0xf08742b8, 0x7f466683, - 0x3f98059f, 0x1fd8c0df, 0x3925744f, 0x9d9d8cf5, 0xbb0c2e1d, 0xbc65fb18, - 0x009ce6cf, 0x8ecd1ded, 0xbec634a6, 0xd4a4c37c, 0xd09eff43, 0x60f927df, - 0xe67aa5fc, 0x6d9284ef, 0x24d8ce1f, 0xc3ea2f28, 0x61dfa053, 0x8db6f157, - 0xa9cbbcf0, 0x3f9e0c63, 0xfce70aeb, 0x82c678f5, 0x32f2932e, 0x32777ea3, - 0x9f1eeb80, 0x9dfb1c3e, 0xfe5d7d7d, 0x936eb03d, 0xec1258cc, 0x598c067b, - 0x0030780e, 0x07c32fac, 0xb40e3442, 0xbea09307, 0x0e74f5c5, 0x2f307c23, - 0x0dd8c89b, 0x06ebef8c, 0xf11fbc39, 0x196494c5, 0x6f9b37f7, 0x3283db0f, - 0x3333a38c, 0x98bbae03, 0x4d3f5875, 0x8eb19800, 0x7f60c34b, 0x3263c066, - 0x24c78096, 0xa1eaa6c6, 0xe9afac13, 0x0990fa97, 0x7884d7d6, 0x85d07014, - 0xd72c7a23, 0xc58bf8c3, 0xbc8ecbbc, 0x58c1c46b, 0xeb07fe10, 0x5de62259, - 0x3d7771dc, 0x9092cb9e, 0xc0b74ce1, 0x7ffa25f5, 0x72c79d0f, 0xf2feefd1, - 0xe29c46ad, 0x7eda1dfe, 0xafa6d9cb, 0x52fcf0f5, 0xfdc46dd6, 0x6a8ceb2e, - 0x0cf9a8ef, 0x977cbbd7, 0x99debeb6, 0xc2748698, 0x97b1b2c6, 0xe74d54f4, - 0x99f448bd, 0xca746faa, 0x66e19fb8, 0x371304c5, 0xf4479f3d, 0xb00cdec2, - 0x63ac7ec8, 0x8b4fd118, 0xb1e74f4b, 0x9cc49764, 0x7ebb18e3, 0x42731657, - 0x61aefd53, 0xc85d2654, 0x5fcffaa0, 0x57de3639, 0xd75e7032, 0xc6ab6abf, - 0x6aff5df5, 0x3aea9511, 0x4e1d049a, 0x867497d5, 0x2ce71d61, 0x9b800eb0, - 0x8162c08e, 0xd66e9a7e, 0x99e11887, 0x57bfb199, 0x596bc72c, 0x424fa5df, - 0xfd8a0e58, 0x3a24974a, 0x1f3c6484, 0x433d61ef, 0x031e627a, 0x79993bb5, - 0xa05ca5cd, 0x398ebb1b, 0x24dfe063, 0x19ce2fce, 0x81ee9ccf, 0xfc583976, - 0x87584ab3, 0x0941ae61, 0x5c737b41, 0x33e436d2, 0xe574f416, 0xe20d73c3, - 0x4e38aeb9, 0x54ee0937, 0x1d2af3cd, 0xadfa2adc, 0x18769a4b, 0xb3c1b2e9, - 0x5121e888, 0xc7acd4c9, 0x406a5fa4, 0x67d5b9fa, 0x623ba4f8, 0x585fa21c, - 0x295e0dc7, 0x7378fc84, 0x50ddb683, 0x44ad75f9, 0x8e47d425, 0xfbf6d5e7, - 0xd003d229, 0x717e103b, 0x9c0c3d24, 0xc3a3c583, 0x1224f073, 0xb9cccbbd, - 0x5be012b9, 0xee181b0e, 0xf7cf14df, 0x97310e79, 0x0f80fd86, 0x8875e260, - 0x2e4fa817, 0xc537e2d7, 0xb0e7c5a3, 0x867e2d3a, 0xb7fbb57b, 0xda6ae435, - 0x35237c33, 0xcb8b59ed, 0xbfb67034, 0xc47fd342, 0xec0d6aea, 0xf4d4ce0a, - 0xa37f5bcf, 0xbd682e06, 0xa8bfd35d, 0xbda6817d, 0xa69f7438, 0x268ed47d, - 0xf9da5c0d, 0x98ffa688, 0xda6b8f5d, 0x6a3786c7, 0x7e1dc7da, 0xe84f034a, - 0x7fe9a2da, 0x34db07cd, 0x5fba93ed, 0xdb5fb4d3, 0x9e0686f3, 0xd35bbbdc, - 0x0385ca7f, 0x1d8ab81a, 0x31aff4d3, 0x4f0356ff, 0xa6abfeb5, 0xc7fb74ff, - 0xce19f69a, 0x67da6a3f, 0xd2d1bfb9, 0x93973c6b, 0xa5ff2bd7, 0x9359ee79, - 0x5f50dfef, 0xdd954b34, 0xebf48641, 0x35ba3e24, 0x0184a74d, 0x972a83fe, - 0x1c9e1d04, 0xc1392561, 0xb78e59f2, 0x32b0e914, 0x6e7c7c8c, 0xe0f24497, - 0x28bd28ab, 0x91ebd1ff, 0x4afd9da0, 0x22765e52, 0xc45d41dd, 0x331e29fc, - 0x39d62393, 0x81aaceac, 0x9aed7b87, 0xa706b6fe, 0xe7c33da6, 0x2d67b4d6, - 0xb6703456, 0x7fd35cbf, 0x068f6ac4, 0x34eb0576, 0x7bd6f3fd, 0x6b417035, - 0x517fa683, 0x5ed34fbb, 0x69ac5a1c, 0xafc3b51f, 0x573b4b81, 0xd98ffa6b, - 0x8fb4d415, 0xb4d7af0d, 0xaadc3b8f, 0xb5742781, 0xf35ffa6b, 0x3ed34841, - 0xa6877ba9, 0x4e9edafd, 0x77b93c0d, 0x94ffa697, 0x5c0d610b, 0xfa688ec5, - 0x6a4f98d7, 0x0fd6a9e0, 0xdba7fd35, 0x67da6b4f, 0xb4d73f38, 0x2cd076ab, - 0x7adad7f7, 0xaf5d1761, 0x7cf359fc, 0x90c3dab0, 0x486f823e, 0xd613b34a, - 0x3fe102eb, 0x777ce49c, 0x28ed1e9c, 0x8c14182f, 0x41ad2901, 0x420c92fd, - 0x480ae90c, 0xe2a6358c, 0x20ac4028, 0xc15549b7, 0x4f68c9f3, 0x73aa9000, - 0x1fa0fcb9, 0xeb5ad813, 0x1bb266a7, 0xdf40971c, 0x29bfc25d, 0xa0944b83, - 0x85ebaa9f, 0x4ea166f9, 0x726f3a02, 0x582e3cf9, 0xaf9d7dcf, 0x6862cb4f, - 0x705b0427, 0x9307a01d, 0x9e6f41bb, 0x79776388, 0x378f064b, 0x89780cc3, - 0x5c48ef98, 0x32cca3ab, 0xcc33fcf4, 0xff7fa967, 0xae3e06b8, 0x8a6bfb04, - 0xa0a7ff18, 0xfbb065ee, 0x37c0035a, 0x153d8c05, 0x4cfc12b0, 0x5b704ec0, - 0x7b6549c0, 0x96e54dc0, 0x1ded4280, 0x5f827281, 0x0e087808, 0xdca8ea05, - 0xfd52f016, 0xc10340f6, 0x547c04af, 0xa62c08ee, 0x9f80b5f2, 0x560677da, - 0x40f3fc13, 0xc0ceca90, 0x237faa7a, 0x9bf04ad0, 0xdf827681, 0xdca8840a, - 0xe541d815, 0xb52740ee, 0x22ec0def, 0x9840edf8, 0x30e070e0, 0x5d0207c1, - 0x7c0c1f04, 0x40a1f040, 0x03879537, 0x0d1e543d, 0xf1fb52f4, 0x078205c0, - 0x576b4bce, 0x2e576133, 0xd2c07412, 0x2f793db8, 0x85f6523f, 0xbb462d8e, - 0x43a09177, 0x87983543, 0xcc867740, 0x2ecd6dc2, 0x13a06a3c, 0x71c9d137, - 0x96af2fb4, 0x4070d04e, 0x33560d7a, 0x5a9bd237, 0xc9e954b6, 0x90ae0cfe, - 0xbb732f42, 0x336feb88, 0xb537f553, 0x85283e37, 0x079b9ed0, 0xf811b276, - 0x9f6123e6, 0xe5c7147c, 0xc1bf39f5, 0xa35f768d, 0x66c0af14, 0xb277fe01, - 0x8c2fe03b, 0x5ed77fa4, 0x9fb456d3, 0xc235f5d4, 0xe7183a38, 0x5a2eecbf, - 0x6c3b2357, 0xbd40f5c0, 0x72fc0f47, 0xe2dbe6c6, 0x2fbeba02, 0x2234175b, - 0x85425913, 0x8cc644de, 0x48f3df76, 0xf7fce7e7, 0x17c1c21c, 0x9c429559, - 0x78537ae7, 0x7f30adf8, 0xb2bd11ef, 0x5e3439cd, 0x00ceb796, 0xf6997de1, - 0xa0773fb7, 0x17f75f1d, 0xe1cf0fbd, 0x21b12184, 0xe9dd7404, 0x3acf8892, - 0xd94d3a5d, 0x02fdf766, 0xa26df9d7, 0xa01d4eff, 0x56ebdbf2, 0xb612b2bc, - 0x20a2b8d4, 0xf055ed19, 0x5f680c0f, 0x034e61cf, 0x989b87ca, 0xea1c5de7, - 0xf823e666, 0x52a41656, 0xe176f9b6, 0x21636ebe, 0xa6157d82, 0x8afb589c, - 0x383bd75e, 0x752c70d8, 0xdd90f29a, 0xfbc70077, 0xeb43d136, 0x7a69313a, - 0x5d4bee21, 0x49c33997, 0xdeb366fd, 0xdf7d7017, 0x53fafbee, 0x9d306f29, - 0x61f488fc, 0x3fb06981, 0x3779c233, 0x38e0ef03, 0x214b0fcd, 0x3e9573a4, - 0xa74cc11a, 0x7a851ff1, 0x805e9229, 0x4b7fd04e, 0x9399cdeb, 0x4dd2f448, - 0x3e926ff2, 0xfa7b0468, 0x28542e84, 0x8c4e89e9, 0x5173ac12, 0xee49d01a, - 0xc0f0f4d0, 0xe423287a, 0x17d9d020, 0xfe9fde38, 0xe2371ae1, 0x93dbf96d, - 0x66b7889c, 0xd0079c1d, 0x9ea8f073, 0x442604ec, 0xd2dafebb, 0xb207f910, - 0xc529cca2, 0x7172e373, 0x7ead9ebf, 0x4ddc863d, 0x74f4e5c8, 0x0ba86ec2, - 0xef9cb8d1, 0x2e7d76d5, 0x2e7d473f, 0x15a6df3f, 0xc3d52d9f, 0xf81c4ffa, - 0x8d2ce8dc, 0x3fd58fb1, 0x823f2879, 0x3aef97ae, 0x7e83cd3d, 0xb92eeb17, - 0xbea07131, 0xd2abcc50, 0xe898de91, 0x5c896adb, 0xc75d3f57, 0xa75d22e7, - 0x11e75d00, 0x768a7f5d, 0x33936cf9, 0xbb2856f9, 0x28613501, 0xc95a2f7d, - 0x14c05c7f, 0x2f32172a, 0x0c808b95, 0xc1bd8e90, 0xf7888d27, 0xd52758fb, - 0x777e503f, 0xbdf5d23a, 0xd9f91f3a, 0xd517594b, 0xb5bd672f, 0xaf37b478, - 0x1daef35f, 0xeb537d56, 0x44915393, 0x7fcd0c6f, 0xdb39cb17, 0x4e834fa5, - 0x5cec93e2, 0xe4b747c0, 0xe613227f, 0xd5677dbf, 0x3f505913, 0x85cfcf5b, - 0xa2e7e31d, 0x7de891ca, 0xe0145f03, 0x78a6dff3, 0xa4fa5f68, 0x345f0d3a, - 0x123cce3e, 0xcfbbd38c, 0x8ae6da14, 0xfbf293e0, 0xf28590ff, 0x13bdee4c, - 0xdbf97bcf, 0xef3c54a6, 0xfbd718fb, 0xaf8d4792, 0x119efaa8, 0xe2cfdfbd, - 0x85f7ec15, 0xb22fefa0, 0x17f7d119, 0x658a3812, 0xcb287603, 0xf2cbd9f1, - 0x72f6f406, 0x88d1cedd, 0x95ebd027, 0x7df70e78, 0xd632d9dc, 0x9420fa85, - 0xe1887683, 0xecd29335, 0x7617e8d2, 0x8d850129, 0x7f3e219f, 0x198ee38a, - 0xfca92ebc, 0xeed19fd0, 0xd0591930, 0xce7c465c, 0x677f2226, 0x9abf891a, - 0x3879b511, 0xb7e9d78f, 0x84ff1e0c, 0xefe1ef58, 0x841d3fb8, 0xc52cbcfd, - 0x2feb879a, 0x3cc0fc53, 0x19d24724, 0x2e4773cd, 0x3e7563e7, 0xa076e966, - 0xc1347e9d, 0x8f9e3b77, 0xfd52471a, 0xcfaec3c8, 0x667cf1f2, 0xe5506c57, - 0xaec78d33, 0x84e972e3, 0xf84419c1, 0x014b9544, 0x6f2fd609, 0xa7ff286f, - 0x371d700f, 0x8c612d98, 0xc34ab077, 0x35ff7ed9, 0xdf1f4077, 0xcae3eaa0, - 0x1a8ef8a8, 0x018a61f7, 0x3ecc57d7, 0xf141f152, 0x0e4e551d, 0xb1b0bfd2, - 0x889fc42e, 0x79c7f597, 0xce3fb9fe, 0x8d79c3a3, 0xe6328e42, 0xf8237b77, - 0xae00d6d4, 0x307fc68b, 0xff8d7cb3, 0xd9c0d560, 0xffa6bb7e, 0x4d4ed588, - 0xd6e82bbb, 0x57ade7b4, 0x6b417034, 0x517fa6b9, 0x170347bb, 0xfd34ea87, - 0x6af0ed47, 0x06ced2e0, 0xbb31ff4d, 0xb1f69a7c, 0xf69ac5e1, 0x1afd8771, - 0x6ad74278, 0x3e6bff4d, 0x27da6a08, 0xb4d7af75, 0xaad3db5f, 0xb6f72781, - 0xb94ffa6b, 0x57b4d210, 0xb4d5bfb1, 0xd75f98d7, 0xf1c62fc0, 0xeb54e778, - 0x9b9e683f, 0x81afdf6e, 0xf1e7885f, 0x23ce199a, 0xf9c5e7da, 0x278b6f06, - 0x3ee5987e, 0xffdf69a9, 0x8dcdc8c8, 0x47a12fc0, 0xb67fe474, 0xc53d71d5, - 0x1d39aa1a, 0xd7bef1c4, 0xe66a1f2b, 0xbaf7d1cb, 0x7a9d8e90, 0x75f2266b, - 0x039cf97e, 0xd0ac7640, 0xc51aa2b3, 0xc9eebb9d, 0xf48e5803, 0x6c8d5ebe, - 0xf270d253, 0x7da39600, 0x1903575f, 0xca716533, 0xf996583b, 0x70d8d6c7, - 0xbce7ab89, 0xe0c4e583, 0xb3941a8a, 0xb17e2660, 0x3e7dd608, 0x846d9238, - 0xaa652575, 0xd10f5e71, 0x1d0caaed, 0xdbaaf9f1, 0x4b37142c, 0xa322d6bf, - 0xe81cdf3e, 0xec10791a, 0xd3a7f4dc, 0x69dc62d7, 0xa1f9d83d, 0xc017b022, - 0x59f2c7ee, 0xe043ebb0, 0xbb046d1c, 0x604dcb1f, 0x73fd63f7, 0x9c23f760, - 0x7ad974fe, 0xc9d56e7c, 0x6172ea7b, 0xca0f11fc, 0xd7533456, 0x0e2b7539, - 0x0fec7ac0, 0x4b28ad1a, 0xe267ae8c, 0xec8eb09c, 0x0a8eb065, 0x51078b42, - 0x3052ecfd, 0x1c39321c, 0x2becfd07, 0x1db81a74, 0x2eb045ff, 0x97cf8b58, - 0xaedee93e, 0xb6f9f630, 0x8a1937b3, 0x5d799f61, 0x014d6db7, 0xe6799738, - 0xf1d3be02, 0x93fc602c, 0x09cd8f79, 0x97860c96, 0x48ff7a14, 0x2cee4972, - 0x16b53e46, 0xeb81947d, 0x85fd50da, 0x3ce2b3a2, 0x0839cc8f, 0x787e7eeb, - 0x23e758bc, 0xaff2aa73, 0x79cf5c66, 0xef50ef94, 0x47218cef, 0xffe853fe, - 0x2f5c7993, 0xe5159fc3, 0x08938d93, 0x949d81b3, 0xf376f20c, 0xd1a7d5a4, - 0x41ad90a7, 0xbb23e509, 0x144fcf08, 0x7823c828, 0x1e44fc4a, 0x537947b2, - 0xe733e454, 0x1f3678c1, 0xf1914ed8, 0x785ac5b1, 0x19e79c33, 0x0c7ac0c3, - 0x3282e977, 0x92f0c1ec, 0x9e605157, 0x5fb0798e, 0xb51b3780, 0x8e9165fe, - 0x9f717d91, 0x378beeba, 0xdda76829, 0xf0f5c797, 0xecbb8096, 0x7ffa0313, - 0x4027d94a, 0xfd8b9947, 0xabe40f92, 0x04abd1ad, 0xd2e19fa1, 0x2237efdf, - 0x3ac5df61, 0xfd639f51, 0x27bb089a, 0xb86b8c47, 0x19bc27a4, 0x6a4abd9a, - 0xbd06fcc4, 0x618cefe4, 0xc9e69577, 0x4666b9fc, 0x1e7786ed, 0x5f309c96, - 0xba486366, 0x4bf1c687, 0xc2dbd40a, 0xb1ab3ebc, 0xf0085a53, 0x3a4e791d, - 0xac9c7507, 0x08feb0c5, 0xa0e5d93c, 0xede78564, 0xc425068f, 0x55eadd83, - 0xdae22258, 0x52bdfc4b, 0xf57db4f0, 0x864fb2c4, 0x8abdbae1, 0xa59be717, - 0xcadf9bf2, 0x2b1f3d70, 0xbd42a9bf, 0xc33d1bf6, 0x9c6f8cfb, 0x8c5a724a, - 0xa9a5a87d, 0x973ccf5b, 0x729267f1, 0x9e93f11e, 0x2ce2ddbc, 0xf17dfe00, - 0xd6c34b36, 0x47767418, 0x75b3a71e, 0xe2deaa99, 0x73d749eb, 0xeafaa93c, - 0x1fa72b1b, 0x4cad6e55, 0xce3ab0e1, 0x24f1ecca, 0x8f5a8637, 0xf98e3dad, - 0x19bbd622, 0xfde2b1e6, 0xac2b77cc, 0x21f03788, 0xcc9f34bc, 0xe7d6e9e5, - 0x4637e4dd, 0x3e20cfd3, 0x5c9bd100, 0x1dd97486, 0x31ba066a, 0x682a33cd, - 0x5bfeda2f, 0x2472848b, 0x284ab593, 0xb5d96d47, 0xe7d46587, 0x1bd8afb2, - 0x12be8ec3, 0xa9e7a83f, 0xcf8325da, 0x2abbf9cf, 0x0c0d43b2, 0xe5c9b6e9, - 0xa9f9e1b4, 0x6474da74, 0xe22faa78, 0x3a0bd73c, 0x7aad672e, 0xd60ad3e4, - 0xeb256549, 0xd63af2a2, 0x5987a54b, 0x99ab2c65, 0xf32d6542, 0xf98d3952, - 0xad63aca9, 0x9d64ce54, 0x2eb3d654, 0xa3bfc12a, 0xe4accbd2, 0x7608de87, - 0x9973960c, 0x985bca97, 0x482dca9f, 0xfef013df, 0xdbe095a1, 0xbb952759, - 0x459dff80, 0x53311f18, 0x39e417b9, 0x3c836f96, 0xf20c32c7, 0xf8c269dc, - 0x83ca9b88, 0x43ca8501, 0x0f2a7281, 0xefd43c07, 0xca8ea068, 0x952f01e3, - 0x540d0227, 0xd47c0576, 0x316054ef, 0xfc05ef95, 0x581fbe54, 0x8107e54d, - 0x12ff9520, 0x91654f58, 0xe20ae411, 0x163ddddb, 0x8f9c9afd, 0xe8271e8d, - 0x84f34fa3, 0xfdd1ebff, 0x78f1e2f7, 0x83ba3a8e, 0x94aed5b1, 0x6e6d1e90, - 0xe504279d, 0x74937746, 0x4eeb9437, 0x64d63b70, 0xd93b244b, 0x724abed6, - 0xa4bbb8c2, 0x9c027d6e, 0x0fbcdeed, 0x4f4198e7, 0x6b65ed54, 0x7f841413, - 0xe819a4ff, 0xdfc1ab70, 0x7fda15bb, 0xcebfd2f5, 0xaece8331, 0xc7f53c48, - 0xed4c38d7, 0x66b20e93, 0xf207c02b, 0x26993f4e, 0x10a075f1, 0xc7d2fe3e, - 0xe3e4d673, 0x791cb93a, 0x368e05d5, 0x5b0f19fa, 0xdb18cfc8, 0x0eac667e, - 0x2dab49e0, 0x471fe865, 0xf5b8a3f4, 0xdba2fd50, 0x563ae7d5, 0x1e2337a4, - 0xee0a7dd6, 0x65e51389, 0xcf8c58f7, 0xbbab8e45, 0xfe99f9ba, 0xf647f332, - 0x5e332e93, 0x54e79151, 0x7403ffde, 0x86df4d1e, 0xaebf1f4b, 0x3598f8a3, - 0xf6faf515, 0x7a772e14, 0xdb43e3b3, 0x53dbdd60, 0x9f21bc05, 0x610eb5f6, - 0x8dbad7d8, 0x6fc764b9, 0x1d36f38f, 0xd1bff6c1, 0x69a0db29, 0x636fbc7b, - 0x14f9c131, 0xea9759af, 0xca5ea377, 0xb1fae049, 0x9c48f1cd, 0xffff8233, - 0xe6eee422, 0xadaebeca, 0xd7ad4fe8, 0x6e7802b1, 0x1b05fadb, 0x4bce30dc, - 0x022ec09b, 0xc2f27938, 0x9ed0050d, 0x513741bb, 0xae1e642f, 0x0b4da5e3, - 0xe128d95f, 0x0b5323b8, 0x213cdc61, 0x7586733f, 0x74095d8f, 0xc6d466de, - 0x63f5fa15, 0x8597e73e, 0xd019cc30, 0x5e2239bf, 0x1ac0d5b1, 0x4166f522, - 0x35b7973e, 0x4c34bc45, 0xd33cf1e1, 0xe3d0f888, 0x11aaffb0, 0xbe93fe3c, - 0x9ff14cd6, 0x9e7fc774, 0xe9ed0e9c, 0x4d053a1d, 0x74b6d95a, 0x9efd018d, - 0xf22758db, 0x3f8956e3, 0x76e6cc1f, 0xb92c1832, 0x1efc2273, 0xf2ca37b0, - 0xf6a7e223, 0x7184a086, 0x4b11aa8c, 0xa7378c25, 0x3093ee3b, 0xe0de91fe, - 0xe8897c93, 0xfda9f927, 0x2b9f22ae, 0x6f67d61f, 0xf735e784, 0x3c0cbeb1, - 0x81b79857, 0x566409f2, 0xecdf3916, 0x27878e22, 0xb43d2064, 0x691ad7df, - 0x9af8d15d, 0x991eaee5, 0x1ce07c3f, 0xccbfdba3, 0xfdb8e7e7, 0xf9029871, - 0x1f8f1260, 0x9339789c, 0x6dd9e5ec, 0x23f41ef1, 0xb2393c4f, 0x2aa7e096, - 0x9eff683c, 0x1a62b978, 0x9a9fb396, 0x484efd49, 0x05c630ec, 0xbb753f66, - 0x7939f58c, 0xef1c2eb0, 0x71e891b4, 0x89f753f6, 0xc5a91fe7, 0xf05d72f6, - 0x2e9fd0ef, 0x012d7e6f, 0x891505e3, 0x7961646f, 0x6abdd742, 0x837fcc3f, - 0xd51afd95, 0xda4377b5, 0x3fc1d4df, 0x6b993ce6, 0x378c78c0, 0xf3ce973f, - 0xf031e626, 0xf92f077c, 0xba3b95b7, 0x8e8b01de, 0x5bd9d75d, 0x9ebad783, - 0x5883d65d, 0x34158756, 0x61ed59a3, 0xa72c41ef, 0xd16bf975, 0xa0fba9bc, - 0xdd9620f5, 0xc45e7d23, 0xedffabff, 0x055e3796, 0xab63c478, 0xe68768ac, - 0x633dde3f, 0x0d2fc51b, 0x60a1f90c, 0x8f55bf92, 0xa6f66c04, 0xf6787ca2, - 0xfa875919, 0x8d6ae4dd, 0x4f74d843, 0x4ce30eae, 0x175a53db, 0xe20bbed3, - 0x28f1e219, 0x8ba421e8, 0x2a6f1482, 0x25f013f2, 0x829dc39d, 0x7e294d3e, - 0x8bd60a6b, 0x7efe8e7b, 0xd85e1cf1, 0x4e35afdf, 0xa55279a2, 0x08cdc4a0, - 0x42ec23b4, 0x7f33b79f, 0x96c3e206, 0xf18adfe8, 0xce2a82ad, 0xd3912cff, - 0x996f7605, 0x10508f48, 0x3fd5bd3e, 0xe6c1cf0b, 0xe01bcfeb, 0xb06a0774, - 0x25c93edf, 0x367fee98, 0x39061c4b, 0x3fc2eb43, 0x5ba4e78c, 0x51cec9d2, - 0x806b6fd7, 0x0eec22f1, 0x968dc7dc, 0xba54e781, 0xf5f620db, 0xe60b2884, - 0xf5d4f1f3, 0x7ae7cc6e, 0xd4edd61d, 0x62f47ae1, 0x5d0fb03d, 0xfa227ac4, - 0xd7fafed1, 0xd23b14cd, 0x897e6305, 0x4729cc97, 0xcea17fee, 0xd71a3713, - 0x615fd6ff, 0xe509295c, 0x67f3ac08, 0x919927fb, 0xf1f7a34f, 0xfb88be42, - 0xfe8cbd80, 0xe71f4cc3, 0xbf46e6df, 0x0d94fe84, 0x43bfdc61, 0xd45c60f6, - 0x0c926966, 0x39b5fb11, 0xd99e9eb8, 0x728fdfe8, 0x82796665, 0x8b3df482, - 0x72b5ae75, 0x0f983efe, 0xfd622beb, 0x7136167f, 0xfe7c4ec0, 0xe24ef799, - 0x67583a91, 0xcfea3155, 0xbca5eec7, 0xcc8fcd89, 0xcfeb8c3c, 0x3fb93f74, - 0x7ef40615, 0x3e7dce2d, 0x77656f8f, 0x87bc9ac8, 0xc9acbf2c, 0xac58c88b, - 0xd07a076d, 0xd95d2ac0, 0xa829d5a5, 0x2509746f, 0x9da06733, 0xf923a492, - 0x9a4a720e, 0x8d1ed31b, 0x7f812ba2, 0xcdde7cf5, 0xb373a7cf, 0xb039f859, - 0x737cc55e, 0x7aacd8a2, 0x336f304e, 0xd03279b0, 0x3ead737d, 0x8f1fa124, - 0xb232f1fd, 0x26f70d97, 0xada73e0e, 0x19cce706, 0xd41fa728, 0x2aaf2959, - 0x67a0af0a, 0x94fc99fe, 0x1da8d307, 0xc53365ea, 0xabd6233d, 0xcf6b058f, - 0x3bfd4ae3, 0x0cce7858, 0x4cfae0d7, 0xa899dcc7, 0x32973367, 0xf6e8ff3a, - 0xe7b547a2, 0x78ef7e4a, 0x50b1a38c, 0xe79c07f8, 0x5af6c74c, 0xcfa3efb4, - 0x9cbba555, 0xc2f5b161, 0x2f5c0523, 0xa72824e4, 0x90aec8ea, 0x66f04ec9, - 0xfd23c3cb, 0xb9f2efa4, 0x57e5301f, 0xec43d216, 0x1f087363, 0x3f5dc255, - 0xa8738629, 0xfba1d3ee, 0x7e3ddec2, 0x5099e9e0, 0x7bf5fd4e, 0xdfa0c74d, - 0xe32cefd4, 0xeb377eb0, 0xa081819e, 0xf90361e0, 0x7cbe6b8d, 0x440315a5, - 0x414c8dcd, 0xe3ceabbd, 0x6efae028, 0x25e4218f, 0xb32c5af9, 0xd907246d, - 0xf4114bc5, 0xe89e9002, 0x6f31b787, 0x91f92b63, 0x8612fcb6, 0xaccd3c79, - 0x97d20ef3, 0xe30c8d67, 0x383637af, 0xffb0550d, 0x869d1b1b, 0x219f78f9, - 0x23b43ab3, 0xa8506a6e, 0x8546a6fe, 0xfd799bd7, 0xd50f06dc, 0xf0f46dcf, - 0x5bd40b7a, 0xd4290f30, 0x6f718015, 0x753aa4b6, 0xe8d01f78, 0x4c17ede5, - 0xfc1c7ed4, 0x8c27cc01, 0xbc910b8f, 0xf1d1ed6f, 0x7c7f237b, 0x9ab58248, - 0x3b0ecb12, 0xe8f77f11, 0xcc175014, 0x2b332d94, 0x7836cfc0, 0x7f687a43, - 0x1032858e, 0x3617bb91, 0x7ea10b79, 0xe2b643b7, 0x7b8376fe, 0xc147f98b, - 0x9de132a5, 0xbdde00fe, 0x3af741d8, 0x3efc455b, 0xf14cc4b8, 0x2875b066, - 0x6496ccde, 0xb7863b0a, 0x86b02c77, 0x39031ed0, 0x7bd8e748, 0x00764c8f, - 0x6ea3c3c8, 0xe6768bb4, 0xca9f182b, 0xb7e5aa5c, 0xaa0b85f4, 0x6646bc68, - 0xbebd3f45, 0xbcd78f91, 0xa1d21753, 0x71b9655d, 0xf341d226, 0x3fa0a60e, - 0x53c2ecfb, 0xee10c3b5, 0x3f2e1450, 0x79a172b4, 0x9c4753e1, 0xcebf1fb8, - 0x79fd405a, 0x5fd9af1c, 0x0d2f5dbd, 0xb79d33f0, 0x0c7e4073, 0x61ca3796, - 0x5e63271c, 0xc1f182b5, 0xc627d874, 0xbc8c3bf3, 0x4ca7783e, 0x0be92df7, - 0xf475b0e5, 0x0b677f00, 0x1f23a614, 0xd17c9126, 0x9dc8d7f0, 0xc179f85a, - 0x32efc0a7, 0x9db82bee, 0xd1673e51, 0x903f6d76, 0x57943a93, 0xfadaedd9, - 0xe3fa8b5b, 0x443c1a02, 0xe7e6d9e3, 0x9f7a2f72, 0xc70afb03, 0x74bed115, - 0xd7285f7c, 0x72d8bea0, 0x1b8bea80, 0x44e9c565, 0x0a79d779, 0x53b45ff7, - 0xeb806166, 0x44cd9617, 0xa4dfaa7a, 0xf5c8f0a3, 0xc2e48bac, 0xc6adf695, - 0x19f7a23b, 0xf2efbfbd, 0xa88e5cf5, 0x6613e0f6, 0x1edb07b2, 0x9ef0e8b6, - 0x78adec15, 0x55dc2b8c, 0x402c1d54, 0x1dc8407b, 0x973d25c3, 0xa216cd27, - 0x51ed8353, 0xa1fc6477, 0x13f55465, 0xd86fd405, 0x6e3c758d, 0x968efb41, - 0xe3173f63, 0xe6d6ea4d, 0x13db5de3, 0xa63f951f, 0x729bc7cd, 0x7f2a3321, - 0x7f2a2f2c, 0x7da6946c, 0x545c75aa, 0x51b5d8fe, 0x1a3563f9, 0x967b9678, - 0xcaf5ffa6, 0x86f81a4d, 0xfd343bf2, 0xd6ee78e7, 0x7754dfb4, 0x66fda6bf, - 0x7c0d4aef, 0x6b5fc36b, 0x6be6dffa, 0xb1dfb4d6, 0xf69a27f8, 0x2d49ff68, - 0xf9701577, 0x3feed9be, 0xd06c0149, 0x3df791f7, 0x28de996a, 0x7b9e46f7, - 0xa7b70252, 0xb9fdfba2, 0x8bfbd380, 0x058f9f12, 0x1c789aed, 0xf135d8f3, - 0x854570ba, 0x71c61bb9, 0x21df951a, 0x0ee262dd, 0x6bb6bfbf, 0x3ff6d9ee, - 0xbc60fd0e, 0x1b5cc4a6, 0xff8c3bea, 0x37b940fa, 0x5f747487, 0x4abf5b61, - 0x69b83d22, 0x5cab8f15, 0xaf3c5230, 0x8eac1d7f, 0xdc46fbc6, 0xeceba96b, - 0x2da47110, 0x85424718, 0xfd4199e4, 0x7ef1c656, 0xe3574d3f, 0x371a3e8e, - 0xa418dca3, 0x7e85bcfc, 0xcdc0e309, 0x7bc5663e, 0x02cb7493, 0x069bff9a, - 0x265d9925, 0xb016da2e, 0x67cc0f33, 0x635c155f, 0x527dbd84, 0xb3d4f7d0, - 0xcfddbcf0, 0x5bd31e28, 0x1853edf0, 0xe143e98f, 0x219d7408, 0xf73f3c73, - 0x5fcfeec0, 0xe6daf981, 0x5ca197a5, 0x5acf6e8d, 0x43ebf7be, 0x6e7f6997, - 0xde1f5bd9, 0x1fe7b97b, 0x25ba75d8, 0x38c87da2, 0xf3264369, 0xe001d044, - 0x80fde62c, 0xf9f5c85c, 0xc5230af2, 0xfc01aeb1, 0xbfbe0215, 0x89cff8aa, - 0x3fb9e03b, 0x44eefb39, 0x65ea1d3b, 0x847e87ac, 0x9fe53fd7, 0x9c92fca3, - 0xa3df6051, 0x9b171dfd, 0x7215c76e, 0x8d6d95ba, 0x6a0718bd, 0xd13a344a, - 0xbb32cfcf, 0x07193eca, 0x7ee06d74, 0xfeffb475, 0xddbfbf5c, 0x9177fe49, - 0x944b2718, 0x9e7f2b7a, 0x4e4c8399, 0x3114f717, 0x6a4fa1f0, 0x655e5097, - 0x8d3f942e, 0x89fd8be4, 0xa4238a46, 0xc1dc445b, 0x171358b2, 0xfb06e350, - 0x9095ef13, 0x4bc3d3ee, 0xf18f9e28, 0x5c6f1c02, 0x11d693a1, 0x32c82f1d, - 0x86bad3e7, 0xd7f59f1e, 0xe6314827, 0x1a875a89, 0x279e889f, 0xea04f684, - 0x64f16599, 0x7bef444f, 0x79556149, 0xd7e470e1, 0x51d393de, 0x90329f7e, - 0x5e8a1c3e, 0x143ccf30, 0x42b4fe31, 0xfe63dfee, 0xe63d6478, 0xe3228787, - 0xef41ccd9, 0x2a0c102b, 0x7bb18466, 0x77ce1143, 0xc277cf94, 0x1ec9d8a0, - 0xfe87b504, 0xd7217d5f, 0x9730d303, 0x19f2386d, 0x81dbcbf7, 0x12dcb1af, - 0xd67d92b0, 0xf087fc01, 0x9527010b, 0xca9b80a1, 0xda85016d, 0x09ca07b7, - 0x21e0257e, 0x8ea04778, 0x5e02d7ca, 0x6819dfaa, 0x01e7f820, 0x819d951f, - 0x46ff54c5, 0x9bf04fc0, 0xbf04d581, 0x0160f685, 0x53d7a9c6, 0x4ad03bb9, - 0xed037bed, 0x081dbf04, 0xec0e1951, 0x8103faa0, 0x060f824e, 0x287c1176, - 0x70f82610, 0x479530e0, 0x7f545d03, 0xc101f03c, 0xc93ee337, 0x15df58ae, - 0x4f8578c0, 0xf77da276, 0x15a16fac, 0x7cfb6bed, 0x79c5159d, 0x04b74fbb, - 0x8d1d1ce3, 0xef131efc, 0x040e3123, 0xed086876, 0x67fcfb39, 0xf6a54c8e, - 0x19bed4b9, 0xc4a70487, 0xafdb82b6, 0xfa91996c, 0x0a2130d9, 0xda58eb9e, - 0xdc03d218, 0xed4f185a, 0xf93215b6, 0xfce9cf6d, 0xeedc8529, 0x336df922, - 0xa541fb70, 0x5c853583, 0xe429aede, 0x161f5cf7, 0xca4a73f1, 0x9e47ad8b, - 0xa6ed542d, 0x7f7187f5, 0x3fb079f6, 0x55bcef5c, 0xb597bc66, 0x72b3a3dd, - 0xcbdf937b, 0xb8bf603a, 0xc50f587e, 0x6e7cd985, 0xade6db2f, 0xe63975a5, - 0xd6ed48df, 0xd05347a2, 0xaff76f4f, 0x6deb439a, 0xd9ae2994, 0x82903bee, - 0x89cf6cf7, 0xf0db277c, 0x64a86f78, 0x8d9e7af0, 0xe3077f5a, 0xec03837e, - 0xec63d7a5, 0x496ed303, 0xc71130cf, 0x331cd47b, 0xe829d78e, 0xfe7121d7, - 0xc4ca0f63, 0xb0302f7f, 0x2db9e0fb, 0x5105df60, 0xb6bf540e, 0xbd55e302, - 0x289dbe85, 0x8e779f37, 0x9c03203f, 0xcfc7c75a, 0x82bf255d, 0xf79c3476, - 0xbf502de7, 0x5e4dbee1, 0x4db0ea5c, 0x6ec835ce, 0xcadff3ed, 0x4397f8c0, - 0x5a8f9ed2, 0xf9f62dbe, 0xb78f8782, 0xf14c9565, 0x378adb64, 0xbcf9075d, - 0x33ff91bb, 0xc38a3e8b, 0x5cde4c30, 0x86450ea7, 0x35fc9e63, 0xff7717ce, - 0xcd423aa6, 0xdf3a8f26, 0x6aef9c58, 0xb1e234f1, 0xc62f9b5a, 0x279286ba, - 0xbf239257, 0x81ef1429, 0x942cb164, 0xb819cf23, 0xe49e0adc, 0x052524f6, - 0x8f3c1a4d, 0xe6a02f9a, 0x0be7440f, 0x29e05efc, 0xde62c4cb, 0x4fd67ee7, - 0xd73a41bf, 0xbd1b3c17, 0x92e36794, 0x35874931, 0x7a12d819, 0xde2aa7ef, - 0x3d0626ba, 0x2853e5a8, 0x1fc100c7, 0x2e713216, 0x38f8ea9b, 0x64ce3e3a, - 0x2ae082b6, 0x4318358b, 0x33e5ab5e, 0x2b7f9c62, 0x759b74e4, 0x870dcedf, - 0x1a8f7cf0, 0x8b6a3728, 0xfd01b42e, 0x3d09e084, 0x7d4cd7c9, 0x2257d6e7, - 0x4117f5d6, 0xa18c5b9f, 0x6e87bc62, 0x504af187, 0x94bf22ae, 0xd582fc50, - 0x7d5de047, 0x1d843fee, 0x75c5fcf0, 0x3cff7429, 0xda1c6d6f, 0x4ccced47, - 0xf83360f4, 0xd046c653, 0x32e90d83, 0x8b387d06, 0xfc0e348c, 0xe226aa59, - 0xcbd70cbd, 0x60972835, 0x2616fbdd, 0x99ac3e91, 0x31acdeff, 0xc9f65700, - 0x65b2cf94, 0x9cd3cf29, 0xca3aeff4, 0x31fb7913, 0xf75df7ee, 0x9fbd2d50, - 0x67ca2194, 0xb283cfd1, 0xc2533d72, 0x0b952e70, 0x99bf142d, 0x133e417c, - 0x4851a7e9, 0x17fa3c7a, 0x6d735e3c, 0x0f79acaf, 0xb68f526d, 0x8f54603f, - 0xb7464676, 0xef3edeb6, 0x6153d3cd, 0xfca5f69e, 0xbf8bf6e1, 0x7070823b, - 0x24e28e95, 0x5064fbea, 0x4df14193, 0xf9819839, 0x8ccc1b9b, 0xbe6db9e4, - 0x60f28ad9, 0xc93c7a7f, 0x2cdbf6bf, 0xcbae8764, 0x3b438a6f, 0x556f34d9, - 0x8c23960a, 0x3b18adc1, 0x2dd5e6bd, 0x9127d937, 0x55f355bc, 0xec1cac82, - 0xdc8dbb81, 0xf73e09c8, 0xe51954f4, 0x9967cf25, 0xa796eaf4, 0xadd8f983, - 0xd4e1d695, 0xf9be4cb1, 0xba76f87e, 0xbeb896b7, 0x1da11a70, 0x7ca379e0, - 0x7b4115d7, 0x3f705a46, 0x9cb66d36, 0x6b7ca469, 0xf982324c, 0xccfd0b0d, - 0x658df588, 0x573e48e6, 0xf2fbe4f9, 0x87c63c7f, 0x0e595f87, 0x2bdc695c, - 0x3e417bf1, 0xfca19be7, 0xf210d369, 0x1f8ff554, 0x8bfce029, 0xf57a4b6c, - 0x7da6318c, 0xce22abf5, 0x9e46e567, 0x61bb32a7, 0xc3dd1d5a, 0xcc65bb04, - 0xdc517be7, 0x27a7b50b, 0x7b713dd2, 0xbde30b2e, 0x8e817041, 0xf8d27bc7, - 0xb98ded7f, 0x936a1f14, 0x3cc129fc, 0xb9f097cc, 0x01dafcf0, 0x7f308947, - 0xeb970e5b, 0xe2b7e42c, 0xb38c357d, 0xe0fd7238, 0x74b505ef, 0xa61ec8cc, - 0x789e85f8, 0x888c69cf, 0x1c5c63b7, 0xcfd117e3, 0xc2d5ee4d, 0xe1682e53, - 0xc0d0662a, 0x3c2d6635, 0x3785aad5, 0x7d3b7115, 0x3f5b5dba, 0x1d85a9c3, - 0x74e307d9, 0xc2dfcf3c, 0xf049e222, 0x447e5ef7, 0x68dd681c, 0x765f3efe, - 0xcb8a52f7, 0x78f0e5b6, 0x3695638f, 0x42c591ce, 0x732fe212, 0xd63c5469, - 0x863f66bd, 0xa30bed97, 0x5efc41e3, 0xa9a1f002, 0x7c8a3147, 0x9e68eaf0, - 0xd23dde87, 0xce08bdb7, 0x5f0c60b3, 0x4d1dabc7, 0xdac53f74, 0x5caf88d3, - 0xb0695f22, 0xe88a7cbe, 0xf90f1d40, 0x7fb11822, 0xf84887e4, 0x37be51a1, - 0x8be41e70, 0x2cfea460, 0xfbd036e9, 0xa1be62ab, 0xcfe543f8, 0xa28f7172, - 0x89f4dde6, 0x9bbcd4b1, 0x705f2255, 0x4ebe5457, 0x1936a39f, 0xaebee7fd, - 0xf8b1f195, 0x682ef910, 0xe5887ce2, 0x837f9106, 0xe22c187c, 0xa6f5887c, - 0x637856ef, 0x050b8bd9, 0x63bfdc5d, 0x224f86c9, 0x73acb7f6, 0xbe5e0685, - 0x910de1eb, 0xe3f751f9, 0xbf08303f, 0xed7e519e, 0x2f9db152, 0x2bcbff4f, - 0x48cd0ccd, 0xcf2807df, 0x319c1596, 0x5ea77bf2, 0x42eb9e23, 0xcc99ff61, - 0x2fd1f2b3, 0xf2e211db, 0x37889d6c, 0x33155b34, 0x3b9981c6, 0x50c71355, - 0x4b4d11e3, 0xd854b65c, 0x7c7f7247, 0x7ca56bc1, 0x14f9e1dc, 0xf1aa48df, - 0x32c6cedc, 0x9c6453d6, 0xdd62066b, 0xc056c18e, 0xd957f9e9, 0xc0c74133, - 0xf8174dbe, 0xb0fdc97b, 0x8f2467ec, 0xea68e42e, 0xa39c44db, 0x0b2dbf9f, - 0x8b3e70aa, 0xb0fb49db, 0x1e1aff31, 0xd1c6d417, 0xe73de24c, 0x343be3c1, - 0x7e226df5, 0xb5f1e572, 0x85d33971, 0x2fc621bc, 0x1adf1a8c, 0x7181fc73, - 0xabbdf1b5, 0x714f37b8, 0x2e3a184f, 0xe9cdd236, 0xdfdd9d69, 0x83317185, - 0x06667fe0, 0xf288993a, 0xe3e9ff80, 0xc1ae7e79, 0x198f8da1, 0xfa0baf30, - 0x98b8973f, 0x3efa8ae4, 0x0599fdb5, 0x27cbca12, 0xa4e8fdf0, 0x5a24f2c1, - 0xde44d88e, 0x811cb47c, 0xd37034f9, 0x36cf5cc3, 0xe50f8a4b, 0xfe7ef473, - 0x7587f17f, 0xc8bbe389, 0x778eceae, 0x0f632e9a, 0x638205b7, 0xf175b9f1, - 0x0778c5fe, 0x918ef77e, 0xe3944f69, 0xf88ceb7b, 0x298ec56c, 0xb60f3173, - 0x13ebf04d, 0xa7a23a69, 0xb7d3dbf4, 0x29e823ea, 0xa173e8dd, 0x13ae9c3d, - 0x87f85ff9, 0xd227b471, 0x318c6db7, 0xa9d76abf, 0xd601adb0, 0x6d8e7111, - 0x9fee9ec2, 0xadcc8eef, 0xd27188fa, 0x34b1be4d, 0xa3fe7f5f, 0x87e5af98, - 0xc459b7cd, 0x6cf9d4c3, 0x67f76a77, 0x7f69fa33, 0xd487a136, 0xfee336f9, - 0x15d5f062, 0x75fe13e7, 0x69777cff, 0xf93367f7, 0xf5367f69, 0x7cea1b3b, - 0x3e6c3f2d, 0x76cfe0bb, 0x3d97def1, 0x64377f9e, 0x9a23f7a8, 0xbdccf3fb, - 0xed2f9466, 0xe850bc6a, 0xfa5173bb, 0x3be849ae, 0x6973f9f5, 0x3dff14b9, - 0x7326f877, 0xfa873d2c, 0x933b098d, 0x09933b09, 0xd9e1133b, 0x0d57a735, - 0xbbfc7a07, 0x95cf371d, 0xbecfaf41, 0x1cf8f4ff, 0xf1d9df80, 0xe832b98b, - 0x9eafd9a9, 0x1e0b337e, 0xfbdbfe29, 0xe9f4fc38, 0x5bb4073e, 0xadcccf82, - 0x18693805, 0xbaeacfd7, 0xb97779d5, 0x7cb95db9, 0x6f8f1e75, 0x3d459c82, - 0x67e39cd6, 0xcafc7f18, 0x1f349bd1, 0xeecf2ffa, 0x03105f4d, 0x7cb96a2f, - 0x1e7f2175, 0x9889c0ad, 0xaf48c6cf, 0xc7bea8dd, 0x8f7da752, 0x23692925, - 0x2c7187d9, 0x96394564, 0xfbd0f660, 0x7316d797, 0x533370bd, 0xe15fb81a, - 0x1c79102c, 0x4dcbdef4, 0x6b5c62e5, 0xfdb12fe5, 0x09e79d66, 0x79ff77f4, - 0x68e1bcd2, 0x7379ab3e, 0x3bde06a3, 0xde7dfedd, 0xb1fd9e4f, 0x64e56dc4, - 0x36998f1e, 0x7bdfc9ca, 0xa22b888b, 0x3e143c5d, 0xff73753f, 0x1e9f007e, - 0x0f54cf8e, 0x37b5a7c7, 0xff9c0d69, 0xf4de94f2, 0xc34f89c7, 0x0835f131, - 0xfbf851af, 0x7ea99b93, 0x88ed1ea0, 0xc55be12b, 0xd85f9aab, 0xc80b392c, - 0x9a19675e, 0x14c660fc, 0x1e7bac67, 0x3d48cfa4, 0x197bb46b, 0x3486a3da, - 0xeff98dc5, 0xc7d17fcd, 0x1573dbcc, 0x525ef88b, 0x367de53c, 0x1fc91927, - 0x93349fdf, 0xb659fc61, 0xd4bc234c, 0x3e51d526, 0xeb187ea6, 0x3a357f44, - 0x7c9f5d0f, 0xe909e53b, 0x4061e86d, 0xecc79fd9, 0xe95f2331, 0x5d92563f, - 0x99570048, 0x295f2e87, 0x26753d0f, 0x324f43cf, 0xd85e313a, 0x998c689e, - 0x9badfe87, 0x71fb5dfb, 0x1fb8697f, 0x886eff23, 0xe56c97d8, 0x9f58eef7, - 0xab46f500, 0x5dfc518f, 0x615bffec, 0x4dfda907, 0xf9433f56, 0x4e2a37a0, - 0xa9f45fb4, 0x77e07f5c, 0xe231dc5b, 0x0dbb5f28, 0xa3fdfcf4, 0x99cf5cac, - 0xfb3eddb9, 0x27dfb137, 0x44962b28, 0xdd3624bc, 0x3737450d, 0x9dde78ea, - 0x2d7397ca, 0x9c07ca46, 0xf7d3b16b, 0x2102e66c, 0xf446a4f6, 0xfe56eebf, - 0xd8acb53e, 0x7b7e9e91, 0xfe5f94ed, 0x00b5e196, 0x66a7db97, 0xc2bde818, - 0x28f31253, 0x5df383a9, 0xa994debd, 0xea1bccb8, 0x7645af4f, 0xc8c3182c, - 0xc1757a4e, 0x4e95ad43, 0x8aea8ff2, 0x737d9e91, 0x770fa2a6, 0x77d8c363, - 0x04f2ffb1, 0xfbd5cf2e, 0xfc09e5a5, 0x646bde7d, 0xffec6cdf, 0x4917c555, - 0x725f48d5, 0x2bae0e6f, 0x33dd3fa2, 0x5b9ff445, 0xcffa813c, 0xf5ddafe6, - 0xce3977d2, 0xc8f99da5, 0xec7ce8c7, 0xf429ecb1, 0xbde458b7, 0xe81f9086, - 0xa3d64577, 0xce22c5bf, 0x6e505a53, 0x4f218eeb, 0x3ec332d4, 0xa042e46e, - 0xb18c8cd7, 0xcff5aa54, 0xa175f47a, 0x90fce718, 0xec1fe738, 0x6ac3b4f7, - 0x3df80e27, 0x843cefe0, 0xe172f8f8, 0xb0f1f4a9, 0xbf6a07a5, 0x6ec7bf26, - 0x16ceffec, 0xb00371f9, 0x2db3bef6, 0xdf8c5bd0, 0x87886019, 0x8bf91189, - 0x25f6bf62, 0xefd0526b, 0x20f4b381, 0xbc0476dd, 0x030d6b23, 0xe42cbfcf, - 0xd2160b08, 0x2eb106f3, 0x0ceb5a47, 0x2c38bb8c, 0x6073ca3a, 0x6791aacc, - 0xa6536a73, 0xbb0ba1a6, 0x2716299c, 0xe45df7fa, 0xfbe06417, 0x7c9f180d, - 0xf78636e7, 0x9d69595f, 0xfd75da12, 0xc6f788f3, 0xe17b8957, 0xed2d5f3e, - 0xefd6c327, 0x5ff23197, 0x507382d3, 0xc33df56e, 0x92f19457, 0xc691ddb6, - 0x5dee1ff3, 0x02721f18, 0xed2d67bd, 0xb04f4fc2, 0x30f8700c, 0xa9719fa6, - 0x7282d5d9, 0x140957e6, 0xe7b7d677, 0xfbc820b3, 0x1bfbecb0, 0xf9c877c2, - 0x6c4f2e90, 0xb65b9e16, 0xb9ec9e28, 0x0675a976, 0xe8f731f9, 0xd178ac58, - 0xa7ee62ce, 0x2b628ffc, 0x4fb5cfbf, 0x1f63f4e4, 0xb8e1723f, 0x77ffe7ab, - 0x49f99e84, 0x7fde93b2, 0x4da3ed52, 0x8e47f843, 0x5f213a91, 0xf8115e84, - 0x199f3333, 0x792f45f9, 0xc774b079, 0x96bdaf6b, 0x5b53e8ce, 0x841b4748, - 0x138ea3fd, 0xc6a21f9f, 0xf243c578, 0xb87ab252, 0xedfab0be, 0x75af3841, - 0xce63e9df, 0xfba085ff, 0xd90fd935, 0xd3ad7fb1, 0xfa32c6e7, 0x9c96983d, - 0x3e78dd7b, 0xe9fb332d, 0x96baec95, 0x61dfce33, 0x28f0563e, 0x9fd837cf, - 0xefc3685d, 0x1b0e5941, 0xe265d364, 0x27d046f1, 0x19d8cbce, 0xdeaf9146, - 0x99e78072, 0xbaca58b6, 0xc5a1af30, 0x6a465692, 0x56f3c2d8, 0xcb16fed5, - 0x1607d221, 0x5adfdf85, 0xb8487f50, 0x0947c04c, 0xe110ebae, 0x5077ed43, - 0x128b5dc8, 0x5a5ef866, 0xfd4ad29c, 0x83d7b2cc, 0x34e6ca79, 0x6644f746, - 0xe217f02b, 0xccc75f35, 0xbec9f431, 0x5a4fae62, 0xaabaca4a, 0x7e327d69, - 0xd8b58eb9, 0xe7a4eccb, 0x7cf0ef11, 0xcf968673, 0x577813bf, 0xf91669c7, - 0x4eae77b4, 0xc38ed609, 0x1bf79338, 0xcb16e7a4, 0xf5107302, 0xcbf8e25a, - 0x391a678e, 0xd7fb78d4, 0x43bef18a, 0x2c4fae79, 0x0678e2b3, 0x8d15f7c6, - 0x9c62e1f7, 0x7bfbd5ff, 0x47bd2cc0, 0x581d304d, 0x7deb1ed8, 0x13f3feac, - 0xcfd1f2f7, 0xbc7960fd, 0x02871b56, 0x091eec79, 0x72565afb, 0xd53550e6, - 0x0bd3f8f0, 0xfd519fc2, 0xf6317492, 0xbf7f120b, 0x2bc5283f, 0xe10c5df4, - 0x69c7a4a7, 0x3ef030f1, 0x6f873f2d, 0xde1e781a, 0x7c4c6937, 0xd7cb4e87, - 0x38ff1cdf, 0x059f9345, 0x7131ec7c, 0xde23c63f, 0x3888f5a7, 0x6f18c21d, - 0x049d17a0, 0x89c7f7ff, 0xc33f9c1b, 0x4099acef, 0x5c60eb8e, 0xfa27e1c9, - 0x5dba3936, 0xe239efc8, 0x78d10ffb, 0x2e48c9fe, 0x7a47a5af, 0x51af785c, - 0x119bd69b, 0x7c5fdf8b, 0xee0642f8, 0xfd19c5e7, 0xdf743b79, 0xe769e2f4, - 0xcbc402e6, 0x6ffbed11, 0x474df8ea, 0x22f8a7ce, 0xe5c0a5fd, 0x3a4b2fdf, - 0xd92571b3, 0xddb80b8d, 0x7dfa7ff8, 0x73e617b3, 0xa497753b, 0x084fcf95, - 0xfc141cb9, 0xd320bb60, 0x2aee43f7, 0x3a40adf2, 0x0bac936a, 0x3ce72e50, - 0x9af2f3cc, 0xb3d55b1e, 0xb47f0628, 0xd5fdf28c, 0xbabf08c8, 0xe491bd7c, - 0x3725b35e, 0x28f772f9, 0x9fbb9f43, 0xde7a94e4, 0x79988f55, 0xdb8f8abe, - 0x7bbee9d1, 0x3a260f29, 0x7ea8653f, 0x449d23d5, 0x137f6a0f, 0xc5f28f8e, - 0x15c52372, 0x818fa1ce, 0xb72b3b71, 0x59d7a233, 0xc098c889, 0x7d0663f1, - 0x49607499, 0x106b8e1c, 0x6a0bdcfe, 0xcca1a45c, 0xde7889ec, 0xb9995b70, - 0x9a4e823a, 0x8e0fcf19, 0x2337ff1e, 0xac22fb55, 0xa80c63b1, 0x94c6317f, - 0x97ed9f26, 0xf278643b, 0x0395b4fc, 0x0ee3cc7c, 0xc5a3e743, 0x232dbe71, - 0xf30dac7b, 0x5e0ec0d2, 0x0460b0d3, 0xf64db7e2, 0x3c0368bd, 0xa2687ef4, - 0x0bdfea3c, 0x7c16ed3e, 0x05f9d43a, 0xd23001d9, 0x1d9c7b18, 0x80e297c4, - 0x2327c64e, 0xebe7345f, 0xf63142ea, 0xf3ec5c79, 0x7878f632, 0xc7b3f7e4, - 0x1afe890f, 0x6ded1c7b, 0x46fdd44f, 0xb6768c24, 0x7e3d8627, 0x05f11242, - 0xc2742791, 0x0dd5dce0, 0x39313978, 0x5697be99, 0x5defc090, 0x527fa04e, - 0xabc87e06, 0x7ed1f3a7, 0x7ff52d99, 0x43f84917, 0x47f0608c, 0x62f905fe, - 0xb6bff30e, 0xe23e2248, 0x1b7835f7, 0x73e57e9f, 0xd19236de, 0xf9c036ba, - 0xdb46fde1, 0x6233f9c5, 0x8ea467dd, 0x5037fd52, 0x13ef1165, 0x889d3c33, - 0xf741acfb, 0x72f75174, 0x9fd36d78, 0xdc1fac77, 0xed7286ff, 0x8b86d9bd, - 0x5a622e3c, 0x4b8f42c2, 0x6daa9798, 0x10cea9bf, 0xb9a82f7d, 0x6bd9bb4f, - 0x7d0f5e88, 0xd621d417, 0x1f71dd9b, 0xcd4fbfdd, 0xa644f9e6, 0x04e28c65, - 0xa66df7d1, 0x3d1e5db1, 0x8c0dcfda, 0x38e8fdec, 0x52a9e639, 0xb181b0fc, - 0x79e5122d, 0x7973df6b, 0xfe73fea6, 0x3ad6947d, 0x760ec79c, 0xd1d3da10, - 0xf7a849ef, 0x51f7ea5a, 0xdfab3c55, 0x4dbf4a8f, 0xc163eb47, 0xc6aed429, - 0xb87bf1fd, 0xf911e955, 0x7f582be4, 0x2b7f7a7f, 0x9bdf7b18, 0xcf29eadb, - 0x7fbc7320, 0xb29a186c, 0xc8784614, 0x6fc8c85a, 0xf2683c00, 0xdbd94c09, - 0x16e79f69, 0x224c3633, 0x33da683c, 0xfdd3d340, 0x7e6d42c0, 0x0353ec01, - 0x57abfb47, 0xd94d53f2, 0xf39597f9, 0x9a638a57, 0x94e4bdc4, 0x97fbe251, - 0xed14aca5, 0x9edbf4a2, 0x0738f3a1, 0x5f7181e7, 0xdd629c74, 0xf1826e3b, - 0x77fc8fd1, 0xe2cd2fc1, 0xaefd5b6e, 0xf4c8f30f, 0xce549b1e, 0xf30d2cd7, - 0x12e97bf2, 0x8a6e7c46, 0x8fcc6667, 0x1e4c2a97, 0x04c9bbc4, 0x32596c30, - 0xd4067332, 0x7b3c45eb, 0x8464c48d, 0xf3315599, 0x5dfaa3f8, 0x577d10a1, - 0xd479a868, 0x20b22bef, 0x679d4e7f, 0x2ef577d0, 0x7bf93cf3, 0x6be7e8d6, - 0xcea99e29, 0x87fe143f, 0xbfde8efa, 0x8137bcd5, 0x441d53c7, 0xf4038daf, - 0x417cf04a, 0xca3cf88f, 0x66d5bb85, 0xfa29577b, 0x4c1e670f, 0x114a3650, - 0xd2ce08fb, 0x7e03eff3, 0xd7faf1bf, 0xbc927761, 0x1897dfef, 0x8beefbef, - 0xdae422fe, 0x09597c3a, 0x191a5ef3, 0xfba431e5, 0x29973faa, 0xa0f600ff, - 0xdf111391, 0xd6f18049, 0x1fefce3d, 0x3e77e336, 0xc0e7fef0, 0x13edfe40, - 0xd1f76c16, 0xbcd43677, 0x5da3cc5c, 0x3ef0325b, 0x837df472, 0x89c611bd, - 0x99b26f98, 0x9f401305, 0x0531f4a4, 0xb9ecf3bf, 0x03a65468, 0xa07d6c7e, - 0x93bf0150, 0xa5ee8999, 0x337ead2a, 0x0ae10eff, 0xef676916, 0xefa56e97, - 0x64bf86bd, 0x3e14bf94, 0xc3ee88cf, 0x70c4c39f, 0xddf8ff2e, 0xcbe47afb, - 0x7a5d7da9, 0xfb93f3d4, 0xf67fa4fc, 0xed3d4fd9, 0x9962e7e2, 0x751f9111, - 0xcf545b1d, 0x979f8ae9, 0x5f27ea2c, 0xfdf86a30, 0x46a35eda, 0x5b17c81e, - 0x65fd46be, 0x67aa89ea, 0xe3e33fd3, 0x2dde28f9, 0x53edb5db, 0xdbd03e44, - 0xc35fdf2a, 0xbc73a1ae, 0xcf331698, 0xd5dce06e, 0x71e26e73, 0x79c7c674, - 0x9ff7946e, 0xff404d46, 0xe87147c0, 0xd82fc464, 0xdd952917, 0x58798ecc, - 0x8e994ce5, 0xf3b2bd72, 0xe487a41d, 0x3c0f3cb3, 0x5ffdfc7a, 0x7e8595be, - 0x9dc99ec3, 0xed2f6859, 0x3d15f2f9, 0xd3d5578e, 0x193eb0cb, 0x58a41e4a, - 0x10aa784c, 0xcf5033b4, 0xf59144e3, 0xe74a9eb4, 0xcfe4e565, 0x871a4e50, - 0xd933df6e, 0x87e4c2c2, 0x3da02675, 0xfe7c7cc7, 0x57cab364, 0x70972fec, - 0x9f81845e, 0x52ea54f6, 0x7b9f616a, 0x6c15919e, 0x46f3d3dc, 0xe7bfce02, - 0x7acd39ec, 0xf322fe98, 0x5afbac45, 0x2b53ee71, 0x7efec97b, 0xf92bac4a, - 0xa1c52f6c, 0x30de9553, 0xc3d4dbea, 0x37fefa7a, 0xc8bcf0b3, 0x38a14c61, - 0xfc5eba9a, 0xd73e2a6e, 0x88de7282, 0x5632b3fb, 0x287eec28, 0x55832a33, - 0xcc9a8f98, 0x6b484a76, 0x417d2b53, 0xa5e4e7a4, 0xad939e9c, 0xbf18c3fe, - 0xa3af5e4f, 0x59f24538, 0xcbf406df, 0x0565cb92, 0xf84ae4c9, 0xb7f310ec, - 0xf9d4f98a, 0xa88cf5d5, 0x7ee84bf4, 0x62e3b324, 0x132aaefe, 0xcc5abf8e, - 0x59eb14ef, 0x2c3be8c5, 0x55ad67c9, 0x83272fe8, 0x33df419d, 0x9a79e2b8, - 0xb745f335, 0x99d94f27, 0xb1e0e745, 0xe30ad91e, 0x365b64a5, 0xceb94154, - 0x32ff23a1, 0x3c5187a9, 0x9d27a93d, 0x4f527de4, 0x8a2728a1, 0x0f4269fa, - 0xd4933970, 0xaf2d50f3, 0xa4d2a16f, 0x3f8717ca, 0xda98fb8c, 0x717cb8cb, - 0x98be4978, 0x517cb8d2, 0x9556b8e9, 0x325acc2b, 0x0ff7ea1f, 0x06b5acff, - 0x73f77b9e, 0xbbe5fefe, 0xbcbe5cd9, 0xfbf725fb, 0xd3bf694d, 0x42aa5ca3, - 0x4dfa05c3, 0x33edc0bb, 0xbaab1f95, 0x48113625, 0xe7839a63, 0xc8ba1f87, - 0xd9843b9f, 0x63af00d5, 0x9529c912, 0xdd056b6e, 0x83eab3ae, 0x81fed849, - 0x3477de89, 0x98e5ce39, 0x83fe1ec1, 0x7c41f7ae, 0x33f7f8ef, 0x415def7a, - 0x437e82f5, 0x9a2e494b, 0xe4396c84, 0x3e416058, 0xae487984, 0xe918721e, - 0x3a080ebc, 0xe9af673e, 0x5b3fc308, 0x69fcdfcc, 0xc1ffd43e, 0x9340eb9e, - 0x1e973d4c, 0x885f2f41, 0xe82b3bf3, 0x7bdd29a6, 0xfc04c953, 0xcd1e62fe, - 0x0dfece7b, 0xdcb27fbd, 0xc69f1ff6, 0x3aa72efa, 0x4f7cfa8e, 0xcf19a568, - 0x1f9bd0f5, 0xabb4409f, 0x7b235fe3, 0x7ee3e4ef, 0xd0f89a33, 0x78cf3b12, - 0xadf3fc90, 0x8b7f9688, 0xc80f864a, 0x91667abf, 0xe7121e79, 0x1e4259eb, - 0xddb8554d, 0xe7e56f5e, 0x5fb25f55, 0x8b8afea6, 0xd2af55f6, 0x5ae4f28d, - 0xf29b7fe4, 0x7d4bd124, 0xbd97a73e, 0x0a0f9e82, 0x63ecce7c, 0xed97e89d, - 0x196e982f, 0xe23ef80b, 0x1cff13d2, 0x52c6bb19, 0x291dcf06, 0x024bf095, - 0xd6c97a6c, 0xcf00a9b5, 0xa7a22452, 0x1dad92fa, 0x967fd04d, 0x03a94135, - 0xb3f9e8f8, 0x0eaf3416, 0x9784bc05, 0xe3f872e9, 0x1b9e1754, 0xcaccd3c7, - 0x4ffe8cb0, 0x8cbf63bd, 0xc46df6fa, 0x2ee311ab, 0x7567c11e, 0x6a571f04, - 0x238fb82c, 0x2f2126a5, 0x5e51e33d, 0xd537cace, 0x7c75a18f, 0x1a4c6c7d, - 0x506f77be, 0xa73c95f8, 0x7e82c9ff, 0x6b27ccea, 0xccdfa053, 0xd7196692, - 0x912cd47b, 0xd7da3cfc, 0xc793f944, 0xd2ac393b, 0x74073d2d, 0x5b6fbc79, - 0x6fb61273, 0xd53e4897, 0xe21d2f2b, 0xa7d38fea, 0x0b0f7e3a, 0x3077e1b6, - 0xb7af29cf, 0xb1f53e60, 0xcccf05be, 0x7f1c3c01, 0xb8c43f53, 0xc0ad1f4d, - 0x244cdf71, 0x356d9e3a, 0x8cb1f469, 0x5e84694e, 0xd36f1ead, 0x0d4af5c0, - 0x29cfd3c5, 0x7806e592, 0xad5df3de, 0xd191397b, 0xbd77da52, 0xe14c7be8, - 0xa1cc797c, 0xd63cbe23, 0x8a9cb8f7, 0xfb4659f0, 0xde769991, 0xb21a92fa, - 0x5b29ceaf, 0x826744f5, 0x54f1d50f, 0x4f8a3e3a, 0x9ced1e23, 0x6df68fff, - 0x1dbd20b3, 0xe323bf75, 0x89675d39, 0xa1d0571a, 0x5df0dfaa, 0xda9fa471, - 0x7ef3fb51, 0x3851eb86, 0xd7946bfe, 0xd57d238f, 0xa7a2643b, 0x9afecaa3, - 0x27bf8614, 0xffecd262, 0x9ac91dfe, 0xda7597f1, 0x5db47034, 0xdbfdcfb5, - 0x0ec4cba7, 0xd847a466, 0x3ec2f947, 0xe0771fd2, 0x1768aefa, 0xf7e8eb29, - 0x45d90649, 0x8a2edcf9, 0xbe5487b6, 0xb889d66e, 0x65c78eac, 0x58dff9a3, - 0xf1eec3fa, 0x8e492ad8, 0xc65bbfbc, 0xbe9073ba, 0x8612a3e6, 0x75d01ef1, - 0x15fc23a7, 0x078b6deb, 0xccad7c39, 0xbfbf6976, 0x3f37bfca, 0x1e77d4be, - 0x367495e5, 0x6561df4c, 0x07e518ab, 0x9e786be8, 0xad665e11, 0x258bd488, - 0x8d2df1fd, 0xd84ba45d, 0xac78859b, 0xf1e46b38, 0x38e89e8f, 0x851fea97, - 0xae2bf225, 0x93ea2e52, 0xe67bb8f9, 0x7f6778f0, 0x938f3379, 0xe5fc0915, - 0x5d691a94, 0xdcf7808a, 0xb59efb16, 0x41fa54a4, 0x07dfa2f9, 0xef8029df, - 0x61e690af, 0xb1553d9e, 0xca5291d7, 0x9777b5e3, 0xa14af278, 0x15f12a2c, - 0x3d5e2296, 0x77d35f60, 0x9f643dc5, 0x33bce3a9, 0xfd16e3ca, 0xbcc96146, - 0xee8f0edc, 0x6863ed07, 0xe3d8869c, 0x7a38fb40, 0xf6ec6e7e, 0xfc39b843, - 0x30fb237d, 0x0c0643d2, 0x52f2a664, 0x16e5e32a, 0x8846aefa, 0x1e0de7fb, - 0x9146f3d2, 0x103788af, 0xf4c7fc91, 0x1cbe34f5, 0x58f7419e, 0x8325d82d, - 0x7691f9fb, 0x6a84ac94, 0x6aade322, 0xdf94a8b9, 0x1528ce73, 0x604cf3ef, - 0xa8afc813, 0xea3cfcbc, 0xc3cd43f3, 0xc85765ec, 0x63f35e7b, 0xc3fa49d3, - 0xa55f27e4, 0x4a0e607d, 0x1f39df91, 0x4a89bf6a, 0xc28a1c94, 0x5cf350d3, - 0x22dc79ed, 0xd76af6e8, 0xcc7a655d, 0x2ed1f94e, 0x056b07ce, 0xd5dbf57d, - 0xbe3f1e3f, 0xfe861f3f, 0xfefbd9ca, 0x4a7ef893, 0x37a56842, 0x145e7ec6, - 0xe531f9fb, 0xce70d3c1, 0xfba18c1b, 0x0799ded1, 0xd20263a7, 0xf1f2c77b, - 0x9eb005f0, 0x2dfcc537, 0x6feb9596, 0x1c5b4785, 0x1ef998ba, 0x7a78fe6f, - 0xd93f0da2, 0xdce395ff, 0xa7206dfb, 0xd07d1e5b, 0x7581b0ac, 0x15d96b30, - 0xe347f9ce, 0x6d5d7513, 0x625e305b, 0xf7aabd4d, 0xaf5c5a14, 0x697de024, - 0x764de7ed, 0xb4460efc, 0x43c6a03d, 0xc6a5bd54, 0xa4bb544d, 0x1fe3c1c2, - 0x7bfced33, 0x69f6153d, 0xb20fdfa4, 0xaff21aae, 0x226d3b30, 0x19fd0ab1, - 0xe4fb5add, 0x4657bf3a, 0x9eda2a3b, 0x45334da8, 0x7abd07d9, 0x1715df94, - 0xfe54fdb5, 0xc454acf8, 0x17795451, 0xcf9a4765, 0xbb40499f, 0x670bedeb, - 0x8d142e28, 0x5c2eeb9f, 0xaebd9fde, 0x83f74f5d, 0xb7ad71d1, 0xfdd2e42f, - 0x1baf11a0, 0xcccad4c1, 0x808cc43f, 0x6b7b4c97, 0x18ec1195, 0xf82983a3, - 0x58fc36dd, 0x8d0dc633, 0x7c9c7817, 0xd7fb9d84, 0x2fc18b89, 0x95335185, - 0x78c17da0, 0xef48ce7c, 0xef5d99d3, 0x09bdbd91, 0x9e2186ea, 0xa6199ec7, - 0x5307118b, 0xc08a63cf, 0xb7e66eef, 0x4d81efe3, 0xf7f78bb1, 0x59db462e, - 0xa22d3cfc, 0x2d62e27f, 0x3ce22d3e, 0x435b8327, 0xd3ec79df, 0xe7116f3e, - 0xfb1a596b, 0x63a3ec1c, 0x7aa2439f, 0xc5b6130e, 0x596c39e1, 0x758a4dbc, - 0x2f8b990e, 0x845b0e7f, 0xefd2a95f, 0xb204acb4, 0xe8a6f7af, 0x7b41fbe8, - 0xcb59c313, 0xb2fdfe31, 0xaccfde99, 0xb4367110, 0x6b9f10a4, 0x84bf97b7, - 0xa371db71, 0x7b8e74f5, 0xbcffd125, 0x60feff8e, 0x1fea78cf, 0xf883b327, - 0xfb0780bb, 0x1bbbe9aa, 0xd3bbfcd1, 0x33dd007a, 0x3db9ceb6, 0x839c016b, - 0x9980fb25, 0xcf839bfb, 0x4a3fef07, 0x7b4bbe05, 0xa654b9f8, 0xbda3d49d, - 0xec66f25e, 0x8fe351f3, 0x3a9da47b, 0xaa362b20, 0x98fc8baf, 0xeca33b91, - 0x642db3e9, 0x47c65b67, 0x39c0f7d5, 0x9f8ebdd1, 0xa1d916ec, 0x87ebaf3d, - 0x114aa738, 0x7d7f3087, 0xfb65e28a, 0x7e714efa, 0x25c6d1e9, 0xfe5df727, - 0xe7135e9c, 0xa1c453b4, 0x00e22e7e, 0x7e7fc29d, 0xf2a4e023, 0xea9b80cd, - 0x04280adf, 0x0b940aef, 0x77cfc161, 0x47cb3e56, 0x84aaaf17, 0xcf47edfb, - 0x7f7dbf73, 0xbe83a862, 0x42de74ef, 0xbda417df, 0xdbbf144d, 0x2c727c07, - 0x1fbf49ce, 0x4cdb3478, 0xa5a3b3f1, 0x8a7bfbbf, 0xd16b7cbb, 0xc70bb8f1, - 0xeb4e7ab3, 0x6f184e70, 0xee8b855d, 0x47e036a5, 0xeeffa114, 0xffbe8932, - 0x040e1b34, 0x3a5445ef, 0xf169f537, 0x65ff0f59, 0x1ddff195, 0x617f42c8, - 0xa4e88b8c, 0x2273ef42, 0x4fba373e, 0x571e5f91, 0x871beed8, 0x7af18071, - 0x14fbbe26, 0x3bac4534, 0xe0426f0e, 0x44895379, 0x0a1a73df, 0x86e5d1bf, - 0xa32fae54, 0x3475ffeb, 0xdd1b83d7, 0x773ce8db, 0x50b2ba3b, 0xf913efaf, - 0x2964b310, 0x285fbf48, 0x1cb1dd77, 0x65915bf6, 0xc011bb1f, 0x6853a32d, - 0x4f4afbfd, 0xd8f81c53, 0x21c65785, 0x76b31dfd, 0x79ce305a, 0x53dfc9cc, - 0xf9951387, 0xf29db77b, 0xa4f2312d, 0xe958f2d5, 0x95fdfa22, 0xef7cfc7f, - 0xdf7cd1da, 0x0af5524c, 0xfb815b8c, 0xdef9424d, 0xc3f902b2, 0xfc83b998, - 0xaa73e8cc, 0x88b35f70, 0xfc64f3de, 0xb6bf4f7b, 0x3f782c86, 0x0267ed1c, - 0xff426c7d, 0x3d04f778, 0x5eadaf7d, 0xe782e7e6, 0x1fa4e788, 0x997e13a3, - 0x65667c76, 0xc0fa633e, 0xde1d6079, 0xf13ad0d7, 0xadefaa3e, 0xf86292bf, - 0xc9d683b5, 0xf9589efc, 0xcdcfd1b0, 0x9a20b276, 0x1615b386, 0x709fa176, - 0x99c69f30, 0xcce3e56d, 0x9b7c7112, 0x1759ffa0, 0x81df9475, 0xcf80d6f4, - 0x7927cc95, 0x50f5cc72, 0xb7ac1d57, 0x41c6ce1e, 0x569346fe, 0x5b39090e, - 0xf745525f, 0x07dcc7bd, 0xbfbea3c6, 0xe1e574be, 0x9fc22732, 0xb74154d4, - 0xd52fa529, 0x945a5d20, 0x4c2f8a2e, 0x5d74cb76, 0x36b97d78, 0x17afd14e, - 0xb44bf4a3, 0x928fa8be, 0x54f7113b, 0xf9c4434e, 0x4b9f72cf, 0xab83a488, - 0x2f1ccbc7, 0xd67baf7e, 0x1da71e05, 0xe9f7978c, 0x7803a573, 0xd8ef3e89, - 0xa73e8978, 0xeaad3c01, 0x8c1dcbaa, 0xbf6f155f, 0x1ac9792e, 0x8d1be799, - 0xaf8a1fb7, 0x4156d1e6, 0x579e5caf, 0x3b7dbe08, 0xb771443b, 0xeff94bb7, - 0xff731d4b, 0xb3bfe296, 0x0d63a858, 0xcbe045ca, 0xe8f94239, 0x344ce423, - 0xf4f8061e, 0xbf2e283f, 0x28b7f3fb, 0x21caaa2e, 0xea25f213, 0xea1fc113, - 0x1f9099b9, 0xf02f6f91, 0x2d5e87ef, 0x457ca87f, 0x383f21eb, 0x1fcc8fa4, - 0x5fc5dffc, 0x18cd717b, 0x52167617, 0xd1cab83c, 0xac7bc7a5, 0x3dd250c9, - 0xd27f8892, 0xf5919c3a, 0x591c6e3c, 0xa12f714f, 0xa6b8d4f7, 0xbb3ebeda, - 0x5518412b, 0xc24d47a4, 0xc4fd51de, 0x64538e7d, 0x54faaa7f, 0x57fef716, - 0x08f74fab, 0xfb543a7d, 0x79bb73de, 0x43cbe7dc, 0x1c800f3d, 0xa46f9c9f, - 0x0e4cb8ef, 0xa3dfcc3f, 0xfe498470, 0x9137746f, 0x69fb0c1f, 0xe604a346, - 0xf3e64475, 0xf3bee5a9, 0xefd60a6d, 0x0af4bb95, 0x16ff07f5, 0x568603e0, - 0x0d869dfa, 0x137d738f, 0xd651f457, 0xba83dee5, 0xe6994fb3, 0x61efc24a, - 0xdf835f6f, 0x8c2a0b01, 0xb598ebbe, 0xee458bb4, 0xdc31a5f7, 0xff9c9daf, - 0x68071dd6, 0x69ea1fdd, 0x035768dd, 0x9d964f9d, 0xcfe7050e, 0xfd23dbf6, - 0xf7d97dec, 0xb7009dda, 0x086c697c, 0xa3c37ad1, 0xecf3017e, 0x078d5733, - 0x73ed8d4b, 0x0bf5181f, 0x7346c7c0, 0xa3cc04d5, 0xdbdfb6ac, 0xdae51f3e, - 0x60265bd9, 0xbcec1bfc, 0x83b7d456, 0xcdb7dff6, 0x5d3bbf8c, 0xd69f78ed, - 0xabafa231, 0x5abfbf06, 0x48f7e0ed, 0x87bed1be, 0x7b404cc6, 0x73c1ec39, - 0x0c9f344f, 0x164cdd22, 0x2f1765eb, 0xbd41fc51, 0x9e73d997, 0xf8ff47d3, - 0x8fb80f40, 0x455cbf6b, 0x7db922f7, 0xa026f9ba, 0x3c7d75d5, 0xf1db0c7f, - 0xbf58e07b, 0x001d8628, 0x4be75cf3, 0xcaebf3c6, 0xde8637ba, 0x36fbedcd, - 0xf6e783e0, 0x44bc7064, 0xc31e6fb7, 0xafb882ed, 0x9272cfde, 0x7ff5c03d, - 0xf312c0b0, 0xa9b7553b, 0x3b1ad2fa, 0x552d450f, 0x23daa579, 0x21b35f80, - 0xc69bbf02, 0x7cfdff70, 0xf103a7a9, 0x7fe77df7, 0xe50b710a, 0xf6cf52f1, - 0xae91c331, 0x97ad5f04, 0xee01c663, 0xc5a3f31c, 0x13416e2b, 0x73beabef, - 0x86e96fe9, 0x7441dba6, 0xf8e95065, 0xffe3a221, 0xe27bf48b, 0x20efd0fb, - 0x14fe7479, 0xd347c3dd, 0x03bf4ab1, 0x9be6c874, 0x79e80692, 0x7ec1ba28, - 0xe806928b, 0xfb7ea87a, 0x931fbfce, 0xe9c607de, 0xabdd2cbd, 0xd059b7f4, - 0x540f7a91, 0xfd79ce29, 0xfeec8cd7, 0xf5463da3, 0x7e35c677, 0xca3fe811, - 0x72b0aea3, 0x37b47fb9, 0x3d19fb97, 0x9a9fba66, 0xbe295ee9, 0x235d0dbb, - 0xf211adc6, 0x75dba67e, 0xeaaf3959, 0xfddf550b, 0x43777c4f, 0x00800098, - 0x00000000, 0x00088b1f, 0x00000000, 0x7dedff00, 0xc754740b, 0xeebd6095, - 0x91a93fd7, 0x16883e9e, 0xc085a092, 0xeb404616, 0x7d3d05ff, 0xa71f3210, - 0x900b18c1, 0x04e08b4c, 0x60dd491b, 0x9e3d90e2, 0x123231a1, 0x1f62cd9f, - 0xbd6678cc, 0x8c030d39, 0xc077b19d, 0x0b611c56, 0x3837e2dc, 0x71c6ec4b, - 0x3c4c9c18, 0x6c0843c2, 0xc718d36c, 0xbc4ab243, 0x0f7adef7, 0x0b756bf5, - 0xcceb43db, 0x40e75764, 0xaabd5ea9, 0xfeeb75ba, 0x7ad3d56f, 0xcecc6333, - 0x53f817d8, 0x08acbc3d, 0x65cb191a, 0xfc05f3f4, 0xebf2e2db, 0xdf632b25, - 0xb4cbeeb9, 0x2c93f943, 0x1e670adf, 0x355faf63, 0xb188acca, 0xf6e3a9ae, - 0xfa87b3ea, 0x8c08758f, 0x127b4315, 0xef768674, 0x0077c154, 0x27d1311e, - 0x7d1e9d2e, 0xfd4c9fde, 0x8795cdae, 0x9d32fab3, 0xaf7a6863, 0x59b18d3e, - 0xca0e9bf8, 0x332d9320, 0x5aedcca0, 0xcca012c7, 0x9636f92c, 0xb12e624c, - 0xf2933184, 0x6bcae99e, 0x39f015df, 0xfe831993, 0x56f595eb, 0x0d5d7f30, - 0xcccf31c0, 0x3889f1bc, 0xc9c9d37a, 0x97cd5ed0, 0xd769e30a, 0xfe9fde1d, - 0xe4f329a5, 0x572e3630, 0xfbcdf5a0, 0xf04cf98c, 0xeb6e756b, 0xe7033602, - 0xd1cc7187, 0x1e60a9c7, 0x1d01e999, 0x2adb5ee5, 0xaa6b3fe8, 0xafe5e1c9, - 0x6cdef84b, 0x3e1bdfc6, 0x4ac67ace, 0xe2d9c686, 0x54fac809, 0x4c498ec6, - 0x6f5b2fe9, 0xf8e767c1, 0xb2857ac3, 0xcd6e533e, 0xebcbc455, 0x07e1c792, - 0x860f6778, 0xcb1d6f8d, 0x55633a58, 0x8b9f699f, 0x387d6d0e, 0x58fb305c, - 0x5f4fe5fa, 0x33467cc0, 0x5d398fc7, 0x5d79f847, 0x3e90fa32, 0xeed4ae2a, - 0x4b189362, 0xfc87ec96, 0x992adcf0, 0x36053e1d, 0x7e53f633, 0x0402b8af, - 0xc29fed04, 0x738014bf, 0x5aef6e9b, 0x16ddd027, 0xa21f4c6c, 0x4c0b2597, - 0x2e96381a, 0x9bd4d449, 0xea69c79a, 0xd44f57cb, 0xdb736fec, 0x43fa9add, - 0xea6a661b, 0x354a27ae, 0xd59d55f5, 0xef56f19a, 0xff69ab9c, 0x686feed6, - 0x7f9e6bea, 0x747f5350, 0xe911caff, 0x885f1a22, 0x89e991b6, 0xd23b0579, - 0x3a4d88bf, 0x9cc5cffc, 0xf7f7a3d3, 0x7ec27f21, 0xb7af6ebd, 0xd5fe82ad, - 0xe78d3f57, 0xc5f4b4fd, 0xf90072bc, 0x17d956a3, 0x402bc798, 0xad528d7b, - 0xf445be95, 0x4536635e, 0xee951be4, 0x11560ab6, 0xda66afc7, 0x6db0aafd, - 0x7e47aebd, 0xebd01a2e, 0x3759be61, 0x2157fcb5, 0xc706fc35, 0xc7afcc67, - 0xa5cb84f5, 0x9318eeff, 0x609e397a, 0xfc017fb5, 0x8cc9acc4, 0xa3c74795, - 0x5db7a74a, 0x6f5f6337, 0xeafccadd, 0xa0582b7a, 0xda3ee90e, 0xfc3b67ba, - 0x516b927a, 0x5ebe1dd6, 0x6feffe15, 0xef815f86, 0xf323ff5f, 0xdb1013ed, - 0xe6fc88b2, 0xcfeb5ddf, 0x02402bb5, 0x7a1527bc, 0x278291a8, 0x0e908b12, - 0x83650398, 0x51f99071, 0xc133d40e, 0x9652846f, 0x38af041c, 0x3034ef68, - 0x7e71eb2a, 0xa6861071, 0x35eb45d2, 0x288dca0e, 0xa92c456f, 0xebc79cee, - 0x875e068e, 0xd52ea8f7, 0x3ee7baf2, 0xea92875e, 0x43af275e, 0x5aefaa3f, - 0xb8cef58c, 0x014489c0, 0x5825beeb, 0x5a1e0e37, 0x05ff4bca, 0xe4994a81, - 0x5de83896, 0xec7ea7a7, 0x3707af22, 0xf2d0fa71, 0xf65e3183, 0x5f19b3f9, - 0x813f3c3d, 0xfdc24dbf, 0x006fd75c, 0x828ad43c, 0xd5ef0ec3, 0x3f87320c, - 0xe4d5f715, 0xe097d990, 0x3133a033, 0x8ccf886d, 0x4ab1982c, 0x0f793e20, - 0xedcaadf1, 0xe968e3e1, 0x5af51eab, 0xfc3bec01, 0xe51931be, 0xfaa7a730, - 0x2c12e0b2, 0xd013f9f1, 0xfc327b3e, 0x1f4e1e4b, 0x32a25c2a, 0x5fb5a55f, - 0x32b6aa8f, 0x59b72618, 0x8559d117, 0xd92c9d79, 0x716dcb87, 0x2e2fe550, - 0x56e1c22f, 0x1f39ade5, 0xfb1a6cf8, 0xb9967c3a, 0xaeb36a0a, 0xd9f0abbe, - 0x933e30ba, 0x8496f7ad, 0x321019f0, 0xb7d9f0d3, 0x276e9e89, 0x83094e5f, - 0x4f182675, 0x23e80cf6, 0xc05499ca, 0x3e244243, 0xb21bfb9b, 0x97c8a21f, - 0x5817f037, 0x987e6e67, 0x5cf4519c, 0xfee7aab5, 0xdda2b3a8, 0x117a67e2, - 0xc87c70cb, 0xd2313b2c, 0xbe3cb573, 0x6bba0609, 0x90f80ea8, 0x63be810f, - 0x06dc151f, 0xcec99bcf, 0x805ab862, 0x31e2aac7, 0x71ad6e8c, 0xec909d2f, - 0xecf505bc, 0x4e6e8518, 0xdf11a766, 0xc7bd76c3, 0xb59de442, 0x01f1cbe8, - 0xc70937cd, 0xbf226673, 0xc6db40d5, 0x33fde182, 0x99f00fb1, 0x3e7cc835, - 0x08eacf78, 0x46af5808, 0xf48d9efd, 0xfe51eacf, 0xe8095f57, 0xe5a5ea25, - 0x00745b97, 0xa4013fbf, 0x517c8b57, 0x642e9c30, 0x7ee3d3e6, 0xaffdd57c, - 0x90341fb6, 0xffdb0ebc, 0xcfb0419a, 0xd5394e00, 0x1afa20e4, 0xc8cf6464, - 0x48c7c14e, 0xbc21acbe, 0xade3f6a8, 0x176826f6, 0x622e91e8, 0xf640b37b, - 0xb36ca7d0, 0xf305f381, 0x867a55fa, 0x30afcbe7, 0x34ed1139, 0x7ed4f3cb, - 0xfa23136c, 0x3c97b6a8, 0xb8476755, 0x44cc7606, 0x0abd24b8, 0xc7153f97, - 0x70e260bd, 0x7f08daf9, 0xe4fe0ad5, 0x43331d41, 0x694fbfbb, 0xff5fa30f, - 0xfcd3b720, 0x702bc44f, 0x43f0c8dd, 0x4ed007bf, 0xe5689306, 0x43ff03dd, - 0x69dcf784, 0x01df3f77, 0xf028ae5d, 0x6e856ffc, 0x5124da3f, 0xf5cd3eb9, - 0xc7a07cfd, 0x7c6e917f, 0x0fc866e2, 0xd5f74439, 0x9027cff6, 0xd9f1521e, - 0x10f48637, 0xe8f84dc2, 0xdb8344b3, 0x387510aa, 0xe5bf0abc, 0x2a57c88c, - 0x577c2a9c, 0x0bab7a7c, 0xe7b37bc6, 0xf61c135f, 0x454bf821, 0xfb847ee7, - 0x674fc1cd, 0x92ef88b8, 0x34667635, 0xfc5266f9, 0x964ca488, 0x3ea2a62b, - 0x85cc7388, 0x74cb8c75, 0x364cbad1, 0x02fd1da3, 0xf393274b, 0x82734860, - 0xf7f08ccf, 0xd2ec37a7, 0xa9d6fb43, 0xfbc13322, 0x36bcb35b, 0x09fea75a, - 0x9399eb86, 0xd60361e9, 0x6577f3e8, 0x9c11293e, 0xbf475083, 0xa2f1c6c7, - 0xf8f4689f, 0xc75fb9e0, 0xc10a1cd6, 0xee02c1cb, 0xe7cd9d8f, 0x1e17dae5, - 0x842976d9, 0xad0fda3f, 0xbdddd4d3, 0x2976dbdf, 0x106ede54, 0x3697dc44, - 0xd9db8e85, 0x5ff404c0, 0xe13b455a, 0x903743a1, 0x2c6bf586, 0xae0a7e78, - 0x008fe70f, 0x5be73fff, 0xd2ff3d62, 0x8ff650a9, 0xff69fee1, 0x0df91f24, - 0x2b1ffcea, 0x5f38ffeb, 0xa6387317, 0xb3ba1e01, 0x9f70c5bf, 0x3f7c6c6a, - 0x7a72504d, 0xf54372e6, 0x739e8677, 0x3ea55179, 0x73de3a0f, 0x1ce91d12, - 0x994c76a8, 0x7de911f6, 0x71bbd227, 0x48b5bea8, 0xf08be8d7, 0x220573fe, - 0x16c07bc1, 0xa15b3db9, 0x5c139d97, 0xdfe8d9dd, 0x6c73ab3f, 0xcbce2586, - 0xe51e3adc, 0x7adb56fd, 0xe2e653a2, 0x38c058eb, 0xf4cbcebf, 0xd1e81978, - 0x82b7fe79, 0x8dd62a42, 0xf886c2cc, 0xe70bf557, 0x01d13e89, 0xd7f2bbfd, - 0x5ddd7199, 0x1c66f5b6, 0x82d684cf, 0xea3c386e, 0xe6ec0fba, 0xf4cbcef3, - 0xb2e9e089, 0xc57bb9b9, 0xa33fa801, 0xee5e7bac, 0x6aaf6a3a, 0x09149ff4, - 0x4367e07f, 0xf568e8dd, 0x87263ce2, 0x3ac246bd, 0xb2c66c73, 0xec89784f, - 0x0dbf5513, 0x9dad4fe9, 0x91bafa72, 0x15d763e4, 0xf244cf9d, 0x07305e53, - 0xbcaf9fde, 0x7b720d6d, 0xa3bf6bbe, 0x1cf7c45f, 0xf3e3f902, 0x764dbf73, - 0x2e77359d, 0x56b3e7b7, 0x98549179, 0x3fa1f04f, 0x5bc54f31, 0x195f569e, - 0xa0b7171d, 0xd4de30fa, 0x2c59d1ea, 0x2abe90c0, 0x70f3fcc2, 0x40bb3b7d, - 0x5972d7b1, 0x2d2bda31, 0xc863df26, 0x420d960f, 0xe2a1c23a, 0x8e814575, - 0x7c8620e8, 0x942667b0, 0xb465d95d, 0xd3ccfaaf, 0x5f980417, 0x4366df17, - 0x8cdbd0be, 0xb31bc47e, 0xa80d1f8a, 0xffc24df3, 0xb7b22533, 0x2f848eb0, - 0xfc79397d, 0x86c7966e, 0xb032eceb, 0xa7f248a6, 0xfdf380b6, 0x927e5907, - 0x8ddad10f, 0x7bd2041b, 0x66377caa, 0xc237d932, 0x5c8cdb78, 0xd25f80ce, - 0x3ebf402b, 0xffa017a4, 0xf7b35a17, 0x7ba205e9, 0xadf1e519, 0x12efb152, - 0xfe1fb90b, 0xca898166, 0x547eca93, 0xc336717f, 0xaffc8235, 0x8430f2aa, - 0xc7ca94df, 0xf1f26533, 0x732f224c, 0x2e3f7195, 0x5cdc7ce2, 0x5fb97b14, - 0xfb7a339a, 0x8d7a4b1c, 0x90285287, 0x98dd79e8, 0xc52e4987, 0xa3396f12, - 0x5da33788, 0xa7073fa1, 0x73fdb513, 0xaaffde45, 0xb274e620, 0xe51472b4, - 0xa4e92c41, 0xde83cfe2, 0x79ff97cf, 0x68da47ec, 0x99a3e3ae, 0xe042d4f2, - 0x2e9cbf93, 0x96e583df, 0xbbdb23d7, 0x772f63f3, 0x72801ed3, 0x37df04f1, - 0x79b3e923, 0xfb97b185, 0x48bed14b, 0xf845f6e1, 0x3d15cbfc, 0xd2794b14, - 0x11b36504, 0xff011fd6, 0xfcc28e8f, 0xef5073cb, 0xe5817b72, 0x0fa4b99e, - 0x67e1dfb1, 0x3ec42eb2, 0x1c147b06, 0x0543b441, 0xeddd9239, 0x2d7efd8d, - 0x643f487d, 0x5c61ccaf, 0x2ff3a81f, 0x7af8e12c, 0xb0e0147a, 0x25eade00, - 0xc29baf6e, 0xbfcb50e0, 0x7dbd8c2d, 0xe043e92a, 0x1fbb0548, 0x444205cb, - 0xd0a7af7b, 0x1a7e7318, 0xe2d9780b, 0xe4918d60, 0xefd8c9c9, 0xca0d9a4b, - 0xd3cee9aa, 0x4b96d728, 0x5c60e787, 0x1ff8fbf9, 0x79d21be6, 0xc1a561be, - 0xaeff45e5, 0xbc3bb24b, 0xac478c76, 0x7ccafaa2, 0x52af43bb, 0x94dfb63e, - 0x6c05db7c, 0xe57d51d7, 0xda1f24ef, 0xd617dfc3, 0xf1c6c99d, 0xfb1deb36, - 0x959dc618, 0xe78d837c, 0x9e36ac1b, 0x3c6d109f, 0x29b560ef, 0xcf1b0779, - 0x4a6d583b, 0xf3c6c1de, 0x929b560e, 0xbcf1b077, 0xe4a6d583, 0xef3c6c1d, - 0x7929b560, 0x3bcf1b07, 0xde6a6d58, 0x1538d3c1, 0x9e3691e3, 0x78dab077, - 0xe36ac1de, 0x97980779, 0x3c6c1de7, 0xf17000ef, 0x722d83bc, 0x943ac1de, - 0xf1ff2077, 0x67a49618, 0x547f5fb8, 0x7b06cfa9, 0x786334dd, 0xe76ab55e, - 0x17182dfe, 0xfc7209ab, 0x5e783955, 0x77b414d9, 0x457e300a, 0x04dfb066, - 0x114565fe, 0xb0d5f0c3, 0x13f3c3f9, 0xbde7d9dd, 0xb0a3fa02, 0x03bc2997, - 0x18ea29e5, 0xfe7c3f7f, 0x3b577161, 0x65d6e78f, 0x3bf08b7e, 0x78482cbb, - 0x8718e7c3, 0x13f253ad, 0xffad56b5, 0xb2e67f2a, 0x995f71f9, 0xf80899d4, - 0xbb6d4590, 0x8c2ff988, 0xd7f15ebb, 0x6ab7dc61, 0x15771b50, 0xb8d41b33, - 0x844bcf3c, 0xe1df39c1, 0x6b045f1c, 0x2a7f016a, 0xc1cfe601, 0x53ae15a4, - 0xa45e7c12, 0x881bddb7, 0x453bbcbe, 0xaa6814c7, 0x9e606404, 0x6a2012a5, - 0xc654d286, 0xf24cd2ac, 0xfe9d389b, 0xf1bdd4d7, 0x030f28d9, 0x6c04467a, - 0xf9a83c23, 0xbf580485, 0x2bfc8334, 0x332aeff2, 0x3a47bffd, 0xcc82eb50, - 0x5d8238f3, 0x2f80cd62, 0x5c266ef9, 0xceab9336, 0x45eb6f90, 0x73c335e6, - 0x9b37e941, 0x2d4e2905, 0x76f28933, 0x6541ccb5, 0x695774d1, 0xcea3f011, - 0x7ae175ec, 0x0966ecaa, 0xee3d85f9, 0xf148db3c, 0x32e97ae4, 0xf60049e0, - 0x48da62f8, 0x2ec88a76, 0x451cf8ab, 0x2f1f48bb, 0xadc92278, 0x61ebd88a, - 0x0a2a83b2, 0x2dc7c919, 0x7cfcb22c, 0xcfcb84ac, 0xdf5d4b37, 0xfbd73c44, - 0x878fd516, 0xd0be8f2e, 0x6d9b794a, 0x5bc2f161, 0x6f628afd, 0x90e72447, - 0xe901b93d, 0x8f04f17a, 0x1688e10d, 0xf62a78c7, 0x1b49ecf0, 0x767baec1, - 0xd45aec14, 0x2aecb743, 0xfa9399fb, 0xb1ca3b50, 0xd0ba4f0e, 0x9092baef, - 0xc3ddaa38, 0x8d67143c, 0x6979af1c, 0x9920e214, 0xfe13bfa8, 0xea639d0b, - 0x87fb023a, 0x54bcfbe5, 0x428ef8e1, 0x634be387, 0xa0d317cf, 0x613e27d4, - 0x771b8d0b, 0x970e0459, 0xf5c0d041, 0xfdff62b9, 0x78f624a0, 0x7d72812a, - 0xf22efca9, 0xf974d561, 0x7caa5867, 0xbae1df3b, 0x2d29fc40, 0xf9024faa, - 0x767f66bc, 0x0689ea01, 0x2ae35edb, 0x52d5f780, 0x3a22fdf9, 0x5b1ff46f, - 0x1eb16e1e, 0xf7bc478f, 0xa3cb22b9, 0xc50911bb, 0x28de4fe4, 0x67e4fee2, - 0xfe288784, 0x638bafe4, 0xea7b2fbe, 0xc9fc8673, 0x5b1ffe70, 0x639de3cc, - 0x068e0147, 0xf1465728, 0xc28ca6eb, 0xbf5a8dfc, 0x443ebf6e, 0x854110ce, - 0xdc6c69e6, 0xfc1163af, 0xba35973d, 0x147b37bf, 0xf310b1d6, 0xf591b571, - 0x31c57dda, 0x7e96aff7, 0x3307ca03, 0xd0a9fd5b, 0x6f30bcc4, 0xb2be50da, - 0x0fafd5c9, 0x383f738d, 0xe537e0e1, 0xb37e7008, 0xf272e638, 0xf91e9c7c, - 0xe119bd75, 0x7e066ae9, 0x255fb08d, 0x9bffdc25, 0x9611e13b, 0x3a637688, - 0xe411f743, 0x3637cf09, 0x83637e29, 0x2a767fa2, 0x2c53d472, 0xe52ce952, - 0xe851b9f5, 0xfbcad7fa, 0xb69c4a8d, 0x2bf26251, 0xec7ff491, 0x38fce6e9, - 0x71c6e728, 0xf30def38, 0xf453dfcf, 0xd3d89ec4, 0xa00c9ecf, 0x91b5b993, - 0xf63075f1, 0x0274b174, 0xf6d4bfcc, 0xf8901cf4, 0x0d9b2fb0, 0x2e9c5f94, - 0xef0c58bf, 0x57c28b6d, 0x69782b9f, 0xb03a3e86, 0x34a05bfb, 0x9010f942, - 0xfa405481, 0x6fec55ed, 0x14308e01, 0xf1de0420, 0x3af4e7e8, 0xce7c1ee4, - 0x7fe46d5c, 0xca1bc884, 0x3999569f, 0x83a774df, 0x0efe88ff, 0x9339d333, - 0x9fcf20ae, 0xfcf26576, 0x6a3c3868, 0x456ff4fe, 0x71cf198f, 0xc4166577, - 0xebddf285, 0x6f26989b, 0xe78575dc, 0x8a4fc185, 0xc949fad3, 0x8f8527e4, - 0x74b9909f, 0x247fa85e, 0x021fdcc8, 0x5c50267f, 0xa917e43c, 0x7c98cffe, - 0x7ff15cf9, 0xcd1dfd02, 0x4947119f, 0x07308b0f, 0x74ddff3e, 0x8f10dff9, - 0x1fd3d023, 0x9fd3d0a3, 0x347fdfb0, 0x11cc627a, 0xf0cc68b7, 0x1eb2bb71, - 0x708eb5b7, 0xd321203f, 0x54ce9119, 0x9b7a02fa, 0xe8763250, 0xb4f3217d, - 0x4b136f4a, 0xbd3ebf8a, 0xf0bec05d, 0xafe1acef, 0xd149d6ec, 0x7ab59dfb, - 0xfa0f28cc, 0xf19bd732, 0x99d4c49e, 0x6bce072e, 0x006c9911, 0x3e5cbb38, - 0x007b9e33, 0x64bf2f3b, 0xcdc1bc84, 0x7e3f2e22, 0xdcffecad, 0x2aff9c09, - 0x7dbe0b96, 0x6c4d7fc0, 0x4df70197, 0x4958ff7d, 0x7b88fdec, 0x35ee4872, - 0xf7208c96, 0xe2f8565e, 0x2b5f0573, 0xe729d6da, 0xfb445899, 0xfdec5567, - 0x942b348c, 0x45d75273, 0x745be3a4, 0x2285e787, 0xe21467ac, 0xe4c7e7e0, - 0xcd4c3ce0, 0xfc406d2b, 0xf1c4563e, 0x7dfecd17, 0xb3fc146a, 0x4ad70089, - 0xfd0199f6, 0xc7ff5969, 0x11e748ac, 0x39d9158e, 0x0390069c, 0x5995df80, - 0xfc31b7ba, 0xb5a495d9, 0x67f7d487, 0x67aefe2b, 0x5267e414, 0xf1c3ce0e, - 0x4c0e7e1a, 0x3ec5cf2d, 0x88b4b01e, 0x80ffb9fb, 0x73fc0efc, 0xe358a4a8, - 0x64a8fee7, 0xb5f73f64, 0x1adc8f7f, 0xcba8e850, 0x7d9ed911, 0x40fbf621, - 0xdd60e0e7, 0xb9157cef, 0xaa6f6e11, 0xdbd89ee5, 0x7a59697b, 0xd1c3879c, - 0x24e7b4c8, 0x28dff16e, 0x8f5d2de0, 0x77e968f3, 0x5ffae325, 0x1a58c385, - 0xe78c73f3, 0xff31e867, 0x7d79f9c3, 0x94be2ba9, 0x198f36ec, 0x07d837f5, - 0xb95f6714, 0xcd1f2539, 0x6b67d82a, 0x93be96a9, 0xefa6474a, 0x403bd2e4, - 0xfc9caadf, 0x534c6117, 0xa899bca8, 0xa5699bc8, 0x29afdfb1, 0x8e48af18, - 0x632baf2c, 0x73dbe71f, 0x79744e77, 0xfb379eac, 0x4f1b4147, 0x8f25bd6e, - 0x69474e63, 0x7921faa9, 0x7087eaac, 0x5e868d3c, 0x0bd10c48, 0xcce4510d, - 0x3631c068, 0x9db51f04, 0x98afe502, 0xc0a6f98d, 0x39d89daf, 0x96c7dee4, - 0x4f138851, 0xc87f8d0f, 0xa047af60, 0xb1a5dde3, 0xbca37fcf, 0xdb7c37e9, - 0x47f9d236, 0x28c5d5a3, 0x3173623f, 0xb19fec3b, 0xf6f295b3, 0x94ad05c6, - 0x029d6687, 0xf498fde5, 0xab79f92e, 0x30a7de6c, 0x9e5c367d, 0x5e398d6c, - 0x97d8728b, 0x28c537f6, 0xf8ebcd7e, 0x37f93a4a, 0x153ca3af, 0xb347ee24, - 0xf74ecc0d, 0xb97cafa4, 0x202f58fb, 0x9a2f3012, 0x763ee8c4, 0x7ac7e1a7, - 0x051b47cc, 0xe65cfe3e, 0x974ff9e7, 0xf0a3fc77, 0x31a0e59e, 0x7f543b7f, - 0xfb4d9a51, 0xcfe569de, 0xf39bf6bb, 0x9ea5849f, 0xc19e15b6, 0xa753e1f3, - 0xec1c5327, 0x6b8f03c5, 0xbc5aecec, 0xdf7e80c7, 0x7e861e0b, 0x35d329a2, - 0x9c3b2471, 0xae927f31, 0xa89a508c, 0xfa5e7a94, 0xf86d9d05, 0xf7f73bfb, - 0xbd67e848, 0x724cc078, 0x9e81ea7f, 0xe32155f8, 0x3e719627, 0xfe3d06b6, - 0x35af0019, 0x093273d3, 0xf92b1def, 0xce799173, 0x632bc2d4, 0x0f9d00a4, - 0x6b5791df, 0x2ebba50e, 0x794cd6a9, 0x639d5ce4, 0xfceb1d8a, 0xf4fc431c, - 0x4082fdda, 0x112edd7e, 0xe19aef50, 0xec7a86ba, 0xc3eb890d, 0x496b53a9, - 0xe72a75ab, 0x2de4761e, 0xc7ef8039, 0xf1a7af4f, 0x7b64593b, 0xe5c658cc, - 0x99068bf0, 0x80f17de6, 0x55c8e748, 0x7c69debc, 0x0f30cbd6, 0xa6dea3e0, - 0xa7d87ba7, 0xe5114e8d, 0x8134e9d0, 0xdf2d82ed, 0xee8578e9, 0x0288ec99, - 0xb94a2fef, 0xa96cca9f, 0xf7a77f44, 0x748f2e77, 0xbfa55f7e, 0xa96433c9, - 0x49c0ed0c, 0xff94269e, 0x36e4b6cc, 0xdf24f17c, 0xe68743bf, 0xcffc03cf, - 0x227fc17d, 0x6b21f70e, 0xf75c78cf, 0x6a76a507, 0x1f0f45bf, 0xb0f442bd, - 0xe3efc8c5, 0x8e717578, 0x858eb003, 0xcf1101d6, 0x8352184f, 0x2a6de794, - 0x8b74f2e3, 0x81630fca, 0x7d3de01f, 0xc507bf06, 0xcea9da26, 0x84270726, - 0x559ea3de, 0x0597aca6, 0xc2f9f132, 0xd83777f8, 0xf6158c1d, 0xb08b37a6, - 0xef8985fe, 0x7a86c86e, 0x5e78ef49, 0xb3f778cf, 0xb2b1896c, 0x9f5e0cde, - 0x9367eef6, 0x9bd15ea0, 0x3095ebc9, 0x9bb078d4, 0xbd9ab37a, 0xa4be3879, - 0x0f15bf19, 0xfd7f1472, 0x45d26f52, 0x28355f8c, 0x031f87eb, 0xfbece3ce, - 0xe2ef3a47, 0x78fd5b34, 0x86c9832e, 0x3419f8b0, 0x6077dc85, 0xff2409a9, - 0xf30bfbd4, 0xf63f7f45, 0x84fd99d7, 0x2759bbdf, 0xad8073d9, 0x7e145fdd, - 0x5c2e7b79, 0xc8d96dee, 0x8c4e785c, 0xef0966b1, 0xd64c0833, 0x78e3c17d, - 0x855f9c4e, 0x187f9d47, 0xc8b5b05c, 0x3d70439f, 0x70a8e34f, 0x7937cb5d, - 0x6b7ade51, 0x0427ae59, 0xe084d74f, 0x456c180f, 0x0f1dacda, 0x1b5d3ee1, - 0x40209c13, 0x1b7cb93d, 0xb1b5dbed, 0x8e081fc1, 0xef81ba90, 0x096f5b63, - 0x289763ed, 0x9b9d21b7, 0x216ed68c, 0xb8eeb191, 0xe60c1984, 0xe5d631d9, - 0x406e7bc5, 0xd8ef7477, 0x1c74659b, 0x8beb3800, 0xc7a1f9b4, 0x83fb3a15, - 0x98e60f22, 0x01ce7976, 0x047bba5d, 0xdc70f786, 0xa88c3783, 0x5df616ff, - 0xa4be6234, 0x11a2e7a3, 0xeb03bee9, 0xf3c74e30, 0x6ff988c6, 0xbd5eb963, - 0x91e74a2f, 0x4f1c4bd6, 0x7aeeb2a7, 0xe9e0152a, 0xbdd02d58, 0x9247f5bc, - 0x7d7d60e6, 0xb192ae2b, 0xe78755e5, 0x38b4b920, 0x72c29ffb, 0x95381b25, - 0xccb4240a, 0x10f667a5, 0x4d62b93d, 0xe887b33c, 0x8a4f16c9, 0x1772bea6, - 0x280cceec, 0xfa686637, 0xeafee531, 0x83f43632, 0x949a98e7, 0xdb665c7d, - 0xeeb8c019, 0x3bc19732, 0xc2de3210, 0x3262cdbe, 0x1c11edc2, 0xcbd28d74, - 0xe0ad3fcf, 0x1c52842b, 0xf7cf1f7a, 0xefc40af4, 0xba7a6d1d, 0xcbdcd3c7, - 0x35e6aeed, 0x202ecf82, 0x0dbdf81e, 0xed40af77, 0xeba7deee, 0x1bef1193, - 0x47000f00, 0x7d84f8da, 0x9347112c, 0x4ad5dce9, 0xdf775605, 0xb38e0339, - 0xdd023be2, 0x9bbf5567, 0xb2bfc2a0, 0x91ce91a9, 0xa45e7c01, 0x4d9d754f, - 0x5ce947f6, 0x9789cad5, 0x6187a80d, 0x3406977d, 0x5bd6d4f8, 0xcafada3c, - 0xd1fada8d, 0xf29ee532, 0xf90d3634, 0x209978e9, 0xb52439e2, 0xf9d651fe, - 0xe75ef1b7, 0x0a79d16e, 0xe8cdb3e9, 0x7efa819f, 0xbaa2e8b7, 0x3bcf0eda, - 0xf89df118, 0xb1f100e1, 0xc5b9fc40, 0xf8354b20, 0x8176973d, 0xb60576e8, - 0x0f67f3ab, 0xfd754fbd, 0x554dfaf0, 0x1b9c5aee, 0x4730bbe8, 0x90ed0905, - 0x9316517a, 0x222f88f3, 0xbdf9779e, 0xa36f07c2, 0xeeb803f6, 0x7d852242, - 0x44feebba, 0xbde6179f, 0x3a56cdeb, 0x215776e7, 0xf91d81d0, 0xd6e7475e, - 0x2f79e3e6, 0x7903ef28, 0x2ef28168, 0x9226a1fd, 0x128d33ef, 0x9ce577c9, - 0xe42f2a97, 0xb6e7b517, 0x219e67e6, 0xe7beeb3b, 0xb579d276, 0xc17239c9, - 0x2d0fa8d3, 0x471dfe7c, 0x1866df04, 0x34ef23a7, 0x3271cfc9, 0x61d72f3f, - 0x2f68e453, 0xfd7551c8, 0x50e3bfb0, 0x692261ae, 0x9bcd1e41, 0x5da9566e, - 0xf8283926, 0xffe8756b, 0xdde6538e, 0x75a76d5f, 0x487a3da7, 0x316775c0, - 0xe60166ef, 0x7c3a82bb, 0x55f950ec, 0xf8b5d7ed, 0x565de80b, 0x5b63b5af, - 0x65e3d745, 0x6dbb5f30, 0x2dcfc8c0, 0x1fa88d06, 0xdef8e0ee, 0xf2c3e348, - 0x50ee7475, 0x4730fbe2, 0x7680983f, 0x39a3face, 0xf608d8e3, 0xd3acde8d, - 0x148311c8, 0xf33791a7, 0x67f2b573, 0x772b43a1, 0xa39651be, 0x4f245f69, - 0xdfdfb4d3, 0x3fa9a858, 0xbcd4ace0, 0x9d5360ff, 0xcdb26ea6, 0xb16fbcd3, - 0xe3d4d62f, 0xde6b9773, 0xa558e31f, 0xf5bd3769, 0xed0126a3, 0xc077b371, - 0x06e87805, 0x1e4b28de, 0x12d323d2, 0xe32865e0, 0x2c562d0a, 0x744df3bb, - 0x3c7bb64e, 0xec4497e8, 0x773a1dff, 0xc97c4e69, 0xdfe5035c, 0xfc5abe0b, - 0xc9a00e7e, 0x3ddbf685, 0xf0e3684f, 0x5f38abc7, 0xb94365a9, 0x280ac1eb, - 0x67b05ef3, 0x81e97bf0, 0xcc7f707b, 0x45db8c71, 0x2ec999af, 0x5376899a, - 0xb071bf88, 0x397e66ba, 0xbe427bf6, 0xf582f917, 0xbc0a6932, 0x3b08cfb7, - 0x35ee7a8b, 0xebcbf523, 0xe685d01d, 0xce597ff7, 0xceb3c1e5, 0xfc717bda, - 0xb2d03e8e, 0x7dcf4fc8, 0xaebf4468, 0x013fafa3, 0xe70cd9f5, 0xcfb44687, - 0x7a2b9e87, 0x61c60c4e, 0x0e1fe39c, 0x63de23e9, 0xa46e5edd, 0x722b4ff1, - 0x7a3be5bd, 0xf78b4f3a, 0x864a6b37, 0xe1cb73e4, 0x63ef1fa0, 0x7bf3b4b7, - 0x368e789b, 0xf9069c92, 0xbca861fc, 0xf41d367d, 0x4f1a4cc1, 0x97960fa3, - 0x3edee9f9, 0xfbcd6fc8, 0x5c34972b, 0xc8257cc5, 0x4cf3ed71, 0xb1961e7e, - 0x73fa0301, 0xed35d720, 0xfb95cb1b, 0xde58d39c, 0x2e072017, 0xdbdf2338, - 0x9f8abb7d, 0xaae0b833, 0x16787da3, 0x47e789f0, 0x3f861d9f, 0xe1dbd78e, - 0x81a465ed, 0x661bfd90, 0xff7157ff, 0x7228e5ea, 0xbfb2a2fb, 0x014084fb, - 0x33b7550a, 0x8577e88e, 0xa5ed75b9, 0xcf97dc42, 0xdebfa2b7, 0xee8123f2, - 0xffb2ffc1, 0xac3b34ad, 0x54f878df, 0x7697de1a, 0x86953a1f, 0x0cdb89f7, - 0xcf68cdf6, 0x3dd07d03, 0x3f5e8ee4, 0xa87edfc1, 0xb79f1fb0, 0x140e0af7, - 0xeb9eeec9, 0x364eb40d, 0xa3fd15b0, 0x3ae0517d, 0xabedce58, 0x2a76e5c3, - 0x13982edd, 0xc98f7ef5, 0x1e9013e7, 0x5c213e40, 0x820fc047, 0xe66dbefa, - 0xd4f648a6, 0x27df0565, 0xde1919b7, 0xfe836dfb, 0x59d38eb8, 0xbdf88da7, - 0xb0c39685, 0x71d7012e, 0x1c7881ee, 0xa181837f, 0xf7c2a19d, 0x03e05671, - 0xabfbff5c, 0x2dcf0c0d, 0x27ad596f, 0x81bfbf7c, 0x87fa27db, 0x0335bd7f, - 0x2e80cbea, 0x270f3bf1, 0x9d38df56, 0xbfbee301, 0x7569db86, 0x2f881b0f, - 0x6e13ad97, 0xa50e4bdd, 0xff6e956b, 0x70d3a146, 0xdba70dfa, 0xe6baf461, - 0xdbebd1eb, 0x90ecb7e5, 0x61f7a819, 0x438ce7ff, 0x731efa3a, 0x1a7e401c, - 0x0718613c, 0x2ada4f70, 0x63c3c039, 0xa7bef5d3, 0x9c6e50d2, 0x6df9ede0, - 0x7f2e057b, 0x7d71cbec, 0x8646dd19, 0x2a2e08f7, 0xd95176fb, 0x0a0b3b37, - 0x62cfc8f1, 0xa9ca1260, 0xf9ce256c, 0x1d35818a, 0xe452ff46, 0x8ffa67f2, - 0x87b77b6d, 0x2b7fefd0, 0xcaab74e7, 0xe64669c5, 0xf7c56c3a, 0x045f8d0f, - 0xe06cbce3, 0x282735e7, 0x09c94de3, 0x52822c36, 0xe4e5c157, 0xd438156f, - 0x3e149ffa, 0x437f2760, 0xe6685cf8, 0xd1b79ff8, 0xf8eb8cdf, 0xbd75c999, - 0x305fde1c, 0xea1b7ce1, 0x3f49eebd, 0xb9dfe3c9, 0xee1d9073, 0xa27ff056, - 0x63cf37fc, 0x3532cfee, 0x72d7f68e, 0xe90969f4, 0x68a532d9, 0x30f148dc, - 0xe66ccdf7, 0xbaba014a, 0x5aa54399, 0xaafc745f, 0x82fc8071, 0x2fc40deb, - 0xb9e9d337, 0x0553efda, 0x8e46e9ee, 0x4a97d607, 0xb6e41b7a, 0x67921658, - 0xfaa0f150, 0xfb2996e3, 0x5b1ebf69, 0xcfee28c7, 0x8f84d3d8, 0x84e76d15, - 0x41e71856, 0x02b06c83, 0x3627cfbe, 0x8534bdad, 0x626c9fb1, 0x3a0b05cc, - 0x5cccc9bb, 0x6c7d0377, 0xd81ea892, 0xbbfaa364, 0x5e54ec9b, 0xa2c738b6, - 0xa4e079fe, 0xede20a67, 0x671ed644, 0xed73cc2d, 0x41f081ac, 0xfdf4063b, - 0x376b4298, 0x0cccf4fa, 0x947a37ed, 0xf028adef, 0x8333743f, 0xfcbe40b9, - 0x8e83e702, 0x467f1bed, 0xe6b1cf72, 0x49fa037a, 0xb7176df9, 0xf1bddd62, - 0x5f680d77, 0x04fa007c, 0x7eec0ce9, 0x9e501366, 0x81da339c, 0xa66f9a0e, - 0xeb2f38d0, 0x77c80d82, 0x430263de, 0xf7a0fcfa, 0xd71c71ba, 0xe12d7457, - 0xe6744df9, 0x48ad2d9f, 0xfbb8fc22, 0x7f7c75f2, 0xf7a1748b, 0xf9effa29, - 0x87ee0243, 0x9dfda379, 0x467fec4a, 0xb7af90cf, 0xa41306d7, 0x02f87208, - 0xa3978b8c, 0x86581d70, 0xbd1937b7, 0x413cf053, 0xe1c74293, 0xfa158bed, - 0x941b4c04, 0x213229ef, 0xc1239f8d, 0x5258169f, 0x41f93262, 0xe7e038fe, - 0xabbabe96, 0x811e9622, 0xcff5a87d, 0x762187d8, 0xfc3a347c, 0x437e25b2, - 0x4329c3e6, 0x4323f475, 0x1fa07fef, 0x82fbe919, 0xe3c9aca6, 0xb9778a46, - 0x83bec007, 0xc300eafd, 0xf4829ec9, 0x4fca8d3e, 0x91d9748e, 0xc171cc7f, - 0xd82fa83d, 0x3bf23a5d, 0x7b5abdda, 0x87e141a8, 0x7a1ec506, 0x3feb42b4, - 0x5ed49f81, 0x84a4fdc1, 0x3fe34ce3, 0xff273f85, 0x057c8cc9, 0xfd834ef3, - 0xfed22579, 0xc7aed554, 0x2ed8137e, 0x740673a2, 0xbe15f48e, 0xe0a8bfce, - 0xebe5547a, 0x48d7c865, 0xaf9cbdbf, 0xa96dc7c3, 0x1c0bf9aa, 0x7b945b77, - 0xf157f710, 0x139fdaf1, 0xe7ee5f08, 0x1f4f0852, 0xb59ce7b3, 0x031f9740, - 0x2e80fb1c, 0xf19d39af, 0x9affd049, 0x6c9f19cb, 0x1d03921d, 0xbf53c5cf, - 0xa717936d, 0x19fd42b4, 0xef187ba4, 0x8a3ade93, 0x1cf43e6f, 0xbe753fe7, - 0x52cbfc0f, 0x0d8a9f90, 0xda03a341, 0x262efb33, 0x7c581da0, 0xe414fee4, - 0x6e7068c3, 0xdce054ad, 0x4bdad8f8, 0xf01e9c29, 0x455aee1c, 0xf49fb9bf, - 0x6bff111b, 0xdfa23237, 0xd97ed7fe, 0x49fc7c81, 0xfa84bc5f, 0xf1a3e3f0, - 0xd7ff945e, 0x3a7c998e, 0x6f10fc81, 0x8fb5c822, 0x91f7030d, 0x2f4479bd, - 0x3ee8ffa1, 0xc83ddbf6, 0x4cd7ee8f, 0xb5b1f968, 0x51d75d7d, 0xddf5b5ef, - 0xf2c4557b, 0x87e5d1a5, 0xd38f8df6, 0x6ffad57a, 0x28ed9937, 0xb9113f47, - 0xfbdb589c, 0x6bbfd92a, 0xc0cc6f07, 0x47c7ea38, 0xca094fff, 0x379bf735, - 0xb99e504a, 0x8251b8df, 0xc71feeed, 0x2dd9227b, 0x84f4b371, 0x665f5557, - 0xe26a27bf, 0xfa141b45, 0xd5dceec8, 0x57f00938, 0x03896e7c, 0x7b6ab6f3, - 0x139d14f1, 0x79fe2fdf, 0x21c3ca7d, 0x22033afd, 0xce8a8de5, 0x0eafc7d5, - 0xaa47cba1, 0x94ef9a0c, 0x0f38d57d, 0x2df7e2b6, 0x0275c56f, 0xec0efa3a, - 0xbfc880b6, 0xf046bb2f, 0xf601bfa1, 0xb23f784b, 0x923daea7, 0x9910f742, - 0xbd3f9ce8, 0x1c53eb08, 0x5628eddb, 0x8726a7cc, 0x02cb4bd8, 0xe809bf3a, - 0xe4cfa9a8, 0x203f7b27, 0x62baa45e, 0xfd743d47, 0x85b26337, 0xdc9a7108, - 0x1ca0e777, 0xc0d78f0f, 0x5b8418cf, 0xa7ceafb5, 0xa651f8f3, 0x042dd247, - 0x993b9ab8, 0x161d7884, 0x4b9a69d7, 0xf8f0a2f1, 0xdbb03d8e, 0x93ecfd8c, - 0xabc21275, 0x8fb8a5da, 0xc0e4113d, 0x7972565f, 0x6757f2a6, 0x3af5e780, - 0xc9e6b503, 0x69577e50, 0xcc7491ef, 0xece9780b, 0xc600ffbb, 0x1f073a17, - 0xf30e9f8c, 0x98b7be74, 0x9ae79e61, 0x829e6b54, 0x9ae706fd, 0xa21bc81f, - 0x1af9f09b, 0x345db92a, 0xd6442f64, 0x5f0aa57f, 0x2c1e968f, 0xd0f3fcac, - 0x579fe083, 0x7cff7254, 0x709f8f05, 0x7f5c3cff, 0x1d5972a8, 0xef82ad77, - 0x2af972e1, 0x47e039d9, 0x5b5e5c93, 0x32f7a769, 0x90a516fb, 0x92defd7f, - 0xf875bb14, 0x43a239f8, 0x7c379c97, 0x739ed57c, 0x6653e57b, 0x3d647bf4, - 0x897ba7f1, 0x97fcc3e0, 0x9db9ff6a, 0xeee5d902, 0xdf0f8366, 0x2c0ae153, - 0x07d8f1e1, 0x22cf8364, 0xaa89d90c, 0xddab791d, 0x6abb5021, 0x63f6aa57, - 0xbbe3c9c0, 0xfb788a4b, 0x556b8b65, 0xa75c58e5, 0x97179e85, 0x398ce7f3, - 0xf55fa14f, 0x918152e0, 0x4aec501c, 0xedc34e95, 0x72fb4fce, 0x438a4712, - 0xa7d0af3d, 0xc21367ca, 0x63d543f8, 0x7e7054cf, 0x5e3d40eb, 0xf7fc7a88, - 0x7c3cfb1a, 0x8fe3d05c, 0x463f5257, 0x2e7e8bfd, 0xebf9233a, 0xadfc6566, - 0x4e05feea, 0x59bc20d6, 0xfd19b02c, 0xf5fa68cc, 0x139d8a7b, 0xc519fdad, - 0x3f1dbc7e, 0xc8e4561f, 0xcbf3f168, 0x70f2b795, 0xf9f9a9ff, 0x8c687d96, - 0xd557bf62, 0x1ffb86bc, 0x6a04f7a7, 0x97feff90, 0xe1eee281, 0xfaa53def, - 0xecd3229f, 0xa32ca9cf, 0xf723fd0e, 0xe83f1e1a, 0x43bfb24e, 0x7a5bcc7e, - 0x05ace386, 0xb8ed107f, 0x51266f47, 0x32f686d9, 0x385e2b94, 0x1588f947, - 0x77f0b46b, 0xfb174c63, 0xf3a6cbaf, 0x9eac2d03, 0x7d2d4ce2, 0x5016d249, - 0x0f63dd0a, 0xf2be469d, 0x0fdbd01e, 0x88ffbe84, 0xc799befa, 0xfba636e1, - 0x661af728, 0xc278b40f, 0x7dad7eed, 0x8dc4a950, 0x6f09d9a2, 0x5cb85bf4, - 0x3e27a339, 0xd378c0ef, 0x7d8cc64c, 0x37b82e5c, 0x474938f2, 0xfc04e6df, - 0xd2bb6a08, 0x500c457e, 0x6bf28a1c, 0xbed5eaf0, 0x3ee8d3a7, 0x27cdac97, - 0x39ffefb5, 0xbcf0cbc9, 0x970f7252, 0xbd36ee4b, 0xa12a4792, 0x83b797ef, - 0xed0e393f, 0x1bfdbb4b, 0x8b807788, 0xc8de48f9, 0x3ecbb89a, 0xe9f4af25, - 0x3f257f99, 0x2891c574, 0x79eea479, 0x7ca48f3c, 0x1e787727, 0x0ca9f4e9, - 0x48f3edfb, 0xe8e7bd1d, 0xf2edcb1e, 0x5baaa649, 0x3b8a1c71, 0x7c79144e, - 0x209f6277, 0x626abc61, 0xe9775f1f, 0xafb238b6, 0x3ab57e1b, 0xba81e505, - 0xe22c9f4f, 0xfde4fdf8, 0x5fb06acf, 0xc944afc9, 0xe37aeb02, 0xcb3f0dfd, - 0xd9bb75e0, 0xc436fd8e, 0xc9f33fa3, 0x23c7d6af, 0x1280df7e, 0x17c7e7f7, - 0xc9f1c8c4, 0x667578a1, 0x959dc515, 0xfa08b578, 0x5c50cc70, 0x8bdfbc27, - 0x746e5c55, 0x7142bb83, 0xef3c23cd, 0x9aee9ddf, 0x9ebff547, 0x29dff8c4, - 0xfd1e2990, 0xc635d02a, 0x62c1a68d, 0x3ffd2f31, 0xe62758e3, 0xbac7ba91, - 0xf47c427e, 0xf23b3ad7, 0xfca7f411, 0x9db0f793, 0x6a8623f4, 0x0333cf31, - 0xf7405b3f, 0xdf295231, 0x8fb28f73, 0xa2cfe0e9, 0x2cd0095f, 0x34f43cc1, - 0x2333df25, 0xfe38898e, 0xfb6b830e, 0xf52fcc54, 0xc4cd8e8b, 0x3c148e04, - 0x779e196f, 0x2f9e6412, 0x6a4ff357, 0xfe5a3cde, 0x9479c049, 0xf3f056ef, - 0xf980b296, 0xc4cf3574, 0xf9293a96, 0x43cca5b5, 0x807c42f7, 0xde73afb3, - 0xcffc846b, 0xf21115c3, 0x982beb3f, 0xf3699f62, 0x5f73db8d, 0xaafd3a21, - 0x78c3c679, 0xe68ee2ae, 0x0fdcecc5, 0x28bb830d, 0xf234d3e9, 0x6ff8febb, - 0xfb67a409, 0xbc3e906e, 0x00b13416, 0x78071fc5, 0x40cfbddc, 0xe06b8671, - 0xd10d8dbf, 0xf054efb3, 0xd5f78f71, 0x04f7fd11, 0xfdf1e3ea, 0xb7cf2bdf, - 0x7ee4b7bd, 0x01bdf7b4, 0xc60b1dfe, 0x13d63fb8, 0x6ed18b10, 0xf2fb83b9, - 0xf5846564, 0x7eb8e399, 0x52a3e70a, 0xab4aff85, 0xdeeb9e38, 0x7b987ee7, - 0x48afcf03, 0x7b705c8a, 0x74fd5e78, 0xc6a09a56, 0xca45c7d3, 0x92091cbf, - 0x447968de, 0x7cc9efa0, 0x33cbfcd9, 0xf1f391e9, 0x462f7a2b, 0x3634bfce, - 0x168cfc90, 0x638f0ecf, 0xff2a9dff, 0x7638f3a6, 0xeb44957a, 0xd7e4f64e, - 0xeb43638c, 0xb0fb83bf, 0x7d845674, 0x6fe383b8, 0xf1db1d9c, 0x3b63caeb, - 0x1e3113fe, 0xc78c7b7f, 0x6c7961ff, 0x8abaebf3, 0xdbffc2d8, 0x1fdfc318, - 0x57fffe09, 0xe78407cf, 0x0bcfc3ff, 0x30039f84, 0x17b0f5bd, 0x9d84badb, - 0xefc33f41, 0x24d6bf8d, 0x93141c80, 0xce7dd3f6, 0x1f3ce505, 0xecdeadb6, - 0x9d0c2bdb, 0xf5f1501b, 0x23f73568, 0x5eebbca5, 0x04d45efc, 0x829f5039, - 0xfe72b2f1, 0x59ae4377, 0x898c5e78, 0xc9e63a52, 0xc5f4cde0, 0x5b749760, - 0x5359e722, 0xe9a2f195, 0x35d58391, 0xe315678b, 0x7c8a3d1f, 0x4a87ff0e, - 0xe5ea521c, 0x6899e9f7, 0xf34c5f4f, 0x1ed1d3da, 0x9fc93c4a, 0xbc99f827, - 0x67b2e097, 0xdc7fe62f, 0x7be11b20, 0x26ffc946, 0x1b2bbbcf, 0x60c9d2e3, - 0xf05e6217, 0x920fcc69, 0x7bd12b3f, 0x66977cea, 0x19ea3f71, 0x9f301303, - 0xcfca9deb, 0xdf9eb139, 0xe6a6fd91, 0xfc1acef5, 0xca055a97, 0xfc23b5eb, - 0xf3f9d53f, 0x442b65f6, 0xebcdf80c, 0xf8df2891, 0xe5dff976, 0x9e1e68ba, - 0xe24c7be7, 0xbf409caf, 0xec78e019, 0xefd12168, 0xffe5e38a, 0xc7fe8cd4, - 0x3cf09164, 0xe254afcc, 0x78941705, 0x502f1a87, 0xacff5bf3, 0xc03e49c4, - 0x03940bf8, 0x72810f18, 0x9ddd2cfb, 0x67db4fd6, 0x67ffe045, 0xf21f1e04, - 0x87c794fe, 0x9c8e8d0a, 0x7f94f3d0, 0x63ef8b35, 0x2fe79fab, 0x0fcf78d4, - 0x7e14f595, 0xefc7ef4f, 0x9d6e15a1, 0x5f3d446e, 0x0e2b35b8, 0x4fb219cb, - 0x5ef80697, 0x4eb0fab6, 0x7448bfdd, 0xe75957b4, 0xca4133b6, 0x961abdef, - 0x8b34bff7, 0xa968679f, 0x097bfbe6, 0xd418a0ff, 0x6e229b1f, 0xb131f341, - 0xca47d24a, 0x5f80b52b, 0x76b6708c, 0x7c55b873, 0x75edf8b7, 0x53c5cf38, - 0x1658adc1, 0xa3aec9ac, 0xf5db7bb8, 0xb9bf68ad, 0xae9c6f07, 0xd19978a6, - 0x43c4fe8e, 0xdbb8da03, 0xfe3cd513, 0xe01a2afe, 0x457bb788, 0xef0b8ff2, - 0x927e8915, 0xbfe42c5b, 0xde981b26, 0xdc45f58a, 0x4c682a2e, 0x5b3ac3ad, - 0x60f64492, 0xd27b19c1, 0x714379c3, 0x377be4b0, 0xdd3c458c, 0xc6aacf2e, - 0xe45b2ed3, 0x5f9fb8e3, 0x7edacf35, 0x6f3a3df6, 0xc54baeaa, 0x8d2f9a8b, - 0xcf556796, 0x3f1bb83d, 0x70d39cd3, 0x8c06c18b, 0xbd1e163f, 0x5fce5468, - 0xa1ecb64a, 0x91e16c3c, 0x557f94eb, 0xcf6eadf3, 0xa1abb275, 0xf7fb119f, - 0xd7f9e26c, 0x2c0e00d7, 0xb2dd617b, 0xdba1ef09, 0x7583eca8, 0x9b63f3e3, - 0x6ff4a972, 0x7c795072, 0xf8951953, 0x64f4c999, 0xa75edbcc, 0x59d5edbc, - 0x524dcec3, 0xe8b76f5e, 0x15f108fc, 0x7aa3f792, 0x1f4fde78, 0xee35e3c7, - 0xbefa0633, 0x99acfba1, 0x5f4d77e4, 0x0ff444eb, 0x9ae73f3e, 0x60777088, - 0x2e842dde, 0x961d913e, 0x9d83f424, 0xdbe60b0e, 0x1aaffb0a, 0x874c3cf1, - 0x3c623018, 0xc0cf200c, 0x9eee8b23, 0x6fdcfceb, 0xf1058d5f, 0x58fcdb7b, - 0x8fcfffef, 0x58fc957d, 0x273f3577, 0x0291caad, 0x8bde4ea7, 0xf2d919e5, - 0xd89c8870, 0x94f9e4e6, 0x1127936d, 0x4e76ee1f, 0x321d5a4a, 0x8f23675e, - 0x3bdf245f, 0xfcfa12d9, 0x1f3cd597, 0x67302c96, 0x33567924, 0xc7ddebfb, - 0xd76e411b, 0x3ffbb244, 0xe5d029f9, 0x238ba04c, 0x90389edf, 0x343f19c7, - 0x71adb71e, 0x2831c4f5, 0xd8982e9f, 0xd3af1e14, 0x5858e3c4, 0x5c5a2e5e, - 0x4ea3456e, 0xa179d0b6, 0xdbd404e0, 0x2633f1e1, 0xbd702706, 0xbde0672e, - 0x83319814, 0xf961b195, 0xdf305fb9, 0xfbc327cf, 0xa4751acb, 0x5d3cd42f, - 0x36c8a341, 0x6c167d01, 0x3f28f834, 0xa45e28d7, 0xec6fc576, 0x90320a94, - 0x6b383fce, 0x16ae3094, 0x34731f1e, 0x049eefee, 0x026d1dfd, 0x5dba0bdd, - 0x073d4f1e, 0x3fdbd2de, 0xf96de307, 0x3d77576c, 0xac9fcff4, 0xf4fcf093, - 0x3f1e7cf0, 0xd8a05dff, 0x3671e139, 0x4bb433a4, 0x1bf0e3c2, 0x38d83a15, - 0xd7adeb9b, 0x1d537f14, 0x4e17ed47, 0xcd9d3f3f, 0xb8b46df5, 0xbc6551fe, - 0x6d82c6ce, 0x177f7193, 0x93ea18e8, 0xf35ac6ce, 0x76f190e4, 0xdbe7e6cc, - 0x60fcc19e, 0x907e686a, 0xf3c301e7, 0x2b9caa82, 0x037dffec, 0xc8377be2, - 0x6e63d46b, 0x141fcf1b, 0x8339ab1e, 0x4e086372, 0xc377b7ae, 0xbec8079e, - 0xbe312473, 0x457bfa2e, 0xc502a3de, 0x7c160ae7, 0xea1e3c76, 0xf74499cc, - 0x2767dcb0, 0x3ca2b16f, 0xe316205a, 0x53b71ebd, 0xc26795b8, 0xeffdd27c, - 0xbcefa1ac, 0x7f903e16, 0x81e5f70e, 0x0f9d0366, 0xfddef554, 0xf03534ef, - 0xc64fbdf6, 0xe0ae7b61, 0x79f1d8b0, 0x763f7d23, 0xfa7e4bfe, 0x110b58bb, - 0x81e7903a, 0xe44497b3, 0xd716cb9b, 0x151f23df, 0x4cf2522e, 0x3f4f5ccd, - 0xc0c8b7d0, 0xead3cec8, 0x9f5913cd, 0x46e83c53, 0x8fe5215f, 0x43fcf052, - 0x29be90de, 0x6c7a0a3c, 0x63d39dcc, 0x112d9d3f, 0x1e82673e, 0x17927843, - 0xf87d3cf1, 0xf650effe, 0x8a5e9a3f, 0xff518726, 0xde63fbf0, 0x5c36c10c, - 0xee31db8f, 0x3af68a53, 0xd3a2e394, 0x71661fdf, 0x628a4eba, 0xa149fdcf, - 0xa7e7a8df, 0xcf27477a, 0x7fd987f4, 0xd563791e, 0x4df352ff, 0xa0f6bfaa, - 0x65ab0f62, 0xbbfe5293, 0x72a037ef, 0x21bf788d, 0x86fdf239, 0x68090e87, - 0x1bf7a8a7, 0xcd59194e, 0x4f3c54e1, 0xf277dcab, 0xe93b222d, 0x62fcdfd4, - 0x78a98beb, 0x509049df, 0x3a1fb51d, 0x1dbe7a47, 0xa7b223ec, 0xe3cb7efa, - 0xf9f887ad, 0xc8def6f0, 0xaddbdddf, 0x32f5dfd8, 0xaed1b923, 0xe86db79c, - 0xb744f251, 0x8b8f96e2, 0xb74b71a1, 0x3d56303d, 0x7f23ebc7, 0x8cc71b4f, - 0x60ecb716, 0xdbb73a41, 0xa07046b1, 0x39ddb87e, 0x79ca5ddc, 0x4c71a8dd, - 0xb973e479, 0xb94c71e1, 0xb9c79b5a, 0xf7c4966f, 0x680825db, 0xce759aef, - 0x7fb73a36, 0x9d22904c, 0xcd5a5ef3, 0x257cf4e5, 0xc8d0720f, 0x8560e3e9, - 0xf06ff740, 0xfbee1e1e, 0x1efc63c1, 0x7e02c1ce, 0x7bcd470f, 0xa66bf7a8, - 0xe83de50e, 0x2f7a9dfe, 0xc367bd47, 0x5ae08f98, 0x7d1c5cf4, 0xe1876bc7, - 0xbddb8d90, 0x1a3f7e5e, 0x43e61065, 0x8913cc4d, 0x6bab6b5f, 0xef7a6ac4, - 0x8f4fdb8e, 0x7bf04754, 0xe91f8a7d, 0x2fea8eae, 0xfad6afac, 0xf70f540b, - 0xde54ee17, 0xecd98be3, 0x87fbfb4e, 0x9e8f1c63, 0xf1b63b32, 0xfb48ecc4, - 0xfda2c5b6, 0x5e5aaf1e, 0xb0dfe456, 0xbb0dc5ef, 0x7af5c92f, 0xa7ff60b7, - 0x1ba7ca4a, 0xcaae9f28, 0x7c31eed5, 0xe3291ffc, 0x294065a9, 0xd77ca3bb, - 0xbc4a97f9, 0x7b944bac, 0x2f69ee10, 0xd397e368, 0x97e3690f, 0x35937b33, - 0x78ff7cf5, 0x6785fbcd, 0x8bda6926, 0xda68f703, 0x68142f4b, 0x1503e5ea, - 0xaf2bf79a, 0xb3ea6ad4, 0x65f8da82, 0x61c5cdf5, 0xb47d38f7, 0xdca01abe, - 0xe6757ed0, 0xcbde6a6f, 0x575da358, 0xaebb4796, 0xebb51b89, 0xf6cdc752, - 0xd397d76a, 0x325f5dad, 0xbef2e3e6, 0x7f2e3e7e, 0xc7c95db6, 0xdfb058e5, - 0x2d938d33, 0xf7a9b768, 0xfef7d5a9, 0x5866372f, 0x007f40df, 0x00000000 -}; - -static const u32 csem_int_table_data_e1h[] = { - 0x00088b1f, 0x00000000, 0xe4b3ff00, 0x51f86066, 0xb97bc10f, 0x726e1818, - 0x0143f821, 0xd08667cf, 0x0c0c2c6a, 0xc6cc401a, 0xcec0c0c4, 0x717ebc44, - 0x1d7b044e, 0x4cc30307, 0x31c8de20, 0x481afef0, 0x7e879d7c, 0x42f3a976, - 0x81c15968, 0x570837f7, 0xb430310a, 0xc430330a, 0x0cf84088, 0x55f2a8a2, - 0xa9b60842, 0x39766524, 0x0003f502, 0x3471cc24, 0x00000380 -}; - -static const u32 csem_pram_data_e1h[] = { - 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd554780b, 0x733ef0b5, 0x7993331e, - 0x0f20f264, 0x0084f102, 0x021842a2, 0x27088784, 0x01a8c421, 0x54bc8083, - 0x48433c26, 0xbfa81132, 0x2677bd6d, 0xb5ad1104, 0xbc1b6951, 0x14101de8, - 0xd1a07515, 0x40e81c06, 0xdbdab114, 0xd5a8f8a8, 0x40445076, 0x8bcbc248, - 0xaf7fd52d, 0xe649cfb5, 0xd4484c9c, 0xffffbff6, 0xdbf3f1fd, 0xd9cfb3ec, - 0xdaf5ed7b, 0xf6bdad6b, 0x9a32c11e, 0xe4224e24, 0x65a3f85b, 0xf4842784, - 0x0adb2ce9, 0x64918fda, 0x8b2ffc42, 0x108e36f2, 0xf08e77ee, 0xbc8451a4, - 0x980b99b5, 0xcfbc3d69, 0x9fad0846, 0x603d34de, 0xff6422ce, 0xef02b308, - 0x8f9ade9f, 0xbd2fc9f5, 0x7b6814e7, 0x00bc4bd5, 0x13bed375, 0x109d88ce, - 0xa1e5b9af, 0xf6f3e96b, 0x85b27897, 0x93fc450e, 0x9085244d, 0xfec21663, - 0x52fab22e, 0x6d56ab2b, 0xf4077fde, 0x2664de5b, 0xd54fda56, 0xaed365ee, - 0x8765f5a5, 0x54af0244, 0xfa95ab6d, 0x00f2fad2, 0x9afa8417, 0x71c67f7d, - 0x79480ada, 0x27212870, 0x5f22167d, 0x96ceeb49, 0x79f45994, 0x11676045, - 0x83b15fbc, 0xfbe89b73, 0x7ff69b15, 0x3457fd0c, 0xda79038a, 0x36ed8aff, - 0x63610f22, 0x1e604b7f, 0xbc01a64b, 0xc4886f55, 0x97e5eb4c, 0x70044956, - 0xa54bd424, 0x61ff180e, 0x38c07649, 0x0d1c7087, 0xd0cf559f, 0xd577e871, - 0x986e702f, 0x7889b55a, 0xddd69e00, 0xda4f39d6, 0xd2b55e61, 0xf77ef860, - 0xb7bc127d, 0xb2f6502c, 0x36f80655, 0xe700454b, 0xd2d2cda6, 0xadfd9da1, - 0x0ea6fed8, 0xd90d63ae, 0x76a89ea9, 0x47d27963, 0xacee6c88, 0x04a21057, - 0x407700ed, 0xf3ac3e9a, 0x812e79f9, 0x3fd0d190, 0x674b644f, 0xc83094ff, - 0xe8f7fe07, 0xf60f813f, 0xb2db023a, 0xd2b5e93a, 0x772dff45, 0x4bacebd2, - 0x9ed09fa5, 0x56bfdd17, 0xa074043e, 0x5cfbd4f0, 0x4be23e58, 0x4f8372c3, - 0xcafdbc46, 0x06cb0437, 0x3f9f1b9f, 0xe58b1be6, 0xe5829f26, 0x2c62be13, - 0x7c52be03, 0x0e6f8b6f, 0x1e7d5b96, 0xaf94fe7c, 0xbeedcb1c, 0xacfe7c1a, - 0x772c6eef, 0xfcf8fcf8, 0x2c7adf05, 0x2c7abe83, 0xb01af977, 0xf005f46c, - 0xdb7d97bd, 0x05f26cb1, 0x5f1ef9f1, 0x5f219613, 0x407dcb18, 0x7d865a5f, - 0xf01e582d, 0xabe5887d, 0x777e08be, 0xcb1c77d0, 0x3bbc5507, 0x817c9027, - 0x10a9cde2, 0x92171517, 0x8be4a258, 0xca589eb4, 0xf9b729ea, 0x4f5a25f3, - 0xc53ad0f1, 0x70cadf63, 0xfbd699be, 0xccf6b0d6, 0x8581487b, 0xacfd33d6, - 0x4a83c07d, 0x07d69581, 0xc1f6b3d4, 0x7105fc9b, 0xc0383eb4, 0x11deafda, - 0xfad1b02e, 0x9ed641d5, 0xed932213, 0x66139eb4, 0x94b7dcf5, 0xcf5a0ec9, - 0xbcf5616d, 0x9d93fd8f, 0x61179eb4, 0x153f8fdf, 0xeb4f1c9e, 0xfb59dbe3, - 0xd0a44bc4, 0x0913eb45, 0x7b02f587, 0xad02617e, 0xbd58b817, 0x20995fa8, - 0x7dbfe0c7, 0xa1116462, 0x7fddb0bc, 0xd3a422b3, 0x455914ba, 0xfe9f14dc, - 0x8b0f5839, 0xbfb43164, 0x84532fe5, 0x912eb471, 0x17fed0d5, 0x1fb6057f, - 0x6f6c6510, 0xf6c2aff7, 0xed8c9203, 0xb07bdaa6, 0x60a8aafe, 0xbded727b, - 0x92abfef8, 0x6b83ed82, 0x41fac21f, 0x63ed83d1, 0xef8d7f6b, 0xd83c941f, - 0x80dac8fe, 0xffeb4852, 0x00b679c1, 0x9e71d75f, 0xfc0d9272, 0xa52b4c1a, - 0x238ebafc, 0x1e3e4073, 0xf2a6a600, 0x525d2eb0, 0xfbedbf40, 0x3c93de47, - 0x3276f2a7, 0xf53e97d4, 0xf3f61640, 0xd223f61c, 0xfb9ef87e, 0x58cdf899, - 0xbf133f5d, 0x69fad729, 0xaceaf784, 0xdf67ebbd, 0xf0f5e337, 0xf5a1537c, - 0x71fb17b3, 0x135e6ef4, 0x87a09dbf, 0xad4adbe7, 0x4fd8839f, 0x09e0ef42, - 0xfd74638b, 0x5a65c584, 0x7ec47f3f, 0x1e0ef4fa, 0xeba71a45, 0x6b969147, - 0xfd887cfd, 0x9faef7a4, 0x1ead74b0, 0xd685691e, 0xa7ec11cf, 0xa5e6ef7f, - 0xc3d3af98, 0xfad2ae63, 0xcf748939, 0x073f5dea, 0x1cfc7a1c, 0xe7e07470, - 0xa833c21c, 0x702af377, 0xe053f1ea, 0x25cfc0ec, 0xdeaae7ec, 0xa9c073f5, - 0x6701cfc7, 0x0e447e07, 0x77ac35e6, 0xd7882af3, 0xbe20a7e3, 0x0e4e3f03, - 0x3bd119e0, 0xa3ed5e78, 0x7dabcfc7, 0x8a93f03a, 0x1dee8cf0, 0x7a29853c, - 0x74a614fc, 0x784647e0, 0x9faef5c6, 0xf8f45357, 0x03a53579, 0x3f61573f, - 0x5e6ef5d7, 0xfc7aa985, 0xe076a614, 0xc9fb1727, 0x78476cf7, 0xd1c7ed08, - 0xfb073f7d, 0xb073f1eb, 0xae7e077f, 0xd0a67ec5, 0xee7bb27e, 0x8f5328a7, - 0x0ecca29f, 0x9e2214fc, 0x3f5de86f, 0xf8f53307, 0x81d99839, 0xcfd8a99f, - 0xabcdded4, 0x7e3d0ae8, 0xf860ae8a, 0xc08c2499, 0x9dae8675, 0x727e9e6e, - 0x857cbf7d, 0x2ef3efa3, 0x6e5de756, 0xaf0f7602, 0x45a433d9, 0xf6fbe9e1, - 0x0fb9091d, 0xa6bb6890, 0x8fc076e0, 0xd1795a83, 0xd8fc4d76, 0x951d9d38, - 0xeaea24a0, 0x757dc549, 0x1d29f7ef, 0x9d4f6ba0, 0x3daeb573, 0xabab93dd, - 0xd78f9467, 0xa6bfdfbd, 0xe2bf5740, 0xef751bee, 0xd16ff967, 0xcfd7b3d5, - 0xa83fbdd3, 0xfdaea17e, 0x5d0a86ca, 0x958155fb, 0xdb35faba, 0x7f7ba27f, - 0xae8d7058, 0x03d3787d, 0xe111f6ba, 0x91f57447, 0xbdd31e87, 0x8b65ba3f, - 0x87cc7dae, 0xc7daeacf, 0xeae97645, 0xa3df1ed7, 0xf6baff7b, 0xa4faba03, - 0xbdd7bf8b, 0xd5de4f9f, 0x3f96dbdb, 0xe29fdeeb, 0x7ed74cfa, 0x0697da7d, - 0x3aeed53b, 0xe75a8d76, 0xfa08ae41, 0x0974fe25, 0x43b0d5ed, 0xd7d4bac2, - 0xc714fcce, 0xe528f952, 0x22c0e91f, 0x92f91939, 0x21bb51fe, 0x95f96fbf, - 0xaefcfa11, 0x5d2b9ef1, 0x925df9f4, 0x862bb867, 0x8df9437d, 0xca506923, - 0xed8d2826, 0xdf8c89f7, 0x0d2e320b, 0xf7bf423e, 0x2707da9a, 0x3e70fad0, - 0xf1f2083f, 0xbb426732, 0x35278e3a, 0x999c5ef0, 0x5f74dfa0, 0xfe93de56, - 0xdf587928, 0x5c19da9f, 0x45ebbf67, 0x51da1a4f, 0xc1f89fb5, 0x9fd759ce, - 0x212fabce, 0x849f70af, 0xf7e903fd, 0x79a697fd, 0x89667f68, 0xe3d119fa, - 0xa1fc744b, 0xe4187e38, 0x3f8c20e1, 0xe6f8ebba, 0xe3756301, 0x75cb325b, - 0x3a245be3, 0xdf908bbe, 0x8eae7ed7, 0x9e30894f, 0xcfb93790, 0x66737c71, - 0x9f7f8e39, 0xe8aefd44, 0xc63ae3f1, 0xbff9816f, 0x07fcdddf, 0x3fcfd78c, - 0x7f3f42b3, 0xa3ffcd89, 0xf8ead3da, 0x3fff3871, 0xfcd9a773, 0xfcd82b33, - 0x8edfaccd, 0xf81d9df1, 0xc7f8c08f, 0x9cdf19ba, 0xff3f413d, 0xf3f52a2b, - 0x4ff1b337, 0xc7505ed6, 0x5ff8e3b7, 0xfcd81772, 0xf1c4a8af, 0x0dc7b325, - 0xc46523fc, 0xf8e804d5, 0x7c551fa4, 0x742ec0a9, 0x2487281c, 0x6421a152, - 0xe100371b, 0xf18e2bb8, 0x947157db, 0xf99f50df, 0x500939f1, 0xfd4799cd, - 0x57d79546, 0x4097c8ec, 0xf53b61ef, 0xa0a896b7, 0x91e26e2e, 0x7306c9bf, - 0xb7851060, 0x43f789b5, 0xeb86f17d, 0xbd5fa002, 0x14a0b266, 0x184813be, - 0xcbfe7f9e, 0xe7a25b61, 0xd4972c65, 0x5122c78b, 0x07e1d6f2, 0x35219016, - 0xc029be14, 0xeb3ba304, 0x0e3f529f, 0xa98fe31c, 0xffa843df, 0xc6c899f3, - 0xf7f50bfb, 0xfea11ea0, 0xa4ce3a1e, 0xdda3bf16, 0xf0a34e1d, 0x7ff0aa97, - 0xfd79302a, 0xe02e36f4, 0xd5f9f2a7, 0x7fa0478f, 0x1b6ee0bd, 0x1c277a45, - 0x5d24fe65, 0x0fcbce9d, 0x6ddf6a74, 0x10e16c0e, 0x6be032bf, 0x21268a3a, - 0x5067d68b, 0xffbe775c, 0x07a9bec1, 0xb7212739, 0xa54c4512, 0x9abedfef, - 0xe3a2efeb, 0xb9cc52ce, 0x32521d6c, 0x24d7284c, 0x909634c3, 0x88471a5b, - 0x5d3207b4, 0x448d3f11, 0x58a33b8d, 0xaa559f5f, 0x8a8ab7af, 0xb570a268, - 0x66c8e74e, 0x39ecefda, 0x9c6d76fa, 0x4644a681, 0x52bc7567, 0xfa74938a, - 0xb9943668, 0x7485d8f0, 0xdf62e39e, 0x1778f06a, 0x7e8c2489, 0x010fbfbc, - 0xf193faba, 0x362e79bd, 0x73bc236f, 0x4a528b44, 0x8ca739e7, 0x1b7f000f, - 0x9f68ffe1, 0xd0e5314d, 0x22a3fd72, 0x8f9d7531, 0x1eb9fe11, 0x22827ce3, - 0xcbf3f3ac, 0xdf19cf8d, 0xffe9531c, 0x2d07f029, 0xa0fe00bf, 0xf9551ff0, - 0x32af53a3, 0x3d9af0fe, 0xda1f80d3, 0xe904f237, 0xadcbf2aa, 0xa92cbf2a, - 0x2105f3d7, 0xb8e8111e, 0xfb970e6c, 0xcc1f1440, 0x5960f956, 0x6e6f9e83, - 0x3d317e27, 0x6ee65d06, 0x9a6f7cd8, 0x9f7e75dc, 0xff337ca8, 0x9f88fdc1, - 0x7464f3ae, 0xd3a543ba, 0xf6fa35ed, 0xdeba555b, 0x4e75d2ae, 0x51afc3c3, - 0xc9e641f5, 0xdde41101, 0x9e8d53fb, 0x3d3d1d11, 0x708d3d2a, 0xf3d2a1de, - 0x7a331f8e, 0xa88de11a, 0x9c348cf4, 0xae80c913, 0x5be11af0, 0xf9977770, - 0xccab5c60, 0xde9e9b1f, 0x4755fca6, 0x05579ea3, 0x3475586f, 0x6c56ce4a, - 0x2fabae9f, 0xbdd5cc0f, 0x4ca1acbf, 0x7ea4bed7, 0xd17daeb9, 0xf5753bfa, - 0x758fff32, 0xbbb82fef, 0x7b7ed756, 0xf6bafdcd, 0xeb0fe5f9, 0x1b3d73ea, - 0x9ecfef75, 0x3ed759b3, 0x5d19f4ab, 0x9de28cfb, 0x6574faba, 0xd37deeb7, - 0x066eabbe, 0x3deb7cfe, 0x713d809e, 0xc605fdc1, 0x45b82f33, 0xd473bc37, - 0x1f5f2327, 0xf2c10df3, 0x7c8dcfb8, 0x1637d27f, 0x66a6d6cb, 0x7413ac3b, - 0x124a5c5d, 0xcd326908, 0x0fdf5dab, 0xeb8269d6, 0xa9e4c869, 0xb37ad3f5, - 0x28794649, 0x78489069, 0x2c1c2124, 0xed1c2a36, 0xa47b547c, 0xaa06f687, - 0xb6ba93f8, 0x3f624497, 0x76523ef7, 0x7765f005, 0xcbfd03eb, 0x4da7bb00, - 0xed8debb5, 0x8d291c95, 0x1ac84e7e, 0x626ac384, 0xc4a54776, 0x5772bfe4, - 0x4271017a, 0xe6b83c3d, 0x2905e372, 0x9f02a793, 0x78e4eb64, 0x3a35c359, - 0x9a204efd, 0x6df807dc, 0x8af9eea4, 0xbeead7ed, 0x479fb53b, 0x5741abb8, - 0xb165838c, 0xe81333f4, 0xe67370e1, 0xa700618c, 0x4deb1472, 0x3c2ed07d, - 0x755e2be5, 0xafd01074, 0xbee3cb14, 0xf31e5839, 0xea3cb079, 0x53f2c72b, - 0x11960d5f, 0xfe58dddf, 0xf2c7e7c5, 0x2c7adf63, 0x63d5f23f, 0x01afa1f9, - 0x017df7cb, 0xb6fb0f2c, 0x2f8ef963, 0xaf8b6588, 0x9f56cb09, 0x7726a582, - 0x71ddf13d, 0x093e1d75, 0xcf8317fc, 0xed7f3aa4, 0x7c9d09fa, 0x87dfc716, - 0xb9e1a67c, 0xf2acc1a4, 0x1f8e8a43, 0x4397c012, 0xbda1eb3e, 0xb0f95441, - 0xb763efbb, 0x6bfcb77b, 0x0fea6df8, 0x7e4eb7e4, 0x53f030ca, 0x34fc4f76, - 0xa7e28f8c, 0xb31726a9, 0xfa7e547b, 0x8623cc19, 0x8c0f315f, 0xf6513e90, - 0x826f929a, 0xbaa56c75, 0x601f420f, 0x763aacfd, 0x05b77d1d, 0x10c0baed, - 0x0ece3758, 0xd860dbf9, 0x21fb3847, 0xf7567e25, 0x49f233f3, 0xd05778f7, - 0xa01a59bf, 0xdaea4f44, 0x78638d6e, 0x31489ab5, 0xfddaeba1, 0x2f729e83, - 0x81758a1c, 0x01f7c224, 0x8c4774f7, 0x0cada97e, 0xaf09edf8, 0x72af8e75, - 0x8f63bfa0, 0xca0f3dfd, 0x2f6626a9, 0x68f335c7, 0x93f093b7, 0xc76fc06e, - 0xa77664ba, 0x7dbdbc41, 0xbb42e490, 0xe3d64c81, 0xc3a05fcf, 0x4714fddf, - 0xd6eeb82d, 0x06fe21a7, 0xbd38357e, 0x49ebf817, 0xcf84f7bf, 0x7fef3085, - 0xd27b3e01, 0x45e93d8f, 0x342fc8a2, 0xedb7f9d1, 0x80fb961b, 0x1e5ee30c, - 0x9afedadf, 0x7e5f9e11, 0x4b6e3e47, 0x25b8f8d1, 0xa41f8093, 0xc6d9cbca, - 0x2e81e32b, 0x40f4fd1d, 0x9f77ee4f, 0x7eff8264, 0xdfdf4b3a, 0xe2fec67d, - 0xa70dc225, 0x89243ae3, 0x92bf53c4, 0xd1e36cf7, 0xfc47719f, 0x67d83710, - 0xe0c9d773, 0xaffc9e37, 0xeb3d0cb0, 0x0f670be3, 0x3f04e93d, 0x5f1a656c, - 0x1d063473, 0x982ab2b5, 0xf68f6355, 0xf5f49a57, 0x715cf5b3, 0xc725e710, - 0xeb061ccf, 0xa8e6ab8c, 0x0d3f7a08, 0x959fad4b, 0x738e1269, 0x3c767b72, - 0x4c02fff3, 0x4048ec9f, 0x67d2737d, 0xd9fff7c1, 0x8fd774f0, 0x8d210f06, - 0xe80b33e4, 0xdd96da73, 0xcaddfbfd, 0x825e7083, 0x890929f8, 0x69bf815f, - 0x3b7fffa5, 0xb015fa00, 0x0debf5ae, 0x70f37ef2, 0x3743be78, 0xd64efd1e, - 0xbbe18cf6, 0x204ee5ee, 0xa7be34c7, 0xbaabfbf4, 0xbb62bdbf, 0xc76f46b5, - 0xdeeae826, 0x9d1af4a6, 0x00ff0b5d, 0x1386bdc3, 0x54ab0960, 0xb04db0d9, - 0xda7e07af, 0xf049c103, 0x5ef6385f, 0x79222595, 0x16971464, 0x6385d3e0, - 0x6797fe35, 0xa9ea99ff, 0x048a6f13, 0xa25c8ce4, 0xaea9e550, 0x899bf220, - 0x917d6898, 0xc6c2f6fa, 0x6eb02515, 0x26f9789d, 0x931643f4, 0xc7f82752, - 0x0f3ea4e5, 0x89a7b5e2, 0xf3e418a9, 0x39c77934, 0xad1e4a32, 0x2e9d8482, - 0xe3b7af5a, 0xabaf7fa9, 0xd7d06b2f, 0x525b9297, 0xe97edf60, 0x38049106, - 0xf6fa1bd0, 0xf61779af, 0xacd48cbb, 0x57fb7583, 0xa16bbc6a, 0x5419088b, - 0xf6fd556f, 0x0a32bcf1, 0x71604b87, 0x7a1f6d16, 0x7ff32279, 0x2406662a, - 0x59ffbe85, 0xa95bc8e3, 0x07dfa206, 0xbc7ec1d6, 0x6f713a7f, 0xf7e95d23, - 0xc237e15d, 0x5d03d9ab, 0x3855c3f6, 0x4a73b792, 0xcb1e8620, 0x67263814, - 0x102bbeaa, 0xc7b8ba5c, 0x7bfd4334, 0xd13253f3, 0xde1ed3f1, 0x668c2793, - 0xc0fc03fc, 0xe792ed09, 0xd69ff487, 0x7f82ffa5, 0x68fdff6a, 0xfeba79ff, - 0xfb53fda7, 0xfe05d81f, 0xaffab179, 0x2ff3edfa, 0xa93ea9fb, 0x4e97f178, - 0x13c9d742, 0x9b8a7d42, 0xdb72b5d2, 0x96854ebd, 0x13bf05c7, 0x8044f5f8, - 0xef458e2f, 0x154e0587, 0x41cec542, 0x49fe0ddc, 0xecf93ffb, 0xf11e30cf, - 0x85d136d5, 0xe6edb4f1, 0x61ca99b0, 0x12f2e375, 0x23f58392, 0x19df7eac, - 0x7a4dea1e, 0xfa78abfe, 0x1f902997, 0x8d453942, 0x9ed1852f, 0x79fadead, - 0x5e4fac11, 0x64728ed2, 0xbfc60efc, 0xaffa8898, 0xdaef8a4c, 0x38c4e14e, - 0x8bc55781, 0x6767f1b7, 0x37942778, 0x82fa017c, 0xc7e8227a, 0x572bbf1b, - 0x8235d4ed, 0x8d98f923, 0x190c7bfe, 0xc3517a03, 0x3b30090b, 0x5f99eeb5, - 0x70a11ce7, 0xa6fada9d, 0x97c28b93, 0x83674f26, 0x8f73fe8b, 0x6ddebddc, - 0x6d16f2a5, 0x96eb690f, 0xd7daa4dc, 0x8a565621, 0xf3e42761, 0xdd166e54, - 0xf2b8fa7e, 0x7a9f27f9, 0x7f99e20c, 0xd107bb32, 0xff3c57fe, 0x69e3fbda, - 0x314ec57d, 0xc34d84b9, 0xd274a5ce, 0xbfff4bc7, 0x1e93b73b, 0x4d79bf15, - 0xe7b18792, 0xd27624f7, 0xfdcec565, 0x15d61912, 0xfb83931f, 0x063d88a5, - 0x8a47827d, 0x7ba85ec0, 0x8825bfe6, 0xc7d89e33, 0x18acd491, 0x1afcdcf8, - 0x278003da, 0xaf4aa7a4, 0xde19fa0e, 0x80ba52f7, 0xcbd236de, 0x5522def8, - 0x90bf40bf, 0xfbf94167, 0x07903d85, 0x0dd991f5, 0x617f2878, 0xf3e61395, - 0xf8c35085, 0x537bf1fc, 0x8b959f40, 0x961714fe, 0x13f979ec, 0x5bfe423f, - 0x528ff6f6, 0x9444be30, 0x45ae1374, 0xe79874fe, 0x70b34d92, 0x07894b9e, - 0x71fcb0f9, 0xcb4034be, 0xde29020b, 0xac4e4319, 0x2f939322, 0xd2e250b6, - 0xfe017e79, 0x77efe824, 0xb436c0f8, 0xa024efbb, 0xcea47e0f, 0x580c5a85, - 0xf46160bf, 0x2ebaabfa, 0xa33eb010, 0x7deb77f9, 0x93a7402d, 0xd85495fd, - 0xc112f177, 0xfb83e2af, 0xbfcbf696, 0xd195253d, 0x9e42c889, 0xf75d1dfa, - 0x7873c327, 0xac5445bf, 0xc8efba39, 0xe39d59b7, 0xa7c756af, 0x7ac1c770, - 0x6c4a45fd, 0xd44f35fb, 0xb75d00f4, 0x4a2cf8a3, 0x6ffc99de, 0xbbc99fbd, - 0xe981ff26, 0xfe7ed0c5, 0xf8239330, 0x0a43d60e, 0xdb153857, 0x50e4cff7, - 0x3a3f503f, 0x156f9c96, 0xb7d73955, 0xc285f91b, 0x51f1702f, 0x24e3037c, - 0xdf701d22, 0xfa06e965, 0xf51e947d, 0xaeceb8c2, 0xbc726afd, 0x455bf34c, - 0x9b203ebd, 0xdee81e98, 0x9e23f2ae, 0x53c0c52a, 0x52fc818f, 0x20cbf579, - 0xcc2962bf, 0xcd1dcbff, 0x72a3cfef, 0x935065fb, 0x355ebd5b, 0xaef96dca, - 0xdc9624d1, 0x9377697e, 0x9f4b7298, 0x7b5b94c7, 0xfff9f904, 0xf0d55eb4, - 0x78f00c38, 0x351e274d, 0x3e1dd93d, 0x90f27a8d, 0x8d5e2320, 0x1dfe927a, - 0xf95d7926, 0x8d43e351, 0xab9e2aff, 0x51f402ba, 0x7c6a9f07, 0x1aa7c1d8, - 0xef89761f, 0x6c68f0ea, 0x34fb00bf, 0x96f9ae14, 0x528ed38d, 0x4ed2d257, - 0x7f26df70, 0xaafb8f26, 0xe584f396, 0xf3111081, 0xd5303f43, 0x753b068c, - 0x3d6fdfe2, 0x7785177d, 0x2c8bf13e, 0x445ea02f, 0xb7d2ffbb, 0xf3a04edf, - 0x79e2a799, 0x54fb453e, 0x0239974a, 0x70a38e17, 0x3f8815ce, 0xb7e2113e, - 0x0a34f91c, 0xfae5f98e, 0x4c4dfc3a, 0xa7a7ece9, 0x9fabbff7, 0xb7cb7df2, - 0x1d3f5d29, 0x50bbc844, 0x10bc388a, 0x81d357cd, 0xde7f14ae, 0x00605c51, - 0x5088a9ea, 0xbd77e51a, 0xf3fb3220, 0xa319c2ed, 0x9fc9bec1, 0xf19e2c3d, - 0x7bf460fb, 0x3b3eaabd, 0x41e397eb, 0x650d9fcf, 0xf67b7fa3, 0xac4722d0, - 0x9566d0bc, 0xf7535ecf, 0x5cecda5d, 0xbff94f3d, 0x7da3b48d, 0xc95bb7e3, - 0x82fb18b6, 0x5f4d451b, 0x7fa374ab, 0x8e7f1d3c, 0xe97387ca, 0x51b9f1a7, - 0xf5399b74, 0x4aece084, 0x34fbf807, 0xa1fb0fca, 0x06be05f8, 0x235b36fc, - 0xe231a545, 0xf8a9cf79, 0x6be0789b, 0x0c2dcfcc, 0xc7800be5, 0x8baf3b42, - 0xc9a93c83, 0x143250eb, 0x60789ae0, 0x5347cff9, 0xe21ef63e, 0xeb8f90dd, - 0x3c919d0d, 0x2361fc31, 0xb07fa13e, 0x2e888f33, 0x627bd7c4, 0xebc012e9, - 0x04acb37b, 0x95df35f6, 0xe0b155dc, 0xf5b3332c, 0xbd292e66, 0xbffb8a30, - 0xb3f9bf0f, 0x8a02e11d, 0x9676b38f, 0xff95ddf7, 0x759fdc98, 0x0e5a8171, - 0xf56790f8, 0x71002e64, 0xf9e222b4, 0xe50e04f9, 0xfeb4527d, 0xfe9a6fca, - 0x54f5e43c, 0x89973887, 0x110b57b6, 0xdbd8f809, 0xfb0053b4, 0x289926fd, - 0x6a108f18, 0x8a8ccd86, 0x05111d7b, 0xdff357c4, 0xf80edde6, 0x4cd3373d, - 0xe8652e00, 0x01d82719, 0x512342e7, 0xd79bba0e, 0x5a647c1f, 0x10fd08a1, - 0x3f230fe4, 0x74db2514, 0x499359f5, 0xdba5373f, 0x95647344, 0xeafd063b, - 0xbd67c624, 0xff966fd6, 0x04dbf4cf, 0x5f18dfaa, 0xedfad18b, 0x7df18926, - 0x8d4b7e94, 0xd656dfa5, 0x17c0a9ca, 0xa766f72b, 0xbe575d02, 0x2c4fa4b1, - 0x8fbaf6fd, 0xa86ff7f9, 0xfd6de679, 0x1e1b7ea8, 0x51fadfa5, 0xae2316fd, - 0xa5ea5a3b, 0xcffcb37e, 0xa0ebdfc8, 0xb7cc62df, 0xa69fc558, 0xb5438adf, - 0xfb8adfa8, 0xa97cbaf1, 0xfa4f5249, 0xb397ecad, 0x6dba2eb0, 0xf007f831, - 0x0dedfa0a, 0x38c1cf55, 0x5dfee7a0, 0x3d277d72, 0x3d5bd557, 0x67843ff7, - 0xecadcf4d, 0xd33da1cf, 0x9e990f95, 0xf4c5995b, 0x4cbdcadc, 0xc41cadcf, - 0xbf519cf4, 0x6fd17415, 0x21eafbec, 0x23f47bf4, 0x1b7d7eb3, 0x23992f6d, - 0xfdf42dba, 0x9f3b5912, 0x5a3a3351, 0xd4bbfddf, 0x9f73be8d, 0x3d2e73c1, - 0x823fbbe9, 0x7a841bbe, 0x91c8206c, 0x1c6e3f91, 0xd3e5d368, 0xb1f5f7bd, - 0x79045ee7, 0xfe8f03f9, 0xe62607f7, 0xfafbed27, 0xbb9048d8, 0xaa1e00f7, - 0xf9519eef, 0x47e7d5af, 0x28793a7d, 0x7baaf793, 0x1baafe18, 0xd5df3639, - 0x7586407c, 0xd1176fe0, 0x2f7dbe8f, 0x9b67a3f3, 0xc0d8fa5b, 0x225fffcf, - 0x2bfd25ca, 0x87e28b29, 0x302b1739, 0xce2bb9ee, 0xccfc05b9, 0x80b10239, - 0xd0e0bb1d, 0x7ec0278d, 0x3d71705d, 0xe00bbdda, 0xc8e92279, 0xa1db98fb, - 0xebf6f527, 0xaf9da6bc, 0xf9ae9065, 0x8ccd1310, 0x7157132e, 0x5d59cd81, - 0x5da823f3, 0xc62df986, 0xabdf893c, 0x47cd9ff3, 0x8fe45f10, 0xe5f8cc7c, - 0x72788def, 0xad54bc33, 0xaa78f5e6, 0x89e262e1, 0x2ca4ba52, 0xb72f13a5, - 0x975914bf, 0x39cbed01, 0xf38cb7f4, 0x9c66f0d6, 0xcd4786bf, 0xbea059bf, - 0x24743f3f, 0x86889e66, 0x22f92ee7, 0xf80dde1a, 0x33d34b78, 0x206190d7, - 0x3c981f97, 0x7c0d1f3f, 0x178a7bf4, 0x73ade70a, 0x2bcee907, 0x65e2a3bd, - 0x6148e7aa, 0x24780c8a, 0xf367c035, 0x96be77ca, 0xb377e742, 0x210b9592, - 0x937f59f5, 0x688f103c, 0x1ea3b6b6, 0x9470f8d4, 0x5985c999, 0xf5ef2bd5, - 0x7ae21575, 0x50b9c4d3, 0x3d06c2be, 0x7999e6a7, 0xd7f261ef, 0xbaf7fdcc, - 0x6788518c, 0x91482e58, 0x5d015eb6, 0x86a73fe8, 0x40bc5d18, 0x69cffa17, - 0xe020fda4, 0x73993abd, 0xa6fde187, 0x3f02f79d, 0xcfa56ebd, 0x39cbce41, - 0x0e8616f7, 0x65ca7a7b, 0xc58858f9, 0xc8cc18c7, 0x173f5ceb, 0x5d897bc0, - 0xe68993ed, 0x8e00f796, 0x366e5489, 0xfd00c3c3, 0x46fe8a2f, 0x07c8c5fb, - 0x7503e53d, 0x2ab9efc7, 0x3a075f9e, 0xeddf01d8, 0xde43d812, 0xb47f5b30, - 0x1720af76, 0x3a34de22, 0x65f5d134, 0x2983a314, 0xd66f9e06, 0xbd9e2aea, - 0xef844e21, 0x6ffea06f, 0x7ebb0712, 0xf8d41f5f, 0xc5772cdd, 0xd215c413, - 0xe806f4a3, 0xcd7de8b7, 0x11b7a6ea, 0xa6ae375f, 0x15dc99e6, 0x407d1a5f, - 0x6f0e5e0f, 0xd34fcadd, 0x61799891, 0x467e55df, 0xb3f2f599, 0xe6fedacf, - 0xedab8870, 0x90af50e5, 0x7e2e8250, 0xecccd330, 0x07ab6696, 0x0dfdbcf9, - 0xee45bdd1, 0xa8a67faa, 0x257f0174, 0x64e27cfa, 0x4de80898, 0xa67c9597, - 0xe3007bcd, 0xe0f5e8b7, 0xe907ab75, 0x33ff5dd7, 0xedfecccc, 0xead31ece, - 0x9078c3d7, 0xc7eb28d7, 0x5a47ae33, 0x79a7a95c, 0xbf71d479, 0x71b4bcef, - 0x84beebbe, 0x3c60b497, 0xd89fdb4e, 0x89767bc3, 0x73163f60, 0x0a107dba, - 0xfe6fee39, 0x59bffa13, 0xff7ddd1a, 0x530a3f10, 0xe3bebf3c, 0x9f638c49, - 0x34c8f67e, 0xaf159f90, 0xe542c4f0, 0x838775af, 0x889e5984, 0x45427604, - 0x5dfb8f23, 0xcde70844, 0xa833b288, 0xf1f0c327, 0x5ef503a2, 0xa0732ec5, - 0xf15f7e84, 0x103967f2, 0xc35d6b7f, 0x59ff9ff4, 0x91fd1f95, 0xa807c81c, - 0xbcfed810, 0xa88f3e91, 0xb76a79fc, 0x6fe80e6d, 0xc73b3b6e, 0x2d9c115b, - 0x0ce2a39a, 0x16459bf7, 0xc36ddee7, 0x33ff6c3c, 0x0331e61c, 0x48e7d17c, - 0x53d0fcb5, 0x5cbd30cf, 0xe00624d1, 0xf6c5703c, 0x1710ad9d, 0x8cd0f8af, - 0xfb77abf6, 0xd3ec0919, 0xcf3e2fc9, 0xf1371bce, 0x976878ba, 0x3e76e438, - 0x59f8866c, 0x01ea1563, 0xf5823f5a, 0xfbf71aa0, 0x15b2718e, 0xd97dee2f, - 0xe2b8514f, 0xf13b4f37, 0x36cb705c, 0xb723c627, 0xa05f7e5f, 0x7831dc4b, - 0x9c771abf, 0xf5c105fa, 0xf1dc7621, 0x2127caa4, 0x48ee3eb3, 0x3c6127b6, - 0x5799c292, 0xd17e231a, 0x5fcfffc1, 0xcdf60278, 0xf2faed4e, 0xf2bb8009, - 0xfc4f739b, 0x2a93e294, 0xdbac1720, 0xc3df67de, 0xbbed067d, 0xd27d55f7, - 0xb8d3ccfa, 0x27fad34f, 0x6b7a1bb3, 0x2645fbdd, 0xeeb453ec, 0xe2053afc, - 0x4ef7abb8, 0xf56d7f41, 0x4953934b, 0x2b407f0c, 0xbd037f81, 0xd23227d8, - 0x39b1b9ad, 0x4d3ce013, 0x77eb0ee9, 0x58393c47, 0xb2f4e2c5, 0x11de471a, - 0x4bae5f7b, 0xc671b8dc, 0x3ac1d7cd, 0x65ba28de, 0xf1f88bd2, 0xe1cf4a61, - 0x0ee3a0bd, 0x38209f75, 0xe3f1b2f5, 0x4a0ff0d3, 0x7d660baf, 0xe342fe1c, - 0x0c7cff92, 0xba931ada, 0x7b871f8d, 0xdf6d3f81, 0x2159bf6f, 0x5da39016, - 0x1edc61cf, 0x0f7d47e8, 0x85fcfad2, 0x1cbb884c, 0xc0efdb17, 0x66bdebfc, - 0xd8aaa3cc, 0x53ca01fb, 0xe36f4beb, 0xf7511abe, 0xc7495adf, 0x5127db1f, - 0x56ef3a7d, 0xab3b8b07, 0xb4b88074, 0x6ae7c4ec, 0xb5f199fc, 0x2eee9716, - 0x32d63d1e, 0xabbfed80, 0x5b5591fb, 0x43112cff, 0x0b1b9fbc, 0xd9723af4, - 0x0f0d547d, 0x98c3c02e, 0xd896fde8, 0xfd8efff1, 0x80dd0316, 0x758f609e, - 0x7ad0a7ec, 0x07ab883f, 0xed620fb8, 0x666eb5df, 0x62ad34fb, 0x6d45bcec, - 0xc5a465ff, 0xe812efb0, 0x4f4bbedd, 0x78aef8f3, 0xb42706ca, 0x9d7c574f, - 0xbf5b14ba, 0xd4e16adf, 0xe7be037b, 0x67257ebe, 0x05981bcc, 0x78d5597c, - 0x4a7b0244, 0xf9b4df5b, 0xe7fd529e, 0x78f2cf53, 0xb05d644e, 0x51bbf519, - 0x1613547f, 0x5bc23437, 0xab7a616e, 0x1fad89ba, 0x023976a7, 0xa9cfda76, - 0xaf91bb03, 0x911c77ab, 0x83bfb4fc, 0x45237fdb, 0x60acf2a2, 0xc14408fd, - 0xfd85ea7f, 0x897f6c39, 0x71c6ebf9, 0xf1c752ee, 0xe38f6286, 0x374671dd, - 0x507f0ace, 0x2e7ee762, 0x4149de3f, 0x9dfd0d99, 0xe409116c, 0xf20c9ffd, - 0xe31881c5, 0x5a88b5cf, 0x0fc98b3c, 0x1cf1475d, 0xbb9d83a6, 0xb42513e4, - 0xc63b57bb, 0xfde7087e, 0x19243b57, 0xb57517e2, 0xeeb52f2c, 0x4069dcdf, - 0x5b84baef, 0xdeae3f71, 0xb2575f80, 0x1ae21f2b, 0x51d2c2ae, 0xbd46aec0, - 0x7498a093, 0x1476aff0, 0xce14caa7, 0x469daab5, 0x0b9e3704, 0xc5459de5, - 0x65de1f30, 0xec635972, 0x52f6883b, 0x8bc289e2, 0xe39fd2e8, 0xca469724, - 0x7f968fd0, 0x39696953, 0x052e8d88, 0xb1858c53, 0x99fcddec, 0xdb779c2e, - 0x507fd50e, 0x614aec88, 0x8eb06479, 0xcf8aedb4, 0x43f1c321, 0xb47e50a2, - 0x1db9cfa9, 0x5e83f7fb, 0x4a24eb5a, 0x8a339502, 0x86cf9955, 0x2c23acf3, - 0xe9f0365c, 0x857aff99, 0xf10d6bf6, 0xd9b457e8, 0x25527cb5, 0x46cce401, - 0x41bcc41e, 0x936fe560, 0xe634e13a, 0x25781213, 0x298d3eea, 0xa1fd1dbc, - 0x7c589bb3, 0xff572780, 0xcf8b027a, 0xafc00091, 0x542b2fae, 0xe212cf38, - 0x3bfbc30e, 0x580f181c, 0x9422c6f6, 0x3443a01f, 0xf58a92be, 0xac1b5ee7, - 0x67f01cce, 0xbf555a36, 0xc0b4afc6, 0x6ac59b39, 0xf54a7dbf, 0x18a962e7, - 0x975e41fa, 0xe5faf2a8, 0x9843a2d2, 0x8a59e68f, 0x8e753e7a, 0x31acdcfe, - 0xaa204b4f, 0xfe601c9f, 0xadbc9773, 0xb708cda6, 0xc56b7f31, 0xc35d7d76, - 0x37a027e3, 0x127402af, 0x80e2e5fb, 0x3237e23d, 0x4613d7f8, 0x9afc777d, - 0xb5f8f4d3, 0xdafc7aca, 0xa7f11886, 0xadc3afc7, 0x97e697c7, 0xf8df8776, - 0xc873fab1, 0x8afc2aff, 0x548ed556, 0x4aff4af1, 0x654c292d, 0x42e9dc03, - 0x28c2e518, 0x30f61947, 0x9feeff07, 0xafc5a81c, 0xefd40edc, 0xb87cea69, - 0x1b3becc5, 0xf00f11c8, 0xe08e51ba, 0x79e82024, 0x75d8f91b, 0xfac40acc, - 0x4d7b7c8c, 0x355cf4f7, 0x0b23d5fd, 0x809b57e9, 0x3f23877f, 0x89bef3b0, - 0x05975024, 0xc176ea72, 0x59f41dfa, 0xb8458bdc, 0x17b885f7, 0x5efb820f, - 0xa43e585c, 0x0db4abe6, 0x306e7825, 0x029f3e18, 0xdca1e9fa, 0xf7a069f6, - 0x29484bbc, 0xc51fc1e8, 0x0f03f3b1, 0x38bf65a8, 0x85abd549, 0xef824c6f, - 0xe70ca243, 0xdb42dbd5, 0xdea0832c, 0x2a3de3c4, 0xabfa84de, 0x90d6fc60, - 0x6c5ae0c8, 0x38820c09, 0xc7115ec8, 0x013c5d6d, 0xd87665cf, 0x2f96216f, - 0xccfa16d2, 0x9f4a28b9, 0x7a3d36b7, 0x36b9c415, 0xa9e7629a, 0x7e9ab14c, - 0xec1bfad8, 0xc537b792, 0x1eeaf2ca, 0x51e7401a, 0xbaacfd3d, 0xb879330e, - 0xabf3a556, 0xf9c46f4b, 0x64e214bf, 0xf88a4758, 0x461a6edb, 0x3dee39e7, - 0xb0cf8d41, 0xf528e578, 0x2fd03afd, 0xdfeb5fa8, 0xddc3e9e5, 0xe7020547, - 0x2cd546f4, 0x15eb7f45, 0xca73e527, 0x704a7917, 0x616df024, 0xcdef0128, - 0xd04c7ef1, 0x22dd1fae, 0x4f33f8e8, 0x22f3575d, 0x44c05e54, 0x3edf50f9, - 0xec18222e, 0xfc0f00a0, 0xfd71ed75, 0xd55685f3, 0x149272ee, 0x970df3e0, - 0x5ef20e78, 0x7b89dadb, 0x6dbb850d, 0xa3845f71, 0xfa9c3ced, 0xbe25e5a5, - 0xbf7ad638, 0x62f8caca, 0x9d7044a3, 0x8ed4b8d9, 0x4b03c5f1, 0xf580ae2b, - 0x7b1fabfd, 0x8e7588ae, 0xc53f4a3c, 0x252c7cb3, 0xfe058c9e, 0xbc31cb5e, - 0xc697a7d7, 0xf8d7f7c8, 0x8d6fe359, 0xc697d3af, 0x35e56279, 0x7665637e, - 0x21d2c15a, 0xdafe049c, 0xe38f0e3e, 0x5cf1aeb6, 0x9f8ddcf6, 0x7800c9ac, - 0xd0e74dbc, 0x3884b6ee, 0xb1bd9625, 0xfec4eac1, 0x6bf8d75b, 0x2eef8f21, - 0x27a09c2a, 0x0377efbb, 0x813f5bfa, 0x677c2ca0, 0x73c32fa9, 0x642c4bbc, - 0x85bbc40b, 0x1c5bf4fa, 0x6f93ffc0, 0x7de14758, 0xeb84d4ac, 0x8dd146eb, - 0x08abfbf0, 0x1a83f8c1, 0x8d37edcf, 0xcf3e8e6c, 0xff3584fc, 0xc7a52b59, - 0xd21756b3, 0xe6e3c925, 0x3ff77e00, 0xf209dbfe, 0x8cd176dd, 0xfaabec74, - 0xaf77da43, 0x36dd9959, 0x0ad94e33, 0x64f293df, 0xc7b71394, 0x123c5ee9, - 0x78a04dee, 0x4ea3928f, 0xbbf1f9fa, 0x71d50f44, 0xbb449e14, 0x2892f909, - 0xc5d2ec8a, 0x4728fd29, 0x30905c9a, 0x4d8f2047, 0x885cabd3, 0x1ca83b0b, - 0xc3d8b28c, 0x962477e0, 0x105379d3, 0xfac2c4ac, 0x754e116b, 0x3cc6cb9c, - 0x7997ca79, 0x608a3870, 0x71121448, 0xdf4d7fa1, 0x6d7a7a6a, 0x59794102, - 0xa810b0fb, 0x126cfda3, 0xaf885622, 0x01722964, 0x0a251aa4, 0xef179e32, - 0xff304e5f, 0x78fd96d2, 0x42dd8742, 0x37c47e85, 0xfb5882fc, 0x869c7c79, - 0x401fcf2f, 0x6a1ce46f, 0x8de6003f, 0x73c6cadb, 0x3b4166bf, 0xa87f43bd, - 0xba9158f6, 0xdcfb8efe, 0xc209f2c4, 0x3ef44893, 0x687f519b, 0xebb8c9f6, - 0xbf606b22, 0x189fdc68, 0x055bb49c, 0xcead1bbe, 0xa89f43b7, 0x1098e6eb, - 0xfbf427d5, 0x66c8d0dc, 0xf72b07b8, 0x5dc72663, 0x3f21c9f4, 0xbefbf80f, - 0x17c8c47a, 0x2e54c223, 0x32a1f6d5, 0xeae1a7dc, 0x19fb43a8, 0x9e49de83, - 0xed152a3e, 0x8cdf955c, 0xdbe4d678, 0x77b9f728, 0x0ccd9bbb, 0x1a47e62e, - 0x275c21c6, 0xe836721c, 0xb078b7a5, 0x29f2dbf7, 0xbf5c281e, 0xf4a3f902, - 0xb81f384b, 0x21bfe601, 0xe415bd74, 0x27af7be4, 0x5475fa21, 0xbcd3f69e, - 0x0fae3e27, 0xc04e27ae, 0xf3fef543, 0x46127aea, 0x01c8777a, 0x78e89395, - 0x46ffc689, 0xa3e4d77e, 0xc8de2e0e, 0x047673c6, 0x0b9e59d6, 0x663065e2, - 0x7805c9b2, 0x3aedecd5, 0xfe25bed5, 0x56ffb474, 0x1eba88bb, 0x4f800665, - 0x5ecd44ea, 0xe3a25b77, 0x051dab53, 0x4fdb97a9, 0xfea45ef5, 0x1b39d459, - 0xfe8ed0af, 0x84a2f79b, 0xfe37bfcf, 0x7914289a, 0x898dfc3a, 0x7f15dd1b, - 0xb08471f1, 0x9ffec2fb, 0x230cdf9f, 0x7727dc7f, 0xe25aefce, 0xf5422579, - 0xf5aade47, 0x3f193675, 0xd7969c39, 0xfb682f55, 0x01e9dd9f, 0xa98fbca3, - 0x70c66fac, 0xeef20f4b, 0x25f8a9b5, 0xb3e80664, 0xb76a61f1, 0xff957564, - 0xbcfceaf3, 0xb6f78636, 0x8307db5b, 0x3de7ad3c, 0x2f687135, 0xb0264c46, - 0xb413762b, 0x8ffbdc7b, 0x5bde513a, 0x4feb7492, 0x8fc0bb57, 0xa7d9a9f2, - 0x7c6a5d9a, 0x552ec3af, 0x3e2d1bd7, 0x795135ca, 0x193cf0a1, 0x1c03f1e7, - 0xbfe62e75, 0xd05701c2, 0x3d584f63, 0x365fc075, 0xd838973a, 0xce12192f, - 0xb096f162, 0x93bb3e4e, 0xde419b47, 0xb03f1482, 0xfae9f9fe, 0x1eeb8837, - 0x0971b19e, 0x85aa5e0c, 0x97e9bec0, 0xd560d847, 0xfbc7f304, 0x6bfbb0e5, - 0xfbb2e5fa, 0x31c73732, 0xa18b65fb, 0xfa5ac27c, 0x144bcc18, 0xfb9cdf88, - 0x5006e1fd, 0x64f90e21, 0xf800d29c, 0x382b14b0, 0x71170c8f, 0x19de9473, - 0xbc839042, 0x994ac489, 0xd247f163, 0xfb48ffb9, 0xf39128cb, 0x06323f81, - 0x9a373c12, 0x9e7d8a11, 0xf13895e8, 0x8debd987, 0xbcc1ce5d, 0x41cfcaa2, - 0xa937ce89, 0xe9839d84, 0xf050fb88, 0x8eadbf01, 0xadb2715b, 0xab3ed817, - 0xd9e1813f, 0xc101bfe8, 0x5a825e60, 0x822257bf, 0x2bfd1135, 0xdfaff03f, - 0xcaff4164, 0xd041dc46, 0xb1c41fb7, 0xce3aecf8, 0xbfea1ebd, 0x702dda10, - 0x37268fcf, 0x343c3c9a, 0x40b716e1, 0x775e755f, 0x5f7c0736, 0x00ef172a, - 0x9c275b9e, 0x6716bc1d, 0xf8c99ed2, 0xf975e14e, 0x9afd1af6, 0xacfd1d44, - 0xd6895710, 0x08690ef3, 0x5cadedd8, 0xaafc1b9c, 0x831ce5d6, 0xe7a8b397, - 0x3cdd0411, 0x1fcc6cd3, 0xe7f55369, 0x90b2e3df, 0x84f5b51f, 0xc63d6fce, - 0xe8f30d7f, 0x386a8738, 0x973c6a77, 0x11dd969a, 0x7cc74a07, 0xee0952dc, - 0x43672332, 0xbce3b436, 0x124cf6ce, 0x6a64bce3, 0x5cf31ac4, 0xbc5256b0, - 0x4b780d7d, 0x40126b15, 0xcedea71f, 0x1f1188f4, 0xc47f9c6d, 0xfb47d841, - 0x1f331883, 0xd2d32b45, 0x4c584a6e, 0xbf4b4fdf, 0x79ed4b01, 0x19885d83, - 0x71b24c57, 0x64dcec3f, 0xfc18b103, 0xed1b24cd, 0x9de7b4ef, 0xff1415f7, - 0x37bb8c76, 0x37bc31c4, 0x37bc31c4, 0xe53e1a48, 0xcebf9078, 0xf7975bba, - 0x4967c1b4, 0xd10f2010, 0xb9f28e9f, 0xdde8c5c4, 0xf682bef9, 0xdca21f4d, - 0xc4941730, 0x436c9106, 0x21f167be, 0xafc87ced, 0x4024cf7c, 0x96db94be, - 0x16fbfaa5, 0x0604df46, 0x530df9f7, 0xb214dc70, 0xe2983ac6, 0xc9a96979, - 0xd3a3710d, 0xc2723f0b, 0x1985e991, 0x0f20792d, 0x1b8f79a7, 0x984a97e6, - 0x8e6cb85f, 0x2ed30814, 0xc2a81b93, 0x01ba7462, 0x4ccb3bf7, 0xc7aef331, - 0xe9fed8d8, 0x961738d1, 0x90d36969, 0x92f59d4e, 0x8c4bf004, 0x35e54a7c, - 0xcea8f17d, 0x6f94cc73, 0x790c5b14, 0x1349136b, 0x185beb87, 0xb1ac95f1, - 0x35b7aab3, 0x39064979, 0x52ab7d84, 0x3a3547aa, 0x4d5f500f, 0xfe28b8c1, - 0xbfd7a171, 0x79c37f06, 0x45ea015d, 0x10c88e4d, 0xa0ade7a6, 0xa1e2a377, - 0xe83f7b6d, 0x9f8efb0f, 0x0739dbfc, 0x55fd3bec, 0x9e807768, 0xbbcf7e3d, - 0xf4c7380e, 0x2e2c3dc9, 0x4fc18772, 0xfa63645b, 0x74ad8f7f, 0x8177e01e, - 0x9e791fef, 0x77257e28, 0xe593fdb3, 0xde70de01, 0x506f7f5d, 0x70c93055, - 0xf11f908f, 0x1fdea55a, 0x46c7a466, 0x2cb78b1b, 0xca59b1df, 0x4f7c6190, - 0x5c7f8c25, 0x378f43f5, 0xd1dfd03a, 0x63b859e0, 0xd9be0484, 0x7566435f, - 0x6445bdff, 0x025287eb, 0x151e67fb, 0x0f38466f, 0x2f6af7aa, 0x8fcb25f9, - 0xdd63a329, 0x27b0f54d, 0x187bcec4, 0x13e4b1e7, 0x129528b9, 0x1cfdc96f, - 0xfef0ddfa, 0xf33d743d, 0xee1f7ddc, 0xd9e719b3, 0x051f5ef5, 0x2a65b3fd, - 0x6de78dbd, 0x3ed88597, 0x41e262f8, 0xfe72ecf9, 0xc5cec436, 0x678de318, - 0x00db650f, 0xa9b0bf0f, 0x323cc4f1, 0xef6dce06, 0xfe20343a, 0x9f56f772, - 0x828bef52, 0x3ca1bb7b, 0xce5823ee, 0xe2902303, 0xf6f432bf, 0xd55fc05d, - 0x3ef13b4d, 0x8faaefb4, 0x9c2742aa, 0xe9ad4b90, 0x6e876a25, 0x8b20f903, - 0x5a7d9d39, 0xc49cf9bd, 0x9f866afc, 0xb7e7d4db, 0x20723e01, 0xd9fe5bdf, - 0xdbef4a04, 0xd1f3c52a, 0x6f3da5f7, 0xf7c3efd3, 0x3cdabe76, 0xed6b79b5, - 0x9c5e6a55, 0x0e4d3bf1, 0xb97ca9e6, 0x75f4eb78, 0xea8a297d, 0xa9917ef6, - 0xf3c3939e, 0x2d9f1a42, 0xe945a523, 0xa349f831, 0x84df076f, 0xd3f38e7e, - 0xbeb8bae8, 0x3f83c54c, 0x4c4fdd4d, 0x91957883, 0xa73a7a8f, 0x32462add, - 0x7c8dbe41, 0x7dcddad2, 0xb31b2128, 0x4acb162f, 0xa8cfc411, 0x15cebbf9, - 0x171cdf65, 0x14fe0fea, 0xe32b6ee4, 0x083d0efb, 0xf7e8314e, 0xff5c4537, - 0x54e43a57, 0xe90fffb8, 0x13f20e37, 0x4f787ecc, 0x4f98e71b, 0x808a0651, - 0x4f2c62ff, 0x81954afa, 0x97db3a83, 0x04e73c6e, 0x086dbbfb, 0xab51b8c1, - 0x69ef0f43, 0xe37a8f1b, 0x4a8f4ab4, 0x3f9be5a1, 0xdadace83, 0xc7177982, - 0xa771a92e, 0x58e2e64b, 0x39d8b4f3, 0x7778bddd, 0xf9a872a8, 0xfa540b35, - 0xfb6211dd, 0x4d370be9, 0xc9747a47, 0xa1fd54bf, 0xf50e46b2, 0x4b3e918e, - 0x3e63d7dc, 0x3e40a2da, 0x5e85df7e, 0xbba441e4, 0xda776e91, 0x371eec5d, - 0x7b8246a1, 0xe26d8eed, 0x8571ff70, 0x73ff7b10, 0x9df4ddb6, 0x479c63e6, - 0xdb2ff077, 0x2faebb5a, 0x908ff981, 0xf08dcf80, 0x425ff36b, 0xd4a7a614, - 0x2f3776f9, 0xf2c49912, 0x7f75d434, 0x815b9c39, 0x790793fd, 0xc6adcf96, - 0x35f834a1, 0x28f38d78, 0x7cf12be2, 0x8f035b41, 0xf877d979, 0x77067dd9, - 0xfd70e5ac, 0x9a4e8eed, 0x7bf6d15e, 0x30ca9baa, 0xfb43cb6f, 0xedb63b01, - 0x29f6c263, 0xcf7873d6, 0x0cf4b75b, 0xeea57cb1, 0xa30849e8, 0x374a62db, - 0xdebb3ff0, 0x0caf909f, 0x0a27de8c, 0x8c0ca0dc, 0x4122b7de, 0xb15957cc, - 0xf9eeba7d, 0x8e35768d, 0x9ef5eaa5, 0x24d48fe4, 0x696f8cc4, 0x9fc9a6f2, - 0xda778f26, 0x0a6f6665, 0x59198381, 0xd1879f80, 0x7afaa1bf, 0x3df99d9e, - 0xafa5cd0f, 0xa73c6f54, 0x3258a7db, 0x096bd196, 0xbbcf825f, 0x0f14bbd3, - 0xd8bdbd3a, 0xf8c3cfae, 0xe6d1f3a1, 0x3689c9a1, 0x189ca33f, 0x43d237bf, - 0xe919ef8b, 0xc007a462, 0x5bc67e09, 0x35816d7b, 0x38b7ce14, 0xaf7fb706, - 0x4d6ee115, 0xb9c0ac9b, 0xf9f4eacd, 0x3e01fe58, 0xb0fb074c, 0x768eceb4, - 0x8d87eaae, 0x225c5dea, 0x5ecbb557, 0xd9232ab2, 0x24d2a7b9, 0xb58993e0, - 0x17161991, 0x583e8f21, 0xa4f7045c, 0x32387c4e, 0xbff14203, 0x5646f07e, - 0xd77916df, 0xfcfb86e2, 0x690a8a4b, 0x2fd071fd, 0x95fa2fa0, 0x6efbe0db, - 0xf973c4eb, 0x1fdeccba, 0xcf9d2e65, 0xed66b1ee, 0xb33ed495, 0xf2aef5d0, - 0x4157e0f0, 0x4a5b2b7e, 0x542e218a, 0xba781109, 0xce2955de, 0xad872db0, - 0x7be9e3fb, 0x4f3cd91f, 0x76ee21d9, 0x8bae2d71, 0x94058795, 0xc588722f, - 0x573a0567, 0x6d6efd2b, 0x2993b51c, 0x5a26d77e, 0xd317e0dc, 0x97f07ee7, - 0xb22a26d7, 0xa35cf51c, 0x70077c1f, 0x7cb135ac, 0x0c6ffd82, 0xc65c8f8e, - 0x23efd82e, 0x34cfe025, 0x1a582cfb, 0x1725f3db, 0x37c8e79e, 0xb18978b1, - 0x76bb6dfd, 0x00ce49ae, 0x243ea8be, 0x1fc3fca1, 0x84559fd8, 0x613549c9, - 0x0eaad0e7, 0x53773c13, 0xcf08a87d, 0x84b9c0dd, 0xe07a754f, 0xa6ee735f, - 0x9e18af93, 0x44ae040a, 0xd0b71a88, 0xf9d5d56e, 0x9810d354, 0xdce3e10f, - 0xcf846e70, 0xa2ecd530, 0xa0afe7f3, 0xe087c525, 0xff70f372, 0x89e4fd4c, - 0x559fdc3c, 0x2d79aa27, 0xbe3e7626, 0xe557dd63, 0x39fb2b4f, 0xdd028f4a, - 0x25b1ff4f, 0x53f6c6cf, 0xe6d6afd0, 0x8429c75b, 0x35ed7f03, 0x7219e782, - 0xe0334993, 0xb19446cf, 0x47166fc0, 0x6c97caa2, 0x65fe9b3f, 0x9b36e940, - 0x7e53237e, 0x9fc1faff, 0xe3bbff22, 0x68b2ab4d, 0x59f8739d, 0x2e74c33d, - 0xef30b28b, 0x6bf565a8, 0xd006e74c, 0xc358e8ba, 0x4af1b0ea, 0xa3b33e17, - 0x143fc8ae, 0xba3171c6, 0x01ae50ee, 0x2c4c16fe, 0x901c23ae, 0xcb477f70, - 0x794b5957, 0xe2d1f806, 0x5d747a60, 0x3673c16d, 0x28179b88, 0xec4fe432, - 0xfa41ef51, 0x5786a5be, 0x7f4266de, 0x7fc04a09, 0x53e183bc, 0x54690ba3, - 0x5e3c81ae, 0x81ae5412, 0x0e7ebd7d, 0x7e83a24f, 0x96adf23f, 0x1bcfa089, - 0x0f28f9df, 0x82bf73ef, 0x2df233f5, 0xf9d243ea, 0xff6dfe9c, 0xe4fbd1cd, - 0xa9f91cfd, 0x03251df0, 0xec9cafda, 0x3951b722, 0x2c8853ac, 0xad9f8365, - 0x091b2ff7, 0xd91f4fd3, 0xa070af4a, 0x3ae3093e, 0x67bb13f6, 0x7e8dd400, - 0xec496933, 0x949dde55, 0x17ee3773, 0x7d346625, 0x85d610b8, 0x4a7bb1df, - 0xfcc14538, 0xee3b17d3, 0x9718236b, 0x373891b2, 0x9b898dc4, 0xd453f9a4, - 0xf1899af8, 0x945e7255, 0x87ceacff, 0x79085f7e, 0x2c6c63f2, 0x8fce81bf, - 0x823afd07, 0x848e58c8, 0xa0365938, 0x3df583d8, 0x4fe1f824, 0x588fff69, - 0xb2ca7c59, 0x8fe2e89d, 0xb7160e65, 0xe2c9c079, 0xf062718f, 0xe22bb016, - 0xd81710ce, 0x4b8f6d15, 0x0bcfee02, 0xdf709bae, 0xe309a0ee, 0x018b4fdc, - 0xb517ec17, 0x5bc8255f, 0x6d7f6748, 0x7eb5dd2a, 0xabe4911f, 0x0bf7ee20, - 0x9d3fab27, 0xbb8f304f, 0x801484fd, 0x0cc4dcfd, 0x3c744d4b, 0xd9839e69, - 0x1573bfbb, 0x043a04cc, 0x1811c6f7, 0x38becc7f, 0xb9e3d013, 0xe056b91d, - 0x4701178b, 0x66890f14, 0x5fd09dd7, 0x6f0a39e2, 0xf9673e16, 0x223c82fd, - 0xfc77e29e, 0xee19768d, 0x1ada7ad1, 0x56f311bc, 0xbde1379f, 0xee4a2fc1, - 0xf17f50e9, 0x3d02ecac, 0x305674fc, 0xbcf3e70e, 0x62f3e709, 0x2bd5fb5c, - 0x0c0fdc29, 0xc12ef161, 0xcfd00446, 0xbe40a982, 0xae5f3e93, 0xafa6b1f2, - 0xd11c8137, 0xc11c23fa, 0x29820c73, 0xcb48e51f, 0x276b6a27, 0x67d44f98, - 0xfc0f0b66, 0x8b5d371c, 0x8879853b, 0x25284d17, 0xb04dcf68, 0x05ce788b, - 0xbce199f2, 0x0f5544db, 0xb2b8fc4f, 0xbb07e584, 0x9ebdc30f, 0x7ef576cd, - 0x739f7530, 0xd727ca92, 0xa16f0891, 0x245dd7ed, 0x4d27886e, 0x8fdfa8ba, - 0x5f60ca78, 0x57fb514e, 0xf0855dda, 0xede89f38, 0x450d29bf, 0x2c3d6027, - 0xfc008a20, 0x6862d934, 0x09d23b07, 0x9febf0f7, 0xfd50e03f, 0x19924cdc, - 0xeda6c79d, 0x87e14d43, 0xb5fb446e, 0x5e037258, 0x0f95da76, 0xdfc03f20, - 0xc5cb9222, 0xb1f29f25, 0x1721c37c, 0x2cae046d, 0x8769fca4, 0x50dd5cf9, - 0x79d2b7ef, 0xf5903d5f, 0xfa087c0f, 0x93c7cae5, 0x8fdf4093, 0x95a5e957, - 0x7f01df1a, 0x7f19e2b9, 0xca7786b9, 0x2c8ed3e7, 0x37934f7c, 0x67e83be0, - 0x1f98188f, 0xf29bbf6b, 0xafc0d3eb, 0xfd04ed3b, 0x5ba59fb8, 0x699c80e6, - 0x7caab4e3, 0xd5d72c6d, 0xbf0fdcae, 0xc0bfe4fb, 0xbec28dd6, 0x75e8a517, - 0x83024fbf, 0xcfd72bd7, 0x68790698, 0xccf31176, 0x5173d452, 0x1e92fcd1, - 0xdf1a2fc5, 0x9c59dab5, 0xc99fe348, 0xe1e5dfbb, 0x840be4f9, 0x8748b2b8, - 0xcff1a2bf, 0xf7187f44, 0xe6122781, 0x67f9189f, 0x93fc3757, 0x40165e7f, - 0x9fe1756f, 0xba7f8c43, 0x0fda1be3, 0xe4616bde, 0xaa1c779f, 0xff2dddbd, - 0xfcf3c25c, 0xbe4ef7ab, 0x93657eec, 0x6a9f9f4f, 0x62d9c72c, 0x54bb2fe7, - 0xea96efbc, 0xbd01ca6f, 0xcec4d531, 0xe32409ef, 0xeeef0a16, 0xfcdeed38, - 0xefa86c9a, 0xda1e9814, 0x1ea33219, 0x78f769da, 0x669b7e30, 0x0557e761, - 0x23ce044f, 0xe45afbb8, 0xd921dfe8, 0x587660ee, 0xfb8f0c50, 0x37f1ec02, - 0x9d8c1f18, 0x2a43cb9a, 0xa662fa5a, 0x971d4617, 0xcfefc336, 0xbfccea3d, - 0x06967c00, 0x79dfa3b8, 0xcf784a8f, 0x0951f552, 0xf76fe3f5, 0xf1045dbd, - 0x79cf2d51, 0x8bb79ecc, 0xfbc2860a, 0xa1fedf8c, 0x8ead65ea, 0x5f404047, - 0x1fddee1a, 0x4b1e71d7, 0x297e6f7f, 0x674e51f0, 0xf93ef1bb, 0x3fdb1c60, - 0x11644d99, 0xb4719886, 0xdeb85ef4, 0xfcaf78cc, 0xff3b30ec, 0x27b0f336, - 0x2af2bdf6, 0x37ef187f, 0x8a77f6a7, 0xe7efec13, 0x6841f65a, 0xdd6cc884, - 0xd7354a0e, 0x26a33f30, 0x9349f81b, 0xf8a3fc43, 0x44327e0b, 0xb706bbf7, - 0xd07ff3a9, 0xa9fbb02d, 0x4bee1222, 0xefb09cfe, 0x363aea82, 0x40f4c9ca, - 0xe617eaee, 0xcb239c03, 0xcba06695, 0xd7162eb3, 0x5b0905f9, 0x6e6e81b2, - 0x8253f701, 0x0bf93ca2, 0x223df3ae, 0xd3b10e94, 0xe27d3df6, 0x8ff8c246, - 0x9c633d3a, 0xed099f60, 0x31bbe087, 0x824773e3, 0x588fb71e, 0x9aeb049b, - 0xab853706, 0x13bd9b78, 0x81ae0d0e, 0x8f97c64e, 0x00c6cb3a, 0xd03be01e, - 0x8e474d4b, 0x8d7be059, 0xcf7b821f, 0xe2883e30, 0x4e83e00b, 0x4016e0be, - 0xa283c35d, 0xfdb7cfae, 0x8b42f88b, 0x17c8f46b, 0x7e70b710, 0x0b98be2f, - 0x05f23578, 0xce3ce7b5, 0x505cf618, 0xc6937962, 0xe7b13fe7, 0x896efbe3, - 0xd913de60, 0x6bbf6567, 0x7dc049e8, 0xd8b8df90, 0x1c9f6d98, 0x28a6a4cb, - 0x7664e559, 0x2a3bf6bd, 0xda1cc223, 0xa2a8239f, 0xbced0db8, 0xdd27a87e, - 0x31c8fe2a, 0x46fb838e, 0x033e3731, 0x1270d0ec, 0xcc236bd8, 0x87906125, - 0x1989b65d, 0xdae63f60, 0xfcc36426, 0xfab21e5f, 0x5ed2584d, 0x9bfe5bee, - 0x7da772ad, 0x66c3e9a5, 0xfc6d5bb5, 0x4c7f2a35, 0x2779d852, 0x70d1ebd0, - 0x9003eb68, 0xc2e0e009, 0xdadf4db3, 0x22878f50, 0x00936f14, 0xfd878a0e, - 0xfb04691c, 0x24a4df21, 0xb03b064f, 0x3800584f, 0x9d7ef6db, 0x92cef109, - 0x021febd0, 0x3eda25bc, 0x0fbf5bac, 0x35b7b46b, 0x3ff3487b, 0xf3497b34, - 0x82aec17b, 0x1fd532f6, 0xbed99971, 0x05b084d8, 0xe47853ef, 0xa2957cac, - 0xe740b3ca, 0xe3cea251, 0x7082d266, 0x4ca9f769, 0x7251f153, 0x39abfa88, - 0x54c84ed0, 0xeaa9878a, 0xdd532a7d, 0x6e22fbfa, 0x3efb1b1e, 0x9e9fad15, - 0x1bae37de, 0xa3f61ad7, 0xc879687e, 0xf94feec7, 0xc3f98fbd, 0x7ef007e3, - 0xb1dfd601, 0x09feec59, 0x21c3c317, 0x763af629, 0xf1eb9551, 0x9c0e48a6, - 0xe7bfdec7, 0x1e6eb8ef, 0xf7f7f3d8, 0x771c8ec1, 0x97902042, 0xa8c4fe3b, - 0x180fcc78, 0x695f232b, 0x6f3f7afd, 0x9cf611b4, 0xccdeff44, 0x728f0a41, - 0xc167c025, 0x8f5395f2, 0x9dfd0a3c, 0xe8902a3f, 0x92451f73, 0xe5c42067, - 0x1ddfd48b, 0x7b31c83a, 0xa83f6b4a, 0x11c7defe, 0x21216f95, 0xc567bb43, - 0xa9e7451c, 0x1a1ffdea, 0x2f1ea75d, 0x74e4213e, 0xfdfc0fa5, 0x5a10e233, - 0xaa9ce1fc, 0x9ff3490f, 0xf5ce7cf0, 0x600a778d, 0xc69f5fbf, 0xdc6a2513, - 0xe9ea641b, 0x4e21c547, 0x6ff60d3a, 0x4e8f33f3, 0xb7e5bc83, 0xf4814c78, - 0x99be7686, 0x3e16f503, 0x462abde6, 0xba1f5efc, 0x9955ef13, 0xa3e4cf1b, - 0x5fc7f1a7, 0x3864f94d, 0x3b309dd0, 0x4bdd8f30, 0x81efa462, 0x1491ff3d, - 0xbe3dda19, 0x91bfa3bb, 0x2a9caf0e, 0x9eac7dc0, 0xdbe461e8, 0xfe9e747d, - 0x5377e12b, 0xbf8fc42d, 0xfac2ea9b, 0xac34beab, 0xddeafc6b, 0xd81264fb, - 0x4e9f1a79, 0x337c6249, 0x49a3f76e, 0x2f49dec4, 0xc586de23, 0xc97ffe33, - 0xee25d9aa, 0xa3e8d359, 0x843ae977, 0x2d27ea8c, 0xaa563790, 0x70fb3ac2, - 0x4425da11, 0x5c62cf3d, 0xb7f366df, 0xda75014d, 0xccfeefd3, 0xf57acb94, - 0x6fc5397b, 0x0eb00bd5, 0x99ab0916, 0x78ed531e, 0x9d231e0d, 0x08a523df, - 0x19f0777f, 0xe708c0f9, 0xf6f91d4b, 0xda07ae0a, 0x18cce0ef, 0xc6262598, - 0x8f868798, 0xc7ae8499, 0x8f5fbdd9, 0xdbd78c6f, 0x178ee7ef, 0xdad011fe, - 0xe919bc9d, 0xf4d76c66, 0x900c1147, 0xec1fa58b, 0x29f1b993, 0x8ba2df48, - 0x3ae85112, 0xcfe9fa43, 0x2b9293f5, 0xb956df91, 0xf8eeb3d8, 0x4f22faad, - 0xf93b233c, 0xd87a6c4e, 0x5bb77c06, 0x1c41b7a8, 0xf4fb3af5, 0xc2bd103a, - 0xe2660bcf, 0x131115fd, 0x94dad081, 0x886699d0, 0x243f7833, 0x20a1be78, - 0xf0327fb4, 0x0b42abe9, 0xe76d59fa, 0xca387909, 0xd50a6cee, 0x6b2ec0d9, - 0xf3e7664a, 0x5d10260e, 0x78c5f4fe, 0x8e9a6fa6, 0xc4a69d9e, 0x62ee1f68, - 0x28833cfc, 0x9ff439c9, 0x7f29eb45, 0xc7dc1f80, 0x42927181, 0x325afdce, - 0x39732dd8, 0xf6da23f4, 0x992d798e, 0x7b7adbc2, 0x2999ea02, 0xe9ddf74d, - 0xfe0884a2, 0x6f3e2463, 0xfef0e32f, 0x8dd92284, 0x59c5a2f5, 0xf98df7e8, - 0x09466926, 0xa220dfb4, 0xaf8533df, 0x755e2014, 0xabc38d3a, 0x9170f63c, - 0x623df85a, 0x0e3674ff, 0xc093f971, 0x24a77d3f, 0x66fe0469, 0x07d5ac9e, - 0x122eefe1, 0xfab6ff83, 0xcdfb73a5, 0x2cf57db4, 0xa78df30e, 0x3f8832b8, - 0xd68a7f8a, 0x5baf384b, 0xc005a942, 0xf58a33d7, 0xaac31ee7, 0xd4ab393d, - 0xfbd10246, 0xe50b9cf9, 0xfdb5a0fa, 0xf11dfc56, 0xf98122bd, 0xa37e7269, - 0xe7b3efca, 0x9bbee924, 0xa9dd984e, 0xaa4dd5c9, 0xfaa8ddfc, 0x193d73cd, - 0x094bf1ba, 0x40fe87b3, 0x64810bda, 0x7ed8b8f7, 0x96f6b4f4, 0x25e1f3c3, - 0xd068dfbe, 0x310d3787, 0xe57cbdf8, 0x348be45a, 0xc8f78dce, 0x37edf5b8, - 0x8dd7d58f, 0x0fd46bf2, 0x8f8b20b3, 0x3427aaef, 0x2f6b307d, 0x683c422f, - 0x33c53e56, 0xbb7ac5da, 0x317d27bd, 0x7d1bae26, 0x17be4971, 0xfa2e90cc, - 0xefe2e3e2, 0x4b7e2fa5, 0x54b196dd, 0x578edfae, 0xa4fecdd7, 0x298de83f, - 0x81478efc, 0xbae8da8f, 0x47c18e69, 0xc5a3bada, 0x1ca88a01, 0xc5381ea3, - 0x5ca663f6, 0x91fe274c, 0x0e80719d, 0x12ed423d, 0xa97b0c77, 0xe51b3e35, - 0x68ef43ab, 0x2eca257a, 0xb87ef311, 0xda85325d, 0xc02e52a3, 0x2be10fd7, - 0x2925ef52, 0x882b8482, 0xc19da61f, 0xa0579038, 0xcfae2cfe, 0x817f224f, - 0x3b12e3fe, 0xaf68c3e5, 0x0ae87168, 0xe94f6697, 0x1e23a5f9, 0xc3dd9339, - 0x1149f1aa, 0x7fe413e0, 0x04fb8f26, 0x7fd41bff, 0x8000b303, 0x00008000, - 0x00088b1f, 0x00000000, 0x7cc5ff00, 0x55547809, 0xf579f096, 0x55492d5e, - 0x146caa92, 0xb612f08b, 0x84582484, 0x5916ec80, 0xa014a358, 0x8168cb80, - 0x9a126b0b, 0x69ee9c71, 0x0242a6ff, 0x83b74343, 0xe8cedad2, 0x3ad857f4, - 0x08b41a83, 0xd09d0301, 0x584c5015, 0xf82e0834, 0x1a6d1ad9, 0x84490ed1, - 0xbfbb46d6, 0x739cffcf, 0x2aaa4bef, 0xffff4d85, 0xb49fdf3f, 0xdeefb97d, - 0x67b9ef77, 0x979ee73f, 0xb3559bdb, 0xf6e008ad, 0x14078a99, 0x77f1d000, - 0xe042c022, 0xadacc37f, 0xc78ef016, 0x69fcd7be, 0xe7f80d87, 0x9c2ffc3b, - 0xa42cfc90, 0x900bcf50, 0xce54b009, 0x7d57fc5f, 0x3c5e3d33, 0x52fe7a27, - 0x92b9fd98, 0xf81b700c, 0xf71c30cd, 0xff8ec5f3, 0xc7154bec, 0x7e8b2e97, - 0x4a4ce99e, 0xff8790bf, 0xbe230118, 0xd4ca0153, 0x22b79dba, 0x5527ddbc, - 0x334c558f, 0x390ffed1, 0x350ffec5, 0x7c800c97, 0x1674df80, 0x3db1f8a7, - 0x1c2111b6, 0xd1bad00d, 0xec71edc6, 0xefc5f107, 0x3c66e7e8, 0x21fc059f, - 0x52b4b607, 0x4801b721, 0xc4ed1805, 0xff602745, 0x0d3f9e2a, 0xc02486c7, - 0x5c2473ef, 0xe7af00d9, 0xf104e798, 0x5eb8c3bd, 0xe30dd700, 0xf75c01fa, - 0xf72746c8, 0xe6e8db5f, 0x442e0dfe, 0xfac0066a, 0x37af2714, 0x8776f72f, - 0xe35bdf1f, 0x50e7e6cc, 0xf844da3e, 0x7b2fe036, 0x1004086a, 0xac77afdf, - 0x807494d0, 0xb1e2b72a, 0x01d1f566, 0x8e58e34f, 0xbe25cbf3, 0x102ab72b, - 0x1fe5e7c4, 0xc4072bae, 0xee33575f, 0x2aa9f887, 0xfc368355, 0x63d34967, - 0x0cdf453b, 0xdefa08d6, 0x33028e22, 0x86cd16b5, 0x28f02cfb, 0xf1f7151e, - 0x6ff78936, 0x1d412af5, 0x278b79ff, 0x63871e9a, 0xae58bee8, 0x0ffe80b3, - 0x47305bdf, 0x9d718609, 0xdfa29305, 0xd6757c5b, 0xfed8cae7, 0xe898b47c, - 0xbf3fb63e, 0xb7744edc, 0xc1863fe3, 0x95fba230, 0x8d6fa58b, 0xc5ba3e85, - 0x8e74b1b6, 0x9d16bf1d, 0x673a27ef, 0xc6ce9b5c, 0xce8b7ffb, 0x904e110f, - 0x1bf470be, 0x30049e8b, 0x1a07e9bb, 0x55f679d1, 0x32add78d, 0x861433ce, - 0xd4fe79d2, 0xb76ff859, 0xaafcdf42, 0xfe2d2fa6, 0xe79f6b82, 0x22bfed6f, - 0x69fde745, 0xdf7e6f5f, 0x8034f3be, 0xf9ce78c1, 0x8df8d139, 0xbd2c6ba5, - 0x62f7ca16, 0xe635b5e9, 0xa05d061c, 0x60689913, 0x555fbc1c, 0xd16b8e19, - 0x162e97ad, 0x7e4f08ff, 0x5f8071ff, 0xd6fab9f3, 0x76827493, 0xe02057cd, - 0x03c84732, 0x052075f2, 0x0ade5be9, 0xec0444e1, 0x3e738b96, 0x28f5a8d7, - 0x39c469f0, 0x8353e7e8, 0xfadf6ace, 0xb2075765, 0x96fb19fc, 0x14b01069, - 0x972173d2, 0xd255f0b1, 0x7e69233a, 0xcb68f980, 0x10b2d32e, 0x05ba639e, - 0x9b51f5ee, 0x4e03da28, 0x9d1a07a1, 0xfbb75e26, 0x6e099b2b, 0xf0e57804, - 0xf8406280, 0x09e7563c, 0x33218bd2, 0xc945fbf0, 0x9cdfcf3a, 0xdc048104, - 0x9b76b41f, 0x2b44f90f, 0x3941c806, 0x825906d3, 0x9d64b835, 0xdc91f616, - 0xa8347b75, 0xd1bbb946, 0xe048ef78, 0x6c92402e, 0xa99474fe, 0x0fde8b26, - 0x79c54fb7, 0xfa6a1537, 0xb2e29c36, 0xf1a03fea, 0x93ab66ae, 0xf83eebde, - 0x5a662dcf, 0x20f02be7, 0x335af084, 0x4f8e1532, 0xa4839873, 0x93d4ca37, - 0xddfb09aa, 0x8fa4003d, 0x970b2da6, 0x3a6dd200, 0xb138d7b4, 0x8c74429d, - 0xd0bfbf43, 0xde843379, 0x9a74881a, 0x4334e921, 0x6692abea, 0x4946f595, - 0xac841a92, 0xb374fd3e, 0x408cd1a4, 0xee0a497b, 0x3c53433b, 0xf9bfd835, - 0x8fc516aa, 0xba3e932f, 0x951f4fb1, 0x3dbdf5c9, 0x019686ba, 0xff344266, - 0x3d0a3596, 0x798b6254, 0xbe0fed2e, 0xe6557cc9, 0x429f1e8c, 0xfbf913ba, - 0x825e8c62, 0xa653fb18, 0x03b935fe, 0xc58af0f1, 0x8454defb, 0x19b4e7bb, - 0x70e7c59e, 0xfb933b11, 0xc631a7e3, 0x07b6c51e, 0x757a270f, 0xe215eb84, - 0x07f50723, 0xd7b1f579, 0xa3b63f9e, 0xf18e98a7, 0x0d22dd4a, 0xcf2d99b2, - 0xf0fb33ba, 0x92bf0fde, 0xad78b10e, 0xdbde7a97, 0x8e8d7ce8, 0xad8f0fdb, - 0x979ed8b3, 0x48d749fc, 0xf8bdfdf5, 0x95e5e434, 0xe25e890b, 0x0c2e57ff, - 0x4afdb2f2, 0x0c3e59d2, 0xfe783879, 0x51e92272, 0x21aea7c4, 0x6cb8f49f, - 0x9f99679e, 0x06841c85, 0xc36e0a8e, 0xc12485fe, 0xf624aff7, 0xbc23cf1c, - 0x3cf262df, 0xeb68db4b, 0x202a2f87, 0xd175b9fd, 0xe2803379, 0x2887e505, - 0x84ee8a4f, 0xa00db1bb, 0x05ff113c, 0x72482152, 0xd0108662, 0x785e35be, - 0xd319da9a, 0xfbc214f4, 0xddb35c65, 0x29e9eb41, 0xd7f0f7c4, 0x057d132b, - 0xbf5ff1fd, 0xee1a7c11, 0xe6d1b0d3, 0x1c2f50d3, 0x7ee4e8d8, 0xb73746e3, - 0xdcea3687, 0xfc913a6e, 0xaa1ff243, 0x169f16bc, 0xa5e657a1, 0x0330fd0a, - 0x35c10ef5, 0x00609403, 0x23c66f79, 0x7288f2c0, 0x10a4dc10, 0x393cf0bd, - 0xfa44f87d, 0xe888ee5c, 0x3b56ad43, 0x82a59321, 0x67985ee9, 0x09d1f7e2, - 0xd59f3e08, 0x3fd23e7f, 0xfc8cbfaa, 0xefc38416, 0xb0b996f2, 0xb37c390d, - 0x7adf885d, 0x4bd1e965, 0xf4b9fdc0, 0x43b95ebc, 0x8feb84bd, 0x1f84cf0f, - 0x8f18bda2, 0xe2bc2184, 0xff045dcf, 0x100b1684, 0xb2b0d07d, 0xf21a167c, - 0x5ca2b5f9, 0x8448fdc0, 0xef8c1bbe, 0xc4c3cb59, 0x23a0074f, 0x645ef08d, - 0x7e49d9f3, 0x3f04b997, 0xdddb9578, 0x3937ae0a, 0x0951e2c3, 0xf1bee1b4, - 0x2d7f11eb, 0xce21b819, 0x1cc9696f, 0xb713e7a2, 0xc93ef1bd, 0x08e6d7b7, - 0xcc986cab, 0xf6111d9d, 0xe33c007c, 0x74927f24, 0x476877dc, 0x0e4e3f5a, - 0x6abb9eb0, 0x6b5e9209, 0x09ec933d, 0xafd33ee3, 0xacbfd8da, 0x6e5117a7, - 0x8f26270f, 0x42133d65, 0x63f2430d, 0x6d98e713, 0x3c23aff6, 0x7a3e65a0, - 0xedfbdf0a, 0xafd20065, 0x543fdbd3, 0x312d0fc9, 0x40e80ee5, 0xa32a8f38, - 0xf27da853, 0x6e7ce4e3, 0x127724cf, 0xec9b0e7e, 0xcefbed3a, 0x0474bd46, - 0x8da9cbf2, 0xf9023a50, 0x368dade3, 0x746f4f6e, 0xa3667b72, 0x38a3db9b, - 0x3af3fc4e, 0xbd7f138e, 0x6fd4e381, 0x4f6a71c3, 0x7ad43ae0, 0x489872df, - 0xe5bc677e, 0xbc2da8d0, 0xfadb892b, 0x742c933b, 0x50c9c38e, 0xfc4fec67, - 0x370c4e14, 0x2ee50780, 0xdb53fdd5, 0xad3f680d, 0x1c6502fe, 0xf754d4c0, - 0xae3a6d5c, 0x8fe87b3b, 0x19f1c2be, 0x6a7ec3a9, 0x3b6f7843, 0x893868e3, - 0xf5c7d2fd, 0x3f883a9f, 0x92a2244f, 0xb7643c24, 0xc7365179, 0xc418d293, - 0x24c2f768, 0xfd19a7ec, 0xc8a5b9ec, 0x3a4a4b0a, 0xb005c0f2, 0x73e1b1f3, - 0x25df886d, 0x513fff76, 0x9b6812df, 0xfa9d3a53, 0xbc927010, 0xcb20e62b, - 0x7d2510fb, 0xadbfda11, 0xd4c4ff0e, 0xabc07f08, 0xf48d21fc, 0x02af44c3, - 0x77a674ae, 0xf7d2a470, 0xd5b798dc, 0x15313651, 0x2ed7f7f9, 0xc269f995, - 0x741bc534, 0x635f97f4, 0x7af384de, 0xe26fd129, 0xd4b559c5, 0xe2e3982e, - 0x4dd96fbe, 0xa5ff24b5, 0x5fbd6b8e, 0x5c87efc2, 0xc547d666, 0x638bce1a, - 0xe3798d17, 0xffc8c991, 0x0c4b69ee, 0x7d7c4b3e, 0x84935fd6, 0x567732fd, - 0x34752aa1, 0x6bb5df70, 0xbf978d1b, 0xe572c0de, 0x59e8f249, 0xa5ed8ac4, - 0xd33e3869, 0x24c278a1, 0xa93ed32a, 0xa771a34d, 0xcdb421e2, 0x553b8ef4, - 0x5423e344, 0x9fea4ccf, 0xd89d4bd5, 0x4e66d19e, 0x66f384bd, 0x6c78a4e7, - 0xf099def8, 0xff10ae8f, 0xf249ccce, 0x1714e824, 0xa4ae9f04, 0xa9eac7be, - 0x8f1ce9d6, 0x3ad32495, 0x6131e2ba, 0x92d6febf, 0x147045ff, 0x514052fb, - 0x91a5dc68, 0xc7e4fb1f, 0xe275293f, 0x0aa1fabc, 0x099cfc90, 0xe091fee7, - 0xa89ad99f, 0xf5402027, 0xbd296716, 0x9c516f57, 0x2befb89b, 0x5181f9a1, - 0x5c79fd66, 0x769de4f7, 0x6fe507b6, 0x745fb3e5, 0x6cc1cef2, 0x9adfca17, - 0x49ed4c56, 0xcbdbf093, 0xc39f2adf, 0x930826e3, 0xebbf2952, 0x1dbdf81f, - 0x4d293f25, 0x0c4ff5c7, 0x416eb173, 0x116a953a, 0x83e70d7a, 0x55dfef42, - 0x945bf3c1, 0x8f3a3f01, 0xa7e4aff3, 0xff715a14, 0x5109e959, 0x710ce7f3, - 0x8de7f545, 0x45aa5818, 0xfcf2b1d8, 0xadfea8ac, 0x88e94a45, 0x69bef988, - 0x45fd5109, 0x11d2aea5, 0x2b6ff311, 0x5fd5181f, 0x54565b72, 0xb269a67f, - 0xa11b1fd0, 0x7dc854bc, 0x9bfb2979, 0x0a87acd9, 0x1bee629d, 0x8e3f7e38, - 0x7f09b617, 0xfe85d0aa, 0xb4a5d214, 0x80fd88ad, 0xc68f7c36, 0x8f52ec8b, - 0x3ddda005, 0xfc80ec91, 0xf62fe209, 0x6677658b, 0x6305fa3b, 0xb768ae89, - 0x752fe023, 0xfaf1db44, 0xcc27e144, 0x0bad7f01, 0x75a739e9, 0x6557fb1e, - 0x6145d5e9, 0xbf467c20, 0x2a370b1f, 0x13779dd1, 0xac6ab61f, 0x890ce737, - 0xd4adafd9, 0xf48c7ec1, 0xb7c8e6ef, 0xe0217d8c, 0xc6ff276d, 0xffb18738, - 0x4733ceb5, 0xe17ec69d, 0xacd73adf, 0xa9a5859c, 0xcf5fe171, 0x9c2c4cfe, - 0x4f32a979, 0xfb15fe81, 0xeca9ad85, 0x7a4fe22f, 0xf0c13f3c, 0xcf51ca7f, - 0x9cf522b9, 0x585f4943, 0x673d6d70, 0xff2d7bac, 0x78d758cf, 0xde54ea1f, - 0xf7bf78df, 0x7fc4aeb9, 0x27e71bbe, 0xae9e79c5, 0x5cfe7fc4, 0x9a19fcf4, - 0x7940e35e, 0x278a0e3e, 0xa93f7840, 0x959ae46b, 0x52d6f59c, 0x5fa1f65b, - 0xf670b723, 0xb52d40f9, 0x27833b53, 0xb9fe78ad, 0xf94eaa39, 0xea2fc307, - 0x0aa56717, 0x55f8e47f, 0x78e3aedd, 0x53b7407d, 0x88ff51dc, 0xaaf8a76e, - 0x28730bde, 0x370ef48e, 0xc438a7ad, 0xf62d879b, 0xfa154def, 0xdf7c857e, - 0xfea90f68, 0x857f0415, 0xf251e3ad, 0xe9bf2a49, 0x1c5f10b1, 0xbf2f7f27, - 0x5c77bfbf, 0xbf683a0b, 0x1d048fe3, 0x7e7d08be, 0x22defebd, 0xe20ca662, - 0xa917c553, 0x096c4a4f, 0x51fd48be, 0xf54574e6, 0x83ff93c7, 0x0f76cdef, - 0xae6f7a8c, 0x0f35159e, 0xf21cd8fd, 0x902c6a87, 0x353e91a3, 0xcfc87a25, - 0xefe3c58b, 0x0e3df9e5, 0x6051b927, 0x7f55d74e, 0x29e4fb1c, 0x7d8bf811, - 0xc4553dbe, 0x9ec88373, 0x52273ae3, 0x556b6e75, 0xd0e6709f, 0x887e267f, - 0xbaac63ed, 0x95c3d68c, 0x1e77c4dd, 0xba0ae9bb, 0xe3d2f0e0, 0x686ae7f3, - 0x4de33dff, 0xfb1c38ff, 0x215f1ec7, 0xfb4d53fa, 0xfadfb1b2, 0x7fa27df8, - 0xd9bc69a3, 0xb819ec83, 0xf9296e7f, 0x7fbee90b, 0x9b75fa27, 0xd4155b1d, - 0xa8099503, 0x4cd5b0d7, 0xf7a6140a, 0x2ddbc7c5, 0xc0915f68, 0x175e6cc8, - 0x156ec0d2, 0xc26574f1, 0x13d920d0, 0x13abd8ad, 0x0c132ade, 0x9264777a, - 0x09da879d, 0xdd9d7151, 0xfbe1ef82, 0x0bff3665, 0xc9c26f82, 0x87a5ea3a, - 0x200d960e, 0xea9138fe, 0xede43c64, 0x7d26ea9b, 0x21edf085, 0x01fffefb, - 0xf078e6be, 0x3ec59ad5, 0x2579f59d, 0x86f38f64, 0x3e947921, 0x3a6a15fa, - 0x21084f3f, 0xeebfb0ef, 0xb1fe5375, 0x90f165c6, 0xf2427eff, 0x35b6f5ef, - 0xdaa18f32, 0x29a91f05, 0xb17bf5a6, 0xcff25b7d, 0x6a2fb919, 0x910ba1be, - 0x33d9c03f, 0xe8815174, 0x6aa87f13, 0xe1f90f61, 0xe490ff3d, 0x83f9f8a1, - 0x183f8144, 0x8fd1f3d2, 0x777bf9f1, 0xf1b679e7, 0x65a78173, 0x0e9aecc1, - 0x06b38fec, 0xe3fca06f, 0x47ff34a1, 0xad3b8784, 0x87cc91c1, 0xb449f58e, - 0x8e05e28f, 0x0ff88c53, 0x32dd3ce3, 0x705c7fbc, 0x46c1fded, 0x64e96576, - 0x7f637781, 0xe88db1c4, 0xf124def1, 0xe10780dc, 0x303e26e8, 0x0785eae0, - 0x8f393886, 0xd4ff2200, 0x2e8be325, 0xa7ec8f5a, 0xdc7910ea, 0xff38983f, - 0x8ac24552, 0x4de77dfd, 0x791a0f1c, 0xfb1022e0, 0x49b53e4d, 0xf803e065, - 0x96a2513b, 0xcb5c695e, 0x7684fdf1, 0xf6fe262d, 0x2a9d3db2, 0xd5a9bfdf, - 0xf6a0e25f, 0x5379e8fd, 0x093f1c65, 0x59c52a82, 0xc6623b93, 0x467fe71b, - 0x18bd4feb, 0x4d293cfd, 0x3041c3da, 0xb24f3228, 0x974dc641, 0x10a7664f, - 0x2b186b1f, 0x8b0f48a8, 0xd4a4c2ae, 0xb0d33d3e, 0x4959e711, 0x2db8da9f, - 0x8fbceb38, 0x88dc69f6, 0xf49a3f0c, 0x435b9baa, 0xc2ce0aee, 0x623630bd, - 0x0617291f, 0x2fbf2f1e, 0x23ae38f0, 0xb0d397e7, 0x43356e6f, 0xc3c3ef50, - 0x0c2f8914, 0xbbfe38df, 0xf6c1d17c, 0x62db626b, 0xead9e495, 0x711e8136, - 0x113d04be, 0x6c7d08f4, 0xea8d49cf, 0xb59e92ab, 0xca7ed109, 0x924fb978, - 0x7ad45067, 0xd062bf86, 0xacea50f3, 0xc663f256, 0xdfb1563b, 0x3b293292, - 0x93a2fd6a, 0x042ef8d1, 0x63e2979f, 0x71c087cf, 0x5ab3c4c0, 0x29327f94, - 0x63f983bc, 0xcfd187d2, 0xee8f9ca7, 0xfcc9a697, 0xaedd2c56, 0xfb184f85, - 0x7fe969cb, 0xde5d3e3f, 0xcda67c68, 0x8667c689, 0x039f1a2f, 0x6be34596, - 0x1f1a3fa0, 0x898d5783, 0x7d61bf1a, 0xd87f5461, 0xcd44a70f, 0x198342cf, - 0x75be1fd9, 0x91fcd45e, 0xf545163b, 0x67753f47, 0xe0dcfcd4, 0xbcf1a88a, - 0x2efe6bdd, 0x368417fa, 0x3427cd44, 0xfe87be9b, 0x4bfe3637, 0x53ff7ed4, - 0xa18daff4, 0xe7d256ff, 0xa85e8813, 0xecfb0b37, 0xa425b919, 0x6f4d5d3f, - 0x9b79437c, 0xf9ceb140, 0xf03cc0aa, 0x2fd8e0d4, 0x7a429f54, 0xdaa2306e, - 0xd6a37a84, 0x1ec8ab04, 0x71326a3c, 0xf390d31e, 0x3f84d317, 0xc89a62f2, - 0x7b78197b, 0xd922ed1a, 0x43ea5541, 0x248efa73, 0x935453f2, 0xfec9da09, - 0x1fd61e69, 0xbe101ce7, 0x0755f719, 0x4ac5e701, 0x982d2792, 0xbea8fc88, - 0xa9fc72a9, 0x8e83f20e, 0xe4e6a4f6, 0x9f8453ce, 0x4e9b0e2b, 0xfaa6ab7c, - 0xf0df6403, 0xa1e7a19c, 0xdef39fbf, 0xf1495846, 0xe65fd196, 0xe699bf5e, - 0xe67bbb2f, 0x7b7f8a48, 0xacaddf9f, 0x43a08d2c, 0xc51739e4, 0xa40eabf1, - 0xd867fb09, 0xdc7ec313, 0x3a6bd569, 0x538c3ed0, 0xbb407d85, 0xf10d2071, - 0x88f281f1, 0x0169f859, 0xed1f9d33, 0xb827df2a, 0x80df21d0, 0xdd9f4a6d, - 0xe643bfd2, 0xda3b20fa, 0x00937d6f, 0xf74438a3, 0x1de33df0, 0x955dfe86, - 0xecbbf8cb, 0xf97f9e88, 0xaf02e1fe, 0x90f620f7, 0xe22ce70e, 0x17fc063c, - 0x42fe5ea5, 0xd24ee5ea, 0xebf911c7, 0x2676bb55, 0x2e7e7f91, 0xc6e3f847, - 0x3a49dff3, 0xe54d2eff, 0x9dddaff3, 0x047cfeb0, 0xae422ade, 0xe3557ea8, - 0xf991f5c0, 0x39c6b5cd, 0xe7468afc, 0xa8e52758, 0xf923b5a2, 0xfe7f604e, - 0xb75c34c3, 0x7b95d772, 0xa6fbd00e, 0x67614c9e, 0xd2dfbc03, 0x82e380f7, - 0x28817fa5, 0xcd33b6bf, 0xa67570cc, 0x09613889, 0xbbe44e36, 0xb803e825, - 0xda637da8, 0x7c3fe22c, 0xbfb0561e, 0xa4cc15a0, 0xb3fa16bf, 0x33f484cc, - 0x3f6779e0, 0x69cfed1e, 0x1b73ef3a, 0xfb7ef8f8, 0x922a7bdd, 0xd6340fd8, - 0x8141d633, 0x3def3f20, 0x499cc057, 0x0ae99f79, 0x9fb817fb, 0xeefb9e8d, - 0xec99bc1e, 0xbbdfb1b0, 0x0ef4bfe0, 0xf022c5f2, 0xfac6baf0, 0x1134d740, - 0x4b03f97a, 0x44ed1d2f, 0xa66d0dbf, 0x3685e530, 0xbdf2b39c, 0xcf75774a, - 0x9c230fcb, 0x66f9af1f, 0x7f7082bf, 0xbfe7bcb4, 0x3bf3e00e, 0x4741529e, - 0xfdd9f1be, 0xbc447a5a, 0x2bfeee79, 0xafe86f2c, 0x2924ff3c, 0x1eac97a5, - 0xd60f9392, 0x322a34bc, 0x9f4e485e, 0xf74e9099, 0xe2d2933b, 0xc6c46fde, - 0x3f886ba5, 0xf6757e59, 0x5cbe0d4b, 0xc372f92d, 0xf9f9a30b, 0xf3dea486, - 0x2af3fe88, 0x3436c1e7, 0xf1af395b, 0x3587e48e, 0x31337e2f, 0x8f57cf32, - 0xa95ba97c, 0xf74b7275, 0x09fa3aa6, 0x1e5e4efb, 0xeaab71cb, 0x1e73a2cf, - 0x3269fabe, 0xf9bdf7f5, 0x6e079f2d, 0xbbf83ebb, 0x78917911, 0x79ea4aae, - 0xc54af497, 0xf94eab01, 0xb90392ac, 0x7ec2ee27, 0x1fea2b65, 0x5725cf3c, - 0x29a7b1c7, 0x00a83b1e, 0xc32ab7e5, 0x2be4ac09, 0xe520941b, 0xee34d6c3, - 0xfb1832dd, 0x1616ea6b, 0x2556bb11, 0x59567d0b, 0xb13704af, 0xe9873e1f, - 0xa365285c, 0xbfee50e4, 0xd778e3e5, 0x85feb171, 0x3cf6b08d, 0xf55d9dc6, - 0x38205e5f, 0x395a35d6, 0x292176cf, 0xfb8c196c, 0x84abda5e, 0xdc9f7a02, - 0x1c44b976, 0x98f42ab6, 0xf55df685, 0xe411c2dc, 0x381d7636, 0xb93d216d, - 0x59b1e1aa, 0x309179f2, 0x8b9641ff, 0x9595bbb5, 0xd5ac7991, 0xa4420ee8, - 0x02f842fd, 0x40eafb13, 0x2cfa494e, 0x435e1a6b, 0xb6bd42e8, 0xf58569ff, - 0x97e242da, 0xf9ef0e0f, 0xdf686fdd, 0x923dff83, 0x7d745ff1, 0x805f07f8, - 0xb94a8bfd, 0x633c5c0f, 0xb2b2f8a1, 0xde217cc1, 0xba6352fd, 0xcfda1eef, - 0xfd638f88, 0x10162dee, 0x10d93ff7, 0x82ec9e7c, 0x1cb2c7a3, 0x9a57f9e1, - 0xce68f080, 0xec0acb1e, 0xc8ce48db, 0xc11db85e, 0xbef57178, 0x84f18d74, - 0x78fac4b1, 0x3921a0f7, 0x5877a25e, 0xe9579f28, 0x5f10b4ee, 0x173f8657, - 0x9f8dfff7, 0x89c6f2cc, 0x574e5fb7, 0x273f33a4, 0x6437de4a, 0x30b9618c, - 0x90c3daf7, 0x60bee58d, 0xa9d90f45, 0x3b91070d, 0xbfb7a214, 0xec0ee087, - 0x7ce9d04f, 0x9f3e0725, 0xcfb111d8, 0xf47ca51f, 0xf95e59e6, 0xf099ac64, - 0xb193efb9, 0xf3df525a, 0xaac74cae, 0x97997978, 0xdedd85d3, 0x18bbec9c, - 0x9e09072d, 0xd95bee30, 0x147be764, 0x2d2d8394, 0x70729145, 0xc45daac7, - 0x07aa4de7, 0x1b2a0225, 0x79abfa17, 0xc887927e, 0x0cce36a3, 0x4eaa1f10, - 0xfc27f31f, 0x289bf715, 0xff508fef, 0x3ff74dcd, 0x39ac724d, 0x1e646560, - 0xf1d4d2a4, 0xe88516ab, 0xa26bc3ba, 0xf5810afd, 0x75f0ea96, 0x94553c70, - 0x7bdc53a9, 0x202cc274, 0x59bcfd3c, 0x39afbce1, 0x8b35bfd5, 0xe55c7be8, - 0x2fa396f9, 0xbbbee804, 0x11141c6b, 0x7f79c67c, 0x2a0c2e3e, 0x00b9b3ae, - 0xe6edb43c, 0xc4dd4b83, 0x38cf3fbf, 0xdd867ec6, 0x2bd20213, 0x503fe835, - 0x1f9ec7de, 0x093ad30a, 0x1522be39, 0xee9359f7, 0x58b4be64, 0x27ca1efd, - 0x36fb203d, 0xe08ab7cd, 0x8a27a5b3, 0xf5c87bf8, 0x48baf9e5, 0x6f74cdfe, - 0x4b7ce7e9, 0x69f05997, 0x71c00dd7, 0x4cfcd722, 0xe32f21a6, 0xb83b06cd, - 0xd6546aad, 0x44d7da46, 0x79e8dbf0, 0x1ea5c1d7, 0x2d9cdf82, 0x91333df9, - 0xff7622e5, 0xa99f888f, 0x62b4c0ce, 0x99e1166b, 0x9ff7a6f0, 0x7be4a1f7, - 0xf9a01f03, 0x115e4873, 0xfcbc6f54, 0xf8bd3f92, 0x7375d12c, 0x95c72faa, - 0xc2bcd7cf, 0xc6277629, 0xff9c3b95, 0x31b7c901, 0x89f095bf, 0xfcd16fef, - 0x51efc236, 0xc5b35f89, 0xfe593ba7, 0xdfed3a7d, 0xf141be7b, 0x3c8df7cf, - 0xff6c96df, 0xcfef9ef7, 0x54e67cf2, 0x2f5a37e4, 0x399e7819, 0xfe201839, - 0xa2824dab, 0xa8f8f84d, 0xe49b966b, 0x6f91cb6e, 0xd7bc9286, 0x40dc7926, - 0x9be6b179, 0x6fdc9196, 0xf3277419, 0xe42f17ff, 0xfb11aa16, 0x7f17a724, - 0x2f3be745, 0xe2c5b1cf, 0x7c73a1cf, 0x9c69cf2c, 0xefba496b, 0xf911e92f, - 0x7e921826, 0xd7b3fc5d, 0x7194d7b8, 0x61da479e, 0x8f38f38c, 0x5c890dd8, - 0xfa57b67f, 0x98f81ae1, 0xd1e0ec7f, 0xc2f2bfd9, 0xa92baa09, 0x36c13169, - 0xb5253e3a, 0x92fdee22, 0x0c119355, 0xb2186d7a, 0x8d3435d3, 0x39d89f3b, - 0x3ee116af, 0xf8550108, 0x0cf9d169, 0x255e2af0, 0xdaf18f32, 0x63cbeb9a, - 0x21afe33c, 0x63cd8d79, 0x969b0e4c, 0x23ae525b, 0xbcdaf19f, 0xd18cf9b8, - 0x5171d119, 0xc0ce8641, 0x7f047285, 0x4189c286, 0xf1833791, 0x26eabf94, - 0x9fe3855b, 0xde5999e3, 0x9b1cae95, 0x13e0ed0b, 0x3adb6c4f, 0x8470e50d, - 0x6bf503c0, 0xf1f5c988, 0xe6f507ec, 0xc31b5e47, 0x3dea387e, 0x4e02f395, - 0x1d0c4b09, 0x137fd08b, 0x2a27a541, 0xf63e12bf, 0xdbf1326d, 0x2dfd549e, - 0x9b4f4fa2, 0x092875ca, 0x15c5875a, 0x900eee47, 0xe076807f, 0x3e84339f, - 0x7b8a35b7, 0x65ee9b4b, 0x74e0993d, 0xe423538e, 0xd8432f24, 0x1f638aa5, - 0x2ca0b50c, 0x4c9d325d, 0xd7f5c7ce, 0xa64fafed, 0x73dade34, 0xd2a44f6f, - 0xff353b9f, 0xff3c0c82, 0x51aeca17, 0xb75bf236, 0x7e12c706, 0xae6ce142, - 0x20d02ccf, 0x87f615a0, 0x3c29eaa7, 0x9504ba14, 0x5b71a54f, 0x257e34d0, - 0x58555ff1, 0x30f6979c, 0x6dcc8aa3, 0xd5dfb854, 0xeb4a9358, 0x79b6fd55, - 0x97afe910, 0xf39f8432, 0xf13cd5e2, 0xcd1a06be, 0x25c33fbf, 0xa2682a99, - 0x324be37c, 0x5575d94f, 0xfec679e5, 0x55338d05, 0x7e41f227, 0xce11c778, - 0x7559368b, 0x73c26fa2, 0x94d1f020, 0xd5687ec0, 0x7640d9e1, 0x1e05dbaf, - 0x24f7c705, 0xfc447cf6, 0xd56cd3d0, 0xc1373ee9, 0x715203b9, 0x1eb23dfd, - 0xb619172c, 0xdcf7d1de, 0xe9a12fd8, 0x24439497, 0xe57be0be, 0x4c076d04, - 0x3be24477, 0xc959d849, 0xc3127b57, 0xe967ba26, 0x59efdf41, 0x4e0fab86, - 0x380d7de0, 0xec0ed973, 0xf85cf4b1, 0xe5c33a71, 0x05c83e24, 0x8d342701, - 0x26af49d6, 0x8e7cbd38, 0x09eea704, 0xaae1fd28, 0x208e8b1a, 0xa4a3cfca, - 0xc9f4a6cc, 0x5f625577, 0xb0b286df, 0xfca41b27, 0x9d2b6eb7, 0x8547d916, - 0xfdefa933, 0xf8e278ff, 0x9c21dab6, 0x48a80bff, 0x49b63b7f, 0x214e74a9, - 0xde122857, 0x0781428c, 0xdbb40baa, 0x7cef78c4, 0x2a4773e4, 0xe79e7fdb, - 0xf3ed3ab1, 0xf85e58b2, 0x0ff0d17e, 0x17c2521f, 0x76d2466e, 0xc94be63e, - 0x9a7573c7, 0x875c3c8e, 0x3cb8fef3, 0xfd8c2a34, 0x79ffab16, 0x3f57cfe2, - 0x80bdb15c, 0xb31eeff4, 0x4ff49ca7, 0xf671e047, 0xeb345fcb, 0x0ee422db, - 0x7264f486, 0x3ecc61dd, 0x3d36e755, 0xf776fe4e, 0xfba74541, 0xcf736ef4, - 0xb2bb8250, 0xd50b33e9, 0xfc1d5663, 0xb2ebfd84, 0xda5eff4c, 0x3563526f, - 0x864dcfd7, 0x873f5c1d, 0x20eb917a, 0x4fa16e43, 0xf51d9f2e, 0x1d04756c, - 0x06f293de, 0x6461fe3d, 0xbca49abf, 0x1c38a61e, 0x772dfddb, 0xf7f5a70c, - 0xf180fccb, 0x191c355e, 0x04df784c, 0x3c6b71af, 0x5c6a0eef, 0xaef79cbf, - 0xc46f5eed, 0xfe52d3fc, 0x56fdcb4f, 0x20dffa67, 0x7cb6d778, 0xc2d2a16a, - 0xa1a1f3aa, 0x3486f714, 0x4719c53d, 0x6fcaf48f, 0x69553c8c, 0x5f9a163d, - 0xaf581175, 0x536bbd20, 0xbd2f7e90, 0x396638db, 0x348fdf3e, 0x8b3b2149, - 0xe3d92af1, 0x60df66fd, 0xcefd5f9a, 0x8f4963d7, 0xf020241d, 0xaf375f7f, - 0x4378461d, 0x244e2ffe, 0xac0bdb39, 0xcd390cd7, 0xf7c53927, 0x8bff89f3, - 0x7acb9fa8, 0x7da58f79, 0x7ee5cb1e, 0x225c9013, 0x203cb3ff, 0xdfc93bff, - 0x3ca277cb, 0x59a3fbf0, 0x9bb4f7ce, 0xa337ecbc, 0xfdc91f5e, 0xdfd4c5e2, - 0x64ea5ed3, 0x843aa739, 0xf0d79242, 0x04275e11, 0x45f2d740, 0xfd22f80a, - 0x648cbcff, 0xf1242f71, 0xd8433939, 0x9e8e5083, 0xd873c1e2, 0x3e4a3555, - 0xe8a5ec22, 0x9a5a7b4b, 0xbf6d97f9, 0x26524698, 0xda5384ed, 0xd678ff49, - 0x6d28fffb, 0xa7d786d5, 0x73c3a82c, 0xf2a5386e, 0xf71961f8, 0x1c9f2585, - 0xb21af991, 0xa89a7a1b, 0x13e7a61f, 0xe5f54fb0, 0x4bebbd13, 0x9a4d1cc8, - 0xb528e3b3, 0x12a17c53, 0x2da6db72, 0x166a3f6b, 0xfc479e62, 0x6e6470d7, - 0x75e3d51e, 0x0242b39f, 0x6df0d882, 0x222f47cf, 0x8c3e1e1e, 0xa7638ff8, - 0x7fcc38f0, 0x060d7fe8, 0x6ef1ff77, 0x4091ea45, 0xc7e27cd2, 0xafb506ae, - 0x2254808f, 0xfddf5363, 0x007b7da4, 0x677fe76d, 0x2267077a, 0xf00ccf3e, - 0xfa7ddb73, 0xcb124cdb, 0x5c4567fd, 0xe6f160df, 0x6434ff11, 0x871ba863, - 0x2299ad4f, 0x856453ef, 0x379cf7b8, 0x18390a67, 0x0aed8015, 0x33aaebc7, - 0xd4bf7488, 0xe82d7aa0, 0xc0845d2f, 0x6fa4a992, 0x01f75e64, 0xfc5e3f90, - 0x283cfa45, 0xdf900fbb, 0xc1eb7682, 0x11d6c45f, 0x316fd978, 0xeb0058f2, - 0x2b5fc44d, 0x0ff8149b, 0x67aac5c4, 0x93afe7a2, 0x1babf275, 0x8c1b1d77, - 0x5cf35d74, 0x2df938cc, 0xe211ff7c, 0x5d5d7878, 0xcdc33d74, 0x197fd299, - 0x7fc9c30e, 0x3d62be41, 0xd5a0d661, 0x60ac7c8a, 0xf6224314, 0x0be04992, - 0x67cb2bf5, 0x8a6f61be, 0xb9ea5e85, 0x94a75c04, 0x94743bbb, 0xd4a681ea, - 0x8f687965, 0x9f189a29, 0xee2598d2, 0x4aa0b4a7, 0xbc930c75, 0x77ec59fe, - 0xa967bc07, 0xd49564de, 0x5fc4e097, 0xd3c8fbca, 0xddfe92af, 0x9d6c60ea, - 0x9553c0a8, 0x8219379c, 0xcaefb435, 0x69dea2dd, 0xf9e8eeed, 0xeb4f1255, - 0x8c7d3a9e, 0xa11585d2, 0xa7897198, 0x3a98c6aa, 0xdc38b116, 0xadef299f, - 0xf5fb7d64, 0xd1fc5bd6, 0xb78dfc2c, 0xf8c63ae5, 0xef914ce6, 0x1063c4ad, - 0xd505d77d, 0x2ad1f120, 0xfc2c9025, 0xc72c705e, 0xb067ddf3, 0xbdcfac81, - 0x3ee9e25f, 0x7e7c3fc9, 0x19e2bf7c, 0xfdc57df1, 0x7f868b3f, 0x832cf80d, - 0x0d83f9f1, 0xde50b03f, 0x56df9631, 0xffd999d5, 0x13f1235d, 0x7a6b5fcb, - 0x858767f9, 0x7f2c5bec, 0x6b95fa55, 0xf6fc2fc0, 0x0df85bff, 0xcb91af3a, - 0x398735ac, 0x09f6b53f, 0xabf943c5, 0xf7ab9d6b, 0x7f7cf23c, 0x359eb9ef, - 0xc6063de8, 0xa4e7bd30, 0x63bd175d, 0x96bdedfd, 0xe726bcde, 0x66b72f05, - 0xe0dd3e73, 0x6675d8ab, 0xf67dbf49, 0xbd7fc253, 0x276258d4, 0xa4fba3ff, - 0x9ce8a3c9, 0xc02e4caf, 0x566f8ff3, 0xee91fc81, 0x033be1a6, 0xa9e17f08, - 0x5f94c5a2, 0xed0a7f1f, 0xb707dd13, 0x0257fd16, 0xd27b07df, 0xb667ee48, - 0xbdfb488d, 0xfb61d783, 0x70b27dde, 0xe9e93967, 0xb445a593, 0x54e382ae, - 0xed285e9f, 0x42c9f554, 0xbd84477b, 0xc8a64dfa, 0xff716fcf, 0x1b8a51fe, - 0x7b35ef66, 0xdb323f28, 0x8094dfec, 0xa0be15f0, 0xb771aa78, 0x9e47ed63, - 0xbe5175a4, 0xf38acd28, 0x8d08e9fe, 0x1851ed57, 0xb2a6eefe, 0x3f643dbc, - 0xec87aa83, 0x7dd37762, 0x1f920ff9, 0xfe40fcd4, 0x1dfb117d, 0x66fa154b, - 0xb6660df6, 0xec839dd7, 0xbca72ebf, 0xeb1777a8, 0xfb43ce8d, 0xc37dfc2c, - 0x78dc051e, 0xa3ee63ce, 0x3a1e132f, 0x50b69c0f, 0x70d25010, 0x4711d2da, - 0x25ed1b7f, 0x9cc2f30c, 0xe161ddaf, 0x7ffdcdfa, 0x2b79d0b0, 0xf384fb9f, - 0x7e286b6f, 0x19ef3f20, 0x3a77bf95, 0x85aafcda, 0x4eb2b4f8, 0x91590181, - 0x271e66e3, 0xcffd4afd, 0x369e84ea, 0xe4857ff8, 0x0dff8377, 0xf5215879, - 0xe35b7dda, 0xffa1bbf3, 0x96ef041e, 0x03deb841, 0x0eb9cb75, 0xd11d81e9, - 0xfc5257f3, 0x17cd237a, 0xa9f2befc, 0xbdd5f1e8, 0xfd601e7c, 0xbf47ab1f, - 0x2e7ff433, 0x5f9f12e4, 0xa618af0e, 0x7d7d3ca1, 0x8830cd7a, 0x293caf93, - 0x6ec306fd, 0xd89b0e5f, 0xebcec5ee, 0x2162bc6a, 0xfad55b7b, 0x6773f627, - 0xf4c97d35, 0xe16a6f28, 0xc05bd97a, 0x79f08ebf, 0x49dd934b, 0x877976fe, - 0x9af303d0, 0x42a0c1ac, 0xa25aa1e3, 0xf161f773, 0x90e049bd, 0x4816fec2, - 0xe252b8bd, 0xe3c4a575, 0x06e38c4a, 0x8c8c7d53, 0xbc652be3, 0xd7673abe, - 0xa9292a31, 0xdaebe394, 0x1e13268e, 0x5bd081e7, 0x6f4242f3, 0xec31f419, - 0x40beac50, 0xd10f770b, 0x95936d77, 0x4be7d6eb, 0x0ebf35bd, 0x5fd296f5, - 0xb40f747f, 0x7ef1fc8b, 0xddac7701, 0x9e886cad, 0xfc201aef, 0x7fd2cbd8, - 0x4d101c2e, 0xb01ef297, 0x9e7f7e53, 0xfc827aae, 0xfb46bb56, 0x7e458eb7, - 0xf55bf5c3, 0xeaf129e1, 0x4df68cb5, 0xfd181719, 0xc3679405, 0x0ee721f9, - 0xffdc6447, 0x7f84039f, 0x1ab266b3, 0xc446ba20, 0xb30a0b49, 0x7349c6e2, - 0x8637f409, 0x71b3f7dc, 0x77927191, 0xb7e228d7, 0x2cef757f, 0xaaa6baa7, - 0xba2fa13a, 0x29bae126, 0xfb03f7e4, 0xd67555d1, 0x5533c520, 0x7dfc2fc8, - 0xc909f11a, 0x46529363, 0xc671827c, 0x42feb4ed, 0xf3c4eaba, 0xfb446c2f, - 0x2c2fcb8e, 0xabf992fd, 0x3738846d, 0xbc406de2, 0x3788c3b8, 0xbf0aaf2a, - 0xa95e78d6, 0x51dc7075, 0xb5ea24d9, 0x337c8e1b, 0xede10b34, 0xd0f3fe6e, - 0x3e4f54e5, 0x86e7d840, 0x54a7d0e2, 0x1ef5f457, 0xb5ff5c5b, 0xb52bff57, - 0xe6950f2c, 0x6bf64c8e, 0x791fa20e, 0xb7d1ea13, 0xa538e0bf, 0xbdc248e1, - 0x5aebcf94, 0xfce61fe1, 0xc3553a1e, 0x3783f626, 0xe4b72d41, 0x8dfa451f, - 0x4ea29d2b, 0x3f6941e9, 0xf208ffa9, 0x773883f5, 0xf97f6146, 0x8549f437, - 0x10d5ebe4, 0xe95532d8, 0xa42a07af, 0xdfcdacdc, 0xf6ae85b5, 0x0aa7fd63, - 0x31184f29, 0xf58cbdb0, 0x8633fe9f, 0x4edfab5f, 0xbbb8ff64, 0xae52754d, - 0xabfbf119, 0x6227e441, 0x271d905c, 0xe485fb5f, 0x7f794ecf, 0x65493d5c, - 0x8b2699fc, 0x10b7f0d6, 0xdd37cc8f, 0xb2411da7, 0x5f87796f, 0x583e26cd, - 0xdefa3bbb, 0xe7e8e889, 0xc8a0b1ba, 0x7cec8547, 0xbf8c6517, 0x31d5f874, - 0x6fd56fc4, 0xd04a3b7f, 0x96519be7, 0x67c36bf4, 0xe2228ab4, 0xe2229366, - 0x475afde6, 0x556bc532, 0x645f5507, 0xef41bf3d, 0x813ca597, 0xf503f226, - 0xabe67403, 0x1fc126ea, 0xe2d166a6, 0x7e444bfe, 0xf7fbccc8, 0xbe462f1b, - 0x067b1ef9, 0x40f21704, 0xf987b995, 0x89b4eaaf, 0x7d3aa9e1, 0xc4447339, - 0x775a017b, 0xeabfe900, 0xc4fac075, 0xe76fa40e, 0xd891f7d3, 0x027eff9f, - 0xb2c761fb, 0xfb8b97b7, 0x7f48152f, 0x9af6fc3d, 0x60f691d1, 0x2f7100e2, - 0x3707840e, 0x10bf3f79, 0x6c3c4bfb, 0xbf324582, 0xaf79f820, 0x2e309b8c, - 0x9c40737b, 0xfd7aecb8, 0x2b66eae9, 0xeab9fe50, 0x19d72b03, 0x92bcdd7d, - 0xeab87ee3, 0x06fa4d1f, 0xa91bfefc, 0xcaf0f87d, 0xebfcf4d1, 0xe46fabc3, - 0x29b2a97c, 0x2011cf2a, 0x5fe4dcf8, 0x5deef57d, 0x69b67fe4, 0xb6149fec, - 0xee977d9d, 0x9835f769, 0x8ad1dbf9, 0x067613fd, 0x2aafc892, 0x11df4f9c, - 0x98d56bed, 0x32dfd0ff, 0xfb3b2bfc, 0xd88aa757, 0x7c75c2bf, 0x4e8b6e41, - 0xa7bad394, 0x9a688b8a, 0xd7a4e382, 0xe57f93c6, 0x0cb7f3e8, 0xf8933e78, - 0xe0496eec, 0xd9028bbc, 0x4460cf82, 0x1aebdc14, 0x64ff675e, 0xf51aa35d, - 0xdef188fd, 0x7b88065f, 0x3e0cef87, 0xe65e290b, 0x5da2bda3, 0x932fb8d7, - 0x1cd6b1ce, 0xaea93e62, 0x3df18b33, 0x07ba05a2, 0x411fc09a, 0x273f0807, - 0x65d211e8, 0x8438259e, 0xbdbdfafc, 0x2eb28af7, 0xf5ea2824, 0xf3875a6a, - 0x5b974c77, 0xb3c7a5f7, 0x9ee92743, 0xe3be1d07, 0x8a1e2259, 0x5badff1d, - 0x9f8e41e4, 0xf8f1fa13, 0x78e8ff4c, 0xc500327a, 0x48a05f22, 0xef8835fa, - 0x35e763ed, 0xfe787ad3, 0xc70243dd, 0xf73b8f89, 0x63fdf026, 0x75e44ba7, - 0x34dbea4b, 0x6d661efa, 0xec813283, 0xf79cdad2, 0xec197bf8, 0x5c9e9117, - 0xf7c83e1b, 0x7b7515af, 0xc0e37967, 0xec2dddb1, 0x9df93cc3, 0x7cf8ec72, - 0x3c067e39, 0xdb9e3219, 0x673ef74e, 0xf14ecdca, 0xeef89bdd, 0xd7a956f5, - 0x6662df17, 0xe80cea3f, 0x227f7166, 0x481639ee, 0xd4ab7dbd, 0x63dfb1f7, - 0x76fdfa1b, 0x67c2ceb9, 0x73dd3360, 0x7d9f7ec4, 0x170ff4bb, 0xefd79781, - 0xf4bd5df7, 0xfeff6313, 0xea5b8942, 0x8a3051f5, 0xed087af4, 0xe45bd70d, - 0x9eddb026, 0xae32305f, 0xa9df41df, 0x753bf2eb, 0x57fa0d6a, 0xf6c7bee7, - 0xb9cb78f0, 0x86fbf997, 0x1d900973, 0xcfad9ee7, 0xe47a1a1e, 0x79774136, - 0x14e151ef, 0xbff41a30, 0x645a1184, 0xffa0cd7e, 0xff0e9283, 0x394575c7, - 0x63e645a0, 0x07fea90e, 0x475419dd, 0x38fec9dd, 0x21ed809e, 0x3ca86b9e, - 0x846b50d7, 0x7034bb9d, 0xee3e5c79, 0x406a5f3b, 0x6e7493d8, 0xecad725b, - 0x14845637, 0x22b0eefe, 0x9b7fa20c, 0x51caf9c2, 0xbf5c2d0d, 0xf154a4b1, - 0x3c5a8578, 0x7c19f04b, 0xfc26c0b4, 0x7a5f8303, 0x88f925f1, 0xb85fc9c6, - 0xb10bfa55, 0xda1a34fc, 0x4bfad167, 0xea878abd, 0x47c9af36, 0x4ebdc6cb, - 0xf8b5eee1, 0x4cd2f908, 0x9f96317a, 0x1ffb735e, 0xb775fc25, 0x80525e5f, - 0xfdcf1feb, 0x4ff1286c, 0xe8e435e5, 0xddbf4945, 0xae71c08e, 0x7597a963, - 0x8db9f504, 0x5697841d, 0xd3b2bf60, 0x8365bed5, 0x8eb9b7f0, 0xc09c22a0, - 0x4d15a5f5, 0xad6efe76, 0x713aa1a2, 0x26e3e90c, 0x7ec763d5, 0x52e9c379, - 0x179423ca, 0x2a973a89, 0xabbba8bb, 0xbbba8bb2, 0xe7fee9b9, 0xeff813dc, - 0x11d74403, 0xb57e3a58, 0x3ef87be1, 0x9335df56, 0x7fe1370f, 0x4b350f4e, - 0xbb686cfc, 0xc4863992, 0x887fdd34, 0xfd7eeee0, 0x8a7d0b45, 0xd5e63551, - 0xd6825459, 0xde79d6ec, 0xb52d752d, 0xe0365694, 0x429dbbb7, 0x43839aef, - 0xbfcd6fd8, 0xea9b7abe, 0x258c6f83, 0xd2d5d5fb, 0xc112d636, 0x501b9def, - 0x63a1c76f, 0x1ca49835, 0xca2adc6b, 0x0947e922, 0x3e6aaeb9, 0x8bf9499a, - 0x7ce7924e, 0x1e49df6a, 0xdec56d81, 0xc923c933, 0x5a2fd99f, 0x4d4bbd63, - 0xad03cf2a, 0x49edd463, 0x666df091, 0xc4852ef8, 0xa31d003a, 0x8e441716, - 0xd6bffcd7, 0x3e851707, 0x07d288e8, 0x16429e06, 0x0388efe0, 0xa75cad87, - 0xae3ff740, 0x036a3a08, 0xc26efd05, 0x76e48a60, 0x0f7bdd32, 0x834f9727, - 0x41afa9bb, 0xfba54b58, 0xea2ab0e9, 0xbeb086fb, 0xbff7289f, 0x50b70b49, - 0x7964f03d, 0xda053a5f, 0xe80cde79, 0x4e0bd6e1, 0x18ba0efe, 0xb24edc3c, - 0x5a53e785, 0xe2143f2b, 0x99c27bef, 0x4d82eb9a, 0x871d6f7e, 0xd3787dde, - 0x0f8182e0, 0x44d5ee95, 0x79ec533d, 0xfc28186e, 0x42bc9bbc, 0x414b910f, - 0x2093c0f5, 0xd3f9f7c4, 0xebde43a1, 0x54c73fc7, 0x1ee90b8c, 0x31ba3a6f, - 0x208f8c89, 0xe7469fcf, 0xa79de351, 0x19933e63, 0x9f049d4a, 0x7d34ce12, - 0x73febf67, 0x28355374, 0xebefbde5, 0x5171fae9, 0xa7a83ddf, 0xa9f78de9, - 0x7af1597e, 0x43d9beb9, 0xfc538ddf, 0x7b3ad613, 0xc03659f5, 0x722b8198, - 0xfbe84e06, 0xc0fc046e, 0xdfb12475, 0x277c448d, 0xfe231702, 0xe751922e, - 0x48b83bbb, 0x65913aa7, 0x7bfe36e9, 0xa1b6853b, 0x79af29e3, 0x339fcd28, - 0x7dea8330, 0x62f246eb, 0xfb02705a, 0xecbf92b9, 0x78449de0, 0xf7c6bc50, - 0xd37cc02b, 0x320bf7fb, 0xb227bf81, 0x3e77c55b, 0x6d1f91db, 0x3a052ca9, - 0x23c35fd5, 0xd3f93a25, 0x0f365c5b, 0x256c477d, 0x707dedb8, 0x1d44d8d7, - 0xd44d8d48, 0x72f51879, 0xb1ad78b1, 0x8f4e7919, 0x98f1fd8d, 0x627e90ef, - 0x7842dff3, 0x98a9287a, 0xde530eff, 0x5cdcd32b, 0x7fbf250f, 0xf03049aa, - 0xe7e36c50, 0xec94f57d, 0x3d52d667, 0x9359c237, 0x78ff5c01, 0x0a546934, - 0xb4d565d5, 0x9aee7a89, 0x77eb008c, 0x7d615fb3, 0xd25ad35f, 0xb2e2f64a, - 0xdd75c2c3, 0x07512e35, 0xd080c81f, 0x3d347af3, 0xa0f419a6, 0x8f594bfb, - 0x5c65d064, 0x7bd0943a, 0x91dec2e3, 0xdb429384, 0xfdd037cb, 0x7470b8c2, - 0x69d2197d, 0xf7a9d135, 0xc9cd1e3b, 0x7d061ef5, 0xd9987190, 0x06ee929d, - 0xdfc69cbd, 0x516af023, 0xa0c08f7f, 0x4144f6e3, 0xe055332f, 0x7577e70c, - 0x4e96375a, 0x14e11bff, 0x4bb0bac1, 0x00004bb0 -}; - -static const u32 xsem_int_table_data_e1h[] = { - 0x00088b1f, 0x00000000, 0x93cbff00, 0x51f86065, 0xd2f9c08f, 0xbcde0c0c, - 0xc4b462a8, 0x0c0c5c0c, 0x0e5c4041, 0x7b401ac4, 0xdbe9016f, 0xcdce1c40, - 0xc40110c0, 0x1ff881fb, 0x6207ff10, 0x04d6200d, 0x79405fe2, 0x5b1ba845, - 0xda181898, 0x8803b880, 0x875880bb, 0x97418191, 0x93fb7891, 0xde181984, - 0x7af82389, 0xcd0c0c12, 0xfff3f452, 0x5631c360, 0x29efb5f4, 0x174e3ed0, - 0x19c73f04, 0x505c2498, 0xe0bb70d5, 0x4d078337, 0xcf8d179e, 0x9e7f4787, - 0x5cbf2a21, 0x4d3f950b, 0x23e18187, 0x2d0a9a92, 0xc7416efc, 0x0c0c468a, - 0xabc4464a, 0xca8c60df, 0xd081300f, 0xb1adf900, 0x0003a809, 0x00000000 -}; - -static const u32 xsem_pram_data_e1h[] = { - 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0xf37df0f5, 0x66499996, - 0x0d909326, 0x8a027108, 0x081380a8, 0xc3b44069, 0x8e22a222, 0x260dc55b, - 0x1037d902, 0xfdaff0fd, 0x2d361032, 0x4682d0d6, 0xa0c0748b, 0x0d0482c1, - 0x00e02418, 0xd52ff82e, 0x5b7bbfd8, 0x16c34a0c, 0x7e1b8092, 0xce7fe5b5, - 0xef25f7b9, 0x6d80264d, 0xfdfb5fbf, 0xe6f169bf, 0x5ddf7bbc, 0x3dcf76ce, - 0x14fbdcf7, 0xf89628db, 0xe0cec663, 0x2cabd20f, 0xdd51b18c, 0xa0db6ce9, - 0x74fa87a1, 0x6559ffe7, 0x4287ead3, 0x6ed0ab1e, 0x9cfdd61e, 0x7e5485b1, - 0x386b8c40, 0xf4d31cbb, 0x8f0e1b10, 0x9616c96d, 0x6e7dd8cc, 0x0901bf46, - 0x912974be, 0x5615ceb1, 0x780cbaf7, 0x085c7aae, 0x20c8f7df, 0xf7c25077, - 0x1652c93c, 0xbaa23fe4, 0xbecc01d7, 0x6cb3233f, 0xe0da66c6, 0xc3fc0f6f, - 0x7cbea07a, 0x63106cac, 0x059969ea, 0x77ea7fa0, 0x3403a512, 0x00efc336, - 0x6c2df978, 0xfeeed0dc, 0xecfd13b9, 0xe8b78073, 0x5b7e89f9, 0x097f90c0, - 0xecffa893, 0x5faa4afb, 0xf2f16f6f, 0x073e6c5b, 0x8d941636, 0x7f963bcf, - 0x8be7c2e9, 0x7aa16e9b, 0xd82c5318, 0xc8b772cf, 0x635cfc4f, 0xbbfaee96, - 0x76a214f1, 0x04d3d874, 0x3188feed, 0xb6bfb5e9, 0xd543c032, 0x0563d556, - 0xaad84cbc, 0x700c7f86, 0x84295ae9, 0x9d9765b0, 0xfb4bc031, 0x9d870e6a, - 0x9fcb0f9a, 0xaa1805a8, 0xff36b728, 0xdbc40afc, 0xa3ad9956, 0xf784fc66, - 0x3bc71b56, 0x9e70e46b, 0x6ba5839d, 0xf7c74f77, 0xccad1a0b, 0x6e95f50e, - 0x057a9fcf, 0x54fbf9c0, 0xd74a4586, 0x01fad02f, 0xea92185c, 0xcf18ee11, - 0x36e0fda8, 0xca1eb439, 0x939ab877, 0x1ff1836f, 0xcf31b4ab, 0x676fd0c5, - 0x80adf273, 0x96d0a287, 0xd15ef849, 0x2c8bc946, 0xfaeb6134, 0x7bc2fb37, - 0xaf241ba5, 0x5c52f015, 0x433ccb17, 0xc0ce1f78, 0x3906d6bf, 0x9fc863fc, - 0x1964e30b, 0x49ead748, 0x57f6c64c, 0x37671e68, 0x0e558e9e, 0x376b1e61, - 0xda01ba5c, 0x5ecaf781, 0xc438bc94, 0x200b0b32, 0xb76fb65f, 0x81d67b4f, - 0x0da05be3, 0x96b8e276, 0x3f2e586a, 0xeecdbb94, 0xd5adfec1, 0xd17e4126, - 0x9e5ab5ea, 0x75c5fe81, 0xcd8f3197, 0x419aafd0, 0x88fe4629, 0x9b018f4c, - 0xc453fb18, 0xf91eaf98, 0x37690944, 0x9fa2e419, 0x2ef44f14, 0xf54d93ae, - 0x4b192603, 0x007eff82, 0x82be027f, 0x57849d3b, 0x05736e9d, 0x3b74e91f, - 0x2987e425, 0xfac6d99d, 0x48e7f4f5, 0x754fe807, 0x5fd29ba5, 0xba52a654, - 0xf443d2b2, 0x07f10279, 0x6fd172e9, 0x4e3658d7, 0x3e5d7681, 0x4b3146e6, - 0xa71be298, 0xe7e09c02, 0x01ddf270, 0xf19673c9, 0x6a13e9eb, 0x72651720, - 0x53e49b15, 0x05ac02fa, 0xb42f30e6, 0x9be8dcaf, 0xd7b19a38, 0x1c71e059, - 0x502922ff, 0xac657480, 0x740fd53e, 0x1e812259, 0xc52d7c01, 0x961e0241, - 0x067e05f4, 0x4f713d3a, 0x24b2b3f6, 0x70889ac6, 0x668f73de, 0x54353d50, - 0x0cf50a8f, 0xc93d773a, 0xf54c73d3, 0xd02f4f24, 0xf54b59eb, 0x9eafcfd8, - 0x318fa627, 0x917a67f7, 0x580bcf5e, 0xfcf3916e, 0x633c95c6, 0x333fb9ac, - 0x949ea84a, 0x002cbdbb, 0x7f9d65e5, 0x864fb358, 0xf8c6c77c, 0x23328f11, - 0x86df8d1f, 0xaa4139f5, 0x97147c8c, 0xa7926313, 0x09825f78, 0x9fb933ee, - 0x7f927ca9, 0x653f29a0, 0x7c11a5da, 0x5eb770e9, 0x54e86026, 0xfea35e38, - 0xd234fd6a, 0xd9fae33b, 0x9fa07e08, 0x03cef483, 0xbb170263, 0x57d8dfa1, - 0x407ff406, 0x8eee5c0b, 0x2e3037c2, 0xea62a589, 0x991a60b1, 0x78e554bf, - 0xfbffdf1b, 0xfde107c1, 0xe0e74b72, 0x4bff8078, 0x8e21f71a, 0x4ca88ffb, - 0x32316e81, 0x3172c0ab, 0x6ffa4656, 0xb3f64669, 0x975e0341, 0x917e000d, - 0xa65debba, 0x1f915206, 0x4115825b, 0x3025cfe4, 0x8c7eb041, 0xe115641d, - 0xfef085e0, 0xc454bc80, 0xfd0355bf, 0x835f6c61, 0xfb5287f6, 0x5b7ed8ad, - 0x075bed2f, 0xb7da98e6, 0xda9817a5, 0x3ed069b7, 0x706747c8, 0xf01f68be, - 0x93b18637, 0x6fb53e6c, 0xf6a02f4d, 0xc0ac6a97, 0x574c7ed4, 0xbb60dffb, - 0x49fb63df, 0x703fc651, 0xe9fc798c, 0x6bf1e645, 0x416cfc7c, 0x431fb450, - 0x20a497e3, 0x117a7f1f, 0xd795bf1f, 0xabbed5db, 0x049aff0b, 0x5ea43aed, - 0xac683fc6, 0x9417fc79, 0xe56fc798, 0x2c17bbed, 0xa83bed13, 0x196978fd, - 0x2505ff1f, 0x0d66bed4, 0xb48f9178, 0x211531fe, 0x40d34f9c, 0x07485280, - 0x921d28fa, 0x93e818c0, 0x8481b2df, 0x38620787, 0x03137ddf, 0xd6e8e6fc, - 0x12042ca7, 0x9970f308, 0x8de2e9e0, 0x3f3e34e3, 0x9f5e6907, 0xab3aba2d, - 0x8cf9a651, 0x2e86b4ad, 0x37b6fe82, 0x678441ca, 0x2432bcad, 0x760a7cd3, - 0xb0a7be02, 0xf3ff3e30, 0x8ceb61aa, 0x674c8ae3, 0x2dadab57, 0xd2eab906, - 0x90d9e3ef, 0x055fe80a, 0x6ea8c132, 0x34f415b8, 0x39fc3d03, 0x0f4c63e8, - 0x392edcab, 0x5d9c7a04, 0x059b946c, 0xb2092edc, 0xff4087f7, 0xdffa227f, - 0xb77c70aa, 0x884293ce, 0xcc566fff, 0xcd9f50d1, 0xa4058eae, 0x5ca3f777, - 0xbb73a9d0, 0x14f64435, 0x9f88074c, 0x191449db, 0x1baed3fb, 0x305c94de, - 0x31f4d63f, 0x0b3777bd, 0xf2854e2d, 0x0ee79733, 0xeff8c370, 0x211d669a, - 0x7cc4fce3, 0xc7242dfd, 0x8725bfac, 0x2b0d69b1, 0xdc00fed4, 0xbcfd4d3e, - 0x1dfef0c5, 0x577c3301, 0x576e1981, 0xed05aa43, 0xad894299, 0xa9ef7a85, - 0xedebe730, 0x3812964c, 0x3f7b455d, 0x85f41c01, 0x3a60f747, 0x89bb1f02, - 0xfcddd3ae, 0xe53fbd5d, 0x4c2ca90f, 0x124b71f3, 0x5127fa23, 0x8f9b80b9, - 0xd3bfb23b, 0x0fcf9b55, 0xa0fe99fd, 0xec8cf84c, 0x58aecb7f, 0xd9ec059f, - 0x552f9a96, 0xf1c8c164, 0xc67ff644, 0xb8f1c8fc, 0x721f9c35, 0x39cf9183, - 0x53f2449f, 0x5fb8e379, 0x53f0321e, 0xbfb5fd69, 0xaf78643c, 0x1326eeb8, - 0xc3ba185c, 0x26bf3e54, 0xbb3f94d7, 0x3f94d0ba, 0x131cd973, 0xd07c1b9c, - 0xfcc67e54, 0x7bfca605, 0xe5311e2a, 0xc2b055df, 0x7811df04, 0xf6fe54ca, - 0xf94d6b69, 0xdc975d96, 0xf5547288, 0xde70cc81, 0xfad1daf8, 0xbf37b473, - 0xa45e2876, 0x57b011c7, 0x818e0e50, 0x7b6982bd, 0xabb248e3, 0x31e60f41, - 0x4b56a130, 0xc6cb83fb, 0xa4665ea2, 0xefd2433f, 0xc634c183, 0x843c979e, - 0x6346b93f, 0x89616061, 0x71f17425, 0x6fc86ca7, 0x0d7e4739, 0x9ec8fa08, - 0xf44b72f9, 0x72ebe5e7, 0xd3bd402f, 0x5f803e9b, 0x3ae79c7f, 0x99103d84, - 0xbf31225f, 0x7ebeb9f1, 0x7ae25cba, 0x53ac44be, 0x3bea5e4a, 0x0e10b99e, - 0x5b38ae0f, 0x5480f57b, 0xfd6893d4, 0x803f2127, 0x51e81814, 0x24c8375c, - 0x65bb6ddf, 0xea1957ea, 0x99abd004, 0x4257bfcc, 0x9bde133d, 0xec30cb7e, - 0xd475ef87, 0x8931acfb, 0xcab6f5e6, 0xa43cbfc9, 0x94fc7d22, 0x469ca91e, - 0x80656b69, 0x059543d2, 0x595e7e94, 0xe54b6941, 0x540f4a7c, 0x63fd2906, - 0x3f4a32e5, 0xf4a6acad, 0x4a1acae3, 0x510cac3f, 0xa3e95eda, 0x2e879754, - 0xf617ebfd, 0xc0b758b0, 0x8b0f6e03, 0xb2822cb1, 0xdee724cd, 0x53f39454, - 0xa3066f8e, 0x63ea7fbd, 0xde8ca260, 0x6fc915f1, 0x47d1d3bd, 0x085e4af6, - 0xcf4fa798, 0xa70c7b7c, 0x26c2dd93, 0x8f47d033, 0xf79cf45c, 0x2b04a1de, - 0xa9c032c8, 0x519c9bde, 0x0fb985ea, 0x3a2e75e9, 0x70e75f31, 0x3eb7675c, - 0xac6c97fd, 0x206972f7, 0xcaf7879f, 0xf0b30f34, 0xd7a45eb3, 0xf49bc50f, - 0x5bd29fda, 0x2e89dca0, 0x33a735fc, 0x6e48e748, 0x8354ffaa, 0xc7882995, - 0x2e10d8a6, 0x7bed4f8d, 0x38f285d6, 0x3eae5537, 0x7c77b234, 0x5467d695, - 0x29e30c3b, 0xa7c3346f, 0xdcc9a5aa, 0xbb89e07f, 0x95f21875, 0x45d0fabb, - 0x4a54ff48, 0xa6e67af5, 0xb1ced46a, 0x7c7141ba, 0x79f10efe, 0xf13c6370, - 0xa93bac2b, 0x3fbb3ffc, 0xf7a3d5bd, 0xf606b187, 0x01f50d85, 0xf73a0de4, - 0xdd07a8fa, 0x3f34af95, 0xfd49abd2, 0x1885ed06, 0x206677f8, 0xac10abd6, - 0x2f5e5bd7, 0xe397ad07, 0xf6a68df3, 0xbe8f3de0, 0x7af7c7a6, 0xb5855be7, - 0x7d04e3ea, 0xe7f0a575, 0xabd9d714, 0xbc4af3cd, 0xec6f2e09, 0x679a6d5b, - 0x7f900ff0, 0xc8292156, 0x9b82253f, 0x32c7143a, 0x6a97fa09, 0xe5bd50f1, - 0x6a572f12, 0x1e02d16b, 0xb466c762, 0xd1cdee33, 0xfb73cff9, 0x1fdf401f, - 0x1ecaadfd, 0xd7e17cc5, 0xb06cf551, 0xe7e82d6f, 0x0dbdd011, 0xef5053c5, - 0x3d76dd1d, 0x98b327d9, 0xa48b85df, 0x8d9d5602, 0x6609ce76, 0x7ffc8c99, - 0x35defd82, 0xc8deb0d2, 0x9fd468b7, 0xf3cccb99, 0x2667d82c, 0x0cc6bf38, - 0x939bb1e7, 0x56f3df91, 0xa0b730aa, 0x6ff39a5c, 0xbe49b8b7, 0x12c559f2, - 0x3f08ef5a, 0xa66ebdd8, 0x2fb907f4, 0xec99e57d, 0x87e8a1dc, 0xf75bfae0, - 0x7026140f, 0x3128a53b, 0xff20f9a4, 0x3f91868b, 0xfbe182b9, 0xa7a825a1, - 0x5de64e82, 0xefd27acf, 0xb23ff687, 0xd27cfabf, 0xfa214fc3, 0xbe49d721, - 0xda759450, 0xd84916c3, 0x974a415b, 0x76eb718b, 0x5c044d6b, 0x47d7011b, - 0xbf377fc0, 0xbf133225, 0x35025aa5, 0x5fce2496, 0x4a482f68, 0x47f816a7, - 0x51ed4fea, 0xb53fed7f, 0x3fa834fe, 0xfd7f54db, 0x0bfeb53f, 0x29bff47b, - 0xafa5fd5a, 0x0416da6c, 0x79b4537d, 0x3cc18b95, 0x4ea95474, 0x4bdd02f6, - 0x21762fd6, 0x82511c1f, 0xa3e7e42e, 0x34727921, 0x22d2f87e, 0xe7cca2fc, - 0x855d7090, 0xc7fd427f, 0x54d9f85e, 0x59bee7b4, 0xbd69baaf, 0x5b0d6754, - 0x1acb4e41, 0xdfa0a70a, 0x1c83e017, 0x46527a5e, 0x9fccd1b8, 0x4aafcf45, - 0x701eff46, 0x844f588a, 0xab2a5ec9, 0x9c24f3fd, 0x2759ca87, 0x7be459c9, - 0x04e9fed8, 0x5ab98fd2, 0xe87ccf5c, 0xe5f9d927, 0x0de52f02, 0xbb293b3f, - 0x30f6bd30, 0x4cb013ea, 0x7c8f0ec8, 0x41d840af, 0xc4ce2c87, 0xb1425856, - 0xa11fb11f, 0xc2f1d4de, 0xaa0edc42, 0xf0e4f0da, 0xb6afd083, 0x24badfda, - 0x7974be03, 0xf33f553b, 0x7a7aafd7, 0x62edcbd7, 0x5efdd7bd, 0x34f3de88, - 0x89adfb0a, 0xd86a25a7, 0xc971f685, 0x841bd55a, 0x9e9b25c7, 0x5c69ee7d, - 0xf5627eaf, 0x17f5045e, 0xc3e37a6f, 0x6f170031, 0xf0a71351, 0xe4a43861, - 0xc394fa6e, 0xba23f9bf, 0xf2f451e9, 0x18679a1b, 0x4270fe7f, 0xb78a5d37, - 0xb0d8d6ec, 0x5098f89e, 0x716b5bbf, 0xfd4fa144, 0x676849c1, 0x56f86d55, - 0xd1e575c3, 0xc94b125d, 0xb5cf8288, 0x80bd906f, 0x0a7a2278, 0x2fd1757a, - 0xd0397ca2, 0x247af505, 0xbdcb22bd, 0x1465fa81, 0x93fd17af, 0xbe2fdfc0, - 0x4fec7e8a, 0x43c45ead, 0xb9f78bc1, 0x95873c70, 0xcfe7ce0a, 0x3f464e2c, - 0x4c1a817d, 0x9fca5376, 0x9fb9ac17, 0xbdff2ff8, 0xfaf993fb, 0x42d7d7d0, - 0x2fb05573, 0xeaf6738e, 0x799c68db, 0x587c402c, 0x0fec8cf0, 0xc2b5fa41, - 0x22896f26, 0x9732c527, 0x80ebc393, 0xc3ce30b8, 0xbf414eb8, 0xd0e5efee, - 0xcc8ff27a, 0xee0fa861, 0x6cf1fdd7, 0x8b5fc12e, 0xb27184fd, 0xdae75f45, - 0xbb5bfc4c, 0x74e919b4, 0x052f806c, 0x4ce56afd, 0x487c0a09, 0xf95ea067, - 0x3853abbd, 0xc947989d, 0x5d81ef16, 0x639f0130, 0x67d566f9, 0x8f7a6e1f, - 0x6ee8c99d, 0x1f689e7f, 0xf3831dfa, 0x5664e1f9, 0x7c651f50, 0x07aeb235, - 0xf0375e60, 0xb9de4199, 0xc23ed7fc, 0xff975de5, 0x31934dd0, 0xb9f7abff, - 0x387be11c, 0xc2bf425f, 0xfbbf9429, 0x83f48956, 0xc9a38595, 0xe42aad79, - 0xc91f9cdc, 0x457fd02f, 0x0df0338a, 0x744093b6, 0xde5abf20, 0xa8df784a, - 0x575db157, 0x39757acf, 0x20fa17ce, 0x707d064f, 0x603eb759, 0xe81eb9ab, - 0xf20aeedd, 0x7a1a9bf5, 0x5f9469ee, 0x07a0d790, 0xe3f557e5, 0xdc6f8ff8, - 0x209de1fb, 0x75ebc7b7, 0xd5eb35b9, 0x782db948, 0x7c84bd69, 0xc7b7291a, - 0x894ac00b, 0x3cf0b726, 0xb416dcaa, 0xaaf44bfc, 0x65c7c78e, 0xf5d55eb3, - 0x8cf86f64, 0xca9793d4, 0x127aa89e, 0xecb3ef7e, 0xf3a8fc9e, 0x457fcea1, - 0x80bd29bf, 0x9f3a09fc, 0xc5d87cea, 0xf61f3aa7, 0xf098cff0, 0x3b7f9918, - 0xc10c04f2, 0x7f255dbf, 0xdf134962, 0xdef7838f, 0xf8459fec, 0xc734d1f2, - 0x9fecdfaa, 0x11438468, 0x79447d70, 0x8fec045f, 0x80881f28, 0x4be54c2b, - 0x8c6af71a, 0x2a6c20f8, 0x2bff9d67, 0x759445f6, 0x950f3eac, 0x82d49c37, - 0x9d691fc8, 0x753fea1a, 0xe8a89821, 0x9329dc3f, 0x7003b0ff, 0xe9da04bc, - 0x0a1198d8, 0x6c591e82, 0x0ecdebe7, 0x012ba777, 0x1cf1c5d2, 0x96d24cee, - 0x9fd41ea0, 0x1fb9da77, 0xe9dfc3a4, 0x31f8378a, 0xa4c9360e, 0x6c425bc7, - 0x093f3472, 0xdf8434cc, 0x3e5bd616, 0xe0768ff7, 0x87b633be, 0xcf40cefb, - 0xfa4765ab, 0x56bf5c7c, 0x23605ecb, 0xedc16b36, 0x77a1742e, 0x71ba0d34, - 0xfd9f3c1a, 0x6db7ccb6, 0xafa53e82, 0x8471dd61, 0x2b189f05, 0x72de7ee1, - 0x4d999fe2, 0x6b321d7c, 0x28797479, 0x39e5ef12, 0x77a869e6, 0xb9f0fd61, - 0xd7ac0fd1, 0xe23ab053, 0x42f5d379, 0x3d69aa6e, 0xce6b5458, 0xd4f5880f, - 0xc9feba37, 0x7fa49964, 0xeb84a170, 0xafb7a17a, 0x38de8796, 0xb1d3e80d, - 0xbfb8664f, 0x2649aa7a, 0xc8da9cfa, 0x305953f7, 0x8cafe489, 0xd4be9275, - 0xf286d6f1, 0x7aef7175, 0x9feb6dac, 0x3e421fb2, 0xe187f6da, 0x6db482bf, - 0x778327db, 0x47cafc20, 0x3d607fe9, 0x65d84fcb, 0xc7733f27, 0x7ff1272e, - 0xa5dfcec7, 0x76f0843f, 0x3af7f92b, 0x1c3b7d76, 0xa163b1f9, 0x60f500b5, - 0x7ebe00c7, 0xedf9daaa, 0x7f9a16f0, 0x331d1117, 0x7de88d14, 0x072fe9aa, - 0x54e02e30, 0xed0a8c13, 0x24b15d8b, 0xdaafe55f, 0xb1d11fc9, 0x80ecdbf3, - 0x9e379fe3, 0xd3ffb132, 0x5ed364e1, 0x73c5fec2, 0x8ef979bf, 0xc02ecfd1, - 0xdd86f1fd, 0x9fc84cda, 0x875fdaf0, 0x78ed7ea3, 0xed4ddb89, 0xdc1acb6a, - 0x48ba18df, 0xbd02a85e, 0xfac851da, 0xd16fb631, 0x4728f1c4, 0x57f2f13d, - 0x2f9cb3f2, 0x7c28263e, 0x8feffb3d, 0xf5c7c90f, 0x9364339f, 0x1ddfdc70, - 0x89ea03f8, 0x4be2565d, 0xebc7bc7d, 0x733d9017, 0xfbdf71ae, 0x52dc6e3f, - 0xbdc67cf8, 0xff9cdfe0, 0xfa878aad, 0x3d072917, 0x03e77cf9, 0x7a726f04, - 0xc9e7bfa9, 0xa7ff6bef, 0xa025fdd1, 0xe3dcebbb, 0x4b3fff0e, 0x0ba7b7f7, - 0x3e31bbba, 0xbfb5fca0, 0xa87eff52, 0x37f96b9e, 0xe36f7ba7, 0xb7fdedd7, - 0x33f79e2c, 0x5664fca1, 0xe2c340ed, 0x6f3dd2da, 0x5bee4267, 0xb1e37b69, - 0xf623e3bf, 0x5e34f47b, 0xf1b6fee5, 0xed03efb8, 0xac4978b2, 0xab3af917, - 0xfa2fb0bf, 0x3b23cbcf, 0x63da7fa4, 0xc5304f64, 0x2bf712b3, 0xe99f4adf, - 0x360bd8a5, 0xc200e3e2, 0x6c052bee, 0x4afe6f5e, 0x4adc3e62, 0xfd7e9fed, - 0xd373b43e, 0x83b264d2, 0xf7fb2521, 0xfe64d775, 0xad3344bc, 0x98f5ae87, - 0x129347d7, 0x89a8ebcd, 0x19abbea2, 0x0ed5ffef, 0x3c021429, 0xcbf01f8c, - 0x8ea7f444, 0x126548bf, 0x605893c0, 0x263bae11, 0x9df5cc3a, 0x836c7dc0, - 0xc5eff1bf, 0x3c2ec4e3, 0x47e95c0e, 0xc9900e3c, 0x3c4e7aaf, 0x6f09bf62, - 0xc78c2199, 0xe3978a61, 0x4bd4a131, 0x1eb16a7e, 0x1da26ec7, 0x349638a3, - 0xb82b3ca3, 0xa078e69e, 0x9ebeb875, 0x4cdf0dee, 0xd115cfac, 0x257f8ea4, - 0xcdd9f64d, 0x5cfad1f5, 0xa50fcba7, 0x7fc74e87, 0xaac92e94, 0x8e692e99, - 0xebca0a39, 0x8c3f5c64, 0x1c99f2c4, 0xb42a0b4e, 0x0fd624df, 0x28e678d7, - 0xa4278041, 0xaf482a65, 0x22f6db7c, 0x79b51f8c, 0xc5c7ea25, 0x1f9a166d, - 0xe112596c, 0x428d487d, 0xf7167bf0, 0xd4f7a428, 0xfe395e2b, 0xbb3f4320, - 0xba06e34f, 0x7c97ef9f, 0xd8cce67f, 0xf0c7f46c, 0xde7fc61f, 0x59b7eb00, - 0x063859ab, 0x615b34f0, 0xf404b8c1, 0x73ec4b93, 0x0cdc9f93, 0xe4aaefe3, - 0x55ce7aee, 0xf2bd37be, 0x015f4ecf, 0x45f9f63d, 0x94c76d8c, 0xc6288a6f, - 0x9a8ff6f5, 0xf7cabe38, 0x1e40d0b3, 0x0dfb2187, 0xab2f8afb, 0xcaf33fdc, - 0x891a5f1f, 0x1d71dceb, 0x7eb8e343, 0xa971e2cd, 0x8a70bd62, 0x0ebce279, - 0xe283afd4, 0x9f74bf68, 0xe7168cec, 0xbfac41b8, 0x28f1837f, 0xb2d47690, - 0x57d7196a, 0xbefc93ac, 0x5b1b5ac1, 0x661e251f, 0x7e116a8d, 0xf8374122, - 0x7fb8d9c9, 0x0d9fdbc3, 0xe919c6af, 0xa8e536d6, 0x1d27bc32, 0x61b9f7f0, - 0xc51feaff, 0x11f7ae2f, 0x2dec1bbf, 0xf451fc93, 0xdfc0bd47, 0x91df3dd4, - 0xa6d2f49f, 0xdfe416b5, 0xa62d6b4b, 0x553ad8fd, 0xb04631f8, 0xa9afd811, - 0x2cceec7b, 0xd93ecba4, 0xe5a5f18b, 0x40b5274d, 0x48c47d94, 0xe8fd627c, - 0xdd556f7f, 0xb50eeed4, 0x75e2267e, 0xc31b09c7, 0xad76f575, 0x3f5a38ba, - 0x7ef2b4ef, 0xf7f566ce, 0xf7f8cf0d, 0x0eb8efc3, 0xae3c7847, 0xf0996b3f, - 0x1ff24483, 0x553e3e23, 0xbf3842c7, 0xf5157ae2, 0x8c8da9c2, 0xc94077e6, - 0x06feb863, 0xd1b1ff79, 0xe37173af, 0x5da0df96, 0xb924d650, 0x4ca24b71, - 0x8fd0d169, 0x2f18de5b, 0xe99c3ce3, 0xdd6fe3d1, 0xc8356ec3, 0x10aaab45, - 0xd98ef6be, 0xfbb61771, 0xd0c69b65, 0xdebdf14e, 0xfc79c2e9, 0x2491a6cb, - 0xeb8dbd07, 0x34564ae5, 0x841ce311, 0x87e48c3e, 0x4c631ba1, 0xa07215f0, - 0x54d7ca1f, 0x6f3ccb6b, 0xd32dfa14, 0x788fb124, 0xf42dfa9e, 0x7b7e99ff, - 0x016fd75f, 0x23906fd9, 0x419bc0bf, 0xd344a5bf, 0x4f25736f, 0xee7de20a, - 0x482941ce, 0xab6fb9d7, 0xdbf4d149, 0x2fbe4aa6, 0x4dc459ba, 0x7e803477, - 0xdfa0dcbb, 0x45bf401a, 0xa3191f89, 0x73fa7ee9, 0xbfd0b7e8, 0xa136fe46, - 0xde328b7e, 0x74fe041b, 0xe9bc36fd, 0xe1b7e920, 0x3c53160d, 0xf84d44f0, - 0x6fd57a9b, 0x68add252, 0xbd53ef1f, 0x67f851b1, 0x37c7b093, 0x6c46388b, - 0x955cf507, 0x5cf4c3f6, 0xb9eaf9de, 0x759e117f, 0x2b77373d, 0x9ee8b8a3, - 0xdcf5c87c, 0xe7a0eddc, 0xae47e424, 0x64eee6e7, 0xa1172fdc, 0xd0f486df, - 0x97ca8c6f, 0xe5fbf985, 0xde4f198d, 0xf08df50d, 0x941b5ea9, 0xefadd11f, - 0x5df51946, 0xbe8bd695, 0xfa7e77db, 0x77d0ab6e, 0xa206c7a0, 0x0fe48d7e, - 0xde39936f, 0xc3e8c77c, 0x79465f1b, 0xfb4c9df9, 0xf859ef92, 0xa33bd1fe, - 0x7f21670f, 0xf3fa2a7d, 0xd9e9c6a2, 0xfaa4195e, 0xc7cebc27, 0xfb91ba57, - 0xb81acbcb, 0x2b56587d, 0xe7f03c87, 0x69df31a4, 0x9dc2ffd8, 0xf8014b12, - 0x13f56b26, 0x9febb40e, 0x1f589957, 0xf034c94d, 0x629cacc3, 0xd957fbf2, - 0xfcf0eb5d, 0xd9852cd1, 0xec5fbfd0, 0xed147498, 0xbe1ce2e0, 0x9e2c501f, - 0xb3b071eb, 0x4464f4bb, 0x9ce3483c, 0x9eb3fb37, 0xad531671, 0x9f53ae9c, - 0xb7184295, 0x22ee33da, 0xb8a17a44, 0x5dfcfcce, 0xc9377f21, 0xf62f842d, - 0xee351cae, 0x85d72f43, 0x4f027da7, 0x9e131780, 0x3c545242, 0x64a7a501, - 0xa5e37726, 0x4b2d77f0, 0xf0a05f70, 0x91f68929, 0xe3adc723, 0x3afc722d, - 0x773f751e, 0xbf2fa8b1, 0x6b9d2d69, 0x8e8bc48a, 0x747c48e7, 0x1f023de1, - 0x7e5d69ef, 0xd71891ed, 0x7a437c04, 0x809ff826, 0x3fc76817, 0xf9d322ee, - 0x5e048f9b, 0x9b8f5646, 0x370fe180, 0xe43a1c61, 0x79ccd5e7, 0x63e02fb3, - 0x119ec7d4, 0x315e9d38, 0x7dc01ac6, 0x4ef60dda, 0x1f3a83d2, 0x3e72b30e, - 0xd95e84d4, 0x3c62afd1, 0x251bf3ad, 0xe521da37, 0xb5e13b61, 0x0ed1f81c, - 0xf53ef645, 0x578124cd, 0x6aaf9d37, 0xd013f314, 0x26eb82c1, 0xf10abe7d, - 0x9b2358f3, 0xebca5d38, 0x58b25d38, 0x94c7ed27, 0x30de48d5, 0x71aca78c, - 0xeba1c50e, 0x0e7e19fa, 0xf0a29d23, 0x7f8d12af, 0xb39b3a19, 0x62cde7bb, - 0xb5aa6e51, 0xe7dc43fa, 0xb1f20a99, 0xfe10d896, 0x3efe1677, 0x2450fc57, - 0x78132ebd, 0x757884db, 0xb93afe20, 0x8efe15fd, 0xf9e969ce, 0x84d04ae5, - 0x9f4f09d7, 0x53b7fce6, 0xac5fa0f2, 0xcfc86f0b, 0xc74a3f90, 0xd233f21b, - 0x465729a1, 0xddf00f38, 0x78e7a327, 0x28d4bf71, 0x0f3b85f7, 0x919ffaf2, - 0xb8ca2cbc, 0xff7f307f, 0x4deebe40, 0xc55987de, 0xf7f0413a, 0xfdcef63b, - 0x77bf9123, 0xd12fdc4a, 0xf7da6f14, 0xd7cac1bc, 0x20ec1b4d, 0xf6dfb807, - 0xe75deab6, 0xae1fa9e9, 0xc03972b2, 0xe0c784f5, 0x0704baf7, 0x75a6f182, - 0xa4178a36, 0xf6e40c7e, 0x6f5f51aa, 0x5ba4b3b2, 0x7faf7ab3, 0x37bfa88a, - 0x8787497b, 0x47a87b61, 0x21bda11b, 0xce45eddd, 0xe0ffba17, 0x43bae35c, - 0x3bdfcff0, 0x1f9dbd2e, 0xce554f1a, 0x4c5f699a, 0xb54aab8f, 0xd1515e04, - 0x992c9bbe, 0xe7a0b7e2, 0x70ffce82, 0xa36ab7fd, 0xa59faf7a, 0xd08ec8da, - 0x2d5ecbcf, 0xf010583b, 0x254fa5f6, 0xe32b0179, 0x7f38b183, 0x1079878c, - 0x8ff72f92, 0xca6ee8fa, 0xed9f6997, 0x29f5dfc6, 0x1bc87dc5, 0xbb1d0c79, - 0xfb225331, 0x6cac3de1, 0x36e1da34, 0x268ab3e6, 0x47e73f21, 0xd73c21f1, - 0x3d5b5992, 0x3d7203c1, 0x85542ea2, 0x674277a9, 0xaf483be2, 0x7a433271, - 0x4cfafb35, 0xbef7f9c0, 0xdc4cb33f, 0x813b078a, 0x8fb119ea, 0x31b96125, - 0xce5a24be, 0xeaf86e8c, 0x7fa05bfd, 0x5ecbf7a3, 0x69bb940f, 0x7281c3af, - 0x85b56436, 0x19780c05, 0xe85542c3, 0xc87d1a77, 0x83ea0b77, 0xf07bb002, - 0xd341497c, 0xc2172ada, 0xbf7a25ab, 0xe498183c, 0xaa6dfe82, 0x32e93939, - 0x0e500bd4, 0xcd5f29ab, 0x4ad795cb, 0xce710c5e, 0xf1415a6b, 0x12b57948, - 0x14dc601d, 0xd78d9892, 0xbd41b21b, 0xfbc3569b, 0xc17f3859, 0xed6f58fb, - 0x416ff7c9, 0xa4fd03bd, 0xfdf237f7, 0xcf783cfa, 0x3b527283, 0x5c2bea87, - 0x073c312d, 0xcf91b053, 0x55fb054f, 0xec37e62f, 0xdde68a7e, 0xdf5ed029, - 0xc28f9c0c, 0xd13ce913, 0xe74dc948, 0x80be1f38, 0x0e0756f4, 0xa5f05f18, - 0x4909f8f3, 0xa3fd62c0, 0x6dfd7fdb, 0x9e535cfc, 0x07d68177, 0x272779ea, - 0xfc42c329, 0xe1f69274, 0x03be010f, 0x79379c56, 0x9cdecb3c, 0xc316b42f, - 0x1b6398fc, 0x6acfef44, 0x1e71471c, 0xe29f99b3, 0xe68ea63c, 0x57bbe776, - 0xefe843da, 0x4ced577b, 0xaf7be7c3, 0xf6f3d2b4, 0xb70f5c4d, 0xbf21680f, - 0x2ad5e1fb, 0x552ff3c3, 0x13d265ab, 0x74aa3787, 0x867e576e, 0x6fe437c7, - 0xdec876e2, 0xc3debcd5, 0x9b7edc75, 0x936dccf0, 0x5fce1e70, 0xeaf9cfcf, - 0x875f5a7a, 0x4d0bb9e6, 0x9ea45bf3, 0xa970f5d5, 0xf54147c0, 0x8f4fda5a, - 0xfaa5bbd4, 0x6fa1187c, 0x9d9f714b, 0x24c3d3f6, 0x91f5a547, 0x6e8e65f1, - 0x43f20dbf, 0xefe23bf8, 0xc32afdb2, 0x45f48d75, 0x678a24db, 0xf21ef9c3, - 0x3e493747, 0xf8287b8c, 0x7b221ad8, 0xe33b943c, 0xf99e703f, 0xc8f0cac4, - 0x03d22b48, 0xb58e54f4, 0x84bf8ff3, 0xb3df47e7, 0xf010e461, 0x5fe12e4f, - 0x5ace138f, 0xb27ee3cf, 0x8c995bde, 0xc4d98de7, 0xf207a43e, 0x3016646b, - 0x92a38de8, 0xf93b96ef, 0xfb46e0fc, 0x966ba747, 0xf3879d56, 0xeb8d916c, - 0x957acf47, 0x0bc78bce, 0x3e0bd618, 0xb70a77b4, 0x0cd648af, 0x73b850fc, - 0x0ea83245, 0xcbc444b6, 0xe6738954, 0xa76f1a85, 0x5ee49770, 0xaf47686b, - 0xdb57af47, 0xb41bdfce, 0xd5bda793, 0xa3fd885f, 0xa1ad7e71, 0xa7ac88de, - 0xd4bdfb47, 0xa75ff393, 0xffb9e257, 0x0a65779c, 0x62f9cf76, 0x3ee320ca, - 0x7eea9e8f, 0x2df7ece6, 0x5fc067cc, 0x98631fce, 0x86ef40cf, 0x40ff2051, - 0xb91a1bbf, 0xea30d73d, 0x459a56a0, 0xbde51bb0, 0xcba3f84c, 0xbbfdf226, - 0x16f7cc86, 0xc94ffca1, 0x581f8892, 0x49f5a030, 0x83cdfb24, 0x59f900fb, - 0x787cfdfc, 0xe1b2e51f, 0xa0a72e29, 0x4fa83c2f, 0x98af56ca, 0x256be544, - 0xb0dfd60f, 0x92ec9736, 0x51991c82, 0xb241ed7e, 0x0f1a0a93, 0x833ca226, - 0x7b44aefc, 0xd5ac6ca0, 0x9758ea8d, 0xdfce5d4b, 0x9961e715, 0xcf0c3dcd, - 0x5876e077, 0xf796f934, 0x72b76133, 0xe1cf2cb9, 0x26eefb72, 0x3e784715, - 0xad724e72, 0x728cb1cb, 0xc72dd59c, 0xd04f577b, 0x870fae50, 0x99a38a24, - 0xe5007a80, 0xe71e837c, 0xf3d8edc4, 0xd973f395, 0xbf20a599, 0x72ea5f38, - 0xa475cbae, 0x2d2b373c, 0xee3f62b7, 0xe34ed2bb, 0xf6d57098, 0xfae3ef0f, - 0x275ff68a, 0x3260f55c, 0x853cc7ea, 0x78e979c7, 0x5c78552d, 0xad7e8f60, - 0x3df5a05c, 0xf445fe9f, 0xd9ab33e3, 0x8b6f125f, 0xb5eff1e7, 0xb9fdf12a, - 0x9c87b3e4, 0x9e7ca79d, 0x4b9d5caf, 0xe5f6f53e, 0xe27ae69d, 0xf5476991, - 0xf01dafac, 0xbe3c0618, 0x8a59f1b5, 0xc2f13e0f, 0x8748a9c1, 0xe7c01de2, - 0x9d1b5fc8, 0x4e7a8c2c, 0x55bcd109, 0x39d320d4, 0xb384a603, 0xe51a716f, - 0x1575c798, 0x3f12766f, 0x0d64bd15, 0x8bf7814d, 0x9c317db6, 0x76166ae2, - 0xf05adc52, 0x072f6105, 0x1ca3865b, 0xbe3c2914, 0xfc2f522c, 0xe7edc6da, - 0xd3b1edb6, 0x1d527c70, 0xa8a2dfbf, 0x6ad576fe, 0xc278a7d8, 0x50bb52a6, - 0x8379f68e, 0xfe78c7c0, 0xbc67fb17, 0x2b8f4157, 0xf5c0db6b, 0x1aa35144, - 0x8a327bc2, 0x63b4b6ea, 0xc7d171bc, 0x957ff256, 0xf3a49dd7, 0x6f361314, - 0x794aff22, 0x8fda6ca3, 0x59df11eb, 0x18ad8727, 0x4a50d897, 0x1f0090fb, - 0xc45eb824, 0xf8c0fe53, 0x3bcde2c3, 0x850105b7, 0xef3f2fc5, 0xac72fd42, - 0xf10bbd79, 0x359ef50e, 0x3c47bade, 0x2223fd67, 0xc386f39e, 0x2f4b6f74, - 0xf0c79cf1, 0xb794100f, 0x4e78e66d, 0xec87d756, 0xb667e84b, 0x47feca3f, - 0xe9be7d97, 0x1e7835eb, 0xe3a5eda1, 0x25dfb06b, 0x0d72fb7f, 0x5db189c6, - 0xcaf79a76, 0xe280f85f, 0xbef7f5b7, 0xc87f09b0, 0xfe29e786, 0xab13fdbd, - 0xdf6b6b17, 0xe31d3879, 0x7cb7db06, 0xccfe8c97, 0x26af3b79, 0xadbcef7f, - 0x94585213, 0x914f4379, 0x11e7437f, 0xb7491f7f, 0x297b0dbd, 0xd004ed9e, - 0x5760f51d, 0x297d6e9c, 0x88f67f8f, 0xd18ddcf8, 0x88f43bcf, 0xe5b86dc7, - 0xff512bc6, 0xf27b7037, 0xefb9719c, 0x3f2f3d03, 0x146e3a0f, 0x37f5d7f1, - 0xf72e359c, 0xf401fe04, 0x74cdd8b2, 0xf661bafc, 0xbcc69faf, 0xc6bd3e86, - 0x03cf86e5, 0x8a79fa7f, 0xa73e6c77, 0xa5e8e51d, 0x343c50df, 0x078a6fd2, - 0xd3afa3e7, 0x11ca3cf1, 0xce3a73b5, 0xad3b9d3f, 0xd14fdf74, 0x9e488fce, - 0x47beb7da, 0xce266a7e, 0xaeb3b435, 0x973f8f1f, 0x9d6b78c4, 0xd0579e3c, - 0x3d7de301, 0xe22e7a2e, 0xeb5f397a, 0xc5bdbef1, 0x1f6d5ef9, 0xe00fee28, - 0xb5a5c8f1, 0xb3f1107f, 0x729374dd, 0xcf075e90, 0xe3ad471a, 0x72f42dc1, - 0xf47b1c77, 0x38aeeab8, 0x21ba08f6, 0xea9e713d, 0x3807538a, 0x49f9046d, - 0x2e768a3e, 0x8f2d7da2, 0xa3576f7f, 0xe3d6379f, 0xf4117dda, 0x9bdbc7d6, - 0x7b72e8bc, 0x50fc71ae, 0x4266d13c, 0xb57c4f52, 0xbf5d1f7d, 0x7f4bb4cf, - 0xebbefad7, 0x148954bc, 0x5eeb1e79, 0x86d2cbe4, 0xeccfe483, 0xf18b7f5a, - 0x7bff09b6, 0xc5320bdb, 0xdfa92f39, 0x523dfa4b, 0xbde1947f, 0x7bfa512d, - 0xe7d85dbf, 0x68fe7c8d, 0x7219c97b, 0x7b6d3d40, 0x975f13b6, 0x71483c6d, - 0xbdd66fd6, 0xe218b5ac, 0x08fe7027, 0xf6d3c619, 0xa4e1eee2, 0x30fdc5cf, - 0x8954ed91, 0xa29bca76, 0xf1be53b7, 0xe29da9a4, 0x76e6bd60, 0x63bdbb9c, - 0xac76ef8a, 0xb73358ef, 0xcbd58f13, 0xf6d14393, 0xd8aaec69, 0x29e6afef, - 0x0f74a3cc, 0x7bdf938e, 0xc862bb23, 0xcce79cee, 0x112e38f9, 0xbae28d53, - 0x388816aa, 0x537a9fb0, 0xce55de91, 0x77f618eb, 0xe0d7e231, 0x01dd51ff, - 0x9aaaf686, 0xbf42cfea, 0xd1dea443, 0x642c2d12, 0xe73cf7a0, 0xed0f14e4, - 0x90d3848b, 0x0f32079e, 0x67ef58ab, 0xcfabfe11, 0x0524b614, 0x5059f7fa, - 0x7a802ef2, 0x0c5ff7d9, 0xd67b3bf0, 0x8781c3af, 0xa9bf9365, 0x0079dacc, - 0x35ec2bd7, 0xc847ed3b, 0x7f74ecbb, 0x3b1af948, 0xd6ef778d, 0xbb239f6f, - 0xc656d7fb, 0x556087f7, 0xb996f783, 0xb7871d79, 0x2fe6bb7e, 0xcbe35768, - 0x1afe7ed0, 0x89eb8f28, 0xfeb4b18d, 0x8e2978e9, 0x7fcb51ee, 0xa8a9a1ed, - 0x3963f2d7, 0x4e6fe63f, 0x7d415509, 0x6e1c49ad, 0xee8034dd, 0xc97e28ab, - 0x7ba5f149, 0x8652beb7, 0xe6fb54f3, 0x60330c58, 0xfb09afed, 0x7ee237ff, - 0x63d51aad, 0x642f338c, 0x2e78c78a, 0x536118a8, 0x3f23135c, 0xfa11c906, - 0xe8e31ab1, 0xc5d8113c, 0xa84e7aa6, 0x89780f9d, 0xf8fd838f, 0x3f70aa39, - 0xe59107d4, 0x76fdfcf4, 0xdcbd8e7e, 0xba39ef0a, 0x9d6b97cb, 0xeeae1c79, - 0x3349f5c7, 0xe744ff95, 0xb3df9173, 0x23fe5e5e, 0x7aaedebd, 0xe265fbf8, - 0xfe489b7e, 0x57a5d43d, 0xb4717afe, 0xf4a25bfb, 0x2fdf9e9f, 0xed05a0b1, - 0xba762d96, 0x67ef0bb7, 0xdb0e73c0, 0x55ffbe34, 0xfdd30ae2, 0x3e843b39, - 0xd309892e, 0x44fd3e7d, 0xc23cb03f, 0x22f2d6cc, 0x15f4bdd2, 0xb3f8c33b, - 0x3e9cd7d2, 0xb6e977a4, 0x957f5b6f, 0xb18bf185, 0x7d2bd7e4, 0x1f117fed, - 0xd3c35a94, 0x2dbcfee9, 0xe7f78656, 0x3b796db5, 0x4db5e51d, 0x9c27a70d, - 0xb4af5f65, 0x57be6ade, 0x58e38c40, 0xbc42e865, 0xaf3f4177, 0x9e8bd45b, - 0xdb8632b9, 0x9f18f6d7, 0xdde48635, 0xb1d44f7c, 0xc641c6ca, 0x9e45fbf3, - 0x7fb17ae8, 0x9d8ffa8c, 0x38f47743, 0x263fdaf7, 0xe699ed09, 0x96407464, - 0xfa8e3d81, 0xe4eea8bc, 0x7c1ff430, 0x6fdfa316, 0xf9c389e0, 0x73ad33e8, - 0xcfbfea18, 0x19873bd2, 0x952399e7, 0x92a28f36, 0x8ed2875f, 0xfaf327b5, - 0xb5378c31, 0xf7a68b4f, 0x12c4c586, 0x8e1e8afe, 0x7a8e7a8d, 0xabe70c4c, - 0x531f6834, 0x43e5176c, 0x2d33f76f, 0x31b87a44, 0x49ebc3c6, 0xbcf8690b, - 0x20fb6eb8, 0x950a1e23, 0x72072a6a, 0x642cf84a, 0x832cb52b, 0x2bdbd6fe, - 0x28f0ef9c, 0xf2813f74, 0x55f8ba7f, 0x3933a6ee, 0x518e3191, 0x5c6614e0, - 0xe7eb33f2, 0x6fd51448, 0xcc69fc43, 0x646456ef, 0xf7926a95, 0xa94f5618, - 0x7e2ecc03, 0x43055a5f, 0xec44793d, 0x0c1fa3ef, 0x3d7c6ed3, 0x383f7a48, - 0x328bb180, 0x4f09bef0, 0xbf80db9c, 0x3eb3706b, 0x2b69e309, 0x5317d718, - 0x488f68dc, 0x033b00c1, 0x595554fc, 0x03df8837, 0x2f187cc2, 0xf42c2649, - 0xf37ee5cf, 0x8083b43b, 0x843df94f, 0x1550b157, 0x86c318a0, 0x9e3aefc9, - 0x96f3fbf1, 0xeb8ccc7d, 0x0741128f, 0x7a4ddc16, 0x7fbac1cc, 0x5aa3009d, - 0x155b7d45, 0xdc1cb7f7, 0x59b8739f, 0x58c3ed18, 0x42c70b07, 0x1caa18ea, - 0x2bbfca33, 0x5f03600b, 0xf39ac7ba, 0xf402e523, 0xf5bb445a, 0xf7a83f84, - 0xbf7a88ab, 0xabf7a88a, 0xe3abd5b3, 0x2836dca9, 0x58a5ef03, 0xf02f595c, - 0x09b3dbc6, 0x867e01bc, 0xcc7f3de0, 0xfb15e312, 0x18d784e6, 0x962b1bd1, - 0x8e6eba07, 0xfa7e20c9, 0x4eaedc59, 0x8966978c, 0xc3d70c35, 0xbefd248b, - 0x1877e64f, 0x1b6e63de, 0xa223e1c9, 0xcf02cd9d, 0x55bf748b, 0xb276f28f, - 0xb7947abf, 0x263e56f7, 0x6f67797a, 0xde8d89fd, 0xea5ef89f, 0x5a8d8eaf, - 0x4bd50fff, 0xf47daf65, 0x76efee0e, 0xa03727e9, 0x6e676cde, 0x1a54fd46, - 0x16b7fadf, 0x4cedc27a, 0xde999a5b, 0xc0dfc831, 0x9a17316f, 0x49f2479f, - 0xf472fe14, 0x29df7185, 0x61f3bbda, 0xe74d5e7e, 0xbe315c83, 0x9f7cb589, - 0xdc79eefc, 0x46cb078f, 0x25dfe61f, 0xe1aeeff2, 0x0fdde3f6, 0x1b0fb4cb, - 0xc1d5bf79, 0xe1efcdff, 0x801f07b8, 0x5f33ddbc, 0xa233850a, 0xdec5dbdd, - 0x677a878f, 0xde44fe88, 0x9e601583, 0x68e4cb49, 0xbe7160f7, 0x45e1cfd4, - 0x8b317fde, 0x66fdc5f9, 0x3159e7e6, 0x22dbe26e, 0x0f55a425, 0x82c79eed, - 0xd1ef802b, 0xc7be04fe, 0x9c592ffd, 0x8d2e66c7, 0x9adfd7c7, 0xa77fd260, - 0x70e27886, 0x8baf66be, 0x7cfe6ee7, 0x149eb5ee, 0xe54579e3, 0x1ee9ac74, - 0x9bd52aa0, 0x3d4dfa8a, 0x80f33d7d, 0x07a76a1c, 0x1f218f31, 0x7e1256ec, - 0x3d24f30c, 0x5084aa95, 0x3f6e2a2f, 0x37bb47cb, 0x5eb3f39e, 0xaebc4b5e, - 0x177ccecb, 0xe6461dfe, 0x5dcfff81, 0xdff3a1e1, 0xa7fc3957, 0x5d95fe71, - 0xa380de39, 0xb7043f27, 0xe15771f2, 0x8e7a33b8, 0x7af34aa7, 0x0ebedec9, - 0xcbf245e6, 0x3fd86d79, 0xc8f9ead9, 0xadfbfd83, 0xd30fd0ca, 0x23de3f13, - 0x153fc821, 0x24714fea, 0xc194dc72, 0xbc72fed8, 0xfff4146f, 0xe8bf7132, - 0x52264aa2, 0x08b7571e, 0x34a51fef, 0x913ea447, 0x8f72a64e, 0x974a7b8a, - 0xd5297a54, 0x56f36bf1, 0xb6983dd3, 0x36fb790b, 0xa25fa0b7, 0x402fe045, - 0xb52d97f6, 0xed1df682, 0xde308aee, 0x60d2c727, 0xb961c1de, 0x9abf09ab, - 0x13bf919b, 0x456c13ca, 0x66b55218, 0x7149d10a, 0xc87cb057, 0x0604754f, - 0xe37da2c7, 0x6987df31, 0xd6711d4d, 0xf8bb31fb, 0xfbc7136d, 0xb7e71263, - 0xa63fbc48, 0x6e307b36, 0xbb6bb1e2, 0xbc22abee, 0xe38872c3, 0x7ef93ffd, - 0x37bc4f6e, 0xc0699b4f, 0x327b33bb, 0x0267fde1, 0x5e054bcf, 0xaa1d04ab, - 0xc4ab3e04, 0xe255afbd, 0x812adcde, 0x3bc42adf, 0x7b888fa4, 0x3d23177b, - 0xef119520, 0xa1d6bfc0, 0x7b432641, 0x520f0f7c, 0xb75be087, 0xb2a4fc85, - 0xbc43efc3, 0xde39135b, 0x03a00e6d, 0xdde035f1, 0xc241f983, 0x78e0eaa7, - 0x0e9cf286, 0xef105602, 0xa739f123, 0xb6fde007, 0x87d424d8, 0xd6784c63, - 0x1f9fc712, 0xf3e29fde, 0xf390a25b, 0x6a25fc48, 0x5d605efc, 0x8fb37bbe, - 0x765c44ab, 0x1197b895, 0xcd7688f1, 0xbb0fc02a, 0x3f93e398, 0x2f60221f, - 0xfd6249a5, 0xc074055f, 0x3d8527fc, 0x74c67884, 0xb75f2c67, 0x762a5a24, - 0x04a788ab, 0x4b0fdf7e, 0x6cb4b20c, 0xf18043c6, 0x1e641a97, 0xe1fdf584, - 0xc8ff335a, 0x7ee2256e, 0xc893cf49, 0x56df2b6f, 0x2f7fb82d, 0x74debfcf, - 0xe69e5bae, 0xfe10f78b, 0x35da1203, 0xb872133f, 0xfa85f902, 0x8bc3d7c7, - 0x152c1f05, 0x223f06f7, 0x2131e7f8, 0x7ceb8fcf, 0x48e7e5e3, 0xf1e64f96, - 0x1699898e, 0x9862bf71, 0xe309e319, 0x834cf5bd, 0xc6dad17e, 0x9fdd2943, - 0x92b63ec9, 0x650ec6dc, 0xf8afe43e, 0xf10c1f8f, 0x7dfd70fb, 0xd78a1ed1, - 0xeb1dbfef, 0x0e83bf89, 0x711587b4, 0xd7cca4cf, 0xef51cd93, 0xeef2ad8d, - 0xa65fa1b1, 0xbeecfeb7, 0x73f11b69, 0x1e44e5de, 0xbfe027d6, 0x8ec03663, - 0xc157581a, 0xc81bd62f, 0xa57a8c5e, 0xebfc49c6, 0x1be7fe80, 0x17b624f8, - 0xc754ceff, 0x5f501bb5, 0x240680bc, 0x6a2fc130, 0xcf11d906, 0xfa0f7380, - 0xfea956b1, 0xac2f38be, 0x8fee8f8a, 0xdf2c65fb, 0x5d657087, 0xac2bf26a, - 0x9ef47d54, 0xef59ac7b, 0x44f314ac, 0x9cb344c2, 0x4fc2f3e8, 0x39577d45, - 0x5fb13b02, 0x9227a7c9, 0x1cde273c, 0x52a89e7d, 0xf7de20b5, 0xcb8c3551, - 0xe3573077, 0xfd0f73f6, 0xe49f68c3, 0x3af06054, 0x7ce983f4, 0x7d7190b6, - 0xaedc6417, 0x04f5c7d4, 0xe715bdf2, 0x3ff13703, 0xcb0807ce, 0xdefc6a17, - 0xe42dbbe3, 0xe4225887, 0x672151ed, 0xfd7c85cb, 0x8acbe51c, 0x297b58f7, - 0xab9085fd, 0x90872895, 0xe0cd8f1e, 0x3fb8bcf6, 0x2ccf5f4c, 0xfba08db4, - 0x161cab22, 0x4f94179a, 0xae0721ac, 0x768f760f, 0x7647ffa3, 0x4e03b966, - 0xfba2cfcc, 0x2cf8a5dc, 0x37cdf237, 0x9c1759ce, 0xc8161e2d, 0x2b16f74f, - 0xea4bf72a, 0x8957c8f7, 0xf75408fb, 0xd5fd0ccd, 0xd856264f, 0x9635de29, - 0xe4d787c7, 0x81de1366, 0x86b19d1e, 0xb4ca5a75, 0xfbeebaeb, 0xec9feac3, - 0xef835ee5, 0x6960de85, 0x41a17641, 0xfb88d44f, 0xc8279924, 0xc5f41886, - 0x31268bc2, 0xd4f5eff4, 0xcde8bd13, 0x2e6f5cf5, 0x4deba292, 0xf5d78edd, - 0xd17ea466, 0x4c17c5d3, 0x54bf9d36, 0x7a465e1d, 0x3f744867, 0xcac3b242, - 0xd7992ff7, 0x33d19b9b, 0xec95f01f, 0xed0be030, 0xf16fdd21, 0x89e328e3, - 0xae4793d4, 0x00d7e7d3, 0x4b343bdd, 0xfa393cf3, 0x79abf3ac, 0xfd3fc85e, - 0x794fcd08, 0x5a5347a7, 0xd92d7350, 0x69770c23, 0x1c2ef70c, 0x0bbf7d5e, - 0x46b87be9, 0x56af9fec, 0x74bf1843, 0x197166b8, 0x0f76d5c1, 0x2fdc66d2, - 0x3de1741e, 0xc8d6b34d, 0x247e9fb4, 0xf14e9826, 0x399fdf9f, 0x63e21b23, - 0x9a5dac16, 0x6b38fc8e, 0x373a52dd, 0x37c1247b, 0x59806fd8, 0x79ec8796, - 0xbcc6fefd, 0xb43ead67, 0xdbe37bc7, 0xfdd1d5bc, 0x27f8553d, 0x779853ae, - 0x7643ae08, 0x8674c6bb, 0xfc8e0f81, 0x82eb4ec2, 0x8ed82d2a, 0x58bad570, - 0x2555837c, 0x280fbf44, 0x0fb571d5, 0xf0ea94e9, 0x73298b5d, 0x4f7ed024, - 0xdbc472ef, 0x3b5f456f, 0x2d3ebbee, 0x3a0245ee, 0xbbf264dd, 0x56d77df2, - 0xb66347e1, 0x4463f25e, 0x7c97a7be, 0x62938f17, 0x7ff9e8ee, 0x6869ffb7, - 0x315df58f, 0xe6b4bf8e, 0xe84f92f8, 0xa11f7989, 0xcf8bc450, 0x5a1b175a, - 0x66ce4518, 0xb3c7f389, 0xce997ec4, 0xebd7858f, 0xe3e739f6, 0x5e973e48, - 0xfaf884b8, 0xcd2a7dcb, 0xafc0656b, 0x17a5efa8, 0x507dd346, 0xe2bb9e0b, - 0xfc0b8c71, 0xf94cbf6a, 0xc4eda725, 0xf53fedc7, 0xce8239d2, 0x9df4a9df, - 0x5df6af88, 0xda01e74d, 0x3ad3fdc5, 0x7c9cd29e, 0xc1c6bc3d, 0xe9de50f5, - 0x743c919f, 0xa66857f1, 0x779e7286, 0x5e5ce7fa, 0x31d9fef0, 0xdeebec38, - 0xe0a1771c, 0x2cd7806b, 0x2169349f, 0xc2df9bd4, 0x0d8d8ae5, 0x7b1f9196, - 0xd1f7ac6d, 0xc6bff228, 0xb5f931e1, 0xf3965bf2, 0x4caec0f7, 0xcc99c434, - 0xc87bdf12, 0x65efcd3f, 0x4b20ee65, 0xfa127945, 0xcc0e5bb0, 0xdbb772f7, - 0xd3d4e3cd, 0x79c6bb17, 0xd6fd6985, 0xe8abce3d, 0x53b09e79, 0x13465bf2, - 0x5f9e3ddc, 0x9e368e8d, 0xa58c71ee, 0xd1f1edf2, 0xb450ffdb, 0xc0595adf, - 0x8b4fa07c, 0x79bffdc4, 0xd434fba1, 0xe3ab791f, 0xb8c32413, 0x4d8a6bf2, - 0x35794ff1, 0x5fdf74b9, 0xed5ceafe, 0x76bc835e, 0x36cd85d1, 0x4743e5d1, - 0xd532e880, 0x40e3dfe1, 0xf0a17cb9, 0x583d4f81, 0x11d3a72f, 0x82bc382d, - 0xae7ddbf4, 0x3ea7e768, 0x8d53a48c, 0x1fac13a0, 0xd2740cb2, 0x7ef913e9, - 0x07d2faeb, 0x8bfdc53e, 0x45edf8a7, 0x08b1ebbd, 0xc74465fa, 0xf383a75f, - 0x0fd82b6b, 0xdfc2f381, 0xbbf8a665, 0xe827f15e, 0x7f47e3ad, 0x51dff60e, - 0x944efb94, 0x1f5851cd, 0xe17387e7, 0xc17dbbad, 0x8fa2e30f, 0xf3a9c527, - 0x04167cc3, 0x71aa3e01, 0xf1f7a3fb, 0xb682c43c, 0x974f18f3, 0xf1362e9c, - 0x01738a43, 0xff415397, 0x211e7ba3, 0xc50d6ebe, 0xbd19ed7a, 0xd9c5278f, - 0x185c1f0b, 0xffb34364, 0x11c1f1ef, 0x29f837cd, 0xde60479c, 0xf0bd79c2, - 0x1b86c7f9, 0x18ea97fb, 0x79c4e697, 0xf6fcfaa9, 0xbde383b7, 0x1e1d70fb, - 0xab7b275c, 0x8e254860, 0xbf7c60c0, 0x37f4f5c8, 0x145bdfe8, 0x68f0c4ff, - 0xcae2f476, 0xdfa0977d, 0x99b2aab5, 0xc5d85552, 0x0ce2ed0c, 0x688f5dfe, - 0x2b5e05f7, 0xcae2ebf4, 0xb5b7ee66, 0x70db9905, 0x323b00cf, 0x8ad8fc92, - 0x69cf6cc3, 0x7e8dc06a, 0x83dc4d73, 0x65812aa0, 0x67e85919, 0x1a0ccc4a, - 0x938d77f0, 0x4f2cd7ef, 0xfdc6e3dd, 0x8fd42b10, 0x9a5b33fe, 0x77e4ca72, - 0xe5995d7b, 0xd7e93a04, 0x7ab0c744, 0x1f91249f, 0x1f8454f2, 0x1fa994f2, - 0x7da6cd89, 0x28bc488a, 0x281dfe36, 0xb3ff0985, 0x9dfe87c0, 0x3e6ea5a4, - 0x8fc295ce, 0xaffa04fd, 0x363b022f, 0xc1f645d6, 0x7c2c0b92, 0xe853687d, - 0x3c6b2bbe, 0xf1c5af2f, 0xff71d871, 0x59f5c643, 0xde276098, 0xd5d32610, - 0xf1c2128b, 0xdc2123cc, 0xe0978587, 0x5c63a37a, 0xfcf803cb, 0xd7207b79, - 0xa6ff7809, 0x0901f36f, 0x81fc33f7, 0x35cf118b, 0x03d33072, 0x772d7fe5, - 0x74b96266, 0x8138fac8, 0x39e017a7, 0x9f618087, 0xdcd7df94, 0xe13dcb0d, - 0x112be60b, 0x5fdf86fb, 0xc7b7cc6c, 0x1fb02af8, 0x4acbdf91, 0xfda242fc, - 0x074cfc41, 0x34fdff9f, 0xf2772f3f, 0x07f10575, 0x6e3ed7f2, 0x3c529d3f, - 0x87efb871, 0xb4dd79d8, 0xbcf363ef, 0x114f686e, 0xe05ad8eb, 0x4fb0c557, - 0xb3e2a177, 0x545d3f20, 0xfd8dcf0d, 0x2727628d, 0xf2dae838, 0xdebd76a8, - 0x83af3c3f, 0x4f4f94f8, 0x92247b22, 0xed74762f, 0x69eff027, 0x9e33a1dd, - 0xf1c388b2, 0xfad1ff4c, 0xfdae93ee, 0x761c45aa, 0x5efca873, 0x69fe3fbe, - 0x99c51c6e, 0xa3b8fdea, 0xda336969, 0xf53477c5, 0xbcf8899d, 0x3fe2e0a3, - 0xed43ba63, 0xfa8b13dc, 0xce897ee2, 0xc1f9dd97, 0xa42c6aeb, 0x475fdf5b, - 0x2f3c1ff7, 0xeb3a71e4, 0x01fe9154, 0x7ef8d6e6, 0x47df8857, 0xae02bcc5, - 0x715fd157, 0xdb743877, 0xf3dd000d, 0x3406e87a, 0xebefa6f7, 0x43d5037c, - 0x893ddea0, 0xf7f494f6, 0x726fbd1a, 0x35d7bf98, 0xe346c57e, 0x8daf1ee9, - 0x0f8fafc6, 0xeff84a7a, 0xf7b88fc2, 0xf8c7c74d, 0x77dc7c99, 0x1d75dec4, - 0xe03acb3b, 0x3fb0db0e, 0xde3e78f3, 0x7cfc489f, 0x1fa05985, 0xf6fa745f, - 0xe33e3f20, 0xbd45edf4, 0x4ceb6257, 0xbc920657, 0xcbcf85bc, 0xc905c0e4, - 0x0313fe30, 0x21271702, 0x9cfb9a1e, 0xc07fbd97, 0x80fbf9ce, 0x81f7f39d, - 0x5baf9d0c, 0xecd7c89c, 0x538d2274, 0x92c77eff, 0xbb1f87ad, 0xc4fbf81d, - 0xbb3efcdb, 0xe373d952, 0x9697e443, 0x3e2e3199, 0xfc203d32, 0x7c5d2d0c, - 0x433bc7c8, 0xa332f2e1, 0xc1ce9621, 0x9b2f98cc, 0x319fdbee, 0x32c3c79f, - 0xadf879a5, 0x22c275a6, 0xb3d2d711, 0x4483f41e, 0xfe7333d6, 0x6517ba04, - 0x471ee69b, 0x9c35917e, 0xf44e66cf, 0x608e78c9, 0xf68932cc, 0xf21f47f1, - 0x3c00b634, 0x45ef1433, 0xe0f99d31, 0xfbc20d7f, 0xb99aca51, 0x9e45347f, - 0x4853f993, 0xf3e1ed57, 0x1073c23d, 0xc79f0e4f, 0x69cfd861, 0xdd322b53, - 0x38f7cfc8, 0x7207a87c, 0x827df56f, 0x22fdd574, 0x0afbbcfa, 0x171801d8, - 0x27b77b9a, 0xb724f907, 0xd4a3eede, 0xd01894c6, 0xb30ab96b, 0x31a29a61, - 0x0c698ec5, 0xbd9a61b3, 0x354fd850, 0xe0fd9137, 0x786bf1ca, 0xd36e79bf, - 0xfbe35ff3, 0xb7784af9, 0xdcabe064, 0xa3bfb7a6, 0x3f3e7673, 0x565efdc5, - 0x9fd699a7, 0xf0cdeac3, 0x38668de5, 0x47866c33, 0x65c333ee, 0x67683638, - 0xe11ef88c, 0x86569d9e, 0xde2b2bdf, 0xf438a56c, 0xa0ae7157, 0xe93b5e78, - 0x4dc509c5, 0x712718d9, 0x05a745fc, 0xfe3b95fd, 0x59c532fa, 0x658a6e74, - 0xfbb86718, 0x831618d3, 0xed9bbc71, 0x18bf30eb, 0xd9fe8768, 0xb5f6cde2, - 0xedb34f18, 0x434f9d52, 0xedb50f14, 0x4bbcfc6f, 0x086b06e7, 0x6f8e2ee3, - 0xe445fe7f, 0xfa1be3cb, 0xaaf61d93, 0x7d60b414, 0xdd3847c1, 0x3ebd08c7, - 0xe2f5e846, 0xfc7af33a, 0xaf6e970a, 0xfce287ba, 0xe3812637, 0x2fb2b5bb, - 0x2577c587, 0x8c6dfb74, 0x40dd67b0, 0x7687cfcf, 0xd08879d3, 0x7ba179cf, - 0x6bd11f35, 0xb3ea0c41, 0x0cdaa38e, 0x5c5d4bf4, 0xcea3c663, 0xcc8497df, - 0x24ba27cf, 0xcf0ce7a1, 0xc55e3033, 0xe71524b3, 0xdfa367ef, 0x8bbd7f53, - 0xbc2f19db, 0x20f2e9a0, 0x992a7b8b, 0xb2ae70c7, 0x79b3ef5b, 0x089e31fd, - 0xfbb035e9, 0xbb447179, 0x2eb1fd7a, 0xda5fcf2e, 0x448279f8, 0x95638781, - 0xe86ec8fb, 0x7d2b23b2, 0x380689be, 0x727766af, 0x776fe12e, 0xf986bdf2, - 0xdec364aa, 0x4e30bbe4, 0x8f414eae, 0xe3b92b36, 0x498f9fb9, 0x3d72e7c4, - 0x11f313f6, 0x6ff56d8f, 0xd81cb0b8, 0x718c23d9, 0x5735f967, 0xe41a26fb, - 0xb9f287fe, 0x3712b74e, 0x392bcbc7, 0x9cf093cd, 0xff0d7148, 0xfd71618e, - 0x80dcb76d, 0xcfcd5ef8, 0xcc2b67d3, 0x963c832f, 0xfaedb96c, 0xfcbcf061, - 0xec5e5199, 0x2b71540f, 0x78de2f3e, 0x3d15ce92, 0x8efee16a, 0x0504fa48, - 0x13fa3d9f, 0x39ea0147, 0xcb75efa8, 0x9f7f7a08, 0x239bec05, 0xdcef83e3, - 0xb38e4505, 0xa06f0ffa, 0x9f3330f8, 0x684bdf02, 0x97ae75bf, 0xe9e8ebbc, - 0xd19becc2, 0xa02df754, 0x8fc87978, 0x0c297eba, 0xa489eb99, 0x6fc16aef, - 0xe4621bf0, 0x7d72c893, 0xdce904a6, 0xd07cc974, 0x43ff0693, 0x8a6aa1c9, - 0x076c8dcf, 0xc1985823, 0xe181da0e, 0x9b972875, 0xfc169c78, 0x88b65b24, - 0x61c41f63, 0xf915c7ba, 0xf8a21811, 0x83d13652, 0x4d99bd78, 0x37d754c6, - 0xc3f5396d, 0x52abfcb1, 0xa2bf73cb, 0xe7249cfa, 0xdd30ee6d, 0x9c4fdb6f, - 0x70f36f47, 0x8feeff58, 0x64d45f9e, 0xe3aeb8a7, 0xbfd23427, 0x149e300b, - 0xb768bfcb, 0x3d68c058, 0x78cfa5be, 0xab6e538c, 0x1fa5f7e7, 0x5e33efab, - 0x1ebccb3b, 0xf9f44fa9, 0x39fe20f6, 0xbe7afd1a, 0x83ce1726, 0x771c788b, - 0xcc8a9f4a, 0xd274288a, 0x2ad44bdf, 0xd3fd7132, 0xbbc38f79, 0xcc14f08e, - 0x9fefc850, 0x5c9a7e4a, 0xe83a9fe1, 0x02edbff6, 0xaca139ba, 0xec25fe0f, - 0xdfa1d793, 0xfbd90bf3, 0xf7507b80, 0xacacfd3e, 0xa3df9d00, 0xfb40f40f, - 0x56161533, 0xe266df80, 0x609c353c, 0xae674f9a, 0x719e2896, 0x78f372d6, - 0xe36ebef0, 0xaac05afc, 0x5622dea9, 0x6ac1694f, 0xce217e73, 0x273c2e47, - 0x8a76e3c7, 0xfaf9cd6a, 0x8d92c0b9, 0xf0d1ac67, 0xc7d335f6, 0xc702fbe7, - 0xa36cdd27, 0x2ab7ddfe, 0x6977ef8e, 0x6df387cc, 0xe9272ae7, 0xa01662ff, - 0xe629dc7e, 0x7307f2fd, 0xed20b37d, 0x37d33f98, 0xcb9e0fab, 0x2d23f3e7, - 0xf99e4919, 0x13c57ebd, 0xbf007859, 0xbce187cf, 0x8524dc5b, 0x036c2187, - 0x9fc11d51, 0x3826bde3, 0x3679e37e, 0x6e38fc7d, 0x3ef673e3, 0x9e116fa7, - 0xb8f9929b, 0x0225f98d, 0xad1b251f, 0x98d17f26, 0x79d0528d, 0x6aaf9e39, - 0x1acaf7a1, 0xf54d58ce, 0xec1d798a, 0xba076601, 0x2b58298d, 0x755660e3, - 0x25d0f1e9, 0x1ccbced1, 0x755c7810, 0x945f5e5b, 0xbed1c7db, 0x9d1027ed, - 0xf84a7a43, 0x06d858a3, 0xec8cc5ed, 0x7b3f2982, 0xe2938721, 0x26a6bd1e, - 0x4a2fbe8d, 0x653361fb, 0x0e789bff, 0xd03e32b3, 0x99da0e37, 0x2ba5f169, - 0xc1bebf24, 0xcf9d6fe4, 0x88e4f0f1, 0xa22a4b8a, 0x3a75b7ac, 0x53d5213f, - 0x3b70409c, 0x599da79f, 0x20c06a9d, 0xb8e32317, 0xd3db8cbe, 0x3a8fe742, - 0xfe744ab7, 0x20e929f9, 0xea7e0f9d, 0xff430f5a, 0x09d02a40, 0x1253eff5, - 0xfcf7845b, 0x34dc3565, 0x73a40de7, 0xe3178c56, 0xc61b4a0f, 0x1a0ea5c9, - 0x62e3b73f, 0xbee2d62b, 0x218cca54, 0x61df9023, 0x866e33dc, 0x3ce3a3e7, - 0x075f5ed4, 0xc2ea7ba7, 0xa1dcc660, 0xce7fbed8, 0xc38f281b, 0x7cbce862, - 0x99cae00a, 0xb432e940, 0xe65952cf, 0x5333b46e, 0xa04678a7, 0x8b957f4f, - 0x916493b7, 0xf684dc67, 0x270e08e3, 0xd6f92c3c, 0xa0ae1311, 0xfcac5276, - 0x1cf87a93, 0xfa1b4ded, 0x7a061c27, 0xc4c8a84f, 0xf10653f6, 0xa70b5134, - 0xbbfb3d61, 0x75a01ee8, 0x23373cc8, 0xbbef3d7d, 0x2eb82971, 0x0b06dfdc, - 0xfb63d075, 0x97fdf4d3, 0xfbec83b0, 0xf2f0870b, 0x97994ec2, 0x24e7cfc9, - 0x15f6eba6, 0xfaa1d72f, 0x5ea246e2, 0xf9db8f7d, 0xe47c395f, 0xeb42bf07, - 0xa0803ce5, 0x58e9f953, 0x0bcc3216, 0x21bed3e5, 0xb4fcb3fb, 0xef1cf4cb, - 0x95c63509, 0xa1ec1497, 0xb2943bef, 0x509f3a66, 0x838e6f5a, 0x7a2622bf, - 0x979f3abb, 0x3059969f, 0xf99abb6a, 0x2c3ee9f9, 0xb95a27d8, 0xd3f3f364, - 0xfc6e1992, 0xe8539456, 0x7169cb39, 0x0a71fae1, 0x67a847ce, 0x7aa09642, - 0xda5d3779, 0x79a62ddd, 0xe1c3dda8, 0xa8bfb10e, 0xb7f5ebe7, 0x39c4d34f, - 0x7bcf7e3d, 0x2028255b, 0x4dd3cfc0, 0x5ddfc927, 0xf09bb4d2, 0x3745f3a3, - 0xd059629e, 0xaae4a780, 0x6405b0e6, 0xfdb8e9fc, 0x025e874b, 0xcba3d924, - 0x7d4b3bf3, 0xbf1f2163, 0xef90616b, 0x792eacd8, 0xcab37527, 0xf0fd0b22, - 0x6389d2ee, 0xdf2f308d, 0x35f37efd, 0xb2b78113, 0x6bf7f286, 0x6b7bdee3, - 0x7506c621, 0x4ce83b9d, 0xb00d3bf7, 0x0076022d, 0xbb00cc3c, 0x2313f223, - 0xe02353f2, 0xcdbe5e34, 0xbd974e19, 0xfb8e6d8c, 0xf4051ae0, 0xf0df5b5c, - 0x6479bc74, 0xd747d579, 0x4b8ef7e0, 0x7bf7f8b3, 0xaf249acb, 0x65a3d064, - 0xe4871e5e, 0x3368b6f0, 0x9a1e2287, 0x507d44df, 0x71b928d2, 0xdfa8e0fd, - 0xdf182612, 0xabde18f3, 0x92d3ebe7, 0x5ef483fa, 0xb10ff5af, 0x3a3f3c90, - 0x772a73e4, 0x362dfdae, 0xaf3dfcc5, 0x52bbf6de, 0x50b7812d, 0xc7f7eadf, - 0xa8f96db7, 0x20aa7bfb, 0x7d7ded7f, 0x469f497b, 0xc72f5b9c, 0xe5ba38fe, - 0xa3e3c745, 0x7dd14e43, 0xd6187fba, 0x079a01f4, 0x2e4ef3b1, 0xff75abc0, - 0x14787a54, 0x27785fda, 0x4f1fce2f, 0x704ba148, 0x059a7a5e, 0xef76c12e, - 0x3768bd29, 0x80ec6a7e, 0x5e0cf2da, 0xdc4df309, 0x01ffc249, 0xfc00cb67, - 0xc7e9dd64, 0xa4e1c2ff, 0xe609ba16, 0xafefeab6, 0x1ecdefc1, 0xc032d018, - 0x8ff7f002, 0xe0993a5f, 0x419e5a8b, 0x04eac2f8, 0x196b0f0e, 0x03fbc320, - 0x23267d83, 0xa3bbd6fd, 0xa109fdcb, 0xc5fef46f, 0x891df60e, 0x84aafb43, - 0x2c783bcf, 0x757a06da, 0x4db1d17a, 0xd31f01eb, 0xf49623ff, 0x5bb6fadd, - 0x1e13f3ae, 0x6f8c7e82, 0xa6f8114c, 0xbbf49179, 0x5f44f642, 0xba130b9c, - 0x6f4ce9e9, 0x71bcd0f6, 0xb416c569, 0x0fa6521f, 0x55e379a5, 0xee27ef97, - 0xe9e9dd51, 0xc4fe9e24, 0x5bfae6ed, 0x46bc50b6, 0xb24e43ca, 0xdf171eab, - 0x23b90067, 0xba0870fe, 0x3c7cdc58, 0x73190dff, 0x80001bd1, 0x00008000, - 0x00088b1f, 0x00000000, 0x7dddff00, 0xc594780d, 0xbbbcf0b5, 0x26effeef, - 0xb24d9bbb, 0xf379f909, 0x71100843, 0xa9189313, 0x18884dd6, 0x220bb531, - 0x49716b62, 0xc93049f8, 0x2d16ad46, 0x544859bd, 0x46d10882, 0xe1b80a04, - 0xfd2b6202, 0x1a8c4582, 0xf68882e8, 0x72dfbd2b, 0xbd3fadeb, 0x8a7e1bd7, - 0xb4564288, 0xeb6dea5c, 0x2666739d, 0x5c9377d9, 0x9f7b7aa8, 0xbe8f8be7, - 0xcef33bce, 0xfe73399c, 0xb3339ce6, 0x9086bb1a, 0x258e4264, 0x4ec730dc, - 0xe631df9f, 0x224c9d15, 0xf433bba4, 0xc84b499c, 0xc421127b, 0x09f04845, - 0x0e7b6853, 0xd1eddf21, 0xb4897504, 0x734de1de, 0x44b2d116, 0xc345bd7c, - 0xd57fbde5, 0xd2b3e5de, 0xd32d3172, 0x9912abe7, 0xbd33f58b, 0xfe5a0e69, - 0xa7aefe02, 0x9f561ee5, 0x58ad25ae, 0x7fbec39f, 0xe5dc84aa, 0x76d4cfa3, - 0x7d296e3a, 0xb5b89dae, 0x916b8e9d, 0x0bca1789, 0x5d6c16e7, 0x736a614e, - 0x897842cc, 0x51269bd7, 0xe6364ef8, 0x76d1566a, 0xc8afa7bf, 0x515c8435, - 0x97b0cde0, 0xff40f9d1, 0x44d21c74, 0x3c369527, 0x37981cfe, 0x7ad7afad, - 0xcf3a64b3, 0x39fe1ddb, 0xe35ebed0, 0xd0b4429d, 0x77c0b789, 0x8823b405, - 0x3b76399f, 0x40f227b6, 0xffffbc19, 0xb8954f08, 0x4f115fee, 0x7534ef77, - 0xf8242c9d, 0xb7fd05f7, 0x2aa1d7b9, 0xbad2fa07, 0xcb871a4e, 0xd0ffc377, - 0x24ad4871, 0x2c3a1493, 0x8d6e22ab, 0xbfe836ff, 0x7a07e979, 0x513781a2, - 0xf02ff43d, 0xeb0a4ebe, 0x82fce952, 0x76cf24fb, 0xb2cfdec2, 0xe8959211, - 0x21e613bf, 0xc3f79ee0, 0xd17f34e6, 0x3f2c7cf0, 0x76e6a978, 0xe4b79c5a, - 0xf4edaecc, 0x590f79fb, 0xdb865108, 0x9d711ed3, 0xb8cf7fdf, 0x9f495c9a, - 0x86b0defa, 0x19fdebe2, 0xb69cb3c4, 0x1a435f7b, 0x73efff00, 0x743f95bc, - 0x853211f7, 0xb5d95f90, 0xd0499df8, 0xbddbe483, 0x53b7e288, 0xd0234122, - 0xd23d4cc3, 0xd28860c3, 0xfeb095c3, 0xfbe87d74, 0x872707ee, 0x067d7482, - 0x619100c9, 0xbec4153e, 0xbfa9895d, 0x29eb00a3, 0xb44d049d, 0x0e68da3e, - 0x5e80956d, 0x50a5a028, 0x5feb093f, 0x07fad895, 0x38e230ef, 0x1d1933dd, - 0x433a3776, 0xb6001cc1, 0xc6de008b, 0x7694a3a2, 0x64487482, 0xb69994ef, - 0xe36c7c61, 0x3a52c172, 0xb4dbe2f0, 0xe4dab23f, 0xb01f4f19, 0xbb943284, - 0x4a3c7152, 0xbe91ab0f, 0xfd470664, 0xab42d38f, 0x394f5c70, 0x36a3cbac, - 0x1f787cef, 0x014591fd, 0xc89937f8, 0x7d09634a, 0xe8c3a44a, 0xe1c0eba4, - 0x134f5d21, 0x60bb83a0, 0x7f878a00, 0x536f386f, 0xd89ffbe8, 0x08038425, - 0x484e58cd, 0x75f5611d, 0xa4c72ccb, 0x86d4f029, 0xddf4090d, 0x03bc1bca, - 0xd972be82, 0xf3fb48d3, 0xeb22ba73, 0x83c036a3, 0x804bbe1f, 0x29b73ffe, - 0xefd32856, 0xd3f2c0a7, 0xbf870bef, 0x7df039ff, 0xe0c7c019, 0x65166d27, - 0x1f8c34bb, 0x80b9fcf1, 0x6f69ebaf, 0x9c6278ec, 0xd98f7ef8, 0xf007ffbd, - 0x4e1ef145, 0xb45e0174, 0xf0f1aeb8, 0xc7d1f4ba, 0x5e7eb44d, 0x82b1d69b, - 0xd4bfd3e2, 0xf015f386, 0xbd1a95de, 0xec8de48e, 0xa5a594ff, 0x2ff9865c, - 0x964f7465, 0x62e22819, 0x2e1fa2f1, 0x485dd253, 0xd23587a2, 0xf0e5ef28, - 0x517f8001, 0xf8f7cc77, 0x621abfdf, 0x21be09db, 0x3f07148a, 0x92452ba7, - 0x12fcdd61, 0x3ebd375b, 0x56e40f3a, 0x9f02dc3c, 0x8de5c6ff, 0x7c788ba0, - 0xbbe01bff, 0x5dbe246c, 0xe84c81fa, 0x80d4bfd7, 0x9fef8a78, 0xf77e1090, - 0x4d0489b4, 0x4bd6ee94, 0xfaebd212, 0x90212d07, 0xe8a6839b, 0x6067c00e, - 0xdeb88dff, 0x0acd1ae7, 0xea364da1, 0xf705bf19, 0x171f18db, 0xdc80140c, - 0xece7473b, 0xee73eba5, 0xa09eda37, 0xa4208024, 0xadda37e5, 0x5ee7ff40, - 0xb3f589be, 0x5a10a2dc, 0xe986000e, 0x7fe081b8, 0x578a11b6, 0xc7119669, - 0x0a57b13f, 0x8fbea019, 0x5e4639e2, 0x36ffa39e, 0x8dcb0c94, 0x3800a841, - 0x07082cfa, 0x8e23699d, 0x59335df7, 0xd16fc745, 0xad0d5e48, 0x2932596f, - 0x31e0ced4, 0x16d5cac6, 0x4a90e90d, 0x45bff986, 0xdee0bc73, 0xa7275622, - 0x60ac7970, 0x851243bb, 0x3ab8c9b3, 0x05fa05a2, 0x4bf5a03e, 0x78673ea0, - 0x7f565a1d, 0x479817f4, 0x7d351ecb, 0x9eaf3d34, 0xba5892c7, 0x17a619ca, - 0x17c3294b, 0xf1a126a9, 0x2f1b5e14, 0x21226a5b, 0xe963e02d, 0x2ae27234, - 0xc0e0f4da, 0x5b23a074, 0xa3a92f69, 0xe269c0cf, 0xa7b8510d, 0x36bcf7f6, - 0xd477b68e, 0xba613244, 0xcdbfa581, 0xf0d5793b, 0xaf380b3a, 0x4b427fe9, - 0x7e1e38ac, 0xeef14147, 0x89bb62b6, 0x7d88aeb3, 0x92efc0ae, 0x0f2f4c35, - 0x1fe02bc0, 0x75cde999, 0xfd526f5c, 0x617af28a, 0xafd404d7, 0xce40ffa0, - 0xf4c0953d, 0x903dc831, 0xaa8e6d33, 0x9e741cab, 0x14d56766, 0xc71b1947, - 0x27e98367, 0xa788fea1, 0x243d78eb, 0xb5e6a5da, 0xc75ab716, 0x0cf9476e, - 0x90dd16f1, 0x2c88e4c8, 0xafd17961, 0x10ab3d75, 0xe6e9193e, 0x2839cdde, - 0x97481b97, 0x89bce81e, 0xc740f484, 0x98248c8b, 0x1162e940, 0x9f48966d, - 0x881bd78b, 0x8d7eb312, 0x89b97521, 0x49bb85cb, 0x7bbfbf04, 0x357d5c67, - 0x7d68db09, 0x2d8491b3, 0xd755ecf0, 0x8e7d50b7, 0x85f7d67c, 0xe93df621, - 0x8bbdf366, 0x3aa3bbaf, 0x79d3f5a4, 0xdd51306f, 0x5d0684ea, 0x97533eb8, - 0x267ae0f5, 0x1e737896, 0x2bf2bd06, 0xa52b679d, 0xf5f03fdb, 0x6639f812, - 0xbc00aaaf, 0x9c1ab59b, 0x0361f47f, 0xd524e7e2, 0x6bfeb0e3, 0x59aee41d, - 0x8dae79f4, 0x8075f378, 0x2cd67b26, 0xaf3c48db, 0x00d4c57a, 0xd0e0d374, - 0xd32ae8a8, 0xf972c3a1, 0xe5ff8e0a, 0x1cd6d096, 0xa014f744, 0xa15cf2a7, - 0x9994c957, 0x474c7cb4, 0x6e5a3bed, 0x43f56399, 0x4f60037f, 0x0efdf2d0, - 0x77eecf26, 0x453d71e8, 0xd057cc59, 0xfb071d0d, 0x9ec55f33, 0x43658e02, - 0x74609fed, 0xbaf0f5c3, 0xea0f7346, 0xd5fa21e1, 0x22dfa410, 0xfaf01e9f, - 0xf32b970a, 0xf8a16ec1, 0x1412857e, 0x2f608fc8, 0x3e295fb3, 0xe5a52de6, - 0x79174e57, 0x67402956, 0xf2bcde4c, 0x4159331d, 0xccf37c87, 0x27fb1f4f, - 0xb4fe7f5a, 0xfad0315e, 0x746b4005, 0x88915efd, 0xbe0bc617, 0xbe810868, - 0x7b33d26c, 0x15ff69b4, 0xfbd19ecc, 0x71842c37, 0xc079d05e, 0x084a69de, - 0xeb03b73d, 0xa2943cd3, 0x863aabc9, 0x16cbe0cf, 0xf439bdf6, 0xa0bb9fb3, - 0xa413d53e, 0xff26a3ed, 0x74d75846, 0x7a889283, 0xc25ad7f9, 0x381709c6, - 0x878f5e28, 0x9c7ddd98, 0x4e304956, 0xa1fb0dbf, 0x90b69a7c, 0x33a273f6, - 0xe543e715, 0x2759da2f, 0x82b618d6, 0x34375dfc, 0x8fed84ae, 0xd3d37ceb, - 0x8bf8f968, 0xb4e59ec5, 0x0fa7d06a, 0x073d29eb, 0xafbb32d6, 0x016ca35e, - 0x16fd90fc, 0x8f58879c, 0xb5c59ac0, 0xb2581f50, 0x8f9016ec, 0xc839f163, - 0x3723127b, 0x166891cf, 0x86c6d3f0, 0xe830dedc, 0x1e89fe95, 0x4dc4af54, - 0x8dd29f17, 0xa93db59d, 0xee8df863, 0x5f3d21d3, 0x1740ff6e, 0x43d33972, - 0xca804e30, 0x0ff82265, 0x594c72e5, 0xad995a3b, 0x5495e063, 0xeba9df6e, - 0x47fc1253, 0x9e5a5d60, 0x97f78ffc, 0x145e302a, 0x4ae922e5, 0xa93cbe46, - 0xba03cef3, 0xf5875475, 0xfd7a3175, 0x99d983a4, 0x076e06f5, 0x963eb092, - 0x797d450f, 0xc5ee9a95, 0x7fa704f3, 0xf7c9845b, 0xce1af591, 0x401ab71f, - 0x20654d8f, 0x23d06c93, 0xc15fe856, 0x0e9ea7fe, 0x3969ebeb, 0xbf58597b, - 0x4f813f88, 0x46c3be28, 0x1b93ef3a, 0x29bf8c6c, 0x459fa01a, 0xe5f50415, - 0x63b52d22, 0xd2bde04b, 0xe5d74037, 0xa40e8bd4, 0x8a67f22f, 0xf9ef8a15, - 0x5033b784, 0xb1ca97bb, 0x30a43a97, 0xafe60bec, 0xe5356c37, 0xb57b5f00, - 0xcdcf5836, 0xf9b1ca12, 0x1b05951d, 0x9ec97968, 0x13fd702b, 0x2e5d182a, - 0x2f503909, 0xb1f2e54e, 0xa3d210de, 0x8933fe1d, 0xf6883ec0, 0x1374f68f, - 0x64ad28fd, 0xae401e24, 0x1421e8ab, 0xd1f6a653, 0x57265ed4, 0x24e79509, - 0xf2126ec6, 0x8938e41e, 0xf4d503b3, 0x88fa1411, 0xa4a23dc9, 0x7213dc82, - 0x97dd98f9, 0x3e3b44e8, 0x97d6153f, 0x9b9327ae, 0x6bc425bb, 0x7d456933, - 0xd0c0f422, 0x9c8f5cb8, 0xbe9906d2, 0xcf813c32, 0xae0e677c, 0x8bd212eb, - 0x95e844fa, 0xdf20e8b1, 0x88fbe1a9, 0xbc60e9d1, 0x9afec153, 0x75f0934e, - 0x65a6bc74, 0x853cdc24, 0x50536d3d, 0x693d323f, 0x9e127a64, 0x97d0cbe6, - 0x5e31faf1, 0xc1ebc61f, 0x77d33d54, 0x3d859d62, 0xd98d3a93, 0x85975301, - 0xfc08a4b4, 0x94eade35, 0x26bb61e4, 0xa8d18ef0, 0x1f65095c, 0x9ef905c9, - 0x2a62f950, 0xc4c80fad, 0xa1657c0b, 0xefa1e978, 0xb7fb7337, 0xd7cd9527, - 0xabf467ad, 0xd8a47d93, 0xc112eb0a, 0x99346f7d, 0x051e81d8, 0xe8db373e, - 0x1df02577, 0xefa1b7e3, 0x1cc3a48d, 0x2bd57df3, 0x173fd426, 0x0c85b65e, - 0xb3f88f68, 0x94bfb41d, 0x4ed01bdf, 0x0d8af73d, 0xae39e9f5, 0xefc25d0f, - 0x7e611e40, 0x41aebe16, 0x008e3552, 0xc6334bed, 0xf6140881, 0xd983b359, - 0x21ed2359, 0x99139f5e, 0x80cae8c3, 0x8e0bcdfb, 0x4ca00781, 0x7fa021e1, - 0x7e32716e, 0x5699ec0f, 0x3efa43fc, 0x187ab3e0, 0x40c5fdf6, 0xf7ed06af, - 0x7d2918e7, 0x8b2ed74d, 0xd1e7483e, 0x83b5699c, 0xfeceab7e, 0x41dddfd7, - 0xd1ee1fcb, 0xf3ac0311, 0x497369f6, 0xb7f2d8ee, 0x3e3ba431, 0x772fc310, - 0x9b9754ef, 0x40e5d57b, 0xbf7cba9f, 0x653ae6d3, 0xf9e1d941, 0xc1b5d282, - 0x87ba7ad0, 0xd5786bc2, 0x8668fa80, 0x1390ffd3, 0x7a26ade4, 0xc86cf018, - 0xf80a78fe, 0x9ffd023b, 0x5034f048, 0x31148a36, 0x5f5f03fc, 0xb6cfcd30, - 0x61b7828f, 0x06a311fc, 0x75ad4cf1, 0x173944f6, 0xd2e27ce0, 0x403c3f7b, - 0x9668bfe7, 0xdf02bed9, 0xcacb6b78, 0x18449ec1, 0x4dfd6049, 0x8bbec21f, - 0xf5846bb6, 0xb693353f, 0xac3570a3, 0x89b0fa67, 0x6f801244, 0x69dda85b, - 0x1bfc4ba4, 0x77776fce, 0xf4c3cb44, 0x359dbb7f, 0xf94e0113, 0xe80fb22f, - 0x37e851e3, 0xeade4ec6, 0x4bfc7264, 0x463299fb, 0x02b699f8, 0x038d9afe, - 0xfe3a4afa, 0x0cf97ff5, 0xa5e2fde5, 0x823ee1af, 0xb33e63ce, 0xc80a4dab, - 0x1e0fc5a7, 0xdf62f7c0, 0x8ad32a76, 0x36d7b6fb, 0xa1d95818, 0xcda9f2c7, - 0xb8b95f6c, 0x3cc10a57, 0x931759a5, 0x6c2f412a, 0x640dd9d6, 0xf1e35e24, - 0xb7a6c1f8, 0xf5efc013, 0xf61d2201, 0xc7b3127b, 0xb809adec, 0x135a507f, - 0xac0cbec0, 0x9043f1bf, 0x6b378b8f, 0x902f603d, 0xcff4367d, 0xc37cde2c, - 0xe85685c4, 0x4aa4d3e7, 0xb96d13f0, 0xd0543c01, 0x7e6217ce, 0xf4f5c89e, - 0x6ae5bcbd, 0xd0f1f805, 0x62ff0666, 0xd0077187, 0xd17ff5d1, 0x1ac97f22, - 0xb93b07e2, 0x089def5b, 0xda6cad7c, 0xe7d61d3e, 0x1ae99983, 0x224bbf6c, - 0x638bc076, 0x5fbc0a69, 0xe03ec92c, 0x8df586e3, 0x4f76b1b5, 0xc7f9939d, - 0xa597b32a, 0xaf91580c, 0x6d3e80e6, 0x08f94cde, 0xdef59fc6, 0x0d70eeef, - 0x6b3495f3, 0xa1532dfd, 0x1e7567ff, 0x7b21bbe0, 0x90b7d366, 0x4c2fe0be, - 0xe398b5f1, 0x99f2abeb, 0xa4f822c1, 0xeae400b5, 0x05ad15e2, 0x8cec51f6, - 0x44d93e21, 0x213272f9, 0xf9129da7, 0x1993fc02, 0x63bed54e, 0xb59a7dac, - 0xc67a8350, 0xedde21e8, 0xb74a99f4, 0xb71fb0c9, 0x6f58c925, 0x7d23d24b, - 0x77ba7fcb, 0xbce86fe7, 0x2ffa749e, 0x26ccbe80, 0x6bd062de, 0x455ed44a, - 0x35405acd, 0x136461da, 0xcc89afb3, 0x92eb85fc, 0x31558ec9, 0x125373fb, - 0x39504fdb, 0x73f405f1, 0x1f3fddee, 0x64b6fc06, 0xec053c7d, 0xcfc5c085, - 0xb35fe0f4, 0xdf284bf6, 0x011f1ead, 0xcff409ba, 0x868a0b24, 0xc3c072e5, - 0xbcfc46f4, 0x98e924e6, 0xb145751c, 0x82974a9f, 0x41076ee5, 0xd4b8da7a, - 0x46fef68c, 0x4004c857, 0x2b7cadff, 0xee46a7ec, 0xfb6e340f, 0x740b5785, - 0xe3ec921e, 0xfe30aca1, 0x17986c18, 0x3e71d2d2, 0xc41796dc, 0x8f4a9ef2, - 0xb759d696, 0x5ccae3fd, 0xce9f53c0, 0x9eaded03, 0xdf980481, 0x244edb87, - 0xb61afcc0, 0x0dde7169, 0x16524fa1, 0x09cb0d16, 0x905fc69d, 0x5d827604, - 0x42f8c2b2, 0xedb87c5e, 0x560594d3, 0x7d403fe6, 0x5e3a3a5a, 0xc9cacecc, - 0xdff5fdf0, 0x6672eb64, 0x72042197, 0xf9898cf0, 0x33bb45f7, 0xaeffa636, - 0xcdfe124b, 0x3fd02cde, 0xa2796543, 0xf7c4e406, 0x2efe6ced, 0xf0166f7d, - 0xba9247e5, 0xb52b259f, 0x52e54424, 0x84894ae3, 0xf33fcca8, 0x20594bdc, - 0xfedc3fff, 0x0c5d5652, 0x89dff17c, 0x6a498de7, 0xaff09a7f, 0x0ce1f4ba, - 0x63ceaf18, 0x31cc7e60, 0x3da2abfc, 0xa4fccf59, 0x816b9483, 0x8377c50e, - 0xd82f660d, 0x18c483bb, 0x5d5b9702, 0x7ad7f73f, 0xd82ef9bd, 0xe3ef88d7, - 0xf40d5ffa, 0xfa92e144, 0x5827f424, 0x9f28a28a, 0x77fcb4bf, 0x918cf5d1, - 0x8d9d74ff, 0xc6cd4eb0, 0x0471e1e8, 0x780f43e9, 0x6558b7d3, 0xed2957d0, - 0xf7a2be8c, 0xe59f706b, 0x814c2732, 0xdd3e80b8, 0x76f9056d, 0x43b9817d, - 0xb3ef0893, 0x333ed042, 0x0bbf10bd, 0x0ffa3156, 0xc3f410a6, 0x095691a5, - 0xe676b4fd, 0x20a8cfe7, 0xf8b455f6, 0xe76624b3, 0xbd6789b8, 0x5fd70f36, - 0xc70738c2, 0x400fd08b, 0xcf2f2047, 0x23a44648, 0x7b425fa9, 0x9de9ab54, - 0x458efd07, 0xbac52b57, 0x2a1aba72, 0xeae89dff, 0x23c74149, 0x20afcae8, - 0xa38db95d, 0x23f715d3, 0x127b765f, 0x36bec1f4, 0x2d6be395, 0xfbd13f97, - 0x2eafc28d, 0x796b7cc1, 0x6b46b57f, 0xc47a0b58, 0xd638fba3, 0xda89bc3f, - 0x4a7fb0c5, 0x3e9ebb03, 0x57cfb5c7, 0x6448dd70, 0x9608fc00, 0x2fa88dab, - 0x7244d31f, 0x9d498ec0, 0xe81bbad4, 0x515e7523, 0x0bee3b49, 0x17a01c33, - 0x7fa2d740, 0x1f34e974, 0x1c5823b3, 0x8f533a28, 0x07969cfb, 0x8ecc7d2b, - 0x097e41a8, 0xa02936ac, 0xe7f5a707, 0x08fa072c, 0x031e232c, 0x86cf71d2, - 0x9dcfe045, 0xac80f56d, 0xb225f113, 0x9d77cd52, 0x05538b12, 0x0f18226f, - 0x0d338e1b, 0xe821f96c, 0xf422c6ff, 0x8ff90c9b, 0x8dea09f3, 0xd6438dcb, - 0xde2136ad, 0xd068fc45, 0x25741146, 0x3fb191fa, 0x7a646892, 0x407ca468, - 0x054a73ff, 0xa1eb7f11, 0x3cca2e9c, 0x5ff823de, 0x456ca3c4, 0xc8b01cbe, - 0xbf399c2b, 0x049c4332, 0xb36c77fc, 0x00fd8416, 0x19598dfa, 0x694fcadd, - 0x50e92028, 0xaaab9ffb, 0xbcca6233, 0xc1f7d0fd, 0x5f573755, 0xa877fa8b, - 0x7aa6c01e, 0x26bd9459, 0xc355e205, 0x83b532f5, 0xff127d8d, 0x1be6e2be, - 0x941eaaa8, 0xee7ff8c4, 0xd11f82f4, 0xc5e35444, 0xf5c727c2, 0x5bfda3af, - 0x383ede15, 0xefe826ee, 0x7e5112a9, 0xe14bd3a0, 0xf753ab5b, 0xdfe52887, - 0xf78c4143, 0xaf0e537f, 0x6c319d5a, 0xe17b501f, 0xc36549cf, 0xefa3c276, - 0x495d76d5, 0x3fd8b2c7, 0x15fe83d5, 0x92e03efa, 0xe7890ed0, 0xf49704d7, - 0x656becd5, 0xe09d7d84, 0x74f5f662, 0x2fba4960, 0x581df941, 0xdf6023e6, - 0xe9c4bb52, 0xe3e4bb42, 0xfd680753, 0x1f9f59b9, 0xbb40a71e, 0xbec1e67b, - 0x4651702a, 0xa9d81bf9, 0x6f94490d, 0xaeccfd8c, 0xe31cfaa6, 0x967e8205, - 0x38fd39d8, 0x97fc0482, 0x32a4fbdd, 0x5a4277a0, 0x6ba36eb3, 0x379703f9, - 0xfbe1c713, 0x9779f8cd, 0x205f98bb, 0xa1b55850, 0x26dffa00, 0x5617b011, - 0x594f1e15, 0x63a9fb80, 0xbe630b29, 0x0a7bec6b, 0x53b8d9f1, 0xcb1e2a37, - 0x7804e1a9, 0x45f9796c, 0x338dc82f, 0x42650921, 0x04ea1c83, 0x41a1b6bb, - 0x29211603, 0x03bfcd0d, 0xf5731fe3, 0x5f9d3c64, 0x8177d706, 0xa706b79d, - 0xbfe9bcc2, 0xd1b57d12, 0xc4e508b7, 0x2b46b9c6, 0xeb0a91c6, 0xd83c41ee, - 0xc3c05ecd, 0x34aac2aa, 0xe665a718, 0x4dc63b74, 0xf5073da8, 0x077e0f2d, - 0xae0245fd, 0x1aba7d55, 0xa9ca77b0, 0x0a0bf75d, 0x4673a677, 0xf5f2878d, - 0xe2eeed38, 0x5710acfb, 0xff8e5d1f, 0x174664bf, 0xf82f921d, 0x8ff452ed, - 0x677f5892, 0x1fb31f76, 0x55e9716f, 0x5c5bf1fe, 0x36bdaecc, 0xe4069918, - 0xb01e5fb2, 0x201d5d80, 0x5f604fde, 0x65567c4d, 0x9313ae3b, 0x0536ae5f, - 0xd74666fd, 0x425763c0, 0xee32b5fd, 0xf03c8867, 0x5cf71863, 0x8ab3cba7, - 0xf2803e70, 0x90214583, 0xfe5cfbc7, 0x96fac2ef, 0xdcf57b73, 0x831637cb, - 0x5fd8517f, 0x5099cf9d, 0x94da766f, 0x4e406b27, 0x796649fe, 0x6468c603, - 0xc967ed1a, 0xb71c4ee7, 0x84ea14d3, 0x68f60ff5, 0xeac9beb1, 0xdbf4045f, - 0x29faeb78, 0x0d608798, 0xd51e8015, 0xd008bab9, 0xa0bedd31, 0xf2e8c51f, - 0x4f238811, 0x2597ce0b, 0x767117d0, 0x63f034cd, 0x85c5bee1, 0xce2adc7e, - 0x1529e31f, 0x2b22329c, 0x34917c74, 0xf9bce76c, 0xbc32d9e7, 0xc68ff614, - 0xd5eefcc8, 0xec04cd73, 0xf448f25c, 0xf8fc06b0, 0x7b0108ae, 0xc257b9b8, - 0x5f0b9a71, 0xe5fec3d0, 0xdfc65eee, 0xa0dfbe01, 0x78c2cbf8, 0xedc2cb94, - 0x67460e81, 0x1c787224, 0xb679f9e0, 0x76d0849e, 0x42577e31, 0xc0793396, - 0xf8f3d3fb, 0x37f73343, 0xf5884d51, 0xcec25cab, 0x5b8ea158, 0x49d771f0, - 0xf016af11, 0xfca92c5a, 0xc3d9e2e4, 0x183c4fbf, 0x1bfc0e9d, 0x7e05f4a5, - 0xccd20da7, 0xf3a75e7b, 0xc93650db, 0x9b98a603, 0x04b69392, 0xa45253de, - 0xfbed2f78, 0x0dd03a64, 0xafc821a9, 0xda957d2d, 0xeb8b2b66, 0xa58c5e60, - 0x53ea07b5, 0xfd442aef, 0x5993710c, 0x1cb3fdf4, 0xe65669af, 0x08af73c7, - 0x341c40e6, 0x9eefa0f1, 0x2bfc61d7, 0x4d87e8cc, 0x73636ba5, 0xf82573e2, - 0xf8a4dcbd, 0x7767e800, 0xf00252ad, 0xc41f7888, 0x0d16670b, 0x3d38e3e7, - 0x7d2b7792, 0x983976ee, 0x6a40cedf, 0x1f785e00, 0x1fc70eb2, 0xe3079fc1, - 0x9e0f7c42, 0x32c2d2e7, 0xc0c9fffa, 0xefb8ed96, 0x483e6037, 0xef1bdf6d, - 0x35adfe80, 0xc78c5e92, 0xd52dd9c6, 0x02beb789, 0xf6783ff4, 0x018796d4, - 0x7af6dbae, 0xce25ef30, 0x9bfeb91e, 0xb33f3ecc, 0x3f00a2dd, 0x9b72e56c, - 0x27c88fda, 0x3f6c5dc1, 0x1e476f19, 0x27f7a975, 0xddafe543, 0x05f0648e, - 0x0b3cb3b7, 0x7c03df21, 0x70d837ff, 0xd7f4013e, 0x13c10dbf, 0x8db20f97, - 0x8ff483e7, 0xe6f20f9e, 0xe8104b0e, 0x09af7ce1, 0x8f3292fd, 0x45b59d7b, - 0x7524001f, 0x01cf0e38, 0x72581b79, 0xca1ae7e6, 0x8b0f727f, 0x8f12c923, - 0x4b4afd33, 0x6bcc5c58, 0x808bff07, 0x774c765b, 0x3e408b7b, 0x713779b2, - 0xb39351bf, 0x2ef16140, 0x94d43796, 0x7b002e10, 0x87ae55ea, 0x5e2ccc9a, - 0x87d0e835, 0x26a35d61, 0x185d1fff, 0x93df62d7, 0xd8941a5f, 0x884f56b8, - 0x0a2775d9, 0x9d3d6135, 0x07d80f67, 0x59ab6eb0, 0x9f286b7c, 0xc7a1bf60, - 0x5890e2c0, 0x41ccec1e, 0xe22f5939, 0x3f99fb56, 0xa7c79eae, 0xf45acc4e, - 0x745ca40c, 0xb035ad48, 0xaab0bb3f, 0x0fe8fd12, 0x9f13393c, 0x7ed52bf5, - 0xa7e045ff, 0x238e1bcf, 0x1d7bff0b, 0xbd99e8f1, 0xd447ec3c, 0x5945fb50, - 0xbe815729, 0x15f621cc, 0x2095ff20, 0xe9abad5d, 0xc13e83b3, 0x12349768, - 0xa77239d8, 0xfbeb0ccb, 0xf5068768, 0xe343b054, 0xcf027685, 0x8fccc939, - 0xf3324d74, 0x0aa5d06b, 0xd9e238c1, 0x0771e3a1, 0xa272dfde, 0x2353c309, - 0x76a3e7b1, 0x7d3466b9, 0xd0ebfa2d, 0x4fc11ab5, 0xa0d4cd17, 0xde82fbdf, - 0xc6fd173b, 0x790202ce, 0xd6b61d54, 0x1eac3595, 0x2982e779, 0xebfac3ea, - 0x12486664, 0x33f209c5, 0xcbe79935, 0x616de1c5, 0x1f1cba97, 0xa90c698f, - 0x3fc4f5cb, 0xc58f2d21, 0xa7df620f, 0x75f93326, 0xc70e5561, 0xe3f307b7, - 0x6797fcc4, 0x3269bc30, 0xb33733d9, 0x41d02e6a, 0x7397c42e, 0xabfcc9e0, - 0x7f082674, 0x092e75ee, 0xde0e23e9, 0x80da300e, 0x3c593abe, 0x3f856ff4, - 0xe4caee1e, 0xbc1fae14, 0xd65f886e, 0x8f18f5db, 0x493f5cbe, 0x0e5ab25d, - 0xfebf950d, 0x27db2cfd, 0x9e796a75, 0x50e51d8d, 0xe5cd9d9d, 0x11d9e484, - 0x6a56f786, 0x3a3cc02f, 0x3f6025b5, 0x8ad5bb4c, 0x6fd968f3, 0xf3703f42, - 0xd02c81b2, 0x03552de3, 0x89b71005, 0x2b402fc7, 0xdb45f90b, 0xfee8b9d5, - 0xd884ec03, 0x4b5f3c76, 0xfef5671d, 0xf60cb920, 0xbf762739, 0xb76afa01, - 0xfd15f509, 0xf00603bf, 0x839cbcb3, 0x3687ccf6, 0x0bb41b7f, 0x9e5bc398, - 0x85bb01cd, 0xfdcd4dd9, 0x0bb01e86, 0xe2623aeb, 0xd59ff07c, 0x591fb8ea, - 0x3bff44e9, 0x6fbf56e9, 0xddf714d8, 0x17603888, 0xbd3af3ae, 0x3bf0227f, - 0x7f983bd5, 0x8351b670, 0x5af50379, 0xb79022cf, 0x7b6a4d67, 0xad8dacfc, - 0x75a196d7, 0xb5bda0f6, 0xf675cc65, 0xd73ac014, 0xb63f886b, 0x6758669f, - 0x7c4dbeba, 0x78becf9d, 0xf3ac0175, 0x2eafbbc7, 0xa75e7580, 0xdf02f2eb, - 0x5bfc39b4, 0x27bf6993, 0x3da1f06f, 0x2f58f225, 0x24f71e97, 0x432bfdab, - 0xff21ffe5, 0x30fa58ca, 0x5a87043c, 0x4af4ba1f, 0x3a83c806, 0xd5bfe1a3, - 0xaa37f08b, 0x4068cf1f, 0x3ffec77f, 0x0766ba7f, 0x2d7e81c8, 0xbfa223da, - 0x0f3fb2fd, 0xeffda1ec, 0x69413db8, 0xb91bfeec, 0x246dd85f, 0x88abf041, - 0x27b0807d, 0x5bf1e5e3, 0x251f3e7c, 0xbb006f7b, 0x8dfacbe6, 0x633bf81b, - 0xe76653e8, 0xcc3c936e, 0x7e8bdc6f, 0xf37d96e4, 0x3e27e0ed, 0xe37e621d, - 0xd18b1796, 0x7a18dc6f, 0x65790c2d, 0xc3b25fa4, 0xdb71a3fe, 0x07c804b1, - 0xba5cfb10, 0x8c933daf, 0xefdea8f4, 0x489d0e9e, 0x0a01fc80, 0x71e82577, - 0x07aa2b8b, 0xfba16fba, 0x6c23c83d, 0xa187a391, 0xc11716df, 0x3ed2973c, - 0xc44ffef5, 0xf4fa3779, 0xf6377728, 0xd790214b, 0x4e7f7a29, 0x9235e806, - 0x2078c761, 0xc98bb3e7, 0xb294d4de, 0xf7baf8d8, 0xe1e4e4f3, 0x0d81b07c, - 0x03bf4889, 0x83b5e23a, 0xe360db3c, 0xf9464cf2, 0x8e4dc7f6, 0x630fcb10, - 0x6218ffed, 0xc8a34276, 0x5849930b, 0x68b5eba6, 0x585df7b6, 0xe1f7906f, - 0x5b1f7938, 0xbbfb7116, 0x52f51849, 0xca181933, 0x176d8b0f, 0x7887d71f, - 0xd21faab8, 0x1f80ac5a, 0x07ab4eec, 0xb8f881e0, 0xf6c83eba, 0x961f94eb, - 0xafd30c96, 0xbf410758, 0x1d0fdc2d, 0x08fe3868, 0x4fa06fd0, 0xd77d83b2, - 0xdbf461e4, 0x905bf744, 0xefcf1b47, 0x379d57a4, 0x97ff163a, 0xd1f5a8a6, - 0xe4eff950, 0x453ebd5f, 0xfe62f7cd, 0x343f6fc2, 0xf1897ecf, 0xe2bcdc65, - 0xfef1a9f7, 0xbccfb176, 0x2738795c, 0x870f2d45, 0x79677fca, 0x2eb43758, - 0x1d50f2f1, 0xe59bf8cf, 0x5c70ffe1, 0x4f7d99e3, 0x03bec027, 0xa7d878ec, - 0x63aedcac, 0xfd1413f9, 0xe9e2f1b1, 0xc597ab5a, 0x5ea2b54f, 0xa657871d, - 0xe33c38f3, 0xd45ed7eb, 0xf335bae2, 0x3ef37138, 0x369a079b, 0x9c631758, - 0xba7e3e36, 0x0e9eec84, 0x471f154b, 0xce7e026d, 0x753c74bb, 0x8f8b0a75, - 0x20725852, 0x6f3e216f, 0xa7eb35eb, 0x7598fe49, 0x1ba22aaf, 0xdbe85182, - 0x33890728, 0x14c6fde6, 0xc6bf5766, 0x7adc8bf3, 0xad608e76, 0xfd85e2cd, - 0xf2c35b8c, 0xf2e07e9f, 0x18bc826d, 0xfaf1c2a3, 0x4344edf2, 0xae8cf2f1, - 0xb04ae517, 0x3901ead9, 0xa237fc28, 0x5e3c8bff, 0x3ffad971, 0xfcf7de8e, - 0x3c7bd30f, 0xf18bf67e, 0xddb8d6fe, 0x151b8a7a, 0xe3a4105f, 0xca5f1023, - 0x63bf4919, 0x1d1633f5, 0x1df14d1f, 0xfe766149, 0xb857cc14, 0x2963394c, - 0x3f009e8d, 0x5063d911, 0x7e09afc0, 0xab8fd412, 0xaa3e78d3, 0xe6267ca7, - 0x2573b369, 0x58ce1ce2, 0x4307e476, 0xc8ecc3eb, 0x9f5cc60f, 0xde47672f, - 0x087df0ee, 0xd2b27674, 0x1e01e78b, 0x61f851b5, 0x619cf87f, 0xe22e73d4, - 0xfca5c63c, 0xd1c45f2d, 0x4bff17d5, 0x3a92d472, 0x75f95d96, 0x13cfd1cb, - 0x763a7fc0, 0xff9e413f, 0x45bc4119, 0x6b6449f7, 0x103b5f8c, 0x197bf961, - 0xfef15e1c, 0xa1bef83f, 0x999bd521, 0xfc7fdf4a, 0x1248d1ae, 0x652e9ea9, - 0x67c5b172, 0x4b42b8c5, 0x697fcb2f, 0x8e504659, 0xb4df80b7, 0x3389fc08, - 0x4f7dd809, 0x2013fd3a, 0xf7d1ee8f, 0x226d41ac, 0x1167dbf8, 0xbdcef3b0, - 0x9c33cacb, 0x6798c9fe, 0xe3006cb7, 0xceb3dd18, 0xf9561e60, 0x523e9f17, - 0xa2f08a53, 0x5065c13f, 0x3db9679f, 0xf133c995, 0x6f843d9c, 0x3ff3fa2f, - 0xdaf9606e, 0x0ed79701, 0x0fe1097e, 0x8c1128b7, 0x61ecb42b, 0x96b95bc6, - 0x30fc87cd, 0x65a9e903, 0xf831654f, 0xa9af494d, 0xf2ddec18, 0xdf715bdf, - 0xe983f1f7, 0xcfb12798, 0x7c02afe5, 0x37434ad8, 0x4d9a7d81, 0xf7bb01c7, - 0x1537dde3, 0xfe42dc03, 0x39bf03ad, 0x4d9d7f1d, 0x462717ed, 0x64bf7796, - 0x33ee2647, 0x5afeac9b, 0x133aff98, 0x9db82383, 0xfee14f9f, 0x17fe78f2, - 0xd5aa9f7c, 0xdfa938e0, 0x5c9c6235, 0x3a7585c8, 0x0de637e2, 0x9e1293cb, - 0xf1701867, 0x99fec73c, 0x97854f2c, 0xbe752ead, 0x37c947e7, 0x253c0094, - 0x8b57f2a9, 0xe4475967, 0xb2a4940b, 0x5cea9678, 0xb322e5a2, 0x7aed73a7, - 0x4adb27a4, 0x9454e2c2, 0xbfaec09e, 0x06991a36, 0xbbf2bce7, 0x9e02d7c3, - 0x20d45ff7, 0x4799e49e, 0x28933e30, 0x56f2f1b1, 0x004e740f, 0xadfd8c7f, - 0x954960eb, 0xa0157b2e, 0xefa749f4, 0xffe45481, 0xaf1842d6, 0x2c745fea, - 0x059f72bf, 0x59dd0cfd, 0x795f984d, 0xea833dee, 0x33fc4e7c, 0x3e605648, - 0x6fdf6e65, 0xdb604e31, 0x279a8d23, 0x15aa44fb, 0x1825a6f9, 0x36398e99, - 0xce50bad7, 0x1f7efbca, 0xee43bb04, 0x91024194, 0x03579d0e, 0xcb82d3e7, - 0xc7f5fa09, 0xb035db77, 0x3f3cd95e, 0x7fff7066, 0xbee3f14e, 0x4205c445, - 0x3749bf2c, 0xc7ec08f0, 0xdf03e5e4, 0xec7ac20c, 0xc05a6871, 0xb68baa7f, - 0x9f65dfa0, 0xd9acfd05, 0xbe2b797d, 0x2bd9cb41, 0x1b0718ed, 0x6ceee57c, - 0xf3a7e7cc, 0x3cca3f1c, 0xf9654a1f, 0x8b3ef248, 0xfc99f406, 0xa8c0f104, - 0x0aa523b2, 0x968a7ee1, 0x07df3f69, 0x8e1e4a7a, 0x0a3f829b, 0xaa4354f4, - 0xcdd0077f, 0xa5a4b9d0, 0x892e7666, 0x2db5a79f, 0x9c176f7d, 0xfdc2d9f7, - 0x4ff707b9, 0xbffe859e, 0x7582594e, 0xf960e0b8, 0xb2a42f95, 0xfc48e278, - 0xd63cc41f, 0x65bf7ddc, 0x02e28d7a, 0x8c7597fa, 0x574ee45e, 0x5f19f80f, - 0xde63f049, 0x611d75ee, 0xeccdc62d, 0xa35c7f27, 0xd677ecc4, 0xb2d33d33, - 0xe3cfed93, 0xd29737f7, 0x921ebf2f, 0x0cbf4c33, 0x764eff95, 0xf4e2efcb, - 0x6fbcdfca, 0x5efdea21, 0xbf12fdbc, 0x8f611bbf, 0x9637f5c7, 0x50f2231d, - 0x61c786aa, 0xd84db4f6, 0x9e554149, 0x9f95954e, 0xfbaa343b, 0x47649f5f, - 0x3b79107a, 0x72caed29, 0xfe8fdbc8, 0x4edfa088, 0x3c8915e4, 0xcb1560a2, - 0x8c6a09f7, 0x4dd12e78, 0x687f30ba, 0x124b091c, 0xf006d7fa, 0xe42a6dfc, - 0x4fefd111, 0xff62e6a4, 0xa567899b, 0x22a6e516, 0xc826fc01, 0xb802493f, - 0xc1161b43, 0x7159b778, 0x9fe4133c, 0x033ee124, 0xc7dd39f9, 0x35a756f2, - 0x3a43b8b0, 0x4e50cfd5, 0x697467cf, 0x3cc7ab9a, 0x22579156, 0x5e044ff2, - 0xd3be38aa, 0x01ca2c27, 0x54f228b9, 0xe53d99d6, 0x39c11760, 0x1cbf3868, - 0xbcf3346c, 0x776fd613, 0x4f9e2e63, 0x2979b2fe, 0xf91678f1, 0x7f44fa29, - 0xe46cbba6, 0x37416739, 0x7089eb31, 0xecc7dc6d, 0x3d06aafc, 0x71b063ce, - 0x072bfa06, 0xec04351b, 0x037eaa81, 0xf1b8c3a3, 0x93d5ce36, 0x872bf430, - 0x054f204c, 0xceca5c3d, 0x085beba5, 0x6d83e0fe, 0x524ef33b, 0xd6d43fde, - 0x9341cf8b, 0x12bdabd4, 0x03cea1cf, 0xb48df5c9, 0x1af95afc, 0x6689b7c8, - 0x6a849449, 0x96faafd3, 0x60c4f54c, 0x287df472, 0x7be1bedf, 0xba3e3cac, - 0x9beda245, 0xed623ed3, 0xa9d33681, 0xefff5ed8, 0x57eb41b5, 0x267f7fd0, - 0x351cf9f1, 0xebf464ee, 0x3f41123c, 0xa57fd712, 0xadba3e4c, 0xdc9fb47a, - 0x54951f3c, 0x8854fcf3, 0x7b72d0f8, 0xefc6315a, 0x13d944ad, 0x030cfa81, - 0xe30827b3, 0xccf1f687, 0xf4e46d6f, 0xbf843240, 0xf208206a, 0x81c73dae, - 0xe7c90fdf, 0xf310863d, 0x8ff1b19b, 0x9e0578be, 0xb679124b, 0x6733d884, - 0x36f9815f, 0x135af2aa, 0xdb29a73f, 0x7bbce133, 0xc1db8ebb, 0xe6c47cbc, - 0x04f3885f, 0xddf6a4be, 0x507e1bd1, 0x7674fc04, 0x41f30fef, 0xa7a8ddce, - 0xe45184fb, 0x933a595a, 0xeb3a836b, 0xb77e894a, 0x016fe6c6, 0x32c77c3a, - 0x311c3a6f, 0xa9549b9a, 0xc1bc0077, 0xd780b4e7, 0x8e274e64, 0x473e0cd9, - 0x3c824fb5, 0x1b1376d4, 0x7b2fd937, 0x7f845cf1, 0x851b74b6, 0xf2625dbb, - 0x88947e9b, 0x92a15576, 0x26c87108, 0xcb55ee7e, 0xcb9688e5, 0x1b6e7f91, - 0xc1a997c8, 0x13ef4d78, 0x7fe7b05a, 0xbfe2e3cb, 0x9f9f51cd, 0xb83371e8, - 0x569673c5, 0xcfe802b9, 0x523aaba5, 0xab40e94b, 0xfd7084f7, 0x37186d32, - 0x772b603e, 0xa5efd00f, 0x42951fec, 0xe67b773e, 0xbe214a8f, 0xdc7a75a7, - 0x8f7298be, 0x357fd19b, 0x59bc03b4, 0xefc14b5a, 0x97f5b5fb, 0xfa2bfb48, - 0xf50dfdf2, 0x35706063, 0x7059a319, 0x9359fe6e, 0xffac3b7f, 0x30c7f985, - 0xfa40fc2e, 0xaf21f7d1, 0xd18ea8e3, 0xe793305d, 0x69ee93e3, 0x0eee9409, - 0x5e7839e7, 0x1ebf8b0a, 0xa8fcc09e, 0xfcb17e54, 0xe61289d1, 0x66ced621, - 0x266f62e7, 0xfa018e91, 0x68593a3d, 0x1c8af4fd, 0x796b7fb4, 0x77f4c89e, - 0x7eb0097c, 0xca8f6fd3, 0xb2c7f720, 0xeb746ee7, 0x3e188194, 0x975149be, - 0x97542e6f, 0x9751e5bf, 0x97f15dbf, 0x9365b109, 0xe8107bd9, 0xdf8955f5, - 0xb10d7147, 0xa4ba7f23, 0x935dd820, 0xe7e74a5f, 0xe53e5989, 0xf17ef94f, - 0xf5820aa5, 0x5b8d3b29, 0xfdcf508d, 0x3f5e5aef, 0xd98c4dd9, 0xea07c44e, - 0xf3c4a8e9, 0x93185d32, 0xb1ef7b22, 0x6d343f33, 0xecfda7ab, 0x1f20af9d, - 0xe43558a7, 0xa5ebc09b, 0x04c3b446, 0x289bb45f, 0x963c537d, 0x819a338f, - 0x9e75dbde, 0xd697d0f5, 0x2f40506c, 0xb1182657, 0xc83fed6f, 0x9b96d7a8, - 0xcb4ec40c, 0x63371f07, 0x3e265cb9, 0x20a123c8, 0x51e786ce, 0x0ad4279d, - 0x60eda5f3, 0x160eedbe, 0xeb96d757, 0x7ed3cf51, 0x3e0f5d71, 0x9c1109a1, - 0xf98ca57f, 0xc1661ca6, 0x7c247477, 0x6be734ff, 0x518486ad, 0x7bb3a58e, - 0xfed10e39, 0xbf83dfa1, 0xdfa0f6d2, 0x13b950ae, 0x271bcfea, 0xc0a8b9e0, - 0x592f79d0, 0xda15c003, 0x67e87cb9, 0x3f04f2e7, 0xa542f90b, 0x852bbe5e, - 0xf8149030, 0x053b050f, 0xfb8204ec, 0xccb71100, 0xd97a8a34, 0x0da6fd0b, - 0xe0e767b5, 0x56997852, 0x60253585, 0x27f1bca7, 0xe4b1c3a0, 0x931a6145, - 0xe429e213, 0xc3c316c5, 0x19af6a47, 0xef0a3d6d, 0x9b0cf2c7, 0x84c7ad9d, - 0xad4be00c, 0xe8064279, 0x478776cd, 0x0b94c5f1, 0xae6a76e9, 0xdb45f013, - 0x35adf2d1, 0x18e5f2c7, 0xc69854fd, 0xe76d00e4, 0x1ef0a24d, 0xc0192934, - 0xdb8ca3bf, 0x7cb5c6cc, 0xe9bae3bd, 0x41ddb4b8, 0xb6971d1b, 0x843266db, - 0x8da30935, 0x78c0a15f, 0xa2971a97, 0x833f911d, 0x93a503af, 0x0ec1f820, - 0xaf4834da, 0xf2be7833, 0x1e3664c1, 0xffe75429, 0xf8e99be4, 0xcea65f98, - 0xda51b9f7, 0xfa7a01d4, 0x56c25369, 0x3837cfa0, 0xfcb61cdd, 0x69d83e43, - 0x382bcc6f, 0x71267284, 0xd1100779, 0xf28bd20c, 0x0bc1c846, 0xa1cac769, - 0x8de1e54c, 0x0fde7469, 0x079d1ee4, 0x3c721f9d, 0xa5f68f9d, 0x56935bd9, - 0x417e1236, 0xa06e029f, 0x218be053, 0x5f838d3a, 0xa5b91bd0, 0x37251317, - 0x9e173b53, 0xa425eec2, 0x2bc5e595, 0xa3f3c399, 0xd8dd3e44, 0x18d1e6ca, - 0x746fb844, 0xe6f318fc, 0xffe718ee, 0xf735c01e, 0xbef04fca, 0x3f9ee222, - 0x1477f601, 0xc96979de, 0xc6f07bff, 0xca97f9db, 0xcf8b1f0f, 0xacd2f8c5, - 0x1e1f989d, 0x7cc56d98, 0x3f3c69f1, 0xc1a0d036, 0x0fdd00b8, 0x85a23ee2, - 0x97204318, 0x5cbb72a7, 0x45785b9c, 0xe0d6fe62, 0x7d45068b, 0xde7c513f, - 0xe97982b8, 0xbf2c65c1, 0x6f7ec87c, 0x1f7ed056, 0x9cfc73d2, 0x93317744, - 0x28f7dded, 0xe689fbea, 0x44fdf513, 0x7121ed0b, 0x32948a6f, 0xdddfbf9c, - 0xbbfe9043, 0x9f58b96d, 0x88fa65ae, 0xa3e9837c, 0xbaa21cee, 0x399d691f, - 0x94f31134, 0x46c15e78, 0x6ff83fc8, 0x9a7e0bf2, 0xc2fca926, 0xc9afe543, - 0xf0e6dc2f, 0x5b3a02ef, 0x92cde458, 0xebd63d28, 0xd2987f99, 0x8108a6eb, - 0x7cd6c574, 0x44dda7d8, 0xe4d2df5a, 0x02febd21, 0xa53275e9, 0xbd153cd7, - 0x15fc61ee, 0xe82d2144, 0x0b4e8875, 0xfd00f3e3, 0x6edc60fb, 0x5befef47, - 0x6fd35f60, 0x683cb0f0, 0x2f19d796, 0x59e0621f, 0x5c783320, 0xf3c22d5a, - 0x0f13f43a, 0x4df0e5cf, 0x12a69d2c, 0xf1631fc6, 0x824caa4f, 0xfe6192b6, - 0x6ffd9931, 0x7c43b8c1, 0xcfdb08f4, 0x6b5b808e, 0x739a7a45, 0x057f8b07, - 0x802ecc2c, 0x1d1a5838, 0x7f1f267f, 0xdaafa74e, 0x4a66ed01, 0xfa610f0c, - 0x167f850f, 0xdfd99faf, 0xb370798c, 0x63c775aa, 0x2f2120ed, 0x2e6ddc45, - 0x7dab7f6f, 0xd2f20ea6, 0xe3aad767, 0x64ef735d, 0xb339b6f1, 0x25ccfdd5, - 0x7cc13fab, 0x03aad24d, 0x53bdcdfc, 0xda49ff5d, 0x026c9c50, 0x710ec9c4, - 0xe520d03f, 0xd7a3e013, 0xba6f1793, 0x84f9d287, 0x8095149f, 0x9486f0df, - 0xd04f6dc6, 0x271bb3f2, 0x94f5f961, 0x28ff7eef, 0xc0296fd4, 0xe25c3572, - 0xe056fb04, 0x8567ca43, 0xc8cc77e5, 0xc27d0049, 0xe087bdfb, 0xdfd9b77b, - 0x73b6933d, 0x3cc5c94f, 0xd7ee6ad6, 0xeac85c18, 0xc6d2be6f, 0x52ef9552, - 0x6d5c5fd0, 0x1d35f766, 0x04bb7e29, 0x73abaaf2, 0xd5e4b979, 0x243e5049, - 0x3af7827d, 0xcab66b9c, 0xe92d0eb0, 0xb93ecfcc, 0xa44f0a50, 0xf276a978, - 0xbcd99bfe, 0x4b9e4b6a, 0xaea93e07, 0xf64cfd62, 0x41e67654, 0x2c79cd3b, - 0x26374b9f, 0xbf05fe00, 0x957df0e5, 0x5c7d2bb0, 0x3de4bc4e, 0xfb4491d6, - 0x0f2519f5, 0x7157d14c, 0x664bdd8c, 0x7d03e765, 0xfc191cde, 0x2cbcd3f4, - 0xb8cab6ef, 0xe1e40d3c, 0x297d7e2d, 0x2c6ecbcc, 0x1179043e, 0x65951589, - 0x246da798, 0xfe94beb8, 0x3f03a7c7, 0x5649fd5e, 0x559d1002, 0xbe82ff4d, - 0xafba0a66, 0xe537d356, 0x65e9c9db, 0x2adf9697, 0xd30d36fa, 0x3ef658f7, - 0xe102ab85, 0xaf5a86fa, 0xc7138d0d, 0x8ee3f19f, 0x2fe03725, 0xc30efe56, - 0x987c8bd7, 0x798dd901, 0x825da7c0, 0x38026f4f, 0x9e089af4, 0x3c96ca8f, - 0x7180f093, 0x7a88c785, 0x055f8e2f, 0x33e0997c, 0x1709192f, 0x6ec2c9fc, - 0xf02e7f65, 0x7af064a3, 0x38979dfa, 0xe3a2e187, 0x7a0e91df, 0xcf0611fc, - 0xc995a966, 0x112fbe19, 0x311697fe, 0x7cf53edf, 0x1eeccdcb, 0xcbf83703, - 0x3c527630, 0xcbee0869, 0x9f310758, 0xb3e7d700, 0x9e9b3e8d, 0x4736edce, - 0xedcfd23d, 0x283aa354, 0xff74c25e, 0xd41e700f, 0x7ec1f704, 0x62f1216f, - 0x47d29cfc, 0x6ec63d20, 0xe3c6f012, 0xb90c65a9, 0x789f3f1a, 0x5baf0cfc, - 0xe29e0d24, 0x7cd0e1fc, 0xf19e732f, 0xaf4b8af6, 0xb93a5bf6, 0xec39d17f, - 0xfa842c4f, 0xa0f6625a, 0xe123d13f, 0xda96af7e, 0x6ba7201f, 0x71fa086b, - 0xfa0d569c, 0x321d8513, 0xff5c9f16, 0x6ab7264d, 0xf73f089b, 0x4f17e6c8, - 0xe064a98f, 0x1ad6787e, 0x800b0d95, 0xaaac1bff, 0x56b50673, 0x4e788f16, - 0x503211c8, 0xa87f7a06, 0x0fef423c, 0x8a1c8194, 0xf6ae7fbf, 0x3b7bf322, - 0xacf84a2f, 0x032b1cf5, 0x19acefbd, 0x56790328, 0x14fef767, 0x13dc55d6, - 0xbdcf8f19, 0x97911ae9, 0x1a745972, 0x0e2247cf, 0x7fe6c47a, 0x3fc63d39, - 0xa08a5675, 0xcbb5759f, 0xcfe7e7ce, 0xd8767a01, 0xefc12a73, 0xaad8db34, - 0xd138bb03, 0xce903fe1, 0x5f17e8e4, 0x9a17e6c0, 0x56de3c52, 0x66587fed, - 0xee1e22c3, 0x81b878e5, 0x9bf3d9eb, 0xa90fb8b4, 0x0d3e16f6, 0x9bc0a0a1, - 0xbe42123a, 0x147ea2f5, 0xa79dc6f7, 0xda185506, 0x7d436f3f, 0xf557f8bb, - 0xb09b2718, 0x1894435e, 0x6431397d, 0x327fdd56, 0x5553a779, 0x5d37a2be, - 0xbecafed5, 0x717d555c, 0xfeaa9278, 0x544b37aa, 0x54c8b2e5, 0xdfabfb55, - 0xaf9552a9, 0x6aa19819, 0x3df403bf, 0x4e37e3c5, 0xffbd52cf, 0x37f4e368, - 0x5d7d3e21, 0xefaa3bf4, 0x043f704f, 0x85237a09, 0x040bfe74, 0x53ac5ebd, - 0x9acd4f7d, 0x7c0e54b0, 0xac16fecf, 0x95f77966, 0xfdb16314, 0xdb52ec2d, - 0x28903713, 0x84b62be6, 0x40984f24, 0xbeba9dde, 0xf107afb1, 0x0f7ba97a, - 0x6be6b826, 0xc69754c0, 0x22633b51, 0x0d5c8220, 0xf1638379, 0xbfd6a5fb, - 0xa97fe480, 0xd5b837f5, 0xd4526feb, 0x54296feb, 0xa3cdbfaf, 0x0ac4ff5e, - 0xbc3bfaf5, 0xaa4ff5ea, 0xb27faf51, 0xa9febd4f, 0x9febd573, 0xffaf57e6, - 0xbaf506b8, 0xd7aab667, 0x7aa97b3b, 0x4b82735d, 0x74f1f554, 0xc849e820, - 0xf795bccf, 0xa453dbaa, 0x42e86268, 0x5f02d9d0, 0x8d63e603, 0x35487aef, - 0x4c7d3c5e, 0xf48f3c20, 0xe547d22b, 0x727f6e38, 0xa97aa0ba, 0xda325c6a, - 0x73c03719, 0xff6e04ee, 0x33b746fb, 0xd58afc84, 0xe6fbb1eb, 0x08dae4b1, - 0xd1f7c57d, 0xd82bea63, 0xf7869b47, 0xefd163d1, 0x59ea84bb, 0xfa357c1c, - 0x33b0eecf, 0x999a0e38, 0x5429ff3d, 0xd1db435d, 0xde141536, 0x743e6177, - 0x93cd77fc, 0x1df20fd1, 0x7183abd2, 0x7c1124ef, 0x7c5123ce, 0x755d89fa, - 0xf10165be, 0x645fb9e9, 0xc9a9e009, 0x7a0e5038, 0xa3fcc2ff, 0xee7c63ef, - 0xdd65d248, 0xe21c7207, 0x3909e33f, 0x49c9e5c5, 0xf2d10388, 0x27f71339, - 0x8ae2897a, 0xee29e7c1, 0x269bacf7, 0x5a259ea1, 0xd5b1e633, 0x9ea12edd, - 0xf60ffbaa, 0xf4c71f6c, 0x52e788da, 0x6e2ed781, 0xa13b301f, 0x62dd0e0f, - 0xadf890fc, 0xec7a8f68, 0x3fb4deb0, 0x47f98716, 0xdbb17f76, 0x25dce0c8, - 0x89c2b911, 0xdd7106c7, 0x7ce1fd61, 0xe0c8db9b, 0x4623a5db, 0xe264efc0, - 0x31f0fb47, 0xd63c8a99, 0xefd624ef, 0x17f05cd1, 0x7e6fcd9a, 0xa9f21aab, - 0xf472e0e5, 0xa88f7fdf, 0xb677f7fd, 0xffbfe84a, 0x3e9b851e, 0x1b8f76dd, - 0xef28b2f4, 0x1e21b802, 0xfbe8ed00, 0x04ab7754, 0xadafb1fe, 0xb10f3dbf, - 0xbfb25f76, 0x83087ea1, 0x3d60fe0b, 0x83367f85, 0xd281b7d2, 0x11efb6cb, - 0xfbc61ff4, 0xa969c76b, 0x31fc8106, 0xc097bb1d, 0xfb67af2d, 0xbb1ec3e2, - 0x7444cfca, 0x7a47380e, 0xf20e7b29, 0x9cc54fbe, 0x3474a0d3, 0x1fbafdea, - 0xa47cb065, 0x44c8b6f6, 0xe39e4b88, 0xdb87d771, 0x56b2c4de, 0x265e60f6, - 0x88e5f7dc, 0xa2ef5ef9, 0x4e7231f5, 0x63efd2b6, 0xeace8de4, 0x1e6bcbc3, - 0xbc608b69, 0x25efc753, 0x5ee3347b, 0xbfc63fbb, 0x6e38cef2, 0xc4831927, - 0x69b8429e, 0x4f4eff4f, 0x5a3f4023, 0x762a7cbb, 0xd3706d1f, 0xeef562fe, - 0x1b1264c5, 0xf6d9587f, 0x88fdc20e, 0x6743f7e4, 0x36127c86, 0x641b7c51, - 0xdf4d0338, 0xe511b86f, 0xaf76deaf, 0x1aa1ee07, 0xb7067f0b, 0x7e56217c, - 0xdf8e387e, 0xe7e5c5cf, 0xc9d16d93, 0xdb7b4e30, 0x5d6f0a80, 0xfdf1176d, - 0xc452369a, 0x7ac43fea, 0xf4828d4d, 0x42d28a73, 0xf27ae204, 0xc1fc0d80, - 0x10263ed4, 0x8db9d67f, 0xb8306f18, 0xa2e4bc18, 0x9e63e90b, 0x3e00c19d, - 0x1f4a4cbf, 0xe1d52fef, 0x4cbefafe, 0xefbfb62b, 0x780fe337, 0x29eadf29, - 0xc37fb41a, 0x61c7867c, 0xf973d3f8, 0x0fbf6449, 0x5d3e80e4, 0xd38538c6, - 0xf1d70b3e, 0xf027f6cb, 0xcc1137ae, 0x5a67d647, 0x5cb85ed1, 0x6a19dd38, - 0x8fe3c7bc, 0xffe509e2, 0xf74f1c7d, 0x93fcc83d, 0xf04fddf7, 0x4a59053c, - 0xe987caff, 0x87971c6a, 0xcf87c4a9, 0x082a36ae, 0x465eb00d, 0xed409fe2, - 0x8d8bd211, 0x82a7e04d, 0x80ecaf7a, 0xaa2788d4, 0xb9e1335d, 0x1764e2a6, - 0x6bdae3b0, 0x13c08b3f, 0x2f801162, 0xc109037b, 0xab98bc55, 0xf877c740, - 0xd7813959, 0xe565cc27, 0xe89f5e44, 0xef4ce563, 0x0035520b, 0xcb471716, - 0xca6f3ab4, 0x80bc7907, 0xfcf173b0, 0x84cd8d7e, 0x73ab0bcb, 0xdfd43566, - 0x8b9cf049, 0xaf09ffa8, 0x5f1eb34f, 0x637a0799, 0x0dfbfab6, 0xd6a90f1c, - 0x30d35de3, 0x17aea6de, 0xeb64acf1, 0xfbf137f9, 0x53fd7522, 0xf59b7bfc, - 0xd41a647c, 0x7fc7abe7, 0xac5bd79c, 0xca8def2c, 0x037f767e, 0xd78c7faf, - 0xc61ea09b, 0x5af5642f, 0x6f09df71, 0x18e1c9d7, 0x431e33e2, 0xbf33260c, - 0x233696f2, 0xbf3c57f2, 0x73f707dd, 0x9bf30d95, 0xf519297d, 0x32fb86de, - 0x5049dc98, 0x51debc06, 0x77a8a2e4, 0x37cc65da, 0x48f5bad0, 0x972b064f, - 0x871f9c27, 0xead489e4, 0xe4c64461, 0x9ae8a5f4, 0x9005f012, 0x0ff4596b, - 0xfbe33ae8, 0x918fe21a, 0x664de973, 0x83e58fe2, 0x39554e05, 0x5574cee5, - 0x5cecd77b, 0x74b5bd55, 0xcc9eaa92, 0xdc9f2276, 0x5ccbe9cb, 0x17aaa254, - 0x6d9065f7, 0xb59d9dbc, 0x554fe5d3, 0xa85f3bb5, 0x9f8d0224, 0xa3dc49ba, - 0x7c8231e6, 0x9b96d7b8, 0xb3f8fc0a, 0x4e440ab6, 0xf627e53b, 0x1ba7f3b4, - 0x54fa598c, 0xcb10b978, 0x7e583bcf, 0x879b7b7f, 0x9e087395, 0xab6f6faf, - 0xca2ef2c1, 0x69fcf09f, 0xdb9f179b, 0xcfa15969, 0x2bfda47f, 0xda1e9fb4, - 0xa19f943f, 0x3373c3fd, 0x3f9e1fed, 0xfd43fda1, 0x942fda06, 0xc170a69f, - 0x0fda29f3, 0xed31ffbc, 0xb44fca1f, 0xb6bcb0f9, 0x1f962e6d, 0xf3e3f36f, - 0x7c06b6b1, 0x8ad6d9df, 0x96db47e5, 0xb6e1f3e2, 0xdbdb3e20, 0x2f7d6256, - 0xf9e793a7, 0x2be7dc79, 0xf103bdd9, 0x219fdfeb, 0x9d2fbb61, 0x154a539f, - 0x3f2ab97a, 0xfc033fa7, 0xfceabd02, 0xc21fc054, 0x8c786261, 0x0668e387, - 0x91270fb3, 0x930b72c8, 0x1f07181f, 0x6159e7df, 0xae35fca1, 0x4e7bad95, - 0xd3eb145f, 0x4778d81a, 0x5c409db9, 0xce519241, 0xbb439b8e, 0xcaa45273, - 0xd007f2c2, 0x14dc430f, 0x5aece53f, 0x21e64672, 0x5725c00d, 0x331e3d50, - 0x397c21af, 0xb7809c18, 0x57fde0d1, 0x696d378e, 0xa75fbb2f, 0x6c0c2ba6, - 0xe2b6f666, 0xb9c63afd, 0x9f4cb0be, 0xef1f9f2e, 0x717498e9, 0x5224dd3a, - 0x9bf176f9, 0x8ccfa144, 0x31fef526, 0x6a89417d, 0xb8bda67f, 0xd1572886, - 0xfbd48b7e, 0xbdfe733c, 0x198cefaa, 0xf5eaa90f, 0xfaaa15ae, 0x1e73bbba, - 0xc73e0371, 0x6199b8b1, 0x210272f5, 0x4fdd85e4, 0x4ce65c20, 0x92738f36, - 0x605f7ec2, 0x133dff37, 0xd6797fbe, 0x5c65f1ce, 0x09f2fb8d, 0x482c560e, - 0x0f406a0c, 0x448bfc7d, 0x9e3b7f94, 0x7e9fa0d1, 0x40690922, 0xe6a64cde, - 0x015fd424, 0xf16b8c37, 0x942d26aa, 0x85a2898b, 0x8a2455f2, 0x7fba3afb, - 0xf5d264d1, 0x9ffad16b, 0xd9f2d131, 0x2cb3ff4c, 0xfa8c30bf, 0x67af80ba, - 0xadc7d881, 0xdcfde397, 0x37f44cc6, 0x7625cfa9, 0x874bfdf0, 0x970df989, - 0xc153ca3b, 0x46373e0e, 0x7dcda83e, 0x14058de2, 0x63b4b6df, 0x1fef14f8, - 0x9ea33457, 0x94cbcfd7, 0xf75e5abe, 0xd44faa7a, 0xf307937c, 0xcffa5b38, - 0x6b76e029, 0xff228fc9, 0x3c84e874, 0x9e411253, 0x893d970d, 0x3b1e6624, - 0x93c9deda, 0x11fa2151, 0x375f326f, 0x4ff95f31, 0x4bc87695, 0xd179e02c, - 0xf2d2db3b, 0x7f0fc7ab, 0x5074e3ef, 0xa0352248, 0x348b0b5f, 0xe074109e, - 0x31fcabb5, 0x2f2efca6, 0x4b930b9c, 0xf2c40788, 0xf785d244, 0xd57fc829, - 0x7c9a3e62, 0x50a21af0, 0x0d6ad8fb, 0x70d16093, 0x75fb84bf, 0xfce5cfbe, - 0x9c6af667, 0xec259c8f, 0x74e80f26, 0x1bd599f2, 0xacfc3a01, 0xf4d8c75b, - 0xd0bebab8, 0x2def504a, 0x1487d42a, 0xebcbee09, 0xe5407bc2, 0xc8c9122d, - 0xb9a63801, 0xdf7e83e7, 0xb63a416b, 0x9fc72fac, 0xe359b830, 0x0efc40af, - 0xc2357b28, 0x9aeda2e8, 0x82b7eb27, 0xf001393d, 0xdcbc0562, 0x430d5f91, - 0x1e2217e7, 0x2f79f217, 0xc8e8f3e4, 0x833fc21c, 0x70bc7887, 0x6ea2ef1f, - 0xcf528fe1, 0xaad2f1f3, 0xa2bdc36f, 0xff2d11ed, 0x3e352299, 0x5322e957, - 0x70c34be6, 0x66173851, 0xb8015c82, 0xd80f82af, 0x919f9afc, 0x941cc6c8, - 0x6f68356b, 0x3f306994, 0x9b2e9e3d, 0x8fdc9932, 0x7dd9d866, 0x4853eee4, - 0x93e5c3cf, 0xc2482c6f, 0x5bb333fd, 0x8fcb326c, 0x58957af4, 0xe12af7bf, - 0x72e7e45f, 0xa1de1ccc, 0xb127057b, 0x892b60bc, 0xb4bc87ac, 0x2bf5f6b1, - 0xdc707332, 0xb53d7de1, 0xa53f205d, 0x5c7988cc, 0xa13e44ab, 0x69995472, - 0x57384f63, 0xfa74e465, 0xf79d4da8, 0x6fcf9db3, 0x418f5f3b, 0xf27bc8a3, - 0x9cc716d6, 0xafeba9f3, 0x88963f47, 0xff720ed3, 0x1d59a0e1, 0xa4e46d57, - 0xaba87830, 0xc1f10cca, 0x6da7162e, 0xdd99bfec, 0xc7efbb6b, 0xed302f78, - 0xa87a0153, 0x57ebede7, 0x0b58fdaa, 0x5f91fa77, 0xf164fde3, 0x398a317e, - 0xe31fec3d, 0x335b62fd, 0x43c27ef9, 0x7b0e218a, 0x61de7562, 0x7277ec33, - 0x1f0f9e08, 0xef017da7, 0x81bba6dd, 0x974fb82e, 0xa3fbb114, 0x54ffd7e2, - 0xb2f11e96, 0x78efac53, 0x3ba5da2b, 0xd81c98cb, 0x2dfce079, 0x2b3f69e3, - 0xf9d52473, 0x3a399580, 0x29b7a75c, 0x97b3c37d, 0xeed19a90, 0xa9943b29, - 0xef726af9, 0xc1eff55a, 0x1c0df734, 0xff2828b6, 0x1fba035e, 0x4279fc3c, - 0x1451f211, 0x08c4bf7f, 0xc19930c2, 0x76b3e70d, 0x17993e6b, 0x676f0f4b, - 0x36ff58ca, 0x0d2f8ba7, 0xae1ab557, 0xa56f45b3, 0xfd7060cc, 0xb9c6e40e, - 0x5894f1f0, 0xb5c0467b, 0x03df8c7b, 0xe2abf0f8, 0x1fad42a9, 0xfa74f062, - 0x6ed3c3bf, 0xfcf0e8fd, 0xb3f3c395, 0x9b5eec43, 0x515ff591, 0xe1ab759f, - 0x647cfb3d, 0x0a49880e, 0x7f115fef, 0x182993ee, 0xebf8e613, 0x59f4e52d, - 0x078fe5ca, 0xc09150cf, 0x1e63577b, 0x924caf66, 0xbe5ca16a, 0x2cf77f00, - 0x02c3ef93, 0xbf9e3f1a, 0x4619ef21, 0x64d77f95, 0x9ddeba31, 0x878a8d2e, - 0xcf362cd2, 0xb2ea4703, 0xd8f1bfc1, 0x7202063b, 0xbfcf3361, 0x6bdecc7e, - 0x05a67b84, 0x425ca11e, 0x747d019f, 0xc7bc2811, 0x2a333f4a, 0xd3c651d6, - 0xc6d6f1b0, 0x4f188df1, 0x1564a73c, 0x3a557b32, 0x387385a4, 0x0b7daf6b, - 0x5b5b7fef, 0xfdeca32a, 0x1d5ff8d2, 0x5bf0ff87, 0x7a30b729, 0xe1459299, - 0x90fe916b, 0x0e5a6df0, 0x2a7fd148, 0xbd157c82, 0xa01fe71f, 0x4691ec78, - 0x8b2d29e2, 0x9f988bd1, 0xdb80bf98, 0x5c02dd76, 0x06bbdb07, 0xbca51a54, - 0x8917d0bd, 0xbcc1ff5c, 0x2b5c5f50, 0x654c73b3, 0xdafbae32, 0xee78a98a, - 0x17cf376c, 0x1fa35e89, 0x164477f5, 0x763dbc70, 0xb811b7f1, 0xafd83947, - 0x883ffbc3, 0x15bee03c, 0x8dff1fee, 0x5389f78c, 0xfb81aa7a, 0x391c0ecc, - 0xebfb009f, 0x843a59f9, 0x87973e7b, 0x35b51783, 0xc8ec1e78, 0x0c6d7667, - 0x6965d7fd, 0x89127db9, 0x35af39c0, 0x8b3cec25, 0xd603db95, 0x001b2723, - 0x43c56b7e, 0xde862906, 0x10196566, 0x68fa35ae, 0x17f6878a, 0x6125a7d8, - 0x7bc1ffe6, 0xb3ce8719, 0x5a1e19da, 0xbda10f4a, 0xf767ed60, 0x2965d635, - 0xb852ce4c, 0xe6f7d2f7, 0xebd99f89, 0x8e94bea1, 0xbdfc3b97, 0xd3d6cecd, - 0x4beec65c, 0x3fed7b5a, 0xc83ee1db, 0x471df844, 0x79f2efd8, 0x7292b80a, - 0x48dfbc35, 0xcbf81724, 0x5abe632e, 0x235ef86f, 0x2f82fbd8, 0x62d5cade, - 0x39f947bb, 0x0a2b4789, 0x4cae7043, 0xdb35b1d0, 0xcc1640ff, 0x0bc5f28f, - 0x7c44ef68, 0xf63f10d3, 0xdf33c862, 0x32e64525, 0x076f443b, 0x68d42c3e, - 0xe116fc54, 0x549e26eb, 0x73dda3fd, 0xa15da73f, 0x46423bf7, 0xfe4de702, - 0x22667178, 0x191da7d8, 0x1af3dec2, 0x259b5f01, 0x8c0e625f, 0xdc5a2ff3, - 0x72381e0f, 0xedc601bc, 0xbe02f3a0, 0xeb75f87d, 0x3a53b06a, 0x53e45eec, - 0xd0ecbe31, 0xfd60f5f0, 0xdf7bd6ec, 0xd4647f04, 0x3acdeec1, 0x11867538, - 0xd3b69fe8, 0xa07f3f40, 0x04f0f7fb, 0xfd1aa7e8, 0xb3ed0b06, 0x8b77c3a6, - 0xb011ff88, 0x6b75176f, 0x3c83f755, 0xc2c5e5cc, 0x8e12168b, 0xac2c2fd9, - 0x6b9e0ef8, 0x0131785c, 0xcfcc3fdf, 0xcfcc3fed, 0xf8e2edbd, 0x5f3f9978, - 0xfb8afacf, 0xde9c4f6f, 0x8eddfe4a, 0xbbf7c63a, 0xa59afd60, 0xfaa83d01, - 0xc73f5335, 0x687f64f3, 0x21b093b3, 0xf311de06, 0x98e1224c, 0x5dda8771, - 0x52709134, 0xfa32faec, 0x15af9e1d, 0xe6d0ffeb, 0xdd8e3c46, 0x1e1538ff, - 0x53cffb87, 0xff6471e1, 0x87ff5805, 0xf44bc2b6, 0xfe8c793f, 0x0ff05473, - 0xef8f9bf7, 0x7bac1dcf, 0xeef942d6, 0xc6c57860, 0xf7e14b57, 0x7bf80cf7, - 0xb7afa41b, 0xeeb9cf0a, 0xfa0e7822, 0x7a7ffd81, 0x1f52f21f, 0xc0f7aad8, - 0xe8ba8318, 0x7a28cf3c, 0x83d89f26, 0x789cef70, 0x87959dbe, 0xdeff1ceb, - 0x90ec8728, 0x942c6a67, 0x8ce7a0ed, 0x015a1224, 0x235297fb, 0xdf1139ca, - 0x34fefd12, 0xb392ab53, 0x46a17ee2, 0x68d87f9e, 0x26aff161, 0xac2cffab, - 0x574d12ff, 0x1f68cfcb, 0xf03b0ba7, 0x0e213b7c, 0xf888d7dc, 0xc5fb0c8e, - 0xf97d703c, 0x9b0b9c08, 0x0cffe397, 0x1509fbbe, 0xd1ef102b, 0x0fcdb15e, - 0xf38f79f9, 0xa6e3e47d, 0x2313db88, 0xf2d9753f, 0xba1bb357, 0xecb7e8e2, - 0x8cc23b77, 0x40d9757e, 0xcfc8dabf, 0x7ce072eb, 0x67bf00e3, 0xb9fb414e, - 0xde30f4ae, 0xfc275947, 0xf3e32b02, 0x601d3256, 0x54788b4f, 0x8217e402, - 0xdd86b0dd, 0x616f5853, 0x275ffae5, 0xba17b9e1, 0x8114b21f, 0x65add99c, - 0x071e22fe, 0x1e61cf3b, 0x02c9ae34, 0x7cf20efc, 0xaffdf397, 0xe7a7bde1, - 0x3a478e57, 0x0fe5ffa8, 0xddc31ef1, 0x0d9f4ce9, 0x3ea1b3ee, 0xca7837ab, - 0xddcd5ee1, 0xed6ecce9, 0x2509c395, 0xa3ec7631, 0xa7285519, 0x5e395e3f, - 0x19271b13, 0xc2e4cd9f, 0x94ffe11a, 0xce70e5a3, 0xf0d2e3ea, 0xdd3ea13f, - 0x1bdfc263, 0x53fdecd3, 0xbabfde39, 0x63bf80c6, 0xe277b551, 0x5fb0b9ba, - 0x1f31904c, 0x84d7b35b, 0xc55d9cf0, 0x6f8383ee, 0xef35ee41, 0xcbbf871d, - 0x62896f56, 0xd9b364de, 0xc1f10053, 0xc0dfbdfa, 0xf1389fdf, 0x902cc4f8, - 0x9593c783, 0xfb6fbc2c, 0x3a748a71, 0x26fbe3ef, 0x579df7b0, 0xdb6ab9e3, - 0x347f8b1a, 0x4bd088ff, 0xedcdf7f1, 0xd73e2f4e, 0x6899f807, 0x5e1c80f4, - 0x675fe438, 0xbfd607f7, 0x24a59d19, 0xf306ffa0, 0xa7edea17, 0xeb1df7f0, - 0x49dd8fbb, 0x42e93e30, 0xbcfb15fa, 0xb9eb71f8, 0x8faddafe, 0xd5df83ce, - 0xf8e76fab, 0x59f7bfe7, 0xdfc629af, 0x5ff8149b, 0xf31f7713, 0xc5de38f7, - 0x1911c4f3, 0x76a4b9ef, 0x8ff81645, 0x2037ec4e, 0x33589dbd, 0x1057ef19, - 0x5853d5e3, 0x8f4f94ed, 0xb029953b, 0x15b20bbe, 0xb676ff36, 0xe9ef157f, - 0xbdf811f8, 0x2d3ee8ce, 0xda0dafe6, 0xc71009a3, 0x7944ed14, 0x5afd3e68, - 0xddb7bdfc, 0xdd7007e9, 0xa0115d29, 0x6d2fcd2b, 0xbf03b7a8, 0xf71bbf64, - 0x82092971, 0x8ef8349f, 0x077bf701, 0x9ed019f7, 0x9d977c1e, 0xef711fcf, - 0x059a359f, 0x7e06dcf7, 0xdae50e39, 0x0b746660, 0x784dbfb3, 0x51e0e4cf, - 0x5e3cd5ff, 0xd1efc69c, 0xefbb034c, 0x18533ec2, 0xc4fa3eec, 0x6c9043b8, - 0xfdfbe373, 0x882fbc16, 0x24f9d93e, 0x7f1b8f69, 0xf1748937, 0xfdf823ef, - 0x09fe5903, 0xc81fa720, 0xe15bfda3, 0xeed893fb, 0x4affae42, 0x9211598c, - 0xc74bc7ce, 0xd9fd337e, 0xccfa5ef8, 0xa80f7ecd, 0xb047d78b, 0x5ff0603e, - 0xbdf8f38d, 0x328cf48d, 0x5f7aafcf, 0x49d97de4, 0x6e028eb8, 0x23b4678a, - 0x93d2f1e3, 0x029ff6cd, 0x3974f11f, 0x80979eb4, 0x7832fc0f, 0xb63ec0bf, - 0xea26ab8e, 0x9ce93c99, 0xde32f68c, 0x27931430, 0x07df7cb8, 0x3a839748, - 0x97a0d3ef, 0x847547a2, 0x2d48c3dd, 0x5457f003, 0x16f576b0, 0x7010f7e6, - 0x07e7e19c, 0x1e593b1a, 0x3ee799e1, 0x856f9ac8, 0xa81ff3f3, 0xff0bcfce, - 0x0124ed21, 0x8f5633fc, 0xc4575092, 0xc22d76ec, 0x6e8f7ec5, 0xdfc14e8d, - 0x3e3e0c0b, 0x2712fd11, 0xbc5ecaf4, 0x15d57607, 0x6d27a01a, 0x4fbf9731, - 0xfb8979b0, 0x6d3dc4dd, 0xc81978f1, 0x99b2fa66, 0x3b82eff8, 0x25138ffe, - 0xf14b0785, 0xff744abe, 0x52cd206b, 0x7e589af6, 0x9185ea3b, 0x2fea42f7, - 0xff827bf1, 0xb053e5bb, 0x9f806556, 0xd5e80260, 0x7fb676d3, 0x40225bc4, - 0x3cd96bbf, 0xb803e03b, 0x4ef882ff, 0x5bc45e83, 0x4e1e2825, 0x9e3eac4b, - 0x1bbc84ce, 0x1ba00f81, 0xa3be17e8, 0x9d9e7f7d, 0x763ff6c3, 0x17943f27, - 0xaa5e43d4, 0x490157d0, 0x0f7dc0d6, 0x024a1d27, 0xcec9e5d0, 0xc872e73c, - 0x292871f7, 0xe076f6b1, 0x0e7bc110, 0x73ff3814, 0x922efc35, 0x05f80a77, - 0xfed53b77, 0x5e787888, 0xfd401ca8, 0xc6985ff3, 0x800053c5, 0x00008000, - 0x00088b1f, 0x00000000, 0x7db5ff00, 0xd554780b, 0x733effb5, 0x79332666, - 0x84841e4e, 0xe4249840, 0x09308401, 0x0741410f, 0x68151048, 0x85280978, - 0x42100793, 0x17b6881e, 0x240cdb5b, 0x41b45a20, 0x768bd151, 0xb4544140, - 0x03414141, 0x58a50077, 0x56d56351, 0x880dcb6d, 0xa8311fbc, 0xadadff97, - 0xfb5bf5ff, 0x90ce649c, 0xf9b7b5a8, 0x67d9d83e, 0x7b5ad7bf, 0x3bdaf5ed, - 0x3f437cdf, 0x756109d7, 0x10f4422b, 0x116dce22, 0xa3109862, 0x42f382dc, - 0x11c885d8, 0xca8df3fc, 0x5c3adb89, 0x8df88588, 0xdaf9aaaa, 0x2bc89eb5, - 0x1f5c2deb, 0x774675e3, 0xb5f1bdf1, 0x28f250ff, 0x084c21b3, 0x5d3dfe87, - 0x1e310f88, 0x90ea7b8d, 0x460ca7dd, 0x09ac2e1a, 0x75ac5442, 0xa51a45fa, - 0xbacc4e6f, 0x4285e653, 0x5c6cc775, 0xe34ad899, 0xca2a6f96, 0x1fb29112, - 0xd0aaf341, 0xea9e55e7, 0x0a8752cd, 0xeaa8f6d1, 0xebf684da, 0x6a8f9e55, - 0xa51eb8f3, 0xdbd627ef, 0x9fa9cb5c, 0x273e7d0a, 0xc5d16b7a, 0x0ab794b9, - 0xf280bdab, 0x45da2d56, 0x54782efd, 0xb177f62d, 0x81f7aa3e, 0xf80ba0b5, - 0x3a894d60, 0x1ea8327c, 0xe39469d6, 0x7268f7bf, 0xc2fcd157, 0x63cc77e9, - 0xd1f7e2a3, 0xd1f44efc, 0xfc7f21e6, 0x82b13093, 0x45daeaf2, 0x2bdceed1, - 0xa1c27de1, 0x01727b45, 0x031eb95f, 0x18e3a19e, 0x7808bcf0, 0xbabd20c6, - 0xabf04bc5, 0xa0f5487d, 0x4be6bece, 0x98df80d1, 0xae47453d, 0x61b5f7c1, - 0xecda8c22, 0xcefe9c3b, 0x8b8f34ad, 0x3d4155ab, 0x193dd28a, 0xdbc68289, - 0x2e7cf96e, 0x4dbf73e0, 0xd2917acc, 0x47a7b7d2, 0x46fd285b, 0x21f51fa7, - 0x6a352709, 0xae7cf47a, 0x98b93edf, 0x9edcc7f2, 0x7aa082c4, 0x2ce9d63f, - 0x6b655f14, 0x718d16ff, 0x78d8d62a, 0x2e5e065d, 0xbf341d62, 0xfe118d8b, - 0x8b9704e5, 0x5fb8dbbd, 0xbf464f03, 0x4183c015, 0xa56f544f, 0xe38fa5db, - 0x114717b3, 0xe1b4d35c, 0x64e82e9e, 0x2e3483c1, 0xe51f5bfa, 0xff7de675, - 0x74780d71, 0x25969be0, 0x8f03fc0c, 0xbc6da44f, 0xde59be97, 0x93d10ab3, - 0x7d78d0e0, 0xcbdf42aa, 0x850984f6, 0xda532bfa, 0x9c09288e, 0xac14fb77, - 0x8c3cf17f, 0x9871f657, 0xf7c7e505, 0xf3c79f5e, 0xc12bc10a, 0x7a2bb529, - 0x96d698bf, 0xdf8209ea, 0x736d3ec5, 0x7d06be79, 0xe79bce74, 0x4c37bb51, - 0x4c5c5f60, 0x76467c23, 0xf801b1c2, 0x5df5c619, 0x6f6fa676, 0xb1d7e01e, - 0x7ac8575e, 0xfdeb215d, 0x0b7d3040, 0x29ebc68f, 0x82cc24ff, 0xdc0fe5ef, - 0x71a6e594, 0x8e3bdf8e, 0xce3c75d7, 0x75fd879b, 0xcffa953c, 0xe59d72bd, - 0x733ad00f, 0x8d9d65bf, 0xb757c64e, 0x7b6b8ceb, 0x3acb7c42, 0x6874ea37, - 0xab33f3ac, 0xfa8ada3b, 0x9cb155bb, 0x14fb6a8a, 0xcc8d7fdf, 0xd0d056bb, - 0x0f4936b5, 0xfc236bb5, 0x6685d7c0, 0x6e7f04db, 0xf1a01f27, 0x583d27be, - 0x8f8e1e98, 0x023c3f75, 0xea9f75f4, 0x9701b9f2, 0x9cfcef21, 0x57efc7f2, - 0xb1f9025d, 0x0fc47e12, 0xc70fe02c, 0x73278b53, 0xb5cdaf7e, 0xb4f9fa82, - 0x047f6ff1, 0x63dc5cfd, 0x5f5e0b73, 0x90b3fdf1, 0xaf82f9a7, 0xc66e5c11, - 0xebce54b8, 0xd619ef57, 0xe8f17288, 0xbba65760, 0x0214be0b, 0xaa358ae7, - 0x01d21f69, 0x3ed5e3c1, 0x3ac6e290, 0x8713380c, 0xa83a9acd, 0x4fc81e13, - 0x9709d41f, 0x9ad0bb5a, 0xfb12fbf8, 0xfc414194, 0x9749f00c, 0x3cff44e7, - 0xa2d2c7c9, 0xc873f683, 0x8ff942fc, 0xff48cf51, 0xcc57c1d2, 0x705178fc, - 0x1950e09e, 0xc21c5f92, 0xca42aa37, 0xb7ca43ab, 0xf99cfaf7, 0x13f8e840, - 0x31bee4d3, 0xc3aa58e0, 0x9145bb71, 0xc53ee47c, 0x2d7e89bf, 0x4bedbab5, - 0x8e2ffe69, 0x4fd0f311, 0xae385599, 0xced97de5, 0x8ab52beb, 0x7c02b086, - 0x633d70f7, 0x435fd4dd, 0xc3e51c58, 0x7aa21f25, 0x7941ec13, 0xf31adf83, - 0xf0934f09, 0x5bc5d230, 0x83c78d9d, 0x14dd59e0, 0xeed7ca6b, 0xee3c6e4a, - 0xc62fcce8, 0x6ff4c92f, 0x387ead22, 0xaa7f22e0, 0x8c1eb577, 0xb249fa20, - 0xd469e168, 0xff83c5ef, 0x66eb9d1b, 0x262f0fbc, 0xe9a816fc, 0xf5a61d2f, - 0x3d56edb6, 0x9befd09b, 0x5f11fcf2, 0x1b787a5f, 0x9bd9af7d, 0x7775ee21, - 0x8e143fae, 0x8a5d7717, 0x17efa74e, 0x05c3d90e, 0xcda501c9, 0xd1ed63f1, - 0x84babfbc, 0xbb875bbb, 0x6b05dfd1, 0xa094f46b, 0x6b44177a, 0x7a20d4f4, - 0xa975dd29, 0xfc31e44e, 0x1f106a7c, 0x8f4f74ff, 0x2f7d2ab1, 0xb1af7dfb, - 0xe9c74a16, 0x736fdefd, 0xe686b93f, 0xe61ddbed, 0xbef34cd9, 0x0b2ce6f0, - 0xb3785fda, 0xea7f4f42, 0x4fb3f4e5, 0xb47e3153, 0x31bbd245, 0x293488de, - 0x8e59954f, 0xfc1a313e, 0x699ed5ff, 0xe59d69f5, 0x2c829665, 0xad9b79e0, - 0x7de62e6d, 0x95ab1141, 0xc67eceb8, 0xfdb9b9a5, 0x9f27dd85, 0xf4f87f00, - 0x60053efe, 0x6776172b, 0x7e5469e7, 0x5921e3e1, 0xc2f7ea2e, 0xf01ec97d, - 0xf7366d85, 0xeede994f, 0xdf60f289, 0x9c61fd1b, 0xf77fe825, 0xa435c355, - 0x52f9cb1f, 0xe3934f3e, 0xce8294fa, 0xee2da37e, 0xbf028f5f, 0xb3cdbdf8, - 0x7fa59299, 0x8b19e8cf, 0x773f61f5, 0xd5b28781, 0xe26dc261, 0xde782b27, - 0x8763c2a5, 0x1172841c, 0xa2e55f44, 0x6fcfbf98, 0x405f7f34, 0x17df027c, - 0xaf7f37ae, 0x5aab8d10, 0xfc8b7d69, 0xf682efe6, 0xfb112f8f, 0xe269f8da, - 0xd6f17ef3, 0xf54cc26f, 0x0fe74f84, 0xa5c7e60e, 0xc7c11fb4, 0xfefc579e, - 0x3defc015, 0x7433af2a, 0xd2d3cb5d, 0x448f1d78, 0x6b6e63fc, 0x598f5e10, - 0xe0893584, 0x1c2ecc7a, 0x47e80549, 0xbeab9c08, 0xcdfe613d, 0xfedee4d4, - 0x3296a55f, 0xe0b24bdf, 0x05c3b83c, 0xedfd47ce, 0x7e8a9939, 0x791756ca, - 0x77e6835b, 0xe47de6d1, 0xdf5790e7, 0xf54d7e23, 0x37f58d8e, 0x1d79a58e, - 0xd4f557bb, 0x33af3177, 0xe3f99f24, 0x28f71e09, 0xf2843fc2, 0x2d4c9ccf, - 0xde9cbc21, 0x34b5327c, 0x3115fe98, 0x8d1e982b, 0xebc26694, 0xf489ac82, - 0xeb05ad18, 0x89d7ad09, 0x0d7cf35f, 0xb1553a78, 0x787a2ba4, 0xe54f7414, - 0x05577f39, 0x3d9acee4, 0x33e83f36, 0x0f17e362, 0x6cfa0adf, 0xda40b9b6, - 0x2f547bb5, 0x5bb174e4, 0x1ce267f5, 0xba34fe6b, 0xeecce712, 0x68352e21, - 0x170e74dd, 0xb0b97ce3, 0x596252eb, 0x1933f72e, 0x9eed44f2, 0xdfa03c87, - 0x5cf1e6ee, 0xf1affa9a, 0xff99af3f, 0x20fdcf9d, 0x81f046f1, 0xc0b2278d, - 0x3e0f89df, 0x99fd8697, 0x791db5f5, 0x83875a21, 0x2c7e68fe, 0x7ff45fbf, - 0xa3a5f2c5, 0xbbfaf559, 0x349ec3c0, 0x07ffc33b, 0xcd026fcf, 0x7e73b12f, - 0xe03d9f34, 0x6b3cc6cb, 0x9c766ddc, 0xd11d17b3, 0xb4a7e079, 0x89f989a0, - 0x06e4f9fa, 0x289b2d7f, 0xee16bf88, 0x09c2bf9e, 0xf151a179, 0x6f280f40, - 0x2adcf956, 0xddfaa0df, 0xecc29784, 0x213bf6bb, 0xe5443e9f, 0x3abc74d4, - 0xa8b38fea, 0x54fbc2fe, 0xf8dbefce, 0x80da3fd3, 0x11360dd7, 0x47863c06, - 0x63c7d26f, 0x3e916879, 0x37cd45bf, 0xb7a0569d, 0x013d51ec, 0xe51cdfb4, - 0xd5b2f7c1, 0xf4c163b6, 0x50bf1f35, 0x2bd7f37f, 0xf81a40fe, 0xc2fcb984, - 0x27ce9f30, 0x5c6fbe42, 0x027f7535, 0x89eb2b52, 0x72e6fc8b, 0xf34ebcfc, - 0xdf7fd5a9, 0x17a6b99a, 0x29c173f0, 0xabf60b44, 0x1df595b5, 0x054d6811, - 0xfeec2f1e, 0xac78152c, 0xb27ff57d, 0xebf81744, 0x51cd4fd8, 0x84222709, - 0xc6e74b38, 0xfdd01637, 0x5dc5c9a5, 0x8fb17fd4, 0x6d5b17dc, 0x63905ebe, - 0x8afc6ff7, 0xddc5c1f9, 0x17575f5a, 0x5fb9dbf4, 0x124b4e7d, 0x205380d2, - 0xbae4da1d, 0xe484fb11, 0x1f417bc1, 0xdd4d569b, 0x6be77944, 0xa2424836, - 0xf7923336, 0xfcc7f60b, 0x7d8d7ea0, 0x017c15b2, 0x1fc930e9, 0xe523ec5e, - 0xbcbad584, 0xfb5f75b0, 0xe62ecce4, 0x26cd3ab3, 0x923edbcf, 0x2b4dcc6f, - 0x9c874f0e, 0x0345f161, 0x75ebc21f, 0x157c1027, 0x97eabe9d, 0x3df0512d, - 0xda723449, 0xfa71345b, 0x245a10b8, 0x0b8f0bea, 0x4fa21670, 0x7bc7e02c, - 0x31abd79e, 0x8e89fcdf, 0xd06af03b, 0xf8562f83, 0xeaefd337, 0x63508746, - 0x46b5ed20, 0xa0d451a3, 0x4beebfa9, 0x540fb6e5, 0x3ed49fd6, 0x2e3d3e06, - 0xc8cbf7e0, 0xf8c131e9, 0x74b877db, 0xdeabfa02, 0xf52e7a49, 0x4d877e77, - 0x5957a004, 0x3d50bf69, 0xec2fe1db, 0xcd4be069, 0x5cbc808a, 0xaf7c794b, - 0xfaf5651d, 0x9792e083, 0x9a91e12e, 0xbb70c59e, 0x9a1ef560, 0x9573fa08, - 0xdbd721da, 0xc04f970e, 0x2a4b6379, 0xfb5e63b5, 0xa4758f0e, 0x56b16f01, - 0x9aab37de, 0x5c5b718d, 0xf62a3fe8, 0x436f9e03, 0x534445ae, 0xc28f86bb, - 0x874c0cfc, 0x3a6143e4, 0x85021b5c, 0xf817770e, 0x14c289f1, 0x77ca8231, - 0xcf3013a8, 0x1752aef3, 0x958b68f0, 0x9b308776, 0x9af40277, 0x78b8d8b0, - 0x7a446fcc, 0xabffcf06, 0xcf3c25d8, 0x80bc48af, 0x7af241be, 0xbd0df231, - 0x7d8655cb, 0x8fbc23e3, 0xfc721d6b, 0x9f2a3da8, 0x43a462a3, 0xbbefdbe7, - 0xc89c68ca, 0xd024dabe, 0xa89f3183, 0xf00baf61, 0x858b1ce7, 0x3786b3e5, - 0x2f80d722, 0xd21be518, 0xf819bd25, 0x75609958, 0xae3c7f81, 0x574ae7d3, - 0x6820a3b1, 0x161eb69d, 0x0ec55e1d, 0xbdbb69c0, 0x97ce10f8, 0x738efa36, - 0x54d27f73, 0xaa14f407, 0x273f4167, 0x64c768ea, 0x0ee9dfa3, 0x424177c0, - 0x5bb478e9, 0xc2ac9628, 0x5eb85b7e, 0x3e208115, 0xe39360db, 0x211cb82e, - 0xc73a4302, 0xe3f8405d, 0xf9a397f6, 0xd653837b, 0xfb92886b, 0x2974cee7, - 0xd3d4ae2f, 0x83fa7ab5, 0xccc7baf9, 0xfec7cfd7, 0xe4a94b71, 0x53a677ef, - 0xeb4ad5bf, 0xab268878, 0x80edda92, 0x973a89ef, 0xcd058408, 0xc6758af7, - 0x38d0408b, 0x3b2ef51d, 0x183e2045, 0x47c66e1f, 0xb9237ae7, 0x125d44fc, - 0xfefbb1c3, 0xec704c53, 0x04c33fec, 0xcffb2bc7, 0x7513f2e2, 0xffd1df39, - 0x4ffa6ec0, 0xb3bfcd33, 0x5dfc7edf, 0x82fad2ec, 0x22eddcbf, 0xd374c07e, - 0xbb2676ca, 0x7606fda2, 0x9871f12f, 0x95f7dc80, 0x0576cb53, 0xe96d87f1, - 0x0b9f5d76, 0xfadf80a4, 0x6b4e3ac4, 0x8f1a5d77, 0x0be26ef6, 0xcbd0e76c, - 0xcf1b456b, 0xfa02fc13, 0xbab648bd, 0x96977cb9, 0x98c8bd0d, 0xf33c8747, - 0x859f48bb, 0x9ed841f6, 0x1f6347bf, 0x4db6b45f, 0xa9aa7d86, 0xde088d59, - 0xfdf407d7, 0x17cfb631, 0xd5d7b079, 0xbdf11da0, 0x9c5dee9f, 0x84d4f80d, - 0xde61e5b5, 0x2dfef7fb, 0x57c8e70f, 0xc5f7167b, 0x9f54adf7, 0x5b7b0fe5, - 0xbfa8278d, 0xb3e5c27e, 0x9b4ce88c, 0xfa1ffdf5, 0xfa9eeb7d, 0x36c7985e, - 0x2e483dd8, 0x56f659ac, 0xb078f1c6, 0xe083ef21, 0x16f8825f, 0xa6bb43eb, - 0xdf2063a9, 0x0f32487d, 0x96ee87e5, 0x3ed0c372, 0x83496fc2, 0x2ce1f7dc, - 0x619a89f0, 0xe1541776, 0x9616fcf0, 0x3987c3b7, 0x9f9f385c, 0xebc193ed, - 0xc84e43b3, 0x78a2fb40, 0xf154e7a6, 0x1b6dc9af, 0xe04ff642, 0x68db350f, - 0x75b56abc, 0xf78538f2, 0xa9f031d1, 0x78bfb79a, 0x135fd747, 0x8c5a9f81, - 0x5f78f04b, 0x432127ef, 0x9a7a893b, 0xabbef5a3, 0x9b8cdea8, 0x1fa15393, - 0x99fae895, 0x19404898, 0x1068fcc9, 0x9e5720ec, 0x7a0f52db, 0xc034d14d, - 0xf0ec97c1, 0x981afce0, 0x71c91c22, 0xf4fed0d8, 0x57ee34a9, 0x2ec316e9, - 0x03de60aa, 0xdf3d35f4, 0x2c6969ab, 0x38fe939f, 0x3b3fd1d0, 0xfbc325ae, - 0xa30bf077, 0xdf3787fe, 0xe2eb483a, 0x79e430dc, 0x36e9bdbb, 0x3aadb3cc, - 0x9847f592, 0xc9eed0f3, 0x2a02c39b, 0xc8b68aec, 0x3fe7d0d5, 0xb07b988a, - 0xfee3c107, 0x83222d28, 0x799acdda, 0x95e42ac3, 0xa5eef1fd, 0xd692e7a0, - 0xd3e7c0e1, 0x83262d4e, 0x6872afc6, 0x8969137d, 0xd968fbe7, 0x8be43831, - 0x449e25e3, 0x2ee2a0f1, 0x53e72fe7, 0x0ff1c8a2, 0xe8496947, 0xf2d2c4a7, - 0x66f855c4, 0x837b616d, 0xfdc1e868, 0x8a8bb79c, 0x037fe4ae, 0x75f4470e, - 0x6b89b3ec, 0xf6fad32f, 0xd4f18dad, 0xefcb7cd3, 0x96b7399e, 0xe296f9d2, - 0x9a6a80c4, 0x55d61677, 0x9be92be5, 0x79f3f24c, 0x65ef3e9b, 0xaeadbcfa, - 0x1cfde0ac, 0x437aef3a, 0xc285f95e, 0x50ff20fa, 0xac5f15fe, 0x87ca5eff, - 0x307d2e59, 0x20d6e70d, 0x3649db0b, 0x22ded384, 0x7d5df23d, 0xbed38f9e, - 0xf7f1c473, 0x149ef8d5, 0x3d27db2e, 0x7ec3f16c, 0x37763c50, 0x9ac9e9e3, - 0x634a8f48, 0x1db70895, 0xf0995072, 0xd9fc5cb2, 0x69edbf98, 0x661575a5, - 0x6e01d768, 0xa92de2f3, 0xb43cf01f, 0x6f205381, 0xf8eb928d, 0xd7937916, - 0x6cb85531, 0x3589942c, 0x531fc816, 0xf329725d, 0xa63fb915, 0xe30daf09, - 0xd71a10cd, 0xbb05c3fb, 0x1fc4fa17, 0xbcd10ba0, 0x7f1f0a67, 0x9cfc2d9f, - 0x5c022ade, 0x95a2c7ff, 0x89bc06f3, 0x4825e63e, 0x53d938fa, 0x8cdff865, - 0x9117bf79, 0xad1967d7, 0xd923ca63, 0xad5fac99, 0xf9f0c1eb, 0xd14f79ae, - 0xeff686e9, 0xfd83f43c, 0x99fa9d3b, 0xfec8637a, 0xe061ec2d, 0xf6dbf333, - 0x877b4b51, 0x4c9914fe, 0x475eb870, 0xc5def5e9, 0xa9153fac, 0xf847c291, - 0xfaa51969, 0xf21c7721, 0xa0484f2e, 0xb9fddc75, 0xb77e83d4, 0x843dbc5c, - 0x46377fca, 0xd2dcf515, 0x64d4f2cb, 0xbdc99fbd, 0x9d869fc7, 0x2408b0f5, - 0x17b9a50c, 0x8f5ed65d, 0x564ef9a1, 0x52c435b7, 0xa4de84f9, 0xbdf104c7, - 0x5bb6121b, 0xd8ddd7a1, 0x627dfccf, 0x99df59ae, 0xc0551a24, 0x7350f279, - 0x0f807dbd, 0x0c8ad7d1, 0x0188b7a9, 0xdfee8062, 0x47fbb963, 0x13ed1f7a, - 0x0be1d92f, 0xbb433579, 0x3a5c7007, 0x18b9b3e9, 0x7ae55857, 0xd951de6a, - 0xe48c779e, 0xdf9d2f2c, 0x84e8ebc7, 0x08f29308, 0x6e48a7f2, 0xcea67a40, - 0x3a39e9cd, 0xa17e51e7, 0x67eb23ce, 0x7d803f14, 0x73faba56, 0xb772f02b, - 0x6ef9c253, 0x761faa67, 0xc6a68ab5, 0xe55e98f1, 0x4883a6ae, 0xe3c503cb, - 0x382ecc71, 0xd220e4b4, 0xb6f43bbb, 0x5fdd0e25, 0x5dbff3c0, 0xa3dbd3a7, - 0x8834dea6, 0xbbedc9f6, 0xf6ebdfa5, 0x4da7533e, 0xc6de404a, 0xa8e8eef9, - 0x3422b2fa, 0xa8cf22da, 0xb758cdde, 0xc1e8f9b7, 0xc9e75a78, 0xff3c11ba, - 0x9e5e75d3, 0x09bad9ff, 0xa33dfe9c, 0x27ae39f8, 0x6c79673e, 0xd6a3b6d2, - 0xe45faa14, 0xb7d8bc55, 0xdf857ad7, 0xdeb1744f, 0xf581cf26, 0x1f600e74, - 0xf534198f, 0xe9303bf1, 0xda276d0c, 0x5171b8cf, 0x3c99c611, 0x7a8ac4a2, - 0x2216bf33, 0x4e93ad3e, 0x8dee8bbf, 0xf8eb57f5, 0x6157bf3b, 0x1bdf9e78, - 0xdf6cf0cb, 0xf9031191, 0x8ccee960, 0x6f89489e, 0x046f7a1a, 0xd97ed7e0, - 0xff6df3c2, 0x8ef59c28, 0x774bf6d0, 0x7a89ec0e, 0x22df0967, 0xfb3cde48, - 0x83b87ffc, 0x71b395cf, 0x027d5f4d, 0xc957f6fe, 0x39b248df, 0x5ff818f1, - 0xd01e5eef, 0xce5d05cb, 0x02233d26, 0x6e8d5fe7, 0x427f0457, 0xb4b86cfe, - 0x217f0ee7, 0x17f62c65, 0x9c1373c6, 0xb9191cc3, 0x7f7087c7, 0xfd467e47, - 0x9258fcbd, 0xb9effa07, 0x63a48fed, 0xf34dadfc, 0xfa8c793f, 0xf8b7ef3f, - 0x9d4e746c, 0x5e174d17, 0x2a7e1f05, 0x777bed92, 0x9c2f342b, 0x717b9bc3, - 0x86b1473e, 0x2c39c32f, 0x73cfbcfc, 0x1975b714, 0x17aaadf1, 0x7a05ed1f, - 0x30608d7c, 0x5b5fca82, 0xed7cc11b, 0xc8e79b35, 0xb8f7f432, 0xfbe9efec, - 0x0bb63cef, 0x05d57de9, 0x65fa5277, 0xa1e31c46, 0x034581fc, 0x79ce9ed0, - 0x3dfd4c91, 0x80128af7, 0xbad06abf, 0x69922b7d, 0x1c37837e, 0x34a2f4b5, - 0x1ea529ff, 0x373ec0e9, 0xf9fd821e, 0x6e6e196f, 0x9a5b643f, 0xd96d829a, - 0x75c9ffcb, 0xe59bfe7c, 0x9f75dc82, 0x3a25ed8f, 0x4a0183e5, 0x348d99d3, - 0x8fd4b0d7, 0x6386340a, 0x6767af23, 0x6ff7b4f3, 0x49075815, 0x8977981e, - 0x91e7c3dd, 0x7811b7df, 0x78e5af3e, 0xf62bbf58, 0x3b7a0a3d, 0x707a25af, - 0xfa4cbd3e, 0x7fa8d5fc, 0x7cebcac4, 0xa2f7a9e5, 0x2189df61, 0xbf09d93d, - 0x78db7e48, 0xe3eeafd4, 0xf587f016, 0x09fae279, 0x8ecd4f80, 0x9fb91b9d, - 0xfa07872a, 0x4bcec56e, 0x2f205307, 0x993c20de, 0x321dc7a0, 0xaf42abff, - 0x56a5a547, 0xe652fc6c, 0x5f398a5b, 0xfc27da4c, 0xca4ca2fe, 0xe7e88f49, - 0x63cd68a0, 0xee24c97e, 0xafd7c4ee, 0xebe518a8, 0xb0c97cd3, 0x27e71b6f, - 0xfda97b9d, 0xb2ec65b0, 0x5bd8cb7d, 0xdf2e1953, 0xebb3dcf3, 0xdfd197e7, - 0x73e17623, 0xdf303f52, 0xc1be9ec0, 0xcdebcf2e, 0x2f4067c4, 0xe34d79c6, - 0xed93f5e6, 0x29afe0bd, 0x076832aa, 0x91e523c1, 0xbe379630, 0x62b3f8ef, - 0x6df9f156, 0xe1b55bc8, 0xd9f22f92, 0x885fed41, 0x37eeaed2, 0x7932760c, - 0x3bab0bde, 0xe3c8f217, 0xfa6bde51, 0x96d5bcb1, 0x39d0358a, 0x53e61d7a, - 0x95fc92a3, 0x457f2411, 0x73af7dc6, 0x2de51034, 0x5beffb42, 0xcd046c7f, - 0xf1290633, 0x86a468ef, 0x485a45de, 0x7d39fc97, 0xf3f8135b, 0x3f926143, - 0xbe610d47, 0x7433ac64, 0x07c4039c, 0x6f3be234, 0x11a339d0, 0x3917183f, - 0x7d78cac6, 0x907552dd, 0x3922e5ce, 0x1ada0802, 0xdef3943b, 0x61638228, - 0x2eb42aa4, 0x252347f4, 0x3ac7cdbc, 0x984427c7, 0xc42515ea, 0xbf8fb1da, - 0x1d55faef, 0x3cb86a4f, 0x8370d4bf, 0x7413babf, 0xfac87dbf, 0x776f7ae5, - 0x3abe630e, 0xeb7ef956, 0xdf15b22e, 0x8b8f3c09, 0x7373e7cc, 0x2394e45c, - 0xd475e09a, 0x7ae87be1, 0x1c25d743, 0xfa8e4fdf, 0x167c2289, 0xedcfc7ec, - 0xb66b776c, 0x5bf73eb5, 0xa2f36b82, 0x47ec0f5c, 0x70bed32f, 0xb54e9f80, - 0x0cdb9cb3, 0x37ea92d9, 0x5c7170f7, 0xdfba6bcb, 0x6f5b37dc, 0xbe7c14ef, - 0xc5eecf34, 0x615ef47e, 0x48ec1034, 0xd26fd2f5, 0x16f25b6c, 0xe5e6ebce, - 0x819a1e29, 0x69efc150, 0x97e47ccb, 0x095ebcfc, 0x817f0adc, 0x40bb73ef, - 0xfeb175fd, 0x5f94e9d5, 0x9e0c8bf7, 0x8fa447cf, 0x8abc62d7, 0xeb5be670, - 0x71c9bd62, 0xff979f04, 0xb279f2a1, 0x91f29f2e, 0x6ed9d7cc, 0x378a6eb3, - 0x04ad7e19, 0x36eb6f1d, 0xb05ef2ca, 0x4d3ca293, 0x26c4ffb6, 0xd7a2dfeb, - 0xfbf1d04b, 0xb4a74eb1, 0x683f99ff, 0xa0ac2393, 0x95fb77ff, 0x46fbc6be, - 0x17e19378, 0x933cac7a, 0x54b7986d, 0xf4c690de, 0x66d3dba4, 0xe8dcfce9, - 0xc31c0d17, 0x9fcb4f21, 0x3b37f3d9, 0x2a33df41, 0x1f21479c, 0x22b1547e, - 0x0cfd7a0a, 0x21840d4d, 0x917a6abe, 0x4bae43b7, 0x395eb8c7, 0x1fa1b96e, - 0xdf00ca06, 0x710e6dbd, 0x81ffcb2f, 0x96fac121, 0xfa45e781, 0x1a6eadbe, - 0x7eb060f3, 0xfe27695d, 0x72e51833, 0x6a45573f, 0xd57d07bf, 0xc1e1baee, - 0x54fbbd60, 0xbc7943f9, 0xcf71f4ef, 0x3c1f79d5, 0x6f39099e, 0xb8c6a702, - 0xf011fa1d, 0xd5f6fd49, 0xefda73cf, 0xdaf00b3e, 0x92fa94e4, 0x85e3edb5, - 0x359faf94, 0x09f7cf80, 0xd85e1d53, 0x8477daf5, 0xadaf61f9, 0xc5ee159f, - 0x44f7eaba, 0x985761f9, 0xd21befa7, 0x6fbbf8bb, 0xade98dbb, 0x667feeca, - 0xdaabb50b, 0x89e99fdb, 0x96ed95e8, 0x642357be, 0x6d37b479, 0xf79450e5, - 0xcd79fa64, 0xf2e18ee6, 0xe5c15537, 0x58ac81e1, 0x539b7782, 0x1375853b, - 0xbcfdb2bd, 0x1fbf2eca, 0xfa12e9d1, 0x96fffb25, 0x42bf7144, 0x8f3f6bcf, - 0x584f7d67, 0x91f3c9bd, 0xaf207dbf, 0x7dcbb347, 0x7ea46a21, 0xe725c478, - 0x9e39a475, 0x8f4185f7, 0xdcb78a47, 0xef809593, 0xfcd2af24, 0x0d4cb2fe, - 0xd06e1fc0, 0xf2f5329f, 0xbb5157db, 0xd9555f4f, 0xd7e7336f, 0xfbe30f8b, - 0x13d5159c, 0x6bbcad39, 0xf5cb9f32, 0xa2eea71f, 0xa7a984f2, 0xe06bbfd8, - 0xd9954e7f, 0xe9989a9f, 0xdf813355, 0x83f6ff5c, 0xd9e1ff54, 0xaf001627, - 0x473533c3, 0xf6dbec26, 0x4cff97d6, 0xfe5d6df3, 0x36a3d627, 0xf8116b44, - 0xd3f7717e, 0xc566bf5c, 0x7e802cff, 0x74956350, 0xb5db9c63, 0x91bf3d3a, - 0xffa2c5a9, 0x63bf15aa, 0xb722223d, 0xbbd7f245, 0x3a3f1fbe, 0x65f9bcd3, - 0x0e2dda85, 0x54e1ae6f, 0xfce1e7f5, 0xa204ab3b, 0x2b860c95, 0x5ce775eb, - 0x47e06881, 0x72b948b3, 0xbf10d6f1, 0xa8925031, 0xdda88bdb, 0x8f5526e2, - 0x41dbf457, 0x17f5a1a7, 0xf7ae77d3, 0x8a57bf3d, 0x763df926, 0x30d7fdd7, - 0xfe0045fe, 0x64cf33ae, 0x9c3d026e, 0x5674f9df, 0x34369fb0, 0x72be72bd, - 0x7df4e7fd, 0xd8be8e73, 0xc2db6f40, 0x0b85f64c, 0xf4eb24cf, 0xc2e9e926, - 0xe7ecd933, 0xd9f7d44e, 0x0967c505, 0x085fbb47, 0x9e10678e, 0x971ce1a6, - 0x0e1a6de3, 0x9d61fbb9, 0x6f8e2e2f, 0x67be0e1a, 0x68e141f0, 0x41bb63ca, - 0xf41e534e, 0x8a7f8364, 0xfe2ca6e2, 0x42ca6fee, 0xd22d97fb, 0xa7cc630e, - 0x8e14b9f2, 0xf0b5a27b, 0x6e7caefe, 0x8de426e0, 0x929dea71, 0x253bd4ef, - 0xb75d097f, 0xe8ed2996, 0x1ee64fa4, 0x3ea4b3a7, 0x5c82f496, 0xde6593e4, - 0x370bf329, 0x6fe1d894, 0xbcc9b7af, 0xfd897d6b, 0x35f7e618, 0x4fc4b569, - 0xc5bf7473, 0xdda97f02, 0xfafefb0b, 0x3f1ce1e5, 0xcf3edb31, 0x7af6694b, - 0x035c69bb, 0xe6fdfd0f, 0xf9f48bef, 0x0b890df4, 0xedb6a5ea, 0xf639c30b, - 0x8e32e8a4, 0xb4a64960, 0x6cfb3ee3, 0xaa917c47, 0x6dc2dbeb, 0xea5ba1d0, - 0x8fd78c1b, 0xef5e06ed, 0x2ff9a148, 0x5ea5e3d6, 0xfab848b6, 0xe37c959e, - 0x052d7ce5, 0xc005d5e7, 0x2c5ce71d, 0xef2173e5, 0x7919bc49, 0xf0a15f03, - 0x82f1f15d, 0x9f95d814, 0xc7f694c8, 0x8f2c7c50, 0xe513de1a, 0xd4cf5c06, - 0xdc00ca1d, 0xa89d758d, 0x68e97af3, 0xafbfb4eb, 0x8c6877cf, 0x30477c8f, - 0x1d6fd77d, 0x20248872, 0xd5ab6e71, 0x5bd42583, 0xbf43f7fd, 0x36aadfa8, - 0x3b9704f9, 0x91739780, 0xbd41dffb, 0x0b621b05, 0xed180fa0, 0xf22fae17, - 0x7bcd0796, 0x5e3356e0, 0xf3993506, 0xf3997783, 0x0d06715b, 0xe5dbe7fb, - 0x21f9cc07, 0x93f9cc87, 0x3371dc1f, 0xea854fb6, 0xbe855fbb, 0x87f1e7f3, - 0x7a9f4e70, 0xe06895f9, 0xcb5ff16b, 0x0b8f420f, 0x3c21678d, 0x7c73d02a, - 0x97a6145b, 0xba5ae22b, 0xdc4643e1, 0x30627606, 0xdf0a54dd, 0x95da6b41, - 0xa68acff5, 0x6744bd9b, 0xcfdecb55, 0xecb37a90, 0x5ad36477, 0xd0cee43b, - 0x3be3bb71, 0xc6ebd222, 0x21192a3e, 0x365eaecb, 0xfe8a7c4e, 0x1e37bcd6, - 0x2bf258f4, 0x929be585, 0x075fb297, 0x3edd1cdd, 0x6f4e46fb, 0x30f0c09e, - 0x9b0b92ec, 0xe5144095, 0x8744235d, 0x8bf11f7f, 0xf1210da5, 0xe2426b9f, - 0xcb99d682, 0xf7daee17, 0x504710ff, 0xe38278e1, 0x678cae2e, 0x5e801ff4, - 0xb04a7959, 0xa9f2aa7d, 0xe5ccc26f, 0xf5f35d72, 0xade71875, 0xf1cb5df0, - 0xaacb577b, 0xa3fe38e2, 0x4ba8e973, 0xcb73853b, 0x5eaf7738, 0xf29551b7, - 0xfd84b7bc, 0x8e7691c8, 0x8876ac8b, 0xebcd0440, 0xebdd9450, 0xd697efa2, - 0xb2bcb147, 0xe85ce480, 0x270a948b, 0x627a4dc7, 0xbbc4eed0, 0xd565cb2a, - 0xd51e12f1, 0xb0fc51bf, 0xa8c3571d, 0x3293fc8b, 0xd80448bf, 0xf23a0bbe, - 0xf803ad06, 0x468bce0b, 0x59565fa9, 0x9f00fb03, 0xab68738e, 0xad155eb9, - 0xc838a3f3, 0x35efe67b, 0xd7eb8da2, 0x2c26faee, 0x3d907bf8, 0x435ef59a, - 0xf97556ff, 0x3865fd4a, 0x20744fcb, 0x6cbe8384, 0xeebedcba, 0x6823921e, - 0x7b0d2b7d, 0xdf295af8, 0x9e51b2dd, 0x679f2463, 0xd6eb4e01, 0xef867c92, - 0xce206fa4, 0xf70a2c44, 0xea5ef94b, 0x6766eb0b, 0xf2f45cb1, 0x400a5e3f, - 0x487b691f, 0xbad2bb61, 0xbaefd97c, 0x3973fafb, 0xe3c2a7f8, 0xb61cb184, - 0xde518a6e, 0x4f91f587, 0xc864c530, 0x1ef7faf9, 0x4bdefe6e, 0x3ec166f5, - 0xb2741e22, 0xfb90c47d, 0x2ebeb90d, 0x1ac9cb56, 0x75feb9d6, 0xf0516db1, - 0xf88a89bb, 0x6cb725ef, 0x36e3cfd6, 0x2afc3f5a, 0x83e295c7, 0xf5198ff0, - 0x73c96646, 0xef58f865, 0xfb1ebd16, 0x532dca5f, 0xe68ebdee, 0xc5b0fe55, - 0x81a17b0d, 0x66f5e107, 0xd7c70e01, 0x77400b3a, 0x7b4ac7c3, 0xc97c91d9, - 0x0a8623e7, 0xab1a378e, 0xcb363bf7, 0xc2934a62, 0x9fa91e89, 0x1ed245e3, - 0x98b4351f, 0x132496ed, 0x6e2aebcc, 0x4fdeb265, 0xf7f8bdb9, 0x4f98bba3, - 0x4a145d07, 0x6df8fbf9, 0x2f3926ca, 0x0e27c72f, 0xf6c9c07f, 0x39fae3ce, - 0xe881e064, 0x0fcb1868, 0x0d8b5f3a, 0xa0b59ba1, 0xa0879c07, 0x6e982507, - 0x8b7174cc, 0xee2be122, 0xbaf7f293, 0xe8379958, 0xf13ff482, 0x229ba0bf, - 0x4eeff0c1, 0xdbd6340f, 0x74481e9d, 0xd07408b0, 0x0e842f51, 0xec3fd584, - 0xa542fcdb, 0x2b876223, 0xab148284, 0x17ce21f0, 0xebc32467, 0xb11fab1e, - 0x12adbd78, 0x92ac7d2f, 0xf1b4e8ee, 0x7d701785, 0x4b7de22f, 0xbc285c1e, - 0x4524bf54, 0x1fad7db0, 0x713155c9, 0x45204edc, 0xbb0a8e58, 0x5f68a513, - 0x2ffb2312, 0xfe3829e9, 0x5af3fa8e, 0x36e674e2, 0xc15efe1c, 0x47da0572, - 0x9f7b7017, 0x5af7b645, 0x219bed29, 0x95b698f5, 0x5cbf1c61, 0x2c9f7772, - 0xb1c4c9d0, 0xa2393a66, 0xde9195d3, 0x8dd6ed94, 0xf0249e75, 0xfe86d283, - 0x3bd4de7c, 0x0277ab8b, 0xb047cf9f, 0xeab259fc, 0x618693c7, 0x7bc42f7e, - 0x9333c280, 0xa83fb3b7, 0x4ff661b4, 0xb4be843e, 0x2bdfc9d5, 0x59f5b5b2, - 0xf715ff90, 0xa1f49ddc, 0x7b01c674, 0x9ad7b512, 0x957f9ca6, 0xedbec9d2, - 0x989e40ef, 0xfae55d3c, 0x3fb48593, 0xce39068b, 0xd6e7df24, 0xd26fea24, - 0x69c38528, 0xa95d3a8e, 0xa40fc1b7, 0x2ca9f7e3, 0xe47f9745, 0x5592813d, - 0x73d2b27d, 0xc9213fe1, 0xfd390bb8, 0x18fea353, 0xa5e40365, 0xfee4e3be, - 0x1fa3ea33, 0x4b3a7bf4, 0xd5bf55ca, 0x09e462e1, 0x7cbf5cae, 0x8cd1d875, - 0x40b6a468, 0xfde9a536, 0x7584bec7, 0xe3174c4e, 0x77ee03d7, 0xcf1362aa, - 0xf984adb7, 0x1b965442, 0x4291abf4, 0xd6e3facd, 0x8f27ccfe, 0x7a3b698e, - 0x6e8fe537, 0x8ced241e, 0xbe617dba, 0x707cb04b, 0x77e48c74, 0x98239b6d, - 0x5ab88ffe, 0x3da4e2a3, 0x650ded8e, 0xb67c493a, 0xf87efeac, 0xed22cbb9, - 0xcc7e7147, 0xc71a687f, 0x53ad9427, 0x07b86103, 0x6f6cc6b0, 0xded48aa8, - 0xb5087ec6, 0x07da841b, 0xa3a03340, 0xd30a35f2, 0x8f7adf61, 0x9cf9993d, - 0xcafac2e2, 0x70fd0323, 0x9c7b940e, 0x857cc71c, 0x826be0fd, 0xb9d870fb, - 0xb5890705, 0x009f6b67, 0x258d254e, 0xe446efac, 0xfabfcc6a, 0xec1704aa, - 0x26fe9d17, 0xbe0b5ec2, 0xc64d6d64, 0x9655fcbe, 0x3130f19b, 0xc91595ce, - 0xfbe4ed74, 0xae6d4711, 0xe8efcc2c, 0xe705a74a, 0x9215c4ed, 0x39df69be, - 0x1ee18f70, 0x3f0708ab, 0xfb259ad8, 0x5adcb39d, 0xbdf291bc, 0x151ac21d, - 0x67cafa07, 0x5fd85efa, 0x75e62dfb, 0x046217ea, 0x35b289e4, 0x74bce56b, - 0x96d610fa, 0xe71a78c2, 0x02b4e6d4, 0xe43a01d8, 0xdb63fedb, 0xba0ec701, - 0x3d30ae98, 0xc10e7ad0, 0xbfde9c8e, 0xe9ca32f4, 0xcbd03efb, 0x7e81b1c4, - 0x522f1b88, 0xb6be38ab, 0xe078493d, 0x6d176c77, 0x93b48f2c, 0x67be023c, - 0x9f8319f0, 0x1d785d10, 0xdef89d89, 0x22534752, 0xceb5be1e, 0x75b3e9c1, - 0x7825612e, 0xe24bab6f, 0x6e750bfc, 0x72ea9b4e, 0x758bfbf8, 0xa8efce1e, - 0x97f9c11b, 0xdf9cbceb, 0xd3813755, 0xf98aeb57, 0x08afc1bb, 0x0c97cc3e, - 0x27f063be, 0x3e0cbe83, 0x73574a15, 0x17b8cc09, 0x1f99ed41, 0xeb107c1a, - 0xf27414b0, 0xe9cf0327, 0x092fb14a, 0xceb450fc, 0x5228ff06, 0x0aff3dcf, - 0x22bdb9c1, 0xed22ed92, 0xf6c1f242, 0x079f0748, 0x0bb176a9, 0xdbfa89f6, - 0x0eef47bc, 0xad6f873a, 0x88358450, 0xc4bc7f8e, 0x7441ac29, 0xac596f3c, - 0xd9673f29, 0xa4f46ffb, 0xd18ddffe, 0x1e69b372, 0xe2797e47, 0xf7d13ff1, - 0x4cf2fcdf, 0xf34ef026, 0xc608fcd8, 0x9f5c2bbd, 0xd79cab47, 0x9796765d, - 0x7d4b86fa, 0xd4b86fab, 0x08e3f0b7, 0xa23dcf8a, 0x2d24a3e3, 0xb1a79df6, - 0x9baeec6f, 0xb44ec047, 0xfa4bde52, 0xf2a3f804, 0x2bf8e8bf, 0x70c6165d, - 0xf7d06d2d, 0x36dc706b, 0xb258f5c1, 0xf14ef960, 0xd7bf010a, 0x03d85fb1, - 0x63882b24, 0x40afc38a, 0x6be52276, 0xab98ec0e, 0xe411f77f, 0x21d96576, - 0x4735b396, 0x087fc724, 0x705ced9f, 0x83b2ca7f, 0xf6b44f5c, 0x466fc536, - 0xc1daf50c, 0xc0e34037, 0x7ece695f, 0x1a2efd81, 0x547fbe15, 0x5f2f7fae, - 0xa2e298ad, 0xf2ab6467, 0x959645de, 0x4259f3d3, 0xf91a473f, 0x96e832bc, - 0x61c708f8, 0xdbe63796, 0xe7f10417, 0x597bfd52, 0xa714c58e, 0x9d967f79, - 0xcd8f39fb, 0x9bdefd49, 0xcf9f6e93, 0xf7cdcffc, 0xa5fa8c05, 0x60ab0539, - 0x835d2e4f, 0xf6cea6a8, 0x7d56d925, 0x7fa92e5e, 0x8b5ce839, 0x2ea2f8e2, - 0x9e4307cf, 0x475f8539, 0xef59fcf2, 0xb9e17caa, 0xac8fe017, 0x9f1873fc, - 0x75839553, 0x7fae4afb, 0x839634f8, 0x70ca91bc, 0xff12e1c8, 0x35fdcf85, - 0xb55d711a, 0x97bda43b, 0x6b48a3d2, 0xfb60aaee, 0xf6878d5e, 0xadf81c49, - 0xfaffefd9, 0xfbe67f0b, 0x14b0849d, 0xe3986e3d, 0x7c766ad4, 0xb06bf1ca, - 0x7286f9c7, 0x1d5f1c7f, 0xf956beda, 0x4257f59a, 0x68a7c32c, 0x3c8997cf, - 0x12979d8f, 0xf76ae7c1, 0x2aec4cac, 0x1fb4288e, 0xb0c1ce23, 0x358ad5ff, - 0x59cfc39f, 0x9384d77b, 0xff65de92, 0xca1eeda1, 0x31384a8e, 0xeec62050, - 0x5893b62a, 0x2c9fc705, 0xed38edd5, 0x63f64cfe, 0xd7772777, 0x2446a7ae, - 0xdd5bb592, 0xbeb38831, 0xae84c428, 0xb649f4f0, 0xd3cf6b94, 0xfb3f823e, - 0xe59536e2, 0xa2db8bca, 0x6cd43f78, 0xe220f07b, 0x529e6b04, 0x2d58edd8, - 0xafce385a, 0x1c2a8766, 0xec1de7c1, 0xcfddf147, 0x5173f173, 0x8b5f404b, - 0x66ef149a, 0xc3bb4f9a, 0x6823d31d, 0xbe80af3e, 0x87173488, 0xff470d35, - 0x079ffcc6, 0x37920b7f, 0xc83f3517, 0xef548df1, 0xbf37cb02, 0x3c38e08d, - 0xc1dec93a, 0x186ecf3c, 0x45f5fec2, 0x586bdb4d, 0xe116d83e, 0x8ce9e982, - 0xe40f7ccd, 0x81de3e80, 0x9c8f296c, 0x67d1edd5, 0x1f59505f, 0x2fb13cc2, - 0xb871e8cf, 0xf537bb46, 0x4b666f76, 0x5b26a7f9, 0xfea34fee, 0xd1a3a6a2, - 0xc9fea8fd, 0xfa73ef5d, 0x166fbebe, 0x3df0b645, 0x223b93cf, 0xc9e09ef8, - 0xfe39ff1d, 0x7cef1a35, 0x250498d3, 0xc89d9f68, 0xba7dc9b6, 0xf32fc641, - 0x13d61725, 0x673d789a, 0xac28a5b7, 0xa4de032f, 0xf1dd9fb7, 0x3643df12, - 0x1c1febe4, 0xb14b382f, 0x18a3dc86, 0x8d72083d, 0xd7bf55a3, 0x63dba6d1, - 0xaffa6ffe, 0x5927bfd1, 0xe471f58a, 0xc4610d3d, 0xbd64b86f, 0x27b73522, - 0xc1dcddf6, 0x97b899ee, 0x7192de2d, 0xfbb7a297, 0x737fe811, 0xbb678ddf, - 0xbb9b52cb, 0x1c5ff227, 0xe0958526, 0xce887733, 0x875a9257, 0x347bbec1, - 0x8615ca4d, 0xb56aad3f, 0xbf04bc22, 0x3e67445e, 0xd0aafde4, 0x49c90760, - 0x563d7c67, 0x71daf161, 0x99d9463e, 0x3bb7ea2e, 0x75bec137, 0xec7c2ec4, - 0x29d17b7f, 0xd2e927fd, 0xf618f20f, 0x7155a517, 0xd878ac81, 0xa9ba74f1, - 0x41e54a9a, 0x29b553f4, 0xea390590, 0x2bda5d9c, 0xa9fd0e51, 0xabd640aa, - 0xfd14e9d7, 0x69a3dfa0, 0xf72c0bae, 0xd0128cee, 0x44af2c3f, 0xd3c8bb49, - 0x41614dce, 0x1cbf76e7, 0xc777118b, 0x66df4afe, 0x0bcc3f39, 0x7b22fcf2, - 0x5de41663, 0xd145dc63, 0x39de3c8d, 0xe145bc7d, 0xa39fd28d, 0x3ea211c7, - 0xec136f8f, 0x267b6a77, 0x33e6e58c, 0x632f2dc9, 0xf4cf33fc, 0xa387b8e7, - 0xbb05fe69, 0xf1c9dcb8, 0x86cf95e7, 0xd3df3005, 0x5db144cf, 0xca4db4eb, - 0x12a3a763, 0x143b1e59, 0xf65cf0f5, 0xa6153d63, 0x5a742ec0, 0x9424f611, - 0xf2c1ee6f, 0x32dd6540, 0x1254d7f6, 0x4b1c817b, 0x7fc804e9, 0x67f737a7, - 0x37e9d17b, 0x415cbe55, 0xbbe357df, 0xfee71a26, 0x0880f58c, 0x799e23b6, - 0x83fd6ff6, 0x5a463bfd, 0x3ed994f9, 0x5183d066, 0xf923945e, 0xd48e5160, - 0x71c86e53, 0xd11d5a71, 0xaf3a70f4, 0xc207f253, 0xb481eb03, 0xef61131f, - 0x3bb4d23f, 0x9c048951, 0x09ff5903, 0xfa956fb8, 0x366d99d6, 0xbe5553f6, - 0x3b65e512, 0xf157ddd4, 0x554ac97d, 0x1695e3ca, 0xf950df79, 0xffb656e5, - 0x2ce33fd4, 0xde083c00, 0x6db6dfac, 0xe471f556, 0xf4b7a7b8, 0x808d7e91, - 0x10797f9e, 0xc62635fb, 0x59537989, 0x0790dace, 0x2a7a5eb8, 0x69fee382, - 0x34e22f1c, 0x73f67f2a, 0x0598cf09, 0xc1d027ac, 0x4ab9fccd, 0x77d5cfe7, - 0xfb83135f, 0x955de210, 0xb25c79ef, 0xff827a7a, 0xd1ebc286, 0xbf3f9d1c, - 0x83f338fc, 0x8837da2a, 0xfbac5b0f, 0xab3f1713, 0x78b95cb0, 0x308f35d5, - 0x26c77ddf, 0x5ce22f70, 0xc1d183d3, 0x91cfa8f8, 0xbdb3b0fc, 0xa62feb87, - 0x5bfdb2fa, 0x2d9f3cd1, 0x13e60f36, 0xddefc78a, 0x07f559fe, 0x226cafb5, - 0xcaef22f9, 0x2d125ff5, 0xf833fd3f, 0xfb2736cb, 0x7cff0951, 0xadacea3f, - 0x7fd60169, 0xf32779f6, 0x72b1b39d, 0xf3a49fdf, 0xf98d97d4, 0xb66bf4dc, - 0x9a61fccb, 0xd0b439c0, 0x98d7ee6f, 0x9b1cead7, 0x4f78b7a4, 0xd544fc0c, - 0x47f40f84, 0xb711f9f8, 0xedc6d77f, 0x40b3d743, 0x4fb1d76f, 0xba608f9f, - 0xe24bdb39, 0xd90bece5, 0x8d1d9e7c, 0xf34ef495, 0x74de854d, 0xb8a65636, - 0xa87a0499, 0x387a4974, 0xed89a63b, 0xed956702, 0xc9b51e9c, 0x74cb9576, - 0x5fd13b7f, 0xb407e812, 0x63aabb09, 0x19e40b4d, 0x05e1f9f0, 0x4f70069c, - 0x0e8ed43b, 0xd7f9c53a, 0xe333efaa, 0xebf6051d, 0x89a79fb0, 0xba6bc7ef, - 0xedb5593c, 0xf0257f4a, 0x614db554, 0x197fda7f, 0x13acd0fd, 0xd1003f0c, - 0xc29f62e5, 0x6e2c22ef, 0xfb116db8, 0xbdac96d3, 0xac6f7415, 0x6f7eb163, - 0xf2a2a8fc, 0x693a8e7c, 0x395ee4ff, 0xdfdf019e, 0xef1d28e7, 0xf38cb875, - 0x3bf0f68b, 0x47496e39, 0xfea46d94, 0x35941aaa, 0xa19a4e3c, 0x19f5cae7, - 0xd8b02270, 0xaa3be761, 0x6eeed3df, 0xbb3cc6fd, 0x9d31cf9b, 0x934d1fcf, - 0xdedb93f7, 0x2fccf796, 0x26243d7d, 0x41e45bee, 0xf46061be, 0xd063b887, - 0x22f3f520, 0x35f61cf8, 0xcf34ebec, 0xff660dac, 0xe653ce4e, 0xe66d80fc, - 0x730eee7c, 0x9cd9af3e, 0xce6ebcf7, 0x0ee309ff, 0xf41384eb, 0x4235c46f, - 0xfd0a46ff, 0xf5261ddb, 0x7fa1e46f, 0x8dfe8523, 0x91bfd0ef, 0x3c8dfe87, - 0xa1e46ff4, 0xfe85237f, 0xfeeeef8d, 0xba554e12, 0xe07814bd, 0x4eddbab8, - 0xf7813e23, 0x89d9c5cb, 0x558547cc, 0x1717a5ea, 0xd8fcb2e5, 0xe29a6f61, - 0x11937b60, 0xad18958f, 0x1c47f785, 0x2ab2d280, 0xb1db8d39, 0x55f6ba1d, - 0x2aae8769, 0xeec24670, 0xe4f2bad1, 0xa73d882a, 0xd418b4a3, 0xdb6b68bf, - 0x2f56f802, 0xff7ec03b, 0x77eee5d6, 0x63f893af, 0x5f118bfb, 0x0f738255, - 0x25f49b7c, 0x71ee7719, 0x4353db04, 0x4d6244fd, 0xd3f21e50, 0xd43e733a, - 0xe6be042f, 0x46abed35, 0x6c6fc7c6, 0xfbe0c96d, 0xe0e33e9f, 0xea9f69fb, - 0xcb313bf6, 0x2198f2c1, 0x1bce23cf, 0x9f7a5970, 0x95e709b2, 0xc31c7fa7, - 0xa650fdb9, 0x68617ee9, 0x0879765a, 0xf91df3cb, 0xe3058a35, 0xbe5f4f94, - 0xcd6af58f, 0xedd2e7cb, 0xd7b2dcfa, 0xeef34c5b, 0xd1370fef, 0x71adc0d1, - 0x5ecc7e21, 0x7783faa6, 0x31f887a5, 0xa7ca9807, 0xbe6219ad, 0x8d7c5f8f, - 0xbdafbca9, 0xa1cf6e23, 0xfce4b9fb, 0xa5ceb25c, 0x6f5e02c8, 0xc554bd68, - 0x6ff827f3, 0x4e52dbc5, 0xc673a72d, 0x2bbfaf1b, 0x9d7f0052, 0x57e03277, - 0x858b64d1, 0x3f4cad9d, 0xf332c487, 0x15615cb9, 0x275c573e, 0x84b855dd, - 0x7fda9637, 0x654c6d69, 0x47e5fa3a, 0x68812aa9, 0x3c9680d1, 0xde8bafe8, - 0xe838727c, 0x98dd5aaa, 0x3bf2a2ea, 0x5c16ff14, 0xb7133f20, 0x9524713d, - 0x495aa927, 0xaa73c27f, 0x1cff702d, 0x19edd1f0, 0x7ca4ef02, 0x68a5e6ba, - 0xe9d41f8e, 0x0ae6d52f, 0x6c6c1d07, 0x814f5954, 0xeb8d4cfd, 0x8d8d93a4, - 0x6bd0e1f1, 0x3e28c62a, 0x5c06c7c8, 0x8508fa0c, 0xefefc907, 0x97bd69ba, - 0x94f7c90e, 0x752e758c, 0x41a2fac9, 0x07de37b6, 0x5c7bd630, 0x372b47d7, - 0x3b7591be, 0x7fd73f7d, 0x7e1b9e5f, 0xbc5dbadc, 0x6d96c5ee, 0x7d29925b, - 0x85dda1c7, 0x7b7d2d75, 0x1a48f45c, 0x326dcbe7, 0x75b3fdae, 0x23e13e4f, - 0xe3777a7e, 0x0fe87693, 0x9dbf5695, 0x6679cddf, 0x0ef11da3, 0xc8dd6fd7, - 0x2d6c17df, 0x71807b61, 0x1194eecf, 0xa3c3ad97, 0xc1b2ac62, 0xde3ceb45, - 0x1585ca5f, 0xa69e32e1, 0x46f51d48, 0x55b5d602, 0xa6bac7c9, 0xe3b76f17, - 0xf58781fd, 0xa6fba17a, 0xa2b4f0fd, 0x357bb01e, 0xd4c71c29, 0x11993edd, - 0x64fbcfe8, 0x4e34e5da, 0xc81e5fa7, 0x8287de7a, 0x239c2fb4, 0xf5fa21b9, - 0xf5da5561, 0x4ef9559a, 0x30903d98, 0x5ec2f20d, 0x35456ef9, 0x0a23439d, - 0x710bb7a0, 0xa3c5a535, 0xd79d1354, 0xf6984616, 0xb4112cc1, 0x9bbfa8af, - 0x7e532f45, 0x530cc4fa, 0x07d399fd, 0x0b9df886, 0x7f99cb3a, 0x8f7a6d5d, - 0x9f2efaa6, 0xc7bb615b, 0x4a77f358, 0xbb3a62ef, 0x5abed4d1, 0x47bd354c, - 0xf7a9e8b3, 0x6544ce18, 0x54e1c476, 0x6658f7e8, 0xeff54769, 0x169dfcad, - 0x7dafda62, 0x927f3c33, 0xfd8da5e7, 0x7d3d8609, 0xe8cf7e16, 0xef0cbcea, - 0xbc451788, 0x9a1dec30, 0x61691e59, 0x3c48553d, 0xa8f6eb54, 0x8f691cea, - 0xd8b5f6aa, 0xf04d8f11, 0x4810a6b7, 0xb6151a6a, 0x477d5237, 0xdfcc9c4a, - 0xcc3bef85, 0xdfd052f7, 0x521f9465, 0x42bfb04b, 0xdd686bcb, 0x606a1738, - 0xd83b6247, 0x076c9384, 0xfbd1c633, 0xf434e837, 0xfed0807d, 0x33700c06, - 0xbadcaeff, 0x822f60fd, 0xd8e2b4cf, 0x549dc47c, 0x95b14d35, 0x6f495ee4, - 0x54bfff06, 0x7ebf6161, 0x4c03e1fb, 0x5615ed6f, 0xff4b8c8f, 0x78d4b876, - 0x9435dda5, 0xbad0170e, 0xb05e7fe0, 0x15f8f143, 0xe9f00f59, 0x810cfa05, - 0x70174a4f, 0x01d5e033, 0x7e7290bf, 0xe2286e3f, 0x0a7be426, 0x1425c057, - 0x0b38fa9e, 0x2772c134, 0xf3cfcbcd, 0x8c57e90a, 0xb78fdd08, 0xb0ffd9db, - 0xe52e1141, 0xf531e1bb, 0xf4e3b4b2, 0x6feb90cd, 0x2078a9db, 0xd97cdfbf, - 0xe83bdfca, 0xd9c658a7, 0xde689f4f, 0x54f41daf, 0x8ccff72c, 0xeedc89cb, - 0xdf5745df, 0xff864f45, 0xdd7e3426, 0x19e647b8, 0x1ab7dfa0, 0xf37d8626, - 0x1be1c44f, 0xe77741f2, 0xe439c74c, 0x9910f1d2, 0xbcf9e5de, 0xe39d2a34, - 0xbedd35cc, 0x4d69f068, 0x5b8c676f, 0x78eee542, 0x7e6f7bd0, 0x43557167, - 0xfbf06a46, 0x1b4ada37, 0x975381db, 0xe25a73c7, 0x7ce22574, 0xdf2e5929, - 0x4f763969, 0x29f844cf, 0x25b4ad8e, 0x8faea44c, 0x553439dd, 0x88be420c, - 0x86d74fd3, 0xcfb60acd, 0x032de91b, 0x9c61f9e4, 0x872de7ef, 0x3f6167a3, - 0x8d19dcae, 0x2bc5a190, 0xa2ee1fdf, 0xa2d9be73, 0xfec01a2d, 0xce7c8de0, - 0x3cc6d70b, 0x390ce7d8, 0x516572a3, 0x5503c84f, 0x04f038ff, 0xb96d01e4, - 0xea72112d, 0x81540fe9, 0xe73a1ad0, 0xe538be58, 0x6a7df494, 0xabdf0473, - 0x2f08a53c, 0xd48b51fc, 0xd32e797d, 0x337cdb79, 0xd2708fc6, 0xae30c3b8, - 0xc6124b7f, 0x30b2f8f5, 0x333cb6ae, 0x8bbb2ba6, 0x97aed691, 0xc316dff2, - 0xa3dbacce, 0x0f23f721, 0x4b645fb9, 0xc8791fb9, 0xf72148fd, 0xfc0d7be3, - 0xd71bf00e, 0x6f43e5b7, 0x39158df5, 0x8e1cf84b, 0x7f5c81cc, 0x01ee12bb, - 0xf15dba3f, 0x8478e4f4, 0xf9e5620f, 0x2357821b, 0xb246dd1d, 0x5edd1059, - 0x8221d977, 0x88c6ebe3, 0x9c7e5358, 0xbf54d923, 0x2a6695c8, 0xbfa93ebf, - 0x7706fca9, 0x537f29be, 0xfd5348ce, 0xa6319e49, 0xdc468ffc, 0xc53faa60, - 0x9f94c53b, 0xa9b66136, 0x12e28cfe, 0x59ccf953, 0xb3e54c8b, 0xf94cdbb5, - 0x34ee2b5b, 0x92f1ffd5, 0xaf72a6e5, 0x0e715970, 0x231f4336, 0x3e85efb8, - 0x6fede946, 0xe3064667, 0x4b38d475, 0x350cef97, 0x56fa900d, 0x39f7ae74, - 0x09ee25d0, 0xe8fb0e81, 0xe2f680f7, 0xbf06199c, 0xfa914065, 0xe8324b70, - 0x685eb426, 0xfd88a8f9, 0x6594f097, 0x9f6ee7ff, 0x313e2561, 0x43fdaaea, - 0xfb7f2832, 0x5619e6c0, 0xaea32fe2, 0x3a52ffd9, 0xdcf17fe5, 0xf07cb237, - 0x57284bfe, 0xfccbf772, 0xc822c134, 0x9bce06af, 0x8c75a3e1, 0x8d7d2eba, - 0xba53da47, 0x5235538c, 0x9d7101c0, 0x00d20380, 0xfdd227d1, 0x5f489f44, - 0xb72cfa27, 0xe8907109, 0xd221e913, 0xf7fdf14b, 0x3d2297a4, 0xd2297a4c, - 0x452f4877, 0x297a42da, 0xcdd43fd2, 0x3a83f4e2, 0xb1fddb8d, 0x8fd382ae, - 0xf7f096ea, 0x7196ea4f, 0x1f3a97fa, 0x8064ff7f, 0xb0087f61, 0x8bf0c69d, - 0x091fc0d5, 0xdb2ede7b, 0xb1bf60b9, 0xabe795e2, 0x5facc7e1, 0xb0235a22, - 0xb1ad5b4f, 0xfe9d1c27, 0xadf9eec9, 0x92089c55, 0xdee19ccb, 0xf8f006cf, - 0xb7cc5dbd, 0xc447eff5, 0x84053eb4, 0xb5d34fa7, 0x3307e0b3, 0xc656ca0a, - 0xeeb8ff10, 0xd03625eb, 0xae9687cb, 0xd5efa3ef, 0x03a7dbf9, 0xf7e86dbd, - 0xa65dfd5a, 0xae321d6b, 0x6b6b5af0, 0xbfdbdb3d, 0x03c46e14, 0xefec33ed, - 0x5ef958f7, 0xe085f2b1, 0xc104e8fc, 0x5b2ffaf9, 0x5af10e38, 0xcf892797, - 0xc46f3d1d, 0xfdf87505, 0xef1413f1, 0x8de1f863, 0x2fc29f78, 0x3e41c75a, - 0x77691d18, 0x0dc48587, 0x2fbedfc0, 0xbcc68fea, 0xc3277df8, 0x97d4ffbf, - 0xf2f78022, 0xb5fe3f0c, 0xd834968e, 0xe1df4615, 0x33c704f0, 0xe57afe19, - 0xe715168b, 0x64af1189, 0x3bcc638c, 0x15fd4aca, 0x5d23c674, 0x47ca6aeb, - 0x757d465c, 0x93d7f724, 0x49dde3be, 0xb955e7aa, 0xec3e535d, 0x22aba3c7, - 0x8ce9423d, 0xafa9e813, 0x3af1ea9b, 0x38d0bf0b, 0x1eb4624e, 0x1c7e8127, - 0x01df9cb2, 0x48109d1c, 0xa39ffbc6, 0xb03dd897, 0xb88e3e83, 0xb8ce82b3, - 0x088fd405, 0x2798c7da, 0x15f7edfa, 0xbcf217cd, 0x9df0cbd7, 0x29f492e6, - 0x3f5e7adc, 0x2c6385af, 0x3d54bbdb, 0xfae61c5f, 0xcfd1046b, 0x90da19ad, - 0x1fdfd481, 0x7ccc8c94, 0x7a3217d6, 0x094fdf60, 0x0bb04779, 0xf03119fa, - 0xbc7e84ff, 0x05bdef12, 0xe942e1db, 0x418fc0c8, 0xbbde064f, 0x0e832ba3, - 0x18d0e282, 0x65711def, 0xf4a17f7a, 0x199d1dd6, 0x43ad75f4, 0x8cf001d2, - 0xae8320f8, 0xf89a2f94, 0x2ae8eb1e, 0x067f9f07, 0xc5d2855d, 0xe9257495, - 0x0e27feb4, 0xba4aefee, 0xc007a4ea, 0x55d387e5, 0xf8f38a8b, 0x79a7a59f, - 0xee3c626d, 0x765c97ff, 0xabda441f, 0x7c17b69f, 0x198c4ca6, 0x2e13120f, - 0x62ec1075, 0xba32f5a1, 0x7f4a17a9, 0xbc6eeda1, 0x6e465da2, 0xfa71bb70, - 0xaeda1959, 0x047aed12, 0x71c21bb7, 0xf7e96f11, 0x1a72de08, 0x999e2d71, - 0xb90e5390, 0x2f2df26d, 0x27cc8de1, 0xf3a719ba, 0x096243f3, 0xee24bf9f, - 0x854f40fa, 0xcb8d693a, 0x42fac85d, 0x71d76461, 0xedea3705, 0xdc5d7fc7, - 0x4f8cf980, 0x37e3cb30, 0xf5fcf2ea, 0x0ffb91a2, 0xc6e1477d, 0xce59ebdc, - 0x61477d0f, 0xfe3d40f3, 0x81a44d20, 0x8f0a17df, 0x0efe9f9c, 0xcfbea146, - 0xc9ba7453, 0x5462ab70, 0x6a9bee1c, 0xaf321c56, 0x3c8c1de3, 0xfce3eb8c, - 0xe9cfc20d, 0xfdc0224d, 0x0903a24c, 0x61091ff9, 0xc85fef93, 0xaa35bafb, - 0x5790dff6, 0x4fba7b8d, 0xb057b53b, 0x4c440fcf, 0x4a77839e, 0xd7190dc6, - 0x17f6ed0f, 0xdbce59ba, 0xb960c8ef, 0x16d2fb13, 0xde27c9d7, 0x5fba73a4, - 0x8a37bca6, 0xfb46f714, 0x3bfa79d1, 0xbf91c73a, 0x40b96731, 0x736ef1bb, - 0xfed193bc, 0x6138d726, 0x9cfeef8d, 0x776f29bc, 0xdecdd86f, 0x042ecd8a, - 0xbd8adf7e, 0x7deb10aa, 0x45a7b62b, 0x4e7661a6, 0xafd2bd07, 0xa0d8b92b, - 0xc6f1cefb, 0xc1dd78f3, 0x286b80d9, 0xff380d3c, 0xeb1eb800, 0x077bae0a, - 0xaa379608, 0xad5f2423, 0xd57c908e, 0x58757380, 0x9ede7dc7, 0x5527f1c1, - 0xf9af090e, 0x5611aecb, 0x2c17f512, 0x93f9c91b, 0xb807c275, 0x6092c69f, - 0xf7b10f10, 0xce58eb09, 0x9ddcef1b, 0xe8bdf87d, 0x2ae79a24, 0x983ff687, - 0x4082b9df, 0xe2844916, 0xbe7a86e4, 0x05fe7f8f, 0xaa7d03d5, 0xf1af754a, - 0x96facec0, 0x7d71ef2a, 0xfe15207d, 0xd754f158, 0x0e55e8f1, 0x9f435f09, - 0x98afd21c, 0x5fb1adf7, 0x80befe85, 0x0ef55f21, 0xc6dcf193, 0xe4eef73d, - 0x92e1e1ad, 0x930ef5af, 0xebc0d8fc, 0xee7ebb06, 0x89c33f53, 0x3afca68f, - 0x98abf59c, 0x2e4c6f58, 0xc28583ec, 0x76189fa4, 0xf904f695, 0x22b5ca7e, - 0x945191eb, 0x13643c2f, 0x076f2a7e, 0x92794043, 0x1fb6b3f4, 0xef82a4ba, - 0xfc294517, 0x6f71863e, 0x22c92c29, 0xc27c41dc, 0xbd370ee9, 0x13911b4b, - 0x7947ca67, 0xc7ea997a, 0x9537488c, 0x98077ac7, 0x1427e3ca, 0x8a3df298, - 0xefd536af, 0x29ac6b39, 0x68ddac9f, 0x31529faa, 0xf83794d5, 0x24fc8a58, - 0xc5b92cfa, 0xb2efbed4, 0x34fd5352, 0x5ca9a55f, 0x319b3bc5, 0x25b7ab40, - 0x81cf1127, 0xd58c9fca, 0xe3de434b, 0xf0cb08b5, 0xfe6b77ce, 0xcbde5a33, - 0x80b91099, 0x6cc9afdf, 0x9e7999fc, 0x2c6b44ea, 0xcdbbd7a5, 0xc928b17c, - 0xb9171f9c, 0x71df814f, 0x9fcccb9c, 0x4d589653, 0xeae51ff9, 0xe44f34fc, - 0xbbe3ddb1, 0x300daff0, 0x4e143fe1, 0x7efc0f44, 0xef9d3b68, 0xcdebcc3e, - 0x070f7e32, 0x75e0937e, 0x0c126fc0, 0x824df807, 0x049bf0f3, 0x24df87d7, - 0x937e1cb8, 0x8721f2e0, 0xd61ff8cc, 0x55ffc662, 0x6ff1991f, 0x787765d0, - 0xa66ad91a, 0x9a29a10f, 0xba782df2, 0x7e9994e6, 0x1d73f142, 0x09b15b89, - 0x09e287c0, 0xbe387fb8, 0x8be08656, 0x37f7c3f0, 0x31477bdb, 0xd7d71e7e, - 0x20606d75, 0x3a2e97df, 0x6fbc0aa4, 0x71f3ac63, 0x6d3fdcfd, 0x89731ad5, - 0x5dcefccf, 0x763e0490, 0xdb7e909d, 0x4f1655f1, 0x207fba80, 0x29d99c64, - 0x3fa843da, 0xaa52fe2b, 0x26d2741d, 0x0e7bcfdf, 0x95d8797c, 0x123eb2f1, - 0xf6bef84f, 0x27be54cf, 0xa8d2c475, 0x8eaf8f80, 0x9f009ed1, 0x84bb9799, - 0x8a249bd7, 0x5c402fb7, 0xa5857fd4, 0xafb73f22, 0x722dc7bc, 0x89fef95b, - 0xa6e727c1, 0x2da9b8c8, 0xdd7fbab9, 0x9ea7e323, 0x777295c9, 0x71c5c794, - 0xf2b925de, 0x8ba90d7e, 0x010773a9, 0xd99d873e, 0x0b3acf80, 0x8ad9ebbf, - 0x9d09e47b, 0x0f21c8f7, 0xa3ecfe43, 0x1ff57fcb, 0x47581c3b, 0x3a617af6, - 0x1dfbfb7f, 0x81e2f8a6, 0xfca65d5b, 0x5324a6a0, 0xdcbbc1fd, 0x40fcf2a6, - 0xc87ca98e, 0x3f298f21, 0xa98465ac, 0x791f55fe, 0xad91f94d, 0xaff54c13, - 0xca6c5539, 0x47b688a7, 0x8abedf01, 0xcd1c53b4, 0xb9fa974d, 0xe4dc705b, - 0xe563bbdc, 0x7edd5f7d, 0x46fbc861, 0xd3a6b9dc, 0xd11ea875, 0xe8e52ed7, - 0xf52164fa, 0x1fae8746, 0xa13eb30a, 0x1de371e9, 0xe67c58f7, 0x5e2371b8, - 0xd0ef43bc, 0x7b8e8af5, 0xe2f19d34, 0xf178e0de, 0xbf5d61b9, 0xc75e7d1f, - 0xfbfce87b, 0xeb7ae5da, 0xbdf3b4ef, 0xa15e631d, 0x96c949f3, 0xd1d9bb74, - 0xbfaabdf5, 0x46fb4ae5, 0x25f1666b, 0x3613fdd0, 0x6dff2b4f, 0xf3c62b84, - 0xb75e22b4, 0xcf7617fe, 0x8f77f70a, 0x5cb07737, 0x658b1ccf, 0x8e5c94de, - 0xddfd338b, 0x92418884, 0x7583adbe, 0x78c84afb, 0xdc646373, 0xbbb1889a, - 0x8fddbf41, 0x6499e127, 0xff7c0d17, 0xf167bf4b, 0xf74d35e3, 0xbd8e68a1, - 0xce3f7f51, 0x4c3d036f, 0x59f24b1c, 0x5b13c93e, 0x49143d7a, 0xcb13ca72, - 0x8a9f6cac, 0x3757fe7b, 0xde75fafb, 0xfa4be99f, 0xb203e810, 0x07a8f40e, - 0xb72954f2, 0x2beb920c, 0xb8eebf52, 0x187ec0e7, 0x43f3f421, 0x174fbc70, - 0x6874c6f4, 0x75dfe3ac, 0xdba0c1ef, 0xfa193850, 0x3be3d0af, 0xd2f319fb, - 0x07ec67e1, 0xfdc67e03, 0xb66df713, 0x7c914de2, 0xe202658f, 0x6dfc0ce5, - 0xc6f693c9, 0x503c3a05, 0xbba8fc0f, 0x6e6a457a, 0xedf7ec0c, 0xeae31dc2, - 0xea3b0e82, 0x62e09bff, 0xfbbbbfc0, 0x87f1dd6d, 0x5df0be50, 0xa3baddf7, - 0xdef67fd3, 0x909f105b, 0x5e3a4bf1, 0x1c2cfdfc, 0x94777017, 0x323f3f79, - 0x9189f248, 0xe4fdf483, 0xccd6fd23, 0x0ffc042f, 0x9d552bf5, 0xbcf3c85f, - 0xdf98ad24, 0x8af9c6af, 0x37f35bfb, 0x8847f94a, 0x87abc4e2, 0xe36f8fc2, - 0x7ad7cbfb, 0x4a6ddb05, 0xde3f151b, 0x75f12af9, 0x9fb30fad, 0x0772cdcf, - 0x26c83bbf, 0x46576a4d, 0x5da5f6ed, 0xc2facef9, 0x60eef948, 0x0beafbe8, - 0x2f19bd75, 0x86df606a, 0x19eebdfa, 0x3cb1fba4, 0x9cf2c3c2, 0xa150d71e, - 0x37a0e9d7, 0x0e6f7cbf, 0x31f6327a, 0x671f1ca5, 0x3f0dcdc0, 0x3cce90d4, - 0x073c37c1, 0xb58379e7, 0x0ec5f8cb, 0xab7e1af8, 0x61ecbf0e, 0x1a1127be, - 0x77ce718f, 0x3f2bba20, 0xeb1fe198, 0xf8741f6e, 0xefc3bec7, 0x89691ed6, - 0x69f1dfc6, 0x67df26df, 0xfd5bf4e9, 0x22cbb865, 0xf03153fd, 0xfdeab53f, - 0x5d798d89, 0x96d50fdd, 0x9438e4ef, 0x73b68b66, 0x2cefad10, 0x7b778ff5, - 0x9fdc89ef, 0x26117788, 0x2ba976ea, 0xcdcbadd7, 0x8fe914a3, 0xef8ca9f6, - 0x5ef209f6, 0x8151f13d, 0x4fc4677d, 0x0481114c, 0x4a1f86a4, 0xe1923d5b, - 0x4aa1f86f, 0x9e792302, 0xda17ea33, 0xeb68e4f0, 0x851577a3, 0x53fd3bbb, - 0x5c647dad, 0xaa7e7754, 0xb9f39769, 0xaf97e9bf, 0x183e7ee1, 0xb6e52694, - 0x036efb86, 0x2ad80d9d, 0xab67586c, 0x4bbfebad, 0xabf3a851, 0x3d9ae812, - 0x96ade282, 0x962fbc2b, 0xbf88c22a, 0xe46f3e62, 0xf9ea352f, 0x7dbf9922, - 0xeab7cca5, 0xd16da7ef, 0x275820ed, 0x7a07ac52, 0x4edd36f9, 0xc5207582, - 0x7c1df03a, 0x35f0790d, 0x90d7c1e4, 0x0a435f07, 0xa5ef86be, 0x761538a2, - 0x0ad3f85b, 0xfc07f683, 0x72418569, 0xc169fc13, 0x82d3f879, 0x169fc3eb, - 0x5a7f0e5c, 0x69fc3970, 0xd3f879c1, 0x9fc3eb82, 0x3f879c16, 0xfc3eb82d, - 0xf879c169, 0xc3eb82d3, 0x0e5c169f, 0x39705a7f, 0x79c169fc, 0xeb82d3f8, - 0x5c169fc3, 0x62996f3e, 0xd3cdb7f2, 0x5b287fdf, 0x51f4cf1f, 0x9b1c5198, - 0xeffdf847, 0xc4fc7f88, 0x373c0e96, 0x2edd022f, 0x48f70ead, 0x904e373c, - 0x8908b778, 0x8cd9b6e7, 0x32ecbbe7, 0xb4e3245f, 0x7e07e943, 0xf49b42ab, - 0xdf85215b, 0x56fc290a, 0x2ab7e148, 0x2b7e94cc, 0xe15bf0a4, 0x4856fc3b, - 0x0a42b7e1, 0xf85215bf, 0x6fc290ad, 0x2b7e1485, 0x0adf83b4, 0xf856fc29, - 0x5215bf0e, 0xfdf0adf8, 0xfe03cd08, 0x905e632b, 0xf499fbf3, 0x9343a252, - 0xe532ea5e, 0xd707e721, 0x5c1f9c87, 0xb83f390e, 0x707e721c, 0x707e721e, - 0xc1f9c87d, 0xdc8349f9, 0xef20bfbc, 0xbc83b707, 0xd41f9c1f, 0xb6037be8, - 0x2e1b49ab, 0x35b48ebc, 0x7142794a, 0x2f353109, 0x8bfc2673, 0x35254ead, - 0x6d8423d6, 0x859980f9, 0x38f4d794, 0x66d13cc7, 0xae39be01, 0x05a6f080, - 0x0f65c704, 0x5cc97ffa, 0xf9b3f86e, 0xbf9ef087, 0x50deb043, 0x35afdfa3, - 0x4b847bda, 0xefd46a45, 0x2f5d77cc, 0x1ea37c74, 0x79a0cbf3, 0x8f996290, - 0xbbfc9378, 0xaf700b22, 0x91458b60, 0x642bb8f1, 0x5d28743c, 0xe793caad, - 0xf6cb16fb, 0x5388e1fd, 0xb83c5129, 0x156591ef, 0x80056c87, 0x7e0292d3, - 0x562f2af7, 0xab92d75f, 0xcc658711, 0x124bb0db, 0x867be09f, 0xbd84daa3, - 0xfd19c69c, 0xefe3b085, 0x4bb44c73, 0xa0ed0279, 0x29f40e6f, 0xf4414dde, - 0x9e4f2cbd, 0xb6ef9a7b, 0xfbe9cbab, 0xae4b6dc0, 0x89c5fdc6, 0xd3ddb2e1, - 0x386689bf, 0xf8506e4e, 0x6da8ce9e, 0xc9fb8bc2, 0x3a7e75cb, 0x5ecb9b70, - 0xf8bae3ce, 0x6fd1a3de, 0xbe5486c9, 0x5a2259a7, 0x450f710b, 0x3df8550c, - 0xb46e037c, 0xbeb1d7be, 0xb02ada2c, 0xfbe0ff2f, 0x7e2e244f, 0xa34ffb9f, - 0x2116c687, 0xcb3450ae, 0x0d2742f7, 0x83d9592d, 0xe5f9a5e6, 0xbfa3a17b, - 0xe706f258, 0x85ef929f, 0xe70cf932, 0x9879f1f9, 0xfdf853ed, 0x8dbec995, - 0xee370496, 0x25b72f65, 0xe136fea2, 0xf5055881, 0x8d8af708, 0x168ae575, - 0xbd01538b, 0x41f10388, 0x639c47f4, 0xdf25e83a, 0x59f7e363, 0x365d58a6, - 0xce431bf0, 0xb1c97129, 0x3151d48b, 0x4432cf7c, 0xd0d4b84e, 0x7e62e383, - 0x3b4e9c78, 0xba5fe7df, 0x8572c9d3, 0xbe615eb6, 0xc65f3e79, 0xf6dd56bb, - 0x7a4b70e1, 0x99ce9c67, 0xbc16ff34, 0x7d267b03, 0x8508f47b, 0x79bd88e5, - 0x0da3d704, 0xcd3df12f, 0xf06f9592, 0x0d4b943d, 0xfbcb450f, 0x52ffd26c, - 0xb0cdc3ae, 0xf1d7cd3b, 0x69c7ae53, 0xef93ab1d, 0xcc39d33a, 0x6a5caeef, - 0x119cb1b0, 0xf21a2f2a, 0x911ef1a7, 0xc23fae10, 0x60d153ce, 0x0bc03be3, - 0x4aac94d7, 0x91ca5712, 0x7339758b, 0xe38d8351, 0xf7f42ab2, 0x6eff42d4, - 0x1e3d62cf, 0xf356f16b, 0x42f24ff7, 0x7de350e4, 0xc94ebd4d, 0xb06607db, - 0xc6c4b43c, 0xcb39cdfe, 0xb6247ca5, 0x93ee3f0b, 0xce3e59cc, 0xe666f782, - 0x947af4ec, 0x5de9e82e, 0xd89a4e5d, 0x4ff864ea, 0xfcc11cb9, 0x14e5ea65, - 0x397cdfce, 0x9799d399, 0xee2adc65, 0x5a6e8122, 0x073be48b, 0xd1f2ebef, - 0xc6b1c40c, 0xc9eb3e43, 0xf44eddf4, 0x74f2218d, 0xabc035be, 0x3878801c, - 0x44ada6d1, 0x8dc4ec9c, 0x4d83ef82, 0xfd451c82, 0x155c82cf, 0x5691fd8f, - 0x2661f7c4, 0x68bf7c28, 0xf4dbd0d2, 0x43fb40fd, 0xf7e13f30, 0x29c2b457, - 0xcd39c47e, 0x805bb6d2, 0x685f637f, 0x5efca3be, 0x629f24ea, 0x9a923bc7, - 0x741b6fae, 0xe63fba1f, 0xb276e846, 0xeb076948, 0xb26193b0, 0xb7c92478, - 0xd3e4266a, 0xf66db0b9, 0x608109d2, 0xcb2b951f, 0xd576fc7b, 0x419206cc, - 0xc9fb55ff, 0xde458b1c, 0x9039233f, 0x96880bef, 0x2f949ea2, 0x4014a359, - 0xf5e6323f, 0x38ec67b9, 0x3a4eb0cf, 0xa7d8ed28, 0xd2e51ef2, 0x7e4d327b, - 0x8cb4d09b, 0x34fd8de0, 0x27f5a637, 0xf468610a, 0x1c2de160, 0x85ebf781, - 0x005428f1, 0xe8b798f1, 0x3bc1eaf9, 0x973ab4ff, 0x91f9c4e1, 0xa6687dbf, - 0xe05ff22f, 0x6b147393, 0x4b1bdff0, 0x0d5768b2, 0x50f7c1ee, 0x11bf03c7, - 0x9efc6db9, 0x4bb64a44, 0x7b10a9f2, 0x8960f54b, 0x4bbb50c7, 0x773cae59, - 0x7a9dd584, 0xdc7bfb2b, 0xd634b76c, 0xbe66cc7d, 0xf3a46be7, 0x5ee7eb07, - 0x9ee7bfdd, 0xf916c3ca, 0x1663c2fe, 0x8857f6ff, 0xd0f72f5e, 0x8fbd6066, - 0xe79ede21, 0x8cfaf1af, 0xf83a4cf7, 0x896efe95, 0x96474f41, 0x2afbe25d, - 0xb77691a5, 0xe54f441a, 0x0fbe15ab, 0xde4cba5a, 0x2b56d6e7, 0x6e845df2, - 0x99bf58ec, 0x9efcbffd, 0x117e6fd5, 0xf8750b2e, 0xbcb7b1ce, 0x84eb48e1, - 0x3d979fef, 0x347c9360, 0x0efb8990, 0xf2712cb7, 0x7b9fd9bb, 0x0f06ab8a, - 0x8c3c9e03, 0xe5d871a7, 0x8c4b7f54, 0x4bdf04b6, 0xd841cb45, 0xfcfee71d, - 0xba8f7e6d, 0xdf8d39b6, 0x95d92cbf, 0xd9ef0abf, 0x7ed1ee7c, 0x4497f582, - 0x4790ecba, 0xf9621a6a, 0x53db9e7c, 0xda2bcfbf, 0xe067cfd8, 0xd2c1bee7, - 0xbe7d778e, 0xaea2e71c, 0x6cc01157, 0xbaf54c53, 0xf61a63b6, 0x4b3b50d1, - 0xdf21bbe8, 0xdd815765, 0x5f641ec4, 0xb632ec35, 0x71b3639c, 0x77b1cfae, - 0xf73ef7fd, 0xf437f3ea, 0x7a1df9da, 0x9ef8ee6d, 0x2ad7ff90, 0xcbd3d82e, - 0x7133dd23, 0x90fca1bf, 0x62b4910d, 0xbe5b9c62, 0x7c8f731f, 0x8ef4a63f, - 0x7367e67c, 0xdc029380, 0xfbc9193b, 0xe94fdcb8, 0xfbf7ee90, 0xf40f6bad, - 0x0a7a0dd9, 0x821df978, 0x1ed79772, 0x951f2417, 0x77a62a35, 0x0bfc8c24, - 0x97c95583, 0xfc00dd48, 0x9a477c7e, 0xcd396f1d, 0xf1093121, 0x27417b99, - 0x51db3ac3, 0x993f8e3d, 0xca0e2e98, 0xfe14bdf7, 0x2f18e4bb, 0x955beff8, - 0xc3df9a36, 0xdf2cfaa0, 0xc51c1aed, 0x68b895fd, 0x5d4869dd, 0x03824f3c, - 0x3eeda9c3, 0xe3cdcfea, 0x02ca3e30, 0x07ec1b7e, 0x42f71073, 0x7e5c5bf9, - 0x6d29c61b, 0x68d4ef90, 0xda38e46b, 0x20fb58ea, 0x975607c8, 0x5cb04fbd, - 0xbddf20d8, 0xddffa39e, 0xcb2f9a11, 0x2704e5cd, 0xee33b3dc, 0xabc286dd, - 0x797f9f44, 0xce59ac63, 0x036b5c6c, 0xf377667e, 0xdd39c65e, 0x30da5d0e, - 0x2837df86, 0xbef97ab7, 0xfbc3a68a, 0xf79cdbb3, 0x7b325fc2, 0x34b623dd, - 0xb065ffca, 0xe9cf6b94, 0x7a6271fb, 0xa9df9320, 0xf1c9cdba, 0x8d5db3e3, - 0x780edebc, 0x81f0443f, 0x662ae2dc, 0xf89d1378, 0xbe596f10, 0xcedf8cce, - 0x77c944f9, 0xf095d7fc, 0xd5605bfe, 0x79e0aeec, 0x8997dfac, 0xb4d9a1f8, - 0x970ef1ef, 0x1f7c6970, 0x3343c4f6, 0x6205eff9, 0xe6cf1c9e, 0xbbc78f71, - 0x4c374453, 0x18fd06d7, 0xf18df3f7, 0xb4ab1eac, 0x6bbe7bc7, 0x420f7a9f, - 0x7c27af4e, 0xddd00fc3, 0x02e3b53e, 0x2f6b8d26, 0x5e07ef97, 0xfdf4efc1, - 0x6a01fffa, 0x00d36c91, 0x0000d36c, 0x00088b1f, 0x00000000, 0x7dedff00, - 0x65555c7b, 0xd6bbf0ba, 0xc0d857da, 0x51b08b66, 0x62020dc0, 0x10106d11, - 0x80a17515, 0x636a735b, 0x8dc42937, 0x910150b7, 0xf39fa8ac, 0xa96f0db1, - 0x962a2695, 0x8da6b675, 0xb2707595, 0xd99b1b46, 0x0f5d9a6a, 0x39d38d3a, - 0x32cdb653, 0x34d209bb, 0x99d37d9f, 0xde79e7be, 0x0daf60b5, 0xf9a675a4, - 0x3efcefce, 0x7df5e3fc, 0xee7d7bd7, 0x765ef3cf, 0xb24c6322, 0x98783631, - 0x8c81b183, 0x45931819, 0x77a13fc8, 0x6302edfb, 0xbeac7195, 0x28d2132d, - 0x0b6bff56, 0xdfe3df63, 0xa2749ef8, 0x8f2c6453, 0x5da0dbb1, 0x10af7c1b, - 0xd6ccabd9, 0x29d33df3, 0x148af7d0, 0xd41dd336, 0x7ec3fb1e, 0x13efd5e3, - 0x338b69fc, 0xe3abea7b, 0xbb78d856, 0x9a7ed0a9, 0xdd8beb05, 0x3ea81bf5, - 0x26e9b3cf, 0x3632c591, 0x87ff04db, 0x7b4894a5, 0x32e6c456, 0x7057b0d6, - 0xe1a8a11a, 0x18b18941, 0xf08b9f48, 0xbec664b1, 0x3bcdf868, 0xcfbd40b7, - 0x64af6f37, 0x35e67b43, 0x398a3fc7, 0xf7363046, 0x0c733652, 0xa5de6c60, - 0x0f569431, 0x073864f3, 0xf8dbd506, 0xc607ba5c, 0xfb2dadbf, 0x5a307fdc, - 0x30e59fb7, 0xbf73fef6, 0xe868e3fd, 0xde9f3197, 0x3acf4d7d, 0xa13ead66, - 0xc304b2af, 0x4d73af8d, 0x83155746, 0x18b6ce79, 0xcd14121c, 0x64c55e5e, - 0x33b32798, 0x13e41a67, 0x422bcc75, 0x16fd6cbf, 0xf3eb04d9, 0xb557fe30, - 0x5da9905c, 0x824fbe63, 0x7a860cf5, 0xdf5e1cc6, 0x58f7f00c, 0x4884670c, - 0x912de8a8, 0xcdbc1903, 0xf83d29f7, 0x21a90c1d, 0x89ef07a7, 0x5ecc1d0a, - 0x7b6d0657, 0x330305f0, 0x65eb0f96, 0xfceaae1c, 0xbff32aa7, 0xfb20bd6d, - 0x4e0ddea0, 0x2757cf07, 0x7ac1e61b, 0x364face7, 0x5cb486cc, 0x473e5ef9, - 0x2f8dde5b, 0xccaf8aab, 0x4f587695, 0x57c71b57, 0xe13d3ad7, 0x2f4f6bab, - 0xa931257c, 0x00771e67, 0x8e00d8be, 0xe382362f, 0x57c0530b, 0xa82f33a5, - 0x7c70bfde, 0xedfe7ecd, 0xd0765e0f, 0xceffa8fa, 0x1dbe8d07, 0xb6acffd0, - 0xf2b784bd, 0xc9f41bd5, 0x99ceaf50, 0xdb51704c, 0xb6cfaecf, 0x6de78032, - 0x1debb7ab, 0xe8eefc16, 0x9521ee93, 0x413f1059, 0x6790099e, 0x3bbc40ba, - 0x397ea7a2, 0x9c617ba4, 0x91cd8b25, 0x719edaec, 0x3cf428b6, 0x86da3ebb, - 0xafaecde3, 0x7165887a, 0xf66777fa, 0x66b3bfe6, 0xa0b317ce, 0xb3cfe43f, - 0xe424ce45, 0xd4510a8b, 0x3e9a9bf0, 0x79837884, 0x35e0063d, 0xdbc3fe23, - 0x0c38469e, 0x6ce6145e, 0xa9a94f86, 0x8b8e1f01, 0x36f38cf4, 0x826bcc88, - 0x8135a97a, 0x548f388b, 0x876c28a0, 0x528d8469, 0x1df90b16, 0x4802ed30, - 0xee9e2453, 0xc3f5f273, 0x677e3f77, 0x5c3c8131, 0xa1cf4abf, 0x3b606af4, - 0xfe00a757, 0xd9cc310d, 0x4fa1e8ec, 0x3e951fb5, 0x6fedfa55, 0x70ae7b7d, - 0x3993677d, 0x3386593c, 0x56e304c9, 0xb9cc3c3e, 0x3afcb846, 0x0f00610d, - 0x817ad05b, 0x7d6c0b58, 0x903537ac, 0x0fcd7657, 0x24a5b7ad, 0x86f58fb6, - 0x93e553ae, 0xc3ce2639, 0x015127c0, 0xfad77798, 0xf10c51a1, 0xca2f302d, - 0xcd8bb39d, 0x5d5bce22, 0x504d53d7, 0xbbb6e619, 0x33e944c9, 0xc368c04d, - 0x764d3e00, 0xe4df3fca, 0x29adb4a0, 0x9ddbca83, 0x633f9a36, 0x80698881, - 0x85308aa7, 0x8f3cfdff, 0xe54165e5, 0xee9c6d53, 0x11035b4e, 0xfd3920b6, - 0x0d79bd71, 0x0efa428b, 0xccfc883c, 0x5db2871a, 0xf5e9d430, 0x4cc42367, - 0x3f3e4fa4, 0x7d12ddb5, 0x163fc927, 0x02ec7061, 0x24b19b96, 0xe02374fb, - 0x38f2ee6b, 0x9b129027, 0xe49438d1, 0xb46f0cc2, 0x7eb00093, 0xcc78430b, - 0xf860e453, 0x2395aa92, 0xb26b7eb1, 0xe6718055, 0x5ae79c5a, 0xced5fda9, - 0x4b7bf1fb, 0x93252199, 0x9026caaa, 0x72287763, 0xdcc0896c, 0xa07787c8, - 0x12fe449c, 0xfea2a50f, 0xf055a3b9, 0x56cf291b, 0x21d7000b, 0x78d2eecd, - 0x055b1394, 0xbb6c0ee7, 0xa9a9e40d, 0x0d769e47, 0x7a817f73, 0xf4077d81, - 0x255ffd07, 0x5d710220, 0xca1c726d, 0x75824df1, 0xb979c317, 0x059f080d, - 0x6e9c9d0a, 0xc8e11339, 0xa3eb81ec, 0x65105ff8, 0x288b23cc, 0x3d141b6f, - 0x79406486, 0x310e4e45, 0xca41f870, 0x3a3f11da, 0xa0e909a7, 0xc51292cb, - 0x886f28fa, 0xf2c38948, 0xc912ad39, 0xaa9e9545, 0x7c2835d5, 0xa3be1733, - 0x2a912bde, 0x56be9162, 0x74a44cb6, 0xcd9286ce, 0x24e3a05e, 0x9a3b1dc1, - 0xb867a3d6, 0x13b5399e, 0x55bc47af, 0x9b4630ef, 0x7a496f00, 0x104e526f, - 0xbed9ce3f, 0xbb41892a, 0xd3cddbf3, 0x5b17fe51, 0xa1a38acb, 0xd16dbcfd, - 0x1e9052d9, 0x7ae6ca49, 0xc4ed4164, 0xacf00638, 0x2791fbf9, 0xe78fa0ac, - 0xe8569f42, 0x70b69bff, 0xd4aa179f, 0x924fed34, 0x31dee780, 0xa1b3e279, - 0xe0f142fe, 0x1f50a32d, 0xe2a7be08, 0xce23bea9, 0x503c87da, 0x0fc073d3, - 0xdaf7a00e, 0xf51ef5ff, 0xd6f895f3, 0xbed0e5f5, 0x4885f6a6, 0xa6e167ec, - 0xa15be43f, 0x49e8a0fc, 0x173ffec3, 0x45653fb6, 0x9edd6c02, 0xee7c7a85, - 0x4f28b4a6, 0xf917f21f, 0xbd51f100, 0xaaf8205f, 0x517c33e5, 0xc7bb8406, - 0x4c560ccf, 0xf480ccad, 0x8d625e7e, 0xf6a80f68, 0x323e5a8c, 0xf3adcb9b, - 0x9093eb51, 0xb53fe64e, 0xccf50925, 0x5f3c1167, 0x6fadd4f1, 0xecf2dca0, - 0xaf101a34, 0x38331d1e, 0x41799f51, 0x551d22bf, 0x93c6ff03, 0x04ae61dd, - 0x0eca2a7a, 0x6fceb827, 0x51fa411d, 0xa77c179d, 0xcc74cff2, 0xd218f385, - 0x748d99dc, 0x7f9d67ff, 0xcff3e22e, 0x17a766f5, 0xf5cd99f1, 0x4bd79fdb, - 0x05ee58a5, 0xe47b4186, 0x885febcf, 0xd8f4b548, 0xfbd2256f, 0xd67684b2, - 0xea36428b, 0x76ccf0ed, 0x1bb22cc3, 0x9d59d118, 0xc359d395, 0xe0e97d01, - 0xa8c7b218, 0x37e746a4, 0x05af85f4, 0x9dd5bd8a, 0x80d7b7df, 0x87b3527c, - 0x6d3511db, 0x508ec867, 0x855a92ed, 0x39ee179f, 0xda857643, 0x871f6eae, - 0x5e3eed4b, 0xc801955e, 0x80e5cd1d, 0x0aba4200, 0xfbf905f1, 0xd3d7f5fe, - 0x7bf26997, 0xb5df7f29, 0x750f2e56, 0xb7a8499d, 0x349c64d6, 0x976bfe20, - 0x5e42fd2b, 0xbcde341f, 0x2f0481ec, 0xc16a1f2c, 0xfd8d0ef6, 0x9a2fbb50, - 0xc36bfbda, 0x97bea356, 0x4c3a2ceb, 0xa42d6b9b, 0x8bd5b7ff, 0x9c5cba19, - 0xed13985c, 0x916183b9, 0x07472859, 0x06653c2e, 0x3b6a0248, 0xbe50888f, - 0x2f73ca3a, 0x031c67d2, 0x6f5090ae, 0x5fb405f8, 0x74f95e3b, 0x6e3ff604, - 0x066be048, 0xbf0bd753, 0xf20c5e9b, 0x2d981964, 0x06671f64, 0x0f1d2046, - 0xf4e5cc3c, 0x1ab67ae3, 0xb9d31bf5, 0xf72834d9, 0x3c42dca3, 0xdbe61b7f, - 0x1dffff05, 0xfec60ff3, 0x143fc999, 0xd0a4bddb, 0x5968dba7, 0xaebcc02d, - 0x8359ea1e, 0xd041be4b, 0x222d935f, 0xac34a40e, 0xdfe7a1d7, 0x82757b55, - 0xc113a722, 0xc8bb408e, 0x416ec830, 0xf3366e3a, 0xccb209f5, 0xf71e611a, - 0x8d9e1e67, 0xa76d7a7a, 0x9d611989, 0xc8c33a13, 0xe41c4d7e, 0x6cd6bd22, - 0x2dbd224e, 0x02ac7438, 0x14ce1fea, 0xcfac3afd, 0xcfac3e4c, 0xae76214c, - 0x9db19668, 0x6fb5f070, 0x960fbe51, 0x82891e2e, 0x47be0df5, 0x9d433670, - 0x8f73aeca, 0x15a41bff, 0xfdec7697, 0x2dff4857, 0xe113b3ca, 0x75cbba7a, - 0x5ba803c6, 0x39336d6b, 0xc160deb9, 0xef7838eb, 0xb13691b7, 0x9d1d7e67, - 0x4dfb9ee7, 0x2726a62e, 0x07099fea, 0xa11fd225, 0xc3b0e9f3, 0x3d5287c4, - 0x2c3b3bb2, 0xb0104fa2, 0x70f791fe, 0x164c137e, 0xbaf684bf, 0xb065ff49, - 0xc48e617e, 0x935773e8, 0x83df614a, 0x938b1091, 0xd1747d47, 0x38eb7642, - 0x3a550f85, 0xdb9b2b7b, 0x72296f8f, 0x73338555, 0xaf582cc8, 0xd66cf0a8, - 0x1022faab, 0xf87b32ce, 0xaf529176, 0x932892eb, 0xf46d5e1d, 0xebb2e831, - 0x33d250e0, 0x3fd9c9fd, 0xf601dda0, 0xf954f2c4, 0x5327845d, 0x0acdeef4, - 0x2dfd54fc, 0xacdffd29, 0x8b66f1c0, 0x5376e1c8, 0x7a14dc08, 0x1e97a50a, - 0xdb41887a, 0xeccf1ba3, 0x51a3f6be, 0x6bdf84c9, 0xfd78e61e, 0xedfaf090, - 0xcd802b5b, 0x4dbfa0d8, 0x0cfefc21, 0xb98bf578, 0xedaf023f, 0x9bf578a1, - 0x375e2187, 0xa0676489, 0xa376881d, 0xb5c0e507, 0x60f6e794, 0x51392306, - 0xd7398529, 0x8077e324, 0x87c91643, 0x541f28a3, 0x15c430b9, 0xe9f506b8, - 0x71e57069, 0x8db1017e, 0x10a4e797, 0xf6b0245d, 0xbc072c78, 0x277da1e7, - 0x7e668699, 0xe5b7720c, 0xdfdedf01, 0x82cd3f40, 0x983ceb6f, 0x8b66f78f, - 0x0eb7ed13, 0xc3d5e89f, 0x59a25a3c, 0xbf187ed6, 0x4e55fe65, 0x4533962f, - 0xf8374c6e, 0xef837ed0, 0xbdf88d49, 0xe97f7f9c, 0x441f67ef, 0x8d33acfb, - 0xb25abad1, 0x67da3a59, 0xf419652d, 0xdcaab7fd, 0xb7823079, 0xddf4e32f, - 0x43e6df32, 0xa3e8f43d, 0x27a8e1be, 0xf1cbb65a, 0x510d4836, 0x981cf89e, - 0xd38920ff, 0x94324b7d, 0x7059ba43, 0x7ec5cf97, 0x0df3e1ae, 0xff3d8794, - 0x4e657414, 0xe506d105, 0x76231ba7, 0xe9555ca0, 0x2e30f074, 0xcf7887df, - 0x7938456c, 0x7a8cb027, 0x8543ffe8, 0x0bf854de, 0x008d36c0, 0x3c1098f7, - 0xa31774a8, 0xca585fc0, 0x413bcfe9, 0xf31d4f59, 0x0091bfa1, 0x38070953, - 0xf0c11a57, 0xd5967483, 0x6ff38d93, 0x91f80c5e, 0x0f1c1d70, 0xdd5645a7, - 0x155f07d6, 0x0df128e6, 0xa6f90218, 0xa9be7192, 0x7a42ba44, 0x0aba046c, - 0x481647a2, 0xae173e88, 0x83ca15d0, 0x1cb8f708, 0xc257e758, 0xf0b1f21f, - 0xa694ffad, 0xa4ce35f7, 0x1e2f2e1c, 0x734a7b33, 0xd04def48, 0x656f9dd8, - 0xfa889a7f, 0xafbdf4e5, 0x149a6025, 0xeb8c9ee5, 0xd7fe5cd8, 0x1fff1452, - 0xb8f407c6, 0xffcb0f8e, 0x2dda224f, 0x235f4b95, 0x79d2bffa, 0x37989996, - 0x5d1ee01c, 0x00fd382c, 0x462d79bf, 0x16f824e7, 0x0c755c57, 0x6ad659e1, - 0x56911874, 0x1c8d62d8, 0x408f2b3b, 0xda1d8a37, 0x39ba246a, 0xf4894bf7, - 0x8b92b9c1, 0x0f800eaf, 0x4e0856e7, 0x32d657ac, 0x3790256c, 0xa816292b, - 0xa057995e, 0x1ca9657a, 0x051a275f, 0xaf4037a2, 0xde283b25, 0x8ef5a731, - 0x13df88a9, 0xa40f5fc5, 0x187ac1f8, 0x2e63e547, 0x959e48de, 0x56abf529, - 0xbb47911b, 0xacb597bf, 0x3ffc88ba, 0xde521bd3, 0xec53e93a, 0x5b51acb7, - 0x8235c6ee, 0x4e57771d, 0x07ca0c44, 0xefce64e6, 0x40f24811, 0x93fa0ff2, - 0x447140bb, 0xc20f30cf, 0x61bc89c3, 0x99eba47a, 0xdba05708, 0xdd7ca5e8, - 0xbe0aa733, 0x99ceb049, 0x1f67ce16, 0xfbbe0996, 0x09ff3e05, 0x5065ef40, - 0x5d740b1e, 0x38e4c316, 0xe626dd48, 0x2e79c70f, 0xca09f61d, 0xd438d3db, - 0x8fefaa28, 0xf75ca1b4, 0xb78911e8, 0xe5a52f32, 0xede947cc, 0x98f34fcc, - 0x74933ac1, 0xfc93af90, 0xf38e312b, 0x0367b32b, 0x8b5fd7d2, 0xe0169c4e, - 0x4239ddfb, 0x439428de, 0xdd68038d, 0x701f5b97, 0x067680a5, 0x5fac41aa, - 0x147ee396, 0x4ccab3fb, 0x74ab718f, 0x995a8e95, 0x17d61537, 0x9be2debb, - 0x6b8beb04, 0xf5c21cf5, 0x38374fa6, 0x1383ef10, 0x74133af8, 0x543f9fdc, - 0x81a3606e, 0x183f360e, 0xdb3a43e6, 0xda2035bc, 0x03e6fea1, 0x97cc0180, - 0xf0bc14af, 0x4e61eadd, 0x7559d38c, 0xfeed111e, 0x188f56a2, 0xe1a7e208, - 0x394441b2, 0x23d3be91, 0x5ab49ea2, 0x353d53d7, 0x4fd4ac5f, 0x59067937, - 0x4e9e4ec9, 0xa15c33f4, 0xd49fb51f, 0x045f8356, 0x4ac917b8, 0x57b7997d, - 0x9e8a61fb, 0x3961db56, 0xab7a67d2, 0x453f4fa3, 0x3f505b4d, 0x08f88f83, - 0x7bd205c6, 0xfd711fca, 0x1bf084da, 0x36abf378, 0x2103374c, 0x9d1c71f8, - 0x79e34cc7, 0x15d33cf8, 0xbfbf87da, 0x63e38f7f, 0xb9bbf01e, 0xe422fef5, - 0x1f00cda3, 0x9de6f3c4, 0xcfd4ccb3, 0x799a59f4, 0xf286a931, 0x4b070825, - 0xa23c75ef, 0xd53d2fcc, 0xbd695a23, 0xe76843ce, 0xe28ccba5, 0x763f6a01, - 0xf405741d, 0x857a776a, 0x90cbcc7a, 0x47b8945a, 0x4eb38e3a, 0x5d31ff40, - 0x6b4957c1, 0xf63361fd, 0x5f1466e3, 0xfe85cf4c, 0x8426fea1, 0xfc37a183, - 0x5e99e742, 0x4273e7cc, 0xf18edfa9, 0xe76c7494, 0x74431158, 0xd5d7e7c5, - 0x1c6214ea, 0xa08fb197, 0x7e90c9fd, 0x0cb8c29e, 0x7e4ecfa4, 0xb42e4a6d, - 0x97d1fe7f, 0x52d0b476, 0x0fb33e0e, 0xf5ab56e5, 0x9c709be6, 0xff9f2283, - 0x5de2724d, 0x206ddf98, 0x53be9a3d, 0x7944db4e, 0xebfd1393, 0x55df56ae, - 0x2cbd422f, 0xeb64c618, 0x0a138f3d, 0x3a15da9c, 0xcb793938, 0x53ef5c20, - 0x582c7745, 0x5f87ed02, 0x3b8d38f7, 0x94fcca7c, 0x9b0fc816, 0x30abcbf8, - 0xc78e5f7f, 0xfee4023c, 0xde5fd2b0, 0x6ae50fb6, 0x821cfce9, 0x4576c597, - 0xda39a9f2, 0xbf02f5e3, 0x52dc4737, 0xd2b8fc8e, 0x24487066, 0xfa19eb77, - 0x7711cd59, 0xe5bfb1db, 0x4c26f9d1, 0x36bfd60d, 0x6e3c9ca1, 0x1e2131c9, - 0x18132d9a, 0x0aaceb96, 0x4f1bbe9e, 0x885240fa, 0x73847772, 0xe5744cba, - 0x0c272864, 0xbcad0609, 0x2f7971d6, 0xb43e1dd9, 0xf5acba9f, 0x60cc8148, - 0x7ca05409, 0x69795493, 0x3c717a71, 0xa3b4e2c9, 0x9142b4bf, 0xaf862c37, - 0xf73960d3, 0x5eaf389f, 0x962e63fd, 0x867f4b50, 0x4128ccb0, 0x9bda3ff9, - 0x573e10c6, 0xbbc58353, 0x6844f518, 0x70205d7f, 0x4fa38e50, 0x7e337647, - 0x5eddee48, 0x7a341bb2, 0x7a5e5ba4, 0xf221f5a2, 0x7a811e52, 0x792058a2, - 0x0ceb61e9, 0x0c12feb8, 0x3c5c00b2, 0x545eb8db, 0xce267bf9, 0x49e5f005, - 0x5e5c9165, 0x2673e4e9, 0xd1efc60e, 0x452a5cae, 0x5e021e22, 0xc3e9e0c9, - 0x9378f79f, 0x9d1e507f, 0xa987fa41, 0x21fe9007, 0x0fe144fd, 0x6f078a8f, - 0x50a3f5d9, 0xd912cb5f, 0x85cb9503, 0xe2cfb436, 0x6947d1bc, 0x2edcc5be, - 0xa6bf9768, 0x892a1cf5, 0x7979444b, 0xc799d962, 0xbebd41ef, 0xfff49c29, - 0x5667a5a4, 0xa66e3c60, 0x211a7057, 0x7d1a59ef, 0x6f987bf7, 0x905d3a34, - 0x81f0ab3f, 0x914597fb, 0xb8084f68, 0x759e8cce, 0x83321656, 0xf139e29b, - 0x3b409633, 0x34e0a34f, 0xa1e07a3b, 0xef527ac7, 0x37bc05f5, 0xfad0fe46, - 0xa8d7bc3f, 0x3e7759c8, 0xc6a2d9ca, 0x700a87e4, 0x7cf5eb5d, 0xd7d18d9e, - 0x3927de53, 0x1cb97639, 0x3fd8a99e, 0x57b3a59e, 0xc0f7c3c6, 0xcef9416a, - 0xc8a956f1, 0x88e340e5, 0x0d3f1863, 0x3e48172c, 0xa252bc79, 0x5ccdda1f, - 0xef784d9e, 0x5d900a28, 0xb43de5d8, 0x722b5a92, 0x3674a3de, 0x94588c17, - 0xe3dfa76f, 0xfe479ffe, 0x9bb62563, 0x83b5a2d3, 0x0cfd0226, 0x67bcb840, - 0xf1e9fd26, 0xefbad196, 0xea6945f0, 0xd38ead55, 0x8bab3de4, 0xe7b0c7ae, - 0x52277bac, 0x3992af3c, 0x2ade9122, 0xc1376e65, 0xe61b259f, 0x4f9d5733, - 0x2ac7b731, 0xa27ec18b, 0xb07b5aef, 0x3389fec7, 0x78a8df20, 0x3a13f154, - 0x19765eef, 0xacd076e3, 0xdd7ada75, 0x16301076, 0xe5caba8a, 0x32bf76da, - 0xb9459fbb, 0xe038dee8, 0xaeabf21b, 0x80821e50, 0x266e7f21, 0xa61f71e3, - 0xced543e8, 0x517a592f, 0x6668728f, 0xc23d45e3, 0x1fd2e673, 0x385fa7e6, - 0xa1bef3b5, 0x3ebb4a20, 0xbf934e39, 0x534435d1, 0x30f766ff, 0xa75bf7cd, - 0x5ef9ab5f, 0xc9a919ee, 0x5e3d5edf, 0xfd467f53, 0x7a1cad24, 0xa3d69a37, - 0x79bfa7e2, 0xa3e8a5bf, 0x12ec4277, 0xe23a9d35, 0xbf91133f, 0xe4672c3f, - 0x33787cbf, 0x1d31f8d3, 0xe7822423, 0xf93d5c80, 0xc8e5f731, 0xbf208fef, - 0xa1f44fc9, 0x7343f3c2, 0xa228c9a1, 0x7ee4627f, 0x725fa879, 0x5e503990, - 0xfdb1d4ce, 0xff8f5442, 0x9cf30e67, 0xe3bafec7, 0xf10f4b0d, 0x1f884378, - 0xff78a573, 0xbfcc0670, 0x4d79790f, 0x16c3f72e, 0xffaf36ee, 0xb58e0838, - 0xfc9ad16d, 0xebf1fda2, 0x3bd60e3f, 0xae1d044b, 0x93e146b3, 0x7da0165a, - 0xa0e8bb52, 0x40c4eafe, 0x583be62c, 0xf4b46c67, 0x0a8b838f, 0x258f800f, - 0xa9de2837, 0x193fc3fa, 0x9e0a453e, 0x1a70b4cb, 0x90e3cb93, 0x29108f5f, - 0xc7239cdd, 0xf103fee7, 0xf49eb41c, 0xdc7fbcdc, 0xc847227a, 0x9f9f0859, - 0xe3dfaf1b, 0x17940f1e, 0x7f0b908e, 0xfe4cb826, 0x47a5c247, 0xd82f47cf, - 0x72a3fa0d, 0xfdfb819d, 0xbf5c33de, 0xfefd7237, 0xf68fb47c, 0x44f39b87, - 0xed070ee7, 0xe93ed297, 0x618d7ba1, 0x59df1819, 0x797d23a1, 0x8190997a, - 0x2126c2fe, 0x0f36fc8c, 0xc81648ab, 0xc878b9be, 0xaa31fd48, 0x3afded07, - 0x0551f390, 0xe4096b3e, 0x71e5ccdf, 0x716e35b1, 0xf5038a4a, 0x1eac1ff6, - 0xe27a8b8a, 0xfd9e1e11, 0x696be130, 0x2bee45df, 0x6bd0127e, 0x8512d1e5, - 0xd5cc5f8f, 0x2e1f3ad1, 0x949db914, 0x1f70ba2a, 0xa9d81563, 0x96065768, - 0x915f28eb, 0x6d59e9c7, 0x9d0a1ff7, 0x14dd94c7, 0xda88f386, 0x7d7dba24, - 0x2e51fb8c, 0x793d0f8f, 0xb3ed1857, 0x68742a01, 0xd6bddbef, 0xaf582e69, - 0x8d96d0bd, 0xdcdadfb6, 0x4d6fea68, 0xcf159746, 0x748cfca1, 0xfe8eca78, - 0x8cfac0a0, 0xe655cd33, 0x580feeab, 0xe936fe94, 0x9da2bf41, 0x1e289822, - 0xf91af161, 0xb16715f9, 0x1ccade26, 0xa76e0b02, 0xf428f3d6, 0x1b42c76a, - 0xeff697e1, 0x5db178d5, 0x1ba417a1, 0xcf4abbc4, 0x8983fda1, 0xe9cc8dec, - 0x15d9f389, 0xe51a8e52, 0x8f748dd9, 0x1f90eafd, 0x07fe5cbc, 0xe3c4be6e, - 0xded7de2c, 0xe18879c3, 0x0c9c525f, 0x5fce4aec, 0xbee2434b, 0x024f913f, - 0x40cf0e66, 0xde1e5684, 0xdac9d0ab, 0x48de827f, 0x3ebc02ba, 0x8fe5cb9c, - 0x36fdc0ab, 0xb2c73bca, 0xfba230d4, 0x96270b1f, 0x51384560, 0x3872ba5e, - 0x1f3df379, 0xcc749e10, 0x7f71b46f, 0x72e1f90b, 0x31c2a47c, 0xbe9e6449, - 0x3c88f2f4, 0xca1bfbe5, 0x6ab7ae7e, 0x61d90fc8, 0x02c57728, 0xcc2cd2c6, - 0xffb6bc61, 0x8f9c0e7a, 0x396ae885, 0x96aee5d2, 0xcfe43094, 0xcabc6564, - 0x0ca7d29b, 0x205fa077, 0x040ed018, 0xe3c0c3bf, 0x574edc3f, 0xb94f7ae5, - 0x72c47ed6, 0x1f8f664f, 0xeaf7daa6, 0x82973c77, 0x59f3aae3, 0xfd61d8a5, - 0x125577cd, 0xdca2724b, 0x808f765a, 0x5ab1dcf0, 0x717df8d4, 0x0325615e, - 0x7fce3e3f, 0x8efd13af, 0xcdafb038, 0xf575cf28, 0x5e083382, 0x0a817b81, - 0xf8871338, 0xe24fe02b, 0x8967bd3a, 0x57c7425e, 0x85abb1d7, 0x5de71b8f, - 0x9f90c82c, 0xa02f5154, 0x9956b7df, 0xa3055c7f, 0x3e9969ef, 0x9e21e301, - 0xe38a5616, 0x03335655, 0x332af5c6, 0xf2865399, 0x7443c6ca, 0x02b9edde, - 0x206f2539, 0x4f3a4fc9, 0xa4f02ae3, 0x4d1d01e7, 0x7643284d, 0x864bb867, - 0x167f89f1, 0x4cb5a71d, 0x59efa2f0, 0x843ce2d4, 0x11d001fe, 0x2d3c7dc5, - 0xe75f1a01, 0x5d7271e5, 0x80e9c18b, 0x658d4875, 0x5521ffb4, 0xd4329c1b, - 0xdf29b63b, 0x2d95f18f, 0x0ddfdc8d, 0xd67493f5, 0xd1c3d7fa, 0x9910ab5f, - 0x790a0144, 0x5659fa2a, 0x30562e85, 0xf7ee3b77, 0x41fe1933, 0xdca548bb, - 0x2a6f3d5a, 0xd0e52266, 0x13dc8378, 0x6b9e409f, 0xd3b240dc, 0x678daa94, - 0xc92b2d48, 0x7d6233af, 0x890faca8, 0xa5d54877, 0xac971714, 0xf35bf2da, - 0x8e086222, 0x9e1e3c59, 0x8d88ef73, 0x727cc2b7, 0x1fe3797f, 0x41873d30, - 0xfe5b8033, 0x4c073bb2, 0xac16ff87, 0xa62378d8, 0xe8cebc4f, 0xe08fc19c, - 0xfa8c6657, 0xe8fafcf1, 0xb2abf295, 0xb9d00f26, 0xd27dafc2, 0x094f1abf, - 0xfe954fe5, 0x4d4ef943, 0x7f865ed7, 0x120526d7, 0xdf4f0f91, 0xdb03323b, - 0x73de3657, 0x5f88c7c8, 0x77d00705, 0x117177a5, 0x5660ba23, 0x5e5bd097, - 0x490b3784, 0x1f37bfec, 0x3b7c863f, 0x13e7effe, 0x95df087f, 0x63ce8c09, - 0xf649fd81, 0xdfaa9a9c, 0x3eb9f223, 0x246790bd, 0xc1464ebc, 0x053bac0a, - 0xc7bee0da, 0x2b4e6078, 0xf02e7fa4, 0x4de38b3c, 0xef9e3c81, 0x6b40fd7b, - 0x4b37ae0c, 0xa78ef5c7, 0x76e68edb, 0xa8ffb748, 0x06590fd8, 0xdced0536, - 0x771126c0, 0xc0e0596e, 0xe2d63be7, 0xc9b96bbe, 0xcaeb0699, 0xf448dfba, - 0xf68a0484, 0xa7689651, 0xb6aee5b8, 0x9f69cb8f, 0xd2c0d1b1, 0x0ee06e28, - 0x006473c3, 0x4caab0cf, 0xacc357b2, 0x857aaf68, 0x1e88aaa4, 0x22f5087b, - 0xef2cb40a, 0x30ac53ad, 0xb042aefe, 0xec7b3347, 0x59fed51c, 0xeb4c9f9c, - 0x6820ed57, 0x8fddb0c7, 0x0b4aa7e5, 0x19bb224b, 0xf7fb83e6, 0x90264cb6, - 0xff5213ed, 0xd92332f4, 0x7baf76af, 0x5bb470ca, 0xa0e6a797, 0x9ae30add, - 0xfd7f6e24, 0xbb67ca3b, 0x285ef94e, 0x49b9e0e6, 0x05801f75, 0x8718d174, - 0xfeaaed53, 0xe763a5e7, 0x9505b954, 0x9f2f9b7f, 0x59ff7ec1, 0x5563dd72, - 0x634d4de8, 0xe9e079f8, 0xcf8dbd0a, 0x9e9a5337, 0x73dbb3ff, 0xfe93aea7, - 0x39feeb79, 0x9ffae1d7, 0xffd88eb1, 0x3cd8f821, 0x3ac67ff9, 0x4ff2996e, - 0x5f37875c, 0x43cfc86e, 0xe746d679, 0x7e2eec88, 0xdee41c2e, 0xcb9cbc3d, - 0x09938b39, 0x74ffc764, 0xfd84d779, 0x1c1f419d, 0x7778a1cf, 0x67183a08, - 0x88a1a588, 0x8ca5cdec, 0x2c8681f6, 0x4340fbe5, 0x224d3a96, 0x6e1603da, - 0xec520e27, 0xb94b41ce, 0x9ca719dd, 0x118b882b, 0x3fd4327d, 0xca5bcbf6, - 0xbee0c6e7, 0xd5ec9190, 0xf5dd36e6, 0x5e53d416, 0x868fce89, 0xd2d289da, - 0x5f9c4a95, 0xf6aa9f6b, 0x79e31a68, 0xb4b3b2fd, 0xa3daa74f, 0xb4f29443, - 0x603f7ca5, 0x1ed68b48, 0xdad6ab8d, 0x1082fa8f, 0xbaa9733b, 0xeb49d07f, - 0xe9d72dd3, 0xa87ffcf1, 0xb07b89dd, 0xab0714a8, 0xfeb4067a, 0xf630d74d, - 0xf9f77e74, 0x1fdc1c8c, 0xd05ab99a, 0xcf5539e8, 0x7e282402, 0x43e3e2a4, - 0x3f8873d4, 0x5fb534f7, 0xaf3e6fd2, 0x2e4c7048, 0x539cd74f, 0x1e7eec62, - 0x3a73712f, 0x11eaf5fa, 0xddaed16b, 0x37c6eeb7, 0xfd697d31, 0x04e5e19d, - 0x6f54f5af, 0xebc6cb7f, 0x7650ff30, 0xe6123dbb, 0x53a8d0f5, 0xefd009ef, - 0x85e33c6a, 0x2978b3eb, 0x9e14b68f, 0x7ab3d08b, 0xa4dbdfda, 0x0d9f4c0f, - 0x45122be5, 0x23be911c, 0x1832981d, 0x59309f9d, 0x35f57e78, 0x30e3ee8c, - 0x1a9f5ce5, 0xd73d0987, 0xc7c3cab7, 0xc4f00559, 0x18963573, 0x39a91f7e, - 0x08e9fee1, 0x818766ef, 0x8b3939e1, 0x624fee72, 0xa82aaed5, 0xbf7edc77, - 0x0bee167d, 0x7e881867, 0x26ce98a4, 0x9ed993c4, 0x71c2af63, 0xcd35e242, - 0x2037e929, 0xfbb5bc59, 0x20679ef0, 0xc9cf7b7d, 0x2a9d312f, 0xf3c3efb5, - 0x88465225, 0xbf6bd29f, 0x9bdc1198, 0x4a5f3387, 0x6e3b9632, 0x754e9110, - 0x869a6feb, 0x50c154fe, 0x4f581ae7, 0x1bf30258, 0xbd611e60, 0x7b7989f6, - 0xce9c20a9, 0xf59648d5, 0xdfd80d15, 0x7fba08a8, 0xae03bec0, 0x4df3a7cb, - 0x80f657f4, 0x0e3a47a8, 0xc38ff653, 0x1fed7b32, 0x30c2fcd3, 0x3b59e14d, - 0x7a15c3e4, 0xca7b635f, 0x6b77fb87, 0x106e5213, 0x69f53d1d, 0xbbd6195f, - 0xab1bbbf2, 0x26fd5f68, 0x9fcf1593, 0xcafb2985, 0xa574e3a1, 0x43675b3a, - 0x6418b46a, 0x55f11673, 0xe0725f0f, 0xe68353d8, 0x9cfaf501, 0x736e3aa7, - 0xda83c71e, 0x64c2d19f, 0xf74323b4, 0x81fb43ad, 0x56be7079, 0x31fda9ea, - 0x01e746d6, 0x518b8874, 0xa7abb57d, 0xe9df0db9, 0xff1fbb24, 0xcc82e382, - 0x35fc431a, 0xcedb55ac, 0x0dcfca9c, 0x2a18f4a8, 0xfdd0a52f, 0x6f7ad4f7, - 0x9f81e138, 0x1fad0827, 0xf6d0d70a, 0x5833b7f0, 0xe160ddde, 0xa95d88fb, - 0xac22b99d, 0x473da57b, 0xbf5a7f33, 0xef7fd3d0, 0xbe6d3cfd, 0xb9f6364c, - 0x7d07943e, 0x4e8277cd, 0x6c596fbb, 0x8d2fb6d1, 0x25777ed1, 0x4592f368, - 0x6d91dfe9, 0x8e1af3a2, 0xf79e137c, 0x18d8f953, 0x8af7efe2, 0x2efa2adf, - 0x1e74c991, 0x79de9375, 0xe3c4e50e, 0x01d24033, 0xf82c3c7d, 0x552e58cc, - 0x0f515bb4, 0x93d3adc6, 0xaefc7a9c, 0xbde0ce5b, 0x6ba016a0, 0xf771e584, - 0xc56e9b47, 0xf148b17c, 0x70fb9b0d, 0xcb51d239, 0x37bf5f77, 0x3a9fcf1b, - 0x5bce740d, 0x75b1b73d, 0x1e2b61ac, 0x94cb8a0b, 0xfdf069cd, 0x84e62aa1, - 0x6323b099, 0xfc712363, 0x15a2d12d, 0xd1f3ddf5, 0x718efff5, 0x8c19e694, - 0xe14219f6, 0x46d23757, 0x756e3672, 0x5bf780b6, 0x5f9b1e1e, 0x06317289, - 0xaf9465fc, 0xc57dca90, 0xf015c717, 0xc5b6c0f8, 0xbe23c52f, 0xdb0f5837, - 0xa2159e69, 0x52d8a713, 0x8b7fe5c1, 0x7b3ed185, 0x3752a8f3, 0x72ec4d1e, - 0x8b3c0ec9, 0x41dee2d8, 0x2d595ef3, 0x9cacd972, 0xc8580197, 0xbe9c3951, - 0xfd4a360c, 0xb3346e98, 0x972839f8, 0x7ce8c292, 0x81f67f50, 0x57cb84b4, - 0xe9cc6f6c, 0x1143debf, 0x5cc8f18d, 0x9fe467cb, 0x6dfd0b9f, 0xf299b19d, - 0x538d3caa, 0xdfbbbbe8, 0x1bba3d10, 0x36724bf0, 0x9e2ce41a, 0x878e63c7, - 0xf575b789, 0x3a20b4c2, 0x7c8055d5, 0x2ee7e2cd, 0xbebb7e30, 0x87e334a8, - 0x9b9d4cfc, 0x5518e5cb, 0x97ebbb1e, 0xda05dc61, 0x635f51fb, 0x0fce783f, - 0xb7d71952, 0x443fa851, 0x830cf37e, 0xe839ef03, 0x430e402a, 0x56825d7b, - 0xc9181c4f, 0xc1fb35f1, 0xa09eccbb, 0x728c4d38, 0xbea3661e, 0xeb069cde, - 0x744338d9, 0x6c78076e, 0xfa1068a9, 0x55c4c78a, 0x0d997e70, 0xde6fd1f5, - 0x1b139152, 0x8c669ebc, 0x36d0c073, 0xdb9f0fd7, 0xbfc885d3, 0xbc79235d, - 0x1cdd67bd, 0x3f4071be, 0x479a87a8, 0x6ae6ae97, 0x557241da, 0x6d6de567, - 0x073a7aae, 0xcfc155d9, 0xf813ad5d, 0xc4a4827e, 0xf28b9bcb, 0x4bf4bf49, - 0x492b152f, 0x57e2849f, 0xe5fd3f9d, 0x9911e907, 0x8719f1f1, 0x4cceb49b, - 0xda07e1fa, 0x4af9743b, 0x1e0bd47d, 0x62ba7f6d, 0xf8e33651, 0xaf105fa8, - 0x7bc5e63a, 0x95fda193, 0x3a16fc2a, 0xe069c91f, 0x8d9db1ed, 0xdbf48bf8, - 0xc8e00169, 0xa1ce82e9, 0x3c38f7b3, 0x7c3a24b7, 0x2e01f86b, 0xae7487d2, - 0x78f7a52b, 0x658e098f, 0x7de8efb8, 0xe7f3a25d, 0xcd4f7aa1, 0xb13070ab, - 0x3e9ce736, 0x0f9c4dec, 0xa76935ea, 0x01fa89d7, 0xed8a97d0, 0x094b2a36, - 0x5cd4b3bb, 0xd7ade8e0, 0xab6d5cba, 0x937282af, 0x03f69983, 0x99534c3c, - 0x79c0307f, 0x1ccf33ed, 0x3df58abf, 0xf803ae0e, 0xe6bce099, 0xe63347f9, - 0xedf37b40, 0xb9b426ad, 0xf5a1cf43, 0x76a4ef6e, 0x4cab4b71, 0x23c519d3, - 0x86b95465, 0xafd90b08, 0xe48674cc, 0xc6c934b3, 0x3d10a7ed, 0x50f80eb9, - 0x644af08f, 0x38d0af04, 0x49f8e871, 0xdefcc905, 0x1a52e2e4, 0xa7454377, - 0x5d90e31e, 0x4ec57aae, 0xefa9f4f2, 0x7bb1fb42, 0xff23a73a, 0xc81a1577, - 0xc1f87e1e, 0xcf119349, 0xc51265de, 0x7bd17ad1, 0x233dbac8, 0x1cae9cf5, - 0x7f28cd8b, 0xdbb9ccb7, 0xfec3e8ec, 0x8b3152d8, 0x965a2fce, 0xa5633b70, - 0x88e481bd, 0xe7b942a5, 0x71cbd8a2, 0xa213bfaa, 0x3754b727, 0x9bdef198, - 0x8590de7a, 0xed97dbd8, 0xbbbd1fbf, 0xf18bf961, 0x2aee4fa8, 0x79c78869, - 0x4ff0896f, 0xd5df1377, 0xf2029f93, 0xf1e51e38, 0x920e91a2, 0x7ff2dd2f, - 0x0e3b39c6, 0x5569181e, 0x43db8af8, 0x417fe25f, 0x928d66bf, 0x1c6014a7, - 0x8e44b52d, 0x74bc6076, 0x00d3bbdf, 0x7abd93ae, 0xfb8d63f2, 0x2fc1f481, - 0x49382632, 0x681e9e5f, 0xac9d22b0, 0x8f46fc6a, 0xe2ce6bf7, 0x7fe855e9, - 0x87b70255, 0x9818c556, 0xa1f342df, 0x2e754f45, 0xf5a7a866, 0x0137dc09, - 0x798fc5bf, 0xfd102316, 0xbaf18e4c, 0x298700ad, 0x30bbbe31, 0xd7ac4aad, - 0x129c60d9, 0xf080b447, 0xc563a29d, 0x9daf1e06, 0x115cf385, 0x59c511f3, - 0xd1c5a727, 0xc5a3547d, 0xc9fbc3ad, 0xf6d5677a, 0x8bce8cb5, 0xb015bc51, - 0x8ce1f74a, 0xb6bdc718, 0xeeab8e27, 0xdcf1a913, 0x04290575, 0xffc1212f, - 0xcb23e22d, 0x1ef1101a, 0x403e987e, 0x46aaf8f6, 0xcd41f913, 0x91da3b09, - 0xf823323d, 0x3e7aa43e, 0xb163e017, 0x0c567c02, 0x95d69bbc, 0x17bb1494, - 0x91faa5e7, 0x50af20f1, 0xcc2565de, 0x4beb8a9b, 0x4aedc37a, 0x0cc67a86, - 0x1660365d, 0xa2b9eae0, 0xc61eac78, 0xd8583c21, 0xabfb4c38, 0x40d122bf, - 0xf2d0d8f1, 0x5c780b27, 0x21050b32, 0x135eebae, 0x755dcfdd, 0xaaf7bee0, - 0x301e7e50, 0x6767c939, 0xffbc1481, 0x66771dde, 0xaeddff7c, 0xdbb5bf9c, - 0xa63f740d, 0xf8ccbe3b, 0xe71abcbe, 0xd9e51a88, 0x31f2788c, 0xc7f421c7, - 0x8f71abfe, 0x4fca461b, 0x6dac7f60, 0x63c515c0, 0x68eac6c2, 0x8529279f, - 0x05f78279, 0x5feb2956, 0x7a870dd5, 0x75f5ea3b, 0xf6079428, 0x378d870f, - 0x2226bbe7, 0x88ec46dd, 0x47dafd47, 0x171343bc, 0x79287bc1, 0xfa6204b1, - 0x9c79aa93, 0x3cea6624, 0x5348778a, 0x0ad93ef9, 0xdcfc6016, 0x7c84c0a0, - 0xfd4beaba, 0xe887700d, 0x927accd7, 0x90ae9193, 0x7f2f48b8, 0x6576e645, - 0xa2dbdc88, 0x02f1f9f0, 0xcf91ee25, 0x93e7bff2, 0x5228bb25, 0x1889f7d9, - 0xe8724295, 0xd90a5711, 0x411cc443, 0x9d9cbef0, 0x87b15073, 0x8f9ca77e, - 0x83e72bf7, 0x83e72b0f, 0x0b77c55f, 0x863f90c0, 0x7a4016ef, 0xe549c9bc, - 0x2815346f, 0x6fe399ca, 0x4892ee45, 0xf9941fb2, 0xadf994e9, 0x25734eb0, - 0x6d567e03, 0x5879d3d3, 0xe984c263, 0xaf32cf68, 0xdb119edc, 0x7587ef73, - 0x9efcbfc2, 0x095da773, 0x3a4f3a1e, 0x3ff7cac7, 0x542d7c55, 0xb612afea, - 0xc75f9019, 0x36e16a76, 0xc6a452fe, 0xda622cae, 0x4d1397f3, 0x4bf53443, - 0x97f3daac, 0x6ad7ec93, 0x68764fbe, 0x975e5fcf, 0x1f643e31, 0x0b574b56, - 0x806e8013, 0x7d33aa4e, 0xd685ff34, 0xcd7b8a52, 0x74c7b90d, 0x3f36ab47, - 0x2fcda7df, 0xabcdaddc, 0x46c3c9e7, 0x9230f429, 0xf131fc8d, 0x0cf7e44e, - 0x0107ef85, 0x3ab36fbf, 0xcfda1199, 0xf8bf7816, 0x1b00c61e, 0x76c94bed, - 0xe3ac238c, 0x5cb09ff7, 0xc3bdcbc7, 0xbe7af695, 0xdb8ec56f, 0x4b1dbee8, - 0x06ede1cc, 0xfc7eeff0, 0x72f1a48e, 0xfe87af0e, 0xa21bd612, 0xe5c353f4, - 0xfe459c93, 0x33ec9b82, 0x62b36b23, 0xc2fe016a, 0xe9399a34, 0xab0c759e, - 0x9075bf27, 0x51327f72, 0x43bca4e8, 0x3e6186b0, 0xf0a67045, 0xe48f85f8, - 0xfe4950c3, 0x89f12a75, 0xf447745b, 0xb90d97e6, 0xaaf007ba, 0x910286f8, - 0x5623e2e4, 0xd8f9ef46, 0xbf13f75c, 0xb016c36e, 0x8f6b336e, 0xf87a1549, - 0x61bcede7, 0x5c135fc4, 0xb52fda0e, 0x780b2415, 0x8588a52e, 0x4536cb9c, - 0xc4a3e869, 0x5f42171a, 0x4be84243, 0x9d7f7f4b, 0x3945d5ec, 0xe842ce90, - 0xe5be2ff0, 0xaf182c51, 0x05fa8f4c, 0x7689d58f, 0xca9e054a, 0x754f9602, - 0xee319b46, 0x73d18b67, 0x3fd8a579, 0xab9f4aa5, 0xb2eb59e4, 0x566bfbe1, - 0xf6e649d1, 0xf13d2dba, 0x96df1825, 0xea35f600, 0x5c919963, 0x1fd3b07d, - 0x7fd43576, 0x65fffc04, 0xeb1bfd0c, 0x65efbc64, 0x5f10e4b5, 0x7949623f, - 0xd05ef300, 0x437f58e8, 0xe5aff731, 0xef826ce8, 0x05bea151, 0xc23da5ef, - 0xc1a94cf2, 0xfebc2df5, 0x5164597a, 0x31189f90, 0x9dbfea82, 0xcef86667, - 0xd9a07781, 0x63ec7187, 0xdd77acf2, 0x7b7feb41, 0xaf07d714, 0xa8f11c19, - 0x7c991e0f, 0xd287a677, 0x685f8d74, 0xbee4104b, 0x8f8517ce, 0x92bd7236, - 0x78c7e25b, 0x34c2747c, 0xfd039957, 0xe90bb71d, 0xf112e742, 0xfd375be8, - 0xa87e2b44, 0x0fc106e4, 0x5d749b4b, 0xe3ff430e, 0x35770b11, 0xd59e291e, - 0x02f98652, 0xd903ee91, 0xd9ebe25c, 0x7e02aeb8, 0xe54af0fe, 0x181ea871, - 0xbfdb9a32, 0x3c448693, 0xdffa1430, 0xb15a2450, 0x2b7a0dff, 0x4ef1e7dd, - 0x1757e466, 0xe097eabb, 0x11096dbc, 0xda6fcf0c, 0xbe781a0a, 0x00ccc0d8, - 0xbd6b934f, 0x4a69f117, 0xf6c08cf5, 0x7a7e0747, 0x5b19ed1c, 0x703a4882, - 0xaef9cba2, 0x2817eb1b, 0x79e29df1, 0x9b3c70eb, 0x599ab445, 0xb9541c0f, - 0xcbc99ebe, 0x0ab2ffc9, 0x0accdef4, 0xce0d436b, 0x708491e7, 0xae6df3b2, - 0x79e20b06, 0xd13d40c3, 0x7f224941, 0xc2556a57, 0xffcc0ab4, 0x7191a062, - 0x1f2ff3be, 0x5381fe8a, 0x5b3575a0, 0xc75e681a, 0xc139892e, 0xa9a896ef, - 0xcf85a1d9, 0xf8f146ef, 0xf1e30990, 0xf5b79f80, 0x8b9a9ccc, 0x78a7a3f4, - 0x6b7c7f53, 0x7ece5d73, 0x2afe61fb, 0x110b0394, 0xc29785be, 0xfa404f98, - 0xfe61293d, 0x5b017f77, 0x60d9d680, 0x6e41fec1, 0xbfa2fabb, 0x7e9cd188, - 0x4b0e0b9b, 0xd7824ef8, 0x341f1021, 0x444e4e5b, 0xb528783e, 0xa1e8e88c, - 0x899a8f82, 0xfcf3862f, 0xeef779db, 0x137a3c41, 0xe77f69c3, 0x315982a1, - 0x60bef4c1, 0x32f44894, 0x4e616fee, 0x9463e23f, 0x91fbf881, 0x8c56c708, - 0xccf3794f, 0x824bbf64, 0x986cd975, 0x2862c4e7, 0x5da2fe87, 0x7ef13e62, - 0x0b8f0575, 0xd57e302b, 0xf8843b65, 0x31664a90, 0x3949ae7e, 0xef9114f7, - 0xb435435c, 0x25956ffa, 0xd8cfde97, 0x4270d092, 0xbb20b6d9, 0x5722906a, - 0x45889406, 0x5906df28, 0xeb655db8, 0xbb940594, 0xaa47fba1, 0xed29d7be, - 0xa65b328c, 0x371b54a3, 0x7d7015d2, 0xe97f6a1b, 0xc35edc2c, 0xae8fbc3f, - 0x893f35cf, 0x317438e7, 0x197f7ada, 0x0a739ca5, 0x3a54afb1, 0x7ae560df, - 0xd1ae4362, 0xa1bd7487, 0x2a59db98, 0x47f2ab1f, 0x872abf85, 0xef7e7bd4, - 0x5195f628, 0x87365e4e, 0xe599eae4, 0xd4076f78, 0xc317739e, 0xfa56897b, - 0x1f72aefe, 0x6f6294f1, 0x5bd8a7bd, 0x5bd8a1ff, 0x05bda3ef, 0x835186f9, - 0x1437bf08, 0x08dd762e, 0x20901af3, 0x3a14df11, 0xedc44c4e, 0x271971af, - 0x61d97d2c, 0x0ea2d111, 0x348f05e3, 0x36497bf2, 0x1598ed97, 0x95cf59f1, - 0x766b2cf9, 0xbcbb3469, 0x7ae3f27c, 0xe43ed1d2, 0xb9557beb, 0x994c794f, - 0xfe6571ff, 0x57f3286f, 0x43498fed, 0xbca132be, 0xefaf10df, 0xfc297e47, - 0xb9d0a729, 0xb57950a8, 0xe908c401, 0xfc9122eb, 0xe778209f, 0x25bde46a, - 0x4ef5f720, 0x1e68c959, 0x7660dbbf, 0x7c462c57, 0xa714664e, 0x27aae89d, - 0xb90365b9, 0xf8b37245, 0xca6ceb5c, 0xe5833847, 0x6381519e, 0x8e5acbb1, - 0x4638be72, 0x24571f4f, 0x5bbdd0a4, 0x1d0efed5, 0x0cf072f7, 0x82a66795, - 0xf3e25ef5, 0x6c7247ff, 0x8ee3e32c, 0xfd3a24bd, 0x4f1cde5c, 0x91237926, - 0x5fed0a7c, 0x636f3795, 0xbe2064cc, 0xfba1644f, 0x610a7700, 0x9de7844e, - 0x3f307c28, 0xff7dd197, 0x673d8ac1, 0x01d1de57, 0xceb8a14e, 0xf5b04ed8, - 0xfc7af883, 0x1bf75325, 0x8f8edc6c, 0x9a27e4d6, 0x4bf535e2, 0xef9ac9ac, - 0x35c3ec93, 0xb23b27df, 0x32ebf935, 0xffea6946, 0xc9a459c2, 0x593050df, - 0x2e4cbf53, 0x6665e4d3, 0x0e4877a5, 0xfa1eed36, 0xa7fd1eb1, 0xa71fa1b6, - 0xa14f86f5, 0x0e0bf0f1, 0xa3b5e160, 0x00e8678b, 0x87518546, 0xfc864cef, - 0x6793d1c6, 0x0aef80e8, 0x3afe1f07, 0xd3685819, 0x7f3c29e8, 0x53afe1f5, - 0xf465bf20, 0x863f3c75, 0x3adcf091, 0x2f0cea7a, 0xea1c59e0, 0xd0347479, - 0xea972df1, 0xf83da28f, 0xe6d365c7, 0x4ef84b26, 0x06625940, 0x8a6ce7cc, - 0x7efc61e7, 0x15acec73, 0xfc761178, 0x8f74f577, 0x79a337ed, 0xfc8b8ebb, - 0x8b8e8d5d, 0xbb0d1dfc, 0x53f6f1c8, 0xcbbef553, 0x7e9a0e04, 0x64115fdf, - 0xfd05af7e, 0xdc6939cd, 0xfd14c4df, 0xdfd14c4d, 0xcdfd14c4, 0x6fee7a39, - 0x26fe8a62, 0x89bfa396, 0x324d5be9, 0xb934efa5, 0x726f6d28, 0xbf7dda53, - 0x6ae729e0, 0xef380a3d, 0x985b8b4f, 0x1117e4c3, 0x4ae7a14e, 0x4f9df43a, - 0x45ca7ed0, 0x12fbc0e6, 0x394e2287, 0x39acbf70, 0x2e7444cf, 0x4c3bb674, - 0x9730bdf0, 0xb62f9be7, 0x617e503b, 0x8e9eed1e, 0x946cb6e8, 0x16b5cdbf, - 0x35bbee27, 0x23c7f45f, 0x1bd6149f, 0x714cdee8, 0xe9c52767, 0xbdfc2d0a, - 0xc7114384, 0x91e3288e, 0x9179da5c, 0x277c45f9, 0xb0eedcc7, 0x3f60e32a, - 0xea326e30, 0x3025c2b7, 0xbf5bf52e, 0xb0a9fa98, 0x842b8f74, 0xe1fa6b8c, - 0x410a2771, 0x3176a6e3, 0xc701177a, 0xf5c66875, 0xfc3f744b, 0x78c25fa2, - 0xd3b44761, 0x354d718e, 0x21df8c5f, 0xdfcf45bf, 0xf8742c5f, 0xb893d425, - 0x5bef89bd, 0x33d881c6, 0x1f0d79d3, 0x47a865c9, 0x5d9db971, 0x9a179d7c, - 0x9f900bfc, 0x6077958a, 0x7ba58cc0, 0x730c4c9b, 0x9128bea2, 0x38363bbe, - 0xe339df17, 0x1b15a0ef, 0x1f90dbdd, 0xde5c74eb, 0xdf3318b0, 0xcfb5d057, - 0x3bd415ff, 0xec983b19, 0x4bfb0495, 0xb404752c, 0x44cae45f, 0x5b24e3bb, - 0x7568724f, 0x8f7fe794, 0x31be7a06, 0xf4505eb3, 0x7763f527, 0xfdc0ef85, - 0x86578e88, 0x4d1f21e5, 0x645e3a33, 0x1f7fbfc0, 0x3cfc44dd, 0x8791ca2d, - 0x7dfdac2f, 0x8f9e0af4, 0x3788bc73, 0x69acad83, 0x8ffc7146, 0xf1452f3f, - 0xa79a740d, 0x7fb43a0a, 0x765373d4, 0x063613d1, 0xfaeb54e0, 0xd7e7c0ca, - 0x7078c069, 0xc10718d4, 0x4661e06f, 0x273a98e7, 0xe076f847, 0xfa80df7e, - 0xb2878c6c, 0xd61e474c, 0xd277d24b, 0xef8ef27d, 0xa827fdf8, 0x50537919, - 0x8389fefc, 0xf8afab92, 0xdc31c9e3, 0x6a945d4e, 0xa8788759, 0x944c9bb3, - 0xe748bc1e, 0x9dce9982, 0xd96bf18a, 0xa97bf7d0, 0xfae18eaf, 0x41a57921, - 0x74410231, 0x30e594c2, 0x0cbde6a6, 0xbbf6d0f4, 0x8bdfbac3, 0x43327003, - 0xdef3c89a, 0xeb178f1d, 0xac65f534, 0xe31dfddf, 0xbda7acf4, 0x8fcddbfc, - 0xc6554f2f, 0xc7997a43, 0xd50c7fc8, 0x6d0b6b3b, 0x843f3bea, 0xcc63c7e7, - 0x523de9db, 0x14877949, 0x4e315aea, 0x3de8ce11, 0x37bfc1ae, 0x9e819afb, - 0x3d399a76, 0xdd3c8aa7, 0xeafaf229, 0xbbeaa53b, 0x7a14cf6b, 0xa3cc2b6e, - 0x8fd4fc7e, 0xdf1b37b4, 0x6d6788cb, 0x6efabe34, 0x012f5a94, 0x2b0920f4, - 0xe23a675d, 0xfb1250ab, 0x63e7e784, 0x1d20e68a, 0xb2f2685c, 0xcdf4824f, - 0xc6c8f085, 0x49d5fc60, 0x3f5af7da, 0xda81331f, 0x1b6beda9, 0x284fb227, - 0x3a27e978, 0x69154daa, 0x624ebd1f, 0x9c3be2af, 0xa80d5920, 0xa776d597, - 0x78e2de40, 0xc5fc82ef, 0xbb903df4, 0x3ed1e89f, 0xfbe94e9d, 0x3f2a1e4d, - 0x694d54dd, 0xca9ea9a0, 0xa46a6a3f, 0x23db96f4, 0x167f9172, 0x3ec65fed, - 0xdaf7a209, 0x1027bd36, 0xd4553f94, 0x51ad1d37, 0x7254e8e8, 0x1c9fdfdf, - 0x53bbedc3, 0x3b3e38e3, 0xf7c0dec0, 0x972e80da, 0xdbfd6d5b, 0xfdca1d1d, - 0xf9e3a3ae, 0x3c4765fe, 0xc31f2fcf, 0x64596efd, 0xe8fed8ad, 0x3fef0378, - 0xefc6ac45, 0x7bf78db2, 0x77a45d2a, 0xb1357ea4, 0x5831fee8, 0x73ca163f, - 0xaea7f27a, 0x41e5dfe2, 0xaf9d5cbc, 0x42b6fdfa, 0x61eefaab, 0x8fcf7f3a, - 0x7a02f7df, 0xfad5fea7, 0x3e702663, 0x4befad0c, 0x43c9e7e5, 0xc2a9f1e1, - 0x6817c4b7, 0x241f2367, 0x9d45f107, 0xa542f883, 0xd6fe9543, 0xa7387216, - 0x0f3a151a, 0x07eee7e7, 0x76842ea3, 0xb4cce383, 0xbbe3208f, 0x9d9eb0cb, - 0xa12fc282, 0x63bca0fc, 0xca83f2ac, 0x0fbd2a07, 0xefe33e06, 0x8c75f334, - 0x5f79fa95, 0x7b475958, 0x845dc46c, 0x2b7a83d7, 0x12b1adea, 0xb0792f7f, - 0xedcef5d8, 0x11b19fc8, 0x96918c0e, 0xf7d4b2ac, 0xfe3ec725, 0x9543c2af, - 0xa3c0fd0b, 0xca0c1c17, 0x123fc3bb, 0x50e7240e, 0xf6fd238e, 0x8c4eb721, - 0x177629b1, 0xc7cfdfa7, 0x1d226fc8, 0x1d660875, 0x30e87bde, 0xf05f7df7, - 0x0ebe78e8, 0x16d68e95, 0xe3074a32, 0x96f6873a, 0xba7aea7b, 0x230779d7, - 0xc61a97f9, 0xacf143cb, 0xfe482bae, 0xa979c19d, 0xec0c64f0, 0xa127e81f, - 0xe8ef42c6, 0xe0e856dd, 0xd3f036fc, 0x67ac0dca, 0x3e8a35fd, 0xf8944c7b, - 0x7e8ac87b, 0xa4172ee9, 0x1a996599, 0xcf4743bd, 0xefe15f3a, 0x5645fb8a, - 0xa372ef8d, 0x171c1d6f, 0xe5c8521f, 0x3cf4d743, 0x2f13f711, 0xf742d5fc, - 0xea0c2f8b, 0xcef68d3c, 0x533d5685, 0x2a9b23de, 0x8b9dde80, 0xf90c133e, - 0xf39ef2a5, 0x0ef7e8e7, 0x176d7a83, 0xb5bda34f, 0x4cc4ab68, 0xeb609e78, - 0x3d20b737, 0x4f457bcd, 0x5b9a99e7, 0x7a471e37, 0xc04fb73c, 0x85d96fe7, - 0x31c5027d, 0x7c225b6b, 0x0a5fa866, 0xc77fac79, 0xe3c7c96e, 0x39c5328b, - 0x3ef1946a, 0xa0a5d731, 0xeb713e5d, 0xfb843a5d, 0x8b02edbc, 0xb48f7e83, - 0xdf0c79de, 0x8db7391d, 0x366b2fdf, 0xf9c0ee47, 0x0ceb4a97, 0xc17ca083, - 0x635e5e76, 0xf70cfd29, 0xcd3c1743, 0x60b3fe28, 0x8ff9046f, 0x1ff45af3, - 0x8eec8205, 0xfcda6dea, 0x4066d67c, 0x53b0583a, 0x07b35e5b, 0x79f241f2, - 0x2f12a150, 0x29b2ce19, 0xe3c2d25e, 0xef7caa07, 0xb97b5f6d, 0xde506d1c, - 0x897f66ff, 0x5f0ff7a5, 0x23e926f9, 0x2997cf0b, 0xff9033f9, 0x178e1bea, - 0xca752e15, 0xb3c55fd8, 0x675836dc, 0x2b662bdd, 0x0775edfa, 0x79e246ce, - 0x016145b0, 0xbd99177a, 0xded1592c, 0xe4bf607b, 0x1ed6f845, 0xfb893f34, - 0x9e2f7598, 0xa13c6030, 0xb262df74, 0xef312657, 0xfd9bf44a, 0x89dac8a2, - 0x7de9da8e, 0xce77265f, 0x1c2e7ec3, 0x0ed15b30, 0x4ff97ba8, 0xfcc76ec7, - 0xa7dd028b, 0x201890bc, 0x55b7993a, 0x0c437ba2, 0x1efcb42d, 0xaf10913a, - 0x28b6e788, 0x0ee58f7a, 0x19e23bc4, 0x4648eef0, 0xd071e13a, 0xf44b4f79, - 0xd9b5b9bd, 0xf9cff580, 0xbc557e38, 0x094b4a97, 0xe71e0bcf, 0x75b89cf8, - 0xa430e6d7, 0x64f5a783, 0x76811f8f, 0x0d3b7883, 0xe15e181d, 0xc5d85ffd, - 0xd37791cf, 0x376301c1, 0x2f3ce01d, 0xa7c00747, 0x472ff7a4, 0x97e89d07, - 0xddffbf92, 0x0ed0c7b9, 0x87e7e08f, 0xd51b77d5, 0x2e071a77, 0xdf14753c, - 0xbfb34ae7, 0xa5777640, 0xc5da8bed, 0x9d09de8c, 0x4be78853, 0x02bdbf26, - 0xca7277d1, 0x2f14d9b3, 0x6d7607d5, 0x744378c1, 0x3ac7c538, 0xe1b6cb92, - 0xb6c598fb, 0xc2f6936f, 0xcefd163a, 0xeb11e748, 0x3fc67e15, 0xbea2073c, - 0xa7780c4b, 0x07b519f3, 0xc65cfc8d, 0xe1fbed3e, 0xce9cf11d, 0x959d0c4b, - 0x804fd18b, 0x411c70fe, 0xc2e9fee6, 0x451dfc83, 0xa85c9fd5, 0x47b8a7be, - 0x60836efb, 0x3dea9b7d, 0x70429850, 0xd6371a18, 0x73797681, 0x0d84f339, - 0xc17d21fd, 0x5c7ca9df, 0xb5fa8bf1, 0x1bd1fb27, 0xbcc91daa, 0x15daf721, - 0x014775b9, 0xbbd1e39f, 0x7be1d0df, 0xf93b1d8c, 0x3fcc3bef, 0x062af208, - 0x1af519f7, 0xd4a753b9, 0x0fe914ff, 0x5bde76e0, 0x052892ff, 0x8bf797cb, - 0xa79a9fb1, 0x48753f79, 0xf5571457, 0xfe830e6f, 0x33d36cbe, 0x4c0597e4, - 0x23fb3791, 0x4bd46e28, 0xbedcecbe, 0x50f7cd12, 0x76085aba, 0x94222e26, - 0x69f6eabe, 0xa85d3deb, 0x670e7bec, 0xfff9e0d7, 0x90e031af, 0xba5f23d7, - 0x8e67e9df, 0x6eefe428, 0xef68287d, 0x056b0fef, 0x77ea0f96, 0x63c4cfb8, - 0xeafe4aa4, 0xfe4d56dd, 0xa6bb369a, 0x1dfbb5fe, 0xfed9ef9a, 0x11f7cd0c, - 0x7c9a9dc7, 0xa6817b5e, 0x64f7c8fe, 0xc0547e4d, 0xe63fa9a5, 0xef935bbc, - 0xf4f584ca, 0xe9a8cf61, 0xa9a0bb24, 0xd661d93f, 0x465d7ff4, 0x65df26b4, - 0xd8a3e051, 0xfbfdaa99, 0xff6e42a7, 0x7c2aa686, 0x8ed4e17f, 0x37edfaa3, - 0x2bc76814, 0x5de3b593, 0x1df05e29, 0xff9e9d41, 0xf8a6027e, 0x34ba09fb, - 0x9809fbfe, 0xc04fdfc7, 0x013f7f14, 0xe4dd7fcb, 0xa6befca4, 0x04bfca02, - 0xf7e6097e, 0xe9829f83, 0x609fe0cb, 0x77e0e5f9, 0xb8f7194c, 0xca1bee32, - 0x4e153fb8, 0xbdfd296f, 0xef87f4a3, 0x3df4ea0d, 0x795d6bdf, 0xe3e025e2, - 0x7467db22, 0x086e595f, 0xa31c6294, 0xe18975f3, 0xf1e667f9, 0x418a6f1d, - 0xa18036fd, 0x9ddcc49d, 0x6e3ee26f, 0xad438bdd, 0x81efae78, 0x07787ffd, - 0x27d85fbf, 0xf0e6bc51, 0xd891b3fe, 0xc29797cf, 0xe90a30e9, 0x7cd7c845, - 0x0d7e502b, 0x6773c77c, 0xca4af793, 0xa46d67bb, 0x554cbeef, 0x2fba3ef3, - 0xd7b3deed, 0xb85a7880, 0x7f7d2f7b, 0xf35af81d, 0xcd76f77d, 0x87d62b77, - 0x47cea174, 0xf7cf8571, 0xa9f9fdab, 0x7f2a4d7e, 0xddf3fe3f, 0x418e5647, - 0x6ab7bc7d, 0x17b5c600, 0x3b1139ee, 0xf1f007fb, 0x66cf4bd5, 0x3da81ea2, - 0xd1e72920, 0x07b57f78, 0xcf9e4af4, 0x6f7526bf, 0x63379e29, 0xb3ba047b, - 0x4f5b25f4, 0xee16c4e7, 0x728355df, 0xedc66176, 0xb57f8a7a, 0x83bc4a49, - 0x6350d3bf, 0x6baedc65, 0xdf123afb, 0xdb7dffa9, 0x1ef1ebd1, 0x23c1c774, - 0xc74c5ef4, 0x4fe3493e, 0xf1cb1d8d, 0xf72c763b, 0x77dcbeff, 0x09cf1224, - 0x8476d03e, 0xa7e75dc3, 0xf2561ff5, 0xbc12901d, 0xfeb44bf7, 0xcd2497f9, - 0xc0b801ef, 0xcdfba171, 0x7022d3fb, 0xf8db275d, 0x7d40d378, 0xd56a7950, - 0x1bff9c1c, 0xe53cf2f6, 0xddfa327d, 0xaeab8ea1, 0x767285db, 0xe7d49b61, - 0xd839f779, 0x98efcc2f, 0xebe9d39e, 0x1b1c2fa9, 0xc37f7004, 0x749b2035, - 0x62af5284, 0xa59bd72c, 0xea2a4f06, 0x47169391, 0xfdf9d204, 0x8811a1ae, - 0x6298c3df, 0xba49ebb9, 0x1f60be07, 0xb5a4ef1f, 0xeee9123d, 0x5211bee4, - 0x2dcbfef0, 0xe9ba7aca, 0x5e6f1bbb, 0x6fb553c2, 0xe9fb05bb, 0x9f2f1fc1, - 0xf54ad636, 0xb89df0df, 0x93aced05, 0xc0ddfc19, 0xfe460663, 0xdc3dc2f5, - 0x70793e4e, 0xfbe0f6f0, 0x7c14d359, 0x7df06474, 0xf5fb0bf5, 0x77dbbd4a, - 0x3d3d4d31, 0xed4ed7c7, 0x33beac7c, 0x5e7da10f, 0x6744b8f3, 0xf5f46a1d, - 0x4ffeb8b1, 0x57e769b7, 0x46b9c0ad, 0x0d8d8fef, 0x039ad7a2, 0x21637cdd, - 0xf2a03f3a, 0xa9f08389, 0x8664f1e2, 0xe765e7c4, 0xecd5f8ef, 0xdd7445dd, - 0xe3c4be3b, 0x31ef83b7, 0x74be2939, 0xb55a7f19, 0x2dfc821b, 0xbd23bdfa, - 0x989e686b, 0x9c1f63d2, 0x1a1f942e, 0x987e879b, 0x93ccfc9b, 0x185bec0c, - 0xebed16b3, 0x891dfa28, 0xd76e38cd, 0xffbd3d3e, 0xb03a6b5f, 0xef23df00, - 0xc0a30272, 0xe9b6bbbc, 0x4667dfbb, 0x629e773b, 0xf0ea7ee7, 0x7fa04be4, - 0xb489976b, 0x923d9abe, 0x5c17cf0f, 0x57dee450, 0x406f937b, 0x2e39ad7a, - 0x9a3fd159, 0x70fc96d8, 0x77e92e61, 0xdaeb57b2, 0xb75c9db8, 0x58bb205b, - 0x156a43b5, 0x629ce43b, 0xd65b9f07, 0x57e3edc9, 0xea11b604, 0x7b030dad, - 0x9b5de604, 0xdaec8539, 0xcadd695a, 0x473c0ec1, 0xe61bb5a5, 0xe7443c1f, - 0xd1cec0ae, 0xaddc2f94, 0x69b6d7cd, 0xf8bfaaf3, 0x3b6ed8d2, 0x37fa3863, - 0x1c615225, 0x0a9bc3f2, 0xe77f555e, 0xf49c6bce, 0xe80f27fb, 0xb8d4531c, - 0xd16bc204, 0xc7cc2f2b, 0xc26afb79, 0x347fe49c, 0xdae096fe, 0xd7ee17f1, - 0x1bdee074, 0xf0e333f2, 0xe9cfd8ed, 0xf05e917c, 0x2cbaefe1, 0xfd815d42, - 0x32df0499, 0xbb7b3b8c, 0x293e4922, 0xca1a08e7, 0x632affb9, 0xb2a6180c, - 0xe7f72c7e, 0x38eaf543, 0x0e8a405d, 0xb1811392, 0xd8af5429, 0xde57cfc0, - 0xfd24e119, 0xedc4c436, 0x6e2621f5, 0x75d10faf, 0x85dfa32e, 0x7df02418, - 0x6997ac8e, 0x9d6d60ff, 0x0417f685, 0xe10e957b, 0x955076b1, 0x887de90e, - 0xfd032db5, 0x8c5f353a, 0xec7b33df, 0x478b5283, 0x8cece387, 0x047d9417, - 0x74cb4fae, 0x90747d56, 0x996c657e, 0x3dea7e66, 0x7e7d9fcc, 0xa59f9856, - 0xef807e67, 0x75ff6c28, 0x86ec93ae, 0xf7f532a4, 0x2e49ea1a, 0x12fcf0a8, - 0x7018bde8, 0x816c7745, 0x1db66a6e, 0x96b2ff22, 0x76c4afb5, 0x1d7c91a5, - 0xbefe06a5, 0x4f186951, 0xfcb8e375, 0xa5d2512a, 0xc3f6b4e3, 0x7eb27191, - 0xc63ba41c, 0xf2e34db9, 0x79953f68, 0x6f0d7d61, 0x43d677f3, 0x13943ee5, - 0x7c0d7d3d, 0x466ff288, 0xd54d60bd, 0xbf9c69d8, 0x6ea2f116, 0xf6f85a3e, - 0xea27c493, 0xc66acc39, 0xa3667bf9, 0xc41a9ad9, 0xdf908b17, 0xc377ded0, - 0x138c7cbf, 0xeb6abff0, 0xe9973a7c, 0xa2b58c69, 0xfa48b75f, 0x7e25f692, - 0xda2ddf2c, 0xcdfbcdaf, 0x11fdfe9c, 0x1949f902, 0x0de3bae3, 0x0a498fc4, - 0x08f76c7f, 0xfb600e74, 0xcf1e3a77, 0x7e2810ab, 0x36143377, 0x624994da, - 0xba22eabd, 0xe333724f, 0x4b596347, 0x3dbbf28c, 0x796fb431, 0x9beeb293, - 0x2843fe75, 0xdbea8e57, 0x749e3192, 0xc4e4d6b4, 0x1b59cbfe, 0xc15a6fbd, - 0x153d29da, 0x9fa2f75e, 0x2226f73a, 0x63c9fddd, 0xf6d678a4, 0x50223be5, - 0xe5b167be, 0x044fdc56, 0xb7c6ec50, 0x73b3fb01, 0xd51df742, 0x2f60c4fb, - 0x027d21c7, 0x1d2127fe, 0xd8dc079c, 0x5fb77a73, 0x2317c7f8, 0x2c5f7f11, - 0x5b96e179, 0x9d5ffa19, 0xa82d47e4, 0x5df7465f, 0x33da9c81, 0xaaf07bf2, - 0x5bc55de2, 0xf01d5e37, 0xb0af182f, 0x938404a6, 0xc91965f4, 0xe8917fa5, - 0xf0e5d69c, 0xbc7dc2aa, 0x0e3b9f82, 0x8a15f970, 0xb70f156f, 0x43f5bbe2, - 0x236eef49, 0xc923313c, 0xb87a50cb, 0x3080be1c, 0xc4d93ce9, 0xa1f92318, - 0x4f2e4583, 0x2813cf07, 0xf33b795e, 0xf48012bc, 0xf5f7f096, 0xc70adefc, - 0xb782855b, 0x2fdf313f, 0x71ff9232, 0xce323b78, 0x606e34dd, 0xe50dbe6f, - 0xb2f8fed3, 0x37fce1c6, 0x18fa5f55, 0x3f0863f2, 0x376bf087, 0x2ff09d1e, - 0xc69e8f08, 0x6ecbe248, 0xae7b4b7c, 0x7fe22f4c, 0x5fb58e30, 0xaf93f9f0, - 0x46055f80, 0xf8f8bfbf, 0x54dead38, 0xa5c2a6f1, 0x07e0b8bf, 0x2ad47fcc, - 0xe70abed0, 0x748dbbe3, 0x57dd43ff, 0x5e4ff751, 0x5cf5c719, 0xd801fa68, - 0xb55fb84b, 0x40e4e326, 0x194f33b4, 0xfef87ed4, 0xdacb07ef, 0xb6f7f113, - 0xe9e2283e, 0xddff0329, 0x872f350f, 0x07e4b8f1, 0xc22f46f1, 0xf86103e9, - 0x1f33d404, 0xcf5cf708, 0x070671f3, 0x26e3cbe6, 0x53903de0, 0x798e357a, - 0xf07f12bf, 0x8f9479f1, 0x027aa62c, 0x074a5dff, 0xf61ddefe, 0x1736082b, - 0xbb83e7cc, 0x9d7de8d2, 0x718d7dee, 0x467f0edc, 0xdc774759, 0xe2815eff, - 0x355133fe, 0x84c4fee1, 0x877c2e2d, 0x437df4f3, 0xb4df69b3, 0xea3e3b41, - 0x978a64fd, 0xfee7e06e, 0xabea752e, 0xb75bf482, 0xc8be2dbe, 0xd1e4e7cb, - 0xbfa88cef, 0x86db2747, 0xc7dcff73, 0xd550df7f, 0x5fc75d67, 0x73c704b0, - 0xdfe2533f, 0x0fe1f9dd, 0xc3eb0526, 0x4dad4f43, 0x0daa7ec7, 0x05a72cde, - 0xb1ee877f, 0xaa5bb424, 0x4e955a9f, 0x0f53f4f6, 0x545fa3a4, 0xba6d63bd, - 0x0f70f94c, 0xbe3a65f9, 0x1b9e2fee, 0xd4f3e745, 0xdccaf6fe, 0x1d30a8af, - 0x3dbd412a, 0x56afeae5, 0xda41fee0, 0xffc5027d, 0x15f6b066, 0x332b67a8, - 0x16b15f38, 0xe87fc913, 0x776bf68f, 0x4ec5ff0d, 0x646f0794, 0x81cfd59c, - 0x203e127a, 0xd5df1035, 0xdfa3adf2, 0x7fcd5c09, 0x7ea7b027, 0x56ffed22, - 0x9de8172d, 0xfcf519ab, 0xf1a4f377, 0x59c704d1, 0xd18fb3ab, 0x794b57fb, - 0x6fa314f9, 0x67ec49df, 0x3fdf818b, 0xe094ee64, 0xb29270fb, 0x9d73385f, - 0xca717bf2, 0x639b6938, 0x53af07b7, 0x591df652, 0xdf2477ea, 0x32f0506e, - 0x5789e975, 0x54efd0ed, 0x1e3cc7bd, 0xe9b3bfbe, 0x619faa5c, 0x3a33f41c, - 0xf066985f, 0xd71f3a3c, 0x7148c3bd, 0xc1acdcd2, 0xcfd41c52, 0x11b45259, - 0xab4b99d3, 0x728f9d1e, 0xcd94d5b8, 0xf9f2358f, 0x114e0835, 0xed91f4e5, - 0xb842ceb7, 0x7fc4df9d, 0xfb61abff, 0xc2ddfa30, 0xafdee4fe, 0xf9eff89a, - 0xa264dd3d, 0x2b26d9f4, 0xcfeba3c3, 0xff29d935, 0x4a0e4daf, 0xcd3cf4d9, - 0xd7f4d8ef, 0xe14b88df, 0xb973bbf4, 0x3bf4cdab, 0x39460d88, 0x2bc03c75, - 0x1ddaaaed, 0xc2eb280f, 0xbdb2b8f7, 0x0e1113c9, 0x3e2c0fb9, 0x75b3a686, - 0x7d97df3c, 0x24eae4f3, 0x2c77d614, 0x7cc4f33d, 0x78fb7ef8, 0x270835f7, - 0x148bb6d3, 0x607238a7, 0xbbc22555, 0xaf91877a, 0xf9f7594f, 0x8f71e94d, - 0x75f97c62, 0x160dc53d, 0xc4f33b6d, 0x877f0c03, 0x9821b177, 0xbd74afde, - 0x7ee78f57, 0xaaf8e5e6, 0x78fc383f, 0x449b5abe, 0xf803b3fc, 0xf3a7f32a, - 0xcba5a2d5, 0xc6cb7e08, 0xb8426fbb, 0x937bd79d, 0x0fce9f90, 0xee744b1f, - 0xf820457d, 0xdbbc72ab, 0xbfe056af, 0x575b6c50, 0xc723dc98, 0x04b961bf, - 0x3e0743df, 0xf9fb474d, 0x3fe5fd9b, 0x6097eeb8, 0x1861fedd, 0x1a5133af, - 0xe0df3dfa, 0xf584ea19, 0x3ef3f7e5, 0x6af1d2e8, 0x539f9ffc, 0x36213fc0, - 0xe6219df8, 0xd4f9828d, 0x61fc141c, 0x26cfa859, 0xbf43a67d, 0x8fcffc11, - 0x198ce734, 0x9f4828fb, 0xcbdf37f7, 0x4fd875a5, 0x1ddc8f5a, 0xfcc89ef9, - 0x547b7a41, 0x83f98c20, 0x73f6edc6, 0xfb40cca0, 0x1724f14e, 0x2e786f10, - 0xe181c2ec, 0x99ff303b, 0xc2f1e381, 0xf14f604b, 0xf2931078, 0xd9f9d67b, - 0x50b22f81, 0xb7ae86ce, 0x882fe5ee, 0xaff66a3e, 0xfad028ba, 0xcba67f27, - 0x0ffafcba, 0x1645f53d, 0x7d33efe2, 0xb6fd1f20, 0x1640860b, 0xb7eea1e2, - 0x58ff9e5c, 0xf3e5a838, 0xf7e81b57, 0x1304eb3a, 0xf48949d1, 0x2e1fc525, - 0x87f1e71c, 0x924f03ba, 0xc83aed3c, 0xc48b40e3, 0x8c38d2f6, 0x399fd49b, - 0xcbacf286, 0xe831fdce, 0x2b71de9f, 0x41e8aa1c, 0xde12675d, 0x4dd83bf7, - 0x3c8fdc0f, 0x0c3bfc8f, 0xf3a369fb, 0x9c2b2cbd, 0x39f15da1, 0x7c30f3f2, - 0x257930bf, 0xdf79f9d2, 0x8f941cc0, 0xadfd666f, 0xbf86e28e, 0xb27ba70f, - 0xe6926db5, 0x3af7799c, 0x703f127c, 0x29fb54c4, 0xe7c1c99c, 0x1b8e0cb9, - 0x837e6ec8, 0xba2e13ef, 0x7b13f38a, 0xed53f399, 0x7b0643f2, 0x15bb7f50, - 0xc8ed527e, 0x1bffbf29, 0x85b3e5f1, 0xd504fd32, 0xffc7a54f, 0x4cf7fe9f, - 0x33412fff, 0x800063ec, 0x00008000, 0x00088b1f, 0x00000000, 0x5aa5ff00, - 0x5554700d, 0xbdef3e96, 0xdd2749fe, 0x12421349, 0x42068408, 0x03621a88, - 0xc4d67281, 0x206efce9, 0x6b01bb33, 0x8d08c42d, 0x749d2422, 0x6aece882, - 0x021a6eb9, 0x367564ac, 0x1d47598c, 0x809f9b47, 0x9476ec28, 0x0da0c040, - 0x6ba2cb0a, 0x3a26aa45, 0xab545b55, 0xa6e00eac, 0xd63b8223, 0x3be7b8e2, - 0x1dddb5ef, 0xa6ed4fe2, 0xee7dba8a, 0x9ee7b9cf, 0xce77ce7b, 0x52b48f3d, - 0x6a22ca22, 0x2a08cdcf, 0x6ea6ff0a, 0x6d4445a2, 0xf67f2429, 0xaf1f4541, - 0x7dbc64d3, 0x58c9a340, 0xce08eb93, 0x4754419e, 0x459a26dd, 0x654284b4, - 0x29bf71a4, 0x795bcbf2, 0x6d0dfebc, 0x61931741, 0xb06aad1b, 0x7aa6d513, - 0x1314360b, 0xaacaab0d, 0x0bcc6286, 0x4b9d2e95, 0x7efe0df4, 0x879b744a, - 0x2a224f99, 0xf60f14d3, 0x169c9d1b, 0x8b5dc9dc, 0x491bfb97, 0xeaa7984d, - 0x534f98f3, 0xa3827c08, 0xd81d4b25, 0x9964b468, 0x8eef3e23, 0x07d6d237, - 0xd2a14e31, 0xf9f6123b, 0x68858f4b, 0xcb17d121, 0x650faa17, 0xdaae79f2, - 0x51337403, 0x29ed768d, 0x70ddf785, 0x05564ccc, 0xafbc67fc, 0x670239f2, - 0xfa65ea34, 0x790a4752, 0x4bceccac, 0x1bcf0f1e, 0xd8293b99, 0x3f6fe7c5, - 0xe78990a0, 0xeeb11db5, 0x6d79e14c, 0x9bb648e6, 0xf036ddf7, 0xdb878b3b, - 0x2cf7fef6, 0xcf58b9ae, 0x9e433647, 0x6dfa1514, 0x174ff277, 0xce607f91, - 0x3f3177fb, 0xf44d69ff, 0x67bd37ed, 0x05d7d621, 0x5afd8f9e, 0x82d5f60e, - 0x56f0a56e, 0x3cfdda27, 0x9bbf48af, 0xe5dff86f, 0xb386575c, 0xf8be7e38, - 0xa7a25d39, 0x69f8bd18, 0xd602f73e, 0x43eb468b, 0x21ee5976, 0x6e717b96, - 0x252e8ece, 0x5fae9d71, 0x4b69768f, 0x9d15cb0e, 0x6615b8a9, 0x6c0d4d15, - 0x851f4276, 0x1797b38a, 0xb97f5f47, 0x9bf42d74, 0x9dbd2c12, 0x90b517cf, - 0xc7e2c7dc, 0x04b49bb6, 0x6a0f1679, 0x3443dc1e, 0xc90e9a95, 0xe2a77bbd, - 0x61bca83e, 0xd61267a9, 0x2b7bbe8d, 0x7955196f, 0x73fafdbd, 0x7975ca04, - 0xc9a9b0ce, 0xd7721b7d, 0x80ede5e7, 0xc400d9fe, 0xfaa94e8e, 0xc7951efe, - 0xbfd7c7e7, 0x46a79c68, 0xf089ce2b, 0x9dc506f8, 0x9f671ce3, 0xf587bb58, - 0xe9ef86be, 0xb46fbe45, 0x6938752f, 0xfda26ccd, 0xff42b91d, 0xda4b8773, - 0xf4914750, 0x16e1d2bf, 0x2dc760fa, 0xf0ea1f42, 0x51d03d08, 0x8ed1ed27, - 0x033fe906, 0x708cff51, 0xe2ec20a0, 0x4a6d7c14, 0x1cce1e9c, 0x9e494f43, - 0x24a99c3f, 0x991453d3, 0x3cb870ff, 0xa5fa6018, 0x939ca732, 0xc0d1ca8d, - 0x4b4e68fa, 0xb40ca12f, 0x674a41f9, 0x037bb1bb, 0x3ffbb61e, 0x43daedd4, - 0x4bcfc533, 0xf33aaf30, 0xdbf846ce, 0x692b2ce5, 0x1ec3cfac, 0xde63dfef, - 0x0555d3e9, 0x683fd1db, 0xfef95b73, 0x94dc5787, 0xff47bd01, 0xb78d234d, - 0xb05a28ae, 0x0ae994b9, 0xcc7622bb, 0xc86e6efc, 0x4fc6bb66, 0xb83553e6, - 0xe3a4d4ba, 0x02b67384, 0xc1aeb7fd, 0xdb261b3e, 0xfc795816, 0x57f7b94a, - 0xf7a627d8, 0x0aeb29da, 0xd98bd0bc, 0xf3cabef5, 0xa66eff02, 0x80f79e5e, - 0xdf649dc3, 0x822bcb47, 0x45c59bb0, 0x07cf36b3, 0xd9ba767f, 0xf5bb3fbc, - 0x51e7c87e, 0xc14e94d3, 0xb8099731, 0xf3fdc410, 0x452e953e, 0x716c30ec, - 0x7f993299, 0x2b22b538, 0x194eebc0, 0xb8da7df7, 0x7dc633ef, 0xd5fdc3bf, - 0xfdcbbedc, 0x1fb88768, 0x9e988aed, 0xd085a34d, 0x0da7f05f, 0xef44792f, - 0xa3a0f9a3, 0x3b0e5a66, 0xd33f025c, 0x81bf27f1, 0x5ca278e5, 0x036ee397, - 0x6b6e867f, 0x85d7d3e8, 0x858b4f84, 0x4bffb0bc, 0x9f609f58, 0xf5f175b1, - 0x9bb2ed24, 0xe7c29029, 0x20b6c3a0, 0x895344f4, 0x0ecb5f80, 0x692e08e7, - 0xcf8ab329, 0x017a644f, 0xabd29e09, 0xae5e7d56, 0x85fc216b, 0x8cfb2475, - 0x9980d504, 0x399fc4ed, 0xf2c99854, 0x167e188e, 0x49fd0fa3, 0xcff6fc13, - 0xd7db9a67, 0xfe7cfd14, 0x13854365, 0xa9b15eb0, 0x4eff33b0, 0xe1acfc7d, - 0x0699fe87, 0x943ce33f, 0x7dc7ca12, 0xce1d8f44, 0x2ee987bf, 0x1ead787b, - 0x8285c207, 0x5c2e14df, 0x42549c06, 0xd44dc8e7, 0xaf7dfc77, 0x47d027e9, - 0xfdd079e8, 0xd3af7fc7, 0x6739df4a, 0x50a4f8e2, 0xfd04e2be, 0x3df74181, - 0x409dc13f, 0x87395f9b, 0xdfa6cb71, 0x3327ab7b, 0xa783586e, 0xff37603b, - 0xed97dba2, 0xd027ff40, 0x2b11cb5b, 0x0f2b2ec1, 0x0af67ff4, 0x3bf4b78f, - 0xa8fb80dc, 0xbbe88667, 0xc7dec8f3, 0x7d236f61, 0xae87f166, 0xfe7bbffd, - 0x25679911, 0x35bd5b98, 0xcfbc4a54, 0xe37fe3d1, 0xb49f6135, 0x6fd015d0, - 0x39179c57, 0xfeea27ea, 0xa9f1543d, 0xf5bd0037, 0xc46bf81f, 0x0a0cfab5, - 0x65e96ec0, 0xe46647be, 0x6a86f57b, 0xc771e12a, 0x6ff04ad0, 0x86eac97b, - 0xcd5efa9d, 0x5f1f84a9, 0xfb14ccf3, 0x3bb1be6b, 0x3d57711f, 0x23cf6fba, - 0x23679859, 0xc99edbc8, 0xf57ac476, 0xdd163b69, 0x6bb7f72f, 0xf7206fcf, - 0x64ed1b3e, 0x03cccd3e, 0x99ef35fb, 0xd1f00c1d, 0xe3fafb5e, 0x1a87b895, - 0xe83db9ed, 0xa6dbb2bf, 0x2d670f42, 0xf8728c9e, 0xbbb359e1, 0xba0ceb17, - 0x2ea27879, 0x56a45a4f, 0x3bab2fee, 0x37d7711f, 0x80bfe1f1, 0xf75af5dc, - 0x3ce2cff3, 0x3884ad7b, 0xeb1f6171, 0xe85dd78d, 0x2dc7cf35, 0x9873ec8f, - 0x94972f60, 0x82cf95ee, 0xef3eaf7f, 0xf45bad92, 0x439de819, 0x11e78fd8, - 0x6525f2e2, 0x85ff527b, 0x5e25bdde, 0x97c5dfd6, 0x09bd8bea, 0x17f31bf6, - 0x526b6edf, 0x6024147c, 0xbf19f25c, 0x3b2019c9, 0x8366dfc7, 0x99e878bc, - 0xbe296791, 0x737ee2fe, 0x6a3ac2d8, 0x94e6d2b6, 0xf83fb8cc, 0x0ebcfef2, - 0x3ba9f3e7, 0x34c7910a, 0x84ac882f, 0x51b05c5f, 0x7bcf2e4a, 0xbe5f88db, - 0x2a971b83, 0x4f2ddf25, 0xc7ee854d, 0x38f57357, 0x16c07576, 0x1ddf280c, - 0x83a3fe8f, 0x8eccef9c, 0x67af77d3, 0x7e71297e, 0xad425b6f, 0x2db7de6e, - 0x738fc753, 0xe33f7f3c, 0xcfb19558, 0xe79287aa, 0x299152df, 0x8966d3f6, - 0xc60e2214, 0x88ac2ff8, 0x10a45ae1, 0x5d763578, 0xe013d23d, 0xe08acbc8, - 0xf2a0ef88, 0xa86e96a1, 0x4fae3b34, 0xa8204a5f, 0x0f7f8c95, 0x7b8c8bb9, - 0x55ef5e60, 0xdbe57ee8, 0x98d8f36f, 0x246a4b4f, 0xab53791d, 0x7c8e9223, - 0x46a8e468, 0xcbeb8d3b, 0x199ff18a, 0x4649afdf, 0xf6643fb8, 0x8fdbc6d8, - 0x6f3c438f, 0x2ab37e1d, 0xfdd0a93e, 0x4d2069a6, 0x646723f6, 0xe9b6ec11, - 0x3875e4b9, 0x1fc133a7, 0x65760647, 0x8fe2137b, 0xaa3b90cf, 0x137e287c, - 0x7ca3fafd, 0xa54f81d8, 0xf6ab0acd, 0x65b1af22, 0x3a294d0a, 0xe5b1b01d, - 0xa7b4befb, 0x5e2e7ec2, 0x1e3f156d, 0x73822251, 0x0aae27b9, 0x23988c3e, - 0xca8e7382, 0x18fc11ff, 0x09591099, 0xb4adcadc, 0xc9f196af, 0x1e2e9591, - 0xa0c2b2ff, 0x03e491a7, 0x57322785, 0xb5ea4f03, 0x3711b7d1, 0x09d99769, - 0x7be9893f, 0xa227a19d, 0x783b86c7, 0xb3410ffc, 0x4e61f10b, 0x0be462a5, - 0xb5f9f896, 0x908d3fb8, 0xf841c0eb, 0xdddd9367, 0xfdc1a32b, 0xbc1f20af, - 0xe5dddb33, 0x326f5eba, 0xcacae587, 0xee2d6afc, 0xfbdd3b29, 0xdfcc158f, - 0x07c91c5f, 0x4bb5b1ce, 0xdd7b6a1c, 0x47fb13ba, 0x807ba3cd, 0xde1c175f, - 0x9f582b27, 0xada196ad, 0x67d22ca5, 0xa429c8e6, 0x6f604bf8, 0xbdba2382, - 0xb2ef148d, 0x561e9f08, 0x9767eb2a, 0x4b940f71, 0xa1f603b4, 0xe6fcf7e8, - 0x00efabc0, 0x6686466f, 0xf58f4e09, 0x4f030ba7, 0x3e3703a6, 0x981ef8e0, - 0x60ffef13, 0xfa0b5ef5, 0xc3b8bf97, 0x9ef6e112, 0xbbe7c9cd, 0x0cf6ed7c, - 0x9e3d0bf8, 0xec7b0fd0, 0xeac7a649, 0x4e197605, 0xe88083f2, 0x29c79cfd, - 0x0e54b7f2, 0xdf0f41b5, 0xd698cbd2, 0x6313e812, 0xa9f331e8, 0xce1fcf41, - 0xb6f84879, 0x430f0b4e, 0xcc07236f, 0xe4ef7c04, 0x7f7426b8, 0x1aef105a, - 0xadc700f5, 0x216e3d2c, 0x0fa4b45e, 0x8cbdc4ad, 0x989d5bf4, 0xa7c8e9bf, - 0xdb3f38f9, 0xdbce3e63, 0x3670e472, 0xf78dcec1, 0x6cc7c704, 0x1ff4b78c, - 0x24bbc6c9, 0x86aadfd6, 0x4717210a, 0x47e012b8, 0x85afdfac, 0x8b7f210b, - 0xf1825432, 0xf996e428, 0x49a06b4c, 0xe8aad1ce, 0x34474f7e, 0xf7b1f9c1, - 0x6e8551f6, 0x250f8caf, 0x1d3707c8, 0xb11254bd, 0xd9a0f1c7, 0xe81395c0, - 0xdffdd62f, 0x09c0c8b9, 0xbf0cda5e, 0xbc27071f, 0xf5a3dc31, 0xae7dc816, - 0xb63b9742, 0x3bcaf85e, 0x6de32023, 0x992a5daf, 0xc6758c59, 0xa3c04a3c, - 0x017c7159, 0x0e0ae40e, 0xf367326c, 0x2bcf7cb9, 0xd25e4eee, 0x96b1b8dc, - 0xd33ad3a7, 0x6bd0b5fd, 0x5de40513, 0xb1ae5637, 0x8570f476, 0x553ebf7e, - 0xf6fb8f7f, 0x964ec128, 0x7d6322eb, 0x9bc17cee, 0x5d67f030, 0xf85ac6f5, - 0x7e597ddf, 0xf9bbe24b, 0xedaff887, 0xadd7a649, 0x339b58df, 0x1efb9f8e, - 0x126a7eda, 0xd9afcf5d, 0xdb36a3bb, 0x4c7f7d75, 0x98b68bee, 0x49e6959c, - 0xbe58fa89, 0xb71276b1, 0xaffe52eb, 0x7dcfd0fa, 0x8c3588f1, 0xb5facbb8, - 0xfdb7fce0, 0x0925bd71, 0x5f807fb7, 0x9d6b0533, 0xfe5bbe33, 0x12ab6db1, - 0x4f80561e, 0xe2bd5fec, 0x0937ec67, 0x18aa6dfb, 0x5a68a753, 0x37791d3d, - 0x4f4f5779, 0x6d8c53ac, 0xa8a72819, 0x49bd88b7, 0xd2b87ecb, 0x623e8e3d, - 0xd4ae6ff3, 0x864d9f64, 0x6fa94f1d, 0x1e15e679, 0x53ccb97f, 0x557ec956, - 0xbf92a9ae, 0xa6a7dd8f, 0x860fcf52, 0x80bf1db2, 0xcd07453d, 0xb949f84e, - 0x4f33eba6, 0xfc2efcbd, 0xe1db2f31, 0x357e64ea, 0xbcfa6955, 0xea273663, - 0x5f63d140, 0xffe07be5, 0xa5cbec5b, 0xd3b262ce, 0x953f1e64, 0x3df0573b, - 0xc6c7cfb6, 0x7aa5693e, 0x645ed3be, 0x533afefe, 0x3adbe3b1, 0xc51be493, - 0x12d9c169, 0xf890bf87, 0xe85c1d16, 0xf7c05cd4, 0xd6fe1da0, 0x677ff5fe, - 0x0c8f0e23, 0x0bba67fe, 0xd3ed75b8, 0xb6cfd874, 0x81d38f81, 0x6606270f, - 0x1d9ed039, 0x1fd03972, 0x16b8fbad, 0x368cbaf3, 0x8b30675e, 0xf636b19c, - 0x13d58e7e, 0xcdd1de12, 0x73af6bd0, 0x614b2fdb, 0x82dda9ef, 0xce8efc63, - 0xd788fc44, 0xe3395c19, 0xeb1265d5, 0xf5b3050c, 0xd45a033a, 0x7acc0a19, - 0xea34019d, 0x6751680c, 0x0cea3f40, 0x006751a0, 0x68033a8d, 0xa2d019d4, - 0x2bfe80ce, 0xbcb16ba8, 0x50de4e51, 0xecd1aadf, 0xf40fff82, 0xf5e4416a, - 0x74d31c0f, 0xc412877a, 0xfbc67f7d, 0xaf460e23, 0x28b075e8, 0xe77953c7, - 0xfbcb341f, 0x5eda1a20, 0xd6f71337, 0x5571b9af, 0xd9371117, 0xa3cddb14, - 0x6a1f5127, 0x1bdc53ef, 0x2e5fe85d, 0x5c1b6c72, 0xfa237ef8, 0xd56ecd7b, - 0x9abafb85, 0x6f97fa8d, 0x58ea57b0, 0x2cc739d5, 0x15fbcf72, 0xeffde1ca, - 0x64efeab0, 0x2cbdc6bf, 0x9545b0f7, 0x1d6fda3c, 0xcb4bf792, 0x4d738a8b, - 0x7eda1e42, 0x1382e7cb, 0x9df4b69d, 0xb21fd790, 0xc524d739, 0x7de48f57, - 0xc174fc7e, 0x45433c8d, 0xa7d5af4c, 0x7b5edf90, 0xf9213801, 0xb47e4248, - 0x33fcd9d6, 0x5da467e4, 0x7efce133, 0x644ee87e, 0x6d3dd6f9, 0xb09228fe, - 0x9930737f, 0x6df60df6, 0x99c823cd, 0x034a8fdc, 0x943fb2e2, 0x74aa1fdc, - 0xc6927d64, 0x3cd1e63f, 0xff755be4, 0x3f40e6b4, 0xdbb977ef, 0x61caf92a, - 0x2570f78f, 0xb349f1fb, 0x272fea47, 0xbde4d98f, 0x9cfb7e75, 0x8d4bfaa4, - 0x1fea5536, 0xc48acc1b, 0xdee52bf1, 0xaacbb063, 0xeea57bba, 0x10eb9552, - 0xe1d98e7f, 0x3786f2d1, 0x5cc377c0, 0x6abfd497, 0xe10bf4ac, 0xf72f7ec7, - 0x7f16683c, 0x8254e9ab, 0xc9abd32a, 0xad7f816d, 0x3d8a7562, 0x298fed99, - 0x78ab0fec, 0xbb04c6af, 0x915db0da, 0x100a42bc, 0x8695e7ac, 0xfe0d573e, - 0xfb0a57eb, 0x3d56bdcb, 0x5553ce0f, 0xc5d79fe1, 0xdfe78b71, 0xfc0b5e47, - 0x55c71d66, 0x5f671cb4, 0x37bf708f, 0x9ebe6a6d, 0xc072bbe7, 0x3319f57f, - 0x726a4f01, 0x95e85e7e, 0xfced5f78, 0x095bef84, 0x737da5df, 0xa8e1f7d3, - 0xc8493e89, 0x759a4f6b, 0xca7d61fc, 0xec14eb7b, 0x5e3eea55, 0x3474cf69, - 0x8ca2bb49, 0x340bffc4, 0xe02f6f3d, 0x4a6672bb, 0xeb0fa2dd, 0x6eedda6b, - 0x0b863fe8, 0xbefc8dbb, 0xe796e540, 0x5bd54eed, 0xdc29d30b, 0xca5b8d3f, - 0xe7617e14, 0x5c71d47c, 0x3d4f3fc2, 0x7d05c0bb, 0x4377697c, 0xc739351f, - 0x31dde1e6, 0x72ffe0cb, 0xdc55c359, 0x029d2797, 0x438f9fd8, 0x5adfacdd, - 0x5d41481c, 0x50d1e43d, 0x38a63f27, 0x1ebfaef1, 0x716fb74f, 0x140acfc2, - 0xb5b7ea27, 0xd935dda9, 0xe676bfcc, 0x9cf0370c, 0x61ea55f1, 0x76eadc23, - 0x53506b70, 0x6ca6b5f4, 0xff0df3d4, 0x54a6f729, 0xd7f78a4d, 0x1d147e1b, - 0xf11d22fc, 0x6dd447f5, 0x807f8377, 0x835eee6c, 0xfea0ec3f, 0xbf5269a6, - 0xe5d1d98d, 0x613b39fd, 0xf4ab5347, 0xef8d8d75, 0x0c4f9199, 0xc1cde6dd, - 0x7cd72bfe, 0xce5b25be, 0x8cbd7e39, 0xb8033771, 0x165eb63b, 0x463df1c3, - 0x6b781dfd, 0x26baea32, 0x326baea3, 0xa326baea, 0xea326bae, 0xaea326ba, - 0xbaea326b, 0x6baea326, 0x26baea32, 0x97ae13a9, 0x878eddf6, 0x08ea1da4, - 0xbc4278c8, 0xc7eab9b8, 0x55175dd5, 0xa577538d, 0xc4865714, 0xbd7bf65d, - 0xcea63dde, 0x26aefeca, 0xe0d57bf8, 0x431e7b84, 0x7163d25e, 0x6b5438b3, - 0x603c16f1, 0x54f07c17, 0x8d6f5b8d, 0xf52ecfe9, 0x9b64cbd9, 0x2ca87b8f, - 0x5152659a, 0x23ee34c7, 0xdf84ef56, 0x1bf09ce0, 0xd31bf0b4, 0xfcdfb8ec, - 0x5daec2d6, 0x0109e7aa, 0x726c13c9, 0x32375bbf, 0x2f7d30ae, 0xe5709339, - 0xc2b831b3, 0x90159a0f, 0x95a0ed63, 0x233f74ba, 0x37254ff8, 0x0e3f9c7f, - 0x9c7484ce, 0xda1a9699, 0xb5a67d87, 0x1791baa5, 0x9d8bbfb3, 0x88a6dc9d, - 0x06a1afbf, 0xbc1c77d9, 0x7c9e4749, 0x73d1c4ef, 0xf7f9e1bf, 0xf25d83fe, - 0xd793ad9d, 0xe0fffa2e, 0xae954d4d, 0x84775f8f, 0x9659e77d, 0x43b654ea, - 0x16d5578e, 0xb8ba922a, 0x50fe2a9a, 0x58ae3da3, 0xd377a380, 0xb577dc3c, - 0xc839e1b5, 0x2efec399, 0xa32cdfef, 0x6a1a6bbe, 0xd9f4cbde, 0xbe373cec, - 0x3dcd4dab, 0x800b0544, 0xb0c57547, 0xadd4b3ab, 0x1963dd60, 0xbf83bfde, - 0xa7cc5edc, 0x96fee356, 0xb3b69753, 0xce63ee4b, 0x32fbdc42, 0xf51fabab, - 0x9e6f2d86, 0xb2c27a90, 0xd442d70c, 0x79bcb61b, 0x5c73a75a, 0xe51b8afd, - 0xabab13b2, 0x66f8827f, 0x109f3eeb, 0x09a1fd67, 0xc0fb7449, 0x09f3eee4, - 0x3f05ae71, 0x3f4e9df8, 0xafb84c53, 0x5c944356, 0xf21dbbd5, 0x4bfeebf9, - 0xa8d3cf7f, 0xaaa7c9c4, 0x749c5c74, 0xe7b0c282, 0xf90ec5d1, 0x713397fe, - 0xdbd43cfd, 0x10b5d8a8, 0xfdaf38f3, 0xe2f8ec35, 0xc1a79ead, 0x7738cf27, - 0x3579f10e, 0x0d90c758, 0xbbe319ed, 0xdbd529e4, 0x3d36b688, 0x357e9260, - 0x6df68a58, 0xfa20f435, 0x81762fd9, 0xf393ed4f, 0x3a622c6e, 0xb79a1acf, - 0xe9788ede, 0x73fe8dd9, 0xec5e9e65, 0xdfeeb637, 0xe58f9c69, 0xc37987d9, - 0xf9e4aa85, 0x6dea37c3, 0x55c22ecc, 0x371d0e3a, 0x93aca8fc, 0x58e7fbe4, - 0xa55e39fb, 0xfdf9781a, 0x47bcb372, 0x7e4c4f20, 0x0a5d5eea, 0xa3de5879, - 0x61afbc86, 0x5299ec9c, 0x7b6ef98f, 0xc77ec80d, 0x7c653b0d, 0xe3af396c, - 0xa685b4a3, 0x0de404e0, 0x4e0d1e53, 0x7653bc80, 0xdc5cda8c, 0xb51810be, - 0xe1787f21, 0xe86d476f, 0x7543c17f, 0x56bfe1e3, 0xc2df09ad, 0x3f5951b2, - 0x921af79d, 0x04e8c277, 0x4d856fe4, 0x6c02596f, 0xe69e73b7, 0xb7f2937d, - 0xd3638922, 0xfe9a5b0d, 0x87b04aa8, 0xe490cfe9, 0x259d54ab, 0xdd14bee3, - 0x3e8f7dff, 0x6e8ec2a8, 0x09dcb208, 0x69e737f6, 0x1248e5d3, 0x6bacb0df, - 0xf3837031, 0x3f71a4b5, 0x3cbe4733, 0xe423c0c5, 0x378c8d8f, 0xbeb7a6fe, - 0x79c8be42, 0x8c7e18dc, 0x261c314d, 0xebef5dc4, 0x20fc1711, 0xbbdade79, - 0xf78ad91e, 0x76e3536d, 0xd78fbc8b, 0xdb456df4, 0x259efada, 0x4cbf2487, - 0x65f9cf9a, 0x9c9d7d12, 0x7b68e463, 0x39adf3f0, 0x76cbece3, 0x0ed12d70, - 0x37439a4e, 0xd27abde0, 0x480eea9f, 0x0fdd091c, 0x6ad9d97c, 0xecae2377, - 0xd8a555fa, 0xa9f5b7d7, 0xfaa98f32, 0xa751d947, 0x52540fcc, 0x87e6fc11, - 0xe1e011da, 0x0c3c24ec, 0x8972dd48, 0xddae7043, 0xadb60778, 0x123e4a71, - 0x5336ebf3, 0x98adc3e8, 0xef90e597, 0x45b70c11, 0x6f7c2ca6, 0x4aeee29a, - 0x2ece2bc8, 0x9d041599, 0x830a19dd, 0x15cfe8ef, 0xd5c8ea37, 0xd6ae3a69, - 0x7bad0da8, 0x352dfc79, 0x5bf1b82c, 0x6ff307e0, 0x7697acb7, 0xb14cd945, - 0x290a5cdb, 0x7067fffa, 0x3d7bc42d, 0x67ad3df6, 0x20efb05b, 0xf04afbde, - 0x8fa8b599, 0xe45d95fe, 0x80d50689, 0x33d3cf99, 0x7bb70481, 0xb8942cee, - 0xc686a513, 0x2cff91fb, 0x6a3a954f, 0x13d704cf, 0xd3da6ef8, 0xf5e4a37c, - 0xc7a4fe87, 0x29a5d1fb, 0x3d71e46e, 0x711b5cf3, 0x5d479eae, 0xa29afe32, - 0xa13c0bf3, 0xa967a7eb, 0xe69ece7e, 0xc59f794c, 0x8767a1ee, 0xbfbe3267, - 0xe5bc3259, 0x1803a8d5, 0x667b1fdf, 0x4fb73f70, 0xde770d29, 0x75733e07, - 0xb9945779, 0xde4edee4, 0x7b13e379, 0xf1867d74, 0x897dac1d, 0xfefde923, - 0xcb80febf, 0x002220b3, 0x00000000 -}; - -#endif /*__BNX2X_INIT_VALUES_H__*/ -- GitLab From 56ed4351c2604c221a82276f51e5dfd467921bf3 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Mon, 27 Apr 2009 03:28:25 -0700 Subject: [PATCH 0753/6080] bnx2x: driver version 1.48.105-1 Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index cdc80e0820cd..a669bb7eb00c 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -56,8 +56,8 @@ #include "bnx2x_init_ops.h" #include "bnx2x_dump.h" -#define DRV_MODULE_VERSION "1.48.105" -#define DRV_MODULE_RELDATE "2009/03/02" +#define DRV_MODULE_VERSION "1.48.105-1" +#define DRV_MODULE_RELDATE "2009/04/22" #define BNX2X_BC_VER 0x040200 #include -- GitLab From 7bd0f2f5fc5f51d351228488dfef5e33d28e8d0c Mon Sep 17 00:00:00 2001 From: dmitry pervushin Date: Mon, 27 Apr 2009 10:35:04 +0100 Subject: [PATCH 0754/6080] [ARM] 5483/1: Freescale STMP: add Kconfig/Makefile entries Added Kconfig/Makefile entries for STMP platform Signed-off-by: dmitry pervushin Signed-off-by: Russell King --- arch/arm/Kconfig | 15 +++++++++++++++ arch/arm/Makefile | 3 +++ 2 files changed, 18 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a930e5c5672c..d17c801a1704 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -302,6 +302,19 @@ config ARCH_MXC help Support for Freescale MXC/iMX-based family of processors +config ARCH_STMP3XXX + bool "Freescale STMP3xxx" + select CPU_ARM926T + select HAVE_CLK + select COMMON_CLKDEV + select ARCH_REQUIRE_GPIOLIB + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select GENERIC_GPIO + select USB_ARCH_HAS_EHCI + help + Support for systems based on the Freescale 3xxx CPUs. + config ARCH_NETX bool "Hilscher NetX based" select CPU_ARM926T @@ -679,6 +692,8 @@ source "arch/arm/mach-s3c6400/Kconfig" source "arch/arm/mach-s3c6410/Kconfig" endif +source "arch/arm/plat-stmp3xxx/Kconfig" + source "arch/arm/mach-lh7a40x/Kconfig" source "arch/arm/mach-imx/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 885a83724b9c..9a0af472c7d4 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -149,6 +149,8 @@ machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 machine-$(CONFIG_ARCH_SA1100) := sa1100 machine-$(CONFIG_ARCH_SHARK) := shark +machine-$(CONFIG_ARCH_STMP378X) := stmp378x +machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx machine-$(CONFIG_ARCH_VERSATILE) := versatile machine-$(CONFIG_ARCH_W90X900) := w90x900 machine-$(CONFIG_FOOTBRIDGE) := footbridge @@ -162,6 +164,7 @@ plat-$(CONFIG_PLAT_ORION) := orion plat-$(CONFIG_PLAT_PXA) := pxa plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c +plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx ifeq ($(CONFIG_ARCH_EBSA110),y) # This is what happens if you forget the IOCS16 line. -- GitLab From edbd9e30306067c3a45c035eb95a6f49daaa2337 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 27 Apr 2009 05:44:29 -0700 Subject: [PATCH 0755/6080] gro: Fix handling of headers that extend over the tail The skb_gro_* code fails to handle the case where a header starts in the linear area but ends in the frags area. Since the goal of skb_gro_* is to optimise the case of completely non-linear packets, we can simply bail out if we have anything in the linear area. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- net/core/dev.c | 11 +++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 31167451d08d..c9ef41916071 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1137,7 +1137,7 @@ static inline void skb_gro_reset_offset(struct sk_buff *skb) static inline void *skb_gro_mac_header(struct sk_buff *skb) { - return skb_mac_header(skb) < skb->data ? skb_mac_header(skb) : + return skb_headlen(skb) ? skb_mac_header(skb) : page_address(skb_shinfo(skb)->frags[0].page) + skb_shinfo(skb)->frags[0].page_offset; } diff --git a/net/core/dev.c b/net/core/dev.c index e48c08af76ad..6785b067ad50 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2378,18 +2378,13 @@ void *skb_gro_header(struct sk_buff *skb, unsigned int hlen) unsigned int offset = skb_gro_offset(skb); hlen += offset; - if (hlen <= skb_headlen(skb)) - return skb->data + offset; - - if (unlikely(!skb_shinfo(skb)->nr_frags || - skb_shinfo(skb)->frags[0].size <= - hlen - skb_headlen(skb) || + if (unlikely(skb_headlen(skb) || + skb_shinfo(skb)->frags[0].size < hlen || PageHighMem(skb_shinfo(skb)->frags[0].page))) return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; return page_address(skb_shinfo(skb)->frags[0].page) + - skb_shinfo(skb)->frags[0].page_offset + - offset - skb_headlen(skb); + skb_shinfo(skb)->frags[0].page_offset + offset; } EXPORT_SYMBOL(skb_gro_header); -- GitLab From 36e7b1b8dac1a785abca3a121b6b0b79f1a8d7df Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 27 Apr 2009 05:44:45 -0700 Subject: [PATCH 0756/6080] gro: Fix COMPLETE checksum handling On a brand new GRO skb, we cannot call ip_hdr since the header may lie in the non-linear area. This patch adds the helper skb_gro_network_header to handle this. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/netdevice.h | 7 +++++++ net/ipv4/tcp_ipv4.c | 2 +- net/ipv6/tcp_ipv6.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c9ef41916071..fe20d171acf1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1142,6 +1142,13 @@ static inline void *skb_gro_mac_header(struct sk_buff *skb) skb_shinfo(skb)->frags[0].page_offset; } +static inline void *skb_gro_network_header(struct sk_buff *skb) +{ + return skb_headlen(skb) ? skb_network_header(skb) : + page_address(skb_shinfo(skb)->frags[0].page) + + skb_shinfo(skb)->frags[0].page_offset + skb_network_offset(skb); +} + static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *daddr, const void *saddr, diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5d427f86b414..bda74e8aed7e 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2343,7 +2343,7 @@ void tcp4_proc_exit(void) struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) { - struct iphdr *iph = ip_hdr(skb); + struct iphdr *iph = skb_gro_network_header(skb); switch (skb->ip_summed) { case CHECKSUM_COMPLETE: diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 4b5aa1854260..d9dd94b6bf66 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -943,7 +943,7 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb) struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb) { - struct ipv6hdr *iph = ipv6_hdr(skb); + struct ipv6hdr *iph = skb_gro_network_header(skb); switch (skb->ip_summed) { case CHECKSUM_COMPLETE: -- GitLab From 4a79ba34cada6a5a4ee86ed53aa8a73ba1e6fc51 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 22 Apr 2009 16:31:35 +0200 Subject: [PATCH 0757/6080] ALSA: hda - Add amp initialization for realtek auto mode In the realtek auto-probing mode, the initialization of amp with some magic COEF or EAPD verbs is applied only when the codec SSID has valid values to satisfy the realtek's definition. However, many devices don't provide in that way, thus the device doesn't work as is. This patch allows the same initialization code even if the SSID doesn't pass the bit test. Also, alc_subsystem_id() is changed just to check and define the type, so that it's called in the parser, instead of the initializer. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 239 +++++++++++++++++++++------------- 1 file changed, 145 insertions(+), 94 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 583603f449b4..3a6306302c70 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -253,6 +253,15 @@ enum { /* for GPIO Poll */ #define GPIO_MASK 0x03 +/* extra amp-initialization sequence types */ +enum { + ALC_INIT_NONE, + ALC_INIT_DEFAULT, + ALC_INIT_GPIO1, + ALC_INIT_GPIO2, + ALC_INIT_GPIO3, +}; + struct alc_spec { /* codec parameterization */ struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ @@ -322,6 +331,7 @@ struct alc_spec { /* other flags */ unsigned int no_analog :1; /* digital I/O only */ + int init_amp; /* for virtual master */ hda_nid_t vmaster_nid; @@ -994,74 +1004,21 @@ static void alc888_coef_init(struct hda_codec *codec) AC_VERB_SET_PROC_COEF, 0x3030); } -/* 32-bit subsystem ID for BIOS loading in HD Audio codec. - * 31 ~ 16 : Manufacture ID - * 15 ~ 8 : SKU ID - * 7 ~ 0 : Assembly ID - * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 - */ -static void alc_subsystem_id(struct hda_codec *codec, - unsigned int porta, unsigned int porte, - unsigned int portd) +static void alc_auto_init_amp(struct hda_codec *codec, int type) { - unsigned int ass, tmp, i; - unsigned nid; - struct alc_spec *spec = codec->spec; - - ass = codec->subsystem_id & 0xffff; - if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) - goto do_sku; - - /* - * 31~30 : port conetcivity - * 29~21 : reserve - * 20 : PCBEEP input - * 19~16 : Check sum (15:1) - * 15~1 : Custom - * 0 : override - */ - nid = 0x1d; - if (codec->vendor_id == 0x10ec0260) - nid = 0x17; - ass = snd_hda_codec_get_pincfg(codec, nid); - snd_printd("realtek: No valid SSID, " - "checking pincfg 0x%08x for NID 0x%x\n", - ass, nid); - if (!(ass & 1) && !(ass & 0x100000)) - return; - if ((ass >> 30) != 1) /* no physical connection */ - return; + unsigned int tmp; - /* check sum */ - tmp = 0; - for (i = 1; i < 16; i++) { - if ((ass >> i) & 1) - tmp++; - } - if (((ass >> 16) & 0xf) != tmp) - return; -do_sku: - snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", - ass & 0xffff, codec->vendor_id); - /* - * 0 : override - * 1 : Swap Jack - * 2 : 0 --> Desktop, 1 --> Laptop - * 3~5 : External Amplifier control - * 7~6 : Reserved - */ - tmp = (ass & 0x38) >> 3; /* external Amp control */ - switch (tmp) { - case 1: + switch (type) { + case ALC_INIT_GPIO1: snd_hda_sequence_write(codec, alc_gpio1_init_verbs); break; - case 3: + case ALC_INIT_GPIO2: snd_hda_sequence_write(codec, alc_gpio2_init_verbs); break; - case 7: + case ALC_INIT_GPIO3: snd_hda_sequence_write(codec, alc_gpio3_init_verbs); break; - case 5: /* set EAPD output high */ + case ALC_INIT_DEFAULT: switch (codec->vendor_id) { case 0x10ec0260: snd_hda_codec_write(codec, 0x0f, 0, @@ -1115,7 +1072,7 @@ do_sku: tmp | 0x2010); break; case 0x10ec0888: - /*alc888_coef_init(codec);*/ /* called in alc_init() */ + alc888_coef_init(codec); break; case 0x10ec0267: case 0x10ec0268: @@ -1130,7 +1087,104 @@ do_sku: tmp | 0x3000); break; } - default: + break; + } +} + +static void alc_init_auto_hp(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + if (!spec->autocfg.hp_pins[0]) + return; + + if (!spec->autocfg.speaker_pins[0]) { + if (spec->autocfg.line_out_pins[0]) + spec->autocfg.speaker_pins[0] = + spec->autocfg.line_out_pins[0]; + else + return; + } + + snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | ALC880_HP_EVENT); + spec->unsol_event = alc_sku_unsol_event; +} + +/* check subsystem ID and set up device-specific initialization; + * return 1 if initialized, 0 if invalid SSID + */ +/* 32-bit subsystem ID for BIOS loading in HD Audio codec. + * 31 ~ 16 : Manufacture ID + * 15 ~ 8 : SKU ID + * 7 ~ 0 : Assembly ID + * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 + */ +static int alc_subsystem_id(struct hda_codec *codec, + hda_nid_t porta, hda_nid_t porte, + hda_nid_t portd) +{ + unsigned int ass, tmp, i; + unsigned nid; + struct alc_spec *spec = codec->spec; + + ass = codec->subsystem_id & 0xffff; + if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) + goto do_sku; + + /* invalid SSID, check the special NID pin defcfg instead */ + /* + * 31~30 : port conetcivity + * 29~21 : reserve + * 20 : PCBEEP input + * 19~16 : Check sum (15:1) + * 15~1 : Custom + * 0 : override + */ + nid = 0x1d; + if (codec->vendor_id == 0x10ec0260) + nid = 0x17; + ass = snd_hda_codec_get_pincfg(codec, nid); + snd_printd("realtek: No valid SSID, " + "checking pincfg 0x%08x for NID 0x%x\n", + nid, ass); + if (!(ass & 1) && !(ass & 0x100000)) + return 0; + if ((ass >> 30) != 1) /* no physical connection */ + return 0; + + /* check sum */ + tmp = 0; + for (i = 1; i < 16; i++) { + if ((ass >> i) & 1) + tmp++; + } + if (((ass >> 16) & 0xf) != tmp) + return 0; +do_sku: + snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", + ass & 0xffff, codec->vendor_id); + /* + * 0 : override + * 1 : Swap Jack + * 2 : 0 --> Desktop, 1 --> Laptop + * 3~5 : External Amplifier control + * 7~6 : Reserved + */ + tmp = (ass & 0x38) >> 3; /* external Amp control */ + switch (tmp) { + case 1: + spec->init_amp = ALC_INIT_GPIO1; + break; + case 3: + spec->init_amp = ALC_INIT_GPIO2; + break; + case 7: + spec->init_amp = ALC_INIT_GPIO3; + break; + case 5: + spec->init_amp = ALC_INIT_DEFAULT; break; } @@ -1138,7 +1192,7 @@ do_sku: * when the external headphone out jack is plugged" */ if (!(ass & 0x8000)) - return; + return 1; /* * 10~8 : Jack location * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered @@ -1146,14 +1200,6 @@ do_sku: * 15 : 1 --> enable the function "Mute internal speaker * when the external headphone out jack is plugged" */ - if (!spec->autocfg.speaker_pins[0]) { - if (spec->autocfg.line_out_pins[0]) - spec->autocfg.speaker_pins[0] = - spec->autocfg.line_out_pins[0]; - else - return; - } - if (!spec->autocfg.hp_pins[0]) { tmp = (ass >> 11) & 0x3; /* HP to chassis */ if (tmp == 0) @@ -1163,23 +1209,23 @@ do_sku: else if (tmp == 2) spec->autocfg.hp_pins[0] = portd; else - return; + return 1; } - if (spec->autocfg.hp_pins[0]) - snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC880_HP_EVENT); -#if 0 /* it's broken in some acses -- temporarily disabled */ - if (spec->autocfg.input_pins[AUTO_PIN_MIC] && - spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) - snd_hda_codec_write(codec, - spec->autocfg.input_pins[AUTO_PIN_MIC], 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC880_MIC_EVENT); -#endif /* disabled */ + alc_init_auto_hp(codec); + return 1; +} - spec->unsol_event = alc_sku_unsol_event; +static void alc_ssid_check(struct hda_codec *codec, + hda_nid_t porta, hda_nid_t porte, hda_nid_t portd) +{ + if (!alc_subsystem_id(codec, porta, porte, portd)) { + struct alc_spec *spec = codec->spec; + snd_printd("realtek: " + "Enable default setup for auto mode as fallback\n"); + spec->init_amp = ALC_INIT_DEFAULT; + alc_init_auto_hp(codec); + } } /* @@ -2923,8 +2969,7 @@ static int alc_init(struct hda_codec *codec) unsigned int i; alc_fix_pll(codec); - if (codec->vendor_id == 0x10ec0888) - alc888_coef_init(codec); + alc_auto_init_amp(codec, spec->init_amp); for (i = 0; i < spec->num_init_verbs; i++) snd_hda_sequence_write(codec, spec->init_verbs[i]); @@ -4198,7 +4243,6 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; - alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; int pin_type = get_pin_type(spec->autocfg.line_out_type); @@ -4303,6 +4347,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux[0]; + alc_ssid_check(codec, 0x15, 0x1b, 0x14); + return 1; } @@ -5678,7 +5724,6 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; hda_nid_t nid; - alc_subsystem_id(codec, 0x10, 0x15, 0x0f); nid = spec->autocfg.line_out_pins[0]; if (nid) { int pin_type = get_pin_type(spec->autocfg.line_out_type); @@ -5788,6 +5833,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux[0]; + alc_ssid_check(codec, 0x10, 0x15, 0x0f); + return 1; } @@ -7013,7 +7060,6 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; - alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; int pin_type = get_pin_type(spec->autocfg.line_out_type); @@ -9154,7 +9200,6 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; - alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; int pin_type = get_pin_type(spec->autocfg.line_out_type); @@ -9317,6 +9362,7 @@ static int patch_alc883(struct hda_codec *codec) if (!spec->capsrc_nids) spec->capsrc_nids = alc883_capsrc_nids; spec->capture_style = CAPT_MIX; /* matrix-style capture */ + spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ break; case 0x10ec0889: spec->stream_name_analog = "ALC889 Analog"; @@ -10842,6 +10888,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + alc_ssid_check(codec, 0x15, 0x14, 0x1b); + return 1; } @@ -13925,7 +13973,6 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; - alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; int pin_type = get_pin_type(spec->autocfg.line_out_type); @@ -14008,6 +14055,8 @@ static int alc861_parse_auto_config(struct hda_codec *codec) spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); set_capture_mixer(spec); + alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); + return 1; } @@ -14889,7 +14938,6 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; - alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; int pin_type = get_pin_type(spec->autocfg.line_out_type); @@ -15107,6 +15155,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + alc_ssid_check(codec, 0x15, 0x1b, 0x14); + return 1; } @@ -16931,7 +16981,6 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; - alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; int pin_type = get_pin_type(spec->autocfg.line_out_type); @@ -17028,6 +17077,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + alc_ssid_check(codec, 0x15, 0x1b, 0x14); + return 1; } -- GitLab From 4bc4d8998a472cd64aa66a4abad3d833be901028 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 27 Apr 2009 14:28:44 +0100 Subject: [PATCH 0758/6080] ASoC: Enforce symmetric rates for S3C64xx I2S interface There is only one LRCLK pin on each interface. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c64xx-i2s.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index a84c4bec56b9..c33524803b3e 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -171,6 +171,7 @@ struct snd_soc_dai s3c64xx_i2s_dai[] = { .formats = S3C64XX_I2S_FMTS, }, .ops = &s3c64xx_i2s_dai_ops, + .symmetric_rates = 1, }, { .name = "s3c64xx-i2s", @@ -189,6 +190,7 @@ struct snd_soc_dai s3c64xx_i2s_dai[] = { .formats = S3C64XX_I2S_FMTS, }, .ops = &s3c64xx_i2s_dai_ops, + .symmetric_rates = 1, }, }; EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); -- GitLab From 008db442efa542357314593c71ab9966be909855 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 27 Apr 2009 19:17:08 +0100 Subject: [PATCH 0759/6080] ASoC: Include WM8350 register definitions in CODEC header It's expected behaviour for the CODEC header to provide them but the WM8350 doesn't due to having all the registers together under drivers/mfd. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8350.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h index d11bd9288cf9..d088eb4b88bb 100644 --- a/sound/soc/codecs/wm8350.h +++ b/sound/soc/codecs/wm8350.h @@ -13,6 +13,7 @@ #define _WM8350_H #include +#include extern struct snd_soc_dai wm8350_dai; extern struct snd_soc_codec_device soc_codec_dev_wm8350; -- GitLab From 5c556a6e190897a0f1ff14e13722591828412031 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 27 Apr 2009 20:23:19 +0100 Subject: [PATCH 0760/6080] ASoC: s3c-i2s-v2 diagnostic improvements Say what invalid values we're seeing when we see an invalid value and ensure that errors are displayed by default. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-i2s-v2.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index ab680aac3fcb..aeea49cbe74a 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -105,7 +105,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + break; } writel(con, regs + S3C2412_IISCON); @@ -132,7 +134,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "TXDIS: Invalid MODE %xin IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + break; } writel(mod, regs + S3C2412_IISMOD); @@ -175,7 +179,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); } writel(mod, regs + S3C2412_IISMOD); @@ -199,7 +204,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); } writel(con, regs + S3C2412_IISCON); @@ -281,7 +287,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= IISMOD_MASTER; break; default: - pr_debug("unknwon master/slave format\n"); + pr_err("unknwon master/slave format\n"); return -EINVAL; } @@ -298,7 +304,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= S3C2412_IISMOD_SDF_IIS; break; default: - pr_debug("Unknown data format\n"); + pr_err("Unknown data format\n"); return -EINVAL; } -- GitLab From a7be4d92d989fc53d840d24cba2ebea9e5ad8480 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 27 Apr 2009 20:24:15 +0100 Subject: [PATCH 0761/6080] ASoC: Use our registration function for S3C64xx Make sure we get the DAI operations initialised. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-i2s-v2.c | 18 ++++++------------ sound/soc/s3c24xx/s3c64xx-i2s.c | 2 +- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index aeea49cbe74a..ab680aac3fcb 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -105,9 +105,7 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - break; + dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); } writel(con, regs + S3C2412_IISCON); @@ -134,9 +132,7 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "TXDIS: Invalid MODE %xin IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - break; + dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); } writel(mod, regs + S3C2412_IISMOD); @@ -179,8 +175,7 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); + dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); } writel(mod, regs + S3C2412_IISMOD); @@ -204,8 +199,7 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); + dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); } writel(con, regs + S3C2412_IISCON); @@ -287,7 +281,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= IISMOD_MASTER; break; default: - pr_err("unknwon master/slave format\n"); + pr_debug("unknwon master/slave format\n"); return -EINVAL; } @@ -304,7 +298,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= S3C2412_IISMOD_SDF_IIS; break; default: - pr_err("Unknown data format\n"); + pr_debug("Unknown data format\n"); return -EINVAL; } diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index c33524803b3e..1345fbdca700 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -225,7 +225,7 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) if (ret) goto err_clk; - ret = snd_soc_register_dai(dai); + ret = s3c_i2sv2_register_dai(dai); if (ret != 0) goto err_i2sv2; -- GitLab From 0b5e92c5e020ee7437fa5304a8451d6dd08d1a26 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 27 Apr 2009 13:49:44 +0000 Subject: [PATCH 0762/6080] ASoC WM8940 Driver Signed-off-by: Jonathan Cameron Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm8940.c | 955 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8940.h | 104 +++++ 4 files changed, 1065 insertions(+) create mode 100644 sound/soc/codecs/wm8940.c create mode 100644 sound/soc/codecs/wm8940.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 121d63f13dbb..1c19ad54a9f9 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -35,6 +35,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8900 if I2C select SND_SOC_WM8903 if I2C + select SND_SOC_WM8940 if I2C select SND_SOC_WM8960 if I2C select SND_SOC_WM8971 if I2C select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI @@ -140,6 +141,9 @@ config SND_SOC_WM8900 config SND_SOC_WM8903 tristate +config SND_SOC_WM8940 + tristate + config SND_SOC_WM8960 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 811696861d31..3d31b6bea834 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -23,6 +23,7 @@ snd-soc-wm8750-objs := wm8750.o snd-soc-wm8753-objs := wm8753.o snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o +snd-soc-wm8940-objs := wm8940.o snd-soc-wm8960-objs := wm8960.o snd-soc-wm8971-objs := wm8971.o snd-soc-wm8988-objs := wm8988.o @@ -57,6 +58,7 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o +obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c new file mode 100644 index 000000000000..26987dcd8d55 --- /dev/null +++ b/sound/soc/codecs/wm8940.c @@ -0,0 +1,955 @@ +/* + * wm8940.c -- WM8940 ALSA Soc Audio driver + * + * Author: Jonathan Cameron + * + * Based on wm8510.c + * Copyright 2006 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * + * 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. + * + * Not currently handled: + * Notch filter control + * AUXMode (inverting vs mixer) + * No means to obtain current gain if alc enabled. + * No use made of gpio + * Fast VMID discharge for power down + * Soft Start + * DLR and ALR Swaps not enabled + * Digital Sidetone not supported + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm8940.h" + +struct wm8940_priv { + unsigned int sysclk; + u16 reg_cache[WM8940_CACHEREGNUM]; + struct snd_soc_codec codec; +}; + +static u16 wm8940_reg_defaults[] = { + 0x8940, /* Soft Reset */ + 0x0000, /* Power 1 */ + 0x0000, /* Power 2 */ + 0x0000, /* Power 3 */ + 0x0010, /* Interface Control */ + 0x0000, /* Companding Control */ + 0x0140, /* Clock Control */ + 0x0000, /* Additional Controls */ + 0x0000, /* GPIO Control */ + 0x0002, /* Auto Increment Control */ + 0x0000, /* DAC Control */ + 0x00FF, /* DAC Volume */ + 0, + 0, + 0x0100, /* ADC Control */ + 0x00FF, /* ADC Volume */ + 0x0000, /* Notch Filter 1 Control 1 */ + 0x0000, /* Notch Filter 1 Control 2 */ + 0x0000, /* Notch Filter 2 Control 1 */ + 0x0000, /* Notch Filter 2 Control 2 */ + 0x0000, /* Notch Filter 3 Control 1 */ + 0x0000, /* Notch Filter 3 Control 2 */ + 0x0000, /* Notch Filter 4 Control 1 */ + 0x0000, /* Notch Filter 4 Control 2 */ + 0x0032, /* DAC Limit Control 1 */ + 0x0000, /* DAC Limit Control 2 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0x0038, /* ALC Control 1 */ + 0x000B, /* ALC Control 2 */ + 0x0032, /* ALC Control 3 */ + 0x0000, /* Noise Gate */ + 0x0041, /* PLLN */ + 0x000C, /* PLLK1 */ + 0x0093, /* PLLK2 */ + 0x00E9, /* PLLK3 */ + 0, + 0, + 0x0030, /* ALC Control 4 */ + 0, + 0x0002, /* Input Control */ + 0x0050, /* PGA Gain */ + 0, + 0x0002, /* ADC Boost Control */ + 0, + 0x0002, /* Output Control */ + 0x0000, /* Speaker Mixer Control */ + 0, + 0, + 0, + 0x0079, /* Speaker Volume */ + 0, + 0x0000, /* Mono Mixer Control */ +}; + +static inline unsigned int wm8940_read_reg_cache(struct snd_soc_codec *codec, + unsigned int reg) +{ + u16 *cache = codec->reg_cache; + + if (reg >= ARRAY_SIZE(wm8940_reg_defaults)) + return -1; + + return cache[reg]; +} + +static inline int wm8940_write_reg_cache(struct snd_soc_codec *codec, + u16 reg, unsigned int value) +{ + u16 *cache = codec->reg_cache; + + if (reg >= ARRAY_SIZE(wm8940_reg_defaults)) + return -1; + + cache[reg] = value; + + return 0; +} + +static int wm8940_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + int ret; + u8 data[3] = { reg, + (value & 0xff00) >> 8, + (value & 0x00ff) + }; + + wm8940_write_reg_cache(codec, reg, value); + + ret = codec->hw_write(codec->control_data, data, 3); + + if (ret < 0) + return ret; + else if (ret != 3) + return -EIO; + return 0; +} + +static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" }; +static const struct soc_enum wm8940_adc_companding_enum += SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding); +static const struct soc_enum wm8940_dac_companding_enum += SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 3, 4, wm8940_companding); + +static const char *wm8940_alc_mode_text[] = {"ALC", "Limiter"}; +static const struct soc_enum wm8940_alc_mode_enum += SOC_ENUM_SINGLE(WM8940_ALC3, 8, 2, wm8940_alc_mode_text); + +static const char *wm8940_mic_bias_level_text[] = {"0.9", "0.65"}; +static const struct soc_enum wm8940_mic_bias_level_enum += SOC_ENUM_SINGLE(WM8940_INPUTCTL, 8, 2, wm8940_mic_bias_level_text); + +static const char *wm8940_filter_mode_text[] = {"Audio", "Application"}; +static const struct soc_enum wm8940_filter_mode_enum += SOC_ENUM_SINGLE(WM8940_ADC, 7, 2, wm8940_filter_mode_text); + +DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1); +DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0); +DECLARE_TLV_DB_SCALE(wm8940_pga_vol_tlv, -1200, 75, 0); +DECLARE_TLV_DB_SCALE(wm8940_alc_min_tlv, -1200, 600, 0); +DECLARE_TLV_DB_SCALE(wm8940_alc_max_tlv, 675, 600, 0); +DECLARE_TLV_DB_SCALE(wm8940_alc_tar_tlv, -2250, 50, 0); +DECLARE_TLV_DB_SCALE(wm8940_lim_boost_tlv, 0, 100, 0); +DECLARE_TLV_DB_SCALE(wm8940_lim_thresh_tlv, -600, 100, 0); +DECLARE_TLV_DB_SCALE(wm8940_adc_tlv, -12750, 50, 1); +DECLARE_TLV_DB_SCALE(wm8940_capture_boost_vol_tlv, 0, 2000, 0); + +static const struct snd_kcontrol_new wm8940_snd_controls[] = { + SOC_SINGLE("Digital Loopback Switch", WM8940_COMPANDINGCTL, + 6, 1, 0), + SOC_ENUM("DAC Companding", wm8940_dac_companding_enum), + SOC_ENUM("ADC Companding", wm8940_adc_companding_enum), + + SOC_ENUM("ALC Mode", wm8940_alc_mode_enum), + SOC_SINGLE("ALC Switch", WM8940_ALC1, 8, 1, 0), + SOC_SINGLE_TLV("ALC Capture Max Gain", WM8940_ALC1, + 3, 7, 1, wm8940_alc_max_tlv), + SOC_SINGLE_TLV("ALC Capture Min Gain", WM8940_ALC1, + 0, 7, 0, wm8940_alc_min_tlv), + SOC_SINGLE_TLV("ALC Capture Target", WM8940_ALC2, + 0, 14, 0, wm8940_alc_tar_tlv), + SOC_SINGLE("ALC Capture Hold", WM8940_ALC2, 4, 10, 0), + SOC_SINGLE("ALC Capture Decay", WM8940_ALC3, 4, 10, 0), + SOC_SINGLE("ALC Capture Attach", WM8940_ALC3, 0, 10, 0), + SOC_SINGLE("ALC ZC Switch", WM8940_ALC4, 1, 1, 0), + SOC_SINGLE("ALC Capture Noise Gate Switch", WM8940_NOISEGATE, + 3, 1, 0), + SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8940_NOISEGATE, + 0, 7, 0), + + SOC_SINGLE("DAC Playback Limiter Switch", WM8940_DACLIM1, 8, 1, 0), + SOC_SINGLE("DAC Playback Limiter Attack", WM8940_DACLIM1, 0, 9, 0), + SOC_SINGLE("DAC Playback Limiter Decay", WM8940_DACLIM1, 4, 11, 0), + SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8940_DACLIM2, + 4, 9, 1, wm8940_lim_thresh_tlv), + SOC_SINGLE_TLV("DAC Playback Limiter Boost", WM8940_DACLIM2, + 0, 12, 0, wm8940_lim_boost_tlv), + + SOC_SINGLE("Capture PGA ZC Switch", WM8940_PGAGAIN, 7, 1, 0), + SOC_SINGLE_TLV("Capture PGA Volume", WM8940_PGAGAIN, + 0, 63, 0, wm8940_pga_vol_tlv), + SOC_SINGLE_TLV("Digital Playback Volume", WM8940_DACVOL, + 0, 255, 0, wm8940_adc_tlv), + SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL, + 0, 255, 0, wm8940_adc_tlv), + SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum), + SOC_SINGLE_TLV("Capture Boost Volue", WM8940_ADCBOOST, + 8, 1, 0, wm8940_capture_boost_vol_tlv), + SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL, + 0, 63, 0, wm8940_spk_vol_tlv), + SOC_SINGLE("Speaker Playback Switch", WM8940_SPKVOL, 6, 1, 1), + + SOC_SINGLE_TLV("Speaker Mixer Line Bypass Volume", WM8940_SPKVOL, + 8, 1, 1, wm8940_att_tlv), + SOC_SINGLE("Speaker Playback ZC Switch", WM8940_SPKVOL, 7, 1, 0), + + SOC_SINGLE("Mono Out Switch", WM8940_MONOMIX, 6, 1, 1), + SOC_SINGLE_TLV("Mono Mixer Line Bypass Volume", WM8940_MONOMIX, + 7, 1, 1, wm8940_att_tlv), + + SOC_SINGLE("High Pass Filter Switch", WM8940_ADC, 8, 1, 0), + SOC_ENUM("High Pass Filter Mode", wm8940_filter_mode_enum), + SOC_SINGLE("High Pass Filter Cut Off", WM8940_ADC, 4, 7, 0), + SOC_SINGLE("ADC Inversion Switch", WM8940_ADC, 0, 1, 0), + SOC_SINGLE("DAC Inversion Switch", WM8940_DAC, 0, 1, 0), + SOC_SINGLE("DAC Auto Mute Switch", WM8940_DAC, 2, 1, 0), + SOC_SINGLE("ZC Timeout Clock Switch", WM8940_ADDCNTRL, 0, 1, 0), +}; + +static const struct snd_kcontrol_new wm8940_speaker_mixer_controls[] = { + SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_SPKMIX, 1, 1, 0), + SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_SPKMIX, 5, 1, 0), + SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_SPKMIX, 0, 1, 0), +}; + +static const struct snd_kcontrol_new wm8940_mono_mixer_controls[] = { + SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_MONOMIX, 1, 1, 0), + SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_MONOMIX, 2, 1, 0), + SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_MONOMIX, 0, 1, 0), +}; + +DECLARE_TLV_DB_SCALE(wm8940_boost_vol_tlv, -1500, 300, 1); +static const struct snd_kcontrol_new wm8940_input_boost_controls[] = { + SOC_DAPM_SINGLE("Mic PGA Switch", WM8940_PGAGAIN, 6, 1, 1), + SOC_DAPM_SINGLE_TLV("Aux Volume", WM8940_ADCBOOST, + 0, 7, 0, wm8940_boost_vol_tlv), + SOC_DAPM_SINGLE_TLV("Mic Volume", WM8940_ADCBOOST, + 4, 7, 0, wm8940_boost_vol_tlv), +}; + +static const struct snd_kcontrol_new wm8940_micpga_controls[] = { + SOC_DAPM_SINGLE("AUX Switch", WM8940_INPUTCTL, 2, 1, 0), + SOC_DAPM_SINGLE("MICP Switch", WM8940_INPUTCTL, 0, 1, 0), + SOC_DAPM_SINGLE("MICN Switch", WM8940_INPUTCTL, 1, 1, 0), +}; + +static const struct snd_soc_dapm_widget wm8940_dapm_widgets[] = { + SND_SOC_DAPM_MIXER("Speaker Mixer", WM8940_POWER3, 2, 0, + &wm8940_speaker_mixer_controls[0], + ARRAY_SIZE(wm8940_speaker_mixer_controls)), + SND_SOC_DAPM_MIXER("Mono Mixer", WM8940_POWER3, 3, 0, + &wm8940_mono_mixer_controls[0], + ARRAY_SIZE(wm8940_mono_mixer_controls)), + SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8940_POWER3, 0, 0), + + SND_SOC_DAPM_PGA("SpkN Out", WM8940_POWER3, 5, 0, NULL, 0), + SND_SOC_DAPM_PGA("SpkP Out", WM8940_POWER3, 6, 0, NULL, 0), + SND_SOC_DAPM_PGA("Mono Out", WM8940_POWER3, 7, 0, NULL, 0), + SND_SOC_DAPM_OUTPUT("MONOOUT"), + SND_SOC_DAPM_OUTPUT("SPKOUTP"), + SND_SOC_DAPM_OUTPUT("SPKOUTN"), + + SND_SOC_DAPM_PGA("Aux Input", WM8940_POWER1, 6, 0, NULL, 0), + SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8940_POWER2, 0, 0), + SND_SOC_DAPM_MIXER("Mic PGA", WM8940_POWER2, 2, 0, + &wm8940_micpga_controls[0], + ARRAY_SIZE(wm8940_micpga_controls)), + SND_SOC_DAPM_MIXER("Boost Mixer", WM8940_POWER2, 4, 0, + &wm8940_input_boost_controls[0], + ARRAY_SIZE(wm8940_input_boost_controls)), + SND_SOC_DAPM_MICBIAS("Mic Bias", WM8940_POWER1, 4, 0), + + SND_SOC_DAPM_INPUT("MICN"), + SND_SOC_DAPM_INPUT("MICP"), + SND_SOC_DAPM_INPUT("AUX"), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + /* Mono output mixer */ + {"Mono Mixer", "PCM Playback Switch", "DAC"}, + {"Mono Mixer", "Aux Playback Switch", "Aux Input"}, + {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"}, + + /* Speaker output mixer */ + {"Speaker Mixer", "PCM Playback Switch", "DAC"}, + {"Speaker Mixer", "Aux Playback Switch", "Aux Input"}, + {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"}, + + /* Outputs */ + {"Mono Out", NULL, "Mono Mixer"}, + {"MONOOUT", NULL, "Mono Out"}, + {"SpkN Out", NULL, "Speaker Mixer"}, + {"SpkP Out", NULL, "Speaker Mixer"}, + {"SPKOUTN", NULL, "SpkN Out"}, + {"SPKOUTP", NULL, "SpkP Out"}, + + /* Microphone PGA */ + {"Mic PGA", "MICN Switch", "MICN"}, + {"Mic PGA", "MICP Switch", "MICP"}, + {"Mic PGA", "AUX Switch", "AUX"}, + + /* Boost Mixer */ + {"Boost Mixer", "Mic PGA Switch", "Mic PGA"}, + {"Boost Mixer", "Mic Volume", "MICP"}, + {"Boost Mixer", "Aux Volume", "Aux Input"}, + + {"ADC", NULL, "Boost Mixer"}, +}; + +static int wm8940_add_widgets(struct snd_soc_codec *codec) +{ + int ret; + + ret = snd_soc_dapm_new_controls(codec, wm8940_dapm_widgets, + ARRAY_SIZE(wm8940_dapm_widgets)); + if (ret) + goto error_ret; + ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + if (ret) + goto error_ret; + ret = snd_soc_dapm_new_widgets(codec); + +error_ret: + return ret; +} + +#define wm8940_reset(c) wm8940_write(c, WM8940_SOFTRESET, 0); + +static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFE67; + u16 clk = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0x1fe; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + clk |= 1; + break; + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + wm8940_write(codec, WM8940_CLOCK, clk); + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface |= (2 << 3); + break; + case SND_SOC_DAIFMT_LEFT_J: + iface |= (1 << 3); + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_DSP_A: + iface |= (3 << 3); + break; + case SND_SOC_DAIFMT_DSP_B: + iface |= (3 << 3) | (1 << 7); + break; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + iface |= (1 << 7); + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= (1 << 8); + break; + case SND_SOC_DAIFMT_IB_IF: + iface |= (1 << 8) | (1 << 7); + break; + } + + wm8940_write(codec, WM8940_IFACE, iface); + + return 0; +} + +static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->card->codec; + u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFD9F; + u16 addcntrl = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFF1; + u16 companding = wm8940_read_reg_cache(codec, + WM8940_COMPANDINGCTL) & 0xFFDF; + int ret; + + /* LoutR control */ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE + && params_channels(params) == 2) + iface |= (1 << 9); + + switch (params_rate(params)) { + case SNDRV_PCM_RATE_8000: + addcntrl |= (0x5 << 1); + break; + case SNDRV_PCM_RATE_11025: + addcntrl |= (0x4 << 1); + break; + case SNDRV_PCM_RATE_16000: + addcntrl |= (0x3 << 1); + break; + case SNDRV_PCM_RATE_22050: + addcntrl |= (0x2 << 1); + break; + case SNDRV_PCM_RATE_32000: + addcntrl |= (0x1 << 1); + break; + case SNDRV_PCM_RATE_44100: + case SNDRV_PCM_RATE_48000: + break; + } + ret = wm8940_write(codec, WM8940_ADDCNTRL, addcntrl); + if (ret) + goto error_ret; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + companding = companding | (1 << 5); + break; + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + iface |= (1 << 5); + break; + case SNDRV_PCM_FORMAT_S24_LE: + iface |= (2 << 5); + break; + case SNDRV_PCM_FORMAT_S32_LE: + iface |= (3 << 5); + break; + } + ret = wm8940_write(codec, WM8940_COMPANDINGCTL, companding); + if (ret) + goto error_ret; + ret = wm8940_write(codec, WM8940_IFACE, iface); + +error_ret: + return ret; +} + +static int wm8940_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u16 mute_reg = wm8940_read_reg_cache(codec, WM8940_DAC) & 0xffbf; + + if (mute) + mute_reg |= 0x40; + + return wm8940_write(codec, WM8940_DAC, mute_reg); +} + +static int wm8940_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + u16 val; + u16 pwr_reg = wm8940_read_reg_cache(codec, WM8940_POWER1) & 0x1F0; + int ret = 0; + + switch (level) { + case SND_SOC_BIAS_ON: + /* ensure bufioen and biasen */ + pwr_reg |= (1 << 2) | (1 << 3); + /* Enable thermal shutdown */ + val = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL); + ret = wm8940_write(codec, WM8940_OUTPUTCTL, val | 0x2); + if (ret) + break; + /* set vmid to 75k */ + ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1); + break; + case SND_SOC_BIAS_PREPARE: + /* ensure bufioen and biasen */ + pwr_reg |= (1 << 2) | (1 << 3); + ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1); + break; + case SND_SOC_BIAS_STANDBY: + /* ensure bufioen and biasen */ + pwr_reg |= (1 << 2) | (1 << 3); + /* set vmid to 300k for standby */ + ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x2); + break; + case SND_SOC_BIAS_OFF: + ret = wm8940_write(codec, WM8940_POWER1, pwr_reg); + break; + } + + return ret; +} + +struct pll_ { + unsigned int pre_scale:2; + unsigned int n:4; + unsigned int k; +}; + +static struct pll_ pll_div; + +/* The size in bits of the pll divide multiplied by 10 + * to allow rounding later */ +#define FIXED_PLL_SIZE ((1 << 24) * 10) +static void pll_factors(unsigned int target, unsigned int source) +{ + unsigned long long Kpart; + unsigned int K, Ndiv, Nmod; + /* The left shift ist to avoid accuracy loss when right shifting */ + Ndiv = target / source; + + if (Ndiv > 12) { + source <<= 1; + /* Multiply by 2 */ + pll_div.pre_scale = 0; + Ndiv = target / source; + } else if (Ndiv < 3) { + source >>= 2; + /* Divide by 4 */ + pll_div.pre_scale = 3; + Ndiv = target / source; + } else if (Ndiv < 6) { + source >>= 1; + /* divide by 2 */ + pll_div.pre_scale = 2; + Ndiv = target / source; + } else + pll_div.pre_scale = 1; + + if ((Ndiv < 6) || (Ndiv > 12)) + printk(KERN_WARNING + "WM8940 N value %d outwith recommended range!d\n", + Ndiv); + + pll_div.n = Ndiv; + Nmod = target % source; + Kpart = FIXED_PLL_SIZE * (long long)Nmod; + + do_div(Kpart, source); + + K = Kpart & 0xFFFFFFFF; + + /* Check if we need to round */ + if ((K % 10) >= 5) + K += 5; + + /* Move down to proper range now rounding is done */ + K /= 10; + + pll_div.k = K; +} + +/* Untested at the moment */ +static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, + int pll_id, unsigned int freq_in, unsigned int freq_out) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 reg; + + /* Turn off PLL */ + reg = wm8940_read_reg_cache(codec, WM8940_POWER1); + wm8940_write(codec, WM8940_POWER1, reg & 0x1df); + + if (freq_in == 0 || freq_out == 0) { + /* Clock CODEC directly from MCLK */ + reg = wm8940_read_reg_cache(codec, WM8940_CLOCK); + wm8940_write(codec, WM8940_CLOCK, reg & 0x0ff); + /* Pll power down */ + wm8940_write(codec, WM8940_PLLN, (1 << 7)); + return 0; + } + + /* Pll is followed by a frequency divide by 4 */ + pll_factors(freq_out*4, freq_in); + if (pll_div.k) + wm8940_write(codec, WM8940_PLLN, + (pll_div.pre_scale << 4) | pll_div.n | (1 << 6)); + else /* No factional component */ + wm8940_write(codec, WM8940_PLLN, + (pll_div.pre_scale << 4) | pll_div.n); + wm8940_write(codec, WM8940_PLLK1, pll_div.k >> 18); + wm8940_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff); + wm8940_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff); + /* Enable the PLL */ + reg = wm8940_read_reg_cache(codec, WM8940_POWER1); + wm8940_write(codec, WM8940_POWER1, reg | 0x020); + + /* Run CODEC from PLL instead of MCLK */ + reg = wm8940_read_reg_cache(codec, WM8940_CLOCK); + wm8940_write(codec, WM8940_CLOCK, reg | 0x100); + + return 0; +} + +static int wm8940_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct wm8940_priv *wm8940 = codec->private_data; + + switch (freq) { + case 11289600: + case 12000000: + case 12288000: + case 16934400: + case 18432000: + wm8940->sysclk = freq; + return 0; + } + return -EINVAL; +} + +static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai, + int div_id, int div) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 reg; + int ret = 0; + + switch (div_id) { + case WM8940_BCLKDIV: + reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFFEF3; + ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 2)); + break; + case WM8940_MCLKDIV: + reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFF1F; + ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 5)); + break; + case WM8940_OPCLKDIV: + reg = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFCF; + ret = wm8940_write(codec, WM8940_ADDCNTRL, reg | (div << 4)); + break; + } + return ret; +} + +#define WM8940_RATES SNDRV_PCM_RATE_8000_48000 + +#define WM8940_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8940_dai_ops = { + .hw_params = wm8940_i2s_hw_params, + .set_sysclk = wm8940_set_dai_sysclk, + .digital_mute = wm8940_mute, + .set_fmt = wm8940_set_dai_fmt, + .set_clkdiv = wm8940_set_dai_clkdiv, + .set_pll = wm8940_set_dai_pll, +}; + +struct snd_soc_dai wm8940_dai = { + .name = "WM8940", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8940_RATES, + .formats = WM8940_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8940_RATES, + .formats = WM8940_FORMATS, + }, + .ops = &wm8940_dai_ops, + .symmetric_rates = 1, +}; +EXPORT_SYMBOL_GPL(wm8940_dai); + +static int wm8940_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + + return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF); +} + +static int wm8940_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->card->codec; + int i; + int ret; + u8 data[3]; + u16 *cache = codec->reg_cache; + + /* Sync reg_cache with the hardware + * Could use auto incremented writes to speed this up + */ + for (i = 0; i < ARRAY_SIZE(wm8940_reg_defaults); i++) { + data[0] = i; + data[1] = (cache[i] & 0xFF00) >> 8; + data[2] = cache[i] & 0x00FF; + ret = codec->hw_write(codec->control_data, data, 3); + if (ret < 0) + goto error_ret; + else if (ret != 3) { + ret = -EIO; + goto error_ret; + } + } + ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + if (ret) + goto error_ret; + ret = wm8940_set_bias_level(codec, codec->suspend_bias_level); + +error_ret: + return ret; +} + +static struct snd_soc_codec *wm8940_codec; + +static int wm8940_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec; + + int ret = 0; + + if (wm8940_codec == NULL) { + dev_err(&pdev->dev, "Codec device not registered\n"); + return -ENODEV; + } + + socdev->card->codec = wm8940_codec; + codec = wm8940_codec; + + mutex_init(&codec->mutex); + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + dev_err(codec->dev, "failed to create pcms: %d\n", ret); + goto pcm_err; + } + + ret = snd_soc_add_controls(codec, wm8940_snd_controls, + ARRAY_SIZE(wm8940_snd_controls)); + if (ret) + goto error_free_pcms; + ret = wm8940_add_widgets(codec); + if (ret) + goto error_free_pcms; + + ret = snd_soc_init_card(socdev); + if (ret < 0) { + dev_err(codec->dev, "failed to register card: %d\n", ret); + goto error_free_pcms; + } + + return ret; + +error_free_pcms: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +pcm_err: + return ret; +} + +static int wm8940_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_wm8940 = { + .probe = wm8940_probe, + .remove = wm8940_remove, + .suspend = wm8940_suspend, + .resume = wm8940_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940); + +static int wm8940_register(struct wm8940_priv *wm8940) +{ + struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data; + struct snd_soc_codec *codec = &wm8940->codec; + int ret; + u16 reg; + if (wm8940_codec) { + dev_err(codec->dev, "Another WM8940 is registered\n"); + return -EINVAL; + } + + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + + codec->private_data = wm8940; + codec->name = "WM8940"; + codec->owner = THIS_MODULE; + codec->read = wm8940_read_reg_cache; + codec->write = wm8940_write; + codec->bias_level = SND_SOC_BIAS_OFF; + codec->set_bias_level = wm8940_set_bias_level; + codec->dai = &wm8940_dai; + codec->num_dai = 1; + codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults); + codec->reg_cache = &wm8940->reg_cache; + + memcpy(codec->reg_cache, wm8940_reg_defaults, + sizeof(wm8940_reg_defaults)); + + ret = wm8940_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset\n"); + return ret; + } + + wm8940_dai.dev = codec->dev; + + wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + ret = wm8940_write(codec, WM8940_POWER1, 0x180); + if (ret < 0) + return ret; + + if (!pdata) + dev_warn(codec->dev, "No platform data supplied\n"); + else { + reg = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL); + ret = wm8940_write(codec, WM8940_OUTPUTCTL, reg | pdata->vroi); + if (ret < 0) + return ret; + } + + + wm8940_codec = codec; + + ret = snd_soc_register_codec(codec); + if (ret) { + dev_err(codec->dev, "Failed to register codec: %d\n", ret); + return ret; + } + + ret = snd_soc_register_dai(&wm8940_dai); + if (ret) { + dev_err(codec->dev, "Failed to register DAI: %d\n", ret); + snd_soc_unregister_codec(codec); + return ret; + } + + return 0; +} + +static void wm8940_unregister(struct wm8940_priv *wm8940) +{ + wm8940_set_bias_level(&wm8940->codec, SND_SOC_BIAS_OFF); + snd_soc_unregister_dai(&wm8940_dai); + snd_soc_unregister_codec(&wm8940->codec); + kfree(wm8940); + wm8940_codec = NULL; +} + +static int wm8940_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8940_priv *wm8940; + struct snd_soc_codec *codec; + + wm8940 = kzalloc(sizeof *wm8940, GFP_KERNEL); + if (wm8940 == NULL) + return -ENOMEM; + + codec = &wm8940->codec; + codec->hw_write = (hw_write_t)i2c_master_send; + i2c_set_clientdata(i2c, wm8940); + codec->control_data = i2c; + codec->dev = &i2c->dev; + + return wm8940_register(wm8940); +} + +static int wm8940_i2c_remove(struct i2c_client *client) +{ + struct wm8940_priv *wm8940 = i2c_get_clientdata(client); + + wm8940_unregister(wm8940); + + return 0; +} + +static const struct i2c_device_id wm8940_i2c_id[] = { + { "wm8940", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id); + +static struct i2c_driver wm8940_i2c_driver = { + .driver = { + .name = "WM8940 I2C Codec", + .owner = THIS_MODULE, + }, + .probe = wm8940_i2c_probe, + .remove = __devexit_p(wm8940_i2c_remove), + .id_table = wm8940_i2c_id, +}; + +static int __init wm8940_modinit(void) +{ + int ret; + + ret = i2c_add_driver(&wm8940_i2c_driver); + if (ret) + printk(KERN_ERR "Failed to register WM8940 I2C driver: %d\n", + ret); + return ret; +} +module_init(wm8940_modinit); + +static void __exit wm8940_exit(void) +{ + i2c_del_driver(&wm8940_i2c_driver); +} +module_exit(wm8940_exit); + +MODULE_DESCRIPTION("ASoC WM8940 driver"); +MODULE_AUTHOR("Jonathan Cameron"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8940.h b/sound/soc/codecs/wm8940.h new file mode 100644 index 000000000000..8410eed3ef84 --- /dev/null +++ b/sound/soc/codecs/wm8940.h @@ -0,0 +1,104 @@ +/* + * wm8940.h -- WM8940 Soc Audio driver + * + * 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 _WM8940_H +#define _WM8940_H + +struct wm8940_setup_data { + /* Vref to analogue output resistance */ +#define WM8940_VROI_1K 0 +#define WM8940_VROI_30K 1 + unsigned int vroi:1; +}; +extern struct snd_soc_dai wm8940_dai; +extern struct snd_soc_codec_device soc_codec_dev_wm8940; + +/* WM8940 register space */ +#define WM8940_SOFTRESET 0x00 +#define WM8940_POWER1 0x01 +#define WM8940_POWER2 0x02 +#define WM8940_POWER3 0x03 +#define WM8940_IFACE 0x04 +#define WM8940_COMPANDINGCTL 0x05 +#define WM8940_CLOCK 0x06 +#define WM8940_ADDCNTRL 0x07 +#define WM8940_GPIO 0x08 +#define WM8940_CTLINT 0x09 +#define WM8940_DAC 0x0A +#define WM8940_DACVOL 0x0B + +#define WM8940_ADC 0x0E +#define WM8940_ADCVOL 0x0F +#define WM8940_NOTCH1 0x10 +#define WM8940_NOTCH2 0x11 +#define WM8940_NOTCH3 0x12 +#define WM8940_NOTCH4 0x13 +#define WM8940_NOTCH5 0x14 +#define WM8940_NOTCH6 0x15 +#define WM8940_NOTCH7 0x16 +#define WM8940_NOTCH8 0x17 +#define WM8940_DACLIM1 0x18 +#define WM8940_DACLIM2 0x19 + +#define WM8940_ALC1 0x20 +#define WM8940_ALC2 0x21 +#define WM8940_ALC3 0x22 +#define WM8940_NOISEGATE 0x23 +#define WM8940_PLLN 0x24 +#define WM8940_PLLK1 0x25 +#define WM8940_PLLK2 0x26 +#define WM8940_PLLK3 0x27 + +#define WM8940_ALC4 0x2A + +#define WM8940_INPUTCTL 0x2C +#define WM8940_PGAGAIN 0x2D + +#define WM8940_ADCBOOST 0x2F + +#define WM8940_OUTPUTCTL 0x31 +#define WM8940_SPKMIX 0x32 + +#define WM8940_SPKVOL 0x36 + +#define WM8940_MONOMIX 0x38 + +#define WM8940_CACHEREGNUM 0x57 + + +/* Clock divider Id's */ +#define WM8940_BCLKDIV 0 +#define WM8940_MCLKDIV 1 +#define WM8940_OPCLKDIV 2 + +/* MCLK clock dividers */ +#define WM8940_MCLKDIV_1 0 +#define WM8940_MCLKDIV_1_5 1 +#define WM8940_MCLKDIV_2 2 +#define WM8940_MCLKDIV_3 3 +#define WM8940_MCLKDIV_4 4 +#define WM8940_MCLKDIV_6 5 +#define WM8940_MCLKDIV_8 6 +#define WM8940_MCLKDIV_12 7 + +/* BCLK clock dividers */ +#define WM8940_BCLKDIV_1 0 +#define WM8940_BCLKDIV_2 1 +#define WM8940_BCLKDIV_4 2 +#define WM8940_BCLKDIV_8 3 +#define WM8940_BCLKDIV_16 4 +#define WM8940_BCLKDIV_32 5 + +/* PLL Out Dividers */ +#define WM8940_OPCLKDIV_1 0 +#define WM8940_OPCLKDIV_2 1 +#define WM8940_OPCLKDIV_3 2 +#define WM8940_OPCLKDIV_4 3 + +#endif /* _WM8940_H */ + -- GitLab From 9c935386512a3faa1be1c3d81cba38b7259a43f5 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 24 Apr 2009 15:00:25 +0200 Subject: [PATCH 0763/6080] ASoC: cs4270: fix Master Capture Switch polarity The control modifies the MUTE register, hence the polarity must be inverted. Signed-off-by: Daniel Mack Acked-By: Timur Tabi Signed-off-by: Mark Brown --- sound/soc/codecs/cs4270.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 7fa09a387622..3c34fe67c3d7 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -486,7 +486,7 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = { SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), - SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 0) + SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1) }; /* -- GitLab From 1a4ba05ec8369d62c10155a8931e81267bfbd31c Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 24 Apr 2009 16:37:45 +0200 Subject: [PATCH 0764/6080] ASoC: cs4270: add Master Playback Switch This adds a new control named 'Master Playback Switch' for cs4270 codecs. It is implemented using the new SOC_DOUBLE_EXT macro to catch the put function and store the information about manually set mute controls from userspace. When a manual mute is set, we don't want the soc core to un-mute the outputs. Renamed cs4270_mute() to cs4270_dai_mute() to avoid confusion. Signed-off-by: Daniel Mack Acked-by: Timur Tabi Signed-off-by: Mark Brown --- sound/soc/codecs/cs4270.c | 44 ++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 3c34fe67c3d7..ece6ed6a844f 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -109,6 +109,7 @@ struct cs4270_private { unsigned int mclk; /* Input frequency of the MCLK pin */ unsigned int mode; /* The mode (I2S or left-justified) */ unsigned int slave_mode; + unsigned int manual_mute; }; /** @@ -453,7 +454,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, } /** - * cs4270_mute - enable/disable the CS4270 external mute + * cs4270_dai_mute - enable/disable the CS4270 external mute * @dai: the SOC DAI * @mute: 0 = disable mute, 1 = enable mute * @@ -462,21 +463,52 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, * board does not have the MUTEA or MUTEB pins connected to such circuitry, * then this function will do nothing. */ -static int cs4270_mute(struct snd_soc_dai *dai, int mute) +static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; + struct cs4270_private *cs4270 = codec->private_data; int reg6; reg6 = snd_soc_read(codec, CS4270_MUTE); if (mute) reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B; - else + else { reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B); + reg6 |= cs4270->manual_mute; + } return snd_soc_write(codec, CS4270_MUTE, reg6); } +/** + * cs4270_soc_put_mute - put callback for the 'Master Playback switch' + * alsa control. + * @kcontrol: mixer control + * @ucontrol: control element information + * + * This function basically passes the arguments on to the generic + * snd_soc_put_volsw() function and saves the mute information in + * our private data structure. This is because we want to prevent + * cs4270_dai_mute() neglecting the user's decision to manually + * mute the codec's output. + * + * Returns 0 for success. + */ +static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct cs4270_private *cs4270 = codec->private_data; + int left = !ucontrol->value.integer.value[0]; + int right = !ucontrol->value.integer.value[1]; + + cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) | + (right ? CS4270_MUTE_DAC_B : 0); + + return snd_soc_put_volsw(kcontrol, ucontrol); +} + /* A list of non-DAPM controls that the CS4270 supports */ static const struct snd_kcontrol_new cs4270_snd_controls[] = { SOC_DOUBLE_R("Master Playback Volume", @@ -486,7 +518,9 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = { SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), - SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1) + SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1), + SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1, + snd_soc_get_volsw, cs4270_soc_put_mute), }; /* @@ -506,7 +540,7 @@ static struct snd_soc_dai_ops cs4270_dai_ops = { .hw_params = cs4270_hw_params, .set_sysclk = cs4270_set_dai_sysclk, .set_fmt = cs4270_set_dai_fmt, - .digital_mute = cs4270_mute, + .digital_mute = cs4270_dai_mute, }; struct snd_soc_dai cs4270_dai = { -- GitLab From 6be01cfb854818298753bfce65543dbc81d51d5a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 27 Apr 2009 20:57:42 +0100 Subject: [PATCH 0765/6080] ASoC: Staticise TLV values in WM8940 Signed-off-by: Mark Brown --- sound/soc/codecs/wm8940.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 26987dcd8d55..a66dacc7cc83 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -168,16 +168,16 @@ static const char *wm8940_filter_mode_text[] = {"Audio", "Application"}; static const struct soc_enum wm8940_filter_mode_enum = SOC_ENUM_SINGLE(WM8940_ADC, 7, 2, wm8940_filter_mode_text); -DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1); -DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0); -DECLARE_TLV_DB_SCALE(wm8940_pga_vol_tlv, -1200, 75, 0); -DECLARE_TLV_DB_SCALE(wm8940_alc_min_tlv, -1200, 600, 0); -DECLARE_TLV_DB_SCALE(wm8940_alc_max_tlv, 675, 600, 0); -DECLARE_TLV_DB_SCALE(wm8940_alc_tar_tlv, -2250, 50, 0); -DECLARE_TLV_DB_SCALE(wm8940_lim_boost_tlv, 0, 100, 0); -DECLARE_TLV_DB_SCALE(wm8940_lim_thresh_tlv, -600, 100, 0); -DECLARE_TLV_DB_SCALE(wm8940_adc_tlv, -12750, 50, 1); -DECLARE_TLV_DB_SCALE(wm8940_capture_boost_vol_tlv, 0, 2000, 0); +static DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1); +static DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0); +static DECLARE_TLV_DB_SCALE(wm8940_pga_vol_tlv, -1200, 75, 0); +static DECLARE_TLV_DB_SCALE(wm8940_alc_min_tlv, -1200, 600, 0); +static DECLARE_TLV_DB_SCALE(wm8940_alc_max_tlv, 675, 600, 0); +static DECLARE_TLV_DB_SCALE(wm8940_alc_tar_tlv, -2250, 50, 0); +static DECLARE_TLV_DB_SCALE(wm8940_lim_boost_tlv, 0, 100, 0); +static DECLARE_TLV_DB_SCALE(wm8940_lim_thresh_tlv, -600, 100, 0); +static DECLARE_TLV_DB_SCALE(wm8940_adc_tlv, -12750, 50, 1); +static DECLARE_TLV_DB_SCALE(wm8940_capture_boost_vol_tlv, 0, 2000, 0); static const struct snd_kcontrol_new wm8940_snd_controls[] = { SOC_SINGLE("Digital Loopback Switch", WM8940_COMPANDINGCTL, @@ -253,7 +253,7 @@ static const struct snd_kcontrol_new wm8940_mono_mixer_controls[] = { SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_MONOMIX, 0, 1, 0), }; -DECLARE_TLV_DB_SCALE(wm8940_boost_vol_tlv, -1500, 300, 1); +static DECLARE_TLV_DB_SCALE(wm8940_boost_vol_tlv, -1500, 300, 1); static const struct snd_kcontrol_new wm8940_input_boost_controls[] = { SOC_DAPM_SINGLE("Mic PGA Switch", WM8940_PGAGAIN, 6, 1, 1), SOC_DAPM_SINGLE_TLV("Aux Volume", WM8940_ADCBOOST, -- GitLab From 879c5e6b7cb4c689d08ca9b2e353d8ab3dc425d5 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 17 Jun 2009 11:47:48 -0400 Subject: [PATCH 0766/6080] jbd2: convert instrumentation from markers to tracepoints Signed-off-by: "Theodore Ts'o" --- fs/jbd2/checkpoint.c | 5 +- fs/jbd2/commit.c | 13 +-- fs/jbd2/journal.c | 69 +++++++++++++++ include/linux/jbd2.h | 6 ++ include/trace/events/jbd2.h | 168 ++++++++++++++++++++++++++++++++++++ 5 files changed, 252 insertions(+), 9 deletions(-) create mode 100644 include/trace/events/jbd2.h diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 17159cacbd9e..5d70b3e6d49b 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c @@ -20,9 +20,9 @@ #include #include #include -#include #include #include +#include /* * Unlink a buffer from a transaction checkpoint list. @@ -358,8 +358,7 @@ int jbd2_log_do_checkpoint(journal_t *journal) * journal straight away. */ result = jbd2_cleanup_journal_tail(journal); - trace_mark(jbd2_checkpoint, "dev %s need_checkpoint %d", - journal->j_devname, result); + trace_jbd2_checkpoint(journal, result); jbd_debug(1, "cleanup_journal_tail returned %d\n", result); if (result <= 0) return result; diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 0b7d3b8226fd..7b4088b2364d 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -26,6 +25,7 @@ #include #include #include +#include /* * Default IO end handler for temporary BJ_IO buffer_heads. @@ -253,6 +253,7 @@ static int journal_submit_data_buffers(journal_t *journal, * block allocation with delalloc. We need to write * only allocated blocks here. */ + trace_jbd2_submit_inode_data(jinode->i_vfs_inode); err = journal_submit_inode_data_buffers(mapping); if (!ret) ret = err; @@ -394,8 +395,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) commit_transaction = journal->j_running_transaction; J_ASSERT(commit_transaction->t_state == T_RUNNING); - trace_mark(jbd2_start_commit, "dev %s transaction %d", - journal->j_devname, commit_transaction->t_tid); + trace_jbd2_start_commit(journal, commit_transaction); jbd_debug(1, "JBD: starting commit of transaction %d\n", commit_transaction->t_tid); @@ -409,6 +409,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) */ if (commit_transaction->t_synchronous_commit) write_op = WRITE_SYNC_PLUG; + trace_jbd2_commit_locking(journal, commit_transaction); stats.u.run.rs_wait = commit_transaction->t_max_wait; stats.u.run.rs_locked = jiffies; stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start, @@ -484,6 +485,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) */ jbd2_journal_switch_revoke_table(journal); + trace_jbd2_commit_flushing(journal, commit_transaction); stats.u.run.rs_flushing = jiffies; stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked, stats.u.run.rs_flushing); @@ -520,6 +522,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) commit_transaction->t_state = T_COMMIT; spin_unlock(&journal->j_state_lock); + trace_jbd2_commit_logging(journal, commit_transaction); stats.u.run.rs_logging = jiffies; stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, stats.u.run.rs_logging); @@ -1054,9 +1057,7 @@ restart_loop: if (journal->j_commit_callback) journal->j_commit_callback(journal, commit_transaction); - trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", - journal->j_devname, commit_transaction->t_tid, - journal->j_tail_sequence); + trace_jbd2_end_commit(journal, commit_transaction); jbd_debug(1, "JBD: commit %d complete, head %d\n", journal->j_commit_sequence, journal->j_tail_sequence); if (to_free) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 62be7d294ec2..18bfd5dab642 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -38,6 +38,10 @@ #include #include #include +#include + +#define CREATE_TRACE_POINTS +#include #include #include @@ -2377,6 +2381,71 @@ static void __exit journal_exit(void) jbd2_journal_destroy_caches(); } +/* + * jbd2_dev_to_name is a utility function used by the jbd2 and ext4 + * tracing infrastructure to map a dev_t to a device name. + * + * The caller should use rcu_read_lock() in order to make sure the + * device name stays valid until its done with it. We use + * rcu_read_lock() as well to make sure we're safe in case the caller + * gets sloppy, and because rcu_read_lock() is cheap and can be safely + * nested. + */ +struct devname_cache { + struct rcu_head rcu; + dev_t device; + char devname[BDEVNAME_SIZE]; +}; +#define CACHE_SIZE_BITS 6 +static struct devname_cache *devcache[1 << CACHE_SIZE_BITS]; +static DEFINE_SPINLOCK(devname_cache_lock); + +static void free_devcache(struct rcu_head *rcu) +{ + kfree(rcu); +} + +const char *jbd2_dev_to_name(dev_t device) +{ + int i = hash_32(device, CACHE_SIZE_BITS); + char *ret; + struct block_device *bd; + + rcu_read_lock(); + if (devcache[i] && devcache[i]->device == device) { + ret = devcache[i]->devname; + rcu_read_unlock(); + return ret; + } + rcu_read_unlock(); + + spin_lock(&devname_cache_lock); + if (devcache[i]) { + if (devcache[i]->device == device) { + ret = devcache[i]->devname; + spin_unlock(&devname_cache_lock); + return ret; + } + call_rcu(&devcache[i]->rcu, free_devcache); + } + devcache[i] = kmalloc(sizeof(struct devname_cache), GFP_KERNEL); + if (!devcache[i]) { + spin_unlock(&devname_cache_lock); + return "NODEV-ALLOCFAILURE"; /* Something non-NULL */ + } + devcache[i]->device = device; + bd = bdget(device); + if (bd) { + bdevname(bd, devcache[i]->devname); + bdput(bd); + } else + __bdevname(device, devcache[i]->devname); + ret = devcache[i]->devname; + spin_unlock(&devname_cache_lock); + return ret; +} +EXPORT_SYMBOL(jbd2_dev_to_name); + MODULE_LICENSE("GPL"); module_init(journal_init); module_exit(journal_exit); diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index cc02393bfce8..d97eb652d6ca 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -1315,6 +1315,12 @@ extern int jbd_blocks_per_page(struct inode *inode); #define BUFFER_TRACE2(bh, bh2, info) do {} while (0) #define JBUFFER_TRACE(jh, info) do {} while (0) +/* + * jbd2_dev_to_name is a utility function used by the jbd2 and ext4 + * tracing infrastructure to map a dev_t to a device name. + */ +extern const char *jbd2_dev_to_name(dev_t device); + #endif /* __KERNEL__ */ #endif /* _LINUX_JBD2_H */ diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h new file mode 100644 index 000000000000..845b0b4b48fd --- /dev/null +++ b/include/trace/events/jbd2.h @@ -0,0 +1,168 @@ +#if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_JBD2_H + +#include +#include + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd2 + +TRACE_EVENT(jbd2_checkpoint, + + TP_PROTO(journal_t *journal, int result), + + TP_ARGS(journal, result), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, result ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->result = result; + ), + + TP_printk("dev %s result %d", + jbd2_dev_to_name(__entry->dev), __entry->result) +); + +TRACE_EVENT(jbd2_start_commit, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %s transaction %d sync %d", + jbd2_dev_to_name(__entry->dev), __entry->transaction, + __entry->sync_commit) +); + +TRACE_EVENT(jbd2_commit_locking, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %s transaction %d sync %d", + jbd2_dev_to_name(__entry->dev), __entry->transaction, + __entry->sync_commit) +); + +TRACE_EVENT(jbd2_commit_flushing, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %s transaction %d sync %d", + jbd2_dev_to_name(__entry->dev), __entry->transaction, + __entry->sync_commit) +); + +TRACE_EVENT(jbd2_commit_logging, + + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + ), + + TP_printk("dev %s transaction %d sync %d", + jbd2_dev_to_name(__entry->dev), __entry->transaction, + __entry->sync_commit) +); + +TRACE_EVENT(jbd2_end_commit, + TP_PROTO(journal_t *journal, transaction_t *commit_transaction), + + TP_ARGS(journal, commit_transaction), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( char, sync_commit ) + __field( int, transaction ) + __field( int, head ) + ), + + TP_fast_assign( + __entry->dev = journal->j_fs_dev->bd_dev; + __entry->sync_commit = commit_transaction->t_synchronous_commit; + __entry->transaction = commit_transaction->t_tid; + __entry->head = journal->j_tail_sequence; + ), + + TP_printk("dev %s transaction %d sync %d head %d", + jbd2_dev_to_name(__entry->dev), __entry->transaction, + __entry->sync_commit, __entry->head) +); + +TRACE_EVENT(jbd2_submit_inode_data, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + ), + + TP_printk("dev %s ino %lu", + jbd2_dev_to_name(__entry->dev), __entry->ino) +); + +#endif /* _TRACE_JBD2_H */ + +/* This part must be outside protection */ +#include -- GitLab From 9bffad1ed2a003a355ed1b42424a0ae3575275ed Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 17 Jun 2009 11:48:11 -0400 Subject: [PATCH 0767/6080] ext4: convert instrumentation from markers to tracepoints Signed-off-by: "Theodore Ts'o" --- fs/ext4/fsync.c | 8 +- fs/ext4/ialloc.c | 15 +- fs/ext4/inode.c | 69 +--- fs/ext4/mballoc.c | 77 ++-- fs/ext4/mballoc.h | 1 - fs/ext4/super.c | 6 +- include/trace/events/ext4.h | 719 ++++++++++++++++++++++++++++++++++++ 7 files changed, 774 insertions(+), 121 deletions(-) create mode 100644 include/trace/events/ext4.h diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 5afe4370840b..83cf6415f599 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -28,10 +28,12 @@ #include #include #include -#include + #include "ext4.h" #include "ext4_jbd2.h" +#include + /* * akpm: A new design for ext4_sync_file(). * @@ -52,9 +54,7 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) J_ASSERT(ext4_journal_current_handle() == NULL); - trace_mark(ext4_sync_file, "dev %s datasync %d ino %ld parent %ld", - inode->i_sb->s_id, datasync, inode->i_ino, - dentry->d_parent->d_inode->i_ino); + trace_ext4_sync_file(file, dentry, datasync); /* * data=writeback: diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 3743bd849bce..7d502f3be914 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -23,11 +23,14 @@ #include #include #include + #include "ext4.h" #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include + /* * ialloc.c contains the inodes allocation and deallocation routines */ @@ -208,11 +211,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) ino = inode->i_ino; ext4_debug("freeing inode %lu\n", ino); - trace_mark(ext4_free_inode, - "dev %s ino %lu mode %d uid %lu gid %lu bocks %llu", - sb->s_id, inode->i_ino, inode->i_mode, - (unsigned long) inode->i_uid, (unsigned long) inode->i_gid, - (unsigned long long) inode->i_blocks); + trace_ext4_free_inode(inode); /* * Note: we must free any quota before locking the superblock, @@ -815,8 +814,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) sb = dir->i_sb; ngroups = ext4_get_groups_count(sb); - trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id, - dir->i_ino, mode); + trace_ext4_request_inode(dir, mode); inode = new_inode(sb); if (!inode) return ERR_PTR(-ENOMEM); @@ -1047,8 +1045,7 @@ got: } ext4_debug("allocating inode %lu\n", inode->i_ino); - trace_mark(ext4_allocate_inode, "dev %s ino %lu dir %lu mode %d", - sb->s_id, inode->i_ino, dir->i_ino, mode); + trace_ext4_allocate_inode(inode, dir, mode); goto really_out; fail: ext4_std_error(sb, err); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 875db944b22f..2418ad36eab5 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -37,11 +37,14 @@ #include #include #include + #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" #include "ext4_extents.h" +#include + #define MPAGE_DA_EXTENT_TAIL 0x01 static inline int ext4_begin_ordered_truncate(struct inode *inode, @@ -1466,10 +1469,7 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, pgoff_t index; unsigned from, to; - trace_mark(ext4_write_begin, - "dev %s ino %lu pos %llu len %u flags %u", - inode->i_sb->s_id, inode->i_ino, - (unsigned long long) pos, len, flags); + trace_ext4_write_begin(inode, pos, len, flags); /* * Reserve one block more for addition to orphan list in case * we allocate blocks but write fails for some reason @@ -1611,10 +1611,7 @@ static int ext4_ordered_write_end(struct file *file, struct inode *inode = mapping->host; int ret = 0, ret2; - trace_mark(ext4_ordered_write_end, - "dev %s ino %lu pos %llu len %u copied %u", - inode->i_sb->s_id, inode->i_ino, - (unsigned long long) pos, len, copied); + trace_ext4_ordered_write_end(inode, pos, len, copied); ret = ext4_jbd2_file_inode(handle, inode); if (ret == 0) { @@ -1658,10 +1655,7 @@ static int ext4_writeback_write_end(struct file *file, struct inode *inode = mapping->host; int ret = 0, ret2; - trace_mark(ext4_writeback_write_end, - "dev %s ino %lu pos %llu len %u copied %u", - inode->i_sb->s_id, inode->i_ino, - (unsigned long long) pos, len, copied); + trace_ext4_writeback_write_end(inode, pos, len, copied); ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, page, fsdata); copied = ret2; @@ -1705,10 +1699,7 @@ static int ext4_journalled_write_end(struct file *file, unsigned from, to; loff_t new_i_size; - trace_mark(ext4_journalled_write_end, - "dev %s ino %lu pos %llu len %u copied %u", - inode->i_sb->s_id, inode->i_ino, - (unsigned long long) pos, len, copied); + trace_ext4_journalled_write_end(inode, pos, len, copied); from = pos & (PAGE_CACHE_SIZE - 1); to = from + len; @@ -2554,9 +2545,7 @@ static int ext4_da_writepage(struct page *page, struct buffer_head *page_bufs; struct inode *inode = page->mapping->host; - trace_mark(ext4_da_writepage, - "dev %s ino %lu page_index %lu", - inode->i_sb->s_id, inode->i_ino, page->index); + trace_ext4_da_writepage(inode, page); size = i_size_read(inode); if (page->index == size >> PAGE_CACHE_SHIFT) len = size & ~PAGE_CACHE_MASK; @@ -2667,19 +2656,7 @@ static int ext4_da_writepages(struct address_space *mapping, int needed_blocks, ret = 0, nr_to_writebump = 0; struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); - trace_mark(ext4_da_writepages, - "dev %s ino %lu nr_t_write %ld " - "pages_skipped %ld range_start %llu " - "range_end %llu nonblocking %d " - "for_kupdate %d for_reclaim %d " - "for_writepages %d range_cyclic %d", - inode->i_sb->s_id, inode->i_ino, - wbc->nr_to_write, wbc->pages_skipped, - (unsigned long long) wbc->range_start, - (unsigned long long) wbc->range_end, - wbc->nonblocking, wbc->for_kupdate, - wbc->for_reclaim, wbc->for_writepages, - wbc->range_cyclic); + trace_ext4_da_writepages(inode, wbc); /* * No pages to write? This is mainly a kludge to avoid starting @@ -2845,14 +2822,7 @@ out_writepages: if (!no_nrwrite_index_update) wbc->no_nrwrite_index_update = 0; wbc->nr_to_write -= nr_to_writebump; - trace_mark(ext4_da_writepage_result, - "dev %s ino %lu ret %d pages_written %d " - "pages_skipped %ld congestion %d " - "more_io %d no_nrwrite_index_update %d", - inode->i_sb->s_id, inode->i_ino, ret, - pages_written, wbc->pages_skipped, - wbc->encountered_congestion, wbc->more_io, - wbc->no_nrwrite_index_update); + trace_ext4_da_writepages_result(inode, wbc, ret, pages_written); return ret; } @@ -2904,11 +2874,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, len, flags, pagep, fsdata); } *fsdata = (void *)0; - - trace_mark(ext4_da_write_begin, - "dev %s ino %lu pos %llu len %u flags %u", - inode->i_sb->s_id, inode->i_ino, - (unsigned long long) pos, len, flags); + trace_ext4_da_write_begin(inode, pos, len, flags); retry: /* * With delayed allocation, we don't log the i_disksize update @@ -3001,10 +2967,7 @@ static int ext4_da_write_end(struct file *file, } } - trace_mark(ext4_da_write_end, - "dev %s ino %lu pos %llu len %u copied %u", - inode->i_sb->s_id, inode->i_ino, - (unsigned long long) pos, len, copied); + trace_ext4_da_write_end(inode, pos, len, copied); start = pos & (PAGE_CACHE_SIZE - 1); end = start + copied - 1; @@ -3255,9 +3218,7 @@ static int ext4_normal_writepage(struct page *page, loff_t size = i_size_read(inode); loff_t len; - trace_mark(ext4_normal_writepage, - "dev %s ino %lu page_index %lu", - inode->i_sb->s_id, inode->i_ino, page->index); + trace_ext4_normal_writepage(inode, page); J_ASSERT(PageLocked(page)); if (page->index == size >> PAGE_CACHE_SHIFT) len = size & ~PAGE_CACHE_MASK; @@ -3343,9 +3304,7 @@ static int ext4_journalled_writepage(struct page *page, loff_t size = i_size_read(inode); loff_t len; - trace_mark(ext4_journalled_writepage, - "dev %s ino %lu page_index %lu", - inode->i_sb->s_id, inode->i_ino, page->index); + trace_ext4_journalled_writepage(inode, page); J_ASSERT(PageLocked(page)); if (page->index == size >> PAGE_CACHE_SHIFT) len = size & ~PAGE_CACHE_MASK; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index ed8482e22c0e..8d98070b48fb 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -22,6 +22,8 @@ */ #include "mballoc.h" +#include + /* * MUSTDO: * - test ext4_ext_search_left() and ext4_ext_search_right() @@ -340,8 +342,6 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, ext4_group_t group); static void release_blocks_on_commit(journal_t *journal, transaction_t *txn); - - static inline void *mb_correct_addr_and_bit(int *bit, void *addr) { #if BITS_PER_LONG == 64 @@ -2859,9 +2859,8 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn) discard_block = (ext4_fsblk_t) entry->group * EXT4_BLOCKS_PER_GROUP(sb) + entry->start_blk + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); - trace_mark(ext4_discard_blocks, "dev %s blk %llu count %u", - sb->s_id, (unsigned long long) discard_block, - entry->count); + trace_ext4_discard_blocks(sb, (unsigned long long)discard_block, + entry->count); sb_issue_discard(sb, discard_block, entry->count); kmem_cache_free(ext4_free_ext_cachep, entry); @@ -3629,10 +3628,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) mb_debug("new inode pa %p: %llu/%u for %u\n", pa, pa->pa_pstart, pa->pa_len, pa->pa_lstart); - trace_mark(ext4_mb_new_inode_pa, - "dev %s ino %lu pstart %llu len %u lstart %u", - sb->s_id, ac->ac_inode->i_ino, - pa->pa_pstart, pa->pa_len, pa->pa_lstart); + trace_ext4_mb_new_inode_pa(ac, pa); ext4_mb_use_inode_pa(ac, pa); atomic_add(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated); @@ -3691,9 +3687,8 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac) pa->pa_type = MB_GROUP_PA; mb_debug("new group pa %p: %llu/%u for %u\n", pa, - pa->pa_pstart, pa->pa_len, pa->pa_lstart); - trace_mark(ext4_mb_new_group_pa, "dev %s pstart %llu len %u lstart %u", - sb->s_id, pa->pa_pstart, pa->pa_len, pa->pa_lstart); + pa->pa_pstart, pa->pa_len, pa->pa_lstart); + trace_ext4_mb_new_group_pa(ac, pa); ext4_mb_use_group_pa(ac, pa); atomic_add(pa->pa_free, &EXT4_SB(sb)->s_mb_preallocated); @@ -3783,10 +3778,8 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh, ext4_mb_store_history(ac); } - trace_mark(ext4_mb_release_inode_pa, - "dev %s ino %lu block %llu count %u", - sb->s_id, pa->pa_inode->i_ino, grp_blk_start + bit, - next - bit); + trace_ext4_mb_release_inode_pa(ac, pa, grp_blk_start + bit, + next - bit); mb_free_blocks(pa->pa_inode, e4b, bit, next - bit); bit = next + 1; } @@ -3820,8 +3813,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, if (ac) ac->ac_op = EXT4_MB_HISTORY_DISCARD; - trace_mark(ext4_mb_release_group_pa, "dev %s pstart %llu len %d", - sb->s_id, pa->pa_pstart, pa->pa_len); + trace_ext4_mb_release_group_pa(ac, pa); BUG_ON(pa->pa_deleted == 0); ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); BUG_ON(group != e4b->bd_group && pa->pa_len != 0); @@ -3889,6 +3881,8 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, INIT_LIST_HEAD(&list); ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); + if (ac) + ac->ac_sb = sb; repeat: ext4_lock_group(sb, group); list_for_each_entry_safe(pa, tmp, @@ -3987,12 +3981,15 @@ void ext4_discard_preallocations(struct inode *inode) } mb_debug("discard preallocation for inode %lu\n", inode->i_ino); - trace_mark(ext4_discard_preallocations, "dev %s ino %lu", sb->s_id, - inode->i_ino); + trace_ext4_discard_preallocations(inode); INIT_LIST_HEAD(&list); ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); + if (ac) { + ac->ac_sb = sb; + ac->ac_inode = inode; + } repeat: /* first, collect all pa's in the inode */ spin_lock(&ei->i_prealloc_lock); @@ -4276,6 +4273,8 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb, INIT_LIST_HEAD(&discard_list); ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); + if (ac) + ac->ac_sb = sb; spin_lock(&lg->lg_prealloc_lock); list_for_each_entry_rcu(pa, &lg->lg_prealloc_list[order], @@ -4445,8 +4444,7 @@ static int ext4_mb_discard_preallocations(struct super_block *sb, int needed) int ret; int freed = 0; - trace_mark(ext4_mb_discard_preallocations, "dev %s needed %d", - sb->s_id, needed); + trace_ext4_mb_discard_preallocations(sb, needed); for (i = 0; i < ngroups && needed > 0; i++) { ret = ext4_mb_discard_group_preallocations(sb, i, needed); freed += ret; @@ -4475,17 +4473,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, sb = ar->inode->i_sb; sbi = EXT4_SB(sb); - trace_mark(ext4_request_blocks, "dev %s flags %u len %u ino %lu " - "lblk %llu goal %llu lleft %llu lright %llu " - "pleft %llu pright %llu ", - sb->s_id, ar->flags, ar->len, - ar->inode ? ar->inode->i_ino : 0, - (unsigned long long) ar->logical, - (unsigned long long) ar->goal, - (unsigned long long) ar->lleft, - (unsigned long long) ar->lright, - (unsigned long long) ar->pleft, - (unsigned long long) ar->pright); + trace_ext4_request_blocks(ar); /* * For delayed allocation, we could skip the ENOSPC and @@ -4521,7 +4509,10 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, } ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); - if (!ac) { + if (ac) { + ac->ac_sb = sb; + ac->ac_inode = ar->inode; + } else { ar->len = 0; *errp = -ENOMEM; goto out1; @@ -4594,18 +4585,7 @@ out3: reserv_blks); } - trace_mark(ext4_allocate_blocks, - "dev %s block %llu flags %u len %u ino %lu " - "logical %llu goal %llu lleft %llu lright %llu " - "pleft %llu pright %llu ", - sb->s_id, (unsigned long long) block, - ar->flags, ar->len, ar->inode ? ar->inode->i_ino : 0, - (unsigned long long) ar->logical, - (unsigned long long) ar->goal, - (unsigned long long) ar->lleft, - (unsigned long long) ar->lright, - (unsigned long long) ar->pleft, - (unsigned long long) ar->pright); + trace_ext4_allocate_blocks(ar, (unsigned long long)block); return block; } @@ -4740,10 +4720,7 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode, } ext4_debug("freeing block %lu\n", block); - trace_mark(ext4_free_blocks, - "dev %s block %llu count %lu metadata %d ino %lu", - sb->s_id, (unsigned long long) block, count, metadata, - inode ? inode->i_ino : 0); + trace_ext4_free_blocks(inode, block, count, metadata); ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); if (ac) { diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h index 75e34f69215b..c96bb19f58f9 100644 --- a/fs/ext4/mballoc.h +++ b/fs/ext4/mballoc.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "ext4_jbd2.h" #include "ext4.h" diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 012c4251397e..e8f0b2af4607 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -47,6 +46,9 @@ #include "xattr.h" #include "acl.h" +#define CREATE_TRACE_POINTS +#include + static int default_mb_history_length = 1000; module_param_named(default_mb_history_length, default_mb_history_length, @@ -3346,7 +3348,7 @@ static int ext4_sync_fs(struct super_block *sb, int wait) int ret = 0; tid_t target; - trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); + trace_ext4_sync_fs(sb, wait); if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { if (wait) jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target); diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h new file mode 100644 index 000000000000..acf4cc9cd36d --- /dev/null +++ b/include/trace/events/ext4.h @@ -0,0 +1,719 @@ +#if !defined(_TRACE_EXT4_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EXT4_H + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ext4 + +#include +#include "../../../fs/ext4/ext4.h" +#include "../../../fs/ext4/mballoc.h" +#include + +TRACE_EVENT(ext4_free_inode, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( umode_t, mode ) + __field( uid_t, uid ) + __field( gid_t, gid ) + __field( blkcnt_t, blocks ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->mode = inode->i_mode; + __entry->uid = inode->i_uid; + __entry->gid = inode->i_gid; + __entry->blocks = inode->i_blocks; + ), + + TP_printk("dev %s ino %lu mode %d uid %u gid %u blocks %llu", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->mode, + __entry->uid, __entry->gid, __entry->blocks) +); + +TRACE_EVENT(ext4_request_inode, + TP_PROTO(struct inode *dir, int mode), + + TP_ARGS(dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + __entry->dev = dir->i_sb->s_dev; + __entry->dir = dir->i_ino; + __entry->mode = mode; + ), + + TP_printk("dev %s dir %lu mode %d", + jbd2_dev_to_name(__entry->dev), __entry->dir, __entry->mode) +); + +TRACE_EVENT(ext4_allocate_inode, + TP_PROTO(struct inode *inode, struct inode *dir, int mode), + + TP_ARGS(inode, dir, mode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, dir ) + __field( umode_t, mode ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->dir = dir->i_ino; + __entry->mode = mode; + ), + + TP_printk("dev %s ino %lu dir %lu mode %d", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->dir, __entry->mode) +); + +TRACE_EVENT(ext4_write_begin, + + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int flags), + + TP_ARGS(inode, pos, len, flags), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, flags ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->flags = flags; + ), + + TP_printk("dev %s ino %lu pos %llu len %u flags %u", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len, + __entry->flags) +); + +TRACE_EVENT(ext4_ordered_write_end, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, copied ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->copied = copied; + ), + + TP_printk("dev %s ino %lu pos %llu len %u copied %u", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len, + __entry->copied) +); + +TRACE_EVENT(ext4_writeback_write_end, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, copied ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->copied = copied; + ), + + TP_printk("dev %s ino %lu pos %llu len %u copied %u", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len, + __entry->copied) +); + +TRACE_EVENT(ext4_journalled_write_end, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + TP_ARGS(inode, pos, len, copied), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, copied ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->copied = copied; + ), + + TP_printk("dev %s ino %lu pos %llu len %u copied %u", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len, + __entry->copied) +); + +TRACE_EVENT(ext4_da_writepage, + TP_PROTO(struct inode *inode, struct page *page), + + TP_ARGS(inode, page), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( pgoff_t, index ) + + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->index = page->index; + ), + + TP_printk("dev %s ino %lu page_index %lu", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->index) +); + +TRACE_EVENT(ext4_da_writepages, + TP_PROTO(struct inode *inode, struct writeback_control *wbc), + + TP_ARGS(inode, wbc), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( long, nr_to_write ) + __field( long, pages_skipped ) + __field( loff_t, range_start ) + __field( loff_t, range_end ) + __field( char, nonblocking ) + __field( char, for_kupdate ) + __field( char, for_reclaim ) + __field( char, for_writepages ) + __field( char, range_cyclic ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->nr_to_write = wbc->nr_to_write; + __entry->pages_skipped = wbc->pages_skipped; + __entry->range_start = wbc->range_start; + __entry->range_end = wbc->range_end; + __entry->nonblocking = wbc->nonblocking; + __entry->for_kupdate = wbc->for_kupdate; + __entry->for_reclaim = wbc->for_reclaim; + __entry->for_writepages = wbc->for_writepages; + __entry->range_cyclic = wbc->range_cyclic; + ), + + TP_printk("dev %s ino %lu nr_t_write %ld pages_skipped %ld range_start %llu range_end %llu nonblocking %d for_kupdate %d for_reclaim %d for_writepages %d range_cyclic %d", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->nr_to_write, + __entry->pages_skipped, __entry->range_start, + __entry->range_end, __entry->nonblocking, + __entry->for_kupdate, __entry->for_reclaim, + __entry->for_writepages, __entry->range_cyclic) +); + +TRACE_EVENT(ext4_da_writepages_result, + TP_PROTO(struct inode *inode, struct writeback_control *wbc, + int ret, int pages_written), + + TP_ARGS(inode, wbc, ret, pages_written), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( int, ret ) + __field( int, pages_written ) + __field( long, pages_skipped ) + __field( char, encountered_congestion ) + __field( char, more_io ) + __field( char, no_nrwrite_index_update ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->ret = ret; + __entry->pages_written = pages_written; + __entry->pages_skipped = wbc->pages_skipped; + __entry->encountered_congestion = wbc->encountered_congestion; + __entry->more_io = wbc->more_io; + __entry->no_nrwrite_index_update = wbc->no_nrwrite_index_update; + ), + + TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld congestion %d more_io %d no_nrwrite_index_update %d", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->ret, + __entry->pages_written, __entry->pages_skipped, + __entry->encountered_congestion, __entry->more_io, + __entry->no_nrwrite_index_update) +); + +TRACE_EVENT(ext4_da_write_begin, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int flags), + + TP_ARGS(inode, pos, len, flags), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, flags ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->flags = flags; + ), + + TP_printk("dev %s ino %lu pos %llu len %u flags %u", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len, + __entry->flags) +); + +TRACE_EVENT(ext4_da_write_end, + TP_PROTO(struct inode *inode, loff_t pos, unsigned int len, + unsigned int copied), + + TP_ARGS(inode, pos, len, copied), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( loff_t, pos ) + __field( unsigned int, len ) + __field( unsigned int, copied ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->len = len; + __entry->copied = copied; + ), + + TP_printk("dev %s ino %lu pos %llu len %u copied %u", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len, + __entry->copied) +); + +TRACE_EVENT(ext4_normal_writepage, + TP_PROTO(struct inode *inode, struct page *page), + + TP_ARGS(inode, page), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( pgoff_t, index ) + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->index = page->index; + ), + + TP_printk("dev %s ino %lu page_index %lu", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->index) +); + +TRACE_EVENT(ext4_journalled_writepage, + TP_PROTO(struct inode *inode, struct page *page), + + TP_ARGS(inode, page), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( pgoff_t, index ) + + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->index = page->index; + ), + + TP_printk("dev %s ino %lu page_index %lu", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->index) +); + +TRACE_EVENT(ext4_discard_blocks, + TP_PROTO(struct super_block *sb, unsigned long long blk, + unsigned long long count), + + TP_ARGS(sb, blk, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( __u64, blk ) + __field( __u64, count ) + + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->blk = blk; + __entry->count = count; + ), + + TP_printk("dev %s blk %llu count %llu", + jbd2_dev_to_name(__entry->dev), __entry->blk, __entry->count) +); + +TRACE_EVENT(ext4_mb_new_inode_pa, + TP_PROTO(struct ext4_allocation_context *ac, + struct ext4_prealloc_space *pa), + + TP_ARGS(ac, pa), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( __u64, pa_pstart ) + __field( __u32, pa_len ) + __field( __u64, pa_lstart ) + + ), + + TP_fast_assign( + __entry->dev = ac->ac_sb->s_dev; + __entry->ino = ac->ac_inode->i_ino; + __entry->pa_pstart = pa->pa_pstart; + __entry->pa_len = pa->pa_len; + __entry->pa_lstart = pa->pa_lstart; + ), + + TP_printk("dev %s ino %lu pstart %llu len %u lstart %llu", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pa_pstart, + __entry->pa_len, __entry->pa_lstart) +); + +TRACE_EVENT(ext4_mb_new_group_pa, + TP_PROTO(struct ext4_allocation_context *ac, + struct ext4_prealloc_space *pa), + + TP_ARGS(ac, pa), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( __u64, pa_pstart ) + __field( __u32, pa_len ) + __field( __u64, pa_lstart ) + + ), + + TP_fast_assign( + __entry->dev = ac->ac_sb->s_dev; + __entry->ino = ac->ac_inode->i_ino; + __entry->pa_pstart = pa->pa_pstart; + __entry->pa_len = pa->pa_len; + __entry->pa_lstart = pa->pa_lstart; + ), + + TP_printk("dev %s ino %lu pstart %llu len %u lstart %llu", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pa_pstart, + __entry->pa_len, __entry->pa_lstart) +); + +TRACE_EVENT(ext4_mb_release_inode_pa, + TP_PROTO(struct ext4_allocation_context *ac, + struct ext4_prealloc_space *pa, + unsigned long long block, unsigned int count), + + TP_ARGS(ac, pa, block, count), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( __u64, block ) + __field( __u32, count ) + + ), + + TP_fast_assign( + __entry->dev = ac->ac_sb->s_dev; + __entry->ino = ac->ac_inode->i_ino; + __entry->block = block; + __entry->count = count; + ), + + TP_printk("dev %s ino %lu block %llu count %u", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->block, + __entry->count) +); + +TRACE_EVENT(ext4_mb_release_group_pa, + TP_PROTO(struct ext4_allocation_context *ac, + struct ext4_prealloc_space *pa), + + TP_ARGS(ac, pa), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( __u64, pa_pstart ) + __field( __u32, pa_len ) + + ), + + TP_fast_assign( + __entry->dev = ac->ac_sb->s_dev; + __entry->ino = ac->ac_inode->i_ino; + __entry->pa_pstart = pa->pa_pstart; + __entry->pa_len = pa->pa_len; + ), + + TP_printk("dev %s pstart %llu len %u", + jbd2_dev_to_name(__entry->dev), __entry->pa_pstart, __entry->pa_len) +); + +TRACE_EVENT(ext4_discard_preallocations, + TP_PROTO(struct inode *inode), + + TP_ARGS(inode), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + ), + + TP_printk("dev %s ino %lu", + jbd2_dev_to_name(__entry->dev), __entry->ino) +); + +TRACE_EVENT(ext4_mb_discard_preallocations, + TP_PROTO(struct super_block *sb, int needed), + + TP_ARGS(sb, needed), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, needed ) + + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->needed = needed; + ), + + TP_printk("dev %s needed %d", + jbd2_dev_to_name(__entry->dev), __entry->needed) +); + +TRACE_EVENT(ext4_request_blocks, + TP_PROTO(struct ext4_allocation_request *ar), + + TP_ARGS(ar), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( unsigned int, flags ) + __field( unsigned int, len ) + __field( __u64, logical ) + __field( __u64, goal ) + __field( __u64, lleft ) + __field( __u64, lright ) + __field( __u64, pleft ) + __field( __u64, pright ) + ), + + TP_fast_assign( + __entry->dev = ar->inode->i_sb->s_dev; + __entry->ino = ar->inode->i_ino; + __entry->flags = ar->flags; + __entry->len = ar->len; + __entry->logical = ar->logical; + __entry->goal = ar->goal; + __entry->lleft = ar->lleft; + __entry->lright = ar->lright; + __entry->pleft = ar->pleft; + __entry->pright = ar->pright; + ), + + TP_printk("dev %s ino %lu flags %u len %u lblk %llu goal %llu lleft %llu lright %llu pleft %llu pright %llu ", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->flags, + __entry->len, + (unsigned long long) __entry->logical, + (unsigned long long) __entry->goal, + (unsigned long long) __entry->lleft, + (unsigned long long) __entry->lright, + (unsigned long long) __entry->pleft, + (unsigned long long) __entry->pright) +); + +TRACE_EVENT(ext4_allocate_blocks, + TP_PROTO(struct ext4_allocation_request *ar, unsigned long long block), + + TP_ARGS(ar, block), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( __u64, block ) + __field( unsigned int, flags ) + __field( unsigned int, len ) + __field( __u64, logical ) + __field( __u64, goal ) + __field( __u64, lleft ) + __field( __u64, lright ) + __field( __u64, pleft ) + __field( __u64, pright ) + ), + + TP_fast_assign( + __entry->dev = ar->inode->i_sb->s_dev; + __entry->ino = ar->inode->i_ino; + __entry->block = block; + __entry->flags = ar->flags; + __entry->len = ar->len; + __entry->logical = ar->logical; + __entry->goal = ar->goal; + __entry->lleft = ar->lleft; + __entry->lright = ar->lright; + __entry->pleft = ar->pleft; + __entry->pright = ar->pright; + ), + + TP_printk("dev %s ino %lu flags %u len %u block %llu lblk %llu goal %llu lleft %llu lright %llu pleft %llu pright %llu ", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->flags, + __entry->len, __entry->block, + (unsigned long long) __entry->logical, + (unsigned long long) __entry->goal, + (unsigned long long) __entry->lleft, + (unsigned long long) __entry->lright, + (unsigned long long) __entry->pleft, + (unsigned long long) __entry->pright) +); + +TRACE_EVENT(ext4_free_blocks, + TP_PROTO(struct inode *inode, __u64 block, unsigned long count, + int metadata), + + TP_ARGS(inode, block, count, metadata), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( __u64, block ) + __field( unsigned long, count ) + __field( int, metadata ) + + ), + + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->block = block; + __entry->count = count; + __entry->metadata = metadata; + ), + + TP_printk("dev %s ino %lu block %llu count %lu metadata %d", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->block, + __entry->count, __entry->metadata) +); + +TRACE_EVENT(ext4_sync_file, + TP_PROTO(struct file *file, struct dentry *dentry, int datasync), + + TP_ARGS(file, dentry, datasync), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( ino_t, ino ) + __field( ino_t, parent ) + __field( int, datasync ) + ), + + TP_fast_assign( + __entry->dev = dentry->d_inode->i_sb->s_dev; + __entry->ino = dentry->d_inode->i_ino; + __entry->datasync = datasync; + __entry->parent = dentry->d_parent->d_inode->i_ino; + ), + + TP_printk("dev %s ino %ld parent %ld datasync %d ", + jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->parent, + __entry->datasync) +); + +TRACE_EVENT(ext4_sync_fs, + TP_PROTO(struct super_block *sb, int wait), + + TP_ARGS(sb, wait), + + TP_STRUCT__entry( + __field( dev_t, dev ) + __field( int, wait ) + + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->wait = wait; + ), + + TP_printk("dev %s wait %d", jbd2_dev_to_name(__entry->dev), + __entry->wait) +); + +#endif /* _TRACE_EXT4_H */ + +/* This part must be outside protection */ +#include -- GitLab From 96159f25112595386c56e09eca90284e85e7ecbf Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 27 Apr 2009 17:24:22 -0400 Subject: [PATCH 0768/6080] ext3: avoid unnecessary spinlock in critical POSIX ACL path If a filesystem supports POSIX ACL's, the VFS layer expects the filesystem to do POSIX ACL checks on any files not owned by the caller, and it does this for every single pathname component that it looks up. That obviously can be pretty expensive if the filesystem isn't careful about it, especially with locking. That's doubly sad, since the common case tends to be that there are no ACL's associated with the files in question. ext3 already caches the ACL data so that it doesn't have to look it up over and over again, but it does so by taking the inode->i_lock spinlock on every lookup. Which is a noticeable overhead even if it's a private lock, especially on CPU's where the serialization is expensive (eg Intel Netburst aka 'P4'). For the special case of not actually having any ACL's, all that locking is unnecessary. Even if somebody else were to be changing the ACL's on another CPU, we simply don't care - if we've seen a NULL ACL, we might as well use it. So just load the ACL speculatively without any locking, and if it was NULL, just use it. If it's non-NULL (either because we had a cached entry, or because the cache hasn't been filled in at all), it means that we'll need to get the lock and re-load it properly. This is noticeable even on Nehalem, which does locking quite well (much better than P4). From lmbench: Processor, Processes - times in microseconds - smaller is better -------------------------------------------------------------------- Host OS Mhz null null open slct fork exec sh call I/O stat clos TCP proc proc proc --------- ------------- ---- ---- ---- ---- ---- ---- ---- ---- ---- - before: nehalem.l Linux 2.6.30- 3193 0.04 0.09 0.95 1.45 2.18 69.1 273. 1141 nehalem.l Linux 2.6.30- 3193 0.04 0.09 0.95 1.48 2.28 69.9 253. 1140 nehalem.l Linux 2.6.30- 3193 0.04 0.10 0.95 1.42 2.19 68.6 284. 1141 - after: nehalem.l Linux 2.6.30- 3193 0.04 0.09 0.92 1.44 2.12 68.3 282. 1094 nehalem.l Linux 2.6.30- 3193 0.04 0.09 0.92 1.39 2.20 67.0 308. 1123 nehalem.l Linux 2.6.30- 3193 0.04 0.09 0.92 1.39 2.36 67.4 293. 1148 where you can see what appears to be a roughly 3% improvement in stat and open/close latencies from just the removal of the locking overhead. Of course, this only matters for files you don't own (the owner never needs to do the ACL checks), but that's the common case for libraries, header files, and executables. As well as for the base components of any absolute pathname, even if you are the owner of the final file. [ At some point we probably want to move this ACL caching logic entirely into the VFS layer (and only call down to the filesystem when uncached), but in the meantime this improves ext3 a bit. A similar fix to btrfs makes a much bigger difference (15x improvement in lmbench) due to broken caching. ] Signed-off-by: Linus Torvalds Signed-off-by: "Theodore Ts'o" Acked-by: Jan Kara Cc: Al Viro --- fs/ext3/acl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index d81ef2fdb08e..e0c745451715 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -129,12 +129,15 @@ fail: static inline struct posix_acl * ext3_iget_acl(struct inode *inode, struct posix_acl **i_acl) { - struct posix_acl *acl = EXT3_ACL_NOT_CACHED; + struct posix_acl *acl = ACCESS_ONCE(*i_acl); - spin_lock(&inode->i_lock); - if (*i_acl != EXT3_ACL_NOT_CACHED) - acl = posix_acl_dup(*i_acl); - spin_unlock(&inode->i_lock); + if (acl) { + spin_lock(&inode->i_lock); + acl = *i_acl; + if (acl != EXT3_ACL_NOT_CACHED) + acl = posix_acl_dup(acl); + spin_unlock(&inode->i_lock); + } return acl; } -- GitLab From 8b0f9e8f78bd0a65fa001bf18f2c47eef2893a10 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 27 Apr 2009 17:33:23 -0400 Subject: [PATCH 0769/6080] ext4: avoid unnecessary spinlock in critical POSIX ACL path If a filesystem supports POSIX ACL's, the VFS layer expects the filesystem to do POSIX ACL checks on any files not owned by the caller, and it does this for every single pathname component that it looks up. That obviously can be pretty expensive if the filesystem isn't careful about it, especially with locking. That's doubly sad, since the common case tends to be that there are no ACL's associated with the files in question. ext4 already caches the ACL data so that it doesn't have to look it up over and over again, but it does so by taking the inode->i_lock spinlock on every lookup. Which is a noticeable overhead even if it's a private lock, especially on CPU's where the serialization is expensive (eg Intel Netburst aka 'P4'). For the special case of not actually having any ACL's, all that locking is unnecessary. Even if somebody else were to be changing the ACL's on another CPU, we simply don't care - if we've seen a NULL ACL, we might as well use it. So just load the ACL speculatively without any locking, and if it was NULL, just use it. If it's non-NULL (either because we had a cached entry, or because the cache hasn't been filled in at all), it means that we'll need to get the lock and re-load it properly. (This commit was ported from a patch originally authored by Linus for ext3.) Signed-off-by: "Theodore Ts'o" --- fs/ext4/acl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 647e0d65a284..605aeed96d68 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -129,12 +129,15 @@ fail: static inline struct posix_acl * ext4_iget_acl(struct inode *inode, struct posix_acl **i_acl) { - struct posix_acl *acl = EXT4_ACL_NOT_CACHED; + struct posix_acl *acl = ACCESS_ONCE(*i_acl); - spin_lock(&inode->i_lock); - if (*i_acl != EXT4_ACL_NOT_CACHED) - acl = posix_acl_dup(*i_acl); - spin_unlock(&inode->i_lock); + if (acl) { + spin_lock(&inode->i_lock); + acl = *i_acl; + if (acl != EXT4_ACL_NOT_CACHED) + acl = posix_acl_dup(acl); + spin_unlock(&inode->i_lock); + } return acl; } -- GitLab From ac2ff946a53e7bd0ae98f4e5d1d6c1b1dced82e5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 12:38:32 +0900 Subject: [PATCH 0770/6080] mg_disk: fix locking IRQ and timeout handlers call functions which expect locked queue lock without locking it. Fix it. While at it, convert 0s used as null pointer constant to NULLs. [ Impact: fix locking, cleanup ] Signed-off-by: Tejun Heo Cc: unsik Kim --- drivers/block/mg_disk.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index fb39d9aa3cdc..d3e72ad08dbe 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -160,11 +160,16 @@ static irqreturn_t mg_irq(int irq, void *dev_id) struct mg_host *host = dev_id; void (*handler)(struct mg_host *) = host->mg_do_intr; - host->mg_do_intr = 0; + spin_lock(&host->lock); + + host->mg_do_intr = NULL; del_timer(&host->timer); if (!handler) handler = mg_unexpected_intr; handler(host); + + spin_unlock(&host->lock); + return IRQ_HANDLED; } @@ -319,7 +324,7 @@ static void mg_read(struct request *req) remains = req->nr_sectors; - if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, 0) != + if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) != MG_ERR_NONE) mg_bad_rw_intr(host); @@ -363,7 +368,7 @@ static void mg_write(struct request *req) remains = req->nr_sectors; - if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, 0) != + if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) != MG_ERR_NONE) { mg_bad_rw_intr(host); return; @@ -521,9 +526,11 @@ void mg_times_out(unsigned long data) char *name; struct request *req; + spin_lock_irq(&host->lock); + req = elv_next_request(host->breq); if (!req) - return; + goto out_unlock; host->mg_do_intr = NULL; @@ -534,6 +541,8 @@ void mg_times_out(unsigned long data) mg_bad_rw_intr(host); mg_request(host->breq); +out_unlock: + spin_unlock_irq(&host->lock); } static void mg_request_poll(struct request_queue *q) -- GitLab From 7090a0a97f55cbf47547a140fcc5a349f32c598c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 28 Apr 2009 12:38:33 +0900 Subject: [PATCH 0771/6080] mg_disk: fix CONFIG_LBD=y warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/block/mg_disk.c: In function ‘mg_dump_status’: drivers/block/mg_disk.c:265: warning: format ‘%ld’ expects type ‘long int’, but argument 2 has type ‘sector_t’ [ Impact: kill build warning ] Cc: unsik Kim Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo --- drivers/block/mg_disk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index d3e72ad08dbe..f3898353d0a8 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -79,7 +79,7 @@ static void mg_dump_status(const char *msg, unsigned int stat, if (host->breq) { req = elv_next_request(host->breq); if (req) - printk(", sector=%ld", req->sector); + printk(", sector=%u", (u32)req->sector); } } -- GitLab From e93b9fb7d85da4fd9d5171649e5ddcac1dd572bf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 12:38:33 +0900 Subject: [PATCH 0772/6080] hd: fix locking hd dance around local irq and HD_IRQ enable without achieving much. It ends up transferring data from irq handler with both local irq and HD_IRQ disabled. The only place it actually does something is while transferring the first block of a request which it does with HD_IRQ disabled but local irq enabled. Unfortunately, the dancing is horribly broken from locking POV. IRQ and timeout handlers access block queue without grabbing the queue lock and running the driver in SMP configuration crashes the whole machine pretty quickly. Remove meaningless irq enable/disable dancing and add proper locking in issue, irq and timeout paths. Signed-off-by: Tejun Heo --- drivers/block/hd.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 3c11f062a18c..baaa9e486e50 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -509,7 +509,6 @@ ok_to_write: if (i > 0) { SET_HANDLER(&write_intr); outsw(HD_DATA, req->buffer, 256); - local_irq_enable(); } else { #if (HD_DELAY > 0) last_req = read_timer(); @@ -541,8 +540,7 @@ static void hd_times_out(unsigned long dummy) if (!CURRENT) return; - disable_irq(HD_IRQ); - local_irq_enable(); + spin_lock_irq(hd_queue->queue_lock); reset = 1; name = CURRENT->rq_disk->disk_name; printk("%s: timeout\n", name); @@ -552,9 +550,8 @@ static void hd_times_out(unsigned long dummy) #endif end_request(CURRENT, 0); } - local_irq_disable(); hd_request(); - enable_irq(HD_IRQ); + spin_unlock_irq(hd_queue->queue_lock); } static int do_special_op(struct hd_i_struct *disk, struct request *req) @@ -592,7 +589,6 @@ static void hd_request(void) return; repeat: del_timer(&device_timer); - local_irq_enable(); req = CURRENT; if (!req) { @@ -601,7 +597,6 @@ repeat: } if (reset) { - local_irq_disable(); reset_hd(); return; } @@ -660,9 +655,7 @@ repeat: static void do_hd_request(struct request_queue *q) { - disable_irq(HD_IRQ); hd_request(); - enable_irq(HD_IRQ); } static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) @@ -684,12 +677,16 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id) { void (*handler)(void) = do_hd; + spin_lock(hd_queue->queue_lock); + do_hd = NULL; del_timer(&device_timer); if (!handler) handler = unexpected_hd_interrupt; handler(); - local_irq_enable(); + + spin_unlock(hd_queue->queue_lock); + return IRQ_HANDLED; } -- GitLab From e686307fdc84f249490e6c9da92fcb2424491f14 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 17 Apr 2009 08:41:21 +0200 Subject: [PATCH 0773/6080] loop: use BIO list management functions Now that the bio list management stuff is generic, convert loop to use bio lists instead of its own private bio list implementation. Cc: Jens Axboe Cc: Christoph Hellwig Signed-off-by: Akinobu Mita Signed-off-by: Jens Axboe --- drivers/block/loop.c | 26 +++++++------------------- include/linux/bio.h | 2 +- include/linux/loop.h | 3 +-- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index ddae80825899..9ca4bb014657 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -511,11 +511,7 @@ out: */ static void loop_add_bio(struct loop_device *lo, struct bio *bio) { - if (lo->lo_biotail) { - lo->lo_biotail->bi_next = bio; - lo->lo_biotail = bio; - } else - lo->lo_bio = lo->lo_biotail = bio; + bio_list_add(&lo->lo_bio_list, bio); } /* @@ -523,16 +519,7 @@ static void loop_add_bio(struct loop_device *lo, struct bio *bio) */ static struct bio *loop_get_bio(struct loop_device *lo) { - struct bio *bio; - - if ((bio = lo->lo_bio)) { - if (bio == lo->lo_biotail) - lo->lo_biotail = NULL; - lo->lo_bio = bio->bi_next; - bio->bi_next = NULL; - } - - return bio; + return bio_list_pop(&lo->lo_bio_list); } static int loop_make_request(struct request_queue *q, struct bio *old_bio) @@ -609,12 +596,13 @@ static int loop_thread(void *data) set_user_nice(current, -20); - while (!kthread_should_stop() || lo->lo_bio) { + while (!kthread_should_stop() || !bio_list_empty(&lo->lo_bio_list)) { wait_event_interruptible(lo->lo_event, - lo->lo_bio || kthread_should_stop()); + !bio_list_empty(&lo->lo_bio_list) || + kthread_should_stop()); - if (!lo->lo_bio) + if (bio_list_empty(&lo->lo_bio_list)) continue; spin_lock_irq(&lo->lo_lock); bio = loop_get_bio(lo); @@ -841,7 +829,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, lo->old_gfp_mask = mapping_gfp_mask(mapping); mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); - lo->lo_bio = lo->lo_biotail = NULL; + bio_list_init(&lo->lo_bio_list); /* * set queue make_request_fn, and add limits based on lower level diff --git a/include/linux/bio.h b/include/linux/bio.h index 7b214fd672a2..f37ca8c726ba 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -506,7 +506,7 @@ static inline int bio_has_data(struct bio *bio) } /* - * BIO list managment for use by remapping drivers (e.g. DM or MD). + * BIO list management for use by remapping drivers (e.g. DM or MD) and loop. * * A bio_list anchors a singly-linked list of bios chained through the bi_next * member of the bio. The bio_list also caches the last list member to allow diff --git a/include/linux/loop.h b/include/linux/loop.h index 40725447f5e0..66c194e2d9b9 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h @@ -56,8 +56,7 @@ struct loop_device { gfp_t old_gfp_mask; spinlock_t lo_lock; - struct bio *lo_bio; - struct bio *lo_biotail; + struct bio_list lo_bio_list; int lo_state; struct mutex lo_ctl_mutex; struct task_struct *lo_thread; -- GitLab From 924cec7789f65ab7f022256f6533ecba0747b5f3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0774/6080] block: clear req->errors on bio completion only for fs requests Impact: subtle behavior change For fs requests, rq is only carrier of bios and rq error status as a whole doesn't mean much. This is the reason why rq->errors is being cleared on each partial completion of a request as on each partial completion the error status is transferred to the respective bios. For pc requests, rq->errors is used to carry error status to the issuer and thus __end_that_request_first() doesn't clear it on such cases. The condition was fine till now as only fs and pc requests have used bio and thus the bio completion path. However, future changes will unify data accesses to bio and all non fs users care about rq error status. Clear rq->errors on bio completion only for fs requests. In general, the implicit clearing is a bit too subtle especially as the meaning of rq->errors is completely dependent on low level drivers. Unifying / cleaning up rq->errors usage and letting llds manage it would be better. TODO comment added. Signed-off-by: Tejun Heo Acked-by: Jens Axboe --- block/blk-core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 2998fe3a2377..41bc0ff75e28 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1741,10 +1741,14 @@ static int __end_that_request_first(struct request *req, int error, trace_block_rq_complete(req->q, req); /* - * for a REQ_TYPE_BLOCK_PC request, we want to carry any eventual - * sense key with us all the way through + * For fs requests, rq is just carrier of independent bio's + * and each partial completion should be handled separately. + * Reset per-request error on each partial completion. + * + * TODO: tj: This is too subtle. It would be better to let + * low level drivers do what they see fit. */ - if (!blk_pc_request(req)) + if (blk_fs_request(req)) req->errors = 0; if (error && (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))) { -- GitLab From 0de57fb93b1daaeaecb658a98b3299ae460c02e9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0775/6080] ide-tape: remove back-to-back REQUEST_SENSE detection Impact: fix an oops which always triggers ide_tape_issue_pc() assumed drive->pc isn't NULL on invocation when checking for back-to-back request sense issues but drive->pc can be NULL and even when it's not NULL, it's not safe to dereference it once the previous command is complete because pc could have been freed or was on stack. Kill back-to-back REQUEST_SENSE detection. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index cb942a9b580f..3a53e0834cf7 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -614,12 +614,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, { idetape_tape_t *tape = drive->driver_data; - if (drive->pc->c[0] == REQUEST_SENSE && - pc->c[0] == REQUEST_SENSE) { - printk(KERN_ERR "ide-tape: possible ide-tape.c bug - " - "Two request sense in serial were issued\n"); - } - if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) drive->failed_pc = pc; -- GitLab From 220d06b5531e7b8a6226b2fdfb21198c3ccc4f76 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0776/6080] ide: use blk_run_queue() instead of blk_start_queueing() blk_start_queueing() is being phased out in favor of [__]blk_run_queue(). Switch. Signed-off-by: Tejun Heo --- drivers/ide/ide-park.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 310d03f2b5b7..a914023d6d03 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c @@ -24,11 +24,8 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) start_queue = 1; spin_unlock_irq(&hwif->lock); - if (start_queue) { - spin_lock_irq(q->queue_lock); - blk_start_queueing(q); - spin_unlock_irq(q->queue_lock); - } + if (start_queue) + blk_run_queue(q); return; } spin_unlock_irq(&hwif->lock); -- GitLab From b2963ac1738542d30305d7e12c8c078a383a425c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0777/6080] ide: don't set REQ_SOFTBARRIER ide doesn't have to worry about REQ_SOFTBARRIER. Don't set it. Signed-off-by: Tejun Heo --- drivers/ide/ide-disk.c | 1 - drivers/ide/ide-ioctls.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index a9fbe2c31210..c2438804d3c4 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -411,7 +411,6 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) cmd->protocol = ATA_PROT_NODATA; rq->cmd_type = REQ_TYPE_ATA_TASKFILE; - rq->cmd_flags |= REQ_SOFTBARRIER; rq->special = cmd; } diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index c1c25ebbaa1f..5991b23793f2 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -231,7 +231,6 @@ static int generic_drive_reset(ide_drive_t *drive) rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_len = 1; rq->cmd[0] = REQ_DRIVE_RESET; - rq->cmd_flags |= REQ_SOFTBARRIER; if (blk_execute_rq(drive->queue, NULL, rq, 1)) ret = rq->errors; blk_put_request(rq); -- GitLab From 214ae19104141404f18ad6651752eb38e3dd584e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0778/6080] ide kill unused ide_cmd->special Impact: removal of unused field No one uses ide_cmd->special anymore. Kill it. Signed-off-by: Tejun Heo --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/ide.h b/include/linux/ide.h index ff65fffb078f..846a1e132407 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -324,7 +324,6 @@ struct ide_cmd { unsigned int cursg_ofs; struct request *rq; /* copy of request */ - void *special; /* valid_t generally */ }; /* ATAPI packet command flags */ -- GitLab From 59a4f6f355fc718581ddcf1bb45a469d4756c035 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:41 +0900 Subject: [PATCH 0779/6080] ide-cd: clear sense buffer before issuing request sense Impact: code simplification ide_cd_request_sense_fixup() clears the tail of the sense buffer if the device didn't completely fill it. This patch makes cdrom_queue_request_sense() clear the sense buffer before issuing the command instead of clearing it afterwards. This simplifies code and eases future changes. Signed-off-by: Tejun Heo --- drivers/ide/ide-cd.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3d4e09969763..b6a0d126b576 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -217,6 +217,8 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, if (sense == NULL) sense = &info->sense_data; + memset(sense, 0, 18); + /* stuff the sense request in front of our current request */ blk_rq_init(NULL, rq); rq->cmd_type = REQ_TYPE_ATA_PC; @@ -504,14 +506,8 @@ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) * and some drives don't send them. Sigh. */ if (rq->cmd[0] == GPCMD_REQUEST_SENSE && - cmd->nleft > 0 && cmd->nleft <= 5) { - unsigned int ofs = cmd->nbytes - cmd->nleft; - - while (cmd->nleft > 0) { - *((u8 *)rq->data + ofs++) = 0; - cmd->nleft--; - } - } + cmd->nleft > 0 && cmd->nleft <= 5) + cmd->nleft = 0; } int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, -- GitLab From 8968932e54db35cf9d69cfbbd50c26dfaaa586c7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0780/6080] ide-floppy: block pc always uses bio Impact: remove unnecessary code path Block pc requests always use bio and rq->data is always NULL. No need to worry about !rq->bio cases in idefloppy_block_pc_cmd(). Note that ide-atapi uses ide_pio_bytes() for bio PIO transfer which handle sg fine. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-floppy.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 2b4868d95f8b..3b22e066287e 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -216,15 +216,13 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, ide_init_pc(pc); memcpy(pc->c, rq->cmd, sizeof(pc->c)); pc->rq = rq; - if (rq->data_len && rq_data_dir(rq) == WRITE) - pc->flags |= PC_FLAG_WRITING; - pc->buf = rq->data; - if (rq->bio) + if (rq->data_len) { pc->flags |= PC_FLAG_DMA_OK; - /* - * possibly problematic, doesn't look like ide-floppy correctly - * handled scattered requests if dma fails... - */ + if (rq_data_dir(rq) == WRITE) + pc->flags |= PC_FLAG_WRITING; + } + /* pio will be performed by ide_pio_bytes() which handles sg fine */ + pc->buf = NULL; pc->req_xfer = pc->buf_size = rq->data_len; } -- GitLab From d868ca24302e99a0e8a86071ca2c66273edf97d9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0781/6080] ide-taskfile: don't abuse rq->buffer Impact: rq->buffer usage cleanup ide_raw_taskfile() directly uses rq->buffer to carry pointer to the data buffer. This complicates both block interface and ide backend request handling. Use blk_rq_map_kern() instead and drop special handling for REQ_TYPE_ATA_TASKFILE from ide_map_sg(). Note that REQ_RW setting is moved upwards as blk_rq_map_kern() uses it to initialize bio rw flag. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-io.c | 5 +---- drivers/ide/ide-taskfile.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 35dc38d3b2c5..9b9e8b1aae5e 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -248,10 +248,7 @@ void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) struct scatterlist *sg = hwif->sg_table; struct request *rq = cmd->rq; - if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { - sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE); - cmd->sg_nents = 1; - } else if (!rq->bio) { + if (!rq->bio) { sg_init_one(sg, rq->data, rq->data_len); cmd->sg_nents = 1; } else diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 4aa6223c11be..f400eb4d4aff 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -424,7 +424,9 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_ATA_TASKFILE; - rq->buffer = buf; + + if (cmd->tf_flags & IDE_TFLAG_WRITE) + rq->cmd_flags |= REQ_RW; /* * (ks) We transfer currently only whole sectors. @@ -432,18 +434,20 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf, * if we would find a solution to transfer any size. * To support special commands like READ LONG. */ - rq->hard_nr_sectors = rq->nr_sectors = nsect; - rq->hard_cur_sectors = rq->current_nr_sectors = nsect; - - if (cmd->tf_flags & IDE_TFLAG_WRITE) - rq->cmd_flags |= REQ_RW; + if (nsect) { + error = blk_rq_map_kern(drive->queue, rq, buf, + nsect * SECTOR_SIZE, __GFP_WAIT); + if (error) + goto put_req; + } rq->special = cmd; cmd->rq = rq; error = blk_execute_rq(drive->queue, NULL, rq, 0); - blk_put_request(rq); +put_req: + blk_put_request(rq); return error; } -- GitLab From ac0b0113ddbab3ed2388132d368c97292f9f3c84 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0782/6080] ide-atapi: don't abuse rq->buffer Impact: rq->buffer usage cleanup ide-atapi uses rq->buffer as private opaque value for internal special requests. rq->special isn't used for these cases (the only case where rq->special is used is for ide-tape rw requests). Use rq->special instead. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-atapi.c | 4 ++-- drivers/ide/ide-floppy.c | 2 +- drivers/ide/ide-tape.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 7201b176d75b..2894577237ba 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -90,7 +90,7 @@ static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, blk_rq_init(NULL, rq); rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd_flags |= REQ_PREEMPT; - rq->buffer = (char *)pc; + rq->special = (char *)pc; rq->rq_disk = disk; if (pc->req_xfer) { @@ -119,7 +119,7 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_SPECIAL; - rq->buffer = (char *)pc; + rq->special = (char *)pc; if (pc->req_xfer) { rq->data = pc->buf; diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 3b22e066287e..94600331a271 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -264,7 +264,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, pc = &floppy->queued_pc; idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); } else if (blk_special_request(rq)) { - pc = (struct ide_atapi_pc *) rq->buffer; + pc = (struct ide_atapi_pc *)rq->special; } else if (blk_pc_request(rq)) { pc = &floppy->queued_pc; idefloppy_blockpc_cmd(floppy, pc, rq); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 3a53e0834cf7..aadf53cfac6f 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -828,7 +828,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, goto out; } if (rq->cmd[13] & REQ_IDETAPE_PC1) { - pc = (struct ide_atapi_pc *) rq->buffer; + pc = (struct ide_atapi_pc *)rq->special; rq->cmd[13] &= ~(REQ_IDETAPE_PC1); rq->cmd[13] |= REQ_IDETAPE_PC2; goto out; -- GitLab From 1f181d2b1569dfb88a584a6e1847e9e1c7645951 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0783/6080] ide-cd: don't abuse rq->buffer Impact: rq->buffer usage cleanup ide-cd uses rq->buffer to carry pointer to the original request when issuing REQUEST_SENSE. Use rq->special instead. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-cd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index b6a0d126b576..bb77c79c1018 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -232,8 +232,8 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, rq->cmd_type = REQ_TYPE_SENSE; rq->cmd_flags |= REQ_PREEMPT; - /* NOTE! Save the failed command in "rq->buffer" */ - rq->buffer = (void *) failed_command; + /* NOTE! Save the failed command in "rq->special" */ + rq->special = (void *)failed_command; if (failed_command) ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x", @@ -247,10 +247,10 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) { /* - * For REQ_TYPE_SENSE, "rq->buffer" points to the original + * For REQ_TYPE_SENSE, "rq->special" points to the original * failed request */ - struct request *failed = (struct request *)rq->buffer; + struct request *failed = (struct request *)rq->special; struct cdrom_info *info = drive->driver_data; void *sense = &info->sense_data; -- GitLab From e69d800f7e8797a8e3423380ee9d8ca1cb90c388 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0784/6080] ide: add helpers for preparing sense requests This is in preparation of removing the queueing of a sense request out of the IRQ handler path. Use struct request_sense as a general sense buffer for all ATAPI devices ide-{floppy,tape,cd}. tj: * blk_get_request(__GFP_WAIT) can't be called from do_request() as it can cause deadlock. Converted to use inline struct request and blk_rq_init(). * Added xfer / cdb len selection depending on device type. * All sense prep logics folded into ide_prep_sense() which never fails. * hwif->rq clearing and sense_rq used handling moved into ide_queue_sense_rq(). * blk_rq_map_kern() conversion is moved to later patch. CC: Bartlomiej Zolnierkiewicz CC: FUJITA Tomonori Signed-off-by: Borislav Petkov Signed-off-by: Tejun Heo --- drivers/ide/ide-atapi.c | 61 +++++++++++++++++++++++++++++++++++++++++ include/linux/ide.h | 11 ++++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 2894577237ba..c6e03485a63a 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -191,6 +191,67 @@ void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc) } EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd); +void ide_prep_sense(ide_drive_t *drive, struct request *rq) +{ + struct request_sense *sense = &drive->sense_data; + struct request *sense_rq = &drive->sense_rq; + unsigned int cmd_len, sense_len; + + debug_log("%s: enter\n", __func__); + + switch (drive->media) { + case ide_floppy: + cmd_len = 255; + sense_len = 18; + break; + case ide_tape: + cmd_len = 20; + sense_len = 20; + break; + default: + cmd_len = 18; + sense_len = 18; + } + + BUG_ON(sense_len > sizeof(*sense)); + + if (blk_sense_request(rq) || drive->sense_rq_armed) + return; + + memset(sense, 0, sizeof(*sense)); + + blk_rq_init(rq->q, sense_rq); + sense_rq->rq_disk = rq->rq_disk; + + sense_rq->data = sense; + sense_rq->cmd[0] = GPCMD_REQUEST_SENSE; + sense_rq->cmd[4] = cmd_len; + sense_rq->data_len = sense_len; + + sense_rq->cmd_type = REQ_TYPE_SENSE; + sense_rq->cmd_flags |= REQ_PREEMPT; + + if (drive->media == ide_tape) + sense_rq->cmd[13] = REQ_IDETAPE_PC1; + + drive->sense_rq_armed = true; +} +EXPORT_SYMBOL_GPL(ide_prep_sense); + +void ide_queue_sense_rq(ide_drive_t *drive, void *special) +{ + BUG_ON(!drive->sense_rq_armed); + + drive->sense_rq.special = special; + drive->sense_rq_armed = false; + + drive->hwif->rq = NULL; + + elv_add_request(drive->queue, &drive->sense_rq, + ELEVATOR_INSERT_FRONT, 0); +} +EXPORT_SYMBOL_GPL(ide_queue_sense_rq); + /* * Called when an error was detected during the last packet command. * We queue a request sense packet command in the head of the request list. diff --git a/include/linux/ide.h b/include/linux/ide.h index 846a1e132407..a69ccac56411 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -26,6 +26,9 @@ #include #include +/* for request_sense */ +#include + #if defined(CONFIG_CRIS) || defined(CONFIG_FRV) || defined(CONFIG_MN10300) # define SUPPORT_VLB_SYNC 0 #else @@ -602,6 +605,11 @@ struct ide_drive_s { struct ide_atapi_pc request_sense_pc; struct request request_sense_rq; + + /* current sense rq and buffer */ + bool sense_rq_armed; + struct request sense_rq; + struct request_sense sense_data; }; typedef struct ide_drive_s ide_drive_t; @@ -1175,6 +1183,9 @@ int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); void ide_retry_pc(ide_drive_t *, struct gendisk *); +void ide_prep_sense(ide_drive_t *drive, struct request *rq); +void ide_queue_sense_rq(ide_drive_t *drive, void *special); + int ide_cd_expiry(ide_drive_t *); int ide_cd_get_xferlen(struct request *); -- GitLab From c457ce874a0f3dfa3d5e9f2309789f6f34e24325 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0785/6080] ide-cd: convert to using generic sense request Preallocate a sense request in the ->do_request method and reinitialize it only on demand, in case it's been consumed in the IRQ handler path. The reason for this is that we don't want to be mapping rq to bio in the IRQ path and introduce all kinds of unnecessary hacks to the block layer. tj: * Both user and kernel PC requests expect sense data to be stored in separate storage other than drive->sense_data. Copy sense data to rq->sense on completion if rq->sense is not NULL. This fixes bogus sense data on PC requests. As a result, remove cdrom_queue_request_sense. CC: Bartlomiej Zolnierkiewicz CC: FUJITA Tomonori Signed-off-by: Borislav Petkov Signed-off-by: Tejun Heo --- drivers/ide/ide-cd.c | 54 ++++++++++---------------------------------- drivers/ide/ide-cd.h | 4 ---- 2 files changed, 12 insertions(+), 46 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index bb77c79c1018..061d7bbcd34a 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -206,44 +206,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, ide_cd_log_error(drive->name, failed_command, sense); } -static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, - struct request *failed_command) -{ - struct cdrom_info *info = drive->driver_data; - struct request *rq = &drive->request_sense_rq; - - ide_debug_log(IDE_DBG_SENSE, "enter"); - - if (sense == NULL) - sense = &info->sense_data; - - memset(sense, 0, 18); - - /* stuff the sense request in front of our current request */ - blk_rq_init(NULL, rq); - rq->cmd_type = REQ_TYPE_ATA_PC; - rq->rq_disk = info->disk; - - rq->data = sense; - rq->cmd[0] = GPCMD_REQUEST_SENSE; - rq->cmd[4] = 18; - rq->data_len = 18; - - rq->cmd_type = REQ_TYPE_SENSE; - rq->cmd_flags |= REQ_PREEMPT; - - /* NOTE! Save the failed command in "rq->special" */ - rq->special = (void *)failed_command; - - if (failed_command) - ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x", - failed_command->cmd[0]); - - drive->hwif->rq = NULL; - - elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); -} - static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) { /* @@ -251,11 +213,16 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) * failed request */ struct request *failed = (struct request *)rq->special; - struct cdrom_info *info = drive->driver_data; - void *sense = &info->sense_data; + struct request_sense *sense = &drive->sense_data; if (failed) { if (failed->sense) { + /* + * Sense is always read into drive->sense_data. + * Copy back if the failed request has its + * sense pointer set. + */ + memcpy(failed->sense, sense, 18); sense = failed->sense; failed->sense_len = rq->sense_len; } @@ -431,7 +398,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) /* if we got a CHECK_CONDITION status, queue a request sense command */ if (stat & ATA_ERR) - cdrom_queue_request_sense(drive, NULL, NULL); + ide_queue_sense_rq(drive, NULL); return 1; end_request: @@ -445,7 +412,7 @@ end_request: hwif->rq = NULL; - cdrom_queue_request_sense(drive, rq->sense, rq); + ide_queue_sense_rq(drive, rq); return 1; } else return 2; @@ -893,6 +860,9 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, goto out_end; } + /* prepare sense request for this command */ + ide_prep_sense(drive, rq); + memset(&cmd, 0, sizeof(cmd)); if (rq_data_dir(rq)) diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 1d97101099ce..93a3cf1b0f3f 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -87,10 +87,6 @@ struct cdrom_info { struct atapi_toc *toc; - /* The result of the last successful request sense command - on this device. */ - struct request_sense sense_data; - u8 max_speed; /* Max speed of the drive. */ u8 current_speed; /* Current speed of the drive. */ -- GitLab From 068753203e6cd085664a62e0fc0636e19b148a12 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0786/6080] ide-atapi: convert ide-{floppy,tape} to using preallocated sense buffer Since we're issuing REQ_TYPE_SENSE now we need to allow those types of rqs in the ->do_request callbacks. As a future improvement, sense_len assignment might be unified across all ATAPI devices. Borislav to check with specs and test. As a result, get rid of ide_queue_pc_head() and drive->request_sense_rq. tj: * Init request sense ide_atapi_pc from sense request. In the longer timer, it would probably better to fold ide_create_request_sense_cmd() into its only current user - ide_floppy_get_format_progress(). * ide_retry_pc() no longer takes @disk. CC: Bartlomiej Zolnierkiewicz CC: FUJITA Tomonori Signed-off-by: Borislav Petkov Signed-off-by: Tejun Heo --- drivers/ide/ide-atapi.c | 48 ++++++++++++---------------------------- drivers/ide/ide-floppy.c | 4 +++- drivers/ide/ide-tape.c | 7 ++++-- include/linux/ide.h | 3 +-- 4 files changed, 23 insertions(+), 39 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index c6e03485a63a..972c522516f8 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -79,34 +79,6 @@ void ide_init_pc(struct ide_atapi_pc *pc) } EXPORT_SYMBOL_GPL(ide_init_pc); -/* - * Generate a new packet command request in front of the request queue, before - * the current request, so that it will be processed immediately, on the next - * pass through the driver. - */ -static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk, - struct ide_atapi_pc *pc, struct request *rq) -{ - blk_rq_init(NULL, rq); - rq->cmd_type = REQ_TYPE_SPECIAL; - rq->cmd_flags |= REQ_PREEMPT; - rq->special = (char *)pc; - rq->rq_disk = disk; - - if (pc->req_xfer) { - rq->data = pc->buf; - rq->data_len = pc->req_xfer; - } - - memcpy(rq->cmd, pc->c, 12); - if (drive->media == ide_tape) - rq->cmd[13] = REQ_IDETAPE_PC1; - - drive->hwif->rq = NULL; - - elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); -} - /* * Add a special packet command request to the tail of the request queue, * and wait for it to be serviced. @@ -254,18 +226,26 @@ EXPORT_SYMBOL_GPL(ide_queue_sense_rq); /* * Called when an error was detected during the last packet command. - * We queue a request sense packet command in the head of the request list. + * We queue a request sense packet command at the head of the request + * queue. */ -void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk) +void ide_retry_pc(ide_drive_t *drive) { - struct request *rq = &drive->request_sense_rq; + struct request *sense_rq = &drive->sense_rq; struct ide_atapi_pc *pc = &drive->request_sense_pc; (void)ide_read_error(drive); - ide_create_request_sense_cmd(drive, pc); + + /* init pc from sense_rq */ + ide_init_pc(pc); + memcpy(pc->c, sense_rq->cmd, 12); + pc->buf = sense_rq->data; + pc->req_xfer = sense_rq->data_len; + if (drive->media == ide_tape) set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - ide_queue_pc_head(drive, disk, pc, rq); + + ide_queue_sense_rq(drive, pc); } EXPORT_SYMBOL_GPL(ide_retry_pc); @@ -404,7 +384,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) debug_log("[cmd %x]: check condition\n", rq->cmd[0]); /* Retry operation */ - ide_retry_pc(drive, rq->rq_disk); + ide_retry_pc(drive); /* queued, but not started */ return ide_stopped; diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 94600331a271..d3302cc891e4 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -263,7 +263,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, } pc = &floppy->queued_pc; idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); - } else if (blk_special_request(rq)) { + } else if (blk_special_request(rq) || blk_sense_request(rq)) { pc = (struct ide_atapi_pc *)rq->special; } else if (blk_pc_request(rq)) { pc = &floppy->queued_pc; @@ -273,6 +273,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, goto out_end; } + ide_prep_sense(drive, rq); + memset(&cmd, 0, sizeof(cmd)); if (rq_data_dir(rq)) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index aadf53cfac6f..8324dfa78a3f 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -695,7 +695,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) printk(KERN_ERR "ide-tape: %s: I/O error, ", tape->name); /* Retry operation */ - ide_retry_pc(drive, tape->disk); + ide_retry_pc(drive); return ide_stopped; } pc->error = 0; @@ -752,7 +752,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, (unsigned long long)rq->sector, rq->nr_sectors, rq->current_nr_sectors); - if (!blk_special_request(rq)) { + if (!(blk_special_request(rq) || blk_sense_request(rq))) { /* We do not support buffer cache originated requests. */ printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " "request queue (%d)\n", drive->name, rq->cmd_type); @@ -840,6 +840,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, BUG(); out: + /* prepare sense request for this command */ + ide_prep_sense(drive, rq); + memset(&cmd, 0, sizeof(cmd)); if (rq_data_dir(rq)) diff --git a/include/linux/ide.h b/include/linux/ide.h index a69ccac56411..9e67ccac3c1f 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -604,7 +604,6 @@ struct ide_drive_s { unsigned long atapi_flags; struct ide_atapi_pc request_sense_pc; - struct request request_sense_rq; /* current sense rq and buffer */ bool sense_rq_armed; @@ -1181,7 +1180,7 @@ int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); -void ide_retry_pc(ide_drive_t *, struct gendisk *); +void ide_retry_pc(ide_drive_t *drive); void ide_prep_sense(ide_drive_t *drive, struct request *rq); void ide_queue_sense_rq(ide_drive_t *drive, void *special); -- GitLab From 02e7cf8f848841ca21864ccd019e480b73c323b7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:42 +0900 Subject: [PATCH 0787/6080] ide-cd,atapi: use bio for internal commands Impact: unify request data buffer handling rq->data is used mostly to pass kernel buffer through request queue without using bio. There are only a couple of places which still do this in kernel and converting to bio isn't difficult. This patch converts ide-cd and atapi to use bio instead of rq->data for request sense and internal pc commands. With previous change to unify sense request handling, this is relatively easily achieved by adding blk_rq_map_kern() during sense_rq prep and PC issue. If blk_rq_map_kern() fails for sense, the error is deferred till sense issue and aborts the failed command which triggered the sense. Note that this is a slim possibility as sense prep is done on each command issue, so for the above condition to actually trigger, all preps since the last sense issue till the issue of the request which would require a sense should fail. * do_request functions might sleep now. This should be okay as ide request_fn - do_ide_request() - is invoked only from make_request and plug work. Make sure this is the case by adding might_sleep() to do_ide_request(). * Functions which access the read sense data before the sense request is complete now should access bio_data(sense_rq->bio) as the sense buffer might have been copied during blk_rq_map_kern(). * ide-tape updated to map sg. * cdrom_do_block_pc() now doesn't have to deal with REQ_TYPE_ATA_PC special case. Simplified. * tp_ops->output/input_data path dropped from ide_pc_intr(). Signed-off-by: Tejun Heo --- drivers/ide/ide-atapi.c | 52 ++++++++++++++++++++++++----------------- drivers/ide/ide-cd.c | 28 +++++++++++----------- drivers/ide/ide-io.c | 3 +++ drivers/ide/ide-tape.c | 3 +++ include/linux/ide.h | 2 +- 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 972c522516f8..5cefe12f5622 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -94,16 +94,18 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, rq->special = (char *)pc; if (pc->req_xfer) { - rq->data = pc->buf; - rq->data_len = pc->req_xfer; + error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer, + GFP_NOIO); + if (error) + goto put_req; } memcpy(rq->cmd, pc->c, 12); if (drive->media == ide_tape) rq->cmd[13] = REQ_IDETAPE_PC1; error = blk_execute_rq(drive->queue, disk, rq, 0); +put_req: blk_put_request(rq); - return error; } EXPORT_SYMBOL_GPL(ide_queue_pc_tail); @@ -168,6 +170,7 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) struct request_sense *sense = &drive->sense_data; struct request *sense_rq = &drive->sense_rq; unsigned int cmd_len, sense_len; + int err; debug_log("%s: enter\n", __func__); @@ -193,13 +196,19 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) memset(sense, 0, sizeof(*sense)); blk_rq_init(rq->q, sense_rq); - sense_rq->rq_disk = rq->rq_disk; - sense_rq->data = sense; + err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len, + GFP_NOIO); + if (unlikely(err)) { + if (printk_ratelimit()) + printk(KERN_WARNING "%s: failed to map sense buffer\n", + drive->name); + return; + } + + sense_rq->rq_disk = rq->rq_disk; sense_rq->cmd[0] = GPCMD_REQUEST_SENSE; sense_rq->cmd[4] = cmd_len; - sense_rq->data_len = sense_len; - sense_rq->cmd_type = REQ_TYPE_SENSE; sense_rq->cmd_flags |= REQ_PREEMPT; @@ -210,9 +219,14 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) } EXPORT_SYMBOL_GPL(ide_prep_sense); -void ide_queue_sense_rq(ide_drive_t *drive, void *special) +int ide_queue_sense_rq(ide_drive_t *drive, void *special) { - BUG_ON(!drive->sense_rq_armed); + /* deferred failure from ide_prep_sense() */ + if (!drive->sense_rq_armed) { + printk(KERN_WARNING "%s: failed queue sense request\n", + drive->name); + return -ENOMEM; + } drive->sense_rq.special = special; drive->sense_rq_armed = false; @@ -221,6 +235,7 @@ void ide_queue_sense_rq(ide_drive_t *drive, void *special) elv_add_request(drive->queue, &drive->sense_rq, ELEVATOR_INSERT_FRONT, 0); + return 0; } EXPORT_SYMBOL_GPL(ide_queue_sense_rq); @@ -239,13 +254,14 @@ void ide_retry_pc(ide_drive_t *drive) /* init pc from sense_rq */ ide_init_pc(pc); memcpy(pc->c, sense_rq->cmd, 12); - pc->buf = sense_rq->data; + pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */ pc->req_xfer = sense_rq->data_len; if (drive->media == ide_tape) set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); - ide_queue_sense_rq(drive, pc); + if (ide_queue_sense_rq(drive, pc)) + ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); } EXPORT_SYMBOL_GPL(ide_retry_pc); @@ -317,7 +333,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) struct ide_cmd *cmd = &hwif->cmd; struct request *rq = hwif->rq; const struct ide_tp_ops *tp_ops = hwif->tp_ops; - xfer_func_t *xferfunc; unsigned int timeout, done; u16 bcount; u8 stat, ireason, dsc = 0; @@ -411,7 +426,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) rq->errors = -EIO; } - if (drive->media == ide_tape) + if (drive->media == ide_tape && !rq->bio) done = ide_rq_bytes(rq); /* FIXME */ else done = blk_rq_bytes(rq); @@ -448,16 +463,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) return ide_do_reset(drive); } - xferfunc = write ? tp_ops->output_data : tp_ops->input_data; - - if (drive->media == ide_floppy && pc->buf == NULL) { + if (drive->media == ide_tape && pc->bh) + done = drive->pc_io_buffers(drive, pc, bcount, write); + else { done = min_t(unsigned int, bcount, cmd->nleft); ide_pio_bytes(drive, cmd, write, done); - } else if (drive->media == ide_tape && pc->bh) { - done = drive->pc_io_buffers(drive, pc, bcount, write); - } else { - done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred); - xferfunc(drive, NULL, pc->cur_pos, done); } /* Update the current position */ diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 061d7bbcd34a..673628790f10 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -210,10 +210,12 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) { /* * For REQ_TYPE_SENSE, "rq->special" points to the original - * failed request + * failed request. Also, the sense data should be read + * directly from rq which might be different from the original + * sense buffer if it got copied during mapping. */ struct request *failed = (struct request *)rq->special; - struct request_sense *sense = &drive->sense_data; + void *sense = bio_data(rq->bio); if (failed) { if (failed->sense) { @@ -398,7 +400,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) /* if we got a CHECK_CONDITION status, queue a request sense command */ if (stat & ATA_ERR) - ide_queue_sense_rq(drive, NULL); + return ide_queue_sense_rq(drive, NULL) ? 2 : 1; return 1; end_request: @@ -412,8 +414,7 @@ end_request: hwif->rq = NULL; - ide_queue_sense_rq(drive, rq); - return 1; + return ide_queue_sense_rq(drive, rq) ? 2 : 1; } else return 2; } @@ -507,8 +508,12 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, rq->cmd_flags |= cmd_flags; rq->timeout = timeout; if (buffer) { - rq->data = buffer; - rq->data_len = *bufflen; + error = blk_rq_map_kern(drive->queue, rq, buffer, + *bufflen, GFP_NOIO); + if (error) { + blk_put_request(rq); + return error; + } } error = blk_execute_rq(drive->queue, info->disk, rq, 0); @@ -802,15 +807,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) drive->dma = 0; /* sg request */ - if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) { + if (rq->bio) { struct request_queue *q = drive->queue; + char *buf = bio_data(rq->bio); unsigned int alignment; - char *buf; - - if (rq->bio) - buf = bio_data(rq->bio); - else - buf = rq->data; drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 9b9e8b1aae5e..3245c2dbda33 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -481,6 +481,9 @@ void do_ide_request(struct request_queue *q) spin_unlock_irq(q->queue_lock); + /* HLD do_request() callback might sleep, make sure it's okay */ + might_sleep(); + if (ide_lock_host(host, hwif)) goto plug_device_2; diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8324dfa78a3f..9b762a2d5d95 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -850,6 +850,9 @@ out: cmd.rq = rq; + ide_init_sg_cmd(&cmd, pc->req_xfer); + ide_map_sg(drive, &cmd); + return ide_tape_issue_pc(drive, &cmd, pc); } diff --git a/include/linux/ide.h b/include/linux/ide.h index 9e67ccac3c1f..1957461ac762 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1183,7 +1183,7 @@ void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); void ide_retry_pc(ide_drive_t *drive); void ide_prep_sense(ide_drive_t *drive, struct request *rq); -void ide_queue_sense_rq(ide_drive_t *drive, void *special); +int ide_queue_sense_rq(ide_drive_t *drive, void *special); int ide_cd_expiry(ide_drive_t *); -- GitLab From 765139ef5f1a4b1d5cb1f1a7a12de7ee61f6500f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 07:00:43 +0900 Subject: [PATCH 0788/6080] ide-pm: don't abuse rq->data Impact: cleanup rq->data usage ide-pm uses rq->data to carry pointer to struct request_pm_state through request queue and rq->special is used to carray pointer to local struct ide_cmd, which isn't necessary. Use rq->special for request_pm_state instead and use local ide_cmd in ide_start_power_step(). Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-io.c | 2 +- drivers/ide/ide-pm.c | 38 +++++++++++++++----------------------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 3245c2dbda33..6e3094e22775 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -368,7 +368,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) return execute_drive_cmd(drive, rq); else if (blk_pm_request(rq)) { - struct request_pm_state *pm = rq->data; + struct request_pm_state *pm = rq->special; #ifdef DEBUG_PM printk("%s: start_power_step(step: %d)\n", drive->name, pm->pm_step); diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index 0d8a151c0a01..ba1488bd8430 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c @@ -7,7 +7,6 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; - struct ide_cmd cmd; int ret; /* call ACPI _GTM only once */ @@ -15,11 +14,9 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) ide_acpi_get_timing(hwif); memset(&rqpm, 0, sizeof(rqpm)); - memset(&cmd, 0, sizeof(cmd)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_SUSPEND; - rq->special = &cmd; - rq->data = &rqpm; + rq->special = &rqpm; rqpm.pm_step = IDE_PM_START_SUSPEND; if (mesg.event == PM_EVENT_PRETHAW) mesg.event = PM_EVENT_FREEZE; @@ -41,7 +38,6 @@ int generic_ide_resume(struct device *dev) ide_hwif_t *hwif = drive->hwif; struct request *rq; struct request_pm_state rqpm; - struct ide_cmd cmd; int err; /* call ACPI _PS0 / _STM only once */ @@ -53,12 +49,10 @@ int generic_ide_resume(struct device *dev) ide_acpi_exec_tfs(drive); memset(&rqpm, 0, sizeof(rqpm)); - memset(&cmd, 0, sizeof(cmd)); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_PM_RESUME; rq->cmd_flags |= REQ_PREEMPT; - rq->special = &cmd; - rq->data = &rqpm; + rq->special = &rqpm; rqpm.pm_step = IDE_PM_START_RESUME; rqpm.pm_state = PM_EVENT_ON; @@ -77,7 +71,7 @@ int generic_ide_resume(struct device *dev) void ide_complete_power_step(ide_drive_t *drive, struct request *rq) { - struct request_pm_state *pm = rq->data; + struct request_pm_state *pm = rq->special; #ifdef DEBUG_PM printk(KERN_INFO "%s: complete_power_step(step: %d)\n", @@ -107,10 +101,8 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq) ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) { - struct request_pm_state *pm = rq->data; - struct ide_cmd *cmd = rq->special; - - memset(cmd, 0, sizeof(*cmd)); + struct request_pm_state *pm = rq->special; + struct ide_cmd cmd = { }; switch (pm->pm_step) { case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ @@ -123,12 +115,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) return ide_stopped; } if (ata_id_flush_ext_enabled(drive->id)) - cmd->tf.command = ATA_CMD_FLUSH_EXT; + cmd.tf.command = ATA_CMD_FLUSH_EXT; else - cmd->tf.command = ATA_CMD_FLUSH; + cmd.tf.command = ATA_CMD_FLUSH; goto out_do_tf; case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ - cmd->tf.command = ATA_CMD_STANDBYNOW1; + cmd.tf.command = ATA_CMD_STANDBYNOW1; goto out_do_tf; case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ ide_set_max_pio(drive); @@ -141,7 +133,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) ide_complete_power_step(drive, rq); return ide_stopped; case IDE_PM_IDLE: /* Resume step 2 (idle) */ - cmd->tf.command = ATA_CMD_IDLEIMMEDIATE; + cmd.tf.command = ATA_CMD_IDLEIMMEDIATE; goto out_do_tf; case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ /* @@ -163,11 +155,11 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) return ide_stopped; out_do_tf: - cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; - cmd->valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; - cmd->protocol = ATA_PROT_NODATA; + cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE; + cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE; + cmd.protocol = ATA_PROT_NODATA; - return do_rw_taskfile(drive, cmd); + return do_rw_taskfile(drive, &cmd); } /** @@ -181,7 +173,7 @@ out_do_tf: void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) { struct request_queue *q = drive->queue; - struct request_pm_state *pm = rq->data; + struct request_pm_state *pm = rq->special; unsigned long flags; ide_complete_power_step(drive, rq); @@ -207,7 +199,7 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) void ide_check_pm_state(ide_drive_t *drive, struct request *rq) { - struct request_pm_state *pm = rq->data; + struct request_pm_state *pm = rq->special; if (blk_pm_suspend_request(rq) && pm->pm_step == IDE_PM_START_SUSPEND) -- GitLab From 08f370f0a2fb223bf48d0bfa2a173be0393c19dc Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0789/6080] ide-tape,floppy: fix failed command completion after request sense Impact: fix infinite retry loop After a command failed, ide-tape and floppy inserts REQUEST_SENSE in front of the failed command and according to the result, sets pc->retries, flags and errors. After REQUEST_SENSE is complete, the failed command is again at the front of the queue and if the verdict was to terminate the request, the issue functions tries to complete it directly by calling drive->pc_callback() and returning ide_stopped. However, drive->pc_callback() doesn't complete a request. It only prepares for completion of the request. As a result, this creates an infinite loop where the failed request is retried perpetually. Fix it by actually ending the request by calling ide_complete_rq(). Signed-off-by: Tejun Heo --- drivers/ide/ide-floppy.c | 1 + drivers/ide/ide-tape.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index d3302cc891e4..d20704ac3183 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -141,6 +141,7 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, drive->failed_pc = NULL; drive->pc_callback(drive, 0); + ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); return ide_stopped; } diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 9b762a2d5d95..2b9a13671c5f 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -643,6 +643,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, } drive->failed_pc = NULL; drive->pc_callback(drive, 0); + ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); -- GitLab From eb6a61bb9543aa54d62595e27206b3d3c0293bcc Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0790/6080] ide-atapi,tape,floppy: allow ->pc_callback() to change rq->data_len Impact: allow residual count implementation in ->pc_callback() rq->data_len has two duties - carrying the number of input bytes on issue and carrying residual count back to the issuer on completion. ide-atapi completion callback ->pc_callback() is the right place to do this but currently ide-atapi depends on rq->data_len carrying the original request size after calling ->pc_callback() to complete the pc request. This patch makes ide_pc_intr(), ide_tape_issue_pc() and ide_floppy_issue_pc() cache length to complete before calling ->pc_callback() so that it can modify rq->data_len as necessary. Note: As using rq->data_len for two purposes can make cases like this incorrect in subtle ways, future changes will introduce separate field for residual count. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-atapi.c | 16 ++++++++++------ drivers/ide/ide-floppy.c | 5 ++++- drivers/ide/ide-tape.c | 5 ++++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 5cefe12f5622..3df5442de710 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -409,6 +409,16 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0) dsc = 1; + /* + * ->pc_callback() might change rq->data_len for + * residual count, cache total length. + */ + if (!blk_special_request(rq) && + (drive->media == ide_tape && !rq->bio)) + done = ide_rq_bytes(rq); /* FIXME */ + else + done = blk_rq_bytes(rq); + /* Command finished - Call the callback function */ uptodate = drive->pc_callback(drive, dsc); @@ -417,7 +427,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if (blk_special_request(rq)) { rq->errors = 0; - done = blk_rq_bytes(rq); error = 0; } else { @@ -426,11 +435,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) rq->errors = -EIO; } - if (drive->media == ide_tape && !rq->bio) - done = ide_rq_bytes(rq); /* FIXME */ - else - done = blk_rq_bytes(rq); - error = uptodate ? 0 : -EIO; } diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index d20704ac3183..537b7c558033 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -134,14 +134,17 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive, drive->pc = pc; if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { + unsigned int done = blk_rq_bytes(drive->hwif->rq); + if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) ide_floppy_report_error(floppy, pc); + /* Giving up */ pc->error = IDE_DRV_ERROR_GENERAL; drive->failed_pc = NULL; drive->pc_callback(drive, 0); - ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); + ide_complete_rq(drive, -EIO, done); return ide_stopped; } diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2b9a13671c5f..8226d52504d0 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -622,6 +622,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, if (pc->retries > IDETAPE_MAX_PC_RETRIES || (pc->flags & PC_FLAG_ABORT)) { + unsigned int done = blk_rq_bytes(drive->hwif->rq); + /* * We will "abort" retrying a packet command in case legitimate * error code was received (crossing a filemark, or end of the @@ -641,9 +643,10 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, /* Giving up */ pc->error = IDE_DRV_ERROR_GENERAL; } + drive->failed_pc = NULL; drive->pc_callback(drive, 0); - ide_complete_rq(drive, -EIO, blk_rq_bytes(drive->hwif->rq)); + ide_complete_rq(drive, -EIO, done); return ide_stopped; } debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); -- GitLab From 7b13354eeaabaf6283b8c669a7d67d104ce7c638 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0791/6080] ide-tape: use single continuous buffer Impact: simpler buffer allocation and handling, kills OOM, fix DMA transfers ide-tape has its own multiple buffer mechanism using struct idetape_bh. It allocates buffer with decreasing order-of-two allocations so that it results in minimum number of segments. However, the implementation is quite complex and works in a way that no other block or ide driver works necessitating a lot of special case handling. The benefit this complex allocation scheme brings is questionable as PIO or DMA the number of segments (16 maximum) doesn't make any noticeable difference and it also doesn't negate the need for multiple order allocation which can fail under memory pressure or high fragmentation although it does lower the highest order necessary by one when the buffer size isn't power of two. As the first step to remove the custom buffer management, this patch makes ide-tape allocate single continous buffer. The maximum order is four. I doubt the change would cause any trouble but if it ever matters, it should be converted to regular sg mechanism like everyone else and even in that case dropping custom buffer handling and moving to standard mechanism first make sense as an intermediate step. This patch makes the first bh to contain the whole buffer and drops multi bh handling code. Following patches will make further changes. This patch has the side effect of killing OOM triggered by allocation path and fixing DMA transfers. Previously, bug in alloc path triggered OOM on command issue and commands were passed to DMA engine without DMA-mapping all the segments. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 256 ++++++++++------------------------------- 1 file changed, 58 insertions(+), 198 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 8226d52504d0..b2afbc7bcb6b 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -134,7 +134,6 @@ enum { struct idetape_bh { u32 b_size; atomic_t b_count; - struct idetape_bh *b_reqnext; char *b_data; }; @@ -228,10 +227,6 @@ typedef struct ide_tape_obj { char *b_data; int b_count; - int pages_per_buffer; - /* Wasted space in each stage */ - int excess_bh_size; - /* Measures average tape speed */ unsigned long avg_time; int avg_size; @@ -303,9 +298,7 @@ static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, struct idetape_bh *bh = pc->bh; int count; - while (bcount) { - if (bh == NULL) - break; + if (bcount && bh) { count = min( (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), bcount); @@ -313,15 +306,10 @@ static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, atomic_read(&bh->b_count), count); bcount -= count; atomic_add(count, &bh->b_count); - if (atomic_read(&bh->b_count) == bh->b_size) { - bh = bh->b_reqnext; - if (bh) - atomic_set(&bh->b_count, 0); - } + if (atomic_read(&bh->b_count) == bh->b_size) + pc->bh = NULL; } - pc->bh = bh; - return bcount; } @@ -331,22 +319,14 @@ static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, struct idetape_bh *bh = pc->bh; int count; - while (bcount) { - if (bh == NULL) - break; + if (bcount && bh) { count = min((unsigned int)pc->b_count, (unsigned int)bcount); drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count); bcount -= count; pc->b_data += count; pc->b_count -= count; - if (!pc->b_count) { - bh = bh->b_reqnext; - pc->bh = bh; - if (bh) { - pc->b_data = bh->b_data; - pc->b_count = atomic_read(&bh->b_count); - } - } + if (!pc->b_count) + pc->bh = NULL; } return bcount; @@ -355,24 +335,20 @@ static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) { struct idetape_bh *bh = pc->bh; - int count; unsigned int bcount = pc->xferred; if (pc->flags & PC_FLAG_WRITING) return; - while (bcount) { - if (bh == NULL) { + if (bcount) { + if (bh == NULL || bcount > bh->b_size) { printk(KERN_ERR "ide-tape: bh == NULL in %s\n", __func__); return; } - count = min((unsigned int)bh->b_size, (unsigned int)bcount); - atomic_set(&bh->b_count, count); + atomic_set(&bh->b_count, bcount); if (atomic_read(&bh->b_count) == bh->b_size) - bh = bh->b_reqnext; - bcount -= count; + pc->bh = NULL; } - pc->bh = bh; } /* @@ -439,24 +415,10 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) /* Free data buffers completely. */ static void ide_tape_kfree_buffer(idetape_tape_t *tape) { - struct idetape_bh *prev_bh, *bh = tape->merge_bh; - - while (bh) { - u32 size = bh->b_size; - - while (size) { - unsigned int order = fls(size >> PAGE_SHIFT)-1; - - if (bh->b_data) - free_pages((unsigned long)bh->b_data, order); + struct idetape_bh *bh = tape->merge_bh; - size &= (order-1); - bh->b_data += (1 << order) * PAGE_SIZE; - } - prev_bh = bh; - bh = bh->b_reqnext; - kfree(prev_bh); - } + kfree(bh->b_data); + kfree(bh); } static void ide_tape_handle_dsc(ide_drive_t *); @@ -861,117 +823,50 @@ out: } /* - * The function below uses __get_free_pages to allocate a data buffer of size - * tape->buffer_size (or a bit more). We attempt to combine sequential pages as - * much as possible. - * - * It returns a pointer to the newly allocated buffer, or NULL in case of - * failure. + * It returns a pointer to the newly allocated buffer, or NULL in case + * of failure. */ static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape, - int full, int clear) -{ - struct idetape_bh *prev_bh, *bh, *merge_bh; - int pages = tape->pages_per_buffer; - unsigned int order, b_allocd; - char *b_data = NULL; - - merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); - bh = merge_bh; - if (bh == NULL) - goto abort; - - order = fls(pages) - 1; - bh->b_data = (char *) __get_free_pages(GFP_KERNEL, order); - if (!bh->b_data) - goto abort; - b_allocd = (1 << order) * PAGE_SIZE; - pages &= (order-1); - - if (clear) - memset(bh->b_data, 0, b_allocd); - bh->b_reqnext = NULL; - bh->b_size = b_allocd; - atomic_set(&bh->b_count, full ? bh->b_size : 0); + int full) +{ + struct idetape_bh *bh; - while (pages) { - order = fls(pages) - 1; - b_data = (char *) __get_free_pages(GFP_KERNEL, order); - if (!b_data) - goto abort; - b_allocd = (1 << order) * PAGE_SIZE; - - if (clear) - memset(b_data, 0, b_allocd); - - /* newly allocated page frames below buffer header or ...*/ - if (bh->b_data == b_data + b_allocd) { - bh->b_size += b_allocd; - bh->b_data -= b_allocd; - if (full) - atomic_add(b_allocd, &bh->b_count); - continue; - } - /* they are above the header */ - if (b_data == bh->b_data + bh->b_size) { - bh->b_size += b_allocd; - if (full) - atomic_add(b_allocd, &bh->b_count); - continue; - } - prev_bh = bh; - bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); - if (!bh) { - free_pages((unsigned long) b_data, order); - goto abort; - } - bh->b_reqnext = NULL; - bh->b_data = b_data; - bh->b_size = b_allocd; - atomic_set(&bh->b_count, full ? bh->b_size : 0); - prev_bh->b_reqnext = bh; + bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); + if (!bh) + return NULL; - pages &= (order-1); + bh->b_data = kmalloc(tape->buffer_size, GFP_KERNEL); + if (!bh->b_data) { + kfree(bh); + return NULL; } - bh->b_size -= tape->excess_bh_size; - if (full) - atomic_sub(tape->excess_bh_size, &bh->b_count); - return merge_bh; -abort: - ide_tape_kfree_buffer(tape); - return NULL; + bh->b_size = tape->buffer_size; + atomic_set(&bh->b_count, full ? bh->b_size : 0); + + return bh; } static int idetape_copy_stage_from_user(idetape_tape_t *tape, const char __user *buf, int n) { struct idetape_bh *bh = tape->bh; - int count; int ret = 0; - while (n) { - if (bh == NULL) { + if (n) { + if (bh == NULL || n > bh->b_size - atomic_read(&bh->b_count)) { printk(KERN_ERR "ide-tape: bh == NULL in %s\n", __func__); return 1; } - count = min((unsigned int) - (bh->b_size - atomic_read(&bh->b_count)), - (unsigned int)n); if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, - count)) + n)) ret = 1; - n -= count; - atomic_add(count, &bh->b_count); - buf += count; - if (atomic_read(&bh->b_count) == bh->b_size) { - bh = bh->b_reqnext; - if (bh) - atomic_set(&bh->b_count, 0); - } + atomic_add(n, &bh->b_count); + if (atomic_read(&bh->b_count) == bh->b_size) + tape->bh = NULL; } - tape->bh = bh; + return ret; } @@ -979,30 +874,20 @@ static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf, int n) { struct idetape_bh *bh = tape->bh; - int count; int ret = 0; - while (n) { - if (bh == NULL) { + if (n) { + if (bh == NULL || n > tape->b_count) { printk(KERN_ERR "ide-tape: bh == NULL in %s\n", __func__); return 1; } - count = min(tape->b_count, n); - if (copy_to_user(buf, tape->b_data, count)) + if (copy_to_user(buf, tape->b_data, n)) ret = 1; - n -= count; - tape->b_data += count; - tape->b_count -= count; - buf += count; - if (!tape->b_count) { - bh = bh->b_reqnext; - tape->bh = bh; - if (bh) { - tape->b_data = bh->b_data; - tape->b_count = atomic_read(&bh->b_count); - } - } + tape->b_data += n; + tape->b_count -= n; + if (!tape->b_count) + tape->bh = NULL; } return ret; } @@ -1254,7 +1139,7 @@ static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) static void ide_tape_flush_merge_buffer(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; - int blocks, min; + int blocks; struct idetape_bh *bh; if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { @@ -1269,31 +1154,16 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) if (tape->merge_bh_size) { blocks = tape->merge_bh_size / tape->blk_size; if (tape->merge_bh_size % tape->blk_size) { - unsigned int i; - + unsigned int i = tape->blk_size - + tape->merge_bh_size % tape->blk_size; blocks++; - i = tape->blk_size - tape->merge_bh_size % - tape->blk_size; - bh = tape->bh->b_reqnext; - while (bh) { - atomic_set(&bh->b_count, 0); - bh = bh->b_reqnext; - } bh = tape->bh; - while (i) { - if (bh == NULL) { - printk(KERN_INFO "ide-tape: bug," - " bh NULL\n"); - break; - } - min = min(i, (unsigned int)(bh->b_size - - atomic_read(&bh->b_count))); + if (bh) { memset(bh->b_data + atomic_read(&bh->b_count), - 0, min); - atomic_add(min, &bh->b_count); - i -= min; - bh = bh->b_reqnext; - } + 0, i); + atomic_add(i, &bh->b_count); + } else + printk(KERN_INFO "ide-tape: bug, bh NULL\n"); } (void) idetape_add_chrdev_write_request(drive, blocks); tape->merge_bh_size = 0; @@ -1321,7 +1191,7 @@ static int idetape_init_read(ide_drive_t *drive) " 0 now\n"); tape->merge_bh_size = 0; } - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0); + tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0); if (!tape->merge_bh) return -ENOMEM; tape->chrdev_dir = IDETAPE_DIR_READ; @@ -1368,23 +1238,18 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) static void idetape_pad_zeros(ide_drive_t *drive, int bcount) { idetape_tape_t *tape = drive->driver_data; - struct idetape_bh *bh; + struct idetape_bh *bh = tape->merge_bh; int blocks; while (bcount) { unsigned int count; - bh = tape->merge_bh; count = min(tape->buffer_size, bcount); bcount -= count; blocks = count / tape->blk_size; - while (count) { - atomic_set(&bh->b_count, - min(count, (unsigned int)bh->b_size)); - memset(bh->b_data, 0, atomic_read(&bh->b_count)); - count -= atomic_read(&bh->b_count); - bh = bh->b_reqnext; - } + atomic_set(&bh->b_count, count); + memset(bh->b_data, 0, atomic_read(&bh->b_count)); + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, tape->merge_bh); } @@ -1596,7 +1461,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, "should be 0 now\n"); tape->merge_bh_size = 0; } - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0); + tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0); if (!tape->merge_bh) return -ENOMEM; tape->chrdev_dir = IDETAPE_DIR_WRITE; @@ -1970,7 +1835,7 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) idetape_tape_t *tape = drive->driver_data; ide_tape_flush_merge_buffer(drive); - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0); + tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1); if (tape->merge_bh != NULL) { idetape_pad_zeros(drive, tape->blk_size * (tape->user_bs_factor - 1)); @@ -2201,11 +2066,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) tape->buffer_size = *ctl * tape->blk_size; } buffer_size = tape->buffer_size; - tape->pages_per_buffer = buffer_size / PAGE_SIZE; - if (buffer_size % PAGE_SIZE) { - tape->pages_per_buffer++; - tape->excess_bh_size = PAGE_SIZE - buffer_size % PAGE_SIZE; - } /* select the "best" DSC read/write polling freq */ speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]); -- GitLab From e998f30b45efb99a3c3ce7b5483f76317a17abed Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0792/6080] ide-tape: use standard data transfer mechanism Impact: use standard way to transfer data ide-tape uses rq in an interesting way. For r/w requests, rq->special is used to carry a private buffer management structure idetape_bh and rq->nr_sectors and current_nr_sectors are initialized to the number of idetape blocks which isn't necessary 512 bytes. Also, rq->current_nr_sectors is used to report back the residual count in units of idetape blocks. This peculiarity taxes both block layer and ide. ide-atapi has different paths and hooks to accomodate it and what a rq means becomes quite confusing and making changes at the block layer becomes quite difficult and error-prone. This patch makes ide-tape use bio instead. With the previous patch, ide-tape currently is using single contiguos buffer so replacing it isn't difficult. Data buffer is mapped into bio using blk_rq_map_kern() in idetape_queue_rw_tail(). idetape_io_buffers() and idetape_update_buffers() are dropped and pc->bh is set to null to tell ide-atapi to use standard data transfer mechanism and idetape_bh byte counts are updated by the issuer on completion using the residual count. This change also nicely removes the FIXME in ide_pc_intr() where ide-tape rqs need to be completed using ide_rq_bytes() instead of blk_rq_bytes() (although this didn't really matter as the request didn't have bio). Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-atapi.c | 6 +-- drivers/ide/ide-tape.c | 112 +++++++++------------------------------- 2 files changed, 24 insertions(+), 94 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 3df5442de710..b9dd4503cbc7 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -413,11 +413,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) * ->pc_callback() might change rq->data_len for * residual count, cache total length. */ - if (!blk_special_request(rq) && - (drive->media == ide_tape && !rq->bio)) - done = ide_rq_bytes(rq); /* FIXME */ - else - done = blk_rq_bytes(rq); + done = blk_rq_bytes(rq); /* Command finished - Call the callback function */ uptodate = drive->pc_callback(drive, dsc); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b2afbc7bcb6b..b373ac876352 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -292,65 +292,6 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) return tape; } -static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount) -{ - struct idetape_bh *bh = pc->bh; - int count; - - if (bcount && bh) { - count = min( - (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), - bcount); - drive->hwif->tp_ops->input_data(drive, NULL, bh->b_data + - atomic_read(&bh->b_count), count); - bcount -= count; - atomic_add(count, &bh->b_count); - if (atomic_read(&bh->b_count) == bh->b_size) - pc->bh = NULL; - } - - return bcount; -} - -static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount) -{ - struct idetape_bh *bh = pc->bh; - int count; - - if (bcount && bh) { - count = min((unsigned int)pc->b_count, (unsigned int)bcount); - drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count); - bcount -= count; - pc->b_data += count; - pc->b_count -= count; - if (!pc->b_count) - pc->bh = NULL; - } - - return bcount; -} - -static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc) -{ - struct idetape_bh *bh = pc->bh; - unsigned int bcount = pc->xferred; - - if (pc->flags & PC_FLAG_WRITING) - return; - if (bcount) { - if (bh == NULL || bcount > bh->b_size) { - printk(KERN_ERR "ide-tape: bh == NULL in %s\n", - __func__); - return; - } - atomic_set(&bh->b_count, bcount); - if (atomic_read(&bh->b_count) == bh->b_size) - pc->bh = NULL; - } -} - /* * called on each failed packet command retry to analyze the request sense. We * currently do not utilize this information. @@ -368,12 +309,10 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) pc->c[0], tape->sense_key, tape->asc, tape->ascq); /* Correct pc->xferred by asking the tape. */ - if (pc->flags & PC_FLAG_DMA_ERROR) { + if (pc->flags & PC_FLAG_DMA_ERROR) pc->xferred = pc->req_xfer - tape->blk_size * get_unaligned_be32(&sense[3]); - idetape_update_buffers(drive, pc); - } /* * If error was the result of a zero-length read or write command, @@ -458,7 +397,7 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) } tape->first_frame += blocks; - rq->current_nr_sectors -= blocks; + rq->data_len -= blocks * tape->blk_size; if (pc->error) { uptodate = 0; @@ -520,19 +459,6 @@ static void ide_tape_handle_dsc(ide_drive_t *drive) idetape_postpone_request(drive); } -static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, - unsigned int bcount, int write) -{ - unsigned int bleft; - - if (write) - bleft = idetape_output_buffers(drive, pc, bcount); - else - bleft = idetape_input_buffers(drive, pc, bcount); - - return bcount - bleft; -} - /* * Packet Command Interface * @@ -683,7 +609,7 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, ide_init_pc(pc); put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; - pc->bh = bh; + pc->bh = NULL; pc->buf = NULL; pc->buf_size = length * tape->blk_size; pc->req_xfer = pc->buf_size; @@ -1063,10 +989,12 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct idetape_bh *bh) { idetape_tape_t *tape = drive->driver_data; + size_t size = blocks * tape->blk_size; struct request *rq; - int ret, errors; + int ret; debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); + BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_SPECIAL; @@ -1074,21 +1002,29 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, rq->rq_disk = tape->disk; rq->special = (void *)bh; rq->sector = tape->first_frame; - rq->nr_sectors = blocks; - rq->current_nr_sectors = blocks; + + if (size) { + ret = blk_rq_map_kern(drive->queue, rq, bh->b_data, size, + __GFP_WAIT); + if (ret) + goto out_put; + } + blk_execute_rq(drive->queue, tape->disk, rq, 0); - errors = rq->errors; - ret = tape->blk_size * (blocks - rq->current_nr_sectors); - blk_put_request(rq); + /* calculate the number of transferred bytes and update bh */ + size -= rq->data_len; + if (cmd == REQ_IDETAPE_READ) + atomic_add(size, &bh->b_count); - if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) - return 0; + ret = size; + if (rq->errors == IDE_DRV_ERROR_GENERAL) + ret = -EIO; if (tape->merge_bh) idetape_init_merge_buffer(tape); - if (errors == IDE_DRV_ERROR_GENERAL) - return -EIO; +out_put: + blk_put_request(rq); return ret; } @@ -2034,8 +1970,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) u16 *ctl = (u16 *)&tape->caps[12]; drive->pc_callback = ide_tape_callback; - drive->pc_update_buffers = idetape_update_buffers; - drive->pc_io_buffers = ide_tape_io_buffers; drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; -- GitLab From 6cf3d545f7d71b183e5b89960d4cc850a42c410d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0793/6080] ide-tape: kill idetape_bh Impact: kill now unnecessary idetape_bh With everything using standard mechanisms, there is no need for idetape_bh anymore. Kill it and use tape->buf, cur and valid to describe data buffer instead. Changes worth mentioning are... * idetape_queue_rq_tail() now always queue tape->buf and and adjusts buffer state properly before completion. * idetape_pad_zeros() clears the buffer only once. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 305 ++++++++++++----------------------------- 1 file changed, 84 insertions(+), 221 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b373ac876352..d2e9c09b5215 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -131,12 +131,6 @@ enum { IDETAPE_DIR_WRITE = (1 << 2), }; -struct idetape_bh { - u32 b_size; - atomic_t b_count; - char *b_data; -}; - /* Tape door status */ #define DOOR_UNLOCKED 0 #define DOOR_LOCKED 1 @@ -218,14 +212,12 @@ typedef struct ide_tape_obj { /* Data buffer size chosen based on the tape's recommendation */ int buffer_size; - /* merge buffer */ - struct idetape_bh *merge_bh; - /* size of the merge buffer */ - int merge_bh_size; - /* pointer to current buffer head within the merge buffer */ - struct idetape_bh *bh; - char *b_data; - int b_count; + /* Staging buffer of buffer_size bytes */ + void *buf; + /* The read/write cursor */ + void *cur; + /* The number of valid bytes in buf */ + size_t valid; /* Measures average tape speed */ unsigned long avg_time; @@ -351,15 +343,6 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) } } -/* Free data buffers completely. */ -static void ide_tape_kfree_buffer(idetape_tape_t *tape) -{ - struct idetape_bh *bh = tape->merge_bh; - - kfree(bh->b_data); - kfree(bh); -} - static void ide_tape_handle_dsc(ide_drive_t *); static int ide_tape_callback(ide_drive_t *drive, int dsc) @@ -603,8 +586,7 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, struct ide_atapi_pc *pc, struct request *rq, u8 opcode) { - struct idetape_bh *bh = (struct idetape_bh *)rq->special; - unsigned int length = rq->current_nr_sectors; + unsigned int length = rq->nr_sectors; ide_init_pc(pc); put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); @@ -616,14 +598,11 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, if (pc->req_xfer == tape->buffer_size) pc->flags |= PC_FLAG_DMA_OK; - if (opcode == READ_6) { + if (opcode == READ_6) pc->c[0] = READ_6; - atomic_set(&bh->b_count, 0); - } else if (opcode == WRITE_6) { + else if (opcode == WRITE_6) { pc->c[0] = WRITE_6; pc->flags |= PC_FLAG_WRITING; - pc->b_data = bh->b_data; - pc->b_count = atomic_read(&bh->b_count); } memcpy(rq->cmd, pc->c, 12); @@ -639,10 +618,8 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, struct ide_cmd cmd; u8 stat; - debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu," - " current_nr_sectors: %u\n", - (unsigned long long)rq->sector, rq->nr_sectors, - rq->current_nr_sectors); + debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu\n" + (unsigned long long)rq->sector, rq->nr_sectors); if (!(blk_special_request(rq) || blk_sense_request(rq))) { /* We do not support buffer cache originated requests. */ @@ -748,89 +725,6 @@ out: return ide_tape_issue_pc(drive, &cmd, pc); } -/* - * It returns a pointer to the newly allocated buffer, or NULL in case - * of failure. - */ -static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape, - int full) -{ - struct idetape_bh *bh; - - bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); - if (!bh) - return NULL; - - bh->b_data = kmalloc(tape->buffer_size, GFP_KERNEL); - if (!bh->b_data) { - kfree(bh); - return NULL; - } - - bh->b_size = tape->buffer_size; - atomic_set(&bh->b_count, full ? bh->b_size : 0); - - return bh; -} - -static int idetape_copy_stage_from_user(idetape_tape_t *tape, - const char __user *buf, int n) -{ - struct idetape_bh *bh = tape->bh; - int ret = 0; - - if (n) { - if (bh == NULL || n > bh->b_size - atomic_read(&bh->b_count)) { - printk(KERN_ERR "ide-tape: bh == NULL in %s\n", - __func__); - return 1; - } - if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, - n)) - ret = 1; - atomic_add(n, &bh->b_count); - if (atomic_read(&bh->b_count) == bh->b_size) - tape->bh = NULL; - } - - return ret; -} - -static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf, - int n) -{ - struct idetape_bh *bh = tape->bh; - int ret = 0; - - if (n) { - if (bh == NULL || n > tape->b_count) { - printk(KERN_ERR "ide-tape: bh == NULL in %s\n", - __func__); - return 1; - } - if (copy_to_user(buf, tape->b_data, n)) - ret = 1; - tape->b_data += n; - tape->b_count -= n; - if (!tape->b_count) - tape->bh = NULL; - } - return ret; -} - -static void idetape_init_merge_buffer(idetape_tape_t *tape) -{ - struct idetape_bh *bh = tape->merge_bh; - tape->bh = tape->merge_bh; - - if (tape->chrdev_dir == IDETAPE_DIR_WRITE) - atomic_set(&bh->b_count, 0); - else { - tape->b_data = bh->b_data; - tape->b_count = atomic_read(&bh->b_count); - } -} - /* * Write a filemark if write_filemark=1. Flush the device buffers without * writing a filemark otherwise. @@ -928,10 +822,10 @@ static void __ide_tape_discard_merge_buffer(ide_drive_t *drive) return; clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags); - tape->merge_bh_size = 0; - if (tape->merge_bh != NULL) { - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + tape->valid = 0; + if (tape->buf != NULL) { + kfree(tape->buf); + tape->buf = NULL; } tape->chrdev_dir = IDETAPE_DIR_NONE; @@ -985,8 +879,7 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive, * Generate a read/write request for the block device interface and wait for it * to be serviced. */ -static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, - struct idetape_bh *bh) +static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks) { idetape_tape_t *tape = drive->driver_data; size_t size = blocks * tape->blk_size; @@ -1000,11 +893,10 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, rq->cmd_type = REQ_TYPE_SPECIAL; rq->cmd[13] = cmd; rq->rq_disk = tape->disk; - rq->special = (void *)bh; rq->sector = tape->first_frame; if (size) { - ret = blk_rq_map_kern(drive->queue, rq, bh->b_data, size, + ret = blk_rq_map_kern(drive->queue, rq, tape->buf, size, __GFP_WAIT); if (ret) goto out_put; @@ -1012,17 +904,17 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, blk_execute_rq(drive->queue, tape->disk, rq, 0); - /* calculate the number of transferred bytes and update bh */ + /* calculate the number of transferred bytes and update buffer state */ size -= rq->data_len; + tape->cur = tape->buf; if (cmd == REQ_IDETAPE_READ) - atomic_add(size, &bh->b_count); + tape->valid = size; + else + tape->valid = 0; ret = size; if (rq->errors == IDE_DRV_ERROR_GENERAL) ret = -EIO; - - if (tape->merge_bh) - idetape_init_merge_buffer(tape); out_put: blk_put_request(rq); return ret; @@ -1064,49 +956,33 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) /* Queue up a character device originated write request. */ static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) { - idetape_tape_t *tape = drive->driver_data; - debug_log(DBG_CHRDEV, "Enter %s\n", __func__); - return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, - blocks, tape->merge_bh); + return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks); } static void ide_tape_flush_merge_buffer(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; int blocks; - struct idetape_bh *bh; if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" " but we are not writing.\n"); return; } - if (tape->merge_bh_size > tape->buffer_size) { - printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n"); - tape->merge_bh_size = tape->buffer_size; - } - if (tape->merge_bh_size) { - blocks = tape->merge_bh_size / tape->blk_size; - if (tape->merge_bh_size % tape->blk_size) { - unsigned int i = tape->blk_size - - tape->merge_bh_size % tape->blk_size; + if (tape->buf) { + blocks = tape->valid / tape->blk_size; + if (tape->valid % tape->blk_size) { blocks++; - bh = tape->bh; - if (bh) { - memset(bh->b_data + atomic_read(&bh->b_count), - 0, i); - atomic_add(i, &bh->b_count); - } else - printk(KERN_INFO "ide-tape: bug, bh NULL\n"); + memset(tape->buf + tape->valid, 0, + tape->blk_size - tape->valid % tape->blk_size); } (void) idetape_add_chrdev_write_request(drive, blocks); - tape->merge_bh_size = 0; } - if (tape->merge_bh != NULL) { - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + if (tape->buf != NULL) { + kfree(tape->buf); + tape->buf = NULL; } tape->chrdev_dir = IDETAPE_DIR_NONE; } @@ -1122,15 +998,15 @@ static int idetape_init_read(ide_drive_t *drive) ide_tape_flush_merge_buffer(drive); idetape_flush_tape_buffers(drive); } - if (tape->merge_bh || tape->merge_bh_size) { - printk(KERN_ERR "ide-tape: merge_bh_size should be" - " 0 now\n"); - tape->merge_bh_size = 0; + if (tape->buf || tape->valid) { + printk(KERN_ERR "ide-tape: valid should be 0 now\n"); + tape->valid = 0; } - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0); - if (!tape->merge_bh) + tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); + if (!tape->buf) return -ENOMEM; tape->chrdev_dir = IDETAPE_DIR_READ; + tape->cur = tape->buf; /* * Issue a read 0 command to ensure that DSC handshake is @@ -1140,11 +1016,10 @@ static int idetape_init_read(ide_drive_t *drive) */ if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { bytes_read = idetape_queue_rw_tail(drive, - REQ_IDETAPE_READ, 0, - tape->merge_bh); + REQ_IDETAPE_READ, 0); if (bytes_read < 0) { - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + kfree(tape->buf); + tape->buf = NULL; tape->chrdev_dir = IDETAPE_DIR_NONE; return bytes_read; } @@ -1157,8 +1032,6 @@ static int idetape_init_read(ide_drive_t *drive) /* called from idetape_chrdev_read() to service a chrdev read request. */ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) { - idetape_tape_t *tape = drive->driver_data; - debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks); /* If we are at a filemark, return a read length of 0 */ @@ -1167,27 +1040,21 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) idetape_init_read(drive); - return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks, - tape->merge_bh); + return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks); } static void idetape_pad_zeros(ide_drive_t *drive, int bcount) { idetape_tape_t *tape = drive->driver_data; - struct idetape_bh *bh = tape->merge_bh; - int blocks; + + memset(tape->buf, 0, tape->buffer_size); while (bcount) { - unsigned int count; + unsigned int count = min(tape->buffer_size, bcount); - count = min(tape->buffer_size, bcount); + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, + count / tape->blk_size); bcount -= count; - blocks = count / tape->blk_size; - atomic_set(&bh->b_count, count); - memset(bh->b_data, 0, atomic_read(&bh->b_count)); - - idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, - tape->merge_bh); } } @@ -1267,7 +1134,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, } if (tape->chrdev_dir == IDETAPE_DIR_READ) { - tape->merge_bh_size = 0; + tape->valid = 0; if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) ++count; ide_tape_discard_merge_buffer(drive, 0); @@ -1333,20 +1200,20 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, return rc; if (count == 0) return (0); - if (tape->merge_bh_size) { - actually_read = min((unsigned int)(tape->merge_bh_size), - (unsigned int)count); - if (idetape_copy_stage_to_user(tape, buf, actually_read)) + if (tape->valid) { + actually_read = min_t(unsigned int, tape->valid, count); + if (copy_to_user(buf, tape->cur, actually_read)) ret = -EFAULT; buf += actually_read; - tape->merge_bh_size -= actually_read; count -= actually_read; + tape->cur += actually_read; + tape->valid -= actually_read; } while (count >= tape->buffer_size) { bytes_read = idetape_add_chrdev_read_request(drive, ctl); if (bytes_read <= 0) goto finish; - if (idetape_copy_stage_to_user(tape, buf, bytes_read)) + if (copy_to_user(buf, tape->cur, bytes_read)) ret = -EFAULT; buf += bytes_read; count -= bytes_read; @@ -1357,10 +1224,11 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, if (bytes_read <= 0) goto finish; temp = min((unsigned long)count, (unsigned long)bytes_read); - if (idetape_copy_stage_to_user(tape, buf, temp)) + if (copy_to_user(buf, tape->cur, temp)) ret = -EFAULT; actually_read += temp; - tape->merge_bh_size = bytes_read-temp; + tape->cur += temp; + tape->valid -= temp; } finish: if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { @@ -1392,16 +1260,15 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { if (tape->chrdev_dir == IDETAPE_DIR_READ) ide_tape_discard_merge_buffer(drive, 1); - if (tape->merge_bh || tape->merge_bh_size) { - printk(KERN_ERR "ide-tape: merge_bh_size " - "should be 0 now\n"); - tape->merge_bh_size = 0; + if (tape->buf || tape->valid) { + printk(KERN_ERR "ide-tape: valid should be 0 now\n"); + tape->valid = 0; } - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0); - if (!tape->merge_bh) + tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); + if (!tape->buf) return -ENOMEM; tape->chrdev_dir = IDETAPE_DIR_WRITE; - idetape_init_merge_buffer(tape); + tape->cur = tape->buf; /* * Issue a write 0 command to ensure that DSC handshake is @@ -1411,11 +1278,10 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, */ if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { ssize_t retval = idetape_queue_rw_tail(drive, - REQ_IDETAPE_WRITE, 0, - tape->merge_bh); + REQ_IDETAPE_WRITE, 0); if (retval < 0) { - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + kfree(tape->buf); + tape->buf = NULL; tape->chrdev_dir = IDETAPE_DIR_NONE; return retval; } @@ -1423,23 +1289,19 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, } if (count == 0) return (0); - if (tape->merge_bh_size) { - if (tape->merge_bh_size >= tape->buffer_size) { - printk(KERN_ERR "ide-tape: bug: merge buf too big\n"); - tape->merge_bh_size = 0; - } - actually_written = min((unsigned int) - (tape->buffer_size - tape->merge_bh_size), - (unsigned int)count); - if (idetape_copy_stage_from_user(tape, buf, actually_written)) - ret = -EFAULT; + if (tape->valid < tape->buffer_size) { + actually_written = min_t(unsigned int, + tape->buffer_size - tape->valid, + count); + if (copy_from_user(tape->cur, buf, actually_written)) + ret = -EFAULT; buf += actually_written; - tape->merge_bh_size += actually_written; count -= actually_written; + tape->cur += actually_written; + tape->valid += actually_written; - if (tape->merge_bh_size == tape->buffer_size) { + if (tape->valid == tape->buffer_size) { ssize_t retval; - tape->merge_bh_size = 0; retval = idetape_add_chrdev_write_request(drive, ctl); if (retval <= 0) return (retval); @@ -1447,7 +1309,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, } while (count >= tape->buffer_size) { ssize_t retval; - if (idetape_copy_stage_from_user(tape, buf, tape->buffer_size)) + if (copy_from_user(tape->cur, buf, tape->buffer_size)) ret = -EFAULT; buf += tape->buffer_size; count -= tape->buffer_size; @@ -1458,9 +1320,10 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, } if (count) { actually_written += count; - if (idetape_copy_stage_from_user(tape, buf, count)) + if (copy_from_user(tape->cur, buf, count)) ret = -EFAULT; - tape->merge_bh_size += count; + tape->cur += count; + tape->valid += count; } return ret ? ret : actually_written; } @@ -1623,7 +1486,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, idetape_flush_tape_buffers(drive); } if (cmd == MTIOCGET || cmd == MTIOCPOS) { - block_offset = tape->merge_bh_size / + block_offset = tape->valid / (tape->blk_size * tape->user_bs_factor); position = idetape_read_position(drive); if (position < 0) @@ -1771,12 +1634,12 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor) idetape_tape_t *tape = drive->driver_data; ide_tape_flush_merge_buffer(drive); - tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1); - if (tape->merge_bh != NULL) { + tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); + if (tape->buf != NULL) { idetape_pad_zeros(drive, tape->blk_size * (tape->user_bs_factor - 1)); - ide_tape_kfree_buffer(tape); - tape->merge_bh = NULL; + kfree(tape->buf); + tape->buf = NULL; } idetape_write_filemark(drive); idetape_flush_tape_buffers(drive); @@ -2042,7 +1905,7 @@ static void ide_tape_release(struct device *dev) ide_drive_t *drive = tape->drive; struct gendisk *g = tape->disk; - BUG_ON(tape->merge_bh_size); + BUG_ON(tape->valid); drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; drive->driver_data = NULL; -- GitLab From 3596b66452491a3cff26256a5e6e6061a66c4142 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:02 +0900 Subject: [PATCH 0794/6080] ide-tape: unify r/w init paths Impact: cleanup Read and write init paths are almost identical. Unify them into idetape_init_rw(). Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 110 +++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 64 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d2e9c09b5215..4da7fa9bca1e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -987,42 +987,50 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) tape->chrdev_dir = IDETAPE_DIR_NONE; } -static int idetape_init_read(ide_drive_t *drive) +static int idetape_init_rw(ide_drive_t *drive, int dir) { idetape_tape_t *tape = drive->driver_data; - int bytes_read; + int rc; - /* Initialize read operation */ - if (tape->chrdev_dir != IDETAPE_DIR_READ) { - if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { - ide_tape_flush_merge_buffer(drive); - idetape_flush_tape_buffers(drive); - } - if (tape->buf || tape->valid) { - printk(KERN_ERR "ide-tape: valid should be 0 now\n"); - tape->valid = 0; - } - tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); - if (!tape->buf) - return -ENOMEM; - tape->chrdev_dir = IDETAPE_DIR_READ; - tape->cur = tape->buf; + BUG_ON(dir != IDETAPE_DIR_READ && dir != IDETAPE_DIR_WRITE); - /* - * Issue a read 0 command to ensure that DSC handshake is - * switched from completion mode to buffer available mode. - * No point in issuing this if DSC overlap isn't supported, some - * drives (Seagate STT3401A) will return an error. - */ - if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { - bytes_read = idetape_queue_rw_tail(drive, - REQ_IDETAPE_READ, 0); - if (bytes_read < 0) { - kfree(tape->buf); - tape->buf = NULL; - tape->chrdev_dir = IDETAPE_DIR_NONE; - return bytes_read; - } + if (tape->chrdev_dir == dir) + return 0; + + if (tape->chrdev_dir == IDETAPE_DIR_READ) + ide_tape_discard_merge_buffer(drive, 1); + else if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { + ide_tape_flush_merge_buffer(drive); + idetape_flush_tape_buffers(drive); + } + + if (tape->buf || tape->valid) { + printk(KERN_ERR "ide-tape: valid should be 0 now\n"); + tape->valid = 0; + } + + tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); + if (!tape->buf) + return -ENOMEM; + tape->chrdev_dir = dir; + tape->cur = tape->buf; + + /* + * Issue a 0 rw command to ensure that DSC handshake is + * switched from completion mode to buffer available mode. No + * point in issuing this if DSC overlap isn't supported, some + * drives (Seagate STT3401A) will return an error. + */ + if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { + int cmd = dir == IDETAPE_DIR_READ ? REQ_IDETAPE_READ + : REQ_IDETAPE_WRITE; + + rc = idetape_queue_rw_tail(drive, cmd, 0); + if (rc < 0) { + kfree(tape->buf); + tape->buf = NULL; + tape->chrdev_dir = IDETAPE_DIR_NONE; + return rc; } } @@ -1038,7 +1046,7 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) return 0; - idetape_init_read(drive); + idetape_init_rw(drive, IDETAPE_DIR_READ); return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks); } @@ -1195,7 +1203,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, (count % tape->blk_size) == 0) tape->user_bs_factor = count / tape->blk_size; } - rc = idetape_init_read(drive); + rc = idetape_init_rw(drive, IDETAPE_DIR_READ); if (rc < 0) return rc; if (count == 0) @@ -1249,6 +1257,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, ssize_t actually_written = 0; ssize_t ret = 0; u16 ctl = *(u16 *)&tape->caps[12]; + int rc; /* The drive is write protected. */ if (tape->write_prot) @@ -1257,36 +1266,9 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); /* Initialize write operation */ - if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { - if (tape->chrdev_dir == IDETAPE_DIR_READ) - ide_tape_discard_merge_buffer(drive, 1); - if (tape->buf || tape->valid) { - printk(KERN_ERR "ide-tape: valid should be 0 now\n"); - tape->valid = 0; - } - tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL); - if (!tape->buf) - return -ENOMEM; - tape->chrdev_dir = IDETAPE_DIR_WRITE; - tape->cur = tape->buf; - - /* - * Issue a write 0 command to ensure that DSC handshake is - * switched from completion mode to buffer available mode. No - * point in issuing this if DSC overlap isn't supported, some - * drives (Seagate STT3401A) will return an error. - */ - if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) { - ssize_t retval = idetape_queue_rw_tail(drive, - REQ_IDETAPE_WRITE, 0); - if (retval < 0) { - kfree(tape->buf); - tape->buf = NULL; - tape->chrdev_dir = IDETAPE_DIR_NONE; - return retval; - } - } - } + rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); + if (rc < 0) + return rc; if (count == 0) return (0); if (tape->valid < tape->buffer_size) { -- GitLab From 71294cf93d22ceaa75448cc6ebee2c65897be8c2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:03 +0900 Subject: [PATCH 0795/6080] ide-tape: use byte size instead of sectors on rw issue functions Impact: cleanup Byte size is what most issue functions deal with, make idetape_queue_rw_tail() and its wrappers take byte size instead of sector counts. idetape_chrdev_read() and write() functions are converted to use tape->buffer_size instead of ctl from tape->cap. This cleans up code a little bit and will ease the next r/w reimplementation. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 45 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 4da7fa9bca1e..d5e9bb286e30 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -879,15 +879,15 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive, * Generate a read/write request for the block device interface and wait for it * to be serviced. */ -static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks) +static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size) { idetape_tape_t *tape = drive->driver_data; - size_t size = blocks * tape->blk_size; struct request *rq; int ret; debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE); + BUG_ON(size < 0 || size % tape->blk_size); rq = blk_get_request(drive->queue, READ, __GFP_WAIT); rq->cmd_type = REQ_TYPE_SPECIAL; @@ -954,17 +954,16 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) } /* Queue up a character device originated write request. */ -static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) +static int idetape_add_chrdev_write_request(ide_drive_t *drive, int size) { debug_log(DBG_CHRDEV, "Enter %s\n", __func__); - return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks); + return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, size); } static void ide_tape_flush_merge_buffer(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; - int blocks; if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer" @@ -972,15 +971,10 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) return; } if (tape->buf) { - blocks = tape->valid / tape->blk_size; - if (tape->valid % tape->blk_size) { - blocks++; - memset(tape->buf + tape->valid, 0, - tape->blk_size - tape->valid % tape->blk_size); - } - (void) idetape_add_chrdev_write_request(drive, blocks); - } - if (tape->buf != NULL) { + size_t aligned = roundup(tape->valid, tape->blk_size); + + memset(tape->cur, 0, aligned - tape->valid); + idetape_add_chrdev_write_request(drive, aligned); kfree(tape->buf); tape->buf = NULL; } @@ -1038,9 +1032,9 @@ static int idetape_init_rw(ide_drive_t *drive, int dir) } /* called from idetape_chrdev_read() to service a chrdev read request. */ -static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) +static int idetape_add_chrdev_read_request(ide_drive_t *drive, int size) { - debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks); + debug_log(DBG_PROCS, "Enter %s, %d bytes\n", __func__, size); /* If we are at a filemark, return a read length of 0 */ if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) @@ -1048,7 +1042,7 @@ static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) idetape_init_rw(drive, IDETAPE_DIR_READ); - return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks); + return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, size); } static void idetape_pad_zeros(ide_drive_t *drive, int bcount) @@ -1060,8 +1054,7 @@ static void idetape_pad_zeros(ide_drive_t *drive, int bcount) while (bcount) { unsigned int count = min(tape->buffer_size, bcount); - idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, - count / tape->blk_size); + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, count); bcount -= count; } } @@ -1193,7 +1186,6 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, ide_drive_t *drive = tape->drive; ssize_t bytes_read, temp, actually_read = 0, rc; ssize_t ret = 0; - u16 ctl = *(u16 *)&tape->caps[12]; debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); @@ -1218,7 +1210,8 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, tape->valid -= actually_read; } while (count >= tape->buffer_size) { - bytes_read = idetape_add_chrdev_read_request(drive, ctl); + bytes_read = idetape_add_chrdev_read_request(drive, + tape->buffer_size); if (bytes_read <= 0) goto finish; if (copy_to_user(buf, tape->cur, bytes_read)) @@ -1228,7 +1221,8 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, actually_read += bytes_read; } if (count) { - bytes_read = idetape_add_chrdev_read_request(drive, ctl); + bytes_read = idetape_add_chrdev_read_request(drive, + tape->buffer_size); if (bytes_read <= 0) goto finish; temp = min((unsigned long)count, (unsigned long)bytes_read); @@ -1256,7 +1250,6 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, ide_drive_t *drive = tape->drive; ssize_t actually_written = 0; ssize_t ret = 0; - u16 ctl = *(u16 *)&tape->caps[12]; int rc; /* The drive is write protected. */ @@ -1284,7 +1277,8 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, if (tape->valid == tape->buffer_size) { ssize_t retval; - retval = idetape_add_chrdev_write_request(drive, ctl); + retval = idetape_add_chrdev_write_request(drive, + tape->buffer_size); if (retval <= 0) return (retval); } @@ -1295,7 +1289,8 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, ret = -EFAULT; buf += tape->buffer_size; count -= tape->buffer_size; - retval = idetape_add_chrdev_write_request(drive, ctl); + retval = idetape_add_chrdev_write_request(drive, + tape->buffer_size); actually_written += tape->buffer_size; if (retval <= 0) return (retval); -- GitLab From 4344d07fb8dbf0cbfec1f7d7c1afeccaceaaa120 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:03 +0900 Subject: [PATCH 0796/6080] ide-tape: simplify read/write functions Impact: cleanup idetape_chrdev_read/write() functions are unnecessarily complex when everything can be handled in a single loop. Collapse idetape_add_chrdev_read/write_request() into the rw functions and simplify the implementation. Signed-off-by: Tejun Heo --- drivers/ide/ide-tape.c | 149 ++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 99 deletions(-) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d5e9bb286e30..2599579e4174 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -953,14 +953,6 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd) pc->flags |= PC_FLAG_WAIT_FOR_DSC; } -/* Queue up a character device originated write request. */ -static int idetape_add_chrdev_write_request(ide_drive_t *drive, int size) -{ - debug_log(DBG_CHRDEV, "Enter %s\n", __func__); - - return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, size); -} - static void ide_tape_flush_merge_buffer(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; @@ -974,7 +966,7 @@ static void ide_tape_flush_merge_buffer(ide_drive_t *drive) size_t aligned = roundup(tape->valid, tape->blk_size); memset(tape->cur, 0, aligned - tape->valid); - idetape_add_chrdev_write_request(drive, aligned); + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, aligned); kfree(tape->buf); tape->buf = NULL; } @@ -1031,20 +1023,6 @@ static int idetape_init_rw(ide_drive_t *drive, int dir) return 0; } -/* called from idetape_chrdev_read() to service a chrdev read request. */ -static int idetape_add_chrdev_read_request(ide_drive_t *drive, int size) -{ - debug_log(DBG_PROCS, "Enter %s, %d bytes\n", __func__, size); - - /* If we are at a filemark, return a read length of 0 */ - if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) - return 0; - - idetape_init_rw(drive, IDETAPE_DIR_READ); - - return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, size); -} - static void idetape_pad_zeros(ide_drive_t *drive, int bcount) { idetape_tape_t *tape = drive->driver_data; @@ -1184,8 +1162,9 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, { struct ide_tape_obj *tape = file->private_data; ide_drive_t *drive = tape->drive; - ssize_t bytes_read, temp, actually_read = 0, rc; + size_t done = 0; ssize_t ret = 0; + int rc; debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); @@ -1195,52 +1174,43 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, (count % tape->blk_size) == 0) tape->user_bs_factor = count / tape->blk_size; } + rc = idetape_init_rw(drive, IDETAPE_DIR_READ); if (rc < 0) return rc; - if (count == 0) - return (0); - if (tape->valid) { - actually_read = min_t(unsigned int, tape->valid, count); - if (copy_to_user(buf, tape->cur, actually_read)) - ret = -EFAULT; - buf += actually_read; - count -= actually_read; - tape->cur += actually_read; - tape->valid -= actually_read; - } - while (count >= tape->buffer_size) { - bytes_read = idetape_add_chrdev_read_request(drive, - tape->buffer_size); - if (bytes_read <= 0) - goto finish; - if (copy_to_user(buf, tape->cur, bytes_read)) - ret = -EFAULT; - buf += bytes_read; - count -= bytes_read; - actually_read += bytes_read; - } - if (count) { - bytes_read = idetape_add_chrdev_read_request(drive, - tape->buffer_size); - if (bytes_read <= 0) - goto finish; - temp = min((unsigned long)count, (unsigned long)bytes_read); - if (copy_to_user(buf, tape->cur, temp)) + + while (done < count) { + size_t todo; + + /* refill if staging buffer is empty */ + if (!tape->valid) { + /* If we are at a filemark, nothing more to read */ + if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) + break; + /* read */ + if (idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, + tape->buffer_size) <= 0) + break; + } + + /* copy out */ + todo = min_t(size_t, count - done, tape->valid); + if (copy_to_user(buf + done, tape->cur, todo)) ret = -EFAULT; - actually_read += temp; - tape->cur += temp; - tape->valid -= temp; + + tape->cur += todo; + tape->valid -= todo; + done += todo; } -finish: - if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { + + if (!done && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); idetape_space_over_filemarks(drive, MTFSF, 1); return 0; } - return ret ? ret : actually_read; + return ret ? ret : done; } static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, @@ -1248,7 +1218,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, { struct ide_tape_obj *tape = file->private_data; ide_drive_t *drive = tape->drive; - ssize_t actually_written = 0; + size_t done = 0; ssize_t ret = 0; int rc; @@ -1262,47 +1232,28 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); if (rc < 0) return rc; - if (count == 0) - return (0); - if (tape->valid < tape->buffer_size) { - actually_written = min_t(unsigned int, - tape->buffer_size - tape->valid, - count); - if (copy_from_user(tape->cur, buf, actually_written)) - ret = -EFAULT; - buf += actually_written; - count -= actually_written; - tape->cur += actually_written; - tape->valid += actually_written; - - if (tape->valid == tape->buffer_size) { - ssize_t retval; - retval = idetape_add_chrdev_write_request(drive, - tape->buffer_size); - if (retval <= 0) - return (retval); - } - } - while (count >= tape->buffer_size) { - ssize_t retval; - if (copy_from_user(tape->cur, buf, tape->buffer_size)) - ret = -EFAULT; - buf += tape->buffer_size; - count -= tape->buffer_size; - retval = idetape_add_chrdev_write_request(drive, - tape->buffer_size); - actually_written += tape->buffer_size; - if (retval <= 0) - return (retval); - } - if (count) { - actually_written += count; - if (copy_from_user(tape->cur, buf, count)) + + while (done < count) { + size_t todo; + + /* flush if staging buffer is full */ + if (tape->valid == tape->buffer_size && + idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, + tape->buffer_size) <= 0) + return rc; + + /* copy in */ + todo = min_t(size_t, count - done, + tape->buffer_size - tape->valid); + if (copy_from_user(tape->cur, buf + done, todo)) ret = -EFAULT; - tape->cur += count; - tape->valid += count; + + tape->cur += todo; + tape->valid += todo; + done += todo; } - return ret ? ret : actually_written; + + return ret ? ret : done; } static int idetape_write_filemark(ide_drive_t *drive) -- GitLab From 29d1a4371035e01b0d079bc5aa88b50f5af7a566 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:03 +0900 Subject: [PATCH 0797/6080] ide-atapi: kill unused fields and callbacks Impact: remove fields and code paths which are no longer necessary Now that ide-tape uses standard mechanisms to transfer data, special case handling for bh handling can be dropped from ide-atapi. Drop the followings. * pc->cur_pos, b_count, bh and b_data * drive->pc_update_buffers() and pc_io_buffers(). Signed-off-by: Tejun Heo --- drivers/ide/ide-atapi.c | 17 ++++------------- drivers/ide/ide-tape.c | 1 - include/linux/ide.h | 12 ------------ 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index b9dd4503cbc7..afe5a4323879 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -359,11 +359,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) drive->name, rq_data_dir(pc->rq) ? "write" : "read"); pc->flags |= PC_FLAG_DMA_ERROR; - } else { + } else pc->xferred = pc->req_xfer; - if (drive->pc_update_buffers) - drive->pc_update_buffers(drive, pc); - } debug_log("%s: DMA finished\n", drive->name); } @@ -463,16 +460,11 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) return ide_do_reset(drive); } - if (drive->media == ide_tape && pc->bh) - done = drive->pc_io_buffers(drive, pc, bcount, write); - else { - done = min_t(unsigned int, bcount, cmd->nleft); - ide_pio_bytes(drive, cmd, write, done); - } + done = min_t(unsigned int, bcount, cmd->nleft); + ide_pio_bytes(drive, cmd, write, done); - /* Update the current position */ + /* Update transferred byte count */ pc->xferred += done; - pc->cur_pos += done; bcount -= done; @@ -650,7 +642,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) /* We haven't transferred any data yet */ pc->xferred = 0; - pc->cur_pos = pc->buf; valid_tf = IDE_VALID_DEVICE; bcount = ((drive->media == ide_tape) ? diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 2599579e4174..8dfc68892d6a 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -591,7 +591,6 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, ide_init_pc(pc); put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); pc->c[1] = 1; - pc->bh = NULL; pc->buf = NULL; pc->buf_size = length * tape->blk_size; pc->req_xfer = pc->buf_size; diff --git a/include/linux/ide.h b/include/linux/ide.h index 1957461ac762..34c128f0a33c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -362,11 +362,7 @@ struct ide_atapi_pc { /* data buffer */ u8 *buf; - /* current buffer position */ - u8 *cur_pos; int buf_size; - /* missing/available data on the current buffer */ - int b_count; /* the corresponding request */ struct request *rq; @@ -379,10 +375,6 @@ struct ide_atapi_pc { */ u8 pc_buf[IDE_PC_BUFFER_SIZE]; - /* idetape only */ - struct idetape_bh *bh; - char *b_data; - unsigned long timeout; }; @@ -595,10 +587,6 @@ struct ide_drive_s { /* callback for packet commands */ int (*pc_callback)(struct ide_drive_s *, int); - void (*pc_update_buffers)(struct ide_drive_s *, struct ide_atapi_pc *); - int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *, - unsigned int, int); - ide_startstop_t (*irq_handler)(struct ide_drive_s *); unsigned long atapi_flags; -- GitLab From 5ad960fe8d0e4f99fe2b8dded45e8251137293c9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 19 Apr 2009 08:46:03 +0900 Subject: [PATCH 0798/6080] ide: drop rq->data handling from ide_map_sg() Impact: remove code path which is no longer necessary All IDE data transfers now use rq->bio. Simplify ide_map_sg() accordingly. Signed-off-by: Tejun Heo Cc: Jens Axboe --- drivers/ide/ide-io.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 6e3094e22775..a0309ea661ac 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -248,11 +248,7 @@ void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) struct scatterlist *sg = hwif->sg_table; struct request *rq = cmd->rq; - if (!rq->bio) { - sg_init_one(sg, rq->data, rq->data_len); - cmd->sg_nents = 1; - } else - cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); + cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); } EXPORT_SYMBOL_GPL(ide_map_sg); -- GitLab From 586cf2681f527ce8b85b9bd57c8b9f7945fbe051 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 21 Apr 2009 12:16:56 +0900 Subject: [PATCH 0799/6080] ide-dma: don't reset request fields on dma_timeout_retry() Impact: drop unnecessary code Now that everything uses bio and block operations, there is no need to reset request fields manually when retrying a request. Every field is guaranteed to be always valid. Drop unnecessary request field resetting from ide_dma_timeout_retry(). Signed-off-by: Tejun Heo --- drivers/ide/ide-dma.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index a0b8cab1d9a6..d9123ecae4a9 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -510,23 +510,11 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) /* * un-busy drive etc and make sure request is sane */ - rq = hwif->rq; - if (!rq) - goto out; - - hwif->rq = NULL; - - rq->errors = 0; - - if (!rq->bio) - goto out; - - rq->sector = rq->bio->bi_sector; - rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9; - rq->hard_cur_sectors = rq->current_nr_sectors; - rq->buffer = bio_data(rq->bio); -out: + if (rq) { + hwif->rq = NULL; + rq->errors = 0; + } return ret; } -- GitLab From db29a6b49674085f136331014ba0eee249c16a2c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 21 Apr 2009 09:27:03 +0200 Subject: [PATCH 0800/6080] block: enable by default support for large devices and files on 32-bit archs Enable by default support for large devices and files (CONFIG_LBD): - With 1TB disks being a commodity hardware it is quite easy to hit 2TB limitation while building RAIDs etc. and many distros have been using CONFIG_LBD=y by default already (at least Fedora 10 and openSUSE 11.1). - This should also prevent a subtle ext4 filesystem compatibility issue: mke2fs.ext4 defaults to creating filesystems with huge_files feature enabled and such filesystems cannot be later mounted read-write on machines with CONFIG_LBD=n (it should be quite easy to hit this issue when trying to use filesystem created using distro kernel on system running the self-build kernel, think about USB disk enclosures & co.). While at it: - Clarify config option help text w.r.t. mounting ext4 filesystems (they can be mounted with CONFIG_LBD=n but in the read-only mode). Cc: "Theodore Ts'o" Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jens Axboe --- block/Kconfig | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/block/Kconfig b/block/Kconfig index e7d12782bcfb..2c39527aa7db 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -26,6 +26,7 @@ if BLOCK config LBD bool "Support for large block devices and files" depends on !64BIT + default y help Enable block devices or files of size 2TB and larger. @@ -38,11 +39,13 @@ config LBD The ext4 filesystem requires that this feature be enabled in order to support filesystems that have the huge_file feature - enabled. Otherwise, it will refuse to mount any filesystems - that use the huge_file feature, which is enabled by default - by mke2fs.ext4. The GFS2 filesystem also requires this feature. + enabled. Otherwise, it will refuse to mount in the read-write + mode any filesystems that use the huge_file feature, which is + enabled by default by mke2fs.ext4. - If unsure, say N. + The GFS2 filesystem also requires this feature. + + If unsure, say Y. config BLK_DEV_BSG bool "Block layer SG support v4 (EXPERIMENTAL)" -- GitLab From db2dbb12dc47a50c7a4c5678f526014063e486f6 Mon Sep 17 00:00:00 2001 From: Jeff Moyer Date: Wed, 22 Apr 2009 14:08:13 +0200 Subject: [PATCH 0801/6080] block: implement blkdev_readpages Doing a proper block dev ->readpages() speeds up the crazy dump(8) approach of using interleaved process IO. Signed-off-by: Jeff Moyer Signed-off-by: Jens Axboe --- fs/block_dev.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/block_dev.c b/fs/block_dev.c index f45dbc18dd17..a85fe310fc6f 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -331,6 +331,12 @@ static int blkdev_readpage(struct file * file, struct page * page) return block_read_full_page(page, blkdev_get_block); } +static int blkdev_readpages(struct file *file, struct address_space *mapping, + struct list_head *pages, unsigned nr_pages) +{ + return mpage_readpages(mapping, pages, nr_pages, blkdev_get_block); +} + static int blkdev_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) @@ -1399,6 +1405,7 @@ static int blkdev_releasepage(struct page *page, gfp_t wait) static const struct address_space_operations def_blk_aops = { .readpage = blkdev_readpage, + .readpages = blkdev_readpages, .writepage = blkdev_writepage, .sync_page = block_sync_page, .write_begin = blkdev_write_begin, -- GitLab From a538cd03be6f363d039daa94199c28cfbd508455 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:17 +0900 Subject: [PATCH 0802/6080] block: merge blk_invoke_request_fn() into __blk_run_queue() __blk_run_queue wraps blk_invoke_request_fn() such that it additionally removes plug and bails out early if the queue is empty. Both extra operations have their own pending mechanisms and don't cause any harm correctness-wise when they are done superflously. The only user of blk_invoke_request_fn() being blk_start_queue(), there isn't much reason to keep both functions around. Merge blk_invoke_request_fn() into __blk_run_queue() and make blk_start_queue() use __blk_run_queue() instead. [ Impact: merge two subtly different internal functions ] Signed-off-by: Tejun Heo --- block/blk-core.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 41bc0ff75e28..02f53bc00e4c 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -333,24 +333,6 @@ void blk_unplug(struct request_queue *q) } EXPORT_SYMBOL(blk_unplug); -static void blk_invoke_request_fn(struct request_queue *q) -{ - if (unlikely(blk_queue_stopped(q))) - return; - - /* - * one level of recursion is ok and is much faster than kicking - * the unplug handling - */ - if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { - q->request_fn(q); - queue_flag_clear(QUEUE_FLAG_REENTER, q); - } else { - queue_flag_set(QUEUE_FLAG_PLUGGED, q); - kblockd_schedule_work(q, &q->unplug_work); - } -} - /** * blk_start_queue - restart a previously stopped queue * @q: The &struct request_queue in question @@ -365,7 +347,7 @@ void blk_start_queue(struct request_queue *q) WARN_ON(!irqs_disabled()); queue_flag_clear(QUEUE_FLAG_STOPPED, q); - blk_invoke_request_fn(q); + __blk_run_queue(q); } EXPORT_SYMBOL(blk_start_queue); @@ -425,12 +407,23 @@ void __blk_run_queue(struct request_queue *q) { blk_remove_plug(q); + if (unlikely(blk_queue_stopped(q))) + return; + + if (elv_queue_empty(q)) + return; + /* * Only recurse once to avoid overrunning the stack, let the unplug * handling reinvoke the handler shortly if we already got there. */ - if (!elv_queue_empty(q)) - blk_invoke_request_fn(q); + if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { + q->request_fn(q); + queue_flag_clear(QUEUE_FLAG_REENTER, q); + } else { + queue_flag_set(QUEUE_FLAG_PLUGGED, q); + kblockd_schedule_work(q, &q->unplug_work); + } } EXPORT_SYMBOL(__blk_run_queue); -- GitLab From a7f557923441186a3cdbabc54f1bcacf42b63bf5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:17 +0900 Subject: [PATCH 0803/6080] block: kill blk_start_queueing() blk_start_queueing() is identical to __blk_run_queue() except that it doesn't check for recursion. None of the current users depends on blk_start_queueing() running request_fn directly. Replace usages of blk_start_queueing() with [__]blk_run_queue() and kill it. [ Impact: removal of mostly duplicate interface function ] Signed-off-by: Tejun Heo --- block/as-iosched.c | 6 +----- block/blk-core.c | 28 ++-------------------------- block/cfq-iosched.c | 6 +++--- block/elevator.c | 7 +++---- include/linux/blkdev.h | 1 - 5 files changed, 9 insertions(+), 39 deletions(-) diff --git a/block/as-iosched.c b/block/as-iosched.c index c48fa670d221..45bd07059c28 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c @@ -1312,12 +1312,8 @@ static void as_merged_requests(struct request_queue *q, struct request *req, static void as_work_handler(struct work_struct *work) { struct as_data *ad = container_of(work, struct as_data, antic_work); - struct request_queue *q = ad->q; - unsigned long flags; - spin_lock_irqsave(q->queue_lock, flags); - blk_start_queueing(q); - spin_unlock_irqrestore(q->queue_lock, flags); + blk_run_queue(ad->q); } static int as_may_queue(struct request_queue *q, int rw) diff --git a/block/blk-core.c b/block/blk-core.c index 02f53bc00e4c..8b4a0af7d69f 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -433,9 +433,7 @@ EXPORT_SYMBOL(__blk_run_queue); * * Description: * Invoke request handling on this queue, if it has pending work to do. - * May be used to restart queueing when a request has completed. Also - * See @blk_start_queueing. - * + * May be used to restart queueing when a request has completed. */ void blk_run_queue(struct request_queue *q) { @@ -894,28 +892,6 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask) } EXPORT_SYMBOL(blk_get_request); -/** - * blk_start_queueing - initiate dispatch of requests to device - * @q: request queue to kick into gear - * - * This is basically a helper to remove the need to know whether a queue - * is plugged or not if someone just wants to initiate dispatch of requests - * for this queue. Should be used to start queueing on a device outside - * of ->request_fn() context. Also see @blk_run_queue. - * - * The queue lock must be held with interrupts disabled. - */ -void blk_start_queueing(struct request_queue *q) -{ - if (!blk_queue_plugged(q)) { - if (unlikely(blk_queue_stopped(q))) - return; - q->request_fn(q); - } else - __generic_unplug_device(q); -} -EXPORT_SYMBOL(blk_start_queueing); - /** * blk_requeue_request - put a request back on queue * @q: request queue where request should be inserted @@ -984,7 +960,7 @@ void blk_insert_request(struct request_queue *q, struct request *rq, drive_stat_acct(rq, 1); __elv_add_request(q, rq, where, 0); - blk_start_queueing(q); + __blk_run_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); } EXPORT_SYMBOL(blk_insert_request); diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index a55a9bd75bd1..def0c698a4bc 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2088,7 +2088,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (blk_rq_bytes(rq) > PAGE_CACHE_SIZE || cfqd->busy_queues > 1) { del_timer(&cfqd->idle_slice_timer); - blk_start_queueing(cfqd->queue); + __blk_run_queue(cfqd->queue); } cfq_mark_cfqq_must_dispatch(cfqq); } @@ -2100,7 +2100,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, * this new queue is RT and the current one is BE */ cfq_preempt_queue(cfqd, cfqq); - blk_start_queueing(cfqd->queue); + __blk_run_queue(cfqd->queue); } } @@ -2345,7 +2345,7 @@ static void cfq_kick_queue(struct work_struct *work) struct request_queue *q = cfqd->queue; spin_lock_irq(q->queue_lock); - blk_start_queueing(q); + __blk_run_queue(cfqd->queue); spin_unlock_irq(q->queue_lock); } diff --git a/block/elevator.c b/block/elevator.c index 7073a9072577..2e0fb21485b7 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -599,7 +599,7 @@ void elv_quiesce_start(struct request_queue *q) */ elv_drain_elevator(q); while (q->rq.elvpriv) { - blk_start_queueing(q); + __blk_run_queue(q); spin_unlock_irq(q->queue_lock); msleep(10); spin_lock_irq(q->queue_lock); @@ -643,8 +643,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) * with anything. There's no point in delaying queue * processing. */ - blk_remove_plug(q); - blk_start_queueing(q); + __blk_run_queue(q); break; case ELEVATOR_INSERT_SORT: @@ -971,7 +970,7 @@ void elv_completed_request(struct request_queue *q, struct request *rq) blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN && (!next || blk_ordered_req_seq(next) > QUEUE_ORDSEQ_DRAIN)) { blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0); - blk_start_queueing(q); + __blk_run_queue(q); } } } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 2755d5c6da22..12e20de44b60 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -797,7 +797,6 @@ extern void blk_sync_queue(struct request_queue *q); extern void __blk_stop_queue(struct request_queue *q); extern void __blk_run_queue(struct request_queue *); extern void blk_run_queue(struct request_queue *); -extern void blk_start_queueing(struct request_queue *); extern int blk_rq_map_user(struct request_queue *, struct request *, struct rq_map_data *, void __user *, unsigned long, gfp_t); -- GitLab From e4025f6c21f1389696c069be2dc647f364925c45 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:17 +0900 Subject: [PATCH 0804/6080] block: don't set REQ_NOMERGE unnecessarily RQ_NOMERGE_FLAGS already clears defines which REQ flags aren't mergeable. There is no reason to specify it superflously. It only adds to confusion. Don't set REQ_NOMERGE for barriers and requests with specific queueing directive. REQ_NOMERGE is now exclusively used by the merging code. [ Impact: cleanup ] Signed-off-by: Tejun Heo --- block/blk-core.c | 5 +---- block/blk-exec.c | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 8b4a0af7d69f..7e0fab53e930 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1082,16 +1082,13 @@ void init_request_from_bio(struct request *req, struct bio *bio) if (bio_failfast_driver(bio)) req->cmd_flags |= REQ_FAILFAST_DRIVER; - /* - * REQ_BARRIER implies no merging, but lets make it explicit - */ if (unlikely(bio_discard(bio))) { req->cmd_flags |= REQ_DISCARD; if (bio_barrier(bio)) req->cmd_flags |= REQ_SOFTBARRIER; req->q->prepare_discard_fn(req->q, req); } else if (unlikely(bio_barrier(bio))) - req->cmd_flags |= (REQ_HARDBARRIER | REQ_NOMERGE); + req->cmd_flags |= REQ_HARDBARRIER; if (bio_sync(bio)) req->cmd_flags |= REQ_RW_SYNC; diff --git a/block/blk-exec.c b/block/blk-exec.c index 6af716d1e54e..49557e91f0da 100644 --- a/block/blk-exec.c +++ b/block/blk-exec.c @@ -51,7 +51,6 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; rq->rq_disk = bd_disk; - rq->cmd_flags |= REQ_NOMERGE; rq->end_io = done; WARN_ON(irqs_disabled()); spin_lock_irq(q->queue_lock); -- GitLab From 10732f5661fb7adf62e20733b0030fc0fc93b0c4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:18 +0900 Subject: [PATCH 0805/6080] block: cleanup REQ_SOFTBARRIER usages blk_insert_request() doesn't need to worry about REQ_SOFTBARRIER. Don't set it. Combined with recent ide updates, REQ_SOFTBARRIER is now only used in elevator proper and for discard requests. [ Impact: cleanup ] Signed-off-by: Tejun Heo --- block/blk-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/block/blk-core.c b/block/blk-core.c index 7e0fab53e930..cf10dfcda99d 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -946,7 +946,6 @@ void blk_insert_request(struct request_queue *q, struct request *rq, * barrier */ rq->cmd_type = REQ_TYPE_SPECIAL; - rq->cmd_flags |= REQ_SOFTBARRIER; rq->special = data; -- GitLab From 2eef33e439ba9ae387cdc3f1abcef2f3f6c4e7a8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:18 +0900 Subject: [PATCH 0806/6080] block: clean up misc stuff after block layer timeout conversion * In blk_rq_timed_out_timer(), else { if } to else if * In blk_add_timer(), simplify if/else block [ Impact: cleanup ] Signed-off-by: Tejun Heo --- block/blk-timeout.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/block/blk-timeout.c b/block/blk-timeout.c index 1ec0d503cacd..1ba7e0aca878 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c @@ -122,10 +122,8 @@ void blk_rq_timed_out_timer(unsigned long data) if (blk_mark_rq_complete(rq)) continue; blk_rq_timed_out(rq); - } else { - if (!next || time_after(next, rq->deadline)) - next = rq->deadline; - } + } else if (!next || time_after(next, rq->deadline)) + next = rq->deadline; } /* @@ -176,16 +174,14 @@ void blk_add_timer(struct request *req) BUG_ON(!list_empty(&req->timeout_list)); BUG_ON(test_bit(REQ_ATOM_COMPLETE, &req->atomic_flags)); - if (req->timeout) - req->deadline = jiffies + req->timeout; - else { - req->deadline = jiffies + q->rq_timeout; - /* - * Some LLDs, like scsi, peek at the timeout to prevent - * a command from being retried forever. - */ + /* + * Some LLDs, like scsi, peek at the timeout to prevent a + * command from being retried forever. + */ + if (!req->timeout) req->timeout = q->rq_timeout; - } + + req->deadline = jiffies + req->timeout; list_add_tail(&req->timeout_list, &q->timeout_list); /* -- GitLab From 5efccd17ceb0fc43837a331297c2c407969d7201 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:18 +0900 Subject: [PATCH 0807/6080] block: reorder request completion functions Reorder request completion functions such that * All request completion functions are located together. * Functions which are used by only one caller is put right above the caller. * end_request() is put after other completion functions but before blk_update_request(). This change is for completion function cleanup which will follow. [ Impact: cleanup, code reorganization ] Signed-off-by: Tejun Heo --- block/blk-core.c | 144 ++++++++++++++++++++--------------------- include/linux/blkdev.h | 16 ++--- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index cf10dfcda99d..406a93e526b6 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1683,6 +1683,35 @@ static void blk_account_io_done(struct request *req) } } +/** + * blk_rq_bytes - Returns bytes left to complete in the entire request + * @rq: the request being processed + **/ +unsigned int blk_rq_bytes(struct request *rq) +{ + if (blk_fs_request(rq)) + return rq->hard_nr_sectors << 9; + + return rq->data_len; +} +EXPORT_SYMBOL_GPL(blk_rq_bytes); + +/** + * blk_rq_cur_bytes - Returns bytes left to complete in the current segment + * @rq: the request being processed + **/ +unsigned int blk_rq_cur_bytes(struct request *rq) +{ + if (blk_fs_request(rq)) + return rq->current_nr_sectors << 9; + + if (rq->bio) + return rq->bio->bi_size; + + return rq->data_len; +} +EXPORT_SYMBOL_GPL(blk_rq_cur_bytes); + /** * __end_that_request_first - end I/O on a request * @req: the request being processed @@ -1797,6 +1826,22 @@ static int __end_that_request_first(struct request *req, int error, return 1; } +static int end_that_request_data(struct request *rq, int error, + unsigned int nr_bytes, unsigned int bidi_bytes) +{ + if (rq->bio) { + if (__end_that_request_first(rq, error, nr_bytes)) + return 1; + + /* Bidi request must be completed as a whole */ + if (blk_bidi_rq(rq) && + __end_that_request_first(rq->next_rq, error, bidi_bytes)) + return 1; + } + + return 0; +} + /* * queue lock must be held */ @@ -1825,78 +1870,6 @@ static void end_that_request_last(struct request *req, int error) } } -/** - * blk_rq_bytes - Returns bytes left to complete in the entire request - * @rq: the request being processed - **/ -unsigned int blk_rq_bytes(struct request *rq) -{ - if (blk_fs_request(rq)) - return rq->hard_nr_sectors << 9; - - return rq->data_len; -} -EXPORT_SYMBOL_GPL(blk_rq_bytes); - -/** - * blk_rq_cur_bytes - Returns bytes left to complete in the current segment - * @rq: the request being processed - **/ -unsigned int blk_rq_cur_bytes(struct request *rq) -{ - if (blk_fs_request(rq)) - return rq->current_nr_sectors << 9; - - if (rq->bio) - return rq->bio->bi_size; - - return rq->data_len; -} -EXPORT_SYMBOL_GPL(blk_rq_cur_bytes); - -/** - * end_request - end I/O on the current segment of the request - * @req: the request being processed - * @uptodate: error value or %0/%1 uptodate flag - * - * Description: - * Ends I/O on the current segment of a request. If that is the only - * remaining segment, the request is also completed and freed. - * - * This is a remnant of how older block drivers handled I/O completions. - * Modern drivers typically end I/O on the full request in one go, unless - * they have a residual value to account for. For that case this function - * isn't really useful, unless the residual just happens to be the - * full current segment. In other words, don't use this function in new - * code. Use blk_end_request() or __blk_end_request() to end a request. - **/ -void end_request(struct request *req, int uptodate) -{ - int error = 0; - - if (uptodate <= 0) - error = uptodate ? uptodate : -EIO; - - __blk_end_request(req, error, req->hard_cur_sectors << 9); -} -EXPORT_SYMBOL(end_request); - -static int end_that_request_data(struct request *rq, int error, - unsigned int nr_bytes, unsigned int bidi_bytes) -{ - if (rq->bio) { - if (__end_that_request_first(rq, error, nr_bytes)) - return 1; - - /* Bidi request must be completed as a whole */ - if (blk_bidi_rq(rq) && - __end_that_request_first(rq->next_rq, error, bidi_bytes)) - return 1; - } - - return 0; -} - /** * blk_end_io - Generic end_io function to complete a request. * @rq: the request being processed @@ -2006,6 +1979,33 @@ int blk_end_bidi_request(struct request *rq, int error, unsigned int nr_bytes, } EXPORT_SYMBOL_GPL(blk_end_bidi_request); +/** + * end_request - end I/O on the current segment of the request + * @req: the request being processed + * @uptodate: error value or %0/%1 uptodate flag + * + * Description: + * Ends I/O on the current segment of a request. If that is the only + * remaining segment, the request is also completed and freed. + * + * This is a remnant of how older block drivers handled I/O completions. + * Modern drivers typically end I/O on the full request in one go, unless + * they have a residual value to account for. For that case this function + * isn't really useful, unless the residual just happens to be the + * full current segment. In other words, don't use this function in new + * code. Use blk_end_request() or __blk_end_request() to end a request. + **/ +void end_request(struct request *req, int uptodate) +{ + int error = 0; + + if (uptodate <= 0) + error = uptodate ? uptodate : -EIO; + + __blk_end_request(req, error, req->hard_cur_sectors << 9); +} +EXPORT_SYMBOL(end_request); + /** * blk_update_request - Special helper function for request stacking drivers * @rq: the request being processed diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 12e20de44b60..156ffd9de967 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -831,6 +831,14 @@ static inline void blk_run_address_space(struct address_space *mapping) extern void blkdev_dequeue_request(struct request *req); +/* + * blk_end_request() takes bytes instead of sectors as a complete size. + * blk_rq_bytes() returns bytes left to complete in the entire request. + * blk_rq_cur_bytes() returns bytes left to complete in the current segment. + */ +extern unsigned int blk_rq_bytes(struct request *rq); +extern unsigned int blk_rq_cur_bytes(struct request *rq); + /* * blk_end_request() and friends. * __blk_end_request() and end_request() must be called with @@ -857,14 +865,6 @@ extern void blk_abort_queue(struct request_queue *); extern void blk_update_request(struct request *rq, int error, unsigned int nr_bytes); -/* - * blk_end_request() takes bytes instead of sectors as a complete size. - * blk_rq_bytes() returns bytes left to complete in the entire request. - * blk_rq_cur_bytes() returns bytes left to complete in the current segment. - */ -extern unsigned int blk_rq_bytes(struct request *rq); -extern unsigned int blk_rq_cur_bytes(struct request *rq); - /* * Access functions for manipulating queue properties */ -- GitLab From 158dbda0068e63c7cce7bd47c123bd1dfa5a902c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:18 +0900 Subject: [PATCH 0808/6080] block: reorganize request fetching functions Impact: code reorganization elv_next_request() and elv_dequeue_request() are public block layer interface than actual elevator implementation. They mostly deal with how requests interact with block layer and low level drivers at the beginning of rqeuest processing whereas __elv_next_request() is the actual eleveator request fetching interface. Move the two functions to blk-core.c. This prepares for further interface cleanup. Signed-off-by: Tejun Heo --- block/blk-core.c | 95 +++++++++++++++++++++++++++++++++++ block/blk.h | 37 ++++++++++++++ block/elevator.c | 128 ----------------------------------------------- 3 files changed, 132 insertions(+), 128 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 406a93e526b6..678ede23ed0a 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1712,6 +1712,101 @@ unsigned int blk_rq_cur_bytes(struct request *rq) } EXPORT_SYMBOL_GPL(blk_rq_cur_bytes); +struct request *elv_next_request(struct request_queue *q) +{ + struct request *rq; + int ret; + + while ((rq = __elv_next_request(q)) != NULL) { + if (!(rq->cmd_flags & REQ_STARTED)) { + /* + * This is the first time the device driver + * sees this request (possibly after + * requeueing). Notify IO scheduler. + */ + if (blk_sorted_rq(rq)) + elv_activate_rq(q, rq); + + /* + * just mark as started even if we don't start + * it, a request that has been delayed should + * not be passed by new incoming requests + */ + rq->cmd_flags |= REQ_STARTED; + trace_block_rq_issue(q, rq); + } + + if (!q->boundary_rq || q->boundary_rq == rq) { + q->end_sector = rq_end_sector(rq); + q->boundary_rq = NULL; + } + + if (rq->cmd_flags & REQ_DONTPREP) + break; + + if (q->dma_drain_size && rq->data_len) { + /* + * make sure space for the drain appears we + * know we can do this because max_hw_segments + * has been adjusted to be one fewer than the + * device can handle + */ + rq->nr_phys_segments++; + } + + if (!q->prep_rq_fn) + break; + + ret = q->prep_rq_fn(q, rq); + if (ret == BLKPREP_OK) { + break; + } else if (ret == BLKPREP_DEFER) { + /* + * the request may have been (partially) prepped. + * we need to keep this request in the front to + * avoid resource deadlock. REQ_STARTED will + * prevent other fs requests from passing this one. + */ + if (q->dma_drain_size && rq->data_len && + !(rq->cmd_flags & REQ_DONTPREP)) { + /* + * remove the space for the drain we added + * so that we don't add it again + */ + --rq->nr_phys_segments; + } + + rq = NULL; + break; + } else if (ret == BLKPREP_KILL) { + rq->cmd_flags |= REQ_QUIET; + __blk_end_request(rq, -EIO, blk_rq_bytes(rq)); + } else { + printk(KERN_ERR "%s: bad return=%d\n", __func__, ret); + break; + } + } + + return rq; +} +EXPORT_SYMBOL(elv_next_request); + +void elv_dequeue_request(struct request_queue *q, struct request *rq) +{ + BUG_ON(list_empty(&rq->queuelist)); + BUG_ON(ELV_ON_HASH(rq)); + + list_del_init(&rq->queuelist); + + /* + * the time frame between a request being removed from the lists + * and to it is freed is accounted as io that is in progress at + * the driver side. + */ + if (blk_account_rq(rq)) + q->in_flight++; +} + /** * __end_that_request_first - end I/O on a request * @req: the request being processed diff --git a/block/blk.h b/block/blk.h index 79c85f7c9ff5..9b2c324e4407 100644 --- a/block/blk.h +++ b/block/blk.h @@ -43,6 +43,43 @@ static inline void blk_clear_rq_complete(struct request *rq) clear_bit(REQ_ATOM_COMPLETE, &rq->atomic_flags); } +/* + * Internal elevator interface + */ +#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash)) + +static inline struct request *__elv_next_request(struct request_queue *q) +{ + struct request *rq; + + while (1) { + while (!list_empty(&q->queue_head)) { + rq = list_entry_rq(q->queue_head.next); + if (blk_do_ordered(q, &rq)) + return rq; + } + + if (!q->elevator->ops->elevator_dispatch_fn(q, 0)) + return NULL; + } +} + +static inline void elv_activate_rq(struct request_queue *q, struct request *rq) +{ + struct elevator_queue *e = q->elevator; + + if (e->ops->elevator_activate_req_fn) + e->ops->elevator_activate_req_fn(q, rq); +} + +static inline void elv_deactivate_rq(struct request_queue *q, struct request *rq) +{ + struct elevator_queue *e = q->elevator; + + if (e->ops->elevator_deactivate_req_fn) + e->ops->elevator_deactivate_req_fn(q, rq); +} + #ifdef CONFIG_FAIL_IO_TIMEOUT int blk_should_fake_timeout(struct request_queue *); ssize_t part_timeout_show(struct device *, struct device_attribute *, char *); diff --git a/block/elevator.c b/block/elevator.c index 2e0fb21485b7..b03b8752e18b 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -53,7 +53,6 @@ static const int elv_hash_shift = 6; (hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift)) #define ELV_HASH_ENTRIES (1 << elv_hash_shift) #define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) -#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash)) DEFINE_TRACE(block_rq_insert); DEFINE_TRACE(block_rq_issue); @@ -310,22 +309,6 @@ void elevator_exit(struct elevator_queue *e) } EXPORT_SYMBOL(elevator_exit); -static void elv_activate_rq(struct request_queue *q, struct request *rq) -{ - struct elevator_queue *e = q->elevator; - - if (e->ops->elevator_activate_req_fn) - e->ops->elevator_activate_req_fn(q, rq); -} - -static void elv_deactivate_rq(struct request_queue *q, struct request *rq) -{ - struct elevator_queue *e = q->elevator; - - if (e->ops->elevator_deactivate_req_fn) - e->ops->elevator_deactivate_req_fn(q, rq); -} - static inline void __elv_rqhash_del(struct request *rq) { hlist_del_init(&rq->hash); @@ -758,117 +741,6 @@ void elv_add_request(struct request_queue *q, struct request *rq, int where, } EXPORT_SYMBOL(elv_add_request); -static inline struct request *__elv_next_request(struct request_queue *q) -{ - struct request *rq; - - while (1) { - while (!list_empty(&q->queue_head)) { - rq = list_entry_rq(q->queue_head.next); - if (blk_do_ordered(q, &rq)) - return rq; - } - - if (!q->elevator->ops->elevator_dispatch_fn(q, 0)) - return NULL; - } -} - -struct request *elv_next_request(struct request_queue *q) -{ - struct request *rq; - int ret; - - while ((rq = __elv_next_request(q)) != NULL) { - if (!(rq->cmd_flags & REQ_STARTED)) { - /* - * This is the first time the device driver - * sees this request (possibly after - * requeueing). Notify IO scheduler. - */ - if (blk_sorted_rq(rq)) - elv_activate_rq(q, rq); - - /* - * just mark as started even if we don't start - * it, a request that has been delayed should - * not be passed by new incoming requests - */ - rq->cmd_flags |= REQ_STARTED; - trace_block_rq_issue(q, rq); - } - - if (!q->boundary_rq || q->boundary_rq == rq) { - q->end_sector = rq_end_sector(rq); - q->boundary_rq = NULL; - } - - if (rq->cmd_flags & REQ_DONTPREP) - break; - - if (q->dma_drain_size && rq->data_len) { - /* - * make sure space for the drain appears we - * know we can do this because max_hw_segments - * has been adjusted to be one fewer than the - * device can handle - */ - rq->nr_phys_segments++; - } - - if (!q->prep_rq_fn) - break; - - ret = q->prep_rq_fn(q, rq); - if (ret == BLKPREP_OK) { - break; - } else if (ret == BLKPREP_DEFER) { - /* - * the request may have been (partially) prepped. - * we need to keep this request in the front to - * avoid resource deadlock. REQ_STARTED will - * prevent other fs requests from passing this one. - */ - if (q->dma_drain_size && rq->data_len && - !(rq->cmd_flags & REQ_DONTPREP)) { - /* - * remove the space for the drain we added - * so that we don't add it again - */ - --rq->nr_phys_segments; - } - - rq = NULL; - break; - } else if (ret == BLKPREP_KILL) { - rq->cmd_flags |= REQ_QUIET; - __blk_end_request(rq, -EIO, blk_rq_bytes(rq)); - } else { - printk(KERN_ERR "%s: bad return=%d\n", __func__, ret); - break; - } - } - - return rq; -} -EXPORT_SYMBOL(elv_next_request); - -void elv_dequeue_request(struct request_queue *q, struct request *rq) -{ - BUG_ON(list_empty(&rq->queuelist)); - BUG_ON(ELV_ON_HASH(rq)); - - list_del_init(&rq->queuelist); - - /* - * the time frame between a request being removed from the lists - * and to it is freed is accounted as io that is in progress at - * the driver side. - */ - if (blk_account_rq(rq)) - q->in_flight++; -} - int elv_queue_empty(struct request_queue *q) { struct elevator_queue *e = q->elevator; -- GitLab From 0b302d5aa7975006fa2ec3d66386610b9b36c669 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:18 +0900 Subject: [PATCH 0809/6080] block: kill blk_end_request_callback() With recent IDE updates, blk_end_request_callback() doesn't have any user now. Kill it. [ Impact: removal of unused convoluted interface ] Signed-off-by: Tejun Heo --- block/blk-core.c | 48 +++--------------------------------------- include/linux/blkdev.h | 3 --- 2 files changed, 3 insertions(+), 48 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 678ede23ed0a..2f277ea0e599 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1971,10 +1971,6 @@ static void end_that_request_last(struct request *req, int error) * @error: %0 for success, < %0 for error * @nr_bytes: number of bytes to complete @rq * @bidi_bytes: number of bytes to complete @rq->next_rq - * @drv_callback: function called between completion of bios in the request - * and completion of the request. - * If the callback returns non %0, this helper returns without - * completion of the request. * * Description: * Ends I/O on a number of bytes attached to @rq and @rq->next_rq. @@ -1985,8 +1981,7 @@ static void end_that_request_last(struct request *req, int error) * %1 - this request is not freed yet, it still has pending buffers. **/ static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes, - unsigned int bidi_bytes, - int (drv_callback)(struct request *)) + unsigned int bidi_bytes) { struct request_queue *q = rq->q; unsigned long flags = 0UL; @@ -1994,10 +1989,6 @@ static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes, if (end_that_request_data(rq, error, nr_bytes, bidi_bytes)) return 1; - /* Special feature for tricky drivers */ - if (drv_callback && drv_callback(rq)) - return 1; - add_disk_randomness(rq->rq_disk); spin_lock_irqsave(q->queue_lock, flags); @@ -2023,7 +2014,7 @@ static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes, **/ int blk_end_request(struct request *rq, int error, unsigned int nr_bytes) { - return blk_end_io(rq, error, nr_bytes, 0, NULL); + return blk_end_io(rq, error, nr_bytes, 0); } EXPORT_SYMBOL_GPL(blk_end_request); @@ -2070,7 +2061,7 @@ EXPORT_SYMBOL_GPL(__blk_end_request); int blk_end_bidi_request(struct request *rq, int error, unsigned int nr_bytes, unsigned int bidi_bytes) { - return blk_end_io(rq, error, nr_bytes, bidi_bytes, NULL); + return blk_end_io(rq, error, nr_bytes, bidi_bytes); } EXPORT_SYMBOL_GPL(blk_end_bidi_request); @@ -2131,39 +2122,6 @@ void blk_update_request(struct request *rq, int error, unsigned int nr_bytes) } EXPORT_SYMBOL_GPL(blk_update_request); -/** - * blk_end_request_callback - Special helper function for tricky drivers - * @rq: the request being processed - * @error: %0 for success, < %0 for error - * @nr_bytes: number of bytes to complete - * @drv_callback: function called between completion of bios in the request - * and completion of the request. - * If the callback returns non %0, this helper returns without - * completion of the request. - * - * Description: - * Ends I/O on a number of bytes attached to @rq. - * If @rq has leftover, sets it up for the next range of segments. - * - * This special helper function is used only for existing tricky drivers. - * (e.g. cdrom_newpc_intr() of ide-cd) - * This interface will be removed when such drivers are rewritten. - * Don't use this interface in other places anymore. - * - * Return: - * %0 - we are done with this request - * %1 - this request is not freed yet. - * this request still has pending buffers or - * the driver doesn't want to finish this request yet. - **/ -int blk_end_request_callback(struct request *rq, int error, - unsigned int nr_bytes, - int (drv_callback)(struct request *)) -{ - return blk_end_io(rq, error, nr_bytes, 0, drv_callback); -} -EXPORT_SYMBOL_GPL(blk_end_request_callback); - void blk_rq_bio_prep(struct request_queue *q, struct request *rq, struct bio *bio) { diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 156ffd9de967..1fa9dcf9aa6a 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -855,9 +855,6 @@ extern int __blk_end_request(struct request *rq, int error, extern int blk_end_bidi_request(struct request *rq, int error, unsigned int nr_bytes, unsigned int bidi_bytes); extern void end_request(struct request *, int); -extern int blk_end_request_callback(struct request *rq, int error, - unsigned int nr_bytes, - int (drv_callback)(struct request *)); extern void blk_complete_request(struct request *); extern void __blk_complete_request(struct request *); extern void blk_abort_request(struct request *); -- GitLab From 2e60e02297cf54e367567f2d85b2ca56b1c4a906 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:18 +0900 Subject: [PATCH 0810/6080] block: clean up request completion API Request completion has gone through several changes and became a bit messy over the time. Clean it up. 1. end_that_request_data() is a thin wrapper around end_that_request_data_first() which checks whether bio is NULL before doing anything and handles bidi completion. blk_update_request() is a thin wrapper around end_that_request_data() which clears nr_sectors on the last iteration but doesn't use the bidi completion. Clean it up by moving the initial bio NULL check and nr_sectors clearing on the last iteration into end_that_request_data() and renaming it to blk_update_request(), which makes blk_end_io() the only user of end_that_request_data(). Collapse end_that_request_data() into blk_end_io(). 2. There are four visible completion variants - blk_end_request(), __blk_end_request(), blk_end_bidi_request() and end_request(). blk_end_request() and blk_end_bidi_request() uses blk_end_request() as the backend but __blk_end_request() and end_request() use separate implementation in __blk_end_request() due to different locking rules. blk_end_bidi_request() is identical to blk_end_io(). Collapse blk_end_io() into blk_end_bidi_request(), separate out request update into internal helper blk_update_bidi_request() and add __blk_end_bidi_request(). Redefine [__]blk_end_request() as thin inline wrappers around [__]blk_end_bidi_request(). 3. As the whole request issue/completion usages are about to be modified and audited, it's a good chance to convert completion functions return bool which better indicates the intended meaning of return values. 4. The function name end_that_request_last() is from the days when it was a public interface and slighly confusing. Give it a proper internal name - blk_finish_request(). 5. Add description explaning that blk_end_bidi_request() can be safely used for uni requests as suggested by Boaz Harrosh. The only visible behavior change is from #1. nr_sectors counts are cleared after the final iteration no matter which function is used to complete the request. I couldn't find any place where the code assumes those nr_sectors counters contain the values for the last segment and this change is good as it makes the API much more consistent as the end result is now same whether a request is completed using [__]blk_end_request() alone or in combination with blk_update_request(). API further cleaned up per Christoph's suggestion. [ Impact: cleanup, rq->*nr_sectors always updated after req completion ] Signed-off-by: Tejun Heo Reviewed-by: Boaz Harrosh Cc: Christoph Hellwig --- block/blk-core.c | 226 ++++++++++++++--------------------------- include/linux/blkdev.h | 94 ++++++++++++++--- 2 files changed, 157 insertions(+), 163 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 2f277ea0e599..89cc05d9a7a9 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1808,25 +1808,35 @@ void elv_dequeue_request(struct request_queue *q, struct request *rq) } /** - * __end_that_request_first - end I/O on a request - * @req: the request being processed + * blk_update_request - Special helper function for request stacking drivers + * @rq: the request being processed * @error: %0 for success, < %0 for error - * @nr_bytes: number of bytes to complete + * @nr_bytes: number of bytes to complete @rq * * Description: - * Ends I/O on a number of bytes attached to @req, and sets it up - * for the next range of segments (if any) in the cluster. + * Ends I/O on a number of bytes attached to @rq, but doesn't complete + * the request structure even if @rq doesn't have leftover. + * If @rq has leftover, sets it up for the next range of segments. + * + * This special helper function is only for request stacking drivers + * (e.g. request-based dm) so that they can handle partial completion. + * Actual device drivers should use blk_end_request instead. + * + * Passing the result of blk_rq_bytes() as @nr_bytes guarantees + * %false return from this function. * * Return: - * %0 - we are done with this request, call end_that_request_last() - * %1 - still buffers pending for this request + * %false - this request doesn't have any more data + * %true - this request has more data **/ -static int __end_that_request_first(struct request *req, int error, - int nr_bytes) +bool blk_update_request(struct request *req, int error, unsigned int nr_bytes) { int total_bytes, bio_nbytes, next_idx = 0; struct bio *bio; + if (!req->bio) + return false; + trace_block_rq_complete(req->q, req); /* @@ -1903,8 +1913,16 @@ static int __end_that_request_first(struct request *req, int error, /* * completely done */ - if (!req->bio) - return 0; + if (!req->bio) { + /* + * Reset counters so that the request stacking driver + * can find how many bytes remain in the request + * later. + */ + req->nr_sectors = req->hard_nr_sectors = 0; + req->current_nr_sectors = req->hard_cur_sectors = 0; + return false; + } /* * if the request wasn't completed, update state @@ -1918,29 +1936,31 @@ static int __end_that_request_first(struct request *req, int error, blk_recalc_rq_sectors(req, total_bytes >> 9); blk_recalc_rq_segments(req); - return 1; + return true; } +EXPORT_SYMBOL_GPL(blk_update_request); -static int end_that_request_data(struct request *rq, int error, - unsigned int nr_bytes, unsigned int bidi_bytes) +static bool blk_update_bidi_request(struct request *rq, int error, + unsigned int nr_bytes, + unsigned int bidi_bytes) { - if (rq->bio) { - if (__end_that_request_first(rq, error, nr_bytes)) - return 1; + if (blk_update_request(rq, error, nr_bytes)) + return true; - /* Bidi request must be completed as a whole */ - if (blk_bidi_rq(rq) && - __end_that_request_first(rq->next_rq, error, bidi_bytes)) - return 1; - } + /* Bidi request must be completed as a whole */ + if (unlikely(blk_bidi_rq(rq)) && + blk_update_request(rq->next_rq, error, bidi_bytes)) + return true; - return 0; + add_disk_randomness(rq->rq_disk); + + return false; } /* * queue lock must be held */ -static void end_that_request_last(struct request *req, int error) +static void blk_finish_request(struct request *req, int error) { if (blk_rq_tagged(req)) blk_queue_end_tag(req->q, req); @@ -1966,161 +1986,65 @@ static void end_that_request_last(struct request *req, int error) } /** - * blk_end_io - Generic end_io function to complete a request. - * @rq: the request being processed - * @error: %0 for success, < %0 for error - * @nr_bytes: number of bytes to complete @rq - * @bidi_bytes: number of bytes to complete @rq->next_rq + * blk_end_bidi_request - Complete a bidi request + * @rq: the request to complete + * @error: %0 for success, < %0 for error + * @nr_bytes: number of bytes to complete @rq + * @bidi_bytes: number of bytes to complete @rq->next_rq * * Description: * Ends I/O on a number of bytes attached to @rq and @rq->next_rq. - * If @rq has leftover, sets it up for the next range of segments. + * Drivers that supports bidi can safely call this member for any + * type of request, bidi or uni. In the later case @bidi_bytes is + * just ignored. * * Return: - * %0 - we are done with this request - * %1 - this request is not freed yet, it still has pending buffers. + * %false - we are done with this request + * %true - still buffers pending for this request **/ -static int blk_end_io(struct request *rq, int error, unsigned int nr_bytes, - unsigned int bidi_bytes) +bool blk_end_bidi_request(struct request *rq, int error, + unsigned int nr_bytes, unsigned int bidi_bytes) { struct request_queue *q = rq->q; - unsigned long flags = 0UL; - - if (end_that_request_data(rq, error, nr_bytes, bidi_bytes)) - return 1; + unsigned long flags; - add_disk_randomness(rq->rq_disk); + if (blk_update_bidi_request(rq, error, nr_bytes, bidi_bytes)) + return true; spin_lock_irqsave(q->queue_lock, flags); - end_that_request_last(rq, error); + blk_finish_request(rq, error); spin_unlock_irqrestore(q->queue_lock, flags); - return 0; -} - -/** - * blk_end_request - Helper function for drivers to complete the request. - * @rq: the request being processed - * @error: %0 for success, < %0 for error - * @nr_bytes: number of bytes to complete - * - * Description: - * Ends I/O on a number of bytes attached to @rq. - * If @rq has leftover, sets it up for the next range of segments. - * - * Return: - * %0 - we are done with this request - * %1 - still buffers pending for this request - **/ -int blk_end_request(struct request *rq, int error, unsigned int nr_bytes) -{ - return blk_end_io(rq, error, nr_bytes, 0); -} -EXPORT_SYMBOL_GPL(blk_end_request); - -/** - * __blk_end_request - Helper function for drivers to complete the request. - * @rq: the request being processed - * @error: %0 for success, < %0 for error - * @nr_bytes: number of bytes to complete - * - * Description: - * Must be called with queue lock held unlike blk_end_request(). - * - * Return: - * %0 - we are done with this request - * %1 - still buffers pending for this request - **/ -int __blk_end_request(struct request *rq, int error, unsigned int nr_bytes) -{ - if (rq->bio && __end_that_request_first(rq, error, nr_bytes)) - return 1; - - add_disk_randomness(rq->rq_disk); - - end_that_request_last(rq, error); - - return 0; + return false; } -EXPORT_SYMBOL_GPL(__blk_end_request); +EXPORT_SYMBOL_GPL(blk_end_bidi_request); /** - * blk_end_bidi_request - Helper function for drivers to complete bidi request. - * @rq: the bidi request being processed + * __blk_end_bidi_request - Complete a bidi request with queue lock held + * @rq: the request to complete * @error: %0 for success, < %0 for error * @nr_bytes: number of bytes to complete @rq * @bidi_bytes: number of bytes to complete @rq->next_rq * * Description: - * Ends I/O on a number of bytes attached to @rq and @rq->next_rq. + * Identical to blk_end_bidi_request() except that queue lock is + * assumed to be locked on entry and remains so on return. * * Return: - * %0 - we are done with this request - * %1 - still buffers pending for this request - **/ -int blk_end_bidi_request(struct request *rq, int error, unsigned int nr_bytes, - unsigned int bidi_bytes) -{ - return blk_end_io(rq, error, nr_bytes, bidi_bytes); -} -EXPORT_SYMBOL_GPL(blk_end_bidi_request); - -/** - * end_request - end I/O on the current segment of the request - * @req: the request being processed - * @uptodate: error value or %0/%1 uptodate flag - * - * Description: - * Ends I/O on the current segment of a request. If that is the only - * remaining segment, the request is also completed and freed. - * - * This is a remnant of how older block drivers handled I/O completions. - * Modern drivers typically end I/O on the full request in one go, unless - * they have a residual value to account for. For that case this function - * isn't really useful, unless the residual just happens to be the - * full current segment. In other words, don't use this function in new - * code. Use blk_end_request() or __blk_end_request() to end a request. + * %false - we are done with this request + * %true - still buffers pending for this request **/ -void end_request(struct request *req, int uptodate) +bool __blk_end_bidi_request(struct request *rq, int error, + unsigned int nr_bytes, unsigned int bidi_bytes) { - int error = 0; + if (blk_update_bidi_request(rq, error, nr_bytes, bidi_bytes)) + return true; - if (uptodate <= 0) - error = uptodate ? uptodate : -EIO; + blk_finish_request(rq, error); - __blk_end_request(req, error, req->hard_cur_sectors << 9); -} -EXPORT_SYMBOL(end_request); - -/** - * blk_update_request - Special helper function for request stacking drivers - * @rq: the request being processed - * @error: %0 for success, < %0 for error - * @nr_bytes: number of bytes to complete @rq - * - * Description: - * Ends I/O on a number of bytes attached to @rq, but doesn't complete - * the request structure even if @rq doesn't have leftover. - * If @rq has leftover, sets it up for the next range of segments. - * - * This special helper function is only for request stacking drivers - * (e.g. request-based dm) so that they can handle partial completion. - * Actual device drivers should use blk_end_request instead. - */ -void blk_update_request(struct request *rq, int error, unsigned int nr_bytes) -{ - if (!end_that_request_data(rq, error, nr_bytes, 0)) { - /* - * These members are not updated in end_that_request_data() - * when all bios are completed. - * Update them so that the request stacking driver can find - * how many bytes remain in the request later. - */ - rq->nr_sectors = rq->hard_nr_sectors = 0; - rq->current_nr_sectors = rq->hard_cur_sectors = 0; - } + return false; } -EXPORT_SYMBOL_GPL(blk_update_request); +EXPORT_SYMBOL_GPL(__blk_end_bidi_request); void blk_rq_bio_prep(struct request_queue *q, struct request *rq, struct bio *bio) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 1fa9dcf9aa6a..501f6845cc73 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -840,27 +840,97 @@ extern unsigned int blk_rq_bytes(struct request *rq); extern unsigned int blk_rq_cur_bytes(struct request *rq); /* - * blk_end_request() and friends. - * __blk_end_request() and end_request() must be called with - * the request queue spinlock acquired. + * Request completion related functions. + * + * blk_update_request() completes given number of bytes and updates + * the request without completing it. + * + * blk_end_request() and friends. __blk_end_request() and + * end_request() must be called with the request queue spinlock + * acquired. * * Several drivers define their own end_request and call * blk_end_request() for parts of the original function. * This prevents code duplication in drivers. */ -extern int blk_end_request(struct request *rq, int error, - unsigned int nr_bytes); -extern int __blk_end_request(struct request *rq, int error, - unsigned int nr_bytes); -extern int blk_end_bidi_request(struct request *rq, int error, - unsigned int nr_bytes, unsigned int bidi_bytes); -extern void end_request(struct request *, int); +extern bool blk_update_request(struct request *rq, int error, + unsigned int nr_bytes); +extern bool blk_end_bidi_request(struct request *rq, int error, + unsigned int nr_bytes, + unsigned int bidi_bytes); +extern bool __blk_end_bidi_request(struct request *rq, int error, + unsigned int nr_bytes, + unsigned int bidi_bytes); + +/** + * blk_end_request - Helper function for drivers to complete the request. + * @rq: the request being processed + * @error: %0 for success, < %0 for error + * @nr_bytes: number of bytes to complete + * + * Description: + * Ends I/O on a number of bytes attached to @rq. + * If @rq has leftover, sets it up for the next range of segments. + * + * Return: + * %false - we are done with this request + * %true - still buffers pending for this request + **/ +static inline bool blk_end_request(struct request *rq, int error, + unsigned int nr_bytes) +{ + return blk_end_bidi_request(rq, error, nr_bytes, 0); +} + +/** + * __blk_end_request - Helper function for drivers to complete the request. + * @rq: the request being processed + * @error: %0 for success, < %0 for error + * @nr_bytes: number of bytes to complete + * + * Description: + * Must be called with queue lock held unlike blk_end_request(). + * + * Return: + * %false - we are done with this request + * %true - still buffers pending for this request + **/ +static inline bool __blk_end_request(struct request *rq, int error, + unsigned int nr_bytes) +{ + return __blk_end_bidi_request(rq, error, nr_bytes, 0); +} + +/** + * end_request - end I/O on the current segment of the request + * @rq: the request being processed + * @uptodate: error value or %0/%1 uptodate flag + * + * Description: + * Ends I/O on the current segment of a request. If that is the only + * remaining segment, the request is also completed and freed. + * + * This is a remnant of how older block drivers handled I/O completions. + * Modern drivers typically end I/O on the full request in one go, unless + * they have a residual value to account for. For that case this function + * isn't really useful, unless the residual just happens to be the + * full current segment. In other words, don't use this function in new + * code. Use blk_end_request() or __blk_end_request() to end a request. + **/ +static inline void end_request(struct request *rq, int uptodate) +{ + int error = 0; + + if (uptodate <= 0) + error = uptodate ? uptodate : -EIO; + + __blk_end_bidi_request(rq, error, rq->hard_cur_sectors << 9, 0); +} + extern void blk_complete_request(struct request *); extern void __blk_complete_request(struct request *); extern void blk_abort_request(struct request *); extern void blk_abort_queue(struct request_queue *); -extern void blk_update_request(struct request *rq, int error, - unsigned int nr_bytes); /* * Access functions for manipulating queue properties -- GitLab From b243ddcbe9be146172baa544dadecebf156eda0e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:18 +0900 Subject: [PATCH 0811/6080] block: move rq->start_time initialization to blk_rq_init() rq->start_time was initialized in init_request_from_bio() so special requests didn't have start_time set. This has been okay as start_time has been used only for fs requests; however, there is no indication of this actually is the case or not. Set rq->start_time in blk_rq_init() and guarantee that all initialized rq's have its start_time set. This improves consistency at virtually no cost and future changes will make use of the timestamp for !bio requests. [ Impact: rq->start_time is valid for all requests ] Signed-off-by: Tejun Heo --- block/blk-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/blk-core.c b/block/blk-core.c index 89cc05d9a7a9..b84250d3019b 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -134,6 +134,7 @@ void blk_rq_init(struct request_queue *q, struct request *rq) rq->cmd_len = BLK_MAX_CDB; rq->tag = -1; rq->ref_count = 1; + rq->start_time = jiffies; } EXPORT_SYMBOL(blk_rq_init); @@ -1099,7 +1100,6 @@ void init_request_from_bio(struct request *req, struct bio *bio) req->errors = 0; req->hard_sector = req->sector = bio->bi_sector; req->ioprio = bio_prio(bio); - req->start_time = jiffies; blk_rq_bio_prep(req->q, req, bio); } -- GitLab From 40cbbb781d3eba5d6ac0860db078af490e5c7c6b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:19 +0900 Subject: [PATCH 0812/6080] block: implement and use [__]blk_end_request_all() There are many [__]blk_end_request() call sites which call it with full request length and expect full completion. Many of them ensure that the request actually completes by doing BUG_ON() the return value, which is awkward and error-prone. This patch adds [__]blk_end_request_all() which takes @rq and @error and fully completes the request. BUG_ON() is added to to ensure that this actually happens. Most conversions are simple but there are a few noteworthy ones. * cdrom/viocd: viocd_end_request() replaced with direct calls to __blk_end_request_all(). * s390/block/dasd: dasd_end_request() replaced with direct calls to __blk_end_request_all(). * s390/char/tape_block: tapeblock_end_request() replaced with direct calls to blk_end_request_all(). [ Impact: cleanup ] Signed-off-by: Tejun Heo Cc: Russell King Cc: Stephen Rothwell Cc: Mike Miller Cc: Martin Schwidefsky Cc: Jeff Garzik Cc: Rusty Russell Cc: Jeremy Fitzhardinge Cc: Alex Dubov Cc: James Bottomley --- arch/arm/plat-omap/mailbox.c | 11 +++------- block/blk-barrier.c | 9 ++------ block/blk-core.c | 2 +- block/elevator.c | 2 +- drivers/block/cpqarray.c | 3 +-- drivers/block/sx8.c | 3 +-- drivers/block/virtio_blk.c | 2 +- drivers/block/xen-blkfront.c | 4 +--- drivers/cdrom/gdrom.c | 2 +- drivers/cdrom/viocd.c | 25 ++++------------------ drivers/memstick/core/mspro_block.c | 2 +- drivers/s390/block/dasd.c | 17 ++++----------- drivers/s390/char/tape_block.c | 15 ++++---------- drivers/scsi/scsi_lib.c | 2 +- include/linux/blkdev.h | 32 +++++++++++++++++++++++++++++ 15 files changed, 58 insertions(+), 73 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 0abfbaa59871..cf81bad8aec2 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -192,8 +192,7 @@ static void mbox_tx_work(struct work_struct *work) } spin_lock(q->queue_lock); - if (__blk_end_request(rq, 0, 0)) - BUG(); + __blk_end_request_all(rq, 0); spin_unlock(q->queue_lock); } } @@ -224,10 +223,7 @@ static void mbox_rx_work(struct work_struct *work) break; msg = (mbox_msg_t) rq->data; - - if (blk_end_request(rq, 0, 0)) - BUG(); - + blk_end_request_all(rq, 0); mbox->rxq->callback((void *)msg); } } @@ -337,8 +333,7 @@ omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf) *p = (mbox_msg_t) rq->data; - if (blk_end_request(rq, 0, 0)) - BUG(); + blk_end_request_all(rq, 0); if (unlikely(mbox_seq_test(mbox, *p))) { pr_info("mbox: Illegal seq bit!(%08x) ignored\n", *p); diff --git a/block/blk-barrier.c b/block/blk-barrier.c index 20b4111fa050..c8d087655eff 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c @@ -106,10 +106,7 @@ bool blk_ordered_complete_seq(struct request_queue *q, unsigned seq, int error) */ q->ordseq = 0; rq = q->orig_bar_rq; - - if (__blk_end_request(rq, q->orderr, blk_rq_bytes(rq))) - BUG(); - + __blk_end_request_all(rq, q->orderr); return true; } @@ -252,9 +249,7 @@ bool blk_do_ordered(struct request_queue *q, struct request **rqp) * with prejudice. */ elv_dequeue_request(q, rq); - if (__blk_end_request(rq, -EOPNOTSUPP, - blk_rq_bytes(rq))) - BUG(); + __blk_end_request_all(rq, -EOPNOTSUPP); *rqp = NULL; return false; } diff --git a/block/blk-core.c b/block/blk-core.c index b84250d3019b..0520cc704585 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1780,7 +1780,7 @@ struct request *elv_next_request(struct request_queue *q) break; } else if (ret == BLKPREP_KILL) { rq->cmd_flags |= REQ_QUIET; - __blk_end_request(rq, -EIO, blk_rq_bytes(rq)); + __blk_end_request_all(rq, -EIO); } else { printk(KERN_ERR "%s: bad return=%d\n", __func__, ret); break; diff --git a/block/elevator.c b/block/elevator.c index b03b8752e18b..1af5d9f04aff 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -810,7 +810,7 @@ void elv_abort_queue(struct request_queue *q) rq = list_entry_rq(q->queue_head.next); rq->cmd_flags |= REQ_QUIET; trace_block_rq_abort(q, rq); - __blk_end_request(rq, -EIO, blk_rq_bytes(rq)); + __blk_end_request_all(rq, -EIO); } } EXPORT_SYMBOL(elv_abort_queue); diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index ca268ca11159..488a8f4a60aa 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -1024,8 +1024,7 @@ static inline void complete_command(cmdlist_t *cmd, int timeout) cmd->req.sg[i].size, ddir); DBGPX(printk("Done with %p\n", rq);); - if (__blk_end_request(rq, error, blk_rq_bytes(rq))) - BUG(); + __blk_end_request_all(rq, error); } /* diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index ff0448e4bf03..60e85bb6f790 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c @@ -749,8 +749,7 @@ static inline void carm_end_request_queued(struct carm_host *host, struct request *req = crq->rq; int rc; - rc = __blk_end_request(req, error, blk_rq_bytes(req)); - assert(rc == 0); + __blk_end_request_all(req, error); rc = carm_put_request(host, crq); assert(rc == 0); diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 5d34764c8a87..50745e64414e 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -62,7 +62,7 @@ static void blk_done(struct virtqueue *vq) break; } - __blk_end_request(vbr->req, error, blk_rq_bytes(vbr->req)); + __blk_end_request_all(vbr->req, error); list_del(&vbr->list); mempool_free(vbr, vblk->pool); } diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 8f905089b72b..cd6cfe3b51e1 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -551,7 +551,6 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) for (i = info->ring.rsp_cons; i != rp; i++) { unsigned long id; - int ret; bret = RING_GET_RESPONSE(&info->ring, i); id = bret->id; @@ -578,8 +577,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) dev_dbg(&info->xbdev->dev, "Bad return from blkdev data " "request: %x\n", bret->status); - ret = __blk_end_request(req, error, blk_rq_bytes(req)); - BUG_ON(ret); + __blk_end_request_all(req, error); break; default: BUG(); diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 2eecb779437b..fee9a9e83fc9 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -632,7 +632,7 @@ static void gdrom_readdisk_dma(struct work_struct *work) * before handling ending the request */ spin_lock(&gdrom_lock); list_del_init(&req->queuelist); - __blk_end_request(req, err, blk_rq_bytes(req)); + __blk_end_request_all(req, err); } spin_unlock(&gdrom_lock); kfree(read_command); diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 13929356135c..cc3efa096e1a 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -291,23 +291,6 @@ static int send_request(struct request *req) return 0; } -static void viocd_end_request(struct request *req, int error) -{ - int nsectors = req->hard_nr_sectors; - - /* - * Make sure it's fully ended, and ensure that we process - * at least one sector. - */ - if (blk_pc_request(req)) - nsectors = (req->data_len + 511) >> 9; - if (!nsectors) - nsectors = 1; - - if (__blk_end_request(req, error, nsectors << 9)) - BUG(); -} - static int rwreq; static void do_viocd_request(struct request_queue *q) @@ -316,11 +299,11 @@ static void do_viocd_request(struct request_queue *q) while ((rwreq == 0) && ((req = elv_next_request(q)) != NULL)) { if (!blk_fs_request(req)) - viocd_end_request(req, -EIO); + __blk_end_request_all(req, -EIO); else if (send_request(req) < 0) { printk(VIOCD_KERN_WARNING "unable to send message to OS/400!"); - viocd_end_request(req, -EIO); + __blk_end_request_all(req, -EIO); } else rwreq++; } @@ -531,9 +514,9 @@ return_complete: "with rc %d:0x%04X: %s\n", req, event->xRc, bevent->sub_result, err->msg); - viocd_end_request(req, -EIO); + __blk_end_request_all(req, -EIO); } else - viocd_end_request(req, 0); + __blk_end_request_all(req, 0); /* restart handling of incoming requests */ spin_unlock_irqrestore(&viocd_reqlock, flags); diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index de143deb06f0..a41634699f84 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -826,7 +826,7 @@ static void mspro_block_submit_req(struct request_queue *q) if (msb->eject) { while ((req = elv_next_request(q)) != NULL) - __blk_end_request(req, -ENODEV, blk_rq_bytes(req)); + __blk_end_request_all(req, -ENODEV); return; } diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index d1815272c435..fabec95686b0 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1613,15 +1613,6 @@ void dasd_block_clear_timer(struct dasd_block *block) del_timer(&block->timer); } -/* - * posts the buffer_cache about a finalized request - */ -static inline void dasd_end_request(struct request *req, int error) -{ - if (__blk_end_request(req, error, blk_rq_bytes(req))) - BUG(); -} - /* * Process finished error recovery ccw. */ @@ -1676,7 +1667,7 @@ static void __dasd_process_request_queue(struct dasd_block *block) "Rejecting write request %p", req); blkdev_dequeue_request(req); - dasd_end_request(req, -EIO); + __blk_end_request_all(req, -EIO); continue; } cqr = basedev->discipline->build_cp(basedev, block, req); @@ -1705,7 +1696,7 @@ static void __dasd_process_request_queue(struct dasd_block *block) "on request %p", PTR_ERR(cqr), req); blkdev_dequeue_request(req); - dasd_end_request(req, -EIO); + __blk_end_request_all(req, -EIO); continue; } /* @@ -1731,7 +1722,7 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) status = cqr->block->base->discipline->free_cp(cqr, req); if (status <= 0) error = status ? status : -EIO; - dasd_end_request(req, error); + __blk_end_request_all(req, error); } /* @@ -2040,7 +2031,7 @@ static void dasd_flush_request_queue(struct dasd_block *block) spin_lock_irq(&block->request_queue_lock); while ((req = elv_next_request(block->request_queue))) { blkdev_dequeue_request(req); - dasd_end_request(req, -EIO); + __blk_end_request_all(req, -EIO); } spin_unlock_irq(&block->request_queue_lock); } diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index f32e89e7c4f2..86596d3813b5 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -73,13 +73,6 @@ tapeblock_trigger_requeue(struct tape_device *device) /* * Post finished request. */ -static void -tapeblock_end_request(struct request *req, int error) -{ - if (blk_end_request(req, error, blk_rq_bytes(req))) - BUG(); -} - static void __tapeblock_end_request(struct tape_request *ccw_req, void *data) { @@ -90,7 +83,7 @@ __tapeblock_end_request(struct tape_request *ccw_req, void *data) device = ccw_req->device; req = (struct request *) data; - tapeblock_end_request(req, (ccw_req->rc == 0) ? 0 : -EIO); + blk_end_request_all(req, (ccw_req->rc == 0) ? 0 : -EIO); if (ccw_req->rc == 0) /* Update position. */ device->blk_data.block_position = @@ -118,7 +111,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req) ccw_req = device->discipline->bread(device, req); if (IS_ERR(ccw_req)) { DBF_EVENT(1, "TBLOCK: bread failed\n"); - tapeblock_end_request(req, -EIO); + blk_end_request_all(req, -EIO); return PTR_ERR(ccw_req); } ccw_req->callback = __tapeblock_end_request; @@ -131,7 +124,7 @@ tapeblock_start_request(struct tape_device *device, struct request *req) * Start/enqueueing failed. No retries in * this case. */ - tapeblock_end_request(req, -EIO); + blk_end_request_all(req, -EIO); device->discipline->free_bread(ccw_req); } @@ -177,7 +170,7 @@ tapeblock_requeue(struct work_struct *work) { DBF_EVENT(1, "TBLOCK: Rejecting write request\n"); blkdev_dequeue_request(req); spin_unlock_irq(&device->blk_data.request_queue_lock); - tapeblock_end_request(req, -EIO); + blk_end_request_all(req, -EIO); spin_lock_irq(&device->blk_data.request_queue_lock); continue; } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index d1cb64ad1a3f..756ac7c93de0 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -922,7 +922,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) if (driver_byte(result) & DRIVER_SENSE) scsi_print_sense("", cmd); } - blk_end_request(req, -EIO, blk_rq_bytes(req)); + blk_end_request_all(req, -EIO); scsi_next_command(cmd); break; case ACTION_REPREP: diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 501f6845cc73..e33c8356b3da 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -882,6 +882,22 @@ static inline bool blk_end_request(struct request *rq, int error, return blk_end_bidi_request(rq, error, nr_bytes, 0); } +/** + * blk_end_request_all - Helper function for drives to finish the request. + * @rq: the request to finish + * @err: %0 for success, < %0 for error + * + * Description: + * Completely finish @rq. + */ +static inline void blk_end_request_all(struct request *rq, int error) +{ + bool pending; + + pending = blk_end_request(rq, error, blk_rq_bytes(rq)); + BUG_ON(pending); +} + /** * __blk_end_request - Helper function for drivers to complete the request. * @rq: the request being processed @@ -901,6 +917,22 @@ static inline bool __blk_end_request(struct request *rq, int error, return __blk_end_bidi_request(rq, error, nr_bytes, 0); } +/** + * __blk_end_request_all - Helper function for drives to finish the request. + * @rq: the request to finish + * @err: %0 for success, < %0 for error + * + * Description: + * Completely finish @rq. Must be called with queue lock held. + */ +static inline void __blk_end_request_all(struct request *rq, int error) +{ + bool pending; + + pending = __blk_end_request(rq, error, blk_rq_bytes(rq)); + BUG_ON(pending); +} + /** * end_request - end I/O on the current segment of the request * @rq: the request being processed -- GitLab From f06d9a2b52e246a66b606130cea3f0d7b7be17a7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:19 +0900 Subject: [PATCH 0813/6080] block: replace end_request() with [__]blk_end_request_cur() end_request() has been kept around for backward compatibility; however, it's about time for it to go away. * There aren't too many users left. * Its use of @updtodate is pretty confusing. * In some cases, newer code ends up using mixture of end_request() and [__]blk_end_request[_all](), which is way too confusing. So, add [__]blk_end_request_cur() and replace end_request() with it. Most conversions are straightforward. Noteworthy ones are... * paride/pcd: next_request() updated to take 0/-errno instead of 1/0. * paride/pf: pf_end_request() and next_request() updated to take 0/-errno instead of 1/0. * xd: xd_readwrite() updated to return 0/-errno instead of 1/0. * mtd/mtd_blkdevs: blktrans_discard_request() updated to return 0/-errno instead of 1/0. Unnecessary local variable res initialization removed from mtd_blktrans_thread(). [ Impact: cleanup ] Signed-off-by: Tejun Heo Acked-by: Joerg Dorchain Acked-by: Geert Uytterhoeven Acked-by: Grant Likely Acked-by: Laurent Vivier Cc: Tim Waugh Cc: Stephen Rothwell Cc: Paul Mackerras Cc: Jeremy Fitzhardinge Cc: Markus Lidel Cc: David Woodhouse Cc: Pete Zaitcev Cc: unsik Kim --- drivers/block/amiflop.c | 10 +++---- drivers/block/ataflop.c | 14 +++++----- drivers/block/hd.c | 14 +++++----- drivers/block/mg_disk.c | 16 ++++++------ drivers/block/paride/pcd.c | 12 ++++----- drivers/block/paride/pd.c | 5 ++-- drivers/block/paride/pf.c | 28 ++++++++++---------- drivers/block/ps3disk.c | 6 ++--- drivers/block/swim.c | 14 +++++----- drivers/block/swim3.c | 26 +++++++++---------- drivers/block/xd.c | 15 ++++++----- drivers/block/xen-blkfront.c | 2 +- drivers/block/xsysace.c | 4 +-- drivers/block/z2ram.c | 4 +-- drivers/cdrom/gdrom.c | 6 ++--- drivers/message/i2o/i2o_block.c | 2 +- drivers/mtd/mtd_blkdevs.c | 22 ++++++++-------- drivers/sbus/char/jsflash.c | 8 +++--- include/linux/blkdev.h | 46 ++++++++++++++++----------------- 19 files changed, 128 insertions(+), 126 deletions(-) diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 8df436ff7068..b99a2a606d02 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1359,7 +1359,7 @@ static void redo_fd_request(void) #endif block = CURRENT->sector + cnt; if ((int)block > floppy->blocks) { - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); goto repeat; } @@ -1373,11 +1373,11 @@ static void redo_fd_request(void) if ((rq_data_dir(CURRENT) != READ) && (rq_data_dir(CURRENT) != WRITE)) { printk(KERN_WARNING "do_fd_request: unknown command\n"); - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); goto repeat; } if (get_track(drive, track) == -1) { - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); goto repeat; } @@ -1391,7 +1391,7 @@ static void redo_fd_request(void) /* keep the drive spinning while writes are scheduled */ if (!fd_motor_on(drive)) { - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); goto repeat; } /* @@ -1410,7 +1410,7 @@ static void redo_fd_request(void) CURRENT->nr_sectors -= CURRENT->current_nr_sectors; CURRENT->sector += CURRENT->current_nr_sectors; - end_request(CURRENT, 1); + __blk_end_request_cur(CURRENT, 0); goto repeat; } diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 4234c11c1e4c..44a8702136a9 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -612,7 +612,7 @@ static void fd_error( void ) CURRENT->errors++; if (CURRENT->errors >= MAX_ERRORS) { printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive ); - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); } else if (CURRENT->errors == RECALIBRATE_ERRORS) { printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive ); @@ -734,7 +734,7 @@ static void do_fd_action( int drive ) /* all sectors finished */ CURRENT->nr_sectors -= CURRENT->current_nr_sectors; CURRENT->sector += CURRENT->current_nr_sectors; - end_request(CURRENT, 1); + __blk_end_request_cur(CURRENT, 0); redo_fd_request(); return; } @@ -1141,7 +1141,7 @@ static void fd_rwsec_done1(int status) /* all sectors finished */ CURRENT->nr_sectors -= CURRENT->current_nr_sectors; CURRENT->sector += CURRENT->current_nr_sectors; - end_request(CURRENT, 1); + __blk_end_request_cur(CURRENT, 0); redo_fd_request(); } return; @@ -1414,7 +1414,7 @@ repeat: if (!UD.connected) { /* drive not connected */ printk(KERN_ERR "Unknown Device: fd%d\n", drive ); - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); goto repeat; } @@ -1430,12 +1430,12 @@ repeat: /* user supplied disk type */ if (--type >= NUM_DISK_MINORS) { printk(KERN_WARNING "fd%d: invalid disk format", drive ); - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); goto repeat; } if (minor2disktype[type].drive_types > DriveType) { printk(KERN_WARNING "fd%d: unsupported disk format", drive ); - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); goto repeat; } type = minor2disktype[type].index; @@ -1445,7 +1445,7 @@ repeat: } if (CURRENT->sector + 1 > UDT->blocks) { - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); goto repeat; } diff --git a/drivers/block/hd.c b/drivers/block/hd.c index baaa9e486e50..5cb300b81c6a 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -410,7 +410,7 @@ static void bad_rw_intr(void) if (req != NULL) { struct hd_i_struct *disk = req->rq_disk->private_data; if (++req->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); disk->special_op = disk->recalibrate = 1; } else if (req->errors % RESET_FREQ == 0) reset = 1; @@ -466,7 +466,7 @@ ok_to_read: req->buffer+512); #endif if (req->current_nr_sectors <= 0) - end_request(req, 1); + __blk_end_request_cur(req, 0); if (i > 0) { SET_HANDLER(&read_intr); return; @@ -505,7 +505,7 @@ ok_to_write: --req->current_nr_sectors; req->buffer += 512; if (!i || (req->bio && req->current_nr_sectors <= 0)) - end_request(req, 1); + __blk_end_request_cur(req, 0); if (i > 0) { SET_HANDLER(&write_intr); outsw(HD_DATA, req->buffer, 256); @@ -548,7 +548,7 @@ static void hd_times_out(unsigned long dummy) #ifdef DEBUG printk("%s: too many errors\n", name); #endif - end_request(CURRENT, 0); + __blk_end_request_cur(CURRENT, -EIO); } hd_request(); spin_unlock_irq(hd_queue->queue_lock); @@ -563,7 +563,7 @@ static int do_special_op(struct hd_i_struct *disk, struct request *req) } if (disk->head > 16) { printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); } disk->special_op = 0; return 1; @@ -607,7 +607,7 @@ repeat: ((block+nsect) > get_capacity(req->rq_disk))) { printk("%s: bad access: block=%d, count=%d\n", req->rq_disk->disk_name, block, nsect); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); goto repeat; } @@ -647,7 +647,7 @@ repeat: break; default: printk("unknown hd-command\n"); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); break; } } diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index f3898353d0a8..408c2bd8a439 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -285,7 +285,7 @@ static void mg_bad_rw_intr(struct mg_host *host) if (req != NULL) if (++req->errors >= MG_MAX_ERRORS || host->error == MG_ERR_TIMEOUT) - end_request(req, 0); + __blk_end_request_cur(req, -EIO); } static unsigned int mg_out(struct mg_host *host, @@ -351,7 +351,7 @@ static void mg_read(struct request *req) if (req->current_nr_sectors <= 0) { MG_DBG("remain : %d sects\n", remains); - end_request(req, 1); + __blk_end_request_cur(req, 0); if (remains > 0) req = elv_next_request(host->breq); } @@ -395,7 +395,7 @@ static void mg_write(struct request *req) if (req->current_nr_sectors <= 0) { MG_DBG("remain : %d sects\n", remains); - end_request(req, 1); + __blk_end_request_cur(req, 0); if (remains > 0) req = elv_next_request(host->breq); } @@ -448,7 +448,7 @@ ok_to_read: /* let know if current segment done */ if (req->current_nr_sectors <= 0) - end_request(req, 1); + __blk_end_request_cur(req, 0); /* set handler if read remains */ if (i > 0) { @@ -497,7 +497,7 @@ ok_to_write: /* let know if current segment or all done */ if (!i || (req->bio && req->current_nr_sectors <= 0)) - end_request(req, 1); + __blk_end_request_cur(req, 0); /* write 1 sector and set handler if remains */ if (i > 0) { @@ -563,7 +563,7 @@ static void mg_request_poll(struct request_queue *q) default: printk(KERN_WARNING "%s:%d unknown command\n", __func__, __LINE__); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); break; } } @@ -617,7 +617,7 @@ static unsigned int mg_issue_req(struct request *req, default: printk(KERN_WARNING "%s:%d unknown command\n", __func__, __LINE__); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); break; } return MG_ERR_NONE; @@ -655,7 +655,7 @@ static void mg_request(struct request_queue *q) "%s: bad access: sector=%d, count=%d\n", req->rq_disk->disk_name, sect_num, sect_cnt); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index e91d4b4b014f..9fd57c2aa463 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -735,16 +735,16 @@ static void do_pcd_request(struct request_queue * q) ps_set_intr(do_pcd_read, NULL, 0, nice); return; } else - end_request(pcd_req, 0); + __blk_end_request_cur(pcd_req, -EIO); } } -static inline void next_request(int success) +static inline void next_request(int err) { unsigned long saved_flags; spin_lock_irqsave(&pcd_lock, saved_flags); - end_request(pcd_req, success); + __blk_end_request_cur(pcd_req, err); pcd_busy = 0; do_pcd_request(pcd_queue); spin_unlock_irqrestore(&pcd_lock, saved_flags); @@ -781,7 +781,7 @@ static void pcd_start(void) if (pcd_command(pcd_current, rd_cmd, 2048, "read block")) { pcd_bufblk = -1; - next_request(0); + next_request(-EIO); return; } @@ -796,7 +796,7 @@ static void do_pcd_read(void) pcd_retries = 0; pcd_transfer(); if (!pcd_count) { - next_request(1); + next_request(0); return; } @@ -815,7 +815,7 @@ static void do_pcd_read_drq(void) return; } pcd_bufblk = -1; - next_request(0); + next_request(-EIO); return; } diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 9299455b0af6..0732df4e901a 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -410,7 +410,8 @@ static void run_fsm(void) pd_claimed = 0; phase = NULL; spin_lock_irqsave(&pd_lock, saved_flags); - end_request(pd_req, res); + __blk_end_request_cur(pd_req, + res == Ok ? 0 : -EIO); pd_req = elv_next_request(pd_queue); if (!pd_req) stop = 1; @@ -477,7 +478,7 @@ static int pd_next_buf(void) if (pd_count) return 0; spin_lock_irqsave(&pd_lock, saved_flags); - end_request(pd_req, 1); + __blk_end_request_cur(pd_req, 0); pd_count = pd_req->current_nr_sectors; pd_buf = pd_req->buffer; spin_unlock_irqrestore(&pd_lock, saved_flags); diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index bef3b997ba3e..3871e3586d6d 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -750,10 +750,10 @@ static int pf_ready(void) static struct request_queue *pf_queue; -static void pf_end_request(int uptodate) +static void pf_end_request(int err) { if (pf_req) { - end_request(pf_req, uptodate); + __blk_end_request_cur(pf_req, err); pf_req = NULL; } } @@ -773,7 +773,7 @@ repeat: pf_count = pf_req->current_nr_sectors; if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) { - pf_end_request(0); + pf_end_request(-EIO); goto repeat; } @@ -788,7 +788,7 @@ repeat: pi_do_claimed(pf_current->pi, do_pf_write); else { pf_busy = 0; - pf_end_request(0); + pf_end_request(-EIO); goto repeat; } } @@ -805,7 +805,7 @@ static int pf_next_buf(void) return 1; if (!pf_count) { spin_lock_irqsave(&pf_spin_lock, saved_flags); - pf_end_request(1); + pf_end_request(0); pf_req = elv_next_request(pf_queue); spin_unlock_irqrestore(&pf_spin_lock, saved_flags); if (!pf_req) @@ -816,12 +816,12 @@ static int pf_next_buf(void) return 0; } -static inline void next_request(int success) +static inline void next_request(int err) { unsigned long saved_flags; spin_lock_irqsave(&pf_spin_lock, saved_flags); - pf_end_request(success); + pf_end_request(err); pf_busy = 0; do_pf_request(pf_queue); spin_unlock_irqrestore(&pf_spin_lock, saved_flags); @@ -844,7 +844,7 @@ static void do_pf_read_start(void) pi_do_claimed(pf_current->pi, do_pf_read_start); return; } - next_request(0); + next_request(-EIO); return; } pf_mask = STAT_DRQ; @@ -863,7 +863,7 @@ static void do_pf_read_drq(void) pi_do_claimed(pf_current->pi, do_pf_read_start); return; } - next_request(0); + next_request(-EIO); return; } pi_read_block(pf_current->pi, pf_buf, 512); @@ -871,7 +871,7 @@ static void do_pf_read_drq(void) break; } pi_disconnect(pf_current->pi); - next_request(1); + next_request(0); } static void do_pf_write(void) @@ -890,7 +890,7 @@ static void do_pf_write_start(void) pi_do_claimed(pf_current->pi, do_pf_write_start); return; } - next_request(0); + next_request(-EIO); return; } @@ -903,7 +903,7 @@ static void do_pf_write_start(void) pi_do_claimed(pf_current->pi, do_pf_write_start); return; } - next_request(0); + next_request(-EIO); return; } pi_write_block(pf_current->pi, pf_buf, 512); @@ -923,11 +923,11 @@ static void do_pf_write_done(void) pi_do_claimed(pf_current->pi, do_pf_write_start); return; } - next_request(0); + next_request(-EIO); return; } pi_disconnect(pf_current->pi); - next_request(1); + next_request(0); } static int __init pf_init(void) diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index bccc42bb9212..d23b54bc2f50 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -158,7 +158,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, if (res) { dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__, __LINE__, op, res); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); return 0; } @@ -180,7 +180,7 @@ static int ps3disk_submit_flush_request(struct ps3_storage_device *dev, if (res) { dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n", __func__, __LINE__, res); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); return 0; } @@ -205,7 +205,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev, break; } else { blk_dump_rq_flags(req, DEVICE_NAME " bad request"); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } } diff --git a/drivers/block/swim.c b/drivers/block/swim.c index d22cc3856937..6544a7b06bf0 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -532,39 +532,39 @@ static void redo_fd_request(struct request_queue *q) fs = req->rq_disk->private_data; if (req->sector < 0 || req->sector >= fs->total_secs) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } if (req->current_nr_sectors == 0) { - end_request(req, 1); + __blk_end_request_cur(req, 0); continue; } if (!fs->disk_in) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } if (rq_data_dir(req) == WRITE) { if (fs->write_protected) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } } switch (rq_data_dir(req)) { case WRITE: /* NOT IMPLEMENTED */ - end_request(req, 0); + __blk_end_request_cur(req, -EIO); break; case READ: if (floppy_read_sectors(fs, req->sector, req->current_nr_sectors, req->buffer)) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } req->nr_sectors -= req->current_nr_sectors; req->sector += req->current_nr_sectors; req->buffer += req->current_nr_sectors * 512; - end_request(req, 1); + __blk_end_request_cur(req, 0); break; } } diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 612965307ba0..5904f7b73c6e 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -320,15 +320,15 @@ static void start_request(struct floppy_state *fs) #endif if (req->sector < 0 || req->sector >= fs->total_secs) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } if (req->current_nr_sectors == 0) { - end_request(req, 1); + __blk_end_request_cur(req, 0); continue; } if (fs->ejected) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } @@ -336,7 +336,7 @@ static void start_request(struct floppy_state *fs) if (fs->write_prot < 0) fs->write_prot = swim3_readbit(fs, WRITE_PROT); if (fs->write_prot) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } } @@ -508,7 +508,7 @@ static void act(struct floppy_state *fs) case do_transfer: if (fs->cur_cyl != fs->req_cyl) { if (fs->retries > 5) { - end_request(fd_req, 0); + __blk_end_request_cur(fd_req, -EIO); fs->state = idle; return; } @@ -540,7 +540,7 @@ static void scan_timeout(unsigned long data) out_8(&sw->intr_enable, 0); fs->cur_cyl = -1; if (fs->retries > 5) { - end_request(fd_req, 0); + __blk_end_request_cur(fd_req, -EIO); fs->state = idle; start_request(fs); } else { @@ -559,7 +559,7 @@ static void seek_timeout(unsigned long data) out_8(&sw->select, RELAX); out_8(&sw->intr_enable, 0); printk(KERN_ERR "swim3: seek timeout\n"); - end_request(fd_req, 0); + __blk_end_request_cur(fd_req, -EIO); fs->state = idle; start_request(fs); } @@ -583,7 +583,7 @@ static void settle_timeout(unsigned long data) return; } printk(KERN_ERR "swim3: seek settle timeout\n"); - end_request(fd_req, 0); + __blk_end_request_cur(fd_req, -EIO); fs->state = idle; start_request(fs); } @@ -615,7 +615,7 @@ static void xfer_timeout(unsigned long data) fd_req->current_nr_sectors -= s; printk(KERN_ERR "swim3: timeout %sing sector %ld\n", (rq_data_dir(fd_req)==WRITE? "writ": "read"), (long)fd_req->sector); - end_request(fd_req, 0); + __blk_end_request_cur(fd_req, -EIO); fs->state = idle; start_request(fs); } @@ -646,7 +646,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) printk(KERN_ERR "swim3: seen sector but cyl=ff?\n"); fs->cur_cyl = -1; if (fs->retries > 5) { - end_request(fd_req, 0); + __blk_end_request_cur(fd_req, -EIO); fs->state = idle; start_request(fs); } else { @@ -731,7 +731,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) printk("swim3: error %sing block %ld (err=%x)\n", rq_data_dir(fd_req) == WRITE? "writ": "read", (long)fd_req->sector, err); - end_request(fd_req, 0); + __blk_end_request_cur(fd_req, -EIO); fs->state = idle; } } else { @@ -740,7 +740,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid); printk(KERN_ERR " state=%d, dir=%x, intr=%x, err=%x\n", fs->state, rq_data_dir(fd_req), intr, err); - end_request(fd_req, 0); + __blk_end_request_cur(fd_req, -EIO); fs->state = idle; start_request(fs); break; @@ -749,7 +749,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) fd_req->current_nr_sectors -= fs->scount; fd_req->buffer += fs->scount * 512; if (fd_req->current_nr_sectors <= 0) { - end_request(fd_req, 1); + __blk_end_request_cur(fd_req, 0); fs->state = idle; } else { fs->req_sector += fs->scount; diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 64b496fce98b..6f6ad82ec0c0 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -314,21 +314,22 @@ static void do_xd_request (struct request_queue * q) int retry; if (!blk_fs_request(req)) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } if (block + count > get_capacity(req->rq_disk)) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } if (rw != READ && rw != WRITE) { printk("do_xd_request: unknown request\n"); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } for (retry = 0; (retry < XD_RETRIES) && !res; retry++) res = xd_readwrite(rw, disk, req->buffer, block, count); - end_request(req, res); /* wrap up, 0 = fail, 1 = success */ + /* wrap up, 0 = success, -errno = fail */ + __blk_end_request_cur(req, res); } } @@ -418,7 +419,7 @@ static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_ printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write")); xd_recalibrate(drive); spin_lock_irq(&xd_lock); - return (0); + return -EIO; case 2: if (sense[0] & 0x30) { printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing")); @@ -439,7 +440,7 @@ static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_ else printk(" - no valid disk address\n"); spin_lock_irq(&xd_lock); - return (0); + return -EIO; } if (xd_dma_buffer) for (i=0; i < (temp * 0x200); i++) @@ -448,7 +449,7 @@ static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_ count -= temp, buffer += temp * 0x200, block += temp; } spin_lock_irq(&xd_lock); - return (1); + return 0; } /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */ diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index cd6cfe3b51e1..b4564479f641 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -302,7 +302,7 @@ static void do_blkif_request(struct request_queue *rq) while ((req = elv_next_request(rq)) != NULL) { info = req->rq_disk->private_data; if (!blk_fs_request(req)) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 4aecf5dc6a93..b1e1d7e5ab1e 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -466,7 +466,7 @@ struct request *ace_get_next_request(struct request_queue * q) while ((req = elv_next_request(q)) != NULL) { if (blk_fs_request(req)) break; - end_request(req, 0); + __blk_end_request_cur(req, -EIO); } return req; } @@ -494,7 +494,7 @@ static void ace_fsm_dostate(struct ace_device *ace) /* Drop all pending requests */ while ((req = elv_next_request(ace->queue)) != NULL) - end_request(req, 0); + __blk_end_request_cur(req, -EIO); /* Drop back to IDLE state and notify waiters */ ace->fsm_state = ACE_FSM_STATE_IDLE; diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 80754cdd3119..b66ad58a3c38 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -77,7 +77,7 @@ static void do_z2_request(struct request_queue *q) if (start + len > z2ram_size) { printk( KERN_ERR DEVICE_NAME ": bad access: block=%lu, count=%u\n", req->sector, req->current_nr_sectors); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } while (len) { @@ -93,7 +93,7 @@ static void do_z2_request(struct request_queue *q) start += size; len -= size; } - end_request(req, 1); + __blk_end_request_cur(req, 0); } } diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index fee9a9e83fc9..cab2b1fb2fe7 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -654,17 +654,17 @@ static void gdrom_request(struct request_queue *rq) while ((req = elv_next_request(rq)) != NULL) { if (!blk_fs_request(req)) { printk(KERN_DEBUG "GDROM: Non-fs request ignored\n"); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); } if (rq_data_dir(req) != READ) { printk(KERN_NOTICE "GDROM: Read only device -"); printk(" write request ignored\n"); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); } if (req->nr_sectors) gdrom_request_handler_dma(req); else - end_request(req, 0); + __blk_end_request_cur(req, -EIO); } } diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index a443e136dc41..221317e6a006 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -923,7 +923,7 @@ static void i2o_block_request_fn(struct request_queue *q) break; } } else - end_request(req, 0); + __blk_end_request_cur(req, -EIO); } }; diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index a49a9c8f2cb1..76c4c8d13073 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -54,33 +54,33 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && req->cmd[0] == REQ_LB_OP_DISCARD) - return !tr->discard(dev, block, nsect); + return tr->discard(dev, block, nsect); if (!blk_fs_request(req)) - return 0; + return -EIO; if (req->sector + req->current_nr_sectors > get_capacity(req->rq_disk)) - return 0; + return -EIO; switch(rq_data_dir(req)) { case READ: for (; nsect > 0; nsect--, block++, buf += tr->blksize) if (tr->readsect(dev, block, buf)) - return 0; - return 1; + return -EIO; + return 0; case WRITE: if (!tr->writesect) - return 0; + return -EIO; for (; nsect > 0; nsect--, block++, buf += tr->blksize) if (tr->writesect(dev, block, buf)) - return 0; - return 1; + return -EIO; + return 0; default: printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req)); - return 0; + return -EIO; } } @@ -96,7 +96,7 @@ static int mtd_blktrans_thread(void *arg) while (!kthread_should_stop()) { struct request *req; struct mtd_blktrans_dev *dev; - int res = 0; + int res; req = elv_next_request(rq); @@ -119,7 +119,7 @@ static int mtd_blktrans_thread(void *arg) spin_lock_irq(rq->queue_lock); - end_request(req, res); + __blk_end_request_cur(req, res); } spin_unlock_irq(rq->queue_lock); diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index a85ad05e8548..09617884a50b 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -192,25 +192,25 @@ static void jsfd_do_request(struct request_queue *q) size_t len = req->current_nr_sectors << 9; if ((offset + len) > jdp->dsize) { - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } if (rq_data_dir(req) != READ) { printk(KERN_ERR "jsfd: write\n"); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } if ((jdp->dbase & 0xff000000) != 0x20000000) { printk(KERN_ERR "jsfd: bad base %x\n", (int)jdp->dbase); - end_request(req, 0); + __blk_end_request_cur(req, -EIO); continue; } jsfd_read(req->buffer, jdp->dbase + offset, len); - end_request(req, 1); + __blk_end_request_cur(req, 0); } } diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e33c8356b3da..cfeb3c2feb27 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -845,9 +845,8 @@ extern unsigned int blk_rq_cur_bytes(struct request *rq); * blk_update_request() completes given number of bytes and updates * the request without completing it. * - * blk_end_request() and friends. __blk_end_request() and - * end_request() must be called with the request queue spinlock - * acquired. + * blk_end_request() and friends. __blk_end_request() must be called + * with the request queue spinlock acquired. * * Several drivers define their own end_request and call * blk_end_request() for parts of the original function. @@ -898,6 +897,19 @@ static inline void blk_end_request_all(struct request *rq, int error) BUG_ON(pending); } +/** + * blk_end_request_cur - Helper function to finish the current request chunk. + * @rq: the request to finish the current chunk for + * @err: %0 for success, < %0 for error + * + * Description: + * Complete the current consecutively mapped chunk from @rq. + */ +static inline void blk_end_request_cur(struct request *rq, int error) +{ + blk_end_request(rq, error, rq->hard_cur_sectors << 9); +} + /** * __blk_end_request - Helper function for drivers to complete the request. * @rq: the request being processed @@ -934,29 +946,17 @@ static inline void __blk_end_request_all(struct request *rq, int error) } /** - * end_request - end I/O on the current segment of the request - * @rq: the request being processed - * @uptodate: error value or %0/%1 uptodate flag + * __blk_end_request_cur - Helper function to finish the current request chunk. + * @rq: the request to finish the current chunk for + * @err: %0 for success, < %0 for error * * Description: - * Ends I/O on the current segment of a request. If that is the only - * remaining segment, the request is also completed and freed. - * - * This is a remnant of how older block drivers handled I/O completions. - * Modern drivers typically end I/O on the full request in one go, unless - * they have a residual value to account for. For that case this function - * isn't really useful, unless the residual just happens to be the - * full current segment. In other words, don't use this function in new - * code. Use blk_end_request() or __blk_end_request() to end a request. - **/ -static inline void end_request(struct request *rq, int uptodate) + * Complete the current consecutively mapped chunk from @rq. Must + * be called with queue lock held. + */ +static inline void __blk_end_request_cur(struct request *rq, int error) { - int error = 0; - - if (uptodate <= 0) - error = uptodate ? uptodate : -EIO; - - __blk_end_bidi_request(rq, error, rq->hard_cur_sectors << 9, 0); + __blk_end_request(rq, error, rq->hard_cur_sectors << 9); } extern void blk_complete_request(struct request *); -- GitLab From ec24751a6b57e1373a12361e581b2458bc9bb791 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:20 +0900 Subject: [PATCH 0814/6080] arm-omap: don't abuse rq->data omap mailbox uses rq->data as the second opaque pointer to carry mbox_msg_t and rq->special message argument which is needed only for tx. Add and use omap_msg_tx_data struct for tx and use rq->special for mbox_msg_t for rx such that only rq->special is used as opaque pointer. [ Impact: cleanup rq->data usage, extra kmalloc in msg_send ] Signed-off-by: Tejun Heo Cc: Russell King --- arch/arm/plat-omap/mailbox.c | 43 ++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index cf81bad8aec2..538ba7541d3f 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -147,24 +147,40 @@ static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void *arg) return ret; } +struct omap_msg_tx_data { + mbox_msg_t msg; + void *arg; +}; + +static void omap_msg_tx_end_io(struct request *rq, int error) +{ + kfree(rq->special); + __blk_put_request(rq->q, rq); +} + int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg, void* arg) { + struct omap_msg_tx_data *tx_data; struct request *rq; struct request_queue *q = mbox->txq->queue; - int ret = 0; + + tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC); + if (unlikely(!tx_data)) + return -ENOMEM; rq = blk_get_request(q, WRITE, GFP_ATOMIC); if (unlikely(!rq)) { - ret = -ENOMEM; - goto fail; + kfree(tx_data); + return -ENOMEM; } - rq->data = (void *)msg; - blk_insert_request(q, rq, 0, arg); + tx_data->msg = msg; + tx_data->arg = arg; + rq->end_io = omap_msg_tx_end_io; + blk_insert_request(q, rq, 0, tx_data); schedule_work(&mbox->txq->work); - fail: - return ret; + return 0; } EXPORT_SYMBOL(omap_mbox_msg_send); @@ -178,6 +194,8 @@ static void mbox_tx_work(struct work_struct *work) struct request_queue *q = mbox->txq->queue; while (1) { + struct omap_msg_tx_data *tx_data; + spin_lock(q->queue_lock); rq = elv_next_request(q); spin_unlock(q->queue_lock); @@ -185,7 +203,9 @@ static void mbox_tx_work(struct work_struct *work) if (!rq) break; - ret = __mbox_msg_send(mbox, (mbox_msg_t) rq->data, rq->special); + tx_data = rq->special; + + ret = __mbox_msg_send(mbox, tx_data->msg, tx_data->arg); if (ret) { enable_mbox_irq(mbox, IRQ_TX); return; @@ -222,7 +242,7 @@ static void mbox_rx_work(struct work_struct *work) if (!rq) break; - msg = (mbox_msg_t) rq->data; + msg = (mbox_msg_t)rq->special; blk_end_request_all(rq, 0); mbox->rxq->callback((void *)msg); } @@ -260,7 +280,6 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) goto nomem; msg = mbox_fifo_read(mbox); - rq->data = (void *)msg; if (unlikely(mbox_seq_test(mbox, msg))) { pr_info("mbox: Illegal seq bit!(%08x)\n", msg); @@ -268,7 +287,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) mbox->err_notify(); } - blk_insert_request(q, rq, 0, NULL); + blk_insert_request(q, rq, 0, (void *)msg); if (mbox->ops->type == OMAP_MBOX_TYPE1) break; } @@ -331,7 +350,7 @@ omap_mbox_read(struct device *dev, struct device_attribute *attr, char *buf) if (!rq) break; - *p = (mbox_msg_t) rq->data; + *p = (mbox_msg_t)rq->special; blk_end_request_all(rq, 0); -- GitLab From 731ec497e5888c6792ad62613ae9be97eebcd7ca Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 23 Apr 2009 11:05:20 +0900 Subject: [PATCH 0815/6080] block: kill rq->data Now that all block request data transfer is done via bio, rq->data isn't used. Kill it. While at it, make the roles of rq->special and buffer clear. [ Impact: drop now unncessary field from struct request ] Signed-off-by: Tejun Heo Cc: Boaz Harrosh --- block/blk-core.c | 5 ++--- block/blk-map.c | 6 +++--- block/scsi_ioctl.c | 1 - drivers/scsi/scsi_lib.c | 1 - include/linux/blkdev.h | 5 ++--- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 0520cc704585..6dd180cf15d2 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -189,10 +189,9 @@ void blk_dump_rq_flags(struct request *rq, char *msg) (unsigned long long)rq->sector, rq->nr_sectors, rq->current_nr_sectors); - printk(KERN_INFO " bio %p, biotail %p, buffer %p, data %p, len %u\n", + printk(KERN_INFO " bio %p, biotail %p, buffer %p, len %u\n", rq->bio, rq->biotail, - rq->buffer, rq->data, - rq->data_len); + rq->buffer, rq->data_len); if (blk_pc_request(rq)) { printk(KERN_INFO " cdb: "); diff --git a/block/blk-map.c b/block/blk-map.c index f103729b462f..694fefad34e7 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -156,7 +156,7 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, if (!bio_flagged(bio, BIO_USER_MAPPED)) rq->cmd_flags |= REQ_COPY_USER; - rq->buffer = rq->data = NULL; + rq->buffer = NULL; return 0; unmap_rq: blk_rq_unmap_user(bio); @@ -235,7 +235,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, blk_queue_bounce(q, &bio); bio_get(bio); blk_rq_bio_prep(q, rq, bio); - rq->buffer = rq->data = NULL; + rq->buffer = NULL; return 0; } EXPORT_SYMBOL(blk_rq_map_user_iov); @@ -313,7 +313,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, blk_rq_bio_prep(q, rq, bio); blk_queue_bounce(q, &rq->bio); - rq->buffer = rq->data = NULL; + rq->buffer = NULL; return 0; } EXPORT_SYMBOL(blk_rq_map_kern); diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index 82a0ca2f6729..bb9aa43551b2 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -500,7 +500,6 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, rq = blk_get_request(q, WRITE, __GFP_WAIT); rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->data = NULL; rq->data_len = 0; rq->extra_len = 0; rq->timeout = BLK_DEFAULT_SG_TIMEOUT; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 756ac7c93de0..aa9fc572e45f 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1088,7 +1088,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) return ret; } else { BUG_ON(req->data_len); - BUG_ON(req->data); memset(&cmd->sdb, 0, sizeof(cmd->sdb)); req->buffer = NULL; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index cfeb3c2feb27..12c545e2737c 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -211,8 +211,8 @@ struct request { unsigned short ioprio; - void *special; - char *buffer; + void *special; /* opaque pointer available for LLD use */ + char *buffer; /* kaddr of the current segment if available */ int tag; int errors; @@ -229,7 +229,6 @@ struct request { unsigned int data_len; unsigned int extra_len; /* length of alignment and padding */ unsigned int sense_len; - void *data; void *sense; unsigned long deadline; -- GitLab From c2553b5844b06910435e40cfab9e6f384840cb97 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 24 Apr 2009 08:10:11 +0200 Subject: [PATCH 0816/6080] block: make blk_do_io_stat() do the full "is this rq accountable" checks We currently check for file system requests outside of blk_do_io_stat(rq), but we may as well just include it. Signed-off-by: Jens Axboe --- block/blk-core.c | 12 +++--------- block/blk.h | 9 ++++++++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 6dd180cf15d2..1e3b97f0ae6e 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -68,7 +68,7 @@ static void drive_stat_acct(struct request *rq, int new_io) int rw = rq_data_dir(rq); int cpu; - if (!blk_fs_request(rq) || !blk_do_io_stat(rq)) + if (!blk_do_io_stat(rq)) return; cpu = part_stat_lock(); @@ -1639,10 +1639,7 @@ EXPORT_SYMBOL(blkdev_dequeue_request); static void blk_account_io_completion(struct request *req, unsigned int bytes) { - if (!blk_do_io_stat(req)) - return; - - if (blk_fs_request(req)) { + if (blk_do_io_stat(req)) { const int rw = rq_data_dir(req); struct hd_struct *part; int cpu; @@ -1656,15 +1653,12 @@ static void blk_account_io_completion(struct request *req, unsigned int bytes) static void blk_account_io_done(struct request *req) { - if (!blk_do_io_stat(req)) - return; - /* * Account IO completion. bar_rq isn't accounted as a normal * IO on queueing nor completion. Accounting the containing * request is enough. */ - if (blk_fs_request(req) && req != &req->q->bar_rq) { + if (blk_do_io_stat(req) && req != &req->q->bar_rq) { unsigned long duration = jiffies - req->start_time; const int rw = rq_data_dir(req); struct hd_struct *part; diff --git a/block/blk.h b/block/blk.h index 9b2c324e4407..404c10b25ca1 100644 --- a/block/blk.h +++ b/block/blk.h @@ -149,9 +149,16 @@ static inline int blk_cpu_to_group(int cpu) #endif } +/* + * Contribute to IO statistics IFF: + * + * a) it's attached to a gendisk, and + * b) the queue had IO stats enabled when this request was started, and + * c) it's a file system request + */ static inline int blk_do_io_stat(struct request *rq) { - return rq->rq_disk && blk_rq_io_stat(rq); + return rq->rq_disk && blk_rq_io_stat(rq) && blk_fs_request(rq); } #endif -- GitLab From c69d48540c201394d08cb4d48b905e001313d9b8 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 24 Apr 2009 08:12:19 +0200 Subject: [PATCH 0817/6080] block: include discard requests in IO accounting We currently don't do merging on discard requests, but we potentially could. If we do, then we need to include discard requests in the IO accounting, or merging would end up decrementing in_flight IO counters for an IO which never incremented them. So enable accounting for discard requests. Problem found by Nikanth Karthikesan Signed-off-by: Jens Axboe --- block/blk.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block/blk.h b/block/blk.h index 404c10b25ca1..51115599df9b 100644 --- a/block/blk.h +++ b/block/blk.h @@ -158,7 +158,8 @@ static inline int blk_cpu_to_group(int cpu) */ static inline int blk_do_io_stat(struct request *rq) { - return rq->rq_disk && blk_rq_io_stat(rq) && blk_fs_request(rq); + return rq->rq_disk && blk_rq_io_stat(rq) && blk_fs_request(rq) && + blk_discard_rq(rq); } #endif -- GitLab From 9eb55b030c4b3227334ee4482402096cd1d1a6fe Mon Sep 17 00:00:00 2001 From: Nikanth Karthikesan Date: Mon, 27 Apr 2009 14:53:54 +0200 Subject: [PATCH 0818/6080] block: catch trying to use more bits than request->cmd_flags has Signed-off-by: Nikanth Karthikesan Signed-off-by: Jens Axboe --- block/blk-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/block/blk-core.c b/block/blk-core.c index 1e3b97f0ae6e..394c5bd81271 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2097,6 +2097,9 @@ EXPORT_SYMBOL(kblockd_schedule_work); int __init blk_dev_init(void) { + BUILD_BUG_ON(__REQ_NR_BITS > 8 * + sizeof(((struct request *)0)->cmd_flags)); + kblockd_workqueue = create_workqueue("kblockd"); if (!kblockd_workqueue) panic("Failed to create kblockd\n"); -- GitLab From 9fd8d0e1bcb848257968d9a7d73ca4d890ea8bd1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:04 +0900 Subject: [PATCH 0819/6080] block: make blk_end_request_cur() return bool In the process of mindlessly copying [__]blk_end_request_all(), [__]blk_end_request_cur() ended up returning void even though they're partial completion functions. Fix it. [ Impact: fix braindead API ] Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 12c545e2737c..3a5b1bd6582c 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -903,10 +903,14 @@ static inline void blk_end_request_all(struct request *rq, int error) * * Description: * Complete the current consecutively mapped chunk from @rq. + * + * Return: + * %false - we are done with this request + * %true - still buffers pending for this request */ -static inline void blk_end_request_cur(struct request *rq, int error) +static inline bool blk_end_request_cur(struct request *rq, int error) { - blk_end_request(rq, error, rq->hard_cur_sectors << 9); + return blk_end_request(rq, error, rq->hard_cur_sectors << 9); } /** @@ -952,10 +956,14 @@ static inline void __blk_end_request_all(struct request *rq, int error) * Description: * Complete the current consecutively mapped chunk from @rq. Must * be called with queue lock held. + * + * Return: + * %false - we are done with this request + * %true - still buffers pending for this request */ -static inline void __blk_end_request_cur(struct request *rq, int error) +static inline bool __blk_end_request_cur(struct request *rq, int error) { - __blk_end_request(rq, error, rq->hard_cur_sectors << 9); + return __blk_end_request(rq, error, rq->hard_cur_sectors << 9); } extern void blk_complete_request(struct request *); -- GitLab From 4c94dece1baf320d925cedb231489c4e0358ac5a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:05 +0900 Subject: [PATCH 0820/6080] block: don't init rq fields unnecessarily blk_get_request() always returns properly zeroed requests. Don't set fields to zero/NULL unnecessarily. [ Impact: cleanup ] Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- block/scsi_ioctl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index bb9aa43551b2..58cf4560f742 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -500,8 +500,6 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, rq = blk_get_request(q, WRITE, __GFP_WAIT); rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->data_len = 0; - rq->extra_len = 0; rq->timeout = BLK_DEFAULT_SG_TIMEOUT; rq->cmd[0] = cmd; rq->cmd[4] = data; -- GitLab From 5b5c5d12b91cb6b2a2967f06aef35d59008dc2e7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:06 +0900 Subject: [PATCH 0821/6080] amiflop,ataflop,xd,mg_disk: clean up unnecessary stuff from block drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rq_data_dir() can only be READ or WRITE and rq->sector and nr_sectors are always automatically updated after partial request completion. Don't worry about rq_data_dir() not being either READ or WRITE or manually update sector and nr_sectors. [ Impact: cleanup ] Signed-off-by: Tejun Heo Cc: Jörg Dorchain Cc: Geert Uytterhoeven Cc: unsik Kim Signed-off-by: Jens Axboe --- drivers/block/amiflop.c | 7 ------- drivers/block/ataflop.c | 4 ---- drivers/block/mg_disk.c | 10 ---------- drivers/block/xd.c | 9 ++------- 4 files changed, 2 insertions(+), 28 deletions(-) diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index b99a2a606d02..8ff95f2c0ede 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1371,11 +1371,6 @@ static void redo_fd_request(void) "0x%08lx\n", track, sector, data); #endif - if ((rq_data_dir(CURRENT) != READ) && (rq_data_dir(CURRENT) != WRITE)) { - printk(KERN_WARNING "do_fd_request: unknown command\n"); - __blk_end_request_cur(CURRENT, -EIO); - goto repeat; - } if (get_track(drive, track) == -1) { __blk_end_request_cur(CURRENT, -EIO); goto repeat; @@ -1407,8 +1402,6 @@ static void redo_fd_request(void) break; } } - CURRENT->nr_sectors -= CURRENT->current_nr_sectors; - CURRENT->sector += CURRENT->current_nr_sectors; __blk_end_request_cur(CURRENT, 0); goto repeat; diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 44a8702136a9..25067287211f 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -732,8 +732,6 @@ static void do_fd_action( int drive ) } else { /* all sectors finished */ - CURRENT->nr_sectors -= CURRENT->current_nr_sectors; - CURRENT->sector += CURRENT->current_nr_sectors; __blk_end_request_cur(CURRENT, 0); redo_fd_request(); return; @@ -1139,8 +1137,6 @@ static void fd_rwsec_done1(int status) } else { /* all sectors finished */ - CURRENT->nr_sectors -= CURRENT->current_nr_sectors; - CURRENT->sector += CURRENT->current_nr_sectors; __blk_end_request_cur(CURRENT, 0); redo_fd_request(); } diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 408c2bd8a439..2c00ad90cd62 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -560,11 +560,6 @@ static void mg_request_poll(struct request_queue *q) case WRITE: mg_write(req); break; - default: - printk(KERN_WARNING "%s:%d unknown command\n", - __func__, __LINE__); - __blk_end_request_cur(req, -EIO); - break; } } } @@ -614,11 +609,6 @@ static unsigned int mg_issue_req(struct request *req, outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); break; - default: - printk(KERN_WARNING "%s:%d unknown command\n", - __func__, __LINE__); - __blk_end_request_cur(req, -EIO); - break; } return MG_ERR_NONE; } diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 6f6ad82ec0c0..14be4c1ed1aa 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -308,7 +308,6 @@ static void do_xd_request (struct request_queue * q) while ((req = elv_next_request(q)) != NULL) { unsigned block = req->sector; unsigned count = req->nr_sectors; - int rw = rq_data_dir(req); XD_INFO *disk = req->rq_disk->private_data; int res = 0; int retry; @@ -321,13 +320,9 @@ static void do_xd_request (struct request_queue * q) __blk_end_request_cur(req, -EIO); continue; } - if (rw != READ && rw != WRITE) { - printk("do_xd_request: unknown request\n"); - __blk_end_request_cur(req, -EIO); - continue; - } for (retry = 0; (retry < XD_RETRIES) && !res; retry++) - res = xd_readwrite(rw, disk, req->buffer, block, count); + res = xd_readwrite(rq_data_dir(req), disk, req->buffer, + block, count); /* wrap up, 0 = success, -errno = fail */ __blk_end_request_cur(req, res); } -- GitLab From cd4c34ebec155e5c10f897d9bebf618248121e70 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:07 +0900 Subject: [PATCH 0822/6080] ps3disk: simplify request completion ps3disk_interrupt() always completes requests fully but it uses rq->hard_cur_sectors for FLUSH requests for some reason. Drop them and simply use __blk_end_request_all(). [ Impact: cleanup ] Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/block/ps3disk.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index d23b54bc2f50..f6586e4d351c 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -231,7 +231,6 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) struct request *req; int res, read, error; u64 tag, status; - unsigned long num_sectors; const char *op; res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status); @@ -261,11 +260,9 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && req->cmd[0] == REQ_LB_OP_FLUSH) { read = 0; - num_sectors = req->hard_cur_sectors; op = "flush"; } else { read = !rq_data_dir(req); - num_sectors = req->nr_sectors; op = read ? "read" : "write"; } if (status) { @@ -281,7 +278,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) } spin_lock(&priv->lock); - __blk_end_request(req, error, num_sectors << 9); + __blk_end_request_all(req, error); priv->req = NULL; ps3disk_do_request(dev, priv->queue); spin_unlock(&priv->lock); -- GitLab From 044208506d35bd62396c4673176e2c12393905b8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:08 +0900 Subject: [PATCH 0823/6080] sunvdc: kill vdc_end_request() vdc_end_request() is a thin silly wrapper on top of __blk_end_request(). Kill it. [ Impact: cleanup ] Signed-off-by: Tejun Heo Acked-by: David S. Miller Signed-off-by: Jens Axboe --- drivers/block/sunvdc.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 5861e33efe63..f59887c5ffbd 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -212,11 +212,6 @@ static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc) vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD); } -static void vdc_end_request(struct request *req, int error, int num_sectors) -{ - __blk_end_request(req, error, num_sectors << 9); -} - static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, unsigned int index) { @@ -239,7 +234,7 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, rqe->req = NULL; - vdc_end_request(req, (desc->status ? -EIO : 0), desc->size >> 9); + __blk_end_request(req, (desc->status ? -EIO : 0), desc->size); if (blk_queue_stopped(port->disk->queue)) blk_start_queue(port->disk->queue); @@ -453,7 +448,7 @@ static void do_vdc_request(struct request_queue *q) blkdev_dequeue_request(req); if (__send_request(req) < 0) - vdc_end_request(req, -EIO, req->hard_nr_sectors); + __blk_end_request_all(req, -EIO); } } -- GitLab From 4d6c84d91d1a539ebc47d1a36a35e9390ba11fdc Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:09 +0900 Subject: [PATCH 0824/6080] ubd: cleanup completion path ubd had its own block request partial completion mechanism, which is unnecessary as block layer already does it. Kill ubd_end_request() and ubd_finish() and replace them with direct call to blk_end_request(). [ Impact: cleanup ] Signed-off-by: Tejun Heo Cc: Jeff Dike Signed-off-by: Jens Axboe --- arch/um/drivers/ubd_kern.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index f934225fd8ef..36ca9fa89d05 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -451,23 +451,6 @@ static void do_ubd_request(struct request_queue * q); /* Only changed by ubd_init, which is an initcall. */ static int thread_fd = -1; - -static void ubd_end_request(struct request *req, int bytes, int error) -{ - blk_end_request(req, error, bytes); -} - -/* Callable only from interrupt context - otherwise you need to do - * spin_lock_irq()/spin_lock_irqsave() */ -static inline void ubd_finish(struct request *req, int bytes) -{ - if(bytes < 0){ - ubd_end_request(req, 0, -EIO); - return; - } - ubd_end_request(req, bytes, 0); -} - static LIST_HEAD(restart); /* XXX - move this inside ubd_intr. */ @@ -475,7 +458,6 @@ static LIST_HEAD(restart); static void ubd_handler(void) { struct io_thread_req *req; - struct request *rq; struct ubd *ubd; struct list_head *list, *next_ele; unsigned long flags; @@ -492,10 +474,7 @@ static void ubd_handler(void) return; } - rq = req->req; - rq->nr_sectors -= req->length >> 9; - if(rq->nr_sectors == 0) - ubd_finish(rq, rq->hard_nr_sectors << 9); + blk_end_request(req->req, 0, req->length); kfree(req); } reactivate_fd(thread_fd, UBD_IRQ); -- GitLab From f81f2f7c9fee307e371f37424577d46f9eaf8692 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:10 +0900 Subject: [PATCH 0825/6080] ubd: drop unnecessary rq->sector manipulation ubd curiously updates rq->sector while issuing the request in multiple pieces. Don't do it and simply use local copy of sector. [ Impact: cleanup ] Signed-off-by: Tejun Heo Cc: Jeff Dike Signed-off-by: Jens Axboe --- arch/um/drivers/ubd_kern.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 36ca9fa89d05..433012764a37 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1222,7 +1222,8 @@ static void do_ubd_request(struct request_queue *q) { struct io_thread_req *io_req; struct request *req; - int n, last_sectors; + sector_t sector; + int n; while(1){ struct ubd *dev = q->queuedata; @@ -1238,11 +1239,10 @@ static void do_ubd_request(struct request_queue *q) } req = dev->request; - last_sectors = 0; + sector = req->sector; while(dev->start_sg < dev->end_sg){ struct scatterlist *sg = &dev->sg[dev->start_sg]; - req->sector += last_sectors; io_req = kmalloc(sizeof(struct io_thread_req), GFP_ATOMIC); if(io_req == NULL){ @@ -1251,10 +1251,10 @@ static void do_ubd_request(struct request_queue *q) return; } prepare_request(req, io_req, - (unsigned long long) req->sector << 9, + (unsigned long long)sector << 9, sg->offset, sg->length, sg_page(sg)); - last_sectors = sg->length >> 9; + sector += sg->length >> 9; n = os_write_file(thread_fd, &io_req, sizeof(struct io_thread_req *)); if(n != sizeof(struct io_thread_req *)){ -- GitLab From e091eb67af957bac4e4f7410c5d1aa263ee483a4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:11 +0900 Subject: [PATCH 0826/6080] hd: clean up request completion paths hd read/write_intr() functions manually manipulate request to incrementally complete it, which block layer already supports. Simply use block layer completion routines instead of manual partial completion. While at it, clear unnecessary elv_next_request() check at the tail of read_intr(). This also makes read and write_intr() more consistent. [ Impact: cleanup ] Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/block/hd.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 5cb300b81c6a..75b9ca95c4eb 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -452,32 +452,25 @@ static void read_intr(void) bad_rw_intr(); hd_request(); return; + ok_to_read: req = CURRENT; insw(HD_DATA, req->buffer, 256); - req->sector++; - req->buffer += 512; - req->errors = 0; - i = --req->nr_sectors; - --req->current_nr_sectors; #ifdef DEBUG printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", - req->rq_disk->disk_name, req->sector, req->nr_sectors, + req->rq_disk->disk_name, req->sector + 1, req->nr_sectors - 1, req->buffer+512); #endif - if (req->current_nr_sectors <= 0) - __blk_end_request_cur(req, 0); - if (i > 0) { + if (__blk_end_request(req, 0, 512)) { SET_HANDLER(&read_intr); return; } + (void) inb_p(HD_STATUS); #if (HD_DELAY > 0) last_req = read_timer(); #endif - if (elv_next_request(QUEUE)) - hd_request(); - return; + hd_request(); } static void write_intr(void) @@ -499,23 +492,18 @@ static void write_intr(void) bad_rw_intr(); hd_request(); return; + ok_to_write: - req->sector++; - i = --req->nr_sectors; - --req->current_nr_sectors; - req->buffer += 512; - if (!i || (req->bio && req->current_nr_sectors <= 0)) - __blk_end_request_cur(req, 0); - if (i > 0) { + if (__blk_end_request(req, 0, 512)) { SET_HANDLER(&write_intr); outsw(HD_DATA, req->buffer, 256); - } else { + return; + } + #if (HD_DELAY > 0) - last_req = read_timer(); + last_req = read_timer(); #endif - hd_request(); - } - return; + hd_request(); } static void recal_intr(void) -- GitLab From 467ca759fc83fc35cb7d15aec0d74c62cffc4481 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:12 +0900 Subject: [PATCH 0827/6080] swim3: clean up request completion paths swim3 curiously tries to update request parameters before calling __blk_end_request() when __blk_end_request() will do it anyway, and it updates request for partial completion manually instead of using blk_update_request(). Also, it does some spurious checks on rq such as testing whether rq->sector is negative or current_nr_sectors is zero right after fetching. Drop unnecessary stuff and use standard block layer mechanisms. [ Impact: cleanup ] Signed-off-by: Tejun Heo Cc: Benjamin Herrenschmidt Signed-off-by: Jens Axboe --- drivers/block/swim3.c | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index 5904f7b73c6e..424855945b9b 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -319,14 +319,10 @@ static void start_request(struct floppy_state *fs) req->errors, req->current_nr_sectors); #endif - if (req->sector < 0 || req->sector >= fs->total_secs) { + if (req->sector >= fs->total_secs) { __blk_end_request_cur(req, -EIO); continue; } - if (req->current_nr_sectors == 0) { - __blk_end_request_cur(req, 0); - continue; - } if (fs->ejected) { __blk_end_request_cur(req, -EIO); continue; @@ -593,8 +589,6 @@ static void xfer_timeout(unsigned long data) struct floppy_state *fs = (struct floppy_state *) data; struct swim3 __iomem *sw = fs->swim3; struct dbdma_regs __iomem *dr = fs->dma; - struct dbdma_cmd *cp = fs->dma_cmd; - unsigned long s; int n; fs->timeout_pending = 0; @@ -605,14 +599,6 @@ static void xfer_timeout(unsigned long data) out_8(&sw->intr_enable, 0); out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION); out_8(&sw->select, RELAX); - if (rq_data_dir(fd_req) == WRITE) - ++cp; - if (ld_le16(&cp->xfer_status) != 0) - s = fs->scount - ((ld_le16(&cp->res_count) + 511) >> 9); - else - s = 0; - fd_req->sector += s; - fd_req->current_nr_sectors -= s; printk(KERN_ERR "swim3: timeout %sing sector %ld\n", (rq_data_dir(fd_req)==WRITE? "writ": "read"), (long)fd_req->sector); __blk_end_request_cur(fd_req, -EIO); @@ -719,9 +705,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) if (intr & ERROR_INTR) { n = fs->scount - 1 - resid / 512; if (n > 0) { - fd_req->sector += n; - fd_req->current_nr_sectors -= n; - fd_req->buffer += n * 512; + blk_update_request(fd_req, 0, n << 9); fs->req_sector += n; } if (fs->retries < 5) { @@ -745,13 +729,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) start_request(fs); break; } - fd_req->sector += fs->scount; - fd_req->current_nr_sectors -= fs->scount; - fd_req->buffer += fs->scount * 512; - if (fd_req->current_nr_sectors <= 0) { - __blk_end_request_cur(fd_req, 0); - fs->state = idle; - } else { + if (__blk_end_request(fd_req, 0, fs->scount << 9)) { fs->req_sector += fs->scount; if (fs->req_sector > fs->secpertrack) { fs->req_sector -= fs->secpertrack; @@ -761,7 +739,8 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) } } act(fs); - } + } else + fs->state = idle; } if (fs->state == idle) start_request(fs); -- GitLab From e138b4e08ef65771000fbe6d93d67e3960ff862b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:13 +0900 Subject: [PATCH 0828/6080] swim: clean up request completion paths swim curiously tries to update request parameters before calling __blk_end_request() when __blk_end_request() will do it anyway and unnecessarily checks whether current_nr_sectors is zero right after fetching. Drop unnecessary stuff and use standard block layer mechanisms. [ Impact: cleanup ] Signed-off-by: Tejun Heo Cc: Laurent Vivier Signed-off-by: Jens Axboe --- drivers/block/swim.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 6544a7b06bf0..97ef4266c4c7 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -535,10 +535,6 @@ static void redo_fd_request(struct request_queue *q) __blk_end_request_cur(req, -EIO); continue; } - if (req->current_nr_sectors == 0) { - __blk_end_request_cur(req, 0); - continue; - } if (!fs->disk_in) { __blk_end_request_cur(req, -EIO); continue; @@ -561,9 +557,6 @@ static void redo_fd_request(struct request_queue *q) __blk_end_request_cur(req, -EIO); continue; } - req->nr_sectors -= req->current_nr_sectors; - req->sector += req->current_nr_sectors; - req->buffer += req->current_nr_sectors * 512; __blk_end_request_cur(req, 0); break; } -- GitLab From eec9462088a26c046d4db3100796a340a50890b8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:14 +0900 Subject: [PATCH 0829/6080] mg_disk: fold mg_disk.h into mg_disk.c include/linux/mg_disk.h is used only by drivers/block/mg_disk.c. No reason to put it in a separate header. Fold it into mg_disk.c. [ Impact: cleanup ] Signed-off-by: Tejun Heo Cc: unsik Kim Signed-off-by: Jens Axboe --- drivers/block/mg_disk.c | 186 +++++++++++++++++++++++++++++++++++- include/linux/mg_disk.h | 206 ---------------------------------------- 2 files changed, 185 insertions(+), 207 deletions(-) delete mode 100644 include/linux/mg_disk.h diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 2c00ad90cd62..2c6127ee8343 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -22,10 +22,194 @@ #include #include #include -#include #define MG_RES_SEC (CONFIG_MG_DISK_RES << 1) +/* name for block device */ +#define MG_DISK_NAME "mgd" +/* name for platform device */ +#define MG_DEV_NAME "mg_disk" + +#define MG_DISK_MAJ 0 +#define MG_DISK_MAX_PART 16 +#define MG_SECTOR_SIZE 512 +#define MG_MAX_SECTS 256 + +/* Register offsets */ +#define MG_BUFF_OFFSET 0x8000 +#define MG_STORAGE_BUFFER_SIZE 0x200 +#define MG_REG_OFFSET 0xC000 +#define MG_REG_FEATURE (MG_REG_OFFSET + 2) /* write case */ +#define MG_REG_ERROR (MG_REG_OFFSET + 2) /* read case */ +#define MG_REG_SECT_CNT (MG_REG_OFFSET + 4) +#define MG_REG_SECT_NUM (MG_REG_OFFSET + 6) +#define MG_REG_CYL_LOW (MG_REG_OFFSET + 8) +#define MG_REG_CYL_HIGH (MG_REG_OFFSET + 0xA) +#define MG_REG_DRV_HEAD (MG_REG_OFFSET + 0xC) +#define MG_REG_COMMAND (MG_REG_OFFSET + 0xE) /* write case */ +#define MG_REG_STATUS (MG_REG_OFFSET + 0xE) /* read case */ +#define MG_REG_DRV_CTRL (MG_REG_OFFSET + 0x10) +#define MG_REG_BURST_CTRL (MG_REG_OFFSET + 0x12) + +/* "Drive Select/Head Register" bit values */ +#define MG_REG_HEAD_MUST_BE_ON 0xA0 /* These 2 bits are always on */ +#define MG_REG_HEAD_DRIVE_MASTER (0x00 | MG_REG_HEAD_MUST_BE_ON) +#define MG_REG_HEAD_DRIVE_SLAVE (0x10 | MG_REG_HEAD_MUST_BE_ON) +#define MG_REG_HEAD_LBA_MODE (0x40 | MG_REG_HEAD_MUST_BE_ON) + + +/* "Device Control Register" bit values */ +#define MG_REG_CTRL_INTR_ENABLE 0x0 +#define MG_REG_CTRL_INTR_DISABLE (0x1<<1) +#define MG_REG_CTRL_RESET (0x1<<2) +#define MG_REG_CTRL_INTR_POLA_ACTIVE_HIGH 0x0 +#define MG_REG_CTRL_INTR_POLA_ACTIVE_LOW (0x1<<4) +#define MG_REG_CTRL_DPD_POLA_ACTIVE_LOW 0x0 +#define MG_REG_CTRL_DPD_POLA_ACTIVE_HIGH (0x1<<5) +#define MG_REG_CTRL_DPD_DISABLE 0x0 +#define MG_REG_CTRL_DPD_ENABLE (0x1<<6) + +/* Status register bit */ +/* error bit in status register */ +#define MG_REG_STATUS_BIT_ERROR 0x01 +/* corrected error in status register */ +#define MG_REG_STATUS_BIT_CORRECTED_ERROR 0x04 +/* data request bit in status register */ +#define MG_REG_STATUS_BIT_DATA_REQ 0x08 +/* DSC - Drive Seek Complete */ +#define MG_REG_STATUS_BIT_SEEK_DONE 0x10 +/* DWF - Drive Write Fault */ +#define MG_REG_STATUS_BIT_WRITE_FAULT 0x20 +#define MG_REG_STATUS_BIT_READY 0x40 +#define MG_REG_STATUS_BIT_BUSY 0x80 + +/* handy status */ +#define MG_STAT_READY (MG_REG_STATUS_BIT_READY | MG_REG_STATUS_BIT_SEEK_DONE) +#define MG_READY_OK(s) (((s) & (MG_STAT_READY | \ + (MG_REG_STATUS_BIT_BUSY | \ + MG_REG_STATUS_BIT_WRITE_FAULT | \ + MG_REG_STATUS_BIT_ERROR))) == MG_STAT_READY) + +/* Error register */ +#define MG_REG_ERR_AMNF 0x01 +#define MG_REG_ERR_ABRT 0x04 +#define MG_REG_ERR_IDNF 0x10 +#define MG_REG_ERR_UNC 0x40 +#define MG_REG_ERR_BBK 0x80 + +/* error code for others */ +#define MG_ERR_NONE 0 +#define MG_ERR_TIMEOUT 0x100 +#define MG_ERR_INIT_STAT 0x101 +#define MG_ERR_TRANSLATION 0x102 +#define MG_ERR_CTRL_RST 0x103 +#define MG_ERR_INV_STAT 0x104 +#define MG_ERR_RSTOUT 0x105 + +#define MG_MAX_ERRORS 6 /* Max read/write errors */ + +/* command */ +#define MG_CMD_RD 0x20 +#define MG_CMD_WR 0x30 +#define MG_CMD_SLEEP 0x99 +#define MG_CMD_WAKEUP 0xC3 +#define MG_CMD_ID 0xEC +#define MG_CMD_WR_CONF 0x3C +#define MG_CMD_RD_CONF 0x40 + +/* operation mode */ +#define MG_OP_CASCADE (1 << 0) +#define MG_OP_CASCADE_SYNC_RD (1 << 1) +#define MG_OP_CASCADE_SYNC_WR (1 << 2) +#define MG_OP_INTERLEAVE (1 << 3) + +/* synchronous */ +#define MG_BURST_LAT_4 (3 << 4) +#define MG_BURST_LAT_5 (4 << 4) +#define MG_BURST_LAT_6 (5 << 4) +#define MG_BURST_LAT_7 (6 << 4) +#define MG_BURST_LAT_8 (7 << 4) +#define MG_BURST_LEN_4 (1 << 1) +#define MG_BURST_LEN_8 (2 << 1) +#define MG_BURST_LEN_16 (3 << 1) +#define MG_BURST_LEN_32 (4 << 1) +#define MG_BURST_LEN_CONT (0 << 1) + +/* timeout value (unit: ms) */ +#define MG_TMAX_CONF_TO_CMD 1 +#define MG_TMAX_WAIT_RD_DRQ 10 +#define MG_TMAX_WAIT_WR_DRQ 500 +#define MG_TMAX_RST_TO_BUSY 10 +#define MG_TMAX_HDRST_TO_RDY 500 +#define MG_TMAX_SWRST_TO_RDY 500 +#define MG_TMAX_RSTOUT 3000 + +/* device attribution */ +/* use mflash as boot device */ +#define MG_BOOT_DEV (1 << 0) +/* use mflash as storage device */ +#define MG_STORAGE_DEV (1 << 1) +/* same as MG_STORAGE_DEV, but bootloader already done reset sequence */ +#define MG_STORAGE_DEV_SKIP_RST (1 << 2) + +#define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST) + +/* names of GPIO resource */ +#define MG_RST_PIN "mg_rst" +/* except MG_BOOT_DEV, reset-out pin should be assigned */ +#define MG_RSTOUT_PIN "mg_rstout" + +/* private driver data */ +struct mg_drv_data { + /* disk resource */ + u32 use_polling; + + /* device attribution */ + u32 dev_attr; + + /* internally used */ + struct mg_host *host; +}; + +/* main structure for mflash driver */ +struct mg_host { + struct device *dev; + + struct request_queue *breq; + spinlock_t lock; + struct gendisk *gd; + + struct timer_list timer; + void (*mg_do_intr) (struct mg_host *); + + u16 id[ATA_ID_WORDS]; + + u16 cyls; + u16 heads; + u16 sectors; + u32 n_sectors; + u32 nres_sectors; + + void __iomem *dev_base; + unsigned int irq; + unsigned int rst; + unsigned int rstout; + + u32 major; + u32 error; +}; + +/* + * Debugging macro and defines + */ +#undef DO_MG_DEBUG +#ifdef DO_MG_DEBUG +# define MG_DBG(fmt, args...) \ + printk(KERN_DEBUG "%s:%d "fmt, __func__, __LINE__, ##args) +#else /* CONFIG_MG_DEBUG */ +# define MG_DBG(fmt, args...) do { } while (0) +#endif /* CONFIG_MG_DEBUG */ + static void mg_request(struct request_queue *); static void mg_dump_status(const char *msg, unsigned int stat, diff --git a/include/linux/mg_disk.h b/include/linux/mg_disk.h deleted file mode 100644 index 1f76b1ebf627..000000000000 --- a/include/linux/mg_disk.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * include/linux/mg_disk.c - * - * Support for the mGine m[g]flash IO mode. - * Based on legacy hd.c - * - * (c) 2008 mGine Co.,LTD - * (c) 2008 unsik Kim - * - * 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 __MG_DISK_H__ -#define __MG_DISK_H__ - -#include -#include - -/* name for block device */ -#define MG_DISK_NAME "mgd" -/* name for platform device */ -#define MG_DEV_NAME "mg_disk" - -#define MG_DISK_MAJ 0 -#define MG_DISK_MAX_PART 16 -#define MG_SECTOR_SIZE 512 -#define MG_MAX_SECTS 256 - -/* Register offsets */ -#define MG_BUFF_OFFSET 0x8000 -#define MG_STORAGE_BUFFER_SIZE 0x200 -#define MG_REG_OFFSET 0xC000 -#define MG_REG_FEATURE (MG_REG_OFFSET + 2) /* write case */ -#define MG_REG_ERROR (MG_REG_OFFSET + 2) /* read case */ -#define MG_REG_SECT_CNT (MG_REG_OFFSET + 4) -#define MG_REG_SECT_NUM (MG_REG_OFFSET + 6) -#define MG_REG_CYL_LOW (MG_REG_OFFSET + 8) -#define MG_REG_CYL_HIGH (MG_REG_OFFSET + 0xA) -#define MG_REG_DRV_HEAD (MG_REG_OFFSET + 0xC) -#define MG_REG_COMMAND (MG_REG_OFFSET + 0xE) /* write case */ -#define MG_REG_STATUS (MG_REG_OFFSET + 0xE) /* read case */ -#define MG_REG_DRV_CTRL (MG_REG_OFFSET + 0x10) -#define MG_REG_BURST_CTRL (MG_REG_OFFSET + 0x12) - -/* "Drive Select/Head Register" bit values */ -#define MG_REG_HEAD_MUST_BE_ON 0xA0 /* These 2 bits are always on */ -#define MG_REG_HEAD_DRIVE_MASTER (0x00 | MG_REG_HEAD_MUST_BE_ON) -#define MG_REG_HEAD_DRIVE_SLAVE (0x10 | MG_REG_HEAD_MUST_BE_ON) -#define MG_REG_HEAD_LBA_MODE (0x40 | MG_REG_HEAD_MUST_BE_ON) - - -/* "Device Control Register" bit values */ -#define MG_REG_CTRL_INTR_ENABLE 0x0 -#define MG_REG_CTRL_INTR_DISABLE (0x1<<1) -#define MG_REG_CTRL_RESET (0x1<<2) -#define MG_REG_CTRL_INTR_POLA_ACTIVE_HIGH 0x0 -#define MG_REG_CTRL_INTR_POLA_ACTIVE_LOW (0x1<<4) -#define MG_REG_CTRL_DPD_POLA_ACTIVE_LOW 0x0 -#define MG_REG_CTRL_DPD_POLA_ACTIVE_HIGH (0x1<<5) -#define MG_REG_CTRL_DPD_DISABLE 0x0 -#define MG_REG_CTRL_DPD_ENABLE (0x1<<6) - -/* Status register bit */ -/* error bit in status register */ -#define MG_REG_STATUS_BIT_ERROR 0x01 -/* corrected error in status register */ -#define MG_REG_STATUS_BIT_CORRECTED_ERROR 0x04 -/* data request bit in status register */ -#define MG_REG_STATUS_BIT_DATA_REQ 0x08 -/* DSC - Drive Seek Complete */ -#define MG_REG_STATUS_BIT_SEEK_DONE 0x10 -/* DWF - Drive Write Fault */ -#define MG_REG_STATUS_BIT_WRITE_FAULT 0x20 -#define MG_REG_STATUS_BIT_READY 0x40 -#define MG_REG_STATUS_BIT_BUSY 0x80 - -/* handy status */ -#define MG_STAT_READY (MG_REG_STATUS_BIT_READY | MG_REG_STATUS_BIT_SEEK_DONE) -#define MG_READY_OK(s) (((s) & (MG_STAT_READY | \ - (MG_REG_STATUS_BIT_BUSY | \ - MG_REG_STATUS_BIT_WRITE_FAULT | \ - MG_REG_STATUS_BIT_ERROR))) == MG_STAT_READY) - -/* Error register */ -#define MG_REG_ERR_AMNF 0x01 -#define MG_REG_ERR_ABRT 0x04 -#define MG_REG_ERR_IDNF 0x10 -#define MG_REG_ERR_UNC 0x40 -#define MG_REG_ERR_BBK 0x80 - -/* error code for others */ -#define MG_ERR_NONE 0 -#define MG_ERR_TIMEOUT 0x100 -#define MG_ERR_INIT_STAT 0x101 -#define MG_ERR_TRANSLATION 0x102 -#define MG_ERR_CTRL_RST 0x103 -#define MG_ERR_INV_STAT 0x104 -#define MG_ERR_RSTOUT 0x105 - -#define MG_MAX_ERRORS 6 /* Max read/write errors */ - -/* command */ -#define MG_CMD_RD 0x20 -#define MG_CMD_WR 0x30 -#define MG_CMD_SLEEP 0x99 -#define MG_CMD_WAKEUP 0xC3 -#define MG_CMD_ID 0xEC -#define MG_CMD_WR_CONF 0x3C -#define MG_CMD_RD_CONF 0x40 - -/* operation mode */ -#define MG_OP_CASCADE (1 << 0) -#define MG_OP_CASCADE_SYNC_RD (1 << 1) -#define MG_OP_CASCADE_SYNC_WR (1 << 2) -#define MG_OP_INTERLEAVE (1 << 3) - -/* synchronous */ -#define MG_BURST_LAT_4 (3 << 4) -#define MG_BURST_LAT_5 (4 << 4) -#define MG_BURST_LAT_6 (5 << 4) -#define MG_BURST_LAT_7 (6 << 4) -#define MG_BURST_LAT_8 (7 << 4) -#define MG_BURST_LEN_4 (1 << 1) -#define MG_BURST_LEN_8 (2 << 1) -#define MG_BURST_LEN_16 (3 << 1) -#define MG_BURST_LEN_32 (4 << 1) -#define MG_BURST_LEN_CONT (0 << 1) - -/* timeout value (unit: ms) */ -#define MG_TMAX_CONF_TO_CMD 1 -#define MG_TMAX_WAIT_RD_DRQ 10 -#define MG_TMAX_WAIT_WR_DRQ 500 -#define MG_TMAX_RST_TO_BUSY 10 -#define MG_TMAX_HDRST_TO_RDY 500 -#define MG_TMAX_SWRST_TO_RDY 500 -#define MG_TMAX_RSTOUT 3000 - -/* device attribution */ -/* use mflash as boot device */ -#define MG_BOOT_DEV (1 << 0) -/* use mflash as storage device */ -#define MG_STORAGE_DEV (1 << 1) -/* same as MG_STORAGE_DEV, but bootloader already done reset sequence */ -#define MG_STORAGE_DEV_SKIP_RST (1 << 2) - -#define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST) - -/* names of GPIO resource */ -#define MG_RST_PIN "mg_rst" -/* except MG_BOOT_DEV, reset-out pin should be assigned */ -#define MG_RSTOUT_PIN "mg_rstout" - -/* private driver data */ -struct mg_drv_data { - /* disk resource */ - u32 use_polling; - - /* device attribution */ - u32 dev_attr; - - /* internally used */ - struct mg_host *host; -}; - -/* main structure for mflash driver */ -struct mg_host { - struct device *dev; - - struct request_queue *breq; - spinlock_t lock; - struct gendisk *gd; - - struct timer_list timer; - void (*mg_do_intr) (struct mg_host *); - - u16 id[ATA_ID_WORDS]; - - u16 cyls; - u16 heads; - u16 sectors; - u32 n_sectors; - u32 nres_sectors; - - void __iomem *dev_base; - unsigned int irq; - unsigned int rst; - unsigned int rstout; - - u32 major; - u32 error; -}; - -/* - * Debugging macro and defines - */ -#undef DO_MG_DEBUG -#ifdef DO_MG_DEBUG -# define MG_DBG(fmt, args...) \ - printk(KERN_DEBUG "%s:%d "fmt, __func__, __LINE__, ##args) -#else /* CONFIG_MG_DEBUG */ -# define MG_DBG(fmt, args...) do { } while (0) -#endif /* CONFIG_MG_DEBUG */ - -#endif -- GitLab From a03bb5a32fff4aa23f081a3cff7e98d4084104cd Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 28 Apr 2009 13:06:15 +0900 Subject: [PATCH 0830/6080] mg_disk: clean up request completion paths mg_disk implements its own partial completion. Convert to standard block layer partial completion. [ Impact: cleanup ] Signed-off-by: Tejun Heo Cc: unsik Kim Signed-off-by: Jens Axboe --- drivers/block/mg_disk.c | 117 ++++++++++++---------------------------- 1 file changed, 33 insertions(+), 84 deletions(-) diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 2c6127ee8343..1a4cc968cfee 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -503,95 +503,68 @@ static unsigned int mg_out(struct mg_host *host, static void mg_read(struct request *req) { - u32 remains, j; + u32 j; struct mg_host *host = req->rq_disk->private_data; - remains = req->nr_sectors; - if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_RD, NULL) != MG_ERR_NONE) mg_bad_rw_intr(host); MG_DBG("requested %d sects (from %ld), buffer=0x%p\n", - remains, req->sector, req->buffer); + req->nr_sectors, req->sector, req->buffer); + + do { + u16 *buff = (u16 *)req->buffer; - while (remains) { if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) { mg_bad_rw_intr(host); return; } - for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) { - *(u16 *)req->buffer = - inw((unsigned long)host->dev_base + - MG_BUFF_OFFSET + (j << 1)); - req->buffer += 2; - } - - req->sector++; - req->errors = 0; - remains = --req->nr_sectors; - --req->current_nr_sectors; - - if (req->current_nr_sectors <= 0) { - MG_DBG("remain : %d sects\n", remains); - __blk_end_request_cur(req, 0); - if (remains > 0) - req = elv_next_request(host->breq); - } + for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) + *buff++ = inw((unsigned long)host->dev_base + + MG_BUFF_OFFSET + (j << 1)); outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); - } + } while (__blk_end_request(req, 0, MG_SECTOR_SIZE)); } static void mg_write(struct request *req) { - u32 remains, j; + u32 j; struct mg_host *host = req->rq_disk->private_data; - remains = req->nr_sectors; - if (mg_out(host, req->sector, req->nr_sectors, MG_CMD_WR, NULL) != MG_ERR_NONE) { mg_bad_rw_intr(host); return; } - MG_DBG("requested %d sects (from %ld), buffer=0x%p\n", - remains, req->sector, req->buffer); - while (remains) { + req->nr_sectors, req->sector, req->buffer); + + do { + u16 *buff = (u16 *)req->buffer; + if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) { mg_bad_rw_intr(host); return; } - for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) { - outw(*(u16 *)req->buffer, - (unsigned long)host->dev_base + - MG_BUFF_OFFSET + (j << 1)); - req->buffer += 2; - } - req->sector++; - remains = --req->nr_sectors; - --req->current_nr_sectors; - - if (req->current_nr_sectors <= 0) { - MG_DBG("remain : %d sects\n", remains); - __blk_end_request_cur(req, 0); - if (remains > 0) - req = elv_next_request(host->breq); - } + for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) + outw(*buff++, (unsigned long)host->dev_base + + MG_BUFF_OFFSET + (j << 1)); outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); - } + } while (__blk_end_request(req, 0, MG_SECTOR_SIZE)); } static void mg_read_intr(struct mg_host *host) { u32 i; + u16 *buff; struct request *req; /* check status */ @@ -612,39 +585,24 @@ static void mg_read_intr(struct mg_host *host) ok_to_read: /* get current segment of request */ req = elv_next_request(host->breq); + buff = (u16 *)req->buffer; /* read 1 sector */ - for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) { - *(u16 *)req->buffer = - inw((unsigned long)host->dev_base + MG_BUFF_OFFSET + - (i << 1)); - req->buffer += 2; - } + for (i = 0; i < MG_SECTOR_SIZE >> 1; i++) + *buff++ = inw((unsigned long)host->dev_base + MG_BUFF_OFFSET + + (i << 1)); - /* manipulate request */ MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n", req->sector, req->nr_sectors - 1, req->buffer); - req->sector++; - req->errors = 0; - i = --req->nr_sectors; - --req->current_nr_sectors; - - /* let know if current segment done */ - if (req->current_nr_sectors <= 0) - __blk_end_request_cur(req, 0); - - /* set handler if read remains */ - if (i > 0) { - host->mg_do_intr = mg_read_intr; - mod_timer(&host->timer, jiffies + 3 * HZ); - } - /* send read confirm */ outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); - /* goto next request */ - if (!i) + if (__blk_end_request(req, 0, MG_SECTOR_SIZE)) { + /* set handler if read remains */ + host->mg_do_intr = mg_read_intr; + mod_timer(&host->timer, jiffies + 3 * HZ); + } else /* goto next request */ mg_request(host->breq); } @@ -653,6 +611,7 @@ static void mg_write_intr(struct mg_host *host) u32 i, j; u16 *buff; struct request *req; + bool rem; /* get current segment of request */ req = elv_next_request(host->breq); @@ -673,18 +632,8 @@ static void mg_write_intr(struct mg_host *host) return; ok_to_write: - /* manipulate request */ - req->sector++; - i = --req->nr_sectors; - --req->current_nr_sectors; - req->buffer += MG_SECTOR_SIZE; - - /* let know if current segment or all done */ - if (!i || (req->bio && req->current_nr_sectors <= 0)) - __blk_end_request_cur(req, 0); - - /* write 1 sector and set handler if remains */ - if (i > 0) { + if ((rem = __blk_end_request(req, 0, MG_SECTOR_SIZE))) { + /* write 1 sector and set handler if remains */ buff = (u16 *)req->buffer; for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) { outw(*buff, (unsigned long)host->dev_base + @@ -700,7 +649,7 @@ ok_to_write: /* send write confirm */ outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND); - if (!i) + if (!rem) mg_request(host->breq); } -- GitLab From 8a11a789c39cd6f61de4243234cf44a46c23ffd0 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 28 Apr 2009 13:06:16 +0900 Subject: [PATCH 0831/6080] mg_disk: fix dependency on libata Add local copies of ata_id_string() and ata_id_c_string() to mg_disk so there is no need for the driver to depend on ATA and SCSI. [ Impact: break dependency on libata by copying ata id string functions ] Cc: unsik Kim Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/block/Kconfig | 2 +- drivers/block/mg_disk.c | 44 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index ddea8e485cc9..f42fa50d3550 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -412,7 +412,7 @@ config ATA_OVER_ETH config MG_DISK tristate "mGine mflash, gflash support" - depends on ARM && ATA && GPIOLIB + depends on ARM && GPIOLIB help mGine mFlash(gFlash) block device driver diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 1a4cc968cfee..8e53cae9fa90 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -357,6 +357,42 @@ static irqreturn_t mg_irq(int irq, void *dev_id) return IRQ_HANDLED; } +/* local copy of ata_id_string() */ +static void mg_id_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len) +{ + unsigned int c; + + BUG_ON(len & 1); + + while (len > 0) { + c = id[ofs] >> 8; + *s = c; + s++; + + c = id[ofs] & 0xff; + *s = c; + s++; + + ofs++; + len -= 2; + } +} + +/* local copy of ata_id_c_string() */ +static void mg_id_c_string(const u16 *id, unsigned char *s, + unsigned int ofs, unsigned int len) +{ + unsigned char *p; + + mg_id_string(id, s, ofs, len - 1); + + p = s + strnlen(s, len - 1); + while (p > s && p[-1] == ' ') + p--; + *p = '\0'; +} + static int mg_get_disk_id(struct mg_host *host) { u32 i; @@ -403,9 +439,9 @@ static int mg_get_disk_id(struct mg_host *host) host->n_sectors -= host->nres_sectors; } - ata_id_c_string(id, fwrev, ATA_ID_FW_REV, sizeof(fwrev)); - ata_id_c_string(id, model, ATA_ID_PROD, sizeof(model)); - ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); + mg_id_c_string(id, fwrev, ATA_ID_FW_REV, sizeof(fwrev)); + mg_id_c_string(id, model, ATA_ID_PROD, sizeof(model)); + mg_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial)); printk(KERN_INFO "mg_disk: model: %s\n", model); printk(KERN_INFO "mg_disk: firm: %.8s\n", fwrev); printk(KERN_INFO "mg_disk: serial: %s\n", serial); -- GitLab From f68adec3c7155a8bbf32a90cb4c4d0737df045d9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 28 Apr 2009 13:06:17 +0900 Subject: [PATCH 0832/6080] mg_disk: use defines from While at it: - remove MG_REG_HEAD_MUST_BE_ON define - remove MG_REG_CTRL_INTR_ENABLE define - remove MG_REG_HEAD_LBA_MODE define - remove unused defines Cc: unsik Kim Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/block/mg_disk.c | 144 ++++++++++++---------------------------- 1 file changed, 43 insertions(+), 101 deletions(-) diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 8e53cae9fa90..71e56cc28cac 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -51,51 +51,10 @@ #define MG_REG_DRV_CTRL (MG_REG_OFFSET + 0x10) #define MG_REG_BURST_CTRL (MG_REG_OFFSET + 0x12) -/* "Drive Select/Head Register" bit values */ -#define MG_REG_HEAD_MUST_BE_ON 0xA0 /* These 2 bits are always on */ -#define MG_REG_HEAD_DRIVE_MASTER (0x00 | MG_REG_HEAD_MUST_BE_ON) -#define MG_REG_HEAD_DRIVE_SLAVE (0x10 | MG_REG_HEAD_MUST_BE_ON) -#define MG_REG_HEAD_LBA_MODE (0x40 | MG_REG_HEAD_MUST_BE_ON) - - -/* "Device Control Register" bit values */ -#define MG_REG_CTRL_INTR_ENABLE 0x0 -#define MG_REG_CTRL_INTR_DISABLE (0x1<<1) -#define MG_REG_CTRL_RESET (0x1<<2) -#define MG_REG_CTRL_INTR_POLA_ACTIVE_HIGH 0x0 -#define MG_REG_CTRL_INTR_POLA_ACTIVE_LOW (0x1<<4) -#define MG_REG_CTRL_DPD_POLA_ACTIVE_LOW 0x0 -#define MG_REG_CTRL_DPD_POLA_ACTIVE_HIGH (0x1<<5) -#define MG_REG_CTRL_DPD_DISABLE 0x0 -#define MG_REG_CTRL_DPD_ENABLE (0x1<<6) - -/* Status register bit */ -/* error bit in status register */ -#define MG_REG_STATUS_BIT_ERROR 0x01 -/* corrected error in status register */ -#define MG_REG_STATUS_BIT_CORRECTED_ERROR 0x04 -/* data request bit in status register */ -#define MG_REG_STATUS_BIT_DATA_REQ 0x08 -/* DSC - Drive Seek Complete */ -#define MG_REG_STATUS_BIT_SEEK_DONE 0x10 -/* DWF - Drive Write Fault */ -#define MG_REG_STATUS_BIT_WRITE_FAULT 0x20 -#define MG_REG_STATUS_BIT_READY 0x40 -#define MG_REG_STATUS_BIT_BUSY 0x80 - /* handy status */ -#define MG_STAT_READY (MG_REG_STATUS_BIT_READY | MG_REG_STATUS_BIT_SEEK_DONE) -#define MG_READY_OK(s) (((s) & (MG_STAT_READY | \ - (MG_REG_STATUS_BIT_BUSY | \ - MG_REG_STATUS_BIT_WRITE_FAULT | \ - MG_REG_STATUS_BIT_ERROR))) == MG_STAT_READY) - -/* Error register */ -#define MG_REG_ERR_AMNF 0x01 -#define MG_REG_ERR_ABRT 0x04 -#define MG_REG_ERR_IDNF 0x10 -#define MG_REG_ERR_UNC 0x40 -#define MG_REG_ERR_BBK 0x80 +#define MG_STAT_READY (ATA_DRDY | ATA_DSC) +#define MG_READY_OK(s) (((s) & (MG_STAT_READY | (ATA_BUSY | ATA_DF | \ + ATA_ERR))) == MG_STAT_READY) /* error code for others */ #define MG_ERR_NONE 0 @@ -225,41 +184,39 @@ static void mg_dump_status(const char *msg, unsigned int stat, } printk(KERN_ERR "%s: %s: status=0x%02x { ", name, msg, stat & 0xff); - if (stat & MG_REG_STATUS_BIT_BUSY) + if (stat & ATA_BUSY) printk("Busy "); - if (stat & MG_REG_STATUS_BIT_READY) + if (stat & ATA_DRDY) printk("DriveReady "); - if (stat & MG_REG_STATUS_BIT_WRITE_FAULT) + if (stat & ATA_DF) printk("WriteFault "); - if (stat & MG_REG_STATUS_BIT_SEEK_DONE) + if (stat & ATA_DSC) printk("SeekComplete "); - if (stat & MG_REG_STATUS_BIT_DATA_REQ) + if (stat & ATA_DRQ) printk("DataRequest "); - if (stat & MG_REG_STATUS_BIT_CORRECTED_ERROR) + if (stat & ATA_CORR) printk("CorrectedError "); - if (stat & MG_REG_STATUS_BIT_ERROR) + if (stat & ATA_ERR) printk("Error "); printk("}\n"); - if ((stat & MG_REG_STATUS_BIT_ERROR) == 0) { + if ((stat & ATA_ERR) == 0) { host->error = 0; } else { host->error = inb((unsigned long)host->dev_base + MG_REG_ERROR); printk(KERN_ERR "%s: %s: error=0x%02x { ", name, msg, host->error & 0xff); - if (host->error & MG_REG_ERR_BBK) + if (host->error & ATA_BBK) printk("BadSector "); - if (host->error & MG_REG_ERR_UNC) + if (host->error & ATA_UNC) printk("UncorrectableError "); - if (host->error & MG_REG_ERR_IDNF) + if (host->error & ATA_IDNF) printk("SectorIdNotFound "); - if (host->error & MG_REG_ERR_ABRT) + if (host->error & ATA_ABORTED) printk("DriveStatusError "); - if (host->error & MG_REG_ERR_AMNF) + if (host->error & ATA_AMNF) printk("AddrMarkNotFound "); printk("}"); - if (host->error & - (MG_REG_ERR_BBK | MG_REG_ERR_UNC | - MG_REG_ERR_IDNF | MG_REG_ERR_AMNF)) { + if (host->error & (ATA_BBK | ATA_UNC | ATA_IDNF | ATA_AMNF)) { if (host->breq) { req = elv_next_request(host->breq); if (req) @@ -284,12 +241,12 @@ static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec) do { cur_jiffies = jiffies; - if (status & MG_REG_STATUS_BIT_BUSY) { - if (expect == MG_REG_STATUS_BIT_BUSY) + if (status & ATA_BUSY) { + if (expect == ATA_BUSY) break; } else { /* Check the error condition! */ - if (status & MG_REG_STATUS_BIT_ERROR) { + if (status & ATA_ERR) { mg_dump_status("mg_wait", status, host); break; } @@ -298,8 +255,8 @@ static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec) if (MG_READY_OK(status)) break; - if (expect == MG_REG_STATUS_BIT_DATA_REQ) - if (status & MG_REG_STATUS_BIT_DATA_REQ) + if (expect == ATA_DRQ) + if (status & ATA_DRQ) break; } if (!msec) { @@ -404,12 +361,10 @@ static int mg_get_disk_id(struct mg_host *host) char serial[ATA_ID_SERNO_LEN + 1]; if (!prv_data->use_polling) - outb(MG_REG_CTRL_INTR_DISABLE, - (unsigned long)host->dev_base + - MG_REG_DRV_CTRL); + outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); outb(MG_CMD_ID, (unsigned long)host->dev_base + MG_REG_COMMAND); - err = mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_RD_DRQ); + err = mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_RD_DRQ); if (err) return err; @@ -449,8 +404,7 @@ static int mg_get_disk_id(struct mg_host *host) host->n_sectors, host->nres_sectors); if (!prv_data->use_polling) - outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base + - MG_REG_DRV_CTRL); + outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); return err; } @@ -464,7 +418,7 @@ static int mg_disk_init(struct mg_host *host) /* hdd rst low */ gpio_set_value(host->rst, 0); - err = mg_wait(host, MG_REG_STATUS_BIT_BUSY, MG_TMAX_RST_TO_BUSY); + err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY); if (err) return err; @@ -475,17 +429,14 @@ static int mg_disk_init(struct mg_host *host) return err; /* soft reset on */ - outb(MG_REG_CTRL_RESET | - (prv_data->use_polling ? MG_REG_CTRL_INTR_DISABLE : - MG_REG_CTRL_INTR_ENABLE), + outb(ATA_SRST | (prv_data->use_polling ? ATA_NIEN : 0), (unsigned long)host->dev_base + MG_REG_DRV_CTRL); - err = mg_wait(host, MG_REG_STATUS_BIT_BUSY, MG_TMAX_RST_TO_BUSY); + err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY); if (err) return err; /* soft reset off */ - outb(prv_data->use_polling ? MG_REG_CTRL_INTR_DISABLE : - MG_REG_CTRL_INTR_ENABLE, + outb(prv_data->use_polling ? ATA_NIEN : 0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); err = mg_wait(host, MG_STAT_READY, MG_TMAX_SWRST_TO_RDY); if (err) @@ -531,7 +482,7 @@ static unsigned int mg_out(struct mg_host *host, MG_REG_CYL_LOW); outb((u8)(sect_num >> 16), (unsigned long)host->dev_base + MG_REG_CYL_HIGH); - outb((u8)((sect_num >> 24) | MG_REG_HEAD_LBA_MODE), + outb((u8)((sect_num >> 24) | ATA_LBA | ATA_DEVICE_OBS), (unsigned long)host->dev_base + MG_REG_DRV_HEAD); outb(cmd, (unsigned long)host->dev_base + MG_REG_COMMAND); return MG_ERR_NONE; @@ -552,8 +503,8 @@ static void mg_read(struct request *req) do { u16 *buff = (u16 *)req->buffer; - if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, - MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) { + if (mg_wait(host, ATA_DRQ, + MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) { mg_bad_rw_intr(host); return; } @@ -583,8 +534,7 @@ static void mg_write(struct request *req) do { u16 *buff = (u16 *)req->buffer; - if (mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, - MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) { + if (mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) { mg_bad_rw_intr(host); return; } @@ -606,11 +556,11 @@ static void mg_read_intr(struct mg_host *host) /* check status */ do { i = inb((unsigned long)host->dev_base + MG_REG_STATUS); - if (i & MG_REG_STATUS_BIT_BUSY) + if (i & ATA_BUSY) break; if (!MG_READY_OK(i)) break; - if (i & MG_REG_STATUS_BIT_DATA_REQ) + if (i & ATA_DRQ) goto ok_to_read; } while (0); mg_dump_status("mg_read_intr", i, host); @@ -655,11 +605,11 @@ static void mg_write_intr(struct mg_host *host) /* check status */ do { i = inb((unsigned long)host->dev_base + MG_REG_STATUS); - if (i & MG_REG_STATUS_BIT_BUSY) + if (i & ATA_BUSY) break; if (!MG_READY_OK(i)) break; - if ((req->nr_sectors <= 1) || (i & MG_REG_STATUS_BIT_DATA_REQ)) + if ((req->nr_sectors <= 1) || (i & ATA_DRQ)) goto ok_to_write; } while (0); mg_dump_status("mg_write_intr", i, host); @@ -752,18 +702,15 @@ static unsigned int mg_issue_req(struct request *req, break; case WRITE: /* TODO : handler */ - outb(MG_REG_CTRL_INTR_DISABLE, - (unsigned long)host->dev_base + - MG_REG_DRV_CTRL); + outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); if (mg_out(host, sect_num, sect_cnt, MG_CMD_WR, &mg_write_intr) != MG_ERR_NONE) { mg_bad_rw_intr(host); return host->error; } del_timer(&host->timer); - mg_wait(host, MG_REG_STATUS_BIT_DATA_REQ, MG_TMAX_WAIT_WR_DRQ); - outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base + - MG_REG_DRV_CTRL); + mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ); + outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); if (host->error) { mg_bad_rw_intr(host); return host->error; @@ -849,9 +796,7 @@ static int mg_suspend(struct platform_device *plat_dev, pm_message_t state) return -EIO; if (!prv_data->use_polling) - outb(MG_REG_CTRL_INTR_DISABLE, - (unsigned long)host->dev_base + - MG_REG_DRV_CTRL); + outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); outb(MG_CMD_SLEEP, (unsigned long)host->dev_base + MG_REG_COMMAND); /* wait until mflash deep sleep */ @@ -859,9 +804,7 @@ static int mg_suspend(struct platform_device *plat_dev, pm_message_t state) if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) { if (!prv_data->use_polling) - outb(MG_REG_CTRL_INTR_ENABLE, - (unsigned long)host->dev_base + - MG_REG_DRV_CTRL); + outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); return -EIO; } @@ -884,8 +827,7 @@ static int mg_resume(struct platform_device *plat_dev) return -EIO; if (!prv_data->use_polling) - outb(MG_REG_CTRL_INTR_ENABLE, (unsigned long)host->dev_base + - MG_REG_DRV_CTRL); + outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL); return 0; } -- GitLab From 52fbc1007eb071c40a367462476eee695b412578 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Mon, 27 Apr 2009 19:42:03 +0000 Subject: [PATCH 0833/6080] atl1c: disable L1/L0s when link detected Disable L1/L0s when link detected. We enable L1/L0s when link connected before, but there is some hareware error on some platform. So just diable this feature when link connected. This feature is about power saving. Signed-off-by: Jie Yang Signed-off-by: David S. Miller --- drivers/net/atl1c/atl1c_main.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index deb7b53167ee..8b17278c4a58 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -220,11 +220,11 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) /* 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"); + atl1c_set_aspm(hw, false); } netif_carrier_off(netdev); } else { @@ -240,10 +240,10 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) adapter->link_duplex != duplex) { adapter->link_speed = speed; adapter->link_duplex = duplex; + atl1c_set_aspm(hw, true); 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", @@ -1242,9 +1242,7 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup) 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_SERDES_PD_EX_L1; pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << PM_CTRL_L1_ENTRY_TIMER_SHIFT); @@ -1254,19 +1252,11 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool 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; - + pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN; + pm_ctrl_data |= PM_CTRL_SERDES_L1_EN; } else { + pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN; + pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN; pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN; -- GitLab From 833cc67c7722e35863c6aaee9df56b442ef957ae Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 27 Apr 2009 21:32:16 +0000 Subject: [PATCH 0834/6080] smsc911x: add fifo byteswap support V2 This is V2 of the smsc911x fifo byteswap patch. The smsc911x hardware supports both big and little and endian hardware configurations, and the linux smsc911x driver currently detects word order. For correct operation on big endian platforms lacking swapped byte lanes the following patch is needed. Only fifo data is swapped, register data does not require any swapping. Signed-off-by: Magnus Damm Acked-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/smsc911x.c | 13 +++++++++++++ include/linux/smsc911x.h | 10 ++++++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index eb7db032a780..5113b26fc2d9 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include "smsc911x.h" @@ -175,6 +176,12 @@ static inline void smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf, unsigned int wordcount) { + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { + while (wordcount--) + smsc911x_reg_write(pdata, TX_DATA_FIFO, swab32(*buf++)); + return; + } + if (pdata->config.flags & SMSC911X_USE_32BIT) { writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount); return; @@ -194,6 +201,12 @@ static inline void smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf, unsigned int wordcount) { + if (pdata->config.flags & SMSC911X_SWAP_FIFO) { + while (wordcount--) + *buf++ = swab32(smsc911x_reg_read(pdata, RX_DATA_FIFO)); + return; + } + if (pdata->config.flags & SMSC911X_USE_32BIT) { readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount); return; diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h index b32725075d71..5241e4fb4eca 100644 --- a/include/linux/smsc911x.h +++ b/include/linux/smsc911x.h @@ -47,4 +47,14 @@ struct smsc911x_platform_config { #define SMSC911X_FORCE_EXTERNAL_PHY (BIT(3)) #define SMSC911X_SAVE_MAC_ADDRESS (BIT(4)) +/* + * SMSC911X_SWAP_FIFO: + * Enables software byte swap for fifo data. Should only be used as a + * "last resort" in the case of big endian mode on boards with incorrectly + * routed data bus to older devices such as LAN9118. Newer devices such as + * LAN9221 can handle this in hardware, there are registers to control + * this swapping but the driver doesn't currently use them. + */ +#define SMSC911X_SWAP_FIFO (BIT(5)) + #endif /* __LINUX_SMSC911X_H__ */ -- GitLab From 3935358ebcb8320965478c0e8ee070e1d65851c8 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Mon, 27 Apr 2009 22:34:54 +0000 Subject: [PATCH 0835/6080] igb: reconfigure mailbox timeout logic This change updates the timeout logic so that it is not possible to have a sucessful check for message and still return an error if countdown = 0. Signed-off-by: Alexander Duyck Reported-by: Juha Leppanen Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/e1000_mbx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c index 840782fb5736..ed9058eca45c 100644 --- a/drivers/net/igb/e1000_mbx.c +++ b/drivers/net/igb/e1000_mbx.c @@ -140,13 +140,13 @@ static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id) struct e1000_mbx_info *mbx = &hw->mbx; int countdown = mbx->timeout; - if (!mbx->ops.check_for_msg) + if (!countdown || !mbx->ops.check_for_msg) goto out; while (mbx->ops.check_for_msg(hw, mbx_id)) { + countdown--; if (!countdown) break; - countdown--; udelay(mbx->usec_delay); } out: @@ -165,13 +165,13 @@ static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id) struct e1000_mbx_info *mbx = &hw->mbx; int countdown = mbx->timeout; - if (!mbx->ops.check_for_ack) + if (!countdown || !mbx->ops.check_for_ack) goto out; while (mbx->ops.check_for_ack(hw, mbx_id)) { + countdown--; if (!countdown) break; - countdown--; udelay(mbx->usec_delay); } out: -- GitLab From 2844f7975837d47fe7f20aa96c1df3bcecf91935 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Mon, 27 Apr 2009 22:35:14 +0000 Subject: [PATCH 0836/6080] igb: make rxcsum configuration seperate from multiqueue The igb driver was being incorrectly setup to only allow disabling receive checksum if multiqueue was disabled. This change corrects that so that RXCSUM is configured regardless of queue configuration. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/e1000_defines.h | 2 +- drivers/net/igb/igb_main.c | 30 +++++++++++------------------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index ad2d319d0f8b..65acbbaca2d5 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -289,8 +289,8 @@ #define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 /* Receive Checksum Control */ +#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ -#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ #define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ /* Header split receive */ diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index ab846ec65204..4ecf4dfce9bd 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2236,29 +2236,21 @@ static void igb_configure_rx(struct igb_adapter *adapter) mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX | E1000_MRQC_RSS_FIELD_IPV6_TCP_EX); - wr32(E1000_MRQC, mrqc); - - /* Multiqueue and raw packet checksumming are mutually - * exclusive. Note that this not the same as TCP/IP - * checksumming, which works fine. */ - rxcsum = rd32(E1000_RXCSUM); - rxcsum |= E1000_RXCSUM_PCSD; - wr32(E1000_RXCSUM, rxcsum); - } else { + } else if (adapter->vfs_allocated_count) { /* Enable multi-queue for sr-iov */ - if (adapter->vfs_allocated_count) - wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ); - /* Enable Receive Checksum Offload for TCP and UDP */ - rxcsum = rd32(E1000_RXCSUM); - if (adapter->rx_csum) - rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE; - else - rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE); - - wr32(E1000_RXCSUM, rxcsum); + wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ); } + /* Enable Receive Checksum Offload for TCP and UDP */ + rxcsum = rd32(E1000_RXCSUM); + /* Disable raw packet checksumming */ + rxcsum |= E1000_RXCSUM_PCSD; + /* Don't need to set TUOFL or IPOFL, they default to 1 */ + if (!adapter->rx_csum) + rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL); + wr32(E1000_RXCSUM, rxcsum); + /* Set the default pool for the PF's first queue */ igb_configure_vt_default_pool(adapter); -- GitLab From 182ff8dfdb63e66ca81e4d3a4c746f8d578e5687 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Mon, 27 Apr 2009 22:35:33 +0000 Subject: [PATCH 0837/6080] igb/ixgbe: remove unecessary checks for CHECKSUM_UNNECESSARY Both of these drivers do a check to verify ip_summed is set to CHECKSUM_UNNECESSARY prior to passing the packet to GRO. GRO itself already does such a check so it is redundant and can be removed as this will likely cause out of order issues when receiving a packet that didn't pass checksum validation. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 20 ++++++-------------- drivers/net/ixgbe/ixgbe_main.c | 17 +++++------------ 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 4ecf4dfce9bd..f7f861215242 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -4430,20 +4430,12 @@ static void igb_receive_skb(struct igb_ring *ring, u8 status, bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP)); skb_record_rx_queue(skb, ring->queue_index); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { - if (vlan_extracted) - vlan_gro_receive(&ring->napi, adapter->vlgrp, - le16_to_cpu(rx_desc->wb.upper.vlan), - skb); - else - napi_gro_receive(&ring->napi, skb); - } else { - if (vlan_extracted) - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - le16_to_cpu(rx_desc->wb.upper.vlan)); - else - netif_receive_skb(skb); - } + if (vlan_extracted) + vlan_gro_receive(&ring->napi, adapter->vlgrp, + le16_to_cpu(rx_desc->wb.upper.vlan), + skb); + else + napi_gro_receive(&ring->napi, skb); } static inline void igb_rx_checksum_adv(struct igb_adapter *adapter, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c45e4e7999ea..42b803d5cfd3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -459,23 +459,16 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); skb_record_rx_queue(skb, q_vector - &adapter->q_vector[0]); - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { if (adapter->vlgrp && is_vlan && (tag != 0)) vlan_gro_receive(napi, adapter->vlgrp, tag, skb); else napi_gro_receive(napi, skb); } else { - if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { - if (adapter->vlgrp && is_vlan && (tag != 0)) - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, tag); - else - netif_receive_skb(skb); - } else { - if (adapter->vlgrp && is_vlan && (tag != 0)) - vlan_hwaccel_rx(skb, adapter->vlgrp, tag); - else - netif_rx(skb); - } + if (adapter->vlgrp && is_vlan && (tag != 0)) + vlan_hwaccel_rx(skb, adapter->vlgrp, tag); + else + netif_rx(skb); } } -- GitLab From 8dc92f7e2ecfd93f5c57da78594a7a5482e2c15e Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Mon, 27 Apr 2009 22:35:52 +0000 Subject: [PATCH 0838/6080] sctp: add feature bit for SCTP offload in hardware this is the sctp code to enable hardware crc32c offload for adapters that support it. Originally by: Vlad Yasevich modified by Jesse Brandeburg Signed-off-by: Jesse Brandeburg Signed-off-by: Vlad Yasevich Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 ++ net/sctp/output.c | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index fe20d171acf1..f8c3619d551f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -670,7 +670,9 @@ struct net_device #define NETIF_F_GRO 16384 /* Generic receive offload */ #define NETIF_F_LRO 32768 /* large receive offload */ +/* the GSO_MASK reserves bits 16 through 23 */ #define NETIF_F_FCOE_CRC (1 << 24) /* FCoE CRC32 */ +#define NETIF_F_SCTP_CSUM (1 << 25) /* SCTP checksum offload */ /* Segmentation offload features */ #define NETIF_F_GSO_SHIFT 16 diff --git a/net/sctp/output.c b/net/sctp/output.c index 7d08f522ec84..f0c91df59d4e 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -412,6 +412,7 @@ int sctp_packet_transmit(struct sctp_packet *packet) /* Build the SCTP header. */ sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr)); + skb_reset_transport_header(nskb); sh->source = htons(packet->source_port); sh->dest = htons(packet->destination_port); @@ -527,15 +528,25 @@ int sctp_packet_transmit(struct sctp_packet *packet) * Note: Adler-32 is no longer applicable, as has been replaced * by CRC32-C as described in . */ - if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) { + if (!sctp_checksum_disable && + !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) { __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); /* 3) Put the resultant value into the checksum field in the * common header, and leave the rest of the bits unchanged. */ sh->checksum = sctp_end_cksum(crc32); - } else - nskb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + if (dst->dev->features & NETIF_F_SCTP_CSUM) { + /* no need to seed psuedo checksum for SCTP */ + nskb->ip_summed = CHECKSUM_PARTIAL; + nskb->csum_start = (skb_transport_header(nskb) - + nskb->head); + nskb->csum_offset = offsetof(struct sctphdr, checksum); + } else { + nskb->ip_summed = CHECKSUM_UNNECESSARY; + } + } /* IP layer ECN support * From RFC 2481 -- GitLab From b9473560c6d882e0fbd3a8817e906c847b11c722 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Mon, 27 Apr 2009 22:36:13 +0000 Subject: [PATCH 0839/6080] igb: Enable SCTP checksum offloading Originally from: Vlad Yasevich This patch, both the driver portion and the sctp code was modified by Jesse Brandeburg and is Copyright(c) 2009 Intel Corporation. Thanks go to Vlad for starting this work. Intel 82576 chipset supports SCTP checksum offloading. This patch enables this functionality in the driver. A new NETIF feature is introduced for SCTP checksum offload. If the driver supports CRC32c checksum, it can set this feature flag. The hardware can offload both transmit and receive. Signed-off-by: Jesse Brandeburg Signed-off-by: Vlad Yasevich Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/e1000_82575.h | 1 + drivers/net/igb/e1000_defines.h | 1 + drivers/net/igb/igb_ethtool.c | 12 +++++++++--- drivers/net/igb/igb_main.c | 21 ++++++++++++++++++++- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h index eaf977050368..0f16abab2565 100644 --- a/drivers/net/igb/e1000_82575.h +++ b/drivers/net/igb/e1000_82575.h @@ -130,6 +130,7 @@ struct e1000_adv_tx_context_desc { #define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ #define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ #define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ +#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 packet TYPE of SCTP */ /* IPSec Encrypt Enable for ESP */ #define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ #define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 65acbbaca2d5..3bda3db73f1f 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -291,6 +291,7 @@ /* Receive Checksum Control */ #define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ +#define E1000_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */ #define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ /* Header split receive */ diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 27eae49e79c2..b1367ce6586e 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -293,10 +293,16 @@ static u32 igb_get_tx_csum(struct net_device *netdev) static int igb_set_tx_csum(struct net_device *netdev, u32 data) { - if (data) + struct igb_adapter *adapter = netdev_priv(netdev); + + if (data) { netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); - else - netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + if (adapter->hw.mac.type == e1000_82576) + netdev->features |= NETIF_F_SCTP_CSUM; + } else { + netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_SCTP_CSUM); + } return 0; } diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index f7f861215242..bca7e9f76be4 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1345,6 +1345,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; + if (adapter->hw.mac.type == e1000_82576) + netdev->features |= NETIF_F_SCTP_CSUM; + adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw); /* before reading the NVM, reset the controller to put the device in a @@ -2249,6 +2252,10 @@ static void igb_configure_rx(struct igb_adapter *adapter) /* Don't need to set TUOFL or IPOFL, they default to 1 */ if (!adapter->rx_csum) rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL); + else if (adapter->hw.mac.type == e1000_82576) + /* Enable Receive Checksum Offload for SCTP */ + rxcsum |= E1000_RXCSUM_CRCOFL; + wr32(E1000_RXCSUM, rxcsum); /* Set the default pool for the PF's first queue */ @@ -3064,11 +3071,15 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter, tu_cmd |= E1000_ADVTXD_TUCMD_IPV4; if (ip_hdr(skb)->protocol == IPPROTO_TCP) tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + else if (ip_hdr(skb)->protocol == IPPROTO_SCTP) + tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP; break; case cpu_to_be16(ETH_P_IPV6): /* XXX what about other V6 headers?? */ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP) + tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP; break; default: if (unlikely(net_ratelimit())) @@ -4449,14 +4460,22 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter, /* TCP/UDP checksum error bit is set */ if (status_err & (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) { + /* + * work around errata with sctp packets where the TCPE aka + * L4E bit is set incorrectly on 64 byte (60 byte w/o crc) + * packets, (aka let the stack check the crc32c) + */ + if (!((adapter->hw.mac.type == e1000_82576) && + (skb->len == 60))) + adapter->hw_csum_err++; /* let the stack verify checksum errors */ - adapter->hw_csum_err++; return; } /* It must be a TCP or UDP packet with a valid checksum */ if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)) skb->ip_summed = CHECKSUM_UNNECESSARY; + dev_dbg(&adapter->pdev->dev, "cksum success: bits %08X\n", status_err); adapter->hw_csum_good++; } -- GitLab From 45a5ead0220cc7cc70f6961879decffbd0a54cc0 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Mon, 27 Apr 2009 22:36:35 +0000 Subject: [PATCH 0840/6080] ixgbe: enable hardware offload for sctp Inspired by: Vlad Yasevich This is the code to enable ixgbe for hardware offload support of CRC32c on both transmit and receive of SCTP traffic. only 82599 supports this offload, not 82598. Signed-off-by: Jesse Brandeburg Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_ethtool.c | 11 +++++++++-- drivers/net/ixgbe/ixgbe_main.c | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index f0a20facc650..a499b6b31ca2 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -311,10 +311,17 @@ static u32 ixgbe_get_tx_csum(struct net_device *netdev) static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) { - if (data) + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + if (data) { netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); - else + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + netdev->features |= NETIF_F_SCTP_CSUM; + } else { netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + netdev->features &= ~NETIF_F_SCTP_CSUM; + } return 0; } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 42b803d5cfd3..c3dff8f02e33 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4189,12 +4189,18 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, if (ip_hdr(skb)->protocol == IPPROTO_TCP) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + else if (ip_hdr(skb)->protocol == IPPROTO_SCTP) + type_tucmd_mlhl |= + IXGBE_ADVTXD_TUCMD_L4T_SCTP; break; case cpu_to_be16(ETH_P_IPV6): /* XXX what about other V6 headers?? */ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP) + type_tucmd_mlhl |= + IXGBE_ADVTXD_TUCMD_L4T_SCTP; break; default: if (unlikely(net_ratelimit())) { @@ -4718,6 +4724,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_TSO6; netdev->features |= NETIF_F_GRO; + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + netdev->features |= NETIF_F_SCTP_CSUM; + netdev->vlan_features |= NETIF_F_TSO; netdev->vlan_features |= NETIF_F_TSO6; netdev->vlan_features |= NETIF_F_IP_CSUM; -- GitLab From f8212f979f777af2a8e3a9deb0c11a9fcf35e305 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Mon, 27 Apr 2009 22:42:37 +0000 Subject: [PATCH 0841/6080] ixgbe: enable HW RSC for 82599 This patch enables hardware receive side coalescing for 82599 hardware. 82599 can merge multiple frames from the same TCP/IP flow into a single structure that can span one ore more descriptors. The accumulated data is arranged similar to how jumbo frames are arranged with the exception that other packets can be interlaced inbetween. To overcome this issue a next pointer is included in the written back descriptor which indicates the next descriptor in the writeback sequence. This feature sets the NETIF_F_LRO flag and clearing it via the ethtool set flags operation will also disable hardware RSC. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 4 + drivers/net/ixgbe/ixgbe_ethtool.c | 24 +++++- drivers/net/ixgbe/ixgbe_main.c | 121 +++++++++++++++++++++++++++--- drivers/net/ixgbe/ixgbe_type.h | 15 ++++ 4 files changed, 152 insertions(+), 12 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index c26433d14605..4b44a8efac8c 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -147,6 +147,7 @@ struct ixgbe_ring { u16 work_limit; /* max work per interrupt */ u16 rx_buf_len; + u64 rsc_count; /* stat for coalesced packets */ }; enum ixgbe_ring_f_enum { @@ -294,6 +295,8 @@ struct ixgbe_adapter { #define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23) #define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 24) #define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25) +#define IXGBE_FLAG_RSC_CAPABLE (u32)(1 << 26) +#define IXGBE_FLAG_RSC_ENABLED (u32)(1 << 27) /* default to trying for four seconds */ #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) @@ -325,6 +328,7 @@ struct ixgbe_adapter { struct timer_list sfp_timer; struct work_struct multispeed_fiber_task; struct work_struct sfp_config_module_task; + u64 rsc_count; u32 wol; u16 eeprom_version; }; diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index a499b6b31ca2..d822c92058c3 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -67,6 +67,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { {"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)}, {"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)}, {"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)}, + {"hw_rsc_count", IXGBE_STAT(rsc_count)}, {"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)}, {"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)}, {"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)}, @@ -1127,6 +1128,27 @@ static int ixgbe_set_coalesce(struct net_device *netdev, return 0; } +static int ixgbe_set_flags(struct net_device *netdev, u32 data) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + ethtool_op_set_flags(netdev, data); + + if (!(adapter->flags & IXGBE_FLAG_RSC_CAPABLE)) + return 0; + + /* if state changes we need to update adapter->flags and reset */ + if ((!!(data & ETH_FLAG_LRO)) != + (!!(adapter->flags & IXGBE_FLAG_RSC_ENABLED))) { + adapter->flags ^= IXGBE_FLAG_RSC_ENABLED; + if (netif_running(netdev)) + ixgbe_reinit_locked(adapter); + else + ixgbe_reset(adapter); + } + return 0; + +} static const struct ethtool_ops ixgbe_ethtool_ops = { .get_settings = ixgbe_get_settings, @@ -1161,7 +1183,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = { .get_coalesce = ixgbe_get_coalesce, .set_coalesce = ixgbe_set_coalesce, .get_flags = ethtool_op_get_flags, - .set_flags = ethtool_op_set_flags, + .set_flags = ixgbe_set_flags, }; void ixgbe_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c3dff8f02e33..419ce472cef8 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -615,6 +615,40 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc) return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; } +static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc) +{ + return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) & + IXGBE_RXDADV_RSCCNT_MASK) >> + IXGBE_RXDADV_RSCCNT_SHIFT; +} + +/** + * ixgbe_transform_rsc_queue - change rsc queue into a full packet + * @skb: pointer to the last skb in the rsc queue + * + * This function changes a queue full of hw rsc buffers into a completed + * packet. It uses the ->prev pointers to find the first packet and then + * turns it into the frag list owner. + **/ +static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb) +{ + unsigned int frag_list_size = 0; + + while (skb->prev) { + struct sk_buff *prev = skb->prev; + frag_list_size += skb->len; + skb->prev = NULL; + skb = prev; + } + + skb_shinfo(skb)->frag_list = skb->next; + skb->next = NULL; + skb->len += frag_list_size; + skb->data_len += frag_list_size; + skb->truesize += frag_list_size; + return skb; +} + static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, struct ixgbe_ring *rx_ring, int *work_done, int work_to_do) @@ -624,7 +658,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, union ixgbe_adv_rx_desc *rx_desc, *next_rxd; struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer; struct sk_buff *skb; - unsigned int i; + unsigned int i, rsc_count = 0; u32 len, staterr; u16 hdr_info; bool cleaned = false; @@ -690,20 +724,38 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, i++; if (i == rx_ring->count) i = 0; - next_buffer = &rx_ring->rx_buffer_info[i]; next_rxd = IXGBE_RX_DESC_ADV(*rx_ring, i); prefetch(next_rxd); - cleaned_count++; + + if (adapter->flags & IXGBE_FLAG_RSC_CAPABLE) + rsc_count = ixgbe_get_rsc_count(rx_desc); + + if (rsc_count) { + u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >> + IXGBE_RXDADV_NEXTP_SHIFT; + next_buffer = &rx_ring->rx_buffer_info[nextp]; + rx_ring->rsc_count += (rsc_count - 1); + } else { + next_buffer = &rx_ring->rx_buffer_info[i]; + } + if (staterr & IXGBE_RXD_STAT_EOP) { + if (skb->prev) + skb = ixgbe_transform_rsc_queue(skb); rx_ring->stats.packets++; rx_ring->stats.bytes += skb->len; } else { - rx_buffer_info->skb = next_buffer->skb; - rx_buffer_info->dma = next_buffer->dma; - next_buffer->skb = skb; - next_buffer->dma = 0; + if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { + rx_buffer_info->skb = next_buffer->skb; + rx_buffer_info->dma = next_buffer->dma; + next_buffer->skb = skb; + next_buffer->dma = 0; + } else { + skb->next = next_buffer->skb; + skb->next->prev = skb; + } adapter->non_eop_descs++; goto next_desc; } @@ -733,7 +785,7 @@ next_desc: /* use prefetched values */ rx_desc = next_rxd; - rx_buffer_info = next_buffer; + rx_buffer_info = &rx_ring->rx_buffer_info[i]; staterr = le32_to_cpu(rx_desc->wb.upper.status_error); } @@ -1729,6 +1781,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) u32 fctrl, hlreg0; u32 reta = 0, mrqc = 0; u32 rdrxctl; + u32 rscctrl; int rx_buf_len; /* Decide whether to use packet split mode or not */ @@ -1746,7 +1799,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype); } } else { - if (netdev->mtu <= ETH_DATA_LEN) + if (!(adapter->flags & IXGBE_FLAG_RSC_ENABLED) && + (netdev->mtu <= ETH_DATA_LEN)) rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; else rx_buf_len = ALIGN(max_frame, 1024); @@ -1868,8 +1922,38 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) if (hw->mac.type == ixgbe_mac_82599EB) { rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; + rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); } + + if (adapter->flags & IXGBE_FLAG_RSC_ENABLED) { + /* Enable 82599 HW-RSC */ + for (i = 0; i < adapter->num_rx_queues; i++) { + j = adapter->rx_ring[i].reg_idx; + rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j)); + rscctrl |= IXGBE_RSCCTL_RSCEN; + /* + * if packet split is enabled we can only support up + * to max frags + 1 descriptors. + */ + if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) +#if (MAX_SKB_FRAGS < 3) + rscctrl |= IXGBE_RSCCTL_MAXDESC_1; +#elif (MAX_SKB_FRAGS < 7) + rscctrl |= IXGBE_RSCCTL_MAXDESC_4; +#elif (MAX_SKB_FRAGS < 15) + rscctrl |= IXGBE_RSCCTL_MAXDESC_8; +#else + rscctrl |= IXGBE_RSCCTL_MAXDESC_16; +#endif + else + rscctrl |= IXGBE_RSCCTL_MAXDESC_16; + IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl); + } + /* Disable RSC for ACK packets */ + IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, + (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); + } } static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) @@ -2438,8 +2522,13 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, rx_buffer_info->dma = 0; } if (rx_buffer_info->skb) { - dev_kfree_skb(rx_buffer_info->skb); + struct sk_buff *skb = rx_buffer_info->skb; rx_buffer_info->skb = NULL; + do { + struct sk_buff *this = skb; + skb = skb->prev; + dev_kfree_skb(this); + } while (skb); } if (!rx_buffer_info->page) continue; @@ -3180,8 +3269,11 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES; if (hw->mac.type == ixgbe_mac_82598EB) adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598; - else if (hw->mac.type == ixgbe_mac_82599EB) + else if (hw->mac.type == ixgbe_mac_82599EB) { adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; + adapter->flags |= IXGBE_FLAG_RSC_CAPABLE; + adapter->flags |= IXGBE_FLAG_RSC_ENABLED; + } #ifdef CONFIG_IXGBE_DCB /* Configure DCB traffic classes */ @@ -3765,9 +3857,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot; if (hw->mac.type == ixgbe_mac_82599EB) { + u64 rsc_count = 0; for (i = 0; i < 16; i++) adapter->hw_rx_no_dma_resources += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + for (i = 0; i < adapter->num_rx_queues; i++) + rsc_count += adapter->rx_ring[i].rsc_count; + adapter->rsc_count = rsc_count; } adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); @@ -4742,6 +4838,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; + if (adapter->flags & IXGBE_FLAG_RSC_ENABLED) + netdev->features |= NETIF_F_LRO; + /* make sure the EEPROM is good */ if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) { dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n"); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 375f0d4ad965..bdfdf3bca273 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -443,6 +443,21 @@ #define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE 0x4 +/* HW RSC registers */ +#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \ + (0x0D02C + ((_i - 64) * 0x40))) +#define IXGBE_RSCDBU 0x03028 +#define IXGBE_RSCCTL_RSCEN 0x01 +#define IXGBE_RSCCTL_MAXDESC_1 0x00 +#define IXGBE_RSCCTL_MAXDESC_4 0x04 +#define IXGBE_RSCCTL_MAXDESC_8 0x08 +#define IXGBE_RSCCTL_MAXDESC_16 0x0C +#define IXGBE_RXDADV_RSCCNT_SHIFT 17 +#define IXGBE_GPIE_RSC_DELAY_SHIFT 11 +#define IXGBE_RXDADV_RSCCNT_MASK 0x001E0000 +#define IXGBE_RSCDBU_RSCACKDIS 0x00000080 +#define IXGBE_RDRXCTL_RSCFRSTSIZE 0x003E0000 + /* DCB registers */ #define IXGBE_RTRPCS 0x02430 #define IXGBE_RTTDCS 0x04900 -- GitLab From 835462fc5d69adc948e8afb2073264888aaa0e2f Mon Sep 17 00:00:00 2001 From: "Nelson, Shannon" Date: Mon, 27 Apr 2009 22:42:54 +0000 Subject: [PATCH 0842/6080] ixgbe: Interrupt management update for 82599 Update the interrupt management to correctly handle greater than 16 queue vectors. Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 90 +++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 419ce472cef8..6c90b6801cbd 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -326,8 +326,18 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter, } /* re-arm the interrupt */ - if (count >= tx_ring->work_limit) - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->v_idx); + if (count >= tx_ring->work_limit) { + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, + tx_ring->v_idx); + else if (tx_ring->v_idx & 0xFFFFFFFF) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), + tx_ring->v_idx); + else + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), + (tx_ring->v_idx >> 32)); + } + tx_ring->total_bytes += total_bytes; tx_ring->total_packets += total_packets; @@ -1166,7 +1176,13 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); rx_ring = &(adapter->rx_ring[r_idx]); /* disable interrupts on this vector only */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx); + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx); + else if (rx_ring->v_idx & 0xFFFFFFFF) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), rx_ring->v_idx); + else + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), + (rx_ring->v_idx >> 32)); napi_schedule(&q_vector->napi); return IRQ_HANDLED; @@ -1180,6 +1196,23 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) return IRQ_HANDLED; } +static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, + u64 qmask) +{ + u32 mask; + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + mask = (IXGBE_EIMS_RTX_QUEUE & qmask); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); + } else { + mask = (qmask & 0xFFFFFFFF); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(0), mask); + mask = (qmask >> 32); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask); + } + /* skip the flush */ +} + /** * ixgbe_clean_rxonly - msix (aka one shot) rx clean routine * @napi: napi struct with our devices info in it @@ -1212,7 +1245,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) if (adapter->itr_setting & 1) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx); + ixgbe_irq_enable_queues(adapter, rx_ring->v_idx); } return work_done; @@ -1234,7 +1267,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget) struct ixgbe_ring *rx_ring = NULL; int work_done = 0, i; long r_idx; - u16 enable_mask = 0; + u64 enable_mask = 0; /* attempt to distribute budget to each queue fairly, but don't allow * the budget to go below 1 because we'll exit polling */ @@ -1261,7 +1294,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget) if (adapter->itr_setting & 1) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask); + ixgbe_irq_enable_queues(adapter, enable_mask); return 0; } @@ -1481,7 +1514,8 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) { u32 mask; - mask = IXGBE_EIMS_ENABLE_MASK; + + mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) mask |= IXGBE_EIMS_GPI_SDP1; if (adapter->hw.mac.type == ixgbe_mac_82599EB) { @@ -1491,14 +1525,7 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) } IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - /* enable the rest of the queue vectors */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), - (IXGBE_EIMS_RTX_QUEUE << 16)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2), - ((IXGBE_EIMS_RTX_QUEUE << 16) | - IXGBE_EIMS_RTX_QUEUE)); - } + ixgbe_irq_enable_queues(adapter, ~0); IXGBE_WRITE_FLUSH(&adapter->hw); } @@ -1622,10 +1649,12 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) **/ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) { - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + if (adapter->hw.mac.type == ixgbe_mac_82598EB) { + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0); + } else { + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000); + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0); } IXGBE_WRITE_FLUSH(&adapter->hw); if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { @@ -1637,18 +1666,6 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter) } } -static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter) -{ - u32 mask = IXGBE_EIMS_RTX_QUEUE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask << 16); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2), - (mask << 16 | mask)); - } - /* skip the flush */ -} - /** * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts * @@ -2714,7 +2731,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) if (adapter->itr_setting & 1) ixgbe_set_itr(adapter); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable_queues(adapter); + ixgbe_irq_enable_queues(adapter, IXGBE_EIMS_RTX_QUEUE); } return work_done; } @@ -4005,16 +4022,9 @@ static void ixgbe_watchdog(unsigned long data) break; case ixgbe_mac_82599EB: if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - /* - * EICS(0..15) first 0-15 q vectors - * EICS[1] (16..31) q vectors 16-31 - * EICS[2] (0..31) q vectors 32-63 - */ - IXGBE_WRITE_REG(hw, IXGBE_EICS, - (u32)(eics & 0xFFFF)); + IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(0), + (u32)(eics & 0xFFFFFFFF)); IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(1), - (u32)(eics & 0xFFFF0000)); - IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(2), (u32)(eics >> 32)); } else { /* -- GitLab From bc59fcda671ee15362986a902bbd90e218fe84c4 Mon Sep 17 00:00:00 2001 From: "Nelson, Shannon" Date: Mon, 27 Apr 2009 22:43:12 +0000 Subject: [PATCH 0843/6080] ixgbe: Clear out stray tx work on link down Ayyappan at VMware noticed that we're missing this check from ixgbe which is in our other drivers. The difference with this implementation from our other drivers is that this checks all the tx queues rather than just tx[0]. Signed-off-by: Shannon Nelson Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 6c90b6801cbd..5020f11ae10f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4110,6 +4110,9 @@ static void ixgbe_watchdog_task(struct work_struct *work) struct ixgbe_hw *hw = &adapter->hw; u32 link_speed = adapter->link_speed; bool link_up = adapter->link_up; + int i; + struct ixgbe_ring *tx_ring; + int some_tx_pending = 0; adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK; @@ -4167,6 +4170,25 @@ static void ixgbe_watchdog_task(struct work_struct *work) } } + if (!netif_carrier_ok(netdev)) { + for (i = 0; i < adapter->num_tx_queues; i++) { + tx_ring = &adapter->tx_ring[i]; + if (tx_ring->next_to_use != tx_ring->next_to_clean) { + some_tx_pending = 1; + break; + } + } + + if (some_tx_pending) { + /* We've lost link, so the controller stops DMA, + * but we've got queued Tx work that's never going + * to get done, so reset controller to flush Tx. + * (Do the reset outside of interrupt context). + */ + schedule_work(&adapter->reset_task); + } + } + ixgbe_update_stats(adapter); adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK; } -- GitLab From 5b644c7a218702668d7b610994e7dcbc3d4705d3 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 28 Apr 2009 08:17:54 +0000 Subject: [PATCH 0844/6080] clocksource: improve sh_cmt clocksource overflow handling This patch improves the sh_cmt clocksource handling. Currently the counter value is ignored in the case of overflow. With this patch the overflow flag is read before and after reading the counter, removing any counter value and overflow flag mismatch issues. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index c24756489612..d607ac2d516b 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -111,16 +111,21 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, int *has_wrapped) { unsigned long v1, v2, v3; + int o1, o2; + + o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; /* Make sure the timer value is stable. Stolen from acpi_pm.c */ do { + o2 = o1; v1 = sh_cmt_read(p, CMCNT); v2 = sh_cmt_read(p, CMCNT); v3 = sh_cmt_read(p, CMCNT); - } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) - || (v3 > v1 && v3 < v2))); + o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; + } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3) + || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2))); - *has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit; + *has_wrapped = o1; return v2; } @@ -394,7 +399,7 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) raw = sh_cmt_get_counter(p, &has_wrapped); if (unlikely(has_wrapped)) - raw = p->match_value; + raw += p->match_value; spin_unlock_irqrestore(&p->lock, flags); return value + raw; -- GitLab From 8e0b842948156e3463879caed12b4ce51bed772e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 28 Apr 2009 08:19:50 +0000 Subject: [PATCH 0845/6080] sh: setup timers in late_time_init() This patch moves the SuperH timer setup code from time_init() to late_time_init(). Good things about this change: - interrupts: they are enabled at late_time_init() - mm: regular kmalloc() can be used at late_time_init() Together with moving to late_time_init() this patch changes the sh_cmt driver to always allocate with kmalloc(). This simplifies the code a bit and also fixes section mismatches. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/time_32.c | 34 ++++++++++++++++++++-------------- drivers/clocksource/sh_cmt.c | 13 ++----------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c index 109409f5ca53..a2458bfdda26 100644 --- a/arch/sh/kernel/time_32.c +++ b/arch/sh/kernel/time_32.c @@ -237,21 +237,8 @@ unsigned long long sched_clock(void) } #endif -void __init time_init(void) +static void __init sh_late_time_init(void) { - if (board_time_init) - board_time_init(); - - clk_init(); - - rtc_sh_get_time(&xtime); - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); - -#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST - local_timer_setup(smp_processor_id()); -#endif - /* * Make sure all compiled-in early timers register themselves. * Run probe() for one "earlytimer" device. @@ -270,3 +257,22 @@ void __init time_init(void) printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); } + +void __init time_init(void) +{ + if (board_time_init) + board_time_init(); + + clk_init(); + + rtc_sh_get_time(&xtime); + set_normalized_timespec(&wall_to_monotonic, + -xtime.tv_sec, -xtime.tv_nsec); + +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST + local_timer_setup(smp_processor_id()); +#endif + + late_time_init = sh_late_time_init; +} + diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index d607ac2d516b..bf3e4c11fd37 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include @@ -645,11 +644,7 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev) return 0; } - if (is_early_platform_device(pdev)) - p = alloc_bootmem(sizeof(*p)); - else - p = kmalloc(sizeof(*p), GFP_KERNEL); - + p = kmalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) { dev_err(&pdev->dev, "failed to allocate driver data\n"); return -ENOMEM; @@ -657,11 +652,7 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev) ret = sh_cmt_setup(p, pdev); if (ret) { - if (is_early_platform_device(pdev)) - free_bootmem(__pa(p), sizeof(*p)); - else - kfree(p); - + kfree(p); platform_set_drvdata(pdev, NULL); } return ret; -- GitLab From 1d58ea30b141c95bd21fb39021d4b602f48b30be Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 28 Apr 2009 02:05:21 -0700 Subject: [PATCH 0846/6080] fs_enet: Remove dead code CONFIG_DUET doesn't exist anymore, remove all the code that exists to support it. [ Simplify fs_init() even further -DaveM ] Signed-off-by: Kumar Gala Signed-off-by: David S. Miller --- drivers/net/fs_enet/fs_enet-main.c | 39 +----------------------------- drivers/net/fs_enet/fs_enet.h | 5 ---- drivers/net/fs_enet/mac-fec.c | 34 -------------------------- 3 files changed, 1 insertion(+), 77 deletions(-) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 9604aaed61d6..b892c3ad9a74 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -941,30 +941,6 @@ extern void fs_mii_disconnect(struct net_device *dev); /**************************************************************************************/ -/* handy pointer to the immap */ -void __iomem *fs_enet_immap = NULL; - -static int setup_immap(void) -{ -#ifdef CONFIG_CPM1 - fs_enet_immap = ioremap(IMAP_ADDR, 0x4000); - WARN_ON(!fs_enet_immap); -#elif defined(CONFIG_CPM2) - fs_enet_immap = cpm2_immr; -#endif - - return 0; -} - -static void cleanup_immap(void) -{ -#if defined(CONFIG_CPM1) - iounmap(fs_enet_immap); -#endif -} - -/**************************************************************************************/ - #ifdef CONFIG_FS_ENET_HAS_FEC #define IS_FEC(match) ((match)->data == &fs_fec_ops) #else @@ -1144,25 +1120,12 @@ static struct of_platform_driver fs_enet_driver = { static int __init fs_init(void) { - int r = setup_immap(); - if (r != 0) - return r; - - r = of_register_platform_driver(&fs_enet_driver); - if (r != 0) - goto out; - - return 0; - -out: - cleanup_immap(); - return r; + return of_register_platform_driver(&fs_enet_driver); } static void __exit fs_cleanup(void) { of_unregister_platform_driver(&fs_enet_driver); - cleanup_immap(); } #ifdef CONFIG_NET_POLL_CONTROLLER diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h index 85a4bab7f630..ef01e09781a5 100644 --- a/drivers/net/fs_enet/fs_enet.h +++ b/drivers/net/fs_enet/fs_enet.h @@ -194,9 +194,4 @@ extern const struct fs_ops fs_scc_ops; /*******************************************************************/ -/* handy pointer to the immap */ -extern void __iomem *fs_enet_immap; - -/*******************************************************************/ - #endif diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index 14e575313c89..ca7bcb8ab3a1 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -245,10 +245,6 @@ static void set_multicast_list(struct net_device *dev) static void restart(struct net_device *dev) { -#ifdef CONFIG_DUET - immap_t *immap = fs_enet_immap; - u32 cptr; -#endif struct fs_enet_private *fep = netdev_priv(dev); fec_t __iomem *fecp = fep->fec.fecp; const struct fs_platform_info *fpi = fep->fpi; @@ -315,36 +311,6 @@ static void restart(struct net_device *dev) FW(fecp, ievent, 0xffc0); FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29); - /* - * adjust to speed (only for DUET & RMII) - */ -#ifdef CONFIG_DUET - if (fpi->use_rmii) { - cptr = in_be32(&immap->im_cpm.cp_cptr); - switch (fs_get_fec_index(fpi->fs_no)) { - case 0: - cptr |= 0x100; - if (fep->speed == 10) - cptr |= 0x0000010; - else if (fep->speed == 100) - cptr &= ~0x0000010; - break; - case 1: - cptr |= 0x80; - if (fep->speed == 10) - cptr |= 0x0000008; - else if (fep->speed == 100) - cptr &= ~0x0000008; - break; - default: - BUG(); /* should never happen */ - break; - } - out_be32(&immap->im_cpm.cp_cptr, cptr); - } -#endif - - FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ /* * adjust to duplex mode -- GitLab From 8555a5948467e941acc34e8b1c30df4c1f2f5862 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 28 Apr 2009 02:11:53 -0700 Subject: [PATCH 0847/6080] net: Fix ucc_geth.c handling of fixed-link w/o phy-connection-type property. Previous rework to ucc_geth.c to add of_mdio support (net: Rework ucc_geth driver to use of_mdio infrastructure) added a block of code which broke older openfirmware device trees which this case. This patch removes the offending blurb. Signed-off-by: Grant Likely Signed-off-by: David S. Miller --- drivers/net/ucc_geth.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index a53628466637..f18017dc0255 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3631,9 +3631,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma prop = of_get_property(np, "phy-connection-type", NULL); if (!prop) { /* handle interface property present in old trees */ - if (!phy) - return -ENODEV; - prop = of_get_property(phy, "interface", NULL); if (prop != NULL) { phy_interface = enet_to_phy_interface[*prop]; -- GitLab From 2a2ed0dfc9ec44a899c7d4672f73f2c045099118 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 28 Apr 2009 13:01:26 +0200 Subject: [PATCH 0848/6080] ALSA: hda - Don't enable auto-mute but for speakers in patch_realtek.c Enable auto-muting in model=auto only for devices with HP and speakers. For devices with HP and line-outs, don't enable the auto-muting. Also, add a debug print to show the auto-mute feature. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3a6306302c70..96475dc95fbb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1099,13 +1099,16 @@ static void alc_init_auto_hp(struct hda_codec *codec) return; if (!spec->autocfg.speaker_pins[0]) { - if (spec->autocfg.line_out_pins[0]) + if (spec->autocfg.line_out_pins[0] && + spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) spec->autocfg.speaker_pins[0] = spec->autocfg.line_out_pins[0]; else return; } + snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", + spec->autocfg.hp_pins[0]); snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT); -- GitLab From cb6605c1e4d2a2eaffdde433fbfe1567ca688458 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 28 Apr 2009 13:03:19 +0200 Subject: [PATCH 0849/6080] ALSA: hda - Fix a typo in patch_realtek.c again The commmit dfed0ef9b3ff9e37903920b6938ed33344ad0b3d was reverted accidentally by the merge of auto-detection fix patch. Fixed again now. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 96475dc95fbb..3e7207b927c8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1151,7 +1151,7 @@ static int alc_subsystem_id(struct hda_codec *codec, ass = snd_hda_codec_get_pincfg(codec, nid); snd_printd("realtek: No valid SSID, " "checking pincfg 0x%08x for NID 0x%x\n", - nid, ass); + ass, nid); if (!(ass & 1) && !(ass & 0x100000)) return 0; if ((ass >> 30) != 1) /* no physical connection */ -- GitLab From 6a321cb370ad3db4ba6e405e638b3a42c41089b0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 28 Apr 2009 04:43:42 -0700 Subject: [PATCH 0850/6080] net: netif_tx_queue_stopped too expensive netif_tx_queue_stopped(txq) is most of the time false. Yet its cost is very expensive on SMP. static inline int netif_tx_queue_stopped(const struct netdev_queue *dev_queue) { return test_bit(__QUEUE_STATE_XOFF, &dev_queue->state); } I saw this on oprofile hunting and bnx2 driver bnx2_tx_int(). We probably should split "struct netdev_queue" in two parts, one being read mostly. __netif_tx_lock() touches _xmit_lock & xmit_lock_owner, these deserve a separate cache line. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f8c3619d551f..505a3c6cb12d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -447,12 +447,18 @@ enum netdev_queue_state_t }; struct netdev_queue { +/* + * read mostly part + */ struct net_device *dev; struct Qdisc *qdisc; unsigned long state; - spinlock_t _xmit_lock; - int xmit_lock_owner; struct Qdisc *qdisc_sleeping; +/* + * write mostly part + */ + spinlock_t _xmit_lock ____cacheline_aligned_in_smp; + int xmit_lock_owner; } ____cacheline_aligned_in_smp; -- GitLab From 4278600644dee621bd50d7498e244b135612e0f6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 28 Apr 2009 23:12:10 +0900 Subject: [PATCH 0851/6080] sh: register the rtc-generic platform device properly. The device registration was accidentally omitted, add it back in. Do some basic device probing as well, so this doesn't show up for platforms that tie in to the RTC interface properly. Signed-off-by: Paul Mundt --- arch/sh/kernel/time_32.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c index a2458bfdda26..457332116e17 100644 --- a/arch/sh/kernel/time_32.c +++ b/arch/sh/kernel/time_32.c @@ -3,7 +3,7 @@ * * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2002 - 2008 Paul Mundt + * Copyright (C) 2002 - 2009 Paul Mundt * Copyright (C) 2002 M. R. Brown * * Some code taken from i386 version. @@ -68,6 +68,21 @@ int set_rtc_time(struct rtc_time *tm) } EXPORT_SYMBOL(set_rtc_time); +static int __init rtc_generic_init(void) +{ + struct platform_device *pdev; + + if (rtc_sh_get_time == null_rtc_get_time) + return -ENODEV; + + pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return 0; +} +module_init(rtc_generic_init); + #ifndef CONFIG_GENERIC_TIME void do_gettimeofday(struct timeval *tv) { -- GitLab From 1130b0296184bc21806225fd06d533515a99d2db Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 28 Apr 2009 14:56:18 +0200 Subject: [PATCH 0852/6080] perf_counter tools: fix Documentation/perf_counter build error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mike Galbraith reported: > marge:..Documentation/perf_counter # make > CC builtin-stat.o > In file included from builtin-stat.c:71: > /usr/include/ctype.h:102: error: expected expression before ‘]’ token Remove the ctype.h include. Signed-off-by: Ingo Molnar --- Documentation/perf_counter/builtin-stat.c | 1 - Documentation/perf_counter/builtin-top.c | 1 - 2 files changed, 2 deletions(-) diff --git a/Documentation/perf_counter/builtin-stat.c b/Documentation/perf_counter/builtin-stat.c index d7ace631fc4f..112b94ed3298 100644 --- a/Documentation/perf_counter/builtin-stat.c +++ b/Documentation/perf_counter/builtin-stat.c @@ -68,7 +68,6 @@ #include #include #include -#include #include #include #include diff --git a/Documentation/perf_counter/builtin-top.c b/Documentation/perf_counter/builtin-top.c index dea016fa41e8..6a276d2b2bbc 100644 --- a/Documentation/perf_counter/builtin-top.c +++ b/Documentation/perf_counter/builtin-top.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include -- GitLab From 6b2db28a7a2da1064df9e179d9b6d07b0bfe156a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 14 Apr 2009 10:54:49 +0900 Subject: [PATCH 0853/6080] fuse: misc cleanups * fuse_file_alloc() was structured in weird way. The success path was split between else block and code following the block. Restructure the code such that it's easier to read and modify. * Unindent success path of fuse_release_common() to ease future changes. Signed-off-by: Tejun Heo Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 81 +++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 06f30e965676..028e17decf2f 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -49,22 +49,26 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir, struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) { struct fuse_file *ff; + ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL); - if (ff) { - ff->reserved_req = fuse_request_alloc(); - if (!ff->reserved_req) { - kfree(ff); - return NULL; - } else { - INIT_LIST_HEAD(&ff->write_entry); - atomic_set(&ff->count, 0); - spin_lock(&fc->lock); - ff->kh = ++fc->khctr; - spin_unlock(&fc->lock); - } - RB_CLEAR_NODE(&ff->polled_node); - init_waitqueue_head(&ff->poll_wait); + if (unlikely(!ff)) + return NULL; + + ff->reserved_req = fuse_request_alloc(); + if (unlikely(!ff->reserved_req)) { + kfree(ff); + return NULL; } + + INIT_LIST_HEAD(&ff->write_entry); + atomic_set(&ff->count, 0); + RB_CLEAR_NODE(&ff->polled_node); + init_waitqueue_head(&ff->poll_wait); + + spin_lock(&fc->lock); + ff->kh = ++fc->khctr; + spin_unlock(&fc->lock); + return ff; } @@ -158,34 +162,37 @@ void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode) int fuse_release_common(struct inode *inode, struct file *file, int isdir) { - struct fuse_file *ff = file->private_data; - if (ff) { - struct fuse_conn *fc = get_fuse_conn(inode); - struct fuse_req *req = ff->reserved_req; + struct fuse_conn *fc; + struct fuse_file *ff; + struct fuse_req *req; - fuse_release_fill(ff, get_node_id(inode), file->f_flags, - isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); + ff = file->private_data; + if (unlikely(!ff)) + return 0; /* return value is ignored by VFS */ - /* Hold vfsmount and dentry until release is finished */ - req->misc.release.vfsmount = mntget(file->f_path.mnt); - req->misc.release.dentry = dget(file->f_path.dentry); + fc = get_fuse_conn(inode); + req = ff->reserved_req; - spin_lock(&fc->lock); - list_del(&ff->write_entry); - if (!RB_EMPTY_NODE(&ff->polled_node)) - rb_erase(&ff->polled_node, &fc->polled_files); - spin_unlock(&fc->lock); + fuse_release_fill(ff, get_node_id(inode), file->f_flags, + isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); - wake_up_interruptible_sync(&ff->poll_wait); - /* - * Normally this will send the RELEASE request, - * however if some asynchronous READ or WRITE requests - * are outstanding, the sending will be delayed - */ - fuse_file_put(ff); - } + /* Hold vfsmount and dentry until release is finished */ + req->misc.release.vfsmount = mntget(file->f_path.mnt); + req->misc.release.dentry = dget(file->f_path.dentry); + + spin_lock(&fc->lock); + list_del(&ff->write_entry); + if (!RB_EMPTY_NODE(&ff->polled_node)) + rb_erase(&ff->polled_node, &fc->polled_files); + spin_unlock(&fc->lock); - /* Return value is ignored by VFS */ + wake_up_interruptible_sync(&ff->poll_wait); + /* + * Normally this will send the RELEASE request, however if + * some asynchronous READ or WRITE requests are outstanding, + * the sending will be delayed. + */ + fuse_file_put(ff); return 0; } -- GitLab From b0be46ebf72ca7478c1c4bd0153c42f90e768a03 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:36 +0200 Subject: [PATCH 0854/6080] fuse: use struct path in release structure Use struct path instead of separate dentry and vfsmount in req->misc.release. Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 9 ++++----- fs/fuse/fuse_i.h | 3 +-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 028e17decf2f..3c8fa93524b0 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -86,15 +86,14 @@ static struct fuse_file *fuse_file_get(struct fuse_file *ff) static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req) { - dput(req->misc.release.dentry); - mntput(req->misc.release.vfsmount); + path_put(&req->misc.release.path); } static void fuse_file_put(struct fuse_file *ff) { if (atomic_dec_and_test(&ff->count)) { struct fuse_req *req = ff->reserved_req; - struct inode *inode = req->misc.release.dentry->d_inode; + struct inode *inode = req->misc.release.path.dentry->d_inode; struct fuse_conn *fc = get_fuse_conn(inode); req->end = fuse_release_end; fuse_request_send_background(fc, req); @@ -177,8 +176,8 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir) isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); /* Hold vfsmount and dentry until release is finished */ - req->misc.release.vfsmount = mntget(file->f_path.mnt); - req->misc.release.dentry = dget(file->f_path.dentry); + path_get(&file->f_path); + req->misc.release.path = file->f_path; spin_lock(&fc->lock); list_del(&ff->write_entry); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 6fc5aedaa0d5..146317ff81b9 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -248,8 +248,7 @@ struct fuse_req { struct fuse_forget_in forget_in; struct { struct fuse_release_in in; - struct vfsmount *vfsmount; - struct dentry *dentry; + struct path path; } release; struct fuse_init_in init_in; struct fuse_init_out init_out; -- GitLab From 2d698b070382442f817813b9dd0103034e5bca81 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:36 +0200 Subject: [PATCH 0855/6080] fuse: clean up fuse_write_fill() Move out code from fuse_write_fill() which is not common to all callers. Remove two function arguments which become unnecessary. Also remove unnecessary memset(), the request is already initialized to zero. Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 3c8fa93524b0..823f84a69733 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -613,20 +613,16 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, return generic_file_aio_read(iocb, iov, nr_segs, pos); } -static void fuse_write_fill(struct fuse_req *req, struct file *file, - struct fuse_file *ff, struct inode *inode, - loff_t pos, size_t count, int writepage) +static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, + struct inode *inode, loff_t pos, size_t count) { struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_write_in *inarg = &req->misc.write.in; struct fuse_write_out *outarg = &req->misc.write.out; - memset(inarg, 0, sizeof(struct fuse_write_in)); inarg->fh = ff->fh; inarg->offset = pos; inarg->size = count; - inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0; - inarg->flags = file ? file->f_flags : 0; req->in.h.opcode = FUSE_WRITE; req->in.h.nodeid = get_node_id(inode); req->in.numargs = 2; @@ -646,9 +642,11 @@ static size_t fuse_send_write(struct fuse_req *req, struct file *file, fl_owner_t owner) { struct fuse_conn *fc = get_fuse_conn(inode); - fuse_write_fill(req, file, file->private_data, inode, pos, count, 0); + struct fuse_write_in *inarg = &req->misc.write.in; + + fuse_write_fill(req, file->private_data, inode, pos, count); + inarg->flags = file->f_flags; if (owner != NULL) { - struct fuse_write_in *inarg = &req->misc.write.in; inarg->write_flags |= FUSE_WRITE_LOCKOWNER; inarg->lock_owner = fuse_lock_owner_id(fc, owner); } @@ -1183,9 +1181,10 @@ static int fuse_writepage_locked(struct page *page) req->ff = fuse_file_get(ff); spin_unlock(&fc->lock); - fuse_write_fill(req, NULL, ff, inode, page_offset(page), 0, 1); + fuse_write_fill(req, ff, inode, page_offset(page), 0); copy_highpage(tmp_page, page); + req->misc.write.in.write_flags |= FUSE_WRITE_CACHE; req->in.argpages = 1; req->num_pages = 1; req->pages[0] = tmp_page; -- GitLab From d09cb9d7f6e4cb1dd0cf12ee0d352440291c74cf Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:36 +0200 Subject: [PATCH 0856/6080] fuse: prepare fuse_direct_io() for CUSE Move code operating on the inode out from fuse_direct_io(). This prepares this function for use by CUSE, where the inode is not owned by a fuse filesystem. Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 823f84a69733..b83d7d86b527 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -993,9 +993,6 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, ssize_t res = 0; struct fuse_req *req; - if (is_bad_inode(inode)) - return -EIO; - req = fuse_get_req(fc); if (IS_ERR(req)) return PTR_ERR(req); @@ -1038,12 +1035,8 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, } } fuse_put_request(fc, req); - if (res > 0) { - if (write) - fuse_write_update_size(inode, pos); + if (res > 0) *ppos = pos; - } - fuse_invalidate_attr(inode); return res; } @@ -1051,7 +1044,17 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, static ssize_t fuse_direct_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - return fuse_direct_io(file, buf, count, ppos, 0); + ssize_t res; + struct inode *inode = file->f_path.dentry->d_inode; + + if (is_bad_inode(inode)) + return -EIO; + + res = fuse_direct_io(file, buf, count, ppos, 0); + + fuse_invalidate_attr(inode); + + return res; } static ssize_t fuse_direct_write(struct file *file, const char __user *buf, @@ -1059,12 +1062,22 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, { struct inode *inode = file->f_path.dentry->d_inode; ssize_t res; + + if (is_bad_inode(inode)) + return -EIO; + /* Don't allow parallel writes to the same file */ mutex_lock(&inode->i_mutex); res = generic_write_checks(file, ppos, &count, 0); - if (!res) + if (!res) { res = fuse_direct_io(file, buf, count, ppos, 1); + if (res > 0) + fuse_write_update_size(inode, *ppos); + } mutex_unlock(&inode->i_mutex); + + fuse_invalidate_attr(inode); + return res; } -- GitLab From da5e4714578ff323f7a61af490fc3539e68f188b Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:36 +0200 Subject: [PATCH 0857/6080] fuse: add members to struct fuse_file Add new members ->fc and ->nodeid to struct fuse_file. This will aid in converting functions for use by CUSE, where the inode is not owned by a fuse filesystem. Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 2 ++ fs/fuse/fuse_i.h | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index b83d7d86b527..3be030105354 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -54,6 +54,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) if (unlikely(!ff)) return NULL; + ff->fc = fc; ff->reserved_req = fuse_request_alloc(); if (unlikely(!ff->reserved_req)) { kfree(ff); @@ -111,6 +112,7 @@ void fuse_finish_open(struct inode *inode, struct file *file, if (outarg->open_flags & FOPEN_NONSEEKABLE) nonseekable_open(inode, file); ff->fh = outarg->fh; + ff->nodeid = get_node_id(inode); file->private_data = fuse_file_get(ff); } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 146317ff81b9..4469d9971588 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -97,8 +97,13 @@ struct fuse_inode { struct list_head writepages; }; +struct fuse_conn; + /** FUSE specific file data */ struct fuse_file { + /** Fuse connection for this file */ + struct fuse_conn *fc; + /** Request reserved for flush and release */ struct fuse_req *reserved_req; @@ -108,6 +113,9 @@ struct fuse_file { /** File handle used by userspace */ u64 fh; + /** Node id of this file */ + u64 nodeid; + /** Refcount */ atomic_t count; @@ -185,8 +193,6 @@ enum fuse_req_state { FUSE_REQ_FINISHED }; -struct fuse_conn; - /** * A request to the client */ -- GitLab From 2106cb18930312af9325d3418e138569c5b903cc Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:37 +0200 Subject: [PATCH 0858/6080] fuse: don't use inode in helpers called by fuse_direct_io() Use ff->fc and ff->nodeid instead of passing down the inode. This prepares this function for use by CUSE, where the inode is not owned by a fuse filesystem. Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 2 +- fs/fuse/file.c | 62 +++++++++++++++++++++++------------------------- fs/fuse/fuse_i.h | 2 +- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8b8eebc5614b..222584b34ce4 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1035,7 +1035,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) req->out.argpages = 1; req->num_pages = 1; req->pages[0] = page; - fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR); + fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, FUSE_READDIR); fuse_request_send(fc, req); nbytes = req->out.args[0].size; err = req->out.h.error; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 3be030105354..aa4a3876ca37 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -379,8 +379,8 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync) return fuse_fsync_common(file, de, datasync, 0); } -void fuse_read_fill(struct fuse_req *req, struct file *file, - struct inode *inode, loff_t pos, size_t count, int opcode) +void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos, + size_t count, int opcode) { struct fuse_read_in *inarg = &req->misc.read.in; struct fuse_file *ff = file->private_data; @@ -390,7 +390,7 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, inarg->size = count; inarg->flags = file->f_flags; req->in.h.opcode = opcode; - req->in.h.nodeid = get_node_id(inode); + req->in.h.nodeid = ff->nodeid; req->in.numargs = 1; req->in.args[0].size = sizeof(struct fuse_read_in); req->in.args[0].value = inarg; @@ -400,12 +400,12 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, } static size_t fuse_send_read(struct fuse_req *req, struct file *file, - struct inode *inode, loff_t pos, size_t count, - fl_owner_t owner) + loff_t pos, size_t count, fl_owner_t owner) { - struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff = file->private_data; + struct fuse_conn *fc = ff->fc; - fuse_read_fill(req, file, inode, pos, count, FUSE_READ); + fuse_read_fill(req, file, pos, count, FUSE_READ); if (owner != NULL) { struct fuse_read_in *inarg = &req->misc.read.in; @@ -463,7 +463,7 @@ static int fuse_readpage(struct file *file, struct page *page) req->out.argpages = 1; req->num_pages = 1; req->pages[0] = page; - num_read = fuse_send_read(req, file, inode, pos, count, NULL); + num_read = fuse_send_read(req, file, pos, count, NULL); err = req->out.h.error; fuse_put_request(fc, req); @@ -512,19 +512,18 @@ static void fuse_readpages_end(struct fuse_conn *fc, struct fuse_req *req) fuse_file_put(req->ff); } -static void fuse_send_readpages(struct fuse_req *req, struct file *file, - struct inode *inode) +static void fuse_send_readpages(struct fuse_req *req, struct file *file) { - struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff = file->private_data; + struct fuse_conn *fc = ff->fc; loff_t pos = page_offset(req->pages[0]); size_t count = req->num_pages << PAGE_CACHE_SHIFT; req->out.argpages = 1; req->out.page_zeroing = 1; - fuse_read_fill(req, file, inode, pos, count, FUSE_READ); + fuse_read_fill(req, file, pos, count, FUSE_READ); req->misc.read.attr_ver = fuse_get_attr_version(fc); if (fc->async_read) { - struct fuse_file *ff = file->private_data; req->ff = fuse_file_get(ff); req->end = fuse_readpages_end; fuse_request_send_background(fc, req); @@ -554,7 +553,7 @@ static int fuse_readpages_fill(void *_data, struct page *page) (req->num_pages == FUSE_MAX_PAGES_PER_REQ || (req->num_pages + 1) * PAGE_CACHE_SIZE > fc->max_read || req->pages[req->num_pages - 1]->index + 1 != page->index)) { - fuse_send_readpages(req, data->file, inode); + fuse_send_readpages(req, data->file); data->req = req = fuse_get_req(fc); if (IS_ERR(req)) { unlock_page(page); @@ -588,7 +587,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); if (!err) { if (data.req->num_pages) - fuse_send_readpages(data.req, file, inode); + fuse_send_readpages(data.req, file); else fuse_put_request(fc, data.req); } @@ -616,9 +615,8 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, } static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, - struct inode *inode, loff_t pos, size_t count) + loff_t pos, size_t count) { - struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_write_in *inarg = &req->misc.write.in; struct fuse_write_out *outarg = &req->misc.write.out; @@ -626,9 +624,9 @@ static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, inarg->offset = pos; inarg->size = count; req->in.h.opcode = FUSE_WRITE; - req->in.h.nodeid = get_node_id(inode); + req->in.h.nodeid = ff->nodeid; req->in.numargs = 2; - if (fc->minor < 9) + if (ff->fc->minor < 9) req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE; else req->in.args[0].size = sizeof(struct fuse_write_in); @@ -640,13 +638,13 @@ static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, } static size_t fuse_send_write(struct fuse_req *req, struct file *file, - struct inode *inode, loff_t pos, size_t count, - fl_owner_t owner) + loff_t pos, size_t count, fl_owner_t owner) { - struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff = file->private_data; + struct fuse_conn *fc = ff->fc; struct fuse_write_in *inarg = &req->misc.write.in; - fuse_write_fill(req, file->private_data, inode, pos, count); + fuse_write_fill(req, ff, pos, count); inarg->flags = file->f_flags; if (owner != NULL) { inarg->write_flags |= FUSE_WRITE_LOCKOWNER; @@ -706,7 +704,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode, req->num_pages = 1; req->pages[0] = page; req->page_offset = offset; - nres = fuse_send_write(req, file, inode, pos, count, NULL); + nres = fuse_send_write(req, file, pos, count, NULL); err = req->out.h.error; fuse_put_request(fc, req); if (!err && !nres) @@ -747,7 +745,7 @@ static size_t fuse_send_write_pages(struct fuse_req *req, struct file *file, for (i = 0; i < req->num_pages; i++) fuse_wait_on_page_writeback(inode, req->pages[i]->index); - res = fuse_send_write(req, file, inode, pos, count, NULL); + res = fuse_send_write(req, file, pos, count, NULL); offset = req->page_offset; count = res; @@ -988,8 +986,8 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf, static ssize_t fuse_direct_io(struct file *file, const char __user *buf, size_t count, loff_t *ppos, int write) { - struct inode *inode = file->f_path.dentry->d_inode; - struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_file *ff = file->private_data; + struct fuse_conn *fc = ff->fc; size_t nmax = write ? fc->max_write : fc->max_read; loff_t pos = *ppos; ssize_t res = 0; @@ -1001,6 +999,7 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, while (count) { size_t nres; + fl_owner_t owner = current->files; size_t nbytes = min(count, nmax); int err = fuse_get_user_pages(req, buf, &nbytes, write); if (err) { @@ -1009,11 +1008,10 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, } if (write) - nres = fuse_send_write(req, file, inode, pos, nbytes, - current->files); + nres = fuse_send_write(req, file, pos, nbytes, owner); else - nres = fuse_send_read(req, file, inode, pos, nbytes, - current->files); + nres = fuse_send_read(req, file, pos, nbytes, owner); + fuse_release_user_pages(req, !write); if (req->out.h.error) { if (!res) @@ -1196,7 +1194,7 @@ static int fuse_writepage_locked(struct page *page) req->ff = fuse_file_get(ff); spin_unlock(&fc->lock); - fuse_write_fill(req, ff, inode, page_offset(page), 0); + fuse_write_fill(req, ff, page_offset(page), 0); copy_highpage(tmp_page, page); req->misc.write.in.write_flags |= FUSE_WRITE_CACHE; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 4469d9971588..a51f63c7d423 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -520,7 +520,7 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, * Initialize READ or READDIR request */ void fuse_read_fill(struct fuse_req *req, struct file *file, - struct inode *inode, loff_t pos, size_t count, int opcode); + loff_t pos, size_t count, int opcode); /** * Send OPEN or OPENDIR request -- GitLab From c7b7143c6342b8751d47b03a025ac5c0ac1ae809 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:37 +0200 Subject: [PATCH 0859/6080] fuse: clean up args in fuse_finish_open() and fuse_release_fill() Move setting ff->fh, ff->nodeid and file->private_data outside fuse_finish_open(). Add ->open_flags member to struct fuse_file. This simplifies the argument passing to fuse_finish_open() and fuse_release_fill(), and paves the way for creating an open helper that doesn't need an inode pointer. Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 16 +++++++++------- fs/fuse/file.c | 28 +++++++++++++++------------- fs/fuse/fuse_i.h | 9 ++++++--- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 222584b34ce4..da87a3d8a8ea 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -365,9 +365,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, * Synchronous release for the case when something goes wrong in CREATE_OPEN */ static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff, - u64 nodeid, int flags) + int flags) { - fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE); + fuse_release_fill(ff, flags, FUSE_RELEASE); ff->reserved_req->force = 1; fuse_request_send(fc, ff->reserved_req); fuse_put_request(fc, ff->reserved_req); @@ -445,12 +445,14 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, goto out_free_ff; fuse_put_request(fc, req); + ff->fh = outopen.fh; + ff->nodeid = outentry.nodeid; + ff->open_flags = outopen.open_flags; inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, &outentry.attr, entry_attr_timeout(&outentry), 0); if (!inode) { flags &= ~(O_CREAT | O_EXCL | O_TRUNC); - ff->fh = outopen.fh; - fuse_sync_release(fc, ff, outentry.nodeid, flags); + fuse_sync_release(fc, ff, flags); fuse_send_forget(fc, forget_req, outentry.nodeid, 1); return -ENOMEM; } @@ -460,11 +462,11 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, fuse_invalidate_attr(dir); file = lookup_instantiate_filp(nd, entry, generic_file_open); if (IS_ERR(file)) { - ff->fh = outopen.fh; - fuse_sync_release(fc, ff, outentry.nodeid, flags); + fuse_sync_release(fc, ff, flags); return PTR_ERR(file); } - fuse_finish_open(inode, file, ff, &outopen); + file->private_data = fuse_file_get(ff); + fuse_finish_open(inode, file); return 0; out_free_ff: diff --git a/fs/fuse/file.c b/fs/fuse/file.c index aa4a3876ca37..d9458cace425 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -79,7 +79,7 @@ void fuse_file_free(struct fuse_file *ff) kfree(ff); } -static struct fuse_file *fuse_file_get(struct fuse_file *ff) +struct fuse_file *fuse_file_get(struct fuse_file *ff) { atomic_inc(&ff->count); return ff; @@ -102,18 +102,16 @@ static void fuse_file_put(struct fuse_file *ff) } } -void fuse_finish_open(struct inode *inode, struct file *file, - struct fuse_file *ff, struct fuse_open_out *outarg) +void fuse_finish_open(struct inode *inode, struct file *file) { - if (outarg->open_flags & FOPEN_DIRECT_IO) + struct fuse_file *ff = file->private_data; + + if (ff->open_flags & FOPEN_DIRECT_IO) file->f_op = &fuse_direct_io_file_operations; - if (!(outarg->open_flags & FOPEN_KEEP_CACHE)) + if (!(ff->open_flags & FOPEN_KEEP_CACHE)) invalidate_inode_pages2(inode->i_mapping); - if (outarg->open_flags & FOPEN_NONSEEKABLE) + if (ff->open_flags & FOPEN_NONSEEKABLE) nonseekable_open(inode, file); - ff->fh = outarg->fh; - ff->nodeid = get_node_id(inode); - file->private_data = fuse_file_get(ff); } int fuse_open_common(struct inode *inode, struct file *file, int isdir) @@ -141,13 +139,17 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir) else { if (isdir) outarg.open_flags &= ~FOPEN_DIRECT_IO; - fuse_finish_open(inode, file, ff, &outarg); + ff->fh = outarg.fh; + ff->nodeid = get_node_id(inode); + ff->open_flags = outarg.open_flags; + file->private_data = fuse_file_get(ff); + fuse_finish_open(inode, file); } return err; } -void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode) +void fuse_release_fill(struct fuse_file *ff, int flags, int opcode) { struct fuse_req *req = ff->reserved_req; struct fuse_release_in *inarg = &req->misc.release.in; @@ -155,7 +157,7 @@ void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode) inarg->fh = ff->fh; inarg->flags = flags; req->in.h.opcode = opcode; - req->in.h.nodeid = nodeid; + req->in.h.nodeid = ff->nodeid; req->in.numargs = 1; req->in.args[0].size = sizeof(struct fuse_release_in); req->in.args[0].value = inarg; @@ -174,7 +176,7 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir) fc = get_fuse_conn(inode); req = ff->reserved_req; - fuse_release_fill(ff, get_node_id(inode), file->f_flags, + fuse_release_fill(ff, file->f_flags, isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); /* Hold vfsmount and dentry until release is finished */ diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index a51f63c7d423..ce46c120f48a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -119,6 +119,9 @@ struct fuse_file { /** Refcount */ atomic_t count; + /** FOPEN_* flags returned by open */ + u32 open_flags; + /** Entry on inode's write_files list */ struct list_head write_entry; @@ -528,12 +531,12 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, int fuse_open_common(struct inode *inode, struct file *file, int isdir); struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); +struct fuse_file *fuse_file_get(struct fuse_file *ff); void fuse_file_free(struct fuse_file *ff); -void fuse_finish_open(struct inode *inode, struct file *file, - struct fuse_file *ff, struct fuse_open_out *outarg); +void fuse_finish_open(struct inode *inode, struct file *file); /** Fill in ff->reserved_req with a RELEASE request */ -void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode); +void fuse_release_fill(struct fuse_file *ff, int flags, int opcode); /** * Send RELEASE or RELEASEDIR request -- GitLab From 91fe96b403f8a0a4a8a045a39b1bd549b0da7941 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:37 +0200 Subject: [PATCH 0860/6080] fuse: create fuse_do_open() helper for CUSE Create a helper for sending an OPEN request that doesn't need a struct inode pointer. Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 2 +- fs/fuse/file.c | 65 +++++++++++++++++++++++++++++------------------- fs/fuse/fuse_i.h | 2 +- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index da87a3d8a8ea..faa3b2f86740 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1103,7 +1103,7 @@ static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c) static int fuse_dir_open(struct inode *inode, struct file *file) { - return fuse_open_common(inode, file, 1); + return fuse_open_common(inode, file, true); } static int fuse_dir_release(struct inode *inode, struct file *file) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index d9458cace425..6bdaa55ae613 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -15,10 +15,9 @@ static const struct file_operations fuse_direct_io_file_operations; -static int fuse_send_open(struct inode *inode, struct file *file, int isdir, - struct fuse_open_out *outargp) +static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file, + int opcode, struct fuse_open_out *outargp) { - struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_open_in inarg; struct fuse_req *req; int err; @@ -31,8 +30,8 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir, inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); if (!fc->atomic_o_trunc) inarg.flags &= ~O_TRUNC; - req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; - req->in.h.nodeid = get_node_id(inode); + req->in.h.opcode = opcode; + req->in.h.nodeid = nodeid; req->in.numargs = 1; req->in.args[0].size = sizeof(inarg); req->in.args[0].value = &inarg; @@ -102,6 +101,35 @@ static void fuse_file_put(struct fuse_file *ff) } } +static int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, + bool isdir) +{ + struct fuse_open_out outarg; + struct fuse_file *ff; + int err; + int opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; + + ff = fuse_file_alloc(fc); + if (!ff) + return -ENOMEM; + + err = fuse_send_open(fc, nodeid, file, opcode, &outarg); + if (err) { + fuse_file_free(ff); + return err; + } + + if (isdir) + outarg.open_flags &= ~FOPEN_DIRECT_IO; + + ff->fh = outarg.fh; + ff->nodeid = nodeid; + ff->open_flags = outarg.open_flags; + file->private_data = fuse_file_get(ff); + + return 0; +} + void fuse_finish_open(struct inode *inode, struct file *file) { struct fuse_file *ff = file->private_data; @@ -114,11 +142,9 @@ void fuse_finish_open(struct inode *inode, struct file *file) nonseekable_open(inode, file); } -int fuse_open_common(struct inode *inode, struct file *file, int isdir) +int fuse_open_common(struct inode *inode, struct file *file, bool isdir) { struct fuse_conn *fc = get_fuse_conn(inode); - struct fuse_open_out outarg; - struct fuse_file *ff; int err; /* VFS checks this, but only _after_ ->open() */ @@ -129,24 +155,13 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir) if (err) return err; - ff = fuse_file_alloc(fc); - if (!ff) - return -ENOMEM; - - err = fuse_send_open(inode, file, isdir, &outarg); + err = fuse_do_open(fc, get_node_id(inode), file, isdir); if (err) - fuse_file_free(ff); - else { - if (isdir) - outarg.open_flags &= ~FOPEN_DIRECT_IO; - ff->fh = outarg.fh; - ff->nodeid = get_node_id(inode); - ff->open_flags = outarg.open_flags; - file->private_data = fuse_file_get(ff); - fuse_finish_open(inode, file); - } + return err; - return err; + fuse_finish_open(inode, file); + + return 0; } void fuse_release_fill(struct fuse_file *ff, int flags, int opcode) @@ -201,7 +216,7 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir) static int fuse_open(struct inode *inode, struct file *file) { - return fuse_open_common(inode, file, 0); + return fuse_open_common(inode, file, false); } static int fuse_release(struct inode *inode, struct file *file) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index ce46c120f48a..429e669d7859 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -528,7 +528,7 @@ void fuse_read_fill(struct fuse_req *req, struct file *file, /** * Send OPEN or OPENDIR request */ -int fuse_open_common(struct inode *inode, struct file *file, int isdir); +int fuse_open_common(struct inode *inode, struct file *file, bool isdir); struct fuse_file *fuse_file_alloc(struct fuse_conn *fc); struct fuse_file *fuse_file_get(struct fuse_file *ff); -- GitLab From 8b0797a4984de4406de25808e1a424344de543e4 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:39 +0200 Subject: [PATCH 0861/6080] fuse: don't use inode in fuse_sync_release() Make fuse_sync_release() a generic helper function that doesn't need a struct inode pointer. This makes it suitable for use by CUSE. Change return value of fuse_release_common() from int to void. Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 21 +++++---------------- fs/fuse/file.c | 49 ++++++++++++++++++++++++++++-------------------- fs/fuse/fuse_i.h | 5 ++--- 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index faa3b2f86740..b3089a083d30 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -361,19 +361,6 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, return ERR_PTR(err); } -/* - * Synchronous release for the case when something goes wrong in CREATE_OPEN - */ -static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff, - int flags) -{ - fuse_release_fill(ff, flags, FUSE_RELEASE); - ff->reserved_req->force = 1; - fuse_request_send(fc, ff->reserved_req); - fuse_put_request(fc, ff->reserved_req); - kfree(ff); -} - /* * Atomic create+open operation * @@ -452,7 +439,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, &outentry.attr, entry_attr_timeout(&outentry), 0); if (!inode) { flags &= ~(O_CREAT | O_EXCL | O_TRUNC); - fuse_sync_release(fc, ff, flags); + fuse_sync_release(ff, flags); fuse_send_forget(fc, forget_req, outentry.nodeid, 1); return -ENOMEM; } @@ -462,7 +449,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, fuse_invalidate_attr(dir); file = lookup_instantiate_filp(nd, entry, generic_file_open); if (IS_ERR(file)) { - fuse_sync_release(fc, ff, flags); + fuse_sync_release(ff, flags); return PTR_ERR(file); } file->private_data = fuse_file_get(ff); @@ -1108,7 +1095,9 @@ static int fuse_dir_open(struct inode *inode, struct file *file) static int fuse_dir_release(struct inode *inode, struct file *file) { - return fuse_release_common(inode, file, 1); + fuse_release_common(file, FUSE_RELEASEDIR); + + return 0; } static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 6bdaa55ae613..ab627b40c3ea 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -93,10 +93,9 @@ static void fuse_file_put(struct fuse_file *ff) { if (atomic_dec_and_test(&ff->count)) { struct fuse_req *req = ff->reserved_req; - struct inode *inode = req->misc.release.path.dentry->d_inode; - struct fuse_conn *fc = get_fuse_conn(inode); + req->end = fuse_release_end; - fuse_request_send_background(fc, req); + fuse_request_send_background(ff->fc, req); kfree(ff); } } @@ -164,11 +163,20 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) return 0; } -void fuse_release_fill(struct fuse_file *ff, int flags, int opcode) +static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode) { + struct fuse_conn *fc = ff->fc; struct fuse_req *req = ff->reserved_req; struct fuse_release_in *inarg = &req->misc.release.in; + spin_lock(&fc->lock); + list_del(&ff->write_entry); + if (!RB_EMPTY_NODE(&ff->polled_node)) + rb_erase(&ff->polled_node, &fc->polled_files); + spin_unlock(&fc->lock); + + wake_up_interruptible_sync(&ff->poll_wait); + inarg->fh = ff->fh; inarg->flags = flags; req->in.h.opcode = opcode; @@ -178,40 +186,28 @@ void fuse_release_fill(struct fuse_file *ff, int flags, int opcode) req->in.args[0].value = inarg; } -int fuse_release_common(struct inode *inode, struct file *file, int isdir) +void fuse_release_common(struct file *file, int opcode) { - struct fuse_conn *fc; struct fuse_file *ff; struct fuse_req *req; ff = file->private_data; if (unlikely(!ff)) - return 0; /* return value is ignored by VFS */ + return; - fc = get_fuse_conn(inode); req = ff->reserved_req; - - fuse_release_fill(ff, file->f_flags, - isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); + fuse_prepare_release(ff, file->f_flags, opcode); /* Hold vfsmount and dentry until release is finished */ path_get(&file->f_path); req->misc.release.path = file->f_path; - spin_lock(&fc->lock); - list_del(&ff->write_entry); - if (!RB_EMPTY_NODE(&ff->polled_node)) - rb_erase(&ff->polled_node, &fc->polled_files); - spin_unlock(&fc->lock); - - wake_up_interruptible_sync(&ff->poll_wait); /* * Normally this will send the RELEASE request, however if * some asynchronous READ or WRITE requests are outstanding, * the sending will be delayed. */ fuse_file_put(ff); - return 0; } static int fuse_open(struct inode *inode, struct file *file) @@ -221,7 +217,20 @@ static int fuse_open(struct inode *inode, struct file *file) static int fuse_release(struct inode *inode, struct file *file) { - return fuse_release_common(inode, file, 0); + fuse_release_common(file, FUSE_RELEASE); + + /* return value is ignored by VFS */ + return 0; +} + +void fuse_sync_release(struct fuse_file *ff, int flags) +{ + WARN_ON(atomic_read(&ff->count) > 1); + fuse_prepare_release(ff, flags, FUSE_RELEASE); + ff->reserved_req->force = 1; + fuse_request_send(ff->fc, ff->reserved_req); + fuse_put_request(ff->fc, ff->reserved_req); + kfree(ff); } /* diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 429e669d7859..ef2e1f3780b5 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -535,13 +535,12 @@ struct fuse_file *fuse_file_get(struct fuse_file *ff); void fuse_file_free(struct fuse_file *ff); void fuse_finish_open(struct inode *inode, struct file *file); -/** Fill in ff->reserved_req with a RELEASE request */ -void fuse_release_fill(struct fuse_file *ff, int flags, int opcode); +void fuse_sync_release(struct fuse_file *ff, int flags); /** * Send RELEASE or RELEASEDIR request */ -int fuse_release_common(struct inode *inode, struct file *file, int isdir); +void fuse_release_common(struct file *file, int opcode); /** * Send FSYNC or FSYNCDIR request -- GitLab From d36f248710c05714f37d921258b630bd1456b99f Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:39 +0200 Subject: [PATCH 0862/6080] fuse: don't use inode in fuse_do_ioctl() helper Create a helper for sending an IOCTL request that doesn't use a struct inode. This prepares this function for use by CUSE, where the inode is not owned by a fuse filesystem. Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index ab627b40c3ea..9f0ade0b4ce8 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1647,12 +1647,11 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, * limits ioctl data transfers to well-formed ioctls and is the forced * behavior for all FUSE servers. */ -static long fuse_file_do_ioctl(struct file *file, unsigned int cmd, - unsigned long arg, unsigned int flags) +static long fuse_do_ioctl(struct file *file, unsigned int cmd, + unsigned long arg, unsigned int flags) { - struct inode *inode = file->f_dentry->d_inode; struct fuse_file *ff = file->private_data; - struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_conn *fc = ff->fc; struct fuse_ioctl_in inarg = { .fh = ff->fh, .cmd = cmd, @@ -1671,13 +1670,6 @@ static long fuse_file_do_ioctl(struct file *file, unsigned int cmd, /* assume all the iovs returned by client always fits in a page */ BUILD_BUG_ON(sizeof(struct iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); - if (!fuse_allow_task(fc, current)) - return -EACCES; - - err = -EIO; - if (is_bad_inode(inode)) - goto out; - err = -ENOMEM; pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL); iov_page = alloc_page(GFP_KERNEL); @@ -1738,7 +1730,7 @@ static long fuse_file_do_ioctl(struct file *file, unsigned int cmd, /* okay, let's send it to the client */ req->in.h.opcode = FUSE_IOCTL; - req->in.h.nodeid = get_node_id(inode); + req->in.h.nodeid = ff->nodeid; req->in.numargs = 1; req->in.args[0].size = sizeof(inarg); req->in.args[0].value = &inarg; @@ -1822,16 +1814,31 @@ static long fuse_file_do_ioctl(struct file *file, unsigned int cmd, return err ? err : outarg.result; } +static long fuse_file_ioctl_common(struct file *file, unsigned int cmd, + unsigned long arg, unsigned int flags) +{ + struct inode *inode = file->f_dentry->d_inode; + struct fuse_conn *fc = get_fuse_conn(inode); + + if (!fuse_allow_task(fc, current)) + return -EACCES; + + if (is_bad_inode(inode)) + return -EIO; + + return fuse_do_ioctl(file, cmd, arg, flags); +} + static long fuse_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return fuse_file_do_ioctl(file, cmd, arg, 0); + return fuse_file_ioctl_common(file, cmd, arg, 0); } static long fuse_file_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return fuse_file_do_ioctl(file, cmd, arg, FUSE_IOCTL_COMPAT); + return fuse_file_ioctl_common(file, cmd, arg, FUSE_IOCTL_COMPAT); } /* -- GitLab From 797759aaf31351a1ab1b9130c4f180ce496f46c5 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 28 Apr 2009 16:56:41 +0200 Subject: [PATCH 0863/6080] fuse: don't use inode in fuse_file_poll Use ff->fc and ff->nodeid instead of file->f_dentry->d_inode in the fuse_file_poll() implementation. This prepares this function for use by CUSE, where the inode is not owned by a fuse filesystem. Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 9f0ade0b4ce8..c5de60e873cb 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1894,9 +1894,8 @@ static void fuse_register_polled_file(struct fuse_conn *fc, static unsigned fuse_file_poll(struct file *file, poll_table *wait) { - struct inode *inode = file->f_dentry->d_inode; struct fuse_file *ff = file->private_data; - struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_conn *fc = ff->fc; struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh }; struct fuse_poll_out outarg; struct fuse_req *req; @@ -1921,7 +1920,7 @@ static unsigned fuse_file_poll(struct file *file, poll_table *wait) return PTR_ERR(req); req->in.h.opcode = FUSE_POLL; - req->in.h.nodeid = get_node_id(inode); + req->in.h.nodeid = ff->nodeid; req->in.numargs = 1; req->in.args[0].size = sizeof(inarg); req->in.args[0].value = &inarg; -- GitLab From a325f9b92273d6c64ec56167905b951b9827ec33 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 14 Apr 2009 10:54:52 +0900 Subject: [PATCH 0864/6080] fuse: update fuse_conn_init() and separate out fuse_conn_kill() Update fuse_conn_init() such that it doesn't take @sb and move bdi registration into a separate function. Also separate out fuse_conn_kill() from fuse_put_super(). These will be used to implement cuse. Signed-off-by: Tejun Heo Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 5 ++- fs/fuse/fuse_i.h | 5 ++- fs/fuse/inode.c | 115 ++++++++++++++++++++++++++--------------------- 3 files changed, 72 insertions(+), 53 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ba76b68c52ff..368189fd4056 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -282,7 +282,7 @@ __releases(&fc->lock) wake_up_all(&fc->blocked_waitq); } if (fc->num_background == FUSE_CONGESTION_THRESHOLD && - fc->connected) { + fc->connected && fc->bdi_initialized) { clear_bdi_congested(&fc->bdi, READ); clear_bdi_congested(&fc->bdi, WRITE); } @@ -408,7 +408,8 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc, fc->num_background++; if (fc->num_background == FUSE_MAX_BACKGROUND) fc->blocked = 1; - if (fc->num_background == FUSE_CONGESTION_THRESHOLD) { + if (fc->num_background == FUSE_CONGESTION_THRESHOLD && + fc->bdi_initialized) { set_bdi_congested(&fc->bdi, READ); set_bdi_congested(&fc->bdi, WRITE); } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index ef2e1f3780b5..2efcf12b763a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -394,6 +394,9 @@ struct fuse_conn { /** Filesystem supports NFS exporting. Only set in INIT */ unsigned export_support:1; + /** Set if bdi is valid */ + unsigned bdi_initialized:1; + /* * The following bitfields are only for optimization purposes * and hence races in setting them will not cause malfunction @@ -662,7 +665,7 @@ struct fuse_conn *fuse_conn_get(struct fuse_conn *fc); /** * Initialize fuse_conn */ -int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb); +void fuse_conn_init(struct fuse_conn *fc); /** * Release reference to fuse_conn diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 75ca5ac603ae..fea7c1064d30 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -274,11 +274,14 @@ static void fuse_send_destroy(struct fuse_conn *fc) } } -static void fuse_put_super(struct super_block *sb) +static void fuse_bdi_destroy(struct fuse_conn *fc) { - struct fuse_conn *fc = get_fuse_conn_super(sb); + if (fc->bdi_initialized) + bdi_destroy(&fc->bdi); +} - fuse_send_destroy(fc); +static void fuse_conn_kill(struct fuse_conn *fc) +{ spin_lock(&fc->lock); fc->connected = 0; fc->blocked = 0; @@ -292,7 +295,15 @@ static void fuse_put_super(struct super_block *sb) list_del(&fc->entry); fuse_ctl_remove_conn(fc); mutex_unlock(&fuse_mutex); - bdi_destroy(&fc->bdi); + fuse_bdi_destroy(fc); +} + +static void fuse_put_super(struct super_block *sb) +{ + struct fuse_conn *fc = get_fuse_conn_super(sb); + + fuse_send_destroy(fc); + fuse_conn_kill(fc); fuse_conn_put(fc); } @@ -463,10 +474,8 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt) return 0; } -int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb) +void fuse_conn_init(struct fuse_conn *fc) { - int err; - memset(fc, 0, sizeof(*fc)); spin_lock_init(&fc->lock); mutex_init(&fc->inst_mutex); @@ -481,49 +490,12 @@ int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb) INIT_LIST_HEAD(&fc->bg_queue); INIT_LIST_HEAD(&fc->entry); atomic_set(&fc->num_waiting, 0); - fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; - fc->bdi.unplug_io_fn = default_unplug_io_fn; - /* fuse does it's own writeback accounting */ - fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; fc->khctr = 0; fc->polled_files = RB_ROOT; - fc->dev = sb->s_dev; - err = bdi_init(&fc->bdi); - if (err) - goto error_mutex_destroy; - if (sb->s_bdev) { - err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", - MAJOR(fc->dev), MINOR(fc->dev)); - } else { - err = bdi_register_dev(&fc->bdi, fc->dev); - } - if (err) - goto error_bdi_destroy; - /* - * For a single fuse filesystem use max 1% of dirty + - * writeback threshold. - * - * This gives about 1M of write buffer for memory maps on a - * machine with 1G and 10% dirty_ratio, which should be more - * than enough. - * - * Privileged users can raise it by writing to - * - * /sys/class/bdi//max_ratio - */ - bdi_set_max_ratio(&fc->bdi, 1); fc->reqctr = 0; fc->blocked = 1; fc->attr_version = 1; get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); - - return 0; - - error_bdi_destroy: - bdi_destroy(&fc->bdi); - error_mutex_destroy: - mutex_destroy(&fc->inst_mutex); - return err; } EXPORT_SYMBOL_GPL(fuse_conn_init); @@ -794,6 +766,48 @@ static void fuse_free_conn(struct fuse_conn *fc) kfree(fc); } +static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) +{ + int err; + + fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; + fc->bdi.unplug_io_fn = default_unplug_io_fn; + /* fuse does it's own writeback accounting */ + fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; + + err = bdi_init(&fc->bdi); + if (err) + return err; + + fc->bdi_initialized = 1; + + if (sb->s_bdev) { + err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", + MAJOR(fc->dev), MINOR(fc->dev)); + } else { + err = bdi_register_dev(&fc->bdi, fc->dev); + } + + if (err) + return err; + + /* + * For a single fuse filesystem use max 1% of dirty + + * writeback threshold. + * + * This gives about 1M of write buffer for memory maps on a + * machine with 1G and 10% dirty_ratio, which should be more + * than enough. + * + * Privileged users can raise it by writing to + * + * /sys/class/bdi//max_ratio + */ + bdi_set_max_ratio(&fc->bdi, 1); + + return 0; +} + static int fuse_fill_super(struct super_block *sb, void *data, int silent) { struct fuse_conn *fc; @@ -840,11 +854,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) if (!fc) goto err_fput; - err = fuse_conn_init(fc, sb); - if (err) { - kfree(fc); - goto err_fput; - } + fuse_conn_init(fc); + + fc->dev = sb->s_dev; + err = fuse_bdi_init(fc, sb); + if (err) + goto err_put_conn; fc->release = fuse_free_conn; fc->flags = d.flags; @@ -908,7 +923,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) err_put_root: dput(root_dentry); err_put_conn: - bdi_destroy(&fc->bdi); + fuse_bdi_destroy(fc); fuse_conn_put(fc); err_fput: fput(file); -- GitLab From 08cbf542bf24fb0481a54526b177347ae4046f5e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 14 Apr 2009 10:54:53 +0900 Subject: [PATCH 0865/6080] fuse: export symbols to be used by CUSE Export the following symbols for CUSE. fuse_conn_put() fuse_conn_get() fuse_conn_kill() fuse_send_init() fuse_do_open() fuse_sync_release() fuse_direct_io() fuse_do_ioctl() fuse_file_poll() fuse_request_alloc() fuse_get_req() fuse_put_request() fuse_request_send() fuse_abort_conn() fuse_dev_release() fuse_dev_operations Signed-off-by: Tejun Heo Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 10 +++++++++- fs/fuse/file.c | 20 +++++++++++++------- fs/fuse/fuse_i.h | 13 +++++++++++++ fs/fuse/inode.c | 5 ++++- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 368189fd4056..8fed2ed12f38 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -46,6 +46,7 @@ struct fuse_req *fuse_request_alloc(void) fuse_request_init(req); return req; } +EXPORT_SYMBOL_GPL(fuse_request_alloc); struct fuse_req *fuse_request_alloc_nofs(void) { @@ -124,6 +125,7 @@ struct fuse_req *fuse_get_req(struct fuse_conn *fc) atomic_dec(&fc->num_waiting); return ERR_PTR(err); } +EXPORT_SYMBOL_GPL(fuse_get_req); /* * Return request in fuse_file->reserved_req. However that may @@ -208,6 +210,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) fuse_request_free(req); } } +EXPORT_SYMBOL_GPL(fuse_put_request); static unsigned len_args(unsigned numargs, struct fuse_arg *args) { @@ -400,6 +403,7 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) } spin_unlock(&fc->lock); } +EXPORT_SYMBOL_GPL(fuse_request_send); static void fuse_request_send_nowait_locked(struct fuse_conn *fc, struct fuse_req *req) @@ -440,6 +444,7 @@ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) req->isreply = 1; fuse_request_send_nowait(fc, req); } +EXPORT_SYMBOL_GPL(fuse_request_send_background); /* * Called under fc->lock @@ -1106,8 +1111,9 @@ void fuse_abort_conn(struct fuse_conn *fc) } spin_unlock(&fc->lock); } +EXPORT_SYMBOL_GPL(fuse_abort_conn); -static int fuse_dev_release(struct inode *inode, struct file *file) +int fuse_dev_release(struct inode *inode, struct file *file) { struct fuse_conn *fc = fuse_get_conn(file); if (fc) { @@ -1121,6 +1127,7 @@ static int fuse_dev_release(struct inode *inode, struct file *file) return 0; } +EXPORT_SYMBOL_GPL(fuse_dev_release); static int fuse_dev_fasync(int fd, struct file *file, int on) { @@ -1143,6 +1150,7 @@ const struct file_operations fuse_dev_operations = { .release = fuse_dev_release, .fasync = fuse_dev_fasync, }; +EXPORT_SYMBOL_GPL(fuse_dev_operations); static struct miscdevice fuse_miscdevice = { .minor = FUSE_MINOR, diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c5de60e873cb..fce6ce694fde 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -12,6 +12,7 @@ #include #include #include +#include static const struct file_operations fuse_direct_io_file_operations; @@ -100,8 +101,8 @@ static void fuse_file_put(struct fuse_file *ff) } } -static int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, - bool isdir) +int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, + bool isdir) { struct fuse_open_out outarg; struct fuse_file *ff; @@ -128,6 +129,7 @@ static int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, return 0; } +EXPORT_SYMBOL_GPL(fuse_do_open); void fuse_finish_open(struct inode *inode, struct file *file) { @@ -232,6 +234,7 @@ void fuse_sync_release(struct fuse_file *ff, int flags) fuse_put_request(ff->fc, ff->reserved_req); kfree(ff); } +EXPORT_SYMBOL_GPL(fuse_sync_release); /* * Scramble the ID space with XTEA, so that the value of the files_struct @@ -1009,8 +1012,8 @@ static int fuse_get_user_pages(struct fuse_req *req, const char __user *buf, return 0; } -static ssize_t fuse_direct_io(struct file *file, const char __user *buf, - size_t count, loff_t *ppos, int write) +ssize_t fuse_direct_io(struct file *file, const char __user *buf, + size_t count, loff_t *ppos, int write) { struct fuse_file *ff = file->private_data; struct fuse_conn *fc = ff->fc; @@ -1066,6 +1069,7 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, return res; } +EXPORT_SYMBOL_GPL(fuse_direct_io); static ssize_t fuse_direct_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) @@ -1647,8 +1651,8 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, * limits ioctl data transfers to well-formed ioctls and is the forced * behavior for all FUSE servers. */ -static long fuse_do_ioctl(struct file *file, unsigned int cmd, - unsigned long arg, unsigned int flags) +long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, + unsigned int flags) { struct fuse_file *ff = file->private_data; struct fuse_conn *fc = ff->fc; @@ -1813,6 +1817,7 @@ static long fuse_do_ioctl(struct file *file, unsigned int cmd, return err ? err : outarg.result; } +EXPORT_SYMBOL_GPL(fuse_do_ioctl); static long fuse_file_ioctl_common(struct file *file, unsigned int cmd, unsigned long arg, unsigned int flags) @@ -1892,7 +1897,7 @@ static void fuse_register_polled_file(struct fuse_conn *fc, spin_unlock(&fc->lock); } -static unsigned fuse_file_poll(struct file *file, poll_table *wait) +unsigned fuse_file_poll(struct file *file, poll_table *wait) { struct fuse_file *ff = file->private_data; struct fuse_conn *fc = ff->fc; @@ -1939,6 +1944,7 @@ static unsigned fuse_file_poll(struct file *file, poll_table *wait) } return POLLERR; } +EXPORT_SYMBOL_GPL(fuse_file_poll); /* * This is called from fuse_handle_notify() on FUSE_NOTIFY_POLL and diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 2efcf12b763a..aaf2f9ff970e 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -261,6 +261,8 @@ struct fuse_req { } release; struct fuse_init_in init_in; struct fuse_init_out init_out; + struct cuse_init_in cuse_init_in; + struct cuse_init_out cuse_init_out; struct { struct fuse_read_in in; u64 attr_ver; @@ -662,6 +664,8 @@ void fuse_invalidate_entry_cache(struct dentry *entry); */ struct fuse_conn *fuse_conn_get(struct fuse_conn *fc); +void fuse_conn_kill(struct fuse_conn *fc); + /** * Initialize fuse_conn */ @@ -704,4 +708,13 @@ void fuse_release_nowrite(struct inode *inode); u64 fuse_get_attr_version(struct fuse_conn *fc); +int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file, + bool isdir); +ssize_t fuse_direct_io(struct file *file, const char __user *buf, + size_t count, loff_t *ppos, int write); +long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, + unsigned int flags); +unsigned fuse_file_poll(struct file *file, poll_table *wait); +int fuse_dev_release(struct inode *inode, struct file *file); + #endif /* _FS_FUSE_I_H */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index fea7c1064d30..d8673ccf90b7 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -280,7 +280,7 @@ static void fuse_bdi_destroy(struct fuse_conn *fc) bdi_destroy(&fc->bdi); } -static void fuse_conn_kill(struct fuse_conn *fc) +void fuse_conn_kill(struct fuse_conn *fc) { spin_lock(&fc->lock); fc->connected = 0; @@ -297,6 +297,7 @@ static void fuse_conn_kill(struct fuse_conn *fc) mutex_unlock(&fuse_mutex); fuse_bdi_destroy(fc); } +EXPORT_SYMBOL_GPL(fuse_conn_kill); static void fuse_put_super(struct super_block *sb) { @@ -508,12 +509,14 @@ void fuse_conn_put(struct fuse_conn *fc) fc->release(fc); } } +EXPORT_SYMBOL_GPL(fuse_conn_put); struct fuse_conn *fuse_conn_get(struct fuse_conn *fc) { atomic_inc(&fc->count); return fc; } +EXPORT_SYMBOL_GPL(fuse_conn_get); static struct inode *fuse_get_root_inode(struct super_block *sb, unsigned mode) { -- GitLab From ac5978e7f83a6cbd9a70282d6e39bd936a31b2bc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 28 Apr 2009 08:03:26 -0700 Subject: [PATCH 0866/6080] inet_diag: Remove dup assignments These are later assigned to other values without being used meanwhile. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/ipv4/inet_diag.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 588a7796e3e3..b0b273503e2a 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -198,8 +198,6 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw, tmo = 0; r->idiag_family = tw->tw_family; - r->idiag_state = tw->tw_state; - r->idiag_timer = 0; r->idiag_retrans = 0; r->id.idiag_if = tw->tw_bound_dev_if; r->id.idiag_cookie[0] = (u32)(unsigned long)tw; -- GitLab From 6c31d55f755ff2bc1f7dc3b45c500032fe90aff8 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 28 Apr 2009 08:04:10 -0700 Subject: [PATCH 0867/6080] gianfar: Use memset instead of cacheable_memzero cacheable_memzero() is completely overkill for the clearing out the FCB block which is only 8-bytes. The compiler should easily optimize this with memset. Additionally, cacheable_memzero() only exists on ppc32 and thus breaks builds of gianfar on ppc64. Signed-off-by: Kumar Gala Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index dae14373296a..2bb038b98cc4 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1207,7 +1207,8 @@ static int gfar_enet_open(struct net_device *dev) static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb) { struct txfcb *fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN); - cacheable_memzero(fcb, GMAC_FCB_LEN); + + memset(fcb, 0, GMAC_FCB_LEN); return fcb; } -- GitLab From fa59440d0c7b5a2bcdc9e35f25fdac693e54c86a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 23 Apr 2009 10:19:58 +0100 Subject: [PATCH 0868/6080] [ARM] 5470/1: U300 register definitions This adds registers, interrupt numbers and IO mappings for the U300 series platforms core support, including basic block offsets and registers definitions for the system controller. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mach-u300/include/mach/hardware.h | 5 + arch/arm/mach-u300/include/mach/io.h | 20 + arch/arm/mach-u300/include/mach/irqs.h | 114 ++++ arch/arm/mach-u300/include/mach/syscon.h | 644 ++++++++++++++++++++ arch/arm/mach-u300/include/mach/u300-regs.h | 187 ++++++ 5 files changed, 970 insertions(+) create mode 100644 arch/arm/mach-u300/include/mach/hardware.h create mode 100644 arch/arm/mach-u300/include/mach/io.h create mode 100644 arch/arm/mach-u300/include/mach/irqs.h create mode 100644 arch/arm/mach-u300/include/mach/syscon.h create mode 100644 arch/arm/mach-u300/include/mach/u300-regs.h diff --git a/arch/arm/mach-u300/include/mach/hardware.h b/arch/arm/mach-u300/include/mach/hardware.h new file mode 100644 index 000000000000..b99d4ce0ac2b --- /dev/null +++ b/arch/arm/mach-u300/include/mach/hardware.h @@ -0,0 +1,5 @@ +/* + * arch/arm/mach-u300/include/mach/hardware.h + */ +#include +#include diff --git a/arch/arm/mach-u300/include/mach/io.h b/arch/arm/mach-u300/include/mach/io.h new file mode 100644 index 000000000000..5d6b4c13b3a0 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/io.h @@ -0,0 +1,20 @@ +/* + * + * arch/arm/mach-u300/include/mach/io.h + * + * + * Copyright (C) 2006-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Dummy IO map for being able to use writew()/readw(), + * writel()/readw() and similar accessor functions. + * Author: Linus Walleij + */ +#ifndef __MACH_IO_H +#define __MACH_IO_H + +#define IO_SPACE_LIMIT 0xffffffff + +#define __io(a) __typesafe_io(a) +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h new file mode 100644 index 000000000000..a6867b12773e --- /dev/null +++ b/arch/arm/mach-u300/include/mach/irqs.h @@ -0,0 +1,114 @@ +/* + * + * arch/arm/mach-u300/include/mach/irqs.h + * + * + * Copyright (C) 2006-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * IRQ channel definitions for the U300 platforms. + * Author: Linus Walleij + */ + +#ifndef __MACH_IRQS_H +#define __MACH_IRQS_H + +#define IRQ_U300_INTCON0_START 0 +#define IRQ_U300_INTCON1_START 32 +/* These are on INTCON0 - 30 lines */ +#define IRQ_U300_IRQ0_EXT 0 +#define IRQ_U300_IRQ1_EXT 1 +#define IRQ_U300_DMA 2 +#define IRQ_U300_VIDEO_ENC_0 3 +#define IRQ_U300_VIDEO_ENC_1 4 +#define IRQ_U300_AAIF_RX 5 +#define IRQ_U300_AAIF_TX 6 +#define IRQ_U300_AAIF_VGPIO 7 +#define IRQ_U300_AAIF_WAKEUP 8 +#define IRQ_U300_PCM_I2S0_FRAME 9 +#define IRQ_U300_PCM_I2S0_FIFO 10 +#define IRQ_U300_PCM_I2S1_FRAME 11 +#define IRQ_U300_PCM_I2S1_FIFO 12 +#define IRQ_U300_XGAM_GAMCON 13 +#define IRQ_U300_XGAM_CDI 14 +#define IRQ_U300_XGAM_CDICON 15 +#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) +/* MMIACC not used on the DB3210 or DB3350 chips */ +#define IRQ_U300_XGAM_MMIACC 16 +#endif +#define IRQ_U300_XGAM_PDI 17 +#define IRQ_U300_XGAM_PDICON 18 +#define IRQ_U300_XGAM_GAMEACC 19 +#define IRQ_U300_XGAM_MCIDCT 20 +#define IRQ_U300_APEX 21 +#define IRQ_U300_UART0 22 +#define IRQ_U300_SPI 23 +#define IRQ_U300_TIMER_APP_OS 24 +#define IRQ_U300_TIMER_APP_DD 25 +#define IRQ_U300_TIMER_APP_GP1 26 +#define IRQ_U300_TIMER_APP_GP2 27 +#define IRQ_U300_TIMER_OS 28 +#define IRQ_U300_TIMER_MS 29 +#define IRQ_U300_KEYPAD_KEYBF 30 +#define IRQ_U300_KEYPAD_KEYBR 31 +/* These are on INTCON1 - 32 lines */ +#define IRQ_U300_GPIO_PORT0 32 +#define IRQ_U300_GPIO_PORT1 33 +#define IRQ_U300_GPIO_PORT2 34 + +#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) || \ + defined(CONFIG_MACH_U300_BS335) +/* These are for DB3150, DB3200 and DB3350 */ +#define IRQ_U300_WDOG 35 +#define IRQ_U300_EVHIST 36 +#define IRQ_U300_MSPRO 37 +#define IRQ_U300_MMCSD_MCIINTR0 38 +#define IRQ_U300_MMCSD_MCIINTR1 39 +#define IRQ_U300_I2C0 40 +#define IRQ_U300_I2C1 41 +#define IRQ_U300_RTC 42 +#define IRQ_U300_NFIF 43 +#define IRQ_U300_NFIF2 44 +#endif + +/* DB3150 and DB3200 have only 45 IRQs */ +#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) +#define U300_NR_IRQS 45 +#endif + +/* The DB3350-specific interrupt lines */ +#ifdef CONFIG_MACH_U300_BS335 +#define IRQ_U300_ISP_F0 45 +#define IRQ_U300_ISP_F1 46 +#define IRQ_U300_ISP_F2 47 +#define IRQ_U300_ISP_F3 48 +#define IRQ_U300_ISP_F4 49 +#define IRQ_U300_GPIO_PORT3 50 +#define IRQ_U300_SYSCON_PLL_LOCK 51 +#define IRQ_U300_UART1 52 +#define IRQ_U300_GPIO_PORT4 53 +#define IRQ_U300_GPIO_PORT5 54 +#define IRQ_U300_GPIO_PORT6 55 +#define U300_NR_IRQS 56 +#endif + +/* The DB3210-specific interrupt lines */ +#ifdef CONFIG_MACH_U300_BS365 +#define IRQ_U300_GPIO_PORT3 35 +#define IRQ_U300_GPIO_PORT4 36 +#define IRQ_U300_WDOG 37 +#define IRQ_U300_EVHIST 38 +#define IRQ_U300_MSPRO 39 +#define IRQ_U300_MMCSD_MCIINTR0 40 +#define IRQ_U300_MMCSD_MCIINTR1 41 +#define IRQ_U300_I2C0 42 +#define IRQ_U300_I2C1 43 +#define IRQ_U300_RTC 44 +#define IRQ_U300_NFIF 45 +#define IRQ_U300_NFIF2 46 +#define IRQ_U300_SYSCON_PLL_LOCK 47 +#define U300_NR_IRQS 48 +#endif + +#define NR_IRQS U300_NR_IRQS + +#endif diff --git a/arch/arm/mach-u300/include/mach/syscon.h b/arch/arm/mach-u300/include/mach/syscon.h new file mode 100644 index 000000000000..1c90d1b1ccb6 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/syscon.h @@ -0,0 +1,644 @@ +/* + * + * arch/arm/mach-u300/include/mach/syscon.h + * + * + * Copyright (C) 2008 ST-Ericsson AB + * + * Author: Rickard Andersson + */ + +#ifndef __MACH_SYSCON_H +#define __MACH_SYSCON_H + +/* + * All register defines for SYSCON registers that concerns individual + * block clocks and reset lines are registered here. This is because + * we don't want any other file to try to fool around with this stuff. + */ + +/* APP side SYSCON registers */ +/* TODO: this is incomplete. Add all from asic_syscon_map.h eventually. */ +/* CLK Control Register 16bit (R/W) */ +#define U300_SYSCON_CCR (0x0000) +#define U300_SYSCON_CCR_I2S1_USE_VCXO (0x0040) +#define U300_SYSCON_CCR_I2S0_USE_VCXO (0x0020) +#define U300_SYSCON_CCR_TURN_VCXO_ON (0x0008) +#define U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK (0x0007) +#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER (0x04) +#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW (0x03) +#define U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE (0x02) +#define U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH (0x01) +#define U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST (0x00) +/* CLK Status Register 16bit (R/W) */ +#define U300_SYSCON_CSR (0x0004) +#define U300_SYSCON_CSR_PLL208_LOCK_IND (0x0002) +#define U300_SYSCON_CSR_PLL13_LOCK_IND (0x0001) +/* Reset lines for SLOW devices 16bit (R/W) */ +#define U300_SYSCON_RSR (0x0014) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_RSR_PPM_RESET_EN (0x0200) +#endif +#define U300_SYSCON_RSR_ACC_TMR_RESET_EN (0x0100) +#define U300_SYSCON_RSR_APP_TMR_RESET_EN (0x0080) +#define U300_SYSCON_RSR_RTC_RESET_EN (0x0040) +#define U300_SYSCON_RSR_KEYPAD_RESET_EN (0x0020) +#define U300_SYSCON_RSR_GPIO_RESET_EN (0x0010) +#define U300_SYSCON_RSR_EH_RESET_EN (0x0008) +#define U300_SYSCON_RSR_BTR_RESET_EN (0x0004) +#define U300_SYSCON_RSR_UART_RESET_EN (0x0002) +#define U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN (0x0001) +/* Reset lines for FAST devices 16bit (R/W) */ +#define U300_SYSCON_RFR (0x0018) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_RFR_UART1_RESET_ENABLE (0x0080) +#endif +#define U300_SYSCON_RFR_SPI_RESET_ENABLE (0x0040) +#define U300_SYSCON_RFR_MMC_RESET_ENABLE (0x0020) +#define U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE (0x0010) +#define U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE (0x0008) +#define U300_SYSCON_RFR_I2C1_RESET_ENABLE (0x0004) +#define U300_SYSCON_RFR_I2C0_RESET_ENABLE (0x0002) +#define U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE (0x0001) +/* Reset lines for the rest of the peripherals 16bit (R/W) */ +#define U300_SYSCON_RRR (0x001c) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_RRR_CDS_RESET_EN (0x4000) +#define U300_SYSCON_RRR_ISP_RESET_EN (0x2000) +#endif +#define U300_SYSCON_RRR_INTCON_RESET_EN (0x1000) +#define U300_SYSCON_RRR_MSPRO_RESET_EN (0x0800) +#define U300_SYSCON_RRR_XGAM_RESET_EN (0x0100) +#define U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN (0x0080) +#define U300_SYSCON_RRR_NANDIF_RESET_EN (0x0040) +#define U300_SYSCON_RRR_EMIF_RESET_EN (0x0020) +#define U300_SYSCON_RRR_DMAC_RESET_EN (0x0010) +#define U300_SYSCON_RRR_CPU_RESET_EN (0x0008) +#define U300_SYSCON_RRR_APEX_RESET_EN (0x0004) +#define U300_SYSCON_RRR_AHB_RESET_EN (0x0002) +#define U300_SYSCON_RRR_AAIF_RESET_EN (0x0001) +/* Clock enable for SLOW peripherals 16bit (R/W) */ +#define U300_SYSCON_CESR (0x0020) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_CESR_PPM_CLK_EN (0x0200) +#endif +#define U300_SYSCON_CESR_ACC_TMR_CLK_EN (0x0100) +#define U300_SYSCON_CESR_APP_TMR_CLK_EN (0x0080) +#define U300_SYSCON_CESR_KEYPAD_CLK_EN (0x0040) +#define U300_SYSCON_CESR_GPIO_CLK_EN (0x0010) +#define U300_SYSCON_CESR_EH_CLK_EN (0x0008) +#define U300_SYSCON_CESR_BTR_CLK_EN (0x0004) +#define U300_SYSCON_CESR_UART_CLK_EN (0x0002) +#define U300_SYSCON_CESR_SLOW_BRIDGE_CLK_EN (0x0001) +/* Clock enable for FAST peripherals 16bit (R/W) */ +#define U300_SYSCON_CEFR (0x0024) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_CEFR_UART1_CLK_EN (0x0200) +#endif +#define U300_SYSCON_CEFR_I2S1_CORE_CLK_EN (0x0100) +#define U300_SYSCON_CEFR_I2S0_CORE_CLK_EN (0x0080) +#define U300_SYSCON_CEFR_SPI_CLK_EN (0x0040) +#define U300_SYSCON_CEFR_MMC_CLK_EN (0x0020) +#define U300_SYSCON_CEFR_I2S1_CLK_EN (0x0010) +#define U300_SYSCON_CEFR_I2S0_CLK_EN (0x0008) +#define U300_SYSCON_CEFR_I2C1_CLK_EN (0x0004) +#define U300_SYSCON_CEFR_I2C0_CLK_EN (0x0002) +#define U300_SYSCON_CEFR_FAST_BRIDGE_CLK_EN (0x0001) +/* Clock enable for the rest of the peripherals 16bit (R/W) */ +#define U300_SYSCON_CERR (0x0028) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_CERR_CDS_CLK_EN (0x2000) +#define U300_SYSCON_CERR_ISP_CLK_EN (0x1000) +#endif +#define U300_SYSCON_CERR_MSPRO_CLK_EN (0x0800) +#define U300_SYSCON_CERR_AHB_SUBSYS_BRIDGE_CLK_EN (0x0400) +#define U300_SYSCON_CERR_SEMI_CLK_EN (0x0200) +#define U300_SYSCON_CERR_XGAM_CLK_EN (0x0100) +#define U300_SYSCON_CERR_VIDEO_ENC_CLK_EN (0x0080) +#define U300_SYSCON_CERR_NANDIF_CLK_EN (0x0040) +#define U300_SYSCON_CERR_EMIF_CLK_EN (0x0020) +#define U300_SYSCON_CERR_DMAC_CLK_EN (0x0010) +#define U300_SYSCON_CERR_CPU_CLK_EN (0x0008) +#define U300_SYSCON_CERR_APEX_CLK_EN (0x0004) +#define U300_SYSCON_CERR_AHB_CLK_EN (0x0002) +#define U300_SYSCON_CERR_AAIF_CLK_EN (0x0001) +/* Single block clock enable 16bit (-/W) */ +#define U300_SYSCON_SBCER (0x002c) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_SBCER_PPM_CLK_EN (0x0009) +#endif +#define U300_SYSCON_SBCER_ACC_TMR_CLK_EN (0x0008) +#define U300_SYSCON_SBCER_APP_TMR_CLK_EN (0x0007) +#define U300_SYSCON_SBCER_KEYPAD_CLK_EN (0x0006) +#define U300_SYSCON_SBCER_GPIO_CLK_EN (0x0004) +#define U300_SYSCON_SBCER_EH_CLK_EN (0x0003) +#define U300_SYSCON_SBCER_BTR_CLK_EN (0x0002) +#define U300_SYSCON_SBCER_UART_CLK_EN (0x0001) +#define U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN (0x0000) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_SBCER_UART1_CLK_EN (0x0019) +#endif +#define U300_SYSCON_SBCER_I2S1_CORE_CLK_EN (0x0018) +#define U300_SYSCON_SBCER_I2S0_CORE_CLK_EN (0x0017) +#define U300_SYSCON_SBCER_SPI_CLK_EN (0x0016) +#define U300_SYSCON_SBCER_MMC_CLK_EN (0x0015) +#define U300_SYSCON_SBCER_I2S1_CLK_EN (0x0014) +#define U300_SYSCON_SBCER_I2S0_CLK_EN (0x0013) +#define U300_SYSCON_SBCER_I2C1_CLK_EN (0x0012) +#define U300_SYSCON_SBCER_I2C0_CLK_EN (0x0011) +#define U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN (0x0010) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_SBCER_CDS_CLK_EN (0x002D) +#define U300_SYSCON_SBCER_ISP_CLK_EN (0x002C) +#endif +#define U300_SYSCON_SBCER_MSPRO_CLK_EN (0x002B) +#define U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN (0x002A) +#define U300_SYSCON_SBCER_SEMI_CLK_EN (0x0029) +#define U300_SYSCON_SBCER_XGAM_CLK_EN (0x0028) +#define U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN (0x0027) +#define U300_SYSCON_SBCER_NANDIF_CLK_EN (0x0026) +#define U300_SYSCON_SBCER_EMIF_CLK_EN (0x0025) +#define U300_SYSCON_SBCER_DMAC_CLK_EN (0x0024) +#define U300_SYSCON_SBCER_CPU_CLK_EN (0x0023) +#define U300_SYSCON_SBCER_APEX_CLK_EN (0x0022) +#define U300_SYSCON_SBCER_AHB_CLK_EN (0x0021) +#define U300_SYSCON_SBCER_AAIF_CLK_EN (0x0020) +/* Single block clock disable 16bit (-/W) */ +#define U300_SYSCON_SBCDR (0x0030) +/* Same values as above for SBCER */ +/* Clock force SLOW peripherals 16bit (R/W) */ +#define U300_SYSCON_CFSR (0x003c) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_CFSR_PPM_CLK_FORCE_EN (0x0200) +#endif +#define U300_SYSCON_CFSR_ACC_TMR_CLK_FORCE_EN (0x0100) +#define U300_SYSCON_CFSR_APP_TMR_CLK_FORCE_EN (0x0080) +#define U300_SYSCON_CFSR_KEYPAD_CLK_FORCE_EN (0x0020) +#define U300_SYSCON_CFSR_GPIO_CLK_FORCE_EN (0x0010) +#define U300_SYSCON_CFSR_EH_CLK_FORCE_EN (0x0008) +#define U300_SYSCON_CFSR_BTR_CLK_FORCE_EN (0x0004) +#define U300_SYSCON_CFSR_UART_CLK_FORCE_EN (0x0002) +#define U300_SYSCON_CFSR_SLOW_BRIDGE_CLK_FORCE_EN (0x0001) +/* Clock force FAST peripherals 16bit (R/W) */ +#define U300_SYSCON_CFFR (0x40) +/* Values not defined. Define if you want to use them. */ +/* Clock force the rest of the peripherals 16bit (R/W) */ +#define U300_SYSCON_CFRR (0x44) +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SYSCON_CFRR_CDS_CLK_FORCE_EN (0x2000) +#define U300_SYSCON_CFRR_ISP_CLK_FORCE_EN (0x1000) +#endif +#define U300_SYSCON_CFRR_MSPRO_CLK_FORCE_EN (0x0800) +#define U300_SYSCON_CFRR_AHB_SUBSYS_BRIDGE_CLK_FORCE_EN (0x0400) +#define U300_SYSCON_CFRR_SEMI_CLK_FORCE_EN (0x0200) +#define U300_SYSCON_CFRR_XGAM_CLK_FORCE_EN (0x0100) +#define U300_SYSCON_CFRR_VIDEO_ENC_CLK_FORCE_EN (0x0080) +#define U300_SYSCON_CFRR_NANDIF_CLK_FORCE_EN (0x0040) +#define U300_SYSCON_CFRR_EMIF_CLK_FORCE_EN (0x0020) +#define U300_SYSCON_CFRR_DMAC_CLK_FORCE_EN (0x0010) +#define U300_SYSCON_CFRR_CPU_CLK_FORCE_EN (0x0008) +#define U300_SYSCON_CFRR_APEX_CLK_FORCE_EN (0x0004) +#define U300_SYSCON_CFRR_AHB_CLK_FORCE_EN (0x0002) +#define U300_SYSCON_CFRR_AAIF_CLK_FORCE_EN (0x0001) +/* PLL208 Frequency Control 16bit (R/W) */ +#define U300_SYSCON_PFCR (0x48) +#define U300_SYSCON_PFCR_DPLL_MULT_NUM (0x000F) +/* Power Management Control 16bit (R/W) */ +#define U300_SYSCON_PMCR (0x50) +#define U300_SYSCON_PMCR_DCON_ENABLE (0x0002) +#define U300_SYSCON_PMCR_PWR_MGNT_ENABLE (0x0001) +/* + * All other clocking registers moved to clock.c! + */ +/* Reset Out 16bit (R/W) */ +#define U300_SYSCON_RCR (0x6c) +#define U300_SYSCON_RCR_RESOUT0_RST_N_DISABLE (0x0001) +/* EMIF Slew Rate Control 16bit (R/W) */ +#define U300_SYSCON_SRCLR (0x70) +#define U300_SYSCON_SRCLR_MASK (0x03FF) +#define U300_SYSCON_SRCLR_VALUE (0x03FF) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_B (0x0200) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_A (0x0100) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_B (0x0080) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_A (0x0040) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_B (0x0020) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_A (0x0010) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_B (0x0008) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_A (0x0004) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_B (0x0002) +#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_A (0x0001) +/* EMIF Clock Control Register 16bit (R/W) */ +#define U300_SYSCON_ECCR (0x0078) +#define U300_SYSCON_ECCR_MASK (0x000F) +#define U300_SYSCON_ECCR_EMIF_1_STATIC_CLK_EN_N_DISABLE (0x0008) +#define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE (0x0004) +#define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE (0x0002) +#define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE (0x0001) +/* PAD MUX Control register 1 (LOW) 16bit (R/W) */ +#define U300_SYSCON_PMC1LR (0x007C) +#define U300_SYSCON_PMC1LR_MASK (0xFFFF) +#define U300_SYSCON_PMC1LR_CDI_MASK (0xC000) +#define U300_SYSCON_PMC1LR_CDI_CDI (0x0000) +#define U300_SYSCON_PMC1LR_CDI_EMIF (0x4000) +#define U300_SYSCON_PMC1LR_CDI_GPIO (0x8000) +#define U300_SYSCON_PMC1LR_CDI_WCDMA (0xC000) +#define U300_SYSCON_PMC1LR_PDI_MASK (0x3000) +#define U300_SYSCON_PMC1LR_PDI_PDI (0x0000) +#define U300_SYSCON_PMC1LR_PDI_EGG (0x1000) +#define U300_SYSCON_PMC1LR_PDI_WCDMA (0x3000) +#define U300_SYSCON_PMC1LR_MMCSD_MASK (0x0C00) +#define U300_SYSCON_PMC1LR_MMCSD_MMCSD (0x0000) +#define U300_SYSCON_PMC1LR_MMCSD_MSPRO (0x0400) +#define U300_SYSCON_PMC1LR_MMCSD_DSP (0x0800) +#define U300_SYSCON_PMC1LR_MMCSD_WCDMA (0x0C00) +#define U300_SYSCON_PMC1LR_ETM_MASK (0x0300) +#define U300_SYSCON_PMC1LR_ETM_ACC (0x0000) +#define U300_SYSCON_PMC1LR_ETM_APP (0x0100) +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK (0x00C0) +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC (0x0000) +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_NFIF (0x0040) +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM (0x0080) +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC_2GB (0x00C0) +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK (0x0030) +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC (0x0000) +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_NFIF (0x0010) +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SDRAM (0x0020) +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SEMI (0x0030) +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK (0x000C) +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_STATIC (0x0000) +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF (0x0004) +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SDRAM (0x0008) +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SEMI (0x000C) +#define U300_SYSCON_PMC1LR_EMIF_1_MASK (0x0003) +#define U300_SYSCON_PMC1LR_EMIF_1_STATIC (0x0000) +#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 (0x0001) +#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM1 (0x0002) +#define U300_SYSCON_PMC1LR_EMIF_1 (0x0003) +/* PAD MUX Control register 2 (HIGH) 16bit (R/W) */ +#define U300_SYSCON_PMC1HR (0x007E) +#define U300_SYSCON_PMC1HR_MASK (0xFFFF) +#define U300_SYSCON_PMC1HR_MISC_2_MASK (0xC000) +#define U300_SYSCON_PMC1HR_MISC_2_APP_GPIO (0x0000) +#define U300_SYSCON_PMC1HR_MISC_2_MSPRO (0x4000) +#define U300_SYSCON_PMC1HR_MISC_2_DSP (0x8000) +#define U300_SYSCON_PMC1HR_MISC_2_AAIF (0xC000) +#define U300_SYSCON_PMC1HR_APP_GPIO_2_MASK (0x3000) +#define U300_SYSCON_PMC1HR_APP_GPIO_2_APP_GPIO (0x0000) +#define U300_SYSCON_PMC1HR_APP_GPIO_2_NFIF (0x1000) +#define U300_SYSCON_PMC1HR_APP_GPIO_2_DSP (0x2000) +#define U300_SYSCON_PMC1HR_APP_GPIO_2_AAIF (0x3000) +#define U300_SYSCON_PMC1HR_APP_GPIO_1_MASK (0x0C00) +#define U300_SYSCON_PMC1HR_APP_GPIO_1_APP_GPIO (0x0000) +#define U300_SYSCON_PMC1HR_APP_GPIO_1_MMC (0x0400) +#define U300_SYSCON_PMC1HR_APP_GPIO_1_DSP (0x0800) +#define U300_SYSCON_PMC1HR_APP_GPIO_1_AAIF (0x0C00) +#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK (0x0300) +#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_APP_GPIO (0x0000) +#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI (0x0100) +#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_AAIF (0x0300) +#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK (0x00C0) +#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_APP_GPIO (0x0000) +#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI (0x0040) +#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_AAIF (0x00C0) +#define U300_SYSCON_PMC1HR_APP_SPI_2_MASK (0x0030) +#define U300_SYSCON_PMC1HR_APP_SPI_2_APP_GPIO (0x0000) +#define U300_SYSCON_PMC1HR_APP_SPI_2_SPI (0x0010) +#define U300_SYSCON_PMC1HR_APP_SPI_2_DSP (0x0020) +#define U300_SYSCON_PMC1HR_APP_SPI_2_AAIF (0x0030) +#define U300_SYSCON_PMC1HR_APP_UART0_2_MASK (0x000C) +#define U300_SYSCON_PMC1HR_APP_UART0_2_APP_GPIO (0x0000) +#define U300_SYSCON_PMC1HR_APP_UART0_2_UART0 (0x0004) +#define U300_SYSCON_PMC1HR_APP_UART0_2_NFIF_CS (0x0008) +#define U300_SYSCON_PMC1HR_APP_UART0_2_AAIF (0x000C) +#define U300_SYSCON_PMC1HR_APP_UART0_1_MASK (0x0003) +#define U300_SYSCON_PMC1HR_APP_UART0_1_APP_GPIO (0x0000) +#define U300_SYSCON_PMC1HR_APP_UART0_1_UART0 (0x0001) +#define U300_SYSCON_PMC1HR_APP_UART0_1_AAIF (0x0003) +/* Step one for killing the applications system 16bit (-/W) */ +#define U300_SYSCON_KA1R (0x0080) +#define U300_SYSCON_KA1R_MASK (0xFFFF) +#define U300_SYSCON_KA1R_VALUE (0xFFFF) +/* Step two for killing the application system 16bit (-/W) */ +#define U300_SYSCON_KA2R (0x0084) +#define U300_SYSCON_KA2R_MASK (0xFFFF) +#define U300_SYSCON_KA2R_VALUE (0xFFFF) +/* MMC/MSPRO frequency divider register 0 16bit (R/W) */ +#define U300_SYSCON_MMF0R (0x90) +#define U300_SYSCON_MMF0R_MASK (0x00FF) +#define U300_SYSCON_MMF0R_FREQ_0_HIGH_MASK (0x00F0) +#define U300_SYSCON_MMF0R_FREQ_0_LOW_MASK (0x000F) +/* MMC/MSPRO frequency divider register 1 16bit (R/W) */ +#define U300_SYSCON_MMF1R (0x94) +#define U300_SYSCON_MMF1R_MASK (0x00FF) +#define U300_SYSCON_MMF1R_FREQ_1_HIGH_MASK (0x00F0) +#define U300_SYSCON_MMF1R_FREQ_1_LOW_MASK (0x000F) +/* AAIF control register 16 bit (R/W) */ +#define U300_SYSCON_AAIFCR (0x98) +#define U300_SYSCON_AAIFCR_MASK (0x0003) +#define U300_SYSCON_AAIFCR_AASW_CTRL_MASK (0x0003) +#define U300_SYSCON_AAIFCR_AASW_CTRL_FUNCTIONAL (0x0000) +#define U300_SYSCON_AAIFCR_AASW_CTRL_MONITORING (0x0001) +#define U300_SYSCON_AAIFCR_AASW_CTRL_ACC_TO_EXT (0x0002) +#define U300_SYSCON_AAIFCR_AASW_CTRL_APP_TO_EXT (0x0003) +/* Clock control for the MMC and MSPRO blocks 16bit (R/W) */ +#define U300_SYSCON_MMCR (0x9C) +#define U300_SYSCON_MMCR_MASK (0x0003) +#define U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE (0x0002) +#define U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE (0x0001) + +/* TODO: More SYSCON registers missing */ +#define U300_SYSCON_PMC3R (0x10c) +#define U300_SYSCON_PMC3R_APP_MISC_11_MASK (0xc000) +#define U300_SYSCON_PMC3R_APP_MISC_11_SPI (0x4000) +#define U300_SYSCON_PMC3R_APP_MISC_10_MASK (0x3000) +#define U300_SYSCON_PMC3R_APP_MISC_10_SPI (0x1000) +/* TODO: Missing other configs, I just added the SPI stuff */ + +/* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */ +#define U300_SYSCON_S0CCR (0x120) +#define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF) +#define U300_SYSCON_S0CCR_CLOCK_REQ (0x4000) +#define U300_SYSCON_S0CCR_CLOCK_INV (0x0200) +#define U300_SYSCON_S0CCR_CLOCK_FREQ_MASK (0x01E0) +#define U300_SYSCON_S0CCR_CLOCK_SELECT_MASK (0x001E) +#define U300_SYSCON_S0CCR_CLOCK_ENABLE (0x0001) +#define U300_SYSCON_S0CCR_SEL_MCLK (0x8<<1) +#define U300_SYSCON_S0CCR_SEL_ACC_FSM_CLK (0xA<<1) +#define U300_SYSCON_S0CCR_SEL_PLL60_48_CLK (0xC<<1) +#define U300_SYSCON_S0CCR_SEL_PLL60_60_CLK (0xD<<1) +#define U300_SYSCON_S0CCR_SEL_ACC_PLL208_CLK (0xE<<1) +#define U300_SYSCON_S0CCR_SEL_APP_PLL13_CLK (0x0<<1) +#define U300_SYSCON_S0CCR_SEL_APP_FSM_CLK (0x2<<1) +#define U300_SYSCON_S0CCR_SEL_RTC_CLK (0x4<<1) +#define U300_SYSCON_S0CCR_SEL_APP_PLL208_CLK (0x6<<1) +/* SYS_1_CLK_CONTROL second clock control 16 bit (R/W) */ +#define U300_SYSCON_S1CCR (0x124) +#define U300_SYSCON_S1CCR_FIELD_MASK (0x43FF) +#define U300_SYSCON_S1CCR_CLOCK_REQ (0x4000) +#define U300_SYSCON_S1CCR_CLOCK_INV (0x0200) +#define U300_SYSCON_S1CCR_CLOCK_FREQ_MASK (0x01E0) +#define U300_SYSCON_S1CCR_CLOCK_SELECT_MASK (0x001E) +#define U300_SYSCON_S1CCR_CLOCK_ENABLE (0x0001) +#define U300_SYSCON_S1CCR_SEL_MCLK (0x8<<1) +#define U300_SYSCON_S1CCR_SEL_ACC_FSM_CLK (0xA<<1) +#define U300_SYSCON_S1CCR_SEL_PLL60_48_CLK (0xC<<1) +#define U300_SYSCON_S1CCR_SEL_PLL60_60_CLK (0xD<<1) +#define U300_SYSCON_S1CCR_SEL_ACC_PLL208_CLK (0xE<<1) +#define U300_SYSCON_S1CCR_SEL_ACC_PLL13_CLK (0x0<<1) +#define U300_SYSCON_S1CCR_SEL_APP_FSM_CLK (0x2<<1) +#define U300_SYSCON_S1CCR_SEL_RTC_CLK (0x4<<1) +#define U300_SYSCON_S1CCR_SEL_APP_PLL208_CLK (0x6<<1) +/* SYS_2_CLK_CONTROL third clock contol 16 bit (R/W) */ +#define U300_SYSCON_S2CCR (0x128) +#define U300_SYSCON_S2CCR_FIELD_MASK (0xC3FF) +#define U300_SYSCON_S2CCR_CLK_STEAL (0x8000) +#define U300_SYSCON_S2CCR_CLOCK_REQ (0x4000) +#define U300_SYSCON_S2CCR_CLOCK_INV (0x0200) +#define U300_SYSCON_S2CCR_CLOCK_FREQ_MASK (0x01E0) +#define U300_SYSCON_S2CCR_CLOCK_SELECT_MASK (0x001E) +#define U300_SYSCON_S2CCR_CLOCK_ENABLE (0x0001) +#define U300_SYSCON_S2CCR_SEL_MCLK (0x8<<1) +#define U300_SYSCON_S2CCR_SEL_ACC_FSM_CLK (0xA<<1) +#define U300_SYSCON_S2CCR_SEL_PLL60_48_CLK (0xC<<1) +#define U300_SYSCON_S2CCR_SEL_PLL60_60_CLK (0xD<<1) +#define U300_SYSCON_S2CCR_SEL_ACC_PLL208_CLK (0xE<<1) +#define U300_SYSCON_S2CCR_SEL_ACC_PLL13_CLK (0x0<<1) +#define U300_SYSCON_S2CCR_SEL_APP_FSM_CLK (0x2<<1) +#define U300_SYSCON_S2CCR_SEL_RTC_CLK (0x4<<1) +#define U300_SYSCON_S2CCR_SEL_APP_PLL208_CLK (0x6<<1) +/* SYS_MISC_CONTROL, miscellaneous 16bit (R/W) */ +#define U300_SYSCON_MCR (0x12c) +#define U300_SYSCON_MCR_FIELD_MASK (0x00FF) +#define U300_SYSCON_MCR_PMGEN_CR_4_MASK (0x00C0) +#define U300_SYSCON_MCR_PMGEN_CR_4_GPIO (0x0000) +#define U300_SYSCON_MCR_PMGEN_CR_4_SPI (0x0040) +#define U300_SYSCON_MCR_PMGEN_CR_4_AAIF (0x00C0) +#define U300_SYSCON_MCR_PMGEN_CR_2_MASK (0x0030) +#define U300_SYSCON_MCR_PMGEN_CR_2_GPIO (0x0000) +#define U300_SYSCON_MCR_PMGEN_CR_2_EMIF_1_STATIC (0x0010) +#define U300_SYSCON_MCR_PMGEN_CR_2_DSP (0x0020) +#define U300_SYSCON_MCR_PMGEN_CR_2_AAIF (0x0030) +#define U300_SYSCON_MCR_PMGEN_CR_0_MASK (0x000C) +#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M1 (0x0000) +#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M2 (0x0004) +#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M3 (0x0008) +#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_0_SDRAM (0x000C) +#define U300_SYSCON_MCR_PM1G_MODE_ENABLE (0x0002) +#define U300_SYSCON_MCR_PMTG5_MODE_ENABLE (0x0001) +/* Clock activity observability register 0 */ +#define U300_SYSCON_C0OAR (0x140) +#define U300_SYSCON_C0OAR_MASK (0xFFFF) +#define U300_SYSCON_C0OAR_VALUE (0xFFFF) +#define U300_SYSCON_C0OAR_BT_H_CLK (0x8000) +#define U300_SYSCON_C0OAR_ASPB_P_CLK (0x4000) +#define U300_SYSCON_C0OAR_APP_SEMI_H_CLK (0x2000) +#define U300_SYSCON_C0OAR_APP_SEMI_CLK (0x1000) +#define U300_SYSCON_C0OAR_APP_MMC_MSPRO_CLK (0x0800) +#define U300_SYSCON_C0OAR_APP_I2S1_CLK (0x0400) +#define U300_SYSCON_C0OAR_APP_I2S0_CLK (0x0200) +#define U300_SYSCON_C0OAR_APP_CPU_CLK (0x0100) +#define U300_SYSCON_C0OAR_APP_52_CLK (0x0080) +#define U300_SYSCON_C0OAR_APP_208_CLK (0x0040) +#define U300_SYSCON_C0OAR_APP_104_CLK (0x0020) +#define U300_SYSCON_C0OAR_APEX_CLK (0x0010) +#define U300_SYSCON_C0OAR_AHPB_M_H_CLK (0x0008) +#define U300_SYSCON_C0OAR_AHB_CLK (0x0004) +#define U300_SYSCON_C0OAR_AFPB_P_CLK (0x0002) +#define U300_SYSCON_C0OAR_AAIF_CLK (0x0001) +/* Clock activity observability register 1 */ +#define U300_SYSCON_C1OAR (0x144) +#define U300_SYSCON_C1OAR_MASK (0x3FFE) +#define U300_SYSCON_C1OAR_VALUE (0x3FFE) +#define U300_SYSCON_C1OAR_NFIF_F_CLK (0x2000) +#define U300_SYSCON_C1OAR_MSPRO_CLK (0x1000) +#define U300_SYSCON_C1OAR_MMC_P_CLK (0x0800) +#define U300_SYSCON_C1OAR_MMC_CLK (0x0400) +#define U300_SYSCON_C1OAR_KP_P_CLK (0x0200) +#define U300_SYSCON_C1OAR_I2C1_P_CLK (0x0100) +#define U300_SYSCON_C1OAR_I2C0_P_CLK (0x0080) +#define U300_SYSCON_C1OAR_GPIO_CLK (0x0040) +#define U300_SYSCON_C1OAR_EMIF_MPMC_CLK (0x0020) +#define U300_SYSCON_C1OAR_EMIF_H_CLK (0x0010) +#define U300_SYSCON_C1OAR_EVHIST_CLK (0x0008) +#define U300_SYSCON_C1OAR_PPM_CLK (0x0004) +#define U300_SYSCON_C1OAR_DMA_CLK (0x0002) +/* Clock activity observability register 2 */ +#define U300_SYSCON_C2OAR (0x148) +#define U300_SYSCON_C2OAR_MASK (0x0FFF) +#define U300_SYSCON_C2OAR_VALUE (0x0FFF) +#define U300_SYSCON_C2OAR_XGAM_CDI_CLK (0x0800) +#define U300_SYSCON_C2OAR_XGAM_CLK (0x0400) +#define U300_SYSCON_C2OAR_VC_H_CLK (0x0200) +#define U300_SYSCON_C2OAR_VC_CLK (0x0100) +#define U300_SYSCON_C2OAR_UA_P_CLK (0x0080) +#define U300_SYSCON_C2OAR_TMR1_CLK (0x0040) +#define U300_SYSCON_C2OAR_TMR0_CLK (0x0020) +#define U300_SYSCON_C2OAR_SPI_P_CLK (0x0010) +#define U300_SYSCON_C2OAR_PCM_I2S1_CORE_CLK (0x0008) +#define U300_SYSCON_C2OAR_PCM_I2S1_CLK (0x0004) +#define U300_SYSCON_C2OAR_PCM_I2S0_CORE_CLK (0x0002) +#define U300_SYSCON_C2OAR_PCM_I2S0_CLK (0x0001) + +/* Chip ID register 16bit (R/-) */ +#define U300_SYSCON_CIDR (0x400) +/* Video IRQ clear 16bit (R/W) */ +#define U300_SYSCON_VICR (0x404) +#define U300_SYSCON_VICR_VIDEO1_IRQ_CLEAR_ENABLE (0x0002) +#define U300_SYSCON_VICR_VIDEO0_IRQ_CLEAR_ENABLE (0x0001) +/* SMCR */ +#define U300_SYSCON_SMCR (0x4d0) +#define U300_SYSCON_SMCR_FIELD_MASK (0x000e) +#define U300_SYSCON_SMCR_SEMI_SREFACK_IND (0x0008) +#define U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE (0x0004) +#define U300_SYSCON_SMCR_SEMI_EXT_BOOT_MODE_ENABLE (0x0002) +/* CPU_SW_DBGEN Software Debug Enable 16bit (R/W) */ +#define U300_SYSCON_CSDR (0x4f0) +#define U300_SYSCON_CSDR_SW_DEBUG_ENABLE (0x0001) +/* PRINT_CONTROL Print Control 16bit (R/-) */ +#define U300_SYSCON_PCR (0x4f8) +#define U300_SYSCON_PCR_SERV_IND (0x0001) +/* BOOT_CONTROL 16bit (R/-) */ +#define U300_SYSCON_BCR (0x4fc) +#define U300_SYSCON_BCR_ACC_CPU_SUBSYS_VINITHI_IND (0x0400) +#define U300_SYSCON_BCR_APP_CPU_SUBSYS_VINITHI_IND (0x0200) +#define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK (0x01FC) +#define U300_SYSCON_BCR_APP_BOOT_SERV_MASK (0x0003) + + +/* CPU clock defines */ +/** + * CPU high frequency in MHz + */ +#define SYSCON_CPU_CLOCK_HIGH 208 +/** + * CPU medium frequency in MHz + */ +#define SYSCON_CPU_CLOCK_MEDIUM 104 +/** + * CPU low frequency in MHz + */ +#define SYSCON_CPU_CLOCK_LOW 13 + +/* EMIF clock defines */ +/** + * EMIF high frequency in MHz + */ +#define SYSCON_EMIF_CLOCK_HIGH 104 +/** + * EMIF medium frequency in MHz + */ +#define SYSCON_EMIF_CLOCK_MEDIUM 104 +/** + * EMIF low frequency in MHz + */ +#define SYSCON_EMIF_CLOCK_LOW 13 + +/* AHB clock defines */ +/** + * AHB high frequency in MHz + */ +#define SYSCON_AHB_CLOCK_HIGH 52 +/** + * AHB medium frequency in MHz + */ +#define SYSCON_AHB_CLOCK_MEDIUM 52 +/** + * AHB low frequency in MHz + */ +#define SYSCON_AHB_CLOCK_LOW 7 /* i.e 13/2=6.5MHz */ + +enum syscon_busmaster { + SYSCON_BM_DMAC, + SYSCON_BM_XGAM, + SYSCON_BM_VIDEO_ENC +}; + +/* + * Note that this array must match the order of the array "clk_reg" + * in syscon.c + */ +enum syscon_clk { + SYSCON_CLKCONTROL_SLOW_BRIDGE, + SYSCON_CLKCONTROL_UART, + SYSCON_CLKCONTROL_BTR, + SYSCON_CLKCONTROL_EH, + SYSCON_CLKCONTROL_GPIO, + SYSCON_CLKCONTROL_KEYPAD, + SYSCON_CLKCONTROL_APP_TIMER, + SYSCON_CLKCONTROL_ACC_TIMER, + SYSCON_CLKCONTROL_FAST_BRIDGE, + SYSCON_CLKCONTROL_I2C0, + SYSCON_CLKCONTROL_I2C1, + SYSCON_CLKCONTROL_I2S0, + SYSCON_CLKCONTROL_I2S1, + SYSCON_CLKCONTROL_MMC, + SYSCON_CLKCONTROL_SPI, + SYSCON_CLKCONTROL_I2S0_CORE, + SYSCON_CLKCONTROL_I2S1_CORE, + SYSCON_CLKCONTROL_AAIF, + SYSCON_CLKCONTROL_AHB, + SYSCON_CLKCONTROL_APEX, + SYSCON_CLKCONTROL_CPU, + SYSCON_CLKCONTROL_DMA, + SYSCON_CLKCONTROL_EMIF, + SYSCON_CLKCONTROL_NAND_IF, + SYSCON_CLKCONTROL_VIDEO_ENC, + SYSCON_CLKCONTROL_XGAM, + SYSCON_CLKCONTROL_SEMI, + SYSCON_CLKCONTROL_AHB_SUBSYS, + SYSCON_CLKCONTROL_MSPRO +}; + +enum syscon_sysclk_mode { + SYSCON_SYSCLK_DISABLED, + SYSCON_SYSCLK_M_CLK, + SYSCON_SYSCLK_ACC_FSM, + SYSCON_SYSCLK_PLL60_48, + SYSCON_SYSCLK_PLL60_60, + SYSCON_SYSCLK_ACC_PLL208, + SYSCON_SYSCLK_APP_PLL13, + SYSCON_SYSCLK_APP_FSM, + SYSCON_SYSCLK_RTC, + SYSCON_SYSCLK_APP_PLL208 +}; + +enum syscon_sysclk_req { + SYSCON_SYSCLKREQ_DISABLED, + SYSCON_SYSCLKREQ_ACTIVE_LOW +}; + +enum syscon_clk_mode { + SYSCON_CLKMODE_OFF, + SYSCON_CLKMODE_DEFAULT, + SYSCON_CLKMODE_LOW, + SYSCON_CLKMODE_MEDIUM, + SYSCON_CLKMODE_HIGH, + SYSCON_CLKMODE_PERMANENT, + SYSCON_CLKMODE_ON, +}; + +enum syscon_call_mode { + SYSCON_CLKCALL_NOWAIT, + SYSCON_CLKCALL_WAIT, +}; + +int syscon_dc_on(bool keep_power_on); +int syscon_set_busmaster_active_state(enum syscon_busmaster busmaster, + bool active); +bool syscon_get_busmaster_active_state(void); +int syscon_set_sleep_mask(enum syscon_clk, + bool sleep_ctrl); +int syscon_config_sysclk(u32 sysclk, + enum syscon_sysclk_mode sysclkmode, + bool inverse, + u32 divisor, + enum syscon_sysclk_req sysclkreq); +bool syscon_can_turn_off_semi_clock(void); + +/* This function is restricted to core.c */ +int syscon_request_normal_power(bool req); + +/* This function is restricted to be used by platform_speed.c */ +int syscon_speed_request(enum syscon_call_mode wait_mode, + enum syscon_clk_mode req_clk_mode); +#endif /* __MACH_SYSCON_H */ diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h new file mode 100644 index 000000000000..88333dfb19fc --- /dev/null +++ b/arch/arm/mach-u300/include/mach/u300-regs.h @@ -0,0 +1,187 @@ +/* + * + * arch/arm/mach-u300/include/mach/u300-regs.h + * + * + * Copyright (C) 2006-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Basic register address definitions in physical memory and + * some block defintions for core devices like the timer. + * Author: Linus Walleij + */ + +#ifndef __MACH_U300_REGS_H +#define __MACH_U300_REGS_H + +/* + * These are the large blocks of memory allocated for I/O. + * the defines are used for setting up the I/O memory mapping. + */ + +/* NAND Flash CS0 */ +#define U300_NAND_CS0_PHYS_BASE 0x80000000 +#define U300_NAND_CS0_VIRT_BASE 0xff040000 + +/* NFIF */ +#define U300_NAND_IF_PHYS_BASE 0x9f800000 +#define U300_NAND_IF_VIRT_BASE 0xff030000 + +/* AHB Peripherals */ +#define U300_AHB_PER_PHYS_BASE 0xa0000000 +#define U300_AHB_PER_VIRT_BASE 0xff010000 + +/* FAST Peripherals */ +#define U300_FAST_PER_PHYS_BASE 0xc0000000 +#define U300_FAST_PER_VIRT_BASE 0xff020000 + +/* SLOW Peripherals */ +#define U300_SLOW_PER_PHYS_BASE 0xc0010000 +#define U300_SLOW_PER_VIRT_BASE 0xff000000 + +/* Boot ROM */ +#define U300_BOOTROM_PHYS_BASE 0xffff0000 +#define U300_BOOTROM_VIRT_BASE 0xffff0000 + +/* SEMI config base */ +#ifdef CONFIG_MACH_U300_BS335 +#define U300_SEMI_CONFIG_BASE 0x2FFE0000 +#else +#define U300_SEMI_CONFIG_BASE 0x30000000 +#endif + +/* + * All the following peripherals are specified at their PHYSICAL address, + * so if you need to access them (in the kernel), you MUST use the macros + * defined in to map to the IO_ADDRESS_AHB() IO_ADDRESS_FAST() + * etc. + */ + +/* + * AHB peripherals + */ + +/* AHB Peripherals Bridge Controller */ +#define U300_AHB_BRIDGE_BASE (U300_AHB_PER_PHYS_BASE+0x0000) + +/* Vectored Interrupt Controller 0, servicing 32 interrupts */ +#define U300_INTCON0_BASE (U300_AHB_PER_PHYS_BASE+0x1000) +#define U300_INTCON0_VBASE (U300_AHB_PER_VIRT_BASE+0x1000) + +/* Vectored Interrupt Controller 1, servicing 32 interrupts */ +#define U300_INTCON1_BASE (U300_AHB_PER_PHYS_BASE+0x2000) +#define U300_INTCON1_VBASE (U300_AHB_PER_VIRT_BASE+0x2000) + +/* Memory Stick Pro (MSPRO) controller */ +#define U300_MSPRO_BASE (U300_AHB_PER_PHYS_BASE+0x3000) + +/* EMIF Configuration Area */ +#define U300_EMIF_CFG_BASE (U300_AHB_PER_PHYS_BASE+0x4000) + + +/* + * FAST peripherals + */ + +/* FAST bridge control */ +#define U300_FAST_BRIDGE_BASE (U300_FAST_PER_PHYS_BASE+0x0000) + +/* MMC/SD controller */ +#define U300_MMCSD_BASE (U300_FAST_PER_PHYS_BASE+0x1000) + +/* PCM I2S0 controller */ +#define U300_PCM_I2S0_BASE (U300_FAST_PER_PHYS_BASE+0x2000) + +/* PCM I2S1 controller */ +#define U300_PCM_I2S1_BASE (U300_FAST_PER_PHYS_BASE+0x3000) + +/* I2C0 controller */ +#define U300_I2C0_BASE (U300_FAST_PER_PHYS_BASE+0x4000) + +/* I2C1 controller */ +#define U300_I2C1_BASE (U300_FAST_PER_PHYS_BASE+0x5000) + +/* SPI controller */ +#define U300_SPI_BASE (U300_FAST_PER_PHYS_BASE+0x6000) + +#ifdef CONFIG_MACH_U300_BS335 +/* Fast UART1 on U335 only */ +#define U300_UART1_BASE (U300_SLOW_PER_PHYS_BASE+0x7000) +#endif + +/* + * SLOW peripherals + */ + +/* SLOW bridge control */ +#define U300_SLOW_BRIDGE_BASE (U300_SLOW_PER_PHYS_BASE) + +/* SYSCON */ +#define U300_SYSCON_BASE (U300_SLOW_PER_PHYS_BASE+0x1000) +#define U300_SYSCON_VBASE (U300_SLOW_PER_VIRT_BASE+0x1000) + +/* Watchdog */ +#define U300_WDOG_BASE (U300_SLOW_PER_PHYS_BASE+0x2000) + +/* UART0 */ +#define U300_UART0_BASE (U300_SLOW_PER_PHYS_BASE+0x3000) + +/* APP side special timer */ +#define U300_TIMER_APP_BASE (U300_SLOW_PER_PHYS_BASE+0x4000) +#define U300_TIMER_APP_VBASE (U300_SLOW_PER_VIRT_BASE+0x4000) + +/* Keypad */ +#define U300_KEYPAD_BASE (U300_SLOW_PER_PHYS_BASE+0x5000) + +/* GPIO */ +#define U300_GPIO_BASE (U300_SLOW_PER_PHYS_BASE+0x6000) + +/* RTC */ +#define U300_RTC_BASE (U300_SLOW_PER_PHYS_BASE+0x7000) + +/* Bus tracer */ +#define U300_BUSTR_BASE (U300_SLOW_PER_PHYS_BASE+0x8000) + +/* Event handler (hardware queue) */ +#define U300_EVHIST_BASE (U300_SLOW_PER_PHYS_BASE+0x9000) + +/* Genric Timer */ +#define U300_TIMER_BASE (U300_SLOW_PER_PHYS_BASE+0xa000) + +/* PPM */ +#define U300_PPM_BASE (U300_SLOW_PER_PHYS_BASE+0xb000) + + +/* + * REST peripherals + */ + +/* ISP (image signal processor) is only available in U335 */ +#ifdef CONFIG_MACH_U300_BS335 +#define U300_ISP_BASE (0xA0008000) +#endif + +/* DMA Controller base */ +#define U300_DMAC_BASE (0xC0020000) + +/* MSL Base */ +#define U300_MSL_BASE (0xc0022000) + +/* APEX Base */ +#define U300_APEX_BASE (0xc0030000) + +/* Video Encoder Base */ +#ifdef CONFIG_MACH_U300_BS335 +#define U300_VIDEOENC_BASE (0xc0080000) +#else +#define U300_VIDEOENC_BASE (0xc0040000) +#endif + +/* XGAM Base */ +#define U300_XGAM_BASE (0xd0000000) + +/* + * Virtual accessor macros for static devices + */ + + +#endif -- GitLab From bd41b99d4661e775ff152f2842782c43dbb30a59 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 23 Apr 2009 21:15:04 +0100 Subject: [PATCH 0869/6080] [ARM] 5471/2: U300 GPIO and PADMUX support This adds GPIO and PADMUX headers and implementation for the U300 platform. This is an implementation in isolation that depend on later patches in this series to plug into the framework. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mach-u300/gpio.c | 701 +++++++++++++++++++++++++ arch/arm/mach-u300/include/mach/gpio.h | 290 ++++++++++ arch/arm/mach-u300/padmux.c | 58 ++ arch/arm/mach-u300/padmux.h | 19 + 4 files changed, 1068 insertions(+) create mode 100644 arch/arm/mach-u300/gpio.c create mode 100644 arch/arm/mach-u300/include/mach/gpio.h create mode 100644 arch/arm/mach-u300/padmux.c create mode 100644 arch/arm/mach-u300/padmux.h diff --git a/arch/arm/mach-u300/gpio.c b/arch/arm/mach-u300/gpio.c new file mode 100644 index 000000000000..2d5ae8ecb8c8 --- /dev/null +++ b/arch/arm/mach-u300/gpio.c @@ -0,0 +1,701 @@ +/* + * + * arch/arm/mach-u300/gpio.c + * + * + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * U300 GPIO module. + * This can driver either of the two basic GPIO cores + * available in the U300 platforms: + * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0) + * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) + * Notice that you also have inline macros in + * Author: Linus Walleij + * Author: Jonas Aaberg + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Need access to SYSCON registers for PADmuxing */ +#include + +#include "padmux.h" + +/* Reference to GPIO block clock */ +static struct clk *clk; + +/* Memory resource */ +static struct resource *memres; +static void __iomem *virtbase; + +struct u300_gpio_port { + const char *name; + int irq; + int number; +}; + + +static struct u300_gpio_port gpio_ports[] = { + { + .name = "gpio0", + .number = 0, + }, + { + .name = "gpio1", + .number = 1, + }, + { + .name = "gpio2", + .number = 2, + }, +#ifdef U300_COH901571_3 + { + .name = "gpio3", + .number = 3, + }, + { + .name = "gpio4", + .number = 4, + }, +#ifdef CONFIG_MACH_U300_BS335 + { + .name = "gpio5", + .number = 5, + }, + { + .name = "gpio6", + .number = 6, + }, +#endif +#endif + +}; + + +#ifdef U300_COH901571_3 + +/* Default input value */ +#define DEFAULT_OUTPUT_LOW 0 +#define DEFAULT_OUTPUT_HIGH 1 + +/* GPIO Pull-Up status */ +#define DISABLE_PULL_UP 0 +#define ENABLE_PULL_UP 1 + +#define GPIO_NOT_USED 0 +#define GPIO_IN 1 +#define GPIO_OUT 2 + +struct u300_gpio_configuration_data { + unsigned char pin_usage; + unsigned char default_output_value; + unsigned char pull_up; +}; + +/* Initial configuration */ +const struct u300_gpio_configuration_data +u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { +#ifdef CONFIG_MACH_U300_BS335 + /* Port 0, pins 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} + }, + /* Port 1, pins 0-7 */ + { + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} + }, + /* Port 2, pins 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} + }, + /* Port 3, pins 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} + }, + /* Port 4, pins 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} + }, + /* Port 5, pins 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} + }, + /* Port 6, pind 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} + } +#endif + +#ifdef CONFIG_MACH_U300_BS365 + /* Port 0, pins 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} + }, + /* Port 1, pins 0-7 */ + { + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} + }, + /* Port 2, pins 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} + }, + /* Port 3, pins 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} + }, + /* Port 4, pins 0-7 */ + { + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + /* These 4 pins doesn't exist on DB3210 */ + {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, + {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} + } +#endif +}; +#endif + + +/* No users == we can power down GPIO */ +static int gpio_users; + +struct gpio_struct { + int (*callback)(void *); + void *data; + int users; +}; + +static struct gpio_struct gpio_pin[U300_GPIO_MAX]; + +/* + * Let drivers register callback in order to get notified when there is + * an interrupt on the gpio pin + */ +int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data) +{ + if (gpio_pin[gpio].callback) + printk(KERN_WARNING "GPIO: %s: WARNING: callback already " \ + "registered for gpio pin#%d\n", __func__, gpio); + gpio_pin[gpio].callback = func; + gpio_pin[gpio].data = data; + + return 0; +} +EXPORT_SYMBOL(gpio_register_callback); + +int gpio_unregister_callback(unsigned gpio) +{ + if (!gpio_pin[gpio].callback) + printk(KERN_WARNING "GPIO: %s: WARNING: callback already " \ + "unregistered for gpio pin#%d\n", __func__, gpio); + gpio_pin[gpio].callback = NULL; + gpio_pin[gpio].data = NULL; + + return 0; +} +EXPORT_SYMBOL(gpio_unregister_callback); + +int gpio_request(unsigned gpio, const char *label) +{ + if (gpio_pin[gpio].users) + return -EINVAL; + else + gpio_pin[gpio].users++; + + gpio_users++; + + return 0; +} +EXPORT_SYMBOL(gpio_request); + +void gpio_free(unsigned gpio) +{ + gpio_users--; + gpio_pin[gpio].users--; + if (unlikely(gpio_pin[gpio].users < 0)) { + printk(KERN_WARNING "GPIO: Warning: gpio#%d release mismatch\n", + gpio); + gpio_pin[gpio].users = 0; + } + + return; +} +EXPORT_SYMBOL(gpio_free); + +/* This returns zero or nonzero */ +int gpio_get_value(unsigned gpio) +{ + return readl(virtbase + U300_GPIO_PXPDIR + + PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07)); +} +EXPORT_SYMBOL(gpio_get_value); + +/* + * We hope that the compiler will optimize away the unused branch + * in case "value" is a constant + */ +void gpio_set_value(unsigned gpio, int value) +{ + u32 val; + unsigned long flags; + + local_irq_save(flags); + if (value) { + /* set */ + val = readl(virtbase + U300_GPIO_PXPDOR + + PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) + & (1 << (gpio & 0x07)); + writel(val | (1 << (gpio & 0x07)), virtbase + + U300_GPIO_PXPDOR + + PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); + } else { + /* clear */ + val = readl(virtbase + U300_GPIO_PXPDOR + + PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) + & (1 << (gpio & 0x07)); + writel(val & ~(1 << (gpio & 0x07)), virtbase + + U300_GPIO_PXPDOR + + PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); + } + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_set_value); + +int gpio_direction_input(unsigned gpio) +{ + unsigned long flags; + u32 val; + + if (gpio > U300_GPIO_MAX) + return -EINVAL; + + local_irq_save(flags); + val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + /* Mask out this pin*/ + val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1)); + /* This is not needed since it sets the bits to zero.*/ + /* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */ + writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + local_irq_restore(flags); + return 0; +} +EXPORT_SYMBOL(gpio_direction_input); + +int gpio_direction_output(unsigned gpio, int value) +{ + unsigned long flags; + u32 val; + + if (gpio > U300_GPIO_MAX) + return -EINVAL; + + local_irq_save(flags); + val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + /* Mask out this pin */ + val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1)); + /* + * FIXME: configure for push/pull, open drain or open source per pin + * in setup. The current driver will only support push/pull. + */ + val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL + << ((gpio & 0x07) << 1)); + writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + gpio_set_value(gpio, value); + local_irq_restore(flags); + return 0; +} +EXPORT_SYMBOL(gpio_direction_output); + +/* + * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0). + */ +void enable_irq_on_gpio_pin(unsigned gpio, int edge) +{ + u32 val; + unsigned long flags; + local_irq_save(flags); + + val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + val |= (1 << (gpio & 0x07)); + writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + if (edge) + val |= (1 << (gpio & 0x07)); + else + val &= ~(1 << (gpio & 0x07)); + writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + local_irq_restore(flags); +} +EXPORT_SYMBOL(enable_irq_on_gpio_pin); + +void disable_irq_on_gpio_pin(unsigned gpio) +{ + u32 val; + unsigned long flags; + + local_irq_save(flags); + val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + val &= ~(1 << (gpio & 0x07)); + writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + local_irq_restore(flags); +} +EXPORT_SYMBOL(disable_irq_on_gpio_pin); + +/* Enable (value == 0) or disable (value == 1) internal pullup */ +void gpio_pullup(unsigned gpio, int value) +{ + u32 val; + unsigned long flags; + + local_irq_save(flags); + if (value) { + val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER + + PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); + } else { + val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) * + U300_GPIO_PORTX_SPACING); + writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER + + PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); + } + local_irq_restore(flags); +} +EXPORT_SYMBOL(gpio_pullup); + +static irqreturn_t gpio_irq_handler(int irq, void *dev_id) +{ + struct u300_gpio_port *port = dev_id; + u32 val; + int pin; + + /* Read event register */ + val = readl(virtbase + U300_GPIO_PXIEV + port->number * + U300_GPIO_PORTX_SPACING); + /* Mask with enable register */ + val &= readl(virtbase + U300_GPIO_PXIEV + port->number * + U300_GPIO_PORTX_SPACING); + /* Mask relevant bits */ + val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK; + /* ACK IRQ (clear event) */ + writel(val, virtbase + U300_GPIO_PXIEV + port->number * + U300_GPIO_PORTX_SPACING); + /* Print message */ + while (val != 0) { + unsigned gpio; + + pin = __ffs(val); + /* mask off this pin */ + val &= ~(1 << pin); + gpio = (port->number << 3) + pin; + + if (gpio_pin[gpio].callback) + (void)gpio_pin[gpio].callback(gpio_pin[gpio].data); + else + printk(KERN_DEBUG "GPIO: Stray GPIO IRQ on line %d\n", + gpio); + } + return IRQ_HANDLED; +} + +static void gpio_set_initial_values(void) +{ +#ifdef U300_COH901571_3 + int i, j; + unsigned long flags; + u32 val; + + /* Write default values to all pins */ + for (i = 0; i < U300_GPIO_NUM_PORTS; i++) { + val = 0; + for (j = 0; j < 8; j++) + val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j; + local_irq_save(flags); + writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING); + local_irq_restore(flags); + } + + /* + * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED' + * to output and 'GPIO_IN' to input for each port. And initalize + * default value on outputs. + */ + for (i = 0; i < U300_GPIO_NUM_PORTS; i++) { + for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) { + local_irq_save(flags); + val = readl(virtbase + U300_GPIO_PXPCR + + i * U300_GPIO_PORTX_SPACING); + /* Mask out this pin */ + val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1)); + + if (u300_gpio_config[i][j].pin_usage != GPIO_IN) + val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1)); + writel(val, virtbase + U300_GPIO_PXPCR + + i * U300_GPIO_PORTX_SPACING); + local_irq_restore(flags); + } + } + + /* Enable or disable the internal pull-ups in the GPIO ASIC block */ + for (i = 0; i < U300_GPIO_MAX; i++) { + val = 0; + for (j = 0; j < 8; j++) + val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP)) << j; + local_irq_save(flags); + writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING); + local_irq_restore(flags); + } +#endif +} + +static int __devinit gpio_probe(struct platform_device *pdev) +{ + u32 val; + int err = 0; + int i; + int num_irqs; + + memset(gpio_pin, 0, sizeof(gpio_pin)); + + /* Get GPIO clock */ + clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + err = PTR_ERR(clk); + printk(KERN_ERR "GPIO: could not get GPIO clock\n"); + goto err_no_clk; + } + err = clk_enable(clk); + if (err) { + printk(KERN_ERR "GPIO: could not enable GPIO clock\n"); + goto err_no_clk_enable; + } + + memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!memres) + goto err_no_resource; + + if (request_mem_region(memres->start, memres->end - memres->start, "GPIO Controller") + == NULL) { + err = -ENODEV; + goto err_no_ioregion; + } + + virtbase = ioremap(memres->start, memres->end - memres->start + 1); + if (!virtbase) { + err = -ENOMEM; + goto err_no_ioremap; + } + +#ifdef U300_COH901335 + printk(KERN_INFO "GPIO: Initializing GPIO Controller COH 901 335\n"); + /* Turn on the GPIO block */ + writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR); +#endif + +#ifdef U300_COH901571_3 + printk(KERN_INFO "GPIO: Initializing GPIO Controller COH 901 571/3\n"); + val = readl(virtbase + U300_GPIO_CR); + printk(KERN_INFO "GPIO: COH901571/3 block version: %d, " \ + "number of cores: %d\n", + ((val & 0x0000FE00) >> 9), + ((val & 0x000001FC) >> 2)); + writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR); +#endif + + /* Set up some padmuxing here */ +#ifdef CONFIG_MMC + pmx_set_mission_mode_mmc(); +#endif +#ifdef CONFIG_SPI_PL022 + pmx_set_mission_mode_spi(); +#endif + + gpio_set_initial_values(); + + for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) { + + gpio_ports[num_irqs].irq = + platform_get_irq_byname(pdev, + gpio_ports[num_irqs].name); + + err = request_irq(gpio_ports[num_irqs].irq, + gpio_irq_handler, IRQF_DISABLED, + gpio_ports[num_irqs].name, + &gpio_ports[num_irqs]); + if (err) { + printk(KERN_CRIT "GPIO: Cannot allocate IRQ for %s!\n", + gpio_ports[num_irqs].name); + goto err_no_irq; + } + /* Turns off PortX_irq_force */ + writel(0x0, virtbase + U300_GPIO_PXIFR + + num_irqs * U300_GPIO_PORTX_SPACING); + } + printk(KERN_INFO "GPIO: U300 gpio module loaded\n"); + + return 0; + + err_no_irq: + for (i = 0; i < num_irqs; i++) + free_irq(gpio_ports[i].irq, &gpio_ports[i]); + iounmap(virtbase); + err_no_ioremap: + release_mem_region(memres->start, memres->end - memres->start); + err_no_ioregion: + err_no_resource: + clk_disable(clk); + err_no_clk_enable: + clk_put(clk); + err_no_clk: + printk(KERN_INFO "GPIO: module ERROR:%d\n", err); + return err; +} + +static int __devexit gpio_remove(struct platform_device *pdev) +{ + int i; + + /* Turn off the GPIO block */ + writel(0x00000000U, virtbase + U300_GPIO_CR); + for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++) + free_irq(gpio_ports[i].irq, &gpio_ports[i]); + iounmap(virtbase); + release_mem_region(memres->start, memres->end - memres->start); + clk_disable(clk); + clk_put(clk); + return 0; +} + +static struct platform_driver gpio_driver = { + .driver = { + .name = "u300-gpio", + }, + .probe = gpio_probe, + .remove = __devexit_p(gpio_remove), +}; + + +static int __init u300_gpio_init(void) +{ + return platform_driver_register(&gpio_driver); +} + +static void __exit u300_gpio_exit(void) +{ + platform_driver_unregister(&gpio_driver); +} + +arch_initcall(u300_gpio_init); +module_exit(u300_gpio_exit); + +MODULE_AUTHOR("Linus Walleij "); + +#ifdef U300_COH901571_3 +MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver"); +#endif + +#ifdef U300_COH901335 +MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver"); +#endif + +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h new file mode 100644 index 000000000000..c8174128d7eb --- /dev/null +++ b/arch/arm/mach-u300/include/mach/gpio.h @@ -0,0 +1,290 @@ +/* + * + * arch/arm/mach-u300/include/mach/gpio.h + * + * + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * GPIO block resgister definitions and inline macros for + * U300 GPIO COH 901 335 or COH 901 571/3 + * Author: Linus Walleij + */ + +#ifndef __MACH_U300_GPIO_H +#define __MACH_U300_GPIO_H + +#include +#include +#include +#include + +/* Switch type depending on platform/chip variant */ +#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) +#define U300_COH901335 +#endif +#if defined(CONFIG_MACH_U300_BS365) || defined(CONFIG_MACH_U300_BS335) +#define U300_COH901571_3 +#endif + +/* Get base address for regs here */ +#include "u300-regs.h" +/* IRQ numbers */ +#include "irqs.h" + +/* + * This is the GPIO block definitions. GPIO (General Purpose I/O) can be + * used for anything, and often is. The event/enable etc figures are for + * the lowermost pin (pin 0 on each port), shift this left to match your + * pin if you're gonna use these values. + */ +#ifdef U300_COH901335 +#define U300_GPIO_PORTX_SPACING (0x1C) +/* Port X Pin Data Register 32bit, this is both input and output (R/W) */ +#define U300_GPIO_PXPDIR (0x00) +#define U300_GPIO_PXPDOR (0x00) +/* Port X Pin Config Register 32bit (R/W) */ +#define U300_GPIO_PXPCR (0x04) +#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL) +#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL) +#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL) +#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL) +#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL) +#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL) +#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL) +/* Port X Interrupt Event Register 32bit (R/W) */ +#define U300_GPIO_PXIEV (0x08) +#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL) +#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL) +/* Port X Interrupt Enable Register 32bit (R/W) */ +#define U300_GPIO_PXIEN (0x0C) +#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL) +#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL) +/* Port X Interrupt Force Register 32bit (R/W) */ +#define U300_GPIO_PXIFR (0x10) +#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL) +#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL) +/* Port X Interrupt Config Register 32bit (R/W) */ +#define U300_GPIO_PXICR (0x14) +#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL) +#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL) +#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL) +#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) +/* Port X Pull-up Enable Register 32bit (R/W) */ +#define U300_GPIO_PXPER (0x18) +#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL) +#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL) +/* Control Register 32bit (R/W) */ +#define U300_GPIO_CR (0x54) +#define U300_GPIO_CR_BLOCK_CLOCK_ENABLE (0x00000001UL) +/* three ports of 8 bits each = GPIO pins 0..23 */ +#define U300_GPIO_NUM_PORTS 3 +#define U300_GPIO_PINS_PER_PORT 8 +#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1) +#endif + +#ifdef U300_COH901571_3 +/* + * Control Register 32bit (R/W) + * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores + * gives the number of GPIO pins. + * bit 8-2 (mask 0x000001FC) contains the core version ID. + */ +#define U300_GPIO_CR (0x00) +#define U300_GPIO_CR_SYNC_SEL_ENABLE (0x00000002UL) +#define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL) +#define U300_GPIO_PORTX_SPACING (0x30) +/* Port X Pin Data INPUT Register 32bit (R/W) */ +#define U300_GPIO_PXPDIR (0x04) +/* Port X Pin Data OUTPUT Register 32bit (R/W) */ +#define U300_GPIO_PXPDOR (0x08) +/* Port X Pin Config Register 32bit (R/W) */ +#define U300_GPIO_PXPCR (0x0C) +#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL) +#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL) +#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL) +#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL) +#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL) +#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL) +#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL) +/* Port X Pull-up Enable Register 32bit (R/W) */ +#define U300_GPIO_PXPER (0x10) +#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL) +#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL) +/* Port X Interrupt Event Register 32bit (R/W) */ +#define U300_GPIO_PXIEV (0x14) +#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL) +#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL) +/* Port X Interrupt Enable Register 32bit (R/W) */ +#define U300_GPIO_PXIEN (0x18) +#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL) +#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL) +/* Port X Interrupt Force Register 32bit (R/W) */ +#define U300_GPIO_PXIFR (0x1C) +#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL) +#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL) +/* Port X Interrupt Config Register 32bit (R/W) */ +#define U300_GPIO_PXICR (0x20) +#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL) +#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL) +#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL) +#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) +#ifdef CONFIG_MACH_U300_BS335 +/* seven ports of 8 bits each = GPIO pins 0..55 */ +#define U300_GPIO_NUM_PORTS 7 +#else +/* five ports of 8 bits each = GPIO pins 0..39 */ +#define U300_GPIO_NUM_PORTS 5 +#endif +#define U300_GPIO_PINS_PER_PORT 8 +#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1) +#endif + +/* + * Individual pin assignments for the B26/S26. Notice that the + * actual usage of these pins depends on the PAD MUX settings, that + * is why the same number can potentially appear several times. + * In the reference design each pin is only used for one purpose. + * These were determined by inspecting the B26/S26 schematic: + * 2/1911-ROA 128 1603 + */ +#ifdef CONFIG_MACH_U300_BS2X +#define U300_GPIO_PIN_UART_RX 0 +#define U300_GPIO_PIN_UART_TX 1 +#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */ +#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */ +#define U300_GPIO_PIN_CAM_SLEEP 4 +#define U300_GPIO_PIN_CAM_REG_EN 5 +#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */ +#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */ + +#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */ +#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */ +#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */ +#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */ +#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */ +#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */ +#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */ +#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */ + +#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */ +#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */ +#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */ +#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */ +#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */ +#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */ +#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */ +#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */ +#endif + +/* + * Individual pin assignments for the B330/S330 and B365/S365. + * Notice that the actual usage of these pins depends on the + * PAD MUX settings, that is why the same number can potentially + * appear several times. In the reference design each pin is only + * used for one purpose. These were determined by inspecting the + * S365 schematic. + */ +#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \ + defined(CONFIG_MACH_U300_BS335) +#define U300_GPIO_PIN_UART_RX 0 +#define U300_GPIO_PIN_UART_TX 1 +#define U300_GPIO_PIN_UART_CTS 2 +#define U300_GPIO_PIN_UART_RTS 3 +#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */ +#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */ +#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */ +#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */ + +#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */ +#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */ +#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */ +#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */ +#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */ +#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */ +#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */ +#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */ + +#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */ +#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */ +#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */ +#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */ +#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */ +#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */ +#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */ +#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */ + +#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */ +#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */ +#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */ +#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */ +#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */ +#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */ +#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */ +#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */ + +#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */ +#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */ +#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */ +#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */ +#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */ +#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */ +#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */ +#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */ + +#ifdef CONFIG_MACH_U300_BS335 + +#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */ +#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */ +#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */ +#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */ +#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */ +#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */ +#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */ +#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */ + +#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */ +#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */ +#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */ +#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */ +#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */ +#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */ +#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */ +#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */ +#endif + +#endif + +/* translates a pin number to a port number */ +#define PIN_TO_PORT(val) (val >> 3) + +/* These can be found in arch/arm/mach-u300/gpio.c */ +extern int gpio_request(unsigned gpio, const char *label); +extern void gpio_free(unsigned gpio); +extern int gpio_direction_input(unsigned gpio); +extern int gpio_direction_output(unsigned gpio, int value); +extern int gpio_register_callback(unsigned gpio, + int (*func)(void *arg), + void *); +extern int gpio_unregister_callback(unsigned gpio); +extern void enable_irq_on_gpio_pin(unsigned gpio, int edge); +extern void disable_irq_on_gpio_pin(unsigned gpio); +extern void gpio_pullup(unsigned gpio, int value); +extern int gpio_get_value(unsigned gpio); +extern void gpio_set_value(unsigned gpio, int value); + +/* wrappers to sleep-enable the previous two functions */ +static inline unsigned gpio_to_irq(unsigned gpio) +{ + return PIN_TO_PORT(gpio) + IRQ_U300_GPIO_PORT0; +} + +static inline unsigned irq_to_gpio(unsigned irq) +{ + /* + * FIXME: This is no 1-1 mapping at all, it points to the + * whole block of 8 pins. + */ + return (irq - IRQ_U300_GPIO_PORT0) << 3; +} + +#endif diff --git a/arch/arm/mach-u300/padmux.c b/arch/arm/mach-u300/padmux.c new file mode 100644 index 000000000000..f3664564f086 --- /dev/null +++ b/arch/arm/mach-u300/padmux.c @@ -0,0 +1,58 @@ +/* + * + * arch/arm/mach-u300/padmux.c + * + * + * Copyright (C) 2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * U300 PADMUX functions + * Author: Linus Walleij + * + */ +#include +#include +#include +#include + +#include "padmux.h" + +/* Set the PAD MUX to route the MMC reader correctly to GPIO0. */ +void pmx_set_mission_mode_mmc(void) +{ + u16 val; + + val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMC1LR); + val &= ~U300_SYSCON_PMC1LR_MMCSD_MASK; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMC1LR); + val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMC1HR); + val &= ~U300_SYSCON_PMC1HR_APP_GPIO_1_MASK; + val |= U300_SYSCON_PMC1HR_APP_GPIO_1_MMC; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMC1HR); +} + +void pmx_set_mission_mode_spi(void) +{ + u16 val; + + /* Set up padmuxing so the SPI port and its chipselects are active */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMC1HR); + /* + * Activate the SPI port (disable the use of these pins for generic + * GPIO, DSP, AAIF + */ + val &= ~U300_SYSCON_PMC1HR_APP_SPI_2_MASK; + val |= U300_SYSCON_PMC1HR_APP_SPI_2_SPI; + /* + * Use GPIO pin SPI CS1 for CS1 actually (it can be used for other + * things also) + */ + val &= ~U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK; + val |= U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI; + /* + * Use GPIO pin SPI CS2 for CS2 actually (it can be used for other + * things also) + */ + val &= ~U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK; + val |= U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMC1HR); +} diff --git a/arch/arm/mach-u300/padmux.h b/arch/arm/mach-u300/padmux.h new file mode 100644 index 000000000000..8c2099ac5046 --- /dev/null +++ b/arch/arm/mach-u300/padmux.h @@ -0,0 +1,19 @@ +/* + * + * arch/arm/mach-u300/padmux.h + * + * + * Copyright (C) 2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * U300 PADMUX API + * Author: Linus Walleij + * + */ + +#ifndef __MACH_U300_PADMUX_H +#define __MACH_U300_PADMUX_H + +void pmx_set_mission_mode_mmc(void); +void pmx_set_mission_mode_spi(void); + +#endif -- GitLab From cd27e485410aa7e7464b0126d968fe8c2a5c045b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 23 Apr 2009 10:21:30 +0100 Subject: [PATCH 0870/6080] [ARM] 5474/1: U300 clocking framework This adds the clocking framework and hooks into the clkdevice for U300 series platforms. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mach-u300/clock.c | 1487 ++++++++++++++++++++++ arch/arm/mach-u300/clock.h | 53 + arch/arm/mach-u300/include/mach/clkdev.h | 7 + 3 files changed, 1547 insertions(+) create mode 100644 arch/arm/mach-u300/clock.c create mode 100644 arch/arm/mach-u300/clock.h create mode 100644 arch/arm/mach-u300/include/mach/clkdev.h diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c new file mode 100644 index 000000000000..d6f8232757ff --- /dev/null +++ b/arch/arm/mach-u300/clock.c @@ -0,0 +1,1487 @@ +/* + * + * arch/arm/mach-u300/clock.c + * + * + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Define clocks in the app platform. + * Author: Linus Walleij + * Author: Jonas Aaberg + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "clock.h" + +/* + * TODO: + * - move all handling of the CCR register into this file and create + * a spinlock for the CCR register + * - switch to the clkdevice lookup mechanism that maps clocks to + * device ID:s instead when it becomes available in kernel 2.6.29. + * - implement rate get/set for all clocks that need it. + */ + +/* + * Syscon clock I/O registers lock so clock requests don't collide + * NOTE: this is a local lock only used to lock access to clock and + * reset registers in syscon. + */ +static DEFINE_SPINLOCK(syscon_clkreg_lock); +static DEFINE_SPINLOCK(syscon_resetreg_lock); + +/* + * The clocking hierarchy currently looks like this. + * NOTE: the idea is NOT to show how the clocks are routed on the chip! + * The ideas is to show dependencies, so a clock higher up in the + * hierarchy has to be on in order for another clock to be on. Now, + * both CPU and DMA can actually be on top of the hierarchy, and that + * is not modeled currently. Instead we have the backbone AMBA bus on + * top. This bus cannot be programmed in any way but conceptually it + * needs to be active for the bridges and devices to transport data. + * + * Please be aware that a few clocks are hw controlled, which mean that + * the hw itself can turn on/off or change the rate of the clock when + * needed! + * + * AMBA bus + * | + * +- CPU + * +- NANDIF NAND Flash interface + * +- SEMI Shared Memory interface + * +- ISP Image Signal Processor (U335 only) + * +- CDS (U335 only) + * +- DMA Direct Memory Access Controller + * +- AAIF APP/ACC Inteface (Mobile Scalable Link, MSL) + * +- APEX + * +- VIDEO_ENC AVE2/3 Video Encoder + * +- XGAM Graphics Accelerator Controller + * +- AHB + * | + * +- ahb:0 AHB Bridge + * | | + * | +- ahb:1 INTCON Interrupt controller + * | +- ahb:3 MSPRO Memory Stick Pro controller + * | +- ahb:4 EMIF External Memory interface + * | + * +- fast:0 FAST bridge + * | | + * | +- fast:1 MMCSD MMC/SD card reader controller + * | +- fast:2 I2S0 PCM I2S channel 0 controller + * | +- fast:3 I2S1 PCM I2S channel 1 controller + * | +- fast:4 I2C0 I2C channel 0 controller + * | +- fast:5 I2C1 I2C channel 1 controller + * | +- fast:6 SPI SPI controller + * | +- fast:7 UART1 Secondary UART (U335 only) + * | + * +- slow:0 SLOW bridge + * | + * +- slow:1 SYSCON (not possible to control) + * +- slow:2 WDOG Watchdog + * +- slow:3 UART0 primary UART + * +- slow:4 TIMER_APP Application timer - used in Linux + * +- slow:5 KEYPAD controller + * +- slow:6 GPIO controller + * +- slow:7 RTC controller + * +- slow:8 BT Bus Tracer (not used currently) + * +- slow:9 EH Event Handler (not used currently) + * +- slow:a TIMER_ACC Access style timer (not used currently) + * +- slow:b PPM (U335 only, what is that?) + */ + +/* + * Reset control functions. We remember if a block has been + * taken out of reset and don't remove the reset assertion again + * and vice versa. Currently we only remove resets so the + * enablement function is defined out. + */ +static void syscon_block_reset_enable(struct clk *clk) +{ + u16 val; + unsigned long iflags; + + /* Not all blocks support resetting */ + if (!clk->res_reg || !clk->res_mask) + return; + spin_lock_irqsave(&syscon_resetreg_lock, iflags); + val = readw(clk->res_reg); + val |= clk->res_mask; + writew(val, clk->res_reg); + spin_unlock_irqrestore(&syscon_resetreg_lock, iflags); + clk->reset = true; +} + +static void syscon_block_reset_disable(struct clk *clk) +{ + u16 val; + unsigned long iflags; + + /* Not all blocks support resetting */ + if (!clk->res_reg || !clk->res_mask) + return; + spin_lock_irqsave(&syscon_resetreg_lock, iflags); + val = readw(clk->res_reg); + val &= ~clk->res_mask; + writew(val, clk->res_reg); + spin_unlock_irqrestore(&syscon_resetreg_lock, iflags); + clk->reset = false; +} + +int __clk_get(struct clk *clk) +{ + u16 val; + + /* The MMC and MSPRO clocks need some special set-up */ + if (!strcmp(clk->name, "MCLK")) { + /* Set default MMC clock divisor to 18.9 MHz */ + writew(0x0054U, U300_SYSCON_VBASE + U300_SYSCON_MMF0R); + val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR); + /* Disable the MMC feedback clock */ + val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE; + /* Disable MSPRO frequency */ + val &= ~U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR); + } + if (!strcmp(clk->name, "MSPRO")) { + val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR); + /* Disable the MMC feedback clock */ + val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE; + /* Enable MSPRO frequency */ + val |= U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR); + } + return 1; +} +EXPORT_SYMBOL(__clk_get); + +void __clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(__clk_put); + +static void syscon_clk_disable(struct clk *clk) +{ + unsigned long iflags; + + /* Don't touch the hardware controlled clocks */ + if (clk->hw_ctrld) + return; + + spin_lock_irqsave(&syscon_clkreg_lock, iflags); + writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCDR); + spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); +} + +static void syscon_clk_enable(struct clk *clk) +{ + unsigned long iflags; + + /* Don't touch the hardware controlled clocks */ + if (clk->hw_ctrld) + return; + + spin_lock_irqsave(&syscon_clkreg_lock, iflags); + writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCER); + spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); +} + +static u16 syscon_clk_get_rate(void) +{ + u16 val; + unsigned long iflags; + + spin_lock_irqsave(&syscon_clkreg_lock, iflags); + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); + val &= U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK; + spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); + return val; +} + +#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER +static void enable_i2s0_vcxo(void) +{ + u16 val; + unsigned long iflags; + + spin_lock_irqsave(&syscon_clkreg_lock, iflags); + /* Set I2S0 to use the VCXO 26 MHz clock */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); + val |= U300_SYSCON_CCR_TURN_VCXO_ON; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + val |= U300_SYSCON_CCR_I2S0_USE_VCXO; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR); + val |= U300_SYSCON_CEFR_I2S0_CLK_EN; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR); + spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); +} + +static void enable_i2s1_vcxo(void) +{ + u16 val; + unsigned long iflags; + + spin_lock_irqsave(&syscon_clkreg_lock, iflags); + /* Set I2S1 to use the VCXO 26 MHz clock */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); + val |= U300_SYSCON_CCR_TURN_VCXO_ON; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + val |= U300_SYSCON_CCR_I2S1_USE_VCXO; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR); + val |= U300_SYSCON_CEFR_I2S1_CLK_EN; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR); + spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); +} + +static void disable_i2s0_vcxo(void) +{ + u16 val; + unsigned long iflags; + + spin_lock_irqsave(&syscon_clkreg_lock, iflags); + /* Disable I2S0 use of the VCXO 26 MHz clock */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); + val &= ~U300_SYSCON_CCR_I2S0_USE_VCXO; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + /* Deactivate VCXO if noone else is using VCXO */ + if (!(val & U300_SYSCON_CCR_I2S1_USE_VCXO)) + val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR); + val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR); + spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); +} + +static void disable_i2s1_vcxo(void) +{ + u16 val; + unsigned long iflags; + + spin_lock_irqsave(&syscon_clkreg_lock, iflags); + /* Disable I2S1 use of the VCXO 26 MHz clock */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); + val &= ~U300_SYSCON_CCR_I2S1_USE_VCXO; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + /* Deactivate VCXO if noone else is using VCXO */ + if (!(val & U300_SYSCON_CCR_I2S0_USE_VCXO)) + val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR); + val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR); + spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); +} +#endif /* CONFIG_MACH_U300_USE_I2S_AS_MASTER */ + + +static void syscon_clk_rate_set_mclk(unsigned long rate) +{ + u16 val; + u32 reg; + unsigned long iflags; + + switch (rate) { + case 18900000: + val = 0x0054; + break; + case 20800000: + val = 0x0044; + break; + case 23100000: + val = 0x0043; + break; + case 26000000: + val = 0x0033; + break; + case 29700000: + val = 0x0032; + break; + case 34700000: + val = 0x0022; + break; + case 41600000: + val = 0x0021; + break; + case 52000000: + val = 0x0011; + break; + case 104000000: + val = 0x0000; + break; + default: + printk(KERN_ERR "Trying to set MCLK to unknown speed! %ld\n", + rate); + return; + } + + spin_lock_irqsave(&syscon_clkreg_lock, iflags); + reg = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) & + ~U300_SYSCON_MMF0R_MASK; + writew(reg | val, U300_SYSCON_VBASE + U300_SYSCON_MMF0R); + spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); +} + +void syscon_clk_rate_set_cpuclk(unsigned long rate) +{ + u16 val; + unsigned long iflags; + + switch (rate) { + case 13000000: + val = U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER; + break; + case 52000000: + val = U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE; + break; + case 104000000: + val = U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH; + break; + case 208000000: + val = U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST; + break; + default: + return; + } + spin_lock_irqsave(&syscon_clkreg_lock, iflags); + val |= readw(U300_SYSCON_VBASE + U300_SYSCON_CCR) & + ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK ; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + spin_unlock_irqrestore(&syscon_clkreg_lock, iflags); +} +EXPORT_SYMBOL(syscon_clk_rate_set_cpuclk); + +void clk_disable(struct clk *clk) +{ + unsigned long iflags; + + spin_lock_irqsave(&clk->lock, iflags); + if (clk->usecount > 0 && !(--clk->usecount)) { + /* some blocks lack clocking registers and cannot be disabled */ + if (clk->disable) + clk->disable(clk); + if (likely((u32)clk->parent)) + clk_disable(clk->parent); + } +#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER + if (unlikely(!strcmp(clk->name, "I2S0"))) + disable_i2s0_vcxo(); + if (unlikely(!strcmp(clk->name, "I2S1"))) + disable_i2s1_vcxo(); +#endif + spin_unlock_irqrestore(&clk->lock, iflags); +} +EXPORT_SYMBOL(clk_disable); + +int clk_enable(struct clk *clk) +{ + int ret = 0; + unsigned long iflags; + + spin_lock_irqsave(&clk->lock, iflags); + if (clk->usecount++ == 0) { + if (likely((u32)clk->parent)) + ret = clk_enable(clk->parent); + + if (unlikely(ret != 0)) + clk->usecount--; + else { + /* remove reset line (we never enable reset again) */ + syscon_block_reset_disable(clk); + /* clocks without enable function are always on */ + if (clk->enable) + clk->enable(clk); +#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER + if (unlikely(!strcmp(clk->name, "I2S0"))) + enable_i2s0_vcxo(); + if (unlikely(!strcmp(clk->name, "I2S1"))) + enable_i2s1_vcxo(); +#endif + } + } + spin_unlock_irqrestore(&clk->lock, iflags); + return ret; + +} +EXPORT_SYMBOL(clk_enable); + +/* Returns the clock rate in Hz */ +static unsigned long clk_get_rate_cpuclk(struct clk *clk) +{ + u16 val; + + val = syscon_clk_get_rate(); + + switch (val) { + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: + return 13000000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: + return 52000000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: + return 104000000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: + return 208000000; + default: + break; + } + return clk->rate; +} + +static unsigned long clk_get_rate_ahb_clk(struct clk *clk) +{ + u16 val; + + val = syscon_clk_get_rate(); + + switch (val) { + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: + return 6500000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: + return 26000000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: + return 52000000; + default: + break; + } + return clk->rate; + +} + +static unsigned long clk_get_rate_emif_clk(struct clk *clk) +{ + u16 val; + + val = syscon_clk_get_rate(); + + switch (val) { + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: + return 13000000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: + return 52000000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: + return 104000000; + default: + break; + } + return clk->rate; + +} + +static unsigned long clk_get_rate_xgamclk(struct clk *clk) +{ + u16 val; + + val = syscon_clk_get_rate(); + + switch (val) { + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: + return 6500000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: + return 26000000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: + return 52000000; + default: + break; + } + + return clk->rate; +} + +static unsigned long clk_get_rate_mclk(struct clk *clk) +{ + u16 val; + + val = syscon_clk_get_rate(); + + switch (val) { + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: + /* + * Here, the 208 MHz PLL gets shut down and the always + * on 13 MHz PLL used for RTC etc kicks into use + * instead. + */ + return 13000000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: + { + /* + * This clock is under program control. The register is + * divided in two nybbles, bit 7-4 gives cycles-1 to count + * high, bit 3-0 gives cycles-1 to count low. Distribute + * these with no more than 1 cycle difference between + * low and high and add low and high to get the actual + * divisor. The base PLL is 208 MHz. Writing 0x00 will + * divide by 1 and 1 so the highest frequency possible + * is 104 MHz. + * + * e.g. 0x54 => + * f = 208 / ((5+1) + (4+1)) = 208 / 11 = 18.9 MHz + */ + u16 val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) & + U300_SYSCON_MMF0R_MASK; + switch (val) { + case 0x0054: + return 18900000; + case 0x0044: + return 20800000; + case 0x0043: + return 23100000; + case 0x0033: + return 26000000; + case 0x0032: + return 29700000; + case 0x0022: + return 34700000; + case 0x0021: + return 41600000; + case 0x0011: + return 52000000; + case 0x0000: + return 104000000; + default: + break; + } + } + default: + break; + } + + return clk->rate; +} + +static unsigned long clk_get_rate_i2s_i2c_spi(struct clk *clk) +{ + u16 val; + + val = syscon_clk_get_rate(); + + switch (val) { + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW: + return 13000000; + case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH: + case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST: + return 26000000; + default: + break; + } + + return clk->rate; +} + +unsigned long clk_get_rate(struct clk *clk) +{ + if (clk->get_rate) + return clk->get_rate(clk); + else + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +static unsigned long clk_round_rate_mclk(struct clk *clk, unsigned long rate) +{ + if (rate >= 18900000) + return 18900000; + if (rate >= 20800000) + return 20800000; + if (rate >= 23100000) + return 23100000; + if (rate >= 26000000) + return 26000000; + if (rate >= 29700000) + return 29700000; + if (rate >= 34700000) + return 34700000; + if (rate >= 41600000) + return 41600000; + if (rate >= 52000000) + return 52000000; + return -EINVAL; +} + +static unsigned long clk_round_rate_cpuclk(struct clk *clk, unsigned long rate) +{ + if (rate >= 13000000) + return 13000000; + if (rate >= 52000000) + return 52000000; + if (rate >= 104000000) + return 104000000; + if (rate >= 208000000) + return 208000000; + return -EINVAL; +} + +/* + * This adjusts a requested rate to the closest exact rate + * a certain clock can provide. For a fixed clock it's + * mostly clk->rate. + */ +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + /* TODO: get apropriate switches for EMIFCLK, AHBCLK and MCLK */ + /* Else default to fixed value */ + + if (clk->round_rate) { + return (long) clk->round_rate(clk, rate); + } else { + printk(KERN_ERR "clock: Failed to round rate of %s\n", + clk->name); + } + return (long) clk->rate; +} +EXPORT_SYMBOL(clk_round_rate); + +static int clk_set_rate_mclk(struct clk *clk, unsigned long rate) +{ + syscon_clk_rate_set_mclk(clk_round_rate(clk, rate)); + return 0; +} + +static int clk_set_rate_cpuclk(struct clk *clk, unsigned long rate) +{ + syscon_clk_rate_set_cpuclk(clk_round_rate(clk, rate)); + return 0; +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + /* TODO: set for EMIFCLK and AHBCLK */ + /* Else assume the clock is fixed and fail */ + if (clk->set_rate) { + return clk->set_rate(clk, rate); + } else { + printk(KERN_ERR "clock: Failed to set %s to %ld hz\n", + clk->name, rate); + return -1; + } +} +EXPORT_SYMBOL(clk_set_rate); + +/* + * Clock definitions. The clock parents are set to respective + * bridge and the clock framework makes sure that the clocks have + * parents activated and are brought out of reset when in use. + * + * Clocks that have hw_ctrld = true are hw controlled, and the hw + * can by itself turn these clocks on and off. + * So in other words, we don't really have to care about them. + */ + +static struct clk amba_clk = { + .name = "AMBA", + .rate = 52000000, /* this varies! */ + .hw_ctrld = true, + .reset = false, +}; + +/* + * These blocks are connected directly to the AMBA bus + * with no bridge. + */ + +static struct clk cpu_clk = { + .name = "CPU", + .parent = &amba_clk, + .rate = 208000000, /* this varies! */ + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_CPU_RESET_EN, + .set_rate = clk_set_rate_cpuclk, + .get_rate = clk_get_rate_cpuclk, + .round_rate = clk_round_rate_cpuclk, +}; + +static struct clk nandif_clk = { + .name = "NANDIF", + .parent = &amba_clk, + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_NANDIF_RESET_EN, + .clk_val = U300_SYSCON_SBCER_NANDIF_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk semi_clk = { + .name = "SEMI", + .parent = &amba_clk, + .rate = 0, /* FIXME */ + /* It is not possible to reset SEMI */ + .hw_ctrld = false, + .reset = false, + .clk_val = U300_SYSCON_SBCER_SEMI_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +#ifdef CONFIG_MACH_U300_BS335 +static struct clk isp_clk = { + .name = "ISP", + .parent = &amba_clk, + .rate = 0, /* FIXME */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_ISP_RESET_EN, + .clk_val = U300_SYSCON_SBCER_ISP_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk cds_clk = { + .name = "CDS", + .parent = &amba_clk, + .rate = 0, /* FIXME */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_CDS_RESET_EN, + .clk_val = U300_SYSCON_SBCER_CDS_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; +#endif + +static struct clk dma_clk = { + .name = "DMA", + .parent = &amba_clk, + .rate = 52000000, /* this varies! */ + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_DMAC_RESET_EN, + .clk_val = U300_SYSCON_SBCER_DMAC_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk aaif_clk = { + .name = "AAIF", + .parent = &amba_clk, + .rate = 52000000, /* this varies! */ + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_AAIF_RESET_EN, + .clk_val = U300_SYSCON_SBCER_AAIF_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk apex_clk = { + .name = "APEX", + .parent = &amba_clk, + .rate = 0, /* FIXME */ + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_APEX_RESET_EN, + .clk_val = U300_SYSCON_SBCER_APEX_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk video_enc_clk = { + .name = "VIDEO_ENC", + .parent = &amba_clk, + .rate = 208000000, /* this varies! */ + .hw_ctrld = false, + .reset = false, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + /* This has XGAM in the name but refers to the video encoder */ + .res_mask = U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN, + .clk_val = U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk xgam_clk = { + .name = "XGAMCLK", + .parent = &amba_clk, + .rate = 52000000, /* this varies! */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_XGAM_RESET_EN, + .clk_val = U300_SYSCON_SBCER_XGAM_CLK_EN, + .get_rate = clk_get_rate_xgamclk, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +/* This clock is used to activate the video encoder */ +static struct clk ahb_clk = { + .name = "AHB", + .parent = &amba_clk, + .rate = 52000000, /* this varies! */ + .hw_ctrld = false, /* This one is set to false due to HW bug */ + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_AHB_RESET_EN, + .clk_val = U300_SYSCON_SBCER_AHB_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, + .get_rate = clk_get_rate_ahb_clk, +}; + + +/* + * Clocks on the AHB bridge + */ + +static struct clk ahb_subsys_clk = { + .name = "AHB_SUBSYS", + .parent = &amba_clk, + .rate = 52000000, /* this varies! */ + .hw_ctrld = true, + .reset = false, + .clk_val = U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, + .get_rate = clk_get_rate_ahb_clk, +}; + +static struct clk intcon_clk = { + .name = "INTCON", + .parent = &ahb_subsys_clk, + .rate = 52000000, /* this varies! */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_INTCON_RESET_EN, + /* INTCON can be reset but not clock-gated */ +}; + +static struct clk mspro_clk = { + .name = "MSPRO", + .parent = &ahb_subsys_clk, + .rate = 0, /* FIXME */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_MSPRO_RESET_EN, + .clk_val = U300_SYSCON_SBCER_MSPRO_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk emif_clk = { + .name = "EMIF", + .parent = &ahb_subsys_clk, + .rate = 104000000, /* this varies! */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR, + .res_mask = U300_SYSCON_RRR_EMIF_RESET_EN, + .clk_val = U300_SYSCON_SBCER_EMIF_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, + .get_rate = clk_get_rate_emif_clk, +}; + + +/* + * Clocks on the FAST bridge + */ +static struct clk fast_clk = { + .name = "FAST_BRIDGE", + .parent = &amba_clk, + .rate = 13000000, /* this varies! */ + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR, + .res_mask = U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE, + .clk_val = U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk mmcsd_clk = { + .name = "MCLK", + .parent = &fast_clk, + .rate = 18900000, /* this varies! */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR, + .res_mask = U300_SYSCON_RFR_MMC_RESET_ENABLE, + .clk_val = U300_SYSCON_SBCER_MMC_CLK_EN, + .get_rate = clk_get_rate_mclk, + .set_rate = clk_set_rate_mclk, + .round_rate = clk_round_rate_mclk, + .disable = syscon_clk_disable, + .enable = syscon_clk_enable, +}; + +static struct clk i2s0_clk = { + .name = "i2s0", + .parent = &fast_clk, + .rate = 26000000, /* this varies! */ + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR, + .res_mask = U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE, + .clk_val = U300_SYSCON_SBCER_I2S0_CORE_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, + .get_rate = clk_get_rate_i2s_i2c_spi, +}; + +static struct clk i2s1_clk = { + .name = "i2s1", + .parent = &fast_clk, + .rate = 26000000, /* this varies! */ + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR, + .res_mask = U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE, + .clk_val = U300_SYSCON_SBCER_I2S1_CORE_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, + .get_rate = clk_get_rate_i2s_i2c_spi, +}; + +static struct clk i2c0_clk = { + .name = "I2C0", + .parent = &fast_clk, + .rate = 26000000, /* this varies! */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR, + .res_mask = U300_SYSCON_RFR_I2C0_RESET_ENABLE, + .clk_val = U300_SYSCON_SBCER_I2C0_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, + .get_rate = clk_get_rate_i2s_i2c_spi, +}; + +static struct clk i2c1_clk = { + .name = "I2C1", + .parent = &fast_clk, + .rate = 26000000, /* this varies! */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR, + .res_mask = U300_SYSCON_RFR_I2C1_RESET_ENABLE, + .clk_val = U300_SYSCON_SBCER_I2C1_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, + .get_rate = clk_get_rate_i2s_i2c_spi, +}; + +static struct clk spi_clk = { + .name = "SPI", + .parent = &fast_clk, + .rate = 26000000, /* this varies! */ + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR, + .res_mask = U300_SYSCON_RFR_SPI_RESET_ENABLE, + .clk_val = U300_SYSCON_SBCER_SPI_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, + .get_rate = clk_get_rate_i2s_i2c_spi, +}; + +#ifdef CONFIG_MACH_U300_BS335 +static struct clk uart1_clk = { + .name = "UART1", + .parent = &fast_clk, + .rate = 13000000, + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR, + .res_mask = U300_SYSCON_RFR_UART1_RESET_ENABLE, + .clk_val = U300_SYSCON_SBCER_UART1_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; +#endif + + +/* + * Clocks on the SLOW bridge + */ +static struct clk slow_clk = { + .name = "SLOW_BRIDGE", + .parent = &amba_clk, + .rate = 13000000, + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN, + .clk_val = U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +/* TODO: implement SYSCON clock? */ + +static struct clk wdog_clk = { + .name = "WDOG", + .parent = &slow_clk, + .hw_ctrld = false, + .rate = 32768, + .reset = false, + /* This is always on, cannot be enabled/disabled or reset */ +}; + +/* This one is hardwired to PLL13 */ +static struct clk uart_clk = { + .name = "UARTCLK", + .parent = &slow_clk, + .rate = 13000000, + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_UART_RESET_EN, + .clk_val = U300_SYSCON_SBCER_UART_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk keypad_clk = { + .name = "KEYPAD", + .parent = &slow_clk, + .rate = 32768, + .hw_ctrld = false, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_KEYPAD_RESET_EN, + .clk_val = U300_SYSCON_SBCER_KEYPAD_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk gpio_clk = { + .name = "GPIO", + .parent = &slow_clk, + .rate = 13000000, + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_GPIO_RESET_EN, + .clk_val = U300_SYSCON_SBCER_GPIO_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk rtc_clk = { + .name = "RTC", + .parent = &slow_clk, + .rate = 32768, + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_RTC_RESET_EN, + /* This clock is always on, cannot be enabled/disabled */ +}; + +static struct clk bustr_clk = { + .name = "BUSTR", + .parent = &slow_clk, + .rate = 13000000, + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_BTR_RESET_EN, + .clk_val = U300_SYSCON_SBCER_BTR_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk evhist_clk = { + .name = "EVHIST", + .parent = &slow_clk, + .rate = 13000000, + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_EH_RESET_EN, + .clk_val = U300_SYSCON_SBCER_EH_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk timer_clk = { + .name = "TIMER", + .parent = &slow_clk, + .rate = 13000000, + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_ACC_TMR_RESET_EN, + .clk_val = U300_SYSCON_SBCER_ACC_TMR_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +static struct clk app_timer_clk = { + .name = "TIMER_APP", + .parent = &slow_clk, + .rate = 13000000, + .hw_ctrld = true, + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_APP_TMR_RESET_EN, + .clk_val = U300_SYSCON_SBCER_APP_TMR_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; + +#ifdef CONFIG_MACH_U300_BS335 +static struct clk ppm_clk = { + .name = "PPM", + .parent = &slow_clk, + .rate = 0, /* FIXME */ + .hw_ctrld = true, /* TODO: Look up if it is hw ctrld or not */ + .reset = true, + .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR, + .res_mask = U300_SYSCON_RSR_PPM_RESET_EN, + .clk_val = U300_SYSCON_SBCER_PPM_CLK_EN, + .enable = syscon_clk_enable, + .disable = syscon_clk_disable, +}; +#endif + +#define DEF_LOOKUP(devid, clkref) \ + { \ + .dev_id = devid, \ + .clk = clkref, \ + } + +/* + * Here we only define clocks that are meaningful to + * look up through clockdevice. + */ +static struct clk_lookup lookups[] = { + /* Connected directly to the AMBA bus */ + DEF_LOOKUP("amba", &amba_clk), + DEF_LOOKUP("cpu", &cpu_clk), + DEF_LOOKUP("nandif", &nandif_clk), + DEF_LOOKUP("semi", &semi_clk), +#ifdef CONFIG_MACH_U300_BS335 + DEF_LOOKUP("isp", &isp_clk), + DEF_LOOKUP("cds", &cds_clk), +#endif + DEF_LOOKUP("dma", &dma_clk), + DEF_LOOKUP("aaif", &aaif_clk), + DEF_LOOKUP("apex", &apex_clk), + DEF_LOOKUP("video_enc", &video_enc_clk), + DEF_LOOKUP("xgam", &xgam_clk), + DEF_LOOKUP("ahb", &ahb_clk), + /* AHB bridge clocks */ + DEF_LOOKUP("ahb", &ahb_subsys_clk), + DEF_LOOKUP("intcon", &intcon_clk), + DEF_LOOKUP("mspro", &mspro_clk), + DEF_LOOKUP("pl172", &emif_clk), + /* FAST bridge clocks */ + DEF_LOOKUP("fast", &fast_clk), + DEF_LOOKUP("mmci", &mmcsd_clk), + /* + * The .0 and .1 identifiers on these comes from the platform device + * .id field and are assigned when the platform devices are registered. + */ + DEF_LOOKUP("i2s.0", &i2s0_clk), + DEF_LOOKUP("i2s.1", &i2s1_clk), + DEF_LOOKUP("stddci2c.0", &i2c0_clk), + DEF_LOOKUP("stddci2c.1", &i2c1_clk), + DEF_LOOKUP("pl022", &spi_clk), +#ifdef CONFIG_MACH_U300_BS335 + DEF_LOOKUP("uart1", &uart1_clk), +#endif + /* SLOW bridge clocks */ + DEF_LOOKUP("slow", &slow_clk), + DEF_LOOKUP("wdog", &wdog_clk), + DEF_LOOKUP("uart0", &uart_clk), + DEF_LOOKUP("apptimer", &app_timer_clk), + DEF_LOOKUP("keypad", &keypad_clk), + DEF_LOOKUP("u300-gpio", &gpio_clk), + DEF_LOOKUP("rtc0", &rtc_clk), + DEF_LOOKUP("bustr", &bustr_clk), + DEF_LOOKUP("evhist", &evhist_clk), + DEF_LOOKUP("timer", &timer_clk), +#ifdef CONFIG_MACH_U300_BS335 + DEF_LOOKUP("ppm", &ppm_clk), +#endif +}; + +static void __init clk_register(void) +{ + int i; + + /* Register the lookups */ + for (i = 0; i < ARRAY_SIZE(lookups); i++) + clkdev_add(&lookups[i]); +} + +/* + * These are the clocks for cells registered as primecell drivers + * on the AMBA bus. These must be on during AMBA device registration + * since the bus probe will attempt to read magic configuration + * registers for these devices. If they are deactivated these probes + * will fail. + * + * + * Please note that on emif, both RAM and NAND is connected in dual + * RAM phones. On single RAM phones, ram is on semi and NAND on emif. + * + */ +void u300_clock_primecells(void) +{ + clk_enable(&intcon_clk); + clk_enable(&uart_clk); +#ifdef CONFIG_MACH_U300_BS335 + clk_enable(&uart1_clk); +#endif + clk_enable(&spi_clk); + + clk_enable(&mmcsd_clk); + +} +EXPORT_SYMBOL(u300_clock_primecells); + +void u300_unclock_primecells(void) +{ + + clk_disable(&intcon_clk); + clk_disable(&uart_clk); +#ifdef CONFIG_MACH_U300_BS335 + clk_disable(&uart1_clk); +#endif + clk_disable(&spi_clk); + clk_disable(&mmcsd_clk); + +} +EXPORT_SYMBOL(u300_unclock_primecells); + +/* + * The interrupt controller is enabled before the clock API is registered. + */ +void u300_enable_intcon_clock(void) +{ + clk_enable(&intcon_clk); +} +EXPORT_SYMBOL(u300_enable_intcon_clock); + +/* + * The timer is enabled before the clock API is registered. + */ +void u300_enable_timer_clock(void) +{ + clk_enable(&app_timer_clk); +} +EXPORT_SYMBOL(u300_enable_timer_clock); + +#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG)) +/* + * The following makes it possible to view the status (especially + * reference count and reset status) for the clocks in the platform + * by looking into the special file /u300_clocks + */ + +/* A list of all clocks in the platform */ +static struct clk *clks[] = { + /* Top node clock for the AMBA bus */ + &amba_clk, + /* Connected directly to the AMBA bus */ + &cpu_clk, + &nandif_clk, + &semi_clk, +#ifdef CONFIG_MACH_U300_BS335 + &isp_clk, + &cds_clk, +#endif + &dma_clk, + &aaif_clk, + &apex_clk, + &video_enc_clk, + &xgam_clk, + &ahb_clk, + + /* AHB bridge clocks */ + &ahb_subsys_clk, + &intcon_clk, + &mspro_clk, + &emif_clk, + /* FAST bridge clocks */ + &fast_clk, + &mmcsd_clk, + &i2s0_clk, + &i2s1_clk, + &i2c0_clk, + &i2c1_clk, + &spi_clk, +#ifdef CONFIG_MACH_U300_BS335 + &uart1_clk, +#endif + /* SLOW bridge clocks */ + &slow_clk, + &wdog_clk, + &uart_clk, + &app_timer_clk, + &keypad_clk, + &gpio_clk, + &rtc_clk, + &bustr_clk, + &evhist_clk, + &timer_clk, +#ifdef CONFIG_MACH_U300_BS335 + &ppm_clk, +#endif +}; + +static int u300_clocks_show(struct seq_file *s, void *data) +{ + struct clk *clk; + int i; + + seq_printf(s, "CLOCK DEVICE RESET STATE\t" \ + "ACTIVE\tUSERS\tHW CTRL FREQ\n"); + seq_printf(s, "---------------------------------------------" \ + "-----------------------------------------\n"); + for (i = 0; i < ARRAY_SIZE(clks); i++) { + clk = clks[i]; + if (clk != ERR_PTR(-ENOENT)) { + /* Format clock and device name nicely */ + char cdp[33]; + int chars; + + chars = snprintf(&cdp[0], 17, "%s", clk->name); + while (chars < 16) { + cdp[chars] = ' '; + chars++; + } + chars = snprintf(&cdp[16], 17, "%s", clk->dev ? + dev_name(clk->dev) : "N/A"); + while (chars < 16) { + cdp[chars+16] = ' '; + chars++; + } + cdp[32] = '\0'; + if (clk->get_rate) + seq_printf(s, + "%s%s\t%s\t%d\t%s\t%lu Hz\n", + &cdp[0], + clk->reset ? + "ASSERTED" : "RELEASED", + clk->usecount ? "ON" : "OFF", + clk->usecount, + clk->hw_ctrld ? "YES" : "NO ", + clk->get_rate(clk)); + else + seq_printf(s, + "%s%s\t%s\t%d\t%s\t" \ + "(unknown rate)\n", + &cdp[0], + clk->reset ? + "ASSERTED" : "RELEASED", + clk->usecount ? "ON" : "OFF", + clk->usecount, + clk->hw_ctrld ? "YES" : "NO "); + } + } + return 0; +} + +static int u300_clocks_open(struct inode *inode, struct file *file) +{ + return single_open(file, u300_clocks_show, NULL); +} + +static const struct file_operations u300_clocks_operations = { + .open = u300_clocks_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void init_clk_read_procfs(void) +{ + /* Expose a simple debugfs interface to view all clocks */ + (void) debugfs_create_file("u300_clocks", S_IFREG | S_IRUGO, + NULL, NULL, &u300_clocks_operations); +} +#else +static inline void init_clk_read_procfs(void) +{ +} +#endif + +static int __init u300_clock_init(void) +{ + u16 val; + + /* + * FIXME: shall all this powermanagement stuff really live here??? + */ + + /* Set system to run at PLL208, max performance, a known state. */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); + val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + /* Wait for the PLL208 to lock if not locked in yet */ + while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) & + U300_SYSCON_CSR_PLL208_LOCK_IND)); + + /* Power management enable */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR); + val |= U300_SYSCON_PMCR_PWR_MGNT_ENABLE; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR); + + clk_register(); + + init_clk_read_procfs(); + + /* + * Some of these may be on when we boot the system so make sure they + * are turned OFF. + */ + syscon_block_reset_enable(&timer_clk); + timer_clk.disable(&timer_clk); + + /* + * These shall be turned on by default when we boot the system + * so make sure they are ON. (Adding CPU here is a bit too much.) + * These clocks will be claimed by drivers later. + */ + syscon_block_reset_disable(&semi_clk); + syscon_block_reset_disable(&emif_clk); + semi_clk.enable(&semi_clk); + emif_clk.enable(&emif_clk); + + return 0; +} +/* initialize clocking early to be available later in the boot */ +core_initcall(u300_clock_init); diff --git a/arch/arm/mach-u300/clock.h b/arch/arm/mach-u300/clock.h new file mode 100644 index 000000000000..fc6d9ccfe7e3 --- /dev/null +++ b/arch/arm/mach-u300/clock.h @@ -0,0 +1,53 @@ +/* + * arch/arm/mach-u300/include/mach/clock.h + * + * Copyright (C) 2004 - 2005 Nokia corporation + * Written by Tuukka Tikkanen + * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc + * Copyright (C) 2007-2009 ST-Ericsson AB + * Adopted to ST-Ericsson U300 platforms by + * Jonas Aaberg + * + * 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 __MACH_CLOCK_H +#define __MACH_CLOCK_H + +#include + +struct clk { + struct list_head node; + struct module *owner; + struct device *dev; + const char *name; + struct clk *parent; + + spinlock_t lock; + unsigned long rate; + bool reset; + __u16 clk_val; + __s8 usecount; + __u32 res_reg; + __u16 res_mask; + + bool hw_ctrld; + + void (*recalc) (struct clk *); + int (*set_rate) (struct clk *, unsigned long); + unsigned long (*get_rate) (struct clk *); + unsigned long (*round_rate) (struct clk *, unsigned long); + void (*init) (struct clk *); + void (*enable) (struct clk *); + void (*disable) (struct clk *); +}; + +void u300_clock_primecells(void); +void u300_unclock_primecells(void); +void u300_enable_intcon_clock(void); +void u300_enable_timer_clock(void); + +#endif diff --git a/arch/arm/mach-u300/include/mach/clkdev.h b/arch/arm/mach-u300/include/mach/clkdev.h new file mode 100644 index 000000000000..92e3cc872c66 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/clkdev.h @@ -0,0 +1,7 @@ +#ifndef __MACH_CLKDEV_H +#define __MACH_CLKDEV_H + +int __clk_get(struct clk *clk); +void __clk_put(struct clk *clk); + +#endif -- GitLab From bb3cee2b35d2b9edab71997bd06040ff37483e08 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 23 Apr 2009 10:22:13 +0100 Subject: [PATCH 0871/6080] [ARM] 5473/1: U300 core machine support This adds core support for the ST-Ericsson U300 series platforms: U300, U330, U335 and U365. Supports memory mappings, interrupt controller, system timer (clocksource and clockevents), and binds to the existing drivers for the PrimeCells used in this design: PL190 (VIC), PL180 (MMC/SD host) and PL011 (UART). This is intented to serve as starting point for our mainling work, more patches to follow. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/mach-u300/Kconfig | 105 +++ arch/arm/mach-u300/Makefile | 11 + arch/arm/mach-u300/core.c | 649 ++++++++++++++++++ arch/arm/mach-u300/include/mach/debug-macro.S | 22 + arch/arm/mach-u300/include/mach/entry-macro.S | 40 ++ arch/arm/mach-u300/include/mach/memory.h | 42 ++ arch/arm/mach-u300/include/mach/platform.h | 19 + arch/arm/mach-u300/include/mach/system.h | 42 ++ arch/arm/mach-u300/include/mach/timex.h | 17 + arch/arm/mach-u300/include/mach/uncompress.h | 46 ++ arch/arm/mach-u300/include/mach/vmalloc.h | 12 + arch/arm/mach-u300/mmc.c | 216 ++++++ arch/arm/mach-u300/mmc.h | 18 + arch/arm/mach-u300/timer.c | 422 ++++++++++++ arch/arm/mach-u300/u300.c | 55 ++ 15 files changed, 1716 insertions(+) create mode 100644 arch/arm/mach-u300/Kconfig create mode 100644 arch/arm/mach-u300/Makefile create mode 100644 arch/arm/mach-u300/core.c create mode 100644 arch/arm/mach-u300/include/mach/debug-macro.S create mode 100644 arch/arm/mach-u300/include/mach/entry-macro.S create mode 100644 arch/arm/mach-u300/include/mach/memory.h create mode 100644 arch/arm/mach-u300/include/mach/platform.h create mode 100644 arch/arm/mach-u300/include/mach/system.h create mode 100644 arch/arm/mach-u300/include/mach/timex.h create mode 100644 arch/arm/mach-u300/include/mach/uncompress.h create mode 100644 arch/arm/mach-u300/include/mach/vmalloc.h create mode 100644 arch/arm/mach-u300/mmc.c create mode 100644 arch/arm/mach-u300/mmc.h create mode 100644 arch/arm/mach-u300/timer.c create mode 100644 arch/arm/mach-u300/u300.c diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig new file mode 100644 index 000000000000..337b9aabce49 --- /dev/null +++ b/arch/arm/mach-u300/Kconfig @@ -0,0 +1,105 @@ +if ARCH_U300 + +menu "ST-Ericsson AB U300/U330/U335/U365 Platform" + +comment "ST-Ericsson Mobile Platform Products" + +config MACH_U300 + bool "U300" + +comment "ST-Ericsson U300/U330/U335/U365 Feature Selections" + +choice + prompt "U300/U330/U335/U365 system type" + default MACH_U300_BS2X + ---help--- + You need to select the target system, i.e. the + U300/U330/U335/U365 board that you want to compile your kernel + for. + +config MACH_U300_BS2X + bool "S26/S26/B25/B26 Test Products" + depends on MACH_U300 + help + Select this if you're developing on the + S26/S25 test products. (Also works on + B26/B25 big boards.) + +config MACH_U300_BS330 + bool "S330/B330 Test Products" + depends on MACH_U300 + help + Select this if you're developing on the + S330/B330 test products. + +config MACH_U300_BS335 + bool "S335/B335 Test Products" + depends on MACH_U300 + help + Select this if you're developing on the + S335/B335 test products. + +config MACH_U300_BS365 + bool "S365/B365 Test Products" + depends on MACH_U300 + help + Select this if you're developing on the + S365/B365 test products. + +endchoice + +choice + prompt "Memory configuration" + default MACH_U300_SINGLE_RAM + ---help--- + You have to config the kernel according to the physical memory + configuration. + +config MACH_U300_SINGLE_RAM + bool "Single RAM" + help + Select this if you want support for Single RAM phones. + +config MACH_U300_DUAL_RAM + bool "Dual RAM" + help + Select this if you want support for Dual RAM phones. + This is two RAM memorys on different EMIFs. +endchoice + +config U300_DEBUG + bool "Debug support for U300" + depends on PM + help + Debug support for U300 in sysfs, procfs etc. + +config MACH_U300_SEMI_IS_SHARED + bool "The SEMI is used by both the access and application side" + depends on MACH_U300 + help + This makes it possible to use the SEMI (Shared External + Memory Interface) from both from access and application + side. + +comment "All the settings below must match the bootloader's settings" + +config MACH_U300_ACCESS_MEM_SIZE + int "Access CPU memory allocation" + range 7 25 + depends on MACH_U300_SINGLE_RAM + default 13 + help + How much memory in MiB that the Access side CPU has allocated + +config MACH_U300_2MB_ALIGNMENT_FIX + bool "2MiB alignment fix" + depends on MACH_U300_SINGLE_RAM + default y + help + If yes and the Access side CPU has allocated an odd size in + MiB, this fix gives you one MiB extra that would otherwise be + lost due to Linux 2 MiB alignment policy. + +endmenu + +endif diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile new file mode 100644 index 000000000000..24950e0df4b4 --- /dev/null +++ b/arch/arm/mach-u300/Makefile @@ -0,0 +1,11 @@ +# +# Makefile for the linux kernel, U300 machine. +# + +obj-y := core.o clock.o timer.o gpio.o padmux.o +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_U300) += u300.o +obj-$(CONFIG_MMC) += mmc.o diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c new file mode 100644 index 000000000000..1f2ed21a0ab1 --- /dev/null +++ b/arch/arm/mach-u300/core.c @@ -0,0 +1,649 @@ +/* + * + * arch/arm/mach-u300/core.c + * + * + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Core platform support, IRQ handling and device definitions. + * Author: Linus Walleij + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "clock.h" +#include "mmc.h" + +/* + * Static I/O mappings that are needed for booting the U300 platforms. The + * only things we need are the areas where we find the timer, syscon and + * intcon, since the remaining device drivers will map their own memory + * physical to virtual as the need arise. + */ +static struct map_desc u300_io_desc[] __initdata = { + { + .virtual = U300_SLOW_PER_VIRT_BASE, + .pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE), + .length = SZ_64K, + .type = MT_DEVICE, + }, + { + .virtual = U300_AHB_PER_VIRT_BASE, + .pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE), + .length = SZ_32K, + .type = MT_DEVICE, + }, + { + .virtual = U300_FAST_PER_VIRT_BASE, + .pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE), + .length = SZ_32K, + .type = MT_DEVICE, + }, + { + .virtual = 0xffff2000, /* TCM memory */ + .pfn = __phys_to_pfn(0xffff2000), + .length = SZ_16K, + .type = MT_DEVICE, + }, + + /* + * This overlaps with the IRQ vectors etc at 0xffff0000, so these + * may have to be moved to 0x00000000 in order to use the ROM. + */ + /* + { + .virtual = U300_BOOTROM_VIRT_BASE, + .pfn = __phys_to_pfn(U300_BOOTROM_PHYS_BASE), + .length = SZ_64K, + .type = MT_ROM, + }, + */ +}; + +void __init u300_map_io(void) +{ + iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc)); +} + +/* + * Declaration of devices found on the U300 board and + * their respective memory locations. + */ +static struct amba_device uart0_device = { + .dev = { + .init_name = "uart0", /* Slow device at 0x3000 offset */ + .platform_data = NULL, + }, + .res = { + .start = U300_UART0_BASE, + .end = U300_UART0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_U300_UART0, NO_IRQ }, +}; + +/* The U335 have an additional UART1 on the APP CPU */ +#ifdef CONFIG_MACH_U300_BS335 +static struct amba_device uart1_device = { + .dev = { + .init_name = "uart1", /* Fast device at 0x7000 offset */ + .platform_data = NULL, + }, + .res = { + .start = U300_UART1_BASE, + .end = U300_UART1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = { IRQ_U300_UART1, NO_IRQ }, +}; +#endif + +static struct amba_device pl172_device = { + .dev = { + .init_name = "pl172", /* AHB device at 0x4000 offset */ + .platform_data = NULL, + }, + .res = { + .start = U300_EMIF_CFG_BASE, + .end = U300_EMIF_CFG_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + + +/* + * Everything within this next ifdef deals with external devices connected to + * the APP SPI bus. + */ +static struct amba_device pl022_device = { + .dev = { + .coherent_dma_mask = ~0, + .init_name = "pl022", /* Fast device at 0x6000 offset */ + }, + .res = { + .start = U300_SPI_BASE, + .end = U300_SPI_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_U300_SPI, NO_IRQ }, + /* + * This device has a DMA channel but the Linux driver does not use + * it currently. + */ +}; + +static struct amba_device mmcsd_device = { + .dev = { + .init_name = "mmci", /* Fast device at 0x1000 offset */ + .platform_data = NULL, /* Added later */ + }, + .res = { + .start = U300_MMCSD_BASE, + .end = U300_MMCSD_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + .irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }, + /* + * This device has a DMA channel but the Linux driver does not use + * it currently. + */ +}; + +/* + * The order of device declaration may be important, since some devices + * have dependencies on other devices being initialized first. + */ +static struct amba_device *amba_devs[] __initdata = { + &uart0_device, +#ifdef CONFIG_MACH_U300_BS335 + &uart1_device, +#endif + &pl022_device, + &pl172_device, + &mmcsd_device, +}; + +/* Here follows a list of all hw resources that the platform devices + * allocate. Note, clock dependencies are not included + */ + +static struct resource gpio_resources[] = { + { + .start = U300_GPIO_BASE, + .end = (U300_GPIO_BASE + SZ_4K - 1), + .flags = IORESOURCE_MEM, + }, + { + .name = "gpio0", + .start = IRQ_U300_GPIO_PORT0, + .end = IRQ_U300_GPIO_PORT0, + .flags = IORESOURCE_IRQ, + }, + { + .name = "gpio1", + .start = IRQ_U300_GPIO_PORT1, + .end = IRQ_U300_GPIO_PORT1, + .flags = IORESOURCE_IRQ, + }, + { + .name = "gpio2", + .start = IRQ_U300_GPIO_PORT2, + .end = IRQ_U300_GPIO_PORT2, + .flags = IORESOURCE_IRQ, + }, +#ifdef U300_COH901571_3 + { + .name = "gpio3", + .start = IRQ_U300_GPIO_PORT3, + .end = IRQ_U300_GPIO_PORT3, + .flags = IORESOURCE_IRQ, + }, + { + .name = "gpio4", + .start = IRQ_U300_GPIO_PORT4, + .end = IRQ_U300_GPIO_PORT4, + .flags = IORESOURCE_IRQ, + }, +#ifdef CONFIG_MACH_U300_BS335 + { + .name = "gpio5", + .start = IRQ_U300_GPIO_PORT5, + .end = IRQ_U300_GPIO_PORT5, + .flags = IORESOURCE_IRQ, + }, + { + .name = "gpio6", + .start = IRQ_U300_GPIO_PORT6, + .end = IRQ_U300_GPIO_PORT6, + .flags = IORESOURCE_IRQ, + }, +#endif /* CONFIG_MACH_U300_BS335 */ +#endif /* U300_COH901571_3 */ +}; + +static struct resource keypad_resources[] = { + { + .start = U300_KEYPAD_BASE, + .end = U300_KEYPAD_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "coh901461-press", + .start = IRQ_U300_KEYPAD_KEYBF, + .end = IRQ_U300_KEYPAD_KEYBF, + .flags = IORESOURCE_IRQ, + }, + { + .name = "coh901461-release", + .start = IRQ_U300_KEYPAD_KEYBR, + .end = IRQ_U300_KEYPAD_KEYBR, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource rtc_resources[] = { + { + .start = U300_RTC_BASE, + .end = U300_RTC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_U300_RTC, + .end = IRQ_U300_RTC, + .flags = IORESOURCE_IRQ, + }, +}; + +/* + * Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2) + * but these are not yet used by the driver. + */ +static struct resource fsmc_resources[] = { + { + .start = U300_NAND_IF_PHYS_BASE, + .end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct resource i2c0_resources[] = { + { + .start = U300_I2C0_BASE, + .end = U300_I2C0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_U300_I2C0, + .end = IRQ_U300_I2C0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource i2c1_resources[] = { + { + .start = U300_I2C1_BASE, + .end = U300_I2C1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_U300_I2C1, + .end = IRQ_U300_I2C1, + .flags = IORESOURCE_IRQ, + }, + +}; + +static struct resource wdog_resources[] = { + { + .start = U300_WDOG_BASE, + .end = U300_WDOG_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_U300_WDOG, + .end = IRQ_U300_WDOG, + .flags = IORESOURCE_IRQ, + } +}; + +/* TODO: These should be protected by suitable #ifdef's */ +static struct resource ave_resources[] = { + { + .name = "AVE3e I/O Area", + .start = U300_VIDEOENC_BASE, + .end = U300_VIDEOENC_BASE + SZ_512K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "AVE3e IRQ0", + .start = IRQ_U300_VIDEO_ENC_0, + .end = IRQ_U300_VIDEO_ENC_0, + .flags = IORESOURCE_IRQ, + }, + { + .name = "AVE3e IRQ1", + .start = IRQ_U300_VIDEO_ENC_1, + .end = IRQ_U300_VIDEO_ENC_1, + .flags = IORESOURCE_IRQ, + }, + { + .name = "AVE3e Physmem Area", + .start = 0, /* 0 will be remapped to reserved memory */ + .end = SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + /* + * The AVE3e requires two regions of 256MB that it considers + * "invisible". The hardware will not be able to access these + * adresses, so they should never point to system RAM. + */ + { + .name = "AVE3e Reserved 0", + .start = 0xd0000000, + .end = 0xd0000000 + SZ_256M - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "AVE3e Reserved 1", + .start = 0xe0000000, + .end = 0xe0000000 + SZ_256M - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device wdog_device = { + .name = "wdog", + .id = -1, + .num_resources = ARRAY_SIZE(wdog_resources), + .resource = wdog_resources, +}; + +static struct platform_device i2c0_device = { + .name = "stddci2c", + .id = 0, + .num_resources = ARRAY_SIZE(i2c0_resources), + .resource = i2c0_resources, +}; + +static struct platform_device i2c1_device = { + .name = "stddci2c", + .id = 1, + .num_resources = ARRAY_SIZE(i2c1_resources), + .resource = i2c1_resources, +}; + +static struct platform_device gpio_device = { + .name = "u300-gpio", + .id = -1, + .num_resources = ARRAY_SIZE(gpio_resources), + .resource = gpio_resources, +}; + +static struct platform_device keypad_device = { + .name = "keypad", + .id = -1, + .num_resources = ARRAY_SIZE(keypad_resources), + .resource = keypad_resources, +}; + +static struct platform_device rtc_device = { + .name = "rtc0", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + +static struct platform_device fsmc_device = { + .name = "nandif", + .id = -1, + .num_resources = ARRAY_SIZE(fsmc_resources), + .resource = fsmc_resources, +}; + +static struct platform_device ave_device = { + .name = "video_enc", + .id = -1, + .num_resources = ARRAY_SIZE(ave_resources), + .resource = ave_resources, +}; + +/* + * Notice that AMBA devices are initialized before platform devices. + * + */ +static struct platform_device *platform_devs[] __initdata = { + &i2c0_device, + &i2c1_device, + &keypad_device, + &rtc_device, + &gpio_device, + &fsmc_device, + &wdog_device, + &ave_device +}; + + +/* + * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected + * together so some interrupts are connected to the first one and some + * to the second one. + */ +void __init u300_init_irq(void) +{ + u32 mask[2] = {0, 0}; + int i; + + for (i = 0; i < NR_IRQS; i++) + set_bit(i, (unsigned long *) &mask[0]); + u300_enable_intcon_clock(); + vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0]); + vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1]); +} + + +/* + * U300 platforms peripheral handling + */ +struct db_chip { + u16 chipid; + const char *name; +}; + +/* + * This is a list of the Digital Baseband chips used in the U300 platform. + */ +static struct db_chip db_chips[] __initdata = { + { + .chipid = 0xb800, + .name = "DB3000", + }, + { + .chipid = 0xc000, + .name = "DB3100", + }, + { + .chipid = 0xc800, + .name = "DB3150", + }, + { + .chipid = 0xd800, + .name = "DB3200", + }, + { + .chipid = 0xe000, + .name = "DB3250", + }, + { + .chipid = 0xe800, + .name = "DB3210", + }, + { + .chipid = 0xf000, + .name = "DB3350 P1x", + }, + { + .chipid = 0xf100, + .name = "DB3350 P2x", + }, + { + .chipid = 0x0000, /* List terminator */ + .name = NULL, + } +}; + +static void u300_init_check_chip(void) +{ + + u16 val; + struct db_chip *chip; + const char *chipname; + const char unknown[] = "UNKNOWN"; + + /* Read out and print chip ID */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR); + /* This is in funky bigendian order... */ + val = (val & 0xFFU) << 8 | (val >> 8); + chip = db_chips; + chipname = unknown; + + for ( ; chip->chipid; chip++) { + if (chip->chipid == (val & 0xFF00U)) { + chipname = chip->name; + break; + } + } + printk(KERN_INFO "Initializing U300 system on %s baseband chip " \ + "(chip ID 0x%04x)\n", chipname, val); + +#ifdef CONFIG_MACH_U300_BS26 + if ((val & 0xFF00U) != 0xc800) { + printk(KERN_ERR "Platform configured for BS25/BS26 " \ + "with DB3150 but %s detected, expect problems!", + chipname); + } +#endif +#ifdef CONFIG_MACH_U300_BS330 + if ((val & 0xFF00U) != 0xd800) { + printk(KERN_ERR "Platform configured for BS330 " \ + "with DB3200 but %s detected, expect problems!", + chipname); + } +#endif +#ifdef CONFIG_MACH_U300_BS335 + if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) { + printk(KERN_ERR "Platform configured for BS365 " \ + " with DB3350 but %s detected, expect problems!", + chipname); + } +#endif +#ifdef CONFIG_MACH_U300_BS365 + if ((val & 0xFF00U) != 0xe800) { + printk(KERN_ERR "Platform configured for BS365 " \ + "with DB3210 but %s detected, expect problems!", + chipname); + } +#endif + + +} + +/* + * Some devices and their resources require reserved physical memory from + * the end of the available RAM. This function traverses the list of devices + * and assigns actual adresses to these. + */ +static void __init u300_assign_physmem(void) +{ + unsigned long curr_start = __pa(high_memory); + int i, j; + + for (i = 0; i < ARRAY_SIZE(platform_devs); i++) { + for (j = 0; j < platform_devs[i]->num_resources; j++) { + struct resource *const res = + &platform_devs[i]->resource[j]; + + if (IORESOURCE_MEM == res->flags && + 0 == res->start) { + res->start = curr_start; + res->end += curr_start; + curr_start += (res->end - res->start + 1); + + printk(KERN_INFO "core.c: Mapping RAM " \ + "%#x-%#x to device %s:%s\n", + res->start, res->end, + platform_devs[i]->name, res->name); + } + } + } +} + +void __init u300_init_devices(void) +{ + int i; + u16 val; + + /* Check what platform we run and print some status information */ + u300_init_check_chip(); + + /* Set system to run at PLL208, max performance, a known state. */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); + val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); + /* Wait for the PLL208 to lock if not locked in yet */ + while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) & + U300_SYSCON_CSR_PLL208_LOCK_IND)); + + /* Register the AMBA devices in the AMBA bus abstraction layer */ + u300_clock_primecells(); + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + u300_unclock_primecells(); + + u300_assign_physmem(); + + /* Register the platform devices */ + platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); + +#ifndef CONFIG_MACH_U300_SEMI_IS_SHARED + /* + * Enable SEMI self refresh. Self-refresh of the SDRAM is entered when + * both subsystems are requesting this mode. + * If we not share the Acc SDRAM, this is never the case. Therefore + * enable it here from the App side. + */ + val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) | + U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE; + writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR); +#endif /* CONFIG_MACH_U300_SEMI_IS_SHARED */ +} + +static int core_module_init(void) +{ + /* + * This needs to be initialized later: it needs the input framework + * to be initialized first. + */ + return mmc_init(&mmcsd_device); +} +module_init(core_module_init); diff --git a/arch/arm/mach-u300/include/mach/debug-macro.S b/arch/arm/mach-u300/include/mach/debug-macro.S new file mode 100644 index 000000000000..f3a1cbbeeab3 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/debug-macro.S @@ -0,0 +1,22 @@ +/* + * + * arch-arm/mach-u300/include/mach/debug-macro.S + * + * + * Copyright (C) 2006-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Debugging macro include header. + * Author: Linus Walleij + */ +#include + + .macro addruart,rx + /* If we move the adress using MMU, use this. */ + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + ldreq \rx, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address + ldrne \rx, = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address + orr \rx, \rx, #0x00003000 + .endm + +#include diff --git a/arch/arm/mach-u300/include/mach/entry-macro.S b/arch/arm/mach-u300/include/mach/entry-macro.S new file mode 100644 index 000000000000..20731ae39d38 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/entry-macro.S @@ -0,0 +1,40 @@ +/* + * + * arch-arm/mach-u300/include/mach/entry-macro.S + * + * + * Copyright (C) 2006-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Low-level IRQ helper macros for ST-Ericsson U300 + * Author: Linus Walleij + */ +#include +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldr \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON0_BASE + ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status + mov \irqnr, #0 + teq \irqstat, #0 + bne 1002f +1001: ldr \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON1_BASE + ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status + mov \irqnr, #32 + teq \irqstat, #0 + beq 1003f +1002: tst \irqstat, #1 + bne 1003f + add \irqnr, \irqnr, #1 + movs \irqstat, \irqstat, lsr #1 + bne 1002b +1003: /* EQ will be set if no irqs pending */ + .endm diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h new file mode 100644 index 000000000000..bf134bcc129d --- /dev/null +++ b/arch/arm/mach-u300/include/mach/memory.h @@ -0,0 +1,42 @@ +/* + * + * arch/arm/mach-u300/include/mach/memory.h + * + * + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Memory virtual/physical mapping constants. + * Author: Linus Walleij + * Author: Jonas Aaberg + */ + +#ifndef __MACH_MEMORY_H +#define __MACH_MEMORY_H + +#ifdef CONFIG_MACH_U300_DUAL_RAM + +#define PHYS_OFFSET UL(0x48000000) +#define BOOT_PARAMS_OFFSET (PHYS_OFFSET + 0x100) + +#else + +#ifdef CONFIG_MACH_U300_2MB_ALIGNMENT_FIX +#define PHYS_OFFSET (0x28000000 + \ + (CONFIG_MACH_U300_ACCESS_MEM_SIZE - \ + (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) +#else +#define PHYS_OFFSET (0x28000000 + \ + (CONFIG_MACH_U300_ACCESS_MEM_SIZE + \ + (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) +#endif +#define BOOT_PARAMS_OFFSET (0x28000000 + \ + (CONFIG_MACH_U300_ACCESS_MEM_SIZE + \ + (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024 + 0x100) +#endif + +/* + * We enable a real big DMA buffer if need be. + */ +#define CONSISTENT_DMA_SIZE SZ_4M + +#endif diff --git a/arch/arm/mach-u300/include/mach/platform.h b/arch/arm/mach-u300/include/mach/platform.h new file mode 100644 index 000000000000..77d9210a82e2 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/platform.h @@ -0,0 +1,19 @@ +/* + * + * arch/arm/mach-u300/include/mach/platform.h + * + * + * Copyright (C) 2006-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Basic platform init and mapping functions. + * Author: Linus Walleij + */ + +#ifndef __ASSEMBLY__ + +void u300_map_io(void); +void u300_init_irq(void); +void u300_init_devices(void); +extern struct sys_timer u300_timer; + +#endif diff --git a/arch/arm/mach-u300/include/mach/system.h b/arch/arm/mach-u300/include/mach/system.h new file mode 100644 index 000000000000..8daf13634ce0 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/system.h @@ -0,0 +1,42 @@ +/* + * + * arch/arm/mach-u300/include/mach/system.h + * + * + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * System shutdown and reset functions. + * Author: Linus Walleij + */ +#include +#include +#include +#include + +/* Forward declare this function from the watchdog */ +void coh901327_watchdog_reset(void); + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +static void arch_reset(char mode, const char *cmd) +{ + switch (mode) { + case 's': + case 'h': + printk(KERN_CRIT "RESET: shutting down/rebooting system\n"); + /* Disable interrupts */ + local_irq_disable(); +#ifdef CONFIG_COH901327_WATCHDOG + coh901327_watchdog_reset(); +#endif + break; + default: + /* Do nothing */ + break; + } + /* Wait for system do die/reset. */ + while (1); +} diff --git a/arch/arm/mach-u300/include/mach/timex.h b/arch/arm/mach-u300/include/mach/timex.h new file mode 100644 index 000000000000..f233b72633f6 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/timex.h @@ -0,0 +1,17 @@ +/* + * + * arch/arm/mach-u300/include/mach/timex.h + * + * + * Copyright (C) 2006-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Platform tick rate definition. + * Author: Linus Walleij + */ +#ifndef __MACH_TIMEX_H +#define __MACH_TIMEX_H + +/* This is for the APP OS GP1 (General Purpose 1) timer */ +#define CLOCK_TICK_RATE 1000000 + +#endif diff --git a/arch/arm/mach-u300/include/mach/uncompress.h b/arch/arm/mach-u300/include/mach/uncompress.h new file mode 100644 index 000000000000..29acb718acf7 --- /dev/null +++ b/arch/arm/mach-u300/include/mach/uncompress.h @@ -0,0 +1,46 @@ +/* + * arch/arm/mach-u300/include/mach/uncompress.h + * + * Copyright (C) 2003 ARM Limited + * + * 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 + */ +#define AMBA_UART_DR (*(volatile unsigned char *)0xc0013000) +#define AMBA_UART_LCRH (*(volatile unsigned char *)0xc001302C) +#define AMBA_UART_CR (*(volatile unsigned char *)0xc0013030) +#define AMBA_UART_FR (*(volatile unsigned char *)0xc0013018) + +/* + * This does not append a newline + */ +static inline void putc(int c) +{ + while (AMBA_UART_FR & (1 << 5)) + barrier(); + + AMBA_UART_DR = c; +} + +static inline void flush(void) +{ + while (AMBA_UART_FR & (1 << 3)) + barrier(); +} + +/* + * nothing to do + */ +#define arch_decomp_setup() +#define arch_decomp_wdog() diff --git a/arch/arm/mach-u300/include/mach/vmalloc.h b/arch/arm/mach-u300/include/mach/vmalloc.h new file mode 100644 index 000000000000..b00c51a66fbe --- /dev/null +++ b/arch/arm/mach-u300/include/mach/vmalloc.h @@ -0,0 +1,12 @@ +/* + * + * arch/arm/mach-u300/include/mach/vmalloc.h + * + * + * Copyright (C) 2006-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Virtual memory allocations + * End must be above the I/O registers and on an even 2MiB boundary. + * Author: Linus Walleij + */ +#define VMALLOC_END 0xfe800000 diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c new file mode 100644 index 000000000000..3138d3955c9e --- /dev/null +++ b/arch/arm/mach-u300/mmc.c @@ -0,0 +1,216 @@ +/* + * + * arch/arm/mach-u300/mmc.c + * + * + * Copyright (C) 2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * + * Author: Linus Walleij + * Author: Johan Lundin + * Author: Jonas Aaberg + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "mmc.h" + +struct mmci_card_event { + struct input_dev *mmc_input; + int mmc_inserted; + struct work_struct workq; + struct mmc_platform_data mmc0_plat_data; +}; + +static unsigned int mmc_status(struct device *dev) +{ + struct mmci_card_event *mmci_card = container_of( + dev->platform_data, + struct mmci_card_event, mmc0_plat_data); + + return mmci_card->mmc_inserted; +} + +/* + * Here follows a large chunk of code which will only be enabled if you + * have both the AB3100 chip mounted and the MMC subsystem activated. + */ + +static u32 mmc_translate_vdd(struct device *dev, unsigned int voltage) +{ + int v; + + /* + * MMC Spec: + * bit 7: 1.70 - 1.95V + * bit 8 - 14: 2.0 - 2.6V + * bit 15 - 23: 2.7 - 3.6V + * + * ab3100 voltages: + * 000 - 2.85V + * 001 - 2.75V + * 010 - 1.8V + * 011 - 1.5V + */ + switch (voltage) { + case 8: + v = 3; + break; + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + v = 1; + break; + case 16: + v = 1; + break; + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + v = 0; + break; + default: + v = 0; + break; + } + + /* PL180 voltage register bits */ + return v << 2; +} + + + +static int mmci_callback(void *data) +{ + struct mmci_card_event *mmci_card = data; + + disable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD); + schedule_work(&mmci_card->workq); + + return 0; +} + + +static ssize_t gpio_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct mmci_card_event *mmci_card = container_of( + dev->platform_data, + struct mmci_card_event, mmc0_plat_data); + + + return sprintf(buf, "%d\n", !mmci_card->mmc_inserted); +} + +static DEVICE_ATTR(mmc_inserted, S_IRUGO, gpio_show, NULL); + +static void _mmci_callback(struct work_struct *ws) +{ + + struct mmci_card_event *mmci_card = container_of( + ws, + struct mmci_card_event, workq); + + mdelay(20); + + mmci_card->mmc_inserted = !!gpio_get_value(U300_GPIO_PIN_MMC_CD); + + input_report_switch(mmci_card->mmc_input, KEY_INSERT, + !mmci_card->mmc_inserted); + input_sync(mmci_card->mmc_input); + + pr_debug("MMC/SD card was %s\n", + mmci_card->mmc_inserted ? "removed" : "inserted"); + + enable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD, !mmci_card->mmc_inserted); +} + +int __devinit mmc_init(struct amba_device *adev) +{ + struct mmci_card_event *mmci_card; + struct device *mmcsd_device = &adev->dev; + int ret = 0; + + mmci_card = kzalloc(sizeof(struct mmci_card_event), GFP_KERNEL); + if (!mmci_card) + return -ENOMEM; + + /* Nominally 2.85V on our platform */ + mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29; + mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd; + mmci_card->mmc0_plat_data.status = mmc_status; + + mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data; + + INIT_WORK(&mmci_card->workq, _mmci_callback); + + ret = gpio_request(U300_GPIO_PIN_MMC_CD, "MMC card detection"); + if (ret) { + printk(KERN_CRIT "Could not allocate MMC card detection " \ + "GPIO pin\n"); + goto out; + } + + ret = gpio_direction_input(U300_GPIO_PIN_MMC_CD); + if (ret) { + printk(KERN_CRIT "Invalid GPIO pin requested\n"); + goto out; + } + + ret = sysfs_create_file(&mmcsd_device->kobj, + &dev_attr_mmc_inserted.attr); + if (ret) + goto out; + + mmci_card->mmc_input = input_allocate_device(); + if (!mmci_card->mmc_input) { + printk(KERN_CRIT "Could not allocate MMC input device\n"); + return -ENOMEM; + } + + mmci_card->mmc_input->name = "MMC insert notification"; + mmci_card->mmc_input->id.bustype = BUS_HOST; + mmci_card->mmc_input->id.vendor = 0; + mmci_card->mmc_input->id.product = 0; + mmci_card->mmc_input->id.version = 0x0100; + mmci_card->mmc_input->dev.parent = mmcsd_device; + input_set_capability(mmci_card->mmc_input, EV_SW, KEY_INSERT); + + /* + * Since this must always be compiled into the kernel, this input + * is never unregistered or free:ed. + */ + ret = input_register_device(mmci_card->mmc_input); + if (ret) { + input_free_device(mmci_card->mmc_input); + goto out; + } + + input_set_drvdata(mmci_card->mmc_input, mmci_card); + + ret = gpio_register_callback(U300_GPIO_PIN_MMC_CD, mmci_callback, + mmci_card); + + schedule_work(&mmci_card->workq); + + printk(KERN_INFO "Registered MMC insert/remove notification\n"); +out: + return ret; +} diff --git a/arch/arm/mach-u300/mmc.h b/arch/arm/mach-u300/mmc.h new file mode 100644 index 000000000000..92b85125abb3 --- /dev/null +++ b/arch/arm/mach-u300/mmc.h @@ -0,0 +1,18 @@ +/* + * + * arch/arm/mach-u300/mmc.h + * + * + * Copyright (C) 2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * + * Author: Jonas Aaberg + */ +#ifndef MMC_H +#define MMC_H + +#include + +int __devinit mmc_init(struct amba_device *adev); + +#endif diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c new file mode 100644 index 000000000000..57b5351b1816 --- /dev/null +++ b/arch/arm/mach-u300/timer.c @@ -0,0 +1,422 @@ +/* + * + * arch/arm/mach-u300/timer.c + * + * + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Timer COH 901 328, runs the OS timer interrupt. + * Author: Linus Walleij + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Generic stuff */ +#include +#include +#include + +#include "clock.h" + +/* + * APP side special timer registers + * This timer contains four timers which can fire an interrupt each. + * OS (operating system) timer @ 32768 Hz + * DD (device driver) timer @ 1 kHz + * GP1 (general purpose 1) timer @ 1MHz + * GP2 (general purpose 2) timer @ 1MHz + */ + +/* Reset OS Timer 32bit (-/W) */ +#define U300_TIMER_APP_ROST (0x0000) +#define U300_TIMER_APP_ROST_TIMER_RESET (0x00000000) +/* Enable OS Timer 32bit (-/W) */ +#define U300_TIMER_APP_EOST (0x0004) +#define U300_TIMER_APP_EOST_TIMER_ENABLE (0x00000000) +/* Disable OS Timer 32bit (-/W) */ +#define U300_TIMER_APP_DOST (0x0008) +#define U300_TIMER_APP_DOST_TIMER_DISABLE (0x00000000) +/* OS Timer Mode Register 32bit (-/W) */ +#define U300_TIMER_APP_SOSTM (0x000c) +#define U300_TIMER_APP_SOSTM_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_SOSTM_MODE_ONE_SHOT (0x00000001) +/* OS Timer Status Register 32bit (R/-) */ +#define U300_TIMER_APP_OSTS (0x0010) +#define U300_TIMER_APP_OSTS_TIMER_STATE_MASK (0x0000000F) +#define U300_TIMER_APP_OSTS_TIMER_STATE_IDLE (0x00000001) +#define U300_TIMER_APP_OSTS_TIMER_STATE_ACTIVE (0x00000002) +#define U300_TIMER_APP_OSTS_ENABLE_IND (0x00000010) +#define U300_TIMER_APP_OSTS_MODE_MASK (0x00000020) +#define U300_TIMER_APP_OSTS_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_OSTS_MODE_ONE_SHOT (0x00000020) +#define U300_TIMER_APP_OSTS_IRQ_ENABLED_IND (0x00000040) +#define U300_TIMER_APP_OSTS_IRQ_PENDING_IND (0x00000080) +/* OS Timer Current Count Register 32bit (R/-) */ +#define U300_TIMER_APP_OSTCC (0x0014) +/* OS Timer Terminal Count Register 32bit (R/W) */ +#define U300_TIMER_APP_OSTTC (0x0018) +/* OS Timer Interrupt Enable Register 32bit (-/W) */ +#define U300_TIMER_APP_OSTIE (0x001c) +#define U300_TIMER_APP_OSTIE_IRQ_DISABLE (0x00000000) +#define U300_TIMER_APP_OSTIE_IRQ_ENABLE (0x00000001) +/* OS Timer Interrupt Acknowledge Register 32bit (-/W) */ +#define U300_TIMER_APP_OSTIA (0x0020) +#define U300_TIMER_APP_OSTIA_IRQ_ACK (0x00000080) + +/* Reset DD Timer 32bit (-/W) */ +#define U300_TIMER_APP_RDDT (0x0040) +#define U300_TIMER_APP_RDDT_TIMER_RESET (0x00000000) +/* Enable DD Timer 32bit (-/W) */ +#define U300_TIMER_APP_EDDT (0x0044) +#define U300_TIMER_APP_EDDT_TIMER_ENABLE (0x00000000) +/* Disable DD Timer 32bit (-/W) */ +#define U300_TIMER_APP_DDDT (0x0048) +#define U300_TIMER_APP_DDDT_TIMER_DISABLE (0x00000000) +/* DD Timer Mode Register 32bit (-/W) */ +#define U300_TIMER_APP_SDDTM (0x004c) +#define U300_TIMER_APP_SDDTM_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_SDDTM_MODE_ONE_SHOT (0x00000001) +/* DD Timer Status Register 32bit (R/-) */ +#define U300_TIMER_APP_DDTS (0x0050) +#define U300_TIMER_APP_DDTS_TIMER_STATE_MASK (0x0000000F) +#define U300_TIMER_APP_DDTS_TIMER_STATE_IDLE (0x00000001) +#define U300_TIMER_APP_DDTS_TIMER_STATE_ACTIVE (0x00000002) +#define U300_TIMER_APP_DDTS_ENABLE_IND (0x00000010) +#define U300_TIMER_APP_DDTS_MODE_MASK (0x00000020) +#define U300_TIMER_APP_DDTS_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_DDTS_MODE_ONE_SHOT (0x00000020) +#define U300_TIMER_APP_DDTS_IRQ_ENABLED_IND (0x00000040) +#define U300_TIMER_APP_DDTS_IRQ_PENDING_IND (0x00000080) +/* DD Timer Current Count Register 32bit (R/-) */ +#define U300_TIMER_APP_DDTCC (0x0054) +/* DD Timer Terminal Count Register 32bit (R/W) */ +#define U300_TIMER_APP_DDTTC (0x0058) +/* DD Timer Interrupt Enable Register 32bit (-/W) */ +#define U300_TIMER_APP_DDTIE (0x005c) +#define U300_TIMER_APP_DDTIE_IRQ_DISABLE (0x00000000) +#define U300_TIMER_APP_DDTIE_IRQ_ENABLE (0x00000001) +/* DD Timer Interrupt Acknowledge Register 32bit (-/W) */ +#define U300_TIMER_APP_DDTIA (0x0060) +#define U300_TIMER_APP_DDTIA_IRQ_ACK (0x00000080) + +/* Reset GP1 Timer 32bit (-/W) */ +#define U300_TIMER_APP_RGPT1 (0x0080) +#define U300_TIMER_APP_RGPT1_TIMER_RESET (0x00000000) +/* Enable GP1 Timer 32bit (-/W) */ +#define U300_TIMER_APP_EGPT1 (0x0084) +#define U300_TIMER_APP_EGPT1_TIMER_ENABLE (0x00000000) +/* Disable GP1 Timer 32bit (-/W) */ +#define U300_TIMER_APP_DGPT1 (0x0088) +#define U300_TIMER_APP_DGPT1_TIMER_DISABLE (0x00000000) +/* GP1 Timer Mode Register 32bit (-/W) */ +#define U300_TIMER_APP_SGPT1M (0x008c) +#define U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT (0x00000001) +/* GP1 Timer Status Register 32bit (R/-) */ +#define U300_TIMER_APP_GPT1S (0x0090) +#define U300_TIMER_APP_GPT1S_TIMER_STATE_MASK (0x0000000F) +#define U300_TIMER_APP_GPT1S_TIMER_STATE_IDLE (0x00000001) +#define U300_TIMER_APP_GPT1S_TIMER_STATE_ACTIVE (0x00000002) +#define U300_TIMER_APP_GPT1S_ENABLE_IND (0x00000010) +#define U300_TIMER_APP_GPT1S_MODE_MASK (0x00000020) +#define U300_TIMER_APP_GPT1S_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_GPT1S_MODE_ONE_SHOT (0x00000020) +#define U300_TIMER_APP_GPT1S_IRQ_ENABLED_IND (0x00000040) +#define U300_TIMER_APP_GPT1S_IRQ_PENDING_IND (0x00000080) +/* GP1 Timer Current Count Register 32bit (R/-) */ +#define U300_TIMER_APP_GPT1CC (0x0094) +/* GP1 Timer Terminal Count Register 32bit (R/W) */ +#define U300_TIMER_APP_GPT1TC (0x0098) +/* GP1 Timer Interrupt Enable Register 32bit (-/W) */ +#define U300_TIMER_APP_GPT1IE (0x009c) +#define U300_TIMER_APP_GPT1IE_IRQ_DISABLE (0x00000000) +#define U300_TIMER_APP_GPT1IE_IRQ_ENABLE (0x00000001) +/* GP1 Timer Interrupt Acknowledge Register 32bit (-/W) */ +#define U300_TIMER_APP_GPT1IA (0x00a0) +#define U300_TIMER_APP_GPT1IA_IRQ_ACK (0x00000080) + +/* Reset GP2 Timer 32bit (-/W) */ +#define U300_TIMER_APP_RGPT2 (0x00c0) +#define U300_TIMER_APP_RGPT2_TIMER_RESET (0x00000000) +/* Enable GP2 Timer 32bit (-/W) */ +#define U300_TIMER_APP_EGPT2 (0x00c4) +#define U300_TIMER_APP_EGPT2_TIMER_ENABLE (0x00000000) +/* Disable GP2 Timer 32bit (-/W) */ +#define U300_TIMER_APP_DGPT2 (0x00c8) +#define U300_TIMER_APP_DGPT2_TIMER_DISABLE (0x00000000) +/* GP2 Timer Mode Register 32bit (-/W) */ +#define U300_TIMER_APP_SGPT2M (0x00cc) +#define U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_SGPT2M_MODE_ONE_SHOT (0x00000001) +/* GP2 Timer Status Register 32bit (R/-) */ +#define U300_TIMER_APP_GPT2S (0x00d0) +#define U300_TIMER_APP_GPT2S_TIMER_STATE_MASK (0x0000000F) +#define U300_TIMER_APP_GPT2S_TIMER_STATE_IDLE (0x00000001) +#define U300_TIMER_APP_GPT2S_TIMER_STATE_ACTIVE (0x00000002) +#define U300_TIMER_APP_GPT2S_ENABLE_IND (0x00000010) +#define U300_TIMER_APP_GPT2S_MODE_MASK (0x00000020) +#define U300_TIMER_APP_GPT2S_MODE_CONTINUOUS (0x00000000) +#define U300_TIMER_APP_GPT2S_MODE_ONE_SHOT (0x00000020) +#define U300_TIMER_APP_GPT2S_IRQ_ENABLED_IND (0x00000040) +#define U300_TIMER_APP_GPT2S_IRQ_PENDING_IND (0x00000080) +/* GP2 Timer Current Count Register 32bit (R/-) */ +#define U300_TIMER_APP_GPT2CC (0x00d4) +/* GP2 Timer Terminal Count Register 32bit (R/W) */ +#define U300_TIMER_APP_GPT2TC (0x00d8) +/* GP2 Timer Interrupt Enable Register 32bit (-/W) */ +#define U300_TIMER_APP_GPT2IE (0x00dc) +#define U300_TIMER_APP_GPT2IE_IRQ_DISABLE (0x00000000) +#define U300_TIMER_APP_GPT2IE_IRQ_ENABLE (0x00000001) +/* GP2 Timer Interrupt Acknowledge Register 32bit (-/W) */ +#define U300_TIMER_APP_GPT2IA (0x00e0) +#define U300_TIMER_APP_GPT2IA_IRQ_ACK (0x00000080) + +/* Clock request control register - all four timers */ +#define U300_TIMER_APP_CRC (0x100) +#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001) + +#define TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) +#define US_PER_TICK ((1000000 + (HZ/2)) / HZ) + +/* + * The u300_set_mode() function is always called first, if we + * have oneshot timer active, the oneshot scheduling function + * u300_set_next_event() is called immediately after. + */ +static void u300_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + /* Disable interrupts on GPT1 */ + writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + /* Disable GP1 while we're reprogramming it. */ + writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); + /* + * Set the periodic mode to a certain number of ticks per + * jiffy. + */ + writel(TICKS_PER_JIFFY, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC); + /* + * Set continuous mode, so the timer keeps triggering + * interrupts. + */ + writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS, + U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M); + /* Enable timer interrupts */ + writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + /* Then enable the OS timer again */ + writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1); + break; + case CLOCK_EVT_MODE_ONESHOT: + /* Just break; here? */ + /* + * The actual event will be programmed by the next event hook, + * so we just set a dummy value somewhere at the end of the + * universe here. + */ + /* Disable interrupts on GPT1 */ + writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + /* Disable GP1 while we're reprogramming it. */ + writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); + /* + * Expire far in the future, u300_set_next_event() will be + * called soon... + */ + writel(0xFFFFFFFF, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC); + /* We run one shot per tick here! */ + writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, + U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M); + /* Enable interrupts for this timer */ + writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + /* Enable timer */ + writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1); + break; + case CLOCK_EVT_MODE_UNUSED: + case CLOCK_EVT_MODE_SHUTDOWN: + /* Disable interrupts on GP1 */ + writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + /* Disable GP1 */ + writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); + break; + case CLOCK_EVT_MODE_RESUME: + /* Ignore this call */ + break; + } +} + +/* + * The app timer in one shot mode obviously has to be reprogrammed + * in EXACTLY this sequence to work properly. Do NOT try to e.g. replace + * the interrupt disable + timer disable commands with a reset command, + * it will fail miserably. Apparently (and I found this the hard way) + * the timer is very sensitive to the instruction order, though you don't + * get that impression from the data sheet. + */ +static int u300_set_next_event(unsigned long cycles, + struct clock_event_device *evt) + +{ + /* Disable interrupts on GPT1 */ + writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + /* Disable GP1 while we're reprogramming it. */ + writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1); + /* Reset the General Purpose timer 1. */ + writel(U300_TIMER_APP_RGPT1_TIMER_RESET, + U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1); + /* IRQ in n * cycles */ + writel(cycles, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC); + /* + * We run one shot per tick here! (This is necessary to reconfigure, + * the timer will tilt if you don't!) + */ + writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT, + U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M); + /* Enable timer interrupts */ + writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE); + /* Then enable the OS timer again */ + writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1); + return 0; +} + + +/* Use general purpose timer 1 as clock event */ +static struct clock_event_device clockevent_u300_1mhz = { + .name = "GPT1", + .rating = 300, /* Reasonably fast and accurate clock event */ + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + /* 22 calculated using the algorithm in arch/mips/kernel/time.c */ + .shift = 22, + .set_next_event = u300_set_next_event, + .set_mode = u300_set_mode, +}; + +/* Clock event timer interrupt handler */ +static irqreturn_t u300_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *evt = &clockevent_u300_1mhz; + /* ACK/Clear timer IRQ for the APP GPT1 Timer */ + writel(U300_TIMER_APP_GPT1IA_IRQ_ACK, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IA); + evt->event_handler(evt); + return IRQ_HANDLED; +} + +static struct irqaction u300_timer_irq = { + .name = "U300 Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .handler = u300_timer_interrupt, +}; + +/* Use general purpose timer 2 as clock source */ +static cycle_t u300_get_cycles(void) +{ + return (cycles_t) readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); +} + +static struct clocksource clocksource_u300_1mhz = { + .name = "GPT2", + .rating = 300, /* Reasonably fast and accurate clock source */ + .read = u300_get_cycles, + .mask = CLOCKSOURCE_MASK(32), /* 32 bits */ + /* 22 calculated using the algorithm in arch/mips/kernel/time.c */ + .shift = 22, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + + +/* + * This sets up the system timers, clock source and clock event. + */ +static void __init u300_timer_init(void) +{ + u300_enable_timer_clock(); + /* + * Disable the "OS" and "DD" timers - these are designed for Symbian! + * Example usage in cnh1601578 cpu subsystem pd_timer_app.c + */ + writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_CRC); + writel(U300_TIMER_APP_ROST_TIMER_RESET, + U300_TIMER_APP_VBASE + U300_TIMER_APP_ROST); + writel(U300_TIMER_APP_DOST_TIMER_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_DOST); + writel(U300_TIMER_APP_RDDT_TIMER_RESET, + U300_TIMER_APP_VBASE + U300_TIMER_APP_RDDT); + writel(U300_TIMER_APP_DDDT_TIMER_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_DDDT); + + /* Reset the General Purpose timer 1. */ + writel(U300_TIMER_APP_RGPT1_TIMER_RESET, + U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1); + + /* Set up the IRQ handler */ + setup_irq(IRQ_U300_TIMER_APP_GP1, &u300_timer_irq); + + /* Reset the General Purpose timer 2 */ + writel(U300_TIMER_APP_RGPT2_TIMER_RESET, + U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT2); + /* Set this timer to run around forever */ + writel(0xFFFFFFFFU, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2TC); + /* Set continuous mode so it wraps around */ + writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS, + U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT2M); + /* Disable timer interrupts */ + writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2IE); + /* Then enable the GP2 timer to use as a free running us counter */ + writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, + U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); + + /* This is a pure microsecond clock source */ + clocksource_u300_1mhz.mult = + clocksource_khz2mult(1000, clocksource_u300_1mhz.shift); + if (clocksource_register(&clocksource_u300_1mhz)) + printk(KERN_ERR "timer: failed to initialize clock " + "source %s\n", clocksource_u300_1mhz.name); + + clockevent_u300_1mhz.mult = + div_sc(1000000, NSEC_PER_SEC, clockevent_u300_1mhz.shift); + /* 32bit counter, so 32bits delta is max */ + clockevent_u300_1mhz.max_delta_ns = + clockevent_delta2ns(0xffffffff, &clockevent_u300_1mhz); + /* This timer is slow enough to set for 1 cycle == 1 MHz */ + clockevent_u300_1mhz.min_delta_ns = + clockevent_delta2ns(1, &clockevent_u300_1mhz); + clockevent_u300_1mhz.cpumask = cpumask_of(0); + clockevents_register_device(&clockevent_u300_1mhz); + /* + * TODO: init and register the rest of the timers too, they can be + * used by hrtimers! + */ +} + +/* + * Very simple system timer that only register the clock event and + * clock source. + */ +struct sys_timer u300_timer = { + .init = u300_timer_init, +}; diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c new file mode 100644 index 000000000000..d2a0b8847a18 --- /dev/null +++ b/arch/arm/mach-u300/u300.c @@ -0,0 +1,55 @@ +/* + * + * arch/arm/mach-u300/u300.c + * + * + * Copyright (C) 2006-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * Platform machine definition. + * Author: Linus Walleij + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void __init u300_init_machine(void) +{ + u300_init_devices(); +} + +#ifdef CONFIG_MACH_U300_BS2X +#define MACH_U300_STRING "Ericsson AB U300 S25/S26/B25/B26 Prototype Board" +#endif + +#ifdef CONFIG_MACH_U300_BS330 +#define MACH_U300_STRING "Ericsson AB U330 S330/B330 Prototype Board" +#endif + +#ifdef CONFIG_MACH_U300_BS335 +#define MACH_U300_STRING "Ericsson AB U335 S335/B335 Prototype Board" +#endif + +#ifdef CONFIG_MACH_U300_BS365 +#define MACH_U300_STRING "Ericsson AB U365 S365/B365 Prototype Board" +#endif + +MACHINE_START(U300, MACH_U300_STRING) + /* Maintainer: Linus Walleij */ + .phys_io = U300_AHB_PER_PHYS_BASE, + .io_pg_offst = ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = BOOT_PARAMS_OFFSET, + .map_io = u300_map_io, + .init_irq = u300_init_irq, + .timer = &u300_timer, + .init_machine = u300_init_machine, +MACHINE_END -- GitLab From d98aac7592114241f378bc8d5b3e424cced7ded2 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 27 Apr 2009 10:21:46 +0100 Subject: [PATCH 0872/6080] [ARM] 5480/1: U300-v5 integrate into the ARM architecture This hooks the U300 support into Kbuild and makes a small hook in mmu.c for supporting an odd memory alignment with shared memory on these systems. This is rebased to RMK:s GIT HEAD. This patch tries to add the Kconfig option in alphabetic order by option text and the Makefile entry after config symbol. Signed-off-by: Linus Walleij Signed-off-by: Russell King --- arch/arm/Kconfig | 16 ++++++++++++++++ arch/arm/Makefile | 1 + arch/arm/mm/mmu.c | 14 ++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a930e5c5672c..44456e163025 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -594,6 +594,20 @@ config ARCH_LH7A40X core with a wide array of integrated devices for hand-held and low-power applications. +config ARCH_U300 + bool "ST-Ericsson U300 Series" + depends on MMU + select CPU_ARM926T + select ARM_AMBA + select ARM_VIC + select GENERIC_TIME + select GENERIC_CLOCKEVENTS + select HAVE_CLK + select COMMON_CLKDEV + select GENERIC_GPIO + help + Support for ST-Ericsson U300 series mobile platforms. + config ARCH_DAVINCI bool "TI DaVinci" select CPU_ARM926T @@ -705,6 +719,8 @@ source "arch/arm/mach-ks8695/Kconfig" source "arch/arm/mach-msm/Kconfig" +source "arch/arm/mach-u300/Kconfig" + source "arch/arm/mach-w90x900/Kconfig" # Definitions to make life easier diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 885a83724b9c..20084c50c23c 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -149,6 +149,7 @@ machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 machine-$(CONFIG_ARCH_SA1100) := sa1100 machine-$(CONFIG_ARCH_SHARK) := shark +machine-$(CONFIG_ARCH_U300) := u300 machine-$(CONFIG_ARCH_VERSATILE) := versatile machine-$(CONFIG_ARCH_W90X900) := w90x900 machine-$(CONFIG_FOOTBRIDGE) := footbridge diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e6344ece00ce..39fca4e416e2 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -839,6 +839,20 @@ void __init reserve_node_zero(pg_data_t *pgdat) reserve_bootmem_node(pgdat, 0xa0200000, 0x1000, BOOTMEM_EXCLUSIVE); + /* + * U300 - This platform family can share physical memory + * between two ARM cpus, one running Linux and the other + * running another OS. + */ + if (machine_is_u300()) { +#ifdef CONFIG_MACH_U300_SINGLE_RAM +#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \ + CONFIG_MACH_U300_2MB_ALIGNMENT_FIX + res_size = 0x00100000; +#endif +#endif + } + #ifdef CONFIG_SA1111 /* * Because of the SA1111 DMA bug, we want to preserve our -- GitLab From 6d0485a99366d4e0e7e725f14995c74cb7ca4499 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Tue, 31 Mar 2009 17:13:15 +0100 Subject: [PATCH 0873/6080] [ARM] 5438/1: AT91: manage clock by functionality instead of CPUs In clock.c file the clock management is grouped by cpu with cpu_is_xxx() function. This lead to some kind of difficulties to read this file and maintainability issues as the number of AT91 cpus & PLLs/clocks is growing. In this patch, I try to group clock functionality together and match cpus with this functionality set. An update to at91_pmc.h is needed to cover some new PMC possibilities (and some update in comments). Signed-off-by: Nicolas Ferre Acked-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91/clock.c | 151 +++++++++++++++------ arch/arm/mach-at91/include/mach/at91_pmc.h | 26 +++- 2 files changed, 132 insertions(+), 45 deletions(-) diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index e4345106ee57..bac578fe0d3d 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -43,6 +43,25 @@ #define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) +/* + * Chips have some kind of clocks : group them by functionality + */ +#define cpu_has_utmi() ( cpu_is_at91cap9() \ + || cpu_is_at91sam9rl()) + +#define cpu_has_800M_plla() (cpu_is_at91sam9g20()) + +#define cpu_has_pllb() (!cpu_is_at91sam9rl()) + +#define cpu_has_upll() (0) + +/* USB host HS & FS */ +#define cpu_has_uhp() (!cpu_is_at91sam9rl()) + +/* USB device FS only */ +#define cpu_has_udpfs() (!cpu_is_at91sam9rl()) + + static LIST_HEAD(clocks); static DEFINE_SPINLOCK(clk_lock); @@ -140,7 +159,7 @@ static struct clk utmi_clk = { }; static struct clk uhpck = { .name = "uhpck", - .parent = &pllb, + /*.parent = ... we choose parent at runtime */ .mode = pmc_sys_mode, }; @@ -173,7 +192,11 @@ static struct clk __init *at91_css_to_clk(unsigned long css) case AT91_PMC_CSS_PLLA: return &plla; case AT91_PMC_CSS_PLLB: - return &pllb; + if (cpu_has_upll()) + /* CSS_PLLB == CSS_UPLL */ + return &utmi_clk; + else if (cpu_has_pllb()) + return &pllb; } return NULL; @@ -322,7 +345,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) u32 pckr; pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); - pckr &= AT91_PMC_CSS_PLLB; /* clock selection */ + pckr &= AT91_PMC_CSS; /* clock selection */ pckr |= prescale << 2; at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); clk->rate_hz = actual; @@ -361,7 +384,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) } EXPORT_SYMBOL(clk_set_parent); -/* establish PCK0..PCK3 parentage and rate */ +/* establish PCK0..PCKN parentage and rate */ static void __init init_programmable_clock(struct clk *clk) { struct clk *parent; @@ -389,11 +412,13 @@ static int at91_clk_show(struct seq_file *s, void *unused) seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); - if (!cpu_is_at91sam9rl()) + if (cpu_has_pllb()) seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); - if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) + if (cpu_has_utmi()) seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR)); seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); + if (cpu_has_upll()) + seq_printf(s, "USB = %8x\n", at91_sys_read(AT91_PMC_USB)); seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); seq_printf(s, "\n"); @@ -554,16 +579,60 @@ static struct clk *const standard_pmc_clocks[] __initdata = { &clk32k, &main_clk, &plla, - &pllb, - - /* PLLB children (USB) */ - &udpck, - &uhpck, /* MCK */ &mck }; +/* PLLB generated USB full speed clock init */ +static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock) +{ + /* + * USB clock init: choose 48 MHz PLLB value, + * disable 48MHz clock during usb peripheral suspend. + * + * REVISIT: assumes MCK doesn't derive from PLLB! + */ + uhpck.parent = &pllb; + + at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; + pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); + if (cpu_is_at91rm9200()) { + uhpck.pmc_mask = AT91RM9200_PMC_UHP; + udpck.pmc_mask = AT91RM9200_PMC_UDP; + at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); + } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { + uhpck.pmc_mask = AT91SAM926x_PMC_UHP; + udpck.pmc_mask = AT91SAM926x_PMC_UDP; + } else if (cpu_is_at91cap9()) { + uhpck.pmc_mask = AT91CAP9_PMC_UHP; + } + at91_sys_write(AT91_CKGR_PLLBR, 0); + + udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); + uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); +} + +/* UPLL generated USB full speed clock init */ +static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) +{ + /* + * USB clock init: choose 480 MHz from UPLL, + */ + unsigned int usbr = AT91_PMC_USBS_UPLL; + + /* Setup divider by 10 to reach 48 MHz */ + usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV; + + at91_sys_write(AT91_PMC_USB, usbr); + + /* Now set uhpck values */ + uhpck.parent = &utmi_clk; + uhpck.pmc_mask = AT91SAM926x_PMC_UHP; + uhpck.rate_hz = utmi_clk.parent->rate_hz; + uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); +} + int __init at91_clock_init(unsigned long main_clock) { unsigned tmp, freq, mckr; @@ -585,43 +654,37 @@ int __init at91_clock_init(unsigned long main_clock) /* report if PLLA is more than mildly overclocked */ plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); - if ((!cpu_is_at91sam9g20() && plla.rate_hz > 209000000) - || (cpu_is_at91sam9g20() && plla.rate_hz > 800000000)) + if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000) + || (cpu_has_800M_plla() && plla.rate_hz > 800000000)) pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); - /* - * USB clock init: choose 48 MHz PLLB value, - * disable 48MHz clock during usb peripheral suspend. - * - * REVISIT: assumes MCK doesn't derive from PLLB! - */ - at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; - pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); - if (cpu_is_at91rm9200()) { - uhpck.pmc_mask = AT91RM9200_PMC_UHP; - udpck.pmc_mask = AT91RM9200_PMC_UDP; - at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); - } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) { - uhpck.pmc_mask = AT91SAM926x_PMC_UHP; - udpck.pmc_mask = AT91SAM926x_PMC_UDP; - } else if (cpu_is_at91cap9()) { - uhpck.pmc_mask = AT91CAP9_PMC_UHP; + + if (cpu_has_upll() && !cpu_has_pllb()) { + /* setup UTMI clock as the fourth primary clock + * (instead of pllb) */ + utmi_clk.type |= CLK_TYPE_PRIMARY; + utmi_clk.id = 3; } - at91_sys_write(AT91_CKGR_PLLBR, 0); - udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); - uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); /* * USB HS clock init */ - if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) { + if (cpu_has_utmi()) /* * multiplier is hard-wired to 40 * (obtain the USB High Speed 480 MHz when input is 12 MHz) */ utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; - } + + /* + * USB FS clock init + */ + if (cpu_has_pllb()) + at91_pllb_usbfs_clock_init(main_clock); + if (cpu_has_upll()) + /* assumes that we choose UPLL for USB and not PLLA */ + at91_upll_usbfs_clock_init(main_clock); /* * MCK and CPU derive from one of those primary clocks. @@ -631,21 +694,31 @@ int __init at91_clock_init(unsigned long main_clock) mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); freq = mck.parent->rate_hz; freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ - if (cpu_is_at91rm9200()) + if (cpu_is_at91rm9200()) { mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ - else if (cpu_is_at91sam9g20()) { + } else if (cpu_is_at91sam9g20()) { mck.rate_hz = (mckr & AT91_PMC_MDIV) ? freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ if (mckr & AT91_PMC_PDIV) freq /= 2; /* processor clock division */ - } else + } else { mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ + } /* Register the PMC's standard clocks */ for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) list_add_tail(&standard_pmc_clocks[i]->node, &clocks); - if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) + if (cpu_has_pllb()) + list_add_tail(&pllb.node, &clocks); + + if (cpu_has_uhp()) + list_add_tail(&uhpck.node, &clocks); + + if (cpu_has_udpfs()) + list_add_tail(&udpck.node, &clocks); + + if (cpu_has_utmi()) list_add_tail(&utmi_clk.node, &clocks); /* MCK and CPU clock are "always on" */ diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index 9561e33b8a9a..64589eaaaee8 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -23,7 +23,7 @@ #define AT91_PMC_PCK (1 << 0) /* Processor Clock */ #define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */ #define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */ -#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [AT91CAP9 revC only] */ +#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [CAP9 revC & some SAM9 only] */ #define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */ #define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */ #define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */ @@ -39,11 +39,11 @@ #define AT91_PMC_PCDR (AT91_PMC + 0x14) /* Peripheral Clock Disable Register */ #define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */ -#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [SAM9RL, CAP9] */ +#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [some SAM9, CAP9] */ #define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */ #define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */ #define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */ -#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI PLL Start-up Time */ +#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */ #define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */ #define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ @@ -72,6 +72,7 @@ #define AT91_PMC_CSS_MAIN (1 << 0) #define AT91_PMC_CSS_PLLA (2 << 0) #define AT91_PMC_CSS_PLLB (3 << 0) +#define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */ #define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */ #define AT91_PMC_PRES_1 (0 << 2) #define AT91_PMC_PRES_2 (1 << 2) @@ -88,12 +89,25 @@ #define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9,CAP9 only] */ #define AT91SAM9_PMC_MDIV_2 (1 << 8) #define AT91SAM9_PMC_MDIV_4 (2 << 8) -#define AT91SAM9_PMC_MDIV_6 (3 << 8) +#define AT91SAM9_PMC_MDIV_6 (3 << 8) /* [some SAM9 only] */ +#define AT91SAM9_PMC_MDIV_3 (3 << 8) /* [some SAM9 only] */ #define AT91_PMC_PDIV (1 << 12) /* Processor Clock Division [some SAM9 only] */ #define AT91_PMC_PDIV_1 (0 << 12) #define AT91_PMC_PDIV_2 (1 << 12) +#define AT91_PMC_PLLADIV2 (1 << 12) /* PLLA divisor by 2 [some SAM9 only] */ +#define AT91_PMC_PLLADIV2_OFF (0 << 12) +#define AT91_PMC_PLLADIV2_ON (1 << 12) -#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-3 Registers */ +#define AT91_PMC_USB (AT91_PMC + 0x38) /* USB Clock Register [some SAM9 only] */ +#define AT91_PMC_USBS (0x1 << 0) /* USB OHCI Input clock selection */ +#define AT91_PMC_USBS_PLLA (0 << 0) +#define AT91_PMC_USBS_UPLL (1 << 0) +#define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */ + +#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */ +#define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */ +#define AT91_PMC_CSSMCK_CSS (0 << 8) +#define AT91_PMC_CSSMCK_MCK (1 << 8) #define AT91_PMC_IER (AT91_PMC + 0x60) /* Interrupt Enable Register */ #define AT91_PMC_IDR (AT91_PMC + 0x64) /* Interrupt Disable Register */ @@ -102,7 +116,7 @@ #define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */ #define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */ #define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */ -#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [AT91CAP9 only] */ +#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9, AT91CAP9 only] */ #define AT91_PMC_OSCSEL (1 << 7) /* Slow Clock Oscillator [AT91CAP9 revC only] */ #define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */ #define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ -- GitLab From 5103c9f7874506cb40fc3c8d3f22486d3c4d91aa Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 28 Apr 2009 15:29:09 +0000 Subject: [PATCH 0874/6080] netxen: fix link event handling Firmware starting 4.0.402 started supporting link events, disable it for older firmwares. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic_ethtool.c | 1 + drivers/net/netxen/netxen_nic_main.c | 2 +- drivers/net/netxen/netxen_nic_phan_reg.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index a452b2facb77..e16ea46c24b8 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -247,6 +247,7 @@ skip: case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN: case LINKEVENT_MODULE_TWINAX: ecmd->port = PORT_TP; + break; default: ecmd->port = -1; } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index e877eefdfeb0..8331580fe161 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -797,7 +797,7 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) if (adapter->max_sds_rings > 1) netxen_config_rss(adapter, 1); - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) netxen_linkevent_request(adapter, 1); return 0; diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 845dcf436cf6..b73a62ca74f8 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -126,6 +126,7 @@ #define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4) #define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8) +#define CRB_FW_CAPABILITIES_1 NETXEN_CAM_RAM(0x128) #define CRB_MAC_BLOCK_START NETXEN_CAM_RAM(0x1c0) /* @@ -136,7 +137,6 @@ #define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) #define CRB_NIC_MSI_MODE_HOST NETXEN_NIC_REG(0x270) #define CRB_NIC_MSI_MODE_FW NETXEN_NIC_REG(0x274) -#define CRB_FW_CAPABILITIES_1 NETXEN_NIC_REG(0x128) #define INTR_SCHEME_PERPORT 0x1 #define MSI_MODE_MULTIFUNC 0x1 -- GitLab From 4ea528a151549df795c984649d75860ea40390bd Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 28 Apr 2009 15:29:10 +0000 Subject: [PATCH 0875/6080] netxen: refactor netxen_recv_context struct o move related fields into netxen_recv_context struct. o allocate rx buffer and descriptor rings dynamically. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 10 +++--- drivers/net/netxen/netxen_nic_ctx.c | 49 +++++++++++++++------------- drivers/net/netxen/netxen_nic_hw.c | 2 +- drivers/net/netxen/netxen_nic_init.c | 46 ++++++++++++++++++++------ drivers/net/netxen/netxen_nic_main.c | 4 +-- 5 files changed, 71 insertions(+), 40 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index ebd6c2edc343..16f5e2267eb3 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -775,8 +775,11 @@ struct netxen_recv_context { u16 context_id; u16 virt_port; - struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS]; + struct nx_host_rds_ring *rds_rings; struct nx_host_sds_ring *sds_rings; + + struct netxen_ring_ctx *hwctx; + dma_addr_t phys_addr; }; /* New HW context creation */ @@ -1258,11 +1261,8 @@ struct netxen_adapter { struct netxen_adapter_stats stats; struct netxen_recv_context recv_ctx; - struct nx_host_tx_ring tx_ring; + struct nx_host_tx_ring *tx_ring; - /* Context interface shared between card and host */ - struct netxen_ring_ctx *ctx_desc; - dma_addr_t ctx_desc_phys_addr; int (*enable_phy_interrupts) (struct netxen_adapter *); int (*disable_phy_interrupts) (struct netxen_adapter *); int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t); diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index fd82adf4f876..4754f5cffad0 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -323,7 +323,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) int err = 0; u64 offset, phys_addr; dma_addr_t rq_phys_addr, rsp_phys_addr; - struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; + struct nx_host_tx_ring *tx_ring = adapter->tx_ring; + struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); rq_addr = pci_alloc_consistent(adapter->pdev, @@ -358,7 +359,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr); - offset = adapter->ctx_desc_phys_addr+sizeof(struct netxen_ring_ctx); + offset = recv_ctx->phys_addr + sizeof(struct netxen_ring_ctx); prq->cmd_cons_dma_addr = cpu_to_le64(offset); prq_cds = &prq->cds_ring; @@ -541,14 +542,16 @@ netxen_init_old_ctx(struct netxen_adapter *adapter) struct nx_host_tx_ring *tx_ring; int ring; int port = adapter->portnum; - struct netxen_ring_ctx *hwctx = adapter->ctx_desc; + struct netxen_ring_ctx *hwctx; u32 signature; - tx_ring = &adapter->tx_ring; + tx_ring = adapter->tx_ring; + recv_ctx = &adapter->recv_ctx; + hwctx = recv_ctx->hwctx; + hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr); hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc); - recv_ctx = &adapter->recv_ctx; for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; @@ -576,9 +579,9 @@ netxen_init_old_ctx(struct netxen_adapter *adapter) NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE; NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port), - lower32(adapter->ctx_desc_phys_addr)); + lower32(recv_ctx->phys_addr)); NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port), - upper32(adapter->ctx_desc_phys_addr)); + upper32(recv_ctx->phys_addr)); NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), signature | port); return 0; @@ -592,25 +595,28 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; struct nx_host_sds_ring *sds_ring; - struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; + struct nx_host_tx_ring *tx_ring; struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; int port = adapter->portnum; + recv_ctx = &adapter->recv_ctx; + tx_ring = adapter->tx_ring; + addr = pci_alloc_consistent(pdev, sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), - &adapter->ctx_desc_phys_addr); - + &recv_ctx->phys_addr); if (addr == NULL) { dev_err(&pdev->dev, "failed to allocate hw context\n"); return -ENOMEM; } + memset(addr, 0, sizeof(struct netxen_ring_ctx)); - adapter->ctx_desc = (struct netxen_ring_ctx *)addr; - adapter->ctx_desc->ctx_id = cpu_to_le32(port); - adapter->ctx_desc->cmd_consumer_offset = - cpu_to_le64(adapter->ctx_desc_phys_addr + + recv_ctx->hwctx = (struct netxen_ring_ctx *)addr; + recv_ctx->hwctx->ctx_id = cpu_to_le32(port); + recv_ctx->hwctx->cmd_consumer_offset = + cpu_to_le64(recv_ctx->phys_addr + sizeof(struct netxen_ring_ctx)); tx_ring->hw_consumer = (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx)); @@ -627,8 +633,6 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) tx_ring->desc_head = (struct cmd_desc_type0 *)addr; - recv_ctx = &adapter->recv_ctx; - for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; addr = pci_alloc_consistent(adapter->pdev, @@ -713,16 +717,18 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) netxen_api_unlock(adapter); } - if (adapter->ctx_desc != NULL) { + recv_ctx = &adapter->recv_ctx; + + if (recv_ctx->hwctx != NULL) { pci_free_consistent(adapter->pdev, sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), - adapter->ctx_desc, - adapter->ctx_desc_phys_addr); - adapter->ctx_desc = NULL; + recv_ctx->hwctx, + recv_ctx->phys_addr); + recv_ctx->hwctx = NULL; } - tx_ring = &adapter->tx_ring; + tx_ring = adapter->tx_ring; if (tx_ring->desc_head != NULL) { pci_free_consistent(adapter->pdev, TX_DESC_RINGSIZE(tx_ring), @@ -730,7 +736,6 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) tx_ring->desc_head = NULL; } - recv_ctx = &adapter->recv_ctx; for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 3bb2b8c74d92..db53d9cfad07 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -521,7 +521,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, i = 0; - tx_ring = &adapter->tx_ring; + tx_ring = adapter->tx_ring; netif_tx_lock_bh(adapter->netdev); producer = tx_ring->producer; diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 8893a973399a..363ef701e71e 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -137,7 +137,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter) struct netxen_cmd_buffer *cmd_buf; struct netxen_skb_frag *buffrag; int i, j; - struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; + struct nx_host_tx_ring *tx_ring = adapter->tx_ring; cmd_buf = tx_ring->cmd_buf_arr; for (i = 0; i < tx_ring->num_desc; i++) { @@ -172,6 +172,10 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) int ring; recv_ctx = &adapter->recv_ctx; + + if (recv_ctx->rds_rings == NULL) + goto skip_rds; + for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; if (rds_ring->rx_buf_arr) { @@ -179,11 +183,15 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) rds_ring->rx_buf_arr = NULL; } } + kfree(recv_ctx->rds_rings); + +skip_rds: + if (adapter->tx_ring == NULL) + return; - tx_ring = &adapter->tx_ring; + tx_ring = adapter->tx_ring; if (tx_ring->cmd_buf_arr) vfree(tx_ring->cmd_buf_arr); - return; } int netxen_alloc_sw_resources(struct netxen_adapter *adapter) @@ -191,17 +199,26 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) struct netxen_recv_context *recv_ctx; struct nx_host_rds_ring *rds_ring; struct nx_host_sds_ring *sds_ring; - struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; + struct nx_host_tx_ring *tx_ring; struct netxen_rx_buffer *rx_buf; - int ring, i, num_rx_bufs; + int ring, i, size; struct netxen_cmd_buffer *cmd_buf_arr; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; + size = sizeof(struct nx_host_tx_ring); + tx_ring = kzalloc(size, GFP_KERNEL); + if (tx_ring == NULL) { + dev_err(&pdev->dev, "%s: failed to allocate tx ring struct\n", + netdev->name); + return -ENOMEM; + } + adapter->tx_ring = tx_ring; + tx_ring->num_desc = adapter->num_txd; - cmd_buf_arr = - (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(tx_ring)); + + cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); if (cmd_buf_arr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n", netdev->name); @@ -211,6 +228,16 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) tx_ring->cmd_buf_arr = cmd_buf_arr; recv_ctx = &adapter->recv_ctx; + + size = adapter->max_rds_rings * sizeof (struct nx_host_rds_ring); + rds_ring = kzalloc(size, GFP_KERNEL); + if (rds_ring == NULL) { + dev_err(&pdev->dev, "%s: failed to allocate rds ring struct\n", + netdev->name); + return -ENOMEM; + } + recv_ctx->rds_rings = rds_ring; + for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; switch (ring) { @@ -262,9 +289,8 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) * Now go through all of them, set reference handles * and put them in the queues. */ - num_rx_bufs = rds_ring->num_desc; rx_buf = rds_ring->rx_buf_arr; - for (i = 0; i < num_rx_bufs; i++) { + for (i = 0; i < rds_ring->num_desc; i++) { list_add_tail(&rx_buf->list, &rds_ring->free_list); rx_buf->ref_handle = i; @@ -1064,7 +1090,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) struct net_device *netdev = adapter->netdev; struct netxen_skb_frag *frag; int done = 0; - struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; + struct nx_host_tx_ring *tx_ring = adapter->tx_ring; if (!spin_trylock(&adapter->tx_clean_lock)) return 1; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 8331580fe161..07959fe06f22 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -857,7 +857,7 @@ netxen_nic_attach(struct netxen_adapter *adapter) } if (adapter->fw_major < 4) { - tx_ring = &adapter->tx_ring; + tx_ring = adapter->tx_ring; tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum]; tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum]; @@ -1315,7 +1315,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); - struct nx_host_tx_ring *tx_ring = &adapter->tx_ring; + struct nx_host_tx_ring *tx_ring = adapter->tx_ring; unsigned int first_seg_len = skb->len - skb->data_len; struct netxen_cmd_buffer *pbuf; struct netxen_skb_frag *buffrag; -- GitLab From f7185c71234434d48b96f9a0387737df1759a4af Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Tue, 28 Apr 2009 15:29:11 +0000 Subject: [PATCH 0876/6080] netxen: fix firmware download o hold the firmware in memory across suspend, since filesystem may not be up after resuming. o reset the chip after requesting firmware, to minimize downtime for NC-SI. Signed-off-by: Dhananjay Phadke Signed-off-by: David S. Miller --- drivers/net/netxen/netxen_nic.h | 9 +- drivers/net/netxen/netxen_nic_hw.c | 195 -------------------------- drivers/net/netxen/netxen_nic_init.c | 196 +++++++++++++++++++++++++++ drivers/net/netxen/netxen_nic_main.c | 23 ++-- 4 files changed, 216 insertions(+), 207 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 16f5e2267eb3..8dacfbb003e2 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -1255,8 +1256,6 @@ struct netxen_adapter { u32 flags; u32 irq; u32 temp; - u32 fw_major; - u32 fw_version; struct netxen_adapter_stats stats; @@ -1295,6 +1294,10 @@ struct netxen_adapter { struct net_device_stats net_stats; nx_nic_intr_coalesce_t coal; + + u32 fw_major; + u32 fw_version; + const struct firmware *fw; }; /* @@ -1376,6 +1379,8 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter); int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); int netxen_load_firmware(struct netxen_adapter *adapter); +void netxen_request_firmware(struct netxen_adapter *adapter); +void netxen_release_firmware(struct netxen_adapter *adapter); int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index db53d9cfad07..9f5ced3eaf9d 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -32,7 +32,6 @@ #include "netxen_nic_hw.h" #include "netxen_nic_phan_reg.h" -#include #include #define MASK(n) ((1ULL<<(n))-1) @@ -1016,200 +1015,6 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off) (ulong)adapter->ahw.pci_base0; } -static int -netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname, - const struct firmware *fw) -{ - u64 *ptr64; - u32 i, flashaddr, size; - struct pci_dev *pdev = adapter->pdev; - - if (fw) - dev_info(&pdev->dev, "loading firmware from file %s\n", fwname); - else - dev_info(&pdev->dev, "loading firmware from flash\n"); - - if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) - NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); - - if (fw) { - __le64 data; - - size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; - - ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START]; - flashaddr = NETXEN_BOOTLD_START; - - for (i = 0; i < size; i++) { - data = cpu_to_le64(ptr64[i]); - adapter->pci_mem_write(adapter, flashaddr, &data, 8); - flashaddr += 8; - } - - size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET]; - size = (__force u32)cpu_to_le32(size) / 8; - - ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START]; - flashaddr = NETXEN_IMAGE_START; - - for (i = 0; i < size; i++) { - data = cpu_to_le64(ptr64[i]); - - if (adapter->pci_mem_write(adapter, - flashaddr, &data, 8)) - return -EIO; - - flashaddr += 8; - } - } else { - u32 data; - - size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4; - flashaddr = NETXEN_BOOTLD_START; - - for (i = 0; i < size; i++) { - if (netxen_rom_fast_read(adapter, - flashaddr, (int *)&data) != 0) - return -EIO; - - if (adapter->pci_mem_write(adapter, - flashaddr, &data, 4)) - return -EIO; - - flashaddr += 4; - } - } - msleep(1); - - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); - else { - NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); - NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0); - } - - return 0; -} - -static int -netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname, - const struct firmware *fw) -{ - __le32 val; - u32 major, minor, build, ver, min_ver, bios; - struct pci_dev *pdev = adapter->pdev; - - if (fw->size < NX_FW_MIN_SIZE) - return -EINVAL; - - val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); - if ((__force u32)val != NETXEN_BDINFO_MAGIC) - return -EINVAL; - - val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); - major = (__force u32)val & 0xff; - minor = ((__force u32)val >> 8) & 0xff; - build = (__force u32)val >> 16; - - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) - min_ver = NETXEN_VERSION_CODE(4, 0, 216); - else - min_ver = NETXEN_VERSION_CODE(3, 4, 216); - - ver = NETXEN_VERSION_CODE(major, minor, build); - - if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { - dev_err(&pdev->dev, - "%s: firmware version %d.%d.%d unsupported\n", - fwname, major, minor, build); - return -EINVAL; - } - - val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); - netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); - if ((__force u32)val != bios) { - dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", - fwname); - return -EINVAL; - } - - /* check if flashed firmware is newer */ - if (netxen_rom_fast_read(adapter, - NX_FW_VERSION_OFFSET, (int *)&val)) - return -EIO; - major = (__force u32)val & 0xff; - minor = ((__force u32)val >> 8) & 0xff; - build = (__force u32)val >> 16; - if (NETXEN_VERSION_CODE(major, minor, build) > ver) - return -EINVAL; - - NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); - return 0; -} - -static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" }; - -int netxen_load_firmware(struct netxen_adapter *adapter) -{ - u32 capability, flashed_ver; - const struct firmware *fw; - int fw_type; - struct pci_dev *pdev = adapter->pdev; - int rc = 0; - - if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { - fw_type = NX_P2_MN_ROMIMAGE; - goto request_fw; - } else { - fw_type = NX_P3_CT_ROMIMAGE; - goto request_fw; - } - -request_mn: - capability = 0; - - netxen_rom_fast_read(adapter, - NX_FW_VERSION_OFFSET, (int *)&flashed_ver); - if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { - capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); - if (capability & NX_PEG_TUNE_MN_PRESENT) { - fw_type = NX_P3_MN_ROMIMAGE; - goto request_fw; - } - } - -request_fw: - rc = request_firmware(&fw, fw_name[fw_type], &pdev->dev); - if (rc != 0) { - if (fw_type == NX_P3_CT_ROMIMAGE) { - msleep(1); - goto request_mn; - } - - fw = NULL; - goto load_fw; - } - - rc = netxen_validate_firmware(adapter, fw_name[fw_type], fw); - if (rc != 0) { - release_firmware(fw); - - if (fw_type == NX_P3_CT_ROMIMAGE) { - msleep(1); - goto request_mn; - } - - fw = NULL; - } - -load_fw: - rc = netxen_do_load_firmware(adapter, fw_name[fw_type], fw); - - if (fw) - release_firmware(fw); - return rc; -} - int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) { diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 363ef701e71e..d18216779a09 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -683,6 +683,202 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) return 0; } +int +netxen_load_firmware(struct netxen_adapter *adapter) +{ + u64 *ptr64; + u32 i, flashaddr, size; + const struct firmware *fw = adapter->fw; + + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) + NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1); + + if (fw) { + __le64 data; + + size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8; + + ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START]; + flashaddr = NETXEN_BOOTLD_START; + + for (i = 0; i < size; i++) { + data = cpu_to_le64(ptr64[i]); + adapter->pci_mem_write(adapter, flashaddr, &data, 8); + flashaddr += 8; + } + + size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET]; + size = (__force u32)cpu_to_le32(size) / 8; + + ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START]; + flashaddr = NETXEN_IMAGE_START; + + for (i = 0; i < size; i++) { + data = cpu_to_le64(ptr64[i]); + + if (adapter->pci_mem_write(adapter, + flashaddr, &data, 8)) + return -EIO; + + flashaddr += 8; + } + } else { + u32 data; + + size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4; + flashaddr = NETXEN_BOOTLD_START; + + for (i = 0; i < size; i++) { + if (netxen_rom_fast_read(adapter, + flashaddr, (int *)&data) != 0) + return -EIO; + + if (adapter->pci_mem_write(adapter, + flashaddr, &data, 4)) + return -EIO; + + flashaddr += 4; + } + } + msleep(1); + + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d); + else { + NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); + NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0); + } + + return 0; +} + +static int +netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname) +{ + __le32 val; + u32 major, minor, build, ver, min_ver, bios; + struct pci_dev *pdev = adapter->pdev; + const struct firmware *fw = adapter->fw; + + if (fw->size < NX_FW_MIN_SIZE) + return -EINVAL; + + val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]); + if ((__force u32)val != NETXEN_BDINFO_MAGIC) + return -EINVAL; + + val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]); + major = (__force u32)val & 0xff; + minor = ((__force u32)val >> 8) & 0xff; + build = (__force u32)val >> 16; + + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + min_ver = NETXEN_VERSION_CODE(4, 0, 216); + else + min_ver = NETXEN_VERSION_CODE(3, 4, 216); + + ver = NETXEN_VERSION_CODE(major, minor, build); + + if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) { + dev_err(&pdev->dev, + "%s: firmware version %d.%d.%d unsupported\n", + fwname, major, minor, build); + return -EINVAL; + } + + val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]); + netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios); + if ((__force u32)val != bios) { + dev_err(&pdev->dev, "%s: firmware bios is incompatible\n", + fwname); + return -EINVAL; + } + + /* check if flashed firmware is newer */ + if (netxen_rom_fast_read(adapter, + NX_FW_VERSION_OFFSET, (int *)&val)) + return -EIO; + major = (__force u32)val & 0xff; + minor = ((__force u32)val >> 8) & 0xff; + build = (__force u32)val >> 16; + if (NETXEN_VERSION_CODE(major, minor, build) > ver) + return -EINVAL; + + NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); + return 0; +} + +static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" }; + +void netxen_request_firmware(struct netxen_adapter *adapter) +{ + u32 capability, flashed_ver; + int fw_type; + struct pci_dev *pdev = adapter->pdev; + int rc = 0; + + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { + fw_type = NX_P2_MN_ROMIMAGE; + goto request_fw; + } else { + fw_type = NX_P3_CT_ROMIMAGE; + goto request_fw; + } + +request_mn: + capability = 0; + + netxen_rom_fast_read(adapter, + NX_FW_VERSION_OFFSET, (int *)&flashed_ver); + if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) { + capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY); + if (capability & NX_PEG_TUNE_MN_PRESENT) { + fw_type = NX_P3_MN_ROMIMAGE; + goto request_fw; + } + } + +request_fw: + rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev); + if (rc != 0) { + if (fw_type == NX_P3_CT_ROMIMAGE) { + msleep(1); + goto request_mn; + } + + adapter->fw = NULL; + goto done; + } + + rc = netxen_validate_firmware(adapter, fw_name[fw_type]); + if (rc != 0) { + release_firmware(adapter->fw); + + if (fw_type == NX_P3_CT_ROMIMAGE) { + msleep(1); + goto request_mn; + } + + adapter->fw = NULL; + goto done; + } + +done: + if (adapter->fw) + dev_info(&pdev->dev, "loading firmware from file %s\n", + fw_name[fw_type]); + else + dev_info(&pdev->dev, "loading firmware from flash\n"); +} + + +void +netxen_release_firmware(struct netxen_adapter *adapter) +{ + if (adapter->fw) + release_firmware(adapter->fw); +} + int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) { uint64_t addr; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 07959fe06f22..5d79c19a6ec0 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -654,19 +654,17 @@ err_out: } static int -netxen_start_firmware(struct netxen_adapter *adapter) +netxen_start_firmware(struct netxen_adapter *adapter, int request_fw) { int val, err, first_boot; struct pci_dev *pdev = adapter->pdev; int first_driver = 0; - if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { - if (adapter->ahw.pci_func == 0) - first_driver = 1; - } else { - if (adapter->portnum == 0) - first_driver = 1; - } + + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) + first_driver = (adapter->portnum == 0); + else + first_driver = (adapter->ahw.pci_func == 0); if (!first_driver) return 0; @@ -679,6 +677,9 @@ netxen_start_firmware(struct netxen_adapter *adapter) return err; } + if (request_fw) + netxen_request_firmware(adapter); + if (first_boot != 0x55555555) { NXWR32(adapter, CRB_CMDPEG_STATE, 0); netxen_pinit_from_rom(adapter, 0); @@ -1014,7 +1015,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } - err = netxen_start_firmware(adapter); + err = netxen_start_firmware(adapter, 1); if (err) goto err_out_iounmap; @@ -1125,6 +1126,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netxen_cleanup_pci_map(adapter); + netxen_release_firmware(adapter); + pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); @@ -1176,7 +1179,7 @@ netxen_nic_resume(struct pci_dev *pdev) adapter->curr_window = 255; - err = netxen_start_firmware(adapter); + err = netxen_start_firmware(adapter, 0); if (err) { dev_err(&pdev->dev, "failed to start firmware\n"); return err; -- GitLab From dd4d8ca6446538a904127838cb6c9a4cffe690f7 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Wed, 29 Apr 2009 00:22:31 -0700 Subject: [PATCH 0877/6080] ixgbe: Use pci_wake_from_d3() instead of multiple pci_enable_wake() We were calling pci_enable_wake() twice in a row for both D3_hot and D3_cold. This replaces those calls with a call to pci_wake_from_d3() to avoid issues with PCI PM vs ordering constraints. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5020f11ae10f..01a88265d401 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3738,8 +3738,7 @@ static int ixgbe_resume(struct pci_dev *pdev) } pci_set_master(pdev); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); + pci_wake_from_d3(pdev, false); err = ixgbe_init_interrupt_scheme(adapter); if (err) { @@ -3813,13 +3812,10 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0); } - if (wufc && hw->mac.type == ixgbe_mac_82599EB) { - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } else { - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - } + if (wufc && hw->mac.type == ixgbe_mac_82599EB) + pci_wake_from_d3(pdev, true); + else + pci_wake_from_d3(pdev, false); *enable_wake = !!wufc; @@ -5101,8 +5097,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) pci_set_master(pdev); pci_restore_state(pdev); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); + pci_wake_from_d3(pdev, false); ixgbe_reset(adapter); IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); -- GitLab From da1a776be1ac7f78bb30ececbec4c1383163b079 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:46:58 +0200 Subject: [PATCH 0878/6080] perf_counter, x86: remove X86_FEATURE_ARCH_PERFMON flag for AMD cpus X86_FEATURE_ARCH_PERFMON is an Intel hardware feature that does not work on AMD CPUs. The flag is now only used in Intel specific code (especially initialization). [ Impact: refactor code ] Signed-off-by: Robert Richter Acked-by: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1241002046-8832-2-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/amd.c | 4 ---- arch/x86/kernel/cpu/perf_counter.c | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index fd69c514ca2a..7e4a459daa64 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -420,10 +420,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) if (c->x86 >= 6) set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK); - /* Enable Performance counter for K7 and later */ - if (c->x86 > 6 && c->x86 <= 0x11) - set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); - if (!c->x86_model_id[0]) { switch (c->x86) { case 0xf: diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 0fcbaab83f9b..7d0f81dcb524 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -949,6 +949,9 @@ static struct pmc_x86_ops *pmc_intel_init(void) unsigned int unused; unsigned int ebx; + if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return NULL; + /* * Check whether the Architectural PerfMon supports * Branch Misses Retired Event or not. @@ -987,9 +990,6 @@ static struct pmc_x86_ops *pmc_amd_init(void) void __init init_hw_perf_counters(void) { - if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return; - switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_INTEL: pmc_ops = pmc_intel_init(); -- GitLab From 829b42dd395c5801f6ae87da87ecbdcfd5ef1a6c Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:46:59 +0200 Subject: [PATCH 0879/6080] perf_counter, x86: declare perf_max_counters only for CONFIG_PERF_COUNTERS This is only needed for CONFIG_PERF_COUNTERS enabled. [ Impact: cleanup ] Signed-off-by: Robert Richter Acked-by: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1241002046-8832-3-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- include/linux/perf_counter.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index 981432885301..be10b3ffe320 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -512,12 +512,13 @@ struct perf_cpu_context { int recursion[4]; }; +#ifdef CONFIG_PERF_COUNTERS + /* * Set by architecture code: */ extern int perf_max_counters; -#ifdef CONFIG_PERF_COUNTERS extern const struct hw_perf_counter_ops * hw_perf_counter_init(struct perf_counter *counter); -- GitLab From 4138960a9251a265002b5cf07e671a49f8495381 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:00 +0200 Subject: [PATCH 0880/6080] perf_counter, x86: add default path to cpu detection This quits hw counter initialization immediately if no cpu is detected. [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-4-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 7d0f81dcb524..d6d6529349dd 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -997,6 +997,8 @@ void __init init_hw_perf_counters(void) case X86_VENDOR_AMD: pmc_ops = pmc_amd_init(); break; + default: + return; } if (!pmc_ops) return; -- GitLab From 4295ee62660b13ddb87d41539f49b239e6e7d56f Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:01 +0200 Subject: [PATCH 0881/6080] perf_counter, x86: rework pmc_amd_save_disable_all() and pmc_amd_restore_all() MSR reads and writes are expensive. This patch adds checks to avoid its usage where possible. [ Impact: micro-optimization on AMD CPUs ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-5-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index d6d6529349dd..75a090394b6d 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -334,11 +334,13 @@ static u64 pmc_amd_save_disable_all(void) for (idx = 0; idx < nr_counters_generic; idx++) { u64 val; + if (!test_bit(idx, cpuc->active_mask)) + continue; rdmsrl(MSR_K7_EVNTSEL0 + idx, val); - if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) { - val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsrl(MSR_K7_EVNTSEL0 + idx, val); - } + if (!(val & ARCH_PERFMON_EVENTSEL0_ENABLE)) + continue; + val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsrl(MSR_K7_EVNTSEL0 + idx, val); } return enabled; @@ -372,13 +374,15 @@ static void pmc_amd_restore_all(u64 ctrl) return; for (idx = 0; idx < nr_counters_generic; idx++) { - if (test_bit(idx, cpuc->active_mask)) { - u64 val; + u64 val; - rdmsrl(MSR_K7_EVNTSEL0 + idx, val); - val |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsrl(MSR_K7_EVNTSEL0 + idx, val); - } + if (!test_bit(idx, cpuc->active_mask)) + continue; + rdmsrl(MSR_K7_EVNTSEL0 + idx, val); + if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) + continue; + val |= ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsrl(MSR_K7_EVNTSEL0 + idx, val); } } -- GitLab From 527e26af3741a2168986d8b82653ffe173891324 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:02 +0200 Subject: [PATCH 0882/6080] perf_counter, x86: protect per-cpu variables with compile barriers only Per-cpu variables needn't to be protected with cpu barriers (smp_wmb()). Protection is only needed for preemption on the same cpu (rescheduling or the nmi handler). This can be done using a compiler barrier only. [ Impact: micro-optimization ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-6-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 75a090394b6d..ad663d5ad2d9 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -673,7 +673,7 @@ try_generic: /* * Make it visible before enabling the hw: */ - smp_wmb(); + barrier(); __hw_perf_counter_set_period(counter, hwc, idx); __pmc_generic_enable(counter, hwc, idx); @@ -745,7 +745,7 @@ static void pmc_generic_disable(struct perf_counter *counter) * Make sure the cleared pointer becomes visible before we * (potentially) free the counter: */ - smp_wmb(); + barrier(); /* * Drain the remaining delta count out of a counter -- GitLab From 4aeb0b4239bb3b67ed402cb9cef3e000c892cadf Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:03 +0200 Subject: [PATCH 0883/6080] perfcounters: rename struct hw_perf_counter_ops into struct pmu This patch renames struct hw_perf_counter_ops into struct pmu. It introduces a structure to describe a cpu specific pmu (performance monitoring unit). It may contain ops and data. The new name of the structure fits better, is shorter, and thus better to handle. Where it was appropriate, names of function and variable have been changed too. [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-7-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_counter.c | 25 ++++++----- arch/x86/kernel/cpu/perf_counter.c | 37 ++++++++-------- include/linux/perf_counter.h | 9 ++-- kernel/perf_counter.c | 68 ++++++++++++++---------------- 4 files changed, 66 insertions(+), 73 deletions(-) diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index bd76d0fa2c35..d9bbe5efc649 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -256,7 +256,7 @@ static int check_excludes(struct perf_counter **ctrs, int n_prev, int n_new) return 0; } -static void power_perf_read(struct perf_counter *counter) +static void power_pmu_read(struct perf_counter *counter) { long val, delta, prev; @@ -405,7 +405,7 @@ void hw_perf_restore(u64 disable) for (i = 0; i < cpuhw->n_counters; ++i) { counter = cpuhw->counter[i]; if (counter->hw.idx && counter->hw.idx != hwc_index[i] + 1) { - power_perf_read(counter); + power_pmu_read(counter); write_pmc(counter->hw.idx, 0); counter->hw.idx = 0; } @@ -477,7 +477,7 @@ static void counter_sched_in(struct perf_counter *counter, int cpu) counter->oncpu = cpu; counter->tstamp_running += counter->ctx->time - counter->tstamp_stopped; if (is_software_counter(counter)) - counter->hw_ops->enable(counter); + counter->pmu->enable(counter); } /* @@ -533,7 +533,7 @@ int hw_perf_group_sched_in(struct perf_counter *group_leader, * re-enable the PMU in order to get hw_perf_restore to do the * actual work of reconfiguring the PMU. */ -static int power_perf_enable(struct perf_counter *counter) +static int power_pmu_enable(struct perf_counter *counter) { struct cpu_hw_counters *cpuhw; unsigned long flags; @@ -573,7 +573,7 @@ static int power_perf_enable(struct perf_counter *counter) /* * Remove a counter from the PMU. */ -static void power_perf_disable(struct perf_counter *counter) +static void power_pmu_disable(struct perf_counter *counter) { struct cpu_hw_counters *cpuhw; long i; @@ -583,7 +583,7 @@ static void power_perf_disable(struct perf_counter *counter) local_irq_save(flags); pmudis = hw_perf_save_disable(); - power_perf_read(counter); + power_pmu_read(counter); cpuhw = &__get_cpu_var(cpu_hw_counters); for (i = 0; i < cpuhw->n_counters; ++i) { @@ -607,10 +607,10 @@ static void power_perf_disable(struct perf_counter *counter) local_irq_restore(flags); } -struct hw_perf_counter_ops power_perf_ops = { - .enable = power_perf_enable, - .disable = power_perf_disable, - .read = power_perf_read +struct pmu power_pmu = { + .enable = power_pmu_enable, + .disable = power_pmu_disable, + .read = power_pmu_read, }; /* Number of perf_counters counting hardware events */ @@ -631,8 +631,7 @@ static void hw_perf_counter_destroy(struct perf_counter *counter) } } -const struct hw_perf_counter_ops * -hw_perf_counter_init(struct perf_counter *counter) +const struct pmu *hw_perf_counter_init(struct perf_counter *counter) { unsigned long ev; struct perf_counter *ctrs[MAX_HWCOUNTERS]; @@ -705,7 +704,7 @@ hw_perf_counter_init(struct perf_counter *counter) if (err) return ERR_PTR(err); - return &power_perf_ops; + return &power_pmu; } /* diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index ad663d5ad2d9..95de980c74a0 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -515,8 +515,8 @@ __pmc_fixed_disable(struct perf_counter *counter, } static inline void -__pmc_generic_disable(struct perf_counter *counter, - struct hw_perf_counter *hwc, unsigned int idx) +__x86_pmu_disable(struct perf_counter *counter, + struct hw_perf_counter *hwc, unsigned int idx) { if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) __pmc_fixed_disable(counter, hwc, idx); @@ -591,8 +591,8 @@ __pmc_fixed_enable(struct perf_counter *counter, } static void -__pmc_generic_enable(struct perf_counter *counter, - struct hw_perf_counter *hwc, int idx) +__x86_pmu_enable(struct perf_counter *counter, + struct hw_perf_counter *hwc, int idx) { if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) __pmc_fixed_enable(counter, hwc, idx); @@ -626,7 +626,7 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) /* * Find a PMC slot for the freshly enabled / scheduled in counter: */ -static int pmc_generic_enable(struct perf_counter *counter) +static int x86_pmu_enable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); struct hw_perf_counter *hwc = &counter->hw; @@ -667,7 +667,7 @@ try_generic: perf_counters_lapic_init(hwc->nmi); - __pmc_generic_disable(counter, hwc, idx); + __x86_pmu_disable(counter, hwc, idx); cpuc->counters[idx] = counter; /* @@ -676,7 +676,7 @@ try_generic: barrier(); __hw_perf_counter_set_period(counter, hwc, idx); - __pmc_generic_enable(counter, hwc, idx); + __x86_pmu_enable(counter, hwc, idx); return 0; } @@ -731,13 +731,13 @@ void perf_counter_print_debug(void) local_irq_enable(); } -static void pmc_generic_disable(struct perf_counter *counter) +static void x86_pmu_disable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); struct hw_perf_counter *hwc = &counter->hw; unsigned int idx = hwc->idx; - __pmc_generic_disable(counter, hwc, idx); + __x86_pmu_disable(counter, hwc, idx); clear_bit(idx, cpuc->used); cpuc->counters[idx] = NULL; @@ -767,7 +767,7 @@ static void perf_save_and_restart(struct perf_counter *counter) __hw_perf_counter_set_period(counter, hwc, idx); if (counter->state == PERF_COUNTER_STATE_ACTIVE) - __pmc_generic_enable(counter, hwc, idx); + __x86_pmu_enable(counter, hwc, idx); } /* @@ -805,7 +805,7 @@ again: perf_save_and_restart(counter); if (perf_counter_overflow(counter, nmi, regs, 0)) - __pmc_generic_disable(counter, &counter->hw, bit); + __x86_pmu_disable(counter, &counter->hw, bit); } hw_perf_ack_status(ack); @@ -1034,19 +1034,18 @@ void __init init_hw_perf_counters(void) register_die_notifier(&perf_counter_nmi_notifier); } -static void pmc_generic_read(struct perf_counter *counter) +static void x86_pmu_read(struct perf_counter *counter) { x86_perf_counter_update(counter, &counter->hw, counter->hw.idx); } -static const struct hw_perf_counter_ops x86_perf_counter_ops = { - .enable = pmc_generic_enable, - .disable = pmc_generic_disable, - .read = pmc_generic_read, +static const struct pmu pmu = { + .enable = x86_pmu_enable, + .disable = x86_pmu_disable, + .read = x86_pmu_read, }; -const struct hw_perf_counter_ops * -hw_perf_counter_init(struct perf_counter *counter) +const struct pmu *hw_perf_counter_init(struct perf_counter *counter) { int err; @@ -1054,7 +1053,7 @@ hw_perf_counter_init(struct perf_counter *counter) if (err) return ERR_PTR(err); - return &x86_perf_counter_ops; + return &pmu; } /* diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index be10b3ffe320..c3db52dc876a 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -334,9 +334,9 @@ struct hw_perf_counter { struct perf_counter; /** - * struct hw_perf_counter_ops - performance counter hw ops + * struct pmu - generic performance monitoring unit */ -struct hw_perf_counter_ops { +struct pmu { int (*enable) (struct perf_counter *counter); void (*disable) (struct perf_counter *counter); void (*read) (struct perf_counter *counter); @@ -381,7 +381,7 @@ struct perf_counter { struct list_head sibling_list; int nr_siblings; struct perf_counter *group_leader; - const struct hw_perf_counter_ops *hw_ops; + const struct pmu *pmu; enum perf_counter_active_state state; enum perf_counter_active_state prev_state; @@ -519,8 +519,7 @@ struct perf_cpu_context { */ extern int perf_max_counters; -extern const struct hw_perf_counter_ops * -hw_perf_counter_init(struct perf_counter *counter); +extern const struct pmu *hw_perf_counter_init(struct perf_counter *counter); extern void perf_counter_task_sched_in(struct task_struct *task, int cpu); extern void perf_counter_task_sched_out(struct task_struct *task, int cpu); diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 09396098dd0d..582108addefa 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -52,8 +52,7 @@ static DEFINE_MUTEX(perf_resource_mutex); /* * Architecture provided APIs - weak aliases: */ -extern __weak const struct hw_perf_counter_ops * -hw_perf_counter_init(struct perf_counter *counter) +extern __weak const struct pmu *hw_perf_counter_init(struct perf_counter *counter) { return NULL; } @@ -124,7 +123,7 @@ counter_sched_out(struct perf_counter *counter, counter->state = PERF_COUNTER_STATE_INACTIVE; counter->tstamp_stopped = ctx->time; - counter->hw_ops->disable(counter); + counter->pmu->disable(counter); counter->oncpu = -1; if (!is_software_counter(counter)) @@ -417,7 +416,7 @@ counter_sched_in(struct perf_counter *counter, */ smp_wmb(); - if (counter->hw_ops->enable(counter)) { + if (counter->pmu->enable(counter)) { counter->state = PERF_COUNTER_STATE_INACTIVE; counter->oncpu = -1; return -EAGAIN; @@ -1096,7 +1095,7 @@ static void __read(void *info) local_irq_save(flags); if (ctx->is_active) update_context_time(ctx); - counter->hw_ops->read(counter); + counter->pmu->read(counter); update_counter_times(counter); local_irq_restore(flags); } @@ -1922,7 +1921,7 @@ static void perf_counter_output(struct perf_counter *counter, leader = counter->group_leader; list_for_each_entry(sub, &leader->sibling_list, list_entry) { if (sub != counter) - sub->hw_ops->read(sub); + sub->pmu->read(sub); group_entry.event = sub->hw_event.config; group_entry.counter = atomic64_read(&sub->count); @@ -2264,7 +2263,7 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) struct pt_regs *regs; counter = container_of(hrtimer, struct perf_counter, hw.hrtimer); - counter->hw_ops->read(counter); + counter->pmu->read(counter); regs = get_irq_regs(); /* @@ -2410,7 +2409,7 @@ static void perf_swcounter_disable(struct perf_counter *counter) perf_swcounter_update(counter); } -static const struct hw_perf_counter_ops perf_ops_generic = { +static const struct pmu perf_ops_generic = { .enable = perf_swcounter_enable, .disable = perf_swcounter_disable, .read = perf_swcounter_read, @@ -2460,7 +2459,7 @@ static void cpu_clock_perf_counter_read(struct perf_counter *counter) cpu_clock_perf_counter_update(counter); } -static const struct hw_perf_counter_ops perf_ops_cpu_clock = { +static const struct pmu perf_ops_cpu_clock = { .enable = cpu_clock_perf_counter_enable, .disable = cpu_clock_perf_counter_disable, .read = cpu_clock_perf_counter_read, @@ -2522,7 +2521,7 @@ static void task_clock_perf_counter_read(struct perf_counter *counter) task_clock_perf_counter_update(counter, time); } -static const struct hw_perf_counter_ops perf_ops_task_clock = { +static const struct pmu perf_ops_task_clock = { .enable = task_clock_perf_counter_enable, .disable = task_clock_perf_counter_disable, .read = task_clock_perf_counter_read, @@ -2574,7 +2573,7 @@ static void cpu_migrations_perf_counter_disable(struct perf_counter *counter) cpu_migrations_perf_counter_update(counter); } -static const struct hw_perf_counter_ops perf_ops_cpu_migrations = { +static const struct pmu perf_ops_cpu_migrations = { .enable = cpu_migrations_perf_counter_enable, .disable = cpu_migrations_perf_counter_disable, .read = cpu_migrations_perf_counter_read, @@ -2600,8 +2599,7 @@ static void tp_perf_counter_destroy(struct perf_counter *counter) ftrace_profile_disable(perf_event_id(&counter->hw_event)); } -static const struct hw_perf_counter_ops * -tp_perf_counter_init(struct perf_counter *counter) +static const struct pmu *tp_perf_counter_init(struct perf_counter *counter) { int event_id = perf_event_id(&counter->hw_event); int ret; @@ -2616,18 +2614,16 @@ tp_perf_counter_init(struct perf_counter *counter) return &perf_ops_generic; } #else -static const struct hw_perf_counter_ops * -tp_perf_counter_init(struct perf_counter *counter) +static const struct pmu *tp_perf_counter_init(struct perf_counter *counter) { return NULL; } #endif -static const struct hw_perf_counter_ops * -sw_perf_counter_init(struct perf_counter *counter) +static const struct pmu *sw_perf_counter_init(struct perf_counter *counter) { struct perf_counter_hw_event *hw_event = &counter->hw_event; - const struct hw_perf_counter_ops *hw_ops = NULL; + const struct pmu *pmu = NULL; struct hw_perf_counter *hwc = &counter->hw; /* @@ -2639,7 +2635,7 @@ sw_perf_counter_init(struct perf_counter *counter) */ switch (perf_event_id(&counter->hw_event)) { case PERF_COUNT_CPU_CLOCK: - hw_ops = &perf_ops_cpu_clock; + pmu = &perf_ops_cpu_clock; if (hw_event->irq_period && hw_event->irq_period < 10000) hw_event->irq_period = 10000; @@ -2650,9 +2646,9 @@ sw_perf_counter_init(struct perf_counter *counter) * use the cpu_clock counter instead. */ if (counter->ctx->task) - hw_ops = &perf_ops_task_clock; + pmu = &perf_ops_task_clock; else - hw_ops = &perf_ops_cpu_clock; + pmu = &perf_ops_cpu_clock; if (hw_event->irq_period && hw_event->irq_period < 10000) hw_event->irq_period = 10000; @@ -2661,18 +2657,18 @@ sw_perf_counter_init(struct perf_counter *counter) case PERF_COUNT_PAGE_FAULTS_MIN: case PERF_COUNT_PAGE_FAULTS_MAJ: case PERF_COUNT_CONTEXT_SWITCHES: - hw_ops = &perf_ops_generic; + pmu = &perf_ops_generic; break; case PERF_COUNT_CPU_MIGRATIONS: if (!counter->hw_event.exclude_kernel) - hw_ops = &perf_ops_cpu_migrations; + pmu = &perf_ops_cpu_migrations; break; } - if (hw_ops) + if (pmu) hwc->irq_period = hw_event->irq_period; - return hw_ops; + return pmu; } /* @@ -2685,7 +2681,7 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, struct perf_counter *group_leader, gfp_t gfpflags) { - const struct hw_perf_counter_ops *hw_ops; + const struct pmu *pmu; struct perf_counter *counter; long err; @@ -2713,46 +2709,46 @@ perf_counter_alloc(struct perf_counter_hw_event *hw_event, counter->cpu = cpu; counter->hw_event = *hw_event; counter->group_leader = group_leader; - counter->hw_ops = NULL; + counter->pmu = NULL; counter->ctx = ctx; counter->state = PERF_COUNTER_STATE_INACTIVE; if (hw_event->disabled) counter->state = PERF_COUNTER_STATE_OFF; - hw_ops = NULL; + pmu = NULL; if (perf_event_raw(hw_event)) { - hw_ops = hw_perf_counter_init(counter); + pmu = hw_perf_counter_init(counter); goto done; } switch (perf_event_type(hw_event)) { case PERF_TYPE_HARDWARE: - hw_ops = hw_perf_counter_init(counter); + pmu = hw_perf_counter_init(counter); break; case PERF_TYPE_SOFTWARE: - hw_ops = sw_perf_counter_init(counter); + pmu = sw_perf_counter_init(counter); break; case PERF_TYPE_TRACEPOINT: - hw_ops = tp_perf_counter_init(counter); + pmu = tp_perf_counter_init(counter); break; } done: err = 0; - if (!hw_ops) + if (!pmu) err = -EINVAL; - else if (IS_ERR(hw_ops)) - err = PTR_ERR(hw_ops); + else if (IS_ERR(pmu)) + err = PTR_ERR(pmu); if (err) { kfree(counter); return ERR_PTR(err); } - counter->hw_ops = hw_ops; + counter->pmu = pmu; if (counter->hw_event.mmap) atomic_inc(&nr_mmap_tracking); -- GitLab From 5f4ec28ffe77c840354cce1820a3436106e9e0f1 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:04 +0200 Subject: [PATCH 0884/6080] perf_counter, x86: rename struct pmc_x86_ops into struct x86_pmu This patch renames struct pmc_x86_ops into struct x86_pmu. It introduces a structure to describe an x86 model specific pmu (performance monitoring unit). It may contain ops and data. The new name of the structure fits better, is shorter, and thus better to handle. Where it was appropriate, names of function and variable have been changed too. [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-8-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 135 +++++++++++++++-------------- 1 file changed, 68 insertions(+), 67 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 95de980c74a0..808a1a113463 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -44,9 +44,9 @@ struct cpu_hw_counters { }; /* - * struct pmc_x86_ops - performance counter x86 ops + * struct x86_pmu - generic x86 pmu */ -struct pmc_x86_ops { +struct x86_pmu { u64 (*save_disable_all)(void); void (*restore_all)(u64); u64 (*get_status)(u64); @@ -60,7 +60,7 @@ struct pmc_x86_ops { int max_events; }; -static struct pmc_x86_ops *pmc_ops __read_mostly; +static struct x86_pmu *x86_pmu __read_mostly; static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = { .enabled = 1, @@ -82,12 +82,12 @@ static const u64 intel_perfmon_event_map[] = [PERF_COUNT_BUS_CYCLES] = 0x013c, }; -static u64 pmc_intel_event_map(int event) +static u64 intel_pmu_event_map(int event) { return intel_perfmon_event_map[event]; } -static u64 pmc_intel_raw_event(u64 event) +static u64 intel_pmu_raw_event(u64 event) { #define CORE_EVNTSEL_EVENT_MASK 0x000000FFULL #define CORE_EVNTSEL_UNIT_MASK 0x0000FF00ULL @@ -114,12 +114,12 @@ static const u64 amd_perfmon_event_map[] = [PERF_COUNT_BRANCH_MISSES] = 0x00c5, }; -static u64 pmc_amd_event_map(int event) +static u64 amd_pmu_event_map(int event) { return amd_perfmon_event_map[event]; } -static u64 pmc_amd_raw_event(u64 event) +static u64 amd_pmu_raw_event(u64 event) { #define K7_EVNTSEL_EVENT_MASK 0x7000000FFULL #define K7_EVNTSEL_UNIT_MASK 0x00000FF00ULL @@ -184,12 +184,12 @@ static bool reserve_pmc_hardware(void) disable_lapic_nmi_watchdog(); for (i = 0; i < nr_counters_generic; i++) { - if (!reserve_perfctr_nmi(pmc_ops->perfctr + i)) + if (!reserve_perfctr_nmi(x86_pmu->perfctr + i)) goto perfctr_fail; } for (i = 0; i < nr_counters_generic; i++) { - if (!reserve_evntsel_nmi(pmc_ops->eventsel + i)) + if (!reserve_evntsel_nmi(x86_pmu->eventsel + i)) goto eventsel_fail; } @@ -197,13 +197,13 @@ static bool reserve_pmc_hardware(void) eventsel_fail: for (i--; i >= 0; i--) - release_evntsel_nmi(pmc_ops->eventsel + i); + release_evntsel_nmi(x86_pmu->eventsel + i); i = nr_counters_generic; perfctr_fail: for (i--; i >= 0; i--) - release_perfctr_nmi(pmc_ops->perfctr + i); + release_perfctr_nmi(x86_pmu->perfctr + i); if (nmi_watchdog == NMI_LOCAL_APIC) enable_lapic_nmi_watchdog(); @@ -216,8 +216,8 @@ static void release_pmc_hardware(void) int i; for (i = 0; i < nr_counters_generic; i++) { - release_perfctr_nmi(pmc_ops->perfctr + i); - release_evntsel_nmi(pmc_ops->eventsel + i); + release_perfctr_nmi(x86_pmu->perfctr + i); + release_evntsel_nmi(x86_pmu->eventsel + i); } if (nmi_watchdog == NMI_LOCAL_APIC) @@ -293,14 +293,14 @@ static int __hw_perf_counter_init(struct perf_counter *counter) * Raw event type provide the config in the event structure */ if (perf_event_raw(hw_event)) { - hwc->config |= pmc_ops->raw_event(perf_event_config(hw_event)); + hwc->config |= x86_pmu->raw_event(perf_event_config(hw_event)); } else { - if (perf_event_id(hw_event) >= pmc_ops->max_events) + if (perf_event_id(hw_event) >= x86_pmu->max_events) return -EINVAL; /* * The generic map: */ - hwc->config |= pmc_ops->event_map(perf_event_id(hw_event)); + hwc->config |= x86_pmu->event_map(perf_event_id(hw_event)); } counter->destroy = hw_perf_counter_destroy; @@ -308,7 +308,7 @@ static int __hw_perf_counter_init(struct perf_counter *counter) return 0; } -static u64 pmc_intel_save_disable_all(void) +static u64 intel_pmu_save_disable_all(void) { u64 ctrl; @@ -318,7 +318,7 @@ static u64 pmc_intel_save_disable_all(void) return ctrl; } -static u64 pmc_amd_save_disable_all(void) +static u64 amd_pmu_save_disable_all(void) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); int enabled, idx; @@ -327,7 +327,8 @@ static u64 pmc_amd_save_disable_all(void) cpuc->enabled = 0; /* * ensure we write the disable before we start disabling the - * counters proper, so that pcm_amd_enable() does the right thing. + * counters proper, so that amd_pmu_enable_counter() does the + * right thing. */ barrier(); @@ -351,19 +352,19 @@ u64 hw_perf_save_disable(void) if (unlikely(!perf_counters_initialized)) return 0; - return pmc_ops->save_disable_all(); + return x86_pmu->save_disable_all(); } /* * Exported because of ACPI idle */ EXPORT_SYMBOL_GPL(hw_perf_save_disable); -static void pmc_intel_restore_all(u64 ctrl) +static void intel_pmu_restore_all(u64 ctrl) { wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); } -static void pmc_amd_restore_all(u64 ctrl) +static void amd_pmu_restore_all(u64 ctrl) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); int idx; @@ -391,14 +392,14 @@ void hw_perf_restore(u64 ctrl) if (unlikely(!perf_counters_initialized)) return; - pmc_ops->restore_all(ctrl); + x86_pmu->restore_all(ctrl); } /* * Exported because of ACPI idle */ EXPORT_SYMBOL_GPL(hw_perf_restore); -static u64 pmc_intel_get_status(u64 mask) +static u64 intel_pmu_get_status(u64 mask) { u64 status; @@ -407,7 +408,7 @@ static u64 pmc_intel_get_status(u64 mask) return status; } -static u64 pmc_amd_get_status(u64 mask) +static u64 amd_pmu_get_status(u64 mask) { u64 status = 0; int idx; @@ -432,15 +433,15 @@ static u64 hw_perf_get_status(u64 mask) if (unlikely(!perf_counters_initialized)) return 0; - return pmc_ops->get_status(mask); + return x86_pmu->get_status(mask); } -static void pmc_intel_ack_status(u64 ack) +static void intel_pmu_ack_status(u64 ack) { wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack); } -static void pmc_amd_ack_status(u64 ack) +static void amd_pmu_ack_status(u64 ack) { } @@ -449,16 +450,16 @@ static void hw_perf_ack_status(u64 ack) if (unlikely(!perf_counters_initialized)) return; - pmc_ops->ack_status(ack); + x86_pmu->ack_status(ack); } -static void pmc_intel_enable(int idx, u64 config) +static void intel_pmu_enable_counter(int idx, u64 config) { wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, config | ARCH_PERFMON_EVENTSEL0_ENABLE); } -static void pmc_amd_enable(int idx, u64 config) +static void amd_pmu_enable_counter(int idx, u64 config) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); @@ -474,15 +475,15 @@ static void hw_perf_enable(int idx, u64 config) if (unlikely(!perf_counters_initialized)) return; - pmc_ops->enable(idx, config); + x86_pmu->enable(idx, config); } -static void pmc_intel_disable(int idx, u64 config) +static void intel_pmu_disable_counter(int idx, u64 config) { wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, config); } -static void pmc_amd_disable(int idx, u64 config) +static void amd_pmu_disable_counter(int idx, u64 config) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); @@ -496,7 +497,7 @@ static void hw_perf_disable(int idx, u64 config) if (unlikely(!perf_counters_initialized)) return; - pmc_ops->disable(idx, config); + x86_pmu->disable(idx, config); } static inline void @@ -613,11 +614,11 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) event = hwc->config & ARCH_PERFMON_EVENT_MASK; - if (unlikely(event == pmc_ops->event_map(PERF_COUNT_INSTRUCTIONS))) + if (unlikely(event == x86_pmu->event_map(PERF_COUNT_INSTRUCTIONS))) return X86_PMC_IDX_FIXED_INSTRUCTIONS; - if (unlikely(event == pmc_ops->event_map(PERF_COUNT_CPU_CYCLES))) + if (unlikely(event == x86_pmu->event_map(PERF_COUNT_CPU_CYCLES))) return X86_PMC_IDX_FIXED_CPU_CYCLES; - if (unlikely(event == pmc_ops->event_map(PERF_COUNT_BUS_CYCLES))) + if (unlikely(event == x86_pmu->event_map(PERF_COUNT_BUS_CYCLES))) return X86_PMC_IDX_FIXED_BUS_CYCLES; return -1; @@ -661,8 +662,8 @@ try_generic: set_bit(idx, cpuc->used); hwc->idx = idx; } - hwc->config_base = pmc_ops->eventsel; - hwc->counter_base = pmc_ops->perfctr; + hwc->config_base = x86_pmu->eventsel; + hwc->counter_base = x86_pmu->perfctr; } perf_counters_lapic_init(hwc->nmi); @@ -710,8 +711,8 @@ void perf_counter_print_debug(void) pr_info("CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); for (idx = 0; idx < nr_counters_generic; idx++) { - rdmsrl(pmc_ops->eventsel + idx, pmc_ctrl); - rdmsrl(pmc_ops->perfctr + idx, pmc_count); + rdmsrl(x86_pmu->eventsel + idx, pmc_ctrl); + rdmsrl(x86_pmu->perfctr + idx, pmc_count); prev_left = per_cpu(prev_left[idx], cpu); @@ -918,35 +919,35 @@ static __read_mostly struct notifier_block perf_counter_nmi_notifier = { .priority = 1 }; -static struct pmc_x86_ops pmc_intel_ops = { - .save_disable_all = pmc_intel_save_disable_all, - .restore_all = pmc_intel_restore_all, - .get_status = pmc_intel_get_status, - .ack_status = pmc_intel_ack_status, - .enable = pmc_intel_enable, - .disable = pmc_intel_disable, +static struct x86_pmu intel_pmu = { + .save_disable_all = intel_pmu_save_disable_all, + .restore_all = intel_pmu_restore_all, + .get_status = intel_pmu_get_status, + .ack_status = intel_pmu_ack_status, + .enable = intel_pmu_enable_counter, + .disable = intel_pmu_disable_counter, .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, .perfctr = MSR_ARCH_PERFMON_PERFCTR0, - .event_map = pmc_intel_event_map, - .raw_event = pmc_intel_raw_event, + .event_map = intel_pmu_event_map, + .raw_event = intel_pmu_raw_event, .max_events = ARRAY_SIZE(intel_perfmon_event_map), }; -static struct pmc_x86_ops pmc_amd_ops = { - .save_disable_all = pmc_amd_save_disable_all, - .restore_all = pmc_amd_restore_all, - .get_status = pmc_amd_get_status, - .ack_status = pmc_amd_ack_status, - .enable = pmc_amd_enable, - .disable = pmc_amd_disable, +static struct x86_pmu amd_pmu = { + .save_disable_all = amd_pmu_save_disable_all, + .restore_all = amd_pmu_restore_all, + .get_status = amd_pmu_get_status, + .ack_status = amd_pmu_ack_status, + .enable = amd_pmu_enable_counter, + .disable = amd_pmu_disable_counter, .eventsel = MSR_K7_EVNTSEL0, .perfctr = MSR_K7_PERFCTR0, - .event_map = pmc_amd_event_map, - .raw_event = pmc_amd_raw_event, + .event_map = amd_pmu_event_map, + .raw_event = amd_pmu_raw_event, .max_events = ARRAY_SIZE(amd_perfmon_event_map), }; -static struct pmc_x86_ops *pmc_intel_init(void) +static struct x86_pmu *intel_pmu_init(void) { union cpuid10_edx edx; union cpuid10_eax eax; @@ -977,10 +978,10 @@ static struct pmc_x86_ops *pmc_intel_init(void) nr_counters_fixed = edx.split.num_counters_fixed; counter_value_mask = (1ULL << eax.split.bit_width) - 1; - return &pmc_intel_ops; + return &intel_pmu; } -static struct pmc_x86_ops *pmc_amd_init(void) +static struct x86_pmu *amd_pmu_init(void) { nr_counters_generic = 4; nr_counters_fixed = 0; @@ -989,22 +990,22 @@ static struct pmc_x86_ops *pmc_amd_init(void) pr_info("AMD Performance Monitoring support detected.\n"); - return &pmc_amd_ops; + return &amd_pmu; } void __init init_hw_perf_counters(void) { switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_INTEL: - pmc_ops = pmc_intel_init(); + x86_pmu = intel_pmu_init(); break; case X86_VENDOR_AMD: - pmc_ops = pmc_amd_init(); + x86_pmu = amd_pmu_init(); break; default: return; } - if (!pmc_ops) + if (!x86_pmu) return; pr_info("... num counters: %d\n", nr_counters_generic); -- GitLab From 39d81eab2374d71b2d9c82f66258a1a4f57ddd2e Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:05 +0200 Subject: [PATCH 0885/6080] perf_counter, x86: make interrupt handler model specific This separates the perfcounter interrupt handler for AMD and Intel cpus. The AMD interrupt handler implementation is a follow-on patch. [ Impact: refactor and clean up code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-9-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 808a1a113463..9d90de0bd0b0 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -4,6 +4,7 @@ * Copyright(C) 2008 Thomas Gleixner * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar * Copyright(C) 2009 Jaswinder Singh Rajput + * Copyright(C) 2009 Advanced Micro Devices, Inc., Robert Richter * * For licencing details see kernel-base/COPYING */ @@ -47,6 +48,7 @@ struct cpu_hw_counters { * struct x86_pmu - generic x86 pmu */ struct x86_pmu { + int (*handle_irq)(struct pt_regs *, int); u64 (*save_disable_all)(void); void (*restore_all)(u64); u64 (*get_status)(u64); @@ -241,6 +243,10 @@ static int __hw_perf_counter_init(struct perf_counter *counter) struct hw_perf_counter *hwc = &counter->hw; int err; + /* disable temporarily */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) + return -ENOSYS; + if (unlikely(!perf_counters_initialized)) return -EINVAL; @@ -780,7 +786,7 @@ static void perf_save_and_restart(struct perf_counter *counter) * This handler is triggered by the local APIC, so the APIC IRQ handling * rules apply: */ -static int __smp_perf_counter_interrupt(struct pt_regs *regs, int nmi) +static int intel_pmu_handle_irq(struct pt_regs *regs, int nmi) { int bit, cpu = smp_processor_id(); u64 ack, status; @@ -827,6 +833,8 @@ out: return ret; } +static int amd_pmu_handle_irq(struct pt_regs *regs, int nmi) { return 0; } + void perf_counter_unthrottle(void) { struct cpu_hw_counters *cpuc; @@ -851,7 +859,7 @@ void smp_perf_counter_interrupt(struct pt_regs *regs) irq_enter(); apic_write(APIC_LVTPC, LOCAL_PERF_VECTOR); ack_APIC_irq(); - __smp_perf_counter_interrupt(regs, 0); + x86_pmu->handle_irq(regs, 0); irq_exit(); } @@ -908,7 +916,7 @@ perf_counter_nmi_handler(struct notifier_block *self, regs = args->regs; apic_write(APIC_LVTPC, APIC_DM_NMI); - ret = __smp_perf_counter_interrupt(regs, 1); + ret = x86_pmu->handle_irq(regs, 1); return ret ? NOTIFY_STOP : NOTIFY_OK; } @@ -920,6 +928,7 @@ static __read_mostly struct notifier_block perf_counter_nmi_notifier = { }; static struct x86_pmu intel_pmu = { + .handle_irq = intel_pmu_handle_irq, .save_disable_all = intel_pmu_save_disable_all, .restore_all = intel_pmu_restore_all, .get_status = intel_pmu_get_status, @@ -934,6 +943,7 @@ static struct x86_pmu intel_pmu = { }; static struct x86_pmu amd_pmu = { + .handle_irq = amd_pmu_handle_irq, .save_disable_all = amd_pmu_save_disable_all, .restore_all = amd_pmu_restore_all, .get_status = amd_pmu_get_status, -- GitLab From b7f8859a8ed1937e2139c17b84878f1d413fa659 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:06 +0200 Subject: [PATCH 0886/6080] perf_counter, x86: remove get_status() from struct x86_pmu This function is Intel only and not necessary for AMD cpus. [ Impact: simplify code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-10-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 39 ++++-------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 9d90de0bd0b0..d0bb02919c63 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -51,7 +51,6 @@ struct x86_pmu { int (*handle_irq)(struct pt_regs *, int); u64 (*save_disable_all)(void); void (*restore_all)(u64); - u64 (*get_status)(u64); void (*ack_status)(u64); void (*enable)(int, u64); void (*disable)(int, u64); @@ -405,41 +404,15 @@ void hw_perf_restore(u64 ctrl) */ EXPORT_SYMBOL_GPL(hw_perf_restore); -static u64 intel_pmu_get_status(u64 mask) +static inline u64 intel_pmu_get_status(u64 mask) { u64 status; - rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); - - return status; -} - -static u64 amd_pmu_get_status(u64 mask) -{ - u64 status = 0; - int idx; - - for (idx = 0; idx < nr_counters_generic; idx++) { - s64 val; - - if (!(mask & (1 << idx))) - continue; - - rdmsrl(MSR_K7_PERFCTR0 + idx, val); - val <<= (64 - counter_value_bits); - if (val >= 0) - status |= (1 << idx); - } - - return status; -} - -static u64 hw_perf_get_status(u64 mask) -{ if (unlikely(!perf_counters_initialized)) return 0; + rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); - return x86_pmu->get_status(mask); + return status; } static void intel_pmu_ack_status(u64 ack) @@ -795,7 +768,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs, int nmi) cpuc->throttle_ctrl = hw_perf_save_disable(); - status = hw_perf_get_status(cpuc->throttle_ctrl); + status = intel_pmu_get_status(cpuc->throttle_ctrl); if (!status) goto out; @@ -820,7 +793,7 @@ again: /* * Repeat if there is more work to be done: */ - status = hw_perf_get_status(cpuc->throttle_ctrl); + status = intel_pmu_get_status(cpuc->throttle_ctrl); if (status) goto again; out: @@ -931,7 +904,6 @@ static struct x86_pmu intel_pmu = { .handle_irq = intel_pmu_handle_irq, .save_disable_all = intel_pmu_save_disable_all, .restore_all = intel_pmu_restore_all, - .get_status = intel_pmu_get_status, .ack_status = intel_pmu_ack_status, .enable = intel_pmu_enable_counter, .disable = intel_pmu_disable_counter, @@ -946,7 +918,6 @@ static struct x86_pmu amd_pmu = { .handle_irq = amd_pmu_handle_irq, .save_disable_all = amd_pmu_save_disable_all, .restore_all = amd_pmu_restore_all, - .get_status = amd_pmu_get_status, .ack_status = amd_pmu_ack_status, .enable = amd_pmu_enable_counter, .disable = amd_pmu_disable_counter, -- GitLab From dee5d9067ca78b317538fd67930be4e09a83dbc5 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:07 +0200 Subject: [PATCH 0887/6080] perf_counter, x86: remove ack_status() from struct x86_pmu This function is Intel only and not necessary for AMD cpus. [ Impact: simplify code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-11-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index d0bb02919c63..6bbdc16cc69f 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -51,7 +51,6 @@ struct x86_pmu { int (*handle_irq)(struct pt_regs *, int); u64 (*save_disable_all)(void); void (*restore_all)(u64); - void (*ack_status)(u64); void (*enable)(int, u64); void (*disable)(int, u64); unsigned eventsel; @@ -415,23 +414,11 @@ static inline u64 intel_pmu_get_status(u64 mask) return status; } -static void intel_pmu_ack_status(u64 ack) +static inline void intel_pmu_ack_status(u64 ack) { wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack); } -static void amd_pmu_ack_status(u64 ack) -{ -} - -static void hw_perf_ack_status(u64 ack) -{ - if (unlikely(!perf_counters_initialized)) - return; - - x86_pmu->ack_status(ack); -} - static void intel_pmu_enable_counter(int idx, u64 config) { wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, @@ -788,7 +775,7 @@ again: __x86_pmu_disable(counter, &counter->hw, bit); } - hw_perf_ack_status(ack); + intel_pmu_ack_status(ack); /* * Repeat if there is more work to be done: @@ -904,7 +891,6 @@ static struct x86_pmu intel_pmu = { .handle_irq = intel_pmu_handle_irq, .save_disable_all = intel_pmu_save_disable_all, .restore_all = intel_pmu_restore_all, - .ack_status = intel_pmu_ack_status, .enable = intel_pmu_enable_counter, .disable = intel_pmu_disable_counter, .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, @@ -918,7 +904,6 @@ static struct x86_pmu amd_pmu = { .handle_irq = amd_pmu_handle_irq, .save_disable_all = amd_pmu_save_disable_all, .restore_all = amd_pmu_restore_all, - .ack_status = amd_pmu_ack_status, .enable = amd_pmu_enable_counter, .disable = amd_pmu_disable_counter, .eventsel = MSR_K7_EVNTSEL0, -- GitLab From 26816c287e13eedc67bc4ed0cd40c138314b7c7d Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:08 +0200 Subject: [PATCH 0888/6080] perf_counter, x86: rename __hw_perf_counter_set_period into x86_perf_counter_set_period [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-12-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 6bbdc16cc69f..fa6541d781bc 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -498,7 +498,7 @@ static DEFINE_PER_CPU(u64, prev_left[X86_PMC_IDX_MAX]); * To be called with the counter disabled in hw: */ static void -__hw_perf_counter_set_period(struct perf_counter *counter, +x86_perf_counter_set_period(struct perf_counter *counter, struct hw_perf_counter *hwc, int idx) { s64 left = atomic64_read(&hwc->period_left); @@ -642,7 +642,7 @@ try_generic: */ barrier(); - __hw_perf_counter_set_period(counter, hwc, idx); + x86_perf_counter_set_period(counter, hwc, idx); __x86_pmu_enable(counter, hwc, idx); return 0; @@ -731,7 +731,7 @@ static void perf_save_and_restart(struct perf_counter *counter) int idx = hwc->idx; x86_perf_counter_update(counter, hwc, idx); - __hw_perf_counter_set_period(counter, hwc, idx); + x86_perf_counter_set_period(counter, hwc, idx); if (counter->state == PERF_COUNTER_STATE_ACTIVE) __x86_pmu_enable(counter, hwc, idx); -- GitLab From 55de0f2e57994b525324bf0d04d242d9358a2417 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:09 +0200 Subject: [PATCH 0889/6080] perf_counter, x86: rename intel only functions [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-13-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index fa6541d781bc..5a52d73ccfa7 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -725,7 +725,7 @@ static void x86_pmu_disable(struct perf_counter *counter) * Save and restart an expired counter. Called by NMI contexts, * so it has to be careful about preempting normal counter ops: */ -static void perf_save_and_restart(struct perf_counter *counter) +static void intel_pmu_save_and_restart(struct perf_counter *counter) { struct hw_perf_counter *hwc = &counter->hw; int idx = hwc->idx; @@ -753,7 +753,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs, int nmi) struct cpu_hw_counters *cpuc = &per_cpu(cpu_hw_counters, cpu); int ret = 0; - cpuc->throttle_ctrl = hw_perf_save_disable(); + cpuc->throttle_ctrl = intel_pmu_save_disable_all(); status = intel_pmu_get_status(cpuc->throttle_ctrl); if (!status) @@ -770,7 +770,7 @@ again: if (!counter) continue; - perf_save_and_restart(counter); + intel_pmu_save_and_restart(counter); if (perf_counter_overflow(counter, nmi, regs, 0)) __x86_pmu_disable(counter, &counter->hw, bit); } @@ -788,7 +788,7 @@ out: * Restore - do not reenable when global enable is off or throttled: */ if (++cpuc->interrupts < PERFMON_MAX_INTERRUPTS) - hw_perf_restore(cpuc->throttle_ctrl); + intel_pmu_restore_all(cpuc->throttle_ctrl); return ret; } -- GitLab From 72eae04d3a3075c26d39e1e685acfc8e8c29db64 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:10 +0200 Subject: [PATCH 0890/6080] perf_counter, x86: modify initialization of struct x86_pmu This patch adds an error handler and changes initialization of struct x86_pmu. No functional changes. Needed for follow-on patches. [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-14-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 5a52d73ccfa7..7c72a9423636 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -913,7 +913,7 @@ static struct x86_pmu amd_pmu = { .max_events = ARRAY_SIZE(amd_perfmon_event_map), }; -static struct x86_pmu *intel_pmu_init(void) +static int intel_pmu_init(void) { union cpuid10_edx edx; union cpuid10_eax eax; @@ -921,7 +921,7 @@ static struct x86_pmu *intel_pmu_init(void) unsigned int ebx; if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return NULL; + return -ENODEV; /* * Check whether the Architectural PerfMon supports @@ -929,49 +929,54 @@ static struct x86_pmu *intel_pmu_init(void) */ cpuid(10, &eax.full, &ebx, &unused, &edx.full); if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED) - return NULL; + return -ENODEV; intel_perfmon_version = eax.split.version_id; if (intel_perfmon_version < 2) - return NULL; + return -ENODEV; pr_info("Intel Performance Monitoring support detected.\n"); pr_info("... version: %d\n", intel_perfmon_version); pr_info("... bit width: %d\n", eax.split.bit_width); pr_info("... mask length: %d\n", eax.split.mask_length); + x86_pmu = &intel_pmu; + nr_counters_generic = eax.split.num_counters; nr_counters_fixed = edx.split.num_counters_fixed; counter_value_mask = (1ULL << eax.split.bit_width) - 1; - return &intel_pmu; + return 0; } -static struct x86_pmu *amd_pmu_init(void) +static int amd_pmu_init(void) { + x86_pmu = &amd_pmu; + nr_counters_generic = 4; nr_counters_fixed = 0; counter_value_mask = 0x0000FFFFFFFFFFFFULL; counter_value_bits = 48; pr_info("AMD Performance Monitoring support detected.\n"); - - return &amd_pmu; + return 0; } void __init init_hw_perf_counters(void) { + int err; + switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_INTEL: - x86_pmu = intel_pmu_init(); + err = intel_pmu_init(); break; case X86_VENDOR_AMD: - x86_pmu = amd_pmu_init(); + err = amd_pmu_init(); break; default: return; } - if (!x86_pmu) + if (err != 0) return; pr_info("... num counters: %d\n", nr_counters_generic); -- GitLab From 4a06bd8508f65ad1dd5cd2046b85694813fa36a2 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:11 +0200 Subject: [PATCH 0891/6080] perf_counter, x86: make x86_pmu data a static struct Instead of using a pointer to reference to the x86 pmu we now have one single data structure that is initialized at the beginning. This saves the pointer access when using this memory. [ Impact: micro-optimization ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-15-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 50 +++++++++++++++--------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 7c72a9423636..68597d763389 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -60,7 +60,7 @@ struct x86_pmu { int max_events; }; -static struct x86_pmu *x86_pmu __read_mostly; +static struct x86_pmu x86_pmu __read_mostly; static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = { .enabled = 1, @@ -184,12 +184,12 @@ static bool reserve_pmc_hardware(void) disable_lapic_nmi_watchdog(); for (i = 0; i < nr_counters_generic; i++) { - if (!reserve_perfctr_nmi(x86_pmu->perfctr + i)) + if (!reserve_perfctr_nmi(x86_pmu.perfctr + i)) goto perfctr_fail; } for (i = 0; i < nr_counters_generic; i++) { - if (!reserve_evntsel_nmi(x86_pmu->eventsel + i)) + if (!reserve_evntsel_nmi(x86_pmu.eventsel + i)) goto eventsel_fail; } @@ -197,13 +197,13 @@ static bool reserve_pmc_hardware(void) eventsel_fail: for (i--; i >= 0; i--) - release_evntsel_nmi(x86_pmu->eventsel + i); + release_evntsel_nmi(x86_pmu.eventsel + i); i = nr_counters_generic; perfctr_fail: for (i--; i >= 0; i--) - release_perfctr_nmi(x86_pmu->perfctr + i); + release_perfctr_nmi(x86_pmu.perfctr + i); if (nmi_watchdog == NMI_LOCAL_APIC) enable_lapic_nmi_watchdog(); @@ -216,8 +216,8 @@ static void release_pmc_hardware(void) int i; for (i = 0; i < nr_counters_generic; i++) { - release_perfctr_nmi(x86_pmu->perfctr + i); - release_evntsel_nmi(x86_pmu->eventsel + i); + release_perfctr_nmi(x86_pmu.perfctr + i); + release_evntsel_nmi(x86_pmu.eventsel + i); } if (nmi_watchdog == NMI_LOCAL_APIC) @@ -297,14 +297,14 @@ static int __hw_perf_counter_init(struct perf_counter *counter) * Raw event type provide the config in the event structure */ if (perf_event_raw(hw_event)) { - hwc->config |= x86_pmu->raw_event(perf_event_config(hw_event)); + hwc->config |= x86_pmu.raw_event(perf_event_config(hw_event)); } else { - if (perf_event_id(hw_event) >= x86_pmu->max_events) + if (perf_event_id(hw_event) >= x86_pmu.max_events) return -EINVAL; /* * The generic map: */ - hwc->config |= x86_pmu->event_map(perf_event_id(hw_event)); + hwc->config |= x86_pmu.event_map(perf_event_id(hw_event)); } counter->destroy = hw_perf_counter_destroy; @@ -356,7 +356,7 @@ u64 hw_perf_save_disable(void) if (unlikely(!perf_counters_initialized)) return 0; - return x86_pmu->save_disable_all(); + return x86_pmu.save_disable_all(); } /* * Exported because of ACPI idle @@ -396,7 +396,7 @@ void hw_perf_restore(u64 ctrl) if (unlikely(!perf_counters_initialized)) return; - x86_pmu->restore_all(ctrl); + x86_pmu.restore_all(ctrl); } /* * Exported because of ACPI idle @@ -441,7 +441,7 @@ static void hw_perf_enable(int idx, u64 config) if (unlikely(!perf_counters_initialized)) return; - x86_pmu->enable(idx, config); + x86_pmu.enable(idx, config); } static void intel_pmu_disable_counter(int idx, u64 config) @@ -463,7 +463,7 @@ static void hw_perf_disable(int idx, u64 config) if (unlikely(!perf_counters_initialized)) return; - x86_pmu->disable(idx, config); + x86_pmu.disable(idx, config); } static inline void @@ -580,11 +580,11 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) event = hwc->config & ARCH_PERFMON_EVENT_MASK; - if (unlikely(event == x86_pmu->event_map(PERF_COUNT_INSTRUCTIONS))) + if (unlikely(event == x86_pmu.event_map(PERF_COUNT_INSTRUCTIONS))) return X86_PMC_IDX_FIXED_INSTRUCTIONS; - if (unlikely(event == x86_pmu->event_map(PERF_COUNT_CPU_CYCLES))) + if (unlikely(event == x86_pmu.event_map(PERF_COUNT_CPU_CYCLES))) return X86_PMC_IDX_FIXED_CPU_CYCLES; - if (unlikely(event == x86_pmu->event_map(PERF_COUNT_BUS_CYCLES))) + if (unlikely(event == x86_pmu.event_map(PERF_COUNT_BUS_CYCLES))) return X86_PMC_IDX_FIXED_BUS_CYCLES; return -1; @@ -628,8 +628,8 @@ try_generic: set_bit(idx, cpuc->used); hwc->idx = idx; } - hwc->config_base = x86_pmu->eventsel; - hwc->counter_base = x86_pmu->perfctr; + hwc->config_base = x86_pmu.eventsel; + hwc->counter_base = x86_pmu.perfctr; } perf_counters_lapic_init(hwc->nmi); @@ -677,8 +677,8 @@ void perf_counter_print_debug(void) pr_info("CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); for (idx = 0; idx < nr_counters_generic; idx++) { - rdmsrl(x86_pmu->eventsel + idx, pmc_ctrl); - rdmsrl(x86_pmu->perfctr + idx, pmc_count); + rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl); + rdmsrl(x86_pmu.perfctr + idx, pmc_count); prev_left = per_cpu(prev_left[idx], cpu); @@ -819,7 +819,7 @@ void smp_perf_counter_interrupt(struct pt_regs *regs) irq_enter(); apic_write(APIC_LVTPC, LOCAL_PERF_VECTOR); ack_APIC_irq(); - x86_pmu->handle_irq(regs, 0); + x86_pmu.handle_irq(regs, 0); irq_exit(); } @@ -876,7 +876,7 @@ perf_counter_nmi_handler(struct notifier_block *self, regs = args->regs; apic_write(APIC_LVTPC, APIC_DM_NMI); - ret = x86_pmu->handle_irq(regs, 1); + ret = x86_pmu.handle_irq(regs, 1); return ret ? NOTIFY_STOP : NOTIFY_OK; } @@ -940,7 +940,7 @@ static int intel_pmu_init(void) pr_info("... bit width: %d\n", eax.split.bit_width); pr_info("... mask length: %d\n", eax.split.mask_length); - x86_pmu = &intel_pmu; + x86_pmu = intel_pmu; nr_counters_generic = eax.split.num_counters; nr_counters_fixed = edx.split.num_counters_fixed; @@ -951,7 +951,7 @@ static int intel_pmu_init(void) static int amd_pmu_init(void) { - x86_pmu = &amd_pmu; + x86_pmu = amd_pmu; nr_counters_generic = 4; nr_counters_fixed = 0; -- GitLab From 0933e5c6a680ba8d8d786a6f7fa377b7ec0d1e49 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:12 +0200 Subject: [PATCH 0892/6080] perf_counter, x86: move counter parameters to struct x86_pmu [ Impact: refactor and generalize code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-16-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 80 ++++++++++++++---------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 68597d763389..75dbb1f0900e 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -24,16 +24,7 @@ #include static bool perf_counters_initialized __read_mostly; - -/* - * Number of (generic) HW counters: - */ -static int nr_counters_generic __read_mostly; static u64 perf_counter_mask __read_mostly; -static u64 counter_value_mask __read_mostly; -static int counter_value_bits __read_mostly; - -static int nr_counters_fixed __read_mostly; struct cpu_hw_counters { struct perf_counter *counters[X86_PMC_IDX_MAX]; @@ -58,6 +49,10 @@ struct x86_pmu { u64 (*event_map)(int); u64 (*raw_event)(u64); int max_events; + int num_counters; + int num_counters_fixed; + int counter_bits; + u64 counter_mask; }; static struct x86_pmu x86_pmu __read_mostly; @@ -183,12 +178,12 @@ static bool reserve_pmc_hardware(void) if (nmi_watchdog == NMI_LOCAL_APIC) disable_lapic_nmi_watchdog(); - for (i = 0; i < nr_counters_generic; i++) { + for (i = 0; i < x86_pmu.num_counters; i++) { if (!reserve_perfctr_nmi(x86_pmu.perfctr + i)) goto perfctr_fail; } - for (i = 0; i < nr_counters_generic; i++) { + for (i = 0; i < x86_pmu.num_counters; i++) { if (!reserve_evntsel_nmi(x86_pmu.eventsel + i)) goto eventsel_fail; } @@ -199,7 +194,7 @@ eventsel_fail: for (i--; i >= 0; i--) release_evntsel_nmi(x86_pmu.eventsel + i); - i = nr_counters_generic; + i = x86_pmu.num_counters; perfctr_fail: for (i--; i >= 0; i--) @@ -215,7 +210,7 @@ static void release_pmc_hardware(void) { int i; - for (i = 0; i < nr_counters_generic; i++) { + for (i = 0; i < x86_pmu.num_counters; i++) { release_perfctr_nmi(x86_pmu.perfctr + i); release_evntsel_nmi(x86_pmu.eventsel + i); } @@ -336,7 +331,7 @@ static u64 amd_pmu_save_disable_all(void) */ barrier(); - for (idx = 0; idx < nr_counters_generic; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { u64 val; if (!test_bit(idx, cpuc->active_mask)) @@ -378,7 +373,7 @@ static void amd_pmu_restore_all(u64 ctrl) if (!ctrl) return; - for (idx = 0; idx < nr_counters_generic; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { u64 val; if (!test_bit(idx, cpuc->active_mask)) @@ -527,7 +522,7 @@ x86_perf_counter_set_period(struct perf_counter *counter, atomic64_set(&hwc->prev_count, (u64)-left); err = checking_wrmsrl(hwc->counter_base + idx, - (u64)(-left) & counter_value_mask); + (u64)(-left) & x86_pmu.counter_mask); } static inline void @@ -621,8 +616,9 @@ static int x86_pmu_enable(struct perf_counter *counter) /* Try to get the previous generic counter again */ if (test_and_set_bit(idx, cpuc->used)) { try_generic: - idx = find_first_zero_bit(cpuc->used, nr_counters_generic); - if (idx == nr_counters_generic) + idx = find_first_zero_bit(cpuc->used, + x86_pmu.num_counters); + if (idx == x86_pmu.num_counters) return -EAGAIN; set_bit(idx, cpuc->used); @@ -654,7 +650,7 @@ void perf_counter_print_debug(void) struct cpu_hw_counters *cpuc; int cpu, idx; - if (!nr_counters_generic) + if (!x86_pmu.num_counters) return; local_irq_disable(); @@ -676,7 +672,7 @@ void perf_counter_print_debug(void) } pr_info("CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); - for (idx = 0; idx < nr_counters_generic; idx++) { + for (idx = 0; idx < x86_pmu.num_counters; idx++) { rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl); rdmsrl(x86_pmu.perfctr + idx, pmc_count); @@ -689,7 +685,7 @@ void perf_counter_print_debug(void) pr_info("CPU#%d: gen-PMC%d left: %016llx\n", cpu, idx, prev_left); } - for (idx = 0; idx < nr_counters_fixed; idx++) { + for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) { rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count); pr_info("CPU#%d: fixed-PMC%d count: %016llx\n", @@ -911,6 +907,9 @@ static struct x86_pmu amd_pmu = { .event_map = amd_pmu_event_map, .raw_event = amd_pmu_raw_event, .max_events = ARRAY_SIZE(amd_perfmon_event_map), + .num_counters = 4, + .counter_bits = 48, + .counter_mask = (1ULL << 48) - 1, }; static int intel_pmu_init(void) @@ -941,10 +940,10 @@ static int intel_pmu_init(void) pr_info("... mask length: %d\n", eax.split.mask_length); x86_pmu = intel_pmu; - - nr_counters_generic = eax.split.num_counters; - nr_counters_fixed = edx.split.num_counters_fixed; - counter_value_mask = (1ULL << eax.split.bit_width) - 1; + x86_pmu.num_counters = eax.split.num_counters; + x86_pmu.num_counters_fixed = edx.split.num_counters_fixed; + x86_pmu.counter_bits = eax.split.bit_width; + x86_pmu.counter_mask = (1ULL << eax.split.bit_width) - 1; return 0; } @@ -952,12 +951,6 @@ static int intel_pmu_init(void) static int amd_pmu_init(void) { x86_pmu = amd_pmu; - - nr_counters_generic = 4; - nr_counters_fixed = 0; - counter_value_mask = 0x0000FFFFFFFFFFFFULL; - counter_value_bits = 48; - pr_info("AMD Performance Monitoring support detected.\n"); return 0; } @@ -979,25 +972,26 @@ void __init init_hw_perf_counters(void) if (err != 0) return; - pr_info("... num counters: %d\n", nr_counters_generic); - if (nr_counters_generic > X86_PMC_MAX_GENERIC) { - nr_counters_generic = X86_PMC_MAX_GENERIC; + pr_info("... num counters: %d\n", x86_pmu.num_counters); + if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { + x86_pmu.num_counters = X86_PMC_MAX_GENERIC; WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!", - nr_counters_generic, X86_PMC_MAX_GENERIC); + x86_pmu.num_counters, X86_PMC_MAX_GENERIC); } - perf_counter_mask = (1 << nr_counters_generic) - 1; - perf_max_counters = nr_counters_generic; + perf_counter_mask = (1 << x86_pmu.num_counters) - 1; + perf_max_counters = x86_pmu.num_counters; - pr_info("... value mask: %016Lx\n", counter_value_mask); + pr_info("... value mask: %016Lx\n", x86_pmu.counter_mask); - if (nr_counters_fixed > X86_PMC_MAX_FIXED) { - nr_counters_fixed = X86_PMC_MAX_FIXED; + if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { + x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!", - nr_counters_fixed, X86_PMC_MAX_FIXED); + x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED); } - pr_info("... fixed counters: %d\n", nr_counters_fixed); + pr_info("... fixed counters: %d\n", x86_pmu.num_counters_fixed); - perf_counter_mask |= ((1LL << nr_counters_fixed)-1) << X86_PMC_IDX_FIXED; + perf_counter_mask |= + ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; pr_info("... counter mask: %016Lx\n", perf_counter_mask); perf_counters_initialized = true; -- GitLab From faa28ae018ed004a22aa4a7704e04ccdde4a941e Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:13 +0200 Subject: [PATCH 0893/6080] perf_counter, x86: make pmu version generic This makes the use of the version variable generic. Also, some debug messages have been generalized. [ Impact: refactor and generalize code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-17-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 75dbb1f0900e..15d2c03e16f1 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -39,6 +39,8 @@ struct cpu_hw_counters { * struct x86_pmu - generic x86 pmu */ struct x86_pmu { + const char *name; + int version; int (*handle_irq)(struct pt_regs *, int); u64 (*save_disable_all)(void); void (*restore_all)(u64); @@ -61,8 +63,6 @@ static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = { .enabled = 1, }; -static __read_mostly int intel_perfmon_version; - /* * Intel PerfMon v3. Used on Core2 and later. */ @@ -658,7 +658,7 @@ void perf_counter_print_debug(void) cpu = smp_processor_id(); cpuc = &per_cpu(cpu_hw_counters, cpu); - if (intel_perfmon_version >= 2) { + if (x86_pmu.version >= 2) { rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl); rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow); @@ -884,6 +884,7 @@ static __read_mostly struct notifier_block perf_counter_nmi_notifier = { }; static struct x86_pmu intel_pmu = { + .name = "Intel", .handle_irq = intel_pmu_handle_irq, .save_disable_all = intel_pmu_save_disable_all, .restore_all = intel_pmu_restore_all, @@ -897,6 +898,7 @@ static struct x86_pmu intel_pmu = { }; static struct x86_pmu amd_pmu = { + .name = "AMD", .handle_irq = amd_pmu_handle_irq, .save_disable_all = amd_pmu_save_disable_all, .restore_all = amd_pmu_restore_all, @@ -918,6 +920,7 @@ static int intel_pmu_init(void) union cpuid10_eax eax; unsigned int unused; unsigned int ebx; + int version; if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) return -ENODEV; @@ -930,16 +933,12 @@ static int intel_pmu_init(void) if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED) return -ENODEV; - intel_perfmon_version = eax.split.version_id; - if (intel_perfmon_version < 2) + version = eax.split.version_id; + if (version < 2) return -ENODEV; - pr_info("Intel Performance Monitoring support detected.\n"); - pr_info("... version: %d\n", intel_perfmon_version); - pr_info("... bit width: %d\n", eax.split.bit_width); - pr_info("... mask length: %d\n", eax.split.mask_length); - x86_pmu = intel_pmu; + x86_pmu.version = version; x86_pmu.num_counters = eax.split.num_counters; x86_pmu.num_counters_fixed = edx.split.num_counters_fixed; x86_pmu.counter_bits = eax.split.bit_width; @@ -951,7 +950,6 @@ static int intel_pmu_init(void) static int amd_pmu_init(void) { x86_pmu = amd_pmu; - pr_info("AMD Performance Monitoring support detected.\n"); return 0; } @@ -972,6 +970,10 @@ void __init init_hw_perf_counters(void) if (err != 0) return; + pr_info("%s Performance Monitoring support detected.\n", x86_pmu.name); + pr_info("... version: %d\n", x86_pmu.version); + pr_info("... bit width: %d\n", x86_pmu.counter_bits); + pr_info("... num counters: %d\n", x86_pmu.num_counters); if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) { x86_pmu.num_counters = X86_PMC_MAX_GENERIC; -- GitLab From bb775fc2d1dcd1aa6eafde37a8289ba2d80783aa Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:14 +0200 Subject: [PATCH 0894/6080] perf_counter, x86: make x86_pmu_read() static inline [ Impact: micro-optimization ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-18-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 15d2c03e16f1..3f3ae477a7dc 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -1002,7 +1002,7 @@ void __init init_hw_perf_counters(void) register_die_notifier(&perf_counter_nmi_notifier); } -static void x86_pmu_read(struct perf_counter *counter) +static inline void x86_pmu_read(struct perf_counter *counter) { x86_perf_counter_update(counter, &counter->hw, counter->hw.idx); } -- GitLab From 93904966934193204ad08e951f806d5631c29eb3 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:15 +0200 Subject: [PATCH 0895/6080] perf_counter, x86: rename cpuc->active_mask This is to have a consistent naming scheme with cpuc->used. [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-19-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 3f3ae477a7dc..9ec51a662db5 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -29,9 +29,9 @@ static u64 perf_counter_mask __read_mostly; struct cpu_hw_counters { struct perf_counter *counters[X86_PMC_IDX_MAX]; unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; + unsigned long active[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; unsigned long interrupts; u64 throttle_ctrl; - unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; int enabled; }; @@ -334,7 +334,7 @@ static u64 amd_pmu_save_disable_all(void) for (idx = 0; idx < x86_pmu.num_counters; idx++) { u64 val; - if (!test_bit(idx, cpuc->active_mask)) + if (!test_bit(idx, cpuc->active)) continue; rdmsrl(MSR_K7_EVNTSEL0 + idx, val); if (!(val & ARCH_PERFMON_EVENTSEL0_ENABLE)) @@ -376,7 +376,7 @@ static void amd_pmu_restore_all(u64 ctrl) for (idx = 0; idx < x86_pmu.num_counters; idx++) { u64 val; - if (!test_bit(idx, cpuc->active_mask)) + if (!test_bit(idx, cpuc->active)) continue; rdmsrl(MSR_K7_EVNTSEL0 + idx, val); if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) @@ -424,7 +424,7 @@ static void amd_pmu_enable_counter(int idx, u64 config) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); - set_bit(idx, cpuc->active_mask); + set_bit(idx, cpuc->active); if (cpuc->enabled) config |= ARCH_PERFMON_EVENTSEL0_ENABLE; @@ -448,7 +448,7 @@ static void amd_pmu_disable_counter(int idx, u64 config) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); - clear_bit(idx, cpuc->active_mask); + clear_bit(idx, cpuc->active); wrmsrl(MSR_K7_EVNTSEL0 + idx, config); } -- GitLab From 095342389e2ed8deed07b3076f990260ce3c7c9f Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:16 +0200 Subject: [PATCH 0896/6080] perf_counter, x86: generic use of cpuc->active cpuc->active will now be used to indicate an enabled counter which implies also valid pointers of cpuc->counters[]. In contrast, cpuc->used only locks the counter, but it can be still uninitialized. [ Impact: refactor and generalize code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-20-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 9ec51a662db5..f7fd4a355159 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -424,7 +424,6 @@ static void amd_pmu_enable_counter(int idx, u64 config) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); - set_bit(idx, cpuc->active); if (cpuc->enabled) config |= ARCH_PERFMON_EVENTSEL0_ENABLE; @@ -446,9 +445,6 @@ static void intel_pmu_disable_counter(int idx, u64 config) static void amd_pmu_disable_counter(int idx, u64 config) { - struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); - - clear_bit(idx, cpuc->active); wrmsrl(MSR_K7_EVNTSEL0 + idx, config); } @@ -633,10 +629,7 @@ try_generic: __x86_pmu_disable(counter, hwc, idx); cpuc->counters[idx] = counter; - /* - * Make it visible before enabling the hw: - */ - barrier(); + set_bit(idx, cpuc->active); x86_perf_counter_set_period(counter, hwc, idx); __x86_pmu_enable(counter, hwc, idx); @@ -700,10 +693,13 @@ static void x86_pmu_disable(struct perf_counter *counter) struct hw_perf_counter *hwc = &counter->hw; unsigned int idx = hwc->idx; + /* + * Must be done before we disable, otherwise the nmi handler + * could reenable again: + */ + clear_bit(idx, cpuc->active); __x86_pmu_disable(counter, hwc, idx); - clear_bit(idx, cpuc->used); - cpuc->counters[idx] = NULL; /* * Make sure the cleared pointer becomes visible before we * (potentially) free the counter: @@ -715,6 +711,8 @@ static void x86_pmu_disable(struct perf_counter *counter) * that we are disabling: */ x86_perf_counter_update(counter, hwc, idx); + cpuc->counters[idx] = NULL; + clear_bit(idx, cpuc->used); } /* @@ -763,7 +761,7 @@ again: struct perf_counter *counter = cpuc->counters[bit]; clear_bit(bit, (unsigned long *) &status); - if (!counter) + if (!test_bit(bit, cpuc->active)) continue; intel_pmu_save_and_restart(counter); -- GitLab From 6f00cada07bb5da7f751929d3173494dcc5446cc Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:17 +0200 Subject: [PATCH 0897/6080] perf_counter, x86: consistent use of type int for counter index The type of counter index is sometimes implemented as unsigned int. This patch changes this to have a consistent usage of int. [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-21-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 8 ++++---- include/linux/perf_counter.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index f7fd4a355159..d8beebeb270f 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -459,7 +459,7 @@ static void hw_perf_disable(int idx, u64 config) static inline void __pmc_fixed_disable(struct perf_counter *counter, - struct hw_perf_counter *hwc, unsigned int __idx) + struct hw_perf_counter *hwc, int __idx) { int idx = __idx - X86_PMC_IDX_FIXED; u64 ctrl_val, mask; @@ -474,7 +474,7 @@ __pmc_fixed_disable(struct perf_counter *counter, static inline void __x86_pmu_disable(struct perf_counter *counter, - struct hw_perf_counter *hwc, unsigned int idx) + struct hw_perf_counter *hwc, int idx) { if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) __pmc_fixed_disable(counter, hwc, idx); @@ -523,7 +523,7 @@ x86_perf_counter_set_period(struct perf_counter *counter, static inline void __pmc_fixed_enable(struct perf_counter *counter, - struct hw_perf_counter *hwc, unsigned int __idx) + struct hw_perf_counter *hwc, int __idx) { int idx = __idx - X86_PMC_IDX_FIXED; u64 ctrl_val, bits, mask; @@ -691,7 +691,7 @@ static void x86_pmu_disable(struct perf_counter *counter) { struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); struct hw_perf_counter *hwc = &counter->hw; - unsigned int idx = hwc->idx; + int idx = hwc->idx; /* * Must be done before we disable, otherwise the nmi handler diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h index c3db52dc876a..41aed4270057 100644 --- a/include/linux/perf_counter.h +++ b/include/linux/perf_counter.h @@ -318,7 +318,7 @@ struct hw_perf_counter { unsigned long config_base; unsigned long counter_base; int nmi; - unsigned int idx; + int idx; }; union { /* software */ atomic64_t count; -- GitLab From 7c90cc45f89af4dd4617f97d452740ad95b800d5 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:18 +0200 Subject: [PATCH 0898/6080] perf_counter, x86: rework counter enable functions There is vendor specific code in generic x86 code, and there is vendor specific code that could be generic. This patch introduces x86_pmu_enable_counter() for x86 generic code. Fixed counter code for Intel is moved to Intel only functions. In the end, checks and calls via function pointers were reduced to the necessary. Also, the internal function i/f changed. [ Impact: refactor and generalize code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-22-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 52 ++++++++++++++---------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index d8beebeb270f..ae55933ce79c 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -44,7 +44,7 @@ struct x86_pmu { int (*handle_irq)(struct pt_regs *, int); u64 (*save_disable_all)(void); void (*restore_all)(u64); - void (*enable)(int, u64); + void (*enable)(struct hw_perf_counter *, int); void (*disable)(int, u64); unsigned eventsel; unsigned perfctr; @@ -414,28 +414,15 @@ static inline void intel_pmu_ack_status(u64 ack) wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack); } -static void intel_pmu_enable_counter(int idx, u64 config) +static inline void x86_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) { - wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, - config | ARCH_PERFMON_EVENTSEL0_ENABLE); -} - -static void amd_pmu_enable_counter(int idx, u64 config) -{ - struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); - - if (cpuc->enabled) - config |= ARCH_PERFMON_EVENTSEL0_ENABLE; - - wrmsrl(MSR_K7_EVNTSEL0 + idx, config); -} + int err; -static void hw_perf_enable(int idx, u64 config) -{ if (unlikely(!perf_counters_initialized)) return; - x86_pmu.enable(idx, config); + err = checking_wrmsrl(hwc->config_base + idx, + hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE); } static void intel_pmu_disable_counter(int idx, u64 config) @@ -522,8 +509,7 @@ x86_perf_counter_set_period(struct perf_counter *counter, } static inline void -__pmc_fixed_enable(struct perf_counter *counter, - struct hw_perf_counter *hwc, int __idx) +intel_pmu_enable_fixed(struct hw_perf_counter *hwc, int __idx) { int idx = __idx - X86_PMC_IDX_FIXED; u64 ctrl_val, bits, mask; @@ -548,14 +534,24 @@ __pmc_fixed_enable(struct perf_counter *counter, err = checking_wrmsrl(hwc->config_base, ctrl_val); } -static void -__x86_pmu_enable(struct perf_counter *counter, - struct hw_perf_counter *hwc, int idx) +static void intel_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) { - if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) - __pmc_fixed_enable(counter, hwc, idx); + if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { + intel_pmu_enable_fixed(hwc, idx); + return; + } + + x86_pmu_enable_counter(hwc, idx); +} + +static void amd_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) +{ + struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters); + + if (cpuc->enabled) + x86_pmu_enable_counter(hwc, idx); else - hw_perf_enable(idx, hwc->config); + amd_pmu_disable_counter(idx, hwc->config); } static int @@ -632,7 +628,7 @@ try_generic: set_bit(idx, cpuc->active); x86_perf_counter_set_period(counter, hwc, idx); - __x86_pmu_enable(counter, hwc, idx); + x86_pmu.enable(hwc, idx); return 0; } @@ -728,7 +724,7 @@ static void intel_pmu_save_and_restart(struct perf_counter *counter) x86_perf_counter_set_period(counter, hwc, idx); if (counter->state == PERF_COUNTER_STATE_ACTIVE) - __x86_pmu_enable(counter, hwc, idx); + intel_pmu_enable_counter(hwc, idx); } /* -- GitLab From d43698918bd46c71d494555fb92195fbea1fcb6c Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:19 +0200 Subject: [PATCH 0899/6080] perf_counter, x86: rework counter disable functions As for the enable function, this patch reworks the disable functions and introduces x86_pmu_disable_counter(). The internal function i/f in struct x86_pmu changed too. [ Impact: refactor and generalize code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-23-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 48 ++++++++++++++---------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index ae55933ce79c..df9012bbd211 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -45,7 +45,7 @@ struct x86_pmu { u64 (*save_disable_all)(void); void (*restore_all)(u64); void (*enable)(struct hw_perf_counter *, int); - void (*disable)(int, u64); + void (*disable)(struct hw_perf_counter *, int); unsigned eventsel; unsigned perfctr; u64 (*event_map)(int); @@ -425,28 +425,19 @@ static inline void x86_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE); } -static void intel_pmu_disable_counter(int idx, u64 config) +static inline void x86_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) { - wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + idx, config); -} - -static void amd_pmu_disable_counter(int idx, u64 config) -{ - wrmsrl(MSR_K7_EVNTSEL0 + idx, config); - -} + int err; -static void hw_perf_disable(int idx, u64 config) -{ if (unlikely(!perf_counters_initialized)) return; - x86_pmu.disable(idx, config); + err = checking_wrmsrl(hwc->config_base + idx, + hwc->config); } static inline void -__pmc_fixed_disable(struct perf_counter *counter, - struct hw_perf_counter *hwc, int __idx) +intel_pmu_disable_fixed(struct hw_perf_counter *hwc, int __idx) { int idx = __idx - X86_PMC_IDX_FIXED; u64 ctrl_val, mask; @@ -460,13 +451,20 @@ __pmc_fixed_disable(struct perf_counter *counter, } static inline void -__x86_pmu_disable(struct perf_counter *counter, - struct hw_perf_counter *hwc, int idx) +intel_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) { - if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) - __pmc_fixed_disable(counter, hwc, idx); - else - hw_perf_disable(idx, hwc->config); + if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { + intel_pmu_disable_fixed(hwc, idx); + return; + } + + x86_pmu_disable_counter(hwc, idx); +} + +static inline void +amd_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) +{ + x86_pmu_disable_counter(hwc, idx); } static DEFINE_PER_CPU(u64, prev_left[X86_PMC_IDX_MAX]); @@ -551,7 +549,7 @@ static void amd_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) if (cpuc->enabled) x86_pmu_enable_counter(hwc, idx); else - amd_pmu_disable_counter(idx, hwc->config); + x86_pmu_disable_counter(hwc, idx); } static int @@ -622,7 +620,7 @@ try_generic: perf_counters_lapic_init(hwc->nmi); - __x86_pmu_disable(counter, hwc, idx); + x86_pmu.disable(hwc, idx); cpuc->counters[idx] = counter; set_bit(idx, cpuc->active); @@ -694,7 +692,7 @@ static void x86_pmu_disable(struct perf_counter *counter) * could reenable again: */ clear_bit(idx, cpuc->active); - __x86_pmu_disable(counter, hwc, idx); + x86_pmu.disable(hwc, idx); /* * Make sure the cleared pointer becomes visible before we @@ -762,7 +760,7 @@ again: intel_pmu_save_and_restart(counter); if (perf_counter_overflow(counter, nmi, regs, 0)) - __x86_pmu_disable(counter, &counter->hw, bit); + intel_pmu_disable_counter(&counter->hw, bit); } intel_pmu_ack_status(ack); -- GitLab From 85cf9dba92152bb4edec118b2f4f0be1ae7fdcab Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:20 +0200 Subject: [PATCH 0900/6080] perf_counter, x86: change and remove pmu initialization checks Some functions are only called if the pmu was proper initialized. That initalization checks can be removed. The way to check initialization changed too. Now, the pointer to the interrupt handler is checked. If it exists the pmu is initialized. This also removes a static variable and uses struct x86_pmu as only data source for the check. [ Impact: simplify code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-24-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 34 ++++++++++++------------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index df9012bbd211..2d3681bbb522 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -23,7 +23,6 @@ #include #include -static bool perf_counters_initialized __read_mostly; static u64 perf_counter_mask __read_mostly; struct cpu_hw_counters { @@ -227,6 +226,11 @@ static void hw_perf_counter_destroy(struct perf_counter *counter) } } +static inline int x86_pmu_initialized(void) +{ + return x86_pmu.handle_irq != NULL; +} + /* * Setup the hardware configuration for a given hw_event_type */ @@ -240,8 +244,8 @@ static int __hw_perf_counter_init(struct perf_counter *counter) if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) return -ENOSYS; - if (unlikely(!perf_counters_initialized)) - return -EINVAL; + if (!x86_pmu_initialized()) + return -ENODEV; err = 0; if (atomic_inc_not_zero(&num_counters)) { @@ -348,9 +352,8 @@ static u64 amd_pmu_save_disable_all(void) u64 hw_perf_save_disable(void) { - if (unlikely(!perf_counters_initialized)) + if (!x86_pmu_initialized()) return 0; - return x86_pmu.save_disable_all(); } /* @@ -388,9 +391,8 @@ static void amd_pmu_restore_all(u64 ctrl) void hw_perf_restore(u64 ctrl) { - if (unlikely(!perf_counters_initialized)) + if (!x86_pmu_initialized()) return; - x86_pmu.restore_all(ctrl); } /* @@ -402,8 +404,6 @@ static inline u64 intel_pmu_get_status(u64 mask) { u64 status; - if (unlikely(!perf_counters_initialized)) - return 0; rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); return status; @@ -417,10 +417,6 @@ static inline void intel_pmu_ack_status(u64 ack) static inline void x86_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) { int err; - - if (unlikely(!perf_counters_initialized)) - return; - err = checking_wrmsrl(hwc->config_base + idx, hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE); } @@ -428,10 +424,6 @@ static inline void x86_pmu_enable_counter(struct hw_perf_counter *hwc, int idx) static inline void x86_pmu_disable_counter(struct hw_perf_counter *hwc, int idx) { int err; - - if (unlikely(!perf_counters_initialized)) - return; - err = checking_wrmsrl(hwc->config_base + idx, hwc->config); } @@ -787,10 +779,10 @@ void perf_counter_unthrottle(void) { struct cpu_hw_counters *cpuc; - if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + if (!x86_pmu_initialized()) return; - if (unlikely(!perf_counters_initialized)) + if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) return; cpuc = &__get_cpu_var(cpu_hw_counters); @@ -829,8 +821,9 @@ void perf_counters_lapic_init(int nmi) { u32 apic_val; - if (!perf_counters_initialized) + if (!x86_pmu_initialized()) return; + /* * Enable the performance counter vector in the APIC LVT: */ @@ -988,7 +981,6 @@ void __init init_hw_perf_counters(void) ((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED; pr_info("... counter mask: %016Lx\n", perf_counter_mask); - perf_counters_initialized = true; perf_counters_lapic_init(0); register_die_notifier(&perf_counter_nmi_notifier); -- GitLab From a29aa8a7ff93e4196d558036928597e68337dd8d Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:21 +0200 Subject: [PATCH 0901/6080] perf_counter, x86: implement the interrupt handler for AMD cpus This patch implements the interrupt handler for AMD performance counters. In difference to the Intel pmu, there is no single status register and also there are no fixed counters. This makes the handler very different and it is useful to make the handler vendor specific. To check if a counter is overflowed the upper bit of the counter is checked. Only counters where the active bit is set are checked. With this patch throttling is enabled for AMD performance counters. This patch also reenables Linux performance counters on AMD cpus. [ Impact: re-enable perfcounters on AMD CPUs ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-25-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 45 ++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 2d3681bbb522..f4d59d4cf3f1 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -240,10 +240,6 @@ static int __hw_perf_counter_init(struct perf_counter *counter) struct hw_perf_counter *hwc = &counter->hw; int err; - /* disable temporarily */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) - return -ENOSYS; - if (!x86_pmu_initialized()) return -ENODEV; @@ -773,7 +769,43 @@ out: return ret; } -static int amd_pmu_handle_irq(struct pt_regs *regs, int nmi) { return 0; } +static int amd_pmu_handle_irq(struct pt_regs *regs, int nmi) +{ + int cpu = smp_processor_id(); + struct cpu_hw_counters *cpuc = &per_cpu(cpu_hw_counters, cpu); + u64 val; + int handled = 0; + struct perf_counter *counter; + struct hw_perf_counter *hwc; + int idx; + + ++cpuc->interrupts; + for (idx = 0; idx < x86_pmu.num_counters; idx++) { + if (!test_bit(idx, cpuc->active)) + continue; + counter = cpuc->counters[idx]; + hwc = &counter->hw; + x86_perf_counter_update(counter, hwc, idx); + val = atomic64_read(&hwc->prev_count); + if (val & (1ULL << (x86_pmu.counter_bits - 1))) + continue; + /* counter overflow */ + x86_perf_counter_set_period(counter, hwc, idx); + handled = 1; + inc_irq_stat(apic_perf_irqs); + if (perf_counter_overflow(counter, nmi, regs, 0)) + amd_pmu_disable_counter(hwc, idx); + else if (cpuc->interrupts >= PERFMON_MAX_INTERRUPTS) + /* + * do not reenable when throttled, but reload + * the register + */ + amd_pmu_disable_counter(hwc, idx); + else if (counter->state == PERF_COUNTER_STATE_ACTIVE) + amd_pmu_enable_counter(hwc, idx); + } + return handled; +} void perf_counter_unthrottle(void) { @@ -782,9 +814,6 @@ void perf_counter_unthrottle(void) if (!x86_pmu_initialized()) return; - if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return; - cpuc = &__get_cpu_var(cpu_hw_counters); if (cpuc->interrupts >= PERFMON_MAX_INTERRUPTS) { if (printk_ratelimit()) -- GitLab From 4b7bfd0d276da3a006d37e85d3cf900d7a14ae2a Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:22 +0200 Subject: [PATCH 0902/6080] perf_counter, x86: return raw count with x86_perf_counter_update() To check on AMD cpus if a counter overflows, the upper bit of the raw counter value must be checked. This value is already internally available in x86_perf_counter_update(). Now, the value is returned so that it can be used directly to check for overflows. [ Impact: micro-optimization ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-26-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index f4d59d4cf3f1..a8a53abd706d 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -132,7 +132,7 @@ static u64 amd_pmu_raw_event(u64 event) * Can only be executed on the CPU where the counter is active. * Returns the delta events processed. */ -static void +static u64 x86_perf_counter_update(struct perf_counter *counter, struct hw_perf_counter *hwc, int idx) { @@ -165,6 +165,8 @@ again: atomic64_add(delta, &counter->count); atomic64_sub(delta, &hwc->period_left); + + return new_raw_count; } static atomic_t num_counters; @@ -785,8 +787,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs, int nmi) continue; counter = cpuc->counters[idx]; hwc = &counter->hw; - x86_perf_counter_update(counter, hwc, idx); - val = atomic64_read(&hwc->prev_count); + val = x86_perf_counter_update(counter, hwc, idx); if (val & (1ULL << (x86_pmu.counter_bits - 1))) continue; /* counter overflow */ -- GitLab From c619b8ffb1cec6a431687a35695dc6fd292a79e6 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:23 +0200 Subject: [PATCH 0903/6080] perf_counter, x86: introduce max_period variable In x86 pmus the allowed counter period to programm differs. This introduces a max_period value and allows the generic implementation for all models to check the max period. [ Impact: generalize code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-27-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index a8a53abd706d..4b8715b34f87 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -54,6 +54,7 @@ struct x86_pmu { int num_counters_fixed; int counter_bits; u64 counter_mask; + u64 max_period; }; static struct x86_pmu x86_pmu __read_mostly; @@ -279,14 +280,8 @@ static int __hw_perf_counter_init(struct perf_counter *counter) hwc->nmi = 1; hwc->irq_period = hw_event->irq_period; - /* - * Intel PMCs cannot be accessed sanely above 32 bit width, - * so we install an artificial 1<<31 period regardless of - * the generic counter period: - */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) - if ((s64)hwc->irq_period <= 0 || hwc->irq_period > 0x7FFFFFFF) - hwc->irq_period = 0x7FFFFFFF; + if ((s64)hwc->irq_period <= 0 || hwc->irq_period > x86_pmu.max_period) + hwc->irq_period = x86_pmu.max_period; atomic64_set(&hwc->period_left, hwc->irq_period); @@ -910,6 +905,12 @@ static struct x86_pmu intel_pmu = { .event_map = intel_pmu_event_map, .raw_event = intel_pmu_raw_event, .max_events = ARRAY_SIZE(intel_perfmon_event_map), + /* + * Intel PMCs cannot be accessed sanely above 32 bit width, + * so we install an artificial 1<<31 period regardless of + * the generic counter period: + */ + .max_period = (1ULL << 31) - 1, }; static struct x86_pmu amd_pmu = { @@ -927,6 +928,8 @@ static struct x86_pmu amd_pmu = { .num_counters = 4, .counter_bits = 48, .counter_mask = (1ULL << 48) - 1, + /* use highest bit to detect overflow */ + .max_period = (1ULL << 47) - 1, }; static int intel_pmu_init(void) @@ -999,6 +1002,7 @@ void __init init_hw_perf_counters(void) perf_max_counters = x86_pmu.num_counters; pr_info("... value mask: %016Lx\n", x86_pmu.counter_mask); + pr_info("... max period: %016Lx\n", x86_pmu.max_period); if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) { x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED; -- GitLab From ef7b3e09ffdcd5200aea9523f6b56d331d1c4fc0 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:24 +0200 Subject: [PATCH 0904/6080] perf_counter, x86: remove vendor check in fixed_mode_idx() The function fixed_mode_idx() is used generically. Now it checks the num_counters_fixed value instead of the vendor to decide if fixed counters are present. [ Impact: generalize code ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-28-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 4b8715b34f87..d1c8036dcbd6 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -542,7 +542,7 @@ fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc) { unsigned int event; - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) + if (!x86_pmu.num_counters_fixed) return -1; if (unlikely(hwc->nmi)) -- GitLab From 19d84dab55a383d75c885b5c1a618f5ead96f2f6 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:25 +0200 Subject: [PATCH 0905/6080] perf_counter, x86: remove unused function argument in intel_pmu_get_status() The mask argument is unused and thus can be removed. [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-29-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index d1c8036dcbd6..856b0b852192 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -393,7 +393,7 @@ void hw_perf_restore(u64 ctrl) */ EXPORT_SYMBOL_GPL(hw_perf_restore); -static inline u64 intel_pmu_get_status(u64 mask) +static inline u64 intel_pmu_get_status(void) { u64 status; @@ -728,7 +728,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs, int nmi) cpuc->throttle_ctrl = intel_pmu_save_disable_all(); - status = intel_pmu_get_status(cpuc->throttle_ctrl); + status = intel_pmu_get_status(); if (!status) goto out; @@ -753,7 +753,7 @@ again: /* * Repeat if there is more work to be done: */ - status = intel_pmu_get_status(cpuc->throttle_ctrl); + status = intel_pmu_get_status(); if (status) goto again; out: -- GitLab From 38105f0234d4795c77c7c6845916caf3a395c451 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 12:47:26 +0200 Subject: [PATCH 0906/6080] perf_counter: update 'perf top' documentation The documentation about the perf-top build was outdated after perfstat has been implemented. This updates it. [ Impact: update documentation ] Signed-off-by: Robert Richter Cc: Paul Mackerras Acked-by: Peter Zijlstra LKML-Reference: <1241002046-8832-30-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- Documentation/perf_counter/builtin-top.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/perf_counter/builtin-top.c b/Documentation/perf_counter/builtin-top.c index 6a276d2b2bbc..8d28864a20c0 100644 --- a/Documentation/perf_counter/builtin-top.c +++ b/Documentation/perf_counter/builtin-top.c @@ -3,7 +3,7 @@ Build with: - cc -O6 -Wall -c -o kerneltop.o kerneltop.c -lrt + make -C Documentation/perf_counter/ Sample output: -- GitLab From 98144511427c192e4249ff66a3f9debc55c59411 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 29 Apr 2009 14:52:50 +0200 Subject: [PATCH 0907/6080] perf_counter: add/update copyrights Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 9 +++++---- kernel/perf_counter.c | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 856b0b852192..47e563bfd4cf 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -1,10 +1,11 @@ /* * Performance counter x86 architecture code * - * Copyright(C) 2008 Thomas Gleixner - * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar - * Copyright(C) 2009 Jaswinder Singh Rajput - * Copyright(C) 2009 Advanced Micro Devices, Inc., Robert Richter + * Copyright (C) 2008 Thomas Gleixner + * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar + * Copyright (C) 2009 Jaswinder Singh Rajput + * Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter + * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra * * For licencing details see kernel-base/COPYING */ diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 582108addefa..a95a171e608c 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1,9 +1,9 @@ /* * Performance counter core code * - * Copyright(C) 2008 Thomas Gleixner - * Copyright(C) 2008 Red Hat, Inc., Ingo Molnar - * + * Copyright (C) 2008 Thomas Gleixner + * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar + * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra * * For licensing details see kernel-base/COPYING */ -- GitLab From ab7ef2e50a557af92f4f90689f51fadadafc16b2 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 29 Apr 2009 22:38:51 +1000 Subject: [PATCH 0908/6080] perf_counter: powerpc: allow use of limited-function counters POWER5+ and POWER6 have two hardware counters with limited functionality: PMC5 counts instructions completed in run state and PMC6 counts cycles in run state. (Run state is the state when a hardware RUN bit is 1; the idle task clears RUN while waiting for work to do and sets it when there is work to do.) These counters can't be written to by the kernel, can't generate interrupts, and don't obey the freeze conditions. That means we can only use them for per-task counters (where we know we'll always be in run state; we can't put a per-task counter on an idle task), and only if we don't want interrupts and we do want to count in all processor modes. Obviously some counters can't go on a limited hardware counter, but there are also situations where we can only put a counter on a limited hardware counter - if there are already counters on that exclude some processor modes and we want to put on a per-task cycle or instruction counter that doesn't exclude any processor mode, it could go on if it can use a limited hardware counter. To keep track of these constraints, this adds a flags argument to the processor-specific get_alternatives() functions, with three bits defined: one to say that we can accept alternative event codes that go on limited counters, one to say we only want alternatives on limited counters, and one to say that this is a per-task counter and therefore events that are gated by run state are equivalent to those that aren't (e.g. a "cycles" event is equivalent to a "cycles in run state" event). These flags are computed for each counter and stored in the counter->hw.counter_base field (slightly wonky name for what it does, but it was an existing unused field). Since the limited counters don't freeze when we freeze the other counters, we need some special handling to avoid getting skew between things counted on the limited counters and those counted on normal counters. To minimize this skew, if we are using any limited counters, we read PMC5 and PMC6 immediately after setting and clearing the freeze bit. This is done in a single asm in the new write_mmcr0() function. The code here is specific to PMC5 and PMC6 being the limited hardware counters. Being more general (e.g. having a bitmap of limited hardware counter numbers) would have meant more complex code to read the limited counters when freezing and unfreezing the normal counters, with conditional branches, which would have increased the skew. Since it isn't necessary for the code to be more general at this stage, it isn't. This also extends the back-ends for POWER5+ and POWER6 to be able to handle up to 6 counters rather than the 4 they previously handled. Signed-off-by: Paul Mackerras Acked-by: Peter Zijlstra Cc: Robert Richter LKML-Reference: <18936.19035.163066.892208@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- arch/powerpc/include/asm/perf_counter.h | 13 +- arch/powerpc/kernel/perf_counter.c | 297 +++++++++++++++++++++--- arch/powerpc/kernel/power4-pmu.c | 3 +- arch/powerpc/kernel/power5+-pmu.c | 117 ++++++++-- arch/powerpc/kernel/power5-pmu.c | 3 +- arch/powerpc/kernel/power6-pmu.c | 119 ++++++++-- arch/powerpc/kernel/ppc970-pmu.c | 3 +- 7 files changed, 479 insertions(+), 76 deletions(-) diff --git a/arch/powerpc/include/asm/perf_counter.h b/arch/powerpc/include/asm/perf_counter.h index 9d7ff6d7fb56..56d66c38143b 100644 --- a/arch/powerpc/include/asm/perf_counter.h +++ b/arch/powerpc/include/asm/perf_counter.h @@ -12,6 +12,7 @@ #define MAX_HWCOUNTERS 8 #define MAX_EVENT_ALTERNATIVES 8 +#define MAX_LIMITED_HWCOUNTERS 2 /* * This struct provides the constants and functions needed to @@ -25,14 +26,24 @@ struct power_pmu { int (*compute_mmcr)(unsigned int events[], int n_ev, unsigned int hwc[], u64 mmcr[]); int (*get_constraint)(unsigned int event, u64 *mskp, u64 *valp); - int (*get_alternatives)(unsigned int event, unsigned int alt[]); + int (*get_alternatives)(unsigned int event, unsigned int flags, + unsigned int alt[]); void (*disable_pmc)(unsigned int pmc, u64 mmcr[]); + int (*limited_pmc_event)(unsigned int event); + int limited_pmc5_6; /* PMC5 and PMC6 have limited function */ int n_generic; int *generic_events; }; extern struct power_pmu *ppmu; +/* + * Values for flags to get_alternatives() + */ +#define PPMU_LIMITED_PMC_OK 1 /* can put this on a limited PMC */ +#define PPMU_LIMITED_PMC_REQD 2 /* have to put this on a limited PMC */ +#define PPMU_ONLY_COUNT_RUN 4 /* only counting in run state */ + /* * The power_pmu.get_constraint function returns a 64-bit value and * a 64-bit mask that express the constraints between this event and diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c index d9bbe5efc649..15cdc8e67229 100644 --- a/arch/powerpc/kernel/perf_counter.c +++ b/arch/powerpc/kernel/perf_counter.c @@ -23,10 +23,14 @@ struct cpu_hw_counters { int n_percpu; int disabled; int n_added; + int n_limited; + u8 pmcs_enabled; struct perf_counter *counter[MAX_HWCOUNTERS]; unsigned int events[MAX_HWCOUNTERS]; + unsigned int flags[MAX_HWCOUNTERS]; u64 mmcr[3]; - u8 pmcs_enabled; + struct perf_counter *limited_counter[MAX_LIMITED_HWCOUNTERS]; + u8 limited_hwidx[MAX_LIMITED_HWCOUNTERS]; }; DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters); @@ -127,7 +131,8 @@ static void write_pmc(int idx, unsigned long val) * and see if any combination of alternative codes is feasible. * The feasible set is returned in event[]. */ -static int power_check_constraints(unsigned int event[], int n_ev) +static int power_check_constraints(unsigned int event[], unsigned int cflags[], + int n_ev) { u64 mask, value, nv; unsigned int alternatives[MAX_HWCOUNTERS][MAX_EVENT_ALTERNATIVES]; @@ -144,11 +149,15 @@ static int power_check_constraints(unsigned int event[], int n_ev) /* First see if the events will go on as-is */ for (i = 0; i < n_ev; ++i) { - alternatives[i][0] = event[i]; + if ((cflags[i] & PPMU_LIMITED_PMC_REQD) + && !ppmu->limited_pmc_event(event[i])) { + ppmu->get_alternatives(event[i], cflags[i], + alternatives[i]); + event[i] = alternatives[i][0]; + } if (ppmu->get_constraint(event[i], &amasks[i][0], &avalues[i][0])) return -1; - choice[i] = 0; } value = mask = 0; for (i = 0; i < n_ev; ++i) { @@ -166,7 +175,9 @@ static int power_check_constraints(unsigned int event[], int n_ev) if (!ppmu->get_alternatives) return -1; for (i = 0; i < n_ev; ++i) { - n_alt[i] = ppmu->get_alternatives(event[i], alternatives[i]); + choice[i] = 0; + n_alt[i] = ppmu->get_alternatives(event[i], cflags[i], + alternatives[i]); for (j = 1; j < n_alt[i]; ++j) ppmu->get_constraint(alternatives[i][j], &amasks[i][j], &avalues[i][j]); @@ -231,28 +242,41 @@ static int power_check_constraints(unsigned int event[], int n_ev) * exclude_{user,kernel,hv} with each other and any previously * added counters. */ -static int check_excludes(struct perf_counter **ctrs, int n_prev, int n_new) +static int check_excludes(struct perf_counter **ctrs, unsigned int cflags[], + int n_prev, int n_new) { - int eu, ek, eh; - int i, n; + int eu = 0, ek = 0, eh = 0; + int i, n, first; struct perf_counter *counter; n = n_prev + n_new; if (n <= 1) return 0; - eu = ctrs[0]->hw_event.exclude_user; - ek = ctrs[0]->hw_event.exclude_kernel; - eh = ctrs[0]->hw_event.exclude_hv; - if (n_prev == 0) - n_prev = 1; - for (i = n_prev; i < n; ++i) { + first = 1; + for (i = 0; i < n; ++i) { + if (cflags[i] & PPMU_LIMITED_PMC_OK) { + cflags[i] &= ~PPMU_LIMITED_PMC_REQD; + continue; + } counter = ctrs[i]; - if (counter->hw_event.exclude_user != eu || - counter->hw_event.exclude_kernel != ek || - counter->hw_event.exclude_hv != eh) + if (first) { + eu = counter->hw_event.exclude_user; + ek = counter->hw_event.exclude_kernel; + eh = counter->hw_event.exclude_hv; + first = 0; + } else if (counter->hw_event.exclude_user != eu || + counter->hw_event.exclude_kernel != ek || + counter->hw_event.exclude_hv != eh) { return -EAGAIN; + } } + + if (eu || ek || eh) + for (i = 0; i < n; ++i) + if (cflags[i] & PPMU_LIMITED_PMC_OK) + cflags[i] |= PPMU_LIMITED_PMC_REQD; + return 0; } @@ -279,6 +303,85 @@ static void power_pmu_read(struct perf_counter *counter) atomic64_sub(delta, &counter->hw.period_left); } +/* + * On some machines, PMC5 and PMC6 can't be written, don't respect + * the freeze conditions, and don't generate interrupts. This tells + * us if `counter' is using such a PMC. + */ +static int is_limited_pmc(int pmcnum) +{ + return ppmu->limited_pmc5_6 && (pmcnum == 5 || pmcnum == 6); +} + +static void freeze_limited_counters(struct cpu_hw_counters *cpuhw, + unsigned long pmc5, unsigned long pmc6) +{ + struct perf_counter *counter; + u64 val, prev, delta; + int i; + + for (i = 0; i < cpuhw->n_limited; ++i) { + counter = cpuhw->limited_counter[i]; + if (!counter->hw.idx) + continue; + val = (counter->hw.idx == 5) ? pmc5 : pmc6; + prev = atomic64_read(&counter->hw.prev_count); + counter->hw.idx = 0; + delta = (val - prev) & 0xfffffffful; + atomic64_add(delta, &counter->count); + } +} + +static void thaw_limited_counters(struct cpu_hw_counters *cpuhw, + unsigned long pmc5, unsigned long pmc6) +{ + struct perf_counter *counter; + u64 val; + int i; + + for (i = 0; i < cpuhw->n_limited; ++i) { + counter = cpuhw->limited_counter[i]; + counter->hw.idx = cpuhw->limited_hwidx[i]; + val = (counter->hw.idx == 5) ? pmc5 : pmc6; + atomic64_set(&counter->hw.prev_count, val); + perf_counter_update_userpage(counter); + } +} + +/* + * Since limited counters don't respect the freeze conditions, we + * have to read them immediately after freezing or unfreezing the + * other counters. We try to keep the values from the limited + * counters as consistent as possible by keeping the delay (in + * cycles and instructions) between freezing/unfreezing and reading + * the limited counters as small and consistent as possible. + * Therefore, if any limited counters are in use, we read them + * both, and always in the same order, to minimize variability, + * and do it inside the same asm that writes MMCR0. + */ +static void write_mmcr0(struct cpu_hw_counters *cpuhw, unsigned long mmcr0) +{ + unsigned long pmc5, pmc6; + + if (!cpuhw->n_limited) { + mtspr(SPRN_MMCR0, mmcr0); + return; + } + + /* + * Write MMCR0, then read PMC5 and PMC6 immediately. + */ + asm volatile("mtspr %3,%2; mfspr %0,%4; mfspr %1,%5" + : "=&r" (pmc5), "=&r" (pmc6) + : "r" (mmcr0), "i" (SPRN_MMCR0), + "i" (SPRN_PMC5), "i" (SPRN_PMC6)); + + if (mmcr0 & MMCR0_FC) + freeze_limited_counters(cpuhw, pmc5, pmc6); + else + thaw_limited_counters(cpuhw, pmc5, pmc6); +} + /* * Disable all counters to prevent PMU interrupts and to allow * counters to be added or removed. @@ -321,7 +424,7 @@ u64 hw_perf_save_disable(void) * executed and the PMU has frozen the counters * before we return. */ - mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC); + write_mmcr0(cpuhw, mfspr(SPRN_MMCR0) | MMCR0_FC); mb(); } local_irq_restore(flags); @@ -342,6 +445,8 @@ void hw_perf_restore(u64 disable) unsigned long val; s64 left; unsigned int hwc_index[MAX_HWCOUNTERS]; + int n_lim; + int idx; if (disable) return; @@ -414,10 +519,18 @@ void hw_perf_restore(u64 disable) /* * Initialize the PMCs for all the new and moved counters. */ + cpuhw->n_limited = n_lim = 0; for (i = 0; i < cpuhw->n_counters; ++i) { counter = cpuhw->counter[i]; if (counter->hw.idx) continue; + idx = hwc_index[i] + 1; + if (is_limited_pmc(idx)) { + cpuhw->limited_counter[n_lim] = counter; + cpuhw->limited_hwidx[n_lim] = idx; + ++n_lim; + continue; + } val = 0; if (counter->hw_event.irq_period) { left = atomic64_read(&counter->hw.period_left); @@ -425,15 +538,16 @@ void hw_perf_restore(u64 disable) val = 0x80000000L - left; } atomic64_set(&counter->hw.prev_count, val); - counter->hw.idx = hwc_index[i] + 1; - write_pmc(counter->hw.idx, val); + counter->hw.idx = idx; + write_pmc(idx, val); perf_counter_update_userpage(counter); } + cpuhw->n_limited = n_lim; cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE; out_enable: mb(); - mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); + write_mmcr0(cpuhw, cpuhw->mmcr[0]); /* * Enable instruction sampling if necessary @@ -448,7 +562,8 @@ void hw_perf_restore(u64 disable) } static int collect_events(struct perf_counter *group, int max_count, - struct perf_counter *ctrs[], unsigned int *events) + struct perf_counter *ctrs[], unsigned int *events, + unsigned int *flags) { int n = 0; struct perf_counter *counter; @@ -457,6 +572,7 @@ static int collect_events(struct perf_counter *group, int max_count, if (n >= max_count) return -1; ctrs[n] = group; + flags[n] = group->hw.counter_base; events[n++] = group->hw.config; } list_for_each_entry(counter, &group->sibling_list, list_entry) { @@ -465,6 +581,7 @@ static int collect_events(struct perf_counter *group, int max_count, if (n >= max_count) return -1; ctrs[n] = counter; + flags[n] = counter->hw.counter_base; events[n++] = counter->hw.config; } } @@ -497,12 +614,14 @@ int hw_perf_group_sched_in(struct perf_counter *group_leader, cpuhw = &__get_cpu_var(cpu_hw_counters); n0 = cpuhw->n_counters; n = collect_events(group_leader, ppmu->n_counter - n0, - &cpuhw->counter[n0], &cpuhw->events[n0]); + &cpuhw->counter[n0], &cpuhw->events[n0], + &cpuhw->flags[n0]); if (n < 0) return -EAGAIN; - if (check_excludes(cpuhw->counter, n0, n)) + if (check_excludes(cpuhw->counter, cpuhw->flags, n0, n)) return -EAGAIN; - if (power_check_constraints(cpuhw->events, n + n0)) + i = power_check_constraints(cpuhw->events, cpuhw->flags, n + n0); + if (i < 0) return -EAGAIN; cpuhw->n_counters = n0 + n; cpuhw->n_added += n; @@ -554,9 +673,10 @@ static int power_pmu_enable(struct perf_counter *counter) goto out; cpuhw->counter[n0] = counter; cpuhw->events[n0] = counter->hw.config; - if (check_excludes(cpuhw->counter, n0, 1)) + cpuhw->flags[n0] = counter->hw.counter_base; + if (check_excludes(cpuhw->counter, cpuhw->flags, n0, 1)) goto out; - if (power_check_constraints(cpuhw->events, n0 + 1)) + if (power_check_constraints(cpuhw->events, cpuhw->flags, n0 + 1)) goto out; counter->hw.config = cpuhw->events[n0]; @@ -592,12 +712,24 @@ static void power_pmu_disable(struct perf_counter *counter) cpuhw->counter[i-1] = cpuhw->counter[i]; --cpuhw->n_counters; ppmu->disable_pmc(counter->hw.idx - 1, cpuhw->mmcr); - write_pmc(counter->hw.idx, 0); - counter->hw.idx = 0; + if (counter->hw.idx) { + write_pmc(counter->hw.idx, 0); + counter->hw.idx = 0; + } perf_counter_update_userpage(counter); break; } } + for (i = 0; i < cpuhw->n_limited; ++i) + if (counter == cpuhw->limited_counter[i]) + break; + if (i < cpuhw->n_limited) { + while (++i < cpuhw->n_limited) { + cpuhw->limited_counter[i-1] = cpuhw->limited_counter[i]; + cpuhw->limited_hwidx[i-1] = cpuhw->limited_hwidx[i]; + } + --cpuhw->n_limited; + } if (cpuhw->n_counters == 0) { /* disable exceptions if no counters are running */ cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE); @@ -613,6 +745,61 @@ struct pmu power_pmu = { .read = power_pmu_read, }; +/* + * Return 1 if we might be able to put counter on a limited PMC, + * or 0 if not. + * A counter can only go on a limited PMC if it counts something + * that a limited PMC can count, doesn't require interrupts, and + * doesn't exclude any processor mode. + */ +static int can_go_on_limited_pmc(struct perf_counter *counter, unsigned int ev, + unsigned int flags) +{ + int n; + unsigned int alt[MAX_EVENT_ALTERNATIVES]; + + if (counter->hw_event.exclude_user + || counter->hw_event.exclude_kernel + || counter->hw_event.exclude_hv + || counter->hw_event.irq_period) + return 0; + + if (ppmu->limited_pmc_event(ev)) + return 1; + + /* + * The requested event isn't on a limited PMC already; + * see if any alternative code goes on a limited PMC. + */ + if (!ppmu->get_alternatives) + return 0; + + flags |= PPMU_LIMITED_PMC_OK | PPMU_LIMITED_PMC_REQD; + n = ppmu->get_alternatives(ev, flags, alt); + if (n) + return alt[0]; + + return 0; +} + +/* + * Find an alternative event that goes on a normal PMC, if possible, + * and return the event code, or 0 if there is no such alternative. + * (Note: event code 0 is "don't count" on all machines.) + */ +static unsigned long normal_pmc_alternative(unsigned long ev, + unsigned long flags) +{ + unsigned int alt[MAX_EVENT_ALTERNATIVES]; + int n; + + flags &= ~(PPMU_LIMITED_PMC_OK | PPMU_LIMITED_PMC_REQD); + n = ppmu->get_alternatives(ev, flags, alt); + if (!n) + return 0; + return alt[0]; +} + /* Number of perf_counters counting hardware events */ static atomic_t num_counters; /* Used to avoid races in calling reserve/release_pmc_hardware */ @@ -633,9 +820,10 @@ static void hw_perf_counter_destroy(struct perf_counter *counter) const struct pmu *hw_perf_counter_init(struct perf_counter *counter) { - unsigned long ev; + unsigned long ev, flags; struct perf_counter *ctrs[MAX_HWCOUNTERS]; unsigned int events[MAX_HWCOUNTERS]; + unsigned int cflags[MAX_HWCOUNTERS]; int n; int err; @@ -661,7 +849,36 @@ const struct pmu *hw_perf_counter_init(struct perf_counter *counter) */ if (!firmware_has_feature(FW_FEATURE_LPAR)) counter->hw_event.exclude_hv = 0; - + + /* + * If this is a per-task counter, then we can use + * PM_RUN_* events interchangeably with their non RUN_* + * equivalents, e.g. PM_RUN_CYC instead of PM_CYC. + * XXX we should check if the task is an idle task. + */ + flags = 0; + if (counter->ctx->task) + flags |= PPMU_ONLY_COUNT_RUN; + + /* + * If this machine has limited counters, check whether this + * event could go on a limited counter. + */ + if (ppmu->limited_pmc5_6) { + if (can_go_on_limited_pmc(counter, ev, flags)) { + flags |= PPMU_LIMITED_PMC_OK; + } else if (ppmu->limited_pmc_event(ev)) { + /* + * The requested event is on a limited PMC, + * but we can't use a limited PMC; see if any + * alternative goes on a normal PMC. + */ + ev = normal_pmc_alternative(ev, flags); + if (!ev) + return ERR_PTR(-EINVAL); + } + } + /* * If this is in a group, check if it can go on with all the * other hardware counters in the group. We assume the counter @@ -670,18 +887,20 @@ const struct pmu *hw_perf_counter_init(struct perf_counter *counter) n = 0; if (counter->group_leader != counter) { n = collect_events(counter->group_leader, ppmu->n_counter - 1, - ctrs, events); + ctrs, events, cflags); if (n < 0) return ERR_PTR(-EINVAL); } events[n] = ev; ctrs[n] = counter; - if (check_excludes(ctrs, n, 1)) + cflags[n] = flags; + if (check_excludes(ctrs, cflags, n, 1)) return ERR_PTR(-EINVAL); - if (power_check_constraints(events, n + 1)) + if (power_check_constraints(events, cflags, n + 1)) return ERR_PTR(-EINVAL); counter->hw.config = events[n]; + counter->hw.counter_base = cflags[n]; atomic64_set(&counter->hw.period_left, counter->hw_event.irq_period); /* @@ -763,6 +982,10 @@ static void perf_counter_interrupt(struct pt_regs *regs) int found = 0; int nmi; + if (cpuhw->n_limited) + freeze_limited_counters(cpuhw, mfspr(SPRN_PMC5), + mfspr(SPRN_PMC6)); + /* * If interrupts were soft-disabled when this PMU interrupt * occurred, treat it as an NMI. @@ -775,6 +998,8 @@ static void perf_counter_interrupt(struct pt_regs *regs) for (i = 0; i < cpuhw->n_counters; ++i) { counter = cpuhw->counter[i]; + if (is_limited_pmc(counter->hw.idx)) + continue; val = read_pmc(counter->hw.idx); if ((int)val < 0) { /* counter has overflowed */ @@ -791,6 +1016,8 @@ static void perf_counter_interrupt(struct pt_regs *regs) */ if (!found) { for (i = 0; i < ppmu->n_counter; ++i) { + if (is_limited_pmc(i + 1)) + continue; val = read_pmc(i + 1); if ((int)val < 0) write_pmc(i + 1, 0); @@ -804,7 +1031,7 @@ static void perf_counter_interrupt(struct pt_regs *regs) * XXX might want to use MSR.PM to keep the counters frozen until * we get back out of this interrupt. */ - mtspr(SPRN_MMCR0, cpuhw->mmcr[0]); + write_mmcr0(cpuhw, cpuhw->mmcr[0]); if (nmi) nmi_exit(); diff --git a/arch/powerpc/kernel/power4-pmu.c b/arch/powerpc/kernel/power4-pmu.c index 1407b19ab619..744a2756958e 100644 --- a/arch/powerpc/kernel/power4-pmu.c +++ b/arch/powerpc/kernel/power4-pmu.c @@ -320,7 +320,8 @@ static unsigned int ppc_inst_cmpl[] = { 0x1001, 0x4001, 0x6001, 0x7001, 0x8001 }; -static int p4_get_alternatives(unsigned int event, unsigned int alt[]) +static int p4_get_alternatives(unsigned int event, unsigned int flags, + unsigned int alt[]) { int i, j, na; diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c index 1222c8ea3c26..8154eaa2404f 100644 --- a/arch/powerpc/kernel/power5+-pmu.c +++ b/arch/powerpc/kernel/power5+-pmu.c @@ -78,8 +78,8 @@ * Layout of constraint bits: * 6666555555555544444444443333333333222222222211111111110000000000 * 3210987654321098765432109876543210987654321098765432109876543210 - * [ ><><>< ><> <><>[ > < >< >< >< ><><><><> - * NC G0G1G2 G3 T0T1 UC B0 B1 B2 B3 P4P3P2P1 + * [ ><><>< ><> <><>[ > < >< >< >< ><><><><><><> + * NC G0G1G2 G3 T0T1 UC B0 B1 B2 B3 P6P5P4P3P2P1 * * NC - number of counters * 51: NC error 0x0008_0000_0000_0000 @@ -105,18 +105,18 @@ * 30: IDU|GRS events needed 0x00_4000_0000 * * B0 - * 20-23: Byte 0 event source 0x00f0_0000 + * 24-27: Byte 0 event source 0x0f00_0000 * Encoding as for the event code * * B1, B2, B3 - * 16-19, 12-15, 8-11: Byte 1, 2, 3 event sources + * 20-23, 16-19, 12-15: Byte 1, 2, 3 event sources * - * P4 - * 7: P1 error 0x80 - * 6-7: Count of events needing PMC4 + * P6 + * 11: P6 error 0x800 + * 10-11: Count of events needing PMC6 * - * P1..P3 - * 0-6: Count of events needing PMC1..PMC3 + * P1..P5 + * 0-9: Count of events needing PMC1..PMC5 */ static const int grsel_shift[8] = { @@ -143,11 +143,13 @@ static int power5p_get_constraint(unsigned int event, u64 *maskp, u64 *valp) pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; if (pmc) { - if (pmc > 4) + if (pmc > 6) return -1; sh = (pmc - 1) * 2; mask |= 2 << sh; value |= 1 << sh; + if (pmc >= 5 && !(event == 0x500009 || event == 0x600005)) + return -1; } if (event & PM_BUSEVENT_MSK) { unit = (event >> PM_UNIT_SH) & PM_UNIT_MSK; @@ -173,16 +175,26 @@ static int power5p_get_constraint(unsigned int event, u64 *maskp, u64 *valp) value |= (u64)((event >> PM_GRS_SH) & fmask) << sh; } /* Set byte lane select field */ - mask |= 0xfULL << (20 - 4 * byte); - value |= (u64)unit << (20 - 4 * byte); + mask |= 0xfULL << (24 - 4 * byte); + value |= (u64)unit << (24 - 4 * byte); + } + if (pmc < 5) { + /* need a counter from PMC1-4 set */ + mask |= 0x8000000000000ull; + value |= 0x1000000000000ull; } - mask |= 0x8000000000000ull; - value |= 0x1000000000000ull; *maskp = mask; *valp = value; return 0; } +static int power5p_limited_pmc_event(unsigned int event) +{ + int pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + + return pmc == 5 || pmc == 6; +} + #define MAX_ALT 3 /* at most 3 alternatives for any event */ static const unsigned int event_alternatives[][MAX_ALT] = { @@ -193,6 +205,7 @@ static const unsigned int event_alternatives[][MAX_ALT] = { { 0x410c7, 0x441084 }, /* PM_THRD_L2MISS_BOTH_CYC */ { 0x800c4, 0xc20e0 }, /* PM_DTLB_MISS */ { 0xc50c6, 0xc60e0 }, /* PM_MRK_DTLB_MISS */ + { 0x100005, 0x600005 }, /* PM_RUN_CYC */ { 0x100009, 0x200009 }, /* PM_INST_CMPL */ { 0x200015, 0x300015 }, /* PM_LSU_LMQ_SRQ_EMPTY_CYC */ { 0x300009, 0x400009 }, /* PM_INST_DISP */ @@ -260,24 +273,85 @@ static int find_alternative_bdecode(unsigned int event) return -1; } -static int power5p_get_alternatives(unsigned int event, unsigned int alt[]) +static int power5p_get_alternatives(unsigned int event, unsigned int flags, + unsigned int alt[]) { int i, j, ae, nalt = 1; + int nlim; alt[0] = event; nalt = 1; + nlim = power5p_limited_pmc_event(event); i = find_alternative(event); if (i >= 0) { for (j = 0; j < MAX_ALT; ++j) { ae = event_alternatives[i][j]; if (ae && ae != event) alt[nalt++] = ae; + nlim += power5p_limited_pmc_event(ae); } } else { ae = find_alternative_bdecode(event); if (ae > 0) alt[nalt++] = ae; } + + if (flags & PPMU_ONLY_COUNT_RUN) { + /* + * We're only counting in RUN state, + * so PM_CYC is equivalent to PM_RUN_CYC + * and PM_INST_CMPL === PM_RUN_INST_CMPL. + * This doesn't include alternatives that don't provide + * any extra flexibility in assigning PMCs (e.g. + * 0x100005 for PM_RUN_CYC vs. 0xf for PM_CYC). + * Note that even with these additional alternatives + * we never end up with more than 3 alternatives for any event. + */ + j = nalt; + for (i = 0; i < nalt; ++i) { + switch (alt[i]) { + case 0xf: /* PM_CYC */ + alt[j++] = 0x600005; /* PM_RUN_CYC */ + ++nlim; + break; + case 0x600005: /* PM_RUN_CYC */ + alt[j++] = 0xf; + break; + case 0x100009: /* PM_INST_CMPL */ + alt[j++] = 0x500009; /* PM_RUN_INST_CMPL */ + ++nlim; + break; + case 0x500009: /* PM_RUN_INST_CMPL */ + alt[j++] = 0x100009; /* PM_INST_CMPL */ + alt[j++] = 0x200009; + break; + } + } + nalt = j; + } + + if (!(flags & PPMU_LIMITED_PMC_OK) && nlim) { + /* remove the limited PMC events */ + j = 0; + for (i = 0; i < nalt; ++i) { + if (!power5p_limited_pmc_event(alt[i])) { + alt[j] = alt[i]; + ++j; + } + } + nalt = j; + } else if ((flags & PPMU_LIMITED_PMC_REQD) && nlim < nalt) { + /* remove all but the limited PMC events */ + j = 0; + for (i = 0; i < nalt; ++i) { + if (power5p_limited_pmc_event(alt[i])) { + alt[j] = alt[i]; + ++j; + } + } + nalt = j; + } + return nalt; } @@ -390,7 +464,7 @@ static int power5p_compute_mmcr(unsigned int event[], int n_ev, unsigned char unituse[16]; int ttmuse; - if (n_ev > 4) + if (n_ev > 6) return -1; /* First pass to count resource use */ @@ -399,7 +473,7 @@ static int power5p_compute_mmcr(unsigned int event[], int n_ev, for (i = 0; i < n_ev; ++i) { pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; if (pmc) { - if (pmc > 4) + if (pmc > 6) return -1; if (pmc_inuse & (1 << (pmc - 1))) return -1; @@ -488,13 +562,16 @@ static int power5p_compute_mmcr(unsigned int event[], int n_ev, if (pmc >= 4) return -1; pmc_inuse |= 1 << pmc; - } else { + } else if (pmc <= 4) { /* Direct event */ --pmc; if (isbus && (byte & 2) && (psel == 8 || psel == 0x10 || psel == 0x28)) /* add events on higher-numbered bus */ mmcr1 |= 1ull << (MMCR1_PMC1_ADDER_SEL_SH - pmc); + } else { + /* Instructions or run cycles on PMC5/6 */ + --pmc; } if (isbus && unit == PM_GRS) { bit = psel & 7; @@ -538,7 +615,7 @@ static int power5p_generic_events[] = { }; struct power_pmu power5p_pmu = { - .n_counter = 4, + .n_counter = 6, .max_alternatives = MAX_ALT, .add_fields = 0x7000000000055ull, .test_adder = 0x3000040000000ull, @@ -548,4 +625,6 @@ struct power_pmu power5p_pmu = { .disable_pmc = power5p_disable_pmc, .n_generic = ARRAY_SIZE(power5p_generic_events), .generic_events = power5p_generic_events, + .limited_pmc5_6 = 1, + .limited_pmc_event = power5p_limited_pmc_event, }; diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c index 116c4bb1809e..6e667dc86470 100644 --- a/arch/powerpc/kernel/power5-pmu.c +++ b/arch/powerpc/kernel/power5-pmu.c @@ -269,7 +269,8 @@ static int find_alternative_bdecode(unsigned int event) return -1; } -static int power5_get_alternatives(unsigned int event, unsigned int alt[]) +static int power5_get_alternatives(unsigned int event, unsigned int flags, + unsigned int alt[]) { int i, j, ae, nalt = 1; diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c index fce1fc290a1d..d44049f0ae27 100644 --- a/arch/powerpc/kernel/power6-pmu.c +++ b/arch/powerpc/kernel/power6-pmu.c @@ -182,7 +182,7 @@ static int p6_compute_mmcr(unsigned int event[], int n_ev, unsigned int ttmset = 0; unsigned int pmc_inuse = 0; - if (n_ev > 4) + if (n_ev > 6) return -1; for (i = 0; i < n_ev; ++i) { pmc = (event[i] >> PM_PMC_SH) & PM_PMC_MSK; @@ -202,6 +202,8 @@ static int p6_compute_mmcr(unsigned int event[], int n_ev, for (pmc = 0; pmc < 4; ++pmc) if (!(pmc_inuse & (1 << pmc))) break; + if (pmc >= 4) + return -1; pmc_inuse |= 1 << pmc; } hwc[i] = pmc; @@ -240,7 +242,8 @@ static int p6_compute_mmcr(unsigned int event[], int n_ev, } if (power6_marked_instr_event(event[i])) mmcra |= MMCRA_SAMPLE_ENABLE; - mmcr1 |= (u64)psel << MMCR1_PMCSEL_SH(pmc); + if (pmc < 4) + mmcr1 |= (u64)psel << MMCR1_PMCSEL_SH(pmc); } mmcr[0] = 0; if (pmc_inuse & 1) @@ -256,19 +259,20 @@ static int p6_compute_mmcr(unsigned int event[], int n_ev, * Layout of constraint bits: * * 0-1 add field: number of uses of PMC1 (max 1) - * 2-3, 4-5, 6-7: ditto for PMC2, 3, 4 - * 8-10 select field: nest (subunit) event selector + * 2-3, 4-5, 6-7, 8-9, 10-11: ditto for PMC2, 3, 4, 5, 6 + * 12-15 add field: number of uses of PMC1-4 (max 4) * 16-19 select field: unit on byte 0 of event bus * 20-23, 24-27, 28-31 ditto for bytes 1, 2, 3 + * 32-34 select field: nest (subunit) event selector */ static int p6_get_constraint(unsigned int event, u64 *maskp, u64 *valp) { - int pmc, byte, sh; - unsigned int mask = 0, value = 0; + int pmc, byte, sh, subunit; + u64 mask = 0, value = 0; pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; if (pmc) { - if (pmc > 4) + if (pmc > 4 && !(event == 0x500009 || event == 0x600005)) return -1; sh = (pmc - 1) * 2; mask |= 2 << sh; @@ -276,26 +280,38 @@ static int p6_get_constraint(unsigned int event, u64 *maskp, u64 *valp) } if (event & PM_BUSEVENT_MSK) { byte = (event >> PM_BYTE_SH) & PM_BYTE_MSK; - sh = byte * 4; + sh = byte * 4 + (16 - PM_UNIT_SH); mask |= PM_UNIT_MSKS << sh; - value |= (event & PM_UNIT_MSKS) << sh; + value |= (u64)(event & PM_UNIT_MSKS) << sh; if ((event & PM_UNIT_MSKS) == (5 << PM_UNIT_SH)) { - mask |= PM_SUBUNIT_MSKS; - value |= event & PM_SUBUNIT_MSKS; + subunit = (event >> PM_SUBUNIT_SH) & PM_SUBUNIT_MSK; + mask |= (u64)PM_SUBUNIT_MSK << 32; + value |= (u64)subunit << 32; } } + if (pmc <= 4) { + mask |= 0x8000; /* add field for count of PMC1-4 uses */ + value |= 0x1000; + } *maskp = mask; *valp = value; return 0; } +static int p6_limited_pmc_event(unsigned int event) +{ + int pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; + + return pmc == 5 || pmc == 6; +} + #define MAX_ALT 4 /* at most 4 alternatives for any event */ static const unsigned int event_alternatives[][MAX_ALT] = { { 0x0130e8, 0x2000f6, 0x3000fc }, /* PM_PTEG_RELOAD_VALID */ { 0x080080, 0x10000d, 0x30000c, 0x4000f0 }, /* PM_LD_MISS_L1 */ { 0x080088, 0x200054, 0x3000f0 }, /* PM_ST_MISS_L1 */ - { 0x10000a, 0x2000f4 }, /* PM_RUN_CYC */ + { 0x10000a, 0x2000f4, 0x600005 }, /* PM_RUN_CYC */ { 0x10000b, 0x2000f5 }, /* PM_RUN_COUNT */ { 0x10000e, 0x400010 }, /* PM_PURR */ { 0x100010, 0x4000f8 }, /* PM_FLUSH */ @@ -340,13 +356,15 @@ static int find_alternatives_list(unsigned int event) return -1; } -static int p6_get_alternatives(unsigned int event, unsigned int alt[]) +static int p6_get_alternatives(unsigned int event, unsigned int flags, + unsigned int alt[]) { - int i, j; + int i, j, nlim; unsigned int aevent, psel, pmc; unsigned int nalt = 1; alt[0] = event; + nlim = p6_limited_pmc_event(event); /* check the alternatives table */ i = find_alternatives_list(event); @@ -358,6 +376,7 @@ static int p6_get_alternatives(unsigned int event, unsigned int alt[]) break; if (aevent != event) alt[nalt++] = aevent; + nlim += p6_limited_pmc_event(aevent); } } else { @@ -375,13 +394,75 @@ static int p6_get_alternatives(unsigned int event, unsigned int alt[]) ((pmc > 2? pmc - 2: pmc + 2) << PM_PMC_SH); } + if (flags & PPMU_ONLY_COUNT_RUN) { + /* + * We're only counting in RUN state, + * so PM_CYC is equivalent to PM_RUN_CYC, + * PM_INST_CMPL === PM_RUN_INST_CMPL, PM_PURR === PM_RUN_PURR. + * This doesn't include alternatives that don't provide + * any extra flexibility in assigning PMCs (e.g. + * 0x10000a for PM_RUN_CYC vs. 0x1e for PM_CYC). + * Note that even with these additional alternatives + * we never end up with more than 4 alternatives for any event. + */ + j = nalt; + for (i = 0; i < nalt; ++i) { + switch (alt[i]) { + case 0x1e: /* PM_CYC */ + alt[j++] = 0x600005; /* PM_RUN_CYC */ + ++nlim; + break; + case 0x10000a: /* PM_RUN_CYC */ + alt[j++] = 0x1e; /* PM_CYC */ + break; + case 2: /* PM_INST_CMPL */ + alt[j++] = 0x500009; /* PM_RUN_INST_CMPL */ + ++nlim; + break; + case 0x500009: /* PM_RUN_INST_CMPL */ + alt[j++] = 2; /* PM_INST_CMPL */ + break; + case 0x10000e: /* PM_PURR */ + alt[j++] = 0x4000f4; /* PM_RUN_PURR */ + break; + case 0x4000f4: /* PM_RUN_PURR */ + alt[j++] = 0x10000e; /* PM_PURR */ + break; + } + } + nalt = j; + } + + if (!(flags & PPMU_LIMITED_PMC_OK) && nlim) { + /* remove the limited PMC events */ + j = 0; + for (i = 0; i < nalt; ++i) { + if (!p6_limited_pmc_event(alt[i])) { + alt[j] = alt[i]; + ++j; + } + } + nalt = j; + } else if ((flags & PPMU_LIMITED_PMC_REQD) && nlim < nalt) { + /* remove all but the limited PMC events */ + j = 0; + for (i = 0; i < nalt; ++i) { + if (p6_limited_pmc_event(alt[i])) { + alt[j] = alt[i]; + ++j; + } + } + nalt = j; + } + return nalt; } static void p6_disable_pmc(unsigned int pmc, u64 mmcr[]) { /* Set PMCxSEL to 0 to disable PMCx */ - mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SH(pmc)); + if (pmc <= 3) + mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SH(pmc)); } static int power6_generic_events[] = { @@ -394,14 +475,16 @@ static int power6_generic_events[] = { }; struct power_pmu power6_pmu = { - .n_counter = 4, + .n_counter = 6, .max_alternatives = MAX_ALT, - .add_fields = 0x55, - .test_adder = 0, + .add_fields = 0x1555, + .test_adder = 0x3000, .compute_mmcr = p6_compute_mmcr, .get_constraint = p6_get_constraint, .get_alternatives = p6_get_alternatives, .disable_pmc = p6_disable_pmc, .n_generic = ARRAY_SIZE(power6_generic_events), .generic_events = power6_generic_events, + .limited_pmc5_6 = 1, + .limited_pmc_event = p6_limited_pmc_event, }; diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c index aed8ccd7c077..af2d1884058c 100644 --- a/arch/powerpc/kernel/ppc970-pmu.c +++ b/arch/powerpc/kernel/ppc970-pmu.c @@ -243,7 +243,8 @@ static int p970_get_constraint(unsigned int event, u64 *maskp, u64 *valp) return 0; } -static int p970_get_alternatives(unsigned int event, unsigned int alt[]) +static int p970_get_alternatives(unsigned int event, unsigned int flags, + unsigned int alt[]) { alt[0] = event; -- GitLab From f25181f598cf4a8ccc40a51d8b74f8b555ecddee Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Thu, 23 Apr 2009 22:18:00 -0400 Subject: [PATCH 0909/6080] xfs_file_last_byte() needs to acquire ilock We had some systems crash with this stack: [] ia64_leave_kernel+0x0/0x280 [] xfs_bmbt_get_startoff+0x0/0x20 [xfs] [] xfs_bmap_last_offset+0x210/0x280 [xfs] [] xfs_file_last_byte+0x70/0x1a0 [xfs] [] xfs_itruncate_start+0xc0/0x1a0 [xfs] [] xfs_inactive_free_eofblocks+0x290/0x460 [xfs] [] xfs_release+0x1b0/0x240 [xfs] [] xfs_file_release+0x70/0xa0 [xfs] [] __fput+0x1a0/0x420 [] fput+0x40/0x60 The problem here is that xfs_file_last_byte() does not acquire the inode lock and can therefore race with another thread that is modifying the extext list. While xfs_bmap_last_offset() is trying to lookup what was the last extent some extents were merged and the extent list shrunk so the index we lookup is now beyond the end of the extent list and potentially in a freed buffer. Signed-off-by: Lachlan McIlroy Reviewed-by: Christoph Hellwig Reviewed-by: Felix Blyakher Signed-off-by: Felix Blyakher --- fs/xfs/xfs_inode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index e7ae08d1df48..123b20c8cbf2 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1258,8 +1258,10 @@ xfs_file_last_byte( * necessary. */ if (ip->i_df.if_flags & XFS_IFEXTENTS) { + xfs_ilock(ip, XFS_ILOCK_SHARED); error = xfs_bmap_last_offset(NULL, ip, &last_block, XFS_DATA_FORK); + xfs_iunlock(ip, XFS_ILOCK_SHARED); if (error) { last_block = 0; } -- GitLab From 2ac00af7a6d2e65013e6f28bd1f37c0cd98ba134 Mon Sep 17 00:00:00 2001 From: Olaf Weber Date: Fri, 17 Apr 2009 16:12:45 -0500 Subject: [PATCH 0910/6080] xfs: add more checks to superblock validation There had been reports where xfs filesystem was randomly corrupted with fsfuzzer, and xfs failed to handle it gracefully. This patch fixes couple of reported problem by providing additional checks in the superblock validation routine. Signed-off-by: Olaf Weber Reviewed-by: Josef 'Jeff' Sipek Reviewed-by: Christoph Hellwig Signed-off-by: Felix Blyakher --- fs/xfs/xfs_mount.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index b101990df027..65a99725d0cc 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -291,14 +291,17 @@ xfs_mount_validate_sb( sbp->sb_sectsize > XFS_MAX_SECTORSIZE || sbp->sb_sectlog < XFS_MIN_SECTORSIZE_LOG || sbp->sb_sectlog > XFS_MAX_SECTORSIZE_LOG || + sbp->sb_sectsize != (1 << sbp->sb_sectlog) || sbp->sb_blocksize < XFS_MIN_BLOCKSIZE || sbp->sb_blocksize > XFS_MAX_BLOCKSIZE || sbp->sb_blocklog < XFS_MIN_BLOCKSIZE_LOG || sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG || + sbp->sb_blocksize != (1 << sbp->sb_blocklog) || sbp->sb_inodesize < XFS_DINODE_MIN_SIZE || sbp->sb_inodesize > XFS_DINODE_MAX_SIZE || sbp->sb_inodelog < XFS_DINODE_MIN_LOG || sbp->sb_inodelog > XFS_DINODE_MAX_LOG || + sbp->sb_inodesize != (1 << sbp->sb_inodelog) || (sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) || (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) || (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) || -- GitLab From 4be4a00fb55879ef44b5914c189aecffa828deb4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 29 Apr 2009 10:50:48 -0400 Subject: [PATCH 0911/6080] xfs: a couple getbmap cleanups - reshuffle various conditionals for data vs attr fork to make the code more readable - do fine-grainded goto-based error handling - exit early from conditionals instead of keeping a long else branch around - allow kmem_alloc to fail Signed-off-by: Christoph Hellwig Reviewed-by: Eric Sandeen Reviewed-by: Felix Blyakher Signed-off-by: Felix Blyakher --- fs/xfs/xfs_bmap.c | 162 ++++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 83 deletions(-) diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 3a6ed426327a..abe42448b1c0 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -5880,7 +5880,7 @@ xfs_getbmap( void *arg) /* formatter arg */ { __int64_t bmvend; /* last block requested */ - int error; /* return value */ + int error = 0; /* return value */ __int64_t fixlen; /* length for -1 case */ int i; /* extent number */ int lock; /* lock state */ @@ -5899,30 +5899,8 @@ xfs_getbmap( mp = ip->i_mount; iflags = bmv->bmv_iflags; - whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK; - /* If the BMV_IF_NO_DMAPI_READ interface bit specified, do not - * generate a DMAPI read event. Otherwise, if the DM_EVENT_READ - * bit is set for the file, generate a read event in order - * that the DMAPI application may do its thing before we return - * the extents. Usually this means restoring user file data to - * regions of the file that look like holes. - * - * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify - * BMV_IF_NO_DMAPI_READ so that read events are generated. - * If this were not true, callers of ioctl( XFS_IOC_GETBMAP ) - * could misinterpret holes in a DMAPI file as true holes, - * when in fact they may represent offline user data. - */ - if ((iflags & BMV_IF_NO_DMAPI_READ) == 0 && - DM_EVENT_ENABLED(ip, DM_EVENT_READ) && - whichfork == XFS_DATA_FORK) { - error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL); - if (error) - return XFS_ERROR(error); - } - if (whichfork == XFS_ATTR_FORK) { if (XFS_IFORK_Q(ip)) { if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS && @@ -5936,11 +5914,37 @@ xfs_getbmap( ip->i_mount); return XFS_ERROR(EFSCORRUPTED); } - } else if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && - ip->i_d.di_format != XFS_DINODE_FMT_BTREE && - ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) - return XFS_ERROR(EINVAL); - if (whichfork == XFS_DATA_FORK) { + + prealloced = 0; + fixlen = 1LL << 32; + } else { + /* + * If the BMV_IF_NO_DMAPI_READ interface bit specified, do + * not generate a DMAPI read event. Otherwise, if the + * DM_EVENT_READ bit is set for the file, generate a read + * event in order that the DMAPI application may do its thing + * before we return the extents. Usually this means restoring + * user file data to regions of the file that look like holes. + * + * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify + * BMV_IF_NO_DMAPI_READ so that read events are generated. + * If this were not true, callers of ioctl(XFS_IOC_GETBMAP) + * could misinterpret holes in a DMAPI file as true holes, + * when in fact they may represent offline user data. + */ + if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && + !(iflags & BMV_IF_NO_DMAPI_READ)) { + error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, + 0, 0, 0, NULL); + if (error) + return XFS_ERROR(error); + } + + if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS && + ip->i_d.di_format != XFS_DINODE_FMT_BTREE && + ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) + return XFS_ERROR(EINVAL); + if (xfs_get_extsz_hint(ip) || ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){ prealloced = 1; @@ -5949,42 +5953,34 @@ xfs_getbmap( prealloced = 0; fixlen = ip->i_size; } - } else { - prealloced = 0; - fixlen = 1LL << 32; } if (bmv->bmv_length == -1) { fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, fixlen)); - bmv->bmv_length = MAX( (__int64_t)(fixlen - bmv->bmv_offset), - (__int64_t)0); - } else if (bmv->bmv_length < 0) - return XFS_ERROR(EINVAL); - if (bmv->bmv_length == 0) { + bmv->bmv_length = + max_t(__int64_t, fixlen - bmv->bmv_offset, 0); + } else if (bmv->bmv_length == 0) { bmv->bmv_entries = 0; return 0; + } else if (bmv->bmv_length < 0) { + return XFS_ERROR(EINVAL); } + nex = bmv->bmv_count - 1; if (nex <= 0) return XFS_ERROR(EINVAL); bmvend = bmv->bmv_offset + bmv->bmv_length; xfs_ilock(ip, XFS_IOLOCK_SHARED); - - if (((iflags & BMV_IF_DELALLOC) == 0) && - (whichfork == XFS_DATA_FORK) && - (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) { - /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ - error = xfs_flush_pages(ip, (xfs_off_t)0, - -1, 0, FI_REMAPF); - if (error) { - xfs_iunlock(ip, XFS_IOLOCK_SHARED); - return error; + if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) { + if (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size) { + error = xfs_flush_pages(ip, 0, -1, 0, FI_REMAPF); + if (error) + goto out_unlock_iolock; } - } - ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) || - ip->i_delayed_blks == 0); + ASSERT(ip->i_delayed_blks == 0); + } lock = xfs_ilock_map_shared(ip); @@ -5995,23 +5991,25 @@ 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) | - ((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE); + bmapi_flags = xfs_bmapi_aflag(whichfork); + if (!(iflags & BMV_IF_PREALLOC)) + bmapi_flags |= XFS_BMAPI_IGSTATE; /* * Allocate enough space to handle "subnex" maps at a time. */ + error = ENOMEM; subnex = 16; - map = kmem_alloc(subnex * sizeof(*map), KM_SLEEP); + map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL); + if (!map) + goto out_unlock_ilock; bmv->bmv_entries = 0; - if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) { - if (((iflags & BMV_IF_DELALLOC) == 0) || - whichfork == XFS_ATTR_FORK) { - error = 0; - goto unlock_and_return; - } + if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0 && + (whichfork == XFS_ATTR_FORK || !(iflags & BMV_IF_DELALLOC))) { + error = 0; + goto out_free_map; } nexleft = nex; @@ -6023,10 +6021,12 @@ xfs_getbmap( bmapi_flags, NULL, 0, map, &nmap, NULL, NULL); if (error) - goto unlock_and_return; + goto out_free_map; ASSERT(nmap <= subnex); for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) { + int full = 0; /* user array is full */ + out.bmv_oflags = 0; if (map[i].br_state == XFS_EXT_UNWRITTEN) out.bmv_oflags |= BMV_OF_PREALLOC; @@ -6041,36 +6041,32 @@ xfs_getbmap( whichfork == XFS_ATTR_FORK) { /* came to the end of attribute fork */ out.bmv_oflags |= BMV_OF_LAST; - goto unlock_and_return; - } else { - int full = 0; /* user array is full */ - - if (!xfs_getbmapx_fix_eof_hole(ip, &out, - prealloced, bmvend, - map[i].br_startblock)) { - goto unlock_and_return; - } - - /* format results & advance arg */ - error = formatter(&arg, &out, &full); - if (error || full) - goto unlock_and_return; - nexleft--; - bmv->bmv_offset = - out.bmv_offset + out.bmv_length; - bmv->bmv_length = MAX((__int64_t)0, - (__int64_t)(bmvend - bmv->bmv_offset)); - bmv->bmv_entries++; + goto out_free_map; } + + if (!xfs_getbmapx_fix_eof_hole(ip, &out, prealloced, + bmvend, map[i].br_startblock)) + goto out_free_map; + + /* format results & advance arg */ + error = formatter(&arg, &out, &full); + if (error || full) + goto out_free_map; + nexleft--; + bmv->bmv_offset = + out.bmv_offset + out.bmv_length; + bmv->bmv_length = + max_t(__int64_t, 0, bmvend - bmv->bmv_offset); + bmv->bmv_entries++; } } while (nmap && nexleft && bmv->bmv_length); -unlock_and_return: + out_free_map: + kmem_free(map); + out_unlock_ilock: xfs_iunlock_map_shared(ip, lock); + out_unlock_iolock: xfs_iunlock(ip, XFS_IOLOCK_SHARED); - - kmem_free(map); - return error; } -- GitLab From 6321e3ed2acf3ee9643cdd403e1c88605d7944ba Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 24 Feb 2009 08:39:02 -0500 Subject: [PATCH 0912/6080] xfs: fix getbmap vs mmap deadlock xfs_getbmap (or rather the formatters called by it) copy out the getbmap structures under the ilock, which can deadlock against mmap. This has been reported via bugzilla a while ago (#717) and has recently also shown up via lockdep. So allocate a temporary buffer to format the kernel getbmap structures into and then copy them out after dropping the locks. A little problem with this is that we limit the number of extents we can copy out by the maximum allocation size, but I see no real way around that. Signed-off-by: Christoph Hellwig Reviewed-by: Eric Sandeen Reviewed-by: Felix Blyakher Signed-off-by: Felix Blyakher --- fs/xfs/xfs_bmap.c | 52 +++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index abe42448b1c0..ca7c6005a487 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -5890,12 +5890,13 @@ xfs_getbmap( int nexleft; /* # of user extents left */ int subnex; /* # of bmapi's can do */ int nmap; /* number of map entries */ - struct getbmapx out; /* output structure */ + struct getbmapx *out; /* output structure */ int whichfork; /* data or attr fork */ int prealloced; /* this is a file with * preallocated data space */ int iflags; /* interface flags */ int bmapi_flags; /* flags for xfs_bmapi */ + int cur_ext = 0; mp = ip->i_mount; iflags = bmv->bmv_iflags; @@ -5971,6 +5972,13 @@ xfs_getbmap( return XFS_ERROR(EINVAL); bmvend = bmv->bmv_offset + bmv->bmv_length; + + if (bmv->bmv_count > ULONG_MAX / sizeof(struct getbmapx)) + return XFS_ERROR(ENOMEM); + out = kmem_zalloc(bmv->bmv_count * sizeof(struct getbmapx), KM_MAYFAIL); + if (!out) + return XFS_ERROR(ENOMEM); + xfs_ilock(ip, XFS_IOLOCK_SHARED); if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) { if (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size) { @@ -6025,39 +6033,39 @@ xfs_getbmap( ASSERT(nmap <= subnex); for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) { - int full = 0; /* user array is full */ - - out.bmv_oflags = 0; + out[cur_ext].bmv_oflags = 0; if (map[i].br_state == XFS_EXT_UNWRITTEN) - out.bmv_oflags |= BMV_OF_PREALLOC; + out[cur_ext].bmv_oflags |= BMV_OF_PREALLOC; else if (map[i].br_startblock == DELAYSTARTBLOCK) - out.bmv_oflags |= BMV_OF_DELALLOC; - out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff); - out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount); - out.bmv_unused1 = out.bmv_unused2 = 0; + out[cur_ext].bmv_oflags |= BMV_OF_DELALLOC; + out[cur_ext].bmv_offset = + XFS_FSB_TO_BB(mp, map[i].br_startoff); + out[cur_ext].bmv_length = + XFS_FSB_TO_BB(mp, map[i].br_blockcount); + out[cur_ext].bmv_unused1 = 0; + out[cur_ext].bmv_unused2 = 0; ASSERT(((iflags & BMV_IF_DELALLOC) != 0) || (map[i].br_startblock != DELAYSTARTBLOCK)); if (map[i].br_startblock == HOLESTARTBLOCK && whichfork == XFS_ATTR_FORK) { /* came to the end of attribute fork */ - out.bmv_oflags |= BMV_OF_LAST; + out[cur_ext].bmv_oflags |= BMV_OF_LAST; goto out_free_map; } - if (!xfs_getbmapx_fix_eof_hole(ip, &out, prealloced, - bmvend, map[i].br_startblock)) + if (!xfs_getbmapx_fix_eof_hole(ip, &out[cur_ext], + prealloced, bmvend, + map[i].br_startblock)) goto out_free_map; - /* format results & advance arg */ - error = formatter(&arg, &out, &full); - if (error || full) - goto out_free_map; nexleft--; bmv->bmv_offset = - out.bmv_offset + out.bmv_length; + out[cur_ext].bmv_offset + + out[cur_ext].bmv_length; bmv->bmv_length = max_t(__int64_t, 0, bmvend - bmv->bmv_offset); bmv->bmv_entries++; + cur_ext++; } } while (nmap && nexleft && bmv->bmv_length); @@ -6067,6 +6075,16 @@ xfs_getbmap( xfs_iunlock_map_shared(ip, lock); out_unlock_iolock: xfs_iunlock(ip, XFS_IOLOCK_SHARED); + + for (i = 0; i < cur_ext; i++) { + int full = 0; /* user array is full */ + + /* format results & advance arg */ + error = formatter(&arg, &out[i], &full); + if (error || full) + break; + } + return error; } -- GitLab From 43f6201a22dbf1c5abe1cab96b49bd56fa9df8f4 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 29 Apr 2009 16:55:56 +0200 Subject: [PATCH 0913/6080] perf_counter, x86: rename bitmasks to ->used_mask and ->active_mask Standardize on explicitly mentioning '_mask' in fields that are not plain flags but masks. This avoids typos like: if (cpuc->used) (which could easily slip through review unnoticed), while if a typo looks like this: if (cpuc->used_mask) it might get noticed during review. [ Impact: cleanup ] Signed-off-by: Robert Richter Cc: Peter Zijlstra Cc: Paul Mackerras LKML-Reference: <1241016956-24648-1-git-send-email-robert.richter@amd.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_counter.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index 47e563bfd4cf..fc06f4d32644 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c @@ -28,8 +28,8 @@ static u64 perf_counter_mask __read_mostly; struct cpu_hw_counters { struct perf_counter *counters[X86_PMC_IDX_MAX]; - unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; - unsigned long active[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; + unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; + unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; unsigned long interrupts; u64 throttle_ctrl; int enabled; @@ -332,7 +332,7 @@ static u64 amd_pmu_save_disable_all(void) for (idx = 0; idx < x86_pmu.num_counters; idx++) { u64 val; - if (!test_bit(idx, cpuc->active)) + if (!test_bit(idx, cpuc->active_mask)) continue; rdmsrl(MSR_K7_EVNTSEL0 + idx, val); if (!(val & ARCH_PERFMON_EVENTSEL0_ENABLE)) @@ -373,7 +373,7 @@ static void amd_pmu_restore_all(u64 ctrl) for (idx = 0; idx < x86_pmu.num_counters; idx++) { u64 val; - if (!test_bit(idx, cpuc->active)) + if (!test_bit(idx, cpuc->active_mask)) continue; rdmsrl(MSR_K7_EVNTSEL0 + idx, val); if (val & ARCH_PERFMON_EVENTSEL0_ENABLE) @@ -576,7 +576,7 @@ static int x86_pmu_enable(struct perf_counter *counter) * Try to get the fixed counter, if that is already taken * then try to get a generic counter: */ - if (test_and_set_bit(idx, cpuc->used)) + if (test_and_set_bit(idx, cpuc->used_mask)) goto try_generic; hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; @@ -590,14 +590,14 @@ static int x86_pmu_enable(struct perf_counter *counter) } else { idx = hwc->idx; /* Try to get the previous generic counter again */ - if (test_and_set_bit(idx, cpuc->used)) { + if (test_and_set_bit(idx, cpuc->used_mask)) { try_generic: - idx = find_first_zero_bit(cpuc->used, + idx = find_first_zero_bit(cpuc->used_mask, x86_pmu.num_counters); if (idx == x86_pmu.num_counters) return -EAGAIN; - set_bit(idx, cpuc->used); + set_bit(idx, cpuc->used_mask); hwc->idx = idx; } hwc->config_base = x86_pmu.eventsel; @@ -609,7 +609,7 @@ try_generic: x86_pmu.disable(hwc, idx); cpuc->counters[idx] = counter; - set_bit(idx, cpuc->active); + set_bit(idx, cpuc->active_mask); x86_perf_counter_set_period(counter, hwc, idx); x86_pmu.enable(hwc, idx); @@ -643,7 +643,7 @@ void perf_counter_print_debug(void) pr_info("CPU#%d: overflow: %016llx\n", cpu, overflow); pr_info("CPU#%d: fixed: %016llx\n", cpu, fixed); } - pr_info("CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used); + pr_info("CPU#%d: used: %016llx\n", cpu, *(u64 *)cpuc->used_mask); for (idx = 0; idx < x86_pmu.num_counters; idx++) { rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl); @@ -677,7 +677,7 @@ static void x86_pmu_disable(struct perf_counter *counter) * Must be done before we disable, otherwise the nmi handler * could reenable again: */ - clear_bit(idx, cpuc->active); + clear_bit(idx, cpuc->active_mask); x86_pmu.disable(hwc, idx); /* @@ -692,7 +692,7 @@ static void x86_pmu_disable(struct perf_counter *counter) */ x86_perf_counter_update(counter, hwc, idx); cpuc->counters[idx] = NULL; - clear_bit(idx, cpuc->used); + clear_bit(idx, cpuc->used_mask); } /* @@ -741,7 +741,7 @@ again: struct perf_counter *counter = cpuc->counters[bit]; clear_bit(bit, (unsigned long *) &status); - if (!test_bit(bit, cpuc->active)) + if (!test_bit(bit, cpuc->active_mask)) continue; intel_pmu_save_and_restart(counter); @@ -779,7 +779,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs, int nmi) ++cpuc->interrupts; for (idx = 0; idx < x86_pmu.num_counters; idx++) { - if (!test_bit(idx, cpuc->active)) + if (!test_bit(idx, cpuc->active_mask)) continue; counter = cpuc->counters[idx]; hwc = &counter->hw; -- GitLab From 88c48db9788862d0290831d081bc3c64e13b592f Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Wed, 29 Apr 2009 14:00:25 -0400 Subject: [PATCH 0914/6080] SELinux: drop secondary_ops->sysctl We are still calling secondary_ops->sysctl even though the capabilities module does not define a sysctl operation. Signed-off-by: Eric Paris Acked-by: Stephen Smalley Signed-off-by: James Morris --- security/selinux/hooks.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ba808ef6babb..dd19ba81201f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1980,10 +1980,6 @@ static int selinux_sysctl(ctl_table *table, int op) u32 tsid, sid; int rc; - rc = secondary_ops->sysctl(table, op); - if (rc) - return rc; - sid = current_sid(); rc = selinux_sysctl_get_sid(table, (op == 0001) ? -- GitLab From 3bcac0263f0b45e67a64034ebcb69eb9abb742f4 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 29 Apr 2009 13:45:05 +0100 Subject: [PATCH 0915/6080] SELinux: Don't flush inherited SIGKILL during execve() Don't flush inherited SIGKILL during execve() in SELinux's post cred commit hook. This isn't really a security problem: if the SIGKILL came before the credentials were changed, then we were right to receive it at the time, and should honour it; if it came after the creds were changed, then we definitely should honour it; and in any case, all that will happen is that the process will be scrapped before it ever returns to userspace. Signed-off-by: David Howells Signed-off-by: Oleg Nesterov Signed-off-by: James Morris --- include/linux/sched.h | 1 + kernel/signal.c | 11 ++++++++--- security/selinux/hooks.c | 9 +++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 1d19c025f9d2..d3b787c7aef3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1875,6 +1875,7 @@ extern void sched_dead(struct task_struct *p); extern void proc_caches_init(void); extern void flush_signals(struct task_struct *); +extern void __flush_signals(struct task_struct *); extern void ignore_signals(struct task_struct *); extern void flush_signal_handlers(struct task_struct *, int force_default); extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info); diff --git a/kernel/signal.c b/kernel/signal.c index 1c8814481a11..f93efec14ff5 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -238,14 +238,19 @@ void flush_sigqueue(struct sigpending *queue) /* * Flush all pending signals for a task. */ +void __flush_signals(struct task_struct *t) +{ + clear_tsk_thread_flag(t, TIF_SIGPENDING); + flush_sigqueue(&t->pending); + flush_sigqueue(&t->signal->shared_pending); +} + void flush_signals(struct task_struct *t) { unsigned long flags; spin_lock_irqsave(&t->sighand->siglock, flags); - clear_tsk_thread_flag(t, TIF_SIGPENDING); - flush_sigqueue(&t->pending); - flush_sigqueue(&t->signal->shared_pending); + __flush_signals(t); spin_unlock_irqrestore(&t->sighand->siglock, flags); } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index dd19ba81201f..5a345115036c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2394,11 +2394,12 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) memset(&itimer, 0, sizeof itimer); for (i = 0; i < 3; i++) do_setitimer(i, &itimer, NULL); - flush_signals(current); spin_lock_irq(¤t->sighand->siglock); - flush_signal_handlers(current, 1); - sigemptyset(¤t->blocked); - recalc_sigpending(); + if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) { + __flush_signals(current); + flush_signal_handlers(current, 1); + sigemptyset(¤t->blocked); + } spin_unlock_irq(¤t->sighand->siglock); } -- GitLab From ecd6de3c88e8cbcad175b2eab48ba05c2014f7b6 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 29 Apr 2009 16:02:24 +0200 Subject: [PATCH 0916/6080] selinux: selinux_bprm_committed_creds() should wake up ->real_parent, not ->parent. We shouldn't worry about the tracer if current is ptraced, exec() must not succeed if the tracer has no rights to trace this task after cred changing. But we should notify ->real_parent which is, well, real parent. Also, we don't need _irq to take tasklist, and we don't need parent's ->siglock to wake_up_interruptible(real_parent->signal->wait_chldexit). Since we hold tasklist, real_parent->signal must be stable. Otherwise spin_lock(siglock) is not safe too and can't help anyway. Signed-off-by: Oleg Nesterov Signed-off-by: James Morris --- security/selinux/hooks.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5a345115036c..39046ddd90a9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2371,10 +2371,8 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) { const struct task_security_struct *tsec = current_security(); struct itimerval itimer; - struct sighand_struct *psig; u32 osid, sid; int rc, i; - unsigned long flags; osid = tsec->osid; sid = tsec->sid; @@ -2405,12 +2403,9 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) /* Wake up the parent if it is waiting so that it can recheck * wait permission to the new task SID. */ - read_lock_irq(&tasklist_lock); - psig = current->parent->sighand; - spin_lock_irqsave(&psig->siglock, flags); - wake_up_interruptible(¤t->parent->signal->wait_chldexit); - spin_unlock_irqrestore(&psig->siglock, flags); - read_unlock_irq(&tasklist_lock); + read_lock(&tasklist_lock); + wake_up_interruptible(¤t->real_parent->signal->wait_chldexit); + read_unlock(&tasklist_lock); } /* superblock security operations */ -- GitLab From ce105a082371570effb71541f299b1dc2771ee03 Mon Sep 17 00:00:00 2001 From: John Dykstra Date: Wed, 29 Apr 2009 17:22:30 -0700 Subject: [PATCH 0917/6080] pcnet32: Remove pointless memory barriers These two memory barriers in performance-critical paths are not needed on x86. Even if some other architecture does buffer PCI I/O space writes, the existing memory-mapped I/O barriers are unlikely to be what is needed. Signed-off-by: John Dykstra Acked-by: Don Fry Signed-off-by: David S. Miller --- drivers/net/pcnet32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index e5e8c59243b6..1c35e1d637a0 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1405,7 +1405,7 @@ static int pcnet32_poll(struct napi_struct *napi, int budget) /* Set interrupt enable. */ lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN); - mmiowb(); + spin_unlock_irqrestore(&lp->lock, flags); } return work_done; @@ -2597,7 +2597,7 @@ pcnet32_interrupt(int irq, void *dev_id) val = lp->a.read_csr(ioaddr, CSR3); val |= 0x5f00; lp->a.write_csr(ioaddr, CSR3, val); - mmiowb(); + __napi_schedule(&lp->napi); break; } -- GitLab From 0821c71751ef88f4251d7206e76ce497ee267a2d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:02:59 +0000 Subject: [PATCH 0918/6080] ethtool: Add port type PORT_OTHER Add a PORT_OTHER to represent all other physical port types. Current NICs generally do not allow switching between multiple port types in software so specific types should not be needed. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/ethtool.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 131b127b70f8..5ccb6bd660c7 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -605,6 +605,7 @@ struct ethtool_ops { #define PORT_MII 0x02 #define PORT_FIBRE 0x03 #define PORT_BNC 0x04 +#define PORT_OTHER 0xff /* Which transceiver to use. */ #define XCVR_INTERNAL 0x00 -- GitLab From 52c94dfae11d9ffd70b7bd003a36a4e210f2866a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:04:14 +0000 Subject: [PATCH 0919/6080] mdio: Add register definitions for MDIO (clause 45) IEEE 802.3 clause 45 specifies the MDIO interface and registers for use in 10G and other PHYs, similar to the MII management interface. PHYs may have up to 32 MMDs corresponding to different sub-layers and functions, each with up to 65536 registers. These are addressed by PRTAD (similar to the MII PHY address) and DEVAD. Define a mapping for specifying PRTAD and DEVAD through the existing MII ioctls. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/mdio.h | 237 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 include/linux/mdio.h diff --git a/include/linux/mdio.h b/include/linux/mdio.h new file mode 100644 index 000000000000..d57ddb08a1b2 --- /dev/null +++ b/include/linux/mdio.h @@ -0,0 +1,237 @@ +/* + * linux/mdio.h: definitions for MDIO (clause 45) transceivers + * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference. + */ + +#ifndef __LINUX_MDIO_H__ +#define __LINUX_MDIO_H__ + +#include + +/* MDIO Manageable Devices (MMDs). */ +#define MDIO_MMD_PMAPMD 1 /* Physical Medium Attachment/ + * Physical Medium Dependent */ +#define MDIO_MMD_WIS 2 /* WAN Interface Sublayer */ +#define MDIO_MMD_PCS 3 /* Physical Coding Sublayer */ +#define MDIO_MMD_PHYXS 4 /* PHY Extender Sublayer */ +#define MDIO_MMD_DTEXS 5 /* DTE Extender Sublayer */ +#define MDIO_MMD_TC 6 /* Transmission Convergence */ +#define MDIO_MMD_AN 7 /* Auto-Negotiation */ +#define MDIO_MMD_C22EXT 29 /* Clause 22 extension */ +#define MDIO_MMD_VEND1 30 /* Vendor specific 1 */ +#define MDIO_MMD_VEND2 31 /* Vendor specific 2 */ + +/* Generic MDIO registers. */ +#define MDIO_CTRL1 MII_BMCR +#define MDIO_STAT1 MII_BMSR +#define MDIO_DEVID1 MII_PHYSID1 +#define MDIO_DEVID2 MII_PHYSID2 +#define MDIO_SPEED 4 /* Speed ability */ +#define MDIO_DEVS1 5 /* Devices in package */ +#define MDIO_DEVS2 6 +#define MDIO_CTRL2 7 /* 10G control 2 */ +#define MDIO_STAT2 8 /* 10G status 2 */ +#define MDIO_PMA_TXDIS 9 /* 10G PMA/PMD transmit disable */ +#define MDIO_PMA_RXDET 10 /* 10G PMA/PMD receive signal detect */ +#define MDIO_PMA_EXTABLE 11 /* 10G PMA/PMD extended ability */ +#define MDIO_PKGID1 14 /* Package identifier */ +#define MDIO_PKGID2 15 +#define MDIO_AN_ADVERTISE 16 /* AN advertising (base page) */ +#define MDIO_AN_LPA 19 /* AN LP abilities (base page) */ +#define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */ + +/* Media-dependent registers. */ +#define MDIO_PMA_10GBT_TXPWR 131 /* 10GBASE-T TX power control */ +#define MDIO_PCS_10GBX_STAT1 24 /* 10GBASE-X PCS status 1 */ +#define MDIO_PCS_10GBRT_STAT1 32 /* 10GBASE-R/-T PCS status 1 */ +#define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */ +#define MDIO_AN_10GBT_CTRL 32 /* 10GBASE-T auto-negotiation control */ +#define MDIO_AN_10GBT_STAT 33 /* 10GBASE-T auto-negotiation status */ + +/* Control register 1. */ +/* Enable extended speed selection */ +#define MDIO_CTRL1_SPEEDSELEXT (BMCR_SPEED1000 | BMCR_SPEED100) +/* All speed selection bits */ +#define MDIO_CTRL1_SPEEDSEL (MDIO_CTRL1_SPEEDSELEXT | 0x003c) +#define MDIO_CTRL1_FULLDPLX BMCR_FULLDPLX +#define MDIO_CTRL1_LPOWER BMCR_PDOWN +#define MDIO_CTRL1_RESET BMCR_RESET +#define MDIO_PMA_CTRL1_LOOPBACK 0x0001 +#define MDIO_PMA_CTRL1_SPEED1000 BMCR_SPEED1000 +#define MDIO_PMA_CTRL1_SPEED100 BMCR_SPEED100 +#define MDIO_PCS_CTRL1_LOOPBACK BMCR_LOOPBACK +#define MDIO_PHYXS_CTRL1_LOOPBACK BMCR_LOOPBACK +#define MDIO_AN_CTRL1_RESTART BMCR_ANRESTART +#define MDIO_AN_CTRL1_ENABLE BMCR_ANENABLE +#define MDIO_AN_CTRL1_XNP 0x2000 /* Enable extended next page */ + +/* 10 Gb/s */ +#define MDIO_CTRL1_SPEED10G (MDIO_CTRL1_SPEEDSELEXT | 0x00) +/* 10PASS-TS/2BASE-TL */ +#define MDIO_CTRL1_SPEED10P2B (MDIO_CTRL1_SPEEDSELEXT | 0x04) + +/* Status register 1. */ +#define MDIO_STAT1_LPOWERABLE 0x0002 /* Low-power ability */ +#define MDIO_STAT1_LSTATUS BMSR_LSTATUS +#define MDIO_STAT1_FAULT 0x0080 /* Fault */ +#define MDIO_AN_STAT1_LPABLE 0x0001 /* Link partner AN ability */ +#define MDIO_AN_STAT1_ABLE BMSR_ANEGCAPABLE +#define MDIO_AN_STAT1_RFAULT BMSR_RFAULT +#define MDIO_AN_STAT1_COMPLETE BMSR_ANEGCOMPLETE +#define MDIO_AN_STAT1_PAGE 0x0040 /* Page received */ +#define MDIO_AN_STAT1_XNP 0x0080 /* Extended next page status */ + +/* Speed register. */ +#define MDIO_SPEED_10G 0x0001 /* 10G capable */ +#define MDIO_PMA_SPEED_2B 0x0002 /* 2BASE-TL capable */ +#define MDIO_PMA_SPEED_10P 0x0004 /* 10PASS-TS capable */ +#define MDIO_PMA_SPEED_1000 0x0010 /* 1000M capable */ +#define MDIO_PMA_SPEED_100 0x0020 /* 100M capable */ +#define MDIO_PMA_SPEED_10 0x0040 /* 10M capable */ +#define MDIO_PCS_SPEED_10P2B 0x0002 /* 10PASS-TS/2BASE-TL capable */ + +/* Device present registers. */ +#define MDIO_DEVS_PRESENT(devad) (1 << (devad)) +#define MDIO_DEVS_PMAPMD MDIO_DEVS_PRESENT(MDIO_MMD_PMAPMD) +#define MDIO_DEVS_WIS MDIO_DEVS_PRESENT(MDIO_MMD_WIS) +#define MDIO_DEVS_PCS MDIO_DEVS_PRESENT(MDIO_MMD_PCS) +#define MDIO_DEVS_PHYXS MDIO_DEVS_PRESENT(MDIO_MMD_PHYXS) +#define MDIO_DEVS_DTEXS MDIO_DEVS_PRESENT(MDIO_MMD_DTEXS) +#define MDIO_DEVS_TC MDIO_DEVS_PRESENT(MDIO_MMD_TC) +#define MDIO_DEVS_AN MDIO_DEVS_PRESENT(MDIO_MMD_AN) +#define MDIO_DEVS_C22EXT MDIO_DEVS_PRESENT(MDIO_MMD_C22EXT) + +/* Control register 2. */ +#define MDIO_PMA_CTRL2_TYPE 0x000f /* PMA/PMD type selection */ +#define MDIO_PMA_CTRL2_10GBCX4 0x0000 /* 10GBASE-CX4 type */ +#define MDIO_PMA_CTRL2_10GBEW 0x0001 /* 10GBASE-EW type */ +#define MDIO_PMA_CTRL2_10GBLW 0x0002 /* 10GBASE-LW type */ +#define MDIO_PMA_CTRL2_10GBSW 0x0003 /* 10GBASE-SW type */ +#define MDIO_PMA_CTRL2_10GBLX4 0x0004 /* 10GBASE-LX4 type */ +#define MDIO_PMA_CTRL2_10GBER 0x0005 /* 10GBASE-ER type */ +#define MDIO_PMA_CTRL2_10GBLR 0x0006 /* 10GBASE-LR type */ +#define MDIO_PMA_CTRL2_10GBSR 0x0007 /* 10GBASE-SR type */ +#define MDIO_PMA_CTRL2_10GBLRM 0x0008 /* 10GBASE-LRM type */ +#define MDIO_PMA_CTRL2_10GBT 0x0009 /* 10GBASE-T type */ +#define MDIO_PMA_CTRL2_10GBKX4 0x000a /* 10GBASE-KX4 type */ +#define MDIO_PMA_CTRL2_10GBKR 0x000b /* 10GBASE-KR type */ +#define MDIO_PMA_CTRL2_1000BT 0x000c /* 1000BASE-T type */ +#define MDIO_PMA_CTRL2_1000BKX 0x000d /* 1000BASE-KX type */ +#define MDIO_PMA_CTRL2_100BTX 0x000e /* 100BASE-TX type */ +#define MDIO_PMA_CTRL2_10BT 0x000f /* 10BASE-T type */ +#define MDIO_PCS_CTRL2_TYPE 0x0003 /* PCS type selection */ +#define MDIO_PCS_CTRL2_10GBR 0x0000 /* 10GBASE-R type */ +#define MDIO_PCS_CTRL2_10GBX 0x0001 /* 10GBASE-X type */ +#define MDIO_PCS_CTRL2_10GBW 0x0002 /* 10GBASE-W type */ +#define MDIO_PCS_CTRL2_10GBT 0x0003 /* 10GBASE-T type */ + +/* Status register 2. */ +#define MDIO_STAT2_RXFAULT 0x0400 /* Receive fault */ +#define MDIO_STAT2_TXFAULT 0x0800 /* Transmit fault */ +#define MDIO_STAT2_DEVPRST 0xc000 /* Device present */ +#define MDIO_STAT2_DEVPRST_VAL 0x8000 /* Device present value */ +#define MDIO_PMA_STAT2_LBABLE 0x0001 /* PMA loopback ability */ +#define MDIO_PMA_STAT2_10GBEW 0x0002 /* 10GBASE-EW ability */ +#define MDIO_PMA_STAT2_10GBLW 0x0004 /* 10GBASE-LW ability */ +#define MDIO_PMA_STAT2_10GBSW 0x0008 /* 10GBASE-SW ability */ +#define MDIO_PMA_STAT2_10GBLX4 0x0010 /* 10GBASE-LX4 ability */ +#define MDIO_PMA_STAT2_10GBER 0x0020 /* 10GBASE-ER ability */ +#define MDIO_PMA_STAT2_10GBLR 0x0040 /* 10GBASE-LR ability */ +#define MDIO_PMA_STAT2_10GBSR 0x0080 /* 10GBASE-SR ability */ +#define MDIO_PMD_STAT2_TXDISAB 0x0100 /* PMD TX disable ability */ +#define MDIO_PMA_STAT2_EXTABLE 0x0200 /* Extended abilities */ +#define MDIO_PMA_STAT2_RXFLTABLE 0x1000 /* Receive fault ability */ +#define MDIO_PMA_STAT2_TXFLTABLE 0x2000 /* Transmit fault ability */ +#define MDIO_PCS_STAT2_10GBR 0x0001 /* 10GBASE-R capable */ +#define MDIO_PCS_STAT2_10GBX 0x0002 /* 10GBASE-X capable */ +#define MDIO_PCS_STAT2_10GBW 0x0004 /* 10GBASE-W capable */ +#define MDIO_PCS_STAT2_RXFLTABLE 0x1000 /* Receive fault ability */ +#define MDIO_PCS_STAT2_TXFLTABLE 0x2000 /* Transmit fault ability */ + +/* Transmit disable register. */ +#define MDIO_PMD_TXDIS_GLOBAL 0x0001 /* Global PMD TX disable */ +#define MDIO_PMD_TXDIS_0 0x0002 /* PMD TX disable 0 */ +#define MDIO_PMD_TXDIS_1 0x0004 /* PMD TX disable 1 */ +#define MDIO_PMD_TXDIS_2 0x0008 /* PMD TX disable 2 */ +#define MDIO_PMD_TXDIS_3 0x0010 /* PMD TX disable 3 */ + +/* Receive signal detect register. */ +#define MDIO_PMD_RXDET_GLOBAL 0x0001 /* Global PMD RX signal detect */ +#define MDIO_PMD_RXDET_0 0x0002 /* PMD RX signal detect 0 */ +#define MDIO_PMD_RXDET_1 0x0004 /* PMD RX signal detect 1 */ +#define MDIO_PMD_RXDET_2 0x0008 /* PMD RX signal detect 2 */ +#define MDIO_PMD_RXDET_3 0x0010 /* PMD RX signal detect 3 */ + +/* Extended abilities register. */ +#define MDIO_PMA_EXTABLE_10GCX4 0x0001 /* 10GBASE-CX4 ability */ +#define MDIO_PMA_EXTABLE_10GBLRM 0x0002 /* 10GBASE-LRM ability */ +#define MDIO_PMA_EXTABLE_10GBT 0x0004 /* 10GBASE-T ability */ +#define MDIO_PMA_EXTABLE_10GBKX4 0x0008 /* 10GBASE-KX4 ability */ +#define MDIO_PMA_EXTABLE_10GBKR 0x0010 /* 10GBASE-KR ability */ +#define MDIO_PMA_EXTABLE_1000BT 0x0020 /* 1000BASE-T ability */ +#define MDIO_PMA_EXTABLE_1000BKX 0x0040 /* 1000BASE-KX ability */ +#define MDIO_PMA_EXTABLE_100BTX 0x0080 /* 100BASE-TX ability */ +#define MDIO_PMA_EXTABLE_10BT 0x0100 /* 10BASE-T ability */ + +/* PHY XGXS lane state register. */ +#define MDIO_PHYXS_LNSTAT_SYNC0 0x0001 +#define MDIO_PHYXS_LNSTAT_SYNC1 0x0002 +#define MDIO_PHYXS_LNSTAT_SYNC2 0x0004 +#define MDIO_PHYXS_LNSTAT_SYNC3 0x0008 +#define MDIO_PHYXS_LNSTAT_ALIGN 0x1000 + +/* PMA 10GBASE-T TX power register. */ +#define MDIO_PMA_10GBT_TXPWR_SHORT 0x0001 /* Short-reach mode */ + +/* PCS 10GBASE-R/-T status register 1. */ +#define MDIO_PCS_10GBRT_STAT1_BLKLK 0x0001 /* Block lock attained */ + +/* PCS 10GBASE-R/-T status register 2. */ +#define MDIO_PCS_10GBRT_STAT2_ERR 0x00ff +#define MDIO_PCS_10GBRT_STAT2_BER 0x3f00 + +/* AN 10GBASE-T control register. */ +#define MDIO_AN_10GBT_CTRL_ADV10G 0x1000 /* Advertise 10GBASE-T */ + +/* AN 10GBASE-T status register. */ +#define MDIO_AN_10GBT_STAT_LPTRR 0x0200 /* LP training reset req. */ +#define MDIO_AN_10GBT_STAT_LPLTABLE 0x0400 /* LP loop timing ability */ +#define MDIO_AN_10GBT_STAT_LP10G 0x0800 /* LP is 10GBT capable */ +#define MDIO_AN_10GBT_STAT_REMOK 0x1000 /* Remote OK */ +#define MDIO_AN_10GBT_STAT_LOCOK 0x2000 /* Local OK */ +#define MDIO_AN_10GBT_STAT_MS 0x4000 /* Master/slave config */ +#define MDIO_AN_10GBT_STAT_MSFLT 0x8000 /* Master/slave config fault */ + +/* Mapping between MDIO PRTAD/DEVAD and mii_ioctl_data::phy_id */ + +#define MDIO_PHY_ID_C45 0x8000 +#define MDIO_PHY_ID_PRTAD 0x03e0 +#define MDIO_PHY_ID_DEVAD 0x001f +#define MDIO_PHY_ID_C45_MASK \ + (MDIO_PHY_ID_C45 | MDIO_PHY_ID_PRTAD | MDIO_PHY_ID_DEVAD) + +static inline __u16 mdio_phy_id_c45(int prtad, int devad) +{ + return MDIO_PHY_ID_C45 | (prtad << 5) | devad; +} + +static inline bool mdio_phy_id_is_c45(int phy_id) +{ + return (phy_id & MDIO_PHY_ID_C45) && !(phy_id & ~MDIO_PHY_ID_C45_MASK); +} + +static inline __u16 mdio_phy_id_prtad(int phy_id) +{ + return (phy_id & MDIO_PHY_ID_PRTAD) >> 5; +} + +static inline __u16 mdio_phy_id_devad(int phy_id) +{ + return phy_id & MDIO_PHY_ID_DEVAD; +} + +#endif /* __LINUX_MDIO_H__ */ -- GitLab From 1b1c2e95103ce391c2ea39a9460968fcb73deb30 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:04:46 +0000 Subject: [PATCH 0920/6080] mdio: Add generic MDIO (clause 45) support functions These roughly mirror many of the MII library functions and are based on code from the sfc driver. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/Kconfig | 3 + drivers/net/Makefile | 1 + drivers/net/mdio.c | 359 +++++++++++++++++++++++++++++++++++++++++++ include/linux/mdio.h | 66 ++++++++ 4 files changed, 429 insertions(+) create mode 100644 drivers/net/mdio.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index bc7eef12d955..2f81db51b45d 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2443,6 +2443,9 @@ menuconfig NETDEV_10000 if NETDEV_10000 +config MDIO + tristate + config CHELSIO_T1 tristate "Chelsio 10Gb Ethernet support" depends on PCI diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 80420f6d0795..dcd5f15dd9e3 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -95,6 +95,7 @@ obj-$(CONFIG_SH_ETH) += sh_eth.o # obj-$(CONFIG_MII) += mii.o +obj-$(CONFIG_MDIO) += mdio.o obj-$(CONFIG_PHYLIB) += phy/ obj-$(CONFIG_SUNDANCE) += sundance.o diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c new file mode 100644 index 000000000000..0604a25748ee --- /dev/null +++ b/drivers/net/mdio.c @@ -0,0 +1,359 @@ +/* + * mdio.c: Generic support for MDIO-compatible transceivers + * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference. + */ + +#include +#include +#include +#include +#include +#include + +/** + * mdio45_probe - probe for an MDIO (clause 45) device + * @mdio: MDIO interface + * @prtad: Expected PHY address + * + * This sets @prtad and @mmds in the MDIO interface if successful. + * Returns 0 on success, negative on error. + */ +int mdio45_probe(struct mdio_if_info *mdio, int prtad) +{ + int mmd, stat2, devs1, devs2; + + /* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY + * XS or DTE XS; give up if none is present. */ + for (mmd = 1; mmd <= 5; mmd++) { + /* Is this MMD present? */ + stat2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_STAT2); + if (stat2 < 0 || + (stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) + continue; + + /* It should tell us about all the other MMDs */ + devs1 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS1); + devs2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS2); + if (devs1 < 0 || devs2 < 0) + continue; + + mdio->prtad = prtad; + mdio->mmds = devs1 | (devs2 << 16); + return 0; + } + + return -ENODEV; +} +EXPORT_SYMBOL(mdio45_probe); + +/** + * mdio_set_flag - set or clear flag in an MDIO register + * @mdio: MDIO interface + * @prtad: PHY address + * @devad: MMD address + * @addr: Register address + * @mask: Mask for flag (single bit set) + * @sense: New value of flag + * + * This debounces changes: it does not write the register if the flag + * already has the proper value. Returns 0 on success, negative on error. + */ +int mdio_set_flag(const struct mdio_if_info *mdio, + int prtad, int devad, u16 addr, int mask, + bool sense) +{ + int old_val = mdio->mdio_read(mdio->dev, prtad, devad, addr); + int new_val; + + if (old_val < 0) + return old_val; + if (sense) + new_val = old_val | mask; + else + new_val = old_val & ~mask; + if (old_val == new_val) + return 0; + return mdio->mdio_write(mdio->dev, prtad, devad, addr, new_val); +} +EXPORT_SYMBOL(mdio_set_flag); + +/** + * mdio_link_ok - is link status up/OK + * @mdio: MDIO interface + * @mmd_mask: Mask for MMDs to check + * + * Returns 1 if the PHY reports link status up/OK, 0 otherwise. + * @mmd_mask is normally @mdio->mmds, but if loopback is enabled + * the MMDs being bypassed should be excluded from the mask. + */ +int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmd_mask) +{ + int devad, reg; + + if (!mmd_mask) { + /* Use absence of XGMII faults in lieu of link state */ + reg = mdio->mdio_read(mdio->dev, mdio->prtad, + MDIO_MMD_PHYXS, MDIO_STAT2); + return reg >= 0 && !(reg & MDIO_STAT2_RXFAULT); + } + + for (devad = 0; mmd_mask; devad++) { + if (mmd_mask & (1 << devad)) { + mmd_mask &= ~(1 << devad); + + /* Read twice because link state is latched and a + * read moves the current state into the register */ + mdio->mdio_read(mdio->dev, mdio->prtad, + devad, MDIO_STAT1); + reg = mdio->mdio_read(mdio->dev, mdio->prtad, + devad, MDIO_STAT1); + if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS)) + return false; + } + } + + return true; +} +EXPORT_SYMBOL(mdio45_links_ok); + +/** + * mdio45_nway_restart - restart auto-negotiation for this interface + * @mdio: MDIO interface + * + * Returns 0 on success, negative on error. + */ +int mdio45_nway_restart(const struct mdio_if_info *mdio) +{ + if (!(mdio->mmds & MDIO_DEVS_AN)) + return -EOPNOTSUPP; + + mdio_set_flag(mdio, mdio->prtad, MDIO_MMD_AN, MDIO_CTRL1, + MDIO_AN_CTRL1_RESTART, true); + return 0; +} +EXPORT_SYMBOL(mdio45_nway_restart); + +static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr) +{ + u32 result = 0; + int reg; + + reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, addr); + if (reg & ADVERTISE_10HALF) + result |= ADVERTISED_10baseT_Half; + if (reg & ADVERTISE_10FULL) + result |= ADVERTISED_10baseT_Full; + if (reg & ADVERTISE_100HALF) + result |= ADVERTISED_100baseT_Half; + if (reg & ADVERTISE_100FULL) + result |= ADVERTISED_100baseT_Full; + return result; +} + +/** + * mdio45_ethtool_gset_npage - get settings for ETHTOOL_GSET + * @mdio: MDIO interface + * @ecmd: Ethtool request structure + * @npage_adv: Modes currently advertised on next pages + * @npage_lpa: Modes advertised by link partner on next pages + * + * Since the CSRs for auto-negotiation using next pages are not fully + * standardised, this function does not attempt to decode them. The + * caller must pass them in. + */ +void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, + struct ethtool_cmd *ecmd, + u32 npage_adv, u32 npage_lpa) +{ + int reg; + + ecmd->transceiver = XCVR_INTERNAL; + ecmd->phy_address = mdio->prtad; + + reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, + MDIO_CTRL2); + switch (reg & MDIO_PMA_CTRL2_TYPE) { + case MDIO_PMA_CTRL2_10GBT: + case MDIO_PMA_CTRL2_1000BT: + case MDIO_PMA_CTRL2_100BTX: + case MDIO_PMA_CTRL2_10BT: + ecmd->port = PORT_TP; + ecmd->supported = SUPPORTED_TP; + reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, + MDIO_SPEED); + if (reg & MDIO_SPEED_10G) + ecmd->supported |= SUPPORTED_10000baseT_Full; + if (reg & MDIO_PMA_SPEED_1000) + ecmd->supported |= (SUPPORTED_1000baseT_Full | + SUPPORTED_1000baseT_Half); + if (reg & MDIO_PMA_SPEED_100) + ecmd->supported |= (SUPPORTED_100baseT_Full | + SUPPORTED_100baseT_Half); + if (reg & MDIO_PMA_SPEED_10) + ecmd->supported |= (SUPPORTED_10baseT_Full | + SUPPORTED_10baseT_Half); + ecmd->advertising = ADVERTISED_TP; + break; + + case MDIO_PMA_CTRL2_10GBCX4: + case MDIO_PMA_CTRL2_10GBKX4: + case MDIO_PMA_CTRL2_10GBKR: + case MDIO_PMA_CTRL2_1000BKX: + ecmd->port = PORT_OTHER; + ecmd->supported = 0; + ecmd->advertising = 0; + break; + + /* All the other defined modes are flavours of optical */ + default: + ecmd->port = PORT_FIBRE; + ecmd->supported = SUPPORTED_FIBRE; + ecmd->advertising = ADVERTISED_FIBRE; + break; + } + + if (mdio->mmds & MDIO_DEVS_AN) { + ecmd->supported |= SUPPORTED_Autoneg; + reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, + MDIO_CTRL1); + if (reg & MDIO_AN_CTRL1_ENABLE) { + ecmd->autoneg = AUTONEG_ENABLE; + ecmd->advertising |= + ADVERTISED_Autoneg | + mdio45_get_an(mdio, MDIO_AN_ADVERTISE) | + npage_adv; + } else { + ecmd->autoneg = AUTONEG_DISABLE; + } + } else { + ecmd->autoneg = AUTONEG_DISABLE; + } + + if (ecmd->autoneg) { + u32 modes = 0; + + /* If AN is complete and successful, report best common + * mode, otherwise report best advertised mode. */ + if (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, + MDIO_STAT1) & + MDIO_AN_STAT1_COMPLETE) + modes = (ecmd->advertising & + (mdio45_get_an(mdio, MDIO_AN_LPA) | + npage_lpa)); + if (modes == 0) + modes = ecmd->advertising; + + if (modes & ADVERTISED_10000baseT_Full) { + ecmd->speed = SPEED_10000; + ecmd->duplex = DUPLEX_FULL; + } else if (modes & (ADVERTISED_1000baseT_Full | + ADVERTISED_1000baseT_Half)) { + ecmd->speed = SPEED_1000; + ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full); + } else if (modes & (ADVERTISED_100baseT_Full | + ADVERTISED_100baseT_Half)) { + ecmd->speed = SPEED_100; + ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); + } else { + ecmd->speed = SPEED_10; + ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); + } + } else { + /* Report forced settings */ + reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, + MDIO_CTRL1); + ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) * + ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10)); + ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX || + ecmd->speed == SPEED_10000); + } +} +EXPORT_SYMBOL(mdio45_ethtool_gset_npage); + +/** + * mdio_mii_ioctl - MII ioctl interface for MDIO (clause 22 or 45) PHYs + * @mdio: MDIO interface + * @mii_data: MII ioctl data structure + * @cmd: MII ioctl command + * + * Returns 0 on success, negative on error. + */ +int mdio_mii_ioctl(const struct mdio_if_info *mdio, + struct mii_ioctl_data *mii_data, int cmd) +{ + int prtad, devad; + u16 addr = mii_data->reg_num; + + /* Validate/convert cmd to one of SIOC{G,S}MIIREG */ + switch (cmd) { + case SIOCGMIIPHY: + if (mdio->prtad == MDIO_PRTAD_NONE) + return -EOPNOTSUPP; + mii_data->phy_id = mdio->prtad; + cmd = SIOCGMIIREG; + break; + case SIOCGMIIREG: + break; + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + break; + default: + return -EOPNOTSUPP; + } + + /* Validate/convert phy_id */ + if ((mdio->mode_support & MDIO_SUPPORTS_C45) && + mdio_phy_id_is_c45(mii_data->phy_id)) { + prtad = mdio_phy_id_prtad(mii_data->phy_id); + devad = mdio_phy_id_devad(mii_data->phy_id); + } else if ((mdio->mode_support & MDIO_SUPPORTS_C22) && + mii_data->phy_id < 0x20) { + prtad = mii_data->phy_id; + devad = MDIO_DEVAD_NONE; + addr &= 0x1f; + } else if ((mdio->mode_support & MDIO_EMULATE_C22) && + mdio->prtad != MDIO_PRTAD_NONE && + mii_data->phy_id == mdio->prtad) { + /* Remap commonly-used MII registers. */ + prtad = mdio->prtad; + switch (addr) { + case MII_BMCR: + case MII_BMSR: + case MII_PHYSID1: + case MII_PHYSID2: + devad = __ffs(mdio->mmds); + break; + case MII_ADVERTISE: + case MII_LPA: + if (!(mdio->mmds & MDIO_DEVS_AN)) + return -EINVAL; + devad = MDIO_MMD_AN; + if (addr == MII_ADVERTISE) + addr = MDIO_AN_ADVERTISE; + else + addr = MDIO_AN_LPA; + break; + default: + return -EINVAL; + } + } else { + return -EINVAL; + } + + if (cmd == SIOCGMIIREG) { + int rc = mdio->mdio_read(mdio->dev, prtad, devad, addr); + if (rc < 0) + return rc; + mii_data->val_out = rc; + return 0; + } else { + return mdio->mdio_write(mdio->dev, prtad, devad, addr, + mii_data->val_in); + } +} +EXPORT_SYMBOL(mdio_mii_ioctl); diff --git a/include/linux/mdio.h b/include/linux/mdio.h index d57ddb08a1b2..ba41537eaa8a 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -234,4 +234,70 @@ static inline __u16 mdio_phy_id_devad(int phy_id) return phy_id & MDIO_PHY_ID_DEVAD; } +#ifdef __KERNEL__ + +/** + * struct mdio_if_info - Ethernet controller MDIO interface + * @prtad: PRTAD of the PHY (%MDIO_PRTAD_NONE if not present/unknown) + * @mmds: Mask of MMDs expected to be present in the PHY. This must be + * non-zero unless @prtad = %MDIO_PRTAD_NONE. + * @mode_support: MDIO modes supported. If %MDIO_SUPPORTS_C22 is set then + * MII register access will be passed through with @devad = + * %MDIO_DEVAD_NONE. If %MDIO_EMULATE_C22 is set then access to + * commonly used clause 22 registers will be translated into + * clause 45 registers. + * @dev: Net device structure + * @mdio_read: Register read function; returns value or negative error code + * @mdio_write: Register write function; returns 0 or negative error code + */ +struct mdio_if_info { + int prtad; + u32 __bitwise mmds; + unsigned mode_support; + + struct net_device *dev; + int (*mdio_read)(struct net_device *dev, int prtad, int devad, + u16 addr); + int (*mdio_write)(struct net_device *dev, int prtad, int devad, + u16 addr, u16 val); +}; + +#define MDIO_PRTAD_NONE (-1) +#define MDIO_DEVAD_NONE (-1) +#define MDIO_SUPPORTS_C22 1 +#define MDIO_SUPPORTS_C45 2 +#define MDIO_EMULATE_C22 4 + +struct ethtool_cmd; +struct ethtool_pauseparam; +extern int mdio45_probe(struct mdio_if_info *mdio, int prtad); +extern int mdio_set_flag(const struct mdio_if_info *mdio, + int prtad, int devad, u16 addr, int mask, + bool sense); +extern int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmds); +extern int mdio45_nway_restart(const struct mdio_if_info *mdio); +extern void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, + struct ethtool_cmd *ecmd, + u32 npage_adv, u32 npage_lpa); + +/** + * mdio45_ethtool_gset - get settings for ETHTOOL_GSET + * @mdio: MDIO interface + * @ecmd: Ethtool request structure + * + * Since the CSRs for auto-negotiation using next pages are not fully + * standardised, this function does not attempt to decode them. Use + * mdio45_ethtool_gset_npage() to specify advertisement bits from next + * pages. + */ +static inline void mdio45_ethtool_gset(const struct mdio_if_info *mdio, + struct ethtool_cmd *ecmd) +{ + mdio45_ethtool_gset_npage(mdio, ecmd, 0, 0); +} + +extern int mdio_mii_ioctl(const struct mdio_if_info *mdio, + struct mii_ioctl_data *mii_data, int cmd); + +#endif /* __KERNEL__ */ #endif /* __LINUX_MDIO_H__ */ -- GitLab From 68e7f45e118f98b77cfa007aa2d97b5dac69fe6b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:05:08 +0000 Subject: [PATCH 0921/6080] sfc: Use generic MDIO functions and definitions Make use of the newly-added generic MDIO clause 45 support and remove redundant definitions. Add an 'efx_' prefix to the remaining driver-specific MDIO functions and remove arguments which are redundant with efx->mdio.prtad. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/Kconfig | 2 +- drivers/net/sfc/efx.c | 10 +- drivers/net/sfc/ethtool.c | 18 +- drivers/net/sfc/falcon.c | 137 ++++-------- drivers/net/sfc/falcon_hwdefs.h | 3 - drivers/net/sfc/falcon_xmac.c | 2 +- drivers/net/sfc/mdio_10g.c | 379 +++++++------------------------- drivers/net/sfc/mdio_10g.h | 281 ++++------------------- drivers/net/sfc/net_driver.h | 8 +- drivers/net/sfc/selftest.c | 21 +- drivers/net/sfc/selftest.h | 2 +- drivers/net/sfc/tenxpress.c | 227 ++++++++----------- drivers/net/sfc/xenpack.h | 15 +- drivers/net/sfc/xfp_phy.c | 51 +++-- 14 files changed, 311 insertions(+), 845 deletions(-) diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig index 12a82966b577..260aafaac235 100644 --- a/drivers/net/sfc/Kconfig +++ b/drivers/net/sfc/Kconfig @@ -1,7 +1,7 @@ config SFC tristate "Solarflare Solarstorm SFC4000 support" depends on PCI && INET - select MII + select MDIO select CRC32 select I2C select I2C_ALGOBIT diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 7269a426051c..d3e240b736c7 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1300,10 +1300,16 @@ out_requeue: static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) { struct efx_nic *efx = netdev_priv(net_dev); + struct mii_ioctl_data *data = if_mii(ifr); EFX_ASSERT_RESET_SERIALISED(efx); - return generic_mii_ioctl(&efx->mii, if_mii(ifr), cmd, NULL); + /* Convert phy_id from older PRTAD/DEVAD format */ + if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) && + (data->phy_id & 0xfc00) == 0x0400) + data->phy_id ^= MDIO_PHY_ID_C45 | 0x0400; + + return mdio_mii_ioctl(&efx->mdio, data, cmd); } /************************************************************************** @@ -1945,7 +1951,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, mutex_init(&efx->mac_lock); efx->mac_op = &efx_dummy_mac_operations; efx->phy_op = &efx_dummy_phy_operations; - efx->mii.dev = net_dev; + efx->mdio.dev = net_dev; INIT_WORK(&efx->phy_work, efx_phy_work); INIT_WORK(&efx->mac_work, efx_mac_work); atomic_set(&efx->netif_stop_count, 1); diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 64309f4e8b19..1c7b6849fe01 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -10,6 +10,7 @@ #include #include +#include #include #include "net_driver.h" #include "workarounds.h" @@ -345,8 +346,8 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, unsigned int n = 0, i; enum efx_loopback_mode mode; - efx_fill_test(n++, strings, data, &tests->mii, - "core", 0, "mii", NULL); + efx_fill_test(n++, strings, data, &tests->mdio, + "core", 0, "mdio", NULL); efx_fill_test(n++, strings, data, &tests->nvram, "core", 0, "nvram", NULL); efx_fill_test(n++, strings, data, &tests->interrupt, @@ -529,14 +530,7 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev) { struct efx_nic *efx = netdev_priv(net_dev); - if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) { - mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN, - MDIO_MMDREG_CTRL1, - __ffs(BMCR_ANRESTART), true); - return 0; - } - - return -EOPNOTSUPP; + return mdio45_nway_restart(&efx->mdio); } static u32 efx_ethtool_get_link(struct net_device *net_dev) @@ -689,7 +683,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, return -EINVAL; } - if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) && + if (!(efx->phy_op->mmds & MDIO_DEVS_AN) && (wanted_fc & EFX_FC_AUTO)) { EFX_LOG(efx, "PHY does not support flow control " "autonegotiation\n"); @@ -717,7 +711,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, mutex_lock(&efx->mac_lock); efx->wanted_fc = wanted_fc; - mdio_clause45_set_pause(efx); + efx_mdio_set_pause(efx); __efx_reconfigure_port(efx); mutex_unlock(&efx->mac_lock); diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 466a8abb0053..c049364aec46 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -2063,26 +2063,6 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) ************************************************************************** */ -/* Use the top bit of the MII PHY id to indicate the PHY type - * (1G/10G), with the remaining bits as the actual PHY id. - * - * This allows us to avoid leaking information from the mii_if_info - * structure into other data structures. - */ -#define FALCON_PHY_ID_ID_WIDTH EFX_WIDTH(MD_PRT_DEV_ADR) -#define FALCON_PHY_ID_ID_MASK ((1 << FALCON_PHY_ID_ID_WIDTH) - 1) -#define FALCON_PHY_ID_WIDTH (FALCON_PHY_ID_ID_WIDTH + 1) -#define FALCON_PHY_ID_MASK ((1 << FALCON_PHY_ID_WIDTH) - 1) -#define FALCON_PHY_ID_10G (1 << (FALCON_PHY_ID_WIDTH - 1)) - - -/* Packing the clause 45 port and device fields into a single value */ -#define MD_PRT_ADR_COMP_LBN (MD_PRT_ADR_LBN - MD_DEV_ADR_LBN) -#define MD_PRT_ADR_COMP_WIDTH MD_PRT_ADR_WIDTH -#define MD_DEV_ADR_COMP_LBN 0 -#define MD_DEV_ADR_COMP_WIDTH MD_DEV_ADR_WIDTH - - /* Wait for GMII access to complete */ static int falcon_gmii_wait(struct efx_nic *efx) { @@ -2108,49 +2088,29 @@ static int falcon_gmii_wait(struct efx_nic *efx) return -ETIMEDOUT; } -/* Writes a GMII register of a PHY connected to Falcon using MDIO. */ -static void falcon_mdio_write(struct net_device *net_dev, int phy_id, - int addr, int value) +/* Write an MDIO register of a PHY connected to Falcon. */ +static int falcon_mdio_write(struct net_device *net_dev, + int prtad, int devad, u16 addr, u16 value) { struct efx_nic *efx = netdev_priv(net_dev); - unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK; efx_oword_t reg; + int rc; - /* The 'generic' prt/dev packing in mdio_10g.h is conveniently - * chosen so that the only current user, Falcon, can take the - * packed value and use them directly. - * Fail to build if this assumption is broken. - */ - BUILD_BUG_ON(FALCON_PHY_ID_10G != MDIO45_XPRT_ID_IS10G); - BUILD_BUG_ON(FALCON_PHY_ID_ID_WIDTH != MDIO45_PRT_DEV_WIDTH); - BUILD_BUG_ON(MD_PRT_ADR_COMP_LBN != MDIO45_PRT_ID_COMP_LBN); - BUILD_BUG_ON(MD_DEV_ADR_COMP_LBN != MDIO45_DEV_ID_COMP_LBN); - - if (phy_id2 == PHY_ADDR_INVALID) - return; - - /* See falcon_mdio_read for an explanation. */ - if (!(phy_id & FALCON_PHY_ID_10G)) { - int mmd = ffs(efx->phy_op->mmds) - 1; - EFX_TRACE(efx, "Fixing erroneous clause22 write\n"); - phy_id2 = mdio_clause45_pack(phy_id2, mmd) - & FALCON_PHY_ID_ID_MASK; - } - - EFX_REGDUMP(efx, "writing GMII %d register %02x with %04x\n", phy_id, - addr, value); + EFX_REGDUMP(efx, "writing MDIO %d register %d.%d with 0x%04x\n", + prtad, devad, addr, value); spin_lock_bh(&efx->phy_lock); - /* Check MII not currently being accessed */ - if (falcon_gmii_wait(efx) != 0) + /* Check MDIO not currently being accessed */ + rc = falcon_gmii_wait(efx); + if (rc) goto out; /* Write the address/ID register */ EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr); falcon_write(efx, ®, MD_PHY_ADR_REG_KER); - EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_id2); + EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad); falcon_write(efx, ®, MD_ID_REG_KER); /* Write data */ @@ -2163,7 +2123,8 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id, falcon_write(efx, ®, MD_CS_REG_KER); /* Wait for data to be written */ - if (falcon_gmii_wait(efx) != 0) { + rc = falcon_gmii_wait(efx); + if (rc) { /* Abort the write operation */ EFX_POPULATE_OWORD_2(reg, MD_WRC, 0, @@ -2174,45 +2135,28 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id, out: spin_unlock_bh(&efx->phy_lock); + return rc; } -/* Reads a GMII register from a PHY connected to Falcon. If no value - * could be read, -1 will be returned. */ -static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr) +/* Read an MDIO register of a PHY connected to Falcon. */ +static int falcon_mdio_read(struct net_device *net_dev, + int prtad, int devad, u16 addr) { struct efx_nic *efx = netdev_priv(net_dev); - unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK; efx_oword_t reg; - int value = -1; - - if (phy_addr == PHY_ADDR_INVALID) - return -1; - - /* Our PHY code knows whether it needs to talk clause 22(1G) or 45(10G) - * but the generic Linux code does not make any distinction or have - * any state for this. - * We spot the case where someone tried to talk 22 to a 45 PHY and - * redirect the request to the lowest numbered MMD as a clause45 - * request. This is enough to allow simple queries like id and link - * state to succeed. TODO: We may need to do more in future. - */ - if (!(phy_id & FALCON_PHY_ID_10G)) { - int mmd = ffs(efx->phy_op->mmds) - 1; - EFX_TRACE(efx, "Fixing erroneous clause22 read\n"); - phy_addr = mdio_clause45_pack(phy_addr, mmd) - & FALCON_PHY_ID_ID_MASK; - } + int rc; spin_lock_bh(&efx->phy_lock); - /* Check MII not currently being accessed */ - if (falcon_gmii_wait(efx) != 0) + /* Check MDIO not currently being accessed */ + rc = falcon_gmii_wait(efx); + if (rc) goto out; EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr); falcon_write(efx, ®, MD_PHY_ADR_REG_KER); - EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_addr); + EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad); falcon_write(efx, ®, MD_ID_REG_KER); /* Request data to be read */ @@ -2220,12 +2164,12 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr) falcon_write(efx, ®, MD_CS_REG_KER); /* Wait for data to become available */ - value = falcon_gmii_wait(efx); - if (value == 0) { + rc = falcon_gmii_wait(efx); + if (rc == 0) { falcon_read(efx, ®, MD_RXD_REG_KER); - value = EFX_OWORD_FIELD(reg, MD_RXD); - EFX_REGDUMP(efx, "read from GMII %d register %02x, got %04x\n", - phy_id, addr, value); + rc = EFX_OWORD_FIELD(reg, MD_RXD); + EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n", + prtad, devad, addr, rc); } else { /* Abort the read operation */ EFX_POPULATE_OWORD_2(reg, @@ -2233,22 +2177,13 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr) MD_GC, 1); falcon_write(efx, ®, MD_CS_REG_KER); - EFX_LOG(efx, "read from GMII 0x%x register %02x, got " - "error %d\n", phy_id, addr, value); + EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n", + prtad, devad, addr, rc); } out: spin_unlock_bh(&efx->phy_lock); - - return value; -} - -static void falcon_init_mdio(struct mii_if_info *gmii) -{ - gmii->mdio_read = falcon_mdio_read; - gmii->mdio_write = falcon_mdio_write; - gmii->phy_id_mask = FALCON_PHY_ID_MASK; - gmii->reg_num_mask = ((1 << EFX_WIDTH(MD_PHY_ADR)) - 1); + return rc; } static int falcon_probe_phy(struct efx_nic *efx) @@ -2342,9 +2277,11 @@ int falcon_probe_port(struct efx_nic *efx) if (rc) return rc; - /* Set up GMII structure for PHY */ - efx->mii.supports_gmii = true; - falcon_init_mdio(&efx->mii); + /* Set up MDIO structure for PHY */ + efx->mdio.mmds = efx->phy_op->mmds; + efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + efx->mdio.mdio_read = falcon_mdio_read; + efx->mdio.mdio_write = falcon_mdio_write; /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */ if (falcon_rev(efx) >= FALCON_REV_B0) @@ -2761,7 +2698,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) if (rc == -EINVAL) { EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n"); efx->phy_type = PHY_TYPE_NONE; - efx->mii.phy_id = PHY_ADDR_INVALID; + efx->mdio.prtad = MDIO_PRTAD_NONE; board_rev = 0; rc = 0; } else if (rc) { @@ -2771,7 +2708,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3; efx->phy_type = v2->port0_phy_type; - efx->mii.phy_id = v2->port0_phy_addr; + efx->mdio.prtad = v2->port0_phy_addr; board_rev = le16_to_cpu(v2->board_revision); if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) { @@ -2793,7 +2730,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx) /* Read the MAC addresses */ memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN); - EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mii.phy_id); + EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad); efx_set_board_info(efx, board_rev); diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h index bda8d5bb72e4..375e2a5961ec 100644 --- a/drivers/net/sfc/falcon_hwdefs.h +++ b/drivers/net/sfc/falcon_hwdefs.h @@ -456,9 +456,6 @@ #define MD_PRT_ADR_WIDTH 5 #define MD_DEV_ADR_LBN 6 #define MD_DEV_ADR_WIDTH 5 -/* Used for writing both at once */ -#define MD_PRT_DEV_ADR_LBN 6 -#define MD_PRT_DEV_ADR_WIDTH 10 /* PHY management status & mask register (DWORD read only) */ #define MD_STAT_REG_KER 0xc50 diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index 5a03713685ac..2b3269c03263 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -133,7 +133,7 @@ bool falcon_xaui_link_ok(struct efx_nic *efx) /* If the link is up, then check the phy side of the xaui link */ if (efx->link_up && link_ok) if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS)) - link_ok = mdio_clause45_phyxgxs_lane_sync(efx); + link_ok = efx_mdio_phyxgxs_lane_sync(efx); return link_ok; } diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 9f5ec3eb3418..11c231a1f875 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -17,7 +17,7 @@ #include "boards.h" #include "workarounds.h" -unsigned mdio_id_oui(u32 id) +unsigned efx_mdio_id_oui(u32 id) { unsigned oui = 0; int i; @@ -32,52 +32,45 @@ unsigned mdio_id_oui(u32 id) return oui; } -int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd, +int efx_mdio_reset_mmd(struct efx_nic *port, int mmd, int spins, int spintime) { u32 ctrl; - int phy_id = port->mii.phy_id; /* Catch callers passing values in the wrong units (or just silly) */ EFX_BUG_ON_PARANOID(spins * spintime >= 5000); - mdio_clause45_write(port, phy_id, mmd, MDIO_MMDREG_CTRL1, - (1 << MDIO_MMDREG_CTRL1_RESET_LBN)); + efx_mdio_write(port, mmd, MDIO_CTRL1, MDIO_CTRL1_RESET); /* Wait for the reset bit to clear. */ do { msleep(spintime); - ctrl = mdio_clause45_read(port, phy_id, mmd, MDIO_MMDREG_CTRL1); + ctrl = efx_mdio_read(port, mmd, MDIO_CTRL1); spins--; - } while (spins && (ctrl & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))); + } while (spins && (ctrl & MDIO_CTRL1_RESET)); return spins ? spins : -ETIMEDOUT; } -static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd, - int fault_fatal) +static int efx_mdio_check_mmd(struct efx_nic *efx, int mmd, int fault_fatal) { int status; - int phy_id = efx->mii.phy_id; if (LOOPBACK_INTERNAL(efx)) return 0; if (mmd != MDIO_MMD_AN) { /* Read MMD STATUS2 to check it is responding. */ - status = mdio_clause45_read(efx, phy_id, mmd, - MDIO_MMDREG_STAT2); - if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) & - ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) != - MDIO_MMDREG_STAT2_PRESENT_VAL) { + status = efx_mdio_read(efx, mmd, MDIO_STAT2); + if ((status & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) { EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd); return -EIO; } } /* Read MMD STATUS 1 to check for fault. */ - status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT1); - if ((status & (1 << MDIO_MMDREG_STAT1_FAULT_LBN)) != 0) { + status = efx_mdio_read(efx, mmd, MDIO_STAT1); + if (status & MDIO_STAT1_FAULT) { if (fault_fatal) { EFX_ERR(efx, "PHY MMD %d reporting fatal" " fault: status %x\n", mmd, status); @@ -94,8 +87,7 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd, #define MDIO45_RESET_TIME 1000 /* ms */ #define MDIO45_RESET_ITERS 100 -int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, - unsigned int mmd_mask) +int efx_mdio_wait_reset_mmds(struct efx_nic *efx, unsigned int mmd_mask) { const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS; int tries = MDIO45_RESET_ITERS; @@ -109,16 +101,13 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, in_reset = 0; while (mask) { if (mask & 1) { - stat = mdio_clause45_read(efx, - efx->mii.phy_id, - mmd, - MDIO_MMDREG_CTRL1); + stat = efx_mdio_read(efx, mmd, MDIO_CTRL1); if (stat < 0) { EFX_ERR(efx, "failed to read status of" " MMD %d\n", mmd); return -EIO; } - if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)) + if (stat & MDIO_CTRL1_RESET) in_reset |= (1 << mmd); } mask = mask >> 1; @@ -137,28 +126,26 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, return rc; } -int mdio_clause45_check_mmds(struct efx_nic *efx, - unsigned int mmd_mask, unsigned int fatal_mask) +int efx_mdio_check_mmds(struct efx_nic *efx, + unsigned int mmd_mask, unsigned int fatal_mask) { - int mmd = 0, probe_mmd, devs0, devs1; + int mmd = 0, probe_mmd, devs1, devs2; u32 devices; /* Historically we have probed the PHYXS to find out what devices are * present,but that doesn't work so well if the PHYXS isn't expected * to exist, if so just find the first item in the list supplied. */ - probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS : + probe_mmd = (mmd_mask & MDIO_DEVS_PHYXS) ? MDIO_MMD_PHYXS : __ffs(mmd_mask); /* Check all the expected MMDs are present */ - devs0 = mdio_clause45_read(efx, efx->mii.phy_id, - probe_mmd, MDIO_MMDREG_DEVS0); - devs1 = mdio_clause45_read(efx, efx->mii.phy_id, - probe_mmd, MDIO_MMDREG_DEVS1); - if (devs0 < 0 || devs1 < 0) { + devs1 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS1); + devs2 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS2); + if (devs1 < 0 || devs2 < 0) { EFX_ERR(efx, "failed to read devices present\n"); return -EIO; } - devices = devs0 | (devs1 << 16); + devices = devs1 | (devs2 << 16); if ((devices & mmd_mask) != mmd_mask) { EFX_ERR(efx, "required MMDs not present: got %x, " "wanted %x\n", devices, mmd_mask); @@ -170,7 +157,7 @@ int mdio_clause45_check_mmds(struct efx_nic *efx, while (mmd_mask) { if (mmd_mask & 1) { int fault_fatal = fatal_mask & 1; - if (mdio_clause45_check_mmd(efx, mmd, fault_fatal)) + if (efx_mdio_check_mmd(efx, mmd, fault_fatal)) return -EIO; } mmd_mask = mmd_mask >> 1; @@ -181,13 +168,8 @@ int mdio_clause45_check_mmds(struct efx_nic *efx, return 0; } -bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) +bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask) { - int phy_id = efx->mii.phy_id; - u32 reg; - bool ok = true; - int mmd = 0; - /* If the port is in loopback, then we should only consider a subset * of mmd's */ if (LOOPBACK_INTERNAL(efx)) @@ -197,241 +179,75 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) else if (efx_phy_mode_disabled(efx->phy_mode)) return false; else if (efx->loopback_mode == LOOPBACK_PHYXS) - mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | - MDIO_MMDREG_DEVS_PCS | - MDIO_MMDREG_DEVS_PMAPMD | - MDIO_MMDREG_DEVS_AN); + mmd_mask &= ~(MDIO_DEVS_PHYXS | + MDIO_DEVS_PCS | + MDIO_DEVS_PMAPMD | + MDIO_DEVS_AN); else if (efx->loopback_mode == LOOPBACK_PCS) - mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | - MDIO_MMDREG_DEVS_PMAPMD | - MDIO_MMDREG_DEVS_AN); + mmd_mask &= ~(MDIO_DEVS_PCS | + MDIO_DEVS_PMAPMD | + MDIO_DEVS_AN); else if (efx->loopback_mode == LOOPBACK_PMAPMD) - mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD | - MDIO_MMDREG_DEVS_AN); - - if (!mmd_mask) { - /* Use presence of XGMII faults in leui of link state */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS, - MDIO_PHYXS_STATUS2); - return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN)); - } + mmd_mask &= ~(MDIO_DEVS_PMAPMD | + MDIO_DEVS_AN); - while (mmd_mask) { - if (mmd_mask & 1) { - /* Double reads because link state is latched, and a - * read moves the current state into the register */ - reg = mdio_clause45_read(efx, phy_id, - mmd, MDIO_MMDREG_STAT1); - reg = mdio_clause45_read(efx, phy_id, - mmd, MDIO_MMDREG_STAT1); - ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN)); - } - mmd_mask = (mmd_mask >> 1); - mmd++; - } - return ok; + return mdio45_links_ok(&efx->mdio, mmd_mask); } -void mdio_clause45_transmit_disable(struct efx_nic *efx) +void efx_mdio_transmit_disable(struct efx_nic *efx) { - mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, - MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN, - efx->phy_mode & PHY_MODE_TX_DISABLED); + efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, + MDIO_PMA_TXDIS, MDIO_PMD_TXDIS_GLOBAL, + efx->phy_mode & PHY_MODE_TX_DISABLED); } -void mdio_clause45_phy_reconfigure(struct efx_nic *efx) +void efx_mdio_phy_reconfigure(struct efx_nic *efx) { - int phy_id = efx->mii.phy_id; - - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD, - MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN, - efx->loopback_mode == LOOPBACK_PMAPMD); - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS, - MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN, - efx->loopback_mode == LOOPBACK_PCS); - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS, - MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN, - efx->loopback_mode == LOOPBACK_NETWORK); + efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, + MDIO_CTRL1, MDIO_PMA_CTRL1_LOOPBACK, + efx->loopback_mode == LOOPBACK_PMAPMD); + efx_mdio_set_flag(efx, MDIO_MMD_PCS, + MDIO_CTRL1, MDIO_PCS_CTRL1_LOOPBACK, + efx->loopback_mode == LOOPBACK_PCS); + efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, + MDIO_CTRL1, MDIO_PHYXS_CTRL1_LOOPBACK, + efx->loopback_mode == LOOPBACK_NETWORK); } -static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx, - int lpower, int mmd) +static void efx_mdio_set_mmd_lpower(struct efx_nic *efx, + int lpower, int mmd) { - int phy = efx->mii.phy_id; - int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1); + int stat = efx_mdio_read(efx, mmd, MDIO_STAT1); EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n", mmd, lpower); - if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) { - mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1, - MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower); + if (stat & MDIO_STAT1_LPOWERABLE) { + efx_mdio_set_flag(efx, mmd, MDIO_CTRL1, + MDIO_CTRL1_LPOWER, lpower); } } -void mdio_clause45_set_mmds_lpower(struct efx_nic *efx, - int low_power, unsigned int mmd_mask) +void efx_mdio_set_mmds_lpower(struct efx_nic *efx, + int low_power, unsigned int mmd_mask) { int mmd = 0; - mmd_mask &= ~MDIO_MMDREG_DEVS_AN; + mmd_mask &= ~MDIO_DEVS_AN; while (mmd_mask) { if (mmd_mask & 1) - mdio_clause45_set_mmd_lpower(efx, low_power, mmd); + efx_mdio_set_mmd_lpower(efx, low_power, mmd); mmd_mask = (mmd_mask >> 1); mmd++; } } -static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr) -{ - int phy_id = efx->mii.phy_id; - u32 result = 0; - int reg; - - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr); - if (reg & ADVERTISE_10HALF) - result |= ADVERTISED_10baseT_Half; - if (reg & ADVERTISE_10FULL) - result |= ADVERTISED_10baseT_Full; - if (reg & ADVERTISE_100HALF) - result |= ADVERTISED_100baseT_Half; - if (reg & ADVERTISE_100FULL) - result |= ADVERTISED_100baseT_Full; - return result; -} - -/** - * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO. - * @efx: Efx NIC - * @ecmd: Buffer for settings - * - * On return the 'port', 'speed', 'supported' and 'advertising' fields of - * ecmd have been filled out. - */ -void mdio_clause45_get_settings(struct efx_nic *efx, - struct ethtool_cmd *ecmd) -{ - mdio_clause45_get_settings_ext(efx, ecmd, 0, 0); -} - /** - * mdio_clause45_get_settings_ext - Read (some of) the PHY settings over MDIO. - * @efx: Efx NIC - * @ecmd: Buffer for settings - * @xnp: Advertised Extended Next Page state - * @xnp_lpa: Link Partner's advertised XNP state - * - * On return the 'port', 'speed', 'supported' and 'advertising' fields of - * ecmd have been filled out. - */ -void mdio_clause45_get_settings_ext(struct efx_nic *efx, - struct ethtool_cmd *ecmd, - u32 npage_adv, u32 npage_lpa) -{ - int phy_id = efx->mii.phy_id; - int reg; - - ecmd->transceiver = XCVR_INTERNAL; - ecmd->phy_address = phy_id; - - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - MDIO_MMDREG_CTRL2); - switch (reg & MDIO_PMAPMD_CTRL2_TYPE_MASK) { - case MDIO_PMAPMD_CTRL2_10G_BT: - case MDIO_PMAPMD_CTRL2_1G_BT: - case MDIO_PMAPMD_CTRL2_100_BT: - case MDIO_PMAPMD_CTRL2_10_BT: - ecmd->port = PORT_TP; - ecmd->supported = SUPPORTED_TP; - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - MDIO_MMDREG_SPEED); - if (reg & (1 << MDIO_MMDREG_SPEED_10G_LBN)) - ecmd->supported |= SUPPORTED_10000baseT_Full; - if (reg & (1 << MDIO_MMDREG_SPEED_1000M_LBN)) - ecmd->supported |= (SUPPORTED_1000baseT_Full | - SUPPORTED_1000baseT_Half); - if (reg & (1 << MDIO_MMDREG_SPEED_100M_LBN)) - ecmd->supported |= (SUPPORTED_100baseT_Full | - SUPPORTED_100baseT_Half); - if (reg & (1 << MDIO_MMDREG_SPEED_10M_LBN)) - ecmd->supported |= (SUPPORTED_10baseT_Full | - SUPPORTED_10baseT_Half); - ecmd->advertising = ADVERTISED_TP; - break; - - /* We represent CX4 as fibre in the absence of anything better */ - case MDIO_PMAPMD_CTRL2_10G_CX4: - /* All the other defined modes are flavours of optical */ - default: - ecmd->port = PORT_FIBRE; - ecmd->supported = SUPPORTED_FIBRE; - ecmd->advertising = ADVERTISED_FIBRE; - break; - } - - if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) { - ecmd->supported |= SUPPORTED_Autoneg; - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, - MDIO_MMDREG_CTRL1); - if (reg & BMCR_ANENABLE) { - ecmd->autoneg = AUTONEG_ENABLE; - ecmd->advertising |= - ADVERTISED_Autoneg | - mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) | - npage_adv; - } else - ecmd->autoneg = AUTONEG_DISABLE; - } else - ecmd->autoneg = AUTONEG_DISABLE; - - if (ecmd->autoneg) { - /* If AN is complete, report best common mode, - * otherwise report best advertised mode. */ - u32 modes = 0; - if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, - MDIO_MMDREG_STAT1) & - (1 << MDIO_AN_STATUS_AN_DONE_LBN)) - modes = (ecmd->advertising & - (mdio_clause45_get_an(efx, MDIO_AN_LPA) | - npage_lpa)); - if (modes == 0) - modes = ecmd->advertising; - - if (modes & ADVERTISED_10000baseT_Full) { - ecmd->speed = SPEED_10000; - ecmd->duplex = DUPLEX_FULL; - } else if (modes & (ADVERTISED_1000baseT_Full | - ADVERTISED_1000baseT_Half)) { - ecmd->speed = SPEED_1000; - ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full); - } else if (modes & (ADVERTISED_100baseT_Full | - ADVERTISED_100baseT_Half)) { - ecmd->speed = SPEED_100; - ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full); - } else { - ecmd->speed = SPEED_10; - ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full); - } - } else { - /* Report forced settings */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - MDIO_MMDREG_CTRL1); - ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) * - ((reg & BMCR_SPEED100) ? 100 : 10)); - ecmd->duplex = (reg & BMCR_FULLDPLX || - ecmd->speed == SPEED_10000); - } -} - -/** - * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO. + * efx_mdio_set_settings - Set (some of) the PHY settings over MDIO. * @efx: Efx NIC * @ecmd: New settings */ -int mdio_clause45_set_settings(struct efx_nic *efx, - struct ethtool_cmd *ecmd) +int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { - int phy_id = efx->mii.phy_id; struct ethtool_cmd prev; u32 required; int reg; @@ -489,94 +305,67 @@ int mdio_clause45_set_settings(struct efx_nic *efx, ADVERTISED_1000baseT_Full)) reg |= ADVERTISE_NPAGE; reg |= efx_fc_advertise(efx->wanted_fc); - mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, - MDIO_AN_ADVERTISE, reg); + efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); /* Set up the (extended) next page if necessary */ if (efx->phy_op->set_npage_adv) efx->phy_op->set_npage_adv(efx, ecmd->advertising); /* Enable and restart AN */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, - MDIO_MMDREG_CTRL1); - reg |= BMCR_ANENABLE; + reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1); + reg |= MDIO_AN_CTRL1_ENABLE; if (!(EFX_WORKAROUND_15195(efx) && LOOPBACK_MASK(efx) & efx->phy_op->loopbacks)) - reg |= BMCR_ANRESTART; + reg |= MDIO_AN_CTRL1_RESTART; if (xnp) - reg |= 1 << MDIO_AN_CTRL_XNP_LBN; + reg |= MDIO_AN_CTRL1_XNP; else - reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN); - mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, - MDIO_MMDREG_CTRL1, reg); + reg &= ~MDIO_AN_CTRL1_XNP; + efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg); } else { /* Disable AN */ - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, - MDIO_MMDREG_CTRL1, - __ffs(BMCR_ANENABLE), false); + efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_CTRL1, + MDIO_AN_CTRL1_ENABLE, false); /* Set the basic control bits */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - MDIO_MMDREG_CTRL1); - reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX | - 0x003c); + reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1); + reg &= ~(MDIO_CTRL1_SPEEDSEL | MDIO_CTRL1_FULLDPLX); if (ecmd->speed == SPEED_100) - reg |= BMCR_SPEED100; + reg |= MDIO_PMA_CTRL1_SPEED100; if (ecmd->duplex) - reg |= BMCR_FULLDPLX; - mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, - MDIO_MMDREG_CTRL1, reg); + reg |= MDIO_CTRL1_FULLDPLX; + efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, reg); } return 0; } -void mdio_clause45_set_pause(struct efx_nic *efx) +void efx_mdio_set_pause(struct efx_nic *efx) { - int phy_id = efx->mii.phy_id; int reg; - if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) { + if (efx->phy_op->mmds & MDIO_DEVS_AN) { /* Set pause capability advertising */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, - MDIO_AN_ADVERTISE); + reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE); reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); reg |= efx_fc_advertise(efx->wanted_fc); - mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, - MDIO_AN_ADVERTISE, reg); + efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); /* Restart auto-negotiation */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, - MDIO_MMDREG_CTRL1); - if (reg & BMCR_ANENABLE) { - reg |= BMCR_ANRESTART; - mdio_clause45_write(efx, phy_id, MDIO_MMD_AN, - MDIO_MMDREG_CTRL1, reg); + reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1); + if (reg & MDIO_AN_CTRL1_ENABLE) { + reg |= MDIO_AN_CTRL1_RESTART; + efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg); } } } -enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx) +enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx) { - int phy_id = efx->mii.phy_id; int lpa; - if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN))) + if (!(efx->phy_op->mmds & MDIO_DEVS_AN)) return efx->wanted_fc; - lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA); + lpa = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_LPA); return efx_fc_resolve(efx->wanted_fc, lpa); } - -void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev, - u16 addr, int bit, bool sense) -{ - int old_val = mdio_clause45_read(efx, prt, dev, addr); - int new_val; - - if (sense) - new_val = old_val | (1 << bit); - else - new_val = old_val & ~(1 << bit); - if (old_val != new_val) - mdio_clause45_write(efx, prt, dev, addr, new_val); -} diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index 7014d2279c20..ea4587d93698 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h @@ -10,247 +10,53 @@ #ifndef EFX_MDIO_10G_H #define EFX_MDIO_10G_H +#include + /* - * Definitions needed for doing 10G MDIO as specified in clause 45 - * MDIO, which do not appear in Linux yet. Also some helper functions. + * Helper functions for doing 10G MDIO as specified in IEEE 802.3 clause 45. */ #include "efx.h" #include "boards.h" -/* Numbering of the MDIO Manageable Devices (MMDs) */ -/* Physical Medium Attachment/ Physical Medium Dependent sublayer */ -#define MDIO_MMD_PMAPMD (1) -/* WAN Interface Sublayer */ -#define MDIO_MMD_WIS (2) -/* Physical Coding Sublayer */ -#define MDIO_MMD_PCS (3) -/* PHY Extender Sublayer */ -#define MDIO_MMD_PHYXS (4) -/* Extender Sublayer */ -#define MDIO_MMD_DTEXS (5) -/* Transmission convergence */ -#define MDIO_MMD_TC (6) -/* Auto negotiation */ -#define MDIO_MMD_AN (7) -/* Clause 22 extension */ -#define MDIO_MMD_C22EXT 29 - -/* Generic register locations */ -#define MDIO_MMDREG_CTRL1 (0) -#define MDIO_MMDREG_STAT1 (1) -#define MDIO_MMDREG_IDHI (2) -#define MDIO_MMDREG_IDLOW (3) -#define MDIO_MMDREG_SPEED (4) -#define MDIO_MMDREG_DEVS0 (5) -#define MDIO_MMDREG_DEVS1 (6) -#define MDIO_MMDREG_CTRL2 (7) -#define MDIO_MMDREG_STAT2 (8) -#define MDIO_MMDREG_TXDIS (9) - -/* Bits in MMDREG_CTRL1 */ -/* Reset */ -#define MDIO_MMDREG_CTRL1_RESET_LBN (15) -#define MDIO_MMDREG_CTRL1_RESET_WIDTH (1) -/* Loopback */ -/* Loopback bit for WIS, PCS, PHYSX and DTEXS */ -#define MDIO_MMDREG_CTRL1_LBACK_LBN (14) -#define MDIO_MMDREG_CTRL1_LBACK_WIDTH (1) -/* Low power */ -#define MDIO_MMDREG_CTRL1_LPOWER_LBN (11) -#define MDIO_MMDREG_CTRL1_LPOWER_WIDTH (1) - -/* Bits in MMDREG_STAT1 */ -#define MDIO_MMDREG_STAT1_FAULT_LBN (7) -#define MDIO_MMDREG_STAT1_FAULT_WIDTH (1) -/* Link state */ -#define MDIO_MMDREG_STAT1_LINK_LBN (2) -#define MDIO_MMDREG_STAT1_LINK_WIDTH (1) -/* Low power ability */ -#define MDIO_MMDREG_STAT1_LPABLE_LBN (1) -#define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1) - -/* Bits in combined ID regs */ -static inline unsigned mdio_id_rev(u32 id) { return id & 0xf; } -static inline unsigned mdio_id_model(u32 id) { return (id >> 4) & 0x3f; } -extern unsigned mdio_id_oui(u32 id); - -/* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out - * so the 'bit present' bit number of an MMD is the number of - * that MMD */ -#define DEV_PRESENT_BIT(_b) (1 << _b) - -#define MDIO_MMDREG_DEVS_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS) -#define MDIO_MMDREG_DEVS_PCS DEV_PRESENT_BIT(MDIO_MMD_PCS) -#define MDIO_MMDREG_DEVS_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD) -#define MDIO_MMDREG_DEVS_AN DEV_PRESENT_BIT(MDIO_MMD_AN) -#define MDIO_MMDREG_DEVS_C22EXT DEV_PRESENT_BIT(MDIO_MMD_C22EXT) - -/* Bits in MMDREG_SPEED */ -#define MDIO_MMDREG_SPEED_10G_LBN 0 -#define MDIO_MMDREG_SPEED_10G_WIDTH 1 -#define MDIO_MMDREG_SPEED_1000M_LBN 4 -#define MDIO_MMDREG_SPEED_1000M_WIDTH 1 -#define MDIO_MMDREG_SPEED_100M_LBN 5 -#define MDIO_MMDREG_SPEED_100M_WIDTH 1 -#define MDIO_MMDREG_SPEED_10M_LBN 6 -#define MDIO_MMDREG_SPEED_10M_WIDTH 1 - -/* Bits in MMDREG_STAT2 */ -#define MDIO_MMDREG_STAT2_PRESENT_VAL (2) -#define MDIO_MMDREG_STAT2_PRESENT_LBN (14) -#define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2) - -/* Bits in MMDREG_TXDIS */ -#define MDIO_MMDREG_TXDIS_GLOBAL_LBN (0) -#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH (1) - -/* MMD-specific bits, ordered by MMD, then register */ -#define MDIO_PMAPMD_CTRL1_LBACK_LBN (0) -#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH (1) - -/* PMA type (4 bits) */ -#define MDIO_PMAPMD_CTRL2_10G_CX4 (0x0) -#define MDIO_PMAPMD_CTRL2_10G_EW (0x1) -#define MDIO_PMAPMD_CTRL2_10G_LW (0x2) -#define MDIO_PMAPMD_CTRL2_10G_SW (0x3) -#define MDIO_PMAPMD_CTRL2_10G_LX4 (0x4) -#define MDIO_PMAPMD_CTRL2_10G_ER (0x5) -#define MDIO_PMAPMD_CTRL2_10G_LR (0x6) -#define MDIO_PMAPMD_CTRL2_10G_SR (0x7) -/* Reserved */ -#define MDIO_PMAPMD_CTRL2_10G_BT (0x9) -/* Reserved */ -/* Reserved */ -#define MDIO_PMAPMD_CTRL2_1G_BT (0xc) -/* Reserved */ -#define MDIO_PMAPMD_CTRL2_100_BT (0xe) -#define MDIO_PMAPMD_CTRL2_10_BT (0xf) -#define MDIO_PMAPMD_CTRL2_TYPE_MASK (0xf) - -/* PMA 10GBT registers */ -#define MDIO_PMAPMD_10GBT_TXPWR (131) -#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0) -#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1) - -/* PHY XGXS Status 2 */ -#define MDIO_PHYXS_STATUS2 (8) -#define MDIO_PHYXS_STATUS2_RX_FAULT_LBN 10 - -/* PHY XGXS lane state */ -#define MDIO_PHYXS_LANE_STATE (0x18) -#define MDIO_PHYXS_LANE_ALIGNED_LBN (12) - -/* AN registers */ -#define MDIO_AN_CTRL_XNP_LBN 13 -#define MDIO_AN_STATUS (1) -#define MDIO_AN_STATUS_XNP_LBN (7) -#define MDIO_AN_STATUS_PAGE_LBN (6) -#define MDIO_AN_STATUS_AN_DONE_LBN (5) -#define MDIO_AN_STATUS_LP_AN_CAP_LBN (0) - -#define MDIO_AN_ADVERTISE 16 -#define MDIO_AN_ADVERTISE_XNP_LBN 12 -#define MDIO_AN_LPA 19 -#define MDIO_AN_XNP 22 -#define MDIO_AN_LPA_XNP 25 - -#define MDIO_AN_10GBT_CTRL 32 -#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12 -#define MDIO_AN_10GBT_STATUS (33) -#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */ -#define MDIO_AN_10GBT_STATUS_MS_LBN (14) /* MASTER/SLAVE config */ -#define MDIO_AN_10GBT_STATUS_LOC_OK_LBN (13) /* Local OK */ -#define MDIO_AN_10GBT_STATUS_REM_OK_LBN (12) /* Remote OK */ -#define MDIO_AN_10GBT_STATUS_LP_10G_LBN (11) /* Link partner is 10GBT capable */ -#define MDIO_AN_10GBT_STATUS_LP_LTA_LBN (10) /* LP loop timing ability */ -#define MDIO_AN_10GBT_STATUS_LP_TRR_LBN (9) /* LP Training Reset Request */ +static inline unsigned efx_mdio_id_rev(u32 id) { return id & 0xf; } +static inline unsigned efx_mdio_id_model(u32 id) { return (id >> 4) & 0x3f; } +extern unsigned efx_mdio_id_oui(u32 id); - -/* Packing of the prt and dev arguments of clause 45 style MDIO into a - * single int so they can be passed into the mdio_read/write functions - * that currently exist. Note that as Falcon is the only current user, - * the packed form is chosen to match what Falcon needs to write into - * a register. This is checked at compile-time so do not change it. If - * your target chip needs things layed out differently you will need - * to unpack the arguments in your chip-specific mdio functions. - */ - /* These are defined by the standard. */ -#define MDIO45_PRT_ID_WIDTH (5) -#define MDIO45_DEV_ID_WIDTH (5) - -/* The prt ID is just packed in immediately to the left of the dev ID */ -#define MDIO45_PRT_DEV_WIDTH (MDIO45_PRT_ID_WIDTH + MDIO45_DEV_ID_WIDTH) - -#define MDIO45_PRT_ID_MASK ((1 << MDIO45_PRT_DEV_WIDTH) - 1) -/* This is the prt + dev extended by 1 bit to hold the 'is clause 45' flag. */ -#define MDIO45_XPRT_ID_WIDTH (MDIO45_PRT_DEV_WIDTH + 1) -#define MDIO45_XPRT_ID_MASK ((1 << MDIO45_XPRT_ID_WIDTH) - 1) -#define MDIO45_XPRT_ID_IS10G (1 << (MDIO45_XPRT_ID_WIDTH - 1)) - - -#define MDIO45_PRT_ID_COMP_LBN MDIO45_DEV_ID_WIDTH -#define MDIO45_PRT_ID_COMP_WIDTH MDIO45_PRT_ID_WIDTH -#define MDIO45_DEV_ID_COMP_LBN 0 -#define MDIO45_DEV_ID_COMP_WIDTH MDIO45_DEV_ID_WIDTH - -/* Compose port and device into a phy_id */ -static inline int mdio_clause45_pack(u8 prt, u8 dev) -{ - efx_dword_t phy_id; - EFX_POPULATE_DWORD_2(phy_id, MDIO45_PRT_ID_COMP, prt, - MDIO45_DEV_ID_COMP, dev); - return MDIO45_XPRT_ID_IS10G | EFX_DWORD_VAL(phy_id); -} - -static inline void mdio_clause45_unpack(u32 val, u8 *prt, u8 *dev) +static inline int efx_mdio_read(struct efx_nic *efx, int devad, int addr) { - efx_dword_t phy_id; - EFX_POPULATE_DWORD_1(phy_id, EFX_DWORD_0, val); - *prt = EFX_DWORD_FIELD(phy_id, MDIO45_PRT_ID_COMP); - *dev = EFX_DWORD_FIELD(phy_id, MDIO45_DEV_ID_COMP); + return efx->mdio.mdio_read(efx->net_dev, efx->mdio.prtad, devad, addr); } -static inline int mdio_clause45_read(struct efx_nic *efx, - u8 prt, u8 dev, u16 addr) +static inline void +efx_mdio_write(struct efx_nic *efx, int devad, int addr, int value) { - return efx->mii.mdio_read(efx->net_dev, - mdio_clause45_pack(prt, dev), addr); + efx->mdio.mdio_write(efx->net_dev, efx->mdio.prtad, devad, addr, value); } -static inline void mdio_clause45_write(struct efx_nic *efx, - u8 prt, u8 dev, u16 addr, int value) -{ - efx->mii.mdio_write(efx->net_dev, - mdio_clause45_pack(prt, dev), addr, value); -} - - -static inline u32 mdio_clause45_read_id(struct efx_nic *efx, int mmd) +static inline u32 efx_mdio_read_id(struct efx_nic *efx, int mmd) { - int phy_id = efx->mii.phy_id; - u16 id_low = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDLOW); - u16 id_hi = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDHI); + u16 id_low = efx_mdio_read(efx, mmd, MDIO_DEVID2); + u16 id_hi = efx_mdio_read(efx, mmd, MDIO_DEVID1); return (id_hi << 16) | (id_low); } -static inline bool mdio_clause45_phyxgxs_lane_sync(struct efx_nic *efx) +static inline bool efx_mdio_phyxgxs_lane_sync(struct efx_nic *efx) { int i, lane_status; bool sync; for (i = 0; i < 2; ++i) - lane_status = mdio_clause45_read(efx, efx->mii.phy_id, - MDIO_MMD_PHYXS, - MDIO_PHYXS_LANE_STATE); + lane_status = efx_mdio_read(efx, MDIO_MMD_PHYXS, + MDIO_PHYXS_LNSTAT); - sync = !!(lane_status & (1 << MDIO_PHYXS_LANE_ALIGNED_LBN)); + sync = !!(lane_status & MDIO_PHYXS_LNSTAT_ALIGN); if (!sync) EFX_LOG(efx, "XGXS lane status: %x\n", lane_status); return sync; } -extern const char *mdio_clause45_mmd_name(int mmd); +extern const char *efx_mdio_mmd_name(int mmd); /* * Reset a specific MMD and wait for reset to clear. @@ -258,54 +64,47 @@ extern const char *mdio_clause45_mmd_name(int mmd); * * This function will sleep */ -extern int mdio_clause45_reset_mmd(struct efx_nic *efx, int mmd, - int spins, int spintime); +extern int efx_mdio_reset_mmd(struct efx_nic *efx, int mmd, + int spins, int spintime); -/* As mdio_clause45_check_mmd but for multiple MMDs */ -int mdio_clause45_check_mmds(struct efx_nic *efx, - unsigned int mmd_mask, unsigned int fatal_mask); +/* As efx_mdio_check_mmd but for multiple MMDs */ +int efx_mdio_check_mmds(struct efx_nic *efx, + unsigned int mmd_mask, unsigned int fatal_mask); /* Check the link status of specified mmds in bit mask */ -extern bool mdio_clause45_links_ok(struct efx_nic *efx, - unsigned int mmd_mask); +extern bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask); /* Generic transmit disable support though PMAPMD */ -extern void mdio_clause45_transmit_disable(struct efx_nic *efx); +extern void efx_mdio_transmit_disable(struct efx_nic *efx); /* Generic part of reconfigure: set/clear loopback bits */ -extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx); +extern void efx_mdio_phy_reconfigure(struct efx_nic *efx); /* Set the power state of the specified MMDs */ -extern void mdio_clause45_set_mmds_lpower(struct efx_nic *efx, - int low_power, unsigned int mmd_mask); - -/* Read (some of) the PHY settings over MDIO */ -extern void mdio_clause45_get_settings(struct efx_nic *efx, - struct ethtool_cmd *ecmd); - -/* Read (some of) the PHY settings over MDIO */ -extern void -mdio_clause45_get_settings_ext(struct efx_nic *efx, struct ethtool_cmd *ecmd, - u32 xnp, u32 xnp_lpa); +extern void efx_mdio_set_mmds_lpower(struct efx_nic *efx, + int low_power, unsigned int mmd_mask); /* Set (some of) the PHY settings over MDIO */ -extern int mdio_clause45_set_settings(struct efx_nic *efx, - struct ethtool_cmd *ecmd); +extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd); /* Set pause parameters to be advertised through AN (if available) */ -extern void mdio_clause45_set_pause(struct efx_nic *efx); +extern void efx_mdio_set_pause(struct efx_nic *efx); /* Get pause parameters from AN if available (otherwise return * requested pause parameters) */ -enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx); +enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx); /* Wait for specified MMDs to exit reset within a timeout */ -extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx, - unsigned int mmd_mask); +extern int efx_mdio_wait_reset_mmds(struct efx_nic *efx, + unsigned int mmd_mask); /* Set or clear flag, debouncing */ -extern void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev, - u16 addr, int bit, bool sense); +static inline void +efx_mdio_set_flag(struct efx_nic *efx, int devad, int addr, + int mask, bool state) +{ + mdio_set_flag(&efx->mdio, efx->mdio.prtad, devad, addr, mask, state); +} #endif /* EFX_MDIO_10G_H */ diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index e169e5dcd1e6..457e2f1d4b43 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -458,8 +458,6 @@ enum phy_type { PHY_TYPE_MAX /* Insert any new items before this */ }; -#define PHY_ADDR_INVALID 0xff - #define EFX_IS10G(efx) ((efx)->link_speed == 10000) enum nic_state { @@ -758,7 +756,7 @@ union efx_multicast_hash { * @phy_lock: PHY access lock * @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) - * @mii: PHY interface + * @mdio: PHY MDIO interface * @phy_mode: PHY operating mode. Serialised by @mac_lock. * @mac_up: MAC link state * @link_up: Link status @@ -845,7 +843,7 @@ struct efx_nic { struct work_struct phy_work; struct efx_phy_operations *phy_op; void *phy_data; - struct mii_if_info mii; + struct mdio_if_info mdio; enum efx_phy_mode phy_mode; bool mac_up; diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 0a598084c513..043795715955 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -80,39 +80,38 @@ struct efx_loopback_state { * **************************************************************************/ -static int efx_test_mii(struct efx_nic *efx, struct efx_self_tests *tests) +static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests) { int rc = 0; + int devad = __ffs(efx->mdio.mmds); u16 physid1, physid2; - struct mii_if_info *mii = &efx->mii; - struct net_device *net_dev = efx->net_dev; if (efx->phy_type == PHY_TYPE_NONE) return 0; mutex_lock(&efx->mac_lock); - tests->mii = -1; + tests->mdio = -1; - physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1); - physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2); + physid1 = efx_mdio_read(efx, devad, MDIO_DEVID1); + physid2 = efx_mdio_read(efx, devad, MDIO_DEVID2); if ((physid1 == 0x0000) || (physid1 == 0xffff) || (physid2 == 0x0000) || (physid2 == 0xffff)) { - EFX_ERR(efx, "no MII PHY present with ID %d\n", - mii->phy_id); + EFX_ERR(efx, "no MDIO PHY present with ID %d\n", + efx->mdio.prtad); rc = -EINVAL; goto out; } if (EFX_IS10G(efx)) { - rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0); + rc = efx_mdio_check_mmds(efx, efx->phy_op->mmds, 0); if (rc) goto out; } out: mutex_unlock(&efx->mac_lock); - tests->mii = rc ? -1 : 1; + tests->mdio = rc ? -1 : 1; return rc; } @@ -673,7 +672,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, /* Online (i.e. non-disruptive) testing * This checks interrupt generation, event delivery and PHY presence. */ - rc = efx_test_mii(efx, tests); + rc = efx_test_mdio(efx, tests); if (rc && !rc_test) rc_test = rc; diff --git a/drivers/net/sfc/selftest.h b/drivers/net/sfc/selftest.h index 39451cf938cf..f6feee04c96b 100644 --- a/drivers/net/sfc/selftest.h +++ b/drivers/net/sfc/selftest.h @@ -32,7 +32,7 @@ struct efx_loopback_self_tests { */ struct efx_self_tests { /* online tests */ - int mii; + int mdio; int nvram; int interrupt; int eventq_dma[EFX_MAX_CHANNELS]; diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index e61dc4d4741c..403f7d70c223 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -23,10 +23,10 @@ * clause 22 extension MMD, but since it doesn't have all the generic * MMD registers it is pointless to include it here. */ -#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD | \ - MDIO_MMDREG_DEVS_PCS | \ - MDIO_MMDREG_DEVS_PHYXS | \ - MDIO_MMDREG_DEVS_AN) +#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \ + MDIO_DEVS_PCS | \ + MDIO_DEVS_PHYXS | \ + MDIO_DEVS_AN) #define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) | \ (1 << LOOPBACK_PCS) | \ @@ -153,10 +153,6 @@ #define LOOPBACK_NEAR_LBN (8) #define LOOPBACK_NEAR_WIDTH (1) -#define PCS_10GBASET_STAT1 32 -#define PCS_10GBASET_BLKLK_LBN 0 -#define PCS_10GBASET_BLKLK_WIDTH 1 - /* Boot status register */ #define PCS_BOOT_STATUS_REG 53248 #define PCS_BOOT_FATAL_ERROR_LBN 0 @@ -206,10 +202,8 @@ static ssize_t show_phy_short_reach(struct device *dev, struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); int reg; - reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, - MDIO_PMAPMD_10GBT_TXPWR); - return sprintf(buf, "%d\n", - !!(reg & (1 << MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN))); + reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR); + return sprintf(buf, "%d\n", !!(reg & MDIO_PMA_10GBT_TXPWR_SHORT)); } static ssize_t set_phy_short_reach(struct device *dev, @@ -219,10 +213,9 @@ static ssize_t set_phy_short_reach(struct device *dev, struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); rtnl_lock(); - mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, - MDIO_PMAPMD_10GBT_TXPWR, - MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN, - count != 0 && *buf != '0'); + efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, + MDIO_PMA_10GBT_TXPWR_SHORT, + count != 0 && *buf != '0'); efx_reconfigure_port(efx); rtnl_unlock(); @@ -238,9 +231,8 @@ int sft9001_wait_boot(struct efx_nic *efx) int boot_stat; for (;;) { - boot_stat = mdio_clause45_read(efx, efx->mii.phy_id, - MDIO_MMD_PCS, - PCS_BOOT_STATUS_REG); + boot_stat = efx_mdio_read(efx, MDIO_MMD_PCS, + PCS_BOOT_STATUS_REG); if (boot_stat >= 0) { EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat); switch (boot_stat & @@ -286,38 +278,32 @@ int sft9001_wait_boot(struct efx_nic *efx) static int tenxpress_init(struct efx_nic *efx) { - int phy_id = efx->mii.phy_id; int reg; if (efx->phy_type == PHY_TYPE_SFX7101) { /* Enable 312.5 MHz clock */ - mdio_clause45_write(efx, phy_id, - MDIO_MMD_PCS, PCS_TEST_SELECT_REG, - 1 << CLK312_EN_LBN); + efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG, + 1 << CLK312_EN_LBN); } else { /* Enable 312.5 MHz clock and GMII */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG); + reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | (1 << PMA_PMD_EXT_CLK_OUT_LBN) | (1 << PMA_PMD_EXT_CLK312_LBN) | (1 << PMA_PMD_EXT_ROBUST_LBN)); - mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG, reg); - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, - GPHY_XCONTROL_REG, GPHY_ISOLATE_LBN, - false); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); + efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, + GPHY_XCONTROL_REG, 1 << GPHY_ISOLATE_LBN, + false); } /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ if (efx->phy_type == PHY_TYPE_SFX7101) { - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_LED_CTRL_REG, - PMA_PMA_LED_ACTIVITY_LBN, - true); - mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT); + efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG, + 1 << PMA_PMA_LED_ACTIVITY_LBN, true); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, + PMA_PMD_LED_DEFAULT); } return 0; @@ -337,22 +323,19 @@ static int tenxpress_phy_init(struct efx_nic *efx) if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { if (efx->phy_type == PHY_TYPE_SFT9001A) { int reg; - reg = mdio_clause45_read(efx, efx->mii.phy_id, - MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG); + reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, + PMA_PMD_XCONTROL_REG); reg |= (1 << PMA_PMD_EXT_SSR_LBN); - mdio_clause45_write(efx, efx->mii.phy_id, - MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG, reg); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + PMA_PMD_XCONTROL_REG, reg); mdelay(200); } - rc = mdio_clause45_wait_reset_mmds(efx, - TENXPRESS_REQUIRED_DEVS); + rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) goto fail; - rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); + rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0); if (rc < 0) goto fail; } @@ -360,7 +343,7 @@ static int tenxpress_phy_init(struct efx_nic *efx) rc = tenxpress_init(efx); if (rc < 0) goto fail; - mdio_clause45_set_pause(efx); + efx_mdio_set_pause(efx); if (efx->phy_type == PHY_TYPE_SFT9001B) { rc = device_create_file(&efx->pci_dev->dev, @@ -395,17 +378,14 @@ static int tenxpress_special_reset(struct efx_nic *efx) efx_stats_disable(efx); /* Initiate reset */ - reg = mdio_clause45_read(efx, efx->mii.phy_id, - MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); + reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); reg |= (1 << PMA_PMD_EXT_SSR_LBN); - mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG, reg); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); mdelay(200); /* Wait for the blocks to come out of reset */ - rc = mdio_clause45_wait_reset_mmds(efx, - TENXPRESS_REQUIRED_DEVS); + rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) goto out; @@ -424,7 +404,6 @@ out: static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok) { struct tenxpress_phy_data *pd = efx->phy_data; - int phy_id = efx->mii.phy_id; bool bad_lp; int reg; @@ -432,11 +411,10 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok) bad_lp = false; } else { /* Check that AN has started but not completed. */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, - MDIO_AN_STATUS); - if (!(reg & (1 << MDIO_AN_STATUS_LP_AN_CAP_LBN))) + reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_STAT1); + if (!(reg & MDIO_AN_STAT1_LPABLE)) return; /* LP status is unknown */ - bad_lp = !(reg & (1 << MDIO_AN_STATUS_AN_DONE_LBN)); + bad_lp = !(reg & MDIO_AN_STAT1_COMPLETE); if (bad_lp) pd->bad_lp_tries++; } @@ -448,8 +426,8 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok) /* Use the RX (red) LED as an error indicator once we've seen AN * failure several times in a row, and also log a message. */ if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) { - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_LED_OVERR_REG); + reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, + PMA_PMD_LED_OVERR_REG); reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN); if (!bad_lp) { reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN; @@ -460,23 +438,22 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok) " supports 10GBASE-T ONLY, so no link can" " be established\n"); } - mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_LED_OVERR_REG, reg); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + PMA_PMD_LED_OVERR_REG, reg); pd->bad_lp_tries = bad_lp; } } static bool sfx7101_link_ok(struct efx_nic *efx) { - return mdio_clause45_links_ok(efx, - MDIO_MMDREG_DEVS_PMAPMD | - MDIO_MMDREG_DEVS_PCS | - MDIO_MMDREG_DEVS_PHYXS); + return efx_mdio_links_ok(efx, + MDIO_DEVS_PMAPMD | + MDIO_DEVS_PCS | + MDIO_DEVS_PHYXS); } static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd) { - int phy_id = efx->mii.phy_id; u32 reg; if (efx_phy_mode_disabled(efx->phy_mode)) @@ -484,50 +461,43 @@ static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd) else if (efx->loopback_mode == LOOPBACK_GPHY) return true; else if (efx->loopback_mode) - return mdio_clause45_links_ok(efx, - MDIO_MMDREG_DEVS_PMAPMD | - MDIO_MMDREG_DEVS_PHYXS); + return efx_mdio_links_ok(efx, + MDIO_DEVS_PMAPMD | + MDIO_DEVS_PHYXS); /* We must use the same definition of link state as LASI, * otherwise we can miss a link state transition */ if (ecmd->speed == 10000) { - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, - PCS_10GBASET_STAT1); - return reg & (1 << PCS_10GBASET_BLKLK_LBN); + reg = efx_mdio_read(efx, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1); + return reg & MDIO_PCS_10GBRT_STAT1_BLKLK; } else { - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, - C22EXT_STATUS_REG); + reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_STATUS_REG); return reg & (1 << C22EXT_STATUS_LINK_LBN); } } static void tenxpress_ext_loopback(struct efx_nic *efx) { - int phy_id = efx->mii.phy_id; - - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS, - PHYXS_TEST1, LOOPBACK_NEAR_LBN, - efx->loopback_mode == LOOPBACK_PHYXS); + efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1, + 1 << LOOPBACK_NEAR_LBN, + efx->loopback_mode == LOOPBACK_PHYXS); if (efx->phy_type != PHY_TYPE_SFX7101) - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, - GPHY_XCONTROL_REG, - GPHY_LOOPBACK_NEAR_LBN, - efx->loopback_mode == LOOPBACK_GPHY); + efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, GPHY_XCONTROL_REG, + 1 << GPHY_LOOPBACK_NEAR_LBN, + efx->loopback_mode == LOOPBACK_GPHY); } static void tenxpress_low_power(struct efx_nic *efx) { - int phy_id = efx->mii.phy_id; - if (efx->phy_type == PHY_TYPE_SFX7101) - mdio_clause45_set_mmds_lpower( + efx_mdio_set_mmds_lpower( efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER), TENXPRESS_REQUIRED_DEVS); else - mdio_clause45_set_flag( - efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG, PMA_PMD_EXT_LPOWER_LBN, + efx_mdio_set_flag( + efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, + 1 << PMA_PMD_EXT_LPOWER_LBN, !!(efx->phy_mode & PHY_MODE_LOW_POWER)); } @@ -568,8 +538,8 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) WARN_ON(rc); } - mdio_clause45_transmit_disable(efx); - mdio_clause45_phy_reconfigure(efx); + efx_mdio_transmit_disable(efx); + efx_mdio_phy_reconfigure(efx); tenxpress_ext_loopback(efx); phy_data->loopback_mode = efx->loopback_mode; @@ -585,7 +555,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) efx->link_fd = ecmd.duplex == DUPLEX_FULL; efx->link_up = sft9001_link_ok(efx, &ecmd); } - efx->link_fc = mdio_clause45_get_pause(efx); + efx->link_fc = efx_mdio_get_pause(efx); } /* Poll PHY for interrupt */ @@ -599,7 +569,7 @@ static void tenxpress_phy_poll(struct efx_nic *efx) if (link_ok != efx->link_up) { change = true; } else { - unsigned int link_fc = mdio_clause45_get_pause(efx); + unsigned int link_fc = efx_mdio_get_pause(efx); if (link_fc != efx->link_fc) change = true; } @@ -609,9 +579,8 @@ static void tenxpress_phy_poll(struct efx_nic *efx) if (link_ok != efx->link_up) change = true; } else { - u32 status = mdio_clause45_read(efx, efx->mii.phy_id, - MDIO_MMD_PMAPMD, - PMA_PMD_LASI_STATUS); + int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD, + PMA_PMD_LASI_STATUS); if (status & (1 << PMA_PMD_LS_ALARM_LBN)) change = true; } @@ -634,8 +603,7 @@ static void tenxpress_phy_fini(struct efx_nic *efx) if (efx->phy_type == PHY_TYPE_SFX7101) { /* Power down the LNPGA */ reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN); - mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG, reg); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); /* Waiting here ensures that the board fini, which can turn * off the power to the PHY, won't get run until the LNPGA @@ -661,8 +629,7 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink) else reg = PMA_PMD_LED_DEFAULT; - mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_LED_OVERR_REG, reg); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg); } static const char *const sfx7101_test_names[] = { @@ -698,7 +665,6 @@ static const char *const sft9001_test_names[] = { static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) { struct ethtool_cmd ecmd; - int phy_id = efx->mii.phy_id; int rc = 0, rc2, i, ctrl_reg, res_reg; if (flags & ETH_TEST_FL_OFFLINE) @@ -717,11 +683,10 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) * must reset the PHY to resume normal service. */ ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN); } - mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_CDIAG_CTRL_REG, ctrl_reg); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG, + ctrl_reg); i = 0; - while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_CDIAG_CTRL_REG) & + while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) & (1 << CDIAG_CTRL_IN_PROG_LBN)) { if (++i == 50) { rc = -ETIMEDOUT; @@ -729,15 +694,13 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) } msleep(100); } - res_reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_CDIAG_RES_REG); + res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG); for (i = 0; i < 4; i++) { int pair_res = (res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH)) & ((1 << CDIAG_RES_WIDTH) - 1); - int len_reg = mdio_clause45_read(efx, efx->mii.phy_id, - MDIO_MMD_PMAPMD, - PMA_PMD_CDIAG_LEN_REG + i); + int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, + PMA_PMD_CDIAG_LEN_REG + i); if (pair_res == CDIAG_RES_OK) results[1 + i] = 1; else if (pair_res == CDIAG_RES_INVALID) @@ -769,32 +732,27 @@ out: static void tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { - int phy_id = efx->mii.phy_id; u32 adv = 0, lpa = 0; int reg; if (efx->phy_type != PHY_TYPE_SFX7101) { - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, - C22EXT_MSTSLV_CTRL); + reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL); if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN)) adv |= ADVERTISED_1000baseT_Full; - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT, - C22EXT_MSTSLV_STATUS); + reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_STATUS); if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN)) lpa |= ADVERTISED_1000baseT_Half; if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN)) lpa |= ADVERTISED_1000baseT_Full; } - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, - MDIO_AN_10GBT_CTRL); - if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN)) + reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL); + if (reg & MDIO_AN_10GBT_CTRL_ADV10G) adv |= ADVERTISED_10000baseT_Full; - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, - MDIO_AN_10GBT_STATUS); - if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN)) + reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); + if (reg & MDIO_AN_10GBT_STAT_LP10G) lpa |= ADVERTISED_10000baseT_Full; - mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa); + mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); if (efx->phy_type != PHY_TYPE_SFX7101) ecmd->supported |= (SUPPORTED_100baseT_Full | @@ -813,29 +771,24 @@ static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) if (!ecmd->autoneg) return -EINVAL; - return mdio_clause45_set_settings(efx, ecmd); + return efx_mdio_set_settings(efx, ecmd); } static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) { - mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN, - MDIO_AN_10GBT_CTRL, - MDIO_AN_10GBT_CTRL_ADV_10G_LBN, - advertising & ADVERTISED_10000baseT_Full); + efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, + MDIO_AN_10GBT_CTRL_ADV10G, + advertising & ADVERTISED_10000baseT_Full); } static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) { - int phy_id = efx->mii.phy_id; - - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT, - C22EXT_MSTSLV_CTRL, - C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN, - advertising & ADVERTISED_1000baseT_Full); - mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN, - MDIO_AN_10GBT_CTRL, - MDIO_AN_10GBT_CTRL_ADV_10G_LBN, - advertising & ADVERTISED_10000baseT_Full); + efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL, + 1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN, + advertising & ADVERTISED_1000baseT_Full); + efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, + MDIO_AN_10GBT_CTRL_ADV10G, + advertising & ADVERTISED_10000baseT_Full); } struct efx_phy_operations falcon_sfx7101_phy_ops = { diff --git a/drivers/net/sfc/xenpack.h b/drivers/net/sfc/xenpack.h index b0d1f225b70a..4e52286e542d 100644 --- a/drivers/net/sfc/xenpack.h +++ b/drivers/net/sfc/xenpack.h @@ -34,29 +34,24 @@ /* Enable LASI interrupts for PHY */ static inline void xenpack_enable_lasi_irqs(struct efx_nic *efx) { - int reg; - int phy_id = efx->mii.phy_id; /* Read to clear LASI status register */ - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD, - MDIO_XP_LASI_STAT); + efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT); - mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD, - MDIO_XP_LASI_CTRL, XP_LASI_LS_ALARM); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_CTRL, + XP_LASI_LS_ALARM); } /* Read the LASI interrupt status to clear the interrupt. */ static inline int xenpack_clear_lasi_irqs(struct efx_nic *efx) { /* Read to clear link status alarm */ - return mdio_clause45_read(efx, efx->mii.phy_id, - MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT); + return efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT); } /* Turn off LASI interrupts */ static inline void xenpack_disable_lasi_irqs(struct efx_nic *efx) { - mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, - MDIO_XP_LASI_CTRL, 0); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_XP_LASI_CTRL, 0); } #endif /* EFX_XENPACK_H */ diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c index bb1ef77d5f56..aad2dca19772 100644 --- a/drivers/net/sfc/xfp_phy.c +++ b/drivers/net/sfc/xfp_phy.c @@ -19,9 +19,9 @@ #include "phy.h" #include "falcon.h" -#define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS | \ - MDIO_MMDREG_DEVS_PMAPMD | \ - MDIO_MMDREG_DEVS_PHYXS) +#define XFP_REQUIRED_DEVS (MDIO_DEVS_PCS | \ + MDIO_DEVS_PMAPMD | \ + MDIO_DEVS_PHYXS) #define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) | \ (1 << LOOPBACK_PMAPMD) | \ @@ -49,8 +49,7 @@ void xfp_set_led(struct efx_nic *p, int led, int mode) { int addr = MDIO_QUAKE_LED0_REG + led; - mdio_clause45_write(p, p->mii.phy_id, MDIO_MMD_PMAPMD, addr, - mode); + efx_mdio_write(p, MDIO_MMD_PMAPMD, addr, mode); } struct xfp_phy_data { @@ -63,14 +62,12 @@ struct xfp_phy_data { static int qt2025c_wait_reset(struct efx_nic *efx) { unsigned long timeout = jiffies + 10 * HZ; - int phy_id = efx->mii.phy_id; int reg, old_counter = 0; /* Wait for firmware heartbeat to start */ for (;;) { int counter; - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, - PCS_FW_HEARTBEAT_REG); + reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_FW_HEARTBEAT_REG); if (reg < 0) return reg; counter = ((reg >> PCS_FW_HEARTB_LBN) & @@ -86,8 +83,7 @@ static int qt2025c_wait_reset(struct efx_nic *efx) /* Wait for firmware status to look good */ for (;;) { - reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS, - PCS_UC8051_STATUS_REG); + reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG); if (reg < 0) return reg; if ((reg & @@ -109,9 +105,9 @@ static int xfp_reset_phy(struct efx_nic *efx) { int rc; - rc = mdio_clause45_reset_mmd(efx, MDIO_MMD_PHYXS, - XFP_MAX_RESET_TIME / XFP_RESET_WAIT, - XFP_RESET_WAIT); + rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS, + XFP_MAX_RESET_TIME / XFP_RESET_WAIT, + XFP_RESET_WAIT); if (rc < 0) goto fail; @@ -126,8 +122,7 @@ static int xfp_reset_phy(struct efx_nic *efx) /* Check that all the MMDs we expect are present and responding. We * expect faults on some if the link is down, but not on the PHY XS */ - rc = mdio_clause45_check_mmds(efx, XFP_REQUIRED_DEVS, - MDIO_MMDREG_DEVS_PHYXS); + rc = efx_mdio_check_mmds(efx, XFP_REQUIRED_DEVS, MDIO_DEVS_PHYXS); if (rc < 0) goto fail; @@ -143,7 +138,7 @@ static int xfp_reset_phy(struct efx_nic *efx) static int xfp_phy_init(struct efx_nic *efx) { struct xfp_phy_data *phy_data; - u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS); + u32 devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS); int rc; phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL); @@ -152,8 +147,8 @@ static int xfp_phy_init(struct efx_nic *efx) efx->phy_data = phy_data; EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n", - devid, mdio_id_oui(devid), mdio_id_model(devid), - mdio_id_rev(devid)); + devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid), + efx_mdio_id_rev(devid)); phy_data->phy_mode = efx->phy_mode; @@ -179,7 +174,7 @@ static void xfp_phy_clear_interrupt(struct efx_nic *efx) static int xfp_link_ok(struct efx_nic *efx) { - return mdio_clause45_links_ok(efx, XFP_REQUIRED_DEVS); + return efx_mdio_links_ok(efx, XFP_REQUIRED_DEVS); } static void xfp_phy_poll(struct efx_nic *efx) @@ -200,9 +195,9 @@ static void xfp_phy_reconfigure(struct efx_nic *efx) * or optical transceivers, varying somewhat between * firmware versions. Only 'static mode' appears to * cover everything. */ - mdio_clause45_set_flag( - efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, - PMA_PMD_FTX_CTRL2_REG, PMA_PMD_FTX_STATIC_LBN, + mdio_set_flag( + &efx->mdio, efx->mdio.prtad, MDIO_MMD_PMAPMD, + PMA_PMD_FTX_CTRL2_REG, 1 << PMA_PMD_FTX_STATIC_LBN, efx->phy_mode & PHY_MODE_TX_DISABLED || efx->phy_mode & PHY_MODE_LOW_POWER || efx->loopback_mode == LOOPBACK_PCS || @@ -213,10 +208,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx) (phy_data->phy_mode & PHY_MODE_TX_DISABLED)) xfp_reset_phy(efx); - mdio_clause45_transmit_disable(efx); + efx_mdio_transmit_disable(efx); } - mdio_clause45_phy_reconfigure(efx); + efx_mdio_phy_reconfigure(efx); phy_data->phy_mode = efx->phy_mode; efx->link_up = xfp_link_ok(efx); @@ -225,6 +220,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx) efx->link_fc = efx->wanted_fc; } +static void xfp_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) +{ + mdio45_ethtool_gset(&efx->mdio, ecmd); +} static void xfp_phy_fini(struct efx_nic *efx) { @@ -243,8 +242,8 @@ struct efx_phy_operations falcon_xfp_phy_ops = { .poll = xfp_phy_poll, .fini = xfp_phy_fini, .clear_interrupt = xfp_phy_clear_interrupt, - .get_settings = mdio_clause45_get_settings, - .set_settings = mdio_clause45_set_settings, + .get_settings = xfp_phy_get_settings, + .set_settings = efx_mdio_set_settings, .mmds = XFP_REQUIRED_DEVS, .loopbacks = XFP_LOOPBACKS, }; -- GitLab From 23c3320cb039debfb94b27e8e9bfe26dd47692c3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:06:34 +0000 Subject: [PATCH 0922/6080] chelsio: Use generic MDIO definitions and mdio_mii_ioctl() Compile-tested only. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/Kconfig | 1 + drivers/net/chelsio/common.h | 2 +- drivers/net/chelsio/cphy.h | 45 ++++++++++++++++++--------------- drivers/net/chelsio/cxgb2.c | 36 +++----------------------- drivers/net/chelsio/mv88x201x.c | 45 +++++++++++++++++---------------- drivers/net/chelsio/my3126.c | 10 +++++--- drivers/net/chelsio/subr.c | 43 ++++++++++++++++--------------- 7 files changed, 82 insertions(+), 100 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2f81db51b45d..1ccd54714c4c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2450,6 +2450,7 @@ config CHELSIO_T1 tristate "Chelsio 10Gb Ethernet support" depends on PCI select CRC32 + select MDIO help This driver supports Chelsio gigabit and 10-gigabit Ethernet cards. More information about adapter features and diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h index 4bd2455b0fe3..699d22c5fe09 100644 --- a/drivers/net/chelsio/common.h +++ b/drivers/net/chelsio/common.h @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h index 79d855e267e0..8b5165a5af3f 100644 --- a/drivers/net/chelsio/cphy.h +++ b/drivers/net/chelsio/cphy.h @@ -43,10 +43,11 @@ struct mdio_ops { void (*init)(adapter_t *adapter, const struct board_info *bi); - int (*read)(adapter_t *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *val); - int (*write)(adapter_t *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val); + int (*read)(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr); + int (*write)(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr, u16 val); + unsigned mode_support; }; /* PHY interrupt types */ @@ -83,11 +84,12 @@ struct cphy_ops { int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex); int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed, int *duplex, int *fc); + + u32 mmds; }; /* A PHY instance */ struct cphy { - int addr; /* PHY address */ int state; /* Link status state machine */ adapter_t *adapter; /* associated adapter */ @@ -101,36 +103,37 @@ struct cphy { u32 elmer_gpo; const struct cphy_ops *ops; /* PHY operations */ - int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *val); - int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val); + struct mdio_if_info mdio; struct cphy_instance *instance; }; /* Convenience MDIO read/write wrappers */ -static inline int mdio_read(struct cphy *cphy, int mmd, int reg, - unsigned int *valp) +static inline int cphy_mdio_read(struct cphy *cphy, int mmd, int reg, + unsigned int *valp) { - return cphy->mdio_read(cphy->adapter, cphy->addr, mmd, reg, valp); + int rc = cphy->mdio.mdio_read(cphy->mdio.dev, cphy->mdio.prtad, mmd, + reg); + *valp = (rc >= 0) ? rc : -1; + return (rc >= 0) ? 0 : rc; } -static inline int mdio_write(struct cphy *cphy, int mmd, int reg, - unsigned int val) +static inline int cphy_mdio_write(struct cphy *cphy, int mmd, int reg, + unsigned int val) { - return cphy->mdio_write(cphy->adapter, cphy->addr, mmd, reg, val); + return cphy->mdio.mdio_write(cphy->mdio.dev, cphy->mdio.prtad, mmd, + reg, val); } static inline int simple_mdio_read(struct cphy *cphy, int reg, unsigned int *valp) { - return mdio_read(cphy, 0, reg, valp); + return cphy_mdio_read(cphy, MDIO_DEVAD_NONE, reg, valp); } static inline int simple_mdio_write(struct cphy *cphy, int reg, unsigned int val) { - return mdio_write(cphy, 0, reg, val); + return cphy_mdio_write(cphy, MDIO_DEVAD_NONE, reg, val); } /* Convenience initializer */ @@ -139,11 +142,13 @@ static inline void cphy_init(struct cphy *phy, adapter_t *adapter, const struct mdio_ops *mdio_ops) { phy->adapter = adapter; - phy->addr = phy_addr; phy->ops = phy_ops; if (mdio_ops) { - phy->mdio_read = mdio_ops->read; - phy->mdio_write = mdio_ops->write; + phy->mdio.prtad = phy_addr; + phy->mdio.mmds = phy_ops->mmds; + phy->mdio.mode_support = mdio_ops->mode_support; + phy->mdio.mdio_read = mdio_ops->read; + phy->mdio.mdio_write = mdio_ops->write; } } diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index fa06994f9737..082cdb28b510 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -589,7 +589,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) } cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; - cmd->phy_address = p->phy->addr; + cmd->phy_address = p->phy->mdio.prtad; cmd->transceiver = XCVR_EXTERNAL; cmd->autoneg = p->link_config.autoneg; cmd->maxtxpkt = 0; @@ -849,39 +849,9 @@ static const struct ethtool_ops t1_ethtool_ops = { static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) { struct adapter *adapter = dev->ml_priv; - struct mii_ioctl_data *data = if_mii(req); - - switch (cmd) { - case SIOCGMIIPHY: - data->phy_id = adapter->port[dev->if_port].phy->addr; - /* FALLTHRU */ - case SIOCGMIIREG: { - struct cphy *phy = adapter->port[dev->if_port].phy; - u32 val; - - if (!phy->mdio_read) - return -EOPNOTSUPP; - phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f, - &val); - data->val_out = val; - break; - } - case SIOCSMIIREG: { - struct cphy *phy = adapter->port[dev->if_port].phy; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (!phy->mdio_write) - return -EOPNOTSUPP; - phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f, - data->val_in); - break; - } + struct mdio_if_info *mdio = &adapter->port[dev->if_port].phy->mdio; - default: - return -EOPNOTSUPP; - } - return 0; + return mdio_mii_ioctl(mdio, if_mii(req), cmd); } static int t1_change_mtu(struct net_device *dev, int new_mtu) diff --git a/drivers/net/chelsio/mv88x201x.c b/drivers/net/chelsio/mv88x201x.c index cd856041af34..29e0cba48d53 100644 --- a/drivers/net/chelsio/mv88x201x.c +++ b/drivers/net/chelsio/mv88x201x.c @@ -53,7 +53,7 @@ static int led_init(struct cphy *cphy) * Writing these bits maps control to another * register. mmd(0x1) addr(0x7) */ - mdio_write(cphy, 0x3, 0x8304, 0xdddd); + cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8304, 0xdddd); return 0; } @@ -62,14 +62,14 @@ static int led_link(struct cphy *cphy, u32 do_enable) u32 led = 0; #define LINK_ENABLE_BIT 0x1 - mdio_read(cphy, 0x1, 0x7, &led); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, &led); if (do_enable & LINK_ENABLE_BIT) { led |= LINK_ENABLE_BIT; - mdio_write(cphy, 0x1, 0x7, led); + cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led); } else { led &= ~LINK_ENABLE_BIT; - mdio_write(cphy, 0x1, 0x7, led); + cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led); } return 0; } @@ -86,7 +86,7 @@ static int mv88x201x_reset(struct cphy *cphy, int wait) static int mv88x201x_interrupt_enable(struct cphy *cphy) { /* Enable PHY LASI interrupts. */ - mdio_write(cphy, 0x1, 0x9002, 0x1); + cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, 0x9002, 0x1); /* Enable Marvell interrupts through Elmer0. */ if (t1_is_asic(cphy->adapter)) { @@ -102,7 +102,7 @@ static int mv88x201x_interrupt_enable(struct cphy *cphy) static int mv88x201x_interrupt_disable(struct cphy *cphy) { /* Disable PHY LASI interrupts. */ - mdio_write(cphy, 0x1, 0x9002, 0x0); + cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, 0x9002, 0x0); /* Disable Marvell interrupts through Elmer0. */ if (t1_is_asic(cphy->adapter)) { @@ -122,25 +122,25 @@ static int mv88x201x_interrupt_clear(struct cphy *cphy) #ifdef MV88x2010_LINK_STATUS_BUGS /* Required to read twice before clear takes affect. */ - mdio_read(cphy, 0x1, 0x9003, &val); - mdio_read(cphy, 0x1, 0x9004, &val); - mdio_read(cphy, 0x1, 0x9005, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9003, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9004, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9005, &val); /* Read this register after the others above it else * the register doesn't clear correctly. */ - mdio_read(cphy, 0x1, 0x1, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val); #endif /* Clear link status. */ - mdio_read(cphy, 0x1, 0x1, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val); /* Clear PHY LASI interrupts. */ - mdio_read(cphy, 0x1, 0x9005, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9005, &val); #ifdef MV88x2010_LINK_STATUS_BUGS /* Do it again. */ - mdio_read(cphy, 0x1, 0x9003, &val); - mdio_read(cphy, 0x1, 0x9004, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9003, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, 0x9004, &val); #endif /* Clear Marvell interrupts through Elmer0. */ @@ -172,13 +172,12 @@ static int mv88x201x_get_link_status(struct cphy *cphy, int *link_ok, int *speed, int *duplex, int *fc) { u32 val = 0; -#define LINK_STATUS_BIT 0x4 if (link_ok) { /* Read link status. */ - mdio_read(cphy, 0x1, 0x1, &val); - val &= LINK_STATUS_BIT; - *link_ok = (val == LINK_STATUS_BIT); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val); + val &= MDIO_STAT1_LSTATUS; + *link_ok = (val == MDIO_STAT1_LSTATUS); /* Turn on/off Link LED */ led_link(cphy, *link_ok); } @@ -205,6 +204,8 @@ static struct cphy_ops mv88x201x_ops = { .interrupt_handler = mv88x201x_interrupt_handler, .get_link_status = mv88x201x_get_link_status, .set_loopback = mv88x201x_set_loopback, + .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | + MDIO_DEVS_PHYXS | MDIO_DEVS_WIS), }; static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr, @@ -219,12 +220,12 @@ static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr, cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops); /* Commands the PHY to enable XFP's clock. */ - mdio_read(cphy, 0x3, 0x8300, &val); - mdio_write(cphy, 0x3, 0x8300, val | 1); + cphy_mdio_read(cphy, MDIO_MMD_PCS, 0x8300, &val); + cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8300, val | 1); /* Clear link status. Required because of a bug in the PHY. */ - mdio_read(cphy, 0x1, 0x8, &val); - mdio_read(cphy, 0x3, 0x8, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT2, &val); + cphy_mdio_read(cphy, MDIO_MMD_PCS, MDIO_STAT2, &val); /* Allows for Link,Ack LED turn on/off */ led_init(cphy); diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c index 040acd29995a..977c7e08b0e0 100644 --- a/drivers/net/chelsio/my3126.c +++ b/drivers/net/chelsio/my3126.c @@ -43,11 +43,11 @@ static int my3126_interrupt_handler(struct cphy *cphy) adapter = cphy->adapter; if (cphy->count == 50) { - mdio_read(cphy, 0x1, 0x1, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val); val16 = (u16) val; status = cphy->bmsr ^ val16; - if (status & BMSR_LSTATUS) + if (status & MDIO_STAT1_LSTATUS) t1_link_changed(adapter, 0); cphy->bmsr = val16; @@ -114,14 +114,14 @@ static int my3126_get_link_status(struct cphy *cphy, adapter_t *adapter; adapter = cphy->adapter; - mdio_read(cphy, 0x1, 0x1, &val); + cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val); val16 = (u16) val; /* Populate elmer_gpo with the register value */ t1_tpi_read(adapter, A_ELMER0_GPO, &val); cphy->elmer_gpo = val; - *link_ok = (val16 & BMSR_LSTATUS); + *link_ok = (val16 & MDIO_STAT1_LSTATUS); if (*link_ok) { /* Turn on the LED. */ @@ -163,6 +163,8 @@ static struct cphy_ops my3126_ops = { .interrupt_handler = my3126_interrupt_handler, .get_link_status = my3126_get_link_status, .set_loopback = my3126_set_loopback, + .mmds = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | + MDIO_DEVS_PHYXS), }; static struct cphy *my3126_phy_create(adapter_t *adapter, diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c index 7adf30230c4f..2564312b3056 100644 --- a/drivers/net/chelsio/subr.c +++ b/drivers/net/chelsio/subr.c @@ -284,32 +284,29 @@ static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi) /* * Elmer MI1 MDIO read/write operations. */ -static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *valp) +static int mi1_mdio_read(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr) { + struct adapter *adapter = dev->ml_priv; u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr); - - if (mmd_addr) - return -EINVAL; + unsigned int val; spin_lock(&adapter->tpi_lock); __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ); mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); - __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); + __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val); spin_unlock(&adapter->tpi_lock); - return 0; + return val; } -static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val) +static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr, u16 val) { + struct adapter *adapter = dev->ml_priv; u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr); - if (mmd_addr) - return -EINVAL; - spin_lock(&adapter->tpi_lock); __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); @@ -324,16 +321,19 @@ static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr, static const struct mdio_ops mi1_mdio_ops = { .init = mi1_mdio_init, .read = mi1_mdio_read, - .write = mi1_mdio_write + .write = mi1_mdio_write, + .mode_support = MDIO_SUPPORTS_C22 }; #endif #endif -static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *valp) +static int mi1_mdio_ext_read(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr) { + struct adapter *adapter = dev->ml_priv; u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); + unsigned int val; spin_lock(&adapter->tpi_lock); @@ -350,14 +350,15 @@ static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); /* Read the data. */ - __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); + __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val); spin_unlock(&adapter->tpi_lock); - return 0; + return val; } -static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val) +static int mi1_mdio_ext_write(struct net_device *dev, int phy_addr, + int mmd_addr, u16 reg_addr, u16 val) { + struct adapter *adapter = dev->ml_priv; u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); spin_lock(&adapter->tpi_lock); @@ -380,7 +381,8 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr, static const struct mdio_ops mi1_mdio_ext_ops = { .init = mi1_mdio_init, .read = mi1_mdio_ext_read, - .write = mi1_mdio_ext_write + .write = mi1_mdio_ext_write, + .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22 }; enum { @@ -1140,6 +1142,7 @@ int __devinit t1_init_sw_modules(adapter_t *adapter, adapter->name, i); goto error; } + adapter->port[i].phy->mdio.dev = adapter->port[i].dev; adapter->port[i].mac = mac = bi->gmac->create(adapter, i); if (!mac) { -- GitLab From 0f07c4ee8c800923ae7918c231532a9256233eed Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:07:20 +0000 Subject: [PATCH 0923/6080] cxgb3: Use generic MDIO definitions and mdio_mii_ioctl() Compile-tested only. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/Kconfig | 1 + drivers/net/cxgb3/ael1002.c | 146 +++++++++++++++++---------------- drivers/net/cxgb3/common.h | 53 ++++++------ drivers/net/cxgb3/cxgb3_main.c | 71 +++------------- drivers/net/cxgb3/t3_hw.c | 78 ++++++++++-------- drivers/net/cxgb3/vsc8211.c | 70 +++++++++------- 6 files changed, 195 insertions(+), 224 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 1ccd54714c4c..435bbc96444f 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2483,6 +2483,7 @@ config CHELSIO_T3 tristate "Chelsio Communications T3 10Gb Ethernet support" depends on CHELSIO_T3_DEPENDS select FW_LOADER + select MDIO help This driver supports Chelsio T3-based gigabit and 10Gb Ethernet adapters. diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c index e1b22490ff59..bebc00d2424d 100644 --- a/drivers/net/cxgb3/ael1002.c +++ b/drivers/net/cxgb3/ael1002.c @@ -33,14 +33,6 @@ #include "regs.h" enum { - PMD_RSD = 10, /* PMA/PMD receive signal detect register */ - PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */ - PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */ - XS_LN_STAT = 24 /* XS lane status register */ -}; - -enum { - AEL100X_TX_DISABLE = 9, AEL100X_TX_CONFIG1 = 0xc002, AEL1002_PWR_DOWN_HI = 0xc011, AEL1002_PWR_DOWN_LO = 0xc012, @@ -74,8 +66,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) for (err = 0; rv->mmd_addr && !err; rv++) { if (rv->clear_bits == 0xffff) - err = mdio_write(phy, rv->mmd_addr, rv->reg_addr, - rv->set_bits); + err = t3_mdio_write(phy, rv->mmd_addr, rv->reg_addr, + rv->set_bits); else err = t3_mdio_change_bits(phy, rv->mmd_addr, rv->reg_addr, rv->clear_bits, @@ -86,7 +78,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) static void ael100x_txon(struct cphy *phy) { - int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; + int tx_on_gpio = + phy->mdio.prtad == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; msleep(100); t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); @@ -97,10 +90,11 @@ static int ael1002_power_down(struct cphy *phy, int enable) { int err; - err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable); + err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable); if (!err) - err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, - BMCR_PDOWN, enable ? BMCR_PDOWN : 0); + err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, + MDIO_MMD_PMAPMD, MDIO_CTRL1, + MDIO_CTRL1_LPOWER, enable); return err; } @@ -109,11 +103,11 @@ static int ael1002_reset(struct cphy *phy, int wait) int err; if ((err = ael1002_power_down(phy, 0)) || - (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) || - (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) || - (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) || - (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) || - (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN, + (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) || + (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) || + (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) || + (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) || + (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN, 0, 1 << 5))) return err; return 0; @@ -132,12 +126,15 @@ static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed, { if (link_ok) { unsigned int stat0, stat1, stat2; - int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); + int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, + MDIO_PMA_RXDET, &stat0); if (!err) - err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1); + err = t3_mdio_read(phy, MDIO_MMD_PCS, + MDIO_PCS_10GBRT_STAT1, &stat1); if (!err) - err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); + err = t3_mdio_read(phy, MDIO_MMD_PHYXS, + MDIO_PHYXS_LNSTAT, &stat2); if (err) return err; *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; @@ -157,6 +154,7 @@ static struct cphy_ops ael1002_ops = { .intr_handler = ael1002_intr_noop, .get_link_status = get_link_status_r, .power_down = ael1002_power_down, + .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, @@ -171,13 +169,13 @@ int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, static int ael1006_reset(struct cphy *phy, int wait) { - return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); + return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait); } static int ael1006_power_down(struct cphy *phy, int enable) { - return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, - BMCR_PDOWN, enable ? BMCR_PDOWN : 0); + return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD, + MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable); } static struct cphy_ops ael1006_ops = { @@ -188,6 +186,7 @@ static struct cphy_ops ael1006_ops = { .intr_handler = t3_phy_lasi_intr_handler, .get_link_status = get_link_status_r, .power_down = ael1006_power_down, + .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, @@ -203,9 +202,9 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, static int ael2005_setup_sr_edc(struct cphy *phy) { static struct reg_val regs[] = { - { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 }, - { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a }, - { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 }, + { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 }, + { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a }, + { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 }, { 0, 0, 0, 0 } }; static u16 sr_edc[] = { @@ -490,8 +489,8 @@ static int ael2005_setup_sr_edc(struct cphy *phy) msleep(50); for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) - err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i], - sr_edc[i + 1]); + err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i], + sr_edc[i + 1]); if (!err) phy->priv = edc_sr; return err; @@ -500,12 +499,12 @@ static int ael2005_setup_sr_edc(struct cphy *phy) static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) { static struct reg_val regs[] = { - { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 }, + { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 }, { 0, 0, 0, 0 } }; static struct reg_val preemphasis[] = { - { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 }, - { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 }, + { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 }, + { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 }, { 0, 0, 0, 0 } }; static u16 twinax_edc[] = { @@ -887,8 +886,8 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) msleep(50); for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) - err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], - twinax_edc[i + 1]); + err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], + twinax_edc[i + 1]); if (!err) phy->priv = edc_twinax; return err; @@ -899,26 +898,26 @@ static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) int i, err; unsigned int stat, data; - err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, - (dev_addr << 8) | (1 << 8) | word_addr); + err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL, + (dev_addr << 8) | (1 << 8) | word_addr); if (err) return err; for (i = 0; i < 5; i++) { msleep(1); - err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); + err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat); if (err) return err; if ((stat & 3) == 1) { - err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, - &data); + err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA, + &data); if (err) return err; return data >> 8; } } CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n", - phy->addr, word_addr); + phy->mdio.prtad, word_addr); return -ETIMEDOUT; } @@ -927,7 +926,7 @@ static int get_module_type(struct cphy *phy, int delay_ms) int v; unsigned int stat; - v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); + v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, &stat); if (v) return v; @@ -971,48 +970,48 @@ unknown: static int ael2005_intr_enable(struct cphy *phy) { - int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200); + int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200); return err ? err : t3_phy_lasi_intr_enable(phy); } static int ael2005_intr_disable(struct cphy *phy) { - int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100); + int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100); return err ? err : t3_phy_lasi_intr_disable(phy); } static int ael2005_intr_clear(struct cphy *phy) { - int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00); + int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00); return err ? err : t3_phy_lasi_intr_clear(phy); } static int ael2005_reset(struct cphy *phy, int wait) { static struct reg_val regs0[] = { - { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 }, - { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 }, - { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 }, - { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, - { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 }, - { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, - { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 }, + { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 }, + { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 }, + { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 }, + { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, + { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 }, + { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, + { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 }, { 0, 0, 0, 0 } }; static struct reg_val regs1[] = { - { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 }, - { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 }, + { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 }, + { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 }, { 0, 0, 0, 0 } }; int err; unsigned int lasi_ctrl; - err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); + err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_CTRL, &lasi_ctrl); if (err) return err; - err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0); + err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 0); if (err) return err; @@ -1051,13 +1050,13 @@ static int ael2005_intr_handler(struct cphy *phy) unsigned int stat; int ret, edc_needed, cause = 0; - ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat); + ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat); if (ret) return ret; if (stat & AEL2005_MODDET_IRQ) { - ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, - 0xd00); + ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, + 0xd00); if (ret) return ret; @@ -1098,6 +1097,7 @@ static struct cphy_ops ael2005_ops = { .intr_handler = ael2005_intr_handler, .get_link_status = get_link_status_r, .power_down = ael1002_power_down, + .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, @@ -1107,7 +1107,7 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | SUPPORTED_IRQ, "10GBASE-R"); msleep(125); - return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0, + return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0, 1 << 5); } @@ -1119,12 +1119,15 @@ static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, { if (link_ok) { unsigned int stat0, stat1, stat2; - int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); + int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, + MDIO_PMA_RXDET, &stat0); if (!err) - err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1); + err = t3_mdio_read(phy, MDIO_MMD_PCS, + MDIO_PCS_10GBX_STAT1, &stat1); if (!err) - err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); + err = t3_mdio_read(phy, MDIO_MMD_PHYXS, + MDIO_PHYXS_LNSTAT, &stat2); if (err) return err; *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; @@ -1144,6 +1147,7 @@ static struct cphy_ops qt2045_ops = { .intr_handler = t3_phy_lasi_intr_handler, .get_link_status = get_link_status_x, .power_down = ael1006_power_down, + .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, }; int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, @@ -1159,9 +1163,10 @@ int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, * Some cards where the PHY is supposed to be at address 0 actually * have it at 1. */ - if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) && + if (!phy_addr && + !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) && stat == 0xffff) - phy->addr = 1; + phy->mdio.prtad = 1; return 0; } @@ -1175,15 +1180,16 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, { if (link_ok) { unsigned int status; + int prtad = phy->mdio.prtad; status = t3_read_reg(phy->adapter, - XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | + XGM_REG(A_XGM_SERDES_STAT0, prtad)) | t3_read_reg(phy->adapter, - XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | + XGM_REG(A_XGM_SERDES_STAT1, prtad)) | t3_read_reg(phy->adapter, - XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | + XGM_REG(A_XGM_SERDES_STAT2, prtad)) | t3_read_reg(phy->adapter, - XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); + XGM_REG(A_XGM_SERDES_STAT3, prtad)); *link_ok = !(status & F_LOWSIG0); } if (speed) @@ -1211,7 +1217,7 @@ static struct cphy_ops xaui_direct_ops = { int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { - cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, + cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops, SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, "10GBASE-CX4"); return 0; diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index e508dc32f3ec..3147789aecec 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include "version.h" #define CH_ERR(adap, fmt, ...) dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__) @@ -184,10 +184,11 @@ struct cphy; struct adapter; struct mdio_ops { - int (*read)(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *val); - int (*write)(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val); + int (*read)(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr); + int (*write)(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr, u16 val); + unsigned mode_support; }; struct adapter_info { @@ -520,17 +521,6 @@ enum { MAC_RXFIFO_SIZE = 32768 }; -/* IEEE 802.3 specified MDIO devices */ -enum { - MDIO_DEV_PMA_PMD = 1, - MDIO_DEV_WIS = 2, - MDIO_DEV_PCS = 3, - MDIO_DEV_XGXS = 4, - MDIO_DEV_ANEG = 7, - MDIO_DEV_VEND1 = 30, - MDIO_DEV_VEND2 = 31 -}; - /* LASI control and status registers */ enum { RX_ALARM_CTRL = 0x9000, @@ -583,11 +573,12 @@ struct cphy_ops { int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed, int *duplex, int *fc); int (*power_down)(struct cphy *phy, int enable); + + u32 mmds; }; /* A PHY instance */ struct cphy { - u8 addr; /* PHY address */ u8 modtype; /* PHY module type */ short priv; /* scratch pad */ unsigned int caps; /* PHY capabilities */ @@ -595,23 +586,23 @@ struct cphy { const char *desc; /* PHY description */ unsigned long fifo_errors; /* FIFO over/under-flows */ const struct cphy_ops *ops; /* PHY operations */ - int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *val); - int (*mdio_write)(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val); + struct mdio_if_info mdio; }; /* Convenience MDIO read/write wrappers */ -static inline int mdio_read(struct cphy *phy, int mmd, int reg, - unsigned int *valp) +static inline int t3_mdio_read(struct cphy *phy, int mmd, int reg, + unsigned int *valp) { - return phy->mdio_read(phy->adapter, phy->addr, mmd, reg, valp); + int rc = phy->mdio.mdio_read(phy->mdio.dev, phy->mdio.prtad, mmd, reg); + *valp = (rc >= 0) ? rc : -1; + return (rc >= 0) ? 0 : rc; } -static inline int mdio_write(struct cphy *phy, int mmd, int reg, - unsigned int val) +static inline int t3_mdio_write(struct cphy *phy, int mmd, int reg, + unsigned int val) { - return phy->mdio_write(phy->adapter, phy->addr, mmd, reg, val); + return phy->mdio.mdio_write(phy->mdio.dev, phy->mdio.prtad, mmd, + reg, val); } /* Convenience initializer */ @@ -620,14 +611,16 @@ static inline void cphy_init(struct cphy *phy, struct adapter *adapter, const struct mdio_ops *mdio_ops, unsigned int caps, const char *desc) { - phy->addr = phy_addr; phy->caps = caps; phy->adapter = adapter; phy->desc = desc; phy->ops = phy_ops; if (mdio_ops) { - phy->mdio_read = mdio_ops->read; - phy->mdio_write = mdio_ops->write; + phy->mdio.prtad = phy_addr; + phy->mdio.mmds = phy_ops->mmds; + phy->mdio.mode_support = mdio_ops->mode_support; + phy->mdio.mdio_read = mdio_ops->read; + phy->mdio.mdio_write = mdio_ops->write; } } diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 7ea48414c6cb..0b87fee023f5 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include @@ -1593,7 +1593,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) } cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; - cmd->phy_address = p->phy.addr; + cmd->phy_address = p->phy.mdio.prtad; cmd->transceiver = XCVR_EXTERNAL; cmd->autoneg = p->link_config.autoneg; cmd->maxtxpkt = 0; @@ -2308,70 +2308,25 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) struct mii_ioctl_data *data = if_mii(req); struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; - int ret, mmd; switch (cmd) { - case SIOCGMIIPHY: - data->phy_id = pi->phy.addr; + case SIOCGMIIREG: + case SIOCSMIIREG: + /* Convert phy_id from older PRTAD/DEVAD format */ + if (is_10G(adapter) && + !mdio_phy_id_is_c45(data->phy_id) && + (data->phy_id & 0x1f00) && + !(data->phy_id & 0xe0e0)) + data->phy_id = mdio_phy_id_c45(data->phy_id >> 8, + data->phy_id & 0x1f); /* FALLTHRU */ - case SIOCGMIIREG:{ - u32 val; - struct cphy *phy = &pi->phy; - - if (!phy->mdio_read) - return -EOPNOTSUPP; - if (is_10G(adapter)) { - mmd = data->phy_id >> 8; - if (!mmd) - mmd = MDIO_DEV_PCS; - else if (mmd > MDIO_DEV_VEND2) - return -EINVAL; - - ret = - phy->mdio_read(adapter, data->phy_id & 0x1f, - mmd, data->reg_num, &val); - } else - ret = - phy->mdio_read(adapter, data->phy_id & 0x1f, - 0, data->reg_num & 0x1f, - &val); - if (!ret) - data->val_out = val; - break; - } - case SIOCSMIIREG:{ - struct cphy *phy = &pi->phy; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (!phy->mdio_write) - return -EOPNOTSUPP; - if (is_10G(adapter)) { - mmd = data->phy_id >> 8; - if (!mmd) - mmd = MDIO_DEV_PCS; - else if (mmd > MDIO_DEV_VEND2) - return -EINVAL; - - ret = - phy->mdio_write(adapter, - data->phy_id & 0x1f, mmd, - data->reg_num, - data->val_in); - } else - ret = - phy->mdio_write(adapter, - data->phy_id & 0x1f, 0, - data->reg_num & 0x1f, - data->val_in); - break; - } + case SIOCGMIIPHY: + return mdio_mii_ioctl(&pi->phy.mdio, data, cmd); case SIOCCHIOCTL: return cxgb_extension_ioctl(dev, req->ifr_data); default: return -EOPNOTSUPP; } - return ret; } static int cxgb_change_mtu(struct net_device *dev, int new_mtu) diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index e1bd690ff831..1dd1637663a3 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -204,35 +204,33 @@ static void mi1_init(struct adapter *adap, const struct adapter_info *ai) /* * MI1 read/write operations for clause 22 PHYs. */ -static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *valp) +static int t3_mi1_read(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr) { + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; int ret; u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); - if (mmd_addr) - return -EINVAL; - mutex_lock(&adapter->mdio_lock); t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); t3_write_reg(adapter, A_MI1_ADDR, addr); t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); if (!ret) - *valp = t3_read_reg(adapter, A_MI1_DATA); + ret = t3_read_reg(adapter, A_MI1_DATA); mutex_unlock(&adapter->mdio_lock); return ret; } -static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val) +static int t3_mi1_write(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr, u16 val) { + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; int ret; u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); - if (mmd_addr) - return -EINVAL; - mutex_lock(&adapter->mdio_lock); t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1)); t3_write_reg(adapter, A_MI1_ADDR, addr); @@ -244,8 +242,9 @@ static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, } static const struct mdio_ops mi1_mdio_ops = { - t3_mi1_read, - t3_mi1_write + .read = t3_mi1_read, + .write = t3_mi1_write, + .mode_support = MDIO_SUPPORTS_C22 }; /* @@ -268,9 +267,11 @@ static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr, /* * MI1 read/write operations for indirect-addressed PHYs. */ -static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int *valp) +static int mi1_ext_read(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr) { + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; int ret; mutex_lock(&adapter->mdio_lock); @@ -280,15 +281,17 @@ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10); if (!ret) - *valp = t3_read_reg(adapter, A_MI1_DATA); + ret = t3_read_reg(adapter, A_MI1_DATA); } mutex_unlock(&adapter->mdio_lock); return ret; } -static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, - int reg_addr, unsigned int val) +static int mi1_ext_write(struct net_device *dev, int phy_addr, int mmd_addr, + u16 reg_addr, u16 val) { + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; int ret; mutex_lock(&adapter->mdio_lock); @@ -304,8 +307,9 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr, } static const struct mdio_ops mi1_mdio_ext_ops = { - mi1_ext_read, - mi1_ext_write + .read = mi1_ext_read, + .write = mi1_ext_write, + .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22 }; /** @@ -325,10 +329,10 @@ int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear, int ret; unsigned int val; - ret = mdio_read(phy, mmd, reg, &val); + ret = t3_mdio_read(phy, mmd, reg, &val); if (!ret) { val &= ~clear; - ret = mdio_write(phy, mmd, reg, val | set); + ret = t3_mdio_write(phy, mmd, reg, val | set); } return ret; } @@ -348,15 +352,16 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait) int err; unsigned int ctl; - err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET); + err = t3_mdio_change_bits(phy, mmd, MDIO_CTRL1, MDIO_CTRL1_LPOWER, + MDIO_CTRL1_RESET); if (err || !wait) return err; do { - err = mdio_read(phy, mmd, MII_BMCR, &ctl); + err = t3_mdio_read(phy, mmd, MDIO_CTRL1, &ctl); if (err) return err; - ctl &= BMCR_RESET; + ctl &= MDIO_CTRL1_RESET; if (ctl) msleep(1); } while (ctl && --wait); @@ -377,7 +382,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) int err; unsigned int val = 0; - err = mdio_read(phy, 0, MII_CTRL1000, &val); + err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_CTRL1000, &val); if (err) return err; @@ -387,7 +392,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) if (advert & ADVERTISED_1000baseT_Full) val |= ADVERTISE_1000FULL; - err = mdio_write(phy, 0, MII_CTRL1000, val); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_CTRL1000, val); if (err) return err; @@ -404,7 +409,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert) val |= ADVERTISE_PAUSE_CAP; if (advert & ADVERTISED_Asym_Pause) val |= ADVERTISE_PAUSE_ASYM; - return mdio_write(phy, 0, MII_ADVERTISE, val); + return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val); } /** @@ -427,7 +432,7 @@ int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert) val |= ADVERTISE_1000XPAUSE; if (advert & ADVERTISED_Asym_Pause) val |= ADVERTISE_1000XPSE_ASYM; - return mdio_write(phy, 0, MII_ADVERTISE, val); + return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val); } /** @@ -444,7 +449,7 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) int err; unsigned int ctl; - err = mdio_read(phy, 0, MII_BMCR, &ctl); + err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_BMCR, &ctl); if (err) return err; @@ -462,30 +467,30 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex) } if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */ ctl |= BMCR_ANENABLE; - return mdio_write(phy, 0, MII_BMCR, ctl); + return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_BMCR, ctl); } int t3_phy_lasi_intr_enable(struct cphy *phy) { - return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1); + return t3_mdio_write(phy, MDIO_MMD_PMAPMD, LASI_CTRL, 1); } int t3_phy_lasi_intr_disable(struct cphy *phy) { - return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0); + return t3_mdio_write(phy, MDIO_MMD_PMAPMD, LASI_CTRL, 0); } int t3_phy_lasi_intr_clear(struct cphy *phy) { u32 val; - return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val); + return t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_STAT, &val); } int t3_phy_lasi_intr_handler(struct cphy *phy) { unsigned int status; - int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status); + int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, LASI_STAT, &status); if (err) return err; @@ -3863,6 +3868,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, ai->mdio_ops); if (ret) return ret; + p->phy.mdio.dev = adapter->port[i]; mac_prep(&p->mac, adapter, j); /* @@ -3918,7 +3924,7 @@ int t3_replay_prep_adapter(struct adapter *adapter) ; pti = &port_types[adapter->params.vpd.port_type[j]]; - ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL); + ret = pti->phy_prep(&p->phy, adapter, p->phy.mdio.prtad, NULL); if (ret) return ret; p->phy.ops->power_down(&p->phy, 1); diff --git a/drivers/net/cxgb3/vsc8211.c b/drivers/net/cxgb3/vsc8211.c index d07130971b8f..4f9a1c2724f4 100644 --- a/drivers/net/cxgb3/vsc8211.c +++ b/drivers/net/cxgb3/vsc8211.c @@ -91,17 +91,18 @@ enum { */ static int vsc8211_reset(struct cphy *cphy, int wait) { - return t3_phy_reset(cphy, 0, 0); + return t3_phy_reset(cphy, MDIO_DEVAD_NONE, 0); } static int vsc8211_intr_enable(struct cphy *cphy) { - return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, INTR_MASK); + return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE, + INTR_MASK); } static int vsc8211_intr_disable(struct cphy *cphy) { - return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, 0); + return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE, 0); } static int vsc8211_intr_clear(struct cphy *cphy) @@ -109,18 +110,20 @@ static int vsc8211_intr_clear(struct cphy *cphy) u32 val; /* Clear PHY interrupts by reading the register. */ - return mdio_read(cphy, 0, VSC8211_INTR_STATUS, &val); + return t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &val); } static int vsc8211_autoneg_enable(struct cphy *cphy) { - return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, + return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR, + BMCR_PDOWN | BMCR_ISOLATE, BMCR_ANENABLE | BMCR_ANRESTART); } static int vsc8211_autoneg_restart(struct cphy *cphy) { - return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, + return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR, + BMCR_PDOWN | BMCR_ISOLATE, BMCR_ANRESTART); } @@ -130,9 +133,9 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok, unsigned int bmcr, status, lpa, adv; int err, sp = -1, dplx = -1, pause = 0; - err = mdio_read(cphy, 0, MII_BMCR, &bmcr); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr); if (!err) - err = mdio_read(cphy, 0, MII_BMSR, &status); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status); if (err) return err; @@ -142,7 +145,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok, * once more to get the current link state. */ if (!(status & BMSR_LSTATUS)) - err = mdio_read(cphy, 0, MII_BMSR, &status); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, + &status); if (err) return err; *link_ok = (status & BMSR_LSTATUS) != 0; @@ -156,7 +160,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok, else sp = SPEED_10; } else if (status & BMSR_ANEGCOMPLETE) { - err = mdio_read(cphy, 0, VSC8211_AUX_CTRL_STAT, &status); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_AUX_CTRL_STAT, + &status); if (err) return err; @@ -170,9 +175,11 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok, sp = SPEED_1000; if (fc && dplx == DUPLEX_FULL) { - err = mdio_read(cphy, 0, MII_LPA, &lpa); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA, + &lpa); if (!err) - err = mdio_read(cphy, 0, MII_ADVERTISE, &adv); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, + MII_ADVERTISE, &adv); if (err) return err; @@ -202,9 +209,9 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok, unsigned int bmcr, status, lpa, adv; int err, sp = -1, dplx = -1, pause = 0; - err = mdio_read(cphy, 0, MII_BMCR, &bmcr); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr); if (!err) - err = mdio_read(cphy, 0, MII_BMSR, &status); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status); if (err) return err; @@ -214,7 +221,8 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok, * once more to get the current link state. */ if (!(status & BMSR_LSTATUS)) - err = mdio_read(cphy, 0, MII_BMSR, &status); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, + &status); if (err) return err; *link_ok = (status & BMSR_LSTATUS) != 0; @@ -228,9 +236,10 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok, else sp = SPEED_10; } else if (status & BMSR_ANEGCOMPLETE) { - err = mdio_read(cphy, 0, MII_LPA, &lpa); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA, &lpa); if (!err) - err = mdio_read(cphy, 0, MII_ADVERTISE, &adv); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_ADVERTISE, + &adv); if (err) return err; @@ -270,23 +279,23 @@ static int vsc8211_set_automdi(struct cphy *phy, int enable) { int err; - err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0x52b5); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0x52b5); if (err) return err; - err = mdio_write(phy, 0, 18, 0x12); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 18, 0x12); if (err) return err; - err = mdio_write(phy, 0, 17, enable ? 0x2803 : 0x3003); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 17, enable ? 0x2803 : 0x3003); if (err) return err; - err = mdio_write(phy, 0, 16, 0x87fa); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 16, 0x87fa); if (err) return err; - err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0); if (err) return err; @@ -315,7 +324,7 @@ static int vsc8211_intr_handler(struct cphy *cphy) unsigned int cause; int err, cphy_cause = 0; - err = mdio_read(cphy, 0, VSC8211_INTR_STATUS, &cause); + err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &cause); if (err) return err; @@ -367,12 +376,13 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter, SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T"); msleep(20); /* PHY needs ~10ms to start responding to MDIO */ - err = mdio_read(phy, 0, VSC8211_EXT_CTRL, &val); + err = t3_mdio_read(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL, &val); if (err) return err; if (val & VSC_CTRL_MEDIA_MODE_HI) { /* copper interface, just need to configure the LEDs */ - return mdio_write(phy, 0, VSC8211_LED_CTRL, 0x100); + return t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_LED_CTRL, + 0x100); } phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | @@ -380,20 +390,20 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter, phy->desc = "1000BASE-X"; phy->ops = &vsc8211_fiber_ops; - err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 1); if (err) return err; - err = mdio_write(phy, 0, VSC8211_SIGDET_CTRL, 1); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_SIGDET_CTRL, 1); if (err) return err; - err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0); if (err) return err; - err = mdio_write(phy, 0, VSC8211_EXT_CTRL, - val | VSC_CTRL_CLAUSE37_VIEW); + err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL, + val | VSC_CTRL_CLAUSE37_VIEW); if (err) return err; -- GitLab From 6b73e10d2d89f9ce773f9b47d61b195936d059ba Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:08:58 +0000 Subject: [PATCH 0924/6080] ixgbe: Use generic MDIO definitions and functions Compile-tested only. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/Kconfig | 1 + drivers/net/ixgbe/ixgbe_82598.c | 33 ++++++------ drivers/net/ixgbe/ixgbe_82599.c | 17 +++--- drivers/net/ixgbe/ixgbe_main.c | 42 +++++++++++++++ drivers/net/ixgbe/ixgbe_phy.c | 95 +++++++++++---------------------- drivers/net/ixgbe/ixgbe_type.h | 33 ++---------- 6 files changed, 102 insertions(+), 119 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 435bbc96444f..b8727d54bdbb 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2519,6 +2519,7 @@ config ENIC config IXGBE tristate "Intel(R) 10GbE PCI Express adapters support" depends on PCI && INET + select MDIO ---help--- This driver supports Intel(R) 10GbE PCI Express family of adapters. For more information on how to identify your adapter, go diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 03eb54f4f1cc..e051964347e4 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -229,14 +229,13 @@ static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, *speed = 0; *autoneg = true; - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, + status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, &speed_ability); if (status == 0) { - if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) + if (speed_ability & MDIO_SPEED_10G) *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) + if (speed_ability & MDIO_PMA_SPEED_1000) *speed |= IXGBE_LINK_SPEED_1GB_FULL; } @@ -526,9 +525,9 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, * clear indicates active; set indicates inactive. */ if (hw->phy.type == ixgbe_phy_nl) { - hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); - hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); - hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV, + hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); + hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); + hw->phy.ops.read_reg(hw, 0xC00C, MDIO_MMD_PMAPMD, &adapt_comp_reg); if (link_up_wait_to_complete) { for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { @@ -541,10 +540,10 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, } msleep(100); hw->phy.ops.read_reg(hw, 0xC79F, - IXGBE_TWINAX_DEV, + MDIO_MMD_PMAPMD, &link_reg); hw->phy.ops.read_reg(hw, 0xC00C, - IXGBE_TWINAX_DEV, + MDIO_MMD_PMAPMD, &adapt_comp_reg); } } else { @@ -990,14 +989,14 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK); hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, + MDIO_MMD_PMAPMD, sfp_addr); /* Poll status */ for (i = 0; i < 100; i++) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, + MDIO_MMD_PMAPMD, &sfp_stat); sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK; if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS) @@ -1013,7 +1012,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, /* Read data */ hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data); + MDIO_MMD_PMAPMD, &sfp_data); *eeprom_data = (u8)(sfp_data >> 8); } else { @@ -1045,13 +1044,13 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) * physical layer because 10GBase-T PHYs use LMS = KX4/KX */ if (hw->phy.type == ixgbe_phy_tn || hw->phy.type == ixgbe_phy_cu_unknown) { - hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); - if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) + hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, + &ext_ability); + if (ext_ability & MDIO_PMA_EXTABLE_10GBT) physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; - if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) + if (ext_ability & MDIO_PMA_EXTABLE_1000BT) physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; - if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) + if (ext_ability & MDIO_PMA_EXTABLE_100BTX) physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; goto out; } diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 9e824b450416..6038ed14c9f9 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -314,14 +314,13 @@ static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw, *speed = 0; *autoneg = true; - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, + status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, &speed_ability); if (status == 0) { - if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) + if (speed_ability & MDIO_SPEED_10G) *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) + if (speed_ability & MDIO_PMA_SPEED_1000) *speed |= IXGBE_LINK_SPEED_1GB_FULL; } @@ -1153,13 +1152,13 @@ u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) if (hw->phy.type == ixgbe_phy_tn || hw->phy.type == ixgbe_phy_cu_unknown) { - hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); - if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) + hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, + &ext_ability); + if (ext_ability & MDIO_PMA_EXTABLE_10GBT) physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; - if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) + if (ext_ability & MDIO_PMA_EXTABLE_1000BT) physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; - if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) + if (ext_ability & MDIO_PMA_EXTABLE_100BTX) physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; goto out; } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 01a88265d401..661bed64407f 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4642,6 +4642,40 @@ static int ixgbe_set_mac(struct net_device *netdev, void *p) return 0; } +static int +ixgbe_mdio_read(struct net_device *netdev, int prtad, int devad, u16 addr) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + u16 value; + int rc; + + if (prtad != hw->phy.mdio.prtad) + return -EINVAL; + rc = hw->phy.ops.read_reg(hw, addr, devad, &value); + if (!rc) + rc = value; + return rc; +} + +static int ixgbe_mdio_write(struct net_device *netdev, int prtad, int devad, + u16 addr, u16 value) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + + if (prtad != hw->phy.mdio.prtad) + return -EINVAL; + return hw->phy.ops.write_reg(hw, addr, devad, value); +} + +static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + + return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); +} + #ifdef CONFIG_NET_POLL_CONTROLLER /* * Polling 'interrupt' - used by things like netconsole to send skbs @@ -4675,6 +4709,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_vlan_rx_register = ixgbe_vlan_rx_register, .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, + .ndo_do_ioctl = ixgbe_ioctl, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ixgbe_netpoll, #endif @@ -4789,6 +4824,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* PHY */ memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops)); hw->phy.sfp_type = ixgbe_sfp_type_unknown; + /* ixgbe_identify_phy_generic will set prtad and mmds properly */ + hw->phy.mdio.prtad = MDIO_PRTAD_NONE; + hw->phy.mdio.mmds = 0; + hw->phy.mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + hw->phy.mdio.dev = netdev; + hw->phy.mdio.mdio_read = ixgbe_mdio_read; + hw->phy.mdio.mdio_write = ixgbe_mdio_write; /* set up this timer and work struct before calling get_invariants * which might start the timer diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 2543c32ca84a..6d385ea3c2a1 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -44,7 +44,6 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data); static bool ixgbe_get_i2c_data(u32 *i2cctl); static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw); -static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr); static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw); @@ -61,8 +60,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) if (hw->phy.type == ixgbe_phy_unknown) { for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { - if (ixgbe_validate_phy_addr(hw, phy_addr)) { - hw->phy.addr = phy_addr; + if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) { ixgbe_get_phy_id(hw); hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); @@ -77,26 +75,6 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) return status; } -/** - * ixgbe_validate_phy_addr - Determines phy address is valid - * @hw: pointer to hardware structure - * - **/ -static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr) -{ - u16 phy_id = 0; - bool valid = false; - - hw->phy.addr = phy_addr; - hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id); - - if (phy_id != 0xFFFF && phy_id != 0x0) - valid = true; - - return valid; -} - /** * ixgbe_get_phy_id - Get the phy type * @hw: pointer to hardware structure @@ -108,14 +86,12 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw) u16 phy_id_high = 0; u16 phy_id_low = 0; - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, + status = hw->phy.ops.read_reg(hw, MDIO_DEVID1, MDIO_MMD_PMAPMD, &phy_id_high); if (status == 0) { hw->phy.id = (u32)(phy_id_high << 16); - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, + status = hw->phy.ops.read_reg(hw, MDIO_DEVID2, MDIO_MMD_PMAPMD, &phy_id_low); hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK); hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK); @@ -160,9 +136,8 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) * Perform soft PHY reset to the PHY_XS. * This will cause a soft reset to the PHY */ - return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, - IXGBE_MDIO_PHY_XS_DEV_TYPE, - IXGBE_MDIO_PHY_XS_RESET); + return hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, + MDIO_CTRL1_RESET); } /** @@ -192,7 +167,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, /* Setup and write the address cycle command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | - (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); @@ -223,7 +198,8 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | - (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (hw->phy.mdio.prtad << + IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); @@ -292,7 +268,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, /* Setup and write the address cycle command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | - (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); @@ -323,7 +299,8 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | - (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (hw->phy.mdio.prtad << + IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); @@ -365,7 +342,7 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) s32 status = IXGBE_NOT_IMPLEMENTED; u32 time_out; u32 max_time_out = 10; - u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; + u16 autoneg_reg; /* * Set advertisement settings in PHY based on autoneg_advertised @@ -373,36 +350,31 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) * tnx devices cannot be "forced" to a autoneg 10G and fail. But can * for a 1G. */ - hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); + hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg); if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL) - autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */ + autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G; else - autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */ + autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G; - hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); + hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg); /* Restart PHY autonegotiation and wait for completion */ - hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); + hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, &autoneg_reg); - autoneg_reg |= IXGBE_MII_RESTART; + autoneg_reg |= MDIO_AN_CTRL1_RESTART; - hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); + hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, autoneg_reg); /* Wait for autonegotiation to finish */ for (time_out = 0; time_out < max_time_out; time_out++) { udelay(10); /* Restart PHY autonegotiation and wait for completion */ - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN, &autoneg_reg); - autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE; - if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) { + autoneg_reg &= MDIO_AN_STAT1_COMPLETE; + if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) { status = 0; break; } @@ -457,23 +429,21 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) s32 ret_val = 0; u32 i; - hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, - IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); + hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data); /* reset the PHY and poll for completion */ - hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, - IXGBE_MDIO_PHY_XS_DEV_TYPE, - (phy_data | IXGBE_MDIO_PHY_XS_RESET)); + hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, + (phy_data | MDIO_CTRL1_RESET)); for (i = 0; i < 100; i++) { - hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, - IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); - if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0) + hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, + &phy_data); + if ((phy_data & MDIO_CTRL1_RESET) == 0) break; msleep(10); } - if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) { + if ((phy_data & MDIO_CTRL1_RESET) != 0) { hw_dbg(hw, "PHY reset did not complete.\n"); ret_val = IXGBE_ERR_PHY; goto out; @@ -509,7 +479,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) for (i = 0; i < edata; i++) { hw->eeprom.ops.read(hw, data_offset, &eword); hw->phy.ops.write_reg(hw, phy_offset, - IXGBE_TWINAX_DEV, eword); + MDIO_MMD_PMAPMD, eword); hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword, phy_offset); data_offset++; @@ -1302,7 +1272,7 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, udelay(10); status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS, - IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + MDIO_MMD_VEND1, &phy_data); phy_link = phy_data & IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; @@ -1330,8 +1300,7 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, { s32 status = 0; - status = hw->phy.ops.read_reg(hw, TNX_FW_REV, - IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, + status = hw->phy.ops.read_reg(hw, TNX_FW_REV, MDIO_MMD_VEND1, firmware_version); return status; diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index bdfdf3bca273..e49e8af59eda 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -29,6 +29,7 @@ #define _IXGBE_TYPE_H_ #include +#include /* Vendor ID */ #define IXGBE_INTEL_VENDOR_ID 0x8086 @@ -848,13 +849,7 @@ /* Omer bit masks */ #define IXGBE_CORECTL_WRITE_CMD 0x00010000 -/* Device Type definitions for new protocol MDIO commands */ -#define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1 -#define IXGBE_MDIO_PCS_DEV_TYPE 0x3 -#define IXGBE_MDIO_PHY_XS_DEV_TYPE 0x4 -#define IXGBE_MDIO_AUTO_NEG_DEV_TYPE 0x7 -#define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE 0x1E /* Device 30 */ -#define IXGBE_TWINAX_DEV 1 +/* MDIO definitions */ #define IXGBE_MDIO_COMMAND_TIMEOUT 100 /* PHY Timeout for 1 GB mode */ @@ -865,32 +860,10 @@ #define IXGBE_MDIO_VENDOR_SPECIFIC_1_10G_SPEED 0x0018 #define IXGBE_MDIO_VENDOR_SPECIFIC_1_1G_SPEED 0x0010 -#define IXGBE_MDIO_AUTO_NEG_CONTROL 0x0 /* AUTO_NEG Control Reg */ -#define IXGBE_MDIO_AUTO_NEG_STATUS 0x1 /* AUTO_NEG Status Reg */ -#define IXGBE_MDIO_PHY_XS_CONTROL 0x0 /* PHY_XS Control Reg */ -#define IXGBE_MDIO_PHY_XS_RESET 0x8000 /* PHY_XS Reset */ -#define IXGBE_MDIO_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/ -#define IXGBE_MDIO_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/ -#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */ -#define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */ -#define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */ -#define IXGBE_MDIO_PHY_EXT_ABILITY 0xB /* Ext Ability Reg */ -#define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */ -#define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */ -#define IXGBE_MDIO_PHY_100BASETX_ABILITY 0x0080 /* 100BaseTX capable */ - #define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */ -/* MII clause 22/28 definitions */ -#define IXGBE_MDIO_PHY_LOW_POWER_MODE 0x0800 - -#define IXGBE_MII_SPEED_SELECTION_REG 0x10 -#define IXGBE_MII_RESTART 0x200 -#define IXGBE_MII_AUTONEG_COMPLETE 0x20 -#define IXGBE_MII_AUTONEG_REG 0x0 - #define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0 #define IXGBE_MAX_PHY_ADDR 32 @@ -2214,8 +2187,8 @@ struct ixgbe_mac_info { struct ixgbe_phy_info { struct ixgbe_phy_operations ops; + struct mdio_if_info mdio; enum ixgbe_phy_type type; - u32 addr; u32 id; enum ixgbe_sfp_type sfp_type; bool sfp_setup_needed; -- GitLab From cdbf0eb478dd4c76aa665c80976837dc58367f52 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:11:05 +0000 Subject: [PATCH 0925/6080] ixgb: Use generic MDIO definitions Compile-tested only. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ixgb/ixgb_hw.c | 20 ++++++++++---------- drivers/net/ixgb/ixgb_hw.h | 14 ++------------ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c index 11dcda0f453e..ff67a84e6802 100644 --- a/drivers/net/ixgb/ixgb_hw.c +++ b/drivers/net/ixgb/ixgb_hw.c @@ -192,7 +192,7 @@ ixgb_identify_xpak_vendor(struct ixgb_hw *hw) vendor_name[i] = ixgb_read_phy_reg(hw, MDIO_PMA_PMD_XPAK_VENDOR_NAME + i, IXGB_PHY_ADDRESS, - MDIO_PMA_PMD_DID); + MDIO_MMD_PMAPMD); } /* Determine the actual vendor */ @@ -1225,15 +1225,15 @@ ixgb_optics_reset(struct ixgb_hw *hw) u16 mdio_reg; ixgb_write_phy_reg(hw, - MDIO_PMA_PMD_CR1, - IXGB_PHY_ADDRESS, - MDIO_PMA_PMD_DID, - MDIO_PMA_PMD_CR1_RESET); - - mdio_reg = ixgb_read_phy_reg( hw, - MDIO_PMA_PMD_CR1, - IXGB_PHY_ADDRESS, - MDIO_PMA_PMD_DID); + MDIO_CTRL1, + IXGB_PHY_ADDRESS, + MDIO_MMD_PMAPMD, + MDIO_CTRL1_RESET); + + mdio_reg = ixgb_read_phy_reg(hw, + MDIO_CTRL1, + IXGB_PHY_ADDRESS, + MDIO_MMD_PMAPMD); } return; diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h index 831fe0c58b2b..af6ca3aab5ad 100644 --- a/drivers/net/ixgb/ixgb_hw.h +++ b/drivers/net/ixgb/ixgb_hw.h @@ -29,6 +29,8 @@ #ifndef _IXGB_HW_H_ #define _IXGB_HW_H_ +#include + #include "ixgb_osdep.h" /* Enums */ @@ -507,18 +509,6 @@ typedef enum { /* Definitions for the optics devices on the MDIO bus. */ #define IXGB_PHY_ADDRESS 0x0 /* Single PHY, multiple "Devices" */ -/* Standard five-bit Device IDs. See IEEE 802.3ae, clause 45 */ -#define MDIO_PMA_PMD_DID 0x01 -#define MDIO_WIS_DID 0x02 -#define MDIO_PCS_DID 0x03 -#define MDIO_XGXS_DID 0x04 - -/* Standard PMA/PMD registers and bit definitions. */ -/* Note: This is a very limited set of definitions, */ -/* only implemented features are defined. */ -#define MDIO_PMA_PMD_CR1 0x0000 -#define MDIO_PMA_PMD_CR1_RESET 0x8000 - #define MDIO_PMA_PMD_XPAK_VENDOR_NAME 0x803A /* XPAK/XENPAK devices only */ /* Vendor-specific MDIO registers */ -- GitLab From 4023939667a906f0c02022ce7ec06d6512470211 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:13:29 +0000 Subject: [PATCH 0926/6080] s2io: Use generic MDIO definitions Compile-tested only. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/s2io-regs.h | 5 ----- drivers/net/s2io.c | 21 +++++++++++---------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index f8274f8941ea..416669fd68c6 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h @@ -271,11 +271,6 @@ struct XENA_dev_config { u64 mdio_control; #define MDIO_MMD_INDX_ADDR(val) vBIT(val, 0, 16) #define MDIO_MMD_DEV_ADDR(val) vBIT(val, 19, 5) -#define MDIO_MMD_PMA_DEV_ADDR 0x1 -#define MDIO_MMD_PMD_DEV_ADDR 0x1 -#define MDIO_MMD_WIS_DEV_ADDR 0x2 -#define MDIO_MMD_PCS_DEV_ADDR 0x3 -#define MDIO_MMD_PHYXS_DEV_ADDR 0x4 #define MDIO_MMS_PRT_ADDR(val) vBIT(val, 27, 5) #define MDIO_CTRL_START_TRANS(val) vBIT(val, 56, 4) #define MDIO_OP(val) vBIT(val, 60, 2) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 1a4979f27fb5..80562ea77de3 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -3328,9 +3329,9 @@ static void s2io_updt_xpak_counter(struct net_device *dev) struct stat_block *stat_info = sp->mac_control.stats_info; /* Check the communication with the MDIO slave */ - addr = 0x0000; + addr = MDIO_CTRL1; val64 = 0x0; - val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); + val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev); if((val64 == 0xFFFF) || (val64 == 0x0000)) { DBG_PRINT(ERR_DBG, "ERR: MDIO slave access failed - " @@ -3338,24 +3339,24 @@ static void s2io_updt_xpak_counter(struct net_device *dev) return; } - /* Check for the expecte value of 2040 at PMA address 0x0000 */ - if(val64 != 0x2040) + /* Check for the expected value of control reg 1 */ + if(val64 != MDIO_CTRL1_SPEED10G) { DBG_PRINT(ERR_DBG, "Incorrect value at PMA address 0x0000 - "); - DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x2040\n", - (unsigned long long)val64); + DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x%x\n", + (unsigned long long)val64, MDIO_CTRL1_SPEED10G); return; } /* Loading the DOM register to MDIO register */ addr = 0xA100; - s2io_mdio_write(MDIO_MMD_PMA_DEV_ADDR, addr, val16, dev); - val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); + s2io_mdio_write(MDIO_MMD_PMAPMD, addr, val16, dev); + val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev); /* Reading the Alarm flags */ addr = 0xA070; val64 = 0x0; - val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); + val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev); flag = CHECKBIT(val64, 0x7); type = 1; @@ -3387,7 +3388,7 @@ static void s2io_updt_xpak_counter(struct net_device *dev) /* Reading the Warning flags */ addr = 0xA074; val64 = 0x0; - val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); + val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev); if(CHECKBIT(val64, 0x7)) stat_info->xpak_stat.warn_transceiver_temp_high++; -- GitLab From 44c22ee91b56d7cad3b48c439dd96aad2e910fbc Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:15:05 +0000 Subject: [PATCH 0927/6080] mii: Simplify mii_resolve_flowctrl_fdx() This is a shorter and more comprehensible formulation of the conditions for each flow control mode. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/mii.h | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/include/linux/mii.h b/include/linux/mii.h index ad748588faf1..14ecb2e114f1 100644 --- a/include/linux/mii.h +++ b/include/linux/mii.h @@ -250,18 +250,12 @@ static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv) { u8 cap = 0; - if (lcladv & ADVERTISE_PAUSE_CAP) { - if (lcladv & ADVERTISE_PAUSE_ASYM) { - if (rmtadv & LPA_PAUSE_CAP) - cap = FLOW_CTRL_TX | FLOW_CTRL_RX; - else if (rmtadv & LPA_PAUSE_ASYM) - cap = FLOW_CTRL_RX; - } else { - if (rmtadv & LPA_PAUSE_CAP) - cap = FLOW_CTRL_TX | FLOW_CTRL_RX; - } - } else if (lcladv & ADVERTISE_PAUSE_ASYM) { - if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM)) + if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) { + cap = FLOW_CTRL_TX | FLOW_CTRL_RX; + } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) { + if (lcladv & ADVERTISE_PAUSE_CAP) + cap = FLOW_CTRL_RX; + else if (rmtadv & ADVERTISE_PAUSE_CAP) cap = FLOW_CTRL_TX; } -- GitLab From a8c30832b5b12e5d4e9d1c20cdac3cc2880e08b8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:19:03 +0000 Subject: [PATCH 0928/6080] mii: Add mii_advertise_flowctrl() This converts flow control capabilites to an advertising mask and can be useful in combination with mii_resolve_flowctrl_fdx(). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- include/linux/mii.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/linux/mii.h b/include/linux/mii.h index 14ecb2e114f1..359fba880274 100644 --- a/include/linux/mii.h +++ b/include/linux/mii.h @@ -239,6 +239,22 @@ static inline unsigned int mii_duplex (unsigned int duplex_lock, return 0; } +/** + * mii_advertise_flowctrl - get flow control advertisement flags + * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both) + */ +static inline u16 mii_advertise_flowctrl(int cap) +{ + u16 adv = 0; + + if (cap & FLOW_CTRL_RX) + adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + if (cap & FLOW_CTRL_TX) + adv ^= ADVERTISE_PAUSE_ASYM; + + return adv; +} + /** * mii_resolve_flowctrl_fdx * @lcladv: value of MII ADVERTISE register -- GitLab From af2a3eac2fe6a6d8e9fdf6927284b34466a7d808 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:19:36 +0000 Subject: [PATCH 0929/6080] mdio: Add mdio45_ethtool_spauseparam_an() This implements the ETHTOOL_SPAUSEPARAM operation for MDIO (clause 45) PHYs with auto-negotiation MMDs. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/mdio.c | 30 ++++++++++++++++++++++++++++++ include/linux/mdio.h | 3 +++ 2 files changed, 33 insertions(+) diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c index 0604a25748ee..2fb0d16b61f7 100644 --- a/drivers/net/mdio.c +++ b/drivers/net/mdio.c @@ -274,6 +274,36 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, } EXPORT_SYMBOL(mdio45_ethtool_gset_npage); +/** + * mdio45_ethtool_spauseparam_an - set auto-negotiated pause parameters + * @mdio: MDIO interface + * @ecmd: Ethtool request structure + * + * This function assumes that the PHY has an auto-negotiation MMD. It + * will enable and disable advertising of flow control as appropriate. + */ +void mdio45_ethtool_spauseparam_an(const struct mdio_if_info *mdio, + const struct ethtool_pauseparam *ecmd) +{ + int adv, old_adv; + + WARN_ON(!(mdio->mmds & MDIO_DEVS_AN)); + + old_adv = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, + MDIO_AN_ADVERTISE); + adv = old_adv & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); + if (ecmd->autoneg) + adv |= mii_advertise_flowctrl( + (ecmd->rx_pause ? FLOW_CTRL_RX : 0) | + (ecmd->tx_pause ? FLOW_CTRL_TX : 0)); + if (adv != old_adv) { + mdio->mdio_write(mdio->dev, mdio->prtad, MDIO_MMD_AN, + MDIO_AN_ADVERTISE, adv); + mdio45_nway_restart(mdio); + } +} +EXPORT_SYMBOL(mdio45_ethtool_spauseparam_an); + /** * mdio_mii_ioctl - MII ioctl interface for MDIO (clause 22 or 45) PHYs * @mdio: MDIO interface diff --git a/include/linux/mdio.h b/include/linux/mdio.h index ba41537eaa8a..5645c0f863dc 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -279,6 +279,9 @@ extern int mdio45_nway_restart(const struct mdio_if_info *mdio); extern void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, struct ethtool_cmd *ecmd, u32 npage_adv, u32 npage_lpa); +extern void +mdio45_ethtool_spauseparam_an(const struct mdio_if_info *mdio, + const struct ethtool_pauseparam *ecmd); /** * mdio45_ethtool_gset - get settings for ETHTOOL_GSET -- GitLab From 3f926da82f128c68c479247b1771729b9487502a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:20:37 +0000 Subject: [PATCH 0930/6080] sfc: Use generic MDIO flow control auto-negotiation functions Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/ethtool.c | 3 ++- drivers/net/sfc/mdio_10g.c | 22 +--------------------- drivers/net/sfc/mdio_10g.h | 3 --- drivers/net/sfc/net_driver.h | 26 ++++---------------------- drivers/net/sfc/tenxpress.c | 1 - 5 files changed, 7 insertions(+), 48 deletions(-) diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 1c7b6849fe01..997ea2a3d53f 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -711,7 +711,8 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, mutex_lock(&efx->mac_lock); efx->wanted_fc = wanted_fc; - efx_mdio_set_pause(efx); + if (efx->phy_op->mmds & MDIO_DEVS_AN) + mdio45_ethtool_spauseparam_an(&efx->mdio, pause); __efx_reconfigure_port(efx); mutex_unlock(&efx->mac_lock); diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index 11c231a1f875..6c33459f9ea9 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -304,7 +304,7 @@ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) else if (ecmd->advertising & (ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full)) reg |= ADVERTISE_NPAGE; - reg |= efx_fc_advertise(efx->wanted_fc); + reg |= mii_advertise_flowctrl(efx->wanted_fc); efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); /* Set up the (extended) next page if necessary */ @@ -340,26 +340,6 @@ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) return 0; } -void efx_mdio_set_pause(struct efx_nic *efx) -{ - int reg; - - if (efx->phy_op->mmds & MDIO_DEVS_AN) { - /* Set pause capability advertising */ - reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE); - reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); - reg |= efx_fc_advertise(efx->wanted_fc); - efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); - - /* Restart auto-negotiation */ - reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1); - if (reg & MDIO_AN_CTRL1_ENABLE) { - reg |= MDIO_AN_CTRL1_RESTART; - efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg); - } - } -} - enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx) { int lpa; diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h index ea4587d93698..6b14421a7444 100644 --- a/drivers/net/sfc/mdio_10g.h +++ b/drivers/net/sfc/mdio_10g.h @@ -87,9 +87,6 @@ extern void efx_mdio_set_mmds_lpower(struct efx_nic *efx, /* Set (some of) the PHY settings over MDIO */ extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd); -/* Set pause parameters to be advertised through AN (if available) */ -extern void efx_mdio_set_pause(struct efx_nic *efx); - /* Get pause parameters from AN if available (otherwise return * requested pause parameters) */ diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 457e2f1d4b43..5eabede9ac18 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -495,8 +495,8 @@ struct efx_nic; /* Pseudo bit-mask flow control field */ enum efx_fc_type { - EFX_FC_RX = 1, - EFX_FC_TX = 2, + EFX_FC_RX = FLOW_CTRL_RX, + EFX_FC_TX = FLOW_CTRL_TX, EFX_FC_AUTO = 4, }; @@ -506,33 +506,15 @@ enum efx_mac_type { EFX_XMAC = 2, }; -static inline unsigned int efx_fc_advertise(enum efx_fc_type wanted_fc) -{ - unsigned int adv = 0; - if (wanted_fc & EFX_FC_RX) - adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; - if (wanted_fc & EFX_FC_TX) - adv ^= ADVERTISE_PAUSE_ASYM; - return adv; -} - static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc, unsigned int lpa) { - unsigned int adv = efx_fc_advertise(wanted_fc); + BUILD_BUG_ON(EFX_FC_AUTO & (EFX_FC_RX | EFX_FC_TX)); if (!(wanted_fc & EFX_FC_AUTO)) return wanted_fc; - if (adv & lpa & ADVERTISE_PAUSE_CAP) - return EFX_FC_RX | EFX_FC_TX; - if (adv & lpa & ADVERTISE_PAUSE_ASYM) { - if (adv & ADVERTISE_PAUSE_CAP) - return EFX_FC_RX; - if (lpa & ADVERTISE_PAUSE_CAP) - return EFX_FC_TX; - } - return 0; + return mii_resolve_flowctrl_fdx(mii_advertise_flowctrl(wanted_fc), lpa); } /** diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 403f7d70c223..0421190db7de 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -343,7 +343,6 @@ static int tenxpress_phy_init(struct efx_nic *efx) rc = tenxpress_init(efx); if (rc < 0) goto fail; - efx_mdio_set_pause(efx); if (efx->phy_type == PHY_TYPE_SFT9001B) { rc = device_create_file(&efx->pci_dev->dev, -- GitLab From 0c09c1a49cc7b819b33566a49d9901f7cfdd6889 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:21:53 +0000 Subject: [PATCH 0931/6080] ethtool/mdio: Report MDIO mode support and link partner advertising Add mdio_support and lp_advertising fields to ethtool_cmd. Set these in mdio45_ethtool_gset{,_npage}(). Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/mdio.c | 19 ++++++++++++------- include/linux/ethtool.h | 4 +++- include/linux/mdio.h | 5 +++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c index 2fb0d16b61f7..ee383c256931 100644 --- a/drivers/net/mdio.c +++ b/drivers/net/mdio.c @@ -173,6 +173,8 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, ecmd->transceiver = XCVR_INTERNAL; ecmd->phy_address = mdio->prtad; + ecmd->mdio_support = + mdio->mode_support & (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22); reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, MDIO_CTRL2); @@ -235,16 +237,19 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, if (ecmd->autoneg) { u32 modes = 0; + int an_stat = mdio->mdio_read(mdio->dev, mdio->prtad, + MDIO_MMD_AN, MDIO_STAT1); /* If AN is complete and successful, report best common * mode, otherwise report best advertised mode. */ - if (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, - MDIO_STAT1) & - MDIO_AN_STAT1_COMPLETE) - modes = (ecmd->advertising & - (mdio45_get_an(mdio, MDIO_AN_LPA) | - npage_lpa)); - if (modes == 0) + if (an_stat & MDIO_AN_STAT1_COMPLETE) { + ecmd->lp_advertising = + mdio45_get_an(mdio, MDIO_AN_LPA) | npage_lpa; + if (an_stat & MDIO_AN_STAT1_LPABLE) + ecmd->lp_advertising |= ADVERTISED_Autoneg; + modes = ecmd->advertising & ecmd->lp_advertising; + } + if ((modes & ~ADVERTISED_Autoneg) == 0) modes = ecmd->advertising; if (modes & ADVERTISED_10000baseT_Full) { diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 5ccb6bd660c7..14e6bc860112 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -26,11 +26,13 @@ struct ethtool_cmd { __u8 phy_address; __u8 transceiver; /* Which transceiver to use */ __u8 autoneg; /* Enable or disable autonegotiation */ + __u8 mdio_support; __u32 maxtxpkt; /* Tx pkts before generating tx int */ __u32 maxrxpkt; /* Rx pkts before generating rx int */ __u16 speed_hi; __u16 reserved2; - __u32 reserved[3]; + __u32 lp_advertising; /* Features the link partner advertises */ + __u32 reserved[2]; }; static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 5645c0f863dc..1bff2f2d0e19 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -234,6 +234,9 @@ static inline __u16 mdio_phy_id_devad(int phy_id) return phy_id & MDIO_PHY_ID_DEVAD; } +#define MDIO_SUPPORTS_C22 1 +#define MDIO_SUPPORTS_C45 2 + #ifdef __KERNEL__ /** @@ -264,8 +267,6 @@ struct mdio_if_info { #define MDIO_PRTAD_NONE (-1) #define MDIO_DEVAD_NONE (-1) -#define MDIO_SUPPORTS_C22 1 -#define MDIO_SUPPORTS_C45 2 #define MDIO_EMULATE_C22 4 struct ethtool_cmd; -- GitLab From 894b19a6b343ce3589237167a56e6df0fe72ef0d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:25:57 +0000 Subject: [PATCH 0932/6080] ethtool/mdio: Support backplane mode negotiation Compile-tested only. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/mdio.c | 30 +++++++++++++++++++++++++----- include/linux/ethtool.h | 10 ++++++++++ include/linux/mdio.h | 5 +++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c index ee383c256931..66483035f683 100644 --- a/drivers/net/mdio.c +++ b/drivers/net/mdio.c @@ -202,12 +202,29 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, break; case MDIO_PMA_CTRL2_10GBCX4: + ecmd->port = PORT_OTHER; + ecmd->supported = 0; + ecmd->advertising = 0; + break; + case MDIO_PMA_CTRL2_10GBKX4: case MDIO_PMA_CTRL2_10GBKR: case MDIO_PMA_CTRL2_1000BKX: ecmd->port = PORT_OTHER; - ecmd->supported = 0; - ecmd->advertising = 0; + ecmd->supported = SUPPORTED_Backplane; + reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, + MDIO_PMA_EXTABLE); + if (reg & MDIO_PMA_EXTABLE_10GBKX4) + ecmd->supported |= SUPPORTED_10000baseKX4_Full; + if (reg & MDIO_PMA_EXTABLE_10GBKR) + ecmd->supported |= SUPPORTED_10000baseKR_Full; + if (reg & MDIO_PMA_EXTABLE_1000BKX) + ecmd->supported |= SUPPORTED_1000baseKX_Full; + reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD, + MDIO_PMA_10GBR_FECABLE); + if (reg & MDIO_PMA_10GBR_FECABLE_ABLE) + ecmd->supported |= SUPPORTED_10000baseR_FEC; + ecmd->advertising = ADVERTISED_Backplane; break; /* All the other defined modes are flavours of optical */ @@ -252,13 +269,16 @@ void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio, if ((modes & ~ADVERTISED_Autoneg) == 0) modes = ecmd->advertising; - if (modes & ADVERTISED_10000baseT_Full) { + if (modes & (ADVERTISED_10000baseT_Full | + ADVERTISED_10000baseKX4_Full | + ADVERTISED_10000baseKR_Full)) { ecmd->speed = SPEED_10000; ecmd->duplex = DUPLEX_FULL; } else if (modes & (ADVERTISED_1000baseT_Full | - ADVERTISED_1000baseT_Half)) { + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseKX_Full)) { ecmd->speed = SPEED_1000; - ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full); + ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half); } else if (modes & (ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half)) { ecmd->speed = SPEED_100; diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 14e6bc860112..380b04272bf1 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -565,6 +565,11 @@ struct ethtool_ops { #define SUPPORTED_Pause (1 << 13) #define SUPPORTED_Asym_Pause (1 << 14) #define SUPPORTED_2500baseX_Full (1 << 15) +#define SUPPORTED_Backplane (1 << 16) +#define SUPPORTED_1000baseKX_Full (1 << 17) +#define SUPPORTED_10000baseKX4_Full (1 << 18) +#define SUPPORTED_10000baseKR_Full (1 << 19) +#define SUPPORTED_10000baseR_FEC (1 << 20) /* Indicates what features are advertised by the interface. */ #define ADVERTISED_10baseT_Half (1 << 0) @@ -583,6 +588,11 @@ struct ethtool_ops { #define ADVERTISED_Pause (1 << 13) #define ADVERTISED_Asym_Pause (1 << 14) #define ADVERTISED_2500baseX_Full (1 << 15) +#define ADVERTISED_Backplane (1 << 16) +#define ADVERTISED_1000baseKX_Full (1 << 17) +#define ADVERTISED_10000baseKX4_Full (1 << 18) +#define ADVERTISED_10000baseKR_Full (1 << 19) +#define ADVERTISED_10000baseR_FEC (1 << 20) /* The following are all involved in forcing a particular link * mode for the device for setting things. When getting the diff --git a/include/linux/mdio.h b/include/linux/mdio.h index 1bff2f2d0e19..26b4eb3bbee9 100644 --- a/include/linux/mdio.h +++ b/include/linux/mdio.h @@ -46,6 +46,7 @@ /* Media-dependent registers. */ #define MDIO_PMA_10GBT_TXPWR 131 /* 10GBASE-T TX power control */ +#define MDIO_PMA_10GBR_FECABLE 170 /* 10GBASE-R FEC ability */ #define MDIO_PCS_10GBX_STAT1 24 /* 10GBASE-X PCS status 1 */ #define MDIO_PCS_10GBRT_STAT1 32 /* 10GBASE-R/-T PCS status 1 */ #define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */ @@ -187,6 +188,10 @@ /* PMA 10GBASE-T TX power register. */ #define MDIO_PMA_10GBT_TXPWR_SHORT 0x0001 /* Short-reach mode */ +/* PMA 10GBASE-R FEC ability register. */ +#define MDIO_PMA_10GBR_FECABLE_ABLE 0x0001 /* FEC ability */ +#define MDIO_PMA_10GBR_FECABLE_ERRABLE 0x0002 /* FEC error indic. ability */ + /* PCS 10GBASE-R/-T status register 1. */ #define MDIO_PCS_10GBRT_STAT1_BLKLK 0x0001 /* Block lock attained */ -- GitLab From 5974700c288aa160fd02b1cb9294173664bcc172 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 29 Apr 2009 08:34:44 +0000 Subject: [PATCH 0933/6080] mii: Rewrite mii_ethtool_gset() to report mdio_support and lp_advertising Ignore link partner advertising flags while AN is not complete. Compile-tested only. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/mii.c | 91 +++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 34 deletions(-) diff --git a/drivers/net/mii.c b/drivers/net/mii.c index 92056051f269..d81a5d22a3a9 100644 --- a/drivers/net/mii.c +++ b/drivers/net/mii.c @@ -31,7 +31,27 @@ #include #include #include -#include +#include + +static u32 mii_get_an(struct mii_if_info *mii, u16 addr) +{ + u32 result = 0; + int advert; + + advert = mii->mdio_read(mii->dev, mii->phy_id, addr); + if (advert & LPA_LPACK) + result |= ADVERTISED_Autoneg; + if (advert & ADVERTISE_10HALF) + result |= ADVERTISED_10baseT_Half; + if (advert & ADVERTISE_10FULL) + result |= ADVERTISED_10baseT_Full; + if (advert & ADVERTISE_100HALF) + result |= ADVERTISED_100baseT_Half; + if (advert & ADVERTISE_100FULL) + result |= ADVERTISED_100baseT_Full; + + return result; +} /** * mii_ethtool_gset - get settings that are specified in @ecmd @@ -43,8 +63,8 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) { struct net_device *dev = mii->dev; - u32 advert, bmcr, lpa, nego; - u32 advert2 = 0, bmcr2 = 0, lpa2 = 0; + u16 bmcr, bmsr, ctrl1000 = 0, stat1000 = 0; + u32 nego; ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | @@ -62,50 +82,51 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) /* this isn't fully supported at higher layers */ ecmd->phy_address = mii->phy_id; + ecmd->mdio_support = MDIO_SUPPORTS_C22; ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII; - advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE); - if (mii->supports_gmii) - advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); - - if (advert & ADVERTISE_10HALF) - ecmd->advertising |= ADVERTISED_10baseT_Half; - if (advert & ADVERTISE_10FULL) - ecmd->advertising |= ADVERTISED_10baseT_Full; - if (advert & ADVERTISE_100HALF) - ecmd->advertising |= ADVERTISED_100baseT_Half; - if (advert & ADVERTISE_100FULL) - ecmd->advertising |= ADVERTISED_100baseT_Full; - if (advert2 & ADVERTISE_1000HALF) - ecmd->advertising |= ADVERTISED_1000baseT_Half; - if (advert2 & ADVERTISE_1000FULL) - ecmd->advertising |= ADVERTISED_1000baseT_Full; bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); - lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA); + bmsr = mii->mdio_read(dev, mii->phy_id, MII_BMSR); if (mii->supports_gmii) { - bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); - lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000); + ctrl1000 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000); + stat1000 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000); } if (bmcr & BMCR_ANENABLE) { ecmd->advertising |= ADVERTISED_Autoneg; ecmd->autoneg = AUTONEG_ENABLE; - nego = mii_nway_result(advert & lpa); - if ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) & - (lpa2 >> 2)) + ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE); + if (ctrl1000 & ADVERTISE_1000HALF) + ecmd->advertising |= ADVERTISED_1000baseT_Half; + if (ctrl1000 & ADVERTISE_1000FULL) + ecmd->advertising |= ADVERTISED_1000baseT_Full; + + if (bmsr & BMSR_ANEGCOMPLETE) { + ecmd->lp_advertising = mii_get_an(mii, MII_LPA); + if (stat1000 & LPA_1000HALF) + ecmd->lp_advertising |= + ADVERTISED_1000baseT_Half; + if (stat1000 & LPA_1000FULL) + ecmd->lp_advertising |= + ADVERTISED_1000baseT_Full; + } else { + ecmd->lp_advertising = 0; + } + + nego = ecmd->advertising & ecmd->lp_advertising; + + if (nego & (ADVERTISED_1000baseT_Full | + ADVERTISED_1000baseT_Half)) { ecmd->speed = SPEED_1000; - else if (nego == LPA_100FULL || nego == LPA_100HALF) + ecmd->duplex = !!(nego & ADVERTISED_1000baseT_Full); + } else if (nego & (ADVERTISED_100baseT_Full | + ADVERTISED_100baseT_Half)) { ecmd->speed = SPEED_100; - else - ecmd->speed = SPEED_10; - if ((lpa2 & LPA_1000FULL) || nego == LPA_100FULL || - nego == LPA_10FULL) { - ecmd->duplex = DUPLEX_FULL; - mii->full_duplex = 1; + ecmd->duplex = !!(nego & ADVERTISED_100baseT_Full); } else { - ecmd->duplex = DUPLEX_HALF; - mii->full_duplex = 0; + ecmd->speed = SPEED_10; + ecmd->duplex = !!(nego & ADVERTISED_10baseT_Full); } } else { ecmd->autoneg = AUTONEG_DISABLE; @@ -116,6 +137,8 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; } + mii->full_duplex = ecmd->duplex; + /* ignore maxtxpkt, maxrxpkt for now */ return 0; -- GitLab From a4fe91ee711f4e955ea85ab05b092cfe384b073e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 29 Apr 2009 17:53:20 -0700 Subject: [PATCH 0934/6080] Revert "vxge: use max() instead of VXGE_HW_SET_LEVEL" This reverts commit 011983048a120e520147361be1067dd82343038e. Causes warnings in the build as reported by Stephen Rothwell. So this change is worse than what it's curing. Signed-off-by: David S. Miller --- drivers/net/vxge/vxge-traffic.c | 55 +++++++++++++++++++-------------- drivers/net/vxge/vxge-traffic.h | 2 ++ 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c index cf4ebb55273d..506625b180ac 100644 --- a/drivers/net/vxge/vxge-traffic.c +++ b/drivers/net/vxge/vxge-traffic.c @@ -505,7 +505,7 @@ enum vxge_hw_status vxge_hw_device_begin_irq(struct __vxge_hw_device *hldev, ret = __vxge_hw_vpath_alarm_process( &hldev->virtual_paths[i], skip_alarms); - error_level = max(ret, error_level); + error_level = VXGE_HW_SET_LEVEL(ret, error_level); if (unlikely((ret == VXGE_HW_ERR_CRITICAL) || (ret == VXGE_HW_ERR_SLOT_FREEZE))) @@ -1921,7 +1921,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( struct vxge_hw_vpath_reg __iomem *vp_reg; if (vpath == NULL) { - alarm_event = max(VXGE_HW_EVENT_UNKNOWN, + alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN, alarm_event); goto out2; } @@ -1931,7 +1931,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( alarm_status = readq(&vp_reg->vpath_general_int_status); if (alarm_status == VXGE_HW_ALL_FOXES) { - alarm_event = max(VXGE_HW_EVENT_SLOT_FREEZE, + alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_SLOT_FREEZE, alarm_event); goto out; } @@ -1945,7 +1945,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT)) { sw_stats->error_stats.unknown_alarms++; - alarm_event = max(VXGE_HW_EVENT_UNKNOWN, + alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN, alarm_event); goto out; } @@ -1975,8 +1975,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( &vp_reg->asic_ntwk_vp_err_mask); __vxge_hw_device_handle_link_down_ind(hldev); - alarm_event = max(VXGE_HW_EVENT_LINK_DOWN, - alarm_event); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_LINK_DOWN, alarm_event); } if (((val64 & @@ -1996,15 +1996,15 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( &vp_reg->asic_ntwk_vp_err_mask); __vxge_hw_device_handle_link_up_ind(hldev); - alarm_event = max(VXGE_HW_EVENT_LINK_UP, - alarm_event); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_LINK_UP, alarm_event); } writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->asic_ntwk_vp_err_reg); - alarm_event = max(VXGE_HW_EVENT_ALARM_CLEARED, - alarm_event); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); if (skip_alarms) return VXGE_HW_OK; @@ -2026,8 +2026,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.ini_serr_det++; - alarm_event = max(VXGE_HW_EVENT_SERR, - alarm_event); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_SERR, alarm_event); } if ((val64 & @@ -2035,8 +2035,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.dblgen_fifo0_overflow++; - alarm_event = max(VXGE_HW_EVENT_FIFO_ERR, - alarm_event); + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_FIFO_ERR, alarm_event); } if ((val64 & @@ -2057,7 +2057,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( if (!skip_alarms) { writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->general_errors_reg); - alarm_event = max(VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); } } @@ -2073,7 +2074,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.kdfcctl_fifo0_overwrite++; - alarm_event = max(VXGE_HW_EVENT_FIFO_ERR, + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_FIFO_ERR, alarm_event); } @@ -2082,7 +2084,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.kdfcctl_fifo0_poison++; - alarm_event = max(VXGE_HW_EVENT_FIFO_ERR, + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_FIFO_ERR, alarm_event); } @@ -2091,14 +2094,16 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.kdfcctl_fifo0_dma_error++; - alarm_event = max(VXGE_HW_EVENT_FIFO_ERR, + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_FIFO_ERR, alarm_event); } if (!skip_alarms) { writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->kdfcctl_errors_reg); - alarm_event = max(VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); } } @@ -2122,7 +2127,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( ~mask64) { sw_stats->error_stats.prc_rxdcm_sc_err++; - alarm_event = max(VXGE_HW_EVENT_VPATH_ERR, + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_VPATH_ERR, alarm_event); } @@ -2130,7 +2136,8 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( & ~mask64) { sw_stats->error_stats.prc_rxdcm_sc_abort++; - alarm_event = max(VXGE_HW_EVENT_VPATH_ERR, + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_VPATH_ERR, alarm_event); } @@ -2138,14 +2145,16 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process( & ~mask64) { sw_stats->error_stats.prc_quanta_size_err++; - alarm_event = max(VXGE_HW_EVENT_VPATH_ERR, + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_VPATH_ERR, alarm_event); } if (!skip_alarms) { writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->prc_alarm_reg); - alarm_event = max(VXGE_HW_EVENT_ALARM_CLEARED, + alarm_event = VXGE_HW_SET_LEVEL( + VXGE_HW_EVENT_ALARM_CLEARED, alarm_event); } } diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h index d03f3d3805c9..7567a1140d07 100644 --- a/drivers/net/vxge/vxge-traffic.h +++ b/drivers/net/vxge/vxge-traffic.h @@ -110,6 +110,8 @@ enum vxge_hw_event { VXGE_HW_EVENT_SLOT_FREEZE = VXGE_HW_EVENT_BASE + 14, }; +#define VXGE_HW_SET_LEVEL(a, b) (((a) > (b)) ? (a) : (b)) + /* * struct vxge_hw_mempool_dma - Represents DMA objects passed to the caller. -- GitLab From e6be3a25861429166f945499c7ee616875bc3db9 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 30 Apr 2009 12:56:37 +0900 Subject: [PATCH 0935/6080] sh: pass through ioremap() for non-mmu processors. All 32-bit SuperH processors currently go through __ioremap_mode() and check for IO_TRAPPED and directly mapped segments. With this patch we simplify the MMU less case with a pass through version of __ioremap_mode() which just returns the physical address. The effects of this is change are: - fix non-MMU ioremap() of high address hardware blocks (sh7203 CMT) - make sure IO_TRAPPED is not selected Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/Kconfig | 6 +++--- arch/sh/include/asm/io.h | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index dcc1af8a2cfe..99e2d47f79f5 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -121,7 +121,7 @@ config SH_RTS7751R2D bool "RTS7751R2D" depends on CPU_SUBTYPE_SH7751R select SYS_SUPPORTS_PCI - select IO_TRAPPED + select IO_TRAPPED if MMU help Select RTS7751R2D if configuring for a Renesas Technology Sales SH-Graphics board. @@ -145,13 +145,13 @@ config SH_HIGHLANDER bool "Highlander" depends on CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 select SYS_SUPPORTS_PCI - select IO_TRAPPED + select IO_TRAPPED if MMU config SH_SH7785LCR bool "SH7785LCR" depends on CPU_SUBTYPE_SH7785 select SYS_SUPPORTS_PCI - select IO_TRAPPED + select IO_TRAPPED if MMU config SH_SH7785LCR_29BIT_PHYSMAPS bool "SH7785LCR 29bit physmaps" diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 0454f8d68059..ef217344afcb 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -228,12 +228,6 @@ void __iounmap(void __iomem *addr); unsigned long onchip_remap(unsigned long addr, unsigned long size, const char *name); extern void onchip_unmap(unsigned long vaddr); -#else -#define __ioremap(offset, size, flags) ((void __iomem *)(offset)) -#define __iounmap(addr) do { } while (0) -#define onchip_remap(addr, size, name) (addr) -#define onchip_unmap(addr) do { } while (0) -#endif /* CONFIG_MMU */ static inline void __iomem * __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) @@ -268,6 +262,12 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags) return __ioremap(offset, size, flags); } +#else +#define onchip_remap(addr, size, name) (addr) +#define onchip_unmap(addr) do { } while (0) +#define __ioremap_mode(offset, size, flags) ((void __iomem *)(offset)) +#define __iounmap(addr) do { } while (0) +#endif /* CONFIG_MMU */ #define ioremap(offset, size) \ __ioremap_mode((offset), (size), 0) -- GitLab From 3014f47460ecfb13d4169daae51f26a20bacfa17 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 29 Apr 2009 14:50:37 +0000 Subject: [PATCH 0936/6080] clocksource: sh_cmt 16-bit fixes This patch contains various fixes for 16-bit cmt hardware. With this applied periodic clockevents work fine on sh7203. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index bf3e4c11fd37..4ff1508e5ab7 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -158,16 +158,18 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) pr_err("sh_cmt: cannot enable clock \"%s\"\n", cfg->clk); return ret; } - *rate = clk_get_rate(p->clk) / 8; /* make sure channel is disabled */ sh_cmt_start_stop_ch(p, 0); /* configure channel, periodic mode and maximum timeout */ - if (p->width == 16) - sh_cmt_write(p, CMCSR, 0); - else + if (p->width == 16) { + *rate = clk_get_rate(p->clk) / 512; + sh_cmt_write(p, CMCSR, 0x43); + } else { + *rate = clk_get_rate(p->clk) / 8; sh_cmt_write(p, CMCSR, 0x01a4); + } sh_cmt_write(p, CMCOR, 0xffffffff); sh_cmt_write(p, CMCNT, 0); @@ -615,7 +617,7 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) if (resource_size(res) == 6) { p->width = 16; p->overflow_bit = 0x80; - p->clear_bits = ~0xc0; + p->clear_bits = ~0x80; } else { p->width = 32; p->overflow_bit = 0x8000; -- GitLab From 698aa99da5f5e2b4c666fd21ab77306f0225b8f5 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 30 Apr 2009 04:08:18 +0000 Subject: [PATCH 0937/6080] sh: sh2/sh2a 16-bit CMT platform data This patch adds 16-bit cmt platform data for the following cpus: - sh7619 (2 channels) - sh7203/sh7263 (2 channels) - sh7206 (2 channels) Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 84 ++++++++++++++++++++++++++ arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 84 ++++++++++++++++++++++++++ arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 84 ++++++++++++++++++++++++++ 3 files changed, 252 insertions(+) diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 0e32d8e448ca..d70c263eb07e 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include enum { UNUSED = 0, @@ -109,9 +111,75 @@ static struct platform_device eth_device = { .resource = eth_resources, }; +static struct sh_cmt_config cmt0_platform_data = { + .name = "CMT0", + .channel_offset = 0x02, + .timer_bit = 0, + .clk = "module_clk", + .clockevent_rating = 125, + .clocksource_rating = 0, /* disabled due to code generation issues */ +}; + +static struct resource cmt0_resources[] = { + [0] = { + .name = "CMT0", + .start = 0xf84a0072, + .end = 0xf84a0077, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 86, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cmt0_device = { + .name = "sh_cmt", + .id = 0, + .dev = { + .platform_data = &cmt0_platform_data, + }, + .resource = cmt0_resources, + .num_resources = ARRAY_SIZE(cmt0_resources), +}; + +static struct sh_cmt_config cmt1_platform_data = { + .name = "CMT1", + .channel_offset = 0x08, + .timer_bit = 1, + .clk = "module_clk", + .clockevent_rating = 125, + .clocksource_rating = 0, /* disabled due to code generation issues */ +}; + +static struct resource cmt1_resources[] = { + [0] = { + .name = "CMT1", + .start = 0xf84a0078, + .end = 0xf84a007d, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 87, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cmt1_device = { + .name = "sh_cmt", + .id = 1, + .dev = { + .platform_data = &cmt1_platform_data, + }, + .resource = cmt1_resources, + .num_resources = ARRAY_SIZE(cmt1_resources), +}; + static struct platform_device *sh7619_devices[] __initdata = { &sci_device, ð_device, + &cmt0_device, + &cmt1_device, }; static int __init sh7619_devices_setup(void) @@ -125,3 +193,19 @@ void __init plat_irq_setup(void) { register_intc_controller(&intc_desc); } + +static struct platform_device *sh7619_early_devices[] __initdata = { + &cmt0_device, + &cmt1_device, +}; + +#define STBCR3 0xf80a0000 + +void __init plat_early_device_setup(void) +{ + /* enable CMT clock */ + __raw_writeb(__raw_readb(STBCR3) & ~0x10, STBCR3); + + early_platform_add_devices(sh7619_early_devices, + ARRAY_SIZE(sh7619_early_devices)); +} diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 820dfb2e8656..0836acee2289 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include enum { UNUSED = 0, @@ -205,6 +207,70 @@ static struct platform_device sci_device = { }, }; +static struct sh_cmt_config cmt0_platform_data = { + .name = "CMT0", + .channel_offset = 0x02, + .timer_bit = 0, + .clk = "module_clk", + .clockevent_rating = 125, + .clocksource_rating = 0, /* disabled due to code generation issues */ +}; + +static struct resource cmt0_resources[] = { + [0] = { + .name = "CMT0", + .start = 0xfffec002, + .end = 0xfffec007, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 142, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cmt0_device = { + .name = "sh_cmt", + .id = 0, + .dev = { + .platform_data = &cmt0_platform_data, + }, + .resource = cmt0_resources, + .num_resources = ARRAY_SIZE(cmt0_resources), +}; + +static struct sh_cmt_config cmt1_platform_data = { + .name = "CMT1", + .channel_offset = 0x08, + .timer_bit = 1, + .clk = "module_clk", + .clockevent_rating = 125, + .clocksource_rating = 0, /* disabled due to code generation issues */ +}; + +static struct resource cmt1_resources[] = { + [0] = { + .name = "CMT1", + .start = 0xfffec008, + .end = 0xfffec00d, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 143, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cmt1_device = { + .name = "sh_cmt", + .id = 1, + .dev = { + .platform_data = &cmt1_platform_data, + }, + .resource = cmt1_resources, + .num_resources = ARRAY_SIZE(cmt1_resources), +}; + static struct resource rtc_resources[] = { [0] = { .start = 0xffff2000, @@ -227,6 +293,8 @@ static struct platform_device rtc_device = { static struct platform_device *sh7203_devices[] __initdata = { &sci_device, + &cmt0_device, + &cmt1_device, &rtc_device, }; @@ -241,3 +309,19 @@ void __init plat_irq_setup(void) { register_intc_controller(&intc_desc); } + +static struct platform_device *sh7203_early_devices[] __initdata = { + &cmt0_device, + &cmt1_device, +}; + +#define STBCR4 0xfffe040c + +void __init plat_early_device_setup(void) +{ + /* enable CMT clock */ + __raw_writeb(__raw_readb(STBCR4) & ~0x04, STBCR4); + + early_platform_add_devices(sh7203_early_devices, + ARRAY_SIZE(sh7203_early_devices)); +} diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index c46a8355726d..f9606e3d2515 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include enum { UNUSED = 0, @@ -165,8 +167,74 @@ static struct platform_device sci_device = { }, }; +static struct sh_cmt_config cmt0_platform_data = { + .name = "CMT0", + .channel_offset = 0x02, + .timer_bit = 0, + .clk = "module_clk", + .clockevent_rating = 125, + .clocksource_rating = 0, /* disabled due to code generation issues */ +}; + +static struct resource cmt0_resources[] = { + [0] = { + .name = "CMT0", + .start = 0xfffec002, + .end = 0xfffec007, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 140, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cmt0_device = { + .name = "sh_cmt", + .id = 0, + .dev = { + .platform_data = &cmt0_platform_data, + }, + .resource = cmt0_resources, + .num_resources = ARRAY_SIZE(cmt0_resources), +}; + +static struct sh_cmt_config cmt1_platform_data = { + .name = "CMT1", + .channel_offset = 0x08, + .timer_bit = 1, + .clk = "module_clk", + .clockevent_rating = 125, + .clocksource_rating = 0, /* disabled due to code generation issues */ +}; + +static struct resource cmt1_resources[] = { + [0] = { + .name = "CMT1", + .start = 0xfffec008, + .end = 0xfffec00d, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 144, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cmt1_device = { + .name = "sh_cmt", + .id = 1, + .dev = { + .platform_data = &cmt1_platform_data, + }, + .resource = cmt1_resources, + .num_resources = ARRAY_SIZE(cmt1_resources), +}; + static struct platform_device *sh7206_devices[] __initdata = { &sci_device, + &cmt0_device, + &cmt1_device, }; static int __init sh7206_devices_setup(void) @@ -180,3 +248,19 @@ void __init plat_irq_setup(void) { register_intc_controller(&intc_desc); } + +static struct platform_device *sh7206_early_devices[] __initdata = { + &cmt0_device, + &cmt1_device, +}; + +#define STBCR4 0xfffe040c + +void __init plat_early_device_setup(void) +{ + /* enable CMT clock */ + __raw_writeb(__raw_readb(STBCR4) & ~0x04, STBCR4); + + early_platform_add_devices(sh7206_early_devices, + ARRAY_SIZE(sh7206_early_devices)); +} -- GitLab From f425752fc66acf1d4e47970ea704ed7d31c14173 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 30 Apr 2009 04:09:26 +0000 Subject: [PATCH 0938/6080] sh: remove old CMT driver This patch removes the old CMT driver (CONFIG_SH_CMT/timer-cmt.c) As replacement, select the sh_cmt driver with CONFIG_SH_TIMER_CMT and configure timer channel using platform data. If multiple CMT channels are enabled using platform data, use the earlytimer parameter on the kernel command line to select channel. For instance, use "earlytimer=sh_cmt.0" to select the first channel. To verify which timer is being used, look at printouts or the timer irq count in /proc/interrupts. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 18 +-- arch/sh/include/asm/timer.h | 2 +- arch/sh/kernel/timers/Makefile | 1 - arch/sh/kernel/timers/timer-cmt.c | 188 ------------------------------ arch/sh/kernel/timers/timer.c | 3 - 5 files changed, 6 insertions(+), 206 deletions(-) delete mode 100644 arch/sh/kernel/timers/timer-cmt.c diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 9db02ced57a5..7e96adea9602 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -462,22 +462,14 @@ config SH_TMU help This enables the use of the TMU as the system timer. -config SH_CMT - bool "CMT timer support" - depends on SYS_SUPPORTS_CMT && CPU_SH2 - default y - help - This enables the use of the CMT as the system timer. - -# -# Support for the new-style CMT driver. This will replace SH_CMT -# once its other dependencies are merged. -# config SH_TIMER_CMT - bool "CMT clockevents driver" - depends on SYS_SUPPORTS_CMT && !SH_CMT + bool "CMT timer driver" + depends on SYS_SUPPORTS_CMT + default y select GENERIC_CLOCKEVENTS select GENERIC_TIME + help + This enables build of the CMT timer driver. config SH_MTU2 bool "MTU2 timer support" diff --git a/arch/sh/include/asm/timer.h b/arch/sh/include/asm/timer.h index 4c3b66e30af2..8f80a55c04ae 100644 --- a/arch/sh/include/asm/timer.h +++ b/arch/sh/include/asm/timer.h @@ -23,7 +23,7 @@ struct sys_timer { #define TICK_SIZE (tick_nsec / 1000) -extern struct sys_timer tmu_timer, cmt_timer, mtu2_timer; +extern struct sys_timer tmu_timer, mtu2_timer; extern struct sys_timer *sys_timer; #ifndef CONFIG_GENERIC_TIME diff --git a/arch/sh/kernel/timers/Makefile b/arch/sh/kernel/timers/Makefile index 0b7f8577193f..1e9a104c2aee 100644 --- a/arch/sh/kernel/timers/Makefile +++ b/arch/sh/kernel/timers/Makefile @@ -6,6 +6,5 @@ obj-y := timer.o obj-$(CONFIG_SH_TMU) += timer-tmu.o obj-$(CONFIG_SH_MTU2) += timer-mtu2.o -obj-$(CONFIG_SH_CMT) += timer-cmt.o obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += timer-broadcast.o diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c deleted file mode 100644 index 9aa348658ae3..000000000000 --- a/arch/sh/kernel/timers/timer-cmt.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * arch/sh/kernel/timers/timer-cmt.c - CMT Timer Support - * - * Copyright (C) 2005 Yoshinori Sato - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(CONFIG_CPU_SUBTYPE_SH7619) -#define CMT_CMSTR 0xf84a0070 -#define CMT_CMCSR_0 0xf84a0072 -#define CMT_CMCNT_0 0xf84a0074 -#define CMT_CMCOR_0 0xf84a0076 -#define CMT_CMCSR_1 0xf84a0078 -#define CMT_CMCNT_1 0xf84a007a -#define CMT_CMCOR_1 0xf84a007c - -#define STBCR3 0xf80a0000 -#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR3) & ~0x10, STBCR3); } while(0) -#define CMT_CMCSR_INIT 0x0040 -#define CMT_CMCSR_CALIB 0x0000 -#elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \ - defined(CONFIG_CPU_SUBTYPE_SH7206) || \ - defined(CONFIG_CPU_SUBTYPE_SH7263) -#define CMT_CMSTR 0xfffec000 -#define CMT_CMCSR_0 0xfffec002 -#define CMT_CMCNT_0 0xfffec004 -#define CMT_CMCOR_0 0xfffec006 - -#define STBCR4 0xfffe040c -#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR4) & ~0x04, STBCR4); } while(0) -#define CMT_CMCSR_INIT 0x0040 -#define CMT_CMCSR_CALIB 0x0000 -#else -#error "Unknown CPU SUBTYPE" -#endif - -static unsigned long cmt_timer_get_offset(void) -{ - int count; - static unsigned short count_p = 0xffff; /* for the first call after boot */ - static unsigned long jiffies_p = 0; - - /* - * cache volatile jiffies temporarily; we have IRQs turned off. - */ - unsigned long jiffies_t; - - /* timer count may underflow right here */ - count = ctrl_inw(CMT_CMCOR_0); - count -= ctrl_inw(CMT_CMCNT_0); - - jiffies_t = jiffies; - - /* - * avoiding timer inconsistencies (they are rare, but they happen)... - * there is one kind of problem that must be avoided here: - * 1. the timer counter underflows - */ - - if (jiffies_t == jiffies_p) { - if (count > count_p) { - /* the nutcase */ - if (ctrl_inw(CMT_CMCSR_0) & 0x80) { /* Check CMF bit */ - count -= LATCH; - } else { - printk("%s (): hardware timer problem?\n", - __func__); - } - } - } else - jiffies_p = jiffies_t; - - count_p = count; - - count = ((LATCH-1) - count) * TICK_SIZE; - count = (count + LATCH/2) / LATCH; - - return count; -} - -static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id) -{ - unsigned long timer_status; - - /* Clear CMF bit */ - timer_status = ctrl_inw(CMT_CMCSR_0); - timer_status &= ~0x80; - ctrl_outw(timer_status, CMT_CMCSR_0); - - handle_timer_tick(); - - return IRQ_HANDLED; -} - -static struct irqaction cmt_irq = { - .name = "timer", - .handler = cmt_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, -}; - -static void cmt_clk_init(struct clk *clk) -{ - u8 divisor = CMT_CMCSR_INIT & 0x3; - ctrl_inw(CMT_CMCSR_0); - ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0); - clk->parent = clk_get(NULL, "module_clk"); - clk->rate = clk->parent->rate / (8 << (divisor << 1)); -} - -static void cmt_clk_recalc(struct clk *clk) -{ - u8 divisor = ctrl_inw(CMT_CMCSR_0) & 0x3; - clk->rate = clk->parent->rate / (8 << (divisor << 1)); -} - -static struct clk_ops cmt_clk_ops = { - .init = cmt_clk_init, - .recalc = cmt_clk_recalc, -}; - -static struct clk cmt0_clk = { - .name = "cmt0_clk", - .ops = &cmt_clk_ops, -}; - -static int cmt_timer_start(void) -{ - ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR); - return 0; -} - -static int cmt_timer_stop(void) -{ - ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR); - return 0; -} - -static int cmt_timer_init(void) -{ - unsigned long interval; - - cmt_clock_enable(); - - setup_irq(CONFIG_SH_TIMER_IRQ, &cmt_irq); - - cmt0_clk.parent = clk_get(NULL, "module_clk"); - - cmt_timer_stop(); - - interval = cmt0_clk.parent->rate / 8 / HZ; - printk(KERN_INFO "Interval = %ld\n", interval); - - ctrl_outw(interval, CMT_CMCOR_0); - - clk_register(&cmt0_clk); - clk_enable(&cmt0_clk); - - cmt_timer_start(); - - return 0; -} - -static struct sys_timer_ops cmt_timer_ops = { - .init = cmt_timer_init, - .start = cmt_timer_start, - .stop = cmt_timer_stop, -#ifndef CONFIG_GENERIC_TIME - .get_offset = cmt_timer_get_offset, -#endif -}; - -struct sys_timer cmt_timer = { - .name = "cmt", - .ops = &cmt_timer_ops, -}; diff --git a/arch/sh/kernel/timers/timer.c b/arch/sh/kernel/timers/timer.c index 4e7e747d1b69..f3bd1413d568 100644 --- a/arch/sh/kernel/timers/timer.c +++ b/arch/sh/kernel/timers/timer.c @@ -19,9 +19,6 @@ static struct sys_timer *sys_timers[] = { #endif #ifdef CONFIG_SH_MTU2 &mtu2_timer, -#endif -#ifdef CONFIG_SH_CMT - &cmt_timer, #endif NULL, }; -- GitLab From c5dd016cdf0a040e1de0b691e274fbfe642b2cdc Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 30 Apr 2009 09:48:16 +1000 Subject: [PATCH 0939/6080] perf_counter: update copyright notice This adds my name to the list of copyright holders on the core perf_counter.c, since I have contributed a significant amount of the code in there. Signed-off-by: Paul Mackerras Cc: Peter Zijlstra Cc: Robert Richter LKML-Reference: <18936.59200.888049.746658@cargo.ozlabs.ibm.com> Signed-off-by: Ingo Molnar --- kernel/perf_counter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index a95a171e608c..75f2b6c82392 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -4,6 +4,7 @@ * Copyright (C) 2008 Thomas Gleixner * Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar * Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra + * Copyright © 2009 Paul Mackerras, IBM Corp. * * For licensing details see kernel-base/COPYING */ -- GitLab From aac3f3c2c41ce49a6dbb98d9145265c00a964dc2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 30 Apr 2009 13:52:19 +0200 Subject: [PATCH 0940/6080] perf_counter tools: add perf-report to the Makefile Build it explicitly until it's a proper builtin command. Signed-off-by: Ingo Molnar --- Documentation/perf_counter/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/perf_counter/Makefile b/Documentation/perf_counter/Makefile index 543ccf28ac4a..877cf5dedb55 100644 --- a/Documentation/perf_counter/Makefile +++ b/Documentation/perf_counter/Makefile @@ -228,7 +228,7 @@ COMPAT_CFLAGS = COMPAT_OBJS = LIB_H = LIB_OBJS = -PROGRAMS = +PROGRAMS = perf-report SCRIPT_PERL = SCRIPT_SH = TEST_PROGRAMS = @@ -808,6 +808,10 @@ clean: $(RM) $(htmldocs).tar.gz $(manpages).tar.gz $(RM) PERF-VERSION-FILE PERF-CFLAGS PERF-BUILD-OPTIONS +# temporary hack: +perf-report: perf-report.cc ../../include/linux/perf_counter.h Makefile + g++ -g -O2 -Wall -lrt -o $@ $< + .PHONY: all install clean strip .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS -- GitLab From 66cf782996f3d57d3cc199f0a2d47a54e2aa5991 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 30 Apr 2009 13:53:33 +0200 Subject: [PATCH 0941/6080] perf_counter tools: perf stat: make -l default-on Turn on scaling display by default - this is less confusing. Signed-off-by: Ingo Molnar --- Documentation/perf_counter/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/perf_counter/builtin-stat.c b/Documentation/perf_counter/builtin-stat.c index 112b94ed3298..1fde12762ca4 100644 --- a/Documentation/perf_counter/builtin-stat.c +++ b/Documentation/perf_counter/builtin-stat.c @@ -171,7 +171,7 @@ static unsigned int page_size; static int zero; -static int scale; +static int scale = 1; static const unsigned int default_count[] = { 1000000, -- GitLab From bad760089c1ef7fe525c0f268a4078b9cb483903 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 30 Apr 2009 14:14:37 +0200 Subject: [PATCH 0942/6080] perf_counter tools: fix infinite loop in perf-report on zeroed event records Bail out early if a record has zero size - we have no chance to make reliable progress in that case. Print out the offset where this happens, and print the number of bytes we missed out on. Signed-off-by: Ingo Molnar --- Documentation/perf_counter/perf-report.cc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Documentation/perf_counter/perf-report.cc b/Documentation/perf_counter/perf-report.cc index 1727317352bf..933a07544534 100644 --- a/Documentation/perf_counter/perf-report.cc +++ b/Documentation/perf_counter/perf-report.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -226,7 +227,7 @@ void load_kallsyms(void) while (!feof(file)) { uint64_t start; char c; - char sym[1024]; + char sym[1024000]; if (getline(&line, &n, file) < 0) break; @@ -416,12 +417,23 @@ more: if (head + event->header.size >= page_size * mmap_window) { unsigned long shift = page_size * (head / page_size); + int ret; + + ret = munmap(buf, page_size * mmap_window); + assert(ret == 0); - munmap(buf, page_size * mmap_window); offset += shift; head -= shift; goto remap; } + + + if (!event->header.size) { + fprintf(stderr, "zero-sized event at file offset %ld\n", offset + head); + fprintf(stderr, "skipping %ld bytes of events.\n", stat.st_size - offset - head); + goto done; + } + head += event->header.size; if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { @@ -458,6 +470,8 @@ more: if (offset + head < stat.st_size) goto more; +done: + close(input); std::map::iterator hi = hist.begin(); -- GitLab From 09aa60df92a9c5ff00e156c0dbc79f166d406a7f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 29 Apr 2009 18:51:48 +0100 Subject: [PATCH 0943/6080] ASoC: Fix error message formatting in s3c64xx-i2s driver Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c64xx-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 1345fbdca700..7679f7bc79c3 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -215,7 +215,7 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); if (IS_ERR(i2s->iis_cclk)) { - dev_err(&pdev->dev, "failed to get audio-bus"); + dev_err(&pdev->dev, "failed to get audio-bus\n"); ret = PTR_ERR(i2s->iis_cclk); goto err; } -- GitLab From 8a0f62b842e2f189e36d9f4c575ee15da9c605ff Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 29 Apr 2009 20:28:47 +0100 Subject: [PATCH 0944/6080] ASoC: Check for supported CPUs when building s3c-i2s-v2 Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-i2s-v2.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index ab680aac3fcb..3b9201cfe43c 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -37,6 +37,20 @@ #include "s3c-i2s-v2.h" +#undef S3C_IIS_V2_SUPPORTED + +#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) +#define S3C_IIS_V2_SUPPORTED +#endif + +#ifdef CONFIG_PLAT_S3C64XX +#define S3C_IIS_V2_SUPPORTED +#endif + +#ifndef S3C_IIS_V2_SUPPORTED +#error Unsupported CPU model +#endif + #define S3C2412_I2S_DEBUG_CON 0 static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) -- GitLab From 51438449e717db54550b4676f38208092eb654da Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 29 Apr 2009 20:30:39 +0100 Subject: [PATCH 0945/6080] ASoC: Make S3C64xx clock export function to return struct clk This makes the interface usable with the s3c-iis-v2 rate calculator and consistent with S3C2412. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c64xx-i2s.c | 7 +++---- sound/soc/s3c24xx/s3c64xx-i2s.h | 4 +++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 7679f7bc79c3..cb11f7831474 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -108,14 +108,13 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, return 0; } - -unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai) +struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) { struct s3c_i2sv2_info *i2s = to_info(dai); - return clk_get_rate(i2s->iis_cclk); + return i2s->iis_cclk; } -EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); +EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); static int s3c64xx_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h index 597822a4658f..02148cee2613 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.h +++ b/sound/soc/s3c24xx/s3c64xx-i2s.h @@ -15,6 +15,8 @@ #ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H #define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__ +struct clk; + #include "s3c-i2s-v2.h" #define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK @@ -26,6 +28,6 @@ extern struct snd_soc_dai s3c64xx_i2s_dai[]; -extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); +extern struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai); #endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ -- GitLab From 553b1dd58c5cf1abd6d0965041169400a3cff1ad Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 29 Apr 2009 20:29:25 +0100 Subject: [PATCH 0946/6080] ASoC: Fix data format configuration for S3C64xx IISv2 and add 24 bit The data format configuration for S3C64xx IISv2 is completely different to that for S3C24xx. Instead of a single bit configuration in bit 0 of IISMOD we have format selection in bits 13 and 14 and bit clock rate selection in bits 1 and 2. While we're here add support for 24 bit samples in S3C64xx. At some point it may be desirable to expose the bit clock rate selection to users but given the limited configuration options that may not be required. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-i2s-v2.c | 22 +++++++++++++++++++++- sound/soc/s3c24xx/s3c64xx-i2s.c | 3 ++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index 3b9201cfe43c..54f4119e6098 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -280,7 +280,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, */ #define IISMOD_MASTER_MASK (1 << 11) #define IISMOD_SLAVE (1 << 11) -#define IISMOD_MASTER (0x0) +#define IISMOD_MASTER (0 << 11) #endif switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -341,6 +341,7 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, iismod = readl(i2s->regs + S3C2412_IISMOD); pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); +#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod |= S3C2412_IISMOD_8BIT; @@ -349,6 +350,25 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, iismod &= ~S3C2412_IISMOD_8BIT; break; } +#endif + +#ifdef CONFIG_PLAT_S3C64XX + iismod &= ~0x606; + /* Sample size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + /* 8 bit sample, 16fs BCLK */ + iismod |= 0x2004; + break; + case SNDRV_PCM_FORMAT_S16_LE: + /* 16 bit sample, 32fs BCLK */ + break; + case SNDRV_PCM_FORMAT_S24_LE: + /* 24 bit sample, 48fs BCLK */ + iismod |= 0x4002; + break; + } +#endif writel(iismod, i2s->regs + S3C2412_IISMOD); pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index cb11f7831474..e0f4a1644f1f 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -146,7 +146,8 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev, SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) #define S3C64XX_I2S_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) + (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE) static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { .set_sysclk = s3c64xx_i2s_set_sysclk, -- GitLab From 07736d48051869c37838635b41850618aa63b9a7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 30 Apr 2009 13:13:14 +0100 Subject: [PATCH 0947/6080] ASoC: Fix boot warnings from S3C IISv2 On startup we try to make sure that the port is quiesced but if the port is already stopped then this will generate a warning about the RX/TX mode configuration. Configure the mode before doing the teardown to suppress these warnings. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-i2s-v2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index 54f4119e6098..34142c859225 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -573,6 +573,7 @@ int s3c_i2sv2_probe(struct platform_device *pdev, unsigned long base) { struct device *dev = &pdev->dev; + unsigned int iismod; i2s->dev = dev; @@ -594,12 +595,16 @@ int s3c_i2sv2_probe(struct platform_device *pdev, clk_enable(i2s->iis_pclk); + /* Mark ourselves as in TXRX mode so we can run through our cleanup + * process without warnings. */ + iismod = readl(i2s->regs + S3C2412_IISMOD); + iismod |= S3C2412_IISMOD_MODE_TXRX; + writel(iismod, i2s->regs + S3C2412_IISMOD); s3c2412_snd_txctrl(i2s, 0); s3c2412_snd_rxctrl(i2s, 0); return 0; } - EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); #ifdef CONFIG_PM -- GitLab From c86bde54062a4d02c1b58203b7802797e4007a8a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 30 Apr 2009 13:09:33 +0100 Subject: [PATCH 0948/6080] ASoC: Allow use of resource from the platform device for S3C IISv2 Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-i2s-v2.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index 34142c859225..cb85498723dd 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -580,6 +580,24 @@ int s3c_i2sv2_probe(struct platform_device *pdev, /* record our i2s structure for later use in the callbacks */ dai->private_data = i2s; + if (!base) { + struct resource *res = platform_get_resource(pdev, + IORESOURCE_MEM, + 0); + if (!res) { + dev_err(dev, "Unable to get register resource\n"); + return -ENXIO; + } + + if (!request_mem_region(res->start, resource_size(res), + "s3c64xx-i2s-v4")) { + dev_err(dev, "Unable to request register region\n"); + return -EBUSY; + } + + base = res->start; + } + i2s->regs = ioremap(base, 0x100); if (i2s->regs == NULL) { dev_err(dev, "cannot ioremap registers\n"); -- GitLab From af3ea7bdc77be000f69a41e7c41060f72b5a7111 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 30 Apr 2009 13:13:55 +0100 Subject: [PATCH 0949/6080] ASoC: Display the clock rate used as the basis for rate calculation Aids debugging. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-i2s-v2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index cb85498723dd..ad690b2b83ae 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -523,6 +523,8 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, unsigned int best_rate = 0; unsigned int best_deviation = INT_MAX; + pr_debug("Input clock rate %ldHz\n", clkrate); + if (fstab == NULL) fstab = iis_fs_tab; -- GitLab From 38e43c81a07de8ee8a757a9c93dd3a4937dd35e0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 30 Apr 2009 13:14:38 +0100 Subject: [PATCH 0950/6080] ASoC: Display S3C IISv2 mode and MS errors by default Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-i2s-v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index ad690b2b83ae..bc4e5044e6ca 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -295,7 +295,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= IISMOD_MASTER; break; default: - pr_debug("unknwon master/slave format\n"); + pr_err("unknwon master/slave format\n"); return -EINVAL; } @@ -312,7 +312,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= S3C2412_IISMOD_SDF_IIS; break; default: - pr_debug("Unknown data format\n"); + pr_err("Unknown data format\n"); return -EINVAL; } -- GitLab From abbc82466967064e4eaafa367fc225a8c803569c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 30 Apr 2009 13:21:52 +0100 Subject: [PATCH 0951/6080] ASoC: Staticise txctrl and rxctrl for S3C IISv2 They aren't used by anything external and aren't prototyped; if any users appear they can be exported again for them. Also report what modes we have a problem with when we encounter invalid mode configurations. Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c-i2s-v2.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index bc4e5044e6ca..972c27684198 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -89,7 +89,7 @@ static inline void dbg_showcon(const char *fn, u32 con) /* Turn on or off the transmission path. */ -void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) +static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) { void __iomem *regs = i2s->regs; u32 fic, con, mod; @@ -119,7 +119,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + break; } writel(con, regs + S3C2412_IISCON); @@ -146,7 +148,9 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + break; } writel(mod, regs + S3C2412_IISMOD); @@ -157,9 +161,8 @@ void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) dbg_showcon(__func__, con); pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); } -EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl); -void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) +static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) { void __iomem *regs = i2s->regs; u32 fic, con, mod; @@ -189,7 +192,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); } writel(mod, regs + S3C2412_IISMOD); @@ -213,7 +217,8 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); + dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); } writel(con, regs + S3C2412_IISCON); @@ -223,7 +228,6 @@ void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) fic = readl(regs + S3C2412_IISFIC); pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); } -EXPORT_SYMBOL_GPL(s3c2412_snd_rxctrl); /* * Wait for the LR signal to allow synchronisation to the L/R clock -- GitLab From 71437552f2564c0d0c5cc4995045683051c5fe62 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 30 Apr 2009 13:42:04 +0100 Subject: [PATCH 0952/6080] ASoC: Use platform device resource for S3C64xx IISv2 Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c64xx-i2s.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index e0f4a1644f1f..3c06c401d0fb 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -220,8 +220,7 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) goto err; } - ret = s3c_i2sv2_probe(pdev, dai, i2s, - dai->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0); + ret = s3c_i2sv2_probe(pdev, dai, i2s, 0); if (ret) goto err_clk; -- GitLab From 03682411b1ccd38cbde2e9a6ab43884ff34fbefc Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 30 Apr 2009 18:38:01 +0200 Subject: [PATCH 0953/6080] alim15x3: Remove historical hacks, re-enable init_hwif for PowerPC Some time ago we had to disable init_hwif callback for PowerPC builds. That was because of a historical IRQ overwrite in the driver, which was causing IDE malfunction on the MPC8610HPCD PowerPC boards. It's unclear whether this overwrite is still useful, but it is proven to cause a bit of harm, and today some PowerPC targets (Xilinx ML510, as reported by Roderick Colenbrander) need the init_hwif, so we have to re-enable it and remove the overwrite. Reported-by: Roderick Colenbrander Suggested-by: Bartlomiej Zolnierkiewicz Cc: Benjamin Herrenschmidt Signed-off-by: Anton Vorontsov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/alim15x3.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 537da1cde16d..e59b6dee9ae2 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -402,27 +402,23 @@ static u8 ali_cable_detect(ide_hwif_t *hwif) return cbl; } -#if !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) +#ifndef CONFIG_SPARC64 /** * init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff * @hwif: interface to configure * * Obtain the IRQ tables for an ALi based IDE solution on the PC * class platforms. This part of the code isn't applicable to the - * Sparc and PowerPC systems. + * Sparc systems. */ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) { - struct pci_dev *dev = to_pci_dev(hwif->dev); u8 ideic, inmir; s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; int irq = -1; - if (dev->device == PCI_DEVICE_ID_AL_M5229) - hwif->irq = hwif->channel ? 15 : 14; - if (isa_dev) { /* * read IDE interface control @@ -455,7 +451,7 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) } #else #define init_hwif_ali15x3 NULL -#endif /* !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) */ +#endif /* CONFIG_SPARC64 */ /** * init_dma_ali15x3 - set up DMA on ALi15x3 -- GitLab From e74cc06df3b05e2b2c1611a043f6e6dcadaab1eb Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Wed, 28 Jan 2009 19:18:32 +0100 Subject: [PATCH 0954/6080] configfs: Silence lockdep on mkdir() and rmdir() When attaching default groups (subdirs) of a new group (in mkdir() or in configfs_register()), configfs recursively takes inode's mutexes along the path from the parent of the new group to the default subdirs. This is needed to ensure that the VFS will not race with operations on these sub-dirs. This is safe for the following reasons: - the VFS allows one to lock first an inode and second one of its children (The lock subclasses for this pattern are respectively I_MUTEX_PARENT and I_MUTEX_CHILD); - from this rule any inode path can be recursively locked in descending order as long as it stays under a single mountpoint and does not follow symlinks. Unfortunately lockdep does not know (yet?) how to handle such recursion. I've tried to use Peter Zijlstra's lock_set_subclass() helper to upgrade i_mutexes from I_MUTEX_CHILD to I_MUTEX_PARENT when we know that we might recursively lock some of their descendant, but this usage does not seem to fit the purpose of lock_set_subclass() because it leads to several i_mutex locked with subclass I_MUTEX_PARENT by the same task. >From inside configfs it is not possible to serialize those recursive locking with a top-level one, because mkdir() and rmdir() are already called with inodes locked by the VFS. So using some mutex_lock_nest_lock() is not an option. I am proposing two solutions: 1) one that wraps recursive mutex_lock()s with lockdep_off()/lockdep_on(). 2) (as suggested earlier by Peter Zijlstra) one that puts the i_mutexes recursively locked in different classes based on their depth from the top-level config_group created. This induces an arbitrary limit (MAX_LOCK_DEPTH - 2 == 46) on the nesting of configfs default groups whenever lockdep is activated but this limit looks reasonably high. Unfortunately, this also isolates VFS operations on configfs default groups from the others and thus lowers the chances to detect locking issues. Nobody likes solution 1), which I can understand. This patch implements solution 2). However lockdep is still not happy with configfs_depend_item(). Next patch reworks the locking of configfs_depend_item() and finally makes lockdep happy. [ Note: This hides a few locking interactions with the VFS from lockdep. That was my big concern, because we like lockdep's protection. However, the current state always dumps a spurious warning. The locking is correct, so I tell people to ignore the warning and that we'll keep our eyes on the locking to make sure it stays correct. With this patch, we eliminate the warning. We do lose some of the lockdep protections, but this only means that we still have to keep our eyes on the locking. We're going to do that anyway. -- Joel ] Signed-off-by: Louis Rilling Signed-off-by: Joel Becker --- fs/configfs/configfs_internal.h | 3 ++ fs/configfs/dir.c | 90 +++++++++++++++++++++++++++++++++ fs/configfs/inode.c | 38 ++++++++++++++ 3 files changed, 131 insertions(+) diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index 762d287123ca..da6061a6df40 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h @@ -39,6 +39,9 @@ struct configfs_dirent { umode_t s_mode; struct dentry * s_dentry; struct iattr * s_iattr; +#ifdef CONFIG_LOCKDEP + int s_depth; +#endif }; #define CONFIGFS_ROOT 0x0001 diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 05373db21a4e..d4d871fba21e 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -78,6 +78,92 @@ static const struct dentry_operations configfs_dentry_ops = { .d_delete = configfs_d_delete, }; +#ifdef CONFIG_LOCKDEP + +/* + * Helpers to make lockdep happy with our recursive locking of default groups' + * inodes (see configfs_attach_group() and configfs_detach_group()). + * We put default groups i_mutexes in separate classes according to their depth + * from the youngest non-default group ancestor. + * + * For a non-default group A having default groups A/B, A/C, and A/C/D, default + * groups A/B and A/C will have their inode's mutex in class + * default_group_class[0], and default group A/C/D will be in + * default_group_class[1]. + * + * The lock classes are declared and assigned in inode.c, according to the + * s_depth value. + * The s_depth value is initialized to -1, adjusted to >= 0 when attaching + * default groups, and reset to -1 when all default groups are attached. During + * attachment, if configfs_create() sees s_depth > 0, the lock class of the new + * inode's mutex is set to default_group_class[s_depth - 1]. + */ + +static void configfs_init_dirent_depth(struct configfs_dirent *sd) +{ + sd->s_depth = -1; +} + +static void configfs_set_dir_dirent_depth(struct configfs_dirent *parent_sd, + struct configfs_dirent *sd) +{ + int parent_depth = parent_sd->s_depth; + + if (parent_depth >= 0) + sd->s_depth = parent_depth + 1; +} + +static void +configfs_adjust_dir_dirent_depth_before_populate(struct configfs_dirent *sd) +{ + /* + * item's i_mutex class is already setup, so s_depth is now only + * used to set new sub-directories s_depth, which is always done + * with item's i_mutex locked. + */ + /* + * sd->s_depth == -1 iff we are a non default group. + * else (we are a default group) sd->s_depth > 0 (see + * create_dir()). + */ + if (sd->s_depth == -1) + /* + * We are a non default group and we are going to create + * default groups. + */ + sd->s_depth = 0; +} + +static void +configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd) +{ + /* We will not create default groups anymore. */ + sd->s_depth = -1; +} + +#else /* CONFIG_LOCKDEP */ + +static void configfs_init_dirent_depth(struct configfs_dirent *sd) +{ +} + +static void configfs_set_dir_dirent_depth(struct configfs_dirent *parent_sd, + struct configfs_dirent *sd) +{ +} + +static void +configfs_adjust_dir_dirent_depth_before_populate(struct configfs_dirent *sd) +{ +} + +static void +configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd) +{ +} + +#endif /* CONFIG_LOCKDEP */ + /* * Allocates a new configfs_dirent and links it to the parent configfs_dirent */ @@ -94,6 +180,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare INIT_LIST_HEAD(&sd->s_links); INIT_LIST_HEAD(&sd->s_children); sd->s_element = element; + configfs_init_dirent_depth(sd); spin_lock(&configfs_dirent_lock); if (parent_sd->s_type & CONFIGFS_USET_DROPPING) { spin_unlock(&configfs_dirent_lock); @@ -187,6 +274,7 @@ static int create_dir(struct config_item * k, struct dentry * p, error = configfs_make_dirent(p->d_fsdata, d, k, mode, CONFIGFS_DIR | CONFIGFS_USET_CREATING); if (!error) { + configfs_set_dir_dirent_depth(p->d_fsdata, d->d_fsdata); error = configfs_create(d, mode, init_dir); if (!error) { inc_nlink(p->d_inode); @@ -789,11 +877,13 @@ static int configfs_attach_group(struct config_item *parent_item, * error, as rmdir() would. */ mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); + configfs_adjust_dir_dirent_depth_before_populate(sd); ret = populate_groups(to_config_group(item)); if (ret) { configfs_detach_item(item); dentry->d_inode->i_flags |= S_DEAD; } + configfs_adjust_dir_dirent_depth_after_populate(sd); mutex_unlock(&dentry->d_inode->i_mutex); if (ret) d_delete(dentry); diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index 5d349d38e056..4921e7426d95 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c @@ -33,10 +33,15 @@ #include #include #include +#include #include #include "configfs_internal.h" +#ifdef CONFIG_LOCKDEP +static struct lock_class_key default_group_class[MAX_LOCK_DEPTH]; +#endif + extern struct super_block * configfs_sb; static const struct address_space_operations configfs_aops = { @@ -150,6 +155,38 @@ struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent * sd) return inode; } +#ifdef CONFIG_LOCKDEP + +static void configfs_set_inode_lock_class(struct configfs_dirent *sd, + struct inode *inode) +{ + int depth = sd->s_depth; + + if (depth > 0) { + if (depth <= ARRAY_SIZE(default_group_class)) { + lockdep_set_class(&inode->i_mutex, + &default_group_class[depth - 1]); + } else { + /* + * In practice the maximum level of locking depth is + * already reached. Just inform about possible reasons. + */ + printk(KERN_INFO "configfs: Too many levels of inodes" + " for the locking correctness validator.\n"); + printk(KERN_INFO "Spurious warnings may appear.\n"); + } + } +} + +#else /* CONFIG_LOCKDEP */ + +static void configfs_set_inode_lock_class(struct configfs_dirent *sd, + struct inode *inode) +{ +} + +#endif /* CONFIG_LOCKDEP */ + int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *)) { int error = 0; @@ -162,6 +199,7 @@ int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode * struct inode *p_inode = dentry->d_parent->d_inode; p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; } + configfs_set_inode_lock_class(sd, inode); goto Proceed; } else -- GitLab From 420118caa32c8ccdf9fce5a623b9de3f951573c5 Mon Sep 17 00:00:00 2001 From: Louis Rilling Date: Wed, 28 Jan 2009 19:18:33 +0100 Subject: [PATCH 0955/6080] configfs: Rework configfs_depend_item() locking and make lockdep happy configfs_depend_item() recursively locks all inodes mutex from configfs root to the target item, which makes lockdep unhappy. The purpose of this recursive locking is to ensure that the item tree can be safely parsed and that the target item, if found, is not about to leave. This patch reworks configfs_depend_item() locking using configfs_dirent_lock. Since configfs_dirent_lock protects all changes to the configfs_dirent tree, and protects tagging of items to be removed, this lock can be used instead of the inodes mutex lock chain. This needs that the check for dependents be done atomically with CONFIGFS_USET_DROPPING tagging. Now lockdep looks happy with configfs. [ Lifted the setting of s_type into configfs_new_dirent() to satisfy the atomic setting of CONFIGFS_USET_CREATING -- Joel ] Signed-off-by: Louis Rilling Signed-off-by: Joel Becker --- fs/configfs/dir.c | 106 ++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 59 deletions(-) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index d4d871fba21e..8e48b52205aa 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -167,8 +167,8 @@ configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd) /* * Allocates a new configfs_dirent and links it to the parent configfs_dirent */ -static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * parent_sd, - void * element) +static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *parent_sd, + void *element, int type) { struct configfs_dirent * sd; @@ -180,6 +180,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare INIT_LIST_HEAD(&sd->s_links); INIT_LIST_HEAD(&sd->s_children); sd->s_element = element; + sd->s_type = type; configfs_init_dirent_depth(sd); spin_lock(&configfs_dirent_lock); if (parent_sd->s_type & CONFIGFS_USET_DROPPING) { @@ -225,12 +226,11 @@ int configfs_make_dirent(struct configfs_dirent * parent_sd, { struct configfs_dirent * sd; - sd = configfs_new_dirent(parent_sd, element); + sd = configfs_new_dirent(parent_sd, element, type); if (IS_ERR(sd)) return PTR_ERR(sd); sd->s_mode = mode; - sd->s_type = type; sd->s_dentry = dentry; if (dentry) { dentry->d_fsdata = configfs_get(sd); @@ -1006,11 +1006,11 @@ static int configfs_dump(struct configfs_dirent *sd, int level) * Note, btw, that this can be called at *any* time, even when a configfs * subsystem isn't registered, or when configfs is loading or unloading. * Just like configfs_register_subsystem(). So we take the same - * precautions. We pin the filesystem. We lock each i_mutex _in_order_ - * on our way down the tree. If we can find the target item in the + * precautions. We pin the filesystem. We lock configfs_dirent_lock. + * If we can find the target item in the * configfs tree, it must be part of the subsystem tree as well, so we - * do not need the subsystem semaphore. Holding the i_mutex chain locks - * out mkdir() and rmdir(), who might be racing us. + * do not need the subsystem semaphore. Holding configfs_dirent_lock helps + * locking out mkdir() and rmdir(), who might be racing us. */ /* @@ -1023,17 +1023,21 @@ static int configfs_dump(struct configfs_dirent *sd, int level) * do that so we can unlock it if we find nothing. * * Here we do a depth-first search of the dentry hierarchy looking for - * our object. We take i_mutex on each step of the way down. IT IS - * ESSENTIAL THAT i_mutex LOCKING IS ORDERED. If we come back up a branch, - * we'll drop the i_mutex. + * our object. + * We deliberately ignore items tagged as dropping since they are virtually + * dead, as well as items in the middle of attachment since they virtually + * do not exist yet. This completes the locking out of racing mkdir() and + * rmdir(). + * Note: subdirectories in the middle of attachment start with s_type = + * CONFIGFS_DIR|CONFIGFS_USET_CREATING set by create_dir(). When + * CONFIGFS_USET_CREATING is set, we ignore the item. The actual set of + * s_type is in configfs_new_dirent(), which has configfs_dirent_lock. * - * If the target is not found, -ENOENT is bubbled up and we have released - * all locks. If the target was found, the locks will be cleared by - * configfs_depend_rollback(). + * If the target is not found, -ENOENT is bubbled up. * * This adds a requirement that all config_items be unique! * - * This is recursive because the locking traversal is tricky. There isn't + * This is recursive. There isn't * much on the stack, though, so folks that need this function - be careful * about your stack! Patches will be accepted to make it iterative. */ @@ -1045,13 +1049,13 @@ static int configfs_depend_prep(struct dentry *origin, BUG_ON(!origin || !sd); - /* Lock this guy on the way down */ - mutex_lock(&sd->s_dentry->d_inode->i_mutex); if (sd->s_element == target) /* Boo-yah */ goto out; list_for_each_entry(child_sd, &sd->s_children, s_sibling) { - if (child_sd->s_type & CONFIGFS_DIR) { + if ((child_sd->s_type & CONFIGFS_DIR) && + !(child_sd->s_type & CONFIGFS_USET_DROPPING) && + !(child_sd->s_type & CONFIGFS_USET_CREATING)) { ret = configfs_depend_prep(child_sd->s_dentry, target); if (!ret) @@ -1060,33 +1064,12 @@ static int configfs_depend_prep(struct dentry *origin, } /* We looped all our children and didn't find target */ - mutex_unlock(&sd->s_dentry->d_inode->i_mutex); ret = -ENOENT; out: return ret; } -/* - * This is ONLY called if configfs_depend_prep() did its job. So we can - * trust the entire path from item back up to origin. - * - * We walk backwards from item, unlocking each i_mutex. We finish by - * unlocking origin. - */ -static void configfs_depend_rollback(struct dentry *origin, - struct config_item *item) -{ - struct dentry *dentry = item->ci_dentry; - - while (dentry != origin) { - mutex_unlock(&dentry->d_inode->i_mutex); - dentry = dentry->d_parent; - } - - mutex_unlock(&origin->d_inode->i_mutex); -} - int configfs_depend_item(struct configfs_subsystem *subsys, struct config_item *target) { @@ -1127,17 +1110,21 @@ int configfs_depend_item(struct configfs_subsystem *subsys, /* Ok, now we can trust subsys/s_item */ - /* Scan the tree, locking i_mutex recursively, return 0 if found */ + spin_lock(&configfs_dirent_lock); + /* Scan the tree, return 0 if found */ ret = configfs_depend_prep(subsys_sd->s_dentry, target); if (ret) - goto out_unlock_fs; + goto out_unlock_dirent_lock; - /* We hold all i_mutexes from the subsystem down to the target */ + /* + * We are sure that the item is not about to be removed by rmdir(), and + * not in the middle of attachment by mkdir(). + */ p = target->ci_dentry->d_fsdata; p->s_dependent_count += 1; - configfs_depend_rollback(subsys_sd->s_dentry, target); - +out_unlock_dirent_lock: + spin_unlock(&configfs_dirent_lock); out_unlock_fs: mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); @@ -1162,10 +1149,10 @@ void configfs_undepend_item(struct configfs_subsystem *subsys, struct configfs_dirent *sd; /* - * Since we can trust everything is pinned, we just need i_mutex - * on the item. + * Since we can trust everything is pinned, we just need + * configfs_dirent_lock. */ - mutex_lock(&target->ci_dentry->d_inode->i_mutex); + spin_lock(&configfs_dirent_lock); sd = target->ci_dentry->d_fsdata; BUG_ON(sd->s_dependent_count < 1); @@ -1176,7 +1163,7 @@ void configfs_undepend_item(struct configfs_subsystem *subsys, * After this unlock, we cannot trust the item to stay alive! * DO NOT REFERENCE item after this unlock. */ - mutex_unlock(&target->ci_dentry->d_inode->i_mutex); + spin_unlock(&configfs_dirent_lock); } EXPORT_SYMBOL(configfs_undepend_item); @@ -1376,13 +1363,6 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) if (sd->s_type & CONFIGFS_USET_DEFAULT) return -EPERM; - /* - * Here's where we check for dependents. We're protected by - * i_mutex. - */ - if (sd->s_dependent_count) - return -EBUSY; - /* Get a working ref until we have the child */ parent_item = configfs_get_config_item(dentry->d_parent); subsys = to_config_group(parent_item)->cg_subsys; @@ -1406,9 +1386,17 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry) mutex_lock(&configfs_symlink_mutex); spin_lock(&configfs_dirent_lock); - ret = configfs_detach_prep(dentry, &wait_mutex); - if (ret) - configfs_detach_rollback(dentry); + /* + * Here's where we check for dependents. We're protected by + * configfs_dirent_lock. + * If no dependent, atomically tag the item as dropping. + */ + ret = sd->s_dependent_count ? -EBUSY : 0; + if (!ret) { + ret = configfs_detach_prep(dentry, &wait_mutex); + if (ret) + configfs_detach_rollback(dentry); + } spin_unlock(&configfs_dirent_lock); mutex_unlock(&configfs_symlink_mutex); @@ -1519,7 +1507,7 @@ static int configfs_dir_open(struct inode *inode, struct file *file) */ err = -ENOENT; if (configfs_dirent_is_ready(parent_sd)) { - file->private_data = configfs_new_dirent(parent_sd, NULL); + file->private_data = configfs_new_dirent(parent_sd, NULL, 0); if (IS_ERR(file->private_data)) err = PTR_ERR(file->private_data); else -- GitLab From 78a3d9d5654a7fd99cf8b2ab06b9497b9c7aad64 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 29 Apr 2009 18:01:23 +0200 Subject: [PATCH 0956/6080] do_wait: do take security_task_wait() into account I was never able to understand what should we actually do when security_task_wait() fails, but the current code doesn't look right. If ->task_wait() returns the error, we update *notask_error correctly. But then we either reap the child (despite the fact this was forbidden) or clear *notask_error (and hide the securiy policy problems). This patch assumes that "stolen by ptrace" doesn't matter. If selinux denies the child we should ignore it but make sure we report -EACCESS instead of -ECHLD if there are no other eligible children. Signed-off-by: Oleg Nesterov Acked-by: Roland McGrath Signed-off-by: James Morris --- kernel/exit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/exit.c b/kernel/exit.c index 167e1e3ad7c6..d2e8239ea187 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1582,6 +1582,7 @@ static int wait_consider_task(struct task_struct *parent, int ptrace, */ if (*notask_error) *notask_error = ret; + return 0; } if (likely(!ptrace) && unlikely(p->ptrace)) { -- GitLab From d6662c351a827264706bf880a36cdd376808ba1c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 12 Dec 2008 00:24:40 +0000 Subject: [PATCH 0957/6080] [ARM] SMDK6410: Ensure LCD settings are setup Ensure that the LCD output type is RGB and that the modem interface is not bypassing the LCD block. This ensures the LCD interface output gets to the pins in the correct format. Signed-off-by: Ben Dooks --- arch/arm/mach-s3c6410/mach-smdk6410.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/mach-s3c6410/mach-smdk6410.c b/arch/arm/mach-s3c6410/mach-smdk6410.c index 7f473e47e4f1..d0b9f09b7269 100644 --- a/arch/arm/mach-s3c6410/mach-smdk6410.c +++ b/arch/arm/mach-s3c6410/mach-smdk6410.c @@ -39,6 +39,9 @@ #include #include +#include +#include +#include #include #include @@ -155,9 +158,23 @@ static struct i2c_board_info i2c_devs1[] __initdata = { static void __init smdk6410_map_io(void) { + u32 tmp; + s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs)); + + /* set the LCD type */ + + tmp = __raw_readl(S3C64XX_SPCON); + tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK; + tmp |= S3C64XX_SPCON_LCD_SEL_RGB; + __raw_writel(tmp, S3C64XX_SPCON); + + /* remove the lcd bypass */ + tmp = __raw_readl(S3C64XX_MODEM_MIFPCON); + tmp &= ~MIFPCON_LCD_BYPASS; + __raw_writel(tmp, S3C64XX_MODEM_MIFPCON); } static void __init smdk6410_machine_init(void) -- GitLab From 3056ea0afba83d19af5f1f3daf6ed7211f0717da Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 27 Jan 2009 16:18:01 +0000 Subject: [PATCH 0958/6080] [ARM] SMDK6410: Add support for SMSC9115 ethernet controller Signed-off-by: Mark Brown Signed-off-by: Ben Dooks --- arch/arm/mach-s3c6410/mach-smdk6410.c | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm/mach-s3c6410/mach-smdk6410.c b/arch/arm/mach-s3c6410/mach-smdk6410.c index d0b9f09b7269..dfd84d00f8d0 100644 --- a/arch/arm/mach-s3c6410/mach-smdk6410.c +++ b/arch/arm/mach-s3c6410/mach-smdk6410.c @@ -24,6 +24,7 @@ #include #include #include +#include #include